diff --git a/build.xml b/build.xml index 99f17fae..4b707e8e 100644 --- a/build.xml +++ b/build.xml @@ -4,8 +4,8 @@ - - + + @@ -137,7 +137,7 @@ - + @@ -159,7 +159,7 @@ - + @@ -254,7 +254,7 @@ - + @@ -301,7 +301,7 @@ - + @@ -325,6 +325,13 @@ + + + + + + + @@ -342,7 +349,6 @@ - diff --git a/src/java/org/lwjgl/input/Keyboard.java b/src/java/org/lwjgl/input/Keyboard.java index ed85da0c..7357d0be 100644 --- a/src/java/org/lwjgl/input/Keyboard.java +++ b/src/java/org/lwjgl/input/Keyboard.java @@ -290,15 +290,10 @@ public class Keyboard { initialize(); if (created) return; - nCreate(); + Display.getImplementation().createKeyboard(); created = true; } - /** - * Native method to create the keyboard - */ - private static native void nCreate() throws LWJGLException; - /** * @return true if the keyboard has been created */ @@ -313,14 +308,9 @@ public class Keyboard { if (!created) return; created = false; - nDestroy(); + Display.getImplementation().destroyKeyboard(); } - /** - * Native method to destroy the keyboard - */ - private static native void nDestroy(); - /** * Polls the keyboard for its current state. Access the polled values using the * isKeyDown method. @@ -346,32 +336,18 @@ public class Keyboard { public static void poll() { if (!created) throw new IllegalStateException("Keyboard must be created before you can poll the device"); - nPoll(keyDownBuffer); + Display.getImplementation().pollKeyboard(keyDownBuffer); if (readBuffer != null) read(); } private static void read() { readBuffer.compact(); - int numEvents = nRead(readBuffer, readBuffer.position()); + int numEvents = Display.getImplementation().readKeyboard(readBuffer, readBuffer.position()); readBuffer.position(readBuffer.position() + numEvents*EVENT_SIZE); readBuffer.flip(); } - /** - * Native method to poll the keyboard. - * - * @param keyDownBufferAddress the address of a 256-byte buffer to place - * key states in. - */ - private static native void nPoll(ByteBuffer keyDownBuffer); - - /** - * Native method to read the keyboard buffer - * @return the total number of events read. - */ - private static native int nRead(IntBuffer buffer, int buffer_position); - /** * Enable keyboard translation. Must be called after the keyboard is created, * and keyboard buffering must be enabled. @@ -381,15 +357,10 @@ public class Keyboard { throw new IllegalStateException("Keyboard must be created before you can read events"); if (readBuffer == null) throw new IllegalStateException("Event buffering must be enabled before you can read events"); - nEnableTranslation(); + Display.getImplementation().enableTranslation(); translationEnabled = true; } - /** - * Native method to enable the translation buffer - */ - private static native void nEnableTranslation() throws LWJGLException; - /** * Enable keyboard buffering. Must be called after the keyboard is created. */ @@ -398,16 +369,9 @@ public class Keyboard { throw new IllegalStateException("Keyboard must be created before you can enable buffering"); readBuffer = BufferUtils.createIntBuffer(EVENT_SIZE*BUFFER_SIZE); readBuffer.limit(0); - nEnableBuffer(); + Display.getImplementation().enableKeyboardBuffer(); } - /** - * Native method to enable the buffer - * @return the event buffer, - * or null if no buffer can be allocated - */ - private static native void nEnableBuffer() throws LWJGLException; - /** * Checks to see if a key is down. * @param key Keycode to check @@ -442,10 +406,9 @@ public class Keyboard { public static int isStateKeySet(int key) { if (!created) throw new IllegalStateException("Keyboard must be created before you can query key state"); - return nisStateKeySet(key); + return Display.getImplementation().isStateKeySet(key); } - private static native int nisStateKeySet(int key); - + /** * Gets a key's name * @param key The key diff --git a/src/java/org/lwjgl/input/Mouse.java b/src/java/org/lwjgl/input/Mouse.java index 33f4136d..03f6010b 100644 --- a/src/java/org/lwjgl/input/Mouse.java +++ b/src/java/org/lwjgl/input/Mouse.java @@ -174,14 +174,9 @@ public class Mouse { * @return A bit mask with native cursor capabilities. */ public static int getNativeCursorCaps() { - return nGetNativeCursorCaps(); + return Display.getImplementation().getNativeCursorCaps(); } - /** - * Native function to determine native cursor support - */ - private static native int nGetNativeCursorCaps(); - /** * Binds a native cursor. If the cursor argument is null, the * native cursor is disabled, as if native cursors were not supported. @@ -204,18 +199,15 @@ public class Mouse { currentCursor = cursor; if (isCreated()) { if (currentCursor != null) { - nSetNativeCursor(currentCursor.getHandle()); + Display.getImplementation().setNativeCursor(currentCursor.getHandle()); currentCursor.setTimeout(); } else { - nSetNativeCursor(null); + Display.getImplementation().setNativeCursor(null); } } return oldCursor; } - /** Native method to set the native cursor */ - private static native void nSetNativeCursor(ByteBuffer handle) throws LWJGLException; - /** * Gets the minimum size of a native cursor. Can only be called if * The Mouse is created and cursor caps includes at least @@ -224,12 +216,9 @@ public class Mouse { * @return the maximum size of a native cursor */ public static int getMinCursorSize() { - return nGetMinCursorSize(); + return Display.getImplementation().getMinCursorSize(); } - /** Native method returning the minimum cursor size */ - private static native int nGetMinCursorSize(); - /** * Gets the maximum size of a native cursor. Can only be called if * The Mouse is created and cursor caps includes at least @@ -238,12 +227,9 @@ public class Mouse { * @return the maximum size of a native cursor */ public static int getMaxCursorSize() { - return nGetMaxCursorSize(); + return Display.getImplementation().getMaxCursorSize(); } - /** Native method returning the maximum cursor size */ - private static native int nGetMaxCursorSize(); - /** * Static initialization */ @@ -281,31 +267,18 @@ public class Mouse { if (!initialized) initialize(); if (created) { return; } - nCreate(); - hasWheel = nHasWheel(); + Display.getImplementation().createMouse(); + hasWheel = Display.getImplementation().hasWheel(); created = true; - + // set mouse buttons - buttonCount = nGetButtonCount(); + buttonCount = Display.getImplementation().getButtonCount(); buttons = BufferUtils.createByteBuffer(buttonCount); coord_buffer = BufferUtils.createIntBuffer(3); setNativeCursor(currentCursor); setGrabbed(isGrabbed); } - /** Native query of wheel support */ - private static native boolean nHasWheel(); - - /** Native query of button count */ - private static native int nGetButtonCount(); - - /** - * Native method to create the mouse. - * - * @return true if the mouse was created - */ - private static native void nCreate(); - /** * @return true if the mouse has been created */ @@ -329,14 +302,9 @@ public class Mouse { buttons = null; coord_buffer = null; - nDestroy(); + Display.getImplementation().destroyMouse(); } - /** - * Native method the destroy the mouse - */ - private static native void nDestroy(); - /** * Polls the mouse for its current state. Access the polled values using the * get methods. @@ -363,7 +331,7 @@ public class Mouse { */ public static void poll() { if (!created) throw new IllegalStateException("Mouse must be created before you can poll it"); - nPoll(coord_buffer, buttons); + Display.getImplementation().pollMouse(coord_buffer, buttons); int poll_dx = coord_buffer.get(0); int poll_dy = coord_buffer.get(1); @@ -410,16 +378,11 @@ public class Mouse { private static void read() { readBuffer.compact(); - int numEvents = nRead(readBuffer, readBuffer.position()); + int numEvents = Display.getImplementation().readMouse(readBuffer, readBuffer.position()); readBuffer.position(readBuffer.position() + numEvents * EVENT_SIZE); readBuffer.flip(); } - /** - * Native method to poll the mouse - */ - private static native void nPoll(IntBuffer coord_buffer, ByteBuffer buttons); - /** * See if a particular mouse button is down. * @@ -465,22 +428,9 @@ public class Mouse { if (!created) throw new IllegalStateException("Mouse must be created before you can enable buffering"); readBuffer = BufferUtils.createIntBuffer(EVENT_SIZE * BUFFER_SIZE); readBuffer.limit(0); - nEnableBuffer(); + Display.getImplementation().enableMouseBuffer(); } - /** - * Native method to enable the buffer - * @return the event buffer, - * or null if no buffer can be allocated - */ - private static native void nEnableBuffer() throws LWJGLException; - - /** - * Native method to read the keyboard buffer - * @return the total number of events read. - */ - private static native int nRead(IntBuffer buffer, int buffer_position); - /** * Gets the next mouse event. You can query which button caused the event by using * getEventButton() (if any). To get the state of that key, for that event, use @@ -638,13 +588,11 @@ public class Mouse { public static void setGrabbed(boolean grab) { isGrabbed = grab; if (isCreated()) { - nGrabMouse(isGrabbed); + Display.getImplementation().grabMouse(isGrabbed); resetMouse(); } } - private static native void nGrabMouse(boolean grab); - /** * Updates the cursor, so that animation can be changed if needed. * This method is called automatically by the window on its update, and diff --git a/src/java/org/lwjgl/opengl/Display.java b/src/java/org/lwjgl/opengl/Display.java index 7e5b928d..259db2c0 100644 --- a/src/java/org/lwjgl/opengl/Display.java +++ b/src/java/org/lwjgl/opengl/Display.java @@ -56,21 +56,14 @@ import org.lwjgl.input.Mouse; public final class Display { - /** The current display mode, if created */ - private static DisplayMode current_mode; + /** The display implementor */ + private final static DisplayImplementation display_impl; /** The initial display mode */ private final static DisplayMode initial_mode; - static { - Sys.initialize(); - current_mode = initial_mode = init(); - Runtime.getRuntime().addShutdownHook(new Thread() { - public void run() { - reset(); - } - }); - } + /** The current display mode, if created */ + private static DisplayMode current_mode; /** Timer for sync() */ private static long timeNow, timeThen; @@ -96,6 +89,38 @@ public final class Display { /** A unique context object, so we can track different contexts between creates() and destroys() */ private static Display context; + static { + Sys.initialize(); + display_impl = createDisplayImplementation(); + current_mode = initial_mode = display_impl.init(); + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + reset(); + } + }); + } + + private final static DisplayImplementation createDisplayImplementation() { + String class_name; + String os_name = System.getProperty("os.name"); + if (os_name.startsWith("Linux")) { + class_name = "org.lwjgl.opengl.LinuxDisplay"; + } else if (os_name.startsWith("Windows")) { + class_name = "org.lwjgl.opengl.Win32Display"; + } else + throw new IllegalStateException("The platform " + os_name + " is not supported"); + try { + Class display_class = Class.forName(class_name); + return (DisplayImplementation)display_class.newInstance(); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } + } + /** * Only constructed by ourselves */ @@ -113,7 +138,7 @@ public final class Display { * @return an array of all display modes the system reckons it can handle. */ public static DisplayMode[] getAvailableDisplayModes() { - DisplayMode[] unfilteredModes = nGetAvailableDisplayModes(); + DisplayMode[] unfilteredModes = display_impl.getAvailableDisplayModes(); if (unfilteredModes == null) { return new DisplayMode[0]; @@ -131,11 +156,6 @@ public final class Display { return filteredModes; } - /** - * Native method for getting displaymodes - */ - private static native DisplayMode[] nGetAvailableDisplayModes(); - /** * Return the current display mode, as set by setDisplayMode(). * @return The current display mode @@ -165,8 +185,8 @@ public final class Display { switchDisplayMode(); createWindow(); } catch (LWJGLException e) { - destroyContext(); - resetDisplayMode(); + display_impl.destroyContext(); + display_impl.resetDisplayMode(); throw e; } } @@ -179,14 +199,12 @@ public final class Display { private static void createWindow() throws LWJGLException { x = Math.max(0, Math.min(initial_mode.getWidth() - current_mode.getWidth(), x)); y = Math.max(0, Math.min(initial_mode.getHeight() - current_mode.getHeight(), y)); - nCreateWindow(current_mode, fullscreen, (fullscreen) ? 0 : x, (fullscreen) ? 0 : y); - nSetTitle(title); + display_impl.createWindow(current_mode, fullscreen, (fullscreen) ? 0 : x, (fullscreen) ? 0 : y); + setTitle(title); initControls(); - nSetVSyncEnabled(vsync); + setVSyncEnabled(vsync); } - private static native void nCreateWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException; - private static void destroyWindow() { // Automatically destroy keyboard, mouse, and controller if (Mouse.isCreated()) { @@ -198,25 +216,15 @@ public final class Display { if (Controller.isCreated()) { Controller.destroy(); } - nDestroyWindow(); + display_impl.destroyWindow(); } - private static native void nDestroyWindow(); - private static void switchDisplayMode() throws LWJGLException { if (!current_mode.isFullscreen()) throw new LWJGLException("The current DisplayMode instance cannot be used for fullscreen mode"); - nSwitchDisplayMode(current_mode); + display_impl.switchDisplayMode(current_mode); } - private static native void nSwitchDisplayMode(DisplayMode mode) throws LWJGLException; - - /** - * Reset the display mode to whatever it was when LWJGL was initialized. - * Fails silently. - */ - private static native void resetDisplayMode(); - /** * Set the display configuration to the specified gamma, brightness and contrast. * The configuration changes will be reset when destroy() is called. @@ -233,7 +241,7 @@ public final class Display { throw new IllegalArgumentException("Invalid brightness value"); if (contrast < 0.0f) throw new IllegalArgumentException("Invalid contrast value"); - int rampSize = getGammaRampLength(); + int rampSize = display_impl.getGammaRampLength(); if (rampSize == 0) { throw new LWJGLException("Display configuration not supported"); } @@ -253,37 +261,10 @@ public final class Display { rampEntry = 0.0f; gammaRamp.put(i, rampEntry); } - setGammaRamp(gammaRamp); + display_impl.setGammaRamp(gammaRamp); Sys.log("Gamma set, gamma = " + gamma + ", brightness = " + brightness + ", contrast = " + contrast); } - /** - * Return the length of the gamma ramp arrays. Returns 0 if gamma settings are - * unsupported. - * - * @return the length of each gamma ramp array, or 0 if gamma settings are unsupported. - */ - private static native int getGammaRampLength(); - - /** - * Native method to set the gamma ramp. - */ - private static native void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException; - - /** - * Get the driver adapter string. This is a unique string describing the actual card's hardware, eg. "Geforce2", "PS2", - * "Radeon9700". If the adapter cannot be determined, this function returns null. - * @return a String - */ - public static native String getAdapter(); - - /** - * Get the driver version. This is a vendor/adapter specific version string. If the version cannot be determined, - * this function returns null. - * @return a String - */ - public static native String getVersion(); - /** * Synchronize the display to a capped frame rate. Note that we are being "smart" about the * desired results in our implementation; we automatically subtract 1 from the desired framerate @@ -323,11 +304,6 @@ public final class Display { timeThen = timeNow; } - /** - * Initialize and return the current display mode. - */ - private static native DisplayMode init(); - /** * @return the X coordinate of the window (always 0 for fullscreen) */ @@ -371,12 +347,12 @@ public final class Display { if (fullscreen) { switchDisplayMode(); } else { - resetDisplayMode(); + display_impl.resetDisplayMode(); } createWindow(); } catch (LWJGLException e) { - destroyContext(); - resetDisplayMode(); + display_impl.destroyContext(); + display_impl.resetDisplayMode(); throw e; } } @@ -399,51 +375,39 @@ public final class Display { } title = newTitle; if (isCreated()) - nSetTitle(title); + display_impl.setTitle(title); } - /** - * Native implementation of setTitle(). This will read the window's title member - * and stash it in the native title of the window. - */ - private static native void nSetTitle(String title); - /** * @return true if the user or operating system has asked the window to close */ public static boolean isCloseRequested() { if (!isCreated()) throw new IllegalStateException("Cannot determine close requested state of uncreated window"); - nUpdate(); - return nIsCloseRequested(); + display_impl.update(); + return display_impl.isCloseRequested(); } - private static native boolean nIsCloseRequested(); - /** * @return true if the window is visible, false if not */ public static boolean isVisible() { if (!isCreated()) throw new IllegalStateException("Cannot determine minimized state of uncreated window"); - nUpdate(); - return nIsVisible(); + display_impl.update(); + return display_impl.isVisible(); } - private static native boolean nIsVisible(); - /** * @return true if window is active, that is, the foreground display of the operating system. */ public static boolean isActive() { if (!isCreated()) throw new IllegalStateException("Cannot determine focused state of uncreated window"); - nUpdate(); - return nIsActive(); + display_impl.update(); + return display_impl.isActive(); } - private static native boolean nIsActive(); - /** * Determine if the window's contents have been damaged by external events. * If you are writing a straightforward game rendering loop and simply paint @@ -457,12 +421,10 @@ public final class Display { public static boolean isDirty() { if (!isCreated()) throw new IllegalStateException("Cannot determine dirty state of uncreated window"); - nUpdate(); - return nIsDirty(); + display_impl.update(); + return display_impl.isDirty(); } - private static native boolean nIsDirty(); - /** * Update the window. This processes operating system events, and if the window is visible * clears the dirty flag and swaps the buffers. @@ -475,10 +437,10 @@ public final class Display { // We paint only when the window is visible or dirty if (isVisible() || isDirty()) { Util.checkGLError(); - swapBuffers(); + display_impl.swapBuffers(); } - nUpdate(); + display_impl.update(); // Poll the input devices while we're here if (Mouse.isCreated()) { @@ -493,11 +455,6 @@ public final class Display { } } - /** - * Swap double buffers. - */ - private static native void swapBuffers(); - /** * Make the Display the current rendering context for GL calls. Also initialize native stubs. * @throws LWJGLException If the context could not be made current @@ -505,15 +462,10 @@ public final class Display { public static void makeCurrent() throws LWJGLException { if (!isCreated()) throw new IllegalStateException("No window created to make current"); - nMakeCurrent(); + display_impl.makeCurrent(); GLContext.useContext(context); } - /** - * Make the window the current rendering context for GL calls. - */ - private static native void nMakeCurrent() throws LWJGLException; - /** * Create the OpenGL context. If isFullscreen() is true or if windowed * context are not supported on the platform, the display mode will be switched to the mode returned by @@ -549,14 +501,14 @@ public final class Display { try { GLContext.loadOpenGLLibrary(); try { - createContext(pixel_format); + display_impl.createContext(pixel_format); try { context = new Display(); createWindow(); makeCurrent(); initContext(); } catch (LWJGLException e) { - destroyContext(); + display_impl.destroyContext(); context = null; throw e; } @@ -565,19 +517,11 @@ public final class Display { throw e; } } catch (LWJGLException e) { - resetDisplayMode(); + display_impl.resetDisplayMode(); throw e; } } - /** - * Create the native OpenGL context. - * @throws LWJGLException - */ - private static native void createContext(PixelFormat pixel_format) throws LWJGLException; - - private static native void destroyContext(); - private static void initContext() { // Put the window into orthographic projection mode with 1:1 pixel ratio. // We haven't used GLU here to do this to avoid an unnecessary dependency. @@ -589,6 +533,10 @@ public final class Display { GL11.glViewport(0, 0, current_mode.getWidth(), current_mode.getHeight()); } + public static DisplayImplementation getImplementation() { + return display_impl; + } + private static void initControls() { // Automatically create mouse, keyboard and controller if (!Boolean.getBoolean("org.lwjgl.opengl.Display.noinput")) { @@ -641,7 +589,7 @@ public final class Display { } destroyWindow(); - destroyContext(); + display_impl.destroyContext(); GLContext.unloadOpenGLLibrary(); context = null; try { @@ -657,7 +605,7 @@ public final class Display { * in the static constructor */ private static void reset() { - resetDisplayMode(); + display_impl.resetDisplayMode(); current_mode = initial_mode; } @@ -675,12 +623,6 @@ public final class Display { return context != null; } - /** - * Updates the windows internal state. This must be called at least once per video frame - * to handle window close requests, moves, paints, etc. - */ - private static native void nUpdate(); - /** * Enable or disable vertical monitor synchronization. This call is a best-attempt at changing * the vertical refresh synchronization of the monitor, and is not guaranteed to be successful. @@ -689,11 +631,9 @@ public final class Display { public static void setVSyncEnabled(boolean sync) { vsync = sync; if (isCreated()) - nSetVSyncEnabled(vsync); + display_impl.setVSyncEnabled(vsync); } - private static native void nSetVSyncEnabled(boolean sync); - /** * Set the window's location. This is a no-op on fullscreen windows. * The window is clamped to remain entirely on the screen. If you attempt @@ -705,17 +645,34 @@ public final class Display { if (fullscreen) { return; } - - // offset if already created - if(isCreated()) { - x = Math.max(0, Math.min(initial_mode.getWidth() - current_mode.getWidth(), x)); - y = Math.max(0, Math.min(initial_mode.getHeight() - current_mode.getHeight(), y)); - nReshape(x, y, current_mode.getWidth(), current_mode.getHeight()); - } - // cache position - Display.x = x; - Display.y = y; + // offset if already created + if(isCreated()) { + x = Math.max(0, Math.min(initial_mode.getWidth() - current_mode.getWidth(), x)); + y = Math.max(0, Math.min(initial_mode.getHeight() - current_mode.getHeight(), y)); + display_impl.reshape(x, y, current_mode.getWidth(), current_mode.getHeight()); + } + + // cache position + Display.x = x; + Display.y = y; + } + + /** + * Get the driver adapter string. This is a unique string describing the actual card's hardware, eg. "Geforce2", "PS2", + * "Radeon9700". If the adapter cannot be determined, this function returns null. + * @return a String + */ + public static String getAdapter() { + return display_impl.getAdapter(); + } + + /** + * Get the driver version. This is a vendor/adapter specific version string. If the version cannot be determined, + * this function returns null. + * @return a String + */ + public static String getVersion() { + return display_impl.getVersion(); } - private static native void nReshape(int x, int y, int width, int height); } diff --git a/src/java/org/lwjgl/opengl/DisplayImplementation.java b/src/java/org/lwjgl/opengl/DisplayImplementation.java new file mode 100644 index 00000000..96d4d535 --- /dev/null +++ b/src/java/org/lwjgl/opengl/DisplayImplementation.java @@ -0,0 +1,232 @@ +/* + * 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; + +public interface DisplayImplementation { + public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException; + public void destroyWindow(); + + public void switchDisplayMode(DisplayMode mode) throws LWJGLException; + + /** + * Reset the display mode to whatever it was when LWJGL was initialized. + * Fails silently. + */ + public void resetDisplayMode(); + + /** + * Return the length of the gamma ramp arrays. Returns 0 if gamma settings are + * unsupported. + * + * @return the length of each gamma ramp array, or 0 if gamma settings are unsupported. + */ + public int getGammaRampLength(); + + /** + * Native method to set the gamma ramp. + */ + public void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException; + + /** + * Get the driver adapter string. This is a unique string describing the actual card's hardware, eg. "Geforce2", "PS2", + * "Radeon9700". If the adapter cannot be determined, this function returns null. + * @return a String + */ + public String getAdapter(); + + /** + * Get the driver version. This is a vendor/adapter specific version string. If the version cannot be determined, + * this function returns null. + * @return a String + */ + public String getVersion(); + + /** + * Initialize and return the current display mode. + */ + public DisplayMode init(); + + /** + * Native implementation of setTitle(). This will read the window's title member + * and stash it in the native title of the window. + */ + public void setTitle(String title); + + public boolean isCloseRequested(); + + public boolean isVisible(); + public boolean isActive(); + + public boolean isDirty(); + + /** + * Swap double buffers. + */ + public void swapBuffers(); + + /** + * Make the window the current rendering context for GL calls. + */ + public void makeCurrent() throws LWJGLException; + + /** + * Create the native OpenGL context. + * @throws LWJGLException + */ + public void createContext(PixelFormat pixel_format) throws LWJGLException; + + public void destroyContext(); + + /** + * Updates the windows internal state. This must be called at least once per video frame + * to handle window close requests, moves, paints, etc. + */ + public void update(); + + public void setVSyncEnabled(boolean sync); + + public void reshape(int x, int y, int width, int height); + + /** + * Native method for getting displaymodes + */ + public DisplayMode[] getAvailableDisplayModes(); + + /* + * Mouse methods + */ + /** Native query of wheel support */ + public boolean hasWheel(); + + /** Native query of button count */ + public int getButtonCount(); + + /** + * Native method to create the mouse. + * + * @return true if the mouse was created + */ + public void createMouse(); + + /** + * Native method the destroy the mouse + */ + public void destroyMouse(); + + /** + * Native method to poll the mouse + */ + public void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons); + + /** + * Native method to enable the buffer + * @return the event buffer, + * or null if no buffer can be allocated + */ + public void enableMouseBuffer() throws LWJGLException; + + /** + * Native method to read the keyboard buffer + * @return the total number of events read. + */ + public int readMouse(IntBuffer buffer, int buffer_position); + + public void grabMouse(boolean grab); + + /** + * Native function to determine native cursor support + */ + public int getNativeCursorCaps(); + + /** Native method to set the native cursor */ + public void setNativeCursor(ByteBuffer handle) throws LWJGLException; + + /** Native method returning the minimum cursor size */ + public int getMinCursorSize(); + + /** Native method returning the maximum cursor size */ + public int getMaxCursorSize(); + + /* + * Keyboard methods + */ + + /** + * Native method to create the keyboard + */ + public void createKeyboard() throws LWJGLException; + + /** + * Native method to destroy the keyboard + */ + public void destroyKeyboard(); + + /** + * Native method to poll the keyboard. + * + * @param keyDownBufferAddress the address of a 256-byte buffer to place + * key states in. + */ + public void pollKeyboard(ByteBuffer keyDownBuffer); + + /** + * Native method to read the keyboard buffer + * @return the total number of events read. + */ + public int readKeyboard(IntBuffer buffer, int buffer_position); + + /** + * Native method to enable the translation buffer + */ + public void enableTranslation() throws LWJGLException; + + /** + * Native method to enable the buffer + * @return the event buffer, + * or null if no buffer can be allocated + */ + public void enableKeyboardBuffer() throws LWJGLException; + + public int isStateKeySet(int key); +} diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java new file mode 100644 index 00000000..988a4d90 --- /dev/null +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -0,0 +1,91 @@ +/* + * 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; + +final class LinuxDisplay implements DisplayImplementation { + public native void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException; + public native void destroyWindow(); + public native void switchDisplayMode(DisplayMode mode) throws LWJGLException; + public native void resetDisplayMode(); + public native int getGammaRampLength(); + public native void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException; + public native String getAdapter(); + public native String getVersion(); + public native DisplayMode init(); + public native void setTitle(String title); + public native boolean isCloseRequested(); + public native boolean isVisible(); + public native boolean isActive(); + public native boolean isDirty(); + public native void swapBuffers(); + public native void makeCurrent() throws LWJGLException; + public native void createContext(PixelFormat pixel_format) throws LWJGLException; + public native void destroyContext(); + public native void update(); + public native void setVSyncEnabled(boolean sync); + public native void reshape(int x, int y, int width, int height); + public native DisplayMode[] getAvailableDisplayModes(); + /* Mouse */ + public native boolean hasWheel(); + public native int getButtonCount(); + public native void createMouse(); + public native void destroyMouse(); + public native void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons); + public native void enableMouseBuffer() throws LWJGLException; + public native int readMouse(IntBuffer buffer, int buffer_position); + public native void grabMouse(boolean grab); + public native int getNativeCursorCaps(); + public native void setNativeCursor(ByteBuffer handle) throws LWJGLException; + public native int getMinCursorSize(); + public native int getMaxCursorSize(); + /* Keyboard */ + public native void createKeyboard() throws LWJGLException; + public native void destroyKeyboard(); + public native void pollKeyboard(ByteBuffer keyDownBuffer); + public native int readKeyboard(IntBuffer buffer, int buffer_position); + public native void enableTranslation() throws LWJGLException; + public native void enableKeyboardBuffer() throws LWJGLException; + public native int isStateKeySet(int key); +} diff --git a/src/java/org/lwjgl/opengl/Win32Display.java b/src/java/org/lwjgl/opengl/Win32Display.java new file mode 100644 index 00000000..b6fbf1d9 --- /dev/null +++ b/src/java/org/lwjgl/opengl/Win32Display.java @@ -0,0 +1,91 @@ +/* + * 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; + +final class Win32Display implements DisplayImplementation { + public native void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException; + public native void destroyWindow(); + public native void switchDisplayMode(DisplayMode mode) throws LWJGLException; + public native void resetDisplayMode(); + public native int getGammaRampLength(); + public native void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException; + public native String getAdapter(); + public native String getVersion(); + public native DisplayMode init(); + public native void setTitle(String title); + public native boolean isCloseRequested(); + public native boolean isVisible(); + public native boolean isActive(); + public native boolean isDirty(); + public native void swapBuffers(); + public native void makeCurrent() throws LWJGLException; + public native void createContext(PixelFormat pixel_format) throws LWJGLException; + public native void destroyContext(); + public native void update(); + public native void setVSyncEnabled(boolean sync); + public native void reshape(int x, int y, int width, int height); + public native DisplayMode[] getAvailableDisplayModes(); + /* Mouse */ + public native boolean hasWheel(); + public native int getButtonCount(); + public native void createMouse(); + public native void destroyMouse(); + public native void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons); + public native void enableMouseBuffer() throws LWJGLException; + public native int readMouse(IntBuffer buffer, int buffer_position); + public native void grabMouse(boolean grab); + public native int getNativeCursorCaps(); + public native void setNativeCursor(ByteBuffer handle) throws LWJGLException; + public native int getMinCursorSize(); + public native int getMaxCursorSize(); + /* Keyboard */ + public native void createKeyboard() throws LWJGLException; + public native void destroyKeyboard(); + public native void pollKeyboard(ByteBuffer keyDownBuffer); + public native int readKeyboard(IntBuffer buffer, int buffer_position); + public native void enableTranslation() throws LWJGLException; + public native void enableKeyboardBuffer() throws LWJGLException; + public native int isStateKeySet(int key); +} diff --git a/src/native/linux/org_lwjgl_input_Keyboard.c b/src/native/linux/org_lwjgl_input_Keyboard.c index c4fa66af..6c6155be 100644 --- a/src/native/linux/org_lwjgl_input_Keyboard.c +++ b/src/native/linux/org_lwjgl_input_Keyboard.c @@ -49,6 +49,7 @@ #include "Window.h" #include "common_tools.h" #include "org_lwjgl_input_Keyboard.h" +#include "org_lwjgl_opengl_LinuxDisplay.h" #define KEYBOARD_BUFFER_SIZE 50 #define KEYBOARD_SIZE 256 @@ -117,8 +118,8 @@ static void setupIMEventMask() { XSetICFocus(xic); } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate - (JNIEnv * env, jclass clazz) +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_createKeyboard + (JNIEnv * env, jobject this) { Display *disp = incDisplay(env); if (disp == NULL) @@ -169,8 +170,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate } } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy - (JNIEnv * env, jclass clazz) +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_destroyKeyboard + (JNIEnv * env, jobject this) { closeUnicodeStructs(); ungrabKeyboard(); @@ -282,27 +283,27 @@ void handleKeyEvent(XKeyEvent *event) { bufferEvent(event); } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nPoll(JNIEnv * env, jclass clazz, jobject buffer) { +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_pollKeyboard(JNIEnv * env, jobject this, jobject buffer) { unsigned char *new_keyboard_buffer = (unsigned char *)(*env)->GetDirectBufferAddress(env, buffer); handleMessages(); memcpy(new_keyboard_buffer, key_buf, KEYBOARD_SIZE*sizeof(unsigned char)); } -JNIEXPORT int JNICALL Java_org_lwjgl_input_Keyboard_nRead(JNIEnv * env, jclass clazz, jobject buffer, jint buffer_position) { +JNIEXPORT int JNICALL Java_org_lwjgl_opengl_LinuxDisplay_readKeyboard(JNIEnv * env, jobject this, jobject buffer, jint buffer_position) { handleMessages(); jint* buffer_ptr = (jint *)(*env)->GetDirectBufferAddress(env, buffer); int buffer_size = ((*env)->GetDirectBufferCapacity(env, buffer))/sizeof(jint) - buffer_position; return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size); } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nEnableTranslation(JNIEnv *env, jclass clazz) { +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_enableTranslation(JNIEnv *env, jobject this) { translation_enabled = true; } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer(JNIEnv * env, jclass clazz) { +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_enableKeyboardBuffer(JNIEnv * env, jobject this) { buffer_enabled = true; } -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nisStateKeySet(JNIEnv *env, jclass clazz, jint key) { +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_isStateKeySet(JNIEnv *env, jobject this, jint key) { return org_lwjgl_input_Keyboard_STATE_UNKNOWN; } diff --git a/src/native/linux/org_lwjgl_input_Mouse.c b/src/native/linux/org_lwjgl_input_Mouse.c index 2897672c..398976e6 100644 --- a/src/native/linux/org_lwjgl_input_Mouse.c +++ b/src/native/linux/org_lwjgl_input_Mouse.c @@ -49,6 +49,7 @@ #include "common_tools.h" #include "display.h" #include "org_lwjgl_input_Mouse.h" +#include "org_lwjgl_opengl_LinuxDisplay.h" #define NUM_BUTTONS 3 @@ -188,8 +189,8 @@ static void doWarpPointer(int center_x, int center_y) { XWarpPointer(getDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, center_x, center_y); } -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetNativeCursorCaps - (JNIEnv *env, jclass clazz) { +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getNativeCursorCaps + (JNIEnv *env, jobject this) { int caps = 0; Display *disp = incDisplay(env); if (disp == NULL) @@ -204,7 +205,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetNativeCursorCaps return caps; } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nSetNativeCursor(JNIEnv *env, jclass clazz, jobject cursor_handle) { +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_setNativeCursor(JNIEnv *env, jobject this, jobject cursor_handle) { if (cursor_handle != NULL) { Cursor *cursor = (Cursor *)(*env)->GetDirectBufferAddress(env, cursor_handle); current_cursor = *cursor; @@ -213,8 +214,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nSetNativeCursor(JNIEnv *env, updateCursor(); } -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetMinCursorSize - (JNIEnv *env, jclass clazz) +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getMinCursorSize + (JNIEnv *env, jobject this) { unsigned int width_return = 0; unsigned int height_return = 0; @@ -222,8 +223,8 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetMinCursorSize return width_return > height_return ? width_return : height_return; } -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetMaxCursorSize - (JNIEnv *env, jclass clazz) +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getMaxCursorSize + (JNIEnv *env, jobject this) { unsigned int width_return = 0; unsigned int height_return = 0; @@ -231,11 +232,11 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetMaxCursorSize return width_return > height_return ? height_return : width_return; } -JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nHasWheel(JNIEnv *env , jclass clazz) { +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_LinuxDisplay_hasWheel(JNIEnv *env , jobject this) { return JNI_TRUE; } -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetButtonCount(JNIEnv *env, jclass clazz) { +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getButtonCount(JNIEnv *env, jobject this) { return NUM_BUTTONS; } @@ -243,8 +244,8 @@ static void resetCursorToCenter(void) { resetCursor(getWindowWidth()/2, transformY(getWindowHeight()/2)); } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate - (JNIEnv * env, jclass clazz) +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_createMouse + (JNIEnv * env, jobject this) { Display *disp = incDisplay(env); if (disp == NULL) @@ -267,8 +268,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate initEventQueue(&event_queue, 5); } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy - (JNIEnv * env, jclass clazz) +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_destroyMouse + (JNIEnv * env, jobject this) { ungrabPointer(); XFreeCursor(getDisplay(), blank_cursor); @@ -355,7 +356,7 @@ void handlePointerMotion(XMotionEvent *event) { doHandlePointerMotion(event->x_root, event->y_root, event->x, event->y); } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll(JNIEnv * env, jclass clazz, jobject coord_buffer_obj, jobject button_buffer_obj) { +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_pollMouse(JNIEnv * env, jobject this, jobject coord_buffer_obj, jobject button_buffer_obj) { int *coords = (int *)(*env)->GetDirectBufferAddress(env, coord_buffer_obj); int coords_length = (*env)->GetDirectBufferCapacity(env, coord_buffer_obj); unsigned char *buttons_buffer = (unsigned char *)(*env)->GetDirectBufferAddress(env, button_buffer_obj); @@ -377,18 +378,18 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll(JNIEnv * env, jclass cla buttons_buffer[i] = buttons[i]; } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nEnableBuffer(JNIEnv *env, jclass clazz) { +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_enableMouseBuffer(JNIEnv *env, jobject this) { buffer_enabled = true; } -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nRead(JNIEnv *env, jclass clazz, jobject buffer, jint buffer_position) { +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_readMouse(JNIEnv *env, jobject this, jobject buffer, jint buffer_position) { jint* buffer_ptr = (jint *)(*env)->GetDirectBufferAddress(env, buffer); int buffer_size = ((*env)->GetDirectBufferCapacity(env, buffer))/sizeof(jint) - buffer_position; handleMessages(); return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size); } -JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nGrabMouse(JNIEnv * env, jclass clazz, jboolean new_grab) { +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_grabMouse(JNIEnv * env, jobject this, jboolean new_grab) { Window root_return, child_return; int root_x, root_y, win_x, win_y; unsigned int mask_return; diff --git a/src/native/linux/org_lwjgl_opengl_Display.c b/src/native/linux/org_lwjgl_opengl_Display.c deleted file mode 100644 index 18597bd7..00000000 --- a/src/native/linux/org_lwjgl_opengl_Display.c +++ /dev/null @@ -1,793 +0,0 @@ -/* - * 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$ - * - * Linux specific display functions. - * - * @author elias_naur - * @version $Revision$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include "common_tools.h" -#include "extgl.h" -#include "extgl_glx.h" -#include "Window.h" -#include "display.h" -#include "org_lwjgl_opengl_Display.h" - -#define USEGLX13 extgl_Extensions.GLX13 -#define ERR_MSG_SIZE 1024 - -typedef struct { - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; -} MotifWmHints; - -#define MWM_HINTS_DECORATIONS (1L << 1) - -typedef enum {FULLSCREEN_LEGACY, FULLSCREEN_NETWM, WINDOWED} window_mode; - -static GLXContext context = NULL; // OpenGL rendering context -static GLXFBConfig *configs = NULL; -static GLXWindow glx_window; -static XVisualInfo *vis_info = NULL; - -static Atom delete_atom; -static Colormap cmap; -static Window current_win; -static window_mode current_window_mode; -static int current_height; -static int current_width; - -static bool input_released; - -static bool dirty; -static bool vsync_enabled; -static bool minimized; -static bool focused; -static bool closerequested; -static bool grab; - -static int current_screen; -static Display *display_connection = NULL; -static int display_connection_usage = 0; -static bool async_x_error; -static char error_message[ERR_MSG_SIZE]; -static Atom warp_atom; - -GLXFBConfig getCurrentGLXFBConfig(void) { - return configs[0]; -} - -GLXContext getCurrentGLXContext(void) { - return context; -} - -int getCurrentScreen(void) { - return current_screen; -} - -bool checkXError(JNIEnv *env) { - XSync(getDisplay(), False); - if (async_x_error) { - async_x_error = false; - if (env != NULL) - throwException(env, error_message); - else - printfDebug(error_message); - return false; - } else - return true; -} - -static int errorHandler(Display *disp, XErrorEvent *error) { - char err_msg_buffer[ERR_MSG_SIZE]; - XGetErrorText(disp, error->error_code, err_msg_buffer, ERR_MSG_SIZE); - err_msg_buffer[ERR_MSG_SIZE - 1] = '\0'; - snprintf(error_message, ERR_MSG_SIZE, "X Error - serial: %d, error_code: %s, request_code: %d, minor_code: %d", (int)error->serial, err_msg_buffer, (int)error->request_code, (int)error->minor_code); - error_message[ERR_MSG_SIZE - 1] = '\0'; - async_x_error = true; - return 0; -} - - -Display *getDisplay(void) { - return display_connection; -} - -Display *incDisplay(JNIEnv *env) { - if (display_connection_usage == 0) { - async_x_error = false; - XSetErrorHandler(errorHandler); - display_connection = XOpenDisplay(NULL); - if (display_connection == NULL) { - if (env != NULL) - throwException(env, "Could not open X display connection"); - else - printfDebug("Could not open X display connection\n"); - return NULL; - } - warp_atom = XInternAtom(display_connection, "_LWJGL_WARP", False); - } - async_x_error = false; - display_connection_usage++; - return display_connection; -} - -Atom getWarpAtom(void) { - return warp_atom; -} - -void decDisplay(void) { - display_connection_usage--; - if (display_connection_usage == 0) { - XCloseDisplay(display_connection); - display_connection = NULL; - } -} - -static void waitMapped(Window win) { - XEvent event; - do { - XMaskEvent(getDisplay(), StructureNotifyMask, &event); - } while ((event.type != MapNotify) || (event.xmap.event != win)); -} - -static void updateInputGrab(void) { - updatePointerGrab(); - updateKeyboardGrab(); -} - -static void setRepeatMode(int mode) { - XKeyboardControl repeat_mode; - repeat_mode.auto_repeat_mode = mode; - Display *disp = XOpenDisplay(NULL); - if (disp == NULL) { - printfDebug("Could not open display to set repeat mode\n"); - return; - } - XChangeKeyboardControl(disp, KBAutoRepeatMode, &repeat_mode); - XCloseDisplay(disp); -} - -static void setDecorations(int dec) { - Atom motif_hints_atom = XInternAtom(getDisplay(), "_MOTIF_WM_HINTS", False); - MotifWmHints motif_hints; - motif_hints.flags = MWM_HINTS_DECORATIONS; - motif_hints.decorations = dec; - XChangeProperty (getDisplay(), getCurrentWindow(), motif_hints_atom, motif_hints_atom, 32, PropModeReplace, (unsigned char *)&motif_hints, sizeof(MotifWmHints)/sizeof(long)); -} - -bool releaseInput(void) { - if (isLegacyFullscreen() || input_released) - return false; - input_released = true; - setRepeatMode(AutoRepeatModeDefault); - updateInputGrab(); - if (current_window_mode == FULLSCREEN_NETWM) { - XIconifyWindow(getDisplay(), getCurrentWindow(), getCurrentScreen()); - resetDisplayMode(getCurrentScreen(), true); - } - return true; -} - -static void acquireInput(void) { - if (isLegacyFullscreen() || !input_released) - return; - input_released = false; - setRepeatMode(AutoRepeatModeOff); - updateInputGrab(); - if (current_window_mode == FULLSCREEN_NETWM) { - temporaryRestoreMode(getCurrentScreen()); - } -} - -bool isLegacyFullscreen(void) { - return current_window_mode == FULLSCREEN_LEGACY; -} - -bool shouldGrab(void) { - return !input_released && grab; -} - -void setGrab(bool new_grab) { - if (new_grab != grab) { - grab = new_grab; - updateInputGrab(); - } -} - -static void checkInput(void) { - Window win; - int revert_mode; - XGetInputFocus(getDisplay(), &win, &revert_mode); - if (win == current_win) { - acquireInput(); - focused = true; - } -} - -void handleMessages(void) { - XEvent event; - Window win; - int revert_mode; - while (XPending(getDisplay()) > 0) { - XNextEvent(getDisplay(), &event); - if (XFilterEvent(&event, None) == True) - continue; - switch (event.type) { - case ClientMessage: - if (event.xclient.message_type == warp_atom) { - handleWarpEvent(&(event.xclient)); - } else if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == delete_atom)) - closerequested = true; - break; - case FocusOut: - XGetInputFocus(getDisplay(), &win, &revert_mode); - if (win != current_win) { - releaseInput(); - focused = false; - } - break; - case FocusIn: - checkInput(); - break; - case MapNotify: - dirty = true; - minimized = false; - break; - case UnmapNotify: - dirty = true; - minimized = true; - break; - case Expose: - dirty = true; - break; - case ButtonPress: - handleButtonPress(&(event.xbutton)); - break; - case ButtonRelease: - handleButtonRelease(&(event.xbutton)); - break; - case MotionNotify: - handlePointerMotion(&(event.xmotion)); - break; - case KeyPress: - case KeyRelease: - handleKeyEvent(&(event.xkey)); - break; - } - } -} - -static void setWindowTitle(const char *title) { - XStoreName(getDisplay(), current_win, title); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nSetTitle - (JNIEnv * env, jclass clazz, jstring title_obj) -{ - const char * title = (*env)->GetStringUTFChars(env, title_obj, NULL); - setWindowTitle(title); - (*env)->ReleaseStringUTFChars(env, title_obj, title); -} - -static void destroyWindow(void) { - if (USEGLX13) - glXDestroyWindow(getDisplay(), glx_window); - XDestroyWindow(getDisplay(), current_win); - XFreeColormap(getDisplay(), cmap); - setRepeatMode(AutoRepeatModeDefault); -} - -static bool isNetWMFullscreenSupported() { - unsigned long nitems; - Atom actual_type; - int actual_format; - unsigned long bytes_after; - Atom *supported_list; - Atom netwm_supported_atom = XInternAtom(getDisplay(), "_NET_SUPPORTED", False); - int result = XGetWindowProperty(getDisplay(), RootWindow(getDisplay(), getCurrentScreen()), netwm_supported_atom, 0, 10000, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, (void *)&supported_list); - if (result != Success) { - printfDebug("Unable to query _NET_SUPPORTED window property\n"); - return false; - } - Atom fullscreen_atom = XInternAtom(getDisplay(), "_NET_WM_STATE_FULLSCREEN", False); - bool supported = false; - unsigned long i; - for (i = 0; i < nitems; i++) { - if (fullscreen_atom == supported_list[i]) { - supported = true; - break; - } - } - XFree(supported_list); - return supported; -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nReshape(JNIEnv *env, jclass clazz, jint x, jint y, jint width, jint height) { - XMoveWindow(getDisplay(), getCurrentWindow(), x, y); -} - -static bool createWindow(JNIEnv* env, int x, int y, int width, int height) { - bool undecorated = getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated"); - dirty = true; - focused = true; - minimized = false; - closerequested = false; - vsync_enabled = false; - grab = false; - Window root_win; - Window win; - XSetWindowAttributes attribs; - int attribmask; - - input_released = false; - current_width = width; - current_height = height; - root_win = RootWindow(getDisplay(), getCurrentScreen()); - cmap = XCreateColormap(getDisplay(), root_win, vis_info->visual, AllocNone); - attribs.colormap = cmap; - attribs.event_mask = ExposureMask | FocusChangeMask | VisibilityChangeMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; - attribs.background_pixel = 0xFF000000; - attribs.win_gravity = NorthWestGravity; - attribmask = CWColormap | CWBackPixel | CWEventMask | CWWinGravity; - if (isLegacyFullscreen()) { - attribmask |= CWOverrideRedirect; - attribs.override_redirect = True; - } - win = XCreateWindow(getDisplay(), root_win, x, y, width, height, 0, vis_info->depth, InputOutput, vis_info->visual, attribmask, &attribs); - if (!checkXError(env)) { - XFreeColormap(getDisplay(), cmap); - return false; - } - printfDebug("Created window\n"); - current_win = win; - if (current_window_mode != WINDOWED || undecorated) { - // Use Motif decoration hint property and hope the window manager respects them - setDecorations(0); - } - XSizeHints * size_hints = XAllocSizeHints(); - size_hints->flags = PMinSize | PMaxSize; - size_hints->min_width = width; - size_hints->max_width = width; - size_hints->min_height = height; - size_hints->max_height = height; - XSetWMNormalHints(getDisplay(), win, size_hints); - XFree(size_hints); - delete_atom = XInternAtom(getDisplay(), "WM_DELETE_WINDOW", False); - XSetWMProtocols(getDisplay(), win, &delete_atom, 1); - if (current_window_mode == FULLSCREEN_NETWM) { - Atom fullscreen_atom = XInternAtom(getDisplay(), "_NET_WM_STATE_FULLSCREEN", False); - XChangeProperty(getDisplay(), getCurrentWindow(), XInternAtom(getDisplay(), "_NET_WM_STATE", False), - XInternAtom(getDisplay(), "ATOM", False), 32, PropModeReplace, (const unsigned char*)&fullscreen_atom, 1); - } - XMapRaised(getDisplay(), win); - waitMapped(win); - XClearWindow(getDisplay(), win); - setRepeatMode(AutoRepeatModeOff); - if (!checkXError(env)) { - destroyWindow(); - return false; - } - return true; -} - -Window getCurrentWindow(void) { - return current_win; -} - -int getWindowWidth(void) { - return current_width; -} - -int getWindowHeight(void) { - return current_height; -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nUpdate - (JNIEnv *env, jclass clazz) -{ - handleMessages(); -} - -static bool makeCurrent(void) { - if (USEGLX13) - return glXMakeContextCurrent(getDisplay(), glx_window, glx_window, context) == True; - else - return glXMakeCurrent(getDisplay(), getCurrentWindow(), context) == True; -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nMakeCurrent - (JNIEnv *env, jclass clazz) -{ - if (!makeCurrent()) - throwException(env, "Could not make display context current"); -} - -int convertToBPE(int bpp) { - int bpe; - switch (bpp) { - case 32: - case 24: - bpe = 8; - break; - case 16: /* Fall through */ - default: - bpe = 4; - break; - } - return bpe; -} - -GLXContext getCurrentContext(void) { - return context; -} - -static GLXFBConfig *chooseVisualGLX13FromBPP(JNIEnv *env, jobject pixel_format, int bpp, int drawable_type, bool double_buffer) { - jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); - int alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "alpha", "I")); - int depth = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "depth", "I")); - int stencil = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stencil", "I")); - int samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I")); - int num_aux_buffers = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "num_aux_buffers", "I")); - int accum_bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_bpp", "I")); - int accum_alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_alpha", "I")); - bool stereo = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stereo", "Z")); - - int bpe = convertToBPE(bpp); - int accum_bpe = convertToBPE(accum_bpp); - attrib_list_t attrib_list; - initAttribList(&attrib_list); - putAttrib(&attrib_list, GLX_RENDER_TYPE); putAttrib(&attrib_list, GLX_RGBA_BIT); - putAttrib(&attrib_list, GLX_DOUBLEBUFFER); putAttrib(&attrib_list, double_buffer ? True : False); - putAttrib(&attrib_list, GLX_DRAWABLE_TYPE); putAttrib(&attrib_list, drawable_type); - putAttrib(&attrib_list, GLX_DEPTH_SIZE); putAttrib(&attrib_list, depth); - putAttrib(&attrib_list, GLX_RED_SIZE); putAttrib(&attrib_list, bpe); - putAttrib(&attrib_list, GLX_GREEN_SIZE); putAttrib(&attrib_list, bpe); - putAttrib(&attrib_list, GLX_BLUE_SIZE); putAttrib(&attrib_list, bpe); - putAttrib(&attrib_list, GLX_ALPHA_SIZE); putAttrib(&attrib_list, alpha); - putAttrib(&attrib_list, GLX_STENCIL_SIZE); putAttrib(&attrib_list, stencil); - putAttrib(&attrib_list, GLX_AUX_BUFFERS); putAttrib(&attrib_list, num_aux_buffers); - putAttrib(&attrib_list, GLX_ACCUM_RED_SIZE); putAttrib(&attrib_list, accum_bpe); - putAttrib(&attrib_list, GLX_ACCUM_GREEN_SIZE); putAttrib(&attrib_list, accum_bpe); - putAttrib(&attrib_list, GLX_ACCUM_BLUE_SIZE); putAttrib(&attrib_list, accum_bpe); - putAttrib(&attrib_list, GLX_ACCUM_ALPHA_SIZE); putAttrib(&attrib_list, accum_alpha); - putAttrib(&attrib_list, GLX_STEREO); putAttrib(&attrib_list, stereo ? True : False); - if (samples > 0 && extgl_Extensions.GLX_ARB_multisample) { - putAttrib(&attrib_list, GLX_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1); - putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples); - } - putAttrib(&attrib_list, None); putAttrib(&attrib_list, None); - int num_formats = 0; - GLXFBConfig* configs = glXChooseFBConfig(getDisplay(), getCurrentScreen(), attrib_list.attribs, &num_formats); - if (num_formats > 0) { - return configs; - } else { - if (configs != NULL) - XFree(configs); - return NULL; - } -} - -GLXFBConfig *chooseVisualGLX13(JNIEnv *env, jobject pixel_format, bool use_display_bpp, int drawable_type, bool double_buffer) { - jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); - int bpp; - if (use_display_bpp) { - bpp = XDefaultDepthOfScreen(XScreenOfDisplay(getDisplay(), getCurrentScreen())); - GLXFBConfig *configs = chooseVisualGLX13FromBPP(env, pixel_format, bpp, drawable_type, double_buffer); - if (configs != NULL) - return configs; - else - bpp = 16; - } else - bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "bpp", "I")); - return chooseVisualGLX13FromBPP(env, pixel_format, bpp, drawable_type, double_buffer); -} - -static XVisualInfo *chooseVisualGLX(JNIEnv *env, jobject pixel_format) { - int bpp = XDefaultDepthOfScreen(XScreenOfDisplay(getDisplay(), getCurrentScreen())); - jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); - int alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "alpha", "I")); - int depth = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "depth", "I")); - int stencil = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stencil", "I")); - int samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I")); - int num_aux_buffers = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "num_aux_buffers", "I")); - int accum_bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_bpp", "I")); - int accum_alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_alpha", "I")); - bool stereo = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stereo", "Z")); - - int bpe = convertToBPE(bpp); - int accum_bpe = convertToBPE(accum_bpp); - attrib_list_t attrib_list; - initAttribList(&attrib_list); - putAttrib(&attrib_list, GLX_RGBA); - putAttrib(&attrib_list, GLX_DOUBLEBUFFER); - putAttrib(&attrib_list, GLX_DEPTH_SIZE); putAttrib(&attrib_list, depth); - putAttrib(&attrib_list, GLX_RED_SIZE); putAttrib(&attrib_list, bpe); - putAttrib(&attrib_list, GLX_GREEN_SIZE); putAttrib(&attrib_list, bpe); - putAttrib(&attrib_list, GLX_BLUE_SIZE); putAttrib(&attrib_list, bpe); - putAttrib(&attrib_list, GLX_ALPHA_SIZE); putAttrib(&attrib_list, alpha); - putAttrib(&attrib_list, GLX_STENCIL_SIZE); putAttrib(&attrib_list, stencil); - putAttrib(&attrib_list, GLX_AUX_BUFFERS); putAttrib(&attrib_list, num_aux_buffers); - putAttrib(&attrib_list, GLX_ACCUM_RED_SIZE); putAttrib(&attrib_list, accum_bpe); - putAttrib(&attrib_list, GLX_ACCUM_GREEN_SIZE); putAttrib(&attrib_list, accum_bpe); - putAttrib(&attrib_list, GLX_ACCUM_BLUE_SIZE); putAttrib(&attrib_list, accum_bpe); - putAttrib(&attrib_list, GLX_ACCUM_ALPHA_SIZE); putAttrib(&attrib_list, accum_alpha); - if (stereo) - putAttrib(&attrib_list, GLX_STEREO); - if (samples > 0 && extgl_Extensions.GLX_ARB_multisample) { - putAttrib(&attrib_list, GLX_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1); - putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples); - } - putAttrib(&attrib_list, None); - return glXChooseVisual(getDisplay(), getCurrentScreen(), attrib_list.attribs); -} - -static void dumpVisualInfo(XVisualInfo *vis_info) { - int alpha, depth, stencil, r, g, b; - int sample_buffers = 0; - int samples = 0; - glXGetConfig(getDisplay(), vis_info, GLX_RED_SIZE, &r); - glXGetConfig(getDisplay(), vis_info, GLX_GREEN_SIZE, &g); - glXGetConfig(getDisplay(), vis_info, GLX_BLUE_SIZE, &b); - glXGetConfig(getDisplay(), vis_info, GLX_ALPHA_SIZE, &alpha); - glXGetConfig(getDisplay(), vis_info, GLX_DEPTH_SIZE, &depth); - glXGetConfig(getDisplay(), vis_info, GLX_STENCIL_SIZE, &stencil); - if (extgl_Extensions.GLX_ARB_multisample) { - glXGetConfig(getDisplay(), vis_info, GLX_SAMPLE_BUFFERS_ARB, &sample_buffers); - glXGetConfig(getDisplay(), vis_info, GLX_SAMPLES_ARB, &samples); - } - printfDebug("Pixel format info: r = %d, g = %d, b = %d, a = %d, depth = %d, stencil = %d, sample buffers = %d, samples = %d\n", r, g, b, alpha, depth, stencil, sample_buffers, samples); -} - -static void destroyContext(void) { - if (USEGLX13) { - XFree(configs); - configs = NULL; - } - XFree(vis_info); - vis_info = NULL; - glXDestroyContext(getDisplay(), context); - context = NULL; -} - -static bool initWindowGLX13(JNIEnv *env, jobject pixel_format) { - configs = chooseVisualGLX13(env, pixel_format, true, GLX_WINDOW_BIT, true); - if (configs == NULL) { - throwException(env, "Could not find a matching pixel format"); - return false; - } - context = glXCreateNewContext(getDisplay(), configs[0], GLX_RGBA_TYPE, NULL, True); - if (context == NULL) { - XFree(configs); - throwException(env, "Could not create a GLX context"); - return false; - } - jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Window.allowSoftwareOpenGL"); - if (!allow_software_acceleration && (glXIsDirect(getDisplay(), context) == False)) { - glXDestroyContext(getDisplay(), context); - XFree(configs); - throwException(env, "Could not create a direct GLX context"); - return false; - } - vis_info = glXGetVisualFromFBConfig(getDisplay(), configs[0]); - if (vis_info == NULL) { - glXDestroyContext(getDisplay(), context); - XFree(configs); - throwException(env, "Could not get visual from FB config"); - return false; - } - if (!checkXError(env)) { - glXDestroyContext(getDisplay(), context); - XFree(configs); - XFree(vis_info); - return false; - } - return true; -} - -static bool initWindowGLX(JNIEnv *env, jobject pixel_format) { - vis_info = chooseVisualGLX(env, pixel_format); - if (vis_info == NULL) { - throwException(env, "Could not find a matching pixel format"); - return false; - } - if (isDebugEnabled()) - dumpVisualInfo(vis_info); - context = glXCreateContext(getDisplay(), vis_info, NULL, True); - if (context == NULL) { - XFree(vis_info); - throwException(env, "Could not create a GLX context"); - return false; - } - jboolean allow_software_acceleration = getBooleanProperty(env, "org.lwjgl.opengl.Window.allowSoftwareOpenGL"); - if (!allow_software_acceleration && glXIsDirect(getDisplay(), context) == False) { - glXDestroyContext(getDisplay(), context); - XFree(vis_info); - throwException(env, "Could not create a direct GLX context"); - return false; - } - if (!checkXError(env)) { - glXDestroyContext(getDisplay(), context); - XFree(vis_info); - return false; - } - return true; -} - -JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_Display_nGetAvailableDisplayModes(JNIEnv *env, jclass clazz) { - return getAvailableDisplayModes(env, getCurrentScreen()); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nSwitchDisplayMode(JNIEnv *env, jclass clazz, jobject mode) { - switchDisplayMode(env, mode, getCurrentScreen()); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_resetDisplayMode(JNIEnv *env, jclass clazz) { - resetDisplayMode(getCurrentScreen(), false); -} - -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Display_getGammaRampLength(JNIEnv *env, jclass clazz) { - return (jint)getGammaRampLength(getCurrentScreen()); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_setGammaRamp(JNIEnv *env, jclass clazz, jobject gamma_buffer) { - setGammaRamp(env, gamma_buffer, getCurrentScreen()); -} - -JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Display_init(JNIEnv *env, jclass clazz) { - return initDisplay(env, getCurrentScreen()); -} - -JNIEXPORT jstring JNICALL Java_org_lwjgl_opengl_Display_getAdapter(JNIEnv *env , jclass clazz) { - return NULL; -} - -JNIEXPORT jstring JNICALL Java_org_lwjgl_opengl_Display_getVersion(JNIEnv *env, jclass clazz) { - return NULL; -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_createContext(JNIEnv *env, jclass clazz, jobject pixel_format) { - Display *disp = incDisplay(env); - if (disp == NULL) { - return; - } - current_screen = XDefaultScreen(disp); - if (!extgl_InitGLX(env, disp, current_screen)) { - decDisplay(); - throwException(env, "Could not init GLX"); - return; - } - - if (USEGLX13) { - initWindowGLX13(env, pixel_format); - } else { - initWindowGLX(env, pixel_format); - } -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_destroyContext(JNIEnv *env, jclass clazz) { - destroyContext(); - decDisplay(); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nCreateWindow(JNIEnv *env, jclass clazz, jobject mode, jboolean fullscreen, int x, int y) { - bool current_fullscreen = fullscreen == JNI_TRUE; - if (current_fullscreen) { - if (getCurrentDisplayModeExtension() == XRANDR && isNetWMFullscreenSupported()) - current_window_mode = FULLSCREEN_NETWM; - else - current_window_mode = FULLSCREEN_LEGACY; - } else - current_window_mode = WINDOWED; - jclass cls_displayMode = (*env)->GetObjectClass(env, mode); - jfieldID fid_width = (*env)->GetFieldID(env, cls_displayMode, "width", "I"); - jfieldID fid_height = (*env)->GetFieldID(env, cls_displayMode, "height", "I"); - int width = (*env)->GetIntField(env, mode, fid_width); - int height = (*env)->GetIntField(env, mode, fid_height); - bool window_created = createWindow(env, x, y, width, height); - if (!window_created) { - return; - } - if (isDebugEnabled()) - dumpVisualInfo(vis_info); - if (USEGLX13) - glx_window = glXCreateWindow(getDisplay(), configs[0], getCurrentWindow(), NULL); - if (!makeCurrent() || !checkXError(env)) { - glXDestroyWindow(getDisplay(), glx_window); - destroyWindow(); - } -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nDestroyWindow(JNIEnv *env, jclass clazz) { - destroyWindow(); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_swapBuffers(JNIEnv * env, jclass clazz) -{ - dirty = false; - if (USEGLX13) - glXSwapBuffers(getDisplay(), glx_window); - else - glXSwapBuffers(getDisplay(), getCurrentWindow()); -} - -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Display_nIsDirty - (JNIEnv *env, jclass clazz) { - bool result = dirty; - dirty = false; - return result ? JNI_TRUE : JNI_FALSE; -} - -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Display_nIsVisible - (JNIEnv *env, jclass clazz) { - return minimized ? JNI_FALSE : JNI_TRUE; -} - -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Display_nIsCloseRequested - (JNIEnv *env, jclass clazz) { - bool saved = closerequested; - closerequested = false; - return saved; -} - -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Display_nIsActive - (JNIEnv *env, jclass clazz) { - return focused ? JNI_TRUE : JNI_FALSE; -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nSetVSyncEnabled - (JNIEnv *env, jclass clazz, jboolean sync) -{ - if (extgl_Extensions.GLX_SGI_swap_control) { - bool vsync = sync == JNI_TRUE ? true : false; - if (vsync != vsync_enabled) { - int interval = vsync ? 1 : 0; - glXSwapIntervalSGI(interval); - vsync_enabled = vsync; - } - } -} -