Jogamp
cd852bb09eec6e398edf38ce6e8865532eb77ef9
[jogl.git] / src / newt / classes / jogamp / newt / driver / macosx / WindowDriver.java
1 /*
2  * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
3  * Copyright (c) 2010 JogAmp Community. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * - Redistribution of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * - Redistribution in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of Sun Microsystems, Inc. or the names of
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * This software is provided "AS IS," without a warranty of any kind. ALL
21  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
24  * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
25  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
26  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
27  * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
28  * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
29  * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
30  * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
31  * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32  *
33  */
34
35 package jogamp.newt.driver.macosx;
36
37 import javax.media.nativewindow.AbstractGraphicsConfiguration;
38 import javax.media.nativewindow.GraphicsConfigurationFactory;
39 import javax.media.nativewindow.NativeWindow;
40 import javax.media.nativewindow.NativeWindowException;
41 import javax.media.nativewindow.MutableSurface;
42 import javax.media.nativewindow.VisualIDHolder;
43 import javax.media.nativewindow.util.Insets;
44 import javax.media.nativewindow.util.Point;
45 import javax.media.nativewindow.util.PointImmutable;
46
47 import jogamp.nativewindow.macosx.OSXUtil;
48 import jogamp.newt.PointerIconImpl;
49 import jogamp.newt.ScreenImpl;
50 import jogamp.newt.WindowImpl;
51 import jogamp.newt.driver.DriverClearFocus;
52 import jogamp.newt.driver.DriverUpdatePosition;
53
54 import com.jogamp.newt.event.InputEvent;
55 import com.jogamp.newt.event.KeyEvent;
56 import com.jogamp.newt.event.MonitorEvent;
57 import com.jogamp.opengl.math.FloatUtil;
58
59 public class WindowDriver extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition {
60
61     static {
62         DisplayDriver.initSingleton();
63     }
64
65     private int pixelScale;
66
67     public WindowDriver() {
68         pixelScale = 1;
69     }
70
71     private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final float newPixelScaleRaw) {
72         final int newPixelScaleSafe = FloatUtil.isZero(newPixelScaleRaw, FloatUtil.EPSILON) ? 1 : (int) newPixelScaleRaw;
73         final boolean changed = pixelScale != newPixelScaleSafe;
74         if( DEBUG_IMPLEMENTATION ) {
75             System.err.println("WindowDriver.updatePixelScale.X: "+pixelScale+" -> "+newPixelScaleSafe+" (raw "+newPixelScaleRaw+") - changed "+changed);
76         }
77         if( changed ) {
78             pixelScale = newPixelScaleSafe;
79             if( sendEvent ) {
80                 super.sizeChanged(defer, getWidth(), getHeight(), true);
81             } else {
82                 defineSize(getWidth(), getHeight());
83             }
84         }
85         return changed;
86     }
87
88     private boolean updatePixelScaleByScreenIdx(final boolean sendEvent) {
89         final float newPixelScaleRaw = (float) OSXUtil.GetPixelScale(getScreen().getIndex());
90         if( DEBUG_IMPLEMENTATION ) {
91             System.err.println("WindowDriver.updatePixelScale.1: "+pixelScale+" -> "+newPixelScaleRaw);
92         }
93         return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw);
94     }
95
96     private boolean updatePixelScaleByWindowHandle(final boolean sendEvent) {
97         final long wh = getWindowHandle();
98         if( 0 != wh ) {
99             final float newPixelScaleRaw = (float)OSXUtil.GetPixelScale(wh);
100             if( DEBUG_IMPLEMENTATION ) {
101                 System.err.println("WindowDriver.updatePixelScale.2: "+pixelScale+" -> "+newPixelScaleRaw);
102             }
103             return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw);
104         } else {
105             return false;
106         }
107     }
108
109     /** Called from native code */
110     protected void updatePixelScale(final boolean defer, final float newPixelScaleRaw) {
111         final long handle = getWindowHandle();
112         if( 0 != handle ) {
113             if( DEBUG_IMPLEMENTATION ) {
114                 System.err.println("WindowDriver.updatePixelScale.3: "+pixelScale+" -> "+newPixelScaleRaw);
115             }
116             updatePixelScale(true /* sendEvent*/, defer, newPixelScaleRaw);
117         }
118     }
119
120     @Override
121     protected final void instantiationFinished() {
122         updatePixelScaleByScreenIdx(false /* sendEvent*/);
123     }
124
125     @Override
126     protected void setScreen(ScreenImpl newScreen) { // never null !
127         super.setScreen(newScreen);
128         updatePixelScaleByScreenIdx(false /* sendEvent*/);  // caller (reparent, ..) will send reshape event
129     }
130
131     @Override
132     protected void monitorModeChanged(MonitorEvent me, boolean success) {
133         updatePixelScaleByWindowHandle(false /* sendEvent*/); // send reshape event itself
134     }
135
136     @Override
137     protected final int getPixelScaleX() {
138         return pixelScale;
139     }
140
141     @Override
142     protected final int getPixelScaleY() {
143         return pixelScale;
144     }
145
146     @Override
147     protected void createNativeImpl() {
148         final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
149                 capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
150         if (null == cfg) {
151             throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
152         }
153         setGraphicsConfiguration(cfg);
154         reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY, true));
155         if (0 == getWindowHandle()) {
156             throw new NativeWindowException("Error creating window");
157         }
158     }
159
160     @Override
161     protected void closeNativeImpl() {
162         try {
163             if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); }
164             final long handle = getWindowHandle();
165             visibleChanged(true, false);
166             setWindowHandle(0);
167             surfaceHandle = 0;
168             sscSurfaceHandle = 0;
169             isOffscreenInstance = false;
170             if (0 != handle) {
171                 OSXUtil.RunOnMainThread(false, new Runnable() {
172                    @Override
173                    public void run() {
174                        close0( handle );
175                    } } );
176             }
177         } catch (Throwable t) {
178             if(DEBUG_IMPLEMENTATION) {
179                 Exception e = new Exception("Warning: closeNative failed - "+Thread.currentThread().getName(), t);
180                 e.printStackTrace();
181             }
182         }
183     }
184
185     @Override
186     protected int lockSurfaceImpl() {
187         /**
188          * if( isOffscreenInstance ) {
189          *    return LOCK_SUCCESS;
190          * }
191          */
192         final long w = getWindowHandle();
193         final long v = surfaceHandle;
194         if( 0 != v && 0 != w ) {
195             return lockSurface0(w, v) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
196         }
197         return LOCK_SURFACE_NOT_READY;
198     }
199
200     @Override
201     protected void unlockSurfaceImpl() {
202         /**
203          * if( isOffscreenInstance ) {
204          *    return;
205          * }
206          */
207         final long w = getWindowHandle();
208         final long v = surfaceHandle;
209         if(0 != w && 0 != v) {
210             if( !unlockSurface0(w, v) ) {
211                 throw new NativeWindowException("Failed to unlock surface, probably not locked!");
212             }
213         }
214     }
215
216     @Override
217     public final long getSurfaceHandle() {
218         return 0 != sscSurfaceHandle ? sscSurfaceHandle : surfaceHandle;
219     }
220
221     @Override
222     public void setSurfaceHandle(long surfaceHandle) {
223         if(DEBUG_IMPLEMENTATION) {
224             System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
225         }
226         sscSurfaceHandle = surfaceHandle;
227         if (isNativeValid()) {
228             if (0 != sscSurfaceHandle) {
229                 OSXUtil.RunOnMainThread(false, new Runnable() {
230                     @Override
231                     public void run() {
232                         orderOut0( 0 != getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() );
233                     } } );
234             } /** this is done by recreation!
235               else if (isVisible()){
236                 OSXUtil.RunOnMainThread(false, new Runnable() {
237                     public void run() {
238                         orderFront0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() );
239                     } } );
240             } */
241         }
242     }
243
244     @Override
245     protected void setTitleImpl(final String title) {
246         OSXUtil.RunOnMainThread(false, new Runnable() {
247             @Override
248             public void run() {
249                 setTitle0(getWindowHandle(), title);
250             } } );
251     }
252
253     @Override
254     protected void requestFocusImpl(final boolean force) {
255         final boolean _isFullscreen = isFullscreen();
256         final boolean _isOffscreenInstance = isOffscreenInstance;
257         if(DEBUG_IMPLEMENTATION) {
258             System.err.println("MacWindow: requestFocusImpl(), isOffscreenInstance "+_isOffscreenInstance+", isFullscreen "+_isFullscreen);
259         }
260         if(!_isOffscreenInstance) {
261             OSXUtil.RunOnMainThread(false, new Runnable() {
262                 @Override
263                 public void run() {
264                     requestFocus0(getWindowHandle(), force);
265                     if(_isFullscreen) {
266                         // 'NewtMacWindow::windowDidBecomeKey()' is not always called in fullscreen-mode!
267                         focusChanged(false, true);
268                     }
269                 } } );
270         } else {
271             focusChanged(false, true);
272         }
273     }
274
275     @Override
276     public final void clearFocus() {
277         if(DEBUG_IMPLEMENTATION) {
278             System.err.println("MacWindow: clearFocus(), isOffscreenInstance "+isOffscreenInstance);
279         }
280         if(!isOffscreenInstance) {
281             OSXUtil.RunOnMainThread(false, new Runnable() {
282                 @Override
283                 public void run() {
284                     resignFocus0(getWindowHandle());
285                 } } );
286         } else {
287             focusChanged(false, false);
288         }
289     }
290
291     private boolean useParent(NativeWindow parent) { return null != parent && 0 != parent.getWindowHandle(); }
292
293     @Override
294     public void updatePosition(int x, int y) {
295         final long handle = getWindowHandle();
296         if( 0 != handle && !isOffscreenInstance ) {
297             final NativeWindow parent = getParent();
298             final boolean useParent = useParent(parent);
299             final int pX=parent.getX(), pY=parent.getY();
300             final Point p0S = getLocationOnScreenImpl(x, y, parent, useParent);
301             if(DEBUG_IMPLEMENTATION) {
302                 System.err.println("MacWindow: updatePosition() parent["+useParent+" "+pX+"/"+pY+"] "+x+"/"+y+" ->  "+x+"/"+y+" rel-client-pos, "+p0S+" screen-client-pos");
303             }
304             OSXUtil.RunOnMainThread(false, new Runnable() {
305                 @Override
306                 public void run() {
307                     setWindowClientTopLeftPoint0(handle, p0S.getX(), p0S.getY(), isVisible());
308                 } } );
309             // no native event (fullscreen, some reparenting)
310             positionChanged(true, x, y);
311         }
312     }
313
314     @Override
315     protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
316         final long handle = getWindowHandle();
317         if( 0 != handle && !isOffscreenInstance ) {
318             final NativeWindow parent = getParent();
319             final boolean useParent = useParent(parent);
320             if( useParent && ( getWidth() != newWidth || getHeight() != newHeight ) ) {
321                 final int x=getX(), y=getY();
322                 final Point p0S = getLocationOnScreenImpl(x, y, parent, useParent);
323                 if(DEBUG_IMPLEMENTATION) {
324                     System.err.println("MacWindow: sizeChanged() parent["+useParent+" "+x+"/"+y+"] "+getX()+"/"+getY()+" "+newWidth+"x"+newHeight+" ->  "+p0S+" screen-client-pos");
325                 }
326                 OSXUtil.RunOnMainThread(false, new Runnable() {
327                     @Override
328                     public void run() {
329                         setWindowClientTopLeftPoint0(getWindowHandle(), p0S.getX(), p0S.getY(), isVisible());
330                     } } );
331             }
332         }
333         super.sizeChanged(defer, newWidth, newHeight, force);
334     }
335
336     @Override
337     protected boolean reconfigureWindowImpl(int x, int y, final int width, final int height, int flags) {
338         final boolean _isOffscreenInstance = isOffscreenInstance(this, this.getParent());
339         isOffscreenInstance = 0 != sscSurfaceHandle || _isOffscreenInstance;
340         final PointImmutable pClientLevelOnSreen;
341         if( isOffscreenInstance ) {
342             x = 0; y = 0;
343             pClientLevelOnSreen = new Point(0, 0);
344         } else  {
345             final NativeWindow parent = getParent();
346             final boolean useParent = useParent(parent);
347             if( useParent ) {
348                 pClientLevelOnSreen = getLocationOnScreenImpl(x, y, parent, useParent);
349             } else {
350                 pClientLevelOnSreen = new Point(x, y);
351             }
352         }
353
354         if(DEBUG_IMPLEMENTATION) {
355             final AbstractGraphicsConfiguration cWinCfg = this.getGraphicsConfiguration();
356             final NativeWindow pWin = getParent();
357             final AbstractGraphicsConfiguration pWinCfg = null != pWin ? pWin.getGraphicsConfiguration() : null;
358             System.err.println("MacWindow reconfig.0: "+x+"/"+y+" -> clientPos "+pClientLevelOnSreen+" - "+width+"x"+height+
359                                ",\n\t parent type "+(null != pWin ? pWin.getClass().getName() : null)+
360                                ",\n\t   this-chosenCaps "+(null != cWinCfg ? cWinCfg.getChosenCapabilities() : null)+
361                                ",\n\t parent-chosenCaps "+(null != pWinCfg ? pWinCfg.getChosenCapabilities() : null)+
362                                ", isOffscreenInstance(sscSurfaceHandle "+toHexString(sscSurfaceHandle)+
363                                ", ioi: "+_isOffscreenInstance+
364                                ") -> "+isOffscreenInstance+
365                                "\n\t, "+getReconfigureFlagsAsString(null, flags));
366             // Thread.dumpStack();
367         }
368
369         final boolean setVisible = 0 != ( FLAG_IS_VISIBLE & flags);
370
371         if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && !setVisible ) {
372             if ( !isOffscreenInstance ) {
373                 OSXUtil.RunOnMainThread(false, new Runnable() {
374                     @Override
375                     public void run() {
376                         orderOut0(getWindowHandle());
377                         visibleChanged(true, false);
378                     } } );
379             } else {
380                 visibleChanged(true, false);
381             }
382         }
383         if( 0 == getWindowHandle() && setVisible ||
384             0 != ( FLAG_CHANGE_DECORATION & flags) ||
385             0 != ( FLAG_CHANGE_PARENTING & flags) ||
386             0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
387             if(isOffscreenInstance) {
388                 createWindow(true, 0 != getWindowHandle(), pClientLevelOnSreen, 64, 64, false, setVisible, false);
389             } else {
390                 createWindow(false, 0 != getWindowHandle(), pClientLevelOnSreen, width, height,
391                                     0 != ( FLAG_IS_FULLSCREEN & flags), setVisible, 0 != ( FLAG_IS_ALWAYSONTOP & flags));
392             }
393             // no native event (fullscreen, some reparenting)
394             positionChanged(false,  x, y);
395             updatePixelScaleByWindowHandle(false /* sendEvent */);
396             super.sizeChanged(false, width, height, true);
397             visibleChanged(false, setVisible);
398         } else {
399             if( width>0 && height>0 ) {
400                 if( !isOffscreenInstance ) {
401                     OSXUtil.RunOnMainThread(false, new Runnable() {
402                         @Override
403                         public void run() {
404                             setWindowClientTopLeftPointAndSize0(getWindowHandle(), pClientLevelOnSreen.getX(), pClientLevelOnSreen.getY(), width, height, setVisible);
405                         } } );
406                 } // else offscreen size is realized via recreation
407                 // no native event (fullscreen, some reparenting)
408                 positionChanged(true,  x, y);
409                 super.sizeChanged(true, width, height, false);
410             }
411             if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && setVisible ) {
412                 if( !isOffscreenInstance ) {
413                     OSXUtil.RunOnMainThread(false, new Runnable() {
414                         @Override
415                         public void run() {
416                             orderFront0(getWindowHandle());
417                             visibleChanged(true, true);
418                         } } );
419                 } else {
420                     visibleChanged(true, true);
421                 }
422             }
423             if( !isOffscreenInstance ) {
424                 setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags));
425             }
426         }
427         if(DEBUG_IMPLEMENTATION) {
428             System.err.println("MacWindow reconfig.X: clientPos "+pClientLevelOnSreen+", "+width+"x"+height+" -> clientPos "+getLocationOnScreenImpl(0, 0)+", insets: "+getInsets());
429         }
430         return true;
431     }
432
433     @Override
434     protected Point getLocationOnScreenImpl(int x, int y) {
435         final NativeWindow parent = getParent();
436         final boolean useParent = useParent(parent);
437         return getLocationOnScreenImpl(x, y, parent, useParent);
438     }
439
440     private Point getLocationOnScreenImpl(final int x, final int y, final NativeWindow parent, final boolean useParent) {
441         if( !useParent && !isOffscreenInstance && 0 != surfaceHandle) {
442             return OSXUtil.GetLocationOnScreen(surfaceHandle, x, y);
443         }
444
445         final Point p = new Point(x, y);
446         if( useParent ) {
447             p.translate( parent.getLocationOnScreen(null) );
448         }
449         return p;
450     }
451
452     @Override
453     protected void updateInsetsImpl(Insets insets) {
454         // nop - using event driven insetsChange(..)
455     }
456
457     /** Callback for native screen position change event of the client area. */
458     protected void screenPositionChanged(boolean defer, int newX, int newY) {
459         // passed coordinates are in screen position of the client area
460         if(getWindowHandle()!=0) {
461             final NativeWindow parent = getParent();
462             if( null == parent || isOffscreenInstance ) {
463                 if(DEBUG_IMPLEMENTATION) {
464                     System.err.println("MacWindow.positionChanged.0 (Screen Pos - TOP): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> "+newX+"/"+newY);
465                 }
466                 positionChanged(defer, newX, newY);
467             } else {
468                 // screen position -> rel child window position
469                 Point absPos = new Point(newX, newY);
470                 Point parentOnScreen = parent.getLocationOnScreen(null);
471                 absPos.translate( parentOnScreen.scale(-1, -1) );
472                 if(DEBUG_IMPLEMENTATION) {
473                     System.err.println("MacWindow.positionChanged.1 (Screen Pos - CHILD): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> absPos "+newX+"/"+newY+", parentOnScreen "+parentOnScreen+" -> "+absPos);
474                 }
475                 positionChanged(defer, absPos.getX(), absPos.getY());
476             }
477         } else if(DEBUG_IMPLEMENTATION) {
478             System.err.println("MacWindow.positionChanged.2 (Screen Pos - IGN): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> "+newX+"/"+newY);
479         }
480     }
481
482     @Override
483     protected void setPointerIconImpl(final PointerIconImpl pi) {
484         if( !isOffscreenInstance ) {
485             final long piHandle = null != pi ? pi.validatedHandle() : 0;
486             OSXUtil.RunOnMainThread(true, new Runnable() { // waitUntildone due to PointerIconImpl's Lifecycle !
487                 @Override
488                 public void run() {
489                     setPointerIcon0(getWindowHandle(), piHandle);
490                 } } );
491         }
492     }
493
494     @Override
495     protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
496         if( !isOffscreenInstance ) {
497             OSXUtil.RunOnMainThread(false, new Runnable() {
498                 @Override
499                 public void run() {
500                     setPointerVisible0(getWindowHandle(), hasFocus(), pointerVisible);
501                 } } );
502             return true;
503         }
504         return false;
505     }
506
507     @Override
508     protected boolean confinePointerImpl(final boolean confine) {
509         if( !isOffscreenInstance ) {
510             confinePointer0(getWindowHandle(), confine);
511             return true;
512         } // else may need offscreen solution ? FIXME
513         return false;
514     }
515
516     @Override
517     protected void warpPointerImpl(final int x, final int y) {
518         if( !isOffscreenInstance ) {
519             warpPointer0(getWindowHandle(), x / getPixelScaleX(), y / getPixelScaleY());
520         } // else may need offscreen solution ? FIXME
521     }
522
523     @Override
524     protected final void doMouseEvent(final boolean enqueue, final boolean wait, final short eventType, final int modifiers,
525                                       final int x, final int y, final short button, final float[] rotationXYZ, final float rotationScale) {
526         super.doMouseEvent(enqueue, wait, eventType, modifiers, x * getPixelScaleX(), y * getPixelScaleY(), button, rotationXYZ, rotationScale);
527     }
528
529     @Override
530     public final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
531         throw new InternalError("XXX: Adapt Java Code to Native Code Changes");
532     }
533
534     @Override
535     public final void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short _keyCode, short _keySym, char keyChar) {
536         throw new InternalError("XXX: Adapt Java Code to Native Code Changes");
537     }
538
539     protected final void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short _keyCode, char keyChar, char keySymChar) {
540         // Note that we send the key char for the key code on this
541         // platform -- we do not get any useful key codes out of the system
542         final short keyCode = MacKeyUtil.validateKeyCode(_keyCode, keyChar);
543         final short keySym;
544         {
545             short _keySym = KeyEvent.NULL_CHAR != keySymChar ? KeyEvent.utf16ToVKey(keySymChar) : KeyEvent.VK_UNDEFINED;
546             keySym = KeyEvent.VK_UNDEFINED != _keySym ? _keySym : keyCode;
547         }
548         /**
549         {
550             final boolean isModifierKeyCode = KeyEvent.isModifierKey(keyCode);
551             System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+
552                                ", keyCode 0x"+Integer.toHexString(_keyCode)+" -> 0x"+Integer.toHexString(keyCode)+
553                                ", keySymChar '"+keySymChar+"', 0x"+Integer.toHexString(keySymChar)+" -> 0x"+Integer.toHexString(keySym)+
554                                ", mods "+toHexString(modifiers)+
555                                ", was: pressed "+isKeyPressed(keyCode)+", isModifierKeyCode "+isModifierKeyCode+
556                                ", nativeValid "+isNativeValid()+", isOffscreen "+isOffscreenInstance);
557         } */
558
559         // OSX delivery order is PRESSED (t0), RELEASED (t1) and TYPED (t2) -> NEWT order: PRESSED (t0) and RELEASED (t1)
560         // Auto-Repeat: OSX delivers only PRESSED, inject auto-repeat RELEASE key _before_ PRESSED
561         switch(eventType) {
562             case KeyEvent.EVENT_KEY_RELEASED:
563                 if( isKeyCodeTracked(keyCode) ) {
564                     setKeyPressed(keyCode, false);
565                 }
566                 break;
567             case KeyEvent.EVENT_KEY_PRESSED:
568                 if( isKeyCodeTracked(keyCode) ) {
569                     if( setKeyPressed(keyCode, true) ) {
570                         // key was already pressed
571                         modifiers |= InputEvent.AUTOREPEAT_MASK;
572                         super.enqueueKeyEvent(wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keySym, keyChar); // RELEASED
573                     }
574                 }
575                 break;
576         }
577         super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keySym, keyChar);
578     }
579
580     //----------------------------------------------------------------------
581     // Internals only
582     //
583
584     private void createWindow(final boolean offscreenInstance, final boolean recreate,
585                               final PointImmutable pS, final int width, final int height,
586                               final boolean fullscreen, final boolean visible, final boolean alwaysOnTop) {
587
588         final long parentWinHandle = getParentWindowHandle();
589         final long preWinHandle = getWindowHandle();
590
591         if(DEBUG_IMPLEMENTATION) {
592             System.err.println("MacWindow.createWindow on thread "+Thread.currentThread().getName()+
593                                ": offscreen "+offscreenInstance+", recreate "+recreate+
594                                ", pS "+pS+", "+width+"x"+height+", fullscreen "+fullscreen+", visible "+visible+
595                                ", alwaysOnTop "+alwaysOnTop+", preWinHandle "+toHexString(preWinHandle)+", parentWin "+toHexString(parentWinHandle)+
596                                ", surfaceHandle "+toHexString(surfaceHandle));
597             // Thread.dumpStack();
598         }
599
600         try {
601             if( 0 != preWinHandle ) {
602                 setWindowHandle(0);
603                 if( 0 == surfaceHandle ) {
604                     throw new NativeWindowException("Internal Error - create w/ window, but no Newt NSView");
605                 }
606                 OSXUtil.RunOnMainThread(false, new Runnable() {
607                     @Override
608                     public void run() {
609                         changeContentView0(parentWinHandle, preWinHandle, 0);
610                         close0( preWinHandle );
611                     } } );
612             } else {
613                 if( 0 != surfaceHandle ) {
614                     throw new NativeWindowException("Internal Error - create w/o window, but has Newt NSView");
615                 }
616                 surfaceHandle = createView0(pS.getX(), pS.getY(), width, height, fullscreen);
617                 if( 0 == surfaceHandle ) {
618                     throw new NativeWindowException("Could not create native view "+Thread.currentThread().getName()+" "+this);
619                 }
620             }
621
622             final long newWin = createWindow0( pS.getX(), pS.getY(), width, height, fullscreen,
623                                                ( isUndecorated() || offscreenInstance ) ? NSBorderlessWindowMask :
624                                                NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask,
625                                                NSBackingStoreBuffered, surfaceHandle);
626             if ( newWin == 0 ) {
627                 throw new NativeWindowException("Could not create native window "+Thread.currentThread().getName()+" "+this);
628             }
629             setWindowHandle( newWin );
630
631             final boolean isOpaque = getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance;
632             // Blocking initialization on main-thread!
633             OSXUtil.RunOnMainThread(true, new Runnable() {
634                 @Override
635                 public void run() {
636                     initWindow0( parentWinHandle, newWin, pS.getX(), pS.getY(), width, height,
637                                  isOpaque, visible && !offscreenInstance, surfaceHandle);
638                     if( offscreenInstance ) {
639                         orderOut0(0!=parentWinHandle ? parentWinHandle : newWin);
640                     } else {
641                         setTitle0(newWin, getTitle());
642                         setAlwaysOnTop0(getWindowHandle(), alwaysOnTop);
643                     }
644                 } } );
645         } catch (Exception ie) {
646             ie.printStackTrace();
647         }
648     }
649
650     protected static native boolean initIDs0();
651     private native long createView0(int x, int y, int w, int h, boolean fullscreen);
652     private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, long view);
653     /** Must be called on Main-Thread */
654     private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h,
655                                     boolean opaque, boolean visible, long view);
656     private native boolean lockSurface0(long window, long view);
657     private native boolean unlockSurface0(long window, long view);
658     /** Must be called on Main-Thread */
659     private native void requestFocus0(long window, boolean force);
660     /** Must be called on Main-Thread */
661     private native void resignFocus0(long window);
662     /** Must be called on Main-Thread. In case this is a child window and parent is still visible, orderBack(..) is issued instead of orderOut(). */
663     private native void orderOut0(long window);
664     /** Must be called on Main-Thread */
665     private native void orderFront0(long window);
666     /** Must be called on Main-Thread */
667     private native void close0(long window);
668     /** Must be called on Main-Thread */
669     private native void setTitle0(long window, String title);
670     private native long contentView0(long window);
671     /** Must be called on Main-Thread */
672     private native void changeContentView0(long parentWindowOrView, long window, long view);
673     /** Must be called on Main-Thread */
674     private native void setWindowClientTopLeftPointAndSize0(long window, int x, int y, int w, int h, boolean display);
675     /** Must be called on Main-Thread */
676     private native void setWindowClientTopLeftPoint0(long window, int x, int y, boolean display);
677     /** Must be called on Main-Thread */
678     private native void setAlwaysOnTop0(long window, boolean atop);
679     private static native Object getLocationOnScreen0(long windowHandle, int src_x, int src_y);
680     private static native void setPointerIcon0(long windowHandle, long handle);
681     private static native void setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible);
682     private static native void confinePointer0(long windowHandle, boolean confine);
683     private static native void warpPointer0(long windowHandle, int x, int y);
684
685     // Window styles
686     private static final int NSBorderlessWindowMask     = 0;
687     private static final int NSTitledWindowMask         = 1 << 0;
688     private static final int NSClosableWindowMask       = 1 << 1;
689     private static final int NSMiniaturizableWindowMask = 1 << 2;
690     private static final int NSResizableWindowMask      = 1 << 3;
691
692     // Window backing store types
693     private static final int NSBackingStoreRetained     = 0;
694     private static final int NSBackingStoreNonretained  = 1;
695     private static final int NSBackingStoreBuffered     = 2;
696
697     private volatile long surfaceHandle = 0;
698     private long sscSurfaceHandle = 0;
699     private boolean isOffscreenInstance = false;
700
701 }
http://JogAmp.org git info: FAQ, tutorial and man pages.