diff options
author | Sven Gothel <[email protected]> | 2010-05-04 06:35:37 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-05-04 06:35:37 +0200 |
commit | 9e792dcef900de7039cd277459c0629abfab9f21 (patch) | |
tree | 81adfd1e07e2118675d62836e1289225f408bb00 /src/newt/native | |
parent | a677e9db03ea44ea353fb9de61e2a86a6e063d0f (diff) |
NEWT Fixes:
- Common native in NewtCommon.c/.h
- Add simple NEWTEventFiFo, providing a pattern
to spool events by an EventListener and to process them
where it impacts (GLEventListener ..)
- Window [X11|Windows]: setSize/setPosition:
- always store the values,
- only act if valid and !fullscreen
- Window [X11]:
- Add requestFocus
- Add setTitle
- Fix parent/child window creation
- Fix parent/child window fullscreen (reparenting)
- JUnit Test: ParentTest:
- Shows parent and client window animation
- Client window shall be able to go into fullscreen,
ie disconnect/reconnect from its parent.
Test: Focus-client + type-'f'
- Both windows receive/dispatch events properly
Diffstat (limited to 'src/newt/native')
-rw-r--r-- | src/newt/native/NewtCommon.c | 13 | ||||
-rw-r--r-- | src/newt/native/NewtCommon.h | 10 | ||||
-rwxr-xr-x | src/newt/native/WindowsWindow.c | 21 | ||||
-rwxr-xr-x | src/newt/native/X11Window.c | 175 |
4 files changed, 158 insertions, 61 deletions
diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c new file mode 100644 index 000000000..8b64ec37f --- /dev/null +++ b/src/newt/native/NewtCommon.c @@ -0,0 +1,13 @@ + +#include "NewtCommon.h" + +jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) +{ + jchar* strChars = NULL; + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } + return strChars; +} + diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h new file mode 100644 index 000000000..46a0d57cf --- /dev/null +++ b/src/newt/native/NewtCommon.h @@ -0,0 +1,10 @@ + +#ifndef NEWT_COMMON_H +#define NEWT_COMMON_H 1 + +#include <jni.h> +#include <stdlib.h> + +jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str); + +#endif diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 82eb81d99..69b87d39d 100755 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -96,6 +96,8 @@ #include "InputEvent.h" #include "KeyEvent.h" +#include "NewtCommon.h" + // #define VERBOSE_ON 1 #ifdef VERBOSE_ON @@ -460,17 +462,6 @@ static void BuildDynamicKeyMapTable() } // for each VK_OEM_* } -// Really need to factor this out in to a separate run-time file -static jchar* GetNullTerminatedStringChars(JNIEnv* env, jstring str) -{ - jchar* strChars = NULL; - strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); - if (strChars != NULL) { - (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); - } - return strChars; -} - static jint GetModifiers() { jint modifiers = 0; // have to do &0xFFFF to avoid runtime assert caused by compiling with @@ -932,7 +923,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_Dispatch JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_LoadLibraryW (JNIEnv *env, jclass clazz, jstring dllName) { - jchar* _dllName = GetNullTerminatedStringChars(env, dllName); + jchar* _dllName = NewtCommon_GetNullTerminatedStringChars(env, dllName); HMODULE lib = LoadLibraryW(_dllName); free(_dllName); return (jlong) (intptr_t) lib; @@ -965,7 +956,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_Register wc.hbrBackground = GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; #ifdef UNICODE - wc.lpszClassName = GetNullTerminatedStringChars(env, wndClassName); + wc.lpszClassName = NewtCommon_GetNullTerminatedStringChars(env, wndClassName); #else _wndClassName = (*env)->GetStringUTFChars(env, wndClassName, NULL); wc.lpszClassName = strdup(_wndClassName); @@ -1062,7 +1053,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi HWND window = NULL; #ifdef UNICODE - wndName = GetNullTerminatedStringChars(env, jWndName); + wndName = NewtCommon_GetNullTerminatedStringChars(env, jWndName); #else wndName = (*env)->GetStringUTFChars(env, jWndName, NULL); #endif @@ -1281,7 +1272,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setTitle { HWND hwnd = (HWND) (intptr_t) window; if (title != NULL) { - jchar *titleString = GetNullTerminatedStringChars(env, title); + jchar *titleString = NewtCommon_GetNullTerminatedStringChars(env, title); if (titleString != NULL) { SetWindowTextW(hwnd, titleString); free(titleString); diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 70fc421e8..e46742aac 100755 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -53,6 +53,8 @@ #include "KeyEvent.h" #include "WindowEvent.h" +#include "NewtCommon.h" + // #define VERBOSE_ON 1 #ifdef VERBOSE_ON @@ -158,8 +160,7 @@ static void _FatalError(JNIEnv *env, const char* msg, ...) vsnprintf(buffer, sizeof(buffer), msg, ap); va_end(ap); - fprintf(stderr, buffer); - fprintf(stderr, "\n"); + fprintf(stderr, "%s\n", buffer); (*env)->FatalError(env, buffer); } @@ -209,10 +210,10 @@ static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e) if (e->error_code == BadAtom) { - fprintf(stderr, " BadAtom (%p): Atom probably already removed\n", e->resourceid); + fprintf(stderr, " BadAtom (%p): Atom probably already removed\n", (void*)e->resourceid); } else if (e->error_code == BadWindow) { - fprintf(stderr, " BadWindow (%p): Window probably already removed\n", e->resourceid); + fprintf(stderr, " BadWindow (%p): Window probably already removed\n", (void*)e->resourceid); } else { _throwNewRuntimeException(NULL, x11ErrorHandlerJNIEnv, "NEWT X11 Error: Display %p, Code 0x%X", dpy, e->error_code); } @@ -443,7 +444,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages if(NULL==jwindow) { fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for invalid X11 window %p\n", - dpy, evt.type, evt.xany.window); + (void*)dpy, evt.type, (void*)evt.xany.window); XUnlockDisplay(dpy) ; // DBG_PRINT1( "X11: DispatchMessages 0x%X - Leave 2\n", dpy); return; @@ -630,7 +631,8 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow (JNIEnv *env, jobject obj, jlong parent, jlong display, jint screen_index, jlong visualID, jlong javaObjectAtom, jlong windowDeleteAtom, - jint x, jint y, jint width, jint height) + jint x, jint y, jint width, jint height, + jboolean undecorated) { Display * dpy = (Display *)(intptr_t)display; int scrn_idx = (int)screen_index; @@ -696,15 +698,15 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow windowParent = XRootWindowOfScreen(scrn); } - attrMask = (CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect) ; + attrMask = ( CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect ) ; memset(&xswa, 0, sizeof(xswa)); - xswa.override_redirect = False; // decorated - xswa.border_pixel = 0; + xswa.override_redirect = ( JNI_TRUE == undecorated || 0 != parent ) ? True : False ; + xswa.border_pixel = 255; xswa.background_pixel = 0; xswa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask; xswa.colormap = XCreateColormap(dpy, - XRootWindow(dpy, scrn_idx), + windowParent, // XRootWindow(dpy, scrn_idx), visual, AllocNone); @@ -724,21 +726,14 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow setJavaWindowProperty(env, dpy, window, javaObjectAtom, (*env)->NewGlobalRef(env, obj)); - XClearWindow(dpy, window); XSync(dpy, False); { long xevent_mask = 0; xevent_mask |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask; xevent_mask |= KeyPressMask|KeyReleaseMask; - xevent_mask |= ExposureMask | StructureNotifyMask | SubstructureNotifyMask | VisibilityNotify ; + xevent_mask |= ExposureMask | StructureNotifyMask | 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); - */ } XUnlockDisplay(dpy) ; @@ -778,10 +773,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow (*env)->DeleteGlobalRef(env, jwindow); XSync(dpy, False); - /** - XUngrabPointer(dpy, CurrentTime); - XUngrabKeyboard(dpy, CurrentTime); - */ XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); XSync(dpy, False); @@ -813,19 +804,39 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0 XSync(dpy, False); if(visible==JNI_TRUE) { XMapRaised(dpy, w); - XSync(dpy, False); - - // XSetInputFocus(dpy, w, RevertToParent, CurrentTime); - // XSync(dpy, False); - } else { - /** - XUngrabPointer(dpy, CurrentTime); - XUngrabKeyboard(dpy, CurrentTime); - */ XUnmapWindow(dpy, w); - XSync(dpy, False); } + XSync(dpy, False); + XUnlockDisplay(dpy) ; +} + +/* + * Class: com_jogamp_newt_impl_x11_X11Window + * Method: setSize0 + * Signature: (JJII)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 + (JNIEnv *env, jobject obj, jlong display, jlong window, jint width, jint height) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + XWindowChanges xwc; + + DBG_PRINT5( "X11: setSize0 %d/%d %dx%d, dec %d\n", x, y, width, height, decorationToggle); + + if(dpy==NULL) { + _FatalError(env, "invalid display connection.."); + } + XLockDisplay(dpy) ; + + XSync(dpy, False); + memset(&xwc, 0, sizeof(XWindowChanges)); + xwc.width=width; + xwc.height=height; + XConfigureWindow(dpy, w, CWWidth|CWHeight, &xwc); + + XSync(dpy, False); XUnlockDisplay(dpy) ; } @@ -838,11 +849,12 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0 /* * Class: com_jogamp_newt_impl_x11_X11Window - * Method: setSize0 + * Method: setPosSizeDecor0 * Signature: (JIJIIIIIZ)V */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 - (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, jint x, jint y, jint width, jint height, jint decorationToggle, jboolean setVisible) +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 + (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, + jint x, jint y, jint width, jint height, jint decorationToggle) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -851,19 +863,17 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 XWindowChanges xwc; - DBG_PRINT6( "X11: setSize0 %d/%d %dx%d, dec %d, vis %d\n", x, y, width, height, decorationToggle, setVisible); + DBG_PRINT5( "X11: setSize0 %d/%d %dx%d, dec %d\n", x, y, width, height, decorationToggle); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } XLockDisplay(dpy) ; - XSync(dpy, False); - - if(setVisible==JNI_TRUE) { - XMapRaised(dpy, w); - XSync(dpy, False); - } + // we need to reparent the window, + // to allow a child window to go fullscreen and back. + XReparentWindow( dpy, w, parent, x, y ); + XRaiseWindow(dpy, w); if(0!=decorationToggle) { #ifdef MWM_FULLSCREEN @@ -878,6 +888,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 XSetWindowAttributes xswa; unsigned long attrMask=CWOverrideRedirect; + memset(&xswa, 0, sizeof(XSetWindowAttributes)); if(decorationToggle<0) { /* undecorated */ xswa.override_redirect = True; @@ -890,12 +901,15 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 #endif } XSync(dpy, False); + + memset(&xwc, 0, sizeof(XWindowChanges)); + xwc.x=x; + xwc.y=y; xwc.width=width; xwc.height=height; - XConfigureWindow(dpy, w, CWWidth|CWHeight, &xwc); - XReparentWindow( dpy, w, parent, x, y ); - + XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc); XSync(dpy, False); + XUnlockDisplay(dpy) ; } @@ -905,7 +919,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 * Signature: (JJII)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 - (JNIEnv *env, jobject obj, jlong display, jlong window, jint x, jint y) + (JNIEnv *env, jobject obj, jlong parent, jlong display, jlong window, jint x, jint y) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -917,6 +931,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 } XLockDisplay(dpy) ; + memset(&xwc, 0, sizeof(XWindowChanges)); xwc.x=x; xwc.y=y; XConfigureWindow(dpy, w, CWX|CWY, &xwc); @@ -925,3 +940,71 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 XUnlockDisplay(dpy) ; } +/* + * Class: com_jogamp_newt_impl_x11_X11Window + * Method: requestFocus0 + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_requestFocus0 + (JNIEnv *env, jobject obj, jlong display, jlong window) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + XWindowAttributes attributes; + + XLockDisplay(dpy) ; + + // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable + XGetWindowAttributes(dpy, w, &attributes); + if(attributes.map_state == IsViewable) { + XSetInputFocus(dpy, w, RevertToParent, CurrentTime); + XSync(dpy, False); + } + + XUnlockDisplay(dpy) ; +} + +/* + * Class: Java_com_jogamp_newt_impl_x11_X11Window + * Method: setTitle0 + * Signature: (JJLjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setTitle0 + (JNIEnv *env, jclass clazz, jlong display, jlong window, jstring title) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + + XLockDisplay(dpy) ; +#if 1 + const char* title_str; + if (NULL != title) { + title_str = (*env)->GetStringUTFChars(env, title, NULL); + if(NULL != title_str) { + XStoreName(dpy, w, title_str); + (*env)->ReleaseStringUTFChars(env, title, title_str); + } + } +#else + char *str_list[] = { NULL }; + XTextProperty text_prop; + if (NULL != title) { + str_list[0] = (char *) NewtCommon_GetNullTerminatedStringChars(env, title); + if (str_list[0] != NULL) { + memset(&text_prop, 0, sizeof(XTextProperty)); + if ( Success != XmbTextListToTextProperty(dpy, str_list, 1, XStringStyle, &text_prop) ) { + DBG_PRINT0( "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); + fprintf(stderr, "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); + } + if(NULL!=text_prop.value) { + XSetWMName(dpy, w, &text_prop); + XFree(text_prop.value); + } + free(str_list[0]); + } + } +#endif + XUnlockDisplay(dpy) ; +} + + |