Added org.lwjgl.opengl.AWTInputAdapter which enabled use of Mouse and

Keyboard with AWTGLCanvases. Programs can now avoid implementing AWT input processing and access the mouse grabbing features from both Display and AWTGLCanvas. See org.lwjgl.test.opengl.awt.AWTInputAdapterTest for an example.

Note: This commit is the linux and generic AWT imlementation and can still
change a lot while implementing windows and mac os x.
This commit is contained in:
Elias Naur 2006-10-26 20:19:40 +00:00
parent 0a17002082
commit 3674d843c2
24 changed files with 1344 additions and 153 deletions

View File

@ -494,6 +494,7 @@
<target name="headers" description="invokes javah on java classes" depends="compile">
<!-- platform specific classes -->
<javah classpath="${lwjgl.bin}" destdir="${lwjgl.src.native}/linux" force="yes">
<class name="org.lwjgl.opengl.LinuxAWTInput" />
<class name="org.lwjgl.opengl.LinuxEvent" />
<class name="org.lwjgl.opengl.LinuxMouse" />
<class name="org.lwjgl.opengl.LinuxKeyboard" />

View File

@ -42,7 +42,7 @@ import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayImplementation;
import org.lwjgl.opengl.InputImplementation;
/**
* <br>
@ -264,7 +264,7 @@ public class Keyboard {
/** One time initialization */
private static boolean initialized;
private static DisplayImplementation implementation;
private static InputImplementation implementation;
/**
* Keyboard cannot be constructed.
@ -282,6 +282,24 @@ public class Keyboard {
initialized = true;
}
/**
* "Create" the keyboard with the given implementation. This is used
* reflectively from AWTInputAdapter.
*
* @throws LWJGLException if the keyboard could not be created for any reason
*/
private static void create(InputImplementation impl) throws LWJGLException {
if (created)
throw new IllegalStateException("Destroy the Keyboard first.");
if (!initialized)
initialize();
implementation = impl;
implementation.createKeyboard();
created = true;
readBuffer = ByteBuffer.allocate(EVENT_SIZE*BUFFER_SIZE);
reset();
}
/**
* "Create" the keyboard. The display must first have been created. The
* reason for this is so the keyboard has a window to "focus" in.
@ -289,17 +307,7 @@ public class Keyboard {
* @throws LWJGLException if the keyboard could not be created for any reason
*/
public static void create() throws LWJGLException {
if (!Display.isCreated())
throw new IllegalStateException("Display must be created before you can create Keyboard");
if (!initialized)
initialize();
if (created)
return;
implementation = Mouse.getImplementation();
implementation.createKeyboard();
created = true;
readBuffer = ByteBuffer.allocate(EVENT_SIZE*BUFFER_SIZE);
reset();
create(Mouse.createImplementation());
}
private static void reset() {

View File

@ -40,8 +40,8 @@ import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.Sys;
import org.lwjgl.opengl.DisplayImplementation;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.InputImplementation;
import java.lang.reflect.Method;
import java.security.AccessController;
@ -57,7 +57,7 @@ import java.security.PrivilegedActionException;
* n buttons supported, n being a native limit. A scrolly wheel is also
* supported, if one such is available. Movement is reported as delta from
* last position or as an absolute position. If the window has been created
* the absolute position will be clamped to 0 - Display (width | height)
* the absolute position will be clamped to 0 - width | height.
*
* @author cix_foo <cix_foo@users.sourceforge.net>
* @author elias_naur <elias_naur@users.sourceforge.net>
@ -134,10 +134,10 @@ public class Mouse {
private static boolean isGrabbed;
private static DisplayImplementation implementation;
private static InputImplementation implementation;
/** Whether we're running windows - which need to manually update cursor animation */
private static final boolean isWindows = LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_WINDOWS;
/** Whether we're running windows - which need to manually update cursor animation */
private static final boolean isWindows = LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_WINDOWS;
/**
* Mouse cannot be constructed.
@ -220,13 +220,19 @@ public class Mouse {
readBuffer.position(readBuffer.limit());
}
static DisplayImplementation getImplementation() {
static InputImplementation getImplementation() {
return implementation;
}
static InputImplementation createImplementation() {
if (!Display.isCreated()) throw new IllegalStateException("Display must be created.");
/* Use reflection since we can't make Display.getImplementation
* public
*/
try {
return (DisplayImplementation)AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception{
return (InputImplementation)AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
Method getImplementation_method = Display.class.getDeclaredMethod("getImplementation", null);
getImplementation_method.setAccessible(true);
return getImplementation_method.invoke(null, null);
@ -238,19 +244,17 @@ public class Mouse {
}
/**
* "Create" the mouse. The display must first have been created.
* Initially, the mouse is not grabbed and the delta values are reported
* with respect to the center of the display.
* "Create" the mouse with the given custom implementation. This is used
* reflectively by AWTInputAdapter.
*
* @throws LWJGLException if the mouse could not be created for any reason
*/
public static void create() throws LWJGLException {
if (!Display.isCreated()) throw new IllegalStateException("Display must be created prior to creating mouse");
private static void create(InputImplementation impl) throws LWJGLException {
if (created)
throw new IllegalStateException("Destroy the mouse first.");
if (!initialized)
initialize();
if (created) return;
implementation = getImplementation();
implementation = impl;
implementation.createMouse();
hasWheel = implementation.hasWheel();
created = true;
@ -259,13 +263,24 @@ public class Mouse {
buttonCount = implementation.getButtonCount();
buttons = BufferUtils.createByteBuffer(buttonCount);
coord_buffer = BufferUtils.createIntBuffer(3);
if (currentCursor != null)
if (currentCursor != null && implementation.getNativeCursorCapabilities() != 0)
setNativeCursor(currentCursor);
readBuffer = ByteBuffer.allocate(EVENT_SIZE * BUFFER_SIZE);
readBuffer.limit(0);
setGrabbed(isGrabbed);
}
/**
* "Create" the mouse. The display must first have been created.
* Initially, the mouse is not grabbed and the delta values are reported
* with respect to the center of the display.
*
* @throws LWJGLException if the mouse could not be created for any reason
*/
public static void create() throws LWJGLException {
create(createImplementation());
}
/**
* @return true if the mouse has been created
*/
@ -327,8 +342,8 @@ public class Mouse {
x = poll_coord1;
y = poll_coord2;
}
x = Math.min(Display.getDisplayMode().getWidth() - 1, Math.max(0, x));
y = Math.min(Display.getDisplayMode().getHeight() - 1, Math.max(0, y));
x = Math.min(implementation.getWidth() - 1, Math.max(0, x));
y = Math.min(implementation.getHeight() - 1, Math.max(0, y));
dwheel += poll_dwheel;
read();
}
@ -404,8 +419,8 @@ public class Mouse {
event_x = new_event_x;
event_y = new_event_y;
}
event_x = Math.min(Display.getDisplayMode().getWidth() - 1, Math.max(0, event_x));
event_y = Math.min(Display.getDisplayMode().getHeight() - 1, Math.max(0, event_y));
event_x = Math.min(implementation.getWidth() - 1, Math.max(0, event_x));
event_y = Math.min(implementation.getHeight() - 1, Math.max(0, event_y));
event_dwheel = readBuffer.getInt();
event_nanos = readBuffer.getLong();
return true;
@ -476,8 +491,8 @@ public class Mouse {
}
/**
* Retrieves the absolute position. If the Display has been created
* x will be clamped to 0...width-1.
* Retrieves the absolute position. It will be clamped to
* 0...width-1.
*
* @return Absolute x axis position of mouse
*/
@ -486,8 +501,8 @@ public class Mouse {
}
/**
* Retrieves the absolute position. If the Display has been created
* y will be clamped to 0...height-1.
* Retrieves the absolute position. It will be clamped to
* 0...height-1.
*
* @return Absolute y axis position of mouse
*/

View File

@ -46,7 +46,7 @@ interface AWTCanvasImplementation {
/**
* Return an opaque handle to the canvas peer information required to create a context from it.
*/
public PeerInfo createPeerInfo(AWTGLCanvas canvas, PixelFormat pixel_format) throws LWJGLException;
PeerInfo createPeerInfo(AWTGLCanvas canvas, PixelFormat pixel_format) throws LWJGLException;
/**
* Find a proper GraphicsConfiguration from the given GraphicsDevice and PixelFormat.
@ -54,5 +54,13 @@ interface AWTCanvasImplementation {
* @return A GraphicsConfiguration matching the given GraphicsConfiguration and PixelFormat.
* @throws LWJGLException if no suitable configuration could be found.
*/
public GraphicsConfiguration findConfiguration(GraphicsDevice device, PixelFormat pixel_format) throws LWJGLException;
GraphicsConfiguration findConfiguration(GraphicsDevice device, PixelFormat pixel_format) throws LWJGLException;
/**
* Create an AWTCanvasInputImplementation for a specified AWTGLCanvas.
*
* @return A platform specific AWTCanvasInputImplementation.
* @param canvas An AWTGLCanvas
*/
AWTCanvasInputImplementation createInput(AWTGLCanvas canvas) throws LWJGLException;
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2002-2006 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;
import org.lwjgl.LWJGLException;
/**
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 2286 $
* $Id: AWTCanvasImplementation.java 2286 2006-03-23 19:32:21Z matzon $
*/
interface AWTCanvasInputImplementation extends InputImplementation {
void processInput(PeerInfo peer_info);
void update();
void init();
void destroy();
}

View File

@ -81,6 +81,9 @@ public class AWTGLCanvas extends Canvas implements Drawable, ComponentListener,
/** Tracks whether initGL() needs to be called */
private boolean first_run;
/** Track the input adapter, if any */
private volatile AWTCanvasInputImplementation awt_input;
static {
Sys.initialize();
String class_name;
@ -109,6 +112,16 @@ public class AWTGLCanvas extends Canvas implements Drawable, ComponentListener,
}
}
/**
* Used from AWTInputAdapter
*/
static AWTCanvasImplementation getImplementation() {
return implementation;
}
void setInput(AWTCanvasInputImplementation awt_input) {
this.awt_input = awt_input;
}
private void setUpdate() {
synchronized(SYNC_LOCK) {
@ -271,8 +284,9 @@ public class AWTGLCanvas extends Canvas implements Drawable, ComponentListener,
*/
public final void paint(Graphics g) {
try {
if (peer_info == null)
if (peer_info == null) {
this.peer_info = implementation.createPeerInfo(this, pixel_format);
}
peer_info.lockAndGetHandle();
try {
if (context == null) {
@ -288,6 +302,9 @@ public class AWTGLCanvas extends Canvas implements Drawable, ComponentListener,
context.update();
update_context = false;
}
AWTCanvasInputImplementation current_input = awt_input;
if (current_input != null)
current_input.processInput(peer_info);
if (first_run) {
first_run = false;
initGL();

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2002-2006 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;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Mouse;
import org.lwjgl.input.Keyboard;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.lang.reflect.Method;
import java.awt.Canvas;
/**
* This is the static class for using LWJGL input (Mouse and Keyboard)
* with an AWTGLCanvas.
*
* @author Elias Naur
* @version $Revision: 2286 $
* $Id: AWTCanvasImplementation.java 2286 2006-03-23 19:32:21Z matzon $
*/
public final class AWTInputAdapter {
private static AWTCanvasInputImplementation awt_input;
/**
* Create AWTInputAdapter with the specified AWTGLCanvas. Use
* update() to receive input.
*
* @param canvas The canvas to receive input from.
*/
public static synchronized void create(AWTGLCanvas canvas) throws LWJGLException {
if (awt_input != null)
throw new IllegalStateException("You need to destroy() the adapter.");
awt_input = AWTGLCanvas.getImplementation().createInput(canvas);
// Invoke Mouse.create(awt_input) and Keyboard.create(awt_input)
try {
AccessController.doPrivileged(new PrivilegedExceptionAction() {
private void invokeCreate(Class input_class) throws Exception {
Method create_method = input_class.getDeclaredMethod("create", new Class[]{InputImplementation.class});
create_method.setAccessible(true);
create_method.invoke(null, new Object[]{awt_input});
}
public Object run() throws Exception {
invokeCreate(Mouse.class);
invokeCreate(Keyboard.class);
return null;
}
});
} catch (PrivilegedActionException e) {
Throwable cause = e.getCause();
if (cause instanceof LWJGLException)
throw (LWJGLException)cause;
else
throw new Error(cause);
}
awt_input.init();
}
public static synchronized void destroy() {
if (awt_input != null) {
awt_input.destroy();
awt_input = null;
}
}
public static synchronized void update() {
if (awt_input == null)
throw new IllegalStateException("You need to create() the adapter.");
awt_input.update();
Display.pollDevices();
}
}

View File

@ -0,0 +1,167 @@
/*
* 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;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import java.awt.event.FocusListener;
import java.awt.Cursor;
/**
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 2586 $
* $Id: LinuxAWTGLCanvasPeerInfo.java 2586 2006-10-20 11:51:34Z elias_naur $
*/
abstract class AbstractAWTInput implements AWTCanvasInputImplementation {
private AWTGLCanvas canvas;
private volatile int current_height;
private volatile int current_width;
private KeyboardEventQueue keyboard_queue;
private MouseEventQueue mouse_queue;
private volatile boolean grab;
protected AbstractAWTInput(AWTGLCanvas canvas) throws LWJGLException {
this.canvas = canvas;
}
public synchronized void grabMouse(boolean grab) {
this.grab = grab;
if (mouse_queue != null)
mouse_queue.setGrabbed(grab);
}
protected boolean isGrabbed() {
return grab;
}
protected final AWTGLCanvas getCanvas() {
return canvas;
}
public final void init() {
canvas.setInput(this);
}
public synchronized void destroy() {
canvas.setInput(null);
canvas = null;
}
public final int getWidth() {
return current_width;
}
public final int getHeight() {
return current_height;
}
public synchronized void processInput(PeerInfo peer_info) {
current_width = canvas.getWidth();
current_height = canvas.getHeight();
}
public boolean hasWheel() {
return AWTUtil.hasWheel();
}
public int getButtonCount() {
return AWTUtil.getButtonCount();
}
public void createMouse() throws LWJGLException {
mouse_queue = new MouseEventQueue(canvas);
mouse_queue.register();
}
public void destroyMouse() {
mouse_queue.unregister();
}
public int getNativeCursorCapabilities() {
return AWTUtil.getNativeCursorCapabilities();
}
public void setCursorPosition(int x, int y) {
AWTUtil.setCursorPosition(canvas, x, y);
}
public void setNativeCursor(Object handle) throws LWJGLException {
canvas.setCursor((Cursor)handle);
}
public int getMinCursorSize() {
return AWTUtil.getMinCursorSize();
}
public int getMaxCursorSize() {
return AWTUtil.getMaxCursorSize();
}
public synchronized void createKeyboard() throws LWJGLException {
keyboard_queue = new KeyboardEventQueue(canvas);
keyboard_queue.register();
}
public synchronized void destroyKeyboard() {
if (keyboard_queue != null)
keyboard_queue.unregister();
}
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);
}
public void destroyCursor(Object cursor_handle) {
}
public synchronized void readMouse(ByteBuffer buffer) {
mouse_queue.copyEvents(buffer);
}
public synchronized void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons) {
mouse_queue.poll(coord_buffer, buttons);
}
public synchronized void readKeyboard(ByteBuffer buffer) {
keyboard_queue.copyEvents(buffer);
}
public synchronized void pollKeyboard(ByteBuffer keyDownBuffer) {
keyboard_queue.poll(keyDownBuffer);
}
}

View File

@ -44,7 +44,7 @@ import java.nio.IntBuffer;
import org.lwjgl.LWJGLException;
public interface DisplayImplementation {
interface DisplayImplementation extends InputImplementation {
void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException;
@ -124,88 +124,6 @@ public interface DisplayImplementation {
*/
DisplayMode[] getAvailableDisplayModes() throws LWJGLException;
/*
* Mouse methods
*/
/** Query of wheel support */
boolean hasWheel();
/** Query of button count */
int getButtonCount();
/**
* Method to create the mouse.
*/
void createMouse() throws LWJGLException;
/**
* Method the destroy the mouse
*/
void destroyMouse();
/**
* Method to poll the mouse
*/
void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons);
/**
* Method to read the keyboard buffer
*/
void readMouse(ByteBuffer buffer);
void grabMouse(boolean grab);
/**
* Function to determine native cursor support
*/
int getNativeCursorCapabilities();
/** Method to set the native cursor position */
void setCursorPosition(int x, int y);
/** Method to set the native cursor */
void setNativeCursor(Object handle) throws LWJGLException;
/** Method returning the minimum cursor size */
int getMinCursorSize();
/** Method returning the maximum cursor size */
int getMaxCursorSize();
/*
* Keyboard methods
*/
/**
* Method to create the keyboard
*/
void createKeyboard() throws LWJGLException;
/**
* Method to destroy the keyboard
*/
void destroyKeyboard();
/**
* Method to poll the keyboard.
*
* @param keyDownBuffer the address of a 256-byte buffer to place
* key states in.
*/
void pollKeyboard(ByteBuffer keyDownBuffer);
/**
* Method to read the keyboard buffer
*/
void readKeyboard(ByteBuffer buffer);
// int isStateKeySet(int key);
/** Native cursor handles */
Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException;
void destroyCursor(Object cursor_handle);
/* Pbuffer */
int getPbufferCapabilities();

View File

@ -0,0 +1,133 @@
/*
* 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 input implementation interface. Mouse and Keyboard delegates
* to implementors of this interface. There is one InputImplementation
* for each supported platform.
* @author elias_naur
*/
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.LWJGLException;
public interface InputImplementation {
/*
* Mouse methods
*/
/** Query of wheel support */
boolean hasWheel();
/** Query of button count */
int getButtonCount();
/**
* Method to create the mouse.
*/
void createMouse() throws LWJGLException;
/**
* Method the destroy the mouse
*/
void destroyMouse();
/**
* Method to poll the mouse
*/
void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons);
/**
* Method to read the keyboard buffer
*/
void readMouse(ByteBuffer buffer);
void grabMouse(boolean grab);
/**
* Function to determine native cursor support
*/
int getNativeCursorCapabilities();
/** Method to set the native cursor position */
void setCursorPosition(int x, int y);
/** Method to set the native cursor */
void setNativeCursor(Object handle) throws LWJGLException;
/** Method returning the minimum cursor size */
int getMinCursorSize();
/** Method returning the maximum cursor size */
int getMaxCursorSize();
/*
* Keyboard methods
*/
/**
* Method to create the keyboard
*/
void createKeyboard() throws LWJGLException;
/**
* Method to destroy the keyboard
*/
void destroyKeyboard();
/**
* Method to poll the keyboard.
*
* @param keyDownBuffer the address of a 256-byte buffer to place
* key states in.
*/
void pollKeyboard(ByteBuffer keyDownBuffer);
/**
* Method to read the keyboard buffer
*/
void readKeyboard(ByteBuffer buffer);
// int isStateKeySet(int key);
/** Native cursor handles */
Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException;
void destroyCursor(Object cursor_handle);
int getWidth();
int getHeight();
}

View File

@ -32,8 +32,7 @@
package org.lwjgl.opengl;
/**
* A java implementation of a LWJGL compatible Keyboard event queue.
* Currently only used by the Mac OS X implementation.
* An AWT implementation of a LWJGL compatible Keyboard event queue.
* @author elias_naur
*/

View File

@ -0,0 +1,233 @@
/*
* 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;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import java.awt.event.FocusEvent;
/**
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 2586 $
* $Id: LinuxAWTGLCanvasPeerInfo.java 2586 2006-10-20 11:51:34Z elias_naur $
*/
final class LinuxAWTInput extends AbstractAWTInput {
private final long display;
private final long input_window;
private final LinuxEvent event = new LinuxEvent();
private long cached_window;
private LinuxMouse cached_mouse;
// private LinuxKeyboard cached_keyboard;
private long blank_cursor = LinuxDisplay.None;
private boolean input_grabbed;
private boolean input_released;
public LinuxAWTInput(AWTGLCanvas canvas) throws LWJGLException {
super(canvas);
LinuxDisplay.lockAWT();
try {
this.display = LinuxDisplay.openDisplay();
this.input_window = createInputOnlyWindow(display, LinuxDisplay.nGetDefaultScreen(display));
} finally {
LinuxDisplay.unlockAWT();
}
}
private static native long createInputOnlyWindow(long display, int screen);
public synchronized void destroy() {
super.destroy();
LinuxDisplay.lockAWT();
try {
destroyCursor();
LinuxDisplay.nDestroyWindow(display, input_window);
LinuxDisplay.closeDisplay(display);
} finally {
LinuxDisplay.unlockAWT();
}
}
private void ungrabInputLocked() {
LinuxDisplay.lockAWT();
try {
ungrabInput();
} finally {
LinuxDisplay.unlockAWT();
}
}
private void ungrabInput() {
if (input_grabbed) {
// LinuxDisplay.nUngrabKeyboard(display);
LinuxDisplay.nUngrabPointer(display);
LinuxDisplay.nSetRepeatMode(display, LinuxDisplay.AutoRepeatModeDefault);
input_grabbed = false;
}
}
private void grabInput(long window) {
if (!input_grabbed) {
// int res1 = LinuxDisplay.nGrabKeyboard(display, window);
LinuxDisplay.nSetRepeatMode(display, LinuxDisplay.AutoRepeatModeOff);
int res2 = LinuxDisplay.nGrabPointer(display, window, blank_cursor);
if (/*res1 == LinuxDisplay.GrabSuccess && */res2 == LinuxDisplay.GrabSuccess)
input_grabbed = true;
}
}
private final void destroyCursor() {
if (blank_cursor != LinuxDisplay.None)
LinuxDisplay.nDestroyCursor(display, blank_cursor);
}
public synchronized void processInput(PeerInfo peer_info) {
super.processInput(peer_info);
LinuxDisplay.lockAWT();
try {
LinuxPeerInfo linux_peer_info = (LinuxPeerInfo)peer_info;
long new_window = linux_peer_info.getDrawable();
if (new_window != cached_window) {
ungrabInput();
cached_window = new_window;
try {
cached_mouse = new LinuxMouse(display, new_window, input_window);
// cached_keyboard = new LinuxKeyboard(display, new_window);
} catch (LWJGLException e) {
LWJGLUtil.log("Failed to create input devices: " + e);
}
destroyCursor();
this.blank_cursor = LinuxDisplay.nCreateBlankCursor(display, new_window);
}
checkFocus();
if (!input_grabbed && shouldGrab())
grabInput(new_window);
} finally {
LinuxDisplay.unlockAWT();
}
}
private void checkFocus() {
if (getCanvas().hasFocus()) {
input_released = false;
} else {
input_released = true;
ungrabInput();
}
}
private boolean shouldGrab() {
return !input_released && isGrabbed();
}
public synchronized void update() {
LinuxDisplay.lockAWT();
try {
while (LinuxEvent.getPending(display) > 0) {
event.nextEvent(display);
if (shouldGrab()) {
long event_window = event.getWindow();
boolean processed = event.filterEvent(event_window) ||
cached_mouse.filterEvent(isGrabbed(), shouldGrab(), event)/* ||
cached_keyboard.filterEvent(event)*/;
}
}
} finally {
LinuxDisplay.unlockAWT();
}
}
public synchronized void grabMouse(boolean grab) {
if (grab != isGrabbed()) {
super.grabMouse(grab);
if (cached_mouse != null)
cached_mouse.changeGrabbed(grab, shouldGrab());
ungrabInputLocked();
}
}
/* public synchronized void pollKeyboard(ByteBuffer keyDownBuffer) {
if (isGrabbed()) {
LinuxDisplay.lockAWT();
try {
if (cached_keyboard != null)
cached_keyboard.poll(keyDownBuffer);
} finally {
LinuxDisplay.unlockAWT();
}
} else
super.pollKeyboard(keyDownBuffer);
}
public synchronized void readKeyboard(ByteBuffer buffer) {
if (isGrabbed()) {
LinuxDisplay.lockAWT();
try {
if (cached_keyboard != null)
cached_keyboard.read(buffer);
} finally {
LinuxDisplay.unlockAWT();
}
} else
super.readKeyboard(buffer);
}
*/
public synchronized void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons) {
if (isGrabbed()) {
LinuxDisplay.lockAWT();
try {
if (cached_mouse != null)
cached_mouse.poll(isGrabbed(), coord_buffer, buttons);
} finally {
LinuxDisplay.unlockAWT();
}
} else
super.pollMouse(coord_buffer, buttons);
}
public synchronized void readMouse(ByteBuffer buffer) {
if (isGrabbed()) {
LinuxDisplay.lockAWT();
try {
if (cached_mouse != null)
cached_mouse.read(buffer);
} finally {
LinuxDisplay.unlockAWT();
}
} else
super.readMouse(buffer);
}
}

View File

@ -119,4 +119,8 @@ final class LinuxCanvasImplementation implements AWTCanvasImplementation {
}
}
private static native int nFindVisualIDFromFormat(long display, int screen, PixelFormat pixel_format) throws LWJGLException;
public AWTCanvasInputImplementation createInput(AWTGLCanvas canvas) throws LWJGLException {
return new LinuxAWTInput(canvas);
}
}

View File

@ -50,9 +50,9 @@ import org.lwjgl.input.Keyboard;
final class LinuxDisplay implements DisplayImplementation {
/* X11 constants */
public final static int GrabSuccess = 0;
private final static int AutoRepeatModeOff = 0;
private final static int AutoRepeatModeOn = 1;
private final static int AutoRepeatModeDefault = 2;
public final static int AutoRepeatModeOff = 0;
public final static int AutoRepeatModeOn = 1;
public final static int AutoRepeatModeDefault = 2;
public final static int None = 0;
/** Window mode enum */
@ -754,7 +754,7 @@ final class LinuxDisplay implements DisplayImplementation {
releaseInput();
}
}
private static native long nGetInputFocus(long display);
static native long nGetInputFocus(long display);
private void releaseInput() {
if (isLegacyFullscreen() || input_released)
@ -789,7 +789,7 @@ final class LinuxDisplay implements DisplayImplementation {
}
}
}
private static native void nSetRepeatMode(long display, int mode);
static native void nSetRepeatMode(long display, int mode);
public void grabMouse(boolean new_grab) {
lockAWT();
@ -1054,4 +1054,12 @@ final class LinuxDisplay implements DisplayImplementation {
}
private static native void nSetWindowIcon(long display, long window, ByteBuffer icon, int icons_size, int width, int height);
public int getWidth() {
return Display.getDisplayMode().getWidth();
}
public int getHeight() {
return Display.getDisplayMode().getHeight();
}
}

View File

@ -44,4 +44,14 @@ abstract class LinuxPeerInfo extends PeerInfo {
super(createHandle());
}
private static native ByteBuffer createHandle();
public final long getDisplay() {
return nGetDisplay(getHandle());
}
private static native long nGetDisplay(ByteBuffer handle);
public final long getDrawable() {
return nGetDrawable(getHandle());
}
private static native long nGetDrawable(ByteBuffer handle);
}

View File

@ -62,4 +62,8 @@ final class MacOSXCanvasImplementation implements AWTCanvasImplementation {
*/
return null;
}
public AWTCanvasInputImplementation createInput(AWTGLCanvas canvas) throws LWJGLException {
throw new UnsupportedOperationException();
}
}

View File

@ -303,7 +303,7 @@ final class MacOSXDisplay implements DisplayImplementation {
public void createMouse() throws LWJGLException {
MacOSXGLCanvas canvas = frame.getCanvas();
this.mouse_queue = new MouseEventQueue(canvas);
this.mouse_queue = new MacOSXMouseEventQueue(canvas);
mouse_queue.register();
}
@ -520,4 +520,12 @@ final class MacOSXDisplay implements DisplayImplementation {
return 1;
}
public int getWidth() {
return Display.getDisplayMode().getWidth();
}
public int getHeight() {
return Display.getDisplayMode().getHeight();
}
}

View File

@ -0,0 +1,76 @@
/*
* 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;
/**
* An AWT implementation of a LWJGL compatible Mouse event queue.
* @author elias_naur
*/
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.Component;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Mouse;
final class MacOSXMouseEventQueue extends MouseEventQueue {
private final IntBuffer delta_buffer = BufferUtils.createIntBuffer(2);
MacOSXMouseEventQueue(Component component) {
super(component);
}
protected void resetCursorToCenter() {
super.resetCursorToCenter();
/* Clear accumulated deltas */
((MacOSXDisplay)Display.getImplementation()).getMouseDeltas(delta_buffer);
}
protected void updateDeltas(long nanos) {
super.updateDeltas(nanos);
synchronized ( this ) {
((MacOSXDisplay)Display.getImplementation()).getMouseDeltas(delta_buffer);
int dx = delta_buffer.get(0);
int dy = -delta_buffer.get(1);
if ( dx != 0 || dy != 0 ) {
putMouseEventWithCoords((byte)-1, (byte)0, dx, dy, 0, nanos);
addDelta(dx, dy);
}
}
}
}

View File

@ -48,7 +48,7 @@ import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Mouse;
final class MouseEventQueue extends EventQueue implements MouseListener, MouseMotionListener, MouseWheelListener {
class MouseEventQueue extends EventQueue implements MouseListener, MouseMotionListener, MouseWheelListener {
private static final int WHEEL_SCALE = 120;
public static final int NUM_BUTTONS = 3;
@ -56,7 +56,6 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo
private boolean grabbed;
private final IntBuffer delta_buffer = BufferUtils.createIntBuffer(2);
/** The accumulated mouse deltas returned by poll() */
private int accum_dx;
@ -107,11 +106,9 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo
return component.getHeight() - 1 - y;
}
private void resetCursorToCenter() {
protected void resetCursorToCenter() {
clearEvents();
accum_dx = accum_dy = 0;
/* Clear accumulated deltas */
((MacOSXDisplay)Display.getImplementation()).getMouseDeltas(delta_buffer);
}
private void putMouseEvent(byte button, byte state, int dz, long nanos) {
@ -121,7 +118,7 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo
putMouseEventWithCoords(button, state, last_x, last_y, dz, nanos);
}
private void putMouseEventWithCoords(byte button, byte state, int coord1, int coord2, int dz, long 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();
@ -149,13 +146,17 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo
return;
int dx = x - last_x;
int dy = y - last_y;
accum_dx += dx;
accum_dy += dy;
addDelta(dx, dy);
last_x = x;
last_y = y;
putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0, nanos);
}
protected void addDelta(int dx, int dy) {
accum_dx += dx;
accum_dy += dy;
}
public void mouseClicked(MouseEvent e) {
}
@ -242,19 +243,7 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo
putMouseEvent((byte)-1, (byte)0, amount, nanos);
}
private void updateDeltas(long nanos) {
if (!grabbed)
return;
synchronized ( this ) {
((MacOSXDisplay)Display.getImplementation()).getMouseDeltas(delta_buffer);
int dx = delta_buffer.get(0);
int dy = -delta_buffer.get(1);
if ( dx != 0 || dy != 0 ) {
putMouseEventWithCoords((byte)-1, (byte)0, dx, dy, 0, nanos);
accum_dx += dx;
accum_dy += dy;
}
}
protected void updateDeltas(long nanos) {
}
public void mouseWheelMoved(MouseWheelEvent e) {

View File

@ -65,6 +65,10 @@ final class WindowsCanvasImplementation implements AWTCanvasImplementation {
});
}
public AWTCanvasInputImplementation createInput(AWTGLCanvas canvas) throws LWJGLException {
throw new UnsupportedOperationException();
}
public PeerInfo createPeerInfo(AWTGLCanvas canvas, PixelFormat pixel_format) throws LWJGLException {
return new WindowsAWTGLCanvasPeerInfo(canvas, pixel_format);
}

View File

@ -589,4 +589,12 @@ final class WindowsDisplay implements DisplayImplementation {
return new WindowsDirectInput3(getDllInstance());
}
}
public int getWidth() {
return Display.getDisplayMode().getWidth();
}
public int getHeight() {
return Display.getDisplayMode().getHeight();
}
}

View File

@ -0,0 +1,369 @@
/*
* Copyright (c) 2002-2005 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.test.opengl.awt;
import java.awt.Frame;
import java.awt.Color;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Mouse;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.ARBTransposeMatrix;
import org.lwjgl.opengl.AWTGLCanvas;
import org.lwjgl.opengl.AWTInputAdapter;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GLContext;
/**
* <p>
* Gears demo using AWTInputAdapter input
* <p>
* @version $Revision$
* @author Brian Matzon <brian@matzon.dk>
* @author Elias Naur <elias_naur@users.sourceforge.net>
* $Id$
*/
public class AWTInputAdapterTest extends Frame {
/** AWT GL canvas */
private AWTGLCanvas canvas0;
private float view_rotx = 20.0f;
private float view_roty = 30.0f;
private float view_rotz = 0.0f;
private int gear1;
private int gear2;
private int gear3;
private float angle = 0.0f;
/**
* C'tor
*/
public AWTInputAdapterTest() throws LWJGLException {
setTitle("Gears");
setSize(300, 300);
setBackground(Color.BLACK);
add(canvas0 = new AWTGLCanvas() {
long startTime = 0;
long fps = 0;
int current_width;
int current_height;
public void paintGL() {
if(startTime == 0) {
setup();
startTime = System.currentTimeMillis() + 5000;
}
try {
angle += 2.0f;
if (getWidth() != current_width || getHeight() != current_height) {
current_width = getWidth();
current_height = getHeight();
GL11.glViewport(0, 0, current_width, current_height);
}
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glPushMatrix();
GL11.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f);
GL11.glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
GL11.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
GL11.glPushMatrix();
GL11.glTranslatef(-3.0f, -2.0f, 0.0f);
GL11.glRotatef(angle, 0.0f, 0.0f, 1.0f);
GL11.glCallList(gear1);
GL11.glPopMatrix();
GL11.glPushMatrix();
GL11.glTranslatef(3.1f, -2.0f, 0.0f);
GL11.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f);
GL11.glCallList(gear2);
GL11.glPopMatrix();
GL11.glPushMatrix();
GL11.glTranslatef(-3.1f, 4.2f, 0.0f);
GL11.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f);
GL11.glCallList(gear3);
GL11.glPopMatrix();
GL11.glPopMatrix();
swapBuffers();
repaint();
} catch (LWJGLException e) {
throw new RuntimeException(e);
}
if (startTime > System.currentTimeMillis()) {
fps++;
} else {
long timeUsed = 5000 + (startTime - System.currentTimeMillis());
startTime = System.currentTimeMillis() + 5000;
System.out.println(fps + " frames in " + (float) (timeUsed / 1000f) + " seconds = "
+ (fps / (timeUsed / 1000f)));
fps = 0;
}
AWTInputAdapter.update();
while (Mouse.next()) {
view_roty += Mouse.getEventDX()*.1;
view_rotx -= Mouse.getEventDY()*.1;
}
while (Keyboard.next()) {
if (Keyboard.getEventKeyState()) {
switch (Keyboard.getEventKey()) {
case Keyboard.KEY_ESCAPE:
System.exit(0);
break;
case Keyboard.KEY_G:
Mouse.setGrabbed(!Mouse.isGrabbed());
break;
default:
break;
}
}
if (Keyboard.getEventCharacter() != Keyboard.CHAR_NONE)
System.out.println("Typed: " + Keyboard.getEventCharacter());
}
if (Keyboard.isKeyDown(Keyboard.KEY_UP))
view_rotx -= .1;
else if (Keyboard.isKeyDown(Keyboard.KEY_DOWN))
view_rotx += .1;
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT))
view_roty -= .1;
else if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
view_roty += .1;
}
});
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
});
AWTInputAdapter.create(canvas0);
canvas0.setFocusable(true);
canvas0.requestFocus();
setResizable(true);
setVisible(true);
}
private void setup() {
// setup ogl
FloatBuffer pos = BufferUtils.createFloatBuffer(4).put(new float[] { 5.0f, 5.0f, 10.0f, 0.0f});
FloatBuffer red = BufferUtils.createFloatBuffer(4).put(new float[] { 0.8f, 0.1f, 0.0f, 1.0f});
FloatBuffer green = BufferUtils.createFloatBuffer(4).put(new float[] { 0.0f, 0.8f, 0.2f, 1.0f});
FloatBuffer blue = BufferUtils.createFloatBuffer(4).put(new float[] { 0.2f, 0.2f, 1.0f, 1.0f});
pos.flip();
red.flip();
green.flip();
blue.flip();
GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, pos);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_LIGHT0);
GL11.glEnable(GL11.GL_DEPTH_TEST);
/* make the gears */
gear1 = GL11.glGenLists(1);
GL11.glNewList(gear1, GL11.GL_COMPILE);
GL11.glMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT_AND_DIFFUSE, red);
gear(1.0f, 4.0f, 1.0f, 20, 0.7f);
GL11.glEndList();
gear2 = GL11.glGenLists(1);
GL11.glNewList(gear2, GL11.GL_COMPILE);
GL11.glMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT_AND_DIFFUSE, green);
gear(0.5f, 2.0f, 2.0f, 10, 0.7f);
GL11.glEndList();
gear3 = GL11.glGenLists(1);
GL11.glNewList(gear3, GL11.GL_COMPILE);
GL11.glMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT_AND_DIFFUSE, blue);
gear(1.3f, 2.0f, 0.5f, 10, 0.7f);
GL11.glEndList();
GL11.glEnable(GL11.GL_NORMALIZE);
GL11.glMatrixMode(GL11.GL_PROJECTION);
System.err.println("Use the arrow keys and the mouse to rotate the gears. Press 'G' to toggle mouse grabbing.");
System.err.println("GL_VENDOR: " + GL11.glGetString(GL11.GL_VENDOR));
System.err.println("GL_RENDERER: " + GL11.glGetString(GL11.GL_RENDERER));
System.err.println("GL_VERSION: " + GL11.glGetString(GL11.GL_VERSION));
System.err.println();
System.err.println("glLoadTransposeMatrixfARB() supported: " + GLContext.getCapabilities().GL_ARB_transpose_matrix);
if (!GLContext.getCapabilities().GL_ARB_transpose_matrix) {
// --- not using extensions
GL11.glLoadIdentity();
} else {
// --- using extensions
final FloatBuffer identityTranspose = BufferUtils.createFloatBuffer(16).put(
new float[] { 1, 0, 0, 0, 0, 1, 0, 0,
0, 0, 1, 0, 0, 0, 0, 1});
identityTranspose.flip();
ARBTransposeMatrix.glLoadTransposeMatrixARB(identityTranspose);
}
float h = (float) 300 / (float) 300;
GL11.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glTranslatef(0.0f, 0.0f, -40.0f);
}
/**
* Draw a gear wheel. You'll probably want to call this function when
* building a display list since we do a lot of trig here.
*
* @param inner_radius radius of hole at center
* @param outer_radius radius at center of teeth
* @param width width of gear
* @param teeth number of teeth
* @param tooth_depth depth of tooth
*/
private void gear(float inner_radius, float outer_radius, float width, int teeth, float tooth_depth) {
int i;
float r0, r1, r2;
float angle, da;
float u, v, len;
r0 = inner_radius;
r1 = outer_radius - tooth_depth / 2.0f;
r2 = outer_radius + tooth_depth / 2.0f;
da = 2.0f * (float) Math.PI / teeth / 4.0f;
GL11.glShadeModel(GL11.GL_FLAT);
GL11.glNormal3f(0.0f, 0.0f, 1.0f);
/* draw front face */
GL11.glBegin(GL11.GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0f * (float) Math.PI / teeth;
GL11.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), width * 0.5f);
GL11.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), width * 0.5f);
if (i < teeth) {
GL11.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), width * 0.5f);
GL11.glVertex3f(r1 * (float) Math.cos(angle + 3.0f * da), r1 * (float) Math.sin(angle + 3.0f * da),
width * 0.5f);
}
}
GL11.glEnd();
/* draw front sides of teeth */
GL11.glBegin(GL11.GL_QUADS);
for (i = 0; i < teeth; i++) {
angle = i * 2.0f * (float) Math.PI / teeth;
GL11.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), width * 0.5f);
GL11.glVertex3f(r2 * (float) Math.cos(angle + da), r2 * (float) Math.sin(angle + da), width * 0.5f);
GL11.glVertex3f(r2 * (float) Math.cos(angle + 2.0f * da), r2 * (float) Math.sin(angle + 2.0f * da), width * 0.5f);
GL11.glVertex3f(r1 * (float) Math.cos(angle + 3.0f * da), r1 * (float) Math.sin(angle + 3.0f * da), width * 0.5f);
}
GL11.glEnd();
/* draw back face */
GL11.glBegin(GL11.GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0f * (float) Math.PI / teeth;
GL11.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), -width * 0.5f);
GL11.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), -width * 0.5f);
GL11.glVertex3f(r1 * (float) Math.cos(angle + 3 * da), r1 * (float) Math.sin(angle + 3 * da), -width * 0.5f);
GL11.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), -width * 0.5f);
}
GL11.glEnd();
/* draw back sides of teeth */
GL11.glBegin(GL11.GL_QUADS);
for (i = 0; i < teeth; i++) {
angle = i * 2.0f * (float) Math.PI / teeth;
GL11.glVertex3f(r1 * (float) Math.cos(angle + 3 * da), r1 * (float) Math.sin(angle + 3 * da), -width * 0.5f);
GL11.glVertex3f(r2 * (float) Math.cos(angle + 2 * da), r2 * (float) Math.sin(angle + 2 * da), -width * 0.5f);
GL11.glVertex3f(r2 * (float) Math.cos(angle + da), r2 * (float) Math.sin(angle + da), -width * 0.5f);
GL11.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), -width * 0.5f);
}
GL11.glEnd();
/* draw outward faces of teeth */
GL11.glBegin(GL11.GL_QUAD_STRIP);
for (i = 0; i < teeth; i++) {
angle = i * 2.0f * (float) Math.PI / teeth;
GL11.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), width * 0.5f);
GL11.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), -width * 0.5f);
u = r2 * (float) Math.cos(angle + da) - r1 * (float) Math.cos(angle);
v = r2 * (float) Math.sin(angle + da) - r1 * (float) Math.sin(angle);
len = (float) Math.sqrt(u * u + v * v);
u /= len;
v /= len;
GL11.glNormal3f(v, -u, 0.0f);
GL11.glVertex3f(r2 * (float) Math.cos(angle + da), r2 * (float) Math.sin(angle + da), width * 0.5f);
GL11.glVertex3f(r2 * (float) Math.cos(angle + da), r2 * (float) Math.sin(angle + da), -width * 0.5f);
GL11.glNormal3f((float) Math.cos(angle), (float) Math.sin(angle), 0.0f);
GL11.glVertex3f(r2 * (float) Math.cos(angle + 2 * da), r2 * (float) Math.sin(angle + 2 * da), width * 0.5f);
GL11.glVertex3f(r2 * (float) Math.cos(angle + 2 * da), r2 * (float) Math.sin(angle + 2 * da), -width * 0.5f);
u = r1 * (float) Math.cos(angle + 3 * da) - r2 * (float) Math.cos(angle + 2 * da);
v = r1 * (float) Math.sin(angle + 3 * da) - r2 * (float) Math.sin(angle + 2 * da);
GL11.glNormal3f(v, -u, 0.0f);
GL11.glVertex3f(r1 * (float) Math.cos(angle + 3 * da), r1 * (float) Math.sin(angle + 3 * da), width * 0.5f);
GL11.glVertex3f(r1 * (float) Math.cos(angle + 3 * da), r1 * (float) Math.sin(angle + 3 * da), -width * 0.5f);
GL11.glNormal3f((float) Math.cos(angle), (float) Math.sin(angle), 0.0f);
}
GL11.glVertex3f(r1 * (float) Math.cos(0), r1 * (float) Math.sin(0), width * 0.5f);
GL11.glVertex3f(r1 * (float) Math.cos(0), r1 * (float) Math.sin(0), -width * 0.5f);
GL11.glEnd();
GL11.glShadeModel(GL11.GL_SMOOTH);
/* draw inside radius cylinder */
GL11.glBegin(GL11.GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0f * (float) Math.PI / teeth;
GL11.glNormal3f(-(float) Math.cos(angle), -(float) Math.sin(angle), 0.0f);
GL11.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), -width * 0.5f);
GL11.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), width * 0.5f);
}
GL11.glEnd();
}
public static void main(String[] args) throws LWJGLException {
new AWTInputAdapterTest();
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.
*/
/**
* $Id: org_lwjgl_opengl_LinuxEvent.c 2598 2006-10-24 08:33:09Z elias_naur $
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision: 2598 $
*/
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <jni.h>
#include "common_tools.h"
#include "org_lwjgl_opengl_LinuxAWTInput.h"
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxAWTInput_createInputOnlyWindow(JNIEnv *env, jclass unused, jlong display_ptr, jint screen) {
Display *disp = (Display *)(intptr_t)display_ptr;
Window window = XCreateWindow(disp, RootWindow(disp, screen), 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, 0, NULL);
return window;
}

View File

@ -46,3 +46,13 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_LinuxPeerInfo_createHandle
(JNIEnv *env, jclass clazz) {
return newJavaManagedByteBuffer(env, sizeof(X11PeerInfo));
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxPeerInfo_nGetDisplay(JNIEnv *env, jclass unused, jobject handle) {
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, handle);
return (jlong)(intptr_t)peer_info->display;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxPeerInfo_nGetDrawable(JNIEnv *env, jclass unused, jobject handle) {
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, handle);
return peer_info->drawable;
}