From: <ma...@us...> - 2012-11-01 20:54:28
|
Revision: 3806 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3806&view=rev Author: matzon Date: 2012-11-01 20:54:17 +0000 (Thu, 01 Nov 2012) Log Message: ----------- Comitting EmuMogs 28008537/src.zip drop to branch Modified Paths: -------------- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/Display.java branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXCanvasPeerInfo.java branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXContextImplementation.java branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXDisplay.java branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXMouseEventQueue.java branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MouseEventQueue.java branches/osx-java7/LWJGL/src/native/macosx/context.h branches/osx-java7/LWJGL/src/native/macosx/context.m branches/osx-java7/LWJGL/src/native/macosx/org_lwjgl_opengl_Display.m branches/osx-java7/LWJGL/src/native/macosx/org_lwjgl_opengl_MacOSXCanvasPeerInfo.m branches/osx-java7/LWJGL/src/native/macosx/org_lwjgl_opengl_MacOSXContextImplementation.m branches/osx-java7/LWJGL/src/native/macosx/org_lwjgl_opengl_MacOSXPbufferPeerInfo.m Added Paths: ----------- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXNativeKeyboard.java branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXNativeMouse.java branches/osx-java7/LWJGL/src/native/macosx/org_lwjgl_opengl_MacOSXNativeKeyboard.m branches/osx-java7/LWJGL/src/native/macosx/org_lwjgl_opengl_MacOSXNativeMouse.m Modified: branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/Display.java =================================================================== --- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/Display.java 2012-11-01 20:36:45 UTC (rev 3805) +++ branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/Display.java 2012-11-01 20:54:17 UTC (rev 3806) @@ -242,7 +242,7 @@ try { if ( was_fullscreen && !isFullscreen() ) display_impl.resetDisplayMode(); - else if ( isFullscreen() ) + else if ( isFullscreen() ) switchDisplayMode(); createWindow(); makeCurrentAndSetSwapInterval(); Modified: branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXCanvasPeerInfo.java =================================================================== --- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXCanvasPeerInfo.java 2012-11-01 20:36:45 UTC (rev 3805) +++ branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXCanvasPeerInfo.java 2012-11-01 20:54:17 UTC (rev 3806) @@ -44,21 +44,15 @@ * $Id$ */ abstract class MacOSXCanvasPeerInfo extends MacOSXPeerInfo { - private final AWTSurfaceLock awt_surface = new AWTSurfaceLock(); - protected MacOSXCanvasPeerInfo(PixelFormat pixel_format, ContextAttribs attribs, boolean support_pbuffer) throws LWJGLException { super(pixel_format, attribs, true, true, support_pbuffer, true); } protected void initHandle(Canvas component) throws LWJGLException { - // Allow the use of a Core Animation Layer only when using non fullscreen Display.setParent() or AWTGLCanvas - final boolean allowCALayer = ((Display.getParent() != null && !Display.isFullscreen()) || component instanceof AWTGLCanvas) && awt_surface.isApplet(component) && LWJGLUtil.isMacOSXEqualsOrBetterThan(10, 6); - - nInitHandle(awt_surface.lockAndGetHandle(component), getHandle(), allowCALayer); + nInitHandle(getHandle()); } - private static native void nInitHandle(ByteBuffer surface_buffer, ByteBuffer peer_info_handle, boolean allowCALayer) throws LWJGLException; + private static native void nInitHandle(ByteBuffer peer_info_handle) throws LWJGLException; protected void doUnlock() throws LWJGLException { - awt_surface.unlock(); } } Modified: branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXContextImplementation.java =================================================================== --- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXContextImplementation.java 2012-11-01 20:36:45 UTC (rev 3805) +++ branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXContextImplementation.java 2012-11-01 20:54:17 UTC (rev 3806) @@ -90,7 +90,7 @@ try { synchronized ( context ) { clearDrawable(context.getHandle()); - setView(peer_handle, context.getHandle()); + setView(peer_handle); } } finally { peer_info.unlock(); @@ -100,14 +100,14 @@ public void makeCurrent(PeerInfo peer_info, ByteBuffer handle) throws LWJGLException { ByteBuffer peer_handle = peer_info.lockAndGetHandle(); try { - setView(peer_handle, handle); + setView(peer_handle); nMakeCurrent(handle); } finally { peer_info.unlock(); } } - private static native void setView(ByteBuffer peer_handle, ByteBuffer context_handle) throws LWJGLException; + private static native void setView(ByteBuffer peer_handle) throws LWJGLException; private static native void nMakeCurrent(ByteBuffer context_handle) throws LWJGLException; Modified: branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXDisplay.java =================================================================== --- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXDisplay.java 2012-11-01 20:36:45 UTC (rev 3805) +++ branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXDisplay.java 2012-11-01 20:54:17 UTC (rev 3806) @@ -40,6 +40,8 @@ import java.awt.Canvas; import java.awt.Cursor; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.Robot; import java.nio.ByteBuffer; import java.nio.FloatBuffer; @@ -51,6 +53,7 @@ import java.util.List; import org.lwjgl.BufferUtils; +import org.lwjgl.MemoryUtil; import org.lwjgl.LWJGLException; import org.lwjgl.LWJGLUtil; @@ -65,14 +68,25 @@ private static final int GAMMA_LENGTH = 256; private MacOSXCanvasListener canvas_listener; - private MacOSXFrame frame; private Canvas canvas; private Robot robot; private MacOSXMouseEventQueue mouse_queue; private KeyboardEventQueue keyboard_queue; private java.awt.DisplayMode requested_mode; + + /* Members for native window use */ + private MacOSXNativeMouse mouse; + private MacOSXNativeKeyboard keyboard; + private ByteBuffer window; + private ByteBuffer context; + private int x; + private int y; + private int width; + private int height; + + /* Whether we're using a native window or an AWT canvas */ + private boolean native_mode; - /* States */ private boolean close_requested; MacOSXDisplay() { @@ -96,49 +110,65 @@ } } - public void createWindow(final DrawableLWJGL drawable, DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException { + private native ByteBuffer nCreateWindow(int x, int y, int width, int height, boolean fullscreen, boolean undecorated, ByteBuffer peer_info_handle, ByteBuffer window_handle) throws LWJGLException; + + private native boolean nIsMiniaturized(ByteBuffer window_handle); + + private native boolean nIsFocused(ByteBuffer window_handle); + + private native void nSetResizable(ByteBuffer window_handle, boolean resizable); + + private native void nResizeWindow(ByteBuffer window_handle, int x, int y, int width, int height); + + private native boolean nWasResized(ByteBuffer window_handle); + + private static boolean isUndecorated() { + return Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated"); + } + + public void createWindow(final DrawableLWJGL drawable, DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException { boolean fullscreen = Display.isFullscreen(); hideUI(fullscreen); close_requested = false; + + DrawableGL gl_drawable = (DrawableGL)Display.getDrawable(); + PeerInfo peer_info = gl_drawable.peer_info; + ByteBuffer peer_handle = peer_info.lockAndGetHandle(); try { - if (parent == null) { - frame = new MacOSXFrame(mode, requested_mode, fullscreen, x, y); - canvas = frame.getCanvas(); - } else { - frame = null; - canvas = parent; - } - canvas_listener = new MacOSXCanvasListener(canvas); - robot = AWTUtil.createRobot(canvas); + window = nCreateWindow(x, y, mode.getWidth(), mode.getHeight(), + fullscreen, isUndecorated(), + peer_handle, window); + native_mode = true; + this.x = x; + this.y = y; + this.width = mode.getWidth(); + this.height = mode.getHeight(); + this.canvas = parent; } catch (LWJGLException e) { destroyWindow(); throw e; - } + } finally { + peer_info.unlock(); + } } - private void doHandleQuit() { + public void doHandleQuit() { synchronized (this) { close_requested = true; } } + public native void nDestroyWindow(ByteBuffer window_handle); + public void destroyWindow() { - if (canvas_listener != null) { - canvas_listener.disableListeners(); - canvas_listener = null; - } - if (frame != null) { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - if (MacOSXFrame.getDevice().getFullScreenWindow() == frame) - MacOSXFrame.getDevice().setFullScreenWindow(null); - return null; - } - }); - if (frame.isDisplayable()) - frame.dispose(); - frame = null; - } + if (native_mode) { + nDestroyWindow(window); + } else { + if (canvas_listener != null) { + canvas_listener.disableListeners(); + canvas_listener = null; + } + } hideUI(false); } @@ -162,7 +192,7 @@ } public void switchDisplayMode(DisplayMode mode) throws LWJGLException { - java.awt.DisplayMode[] awt_modes = MacOSXFrame.getDevice().getDisplayModes(); + java.awt.DisplayMode[] awt_modes = getDevice().getDisplayModes(); for ( java.awt.DisplayMode awt_mode : awt_modes ) { if (equals(awt_mode, mode)) { requested_mode = awt_mode; @@ -172,9 +202,17 @@ throw new LWJGLException(mode + " is not supported"); } + private static GraphicsDevice getDevice() { + GraphicsEnvironment g_env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice device = g_env.getDefaultScreenDevice(); + return device; + } + public void resetDisplayMode() { - if (MacOSXFrame.getDevice().getFullScreenWindow() != null) - MacOSXFrame.getDevice().setFullScreenWindow(null); + if (!native_mode) { + if (getDevice().getFullScreenWindow() != null) + getDevice().setFullScreenWindow(null); + } requested_mode = null; restoreGamma(); } @@ -198,11 +236,11 @@ } public DisplayMode init() throws LWJGLException { - return createLWJGLDisplayMode(MacOSXFrame.getDevice().getDisplayMode()); + return createLWJGLDisplayMode(getDevice().getDisplayMode()); } public DisplayMode[] getAvailableDisplayModes() throws LWJGLException { - java.awt.DisplayMode[] awt_modes = MacOSXFrame.getDevice().getDisplayModes(); + java.awt.DisplayMode[] awt_modes = getDevice().getDisplayModes(); List<DisplayMode> modes = new ArrayList<DisplayMode>(); for ( java.awt.DisplayMode awt_mode : awt_modes ) if ( awt_mode.getBitDepth() >= 16 ) @@ -210,26 +248,33 @@ return modes.toArray(new DisplayMode[modes.size()]); } + private native void nSetTitle(ByteBuffer window_handle, ByteBuffer title_buffer); + public void setTitle(String title) { - if (frame != null) - frame.setTitle(title); + ByteBuffer buffer = MemoryUtil.encodeUTF8(title); + nSetTitle(window, buffer); } public boolean isCloseRequested() { boolean result; synchronized (this) { - result = close_requested || (frame != null && frame.syncIsCloseRequested()); + result = close_requested; close_requested = false; } return result; } public boolean isVisible() { - return frame == null || frame.syncIsVisible(); + return true; } public boolean isActive() { - return canvas.isFocusOwner(); + if (native_mode) { + boolean ret = nIsFocused(window); + return ret; + } else { + return canvas.isFocusOwner(); + } } public Canvas getCanvas() { @@ -237,7 +282,7 @@ } public boolean isDirty() { - return frame != null && frame.getCanvas().syncIsDirty(); + return false; } public PeerInfo createPeerInfo(PixelFormat pixel_format, ContextAttribs attribs) throws LWJGLException { @@ -250,7 +295,10 @@ private static final IntBuffer current_viewport = BufferUtils.createIntBuffer(16); public void update() { - boolean should_update = canvas_listener.syncShouldUpdateContext(); + boolean should_update = true; + if (!native_mode) { + should_update = canvas_listener.syncShouldUpdateContext(); + } /* * Workaround for the "white screen in fullscreen mode" problem * @@ -273,46 +321,38 @@ * - elias */ DrawableGL drawable = (DrawableGL)Display.getDrawable(); - if (Display.isFullscreen() && (frame != null && frame.getCanvas().syncCanvasPainted() || should_update)) { - try { - MacOSXContextImplementation.resetView(drawable.peer_info, drawable.context); - } catch (LWJGLException e) { - LWJGLUtil.log("Failed to reset context: " + e); - } - } if (should_update) { drawable.context.update(); /* This is necessary to make sure the context won't "forget" about the view size */ glGetInteger(GL_VIEWPORT, current_viewport); glViewport(current_viewport.get(0), current_viewport.get(1), current_viewport.get(2), current_viewport.get(3)); } + /* if (frame != null && mouse_queue != null) { if (frame.syncShouldReleaseCursor()) MacOSXMouseEventQueue.nGrabMouse(false); if (frame.syncShouldWarpCursor()) mouse_queue.warpCursor(); } + */ } /** - * This is an interface to the native Carbon call - * SetSystemUIMode. It is used to hide the dock in a way - * that will prevent AWT from shifting the fullscreen window - * - * The workaround is not necessary on 10.4, and since 10.4 shows - * instability problems calling SetSystemUIMode, we'll only call it - * when the OS version is 10.3 or lower. + * This is an interface to the native Cocoa function, + * NSWindow:setStyleMask. It is used to set the window's border to + * undecorated. */ private void hideUI(boolean hide) { - if (!LWJGLUtil.isMacOSXEqualsOrBetterThan(10, 4)) - nHideUI(hide); + //if (!LWJGLUtil.isMacOSXEqualsOrBetterThan(10, 4)) + nHideUI(window, hide); } - private native void nHideUI(boolean hide); + private native void nHideUI(ByteBuffer window_handle, boolean hide); public void reshape(int x, int y, int width, int height) { - if (frame != null) - frame.resize(x, y, width, height); + //if (native_mode) { + // nResizeWindow(window, x, y, width, height); + //} } /* Mouse */ @@ -325,28 +365,52 @@ } public void createMouse() throws LWJGLException { - this.mouse_queue = new MacOSXMouseEventQueue(canvas); - mouse_queue.register(); + if (native_mode) { + mouse = new MacOSXNativeMouse(this, window); + mouse.register(); + } else { + mouse_queue = new MacOSXMouseEventQueue(canvas); + mouse_queue.register(); + } } public void destroyMouse() { - if (mouse_queue != null) { - MacOSXMouseEventQueue.nGrabMouse(false); - mouse_queue.unregister(); - } - this.mouse_queue = null; + MacOSXMouseEventQueue.nGrabMouse(false); + if (native_mode) { + if (mouse != null) { + mouse.unregister(); + } + mouse = null; + } else { + if (mouse_queue != null) { + mouse_queue.unregister(); + } + mouse_queue = null; + } } public void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons_buffer) { - mouse_queue.poll(coord_buffer, buttons_buffer); + if (native_mode) { + mouse.poll(coord_buffer, buttons_buffer); + } else { + mouse_queue.poll(coord_buffer, buttons_buffer); + } } public void readMouse(ByteBuffer buffer) { - mouse_queue.copyEvents(buffer); + if (native_mode) { + mouse.copyEvents(buffer); + } else { + mouse_queue.copyEvents(buffer); + } } public void grabMouse(boolean grab) { - mouse_queue.setGrabbed(grab); + if (native_mode) { + mouse.setGrabbed(grab); + } else { + mouse_queue.setGrabbed(grab); + } } public int getNativeCursorCapabilities() { @@ -354,13 +418,10 @@ } public void setCursorPosition(int x, int y) { - AWTUtil.setCursorPosition(canvas, robot, x, y); + MacOSXMouseEventQueue.nWarpCursor(x, y); } public void setNativeCursor(Object handle) throws LWJGLException { - Cursor awt_cursor = (Cursor)handle; - if (frame != null) - frame.setCursor(awt_cursor); } public int getMinCursorSize() { @@ -373,48 +434,43 @@ /* Keyboard */ public void createKeyboard() throws LWJGLException { - this.keyboard_queue = new KeyboardEventQueue(canvas); - keyboard_queue.register(); + if (native_mode) { + this.keyboard = new MacOSXNativeKeyboard(window); + keyboard.register(); + } else { + this.keyboard_queue = new KeyboardEventQueue(canvas); + keyboard_queue.register(); + } } public void destroyKeyboard() { - if (keyboard_queue != null) - keyboard_queue.unregister(); - this.keyboard_queue = null; + if (native_mode) { + if (keyboard != null) + keyboard.unregister(); + keyboard = null; + } else { + if (keyboard_queue != null) + keyboard_queue.unregister(); + keyboard_queue = null; + } } public void pollKeyboard(ByteBuffer keyDownBuffer) { - keyboard_queue.poll(keyDownBuffer); + if (native_mode) { + keyboard.poll(keyDownBuffer); + } else { + keyboard_queue.poll(keyDownBuffer); + } } public void readKeyboard(ByteBuffer buffer) { - keyboard_queue.copyEvents(buffer); + if (native_mode) { + keyboard.copyEvents(buffer); + } else { + keyboard_queue.copyEvents(buffer); + } } -/* public int isStateKeySet(int key) { - int awt_key; - switch (key) { - case Keyboard.KEY_CAPITAL: - awt_key = KeyEvent.VK_CAPS_LOCK; - break; - case Keyboard.KEY_NUMLOCK: - awt_key = KeyEvent.VK_NUM_LOCK; - break; - case Keyboard.KEY_SYSRQ: - awt_key = KeyEvent.VK_SCROLL_LOCK; - break; - default: - return Keyboard.STATE_UNKNOWN; - } - try { - boolean state = Toolkit.getDefaultToolkit().getLockingKeyState(awt_key); - return state ? Keyboard.STATE_ON : Keyboard.STATE_OFF; - } catch (Exception e) { - LWJGLUtil.log("Failed to query key state: " + e); - return Keyboard.STATE_UNKNOWN; - } - } -*/ /** Native cursor handles */ public Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException { return AWTUtil.createCursor(width, height, xHotspot, yHotspot, numImages, images, delays); @@ -497,19 +553,19 @@ } public int getX() { - return frame.getX(); + return x; } public int getY() { - return frame.getY(); + return y; } public int getWidth() { - return frame.getWidth(); + return width; } public int getHeight() { - return frame.getHeight(); + return height; } public boolean isInsideWindow() { @@ -517,11 +573,17 @@ } public void setResizable(boolean resizable) { - frame.setResizable(resizable); + if (native_mode) { + nSetResizable(window, resizable); + } } public boolean wasResized() { - return canvas_listener.wasResized(); + if (native_mode) { + return nWasResized(window); + } else { + return canvas_listener.wasResized(); + } } } Modified: branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXMouseEventQueue.java =================================================================== --- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXMouseEventQueue.java 2012-11-01 20:36:45 UTC (rev 3805) +++ branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXMouseEventQueue.java 2012-11-01 20:54:17 UTC (rev 3806) @@ -44,13 +44,13 @@ import org.lwjgl.BufferUtils; final class MacOSXMouseEventQueue extends MouseEventQueue { - private final IntBuffer delta_buffer = BufferUtils.createIntBuffer(2); - - private boolean skip_event; - private static boolean is_grabbed; + private IntBuffer delta_buffer = BufferUtils.createIntBuffer(2); + + private boolean skip_event; + private static boolean is_grabbed; MacOSXMouseEventQueue(Component component) { - super(component); + super(component); } public void setGrabbed(boolean grab) { @@ -96,18 +96,11 @@ // If we're going to warp the cursor position, we'll skip the next event to avoid bogus delta values skip_event = isGrabbed(); } -/* if (isGrabbed()) { - Rectangle bounds = getComponent().getBounds(); - Point location_on_screen = getComponent().getLocationOnScreen(); - int x = location_on_screen.x + bounds.width/2; - int y = location_on_screen.y + bounds.height/2; - nWarpCursor(x, y); - }*/ } private static native void getMouseDeltas(IntBuffer delta_buffer); - private static native void nWarpCursor(int x, int y); + public static native void nWarpCursor(int x, int y); - static native void nGrabMouse(boolean grab); + public static native void nGrabMouse(boolean grab); } Added: branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXNativeKeyboard.java =================================================================== --- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXNativeKeyboard.java (rev 0) +++ branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXNativeKeyboard.java 2012-11-01 20:54:17 UTC (rev 3806) @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * An AWT implementation of a LWJGL compatible Keyboard event queue. + * @author elias_naur + */ + +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.util.HashMap; +import java.awt.Component; +import java.nio.ByteBuffer; + +import org.lwjgl.input.Keyboard; + +final class MacOSXNativeKeyboard extends EventQueue { + private final byte[] key_states = new byte[Keyboard.KEYBOARD_SIZE]; + + /** Event scratch array */ + private final ByteBuffer event = ByteBuffer.allocate(Keyboard.EVENT_SIZE); + + private ByteBuffer window_handle; + + private boolean has_deferred_event; + private long deferred_nanos; + private int deferred_key_code; + private byte deferred_key_state; + private int deferred_character; + + private HashMap<Short, Integer> nativeToLwjglMap; + + MacOSXNativeKeyboard(ByteBuffer window_handle) { + super(Keyboard.EVENT_SIZE); + nativeToLwjglMap = new HashMap<Short, Integer>(); + initKeyboardMappings(); + this.window_handle = window_handle; + } + + private native void nRegisterKeyListener(ByteBuffer window_handle); + + private native void nUnregisterKeyListener(ByteBuffer window_handle); + + private void initKeyboardMappings() { + nativeToLwjglMap.put((Short)(short)0x1D, Keyboard.KEY_0); + nativeToLwjglMap.put((Short)(short)0x12, Keyboard.KEY_1); + nativeToLwjglMap.put((Short)(short)0x13, Keyboard.KEY_2); + nativeToLwjglMap.put((Short)(short)0x14, Keyboard.KEY_3); + nativeToLwjglMap.put((Short)(short)0x15, Keyboard.KEY_4); + nativeToLwjglMap.put((Short)(short)0x17, Keyboard.KEY_5); + nativeToLwjglMap.put((Short)(short)0x16, Keyboard.KEY_6); + nativeToLwjglMap.put((Short)(short)0x1A, Keyboard.KEY_7); + nativeToLwjglMap.put((Short)(short)0x1C, Keyboard.KEY_8); + nativeToLwjglMap.put((Short)(short)0x19, Keyboard.KEY_9); + nativeToLwjglMap.put((Short)(short)0x00, Keyboard.KEY_A); + nativeToLwjglMap.put((Short)(short)0x0B, Keyboard.KEY_B); + nativeToLwjglMap.put((Short)(short)0x08, Keyboard.KEY_C); + nativeToLwjglMap.put((Short)(short)0x02, Keyboard.KEY_D); + nativeToLwjglMap.put((Short)(short)0x0E, Keyboard.KEY_E); + nativeToLwjglMap.put((Short)(short)0x03, Keyboard.KEY_F); + nativeToLwjglMap.put((Short)(short)0x05, Keyboard.KEY_G); + nativeToLwjglMap.put((Short)(short)0x04, Keyboard.KEY_H); + nativeToLwjglMap.put((Short)(short)0x22, Keyboard.KEY_I); + nativeToLwjglMap.put((Short)(short)0x26, Keyboard.KEY_J); + nativeToLwjglMap.put((Short)(short)0x28, Keyboard.KEY_K); + nativeToLwjglMap.put((Short)(short)0x25, Keyboard.KEY_L); + nativeToLwjglMap.put((Short)(short)0x2E, Keyboard.KEY_M); + nativeToLwjglMap.put((Short)(short)0x2D, Keyboard.KEY_N); + nativeToLwjglMap.put((Short)(short)0x1F, Keyboard.KEY_O); + nativeToLwjglMap.put((Short)(short)0x23, Keyboard.KEY_P); + nativeToLwjglMap.put((Short)(short)0x0C, Keyboard.KEY_Q); + nativeToLwjglMap.put((Short)(short)0x0F, Keyboard.KEY_R); + nativeToLwjglMap.put((Short)(short)0x01, Keyboard.KEY_S); + nativeToLwjglMap.put((Short)(short)0x11, Keyboard.KEY_T); + nativeToLwjglMap.put((Short)(short)0x20, Keyboard.KEY_U); + nativeToLwjglMap.put((Short)(short)0x09, Keyboard.KEY_V); + nativeToLwjglMap.put((Short)(short)0x0D, Keyboard.KEY_W); + nativeToLwjglMap.put((Short)(short)0x07, Keyboard.KEY_X); + nativeToLwjglMap.put((Short)(short)0x10, Keyboard.KEY_Y); + nativeToLwjglMap.put((Short)(short)0x06, Keyboard.KEY_Z); + nativeToLwjglMap.put((Short)(short)0x2B, Keyboard.KEY_COMMA); + nativeToLwjglMap.put((Short)(short)0x2C, Keyboard.KEY_SLASH); + nativeToLwjglMap.put((Short)(short)0x2F, Keyboard.KEY_PERIOD); + nativeToLwjglMap.put((Short)(short)0x32, Keyboard.KEY_CIRCUMFLEX); + nativeToLwjglMap.put((Short)(short)0x29, Keyboard.KEY_SEMICOLON); + nativeToLwjglMap.put((Short)(short)0x129, Keyboard.KEY_COLON); + nativeToLwjglMap.put((Short)(short)0x2A, Keyboard.KEY_BACKSLASH); + nativeToLwjglMap.put((Short)(short)0x52, Keyboard.KEY_NUMPAD0); + nativeToLwjglMap.put((Short)(short)0x53, Keyboard.KEY_NUMPAD1); + nativeToLwjglMap.put((Short)(short)0x54, Keyboard.KEY_NUMPAD2); + nativeToLwjglMap.put((Short)(short)0x55, Keyboard.KEY_NUMPAD3); + nativeToLwjglMap.put((Short)(short)0x56, Keyboard.KEY_NUMPAD4); + nativeToLwjglMap.put((Short)(short)0x57, Keyboard.KEY_NUMPAD5); + nativeToLwjglMap.put((Short)(short)0x58, Keyboard.KEY_NUMPAD6); + nativeToLwjglMap.put((Short)(short)0x59, Keyboard.KEY_NUMPAD7); + nativeToLwjglMap.put((Short)(short)0x5B, Keyboard.KEY_NUMPAD8); + nativeToLwjglMap.put((Short)(short)0x5C, Keyboard.KEY_NUMPAD9); + nativeToLwjglMap.put((Short)(short)0x7A, Keyboard.KEY_F1); + nativeToLwjglMap.put((Short)(short)0x78, Keyboard.KEY_F2); + nativeToLwjglMap.put((Short)(short)0x63, Keyboard.KEY_F3); + nativeToLwjglMap.put((Short)(short)0x76, Keyboard.KEY_F4); + nativeToLwjglMap.put((Short)(short)0x60, Keyboard.KEY_F5); + nativeToLwjglMap.put((Short)(short)0x61, Keyboard.KEY_F6); + nativeToLwjglMap.put((Short)(short)0x62, Keyboard.KEY_F7); + nativeToLwjglMap.put((Short)(short)0x64, Keyboard.KEY_F8); + nativeToLwjglMap.put((Short)(short)0x65, Keyboard.KEY_F9); + nativeToLwjglMap.put((Short)(short)0x6D, Keyboard.KEY_F10); + nativeToLwjglMap.put((Short)(short)0x67, Keyboard.KEY_F11); + nativeToLwjglMap.put((Short)(short)0x6F, Keyboard.KEY_F12); + nativeToLwjglMap.put((Short)(short)0x69, Keyboard.KEY_F13); + nativeToLwjglMap.put((Short)(short)0x6B, Keyboard.KEY_F14); + nativeToLwjglMap.put((Short)(short)0x71, Keyboard.KEY_F15); + nativeToLwjglMap.put((Short)(short)0x72, Keyboard.KEY_HOME); + nativeToLwjglMap.put((Short)(short)0x18, Keyboard.KEY_EQUALS); + nativeToLwjglMap.put((Short)(short)0x7B, Keyboard.KEY_LEFT); + nativeToLwjglMap.put((Short)(short)0x7C, Keyboard.KEY_RIGHT); + nativeToLwjglMap.put((Short)(short)0x7E, Keyboard.KEY_UP); + nativeToLwjglMap.put((Short)(short)0x7D, Keyboard.KEY_DOWN); + nativeToLwjglMap.put((Short)(short)0x31, Keyboard.KEY_SPACE); + nativeToLwjglMap.put((Short)(short)0x30, Keyboard.KEY_TAB); + nativeToLwjglMap.put((Short)(short)0x35, Keyboard.KEY_ESCAPE); + nativeToLwjglMap.put((Short)(short)0x74, Keyboard.KEY_PRIOR); + nativeToLwjglMap.put((Short)(short)0x79, Keyboard.KEY_NEXT); + nativeToLwjglMap.put((Short)(short)0x41, Keyboard.KEY_DECIMAL); + nativeToLwjglMap.put((Short)(short)0x43, Keyboard.KEY_MULTIPLY); + nativeToLwjglMap.put((Short)(short)0x45, Keyboard.KEY_ADD); + nativeToLwjglMap.put((Short)(short)0x4B, Keyboard.KEY_DIVIDE); + nativeToLwjglMap.put((Short)(short)0x1B, Keyboard.KEY_MINUS); + nativeToLwjglMap.put((Short)(short)0x4E, Keyboard.KEY_SUBTRACT); + nativeToLwjglMap.put((Short)(short)0x1E, Keyboard.KEY_RBRACKET); + nativeToLwjglMap.put((Short)(short)0x21, Keyboard.KEY_LBRACKET); + nativeToLwjglMap.put((Short)(short)0x33, Keyboard.KEY_BACK); + nativeToLwjglMap.put((Short)(short)0x24, Keyboard.KEY_RETURN); + nativeToLwjglMap.put((Short)(short)0xF0, Keyboard.KEY_CAPITAL); + nativeToLwjglMap.put((Short)(short)0x39, Keyboard.KEY_CAPITAL); + nativeToLwjglMap.put((Short)(short)0xF1, Keyboard.KEY_LSHIFT); + nativeToLwjglMap.put((Short)(short)0x38, Keyboard.KEY_LSHIFT); + nativeToLwjglMap.put((Short)(short)0x3C, Keyboard.KEY_RSHIFT); + nativeToLwjglMap.put((Short)(short)0xF2, Keyboard.KEY_LCONTROL); + nativeToLwjglMap.put((Short)(short)0xF3, Keyboard.KEY_LMENU); + nativeToLwjglMap.put((Short)(short)0x3A, Keyboard.KEY_LMENU); + nativeToLwjglMap.put((Short)(short)0x3D, Keyboard.KEY_RMENU); + nativeToLwjglMap.put((Short)(short)0xF4, Keyboard.KEY_RETURN); + nativeToLwjglMap.put((Short)(short)0xF5, Keyboard.KEY_NUMLOCK); + nativeToLwjglMap.put((Short)(short)0x27, Keyboard.KEY_APOSTROPHE); + + /*KEY_MAP[KeyEvent.VK_ALT_GRAPH] = Keyboard.KEY_RMENU; + KEY_MAP[KeyEvent.VK_AT] = Keyboard.KEY_AT; + KEY_MAP[KeyEvent.VK_BACK_SPACE] = Keyboard.KEY_BACK; + KEY_MAP[KeyEvent.VK_CAPS_LOCK] = Keyboard.KEY_CAPITAL; + KEY_MAP[KeyEvent.VK_COLON] = Keyboard.KEY_COLON; + KEY_MAP[KeyEvent.VK_CONVERT] = Keyboard.KEY_CONVERT; + KEY_MAP[KeyEvent.VK_END] = Keyboard.KEY_END; + KEY_MAP[KeyEvent.VK_INSERT] = Keyboard.KEY_INSERT; + KEY_MAP[KeyEvent.VK_KANA] = Keyboard.KEY_KANA; + KEY_MAP[KeyEvent.VK_KANJI] = Keyboard.KEY_KANJI; + KEY_MAP[KeyEvent.VK_NUM_LOCK] = Keyboard.KEY_NUMLOCK; + KEY_MAP[KeyEvent.VK_PAUSE] = Keyboard.KEY_PAUSE; + KEY_MAP[KeyEvent.VK_SCROLL_LOCK] = Keyboard.KEY_SCROLL; + KEY_MAP[KeyEvent.VK_SEPARATOR] = Keyboard.KEY_DECIMAL; + KEY_MAP[KeyEvent.VK_STOP] = Keyboard.KEY_STOP;*/ + } + + public void register() { + nRegisterKeyListener(window_handle); + } + + public void unregister() { + nUnregisterKeyListener(window_handle); + } + + public void putKeyboardEvent(int key_code, byte state, int character, long nanos, boolean repeat) { + event.clear(); + event.putInt(key_code).put(state).putInt(character).putLong(nanos).put(repeat ? (byte)1 : (byte)0); + event.flip(); + putEvent(event); + } + + public synchronized void poll(ByteBuffer key_down_buffer) { + flushDeferredEvent(); + int old_position = key_down_buffer.position(); + key_down_buffer.put(key_states); + key_down_buffer.position(old_position); + } + + public synchronized void copyEvents(ByteBuffer dest) { + flushDeferredEvent(); + super.copyEvents(dest); + } + + private synchronized void handleKey(int key_code, byte state, int character, long nanos) { + if (character == KeyEvent.CHAR_UNDEFINED) + character = Keyboard.CHAR_NONE; + if (state == 1) { + boolean repeat = false; + if (has_deferred_event) { + if ((nanos == deferred_nanos && deferred_key_code == key_code)) { + has_deferred_event = false; + repeat = true; // Repeat event + } else + flushDeferredEvent(); + } + putKeyEvent(key_code, state, character, nanos, repeat); + } else { + flushDeferredEvent(); + has_deferred_event = true; + deferred_nanos = nanos; + deferred_key_code = key_code; + deferred_key_state = state; + deferred_character = character; + } + } + + private void flushDeferredEvent() { + if (has_deferred_event) { + putKeyEvent(deferred_key_code, deferred_key_state, deferred_character, deferred_nanos, false); + has_deferred_event = false; + } + } + + public void putKeyEvent(int key_code, byte state, int character, long nanos, boolean repeat) { + /* Ignore repeating presses */ + int mapped_code = getMappedKeyCode((short)key_code); + if (mapped_code < 0) { + System.out.println("Unrecognized keycode: " + key_code); + /* Unrecognized / unmapped code, do nothing */ + return; + } + if ( key_states[mapped_code] == state ) + repeat = true; + key_states[mapped_code] = state; + int key_int_char = character & 0xffff; + putKeyboardEvent(mapped_code, state, key_int_char, nanos, repeat); + } + + private int getMappedKeyCode(short key_code) { + if (nativeToLwjglMap.containsKey(key_code)) { + return nativeToLwjglMap.get(key_code); + } + return -1; + } + + public void keyPressed(int key_code, int character, long nanos) { + handleKey(key_code, (byte)1, character, nanos); + } + + public void keyReleased(int key_code, int character, long nanos) { + handleKey(key_code, (byte)0, character, nanos); + } + + public void keyTyped(KeyEvent e) { + } +} Added: branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXNativeMouse.java =================================================================== --- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXNativeMouse.java (rev 0) +++ branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MacOSXNativeMouse.java 2012-11-01 20:54:17 UTC (rev 3806) @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * A Cocoa implementation of a LWJGL compatible Mouse. + * @author mojang + */ + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.input.Mouse; + +import java.lang.reflect.*; +import java.lang.Integer; +import java.lang.Long; + +import org.lwjgl.BufferUtils; + +final class MacOSXNativeMouse extends EventQueue { + private static final int WHEEL_SCALE = 120; + private static final int NUM_BUTTONS = 3; + + private ByteBuffer window_handle; + private MacOSXDisplay display; + + private boolean grabbed; + + /** The accumulated mouse deltas returned by poll() */ + private float accum_dx; + private float accum_dy; + private int accum_dz; + + /** The last mouse position */ + private float last_x; + private float last_y; + + /** Saved control key state for ctrl-click right button emulation */ + private boolean saved_control_state; + + private final ByteBuffer event = ByteBuffer.allocate(Mouse.EVENT_SIZE); + private IntBuffer delta_buffer = BufferUtils.createIntBuffer(2); + private int skip_event; + + private final byte[] buttons = new byte[NUM_BUTTONS]; + + MacOSXNativeMouse(MacOSXDisplay display, ByteBuffer window_handle) { + super(Mouse.EVENT_SIZE); + this.display = display; + this.window_handle = window_handle; + } + + private native void nWarpCursor(ByteBuffer window_handle, int x, int y); + + public static native void nGrabMouse(boolean grab); + + private native void nRegisterMouseListener(ByteBuffer window_handle); + + private native void nUnregisterMouseListener(ByteBuffer window_handle); + + public synchronized void register() { + nRegisterMouseListener(window_handle); + } + + public synchronized void unregister() { + nUnregisterMouseListener(window_handle); + } + + public synchronized void setGrabbed(boolean grabbed) { + this.grabbed = grabbed; + nGrabMouse(grabbed); + skip_event = 1; + accum_dx = accum_dy = 0; + } + + public synchronized boolean isGrabbed() { + return grabbed; + } + + protected void resetCursorToCenter() { + clearEvents(); + accum_dx = accum_dy = 0; + if (display != null) { + last_x = display.getWidth() / 2; + last_y = display.getHeight() / 2; + } + } + + private void putMouseEvent(byte button, byte state, int dz, long nanos) { + if (grabbed) + putMouseEventWithCoords(button, state, 0, 0, dz, nanos); + else + putMouseEventWithCoords(button, state, (int)last_x, (int)last_y, dz, nanos); + } + + protected void putMouseEventWithCoords(byte button, byte state, int coord1, int coord2, int dz, long nanos) { + event.clear(); + event.put(button).put(state).putInt(coord1).putInt(coord2).putInt(dz).putLong(nanos); + event.flip(); + putEvent(event); + } + + public synchronized void poll(IntBuffer coord_buffer, ByteBuffer buttons_buffer) { + if (grabbed) { + coord_buffer.put(0, (int)accum_dx); + coord_buffer.put(1, (int)accum_dy); + } else { + coord_buffer.put(0, (int)last_x); + coord_buffer.put(1, (int)last_y); + } + coord_buffer.put(2, accum_dz); + accum_dx = accum_dy = accum_dz = 0; + int old_position = buttons_buffer.position(); + buttons_buffer.put(buttons, 0, buttons.length); + buttons_buffer.position(old_position); + } + + private void setCursorPos(float x, float y, long nanos) { + if ( grabbed ) + return; + float dx = x - last_x; + float dy = y - last_y; + addDelta(dx, dy); + last_x = x; + last_y = y; + putMouseEventWithCoords((byte)-1, (byte)0, (int)x, (int)y, 0, nanos); + } + + protected void addDelta(float dx, float dy) { + accum_dx += dx; + accum_dy += -dy; + } + + public synchronized void setButton(int button, int state, long nanos) { + buttons[button] = (byte)state; + putMouseEvent((byte)button, (byte)state, 0, nanos); + } + + public synchronized void mouseMoved(float x, float y, float dx, float dy, float dz, long nanos) { + if (skip_event > 0) { + skip_event--; + if (skip_event == 0) { + last_x = x; + last_y = y; + } + return; + } + if (grabbed) { + if ( dx != 0 || dy != 0 ) { + putMouseEventWithCoords((byte)-1, (byte)0, (int)dx, (int)-dy, 0, nanos); + addDelta(dx, dy); + } + } else { + setCursorPos(x, y, nanos); + } + if ( dz != 0 ) { + int wheel_amount = (int)(-dz * WHEEL_SCALE); + accum_dz += wheel_amount; + putMouseEvent((byte)-1, (byte)0, wheel_amount, nanos); + } + } +} Modified: branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MouseEventQueue.java =================================================================== --- branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MouseEventQueue.java 2012-11-01 20:36:45 UTC (rev 3805) +++ branches/osx-java7/LWJGL/src/java/org/lwjgl/opengl/MouseEventQueue.java 2012-11-01 20:54:17 UTC (rev 3806) @@ -81,15 +81,19 @@ public synchronized void register() { resetCursorToCenter(); - component.addMouseListener(this); - component.addMouseMotionListener(this); - component.addMouseWheelListener(this); + if (component != null) { + component.addMouseListener(this); + component.addMouseMotionListener(this); + component.addMouseWheelListener(this); + } } public synchronized void unregister() { - component.removeMouseListener(this); - component.removeMouseMotionListener(this); - component.removeMouseWheelListener(this); + if (component != null) { + component.removeMouseListener(this); + component.removeMouseMotionListener(this); + component.removeMouseWheelListener(this); + } } protected Component getComponent() { @@ -105,18 +109,23 @@ return grabbed; } - private int transformY(int y) { - return component.getHeight() - 1 - y; + protected int transformY(int y) { + if (component != null) { + return component.getHeight() - 1 - y; + } + return y; } protected void resetCursorToCenter() { clearEvents(); accum_dx = accum_dy = 0; - Point cursor_location = AWTUtil.getCursorPosition(component); - if (cursor_location != null) { - last_x = cursor_location.x; - last_y = cursor_location.y; - } + if (component != null) { + Point cursor_location = AWTUtil.getCursorPosition(component); + if (cursor_location != null) { + last_x = cursor_location.x; + last_y = cursor_location.y; + } + } } private void putMouseEvent(byte button, byte state, int dz, long nanos) { Modified: branches/osx-java7/LWJGL/src/native/macosx/context.h =================================================================== --- branches/osx-java7/LWJGL/src/native/macosx/context.h 2012-11-01 20:36:45 UTC (rev 3805) +++ branches/osx-java7/LWJGL/src/native/macosx/context.h 2012-11-01 20:54:17 UTC (rev 3806) @@ -47,15 +47,65 @@ #include <OpenGL/glext.h> #include "common_tools.h" +@class NSOpenGLContext, NSOpenGLPixelFormat, MacOSXOpenGLView, MacOSXKeyableWindow; + typedef struct { + MacOSXKeyableWindow *window; + + NSRect display_rect; + + MacOSXOpenGLView *view; + NSOpenGLContext *context; + + // Native objects for Java callbacks + jobject jdisplay; + jobject jmouse; + jobject jkeyboard; + jboolean resized; + + // Cached for window creation + NSApplicationPresentationOptions window_options; +} MacOSXWindowInfo; + +@interface MacOSXKeyableWindow : NSWindow + +- (BOOL)canBecomeKeyWindow; +@end + +@interface MacOSXOpenGLView : NSView +{ + @public + MacOSXWindowInfo* _parent; + + @private + NSOpenGLContext* _openGLContext; + NSOpenGLPixelFormat* _pixelFormat; + NSUInteger _lastModifierFlags; + NSUInteger _modifierFlags; +} + ++ (NSOpenGLPixelFormat*)defaultPixelFormat; +- (id)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat*)format; +- (void)setOpenGLContext:(NSOpenGLContext*)context; +- (NSOpenGLContext*)openGLContext; +- (void)clearGLContext; +- (void)prepareOpenGL; +- (void)update; +- (void)lockFocus; +- (void)setPixelFormat:(NSOpenGLPixelFormat*)pixelFormat; +- (NSOpenGLPixelFormat*)pixelFormat; +- (void)setParent:(MacOSXWindowInfo*)parent; +- (BOOL)acceptsFirstResponder; +@end + +typedef struct { + bool isWindowed; + bool canDrawGL; + MacOSXWindowInfo *window_info; NSOpenGLPixelFormat *pixel_format; - bool window; - bool canDrawGL; - union { - NSView *nsview; - NSOpenGLPixelBuffer *pbuffer; - }; + NSOpenGLPixelBuffer *pbuffer; } MacOSXPeerInfo; + NSOpenGLPixelFormat *choosePixelFormat(JNIEnv *env, jobject pixel_format, bool gl32, bool use_display_bpp, bool support_window, bool support_pbuffer, bool double_buffered); #endif Modified: branches/osx-java7/LWJGL/src/native/macosx/context.m =================================================================== --- branches/osx-java7/LWJGL/src/native/macosx/context.m 2012-11-01 20:36:45 UTC (rev 3805) +++ branches/osx-java7/LWJGL/src/native/macosx/context.m 2012-11-01 20:54:17 UTC (rev 3806) @@ -91,7 +91,16 @@ int bpp; jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); if (use_display_bpp) - bpp = CGDisplayBitsPerPixel(kCGDirectMainDisplay); + { + CGDisplayModeRef mode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); + CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode); + if (CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + bpp = 32; + else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + bpp = 16; + else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + bpp = 8; + } else bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "bpp", "I")); Modified: branches/osx-java7/LWJGL/src/native/macosx/org_lwjgl_opengl_Display.m =================================================================== --- branches/osx-java7/LWJGL/src/native/macosx/org_lwjgl_opengl_Display.m 2012-11-01 20:36:45 UTC (rev 3805) +++ branches/osx-java7/LWJGL/src/native/macosx/org_lwjgl_opengl_Display.m 2012-11-01 20:54:17 UTC (rev 3806) @@ -39,18 +39,433 @@ * @version $Revision$ */ +#import <AppKit/NSApplication.h> #import <Cocoa/Cocoa.h> #import <Carbon/Carbon.h> -#import <jawt_md.h> #import <jni.h> #import <unistd.h> -//#import "display.h" #import "common_tools.h" #import "org_lwjgl_opengl_MacOSXDisplay.h" #import "org_lwjgl_MacOSXSysImplementation.h" +#import "context.h" #define WAIT_DELAY 100 +static NSOpenGLPixelFormat *default_format = nil; + +@implementation MacOSXKeyableWindow +- (BOOL)canBecomeKeyWindow; +{ + return YES; +} +@end + +@implementation MacOSXOpenGLView + ++ (NSOpenGLPixelFormat*)defaultPixelFormat +{ + NSOpenGLPixelFormatAttribute defaultAttribs[] = { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, 16, + NSOpenGLPFAColorSize, 32, + 0 + }; + if (default_format == nil) { + default_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:defaultAttribs]; + } + return default_format; +} + +- (void) windowWillClose:(NSNotification *)notification +{ + MacOSXKeyableWindow *closingWindow = [notification object]; + + if (_parent != nil && closingWindow == _parent->window) { + JNIEnv *env = attachCurrentThread(); + jclass display_class = (*env)->GetObjectClass(env, _parent->jdisplay); + jmethodID close_callback = (*env)->GetMethodID(env, display_class, "doHandleQuit", "()V"); + (*env)->CallVoidMethod(env, _parent->jdisplay, close_callback); + } +} + +- (id)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat*)format +{ + self = [super initWithFrame:frameRect]; + _lastModifierFlags = 0; + _modifierFlags = 0; + if (self != nil) { + _pixelFormat = [format retain]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(_surfaceNeedsUpdate:) + name:NSViewGlobalFrameDidChangeNotification + object:self]; + } + return self; +} + +- (void) _surfaceNeedsUpdate:(NSNotification*)notification +{ + [self update]; +} + +- (void)setOpenGLContext:(NSOpenGLContext*)context +{ + _openGLContext = context; +} + +- (NSOpenGLContext*)openGLContext +{ + return _openGLContext; +} + +- (void)clearGLContext +{ + [_openGLContext release]; + _openGLContext = nil; +} + +- (void)prepareOpenGL +{ + +} + +- (void)update +{ + [_openGLContext update]; +} + +- (void)lockFocus +{ + NSOpenGLContext* context = [self openGLContext]; + + [super lockFocus]; + if ([context view] != self) { + [context setView:self]; + } + + [context makeCurrentContext]; +} + +- (void)setPixelFormat:(NSOpenGLPixelFormat*)pixelFormat +{ + _pixelFormat = [pixelFormat retain]; +} + +- (NSOpenGLPixelFormat*)pixelFormat +{ + return _pixelFormat; +} + +- (BOOL)acceptsFirstResponder { + return YES; +} + +- (void)setParent:(MacOSXWindowInfo*)parent { + // Un-register for native window close events if we have a parent window already + if (_parent != nil) { + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSWindowWillCloseNotification + object:_parent->window]; + } + _parent = parent; + // Register for native window close events if we now have a parent window + if (_parent != nil) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification + object:_parent->window]; + } +} + +- (void)keyDown:(NSEvent *)event { + JNIEnv *env = attachCurrentThread(); + if (env == nil || event == nil || _parent == nil || _parent->jkeyboard == nil) { + return; + } + long time = [event timestamp] * 1000000000; + jclass keyboard_class = (*env)->GetObjectClass(env, _parent->jkeyboard); + jmethodID keydown = (*env)->GetMethodID(env, keyboard_class, "keyPressed", "(IIJ)V"); + const char* charbuf = [[event characters] cStringUsingEncoding:NSASCIIStringEncoding]; + int charcode = (charbuf == nil) ? 0 : charbuf[0]; + (*env)->CallVoidMethod(env, _parent->jkeyboard, keydown, [event keyCode], charcode, time); +} + +- (void)keyUp:(NSEvent *)event { + JNIEnv *env = attachCurrentThread(); + if (env == nil || event == nil || _parent == nil || _parent->jkeyboard == nil) { + return; + } + long time = [event timestamp] * 1000000000; + jclass keyboard_class = (*env)->GetObjectClass(env, _parent->jkeyboard); + jmethodID keyup = (*env)->GetMethodID(env, keyboard_class, "keyReleased", "(IIJ)V"); + const char* charbuf = [[event characters] cStringUsingEncoding:NSASCIIStringEncoding]; + int charcode = (charbuf == nil) ? 0 : charbuf[0]; + (*env)->CallVoidMethod(env, _parent->jkeyboard, keyup, [event keyCode], charcode, time); +} + +- (void)flagsChanged:(NSEvent *)event { + JNIEnv *env = attachCurrentThread(); + if (env == nil || event == nil || _parent == nil || _parent->jkeyboard == nil) { + return; + } + long time = [event timestamp] * 1000000000; + jclass keyboard_class = (*env)->GetObjectClass(env, _parent->jkeyboard); + jmethodID keydown = (*env)->GetMethodID(env, keyboard_class, "keyPressed", "(IIJ)V"); + jmethodID keyup = (*env)->GetMethodID(env, keyboard_class, "keyReleased", "(IIJ)V"); + _lastModifierFlags = _modifierFlags; + _modifierFlags = [event modifierFlags]; + NSUInteger flagDown = ~_lastModifierFlags & _modifierFlags; + NSUInteger flagUp = _lastModifierFlags & ~_modifierFlags; + if (flagDown & NSAlphaShiftKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keydown, 0xf0, 0, time); + } + if (flagUp & NSAlphaShiftKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keyup, 0xf0, 0, time); + } + if (flagDown & NSShiftKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keydown, 0xf1, 0, time); + } + if (flagUp & NSShiftKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keyup, 0xf1, 0, time); + } + if (flagDown & NSControlKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keydown, 0xf2, 0, time); + } + if (flagUp & NSControlKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keyup, 0xf2, 0, time); + } + if (flagDown & NSAlternateKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keydown, 0xf3, 0, time); + } + if (flagUp & NSAlternateKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keyup, 0xf3, 0, time); + } + if (flagDown & NSCommandKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keydown, 0xf4, 0, time); + } + if (flagUp & NSCommandKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keyup, 0xf4, 0, time); + } + if (flagDown & NSNumericPadKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keydown, 0xf5, 0, time); + } + if (flagUp & NSNumericPadKeyMask) { + (*env)->CallVoidMethod(env, _parent->jkeyboard, keyup, 0xf5, 0, time); + } + //const char* charbuf = [[event characters] cStringUsingEncoding:NSASCIIStringEncoding]; + //(*env)->CallVoidMethod(env, _parent->jkeyboard, keymod, (jint)[event keyCode], (jint)charbuf[0], time); +} + +- (void)mouseButtonState:(NSEvent *)event :(int)button :(int)state { + JNIEnv *env = attachCurrentThread(); + if (env == nil || event == nil || _parent == nil || _parent->jkeyboard == nil) { + return; + } + long time = [event timestamp] * 1000000000; + jclass mouse_class = (*env)->GetObjectClass(env, _parent->jmouse); + jmethodID mousebutton = (*env)->GetMethodID(env, mouse_class, "setButton", "(IIJ)V"); + (*env)->CallVoidMethod(env, _parent->jmouse, mousebutton, button, state, time); +} + +- (void)mouseDown:(NSEvent *)event { + [self mouseButtonState:event :0 :1]; +} + +- (void)rightMouseDown:(NSEvent *)event { + [self mouseButtonState:event :1 :1]; +} + +- (void)otherMouseDown:(NSEvent *)event { + [self mouseButtonState:event :2 :1]; +} + +- (void)mouseUp:(NSEvent *)event { + [self mouseButtonState:event :0 :0]; +} + +- (void)rightMouseUp:(NSEvent *)event { + [self mouseButtonState:event :1 :0]; +} + +- (void)otherMouseUp:(NSEvent *)event { + [self mouseButtonState:event :2 :0]; +} + +- (void)mouseDragged:(NSEvent *)event { + JNIEnv *env = attachCurrentThread(); + if (env == nil || event == nil || _parent == nil) { + return; + } + long time = [event timestamp] * 1000000000; + jclass mouse_class = (*env)->GetObjectClass(env, _parent->jmouse); + jmethodID mousemove = (*env)->GetMethodID(env, mouse_class, "mouseMoved", "(FFFFFJ)V"); + NSPoint loc = [self convertPoint:[event locationInWindow] toView:self]; + (*env)->CallVoidMethod(env, _parent->jmouse, mousemove, loc.x, loc.y, [event deltaX], [event deltaY], 0.0f, time); +} + +- (void)mouseMoved:(NSEvent *)event { + JNIEnv *env = attachCurrentThread(); + if (env == nil || event == nil || _parent == nil || _parent->jmouse == nil) { + return; + } + long time = [event timestamp] * 1000000000; + jclass mouse_class = (*env)->GetObjectClass(env, _parent->jmouse); + jmethodID mousemove = (*env)->GetMethodID(env, mouse_class, "mouseMoved", "(FFFFFJ)V"); + NSPoint loc = [self convertPoint:[event locationInWindow] toView:self]; + (*env)->CallVoidMethod(env, _parent->jmouse, mousemove, loc.x, loc.y, [event deltaX], [event deltaY], 0.0f, time); +} + +- (void)scrollWheel:(NSEvent *)event { + JNIEnv *env = attachCurrentThread(); + if (env == nil || event == nil || _parent == nil) { + return; + } + long time = [event timestamp] * 1000000000; + float dz = [event scrollingDeltaY]; + if (![event hasPreciseScrollingDeltas]) { + dz *= 12; // or so + } + jclass mouse_class = (*env)->GetObjectClass(env, _parent->jmouse); + jmethodID mousemove = (*env)->GetMethodID(env, mouse_class, "mouseMoved", "(FFFFFJ)V"); + NSPoint loc = [self convertPoint:[event locationInWindow] toView:self]; + (*env)->CallVoidMethod(env, _parent->jmouse, mousemove, loc.x, loc.y, [event deltaX], [event deltaY], dz, time); +} + +- (void)viewDidMoveToWindow +{ + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowResized:) + name:NSWindowDidResizeNotification + object:[self window]]; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + +- (void)windowResized:(NSNotification *)notification; +{ + if (_parent != nil) { + _parent->display_rect = [[self window] frame]; + _parent->resized = JNI_TRUE; + } +} +@end + +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nIsMiniaturized(JNIEnv *env, jobject this, jobject window_handle) { + MacOSXWindowInfo *window_info = (MacOSXWindowInfo *)(*env)->GetDirectBufferAddress(env, window_handle); + return (jboolean)[window_info->window isMiniaturized]; +} + +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nIsFocused(JNIEnv *env, jobject this, jobject window_handle) { + return JNI_TRUE; + //MacOSXWindowInfo *window_info = (MacOSXWindowInfo *)(*env)->GetDirectBufferAddress(env, window_handle); + //return (jboolean)([window_info->window isKeyWindow] || [window_info->window isMainWindow]); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nResizeWindow(JNIEnv *env, jobject this, jobject window_handle, jint x, jint y, jint width, jint height) { + MacOSXWindowInfo *window_info = (MacOSXWindowInfo *)(*env)->GetDirectBufferAddress(env, window_handle); + window_info->display_rect = NSMakeRect(x, y, width, height); + [window_info->window setFrame:window_info->display_rect display:false]; + [window_info->view ... [truncated message content] |