From 62e561cddf26455461420ee883db05f223e9bf56 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Mon, 21 Feb 2005 14:46:47 +0000 Subject: [PATCH] Win32 part of refactor and AWTGLCanvas --- build.xml | 5 + platform_build/win32_ms_cmdline/build.bat | 2 +- src/java/org/lwjgl/Sys.java | 2 + .../lwjgl/opengl/AWTCanvasImplementation.java | 2 +- src/java/org/lwjgl/opengl/AWTGLCanvas.java | 5 +- src/java/org/lwjgl/opengl/AWTSurfaceLock.java | 8 +- src/java/org/lwjgl/opengl/GLContext.java | 2 + .../opengl/LinuxAWTGLCanvasPeerInfo.java | 2 - .../opengl/LinuxCanvasImplementation.java | 2 +- src/java/org/lwjgl/opengl/LinuxDisplay.java | 2 +- .../lwjgl/opengl/LinuxDisplayPeerInfo.java | 14 +- .../opengl/Win32AWTGLCanvasPeerInfo.java | 70 +++ .../opengl/Win32CanvasImplementation.java | 68 +++ .../opengl/Win32ContextImplementation.java | 103 +++++ src/java/org/lwjgl/opengl/Win32Display.java | 79 +++- .../lwjgl/opengl/Win32DisplayPeerInfo.java | 78 ++++ .../lwjgl/opengl/Win32PbufferPeerInfo.java | 85 ++++ src/java/org/lwjgl/opengl/Win32PeerInfo.java | 58 +++ src/native/common/awt_tools.h | 5 + src/native/common/common_tools.c | 7 + src/native/common/common_tools.h | 1 + src/native/common/extgl.h | 1 - .../common/org_lwjgl_opengl_AWTSurfaceLock.c | 19 +- src/native/win32/Window.h | 21 +- src/native/win32/context.c | 417 ++++++++++++++++++ src/native/win32/context.h | 88 ++++ src/native/win32/display.c | 81 +--- src/native/win32/extgl_wgl.c | 3 +- src/native/win32/extgl_wgl.h | 2 + src/native/win32/org_lwjgl_input_Cursor.c | 157 ++++--- .../win32/org_lwjgl_opengl_AWTGLCanvas.c | 331 -------------- src/native/win32/org_lwjgl_opengl_Display.c | 172 +++----- src/native/win32/org_lwjgl_opengl_Pbuffer.c | 105 ++++- ...rg_lwjgl_opengl_Win32AWTGLCanvasPeerInfo.c | 57 +++ ..._lwjgl_opengl_Win32ContextImplementation.c | 122 +++++ .../org_lwjgl_opengl_Win32DisplayPeerInfo.c | 78 ++++ .../win32/org_lwjgl_opengl_Win32PeerInfo.c | 60 +++ 37 files changed, 1644 insertions(+), 670 deletions(-) create mode 100644 src/java/org/lwjgl/opengl/Win32AWTGLCanvasPeerInfo.java create mode 100644 src/java/org/lwjgl/opengl/Win32CanvasImplementation.java create mode 100644 src/java/org/lwjgl/opengl/Win32ContextImplementation.java create mode 100644 src/java/org/lwjgl/opengl/Win32DisplayPeerInfo.java create mode 100644 src/java/org/lwjgl/opengl/Win32PbufferPeerInfo.java create mode 100644 src/java/org/lwjgl/opengl/Win32PeerInfo.java create mode 100644 src/native/win32/context.c create mode 100644 src/native/win32/context.h delete mode 100644 src/native/win32/org_lwjgl_opengl_AWTGLCanvas.c create mode 100644 src/native/win32/org_lwjgl_opengl_Win32AWTGLCanvasPeerInfo.c create mode 100644 src/native/win32/org_lwjgl_opengl_Win32ContextImplementation.c create mode 100644 src/native/win32/org_lwjgl_opengl_Win32DisplayPeerInfo.c create mode 100644 src/native/win32/org_lwjgl_opengl_Win32PeerInfo.c diff --git a/build.xml b/build.xml index 27fa2ca9..aaeb83cd 100644 --- a/build.xml +++ b/build.xml @@ -566,8 +566,13 @@ + + + + + diff --git a/platform_build/win32_ms_cmdline/build.bat b/platform_build/win32_ms_cmdline/build.bat index 120103f2..19f74a04 100644 --- a/platform_build/win32_ms_cmdline/build.bat +++ b/platform_build/win32_ms_cmdline/build.bat @@ -10,7 +10,7 @@ rem Can't get /DELAYLOAD to work rem set LINKEROPTS=/link /LIBPATH:"%JAVA_HOME%\lib" /LIBPATH:"%ALHOME%\libs" /LIBPATH:"%DXHOME%\Lib" /LIBPATH:"%PLTSDKHOME%\Lib" /LIBPATH:"%CHOME%\Lib" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:X86 /NOLOGO /DLL /DELAYLOAD:jawt.dll rem set LIBS=dinput.lib dxguid.lib OpenGL32.Lib Version.lib user32.lib Gdi32.lib Advapi32.lib jawt.lib delayimp.lib set LINKEROPTS=/link /LIBPATH:"%JAVA_HOME%\lib" /LIBPATH:"%ALHOME%\libs" /LIBPATH:"%DXHOME%\Lib" /LIBPATH:"%PLTSDKHOME%\Lib" /LIBPATH:"%CHOME%\Lib" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:X86 /NOLOGO /DLL -set LIBS=dinput.lib dxguid.lib OpenGL32.Lib Version.lib user32.lib Gdi32.lib Advapi32.lib jawt.lib +set LIBS=Kernel32.lib dinput.lib dxguid.lib OpenGL32.Lib Version.lib user32.lib Gdi32.lib Advapi32.lib jawt.lib for %%x in (..\..\src\native\win32\*.c) do cl %COPTIONS% %%x for %%x in (..\..\src\native\common\*.c) do cl %COPTIONS% %%x diff --git a/src/java/org/lwjgl/Sys.java b/src/java/org/lwjgl/Sys.java index cf2fe98a..9e9a0b27 100644 --- a/src/java/org/lwjgl/Sys.java +++ b/src/java/org/lwjgl/Sys.java @@ -63,6 +63,8 @@ public final class Sys { private final static SysImplementation implementation; static { + System.loadLibrary("awt"); + System.loadLibrary("jawt"); System.loadLibrary(LIBRARY_NAME); implementation = createImplementation(); String native_version = implementation.getNativeLibraryVersion(); diff --git a/src/java/org/lwjgl/opengl/AWTCanvasImplementation.java b/src/java/org/lwjgl/opengl/AWTCanvasImplementation.java index 555ca38f..18b4e174 100644 --- a/src/java/org/lwjgl/opengl/AWTCanvasImplementation.java +++ b/src/java/org/lwjgl/opengl/AWTCanvasImplementation.java @@ -48,7 +48,7 @@ interface AWTCanvasImplementation { /** * Return an opaque handle to the canvas peer information required to create a context from it. */ - public PeerInfo createPeerInfo(AWTGLCanvas canvas) throws LWJGLException; + public PeerInfo createPeerInfo(AWTGLCanvas canvas, PixelFormat pixel_format) throws LWJGLException; /** * Find a proper GraphicsConfiguration from the given GraphicsDevice and PixelFormat. diff --git a/src/java/org/lwjgl/opengl/AWTGLCanvas.java b/src/java/org/lwjgl/opengl/AWTGLCanvas.java index 1e5560b1..2e726ec5 100644 --- a/src/java/org/lwjgl/opengl/AWTGLCanvas.java +++ b/src/java/org/lwjgl/opengl/AWTGLCanvas.java @@ -51,14 +51,13 @@ public class AWTGLCanvas extends Canvas implements Drawable { private final static AWTCanvasImplementation implementation; static { - System.loadLibrary("jawt"); Sys.initialize(); String class_name; String OS_NAME = System.getProperty("os.name"); if (OS_NAME.startsWith("Linux")) { class_name = "org.lwjgl.opengl.LinuxCanvasImplementation"; } else if (OS_NAME.startsWith("Windows")) { - class_name = "org.lwjgl.opengl.DefaultCanvasImplementation"; + class_name = "org.lwjgl.opengl.Win32CanvasImplementation"; } else if (OS_NAME.startsWith("Mac")) { class_name = "org.lwjgl.opengl.DefaultCanvasImplementation"; } else @@ -127,7 +126,7 @@ public class AWTGLCanvas extends Canvas implements Drawable { */ public AWTGLCanvas(GraphicsDevice device, PixelFormat pixel_format, Drawable drawable) throws LWJGLException { super(implementation.findConfiguration(device, pixel_format)); - this.peer_info = implementation.createPeerInfo(this); + this.peer_info = implementation.createPeerInfo(this, pixel_format); this.drawable = drawable; } diff --git a/src/java/org/lwjgl/opengl/AWTSurfaceLock.java b/src/java/org/lwjgl/opengl/AWTSurfaceLock.java index 9b3812c2..14475247 100644 --- a/src/java/org/lwjgl/opengl/AWTSurfaceLock.java +++ b/src/java/org/lwjgl/opengl/AWTSurfaceLock.java @@ -46,8 +46,12 @@ import java.awt.Canvas; * @version $Revision$ */ final class AWTSurfaceLock { - private final static int LOCK_HANDLE_SIZE = 64; - private final ByteBuffer lock_buffer = BufferUtils.createByteBuffer(LOCK_HANDLE_SIZE); + private final ByteBuffer lock_buffer; + + public AWTSurfaceLock() { + lock_buffer = createHandle(); + } + private static native ByteBuffer createHandle(); public ByteBuffer lockAndGetHandle(Canvas canvas) throws LWJGLException { lockAndInitHandle(lock_buffer, canvas); diff --git a/src/java/org/lwjgl/opengl/GLContext.java b/src/java/org/lwjgl/opengl/GLContext.java index caa7477c..288ec814 100644 --- a/src/java/org/lwjgl/opengl/GLContext.java +++ b/src/java/org/lwjgl/opengl/GLContext.java @@ -111,6 +111,8 @@ public final class GLContext { static Set getSupportedExtensions() { Set supported_extensions = new HashSet(); String extensions_string = GL11.glGetString(GL11.GL_EXTENSIONS); + if (extensions_string == null) + throw new IllegalStateException("glGetString(GL_EXTENSIONS) returned null - is there a context current?"); StringTokenizer tokenizer = new StringTokenizer(extensions_string); while ( tokenizer.hasMoreTokens() ) { String extension_string = tokenizer.nextToken(); diff --git a/src/java/org/lwjgl/opengl/LinuxAWTGLCanvasPeerInfo.java b/src/java/org/lwjgl/opengl/LinuxAWTGLCanvasPeerInfo.java index 9cb5b193..02f4f11b 100644 --- a/src/java/org/lwjgl/opengl/LinuxAWTGLCanvasPeerInfo.java +++ b/src/java/org/lwjgl/opengl/LinuxAWTGLCanvasPeerInfo.java @@ -44,8 +44,6 @@ import org.lwjgl.Sys; * @version $Revision$ */ final class LinuxAWTGLCanvasPeerInfo extends LinuxPeerInfo { - private final static int LOCK_HANDLE_SIZE = 64; - private final ByteBuffer lock_buffer = BufferUtils.createByteBuffer(LOCK_HANDLE_SIZE); private final AWTGLCanvas canvas; private final AWTSurfaceLock awt_surface = new AWTSurfaceLock(); diff --git a/src/java/org/lwjgl/opengl/LinuxCanvasImplementation.java b/src/java/org/lwjgl/opengl/LinuxCanvasImplementation.java index 683d4b4f..6e4d40fd 100644 --- a/src/java/org/lwjgl/opengl/LinuxCanvasImplementation.java +++ b/src/java/org/lwjgl/opengl/LinuxCanvasImplementation.java @@ -68,7 +68,7 @@ final class LinuxCanvasImplementation implements AWTCanvasImplementation { } } - public PeerInfo createPeerInfo(AWTGLCanvas canvas) throws LWJGLException { + public PeerInfo createPeerInfo(AWTGLCanvas canvas, PixelFormat pixel_format) throws LWJGLException { return new LinuxAWTGLCanvasPeerInfo(canvas); } diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index 302c5780..865bb362 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -49,7 +49,7 @@ import org.lwjgl.input.Keyboard; final class LinuxDisplay implements DisplayImplementation { private static final int CURSOR_HANDLE_SIZE = 8; - private static final int PBUFFER_HANDLE_SIZE = 24; +// private static final int PBUFFER_HANDLE_SIZE = 24; private static final int NUM_BUTTONS = 3; private static PeerInfo peer_info; diff --git a/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java b/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java index 92273cc3..1a655621 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplayPeerInfo.java @@ -46,15 +46,21 @@ import org.lwjgl.Sys; final class LinuxDisplayPeerInfo extends LinuxPeerInfo { public LinuxDisplayPeerInfo(PixelFormat pixel_format) throws LWJGLException { LinuxDisplay.lockAWT(); - initDefaultPeerInfo(getHandle(), pixel_format); - LinuxDisplay.unlockAWT(); + try { + initDefaultPeerInfo(getHandle(), pixel_format); + } finally { + LinuxDisplay.unlockAWT(); + } } private static native void initDefaultPeerInfo(ByteBuffer peer_info_handle, PixelFormat pixel_format) throws LWJGLException; protected void doLockAndInitHandle() throws LWJGLException { LinuxDisplay.lockAWT(); - initDrawable(getHandle()); - LinuxDisplay.unlockAWT(); + try { + initDrawable(getHandle()); + } finally { + LinuxDisplay.unlockAWT(); + } } private static native void initDrawable(ByteBuffer peer_info_handle); diff --git a/src/java/org/lwjgl/opengl/Win32AWTGLCanvasPeerInfo.java b/src/java/org/lwjgl/opengl/Win32AWTGLCanvasPeerInfo.java new file mode 100644 index 00000000..84aeb071 --- /dev/null +++ b/src/java/org/lwjgl/opengl/Win32AWTGLCanvasPeerInfo.java @@ -0,0 +1,70 @@ +/* + * 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.ByteBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; + +/** + * $Id$ + * + * @author elias_naur + * @version $Revision$ + */ +final class Win32AWTGLCanvasPeerInfo extends Win32PeerInfo { + private final AWTGLCanvas canvas; + private final AWTSurfaceLock awt_surface = new AWTSurfaceLock(); + private final PixelFormat pixel_format; + private boolean has_pixel_format= false; + + public Win32AWTGLCanvasPeerInfo(AWTGLCanvas canvas, PixelFormat pixel_format) { + this.canvas = canvas; + this.pixel_format = pixel_format; + } + + protected void doLockAndInitHandle() throws LWJGLException { + nInitHandle(awt_surface.lockAndGetHandle(canvas), getHandle()); + if (!has_pixel_format) { + // If we haven't applied a pixel format yet, do it now + choosePixelFormat(canvas.getX(), canvas.getY(), pixel_format, null, true, true, false, true); + has_pixel_format = true; + } + } + private static native void nInitHandle(ByteBuffer surface_buffer, ByteBuffer peer_info_handle) throws LWJGLException; + + protected void doUnlock() throws LWJGLException { + awt_surface.unlock(); + } +} diff --git a/src/java/org/lwjgl/opengl/Win32CanvasImplementation.java b/src/java/org/lwjgl/opengl/Win32CanvasImplementation.java new file mode 100644 index 00000000..75790253 --- /dev/null +++ b/src/java/org/lwjgl/opengl/Win32CanvasImplementation.java @@ -0,0 +1,68 @@ +/* + * 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.ByteBuffer; + +import org.lwjgl.LWJGLException; +import org.lwjgl.BufferUtils; + +import java.awt.GraphicsDevice; +import java.awt.GraphicsConfiguration; +import java.awt.Rectangle; + +import java.lang.reflect.Method; + +/** + * $Id$ + * + * @author elias_naur + * @version $Revision$ + */ +final class Win32CanvasImplementation implements AWTCanvasImplementation { + public PeerInfo createPeerInfo(AWTGLCanvas canvas, PixelFormat pixel_format) throws LWJGLException { + return new Win32AWTGLCanvasPeerInfo(canvas, pixel_format); + } + + /** + * Find a proper GraphicsConfiguration from the given GraphicsDevice and PixelFormat. + * + * @return The GraphicsConfiguration corresponding to a visual that matches the pixel format. + */ + public GraphicsConfiguration findConfiguration(GraphicsDevice device, PixelFormat pixel_format) throws LWJGLException { + /* + * It seems like the best way is to simply return null and let + * use SetPixelFormat in JNI later. + */ + return null; + } +} diff --git a/src/java/org/lwjgl/opengl/Win32ContextImplementation.java b/src/java/org/lwjgl/opengl/Win32ContextImplementation.java new file mode 100644 index 00000000..97041b31 --- /dev/null +++ b/src/java/org/lwjgl/opengl/Win32ContextImplementation.java @@ -0,0 +1,103 @@ +/* + * 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.ByteBuffer; + +import org.lwjgl.LWJGLException; +import org.lwjgl.BufferUtils; + +/** + * $Id$ + * + * @author elias_naur + * @version $Revision$ + */ +final class Win32ContextImplementation implements ContextImplementation { + private static PeerInfo getCurrentPeerInfo() { + return Context.getCurrentContext().getPeerInfo(); + } + + public ByteBuffer create(PeerInfo peer_info, ByteBuffer shared_context_handle) throws LWJGLException { + ByteBuffer peer_handle = peer_info.lockAndGetHandle(); + try { + return nCreate(peer_handle, shared_context_handle); + } finally { + peer_info.unlock(); + } + } + private static native ByteBuffer nCreate(ByteBuffer peer_handle, ByteBuffer shared_context_handle) throws LWJGLException; + + public void swapBuffers() throws LWJGLException { + PeerInfo current_peer_info = getCurrentPeerInfo(); + if (current_peer_info == null) + throw new IllegalStateException("No context is current"); + ByteBuffer peer_handle = current_peer_info.lockAndGetHandle(); + try { + nSwapBuffers(peer_handle); + } finally { + current_peer_info.unlock(); + } + } + private static native void nSwapBuffers(ByteBuffer peer_info_handle) throws LWJGLException; + + public void releaseCurrentContext() throws LWJGLException { + nReleaseCurrentContext(); + } + private static native void nReleaseCurrentContext() throws LWJGLException; + + public void makeCurrent(PeerInfo peer_info, ByteBuffer handle) throws LWJGLException { + ByteBuffer peer_handle = peer_info.lockAndGetHandle(); + try { + nMakeCurrent(peer_handle, handle); + } finally { + peer_info.unlock(); + } + } + private static native void nMakeCurrent(ByteBuffer peer_handle, ByteBuffer context_handle) throws LWJGLException; + + public boolean isCurrent(ByteBuffer handle) throws LWJGLException { + boolean result = nIsCurrent(handle); + return result; + } + private static native boolean nIsCurrent(ByteBuffer context_handle) throws LWJGLException; + + public void setVSync(boolean enabled) { + nSetVSync(enabled); + } + private static native void nSetVSync(boolean enabled); + + public void destroy(PeerInfo peer_info, ByteBuffer handle) throws LWJGLException { + nDestroy(handle); + } + private static native void nDestroy(ByteBuffer context_handle) throws LWJGLException; +} diff --git a/src/java/org/lwjgl/opengl/Win32Display.java b/src/java/org/lwjgl/opengl/Win32Display.java index 61650494..bacb496e 100644 --- a/src/java/org/lwjgl/opengl/Win32Display.java +++ b/src/java/org/lwjgl/opengl/Win32Display.java @@ -42,15 +42,21 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; +import org.lwjgl.Sys; import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLException; import org.lwjgl.input.Cursor; final class Win32Display implements DisplayImplementation { - private static final int CURSOR_HANDLE_SIZE = 8; - private static final int PBUFFER_HANDLE_SIZE = 24; +// private static final int PBUFFER_HANDLE_SIZE = 24; - public native void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException; + private static Win32DisplayPeerInfo peer_info; + + public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException { + nCreateWindow(mode, fullscreen, x, y); + peer_info.initDC(); + } + private native void nCreateWindow(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(); @@ -67,13 +73,41 @@ final class Win32Display implements DisplayImplementation { // public native void swapBuffers(); // public native void makeCurrent() throws LWJGLException; public PeerInfo createPeerInfo(PixelFormat pixel_format) throws LWJGLException { - throw new RuntimeException("Not supported yet"); + GLContext.loadOpenGLLibrary(); + try { + peer_info = new Win32DisplayPeerInfo(pixel_format); + return peer_info; + } catch (LWJGLException e) { + GLContext.unloadOpenGLLibrary(); + throw e; + } } // public native void createContext(PixelFormat pixel_format) throws LWJGLException; // public native void destroyContext(); - public native void destroyPeerInfo(); - public native void update(); - public native void setVSyncEnabled(boolean sync); + public void destroyPeerInfo() { + peer_info.destroy(); + GLContext.unloadOpenGLLibrary(); + } + public void update() { + nUpdate(); + if (didMaximize()) { + /** + * WORKAROUND: + * Making the context current (redundantly) when the window + * is maximized helps some gfx recover from fullscreen + */ + try { + if (Display.getContext().isCurrent()) + Display.getContext().makeCurrent(); + } catch (LWJGLException e) { + Sys.log("Exception occurred while trying to make context current: " + e); + } + } + } + private native void nUpdate(); + private native boolean didMaximize(); + +// public native void setVSyncEnabled(boolean sync); public native void reshape(int x, int y, int width, int height); public native DisplayMode[] getAvailableDisplayModes() throws LWJGLException; @@ -100,24 +134,25 @@ final class Win32Display implements DisplayImplementation { public native int readKeyboard(IntBuffer buffer, int buffer_position); public native int isStateKeySet(int key); - public native void nCreateCursor(ByteBuffer handle, int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, int images_offset, IntBuffer delays, int delays_offset) throws LWJGLException; + public native ByteBuffer nCreateCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, int images_offset, IntBuffer delays, int delays_offset) throws LWJGLException; public Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException { - ByteBuffer handle = BufferUtils.createByteBuffer(CURSOR_HANDLE_SIZE); - nCreateCursor(handle, width, height, xHotspot, yHotspot, numImages, images, images.position(), delays, delays != null ? delays.position() : -1); - return handle; + return nCreateCursor(width, height, xHotspot, yHotspot, numImages, images, images.position(), delays, delays != null ? delays.position() : -1); } public native void destroyCursor(Object cursorHandle); public native int getPbufferCapabilities(); - public native boolean isBufferLost(PeerInfo handle); + public boolean isBufferLost(PeerInfo handle) { + return ((Win32PbufferPeerInfo)handle).isBufferLost(); + } + // public native boolean isBufferLost(ByteBuffer handle); // public native void makePbufferCurrent(ByteBuffer handle) throws LWJGLException; public PeerInfo createPbuffer(int width, int height, PixelFormat pixel_format, IntBuffer pixelFormatCaps, IntBuffer pBufferAttribs) throws LWJGLException { - throw new RuntimeException("Not yet supported"); + return new Win32PbufferPeerInfo(width, height, pixel_format, pixelFormatCaps, pBufferAttribs); } /* public ByteBuffer createPbuffer(int width, int height, PixelFormat pixel_format, @@ -132,12 +167,22 @@ final class Win32Display implements DisplayImplementation { IntBuffer pixelFormatCaps, IntBuffer pBufferAttribs, ByteBuffer shared_pbuffer_handle) throws LWJGLException; */ - public native void destroyPbuffer(PeerInfo handle); + public void destroyPbuffer(PeerInfo handle) { + ((Win32PbufferPeerInfo)handle).destroy(); + } // public native void destroyPbuffer(ByteBuffer handle); - public native void setPbufferAttrib(PeerInfo handle, int attrib, int value); - public native void bindTexImageToPbuffer(PeerInfo handle, int buffer); - public native void releaseTexImageFromPbuffer(PeerInfo handle, int buffer); + public void setPbufferAttrib(PeerInfo handle, int attrib, int value) { + ((Win32PbufferPeerInfo)handle).setPbufferAttrib(attrib, value); + } + + public void bindTexImageToPbuffer(PeerInfo handle, int buffer) { + ((Win32PbufferPeerInfo)handle).bindTexImageToPbuffer(buffer); + } + + public void releaseTexImageFromPbuffer(PeerInfo handle, int buffer) { + ((Win32PbufferPeerInfo)handle).releaseTexImageFromPbuffer(buffer); + } /* public native void setPbufferAttrib(ByteBuffer handle, int attrib, int value); public native void bindTexImageToPbuffer(ByteBuffer handle, int buffer); public native void releaseTexImageFromPbuffer(ByteBuffer handle, int buffer);*/ diff --git a/src/java/org/lwjgl/opengl/Win32DisplayPeerInfo.java b/src/java/org/lwjgl/opengl/Win32DisplayPeerInfo.java new file mode 100644 index 00000000..3cb4ee5d --- /dev/null +++ b/src/java/org/lwjgl/opengl/Win32DisplayPeerInfo.java @@ -0,0 +1,78 @@ +/* + * 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.ByteBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; + +/** + * $Id$ + * + * @author elias_naur + * @version $Revision$ + */ +final class Win32DisplayPeerInfo extends Win32PeerInfo { + public Win32DisplayPeerInfo(PixelFormat pixel_format) throws LWJGLException { + createDummyDC(getHandle()); + try { + choosePixelFormat(0, 0, pixel_format, null, true, true, false, true); + } catch (LWJGLException e) { + destroy(); + throw e; + } + } + private static native void createDummyDC(ByteBuffer peer_info_handle) throws LWJGLException; + + void initDC() { + nInitDC(getHandle()); + } + private static native void nInitDC(ByteBuffer peer_info_handle); + + void destroy() { + nDestroy(getHandle()); + } + + private static native void nDestroy(ByteBuffer peer_info_handle); + + protected void doLockAndInitHandle() throws LWJGLException { + // NO-OP + } + + private static native void setPixelFormat(ByteBuffer peer_info_handle); + + protected void doUnlock() throws LWJGLException { + // NO-OP + } +} diff --git a/src/java/org/lwjgl/opengl/Win32PbufferPeerInfo.java b/src/java/org/lwjgl/opengl/Win32PbufferPeerInfo.java new file mode 100644 index 00000000..028bcc3f --- /dev/null +++ b/src/java/org/lwjgl/opengl/Win32PbufferPeerInfo.java @@ -0,0 +1,85 @@ +/* + * 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.ByteBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; + +/** + * $Id$ + * + * @author elias_naur + * @version $Revision$ + */ +final class Win32PbufferPeerInfo extends Win32PeerInfo { + public Win32PbufferPeerInfo(int width, int height, PixelFormat pixel_format, IntBuffer pixelFormatCaps, IntBuffer pBufferAttribs) throws LWJGLException { + nCreate(getHandle(), width, height, pixel_format, pixelFormatCaps, pBufferAttribs); + } + private static native void nCreate(ByteBuffer handle, int width, int height, PixelFormat pixel_format, IntBuffer pixelFormatCaps, IntBuffer pBufferAttribs) throws LWJGLException; + + public boolean isBufferLost() { + return nIsBufferLost(getHandle()); + } + private static native boolean nIsBufferLost(ByteBuffer handle); + + public void setPbufferAttrib(int attrib, int value) { + nSetPbufferAttrib(getHandle(), attrib, value); + } + private static native void nSetPbufferAttrib(ByteBuffer handle, int attrib, int value); + + public void bindTexImageToPbuffer(int buffer) { + nBindTexImageToPbuffer(getHandle(), buffer); + } + private static native void nBindTexImageToPbuffer(ByteBuffer handle, int buffer); + + public void releaseTexImageFromPbuffer(int buffer) { + nReleaseTexImageFromPbuffer(getHandle(), buffer); + } + private static native void nReleaseTexImageFromPbuffer(ByteBuffer handle, int buffer); + + public void destroy() { + nDestroy(getHandle()); + } + private static native void nDestroy(ByteBuffer handle); + + protected void doLockAndInitHandle() throws LWJGLException { + // NO-OP + } + + protected void doUnlock() throws LWJGLException { + // NO-OP + } +} diff --git a/src/java/org/lwjgl/opengl/Win32PeerInfo.java b/src/java/org/lwjgl/opengl/Win32PeerInfo.java new file mode 100644 index 00000000..5e80500e --- /dev/null +++ b/src/java/org/lwjgl/opengl/Win32PeerInfo.java @@ -0,0 +1,58 @@ +/* + * 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.ByteBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; + +import java.nio.IntBuffer; + +/** + * $Id$ + * + * @author elias_naur + * @version $Revision$ + */ +abstract class Win32PeerInfo extends PeerInfo { + public Win32PeerInfo() { + super(createHandle()); + } + private static native ByteBuffer createHandle(); + + protected void choosePixelFormat(int origin_x, int origin_y, PixelFormat pixel_format, IntBuffer pixel_format_caps, boolean use_hdc_bpp, boolean support_window, boolean support_pbuffer, boolean double_buffered) throws LWJGLException { + nChoosePixelFormat(getHandle(), origin_x, origin_y, pixel_format, pixel_format_caps, use_hdc_bpp, support_window, support_pbuffer, double_buffered); + } + private static native void nChoosePixelFormat(ByteBuffer peer_info_handle, int origin_x, int origin_y, PixelFormat pixel_format, IntBuffer pixel_format_caps, boolean use_hdc_bpp, boolean support_window, boolean support_pbuffer, boolean double_buffered) throws LWJGLException; +} diff --git a/src/native/common/awt_tools.h b/src/native/common/awt_tools.h index ac641d70..d734c577 100644 --- a/src/native/common/awt_tools.h +++ b/src/native/common/awt_tools.h @@ -37,6 +37,9 @@ * @version $Revision$ */ +#ifndef __LWJGL_AWT_TOOLS_H +#define __LWJGL_AWT_TOOLS_H + #include #include #include @@ -46,3 +49,5 @@ typedef struct { JAWT_DrawingSurface* ds; JAWT_DrawingSurfaceInfo *dsi; } AWTSurfaceLock; + +#endif \ No newline at end of file diff --git a/src/native/common/common_tools.c b/src/native/common/common_tools.c index 468b0b71..8d73872e 100644 --- a/src/native/common/common_tools.c +++ b/src/native/common/common_tools.c @@ -273,6 +273,13 @@ bool ext_InitializeFunctions(ExtGetProcAddressPROC gpa, int num_functions, ExtFu return true; } +jobject newJavaManagedByteBuffer(JNIEnv *env, const int size) { + jclass bufferutils_class = (*env)->FindClass(env, "org/lwjgl/BufferUtils"); + jmethodID createByteBuffer = (*env)->GetStaticMethodID(env, bufferutils_class, "createByteBuffer", "(I)Ljava/nio/ByteBuffer;"); + jobject buffer = (*env)->CallStaticObjectMethod(env, bufferutils_class, createByteBuffer, size); + return buffer; +} + void ext_InitializeClass(JNIEnv *env, jclass clazz, ExtGetProcAddressPROC gpa, int num_functions, JavaMethodAndExtFunction *functions) { JNINativeMethod *methods; JavaMethodAndExtFunction *function; diff --git a/src/native/common/common_tools.h b/src/native/common/common_tools.h index 75645481..0e32b388 100644 --- a/src/native/common/common_tools.h +++ b/src/native/common/common_tools.h @@ -148,6 +148,7 @@ extern void printfDebug(const char *format, ...); extern bool getBooleanProperty(JNIEnv *env, const char* propertyName); extern char * GetStringNativeChars(JNIEnv *env, jstring jstr); extern jstring NewStringNative(JNIEnv *env, const char *str); +extern jobject newJavaManagedByteBuffer(JNIEnv *env, const int size); extern void ext_InitializeClass(JNIEnv *env, jclass clazz, ExtGetProcAddressPROC gpa, int num_functions, JavaMethodAndExtFunction *functions); extern bool ext_InitializeFunctions(ExtGetProcAddressPROC gpa, int num_functions, ExtFunction *functions); diff --git a/src/native/common/extgl.h b/src/native/common/extgl.h index 4f832451..c5a809bc 100644 --- a/src/native/common/extgl.h +++ b/src/native/common/extgl.h @@ -79,7 +79,6 @@ THE POSSIBILITY OF SUCH DAMAGE. #if defined(_WIN32) && !defined(APIENTRY) #define WIN32_LEAN_AND_MEAN 1 #include - #endif #define __glext_h_ diff --git a/src/native/common/org_lwjgl_opengl_AWTSurfaceLock.c b/src/native/common/org_lwjgl_opengl_AWTSurfaceLock.c index 57d72948..a3eee297 100644 --- a/src/native/common/org_lwjgl_opengl_AWTSurfaceLock.c +++ b/src/native/common/org_lwjgl_opengl_AWTSurfaceLock.c @@ -39,7 +39,9 @@ #include #include -#ifndef _WIN32 +#ifdef _WIN32 +#include +#else #include #endif #include "org_lwjgl_opengl_AWTSurfaceLock.h" @@ -48,16 +50,17 @@ #define WAIT_DELAY 100 +JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_AWTSurfaceLock_createHandle + (JNIEnv *env, jclass clazz) { + return newJavaManagedByteBuffer(env, sizeof(AWTSurfaceLock)); +} + JNIEXPORT void JNICALL Java_org_lwjgl_opengl_AWTSurfaceLock_lockAndInitHandle (JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject canvas) { JAWT awt; JAWT_DrawingSurface* ds; JAWT_DrawingSurfaceInfo *dsi; AWTSurfaceLock *awt_lock = (AWTSurfaceLock *)(*env)->GetDirectBufferAddress(env, lock_buffer_handle); - if ((*env)->GetDirectBufferCapacity(env, lock_buffer_handle) < sizeof(AWTSurfaceLock)) { - throwException(env, "Lock handle buffer not large enough"); - return; - } awt.version = JAWT_VERSION_1_4; while (true) { if (JAWT_GetAWT(env, &awt) == JNI_FALSE) { @@ -84,7 +87,11 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_AWTSurfaceLock_lockAndInitHandle printfDebug("Could not get drawing surface info, retrying... \n"); ds->Unlock(ds); awt.FreeDrawingSurface(ds); - usleep(WAIT_DELAY); +#ifdef _WIN32 + Sleep(WAIT_DELAY); +#else + usleep(WAIT_DELAY*1000); +#endif } awt_lock->awt = awt; awt_lock->ds = ds; diff --git a/src/native/win32/Window.h b/src/native/win32/Window.h index 58f1c657..7ef978f1 100644 --- a/src/native/win32/Window.h +++ b/src/native/win32/Window.h @@ -61,12 +61,14 @@ #endif /* _PRIVATE_WINDOW_H_ */ WINDOW_H_API HWND getCurrentHWND(); + + WINDOW_H_API HDC getCurrentHDC(); - WINDOW_H_API HGLRC getCurrentContext(); +// WINDOW_H_API HGLRC getCurrentContext(); - WINDOW_H_API bool applyPixelFormat(HDC hdc, int iPixelFormat); +// WINDOW_H_API bool applyPixelFormat(HDC hdc, int iPixelFormat); - WINDOW_H_API void closeWindow(HWND *hwnd, HDC *hdc); +// WINDOW_H_API void closeWindow(HWND *hwnd, HDC *hdc); WINDOW_H_API void handleMouseMoved(int x, int y); @@ -79,21 +81,12 @@ /* * Find a suitable pixel format */ - WINDOW_H_API int findPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_format); +// WINDOW_H_API int findPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_format); /* * Find a suitable pixel format using the WGL_ARB_pixel_format extension */ - WINDOW_H_API int findPixelFormatARB(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer, bool double_buffer); - - /* - * Create a window with the specified title, position, size, and - * fullscreen attribute. The window will have DirectInput associated - * with it. - * - * Returns true for success, or false for failure - */ - WINDOW_H_API HWND createWindow(int x, int y, int width, int height, bool fullscreen, bool undecorated); +// WINDOW_H_API int findPixelFormatARB(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer, bool double_buffer); /* diff --git a/src/native/win32/context.c b/src/native/win32/context.c new file mode 100644 index 00000000..e76a4177 --- /dev/null +++ b/src/native/win32/context.c @@ -0,0 +1,417 @@ +/* + * 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$ + * + * Base Win32 display + * + * @author cix_foo + * @version $Revision$ + */ + +#include +#include "common_tools.h" +#include "extgl.h" +#include "extgl_wgl.h" +#include "context.h" + +extern HINSTANCE dll_handle; // Handle to the LWJGL dll + +#define _CONTEXT_PRIVATE_CLASS_NAME "__lwjgl_context_class_name" + +/* + * Register the LWJGL window class. + * Returns true for success, or false for failure + */ +bool registerWindow(WNDPROC win_proc, LPCTSTR class_name) +{ + WNDCLASS windowClass; + windowClass.style = CS_OWNDC; + windowClass.lpfnWndProc = win_proc; + windowClass.cbClsExtra = 0; + windowClass.cbWndExtra = 0; + windowClass.hInstance = dll_handle; + windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.hbrBackground = NULL; + windowClass.lpszMenuName = NULL; + windowClass.lpszClassName = class_name; + + if (RegisterClass(&windowClass) == 0) { + printfDebug("Failed to register window class\n"); + return false; + } + return true; +} + +static LRESULT CALLBACK dummyWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +bool applyPixelFormat(HDC hdc, int iPixelFormat) { + PIXELFORMATDESCRIPTOR desc; + if (DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &desc) == 0) { + return false; + } + + // make that the pixel format of the device context + if (SetPixelFormat(hdc, iPixelFormat, &desc) == FALSE) { + return false; + } + return true; +} + +/* + * Close the window + */ +void closeWindow(HWND *hwnd, HDC *hdc) +{ + // Release device context + if (*hdc != NULL && *hwnd != NULL) { + ReleaseDC(*hwnd, *hdc); + *hdc = NULL; + } + + // Close the window + if (*hwnd != NULL) { + ShowWindow(*hwnd, SW_HIDE); + DestroyWindow(*hwnd); + *hwnd = NULL; + } +} + +/* + * Create a window with the specified title, position, size, and + * fullscreen attribute. The window will have DirectInput associated + * with it. + * + * Returns true for success, or false for failure + */ +HWND createWindow(LPCTSTR window_class_name, int x, int y, int width, int height, bool fullscreen, bool undecorated) +{ + RECT clientSize; + int exstyle, windowflags; + HWND new_hwnd; + if (fullscreen) { + exstyle = WS_EX_APPWINDOW | WS_EX_TOPMOST; + windowflags = WS_POPUP; + } else if (undecorated) { + exstyle = WS_EX_APPWINDOW; + windowflags = WS_POPUP; + } else { + exstyle = WS_EX_APPWINDOW; + windowflags = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_MINIMIZEBOX | WS_SYSMENU; + } + + // If we're not a fullscreen window, adjust the height to account for the + // height of the title bar (unless undecorated) + clientSize.bottom = height; + clientSize.left = 0; + clientSize.right = width; + clientSize.top = 0; + + AdjustWindowRectEx( + &clientSize, // client-rectangle structure + windowflags, // window styles + FALSE, // menu-present option + exstyle // extended window style + ); + // Create the window now, using that class: + new_hwnd = CreateWindowEx ( + exstyle, + window_class_name, + "", + windowflags, + x, y, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, + NULL, + NULL, + dll_handle, + NULL); + + return new_hwnd; +} + +static int findPixelFormatARBFromBPP(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, int bpp, bool window, bool pbuffer, 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")); + jboolean stereo = (*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stereo", "Z")); + int iPixelFormat; + unsigned int num_formats_returned; + attrib_list_t attrib_list; + GLuint *pixelFormatCaps_ptr; + jlong pixelFormatCapsSize; + BOOL result; + jlong i; + + initAttribList(&attrib_list); + if (window) { + putAttrib(&attrib_list, WGL_DRAW_TO_WINDOW_ARB); putAttrib(&attrib_list, TRUE); + } + if (pbuffer) { + putAttrib(&attrib_list, WGL_DRAW_TO_PBUFFER_ARB); putAttrib(&attrib_list, TRUE); + } + if (!getBooleanProperty(env, "org.lwjgl.opengl.Display.allowSoftwareOpenGL")) + putAttrib(&attrib_list, WGL_ACCELERATION_ARB); putAttrib(&attrib_list, WGL_FULL_ACCELERATION_ARB); + putAttrib(&attrib_list, WGL_PIXEL_TYPE_ARB); putAttrib(&attrib_list, WGL_TYPE_RGBA_ARB); + putAttrib(&attrib_list, WGL_DOUBLE_BUFFER_ARB); putAttrib(&attrib_list, double_buffer ? TRUE : FALSE); + putAttrib(&attrib_list, WGL_SUPPORT_OPENGL_ARB); putAttrib(&attrib_list, TRUE); + putAttrib(&attrib_list, WGL_COLOR_BITS_ARB); putAttrib(&attrib_list, bpp); + putAttrib(&attrib_list, WGL_ALPHA_BITS_ARB); putAttrib(&attrib_list, alpha); + putAttrib(&attrib_list, WGL_DEPTH_BITS_ARB); putAttrib(&attrib_list, depth); + putAttrib(&attrib_list, WGL_STENCIL_BITS_ARB); putAttrib(&attrib_list, stencil); + if (samples > 0 && extension_flags.WGL_ARB_multisample) { + putAttrib(&attrib_list, WGL_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1); + putAttrib(&attrib_list, WGL_SAMPLES_ARB); putAttrib(&attrib_list, samples); + } + putAttrib(&attrib_list, WGL_ACCUM_BITS_ARB); putAttrib(&attrib_list, accum_bpp); + putAttrib(&attrib_list, WGL_ACCUM_ALPHA_BITS_ARB); putAttrib(&attrib_list, accum_alpha); + putAttrib(&attrib_list, WGL_STEREO_ARB); putAttrib(&attrib_list, stereo ? TRUE : FALSE); + putAttrib(&attrib_list, WGL_AUX_BUFFERS_ARB); putAttrib(&attrib_list, num_aux_buffers); + if ( pixelFormatCaps != NULL ) { + if ( !extension_flags.WGL_ARB_render_texture ) { + return -1; + } + + pixelFormatCaps_ptr = (GLuint *)(*env)->GetDirectBufferAddress(env, pixelFormatCaps); + pixelFormatCapsSize = (*env)->GetDirectBufferCapacity(env, pixelFormatCaps); + + for (i = 0; i < pixelFormatCapsSize; i++) + putAttrib(&attrib_list, pixelFormatCaps_ptr[i]); + } + putAttrib(&attrib_list, 0); putAttrib(&attrib_list, 0); + result = wglChoosePixelFormatARB(hdc, attrib_list.attribs, NULL, 1, &iPixelFormat, &num_formats_returned); + + if (result == FALSE || num_formats_returned < 1) { + return -1; + } + return iPixelFormat; +} + +static int findPixelFormatARB(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer, bool double_buffer) { + int bpp; + int iPixelFormat; + jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); + if (use_hdc_bpp) { + bpp = GetDeviceCaps(hdc, BITSPIXEL); + iPixelFormat = findPixelFormatARBFromBPP(env, hdc, pixel_format, pixelFormatCaps, bpp, window, pbuffer, double_buffer); + if (iPixelFormat == -1) + bpp = 16; + else + return iPixelFormat; + } else + bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "bpp", "I")); + return findPixelFormatARBFromBPP(env, hdc, pixel_format, pixelFormatCaps, bpp, window, pbuffer, double_buffer); +} + +/* + * Find an appropriate pixel format + */ +static int findPixelFormatFromBPP(JNIEnv *env, HDC hdc, jobject pixel_format, int bpp, 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")); + jboolean stereo = (*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stereo", "Z")); + unsigned int flags = PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | + (double_buffer ? PFD_DOUBLEBUFFER : 0) | + (stereo ? PFD_STEREO : 0); + PIXELFORMATDESCRIPTOR desc; + int iPixelFormat; + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + flags, // RGBA type + PFD_TYPE_RGBA, + (BYTE)bpp, + 0, 0, 0, 0, 0, 0, // color bits ignored + (BYTE)alpha, + 0, // shift bit ignored + accum_bpp + accum_alpha, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + (BYTE)depth, + (BYTE)stencil, + num_aux_buffers, + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + // get the best available match of pixel format for the device context + iPixelFormat = ChoosePixelFormat(hdc, &pfd); + if (iPixelFormat == 0) { + printfDebugJava(env, "Failed to choose pixel format"); + return -1; + } + + if (DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &desc) == 0) { + printfDebugJava(env, "Could not describe pixel format"); + return -1; + } + + if (desc.cColorBits < bpp) { + printfDebugJava(env, "Insufficient color precision"); + return -1; + } + + if (desc.cAlphaBits < alpha) { + printfDebugJava(env, "Insufficient alpha precision"); + return -1; + } + + if (desc.cStencilBits < stencil) { + printfDebugJava(env, "Insufficient stencil precision"); + return -1; + } + + if (desc.cDepthBits < depth) { + printfDebugJava(env, "Insufficient depth buffer precision"); + return -1; + } + + if ((desc.dwFlags & PFD_GENERIC_FORMAT) != 0 || (desc.dwFlags & PFD_GENERIC_ACCELERATED) != 0) { + jboolean allowSoftwareOpenGL = getBooleanProperty(env, "org.lwjgl.opengl.Display.allowSoftwareOpenGL"); + // secondary check for software override + if(!allowSoftwareOpenGL) { + printfDebugJava(env, "Pixel format not accelerated"); + return -1; + } + } + + if ((desc.dwFlags & flags) != flags) { + printfDebugJava(env, "Capabilities not supported"); + return -1; + } + return iPixelFormat; +} + +static int findPixelFormatDefault(JNIEnv *env, HDC hdc, jobject pixel_format, bool use_hdc_bpp, bool double_buffer) { + int bpp; + int iPixelFormat; + jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); + if (use_hdc_bpp) { + bpp = GetDeviceCaps(hdc, BITSPIXEL); + iPixelFormat = findPixelFormatFromBPP(env, hdc, pixel_format, bpp, double_buffer); + if (iPixelFormat == -1) + bpp = 16; + else + return iPixelFormat; + } else + bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "bpp", "I")); + return findPixelFormatFromBPP(env, hdc, pixel_format, bpp, double_buffer); +} + +int findPixelFormatOnDC(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer, bool double_buffer) { + HGLRC dummy_hglrc; + HDC saved_current_hdc; + HGLRC saved_current_hglrc; + int pixel_format_id; + jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); + int samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I")); + bool use_arb_selection = samples > 0 || pbuffer || pixelFormatCaps != NULL; + pixel_format_id = findPixelFormatDefault(env, hdc, pixel_format, use_hdc_bpp, double_buffer); + if (use_arb_selection) { + if (!applyPixelFormat(hdc, pixel_format_id)) { + throwException(env, "Could not apply pixel format to window"); + return -1; + } + dummy_hglrc = wglCreateContext(hdc); + if (dummy_hglrc == NULL) { + throwException(env, "Failed to create OpenGL rendering context"); + return -1; + } + // Save the current HDC and HGLRC to avoid disruption + saved_current_hdc = wglGetCurrentDC(); + saved_current_hglrc = wglGetCurrentContext(); + if (!wglMakeCurrent(hdc, dummy_hglrc)) { + wglDeleteContext(dummy_hglrc); + throwException(env, "Could not bind context to dummy window"); + return -1; + } + extgl_InitWGL(env); + + if (!extension_flags.WGL_ARB_pixel_format) { + throwException(env, "No support for WGL_ARB_pixel_format"); + return -1; + } + pixel_format_id = findPixelFormatARB(env, hdc, pixel_format, pixelFormatCaps, use_hdc_bpp, window, pbuffer, double_buffer); + wglMakeCurrent(saved_current_hdc, saved_current_hglrc); + wglDeleteContext(dummy_hglrc); + } + if (pixel_format_id == -1) { + throwException(env, "Could not find a valid pixel format"); + } + return pixel_format_id; +} + +static bool registerDummyWindow() { + static bool window_registered = false; + if (!window_registered) { + if (!registerWindow(dummyWindowProc, _CONTEXT_PRIVATE_CLASS_NAME)) { + return false; + } + window_registered = true; + } + return true; +} + +HWND createDummyWindow(int origin_x, int origin_y) { + if (!registerDummyWindow()) + return NULL; + return createWindow(_CONTEXT_PRIVATE_CLASS_NAME, origin_x, origin_y, 1, 1, false, false); +} + +int findPixelFormat(JNIEnv *env, int origin_x, int origin_y, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer, bool double_buffer) { + HWND dummy_hwnd; + HDC dummy_hdc; + int pixel_format_id; + dummy_hwnd = createDummyWindow(origin_x, origin_y); + if (dummy_hwnd == NULL) { + throwException(env, "Failed to create the dummy window."); + return -1; + } + dummy_hdc = GetDC(dummy_hwnd); + pixel_format_id = findPixelFormatOnDC(env, dummy_hdc, pixel_format, pixelFormatCaps, use_hdc_bpp, window, pbuffer, double_buffer); + closeWindow(&dummy_hwnd, &dummy_hdc); + return pixel_format_id; +} diff --git a/src/native/win32/context.h b/src/native/win32/context.h new file mode 100644 index 00000000..8c063403 --- /dev/null +++ b/src/native/win32/context.h @@ -0,0 +1,88 @@ +/* + * 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$ + * + * Base Win32 display + * + * @author cix_foo + * @version $Revision$ + */ + +#ifndef __LWJGL_CONTEXT_H +#define __LWJGL_CONTEXT_H + +#include +#include "common_tools.h" +#include "extgl.h" +#include "extgl_wgl.h" + +typedef struct { + union { + HWND format_hwnd; + HPBUFFERARB pbuffer; + }; + HDC format_hdc; + HDC drawable_hdc; +} Win32PeerInfo; + +/* + * Register the LWJGL window class. + * Returns true for success, or false for failure + */ +extern bool registerWindow(); + +extern bool applyPixelFormat(HDC hdc, int iPixelFormat); + +/* + * Close the window + */ +extern void closeWindow(HWND *hwnd, HDC *hdc); + +/** + * Create a dummy window suitable to create contexts from + */ +extern HWND createDummyWindow(int x, int y); + +/* + * Create a window with the specified position, size, and + * fullscreen attribute. The window will have DirectInput associated + * with it. + * + * Returns true for success, or false for failure + */ +extern HWND createWindow(LPCTSTR window_class_name, int x, int y, int width, int height, bool fullscreen, bool undecorated); + +extern int findPixelFormat(JNIEnv *env, int origin_x, int origin_y, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer, bool double_buffer); + +#endif diff --git a/src/native/win32/display.c b/src/native/win32/display.c index 0f33e814..6a96c690 100644 --- a/src/native/win32/display.c +++ b/src/native/win32/display.c @@ -40,6 +40,10 @@ */ #include +// Multimon.h enables multi monitor emulation on win95 and winnt4 +// So we only need the extended, multi-monitor aware path +#define COMPILE_MULTIMON_STUBS +#include #include #include "display.h" #include "common_tools.h" @@ -49,22 +53,18 @@ #define GAMMA_SIZE (3*256) static jobjectArray GetAvailableDisplayModesEx(JNIEnv * env); -static jobjectArray GetAvailableDisplayModes(JNIEnv * env); static char * getDriver(); static bool modeSet = false; // Whether we've done a display mode change static WORD originalGamma[GAMMA_SIZE]; // Original gamma settings static WORD currentGamma[GAMMA_SIZE]; // Current gamma settings static DEVMODE devmode; // Now we'll remember this value for the future extern HWND display_hwnd; // Handle to the window -extern RECT clientSize; + + jobjectArray getAvailableDisplayModes(JNIEnv *env) { jobjectArray result = GetAvailableDisplayModesEx(env); - if (result == NULL) { - printfDebug("Extended display mode selection failed, using fallback\n"); - result = GetAvailableDisplayModes(env); - } return result; } @@ -72,12 +72,7 @@ jobjectArray getAvailableDisplayModes(JNIEnv *env) * Choose displaymodes using extended codepath (multiple displaydevices) */ static jobjectArray GetAvailableDisplayModesEx(JNIEnv * env) { - typedef BOOL (WINAPI * EnumDisplayDevicesAPROC)(IN LPCSTR lpDevice, IN DWORD iDevNum, OUT PDISPLAY_DEVICEA lpDisplayDevice, IN DWORD dwFlags); - typedef BOOL (WINAPI * EnumDisplaySettingsExAPROC)(IN LPCSTR lpszDeviceName, IN DWORD iModeNum, OUT LPDEVMODEA lpDevMode, IN DWORD dwFlags); - EnumDisplayDevicesAPROC EnumDisplayDevicesA; - EnumDisplaySettingsExAPROC EnumDisplaySettingsExA; - HMODULE lib_handle = LoadLibrary("user32.dll"); int i = 0, j = 0, n = 0; DISPLAY_DEVICE DisplayDevice; @@ -90,17 +85,6 @@ static jobjectArray GetAvailableDisplayModesEx(JNIEnv * env) { jobjectArray ret; jmethodID displayModeConstructor; - if (lib_handle == NULL) { - printfDebug("Could not load user32.dll\n"); - return NULL; - } - EnumDisplayDevicesA = (EnumDisplayDevicesAPROC)GetProcAddress(lib_handle, "EnumDisplayDevicesA"); - if (EnumDisplayDevicesA == NULL) - return NULL; - EnumDisplaySettingsExA = (EnumDisplaySettingsExAPROC)GetProcAddress(lib_handle, "EnumDisplaySettingsExA"); - if (EnumDisplaySettingsExA == NULL) - return NULL; - ZeroMemory(&DevMode, sizeof(DEVMODE)); ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); @@ -110,14 +94,14 @@ static jobjectArray GetAvailableDisplayModesEx(JNIEnv * env) { displayModeClass = (*env)->FindClass(env, "org/lwjgl/opengl/DisplayMode"); displayModeConstructor = (*env)->GetMethodID(env, displayModeClass, "", "(IIII)V"); - while(EnumDisplayDevicesA(NULL, i++, &DisplayDevice, 0) != 0) { + while(EnumDisplayDevices(NULL, i++, &DisplayDevice, 0) != 0) { // continue if mirroring device if((DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) != 0) { continue; } j = 0; - while(EnumDisplaySettingsExA((const char *) DisplayDevice.DeviceName, j++, &DevMode, 0) != 0) { + while(EnumDisplaySettings((const char *) DisplayDevice.DeviceName, j++, &DevMode) != 0) { // Filter out indexed modes if (DevMode.dmBitsPerPel > 8 && ChangeDisplaySettings(&DevMode, CDS_FULLSCREEN | CDS_TEST) == DISP_CHANGE_SUCCESSFUL) { jobject displayMode; @@ -141,55 +125,6 @@ static jobjectArray GetAvailableDisplayModesEx(JNIEnv * env) { (*env)->SetObjectArrayElement(env, ret, i, display_mode_objects[i]); } free(display_mode_objects); - FreeLibrary(lib_handle); - return ret; -} - -/** - * Choose displaymodes using standard codepath (single displaydevice) - */ -static jobjectArray GetAvailableDisplayModes(JNIEnv * env) { - int i = 0, j = 0, n = 0; - - DEVMODE DevMode; - - jclass displayModeClass; - - jobjectArray ret; - jmethodID displayModeConstructor; - jobject *display_mode_objects = NULL; - int list_size = 0; - - ZeroMemory(&DevMode, sizeof(DEVMODE)); - - DevMode.dmSize = sizeof(DEVMODE); - - displayModeClass = (*env)->FindClass(env, "org/lwjgl/opengl/DisplayMode"); - - displayModeConstructor = (*env)->GetMethodID(env, displayModeClass, "", "(IIII)V"); - - while(EnumDisplaySettings(NULL, j++, &DevMode) != 0) { - // Filter out indexed modes - if (DevMode.dmBitsPerPel > 8 && ChangeDisplaySettings(&DevMode, CDS_FULLSCREEN | CDS_TEST) == DISP_CHANGE_SUCCESSFUL) { - jobject displayMode; - if (list_size <= n) { - list_size += 1; - display_mode_objects = (jobject *)realloc(display_mode_objects, sizeof(jobject)*list_size); - if (display_mode_objects == NULL) - return NULL; - } - displayMode = (*env)->NewObject(env, displayModeClass, displayModeConstructor, - DevMode.dmPelsWidth, DevMode.dmPelsHeight, - DevMode.dmBitsPerPel, DevMode.dmDisplayFrequency); - display_mode_objects[n++] = displayMode; - } - } - ret = (*env)->NewObjectArray(env, n, displayModeClass, NULL); - for (i = 0; i < n; i++) { - (*env)->SetObjectArrayElement(env, ret, i, display_mode_objects[i]); - } - free(display_mode_objects); - printfDebug("Found %d displaymodes\n", n); return ret; } diff --git a/src/native/win32/extgl_wgl.c b/src/native/win32/extgl_wgl.c index 89e5c53f..15576f06 100644 --- a/src/native/win32/extgl_wgl.c +++ b/src/native/win32/extgl_wgl.c @@ -35,9 +35,8 @@ THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include "extgl.h" #include "extgl_wgl.h" -#include "common_tools.h" +#include "extgl.h" WGLExtensions extension_flags; diff --git a/src/native/win32/extgl_wgl.h b/src/native/win32/extgl_wgl.h index e0a50f29..3478b701 100644 --- a/src/native/win32/extgl_wgl.h +++ b/src/native/win32/extgl_wgl.h @@ -37,6 +37,8 @@ THE POSSIBILITY OF SUCH DAMAGE. #define _EXTGL_WGL_H #include +#include "extgl.h" +#include "common_tools.h" typedef struct { bool WGL_ARB_buffer_region; diff --git a/src/native/win32/org_lwjgl_input_Cursor.c b/src/native/win32/org_lwjgl_input_Cursor.c index 8c73d612..93b25640 100644 --- a/src/native/win32/org_lwjgl_input_Cursor.c +++ b/src/native/win32/org_lwjgl_input_Cursor.c @@ -45,110 +45,111 @@ #include "common_tools.h" JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_getMaxCursorSize - (JNIEnv *env, jobject self) +(JNIEnv *env, jobject self) { return GetSystemMetrics(SM_CXCURSOR); } JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_getMinCursorSize - (JNIEnv *env, jobject self) +(JNIEnv *env, jobject self) { return GetSystemMetrics(SM_CXCURSOR); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nCreateCursor - (JNIEnv *env, jobject self, jobject handle_buffer, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset, jobject delay_buffer, jint delays_offset) +JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Win32Display_nCreateCursor +(JNIEnv *env, jobject self, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset, jobject delay_buffer, jint delays_offset) { - unsigned char col0, col1, col2, col3, col4, col5, col6, col7; - unsigned char mask; - BITMAPINFO bitmapInfo; + unsigned char col0, col1, col2, col3, col4, col5, col6, col7; + unsigned char mask; + BITMAPINFO bitmapInfo; - HBITMAP cursorMask; - HCURSOR *cursor_handle; + HBITMAP cursorMask; + HCURSOR *cursor_handle; - HCURSOR cursor = NULL; - ICONINFO iconInfo; - char *ptrCursorImage; - HBITMAP colorDIB; - int *srcPtr; - char *dstPtr; - int bitWidth; - int scanlinePad; - int imageSize; // Size in bits - unsigned char *maskPixels; - int pixelCount = 0; - int maskCount = 0; + HCURSOR cursor = NULL; + ICONINFO iconInfo; + char *ptrCursorImage; + HBITMAP colorDIB; + int *srcPtr; + char *dstPtr; + int bitWidth; + int scanlinePad; + int imageSize; // Size in bits + unsigned char *maskPixels; + int pixelCount = 0; + int maskCount = 0; HBITMAP colorBitmap; int x, y; + jobject handle_buffer = newJavaManagedByteBuffer(env, sizeof(HCURSOR)); - int *pixels; - if ((*env)->GetDirectBufferCapacity(env, handle_buffer) < sizeof(HCURSOR)) { - throwException(env, "Handle buffer not large enough"); - return; + int *pixels; + if (handle_buffer == NULL) { + throwException(env, "Could not allocate handle"); + return NULL; } - pixels = (int *)(*env)->GetDirectBufferAddress(env, image_buffer) + images_offset; + pixels = (int *)(*env)->GetDirectBufferAddress(env, image_buffer) + images_offset; - memset(&bitmapInfo, 0, sizeof(BITMAPINFO)); - bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bitmapInfo.bmiHeader.biWidth = width; - bitmapInfo.bmiHeader.biHeight = -height; - bitmapInfo.bmiHeader.biPlanes = 1; + memset(&bitmapInfo, 0, sizeof(BITMAPINFO)); + bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmapInfo.bmiHeader.biWidth = width; + bitmapInfo.bmiHeader.biHeight = -height; + bitmapInfo.bmiHeader.biPlanes = 1; - bitmapInfo.bmiHeader.biBitCount = 24; - bitmapInfo.bmiHeader.biCompression = BI_RGB; + bitmapInfo.bmiHeader.biBitCount = 24; + bitmapInfo.bmiHeader.biCompression = BI_RGB; - colorDIB = CreateDIBSection(GetDC(NULL), (BITMAPINFO*)&(bitmapInfo), - DIB_RGB_COLORS, - (void**)&(ptrCursorImage), - NULL, 0); - srcPtr = pixels; - dstPtr = ptrCursorImage; - if (!dstPtr) { + colorDIB = CreateDIBSection(GetDC(NULL), (BITMAPINFO*)&(bitmapInfo), + DIB_RGB_COLORS, + (void**)&(ptrCursorImage), + NULL, 0); + srcPtr = pixels; + dstPtr = ptrCursorImage; + if (!dstPtr) { throwException(env, "Could not allocate DIB section."); - return; - } - for (y = 0; y < height; y++ ) { - for (x = 0; x < width; x++ ) { - dstPtr[2] = (*srcPtr >> 0x10) & 0xFF; - dstPtr[1] = (*srcPtr >> 0x08) & 0xFF; - dstPtr[0] = *srcPtr & 0xFF; + return NULL; + } + for (y = 0; y < height; y++ ) { + for (x = 0; x < width; x++ ) { + dstPtr[2] = (*srcPtr >> 0x10) & 0xFF; + dstPtr[1] = (*srcPtr >> 0x08) & 0xFF; + dstPtr[0] = *srcPtr & 0xFF; - srcPtr++; - dstPtr += 3; - } - } + srcPtr++; + dstPtr += 3; + } + } - colorBitmap = CreateDIBitmap(GetDC(NULL), - (BITMAPINFOHEADER*)&bitmapInfo.bmiHeader, - CBM_INIT, - (void *)ptrCursorImage, - (BITMAPINFO*)&bitmapInfo, - DIB_RGB_COLORS); + colorBitmap = CreateDIBitmap(GetDC(NULL), + (BITMAPINFOHEADER*)&bitmapInfo.bmiHeader, + CBM_INIT, + (void *)ptrCursorImage, + (BITMAPINFO*)&bitmapInfo, + DIB_RGB_COLORS); - DeleteObject(colorDIB); + DeleteObject(colorDIB); // Convert alpha map to pixel packed mask - bitWidth = width >> 3; - scanlinePad = bitWidth & (sizeof(WORD) - 1); - imageSize = (bitWidth + scanlinePad)*height; // Size in bits - maskPixels = (unsigned char*)malloc(sizeof(unsigned char)*imageSize); + bitWidth = width >> 3; + scanlinePad = bitWidth & (sizeof(WORD) - 1); + imageSize = (bitWidth + scanlinePad)*height; // Size in bits + maskPixels = (unsigned char*)malloc(sizeof(unsigned char)*imageSize); memset(maskPixels, 0, imageSize); for (y = 0; y < height; y++) for (x = 0; x < bitWidth; x++) { - col0 = (pixels[pixelCount++] & 0x01000000) >> 17; - col1 = (pixels[pixelCount++] & 0x01000000) >> 18; - col2 = (pixels[pixelCount++] & 0x01000000) >> 19; - col3 = (pixels[pixelCount++] & 0x01000000) >> 20; - col4 = (pixels[pixelCount++] & 0x01000000) >> 21; - col5 = (pixels[pixelCount++] & 0x01000000) >> 22; - col6 = (pixels[pixelCount++] & 0x01000000) >> 23; - col7 = (pixels[pixelCount++] & 0x01000000) >> 24; - mask = col0 | col1 | col2 | col3 | col4 | col5 | col6 | col7; + col0 = (pixels[pixelCount++] & 0x01000000) >> 17; + col1 = (pixels[pixelCount++] & 0x01000000) >> 18; + col2 = (pixels[pixelCount++] & 0x01000000) >> 19; + col3 = (pixels[pixelCount++] & 0x01000000) >> 20; + col4 = (pixels[pixelCount++] & 0x01000000) >> 21; + col5 = (pixels[pixelCount++] & 0x01000000) >> 22; + col6 = (pixels[pixelCount++] & 0x01000000) >> 23; + col7 = (pixels[pixelCount++] & 0x01000000) >> 24; + mask = col0 | col1 | col2 | col3 | col4 | col5 | col6 | col7; maskPixels[maskCount++] = ~mask; // 1 is tranparant, 0 opaque } - cursorMask = CreateBitmap(width, height, 1, 1, maskPixels); + cursorMask = CreateBitmap(width, height, 1, 1, maskPixels); memset(&iconInfo, 0, sizeof(ICONINFO)); iconInfo.hbmMask = cursorMask; @@ -159,19 +160,15 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nCreateCursor cursor = CreateIconIndirect(&iconInfo); DeleteObject(colorBitmap); DeleteObject(cursorMask); - free(maskPixels); + free(maskPixels); - cursor_handle = (HCURSOR *)(*env)->GetDirectBufferAddress(env, handle_buffer); + cursor_handle = (HCURSOR *)(*env)->GetDirectBufferAddress(env, handle_buffer); *cursor_handle = cursor; + return handle_buffer; } -/* - * Class: org_lwjgl_input_Cursor - * Method: nDestroyCursor - * Signature: (I)V - */ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_destroyCursor - (JNIEnv *env, jobject self, jobject handle_buffer) +(JNIEnv *env, jobject self, jobject handle_buffer) { HCURSOR *cursor_handle = (HCURSOR *)(*env)->GetDirectBufferAddress(env, handle_buffer); DestroyCursor(*cursor_handle); diff --git a/src/native/win32/org_lwjgl_opengl_AWTGLCanvas.c b/src/native/win32/org_lwjgl_opengl_AWTGLCanvas.c deleted file mode 100644 index c9ff2009..00000000 --- a/src/native/win32/org_lwjgl_opengl_AWTGLCanvas.c +++ /dev/null @@ -1,331 +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$ - * - * @author$ - * @version$ - */ - -#include -#include -#include "../common/common_tools.h" -#include "extgl_wgl.h" -#include "org_lwjgl_opengl_AWTGLCanvas.h" - -extern bool createARBContextAndPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_format, int *pixel_format_index_return, HGLRC *context_return); -extern int findPixelFormatARB(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixelFormatCaps, bool use_hdc_bpp, bool window, bool pbuffer, bool double_buffer); -extern int findPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_format); -extern bool applyPixelFormat(HDC hdc, int iPixelFormat); - -/* - * Grab the context from the incoming AWTGLCanvas and return it - */ -HGLRC getContext(JNIEnv * env, jobject awtglcanvas) { - jclass cls_AWTGLCanvas = (*env)->GetObjectClass(env, awtglcanvas); - jlong hglrc = (int)(*env)->GetLongField(env, awtglcanvas, (*env)->GetFieldID(env, cls_AWTGLCanvas, "context", "J")); - return (HGLRC) hglrc; -} - -/* - * Grab the HWND from the incoming AWTGLCanvas's peer - */ -HWND getHWND(JNIEnv * env, jobject awtglcanvas) { - jclass cls_AWTGLCanvas = (*env)->GetObjectClass(env, awtglcanvas); - jobject componentPeer = (*env)->GetObjectField(env, awtglcanvas, (*env)->GetFieldID(env, cls_AWTGLCanvas, "peer", "Ljava/awt/peer/ComponentPeer;")); - jclass cls_CanvasPeer = (*env)->GetObjectClass(env, componentPeer); - jlong hwnd = (*env)->GetLongField(env, componentPeer, (*env)->GetFieldID(env, cls_CanvasPeer, "hwnd", "J")); - return (HWND) hwnd; -} - -/* - * Stash the incoming context int the incoming AWTGLCanvas - */ -void setContext(JNIEnv * env, jobject awtglcanvas, HGLRC hglrc) { - jclass cls_AWTGLCanvas = (*env)->GetObjectClass(env, awtglcanvas); - (*env)->SetLongField(env, awtglcanvas, (*env)->GetFieldID(env, cls_AWTGLCanvas, "context", "J"), (jlong) hglrc); -} - -/* - * Class: org_lwjgl_opengl_AWTGLCanvas - * Method: nCreateContext - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_AWTGLCanvas_nCreateContext - (JNIEnv * env, jobject awtglcanvas) -{ - HWND hwnd; - HDC hdc; - HGLRC hglrc; - BOOL result; - jclass cls_pixel_format; - int samples; - int pixel_format_index_arb; - int pixel_format_index; - HGLRC context_arb; - bool arb_success; - jclass cls_AWTGLCanvas; - jobject pixel_format; - - hwnd = getHWND(env, awtglcanvas); - hdc = GetDC(hwnd); - cls_AWTGLCanvas = (*env)->GetObjectClass(env, awtglcanvas); - pixel_format = (*env)->GetObjectField(env, awtglcanvas, (*env)->GetFieldID(env, cls_AWTGLCanvas, "pixelFormat", "Lorg/lwjgl/opengl/PixelFormat;")); - pixel_format_index = findPixelFormat(env, hdc, pixel_format); - - if (pixel_format_index == -1) { - throwException(env, "Could not find a suitable pixel format"); - ReleaseDC(hwnd, hdc); - return; - } - - if (!applyPixelFormat(hdc, pixel_format_index)) { - throwException(env, "Could not apply pixel format to component"); - ReleaseDC(hwnd, hdc); - return; - } - - hglrc = wglCreateContext(hdc); - if (hglrc == NULL) { - throwException(env, "Failed to create OpenGL rendering context"); - ReleaseDC(hwnd, hdc); - return; - } - result = wglMakeCurrent(hdc, hglrc); - if (!result) { - throwException(env, "Could not bind context to component"); - wglDeleteContext(hglrc); - ReleaseDC(hwnd, hdc); - return; - } - extgl_InitWGL(env); - cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); - samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I")); - if (samples > 0) { - // Create a new context using ARB pixel format instead - arb_success = createARBContextAndPixelFormat(env, hdc, pixel_format, &pixel_format_index_arb, &context_arb); - wglDeleteContext(hglrc); - if (!arb_success) { - throwException(env, "Samples > 0 but could not find a suitable ARB pixel format"); - return; - } - hglrc = context_arb; - pixel_format_index = pixel_format_index_arb; - } - - // 4. Stash the native handle back - setContext(env, awtglcanvas, hglrc); - - // 5. Release the GLRC - wglMakeCurrent(hdc, NULL); - - // 6. Release DC back to windoze - ReleaseDC(hwnd, hdc); - -} - -/* - * Class: org_lwjgl_opengl_AWTGLCanvas - * Method: nMakeCurrent - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_AWTGLCanvas_nMakeCurrent - (JNIEnv * env, jobject awtglcanvas) -{ - HGLRC hglrc = getContext(env, awtglcanvas); - HWND hwnd = getHWND(env, awtglcanvas); - HDC hdc = GetDC(hwnd); - BOOL result = wglMakeCurrent(hdc, hglrc); - ReleaseDC(hwnd, hdc); - if (result != TRUE) { - LPVOID lpMsgBuf; - if (!FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL )) - { - // Handle the error. - printf("Failed\n"); - } else { - throwException(env, (LPCTSTR)lpMsgBuf); - // Free the buffer. - LocalFree( lpMsgBuf ); - } - } -} - - -/* - * Class: org_lwjgl_opengl_AWTGLCanvas - * Method: nDestroyContext - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_AWTGLCanvas_nDestroyContext - (JNIEnv *env, jobject canvas) -{ - JAWT awt; - JAWT_DrawingSurface* ds; - JAWT_DrawingSurfaceInfo* dsi; - JAWT_Win32DrawingSurfaceInfo* dsi_win; - jboolean result; - HGLRC hglrc; - - // Get the AWT - awt.version = JAWT_VERSION_1_4; - result = JAWT_GetAWT(env, &awt); - if (result == JNI_FALSE) { - throwGeneralException(env, "java/lang/RuntimeException", "Failed get AWT."); - return; - } - - // Get the drawing surface - ds = awt.GetDrawingSurface(env, canvas); - if (ds == NULL) { - throwGeneralException(env, "java/lang/RuntimeException", "Failed get drawing surface."); - return; - } - - // Get the drawing surface info - dsi = ds->GetDrawingSurfaceInfo(ds); - - // Get the platform-specific drawing info - dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo; - - hglrc = getContext(env, canvas); - // make the rendering context not current - wglMakeCurrent(NULL, NULL) ; - // delete the rendering context - wglDeleteContext(hglrc); - - // Free the drawing surface info - ds->FreeDrawingSurfaceInfo(dsi); - - // Free the drawing surface - awt.FreeDrawingSurface(ds); -} - -/* - * Class: org_lwjgl_opengl_AWTGLCanvas - * Method: nPaint - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_AWTGLCanvas_nPaint - (JNIEnv *env, jobject canvas) -{ - JAWT awt; - JAWT_DrawingSurface* ds; - JAWT_DrawingSurfaceInfo* dsi; - JAWT_Win32DrawingSurfaceInfo* dsi_win; - jboolean result; - jint lock; - HGLRC hglrc; - BOOL mcResult; - LPVOID lpMsgBuf; - jclass cls_AWTGLCanvas; - jmethodID mid_doPaint; - - // Get the AWT - awt.version = JAWT_VERSION_1_4; - result = JAWT_GetAWT(env, &awt); - if (result == JNI_FALSE) { - throwGeneralException(env, "java/lang/RuntimeException", "Failed get AWT."); - return; - } - - // Get the drawing surface - ds = awt.GetDrawingSurface(env, canvas); - if (ds == NULL) { - throwGeneralException(env, "java/lang/RuntimeException", "Failed get drawing surface."); - return; - } - - // Lock the drawing surface - lock = ds->Lock(ds); - if ((lock & JAWT_LOCK_ERROR) != 0) { - throwGeneralException(env, "java/lang/RuntimeException", "Failed to lock drawing surface."); - return; - } - - // Get the drawing surface info - dsi = ds->GetDrawingSurfaceInfo(ds); - - // Get the platform-specific drawing info - dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo; - - hglrc = getContext(env, canvas); - mcResult = wglMakeCurrent(dsi_win->hdc, hglrc); - if (mcResult != TRUE) { - if (!FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL )) - { - // Handle the error. - printf("Failed\n"); - } else { - printfDebug("%s\n", lpMsgBuf); - throwGeneralException(env, "java/lang/RuntimeException", lpMsgBuf); - // Free the buffer. - LocalFree( lpMsgBuf ); - // Don't return yet, let's free up stuff - } - } else { - // Callback paint - cls_AWTGLCanvas = (*env)->GetObjectClass(env, canvas); - mid_doPaint = (*env)->GetMethodID(env, cls_AWTGLCanvas, "cPaint", "()V"); - (*env)->CallVoidMethod(env, canvas, mid_doPaint); - SwapBuffers(dsi_win->hdc); - } - - // Free the drawing surface info - ds->FreeDrawingSurfaceInfo(dsi); - - // Unlock the drawing surface - ds->Unlock(ds); - - // Free the drawing surface - awt.FreeDrawingSurface(ds); -} - diff --git a/src/native/win32/org_lwjgl_opengl_Display.c b/src/native/win32/org_lwjgl_opengl_Display.c index 7e45b48e..99279db7 100644 --- a/src/native/win32/org_lwjgl_opengl_Display.c +++ b/src/native/win32/org_lwjgl_opengl_Display.c @@ -40,34 +40,32 @@ */ #define _PRIVATE_WINDOW_H_ -#include "Window.h" #include +#include +#include "Window.h" #include "extgl_wgl.h" #include "common_tools.h" -#include "extgl_wgl.h" #include "display.h" #include "org_lwjgl_opengl_Win32Display.h" -#include - -static bool oneShotInitialised = false; // Registers the LWJGL window class +#include "context.h" static HWND display_hwnd = NULL; // Handle to the window static HDC display_hdc = NULL; // Device context -static HGLRC display_hglrc = NULL; // OpenGL context +//static HGLRC display_hglrc = NULL; // OpenGL context static bool isFullScreen = false; // Whether we're fullscreen or not static bool isMinimized = false; // Whether we're minimized or not static bool isFocused = false; // whether we're focused or not static bool isDirty = false; // Whether we're dirty or not static bool isUndecorated = false; // Whether we're undecorated or not -extern HINSTANCE dll_handle; // Handle to the LWJGL dll -RECT clientSize; // client size rect used when creating and positioning window +static bool did_maximize = false; // A flag to tell when a window + // has recovered from minimized static bool closerequested; -static int pixel_format_index; +//static int pixel_format_index; #define WINDOWCLASSNAME "LWJGL" -bool applyPixelFormat(HDC hdc, int iPixelFormat) { +/*bool applyPixelFormat(HDC hdc, int iPixelFormat) { PIXELFORMATDESCRIPTOR desc; if (DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &desc) == 0) { return false; @@ -79,12 +77,17 @@ bool applyPixelFormat(HDC hdc, int iPixelFormat) { } return true; } +*/ + +HDC getCurrentHDC() { + return display_hdc; +} HWND getCurrentHWND() { return display_hwnd; } -HGLRC getCurrentContext() { +/*HGLRC getCurrentContext() { return display_hglrc; } @@ -164,10 +167,11 @@ int findPixelFormatARB(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixel bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "bpp", "I")); return findPixelFormatARBFromBPP(env, hdc, pixel_format, pixelFormatCaps, bpp, window, pbuffer, double_buffer); } - +*/ /* * Find an appropriate pixel format */ +/* static int findPixelFormatFromBPP(JNIEnv *env, HDC hdc, jobject pixel_format, int bpp) { jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); @@ -261,28 +265,7 @@ int findPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_format) { } else return iPixelFormat; } - -/* - * Close the window - */ -void closeWindow(HWND *hwnd, HDC *hdc) -{ - // Release device context - if (*hdc != NULL && *hwnd != NULL) { - printfDebug("Releasing DC\n"); - ReleaseDC(*hwnd, *hdc); - *hdc = NULL; - } - - // Close the window - if (*hwnd != NULL) { - ShowWindow(*hwnd, SW_HIDE); - printfDebug("Destroy window\n"); - DestroyWindow(*hwnd); - *hwnd = NULL; - } -} - +*/ /* * Called when the application is alt-tabbed to or from */ @@ -301,12 +284,7 @@ static void appActivate(bool active) ShowWindow(display_hwnd, SW_RESTORE); SetForegroundWindow(display_hwnd); SetFocus(display_hwnd); - /* - * Calling wglMakeCurrent() (redundantly) seems to help some gfx cards - * restore from minimized to fullscreen. - */ - if (wglGetCurrentContext() == display_hglrc) - wglMakeCurrent(display_hdc, display_hglrc); + did_maximize = true; } else if (isFullScreen) { ShowWindow(display_hwnd, SW_SHOWMINNOACTIVE); resetDisplayMode(NULL); @@ -314,6 +292,12 @@ static void appActivate(bool active) inAppActivate = false; } +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Win32Display_didMaximize + (JNIEnv *env, jobject self) { + jboolean result = did_maximize ? JNI_TRUE : JNI_FALSE; + did_maximize = false; + return result; +} /* * WindowProc for the GL window. */ @@ -427,7 +411,7 @@ LRESULT CALLBACK lwjglWindowProc(HWND hWnd, * Register the LWJGL window class. * Returns true for success, or false for failure */ -static bool registerWindow() +/*static bool registerWindow() { WNDCLASS windowClass; if (!oneShotInitialised) { @@ -452,7 +436,7 @@ static bool registerWindow() return true; } - +*/ /* * Handle native Win32 messages */ @@ -476,61 +460,6 @@ void handleMessages(void) }; } -/* - * Create a window with the specified title, position, size, and - * fullscreen attribute. The window will have DirectInput associated - * with it. - * - * Returns true for success, or false for failure - */ -HWND createWindow(int x, int y, int width, int height, bool fullscreen, bool undecorated) -{ - int exstyle, windowflags; - HWND new_hwnd; - // 1. Register window class if necessary - if (!registerWindow()) { - return NULL; - } - - if (fullscreen) { - exstyle = WS_EX_APPWINDOW | WS_EX_TOPMOST; - windowflags = WS_POPUP; - } else if (undecorated) { - exstyle = WS_EX_APPWINDOW; - windowflags = WS_POPUP; - } else { - exstyle = WS_EX_APPWINDOW; - windowflags = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_MINIMIZEBOX | WS_SYSMENU; - } - - // If we're not a fullscreen window, adjust the height to account for the - // height of the title bar (unless undecorated) - clientSize.bottom = height; - clientSize.left = 0; - clientSize.right = width; - clientSize.top = 0; - - AdjustWindowRectEx( - &clientSize, // client-rectangle structure - windowflags, // window styles - FALSE, // menu-present option - exstyle // extended window style - ); - // Create the window now, using that class: - new_hwnd = CreateWindowEx ( - exstyle, - WINDOWCLASSNAME, - "", - windowflags, - x, y, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, - NULL, - NULL, - dll_handle, - NULL); - - return new_hwnd; -} - /* * Class: org_lwjgl_Window * Method: nSetTitle @@ -549,7 +478,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setTitle * Method: update * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_update +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nUpdate (JNIEnv * env, jobject self) { handleMessages(); @@ -561,13 +490,13 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_update * Method: swapBuffers * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_swapBuffers +/*JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_swapBuffers (JNIEnv * env, jobject self) { isDirty = false; SwapBuffers(display_hdc); } - +*/ /* * Class: org_lwjgl_opengl_Window * Method: nIsDirty @@ -617,7 +546,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Win32Display_isActive * Method: nSetVSyncEnabled * Signature: (Z)Z */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setVSyncEnabled +/*JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setVSyncEnabled (JNIEnv * env, jobject self, jboolean sync) { if (extension_flags.WGL_EXT_swap_control) { @@ -636,37 +565,45 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_makeCurrent if (!result) throwException(env, "Could not make display context current"); } - +*/ JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_Win32Display_getAvailableDisplayModes(JNIEnv *env, jobject self) { return getAvailableDisplayModes(env); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_createWindow(JNIEnv *env, jobject self, jobject mode, jboolean fullscreen, jint x, jint y) { - 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 result; +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nCreateWindow(JNIEnv *env, jobject self, jobject mode, jboolean fullscreen, jint x, jint y) { + 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 result; + static bool oneShotInitialised = false; + if (!oneShotInitialised) { + if (!registerWindow(lwjglWindowProc, WINDOWCLASSNAME)) { + throwException(env, "Could not register window class"); + return; + } + oneShotInitialised = true; + } + closerequested = false; isMinimized = false; isFocused = false; isDirty = true; isFullScreen = fullscreen == JNI_TRUE; isUndecorated = getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated"); - - display_hwnd = createWindow(x, y, width, height, isFullScreen, isUndecorated); + display_hwnd = createWindow(WINDOWCLASSNAME, x, y, width, height, isFullScreen, isUndecorated); if (display_hwnd == NULL) { throwException(env, "Failed to create the window."); return; } display_hdc = GetDC(display_hwnd); - if (!applyPixelFormat(display_hdc, pixel_format_index)) { +/* if (!applyPixelFormat(display_hdc, pixel_format_index)) { closeWindow(&display_hwnd, &display_hdc); throwException(env, "Could not apply pixel format to window"); return; } - +*/ ShowWindow(display_hwnd, SW_SHOWDEFAULT); UpdateWindow(display_hwnd); SetForegroundWindow(display_hwnd); @@ -705,7 +642,7 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Win32Display_init(JNIEnv *env, j return initDisplay(env); } -bool createARBContextAndPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_format, int *pixel_format_index_return, HGLRC *context_return) { +/*bool createARBContextAndPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_format, int *pixel_format_index_return, HGLRC *context_return) { int pixel_format_index; HWND arb_hwnd; HDC arb_hdc; @@ -752,8 +689,8 @@ bool createARBContextAndPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_format, return true; } - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_createContext(JNIEnv *env, jobject self, jobject pixel_format) { +*/ +/*JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_createContext(JNIEnv *env, jobject self, jobject pixel_format) { HWND dummy_hwnd; HDC dummy_hdc; BOOL result; @@ -817,9 +754,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_destroyContext(JNIEnv display_hglrc = NULL; } } - +*/ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_reshape(JNIEnv *env, jobject self, jint x, jint y, jint width, jint height) { int exstyle, windowflags; + RECT clientSize; if (isFullScreen) { return; diff --git a/src/native/win32/org_lwjgl_opengl_Pbuffer.c b/src/native/win32/org_lwjgl_opengl_Pbuffer.c index e41bcc77..29c02b20 100644 --- a/src/native/win32/org_lwjgl_opengl_Pbuffer.c +++ b/src/native/win32/org_lwjgl_opengl_Pbuffer.c @@ -42,7 +42,7 @@ #include #include "org_lwjgl_opengl_Win32Display.h" #include "org_lwjgl_opengl_Pbuffer.h" -#include "Window.h" +#include "context.h" #include "extgl.h" #include "extgl_wgl.h" @@ -78,7 +78,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_getPbufferCapabilities return caps; } -static HPBUFFERARB createPbuffer(JNIEnv *env, int width, int height, jobject pixel_format, jobject pixelFormatCaps, const int *pBufferAttribs_ptr) { +/*static HPBUFFERARB createPbuffer(JNIEnv *env, int width, int height, jobject pixel_format, jobject pixelFormatCaps, const int *pBufferAttribs_ptr) { HWND dummy_hwnd = createWindow(0, 0, 1, 1, false, false); HDC dummy_hdc; int iPixelFormat; @@ -149,15 +149,72 @@ static HGLRC createPbufferContext(JNIEnv *env, HDC Pbuffer_dc, HGLRC shared_cont } return Pbuffer_context; } - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nCreatePbuffer - (JNIEnv *env, jobject self, jobject buffer_handle, +*/ +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32PbufferPeerInfo_nCreate + (JNIEnv *env, jobject self, jobject peer_info_handle, jint width, jint height, jobject pixel_format, - jobject pixelFormatCaps, jobject pBufferAttribs, jobject shared_context_handle_buffer) + jobject pixelFormatCaps, jobject pBufferAttribs) { + int origin_x = 0; int origin_y = 0; + HWND dummy_hwnd; + HDC dummy_hdc; HPBUFFERARB Pbuffer; + HDC Pbuffer_dc; const int *pBufferAttribs_ptr; - HDC Pbuffer_dc; + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + int pixel_format_id; + + if ( pBufferAttribs != NULL ) { + pBufferAttribs_ptr = (const int *)(*env)->GetDirectBufferAddress(env, pBufferAttribs); + } else { + pBufferAttribs_ptr = NULL; + } + pixel_format_id = findPixelFormat(env, origin_x, origin_y, pixel_format, pixelFormatCaps, false, false, true, false); + + dummy_hwnd = createDummyWindow(origin_x, origin_y); + if (dummy_hwnd == NULL) { + throwException(env, "Could not create dummy window"); + return; + } + dummy_hdc = GetDC(dummy_hwnd); + if (!applyPixelFormat(dummy_hdc, pixel_format_id)) { + closeWindow(&dummy_hwnd, &dummy_hdc); + throwException(env, "Could not apply pixel format"); + return; + } + Pbuffer = wglCreatePbufferARB(dummy_hdc, pixel_format_id, width, height, pBufferAttribs_ptr); + closeWindow(&dummy_hwnd, &dummy_hdc); + if (Pbuffer == NULL) { + throwException(env, "Could not create Pbuffer"); + return; + } + Pbuffer_dc = wglGetPbufferDCARB(Pbuffer); + if (Pbuffer_dc == NULL) { + wglDestroyPbufferARB(Pbuffer); + throwException(env, "Could not get Pbuffer DC"); + return; + } + peer_info->format_hdc = Pbuffer_dc; + peer_info->pbuffer = Pbuffer; + peer_info->drawable_hdc = Pbuffer_dc; + +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32PbufferPeerInfo_nDestroy + (JNIEnv *env, jclass clazz, jobject peer_info_handle) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + wglReleasePbufferDCARB(peer_info->pbuffer, peer_info->drawable_hdc); + wglDestroyPbufferARB(peer_info->pbuffer); +} + +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Win32PbufferPeerInfo_nIsBufferLost + (JNIEnv *env, jclass clazz, jobject peer_info_handle) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + BOOL buffer_lost; + wglQueryPbufferARB(peer_info->pbuffer, WGL_PBUFFER_LOST_ARB, &buffer_lost); + return buffer_lost ? JNI_TRUE : JNI_FALSE; +} +/* HDC Pbuffer_dc; HGLRC Pbuffer_context; HGLRC shared_context; PbufferInfo *Pbuffer_info; @@ -165,11 +222,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nCreatePbuffer throwException(env, "Buffer handle not large enough"); return; } - if ( pBufferAttribs != NULL ) { - pBufferAttribs_ptr = (const int *)(*env)->GetDirectBufferAddress(env, pBufferAttribs); - } else { - pBufferAttribs_ptr = NULL; - } Pbuffer = createPbuffer(env, width, height, pixel_format, pixelFormatCaps, pBufferAttribs_ptr); if (Pbuffer == NULL) { @@ -203,7 +255,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nCreatePbuffer JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Win32Display_isBufferLost (JNIEnv *env, jobject self, jobject buffer_handle) { - PbufferInfo *Pbuffer_info = (PbufferInfo *)(*env)->GetDirectBufferAddress(env, buffer_handle); + PbufferInfo *Pbuffer_info = (PbufferInfo *)(*env)->GetDirectBufferAddress(env, buffer_handle); BOOL buffer_lost; wglQueryPbufferARB(Pbuffer_info->Pbuffer, WGL_PBUFFER_LOST_ARB, &buffer_lost); return buffer_lost ? JNI_TRUE : JNI_FALSE; @@ -226,7 +278,32 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_destroyPbuffer wglReleasePbufferDCARB(Pbuffer_info->Pbuffer, Pbuffer_info->Pbuffer_dc); wglDestroyPbufferARB(Pbuffer_info->Pbuffer); } +*/ +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32PbufferPeerInfo_nSetPbufferAttrib + (JNIEnv *env, jclass clazz, jobject peer_info_handle, jint attrib, jint value) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + int attribs[3]; + + attribs[0] = attrib; + attribs[1] = value; + attribs[2] = 0; + + wglSetPbufferAttribARB(peer_info->pbuffer, attribs); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32PbufferPeerInfo_nBindTexImageToPbuffer + (JNIEnv *env, jclass clazz, jobject peer_info_handle, jint buffer) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + wglBindTexImageARB(peer_info->pbuffer, buffer); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32PbufferPeerInfo_nReleaseTexImageFromPbuffer + (JNIEnv *env, jclass clazz, jobject peer_info_handle, jint buffer) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + wglReleaseTexImageARB(peer_info->pbuffer, buffer); +} +/* JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setPbufferAttrib (JNIEnv *env, jobject self, jobject buffer_handle, jint attrib, jint value) { @@ -253,4 +330,4 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_releaseTexImageFromPbu { PbufferInfo *Pbuffer_info = (PbufferInfo *)(*env)->GetDirectBufferAddress(env, buffer_handle); wglReleaseTexImageARB(Pbuffer_info->Pbuffer, buffer); -} +}*/ diff --git a/src/native/win32/org_lwjgl_opengl_Win32AWTGLCanvasPeerInfo.c b/src/native/win32/org_lwjgl_opengl_Win32AWTGLCanvasPeerInfo.c new file mode 100644 index 00000000..1ff19b75 --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_Win32AWTGLCanvasPeerInfo.c @@ -0,0 +1,57 @@ +/* + * 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$ + * + * @author elias_naur + * @version $Revision$ + */ + +#include +#include +#include +#include "awt_tools.h" +#include "org_lwjgl_opengl_Win32AWTGLCanvasPeerInfo.h" +#include "context.h" +#include "common_tools.h" + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32AWTGLCanvasPeerInfo_nInitHandle + (JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject peer_info_handle) { + const AWTSurfaceLock *awt_lock = (AWTSurfaceLock *)(*env)->GetDirectBufferAddress(env, lock_buffer_handle); + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + AWTSurfaceLock *surface = (AWTSurfaceLock *)(*env)->GetDirectBufferAddress(env, lock_buffer_handle); + JAWT_Win32DrawingSurfaceInfo *win32_dsi = (JAWT_Win32DrawingSurfaceInfo *)surface->dsi->platformInfo; + peer_info->format_hwnd = win32_dsi->hwnd; + peer_info->format_hdc = win32_dsi->hdc; + peer_info->drawable_hdc = win32_dsi->hdc; +} diff --git a/src/native/win32/org_lwjgl_opengl_Win32ContextImplementation.c b/src/native/win32/org_lwjgl_opengl_Win32ContextImplementation.c new file mode 100644 index 00000000..6e1c55ba --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_Win32ContextImplementation.c @@ -0,0 +1,122 @@ +/* + * 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$ + * + * @author elias_naur + * @version $Revision$ + */ + +#include +#include "org_lwjgl_opengl_Win32ContextImplementation.h" +#include "context.h" +#include "common_tools.h" + +typedef struct { + HGLRC context; +} Win32Context; + +JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Win32ContextImplementation_nCreate + (JNIEnv *env, jclass clazz, jobject peer_info_handle, jobject shared_context_handle) { + Win32PeerInfo *peer_info; + Win32Context *shared_context_info; + Win32Context *context_info; + HGLRC context; + HGLRC shared_context = NULL; + jobject context_handle = newJavaManagedByteBuffer(env, sizeof(Win32Context)); + + if (context_handle == NULL) { + throwException(env, "Could not create handle buffer"); + return NULL; + } + peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + context = wglCreateContext(peer_info->format_hdc); + if (context == NULL) { + throwException(env, "Could not create context"); + return NULL; + } + if (shared_context_handle != NULL) { + shared_context_info = (Win32Context *)(*env)->GetDirectBufferAddress(env, shared_context_handle); + shared_context = shared_context_info->context; + if (!wglShareLists(shared_context, context)) { + wglDeleteContext(context); + throwException(env, "Could not share contexts"); + return NULL; + } + } + context_info = (Win32Context *)(*env)->GetDirectBufferAddress(env, context_handle); + context_info->context = context; + return context_handle; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32ContextImplementation_nSwapBuffers + (JNIEnv *env, jclass clazz, jobject peer_info_handle) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + SwapBuffers(peer_info->drawable_hdc); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32ContextImplementation_nReleaseCurrentContext + (JNIEnv *env, jclass clazz) { + wglMakeCurrent(NULL, NULL); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32ContextImplementation_nMakeCurrent + (JNIEnv *env, jclass clazz, jobject peer_info_handle, jobject context_handle) { + Win32Context *context_info = (Win32Context *)(*env)->GetDirectBufferAddress(env, context_handle); + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + if (!wglMakeCurrent(peer_info->drawable_hdc, context_info->context)) + throwException(env, "Could not make context current"); +} + +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Win32ContextImplementation_nIsCurrent + (JNIEnv *env, jclass clazz, jobject context_handle) { + Win32Context *context_info = (Win32Context *)(*env)->GetDirectBufferAddress(env, context_handle); + return wglGetCurrentContext() == context_info->context; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32ContextImplementation_nSetVSync + (JNIEnv *env, jclass clazz, jboolean enable) { + if (extension_flags.WGL_EXT_swap_control) { + if (enable == JNI_TRUE) { + wglSwapIntervalEXT(1); + } else { + wglSwapIntervalEXT(0); + } + } +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32ContextImplementation_nDestroy + (JNIEnv *env, jclass clazz, jobject context_handle) { + Win32Context *context_info = (Win32Context *)(*env)->GetDirectBufferAddress(env, context_handle); + wglDeleteContext(context_info->context); +} diff --git a/src/native/win32/org_lwjgl_opengl_Win32DisplayPeerInfo.c b/src/native/win32/org_lwjgl_opengl_Win32DisplayPeerInfo.c new file mode 100644 index 00000000..a4888d45 --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_Win32DisplayPeerInfo.c @@ -0,0 +1,78 @@ +/* + * 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$ + * + * @author elias_naur + * @version $Revision$ + */ + +#include +#include "Window.h" +#include "org_lwjgl_opengl_Win32DisplayPeerInfo.h" +#include "context.h" +#include "common_tools.h" + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32DisplayPeerInfo_createDummyDC + (JNIEnv *env, jclass clazz, jobject peer_info_handle) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + HWND dummy_hwnd = createDummyWindow(0, 0); + HDC dummy_hdc; + if (dummy_hwnd == NULL) { + throwException(env, "Failed to create a dummy window."); + return; + } + dummy_hdc = GetDC(dummy_hwnd); + peer_info->format_hwnd = dummy_hwnd; + peer_info->format_hdc = dummy_hdc; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32DisplayPeerInfo_nDestroy + (JNIEnv *env, jclass clazz, jobject peer_info_handle) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + closeWindow(&peer_info->format_hwnd, &peer_info->format_hdc); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32DisplayPeerInfo_nInitDC + (JNIEnv *env, jclass clazz, jobject peer_info_handle) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + int pixel_format; + peer_info->drawable_hdc = getCurrentHDC(); + pixel_format = GetPixelFormat(peer_info->format_hdc); + if (pixel_format == 0) { + throwException(env, "Could not get pixel format from dummy hdc"); + return; + } + if (!applyPixelFormat(peer_info->drawable_hdc, pixel_format)) + throwException(env, "Could not apply pixel format to drawable"); +} diff --git a/src/native/win32/org_lwjgl_opengl_Win32PeerInfo.c b/src/native/win32/org_lwjgl_opengl_Win32PeerInfo.c new file mode 100644 index 00000000..40fd1714 --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_Win32PeerInfo.c @@ -0,0 +1,60 @@ +/* + * 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$ + * + * @author elias_naur + * @version $Revision$ + */ + +#include +#include "org_lwjgl_opengl_Win32PeerInfo.h" +#include "context.h" +#include "common_tools.h" + +JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Win32PeerInfo_createHandle + (JNIEnv *env, jclass clazz) { + return newJavaManagedByteBuffer(env, sizeof(Win32PeerInfo)); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32PeerInfo_nChoosePixelFormat + (JNIEnv *env, jclass clazz, jobject peer_info_handle, jint origin_x, jint origin_y, jobject pixel_format, jobject pixel_format_caps, jboolean use_hdc_bpp, jboolean window, jboolean pbuffer, jboolean double_buffer) { + Win32PeerInfo *peer_info = (Win32PeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); + int pixel_format_id = findPixelFormat(env, origin_x, origin_y, pixel_format, pixel_format_caps, use_hdc_bpp, window, pbuffer, double_buffer); + if (pixel_format_id == -1) + return; + if (!applyPixelFormat(peer_info->format_hdc, pixel_format_id)) { + throwException(env, "Could not apply pixel format"); + return; + } +}