Mac OS X port, second try :)

This commit is contained in:
Elias Naur 2004-11-11 16:03:19 +00:00
parent 4e35eea9ca
commit 1ec70842d0
22 changed files with 1036 additions and 1854 deletions

View file

@ -197,6 +197,8 @@ public class Keyboard {
public static final int STATE_OFF = 1;
public static final int STATE_UNKNOWN = 2;
public final static int KEYBOARD_SIZE = 256;
/** Buffer size in events */
private final static int BUFFER_SIZE = 50;
/** Event size in elements */
@ -237,7 +239,7 @@ public class Keyboard {
private static boolean created;
/** The keys status from the last poll */
private static final ByteBuffer keyDownBuffer = BufferUtils.createByteBuffer(256);
private static final ByteBuffer keyDownBuffer = BufferUtils.createByteBuffer(KEYBOARD_SIZE);
/**
* The key events from the last read: a sequence of pairs of key number,

View file

@ -0,0 +1,279 @@
/*
* Copyright (c) 2002-2004 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 java implementation of a LWJGL compatible Keyboard event queue.
* Currently only used by the Mac OS X implementation.
* @author elias_naur
*/
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import org.lwjgl.input.Keyboard;
final class KeyboardEventQueue extends EventQueue implements KeyListener {
private final static int[] KEY_MAP = new int[0xffff];
private final static int EVENT_SIZE = 3;
private final byte[] key_states = new byte[Keyboard.KEYBOARD_SIZE];
/** Event scratch array */
private final int[] event = new int[EVENT_SIZE];
static {
KEY_MAP[KeyEvent.VK_0] = Keyboard.KEY_0;
KEY_MAP[KeyEvent.VK_1] = Keyboard.KEY_1;
KEY_MAP[KeyEvent.VK_2] = Keyboard.KEY_2;
KEY_MAP[KeyEvent.VK_3] = Keyboard.KEY_3;
KEY_MAP[KeyEvent.VK_4] = Keyboard.KEY_4;
KEY_MAP[KeyEvent.VK_5] = Keyboard.KEY_5;
KEY_MAP[KeyEvent.VK_6] = Keyboard.KEY_6;
KEY_MAP[KeyEvent.VK_7] = Keyboard.KEY_7;
KEY_MAP[KeyEvent.VK_8] = Keyboard.KEY_8;
KEY_MAP[KeyEvent.VK_9] = Keyboard.KEY_9;
KEY_MAP[KeyEvent.VK_A] = Keyboard.KEY_A;
// KEY_MAP[KeyEvent.VK_ACCEPT] = Keyboard.KEY_ACCEPT;
KEY_MAP[KeyEvent.VK_ADD] = Keyboard.KEY_ADD;
// KEY_MAP[KeyEvent.VK_AGAIN] = Keyboard.KEY_AGAIN;
// KEY_MAP[KeyEvent.VK_ALL_CANDIDATES] = Keyboard.KEY_ALL_CANDIDATES;
// KEY_MAP[KeyEvent.VK_ALPHANUMERIC] = Keyboard.KEY_ALPHANUMERIC;
KEY_MAP[KeyEvent.VK_ALT] = Keyboard.KEY_LMENU;
KEY_MAP[KeyEvent.VK_ALT_GRAPH] = Keyboard.KEY_RMENU;
// KEY_MAP[KeyEvent.VK_AMPERSAND] = Keyboard.KEY_AMPERSAND;
// KEY_MAP[KeyEvent.VK_ASTERISK] = Keyboard.KEY_ASTERISK;
KEY_MAP[KeyEvent.VK_AT] = Keyboard.KEY_AT;
KEY_MAP[KeyEvent.VK_B] = Keyboard.KEY_B;
// KEY_MAP[KeyEvent.VK_BACK_QUOTE] = Keyboard.KEY_BACK_QUOTE;
KEY_MAP[KeyEvent.VK_BACK_SLASH] = Keyboard.KEY_BACKSLASH;
KEY_MAP[KeyEvent.VK_BACK_SPACE] = Keyboard.KEY_BACK;
// KEY_MAP[KeyEvent.VK_BRACELEFT] = Keyboard.KEY_BRACELEFT;
// KEY_MAP[KeyEvent.VK_BRACERIGHT] = Keyboard.KEY_BRACERIGHT;
KEY_MAP[KeyEvent.VK_C] = Keyboard.KEY_C;
// KEY_MAP[KeyEvent.VK_CANCEL] = Keyboard.KEY_CANCEL;
KEY_MAP[KeyEvent.VK_CAPS_LOCK] = Keyboard.KEY_CAPITAL;
KEY_MAP[KeyEvent.VK_CIRCUMFLEX] = Keyboard.KEY_CIRCUMFLEX;
// KEY_MAP[KeyEvent.VK_CLEAR] = Keyboard.KEY_CLEAR;
KEY_MAP[KeyEvent.VK_CLOSE_BRACKET] = Keyboard.KEY_RBRACKET;
// KEY_MAP[KeyEvent.VK_CODE_INPUT] = Keyboard.KEY_CODE_INPUT;
KEY_MAP[KeyEvent.VK_COLON] = Keyboard.KEY_COLON;
KEY_MAP[KeyEvent.VK_COMMA] = Keyboard.KEY_COMMA;
// KEY_MAP[KeyEvent.VK_COMPOSE] = Keyboard.KEY_COMPOSE;
KEY_MAP[KeyEvent.VK_CONTROL] = Keyboard.KEY_LCONTROL;
KEY_MAP[KeyEvent.VK_CONVERT] = Keyboard.KEY_CONVERT;
// KEY_MAP[KeyEvent.VK_COPY] = Keyboard.KEY_COPY;
// KEY_MAP[KeyEvent.VK_CUT] = Keyboard.KEY_CUT;
KEY_MAP[KeyEvent.VK_D] = Keyboard.KEY_D;
// KEY_MAP[KeyEvent.VK_DEAD_ABOVEDOT] = Keyboard.KEY_DEAD_ABOVEDOT;
// KEY_MAP[KeyEvent.VK_DEAD_ABOVERING] = Keyboard.KEY_DEAD_ABOVERING;
// KEY_MAP[KeyEvent.VK_DEAD_ACUTE] = Keyboard.KEY_DEAD_ACUTE;
// KEY_MAP[KeyEvent.VK_DEAD_BREVE] = Keyboard.KEY_DEAD_BREVE;
// KEY_MAP[KeyEvent.VK_DEAD_CARON] = Keyboard.KEY_DEAD_CARON;
// KEY_MAP[KeyEvent.VK_DEAD_CEDILLA] = Keyboard.KEY_DEAD_CEDILLA;
// KEY_MAP[KeyEvent.VK_DEAD_CIRCUMFLEX] = Keyboard.KEY_DEAD_CIRCUMFLEX;
// KEY_MAP[KeyEvent.VK_DEAD_DIAERESIS] = Keyboard.KEY_DEAD_DIAERESIS;
// KEY_MAP[KeyEvent.VK_DEAD_DOUBLEACUTE] = Keyboard.KEY_DEAD_DOUBLEACUTE;
// KEY_MAP[KeyEvent.VK_DEAD_GRAVE] = Keyboard.KEY_DEAD_GRAVE;
// KEY_MAP[KeyEvent.VK_DEAD_IOTA] = Keyboard.KEY_DEAD_IOTA;
// KEY_MAP[KeyEvent.VK_DEAD_MACRON] = Keyboard.KEY_DEAD_MACRON;
// KEY_MAP[KeyEvent.VK_DEAD_OGONEK] = Keyboard.KEY_DEAD_OGONEK;
// KEY_MAP[KeyEvent.VK_DEAD_SEMIVOICED_SOUND] = Keyboard.KEY_DEAD_SEMIVOICED_SOUND;
// KEY_MAP[KeyEvent.VK_DEAD_TILDE] = Keyboard.KEY_DEAD_TILDE;
// KEY_MAP[KeyEvent.VK_DEAD_VOICED_SOUND] = Keyboard.KEY_DEAD_VOICED_SOUND;
KEY_MAP[KeyEvent.VK_DECIMAL] = Keyboard.KEY_DECIMAL;
KEY_MAP[KeyEvent.VK_DELETE] = Keyboard.KEY_DELETE;
KEY_MAP[KeyEvent.VK_DIVIDE] = Keyboard.KEY_DIVIDE;
// KEY_MAP[KeyEvent.VK_DOLLAR] = Keyboard.KEY_DOLLAR;
KEY_MAP[KeyEvent.VK_DOWN] = Keyboard.KEY_DOWN;
KEY_MAP[KeyEvent.VK_E] = Keyboard.KEY_E;
KEY_MAP[KeyEvent.VK_END] = Keyboard.KEY_END;
KEY_MAP[KeyEvent.VK_ENTER] = Keyboard.KEY_RETURN;
KEY_MAP[KeyEvent.VK_EQUALS] = Keyboard.KEY_EQUALS;
KEY_MAP[KeyEvent.VK_ESCAPE] = Keyboard.KEY_ESCAPE;
// KEY_MAP[KeyEvent.VK_EURO_SIGN] = Keyboard.KEY_EURO_SIGN;
// KEY_MAP[KeyEvent.VK_EXCLAMATION_MARK] = Keyboard.KEY_EXCLAMATION_MARK;
KEY_MAP[KeyEvent.VK_F] = Keyboard.KEY_F;
KEY_MAP[KeyEvent.VK_F1] = Keyboard.KEY_F1;
KEY_MAP[KeyEvent.VK_F10] = Keyboard.KEY_F10;
KEY_MAP[KeyEvent.VK_F11] = Keyboard.KEY_F11;
KEY_MAP[KeyEvent.VK_F12] = Keyboard.KEY_F12;
KEY_MAP[KeyEvent.VK_F13] = Keyboard.KEY_F13;
KEY_MAP[KeyEvent.VK_F14] = Keyboard.KEY_F14;
KEY_MAP[KeyEvent.VK_F15] = Keyboard.KEY_F15;
// KEY_MAP[KeyEvent.VK_F16] = Keyboard.KEY_F16;
// KEY_MAP[KeyEvent.VK_F17] = Keyboard.KEY_F17;
// KEY_MAP[KeyEvent.VK_F18] = Keyboard.KEY_F18;
// KEY_MAP[KeyEvent.VK_F19] = Keyboard.KEY_F19;
KEY_MAP[KeyEvent.VK_F2] = Keyboard.KEY_F2;
// KEY_MAP[KeyEvent.VK_F20] = Keyboard.KEY_F20;
// KEY_MAP[KeyEvent.VK_F21] = Keyboard.KEY_F21;
// KEY_MAP[KeyEvent.VK_F22] = Keyboard.KEY_F22;
// KEY_MAP[KeyEvent.VK_F23] = Keyboard.KEY_F23;
// KEY_MAP[KeyEvent.VK_F24] = Keyboard.KEY_F24;
KEY_MAP[KeyEvent.VK_F3] = Keyboard.KEY_F3;
KEY_MAP[KeyEvent.VK_F4] = Keyboard.KEY_F4;
KEY_MAP[KeyEvent.VK_F5] = Keyboard.KEY_F5;
KEY_MAP[KeyEvent.VK_F6] = Keyboard.KEY_F6;
KEY_MAP[KeyEvent.VK_F7] = Keyboard.KEY_F7;
KEY_MAP[KeyEvent.VK_F8] = Keyboard.KEY_F8;
KEY_MAP[KeyEvent.VK_F9] = Keyboard.KEY_F9;
// KEY_MAP[KeyEvent.VK_FINAL] = Keyboard.KEY_FINAL;
// KEY_MAP[KeyEvent.VK_FIND] = Keyboard.KEY_FIND;
// KEY_MAP[KeyEvent.VK_FULL_WIDTH] = Keyboard.KEY_FULL_WIDTH;
KEY_MAP[KeyEvent.VK_G] = Keyboard.KEY_G;
// KEY_MAP[KeyEvent.VK_GREATER] = Keyboard.KEY_GREATER;
KEY_MAP[KeyEvent.VK_H] = Keyboard.KEY_H;
// KEY_MAP[KeyEvent.VK_HALF_WIDTH] = Keyboard.KEY_HALF_WIDTH;
// KEY_MAP[KeyEvent.VK_HELP] = Keyboard.KEY_HELP;
// KEY_MAP[KeyEvent.VK_HIRAGANA] = Keyboard.KEY_HIRAGANA;
KEY_MAP[KeyEvent.VK_HOME] = Keyboard.KEY_HOME;
KEY_MAP[KeyEvent.VK_I] = Keyboard.KEY_I;
// KEY_MAP[KeyEvent.VK_INPUT_METHOD_ON_OFF] = Keyboard.KEY_INPUT_METHOD_ON_OFF;
KEY_MAP[KeyEvent.VK_INSERT] = Keyboard.KEY_INSERT;
// KEY_MAP[KeyEvent.VK_INVERTED_EXCLAMATION_MARK] = Keyboard.KEY_INVERTED_EXCLAMATION_MARK;
KEY_MAP[KeyEvent.VK_J] = Keyboard.KEY_J;
// KEY_MAP[KeyEvent.VK_JAPANESE_HIRAGANA] = Keyboard.KEY_JAPANESE_HIRAGANA;
// KEY_MAP[KeyEvent.VK_JAPANESE_KATAKANA] = Keyboard.KEY_JAPANESE_KATAKANA;
// KEY_MAP[KeyEvent.VK_JAPANESE_ROMAN] = Keyboard.KEY_JAPANESE_ROMAN;
KEY_MAP[KeyEvent.VK_K] = Keyboard.KEY_K;
KEY_MAP[KeyEvent.VK_KANA] = Keyboard.KEY_KANA;
// KEY_MAP[KeyEvent.VK_KANA_LOCK] = Keyboard.KEY_KANA_LOCK;
KEY_MAP[KeyEvent.VK_KANJI] = Keyboard.KEY_KANJI;
// KEY_MAP[KeyEvent.VK_KATAKANA] = Keyboard.KEY_KATAKANA;
// KEY_MAP[KeyEvent.VK_KP_DOWN] = Keyboard.KEY_KP_DOWN;
// KEY_MAP[KeyEvent.VK_KP_LEFT] = Keyboard.KEY_KP_LEFT;
// KEY_MAP[KeyEvent.VK_KP_RIGHT] = Keyboard.KEY_KP_RIGHT;
// KEY_MAP[KeyEvent.VK_KP_UP] = Keyboard.KEY_KP_UP;
KEY_MAP[KeyEvent.VK_L] = Keyboard.KEY_L;
KEY_MAP[KeyEvent.VK_LEFT] = Keyboard.KEY_LEFT;
// KEY_MAP[KeyEvent.VK_LEFT_PARENTHESIS] = Keyboard.KEY_LEFT_PARENTHESIS;
// KEY_MAP[KeyEvent.VK_LESS] = Keyboard.KEY_LESS;
KEY_MAP[KeyEvent.VK_M] = Keyboard.KEY_M;
// KEY_MAP[KeyEvent.VK_META] = Keyboard.KEY_META;
KEY_MAP[KeyEvent.VK_MINUS] = Keyboard.KEY_MINUS;
// KEY_MAP[KeyEvent.VK_MODECHANGE] = Keyboard.KEY_MODECHANGE;
KEY_MAP[KeyEvent.VK_MULTIPLY] = Keyboard.KEY_MULTIPLY;
KEY_MAP[KeyEvent.VK_N] = Keyboard.KEY_N;
// KEY_MAP[KeyEvent.VK_NONCONVERT] = Keyboard.KEY_NONCONVERT;
KEY_MAP[KeyEvent.VK_NUM_LOCK] = Keyboard.KEY_NUMLOCK;
// KEY_MAP[KeyEvent.VK_NUMBER_SIGN] = Keyboard.KEY_NUMBER_SIGN;
KEY_MAP[KeyEvent.VK_NUMPAD0] = Keyboard.KEY_NUMPAD0;
KEY_MAP[KeyEvent.VK_NUMPAD1] = Keyboard.KEY_NUMPAD1;
KEY_MAP[KeyEvent.VK_NUMPAD2] = Keyboard.KEY_NUMPAD2;
KEY_MAP[KeyEvent.VK_NUMPAD3] = Keyboard.KEY_NUMPAD3;
KEY_MAP[KeyEvent.VK_NUMPAD4] = Keyboard.KEY_NUMPAD4;
KEY_MAP[KeyEvent.VK_NUMPAD5] = Keyboard.KEY_NUMPAD5;
KEY_MAP[KeyEvent.VK_NUMPAD6] = Keyboard.KEY_NUMPAD6;
KEY_MAP[KeyEvent.VK_NUMPAD7] = Keyboard.KEY_NUMPAD7;
KEY_MAP[KeyEvent.VK_NUMPAD8] = Keyboard.KEY_NUMPAD8;
KEY_MAP[KeyEvent.VK_NUMPAD9] = Keyboard.KEY_NUMPAD9;
KEY_MAP[KeyEvent.VK_O] = Keyboard.KEY_O;
KEY_MAP[KeyEvent.VK_OPEN_BRACKET] = Keyboard.KEY_LBRACKET;
KEY_MAP[KeyEvent.VK_P] = Keyboard.KEY_P;
KEY_MAP[KeyEvent.VK_PAGE_DOWN] = Keyboard.KEY_NEXT;
KEY_MAP[KeyEvent.VK_PAGE_UP] = Keyboard.KEY_PRIOR;
// KEY_MAP[KeyEvent.VK_PASTE] = Keyboard.KEY_PASTE;
KEY_MAP[KeyEvent.VK_PAUSE] = Keyboard.KEY_PAUSE;
KEY_MAP[KeyEvent.VK_PERIOD] = Keyboard.KEY_PERIOD;
// KEY_MAP[KeyEvent.VK_PLUS] = Keyboard.KEY_PLUS;
// KEY_MAP[KeyEvent.VK_PREVIOUS_CANDIDATE] = Keyboard.KEY_PREVIOUS_CANDIDATE;
// KEY_MAP[KeyEvent.VK_PRINTSCREEN] = Keyboard.KEY_PRINTSCREEN;
// KEY_MAP[KeyEvent.VK_PROPS] = Keyboard.KEY_PROPS;
KEY_MAP[KeyEvent.VK_Q] = Keyboard.KEY_Q;
// KEY_MAP[KeyEvent.VK_QUOTE] = Keyboard.KEY_QUOTE;
// KEY_MAP[KeyEvent.VK_QUOTEDBL] = Keyboard.KEY_QUOTEDBL;
KEY_MAP[KeyEvent.VK_R] = Keyboard.KEY_R;
KEY_MAP[KeyEvent.VK_RIGHT] = Keyboard.KEY_RIGHT;
// KEY_MAP[KeyEvent.VK_RIGHT_PARENTHESIS] = Keyboard.KEY_RIGHT_PARENTHESIS;
// KEY_MAP[KeyEvent.VK_ROMAN_CHARACTERS] = Keyboard.KEY_ROMAN_CHARACTERS;
KEY_MAP[KeyEvent.VK_S] = Keyboard.KEY_S;
KEY_MAP[KeyEvent.VK_SCROLL_LOCK] = Keyboard.KEY_SCROLL;
KEY_MAP[KeyEvent.VK_SEMICOLON] = Keyboard.KEY_SEMICOLON;
KEY_MAP[KeyEvent.VK_SEPARATOR] = Keyboard.KEY_DECIMAL;
KEY_MAP[KeyEvent.VK_SHIFT] = Keyboard.KEY_LSHIFT;
KEY_MAP[KeyEvent.VK_SLASH] = Keyboard.KEY_SLASH;
KEY_MAP[KeyEvent.VK_SPACE] = Keyboard.KEY_SPACE;
KEY_MAP[KeyEvent.VK_STOP] = Keyboard.KEY_STOP;
KEY_MAP[KeyEvent.VK_SUBTRACT] = Keyboard.KEY_SUBTRACT;
KEY_MAP[KeyEvent.VK_T] = Keyboard.KEY_T;
KEY_MAP[KeyEvent.VK_TAB] = Keyboard.KEY_TAB;
KEY_MAP[KeyEvent.VK_U] = Keyboard.KEY_U;
// KEY_MAP[KeyEvent.VK_UNDERSCORE] = Keyboard.KEY_UNDERSCORE;
// KEY_MAP[KeyEvent.VK_UNDO] = Keyboard.KEY_UNDO;
KEY_MAP[KeyEvent.VK_UP] = Keyboard.KEY_UP;
KEY_MAP[KeyEvent.VK_V] = Keyboard.KEY_V;
KEY_MAP[KeyEvent.VK_W] = Keyboard.KEY_W;
KEY_MAP[KeyEvent.VK_X] = Keyboard.KEY_X;
KEY_MAP[KeyEvent.VK_Y] = Keyboard.KEY_Y;
KEY_MAP[KeyEvent.VK_Z] = Keyboard.KEY_Z;
}
public KeyboardEventQueue() {
super(EVENT_SIZE);
}
private void putKeyboardEvent(int key_code, int state, int character) {
event[0] = key_code;
event[1] = state;
event[2] = character;
putEvent(event);
}
public synchronized void poll(ByteBuffer key_down_buffer) {
int old_position = key_down_buffer.position();
key_down_buffer.put(key_states);
key_down_buffer.position(old_position);
}
private synchronized void handleKey(int key_code, int state, char character) {
int key_code_mapped = KEY_MAP[key_code];
if (character == KeyEvent.CHAR_UNDEFINED)
character = Keyboard.CHAR_NONE;
int key_int_char = ((int)character) & 0xffff;
putKeyboardEvent(key_code_mapped, state, key_int_char);
}
public void keyPressed(KeyEvent e) {
handleKey(e.getKeyCode(), 1, e.getKeyChar());
}
public void keyReleased(KeyEvent e) {
handleKey(e.getKeyCode(), 0, Keyboard.CHAR_NONE);
}
public void keyTyped(KeyEvent e) {
}
}

View file

@ -0,0 +1,399 @@
/*
* Copyright (c) 2002-2004 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;
/**
* This is the Display implementation interface. Display delegates
* to implementors of this interface. There is one DisplayImplementation
* for each supported platform.
* @author elias_naur
*/
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Mouse;
import java.util.List;
import java.util.ArrayList;
import java.awt.BorderLayout;
import java.awt.Frame;
import javax.swing.JFrame;
import java.awt.Insets;
import java.awt.Cursor;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.GraphicsEnvironment;
import java.awt.GraphicsDevice;
import java.awt.image.BufferedImage;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import com.apple.eawt.Application;
import com.apple.eawt.ApplicationListener;
import com.apple.eawt.ApplicationEvent;
final class MacOSXDisplay extends WindowAdapter implements DisplayImplementation, ApplicationListener {
private JFrame frame;
private MacOSXGLCanvas canvas;
private boolean close_requested;
private MouseEventQueue mouse_queue;
private KeyboardEventQueue keyboard_queue;
private java.awt.DisplayMode requested_mode;
public MacOSXDisplay() {
Application.getApplication().addApplicationListener(this);
System.out.println("getMaxCursorSize = " + getMaxCursorSize());
}
public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException {
close_requested = false;
frame = new JFrame();
frame.setResizable(false);
frame.addWindowListener(this);
canvas = new MacOSXGLCanvas();
frame.getContentPane().add(canvas, BorderLayout.CENTER);
frame.setUndecorated(fullscreen);
if (fullscreen) {
getDevice().setFullScreenWindow(frame);
getDevice().setDisplayMode(requested_mode);
/** For some strange reason, the display mode is sometimes silently capped even though the mode is reported as supported */
if (requested_mode.getWidth() != getDevice().getDisplayMode().getWidth() || requested_mode.getHeight() != getDevice().getDisplayMode().getHeight()) {
destroyWindow();
throw new LWJGLException("AWT capped mode");
}
}
frame.pack();
reshape(x, y, mode.getWidth(), mode.getHeight());
frame.setVisible(true);
frame.requestFocus();
canvas.requestFocus();
canvas.waitForCanvasCreated();
}
private GraphicsDevice getDevice() {
GraphicsEnvironment g_env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = g_env.getDefaultScreenDevice();
return device;
}
public void handleAbout(ApplicationEvent event) {
}
public void handleOpenApplication(ApplicationEvent event) {
}
public void handleOpenFile(ApplicationEvent event) {
}
public void handlePreferences(ApplicationEvent event) {
}
public void handlePrintFile(ApplicationEvent event) {
}
public void handleQuit(ApplicationEvent event) {
handleQuit();
}
public void handleReOpenApplication(ApplicationEvent event) {
}
private void handleQuit() {
synchronized (this) {
close_requested = true;
}
}
public void windowClosing(WindowEvent e) {
handleQuit();
}
public void windowActivated(WindowEvent e) {
warpCursor();
}
public void destroyWindow() {
if (getDevice().getFullScreenWindow() != null)
getDevice().setFullScreenWindow(null);
setView(null);
frame.dispose();
frame = null;
canvas = null;
}
public native int getGammaRampLength();
public native void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException;
public String getAdapter() {
return null;
}
public String getVersion() {
return null;
}
private boolean equals(java.awt.DisplayMode awt_mode, DisplayMode mode) {
return awt_mode.getWidth() == mode.getWidth() && awt_mode.getHeight() == mode.getHeight()
&& awt_mode.getBitDepth() == mode.getBitsPerPixel() && awt_mode.getRefreshRate() == mode.getFrequency();
}
public void switchDisplayMode(DisplayMode mode) throws LWJGLException {
java.awt.DisplayMode[] awt_modes = getDevice().getDisplayModes();
for (int i = 0; i < awt_modes.length; i++)
if (equals(awt_modes[i], mode)) {
requested_mode = awt_modes[i];
return;
}
throw new LWJGLException(mode + " is not supported");
}
public void resetDisplayMode() {
if (getDevice().getFullScreenWindow() != null)
getDevice().setFullScreenWindow(null);
requested_mode = null;
}
private DisplayMode createLWJGLDisplayMode(java.awt.DisplayMode awt_mode) {
int bit_depth;
int refresh_rate;
int awt_bit_depth = awt_mode.getBitDepth();
int awt_refresh_rate = awt_mode.getRefreshRate();
if (awt_bit_depth != java.awt.DisplayMode.BIT_DEPTH_MULTI)
bit_depth = awt_bit_depth;
else
bit_depth = 32; // Assume the best bit depth
if (awt_refresh_rate != java.awt.DisplayMode.REFRESH_RATE_UNKNOWN)
refresh_rate = awt_refresh_rate;
else
refresh_rate = 0;
return new DisplayMode(awt_mode.getWidth(), awt_mode.getHeight(), bit_depth, refresh_rate);
}
public DisplayMode init() {
return createLWJGLDisplayMode(getDevice().getDisplayMode());
}
public DisplayMode[] getAvailableDisplayModes() {
java.awt.DisplayMode[] awt_modes = getDevice().getDisplayModes();
List modes = new ArrayList();
for (int i = 0; i < awt_modes.length; i++)
if (awt_modes[i].getBitDepth() >= 16)
modes.add(createLWJGLDisplayMode(awt_modes[i]));
DisplayMode[] mode_list = new DisplayMode[modes.size()];
modes.toArray(mode_list);
return mode_list;
}
public void setTitle(String title) {
frame.setTitle(title);
}
public boolean isCloseRequested() {
boolean result;
synchronized (this) {
result = close_requested;
close_requested = false;
}
return result;
}
public boolean isVisible() {
return frame.isShowing();
}
public boolean isActive() {
return frame.isFocused();
}
public boolean isDirty() {
return canvas.isDirty();
}
public native void setView(MacOSXGLCanvas canvas);
public native void swapBuffers();
public native void makeCurrent() throws LWJGLException;
public native void createContext(PixelFormat pixel_format) throws LWJGLException;
public native void destroyContext();
public void update() {
if (canvas.shouldUpdateContext()) {
updateContext();
/* This is necessary to make sure the context won't "forget" about the view size */
GL11.glViewport(0, 0, canvas.getWidth(), canvas.getHeight());
warpCursor();
}
mouse_queue.updateDeltas();
}
private void warpCursor() {
if (mouse_queue != null && mouse_queue.isGrabbed()) {
Rectangle bounds = frame.getBounds();
int x = bounds.x + bounds.width/2;
int y = bounds.y + bounds.height/2;
nWarpCursor(x, y);
}
}
native void getMouseDeltas(IntBuffer delta_buffer);
private native void updateContext();
public native void setVSyncEnabled(boolean sync);
public void reshape(int x, int y, int width, int height) {
Insets insets = frame.getInsets();
frame.setBounds(x, y, width + insets.left + insets.right, height + insets.top + insets.bottom);
}
/* Mouse */
public boolean hasWheel() {
return true;
}
public int getButtonCount() {
return MouseEventQueue.NUM_BUTTONS;
}
public void createMouse() {
this.mouse_queue = new MouseEventQueue(canvas.getWidth(), canvas.getHeight());
canvas.addMouseListener(mouse_queue);
canvas.addMouseMotionListener(mouse_queue);
canvas.addMouseWheelListener(mouse_queue);
}
public void destroyMouse() {
canvas.removeMouseListener(mouse_queue);
canvas.removeMouseWheelListener(mouse_queue);
canvas.removeMouseMotionListener(mouse_queue);
this.mouse_queue = null;
}
public void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons_buffer) {
mouse_queue.poll(coord_buffer, buttons_buffer);
}
public void enableMouseBuffer() throws LWJGLException {
}
public int readMouse(IntBuffer buffer, int buffer_position) {
assert buffer_position == buffer.position();
return mouse_queue.copyEvents(buffer);
}
public void grabMouse(boolean grab) {
nGrabMouse(grab);
mouse_queue.setGrabbed(grab);
warpCursor();
}
private native void nWarpCursor(int x, int y);
private native void nGrabMouse(boolean grab);
public int getNativeCursorCaps() {
int cursor_colors = Toolkit.getDefaultToolkit().getMaximumCursorColors();
boolean supported = cursor_colors >= Short.MAX_VALUE && getMaxCursorSize() > 0;
int caps = supported ? Mouse.CURSOR_8_BIT_ALPHA | Mouse.CURSOR_ONE_BIT_TRANSPARENCY: 0;
return caps;
}
public void setNativeCursor(Object handle) throws LWJGLException {
Cursor awt_cursor = (Cursor)handle;
canvas.setCursor(awt_cursor);
}
public int getMinCursorSize() {
Dimension min_size = Toolkit.getDefaultToolkit().getBestCursorSize(0, 0);
return Math.max(min_size.width, min_size.height);
}
public int getMaxCursorSize() {
Dimension max_size = Toolkit.getDefaultToolkit().getBestCursorSize(10000, 10000);
return Math.min(max_size.width, max_size.height);
}
/* Keyboard */
public void createKeyboard() throws LWJGLException {
this.keyboard_queue = new KeyboardEventQueue();
canvas.addKeyListener(keyboard_queue);
}
public void destroyKeyboard() {
/*
* This line is commented out to work around AWT bug 4867453:
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4867453
*/
// canvas.removeKeyListener(keyboard_queue);
this.keyboard_queue = null;
}
public void pollKeyboard(ByteBuffer keyDownBuffer) {
keyboard_queue.poll(keyDownBuffer);
}
public int readKeyboard(IntBuffer buffer, int buffer_position) {
assert buffer_position == buffer.position();
return keyboard_queue.copyEvents(buffer);
}
public void enableTranslation() throws LWJGLException {
}
public void enableKeyboardBuffer() throws LWJGLException {
}
public native int isStateKeySet(int key);
/** Native cursor handles */
public Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException {
BufferedImage cursor_image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
int[] pixels = new int[images.remaining()];
int old_position = images.position();
images.get(pixels);
images.position(old_position);
cursor_image.setRGB(0, 0, width, height, pixels, 0, width);
return Toolkit.getDefaultToolkit().createCustomCursor(cursor_image, new Point(xHotspot, yHotspot), "LWJGL Custom cursor");
}
public void destroyCursor(Object cursor_handle) {
}
}

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2002-2004 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;
/**
* The AWT compatible Canvas for Mac OS X.
* @author elias_naur
*/
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.event.HierarchyBoundsListener;
import java.awt.event.HierarchyEvent;
final class MacOSXGLCanvas extends Canvas implements HierarchyBoundsListener {
private boolean context_update;
private boolean canvas_created;
private boolean dirty;
public MacOSXGLCanvas() {
setFocusTraversalKeysEnabled(false);
/* Input methods are not enabled in fullscreen anyway, so disable always */
enableInputMethods(false);
addHierarchyBoundsListener(this);
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
synchronized (this) {
dirty = true;
if (!canvas_created) {
((MacOSXDisplay)Display.getImplementation()).setView(this);
canvas_created = true;
setUpdate();
notify();
}
}
}
public boolean isDirty() {
boolean result;
synchronized (this) {
result = dirty;
dirty = false;
}
return result;
}
public void waitForCanvasCreated() {
synchronized (this) {
while (!canvas_created) {
try {
wait();
} catch (InterruptedException e) {
// ignore
}
}
}
}
public boolean shouldUpdateContext() {
boolean should_update;
synchronized (this) {
should_update = context_update;
context_update = false;
}
return should_update;
}
private synchronized void setUpdate() {
context_update = true;
}
public void ancestorResized(HierarchyEvent e) {
setUpdate();
}
public void ancestorMoved(HierarchyEvent e) {
setUpdate();
}
public void setLocation(int x, int y) {
super.setLocation(x, y);
setUpdate();
}
public void setLocation(Point p) {
super.setLocation(p);
setUpdate();
}
public void setSize(Dimension d) {
super.setSize(d);
setUpdate();
}
public void setSize(int width, int height) {
super.setSize(width, height);
setUpdate();
}
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
setUpdate();
}
}

View file

@ -74,9 +74,22 @@ public class WindowCreationTest {
System.out.println("Window created");
System.out.println(Display.getDisplayMode().getHeight() + ", " + Display.getDisplayMode().getWidth() + ", " + Display.getTitle());
Display.setVSyncEnabled(true);
Display.setTitle("WindowCreationTest");
float color = 0f;
int direction = 1;
// wait for user to close window
while(!Display.isCloseRequested()) {
GL11.glClearColor(color, color, color, 1f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
color += direction*.05f;
if (color > 1f) {
color = 1f;
direction = -1*direction;
} else if (color < 0f) {
direction = -1*direction;
color = 0f;
}
Display.update();
try {
Thread.sleep(100);