Jogamp
Bug 741 HiDPI: Add ScalableSurface interface to get/set pixelScale w/ full OSX impl.
[jogl.git] / src / newt / native / MacWindow.m
1 /*
2  * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
3  * 
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  * 
8  * - Redistribution of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * 
11  * - Redistribution in binary form must reproduce the above copyright
12  *   notice, this list of conditions and the following disclaimer in the
13  *   documentation and/or other materials provided with the distribution.
14  * 
15  * Neither the name of Sun Microsystems, Inc. or the names of
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  * 
19  * This software is provided "AS IS," without a warranty of any kind. ALL
20  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
23  * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
24  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
25  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
26  * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
27  * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
28  * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
29  * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
30  * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  * 
32  */
33
34 #import <inttypes.h>
35
36 #import "jogamp_newt_driver_macosx_WindowDriver.h"
37 #import "NewtMacWindow.h"
38
39 #import "MouseEvent.h"
40 #import "KeyEvent.h"
41 #import "ScreenMode.h"
42
43 #import <ApplicationServices/ApplicationServices.h>
44
45 #import <stdio.h>
46
47 #ifdef DBG_PERF
48     #include "timespec.h"
49 #endif
50
51 static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point";
52 static const char * const ClazzAnyCstrName = "<init>";
53 static const char * const ClazzNamePointCstrSignature = "(II)V";
54 static jclass pointClz = NULL;
55 static jmethodID pointCstr = NULL;
56
57 static NSString* jstringToNSString(JNIEnv* env, jstring jstr)
58 {
59     const jchar* jstrChars = (*env)->GetStringChars(env, jstr, NULL);
60     NSString* str = [[NSString alloc] initWithCharacters: jstrChars length: (*env)->GetStringLength(env, jstr)];
61     (*env)->ReleaseStringChars(env, jstr, jstrChars);
62     return str;
63 }
64
65 static void setWindowClientTopLeftPoint(NewtMacWindow* mWin, jint x, jint y, BOOL doDisplay) {
66     DBG_PRINT( "setWindowClientTopLeftPoint.0 - window: %p %d/%d, display %d\n", mWin, (int)x, (int)y, (int)doDisplay);
67     NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)];
68     DBG_PRINT( "setWindowClientTopLeftPoint.1: %d/%d\n", (int)pS.x, (int)pS.y);
69
70     [mWin setFrameOrigin: pS];
71     DBG_PRINT( "setWindowClientTopLeftPoint.X: %d/%d\n", (int)pS.x, (int)pS.y);
72
73     if( doDisplay ) {
74         NSView* mView = [mWin contentView];
75         [mWin invalidateCursorRectsForView: mView];
76     }
77 }
78
79 static void setWindowClientTopLeftPointAndSize(NewtMacWindow* mWin, jint x, jint y, jint width, jint height, BOOL doDisplay) {
80     DBG_PRINT( "setWindowClientTopLeftPointAndSize.0 - window: %p %d/%d %dx%d, display %d\n", mWin, (int)x, (int)y, (int)width, (int)height, (int)doDisplay);
81     NSSize clientSZ = NSMakeSize(width, height);
82     NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y) size: clientSZ];
83     NSSize topSZ = [mWin newtClientSize2TLSize: clientSZ];
84     NSRect rect = { pS, topSZ };
85     DBG_PRINT( "setWindowClientTopLeftPointAndSize.1: %d/%d %dx%d\n", (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height);
86
87     [mWin setFrame: rect display:doDisplay];
88     DBG_PRINT( "setWindowClientTopLeftPointAndSize.X: %d/%d %dx%d\n", (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height);
89
90     // -> display:YES
91     // if( doDisplay ) {
92     //   NSView* mView = [mWin contentView];
93     //   [mWin invalidateCursorRectsForView: mView];
94     // }
95 }
96
97 #ifdef VERBOSE_ON
98 static int getRetainCount(NSObject * obj) {
99     return ( NULL == obj ) ? -1 : (int)([obj retainCount]) ;
100 }
101 #endif
102
103 static void setJavaWindowObject(JNIEnv *env, jobject newJavaWindowObject, NewtView *view, BOOL enable) {
104     DBG_PRINT( "setJavaWindowObject.0: View %p\n", view);
105     if( !enable) {
106         jobject globJavaWindowObject = [view getJavaWindowObject];
107         if( NULL != globJavaWindowObject ) {
108             DBG_PRINT( "setJavaWindowObject.1: View %p - Clear old javaWindowObject %p\n", view, globJavaWindowObject);
109             (*env)->DeleteGlobalRef(env, globJavaWindowObject);
110             [view setJavaWindowObject: NULL];
111         }
112     } else if( NULL != newJavaWindowObject ) {
113         DBG_PRINT( "setJavaWindowObject.2: View %p - Set new javaWindowObject %p\n", view, newJavaWindowObject);
114         jobject globJavaWindowObject = (*env)->NewGlobalRef(env, newJavaWindowObject);
115         [view setJavaWindowObject: globJavaWindowObject];
116     }
117     DBG_PRINT( "setJavaWindowObject.X: View %p\n", view);
118 }
119
120 static void changeContentView(JNIEnv *env, jobject javaWindowObject, NSView *pview, NewtMacWindow *win, NewtView *newView, BOOL setJavaWindow) {
121     NSView* oldNSView = [win contentView];
122     NewtView* oldNewtView = NULL;
123 #ifdef VERBOSE_ON
124     int dbgIdx = 1;
125 #endif
126
127     if( [oldNSView isKindOfClass:[NewtView class]] ) {
128         oldNewtView = (NewtView *) oldNSView;
129     }
130
131     DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d), parent view %p\n", 
132         dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldNewtView, newView, getRetainCount(newView), pview);
133
134     if( NULL!=oldNSView ) {
135 NS_DURING
136         // Available >= 10.5 - Makes the menubar disapear
137         BOOL iifs;
138         if ( [oldNSView respondsToSelector:@selector(isInFullScreenMode)] ) {
139             iifs = [oldNSView isInFullScreenMode];
140         } else {
141             iifs = NO;
142         }
143         if(iifs && [oldNSView respondsToSelector:@selector(exitFullScreenModeWithOptions:)] ) {
144             [oldNSView exitFullScreenModeWithOptions: NULL];
145         }
146 NS_HANDLER
147 NS_ENDHANDLER
148         DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d)\n", 
149             dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldNewtView, newView, getRetainCount(newView));
150
151         if( NULL != oldNewtView ) {
152             [oldNewtView setDestroyNotifySent: false];
153             setJavaWindowObject(env, NULL, oldNewtView, NO);
154         }
155         [oldNSView removeFromSuperviewWithoutNeedingDisplay];
156     }
157     DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", 
158         dbgIdx++, win, oldNSView, getRetainCount(oldNSView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]);
159
160     if( NULL!=newView ) {
161         [newView setDestroyNotifySent: false];
162         if( setJavaWindow ) {
163             setJavaWindowObject(env, javaWindowObject, newView, YES);
164         }
165
166         DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d)\n", 
167             dbgIdx++, win, oldNSView, getRetainCount(oldNSView), newView, getRetainCount(newView));
168
169         if(NULL!=pview) {
170             [pview addSubview: newView positioned: NSWindowAbove relativeTo: nil];
171         }
172     }
173     DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", 
174         dbgIdx++, win, oldNSView, getRetainCount(oldNSView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]);
175
176     [win setContentView: newView];
177
178     DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", 
179         dbgIdx++, win, oldNSView, getRetainCount(oldNSView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]);
180
181     // make sure the insets are updated in the java object
182     [win updateInsets: env jwin:javaWindowObject];
183
184     DBG_PRINT( "changeContentView.X win %p, view (%p,%d -> %p,%d)\n", 
185         win, oldNSView, getRetainCount(oldNSView), newView, getRetainCount(newView));
186 }
187
188 /*
189  * Class:     jogamp_newt_driver_macosx_DisplayDriver
190  * Method:    initIDs
191  * Signature: ()Z
192  */
193 JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_initNSApplication0
194   (JNIEnv *env, jclass clazz)
195 {
196     static int initialized = 0;
197
198     if(initialized) return JNI_TRUE;
199     initialized = 1;
200
201     NewtCommon_init(env);
202
203     // This little bit of magic is needed in order to receive mouse
204     // motion events and allow key focus to be properly transferred.
205     // FIXME: are these Carbon APIs? They come from the
206     // ApplicationServices.framework.
207     ProcessSerialNumber psn;
208     if (GetCurrentProcess(&psn) == noErr) {
209         TransformProcessType(&psn, kProcessTransformToForegroundApplication);
210         SetFrontProcess(&psn);
211     }
212
213     // Initialize the shared NSApplication instance
214     [NSApplication sharedApplication];
215
216     // Need this when debugging, as it is necessary to attach gdb to
217     // the running java process -- "gdb java" doesn't work
218     //    printf("Going to sleep for 10 seconds\n");
219     //    sleep(10);
220
221     return (jboolean) JNI_TRUE;
222 }
223
224 /*
225  * Class:     jogamp_newt_driver_macosx_DisplayDriver
226  * Method:    runNSApplication0
227  * Signature: ()V
228  */
229 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_runNSApplication0
230   (JNIEnv *env, jclass clazz)
231 {
232     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
233     DBG_PRINT( "\nrunNSApplication0.0\n");
234
235     [NSApp run];
236
237     DBG_PRINT( "\nrunNSApplication0.X\n");
238     [pool release];
239 }
240
241 /*
242  * Class:     jogamp_newt_driver_macosx_DisplayDriver
243  * Method:    stopNSApplication0
244  * Signature: ()V
245  */
246 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_stopNSApplication0
247   (JNIEnv *env, jclass clazz)
248 {
249     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
250     DBG_PRINT( "\nstopNSApplication0.0 nsApp.running %d\n", (NSApp && [NSApp isRunning]));
251
252     if(NSApp && [NSApp isRunning]) {
253         [NSApp performSelectorOnMainThread:@selector(stop:) withObject:nil waitUntilDone:YES];
254         // [NSApp stop: nil];
255         NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined
256                                             location: NSMakePoint(0,0)
257                                        modifierFlags: 0
258                                            timestamp: 0.0
259                                         windowNumber: 0
260                                              context: nil
261                                              subtype: 0
262                                                data1: 0
263                                                data2: 0];
264         DBG_PRINT( "\nstopNSApplication0.1\n");
265         [NSApp postEvent: event atStart: true];
266     }
267     /**
268     DBG_PRINT( "\nstopNSApplication0.2\n");
269     if(NSApp && [NSApp isRunning]) {
270         DBG_PRINT( "\nstopNSApplication0.3\n");
271         [NSApp terminate:nil];
272     } */
273
274     DBG_PRINT( "\nstopNSApplication0.X\n");
275     [pool release];
276 }
277
278 static NSImage * createNSImageFromData(JNIEnv *env, unsigned char * iconData, jint jiconWidth, jint jiconHeight) {
279     if( NULL != iconData ) {
280         NSInteger iconWidth = (NSInteger) jiconWidth;
281         NSInteger iconHeight = (NSInteger) jiconHeight;
282         const NSInteger bpc = 8 /* bits per component */, spp=4 /* RGBA */, bpp = bpc * spp;
283         const NSBitmapFormat bfmt = NSAlphaNonpremultipliedBitmapFormat;
284         const BOOL hasAlpha = YES;
285
286         NSBitmapImageRep* bir = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: &iconData
287                                     pixelsWide: iconWidth
288                                     pixelsHigh: iconHeight
289                                     bitsPerSample: bpc
290                                     samplesPerPixel: spp
291                                     hasAlpha: hasAlpha
292                                     isPlanar: NO
293                                     colorSpaceName: NSCalibratedRGBColorSpace
294                                     bitmapFormat: bfmt
295                                     bytesPerRow: iconWidth*4
296                                     bitsPerPixel: bpp];
297         [bir autorelease];
298         NSImage* nsImage = [[NSImage alloc] initWithCGImage: [bir CGImage] size:NSZeroSize];
299         return nsImage;
300     }
301     return NULL;
302 }
303
304 /*
305  * Class:     jogamp_newt_driver_macosx_DisplayDriver
306  * Method:    setAppIcon0
307  */
308 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_setAppIcon0
309   (JNIEnv *env, jobject unused, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height)
310 {
311     if( 0 == pixels ) {
312         return;
313     }
314     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
315     // NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly!
316     unsigned char * pixelPtr = (unsigned char *) ( JNI_TRUE == pixels_is_direct ? 
317                                             (*env)->GetDirectBufferAddress(env, pixels) : 
318                                             (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) );
319     NSImage * nsImage = createNSImageFromData(env, pixelPtr + pixels_byte_offset, width, height);
320     if( NULL != nsImage ) {
321         [nsImage autorelease];
322         [NSApp setApplicationIconImage: nsImage];
323     }
324     if ( JNI_FALSE == pixels_is_direct ) {
325         (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);  
326     }
327     [pool release];
328 }
329
330 JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_createPointerIcon0
331   (JNIEnv *env, jobject unused, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jint hotX, jint hotY)
332 {
333     if( 0 == pixels ) {
334         return 0;
335     }
336     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
337     unsigned char * pixelPtr = (unsigned char *) ( JNI_TRUE == pixels_is_direct ? 
338                                             (*env)->GetDirectBufferAddress(env, pixels) : 
339                                             (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) );
340     NSImage * nsImage = createNSImageFromData(env, pixelPtr + pixels_byte_offset, width, height);
341     NSCursor * res = NULL;
342     if( NULL != nsImage ) {
343         [nsImage autorelease];
344         NSPoint hotP = { hotX, hotY };
345         res = [[NSCursor alloc] initWithImage: nsImage hotSpot: hotP];
346     }
347     if ( JNI_FALSE == pixels_is_direct ) {
348         (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);  
349     }
350     [pool release];
351     DBG_PRINT( "createPointerIcon0 %p\n", res);
352     return (jlong) (intptr_t) res;
353 }
354
355 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_destroyPointerIcon0
356   (JNIEnv *env, jobject unused, jlong handle)
357 {
358     NSCursor * c = (NSCursor*) (intptr_t) handle ;
359     if( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
360         NewtCommon_throwNewRuntimeException(env, "Not a NSCursor %p", c);
361         return;
362     }
363     DBG_PRINT( "destroyPointerIcon0 %p\n", c);
364     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
365     [c release];
366     [pool release];
367 }
368
369 NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx, BOOL cap) {
370     NSArray *screens = [NSScreen screens];
371     if( screen_idx<0 || screen_idx>=[screens count] ) {
372         if( cap ) {
373             screen_idx=0;
374         } else {
375             return NULL;
376         }
377     }
378     return (NSScreen *) [screens objectAtIndex: screen_idx];
379 }
380
381 NSScreen * NewtScreen_getNSScreenByCoord(int x, int y) {
382     NSArray *screens = [NSScreen screens];
383     int i;
384     for(i=[screens count]-1; i>=0; i--) {
385         NSScreen * screen = (NSScreen *) [screens objectAtIndex: i];
386         NSRect frame = [screen frame];
387         if( x >= frame.origin.x && 
388             y >= frame.origin.y &&
389             x <  frame.origin.x + frame.size.width &&
390             y <  frame.origin.y + frame.size.height ) {
391             return screen;
392         }
393     }
394     return (NSScreen *) [screens objectAtIndex: 0];
395 }
396
397 static void NewtScreen_dump() {
398 #ifdef VERBOSE_ON
399     NSArray *screens = [NSScreen screens];
400     int i;
401     for(i=0; i<[screens count]; i++) {
402         NSScreen * screen = (NSScreen *) [screens objectAtIndex: i];
403         NSRect screenFrame = [screen frame];
404         NSRect screenVisibleFrame = [screen visibleFrame];
405         CGFloat pixelScale = 1.0; // default
406 NS_DURING
407         // Available >= 10.7
408         pixelScale = [screen backingScaleFactor]; // HiDPI scaling
409 NS_HANDLER
410 NS_ENDHANDLER
411         NSWindowDepth depth = [screen depth]; // an (int) value!
412         DBG_PRINT( "NSScreen #%d (%p): Frame %lf/%lf %lfx%lf (vis %lf/%lf %lfx%lf), scale %lf, depth %d\n",
413             i, screen,
414             screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height,
415             screenVisibleFrame.origin.x, screenVisibleFrame.origin.y, screenVisibleFrame.size.width, screenVisibleFrame.size.height,
416             pixelScale, depth);
417     }
418 #endif
419 }
420
421
422 CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
423     // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
424     NSDictionary * dict = [screen deviceDescription];
425     NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
426     // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
427     return (CGDirectDisplayID) [val integerValue];
428 }
429
430 /**
431  * Only in >= 10.6:
432  *   CGDisplayModeGetWidth(mode)
433  *   CGDisplayModeGetRefreshRate(mode)
434  *   CGDisplayModeGetHeight(mode)
435  */
436 static long GetDictionaryLong(CFDictionaryRef theDict, const void* key) 
437 {
438     long value = 0;
439     CFNumberRef numRef;
440     numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key); 
441     if (numRef != NULL)
442         CFNumberGetValue(numRef, kCFNumberLongType, &value);    
443     return value;
444 }
445 #define CGDDGetModeWidth(mode) GetDictionaryLong((mode), kCGDisplayWidth)
446 #define CGDDGetModeHeight(mode) GetDictionaryLong((mode), kCGDisplayHeight)
447 #define CGDDGetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
448 #define CGDDGetModeBitsPerPixel(mode) GetDictionaryLong((mode), kCGDisplayBitsPerPixel)
449
450 // Duplicate each Mode by all possible rotations (4):
451 // For each real-mode: [mode, 0], [mode, 90], [mode, 180], [mode, 270]
452 #define ROTMODES_PER_REALMODE 4
453
454 /*
455  * Class:     jogamp_newt_driver_macosx_ScreenDriver
456  * Method:    getMonitorCount0
457  * Signature: ()I
458  */
459 JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonitorCount0
460   (JNIEnv *env, jobject obj)
461 {
462     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
463     NSArray *screens = [NSScreen screens];
464     [pool release];
465     return (jint) [screens count];
466 }
467
468 /*
469  * Class:     jogamp_newt_driver_macosx_ScreenDriver
470  * Method:    getMonitorProps0
471  * Signature: (I)[I
472  */
473 JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonitorProps0
474   (JNIEnv *env, jobject obj, jint crt_idx)
475 {
476     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
477
478 #ifdef DBG_PERF
479     struct timespec t0, t1, td;
480     long td_ms;
481     timespec_now(&t0);
482 #endif
483
484 #ifdef DBG_PERF
485     timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
486     fprintf(stderr, "MacScreen_getMonitorProps0.1: %ld ms\n", td_ms); fflush(NULL);
487 #endif
488     NSScreen *screen = NewtScreen_getNSScreenByIndex((int)crt_idx, false);
489     if( NULL == screen ) {
490         [pool release];
491         return NULL;
492     }
493     CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
494 #ifdef DBG_PERF
495     timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
496     fprintf(stderr, "MacScreen_getMonitorProps0.2: %ld ms\n", td_ms); fflush(NULL);
497 #endif
498
499     CGSize sizeMM = CGDisplayScreenSize(display);
500 #ifdef DBG_PERF
501     timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
502     fprintf(stderr, "MacScreen_getMonitorProps0.3: %ld ms\n", td_ms); fflush(NULL);
503 #endif
504
505     CGRect dBounds = CGDisplayBounds (display); // origin top-left
506 #ifdef VERBOSE_ON
507     BOOL usesGL = CGDisplayUsesOpenGLAcceleration(display);
508     NSRect sFrame = [screen frame]; // origin bottom-left
509     DBG_PRINT( "getMonitorProps0: scrn %d, top-left displayBounds[%d/%d %dx%d], bottom-left screenFrame[%d/%d %dx%d], usesGL %d\n", (int)crt_idx, 
510                  (int)dBounds.origin.x, (int)dBounds.origin.y, (int)dBounds.size.width, (int)dBounds.size.height,
511                  (int)sFrame.origin.x, (int)sFrame.origin.y, (int)sFrame.size.width, (int)sFrame.size.height,
512                  (int)usesGL);
513 #endif
514
515     jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES;
516     jint prop[ propCount ];
517     int offset = 0;
518     prop[offset++] = propCount;
519     prop[offset++] = crt_idx;
520     prop[offset++] = (jint) sizeMM.width;
521     prop[offset++] = (jint) sizeMM.height;
522     prop[offset++] = (jint) dBounds.origin.x;    // rotated viewport x      (pixel units, will be fixed in java code)
523     prop[offset++] = (jint) dBounds.origin.y;    // rotated viewport y      (pixel units, will be fixed in java code)
524     prop[offset++] = (jint) dBounds.size.width;  // rotated viewport width  (pixel units, will be fixed in java code)
525     prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (pixel units, will be fixed in java code)
526     prop[offset++] = (jint) dBounds.origin.x;    // rotated viewport x      (window units, will be fixed in java code)
527     prop[offset++] = (jint) dBounds.origin.y;    // rotated viewport y      (window units, will be fixed in java code)
528     prop[offset++] = (jint) dBounds.size.width;  // rotated viewport width  (window units, will be fixed in java code)
529     prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (window units, will be fixed in java code)
530
531     jintArray properties = (*env)->NewIntArray(env, propCount);
532     if (properties == NULL) {
533         NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount);
534     }
535     (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop);
536     
537     [pool release];
538
539     return properties;
540 }
541
542 /*
543  * Class:     jogamp_newt_driver_macosx_ScreenDriver
544  * Method:    getMonitorMode0
545  * Signature: (II)[I
546  */
547 JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonitorMode0
548   (JNIEnv *env, jobject obj, jint crt_idx, jint mode_idx)
549 {
550     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
551
552     NSScreen *screen = NewtScreen_getNSScreenByIndex((int)crt_idx, false);
553     if( NULL == screen ) {
554         [pool release];
555         return NULL;
556     }
557     CGFloat pixelScale = 1.0; // default
558 NS_DURING
559     // Available >= 10.7
560     pixelScale = [screen backingScaleFactor]; // HiDPI scaling
561 NS_HANDLER
562 NS_ENDHANDLER
563
564     CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
565
566     CFArrayRef availableModes = CGDisplayAvailableModes(display);
567     CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes);
568     CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes; 
569     CFDictionaryRef mode = NULL;
570     int currentCCWRot = (int)CGDisplayRotation(display);
571     jint ccwRot = 0;
572     int nativeId = 0;
573
574 #ifdef VERBOSE_ON
575     if(0 >= mode_idx) {
576         // only for current mode (-1) and first mode (scanning)
577         DBG_PRINT( "getScreenMode0: scrn %d (s %p, d %p, pscale %lf), mode %d, avail: %d/%d, current rot %d ccw\n",  
578             (int)crt_idx, screen, (void*)(intptr_t)display, pixelScale, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot);
579     }
580 #endif
581
582     if(numberOfAvailableModesRots<=mode_idx) {
583         // n/a - end of modes
584         DBG_PRINT( "getScreenMode0: end of modes: mode %d, avail: %d/%d\n",
585             (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots);
586         [pool release];
587         return NULL;
588     } else if(-1 < mode_idx) {
589         // only at initialization time, where index >= 0
590         nativeId = mode_idx / ROTMODES_PER_REALMODE;
591         ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90;
592         mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, nativeId);
593     } else {
594         // current mode
595         mode = CGDisplayCurrentMode(display);
596         ccwRot = currentCCWRot;
597         CFRange range = CFRangeMake (0, numberOfAvailableModes);
598         nativeId = CFArrayGetFirstIndexOfValue(availableModes, range, (CFDictionaryRef)mode);
599     }
600     // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
601
602     int mWidth = CGDDGetModeWidth(mode);
603     int mHeight = CGDDGetModeHeight(mode);
604     if( -1 == mode_idx ) {
605         mWidth *= (int)pixelScale;   // accomodate HiDPI
606         mHeight *= (int)pixelScale; // accomodate HiDPI
607     }
608
609     // swap width and height, since OSX reflects rotated dimension, we don't
610     if ( 90 == currentCCWRot || 270 == currentCCWRot ) {
611         int tempWidth = mWidth;
612         mWidth = mHeight;
613         mHeight = tempWidth;
614     }
615
616     jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ];
617     int propIndex = 0;
618
619     int refreshRate = CGDDGetModeRefreshRate(mode);
620     int fRefreshRate = ( 0 < refreshRate ) ? refreshRate : 60; // default .. (experienced on OSX 10.6.8)
621     prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL;
622     prop[propIndex++] = mWidth;
623     prop[propIndex++] = mHeight;
624     prop[propIndex++] = CGDDGetModeBitsPerPixel(mode);
625     prop[propIndex++] = fRefreshRate * 100; // Hz*100
626     prop[propIndex++] = 0; // flags
627     prop[propIndex++] = nativeId;
628     prop[propIndex++] = ccwRot;
629  
630     DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %d / %d Hz, nativeId %d, rot %d ccw\n",
631         (int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes, 
632         (int)prop[1], (int)prop[2], (int)prop[3],
633         (int)prop[4], refreshRate, (int)prop[6], (int)prop[7]);
634
635     jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL);
636     if (properties == NULL) {
637         NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL);
638     }
639     (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop);
640     
641     // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef
642     [pool release];
643
644     return properties;
645 }
646
647 /*
648  * Class:     jogamp_newt_driver_macosx_ScreenDriver
649  * Method:    setMonitorMode0
650  * Signature: (III)Z
651  */
652 JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_setMonitorMode0
653   (JNIEnv *env, jobject object, jint crt_idx, jint nativeId, jint ccwRot)
654 {
655     jboolean res = JNI_TRUE;
656     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
657
658     NSScreen *screen = NewtScreen_getNSScreenByIndex((int)crt_idx, false);
659     if( NULL == screen ) {
660         [pool release];
661         return JNI_FALSE;
662     }
663     CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
664
665     CFArrayRef availableModes = CGDisplayAvailableModes(display);
666     CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes);
667 #ifdef VERBOSE_ON
668     CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes;
669 #endif
670
671     DBG_PRINT( "setScreenMode0: scrn %d (%p, %p), nativeID %d, rot %d ccw, avail: %d/%d\n",  
672         (int)crt_idx, screen, (void*)(intptr_t)display, (int)nativeId, ccwRot, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots);
673
674     CFDictionaryRef mode = NULL;
675
676     if( 0 != ccwRot ) {
677         // FIXME: How to rotate the display/screen on OSX programmatically ?
678         DBG_PRINT( "setScreenMode0: Don't know how to rotate screen on OS X: rot %d ccw\n", ccwRot);
679         res = JNI_FALSE;
680     } else {
681         if( numberOfAvailableModes <= nativeId ) {
682             res = JNI_FALSE;
683         } else {
684             mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, nativeId);
685             // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
686         }
687     }
688
689     if( NULL != mode ) {
690         CGError err = CGDisplaySwitchToMode(display, mode);
691         if(kCGErrorSuccess != err) {
692             DBG_PRINT( "setScreenMode0: SetMode failed: %d\n", (int)err);
693             res = JNI_FALSE;
694         }
695     }
696
697     // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef
698     [pool release];
699
700     return res;
701 }
702
703 /*
704  * Class:     jogamp_newt_driver_macosx_WindowDriver
705  * Method:    initIDs
706  * Signature: ()Z
707  */
708 JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0
709   (JNIEnv *env, jclass clazz)
710 {
711     static int initialized = 0;
712
713     if(initialized) return JNI_TRUE;
714     initialized = 1;
715
716     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
717
718     NewtScreen_dump();
719
720     jclass c;
721     c = (*env)->FindClass(env, ClazzNamePoint);
722     if(NULL==c) {
723         NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't find %s", ClazzNamePoint);
724     }
725     pointClz = (jclass)(*env)->NewGlobalRef(env, c);
726     (*env)->DeleteLocalRef(env, c);
727     if(NULL==pointClz) {
728         NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't use %s", ClazzNamePoint);
729     }
730     pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
731     if(NULL==pointCstr) {
732         NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't fetch %s.%s %s",
733             ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
734     }
735
736     // Need this when debugging, as it is necessary to attach gdb to
737     // the running java process -- "gdb java" doesn't work
738     //    printf("Going to sleep for 10 seconds\n");
739     //    sleep(10);
740
741     BOOL res =  [NewtMacWindow initNatives: env forClass: clazz];
742     [pool release];
743
744     return (jboolean) res;
745 }
746
747 /**
748  * Class:     jogamp_newt_driver_macosx_WindowDriver
749  * Method:    createView0
750  * Signature: (IIII)J
751  */
752 JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0
753   (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h)
754 {
755     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
756
757     DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d (START)\n",
758         (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h);
759
760     NSRect rectView = NSMakeRect(0, 0, w, h);
761     NewtView *myView = [[NewtView alloc] initWithFrame: rectView] ;
762     DBG_PRINT( "createView0.X - new view: %p\n", myView);
763
764     [pool release];
765
766     return (jlong) (intptr_t) myView;
767 }
768
769 /**
770  * Method creates a deferred un-initialized Window, hence no special invocation required inside method.
771  *
772  * Class:     jogamp_newt_driver_macosx_WindowDriver
773  * Method:    createWindow0
774  * Signature: (IIIIZIIJ)J
775  */
776 JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow0
777   (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h,
778    jboolean fullscreen, jint styleMask, jint bufferingType, jlong jview)
779 {
780     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
781     NewtView* myView = (NewtView*) (intptr_t) jview ;
782
783     DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, view %p (START)\n",
784         (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, 
785         (int)styleMask, (int)bufferingType, myView);
786     (void)myView;
787
788     if (fullscreen) {
789         styleMask = NSBorderlessWindowMask;
790     }
791     NSRect rectWin = NSMakeRect(x, y, w, h);
792
793     // Allocate the window
794     NewtMacWindow* myWindow = [[NewtMacWindow alloc] initWithContentRect: rectWin
795                                                styleMask: (NSUInteger) styleMask
796                                                backing: (NSBackingStoreType) bufferingType
797                                                defer: YES
798                                                isFullscreenWindow: fullscreen];
799     // DBG_PRINT( "createWindow0.1 - %p, isVisible %d\n", myWindow, [myWindow isVisible]);
800
801     DBG_PRINT( "createWindow0.X - %p, isVisible %d\n", myWindow, [myWindow isVisible]);
802
803     [pool release];
804
805     return (jlong) ((intptr_t) myWindow);
806 }
807
808 /**
809  * Method is called on Main-Thread, hence no special invocation required inside method.
810  *
811  * Class:     jogamp_newt_driver_macosx_WindowDriver
812  * Method:    initWindow0
813  * Signature: (JJIIIIFZZZJ)V
814  */
815 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0
816   (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, jfloat reqPixelScale,
817    jboolean opaque, jboolean visible, jlong jview)
818 {
819     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
820     NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window);
821     NewtView* myView = (NewtView*) (intptr_t) jview ;
822     BOOL fullscreen = myWindow->isFullscreenWindow;
823
824     DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, fs %d, visible %d, view %p (START)\n",
825         (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, (float)reqPixelScale,
826         (int) opaque, (int)fullscreen, (int)visible, myView);
827
828 NS_DURING
829     // HiDPI scaling: Setup - Available >= 10.7
830     if( 1.0 == reqPixelScale ) {
831         [myView setWantsBestResolutionOpenGLSurface: NO];
832     } else {
833         [myView setWantsBestResolutionOpenGLSurface: YES];
834     }
835 NS_HANDLER
836 NS_ENDHANDLER
837
838     [myWindow setReleasedWhenClosed: NO]; // We control NSWindow destruction!
839     [myWindow setPreservesContentDuringLiveResize: NO];
840 NS_DURING
841         if ( [myWindow respondsToSelector:@selector(setRestorable:)] ) {
842             // Available >= 10.7 - Removes restauration 'feature', really close
843             [myWindow setRestorable: NO];
844         }
845 NS_HANDLER
846 NS_ENDHANDLER
847
848     NSObject* nsParentObj = (NSObject*) ((intptr_t) parent);
849     NSWindow* parentWindow = NULL;
850     NSView* parentView = NULL;
851     if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSWindow class]] ) {
852         parentWindow = (NSWindow*) nsParentObj;
853         parentView = [parentWindow contentView];
854         DBG_PRINT( "initWindow0 - Parent is NSWindow : %p (win) -> %p (view) \n", parentWindow, parentView);
855     } else if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSView class]] ) {
856         parentView = (NSView*) nsParentObj;
857         parentWindow = [parentView window];
858         DBG_PRINT( "initWindow0 - Parent is NSView : %p -(view) > %p (win) \n", parentView, parentWindow);
859     } else {
860         DBG_PRINT( "initWindow0 - Parent is neither NSWindow nor NSView : %p\n", nsParentObj);
861     }
862     DBG_PRINT( "initWindow0 - is visible.1: %d\n", [myWindow isVisible]);
863
864     // Remove animations for child windows
865     if(NULL != parentWindow) {
866 NS_DURING
867         if ( [myWindow respondsToSelector:@selector(setAnimationBehavior:)] ) {
868             // Available >= 10.7 - Removes default animations
869             [myWindow setAnimationBehavior: NSWindowAnimationBehaviorNone];
870         }
871 NS_HANDLER
872 NS_ENDHANDLER
873     }
874
875 #ifdef VERBOSE_ON
876     int dbgIdx = 1;
877 #endif
878     if(opaque) {
879         [myWindow setOpaque: YES];
880         DBG_PRINT( "initWindow0.%d\n", dbgIdx++);
881         if (!fullscreen) {
882             [myWindow setShowsResizeIndicator: YES];
883         }
884         DBG_PRINT( "initWindow0.%d\n", dbgIdx++);
885     } else {
886         [myWindow setOpaque: NO];
887         [myWindow setBackgroundColor: [NSColor clearColor]];
888     }
889
890     // specify we want mouse-moved events
891     [myWindow setAcceptsMouseMovedEvents:YES];
892
893     DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
894         dbgIdx++, myWindow, myView, [myWindow isVisible]);
895
896     // Set the content view
897     changeContentView(env, jthis, parentView, myWindow, myView, NO);
898     [myWindow setInitialFirstResponder: myView];
899
900     DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
901         dbgIdx++, myWindow, myView, [myWindow isVisible]);
902
903     if(NULL!=parentWindow) {
904         [myWindow attachToParent: parentWindow];
905     }
906
907     DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d, visible %d\n", 
908         dbgIdx++, myWindow, myView, [myWindow isVisible], visible);
909
910     // Immediately re-position this window based on an upper-left coordinate system
911     setWindowClientTopLeftPointAndSize(myWindow, x, y, w, h, NO);
912
913     DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
914         dbgIdx++, myWindow, myView, [myWindow isVisible]);
915
916 NS_DURING
917     // concurrent view rendering
918     // Available >= 10.6 - Makes the menubar disapear
919     if ( [myWindow respondsToSelector:@selector(setAllowsConcurrentViewDrawing:)] ) {
920         [myWindow setAllowsConcurrentViewDrawing: YES];
921     }
922
923     DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
924         dbgIdx++, myWindow, myView, [myWindow isVisible]);
925
926     if ( [myView respondsToSelector:@selector(setCanDrawConcurrently:)] ) {
927         [myView setCanDrawConcurrently: YES];
928     }
929 NS_HANDLER
930 NS_ENDHANDLER
931
932     DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
933         dbgIdx++, myWindow, myView, [myWindow isVisible]);
934
935     // visible on front
936     if( visible ) {
937         [myWindow orderFront: myWindow];
938     }
939
940     DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", 
941         dbgIdx++, myWindow, myView, [myWindow isVisible]);
942
943     // force surface creation
944     // [myView lockFocus];
945     // [myView unlockFocus];
946
947     // Set the next responder to be the window so that we can forward
948     // right mouse button down events
949     [myView setNextResponder: myWindow];
950
951     DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n",
952         dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView);
953
954     [myView setDestroyNotifySent: false];
955     setJavaWindowObject(env, jthis, myView, YES);
956
957     DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n",
958         dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView);
959
960 NS_DURING
961     if( fullscreen ) {
962         /** 
963          * See Bug 914: We don't use exclusive fullscreen anymore (capturing display)
964          * allowing ALT-TAB to allow process/app switching!
965          * Shall have no penalty on modern GPU and is also recommended, see bottom box @
966          * <https://developer.apple.com/library/mac/documentation/graphicsimaging/Conceptual/QuartzDisplayServicesConceptual/Articles/DisplayCapture.html>
967          *
968         NSScreen *myScreen =  NewtScreen_getNSScreenByCoord(x, y);
969         if ( [myView respondsToSelector:@selector(enterFullScreenMode:withOptions:)] ) {
970             // Available >= 10.5 - Makes the menubar disapear
971             [myView enterFullScreenMode: myScreen withOptions:NULL];
972         } */
973         if( myWindow->hasPresentationSwitch ) {
974             DBG_PRINT( "initWindow0.%d - %p view %p, setPresentationOptions 0x%X\n", 
975                 dbgIdx++, myWindow, myView, (int)myWindow->fullscreenPresentationOptions);
976             [NSApp setPresentationOptions: myWindow->fullscreenPresentationOptions];
977         }
978     }
979 NS_HANDLER
980 NS_ENDHANDLER
981
982     DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n",
983         dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView);
984
985     [pool release];
986     DBG_PRINT( "initWindow0.X - %p (this), %p (parent): new window: %p, view %p\n",
987         (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView);
988 }
989
990 /**
991  * Method is called on Main-Thread, hence no special invocation required inside method.
992  *
993  * Class:     jogamp_newt_driver_macosx_WindowDriver
994  * Method:    setPixelScale0
995  * Signature: (JJF)V
996  */
997 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPixelScale0
998   (JNIEnv *env, jobject jthis, jlong window, jlong view, jfloat reqPixelScale)
999 {
1000     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1001     NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window);
1002     NewtView* myView = (NewtView*) (intptr_t) view ;
1003 #ifdef VERBOSE_ON
1004     int dbgIdx = 1;
1005 #endif
1006
1007     DBG_PRINT( "setPixelScale0 - %p (this), %p (window), view %p, reqPixScale %f (START)\n",
1008         (void*)(intptr_t)jthis, myWindow, myView, (float)reqPixelScale);
1009
1010 NS_DURING
1011     // HiDPI scaling: Setup - Available >= 10.7
1012     if( 1.0 == reqPixelScale ) {
1013         [myView setWantsBestResolutionOpenGLSurface: NO];
1014     } else {
1015         [myView setWantsBestResolutionOpenGLSurface: YES];
1016     }
1017 NS_HANDLER
1018 NS_ENDHANDLER
1019
1020     DBG_PRINT( "setPixelScale0.%d - %p (this), window: %p, view %p\n",
1021         dbgIdx++, (void*)(intptr_t)jthis, myWindow, myView);
1022
1023     [pool release];
1024     DBG_PRINT( "setPixelScale0.X - %p (this), window: %p, view %p\n",
1025         (void*)(intptr_t)jthis, myWindow, myView);
1026 }
1027
1028 /**
1029  * Method is called on Main-Thread, hence no special invocation required inside method.
1030  *
1031  * Class:     jogamp_newt_driver_macosx_WindowDriver
1032  * Method:    close0
1033  * Signature: (J)V
1034  */
1035 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0
1036   (JNIEnv *env, jobject unused, jlong window)
1037 {
1038     NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
1039     if( NULL == mWin ) {
1040         DBG_PRINT( "windowClose.0 - NULL NEWT win - abort\n");
1041         return;
1042     }
1043     BOOL isNSWin = [mWin isKindOfClass:[NSWindow class]];
1044     BOOL isNewtWin = [mWin isKindOfClass:[NewtMacWindow class]];
1045     NSWindow *pWin = [mWin parentWindow];
1046     DBG_PRINT( "windowClose.0 - %p [isNSWindow %d, isNewtWin %d], parent %p\n", mWin, isNSWin, isNewtWin, pWin);
1047     (void)isNSWin; // silence
1048     if( !isNewtWin ) {
1049         NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
1050         return;
1051     }
1052     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1053     NewtView* mView = (NewtView *)[mWin contentView];
1054     BOOL fullscreen = mWin->isFullscreenWindow;
1055     BOOL destroyNotifySent, isNSView, isNewtView;
1056     if( NULL != mView ) {
1057         isNSView = [mView isKindOfClass:[NSView class]];
1058         isNewtView = [mView isKindOfClass:[NewtView class]];
1059         destroyNotifySent = isNewtView ? [mView getDestroyNotifySent] : false;
1060     } else {
1061         isNSView = false;
1062         isNewtView = false;
1063         destroyNotifySent = false;
1064     }
1065
1066     DBG_PRINT( "windowClose.0 - %p, destroyNotifySent %d, view %p [isNSView %d, isNewtView %d], fullscreen %d, parent %p\n", 
1067         mWin, destroyNotifySent, mView, isNSView, isNewtView, (int)fullscreen, pWin);
1068
1069     [mWin setRealized: NO];
1070
1071     if( isNewtView ) {
1072         // cleanup view
1073         [mView setDestroyNotifySent: true];
1074         setJavaWindowObject(env, NULL, mView, NO);
1075     }
1076
1077 NS_DURING
1078     /** 
1079      * See Bug 914: We don't use exclusive fullscreen anymore (capturing display)
1080      * See initWindow0(..) above ..
1081     if(NULL!=mView) {
1082         BOOL iifs;
1083         if ( [mView respondsToSelector:@selector(isInFullScreenMode)] ) {
1084             iifs = [mView isInFullScreenMode];
1085         } else {
1086             iifs = NO;
1087         }
1088         if(iifs && [mView respondsToSelector:@selector(exitFullScreenModeWithOptions:)] ) {
1089             [mView exitFullScreenModeWithOptions: NULL];
1090         }
1091     } */
1092     // Note: mWin's release will also release it's mView!
1093     DBG_PRINT( "windowClose.1a - %p view %p, fullscreen %d, hasPresSwitch %d, defaultPresentationOptions 0x%X\n", 
1094         mWin, mView, (int)fullscreen, (int)mWin->hasPresentationSwitch, (int)mWin->defaultPresentationOptions);
1095
1096     if( fullscreen && mWin->hasPresentationSwitch ) {
1097         DBG_PRINT( "windowClose.1b - %p view %p, setPresentationOptions 0x%X\n", 
1098             mWin, mView, (int)mWin->defaultPresentationOptions);
1099         [NSApp setPresentationOptions: mWin->defaultPresentationOptions];
1100     }
1101 NS_HANDLER
1102 NS_ENDHANDLER
1103
1104     if(NULL!=pWin) {
1105         [mWin detachFromParent: pWin];
1106     }
1107     [mWin orderOut: mWin];
1108
1109     DBG_PRINT( "windowClose.2 - %p view %p, parent %p\n", mWin, mView, pWin);
1110
1111     [mWin release];
1112
1113     DBG_PRINT( "windowClose.Xp\n");
1114
1115     [pool release];
1116 }
1117
1118 /*
1119  * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
1120  * Method:    lockSurface0
1121  * Signature: (JJ)Z
1122  */
1123 JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_lockSurface0
1124   (JNIEnv *env, jclass clazz, jlong window, jlong view)
1125 {
1126     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
1127     if(NO == [mWin isRealized]) {
1128         return JNI_FALSE;
1129     }
1130     NewtView * mView = (NewtView *) ((intptr_t) view);
1131     return [mView softLock] == YES ? JNI_TRUE : JNI_FALSE;
1132     /** deadlocks, since we render independent of focus
1133     return [mView lockFocusIfCanDraw] == YES ? JNI_TRUE : JNI_FALSE; */
1134 }
1135
1136 /*
1137  * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
1138  * Method:    unlockSurface0
1139  * Signature: (JJ)Z
1140  */
1141 JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_unlockSurface0
1142   (JNIEnv *env, jclass clazz, jlong window, jlong view)
1143 {
1144     // NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
1145     (void) window;
1146     NewtView * mView = (NewtView *) ((intptr_t) view);
1147     return [mView softUnlock] == YES ? JNI_TRUE : JNI_FALSE;
1148     /** deadlocks, since we render independent of focus
1149     [mView unlockFocus]; */
1150 }
1151
1152 /*
1153  * Class:     jogamp_newt_driver_macosx_WindowDriver
1154  * Method:    requestFocus0
1155  * Signature: (JZ)V
1156  */
1157 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
1158   (JNIEnv *env, jobject window, jlong w, jboolean force)
1159 {
1160     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1161     NSWindow* mWin = (NSWindow*) ((intptr_t) w);
1162 #ifdef VERBOSE_ON
1163     BOOL hasFocus = [mWin isKeyWindow];
1164 #endif
1165     DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus);
1166
1167     [mWin setAcceptsMouseMovedEvents: YES];
1168     [mWin makeFirstResponder: nil];
1169     [mWin orderFrontRegardless];
1170     [mWin makeKeyWindow];
1171
1172     DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", mWin, force);
1173
1174     [pool release];
1175 }
1176
1177 /*
1178  * Class:     jogamp_newt_driver_macosx_WindowDriver
1179  * Method:    resignFocus0
1180  * Signature: (J)V
1181  */
1182 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0
1183   (JNIEnv *env, jobject window, jlong w)
1184 {
1185     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1186     NSWindow* mWin = (NSWindow*) ((intptr_t) w);
1187     NSWindow* pWin = [mWin parentWindow];
1188     BOOL hasFocus = [mWin isKeyWindow];
1189
1190     DBG_PRINT( "requestFocusParent0 - window: %p, parent %p, hasFocus %d (START)\n", mWin, pWin, hasFocus );
1191     if( hasFocus ) {
1192         if(NULL != pWin) {
1193             // [mWin makeFirstResponder: pWin];
1194             [pWin makeKeyWindow];
1195         } else {
1196             [pWin resignKeyWindow];
1197         }
1198     }
1199     DBG_PRINT( "requestFocusParent0 - window: %p (END)\n", mWin);
1200
1201     [pool release];
1202 }
1203
1204 /*
1205  * Class:     jogamp_newt_driver_macosx_WindowDriver
1206  * Method:    orderFront0
1207  * Signature: (J)V
1208  */
1209 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderFront0
1210   (JNIEnv *env, jobject unused, jlong window)
1211 {
1212     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1213     NSWindow* mWin = (NSWindow*) ((intptr_t) window);
1214     NSWindow* pWin = [mWin parentWindow];
1215
1216     DBG_PRINT( "orderFront0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]);
1217
1218     if( NULL == pWin ) {
1219         [mWin orderFrontRegardless];
1220     } else {
1221         [mWin orderWindow: NSWindowAbove relativeTo: [pWin windowNumber]];
1222     }
1223
1224     DBG_PRINT( "orderFront0 - window: (parent %p) %p (END)\n", pWin, mWin);
1225
1226     [pool release];
1227 }
1228
1229 /*
1230  * Class:     jogamp_newt_driver_macosx_WindowDriver
1231  * Method:    orderOut
1232  * Signature: (J)V
1233  */
1234 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderOut0
1235   (JNIEnv *env, jobject unused, jlong window)
1236 {
1237     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1238     NSWindow* mWin = (NSWindow*) ((intptr_t) window);
1239     NSWindow* pWin = [mWin parentWindow];
1240
1241     DBG_PRINT( "orderOut0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]);
1242
1243     if( NULL == pWin ) {
1244         [mWin orderOut: mWin];
1245     } else {
1246         [mWin orderWindow: NSWindowOut relativeTo: [pWin windowNumber]];
1247     }
1248
1249     DBG_PRINT( "orderOut0 - window: (parent %p) %p (END)\n", pWin, mWin);
1250
1251     [pool release];
1252 }
1253
1254 /*
1255  * Class:     jogamp_newt_driver_macosx_WindowDriver
1256  * Method:    setTitle0
1257  * Signature: (JLjava/lang/String;)V
1258  */
1259 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setTitle0
1260   (JNIEnv *env, jobject unused, jlong window, jstring title)
1261 {
1262     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1263     NSWindow* win = (NSWindow*) ((intptr_t) window);
1264
1265     DBG_PRINT( "setTitle0 - window: %p (START)\n", win);
1266
1267     NSString* str = jstringToNSString(env, title);
1268     [str autorelease];
1269     [win setTitle: str];
1270
1271     DBG_PRINT( "setTitle0 - window: %p (END)\n", win);
1272
1273     [pool release];
1274 }
1275
1276 /*
1277  * Class:     jogamp_newt_driver_macosx_WindowDriver
1278  * Method:    contentView0
1279  * Signature: (J)J
1280  */
1281 JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_contentView0
1282   (JNIEnv *env, jobject unused, jlong window)
1283 {
1284     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1285     NSWindow* win = (NSWindow*) ((intptr_t) window);
1286     NSView* nsView = [win contentView];
1287     NewtView* newtView = NULL;
1288
1289     if( [nsView isKindOfClass:[NewtView class]] ) {
1290         newtView = (NewtView *) nsView;
1291     }
1292
1293     DBG_PRINT( "contentView0 - window: %p, view: %p, newtView %p\n", win, nsView, newtView);
1294
1295     jlong res = (jlong) ((intptr_t) nsView);
1296
1297     [pool release];
1298     return res;
1299 }
1300
1301 /**
1302  * Method is called on Main-Thread, hence no special invocation required inside method.
1303  *
1304  * Class:     jogamp_newt_driver_macosx_WindowDriver
1305  * Method:    changeContentView
1306  * Signature: (J)V
1307  */
1308 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeContentView0
1309   (JNIEnv *env, jobject jthis, jlong parentWindowOrView, jlong window, jlong jview)
1310 {
1311     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1312
1313     NewtView* newView = (NewtView *) ((intptr_t) jview);
1314     NewtMacWindow* win = (NewtMacWindow*) ((intptr_t) window);
1315
1316     DBG_PRINT( "changeContentView0.0 -  win %p, view (%p,%d)\n", 
1317         win, newView, getRetainCount(newView));
1318
1319     NSObject *nsParentObj = (NSObject*) ((intptr_t) parentWindowOrView);
1320     NSView* pView = NULL;
1321     if( NULL != nsParentObj ) {
1322         if( [nsParentObj isKindOfClass:[NSWindow class]] ) {
1323             NSWindow * pWin = (NSWindow*) nsParentObj;
1324             pView = [pWin contentView];
1325         } else if( [nsParentObj isKindOfClass:[NSView class]] ) {
1326             pView = (NSView*) nsParentObj;
1327         }
1328     }
1329
1330     changeContentView(env, jthis, pView, win, newView, YES);
1331
1332     DBG_PRINT( "changeContentView0.X\n");
1333
1334     [pool release];
1335 }
1336
1337 /*
1338  * Class:     jogamp_newt_driver_macosx_WindowDriver
1339  * Method:    setWindowClientTopLeftPointAndSize0
1340  * Signature: (JIIIIZ)V
1341  */
1342 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPointAndSize0
1343   (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jint w, jint h, jboolean display)
1344 {
1345     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1346     NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
1347
1348     DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin);
1349
1350     setWindowClientTopLeftPointAndSize(mWin, x, y, w, h, display);
1351
1352     DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (END)\n", mWin);
1353
1354     [pool release];
1355 }
1356
1357 /*
1358  * Class:     jogamp_newt_driver_macosx_WindowDriver
1359  * Method:    setWindowClientTopLeftPoint0
1360  * Signature: (JIIZ)V
1361  */
1362 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPoint0
1363   (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jboolean display)
1364 {
1365     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1366     NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
1367
1368     DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (START)\n", mWin);
1369
1370     setWindowClientTopLeftPoint(mWin, x, y, display);
1371
1372     DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (END)\n", mWin);
1373
1374     [pool release];
1375 }
1376
1377 /*
1378  * Class:     jogamp_newt_driver_macosx_WindowDriver
1379  * Method:    setAlwaysOnTop0
1380  * Signature: (JZ)V
1381  */
1382 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setAlwaysOnTop0
1383   (JNIEnv *env, jobject unused, jlong window, jboolean atop)
1384 {
1385     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1386     NSWindow* win = (NSWindow*) ((intptr_t) window);
1387
1388     DBG_PRINT( "setAlwaysOnTop0 - window: %p, atop %d (START)\n", win, (int)atop);
1389
1390     if(atop) {
1391         [win setLevel:NSFloatingWindowLevel];
1392     } else {
1393         [win setLevel:NSNormalWindowLevel];
1394     }
1395
1396     DBG_PRINT( "setAlwaysOnTop0 - window: %p, atop %d (END)\n", win, (int)atop);
1397
1398     [pool release];
1399 }
1400
1401 /*
1402  * Class:     jogamp_newt_driver_macosx_WindowDriver
1403  * Method:    getLocationOnScreen0
1404  * Signature: (JII)Ljavax/media/nativewindow/util/Point;
1405  */
1406 JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocationOnScreen0
1407   (JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y)
1408 {
1409     NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) win;
1410     if( ![mWin isKindOfClass:[NewtMacWindow class]] ) {
1411         NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
1412         return NULL;
1413     }
1414     NSPoint p0 = [mWin getLocationOnScreen: NSMakePoint(src_x, src_y)];
1415     return (*env)->NewObject(env, pointClz, pointCstr, (jint)p0.x, (jint)p0.y);
1416 }
1417
1418 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0
1419   (JNIEnv *env, jobject unused, jlong window, jlong handle)
1420 {
1421     NSCursor *c = (NSCursor*) (intptr_t) handle ;
1422     if ( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
1423         NewtCommon_throwNewRuntimeException(env, "Not a NSCursor %p", c);
1424         return;
1425     }
1426     NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
1427     if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
1428         NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
1429         return;
1430     }
1431     NewtView* nView = (NewtView *) [mWin contentView];
1432     if( ! [nView isKindOfClass:[NewtView class]] ) {
1433         NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView);
1434         return;
1435     }
1436     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1437     [nView setPointerIcon: c];
1438     [pool release];
1439 }
1440
1441 /*
1442  * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
1443  * Method:    setPointerVisible0
1444  * Signature: (JZ)Z
1445  */
1446 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVisible0
1447   (JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible)
1448 {
1449     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
1450     if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
1451         NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
1452         return;
1453     }
1454     NewtView* nView = (NewtView *) [mWin contentView];
1455     if( ! [nView isKindOfClass:[NewtView class]] ) {
1456         NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView);
1457         return;
1458     }
1459     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1460     [nView setMouseVisible: ( JNI_TRUE == mouseVisible ) ? YES : NO 
1461                   hasFocus: ( JNI_TRUE == hasFocus ) ? YES : NO];
1462     [pool release];
1463 }
1464
1465 /*
1466  * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
1467  * Method:    confinePointer0
1468  * Signature: (JZ)Z
1469  */
1470 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointer0
1471   (JNIEnv *env, jclass clazz, jlong window, jboolean confine)
1472 {
1473     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
1474     if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
1475         NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
1476         return;
1477     }
1478     NewtView* nView = (NewtView *) [mWin contentView];
1479     if( ! [nView isKindOfClass:[NewtView class]] ) {
1480         NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView);
1481         return;
1482     }
1483     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1484     [nView setMouseConfined: ( JNI_TRUE == confine ) ? YES : NO];
1485     [pool release];
1486 }
1487
1488 /*
1489  * Class:     Java_jogamp_newt_driver_macosx_WindowDriver
1490  * Method:    warpPointer0
1491  * Signature: (JJII)V
1492  */
1493 JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0
1494   (JNIEnv *env, jclass clazz, jlong window, jint x, jint y)
1495 {
1496     NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
1497     if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
1498         NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
1499         return;
1500     }
1501     NewtView* nView = (NewtView *) [mWin contentView];
1502     if( ! [nView isKindOfClass:[NewtView class]] ) {
1503         NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView);
1504         return;
1505     }
1506     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1507     [nView setMousePosition: [mWin newtRelClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]];
1508     [pool release];
1509 }
1510
http://JogAmp.org git info: FAQ, tutorial and man pages.