summaryrefslogtreecommitdiffstats
path: root/src/newt/native
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/native')
-rw-r--r--src/newt/native/KDWindow.c2
-rw-r--r--src/newt/native/KeyEvent.h27
-rw-r--r--src/newt/native/MacWindow.m295
-rw-r--r--src/newt/native/MouseEvent.h27
-rw-r--r--src/newt/native/NewtCommon.h27
-rw-r--r--src/newt/native/NewtMacWindow.h10
-rw-r--r--src/newt/native/NewtMacWindow.m111
-rw-r--r--src/newt/native/ScreenMode.h28
-rw-r--r--src/newt/native/Window.h27
-rw-r--r--src/newt/native/WindowEvent.h27
-rw-r--r--src/newt/native/WindowsWindow.c111
-rw-r--r--src/newt/native/X11Common.h80
-rw-r--r--src/newt/native/X11Display.c660
-rw-r--r--src/newt/native/X11Screen.c469
-rw-r--r--src/newt/native/X11Window.c1115
15 files changed, 1784 insertions, 1232 deletions
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index 5f1affed1..e6bc7952e 100644
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -256,7 +256,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_RealizeWindow
jint res = kdRealizeWindow(w, &nativeWindow);
if(res) {
fprintf(stderr, "[RealizeWindow] failed: 0x%X, 0x%X\n", res, kdGetError());
- nativeWindow = NULL;
+ nativeWindow = 0;
}
DBG_PRINT( "[RealizeWindow] ok: %p\n", nativeWindow);
return (jlong) (intptr_t) nativeWindow;
diff --git a/src/newt/native/KeyEvent.h b/src/newt/native/KeyEvent.h
index 1ead0f5e8..0f7b1606b 100644
--- a/src/newt/native/KeyEvent.h
+++ b/src/newt/native/KeyEvent.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
#ifndef _KEY_EVENT_H_
#define _KEY_EVENT_H_
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index a13ffaf31..ddd59f0a1 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -38,6 +38,7 @@
#import "MouseEvent.h"
#import "KeyEvent.h"
+#import "ScreenMode.h"
#import <ApplicationServices/ApplicationServices.h>
@@ -48,7 +49,6 @@ static const char * const ClazzAnyCstrName = "<init>";
static const char * const ClazzNamePointCstrSignature = "(II)V";
static jclass pointClz = NULL;
static jmethodID pointCstr = NULL;
-static jmethodID focusActionID = NULL;
static NSString* jstringToNSString(JNIEnv* env, jstring jstr)
{
@@ -192,13 +192,57 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSAppli
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplication0
(JNIEnv *env, jclass clazz)
{
- // NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
DBG_PRINT( "\nrunNSApplication0.0\n");
[NSApp run];
DBG_PRINT( "\nrunNSApplication0.X\n");
- // [pool release];
+ [pool release];
+}
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacDisplay
+ * Method: stopNSApplication0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_stopNSApplication0
+ (JNIEnv *env, jclass clazz)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT( "\nstopNSApplication0.0 nsApp.running %d\n", (NSApp && [NSApp isRunning]));
+
+ if(NSApp && [NSApp isRunning]) {
+ [NSApp performSelectorOnMainThread:@selector(stop:) withObject:nil waitUntilDone:YES];
+ // [NSApp stop: nil];
+ NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined
+ location: NSMakePoint(0,0)
+ modifierFlags: 0
+ timestamp: 0.0
+ windowNumber: 0
+ context: nil
+ subtype: 0
+ data1: 0
+ data2: 0];
+ DBG_PRINT( "\nstopNSApplication0.1\n");
+ [NSApp postEvent: event atStart: true];
+ }
+ /**
+ DBG_PRINT( "\nstopNSApplication0.2\n");
+ if(NSApp && [NSApp isRunning]) {
+ DBG_PRINT( "\nstopNSApplication0.3\n");
+ [NSApp terminate:nil];
+ } */
+
+ DBG_PRINT( "\nstopNSApplication0.X\n");
+ [pool release];
+}
+
+static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
+ NSArray *screens = [NSScreen screens];
+ if(screen_idx<0) screen_idx=0;
+ if(screen_idx>=[screens count]) screen_idx=0;
+ return (NSScreen *) [screens objectAtIndex: screen_idx];
}
/*
@@ -211,10 +255,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getWidthImpl0
{
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];
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx);
NSRect rect = [screen frame];
[pool release];
@@ -232,10 +273,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getHeightImpl0
{
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];
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx);
NSRect rect = [screen frame];
[pool release];
@@ -243,6 +281,175 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getHeightImpl0
return (jint) (rect.size.height);
}
+static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
+ // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
+ NSDictionary * dict = [screen deviceDescription];
+ NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
+ // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
+ return (CGDirectDisplayID) [val integerValue];
+}
+
+/**
+ * Only in >= 10.6:
+ * CGDisplayModeGetWidth(mode)
+ * CGDisplayModeGetRefreshRate(mode)
+ * CGDisplayModeGetHeight(mode)
+ */
+static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
+{
+ long value = 0;
+ CFNumberRef numRef;
+ numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key);
+ if (numRef != NULL)
+ CFNumberGetValue(numRef, kCFNumberLongType, &value);
+ return value;
+}
+#define CGDDGetModeWidth(mode) GetDictionaryLong((mode), kCGDisplayWidth)
+#define CGDDGetModeHeight(mode) GetDictionaryLong((mode), kCGDisplayHeight)
+#define CGDDGetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
+#define CGDDGetModeBitsPerPixel(mode) GetDictionaryLong((mode), kCGDisplayBitsPerPixel)
+
+// Duplicate each Mode by all possible rotations (4):
+// For each real-mode: [mode, 0], [mode, 90], [mode, 180], [mode, 270]
+#define ROTMODES_PER_REALMODE 4
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacScreen
+ * Method: getScreenMode0
+ * Signature: (II)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMode0
+ (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ int prop_num = NUM_SCREEN_MODE_PROPERTIES_ALL;
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+ CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
+
+ CFArrayRef availableModes = CGDisplayAvailableModes(display);
+ CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes);
+ CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes;
+ CFDictionaryRef mode = NULL;
+ int currentCCWRot = (int)CGDisplayRotation(display);
+ jint ccwRot = 0;
+
+#ifdef VERBOSE_ON
+ if(0 >= mode_idx) {
+ // only for current mode (-1) and first mode (scanning)
+ DBG_PRINT( "getScreenMode0: scrn %d (%p, %p), mode %d, avail: %d/%d, current rot %d ccw\n",
+ (int)scrn_idx, screen, (void*)(intptr_t)display, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot);
+ }
+#endif
+
+ if(numberOfAvailableModesRots<=mode_idx) {
+ // n/a - end of modes
+ DBG_PRINT( "getScreenMode0: end of modes: mode %d, avail: %d/%d\n",
+ (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots);
+ [pool release];
+ return (*env)->NewIntArray(env, 0);
+ } else if(-1 < mode_idx) {
+ // only at initialization time, where index >= 0
+ prop_num++; // add 1st extra prop, mode_idx
+ mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, mode_idx / ROTMODES_PER_REALMODE);
+ ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90;
+ } else {
+ // current mode
+ mode = CGDisplayCurrentMode(display);
+ ccwRot = currentCCWRot;
+ }
+ // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
+
+ CGSize screenDim = CGDisplayScreenSize(display);
+ int mWidth = CGDDGetModeWidth(mode);
+ int mHeight = CGDDGetModeHeight(mode);
+
+ // swap width and height, since OSX reflects rotated dimension, we don't
+ if ( 90 == currentCCWRot || 270 == currentCCWRot ) {
+ int tempWidth = mWidth;
+ mWidth = mHeight;
+ mHeight = tempWidth;
+ }
+
+ jint prop[ prop_num ];
+ int propIndex = 0;
+ int propIndexRes = 0;
+
+ if( -1 < mode_idx ) {
+ prop[propIndex++] = mode_idx;
+ }
+ prop[propIndex++] = 0; // set later for verification of iterator
+ propIndexRes = propIndex;
+ prop[propIndex++] = mWidth;
+ prop[propIndex++] = mHeight;
+ prop[propIndex++] = CGDDGetModeBitsPerPixel(mode);
+ prop[propIndex++] = (jint) screenDim.width;
+ prop[propIndex++] = (jint) screenDim.height;
+ prop[propIndex++] = CGDDGetModeRefreshRate(mode);
+ prop[propIndex++] = ccwRot;
+ prop[propIndex - NUM_SCREEN_MODE_PROPERTIES_ALL] = ( -1 < mode_idx ) ? propIndex-1 : propIndex ; // count == NUM_SCREEN_MODE_PROPERTIES_ALL
+
+ DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %dx%d mm, %d Hz, rot %d ccw\n",
+ (int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes,
+ (int)prop[propIndexRes+0], (int)prop[propIndexRes+1], (int)prop[propIndexRes+2],
+ (int)prop[propIndexRes+3], (int)prop[propIndexRes+4], (int)prop[propIndexRes+5], (int)prop[propIndexRes+6]);
+
+ jintArray properties = (*env)->NewIntArray(env, prop_num);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", prop_num);
+ }
+ (*env)->SetIntArrayRegion(env, properties, 0, prop_num, prop);
+
+ // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef
+ [pool release];
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacScreen
+ * Method: setScreenMode0
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacScreen_setScreenMode0
+ (JNIEnv *env, jobject object, jint scrn_idx, jint mode_idx)
+{
+ jboolean res = JNI_TRUE;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+ CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
+
+ CFArrayRef availableModes = CGDisplayAvailableModes(display);
+ CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes);
+ CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes;
+
+ CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, mode_idx / ROTMODES_PER_REALMODE);
+ // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
+
+ int ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90;
+ DBG_PRINT( "setScreenMode0: scrn %d (%p, %p), mode %d, rot %d ccw, avail: %d/%d\n",
+ (int)scrn_idx, screen, (void*)(intptr_t)display, (int)mode_idx, ccwRot, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots);
+
+ if(ccwRot!=0) {
+ // FIXME: How to rotate the display/screen on OSX programmatically ?
+ DBG_PRINT( "setScreenMode0: Don't know how to rotate screen on OS X: rot %d ccw\n", ccwRot);
+ res = JNI_FALSE;
+ }
+ if(JNI_TRUE == res) {
+ CGError err = CGDisplaySwitchToMode(display, mode);
+ if(kCGErrorSuccess != err) {
+ DBG_PRINT( "setScreenMode0: SetMode failed: %d\n", (int)err);
+ res = JNI_FALSE;
+ }
+ }
+
+ // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef
+ [pool release];
+
+ return res;
+}
+
/*
* Class: jogamp_newt_driver_macosx_MacWindow
* Method: initIDs
@@ -272,11 +479,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
- if(NULL==focusActionID) {
- NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch method focusAction()Z");
- }
-
// 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");
@@ -449,8 +651,9 @@ NS_DURING
if([mView isInFullScreenMode]) {
[mView exitFullScreenModeWithOptions: NULL];
}
- [mWin setContentView: nil];
- [mView release];
+ // Note: mWin's release will also release it's mView!
+ // [mWin setContentView: nil];
+ // [mView release];
}
NS_HANDLER
NS_ENDHANDLER
@@ -463,7 +666,11 @@ NS_ENDHANDLER
DBG_PRINT( "windowClose.1 - %p,%d view %p,%d, parent %p\n",
mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
- [mWin close]; // performs release!
+ // '[mWin close]' causes a crash at exit.
+ // This probably happens b/c it sends events to the main loop
+ // but our resources are gone ?!
+ // However, issuing a simple release seems to work quite well.
+ [mWin release];
DBG_PRINT( "windowClose.X - %p,%d view %p,%d, parent %p\n",
mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
@@ -510,26 +717,44 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0
(JNIEnv *env, jobject window, jlong w, jboolean force)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* win = (NSWindow*) ((intptr_t) w);
+ NSWindow* mWin = (NSWindow*) ((intptr_t) w);
#ifdef VERBOSE_ON
- BOOL hasFocus = [win isKeyWindow];
+ BOOL hasFocus = [mWin isKeyWindow];
#endif
- DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", win, force, hasFocus);
-
- // Even if we already own the focus, we need the 'focusAction()' call
- // and the other probably redundant NS calls to force proper focus traversal
- // of the parent TK (AWT doesn't do it properly on OSX).
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- DBG_PRINT( "makeKeyWindow win %p\n", win);
- // [win performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES];
- // [win performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:YES];
- [win orderFrontRegardless];
- [win makeKeyWindow];
- [win makeFirstResponder: nil];
- }
+ DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus);
+
+ [mWin makeFirstResponder: nil];
+ // [mWin performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES];
+ // [mWin performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:YES];
+ [mWin orderFrontRegardless];
+ [mWin makeKeyWindow];
+
+ DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", mWin, force);
+
+ [pool release];
+}
- DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", win, force);
+/*
+ * Class: jogamp_newt_driver_macosx_MacWindow
+ * Method: requestFocusParent0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocusParent0
+ (JNIEnv *env, jobject window, jlong w)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* mWin = (NSWindow*) ((intptr_t) w);
+ NSWindow* pWin = [mWin parentWindow];
+#ifdef VERBOSE_ON
+ BOOL hasFocus = [mWin isKeyWindow];
+#endif
+
+ DBG_PRINT( "requestFocusParent0 - window: %p, parent: %p, hasFocus %d (START)\n", mWin, pWin, hasFocus );
+ if(NULL != pWin) {
+ [pWin makeKeyWindow];
+ }
+ DBG_PRINT( "requestFocusParent0 - window: %p, parent: %p (END)\n", mWin, pWin);
[pool release];
}
diff --git a/src/newt/native/MouseEvent.h b/src/newt/native/MouseEvent.h
index e9c0476ef..59d63cecf 100644
--- a/src/newt/native/MouseEvent.h
+++ b/src/newt/native/MouseEvent.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
#ifndef _MOUSE_EVENT_H_
#define _MOUSE_EVENT_H_
diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h
index 91fceb310..33aba64ae 100644
--- a/src/newt/native/NewtCommon.h
+++ b/src/newt/native/NewtCommon.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
#ifndef NEWT_COMMON_H
#define NEWT_COMMON_H 1
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index cb256e71f..3ba89de1e 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2011 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -40,7 +41,8 @@
// #define VERBOSE_ON 1
#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+ #define DBG_PRINT(...) NSLog(@ __VA_ARGS__)
+ // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
#else
#define DBG_PRINT(...)
#endif
@@ -53,8 +55,8 @@
JavaVM *jvmHandle;
int jvmVersion;
- BOOL destroyNotifySent;
- BOOL softLocked;
+ volatile BOOL destroyNotifySent;
+ volatile BOOL softLocked;
pthread_mutex_t softLockSync;
NSTrackingRectTag ptrTrackingTag;
@@ -88,7 +90,7 @@
- (BOOL) needsDisplay;
- (void) displayIfNeeded;
-- (void) viewWillDraw;
+- (void) display;
- (void) drawRect:(NSRect)dirtyRect;
- (void) viewDidHide;
- (void) viewDidUnhide;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 1f74742ec..ce41673c4 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -44,15 +44,17 @@ jint GetDeltaY(NSEvent *event, jint javaMods) {
// mouse pad case
deltaY =
CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1);
+ // fprintf(stderr, "WHEEL/PAD: %lf\n", (double)deltaY);
} else {
// traditional mouse wheel case
deltaY = [event deltaY];
+ // fprintf(stderr, "WHEEL/TRAD: %lf\n", (double)deltaY);
if (deltaY == 0.0 && (javaMods & EVENT_SHIFT_MASK) != 0) {
// shift+vertical wheel scroll produces horizontal scroll
// we convert it to vertical
deltaY = [event deltaX];
}
- if (deltaY < 1.0 && deltaY > -1.0) {
+ if (-1.0 < deltaY && deltaY < 1.0) {
deltaY *= 10.0;
} else {
if (deltaY < 0.0) {
@@ -62,21 +64,15 @@ jint GetDeltaY(NSEvent *event, jint javaMods) {
}
}
}
-
- if (deltaY > 0) {
- return (NSInteger)deltaY;
- } else if (deltaY < 0) {
- return -(NSInteger)deltaY;
- }
-
- return 0;
+ // fprintf(stderr, "WHEEL/res: %d\n", (int)deltaY);
+ return (jint) deltaY;
}
static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
+static jmethodID requestFocusID = NULL;
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
@@ -104,7 +100,11 @@ static jmethodID windowRepaintID = NULL;
jvmVersion = 0;
destroyNotifySent = NO;
softLocked = NO;
- pthread_mutex_init(&softLockSync, NULL); // fast non-recursive
+
+ pthread_mutexattr_t softLockSyncAttr;
+ pthread_mutexattr_init(&softLockSyncAttr);
+ pthread_mutexattr_settype(&softLockSyncAttr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&softLockSync, &softLockSyncAttr); // recursive
ptrTrackingTag = 0;
@@ -122,7 +122,7 @@ static jmethodID windowRepaintID = NULL;
- (void) dealloc
{
if(softLocked) {
- fprintf(stderr, "*** Warning: softLock still hold @ dealloc!\n"); fflush(NULL);
+ NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n");
}
pthread_mutex_destroy(&softLockSync);
[super dealloc];
@@ -193,72 +193,61 @@ static jmethodID windowRepaintID = NULL;
return destroyNotifySent;
}
-#define SOFT_LOCK_BLOCKING 1
-
- (BOOL) softLock
{
+ // DBG_PRINT("*************** softLock.0: %p\n", (void*)pthread_self());
+ // NSLog(@"NewtView::softLock: %@",[NSThread callStackSymbols]);
pthread_mutex_lock(&softLockSync);
softLocked = YES;
-#ifndef SOFT_LOCK_BLOCKING
- pthread_mutex_unlock(&softLockSync);
-#endif
+ // DBG_PRINT("*************** softLock.X: %p\n", (void*)pthread_self());
return softLocked;
}
- (void) softUnlock
{
-#ifndef SOFT_LOCK_BLOCKING
- pthread_mutex_lock(&softLockSync);
-#endif
+ // DBG_PRINT("*************** softUnlock: %p\n", (void*)pthread_self());
softLocked = NO;
pthread_mutex_unlock(&softLockSync);
}
- (BOOL) needsDisplay
{
-#ifndef SOFT_LOCK_BLOCKING
- return NO == softLocked && NO == destroyNotifySent && [super needsDisplay];
-#else
return NO == destroyNotifySent && [super needsDisplay];
-#endif
}
- (void) displayIfNeeded
{
-#ifndef SOFT_LOCK_BLOCKING
- if( NO == softLocked && NO == destroyNotifySent ) {
+ if( YES == [self needsDisplay] ) {
+ [self softLock];
[super displayIfNeeded];
+ [self softUnlock];
}
-#else
- [self softLock];
- if( NO == destroyNotifySent ) {
- [super displayIfNeeded];
- }
- [self softUnlock];
-#endif
}
-- (void) viewWillDraw
+- (void) display
{
- DBG_PRINT("*************** viewWillDraw: 0x%p\n", javaWindowObject);
- [super viewWillDraw];
+ if( NO == destroyNotifySent ) {
+ [self softLock];
+ [super display];
+ [self softUnlock];
+ }
}
- (void) drawRect:(NSRect)dirtyRect
{
- DBG_PRINT("*************** dirtyRect: 0x%p %lf/%lf %lfx%lf\n",
+ DBG_PRINT("*************** dirtyRect: %p %lf/%lf %lfx%lf\n",
javaWindowObject, dirtyRect.origin.x, dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height);
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
NSRect viewFrame = [self frame];
- (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_FALSE,
+ (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE, // defer ..
dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y,
dirtyRect.size.width, dirtyRect.size.height);
@@ -272,7 +261,7 @@ static jmethodID windowRepaintID = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
@@ -290,7 +279,7 @@ static jmethodID windowRepaintID = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
@@ -325,9 +314,9 @@ static jmethodID windowRepaintID = NULL;
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
+ requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (enqueueMouseEventID && sendMouseEventID && enqueueKeyEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
- positionChangedID && focusChangedID && windowDestroyNotifyID && enqueueRequestFocusID && windowRepaintID)
+ positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
{
return YES;
}
@@ -512,14 +501,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"sendKeyEvent: null javaWindowObject");
+ DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"sendKeyEvent: null JNIEnv");
+ DBG_PRINT("sendKeyEvent: null JNIEnv\n");
return;
}
@@ -533,6 +522,8 @@ static jint mods2JavaMods(NSUInteger mods)
// Note: the key code in the NSEvent does not map to anything we can use
jchar keyChar = (jchar) [chars characterAtIndex: i];
+ DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode);
+
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
evType, javaMods, keyCode, keyChar);
@@ -567,14 +558,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"sendMouseEvent: null javaWindowObject");
+ DBG_PRINT("sendMouseEvent: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"sendMouseEvent: null JNIEnv");
+ DBG_PRINT("sendMouseEvent: null JNIEnv\n");
return;
}
jint javaMods = mods2JavaMods([event modifierFlags]);
@@ -586,6 +577,7 @@ static jint mods2JavaMods(NSUInteger mods)
switch ([event type]) {
case NSScrollWheel: {
scrollDeltaY = GetDeltaY(event, javaMods);
+ javaButtonNum = 1;
break;
}
case NSLeftMouseDown:
@@ -603,9 +595,6 @@ static jint mods2JavaMods(NSUInteger mods)
case NSOtherMouseDragged:
javaButtonNum = 2;
break;
- default:
- javaButtonNum = 0;
- break;
}
if (evType == EVENT_MOUSE_WHEEL_MOVED && scrollDeltaY == 0) {
@@ -613,7 +602,7 @@ static jint mods2JavaMods(NSUInteger mods)
return;
}
if (evType == EVENT_MOUSE_PRESSED) {
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, javaWindowObject, requestFocusID, JNI_FALSE);
}
NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]];
@@ -770,14 +759,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"windowDidResize: null javaWindowObject");
+ DBG_PRINT("windowDidResize: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowDidResize: null JNIEnv");
+ DBG_PRINT("windowDidResize: null JNIEnv\n");
return;
}
@@ -805,14 +794,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"windowDidMove: null javaWindowObject");
+ DBG_PRINT("windowDidMove: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowDidMove: null JNIEnv");
+ DBG_PRINT("windowDidMove: null JNIEnv\n");
return;
}
@@ -839,16 +828,16 @@ static jint mods2JavaMods(NSUInteger mods)
if( false == [view getDestroyNotifySent] ) {
jobject javaWindowObject = [view getJavaWindowObject];
- DBG_PRINT( "*************** windowWillClose.0: 0x%p\n", (void *)(intptr_t)javaWindowObject);
+ DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject);
if (javaWindowObject == NULL) {
- NSLog(@"windowWillClose: null javaWindowObject");
+ DBG_PRINT("windowWillClose: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowWillClose: null JNIEnv");
+ DBG_PRINT("windowWillClose: null JNIEnv\n");
return;
}
@@ -863,7 +852,7 @@ static jint mods2JavaMods(NSUInteger mods)
if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
}
- DBG_PRINT( "*************** windowWillClose.X: 0x%p\n", (void *)(intptr_t)javaWindowObject);
+ DBG_PRINT( "*************** windowWillClose.X: %p\n", (void *)(intptr_t)javaWindowObject);
} else {
DBG_PRINT( "*************** windowWillClose (skip)\n");
}
@@ -916,14 +905,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"focusChanged: null javaWindowObject");
+ DBG_PRINT("focusChanged: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"focusChanged: null JNIEnv");
+ DBG_PRINT("focusChanged: null JNIEnv\n");
return;
}
diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h
index 0a760d54a..bb782910e 100644
--- a/src/newt/native/ScreenMode.h
+++ b/src/newt/native/ScreenMode.h
@@ -1,4 +1,32 @@
/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+/**
* WARNING: must be synced with com.jogamp.newt.util.ScreenModeUtil#streamIn*(int[])
*/
diff --git a/src/newt/native/Window.h b/src/newt/native/Window.h
index 865746b91..4755c4fc5 100644
--- a/src/newt/native/Window.h
+++ b/src/newt/native/Window.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
#ifndef _WINDOW_H_
#define _WINDOW_H_
diff --git a/src/newt/native/WindowEvent.h b/src/newt/native/WindowEvent.h
index 05491b43c..3dc6ba97e 100644
--- a/src/newt/native/WindowEvent.h
+++ b/src/newt/native/WindowEvent.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
#ifndef _WINDOW_EVENT_H_
#define _WINDOW_EVENT_H_
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index d60c40496..97fe6f28d 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -115,8 +115,7 @@ static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID focusActionID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
+static jmethodID requestFocusID = NULL;
static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd);
@@ -602,18 +601,14 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jb
(void*) pHwnd, (void*)hwnd, current==hwnd);
if( JNI_TRUE==force || current!=hwnd) {
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
- SetForegroundWindow(hwnd); // Slightly Higher Priority
- SetFocus(hwnd);// Sets Keyboard Focus To Window
- if(NULL!=pHwnd) {
- SetActiveWindow(hwnd);
- }
- DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
- } else {
- DBG_PRINT("*** WindowsWindow: requestFocus.X0\n");
+ UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
+ SetForegroundWindow(hwnd); // Slightly Higher Priority
+ SetFocus(hwnd);// Sets Keyboard Focus To Window
+ if(NULL!=pHwnd) {
+ SetActiveWindow(hwnd);
}
+ DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
}
DBG_PRINT("*** WindowsWindow: requestFocus.XX\n");
}
@@ -870,11 +865,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_LBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: LBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 1, (jint) 0);
useDefWindowProc = 1;
break;
@@ -883,18 +878,18 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 1, (jint) 0);
useDefWindowProc = 1;
break;
case WM_MBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: MBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 2, (jint) 0);
useDefWindowProc = 1;
break;
@@ -903,18 +898,18 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 2, (jint) 0);
useDefWindowProc = 1;
break;
case WM_RBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: RBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 3, (jint) 0);
useDefWindowProc = 1;
break;
@@ -923,7 +918,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 3, (jint) 0);
useDefWindowProc = 1;
break;
@@ -932,7 +927,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_MOVED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 0, (jint) 0);
useDefWindowProc = 1;
break;
@@ -958,7 +953,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(jint) EVENT_MOUSE_WHEEL_MOVED,
GetModifiers(),
(jint) eventPt.x, (jint) eventPt.y,
- (jint) 0, (jint) (GET_WHEEL_DELTA_WPARAM(wParam)/120.0f));
+ (jint) 1, (jint) (GET_WHEEL_DELTA_WPARAM(wParam)/120.0f));
useDefWindowProc = 1;
break;
}
@@ -978,8 +973,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
break;
case WM_MOVE:
- DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, (int)LOWORD(lParam), (int)HIWORD(lParam));
- (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)LOWORD(lParam), (jint)HIWORD(lParam));
+ DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)GET_X_LPARAM(lParam), (jint)GET_Y_LPARAM(lParam));
useDefWindowProc = 1;
break;
@@ -1046,13 +1041,47 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMe
/*
* Class: jogamp_newt_driver_windows_WindowsScreen
+ * Method: getOriginX0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginX0
+ (JNIEnv *env, jobject obj, jint scrn_idx)
+{
+ if( GetSystemMetrics( SM_CMONITORS) > 1) {
+ return (jint)GetSystemMetrics(SM_XVIRTUALSCREEN);
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_WindowsScreen
+ * Method: getOriginY0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginY0
+ (JNIEnv *env, jobject obj, jint scrn_idx)
+{
+ if( GetSystemMetrics( SM_CMONITORS ) > 1) {
+ return (jint)GetSystemMetrics(SM_YVIRTUALSCREEN);
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_WindowsScreen
* Method: getWidthImpl
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImpl0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
- return (jint)GetSystemMetrics(SM_CXSCREEN);
+ if( GetSystemMetrics( SM_CMONITORS) > 1) {
+ return (jint)GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ } else {
+ return (jint)GetSystemMetrics(SM_CXSCREEN);
+ }
}
/*
@@ -1063,7 +1092,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImp
JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getHeightImpl0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
- return (jint)GetSystemMetrics(SM_CYSCREEN);
+ if( GetSystemMetrics( SM_CMONITORS ) > 1) {
+ return (jint)GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ } else {
+ return (jint)GetSystemMetrics(SM_CYSCREEN);
+ }
}
static int NewtScreen_RotationNativeCCW2NewtCCW(JNIEnv *env, int native) {
@@ -1270,8 +1303,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
+ requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (insetsChangedID == NULL ||
sizeChangedID == NULL ||
@@ -1284,8 +1316,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
sendMouseEventID == NULL ||
enqueueKeyEventID == NULL ||
sendKeyEventID == NULL ||
- focusActionID == NULL ||
- enqueueRequestFocusID == NULL) {
+ requestFocusID == NULL) {
return JNI_FALSE;
}
BuildDynamicKeyMapTable();
@@ -1317,9 +1348,6 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible,
} else {
flags = SWP_NOACTIVATE | SWP_NOZORDER;
}
- if(0>x || 0>y) {
- flags |= SWP_NOMOVE;
- }
if(0>=width || 0>=height ) {
flags |= SWP_NOSIZE;
}
@@ -1345,7 +1373,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
(JNIEnv *env, jobject obj,
jlong hInstance, jstring jWndClassName, jstring jWndName,
jlong parent,
- jint jx, jint jy, jint defaultWidth, jint defaultHeight, jint flags)
+ jint jx, jint jy, jint defaultWidth, jint defaultHeight, jboolean autoPosition, jint flags)
{
HWND parentWindow = (HWND) (intptr_t) parent;
const TCHAR* wndClassName = NULL;
@@ -1374,7 +1402,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
} else {
windowStyle |= WS_OVERLAPPEDWINDOW;
- if(0>_x || 0>_y) {
+ if(JNI_TRUE == autoPosition) {
// user didn't requested specific position, use WM default
_x = CW_USEDEFAULT;
_y = 0;
@@ -1387,9 +1415,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
(HINSTANCE) (intptr_t) hInstance,
NULL);
- DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d\n",
+ DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
(int)GetCurrentThreadId(), parentWindow, window, x, y, width, height,
- TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags));
+ TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), autoPosition);
if (NULL == window) {
int lastError = (int) GetLastError();
@@ -1409,7 +1437,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
{
RECT rc;
RECT * insets;
- BOOL userPos = 0<=x && 0<=y ;
ShowWindow(window, SW_SHOW);
@@ -1417,12 +1444,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
insets = UpdateInsets(env, wud->jinstance, window);
(*env)->CallVoidMethod(env, wud->jinstance, visibleChangedID, JNI_FALSE, JNI_TRUE);
- if(!userPos) {
+ if(JNI_TRUE == autoPosition) {
GetWindowRect(window, &rc);
x = rc.left + insets->left; // client coords
y = rc.top + insets->top; // client coords
}
- DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (is user-pos %d)\n", x, y, width, height, userPos);
+ DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, autoPosition);
x -= insets->left; // top-level
y -= insets->top; // top-level
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h
new file mode 100644
index 000000000..cefef690f
--- /dev/null
+++ b/src/newt/native/X11Common.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#ifndef _X11COMMON_H_
+#define _X11COMMON_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>
+
+#include <X11/extensions/Xrandr.h>
+
+#include "jogamp_newt_driver_x11_X11Screen.h"
+#include "jogamp_newt_driver_x11_X11Display.h"
+#include "jogamp_newt_driver_x11_X11Window.h"
+
+#include "Window.h"
+#include "MouseEvent.h"
+#include "InputEvent.h"
+#include "KeyEvent.h"
+#include "WindowEvent.h"
+#include "ScreenMode.h"
+
+#include "NewtCommon.h"
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
+
+extern jclass X11NewtWindowClazz;
+extern jmethodID insetsChangedID;
+extern jmethodID visibleChangedID;
+
+jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning);
+
+void NewtDisplay_displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env);
+Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return);
+Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom);
+
+#endif /* _X11COMMON_H_ */
+
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
new file mode 100644
index 000000000..283636040
--- /dev/null
+++ b/src/newt/native/X11Display.c
@@ -0,0 +1,660 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#include "X11Common.h"
+
+#define USE_SENDIO_DIRECT 1
+
+jclass X11NewtWindowClazz = NULL;
+jmethodID insetsChangedID = NULL;
+jmethodID visibleChangedID = NULL;
+
+static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/X11Window";
+
+static jmethodID displayCompletedID = NULL;
+
+static jmethodID sizeChangedID = NULL;
+static jmethodID positionChangedID = NULL;
+static jmethodID focusChangedID = NULL;
+static jmethodID reparentNotifyID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
+static jmethodID windowRepaintID = NULL;
+static jmethodID enqueueMouseEventID = NULL;
+static jmethodID sendMouseEventID = NULL;
+static jmethodID enqueueKeyEventID = NULL;
+static jmethodID sendKeyEventID = NULL;
+static jmethodID requestFocusID = NULL;
+
+static JavaVM *jvmHandle = NULL;
+static int jvmVersion = 0;
+
+static void setupJVMVars(JNIEnv * env) {
+ if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
+ jvmHandle = NULL;
+ }
+ jvmVersion = (*env)->GetVersion(env);
+}
+
+static XErrorHandler origErrorHandler = NULL ;
+
+static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e)
+{
+ fprintf(stderr, "Warning: NEWT X11 Error: DisplayDispatch %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno));
+
+ if (e->error_code == BadAtom) {
+ 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", (void*)e->resourceid);
+ } else {
+ int shallBeDetached = 0;
+ JNIEnv *jniEnv = NULL;
+ const char * errStr = strerror(errno);
+
+ fprintf(stderr, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, errStr);
+
+ jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ if(NULL==jniEnv) {
+ fprintf(stderr, "NEWT X11 Error: null JNIEnv");
+ return;
+ }
+
+ NewtCommon_throwNewRuntimeException(jniEnv, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s",
+ dpy, e->error_code, errStr);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
+ }
+
+ return 0;
+}
+
+void NewtDisplay_displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env) {
+ if(onoff) {
+ if(NULL==origErrorHandler) {
+ setupJVMVars(env);
+ origErrorHandler = XSetErrorHandler(displayDispatchErrorHandler);
+ }
+ } else {
+ if(NULL!=origErrorHandler) {
+ XSetErrorHandler(origErrorHandler);
+ origErrorHandler = NULL;
+ }
+ }
+}
+
+/**
+ * Keycode
+ */
+
+#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
+
+static jint X11KeySym2NewtVKey(KeySym keySym) {
+ if(IS_WITHIN(keySym,XK_F1,XK_F12))
+ return (keySym-XK_F1)+J_VK_F1;
+ if(IS_WITHIN(keySym,XK_KP_0,XK_KP_9))
+ return (keySym-XK_KP_0)+J_VK_NUMPAD0;
+
+ switch(keySym) {
+ case XK_Return:
+ case XK_KP_Enter:
+ return J_VK_ENTER;
+ case XK_BackSpace:
+ return J_VK_BACK_SPACE;
+ case XK_Tab:
+ case XK_KP_Tab:
+ case XK_ISO_Left_Tab:
+ return J_VK_TAB;
+ case XK_Cancel:
+ return J_VK_CANCEL;
+ case XK_Clear:
+ return J_VK_CLEAR;
+ case XK_Shift_L:
+ case XK_Shift_R:
+ return J_VK_SHIFT;
+ case XK_Control_L:
+ case XK_Control_R:
+ return J_VK_CONTROL;
+ case XK_Alt_L:
+ case XK_Alt_R:
+ return J_VK_ALT;
+ case XK_Pause:
+ return J_VK_PAUSE;
+ case XK_Caps_Lock:
+ return J_VK_CAPS_LOCK;
+ case XK_Escape:
+ return J_VK_ESCAPE;
+ case XK_space:
+ case XK_KP_Space:
+ return J_VK_SPACE;
+ case XK_Page_Up:
+ case XK_KP_Page_Up:
+ return J_VK_PAGE_UP;
+ case XK_Page_Down:
+ case XK_KP_Page_Down:
+ return J_VK_PAGE_DOWN;
+ case XK_End:
+ case XK_KP_End:
+ return J_VK_END;
+ case XK_Home:
+ case XK_KP_Home:
+ return J_VK_HOME;
+ case XK_Left:
+ case XK_KP_Left:
+ return J_VK_LEFT;
+ case XK_Up:
+ case XK_KP_Up:
+ return J_VK_UP;
+ case XK_Right:
+ case XK_KP_Right:
+ return J_VK_RIGHT;
+ case XK_Down:
+ case XK_KP_Down:
+ return J_VK_DOWN;
+ case XK_KP_Multiply:
+ return J_VK_MULTIPLY;
+ case XK_KP_Add:
+ return J_VK_ADD;
+ case XK_KP_Separator:
+ return J_VK_SEPARATOR;
+ case XK_KP_Subtract:
+ return J_VK_SUBTRACT;
+ case XK_KP_Decimal:
+ return J_VK_DECIMAL;
+ case XK_KP_Divide:
+ return J_VK_DIVIDE;
+ case XK_Delete:
+ case XK_KP_Delete:
+ return J_VK_DELETE;
+ case XK_Num_Lock:
+ return J_VK_NUM_LOCK;
+ case XK_Scroll_Lock:
+ return J_VK_SCROLL_LOCK;
+ case XK_Print:
+ return J_VK_PRINTSCREEN;
+ case XK_Insert:
+ case XK_KP_Insert:
+ return J_VK_INSERT;
+ case XK_Help:
+ return J_VK_HELP;
+ }
+ return keySym;
+}
+
+static jint X11InputState2NewtModifiers(unsigned int xstate) {
+ jint modifiers = 0;
+ if ((ControlMask & xstate) != 0) {
+ modifiers |= EVENT_CTRL_MASK;
+ }
+ if ((ShiftMask & xstate) != 0) {
+ modifiers |= EVENT_SHIFT_MASK;
+ }
+ if ((Mod1Mask & xstate) != 0) {
+ modifiers |= EVENT_ALT_MASK;
+ }
+ if ((Button1Mask & xstate) != 0) {
+ modifiers |= EVENT_BUTTON1_MASK;
+ }
+ if ((Button2Mask & xstate) != 0) {
+ modifiers |= EVENT_BUTTON2_MASK;
+ }
+ if ((Button3Mask & xstate) != 0) {
+ modifiers |= EVENT_BUTTON3_MASK;
+ }
+
+ return modifiers;
+}
+
+
+/**
+ * Keycode
+ */
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: initIDs
+ * Signature: (Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
+ (JNIEnv *env, jclass clazz)
+{
+ jclass c;
+
+ NewtCommon_init(env);
+
+ if(NULL==X11NewtWindowClazz) {
+ c = (*env)->FindClass(env, ClazzNameX11NewtWindow);
+ if(NULL==c) {
+ NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameX11NewtWindow);
+ }
+ X11NewtWindowClazz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==X11NewtWindowClazz) {
+ NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameX11NewtWindow);
+ }
+ }
+
+ displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
+ insetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsChanged", "(ZIIII)V");
+ sizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizeChanged", "(ZIIZ)V");
+ positionChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "positionChanged", "(ZII)V");
+ focusChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusChanged", "(ZZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(ZZ)V");
+ reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V");
+ windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "()V");
+ windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V");
+ enqueueMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueMouseEvent", "(ZIIIIII)V");
+ sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(IIIIII)V");
+ enqueueKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueKeyEvent", "(ZIIIC)V");
+ sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(IIIC)V");
+ requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V");
+
+ if (displayCompletedID == NULL ||
+ insetsChangedID == NULL ||
+ sizeChangedID == NULL ||
+ positionChangedID == NULL ||
+ focusChangedID == NULL ||
+ visibleChangedID == NULL ||
+ reparentNotifyID == NULL ||
+ windowDestroyNotifyID == NULL ||
+ windowRepaintID == NULL ||
+ enqueueMouseEventID == NULL ||
+ sendMouseEventID == NULL ||
+ enqueueKeyEventID == NULL ||
+ sendKeyEventID == NULL ||
+ requestFocusID == NULL) {
+ return JNI_FALSE;
+ }
+
+
+ return JNI_TRUE;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: CompleteDisplay
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
+ (JNIEnv *env, jobject obj, jlong display)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ jlong javaObjectAtom;
+ jlong windowDeleteAtom;
+
+ if(dpy==NULL) {
+ NewtCommon_FatalError(env, "invalid display connection..");
+ }
+
+ javaObjectAtom = (jlong) XInternAtom(dpy, "NEWT_JAVA_OBJECT", False);
+ if(None==javaObjectAtom) {
+ NewtCommon_throwNewRuntimeException(env, "could not create Atom NEWT_JAVA_OBJECT, bail out!");
+ return;
+ }
+
+ windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+ if(None==windowDeleteAtom) {
+ NewtCommon_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!");
+ return;
+ }
+
+ // XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
+
+ DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy);
+
+ (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: DisplayRelease0
+ * Signature: (JJJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
+ (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ Atom wm_javaobject_atom = (Atom)javaObjectAtom;
+ Atom wm_delete_atom = (Atom)windowDeleteAtom;
+
+ if(dpy==NULL) {
+ NewtCommon_FatalError(env, "invalid display connection..");
+ }
+
+ // nothing to do to free the atoms !
+ (void) wm_javaobject_atom;
+ (void) wm_delete_atom;
+
+ XSync(dpy, True); // discard all pending events
+ DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: DispatchMessages
+ * Signature: (JIJJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
+ (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ Atom wm_delete_atom = (Atom)windowDeleteAtom;
+ 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, (int)evt.type);
+
+ NewtDisplay_displayDispatchErrorHandlerEnable(1, env);
+
+ jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
+ #ifdef VERBOSE_ON
+ True
+ #else
+ False
+ #endif
+ );
+
+ NewtDisplay_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 = X11KeySym2NewtVKey(upper_return);
+ } else {
+ keyChar=0;
+ keySym = X11KeySym2NewtVKey(keySym);
+ }
+ modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+ break;
+
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ modifiers = X11InputState2NewtModifiers(evt.xbutton.state);
+ break;
+
+ default:
+ break;
+ }
+
+ switch(evt.type) {
+ case ButtonPress:
+ (*env)->CallVoidMethod(env, jwindow, requestFocusID, 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 EnterNotify:
+ DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_ENTERED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_ENTERED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #endif
+ break;
+ case LeaveNotify:
+ DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_EXITED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_EXITED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #endif
+ break;
+ case KeyPress:
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
+ modifiers, keySym, (jchar) -1);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED,
+ modifiers, keySym, (jchar) -1);
+ #endif
+
+ break;
+ case KeyRelease:
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
+ modifiers, keySym, (jchar) -1);
+
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED,
+ modifiers, keySym, (jchar) keyChar);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED,
+ modifiers, keySym, (jchar) -1);
+
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED,
+ modifiers, keySym, (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
+ {
+ // update insets
+ int left, right, top, bottom;
+ NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
+ }
+ (*env)->CallVoidMethod(env, jwindow, sizeChangedID, JNI_FALSE,
+ (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
+ (*env)->CallVoidMethod(env, jwindow, positionChangedID, JNI_FALSE,
+ (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ }
+ break;
+ case ClientMessage:
+ if (evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_atom) { // windowDeleteAtom
+ 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_FALSE, JNI_TRUE);
+ break;
+
+ case FocusOut:
+ DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
+ (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, 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, JNI_FALSE,
+ 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
+ {
+ // update insets
+ int left, right, top, bottom;
+ NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
+ }
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, 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, 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 %d/%d OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n",
+ evt.xreparent.x, evt.xreparent.y,
+ (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, reparentNotifyID, (jlong)evt.xreparent.parent);
+ }
+ 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/X11Screen.c b/src/newt/native/X11Screen.c
new file mode 100644
index 000000000..1b7fea770
--- /dev/null
+++ b/src/newt/native/X11Screen.c
@@ -0,0 +1,469 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#include "X11Common.h"
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: GetScreen
+ * Signature: (JI)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ Screen * scrn= NULL;
+
+ DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
+
+ if(dpy==NULL) {
+ NewtCommon_FatalError(env, "invalid display connection..");
+ }
+
+ scrn = ScreenOfDisplay(dpy, screen_index);
+ if(scrn==NULL) {
+ fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
+ }
+ DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
+ return (jlong) (intptr_t) scrn;
+}
+
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ return (jint) DisplayWidth( dpy, scrn_idx);
+}
+
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ return (jint) DisplayHeight( dpy, scrn_idx);
+}
+
+static int showedRandRVersion = 0;
+
+static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
+ if( 0 == XRRQueryVersion(dpy, major, minor) ) {
+ return False;
+ }
+ if(0 == showedRandRVersion) {
+ fprintf(stderr, "X11 RandR Version %d.%d\n", *major, *minor);
+ showedRandRVersion = 1;
+ }
+ return True;
+}
+
+static Bool NewtScreen_hasRANDR(Display *dpy) {
+ int major, minor;
+ return NewtScreen_getRANDRVersion(dpy, &major, &minor);
+}
+
+static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
+ int rot;
+ if(xrotation == RR_Rotate_0) {
+ rot = 0;
+ }
+ else if(xrotation == RR_Rotate_90) {
+ rot = 90;
+ }
+ else if(xrotation == RR_Rotate_180) {
+ rot = 180;
+ }
+ else if(xrotation == RR_Rotate_270) {
+ rot = 270;
+ } else {
+ NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
+ }
+ return rot;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getAvailableScreenModeRotations0
+ * Signature: (JI)I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ int num_rotations = 0;
+ Rotation cur_rotation, rotations_supported;
+ int rotations[4];
+ int major, minor;
+
+ if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) {
+ fprintf(stderr, "RANDR not available\n");
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation);
+
+ if(0 != (rotations_supported & RR_Rotate_0)) {
+ rotations[num_rotations++] = 0;
+ }
+ if(0 != (rotations_supported & RR_Rotate_90)) {
+ rotations[num_rotations++] = 90;
+ }
+ if(0 != (rotations_supported & RR_Rotate_180)) {
+ rotations[num_rotations++] = 180;
+ }
+ if(0 != (rotations_supported & RR_Rotate_270)) {
+ rotations[num_rotations++] = 270;
+ }
+
+ jintArray properties = NULL;
+
+ if(num_rotations>0) {
+ properties = (*env)->NewIntArray(env, num_rotations);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rotations);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, num_rotations, rotations);
+ }
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getNumScreenModeResolution0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
+ return 0;
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
+
+ return num_sizes;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getScreenModeResolutions0
+ * Signature: (JII)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ // Fill the properties in temp jint array
+ int propIndex = 0;
+ jint prop[4];
+
+ prop[propIndex++] = xrrs[(int)resMode_idx].width;
+ prop[propIndex++] = xrrs[(int)resMode_idx].height;
+ prop[propIndex++] = xrrs[(int)resMode_idx].mwidth;
+ prop[propIndex++] = xrrs[(int)resMode_idx].mheight;
+
+ jintArray properties = (*env)->NewIntArray(env, 4);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, 4, prop);
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getScreenModeRates0
+ * Signature: (JII)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ int num_rates;
+ short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates);
+
+ jint prop[num_rates];
+ int i;
+ for(i=0; i<num_rates; i++) {
+ prop[i] = (int) rates[i];
+ /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */
+ }
+
+ jintArray properties = (*env)->NewIntArray(env, num_rates);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop);
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getCurrentScreenRate0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0: RANDR not available\n");
+ return -1;
+ }
+
+ // get current resolutions and frequencies
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+ short original_rate = XRRConfigCurrentRate(conf);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
+ DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
+
+ return (jint) original_rate;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getCurrentScreenRotation0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0: RANDR not available\n");
+ return -1;
+ }
+
+ //get current resolutions and frequencies
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+
+ Rotation rotation;
+ XRRConfigCurrentConfiguration(conf, &rotation);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
+ return NewtScreen_XRotation2Degree(env, rotation);
+}
+
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getCurrentScreenResolutionIndex0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0: RANDR not available\n");
+ return -1;
+ }
+
+ // get current resolutions and frequency configuration
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+ short original_rate = XRRConfigCurrentRate(conf);
+
+ Rotation original_rotation;
+ SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
+ DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
+ return (jint)original_size_id;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: setCurrentScreenModeStart0
+ * Signature: (JIIII)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)screen_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0: RANDR not available\n");
+ return JNI_FALSE;
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenConfiguration *conf;
+ int rot;
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ conf = XRRGetScreenInfo(dpy, root);
+
+ switch(rotation) {
+ case 0:
+ rot = RR_Rotate_0;
+ break;
+ case 90:
+ rot = RR_Rotate_90;
+ break;
+ case 180:
+ rot = RR_Rotate_180;
+ break;
+ case 270:
+ rot = RR_Rotate_270;
+ break;
+ default:
+ NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
+ }
+
+ DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
+ resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
+
+ XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
+
+ XSync(dpy, False);
+ XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
+ XSync(dpy, False);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+ XSync(dpy, False);
+
+ return JNI_TRUE;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: setCurrentScreenModePollEnd0
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ int randr_event_base, randr_error_base;
+ XEvent evt;
+ XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
+ return JNI_FALSE;
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenConfiguration *conf;
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ XRRQueryExtension(dpy, &randr_event_base, &randr_error_base);
+
+ int done = 0;
+ int rot;
+ do {
+ if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
+ return;
+ }
+ XNextEvent(dpy, &evt);
+
+ switch (evt.type - randr_event_base) {
+ case RRScreenChangeNotify:
+ rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
+ DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n",
+ (void*)scn_event->window, (void*)scn_event->root,
+ (int)scn_event->size_index, rot,
+ scn_event->width, scn_event->height);
+ // done = scn_event->size_index == resMode_idx; // not reliable ..
+ done = rot == rotation &&
+ scn_event->width == xrrs[resMode_idx].width &&
+ scn_event->height == xrrs[resMode_idx].height;
+ break;
+ default:
+ DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);
+ }
+ XRRUpdateConfiguration(&evt);
+ } while(!done);
+
+ XSync(dpy, False);
+
+}
+
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index f14138a0a..0a7e1cf77 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -32,40 +32,9 @@
*
*/
-#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>
-
-#include <X11/extensions/Xrandr.h>
-
-#include "jogamp_newt_driver_x11_X11Screen.h"
-#include "jogamp_newt_driver_x11_X11Display.h"
-#include "jogamp_newt_driver_x11_X11Window.h"
-
-#include "Window.h"
-#include "MouseEvent.h"
-#include "InputEvent.h"
-#include "KeyEvent.h"
-#include "WindowEvent.h"
-#include "ScreenMode.h"
-
-#include "NewtCommon.h"
-
-// #define VERBOSE_ON 1
+#include "X11Common.h"
#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
-
#define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b))
static void _dumpVisualInfo(const char * msg, XVisualInfo *pVisualQuery) {
@@ -90,259 +59,12 @@
#else
- #define DBG_PRINT(...)
-
#define DUMP_VISUAL_INFO(a,b)
#endif
-/**
- * Keycode
- */
-
-#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
-
-static jint X11KeySym2NewtVKey(KeySym keySym) {
- if(IS_WITHIN(keySym,XK_F1,XK_F12))
- return (keySym-XK_F1)+J_VK_F1;
-
- switch(keySym) {
- case XK_Alt_L:
- case XK_Alt_R:
- return J_VK_ALT;
-
- case XK_Left:
- return J_VK_LEFT;
- case XK_Right:
- return J_VK_RIGHT;
- case XK_Up:
- return J_VK_UP;
- case XK_Down:
- return J_VK_DOWN;
- case XK_Page_Up:
- return J_VK_PAGE_UP;
- case XK_Page_Down:
- return J_VK_PAGE_DOWN;
- case XK_Shift_L:
- case XK_Shift_R:
- return J_VK_SHIFT;
- case XK_Control_L:
- case XK_Control_R:
- return J_VK_CONTROL;
- case XK_Escape:
- return J_VK_ESCAPE;
- case XK_Delete:
- return J_VK_DELETE;
- }
- return keySym;
-}
-
-static jint X11InputState2NewtModifiers(unsigned int xstate) {
- jint modifiers = 0;
- if ((ControlMask & xstate) != 0) {
- modifiers |= EVENT_CTRL_MASK;
- }
- if ((ShiftMask & xstate) != 0) {
- modifiers |= EVENT_SHIFT_MASK;
- }
- if ((Mod1Mask & xstate) != 0) {
- modifiers |= EVENT_ALT_MASK;
- }
- if ((Button1Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON1_MASK;
- }
- if ((Button2Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON2_MASK;
- }
- if ((Button3Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON3_MASK;
- }
-
- return modifiers;
-}
-
#define X11_MOUSE_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask)
-static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window";
-
-static jclass newtWindowClz=NULL;
-
-static jmethodID insetsChangedID = NULL;
-static jmethodID sizeChangedID = NULL;
-static jmethodID positionChangedID = NULL;
-static jmethodID focusChangedID = NULL;
-static jmethodID visibleChangedID = NULL;
-static jmethodID reparentNotifyID = NULL;
-static jmethodID windowDestroyNotifyID = NULL;
-static jmethodID windowRepaintID = 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;
-
-static jmethodID displayCompletedID = NULL;
-
-
-/**
- * Display
- */
-
-static JavaVM *jvmHandle = NULL;
-static int jvmVersion = 0;
-
-static void setupJVMVars(JNIEnv * env) {
- if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
- jvmHandle = NULL;
- }
- jvmVersion = (*env)->GetVersion(env);
-}
-
-static XErrorHandler origErrorHandler = NULL ;
-
-static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e)
-{
- fprintf(stderr, "Warning: NEWT X11 Error: DisplayDispatch %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno));
-
- if (e->error_code == BadAtom) {
- 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", (void*)e->resourceid);
- } else {
- int shallBeDetached = 0;
- JNIEnv *jniEnv = NULL;
- const char * errStr = strerror(errno);
-
- fprintf(stderr, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, errStr);
-
- jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
- if(NULL==jniEnv) {
- fprintf(stderr, "NEWT X11 Error: null JNIEnv");
- return;
- }
-
- NewtCommon_throwNewRuntimeException(jniEnv, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s",
- dpy, e->error_code, errStr);
-
- if (shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
- }
-
- return 0;
-}
-
-static void displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env) {
- if(onoff) {
- if(NULL==origErrorHandler) {
- setupJVMVars(env);
- origErrorHandler = XSetErrorHandler(displayDispatchErrorHandler);
- }
- } else {
- if(NULL!=origErrorHandler) {
- XSetErrorHandler(origErrorHandler);
- origErrorHandler = NULL;
- }
- }
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: initIDs
- * Signature: (Z)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
- (JNIEnv *env, jclass clazz)
-{
- jclass c;
-
- NewtCommon_init(env);
-
- displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
- if (displayCompletedID == NULL) {
- return JNI_FALSE;
- }
-
- if(NULL==newtWindowClz) {
- c = (*env)->FindClass(env, ClazzNameNewtWindow);
- if(NULL==c) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameNewtWindow);
- }
- newtWindowClz = (jclass)(*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- if(NULL==newtWindowClz) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameNewtWindow);
- }
- }
-
- return JNI_TRUE;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: CompleteDisplay
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
- (JNIEnv *env, jobject obj, jlong display)
-{
- Display * dpy = (Display *)(intptr_t)display;
- jlong javaObjectAtom;
- jlong windowDeleteAtom;
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- javaObjectAtom = (jlong) XInternAtom(dpy, "NEWT_JAVA_OBJECT", False);
- if(None==javaObjectAtom) {
- NewtCommon_throwNewRuntimeException(env, "could not create Atom NEWT_JAVA_OBJECT, bail out!");
- return;
- }
-
- windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- if(None==windowDeleteAtom) {
- NewtCommon_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!");
- return;
- }
-
- // XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
-
- DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy);
-
- (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: DisplayRelease0
- * Signature: (JJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
- Display * dpy = (Display *)(intptr_t)display;
- Atom wm_javaobject_atom = (Atom)javaObjectAtom;
- Atom wm_delete_atom = (Atom)windowDeleteAtom;
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- // nothing to do to free the atoms !
- (void) wm_javaobject_atom;
- (void) wm_delete_atom;
-
- XSync(dpy, True); // discard all pending events
- DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
-}
-
-
-/**
- * Window
- */
-
static int putPtrIn32Long(unsigned long * dst, uintptr_t src) {
int i=0;
dst[i++] = (unsigned long) ( ( src >> 0 ) & 0xFFFFFFFF ) ;
@@ -375,7 +97,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 getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) {
Atom actual_type;
int actual_format;
int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ;
@@ -413,7 +135,7 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
XFree(jogl_java_object_data_pp);
#ifdef VERBOSE_ON
- if(JNI_FALSE == (*env)->IsInstanceOf(env, jwindow, newtWindowClz)) {
+ if(JNI_FALSE == (*env)->IsInstanceOf(env, jwindow, X11NewtWindowClazz)) {
NewtCommon_throwNewRuntimeException(env, "fetched Atom NEWT_JAVA_OBJECT window is not a NEWT Window: javaWindow 0x%X !", jwindow);
}
#endif
@@ -421,7 +143,7 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
}
/** @return zero if fails, non zero if OK */
-static Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return) {
+Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return) {
Window *children_return=NULL;
unsigned int nchildren_return=0;
@@ -502,7 +224,7 @@ static Status NewtWindows_getFrameExtends(Display *dpy, Window window, int *left
return 1; // Ok
}
-static Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom) {
+Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom) {
if(0 != NewtWindows_getFrameExtends(dpy, window, left, right, top, bottom)) {
DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n",
*left, *right, *top, *bottom);
@@ -535,16 +257,14 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)w, force, focus_return==w);
if( JNI_TRUE==force || focus_return!=w) {
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
- XRaiseWindow(dpy, w);
- NewtWindows_setCWAbove(dpy, w);
- // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
- XGetWindowAttributes(dpy, w, &xwa);
- if(xwa.map_state == IsViewable) {
- DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w);
- XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
- }
+ DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
+ XRaiseWindow(dpy, w);
+ NewtWindows_setCWAbove(dpy, w);
+ // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
+ XGetWindowAttributes(dpy, w, &xwa);
+ if(xwa.map_state == IsViewable) {
+ DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w);
+ XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
}
}
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)w, force);
@@ -710,752 +430,6 @@ static Bool NewtWindows_setFullscreenEWMH (Display *dpy, Window root, Window w,
return res;
}
-#define USE_SENDIO_DIRECT 1
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: DispatchMessages
- * Signature: (JIJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Atom wm_delete_atom = (Atom)windowDeleteAtom;
- 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, (int)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 EnterNotify:
- DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_ENTERED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_ENTERED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #endif
- break;
- case LeaveNotify:
- DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_EXITED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_EXITED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.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
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
- }
- (*env)->CallVoidMethod(env, jwindow, sizeChangedID, JNI_FALSE,
- (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
- (*env)->CallVoidMethod(env, jwindow, positionChangedID, JNI_FALSE,
- (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
- }
- break;
- case ClientMessage:
- if (evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_atom) { // windowDeleteAtom
- 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_FALSE, JNI_TRUE);
- break;
-
- case FocusOut:
- DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
- (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, 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, JNI_FALSE,
- 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
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
- }
- (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, 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, 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 %d/%d OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n",
- evt.xreparent.x, evt.xreparent.y,
- (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, reparentNotifyID, (jlong)evt.xreparent.parent);
- }
- 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);
- }
- }
-}
-
-
-/**
- * Screen
- */
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: GetScreen
- * Signature: (JI)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
-{
- Display * dpy = (Display *)(intptr_t)display;
- Screen * scrn= NULL;
-
- DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- scrn = ScreenOfDisplay(dpy, screen_index);
- if(scrn==NULL) {
- fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
- }
- DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
- return (jlong) (intptr_t) scrn;
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display * dpy = (Display *) (intptr_t) display;
- return (jint) XDisplayWidth( dpy, scrn_idx);
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display * dpy = (Display *) (intptr_t) display;
- return (jint) XDisplayHeight( dpy, scrn_idx);
-}
-
-
-static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
- if( 0 == XRRQueryVersion(dpy, major, minor) ) {
- return False;
- }
- return True;
-}
-
-static Bool NewtScreen_hasRANDR(Display *dpy) {
- int major, minor;
- return NewtScreen_getRANDRVersion(dpy, &major, &minor);
-}
-
-static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
- int rot;
- if(xrotation == RR_Rotate_0) {
- rot = 0;
- }
- else if(xrotation == RR_Rotate_90) {
- rot = 90;
- }
- else if(xrotation == RR_Rotate_180) {
- rot = 180;
- }
- else if(xrotation == RR_Rotate_270) {
- rot = 270;
- } else {
- NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
- }
- return rot;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getAvailableScreenModeRotations0
- * Signature: (JI)I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
- int num_rotations = 0;
- Rotation cur_rotation, rotations_supported;
- int rotations[4];
- int major, minor;
-
- if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) {
- fprintf(stderr, "RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation);
-
- if(0 != (rotations_supported & RR_Rotate_0)) {
- rotations[num_rotations++] = 0;
- }
- if(0 != (rotations_supported & RR_Rotate_90)) {
- rotations[num_rotations++] = 90;
- }
- if(0 != (rotations_supported & RR_Rotate_180)) {
- rotations[num_rotations++] = 180;
- }
- if(0 != (rotations_supported & RR_Rotate_270)) {
- rotations[num_rotations++] = 270;
- }
-
- jintArray properties = NULL;
-
- if(num_rotations>0) {
- properties = (*env)->NewIntArray(env, num_rotations);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rotations);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, num_rotations, rotations);
- }
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getNumScreenModeResolution0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
- return 0;
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
-
- return num_sizes;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeResolutions0
- * Signature: (JII)[I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- // Fill the properties in temp jint array
- int propIndex = 0;
- jint prop[4];
-
- prop[propIndex++] = xrrs[(int)resMode_idx].width;
- prop[propIndex++] = xrrs[(int)resMode_idx].height;
- prop[propIndex++] = xrrs[(int)resMode_idx].mwidth;
- prop[propIndex++] = xrrs[(int)resMode_idx].mheight;
-
- jintArray properties = (*env)->NewIntArray(env, 4);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, 4, prop);
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeRates0
- * Signature: (JII)[I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- int num_rates;
- short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates);
-
- jint prop[num_rates];
- int i;
- for(i=0; i<num_rates; i++) {
- prop[i] = (int) rates[i];
- /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */
- }
-
- jintArray properties = (*env)->NewIntArray(env, num_rates);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop);
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRate0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0: RANDR not available\n");
- return -1;
- }
-
- // get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
- short original_rate = XRRConfigCurrentRate(conf);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
-
- return (jint) original_rate;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRotation0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0: RANDR not available\n");
- return -1;
- }
-
- //get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-
- Rotation rotation;
- XRRConfigCurrentConfiguration(conf, &rotation);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- return NewtScreen_XRotation2Degree(env, rotation);
-}
-
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenResolutionIndex0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0: RANDR not available\n");
- return -1;
- }
-
- // get current resolutions and frequency configuration
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
- short original_rate = XRRConfigCurrentRate(conf);
-
- Rotation original_rotation;
- SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
- return (jint)original_size_id;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModeStart0
- * Signature: (JIIII)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)screen_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0: RANDR not available\n");
- return JNI_FALSE;
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- XRRScreenConfiguration *conf;
- int rot;
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- conf = XRRGetScreenInfo(dpy, root);
-
- switch(rotation) {
- case 0:
- rot = RR_Rotate_0;
- break;
- case 90:
- rot = RR_Rotate_90;
- break;
- case 180:
- rot = RR_Rotate_180;
- break;
- case 270:
- rot = RR_Rotate_270;
- break;
- default:
- NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
- }
-
- DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
- resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
-
- XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
-
- XSync(dpy, False);
- XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
- XSync(dpy, False);
-
- //free
- XRRFreeScreenConfigInfo(conf);
- XSync(dpy, False);
-
- return JNI_TRUE;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModePollEnd0
- * Signature: (J)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
-{
- Display *dpy = (Display *) (intptr_t) display;
- int randr_event_base, randr_error_base;
- XEvent evt;
- XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
- return JNI_FALSE;
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- XRRScreenConfiguration *conf;
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- XRRQueryExtension(dpy, &randr_event_base, &randr_error_base);
-
- int done = 0;
- int rot;
- do {
- if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
- return;
- }
- XNextEvent(dpy, &evt);
-
- switch (evt.type - randr_event_base) {
- case RRScreenChangeNotify:
- rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
- DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n",
- (void*)scn_event->window, (void*)scn_event->root,
- (int)scn_event->size_index, rot,
- scn_event->width, scn_event->height);
- // done = scn_event->size_index == resMode_idx; // not reliable ..
- done = rot == rotation &&
- scn_event->width == xrrs[resMode_idx].width &&
- scn_event->height == xrrs[resMode_idx].height;
- break;
- default:
- DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);
- }
- XRRUpdateConfiguration(&evt);
- } while(!done);
-
- XSync(dpy, False);
-
-}
-
/**
* Window
*/
@@ -1468,37 +442,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0
(JNIEnv *env, jclass clazz)
{
- insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
- positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V");
- focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
- reparentNotifyID = (*env)->GetMethodID(env, clazz, "reparentNotify", "(J)V");
- windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
- windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
- enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIII)V");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
- enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
-
- if (insetsChangedID == NULL ||
- sizeChangedID == NULL ||
- positionChangedID == NULL ||
- focusChangedID == NULL ||
- visibleChangedID == NULL ||
- reparentNotifyID == NULL ||
- windowDestroyNotifyID == NULL ||
- windowRepaintID == NULL ||
- enqueueMouseEventID == NULL ||
- sendMouseEventID == NULL ||
- enqueueKeyEventID == NULL ||
- sendKeyEventID == NULL ||
- focusActionID == NULL ||
- enqueueRequestFocusID == NULL) {
- return JNI_FALSE;
- }
return JNI_TRUE;
}
@@ -1513,14 +456,12 @@ static Bool WaitForUnmapNotify( Display *dpy, XEvent *event, XPointer arg ) {
static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height) {
if(width>0 && height>0 || x>=0 && y>=0) { // resize/position if requested
XWindowChanges xwc;
- int flags = 0;
+ int flags = CWX | CWY;
memset(&xwc, 0, sizeof(XWindowChanges));
- if(0<=x && 0<=y) {
- flags |= CWX | CWY;
- xwc.x=x;
- xwc.y=y;
- }
+ xwc.x=x;
+ xwc.y=y;
+
if(0<width && 0<height) {
flags |= CWWidth | CWHeight;
xwc.width=width;
@@ -1534,13 +475,12 @@ static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint
/*
* Class: jogamp_newt_driver_x11_X11Window
* Method: CreateWindow
- * Signature: (JJIJIIII)J
*/
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
(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, int flags)
+ jint x, jint y, jint width, jint height, jboolean autoPosition, int flags)
{
Display * dpy = (Display *)(intptr_t)display;
Atom wm_delete_atom = (Atom)windowDeleteAtom;
@@ -1576,9 +516,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
if(0==windowParent) {
windowParent = root;
}
- DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d, alwaysOnTop %d\n",
+ DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
(void*)dpy, (void*)windowParent, x, y, width, height,
- TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags));
+ TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), autoPosition);
// try given VisualID on screen
memset(&visualTemplate, 0, sizeof(XVisualInfo));
@@ -1628,7 +568,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
{
int _x = x, _y = y; // pos for CreateWindow, might be tweaked
- if(0>_x || 0>_y) {
+ if(JNI_TRUE == autoPosition) {
// user didn't requested specific position, use WM default
_x = 0;
_y = 0;
@@ -1662,7 +602,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
{
XEvent event;
int left, right, top, bottom;
- Bool userPos = 0<=x && 0<=y ;
XMapWindow(dpy, window);
XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) window ); // wait to get proper insets values
@@ -1671,19 +610,17 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
NewtWindows_updateInsets(env, jwindow, dpy, window, &left, &right, &top, &bottom);
(*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
- if(!userPos) {
+ if(JNI_TRUE == autoPosition) {
// get position from WM
int dest_x, dest_y;
Window child;
XTranslateCoordinates(dpy, window, windowParent, 0, 0, &dest_x, &dest_y, &child);
x = (int)dest_x; y = (int)dest_y;
}
- DBG_PRINT("X11: [CreateWindow]: client: %d/%d %dx%d (is user-pos %d)\n", x, y, width, height, userPos);
+ DBG_PRINT("X11: [CreateWindow]: client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, autoPosition);
x -= left; // top-level
y -= top; // top-level
- if(0>x) { x = 0; }
- if(0>y) { y = 0; }
DBG_PRINT("X11: [CreateWindow]: top-level: %d/%d\n", x, y);
NewtWindows_setPosSize(dpy, window, x, y, width, height);
@@ -1774,7 +711,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
fsEWMHFlags |= _NET_WM_ABOVE; // toggle above only
}
- displayDispatchErrorHandlerEnable(1, env);
+ NewtDisplay_displayDispatchErrorHandlerEnable(1, env);
DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n",
(void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w,
@@ -1792,7 +729,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) {
Bool enable = TST_FLAG_CHANGE_FULLSCREEN(flags) ? TST_FLAG_IS_FULLSCREEN(flags) : TST_FLAG_IS_ALWAYSONTOP(flags) ;
if( NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
- displayDispatchErrorHandlerEnable(0, env);
+ NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
return;
}
}
@@ -1856,7 +793,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, True);
}
- displayDispatchErrorHandlerEnable(0, env);
+ NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
DBG_PRINT( "X11: reconfigureWindow0 X\n");
}