diff --git a/src/java/org/lwjgl/opengl/Display.java b/src/java/org/lwjgl/opengl/Display.java index 0981562d..8b60f694 100644 --- a/src/java/org/lwjgl/opengl/Display.java +++ b/src/java/org/lwjgl/opengl/Display.java @@ -75,14 +75,14 @@ public final class Display { /** Timer for sync() */ private static long timeNow, timeThen; -// /** X coordinate of the window */ -// private static int x; + /** X coordinate of the window */ + private static int x; /** * Y coordinate of the window. Y in window coordinates is from the top of the display down, * unlike GL, where it is typically at the bottom of the display. */ -// private static int y; + private static int y; /** Title of the window (never null) */ private static String title = "Game"; @@ -177,13 +177,15 @@ public final class Display { * A native context must exist, and it will be attached to the window. */ private static void createWindow() throws LWJGLException { - nCreateWindow(current_mode, fullscreen); + x = Math.max(0, Math.min(initial_mode.getWidth() - current_mode.getWidth(), x)); + y = Math.max(0, Math.min(initial_mode.getHeight() - current_mode.getHeight(), y)); + nCreateWindow(current_mode, fullscreen, (fullscreen) ? 0 : x, (fullscreen) ? 0 : y); nSetTitle(title); initControls(); nSetVSyncEnabled(vsync); } - private static native void nCreateWindow(DisplayMode mode, boolean fullscreen) throws LWJGLException; + private static native void nCreateWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException; private static void destroyWindow() { // Automatically destroy keyboard, mouse, and controller @@ -329,21 +331,17 @@ public final class Display { /** * @return the X coordinate of the window (always 0 for fullscreen) */ -/* public static int getX() { - if (!isCreated()) - throw new IllegalStateException("Cannot get X on uncreated window"); - return x; - } -*/ + /*public static int getX() { + return (fullscreen) ? 0 : x; + }*/ + /** * @return the Y coordinate of the window (always 0 for fullscreen) */ -/* public static int getY() { - if (!isCreated()) - throw new IllegalStateException("Cannot get Y on uncreated window"); - return y; - } -*/ + /*public static int getY() { + return (fullscreen) ? 0 : y; + }*/ + /** * @return the title of the window @@ -370,10 +368,11 @@ public final class Display { return; destroyWindow(); try { - if (fullscreen) + if (fullscreen) { switchDisplayMode(); - else + } else { resetDisplayMode(); + } createWindow(); } catch (LWJGLException e) { destroyContext(); @@ -697,30 +696,28 @@ public final class Display { private static native void nSetVSyncEnabled(boolean sync); -// /** -// * Set the window's location. This is a no-op on fullscreen windows. -// * The window is clamped to remain entirely on the screen. If you attempt -// * to position the window such that it would extend off the screen, the window -// * is simply placed as close to the edge as possible. -// * @param x, y The new window location -// */ -// public static void setLocation(int x, int y) { -// if (!isCreated()) -// throw new IllegalStateException("Cannot move uncreated window"); -// if (fullscreen) { -// return; -// } -// Display.x = Math.max(0, Math.min(Display.getWidth() - Display.width, x)); -// Display.y = Math.max(0, Math.min(Display.getHeight() - Display.height, y)); -// nReshape(Display.x, Display.y, Display.width, Display.height); -// } -// -// -// /** -// * Native method to reshape the window -// * @param x, y The new window location -// * @param width, height The new window dimensions -// */ -// private static native void nReshape(int x, int y, int width, int height); + /** + * Set the window's location. This is a no-op on fullscreen windows. + * The window is clamped to remain entirely on the screen. If you attempt + * to position the window such that it would extend off the screen, the window + * is simply placed as close to the edge as possible. + * @param x, y The new window location + */ + public static void setLocation(int x, int y) { + if (fullscreen) { + return; + } + + // offset if already created + if(isCreated()) { + x = Math.max(0, Math.min(initial_mode.getWidth() - current_mode.getWidth(), x)); + y = Math.max(0, Math.min(initial_mode.getHeight() - current_mode.getHeight(), y)); + nReshape(x, y, current_mode.getWidth(), current_mode.getHeight()); + } + // cache position + Display.x = x; + Display.y = y; + } + private static native void nReshape(int x, int y, int width, int height); } diff --git a/src/java/org/lwjgl/test/WindowCreationTest.java b/src/java/org/lwjgl/test/WindowCreationTest.java index 6bf8f8cc..9af934d3 100644 --- a/src/java/org/lwjgl/test/WindowCreationTest.java +++ b/src/java/org/lwjgl/test/WindowCreationTest.java @@ -31,8 +31,10 @@ */ package org.lwjgl.test; +import org.lwjgl.LWJGLException; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; +import org.lwjgl.opengl.GL11; import org.lwjgl.input.Keyboard; /** @@ -52,6 +54,12 @@ public class WindowCreationTest { // get avaialble modes, and print out DisplayMode[] modes = Display.getAvailableDisplayModes(); System.out.println("Found " + modes.length + " display modes"); + + int x = 100, y = 100; + boolean fullscreen = false; + + System.out.println("Moving to 100, 100"); + Display.setLocation(x, y); // Create the actual window try { @@ -65,9 +73,10 @@ public class WindowCreationTest { System.out.println("Window created"); System.out.println(Display.getDisplayMode().getHeight() + ", " + Display.getDisplayMode().getWidth() + ", " + Display.getTitle()); - + // wait for user to close window - while(!Display.isCloseRequested()) { + while(!Display.isCloseRequested()) { + GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); Display.update(); try { Thread.sleep(100); @@ -78,6 +87,31 @@ public class WindowCreationTest { if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { break; } + + if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)) { + Display.setLocation(x -= 10, y); + } + + if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) { + Display.setLocation(x += 10, y); + } + + if(Keyboard.isKeyDown(Keyboard.KEY_UP)) { + Display.setLocation(x, y -= 10); + } + + if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)) { + Display.setLocation(x, y += 10); + } + + if(Keyboard.isKeyDown(Keyboard.KEY_F)) { + try { + Display.setFullscreen(fullscreen = !fullscreen); + } catch (LWJGLException lwjgle) { + lwjgle.printStackTrace(); + } + } + } // nuke window and get out diff --git a/src/native/win32/Window.h b/src/native/win32/Window.h index f3eb2be6..ca0c934c 100644 --- a/src/native/win32/Window.h +++ b/src/native/win32/Window.h @@ -83,7 +83,7 @@ * * Returns true for success, or false for failure */ - WINDOW_H_API HWND createWindow(int width, int height, bool fullscreen, bool undecorated); + WINDOW_H_API HWND createWindow(int x, int y, int width, int height, bool fullscreen, bool undecorated); /* diff --git a/src/native/win32/display.cpp b/src/native/win32/display.cpp index e0dabd46..da2c13b5 100644 --- a/src/native/win32/display.cpp +++ b/src/native/win32/display.cpp @@ -53,6 +53,8 @@ bool modeSet = false; // Whether we've done a display mode change WORD* originalGamma = new WORD[256 * 3]; // Original gamma settings WORD* currentGamma = new WORD[256 * 3]; // Current gamma settings DEVMODE devmode; // Now we'll remember this value for the future +extern HWND display_hwnd = NULL; // Handle to the window +extern RECT clientSize; char * driver = getDriver(); jobjectArray getAvailableDisplayModes(JNIEnv *env) @@ -213,7 +215,7 @@ void switchDisplayMode(JNIEnv * env, jobject mode) devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS; if (freq != 0) devmode.dmFields |= DM_DISPLAYFREQUENCY; - LONG cdsret = ChangeDisplaySettings(&devmode, CDS_FULLSCREEN); + LONG cdsret = ChangeDisplaySettings(&devmode, CDS_FULLSCREEN); if (cdsret != DISP_CHANGE_SUCCESSFUL) { // Failed: so let's check to see if it's a wierd dual screen display @@ -227,7 +229,6 @@ void switchDisplayMode(JNIEnv * env, jobject mode) return; } } - modeSet = true; } diff --git a/src/native/win32/org_lwjgl_opengl_Display.cpp b/src/native/win32/org_lwjgl_opengl_Display.cpp index 2aed631e..87418700 100644 --- a/src/native/win32/org_lwjgl_opengl_Display.cpp +++ b/src/native/win32/org_lwjgl_opengl_Display.cpp @@ -47,17 +47,18 @@ #include "display.h" #include "org_lwjgl_opengl_Display.h" -static bool oneShotInitialised = false; // Registers the LWJGL window class +static bool oneShotInitialised = false; // Registers the LWJGL window class -static HWND display_hwnd = NULL; // Handle to the window -static HDC display_hdc = NULL; // Device 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 HWND display_hwnd = NULL; // Handle to the window +static HDC display_hdc = NULL; // Device 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 +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 closerequested; static int pixel_format_index; @@ -346,6 +347,17 @@ LRESULT CALLBACK lwjglWindowProc(HWND hWnd, { isDirty = true; } + /*case WM_MOVE: { + // get fields of display + jclass cls_display = env->FindClass("org/lwjgl/opengl/Display"); + jfieldID fid_x = env->GetStaticFieldID(cls_display, "x", "I"); + jfieldID fid_y = env->GetStaticFieldID(cls_display, "y", "I"); + + // set fields + env->SetStaticIntField(cls_display, fid_x, (int)(short) LOWORD(lParam)); + env->SetStaticIntField(cls_display, fid_y, (int)(short) HIWORD(lParam)); + + }*/ } // default action @@ -414,7 +426,7 @@ static void handleMessages(JNIEnv * env, jclass clazz) * * Returns true for success, or false for failure */ -HWND createWindow(int width, int height, bool fullscreen, bool undecorated) +HWND createWindow(int x, int y, int width, int height, bool fullscreen, bool undecorated) { int exstyle, windowflags; @@ -436,7 +448,6 @@ HWND createWindow(int width, int height, bool fullscreen, bool undecorated) // If we're not a fullscreen window, adjust the height to account for the // height of the title bar (unless undecorated) - RECT clientSize; clientSize.bottom = height; clientSize.left = 0; clientSize.right = width; @@ -455,7 +466,7 @@ HWND createWindow(int width, int height, bool fullscreen, bool undecorated) WINDOWCLASSNAME, "", windowflags, - 0, 0, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, + x, y, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, NULL, NULL, dll_handle, @@ -574,7 +585,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_Display_nGetAvailableDispla return getAvailableDisplayModes(env); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nCreateWindow(JNIEnv *env, jclass clazz, jobject mode, jboolean fullscreen) { +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nCreateWindow(JNIEnv *env, jclass clazz, jobject mode, jboolean fullscreen, jint x, jint y) { closerequested = false; isMinimized = false; isFocused = true; @@ -587,7 +598,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nCreateWindow(JNIEnv *env, int width = env->GetIntField(mode, fid_width); int height = env->GetIntField(mode, fid_height); - display_hwnd = createWindow(width, height, isFullScreen, isUndecorated); + display_hwnd = createWindow(x, y, width, height, isFullScreen, isUndecorated); if (display_hwnd == NULL) { throwException(env, "Failed to create the window."); return; @@ -656,7 +667,7 @@ static bool createARBContextAndPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_f if (pixel_format_index == -1) return false; } - HWND arb_hwnd = createWindow(1, 1, false, false); + HWND arb_hwnd = createWindow(0, 0, 1, 1, false, false); if (arb_hwnd == NULL) return false; HDC arb_hdc = GetDC(arb_hwnd); @@ -672,7 +683,7 @@ static bool createARBContextAndPixelFormat(JNIEnv *env, HDC hdc, jobject pixel_f } JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_createContext(JNIEnv *env, jclass clazz, jobject pixel_format) { - HWND dummy_hwnd = createWindow(1, 1, false, false); + HWND dummy_hwnd = createWindow(0, 0, 1, 1, false, false); if (dummy_hwnd == NULL) { throwException(env, "Failed to create the window."); return; @@ -729,3 +740,38 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_destroyContext(JNIEnv *env, display_hglrc = NULL; } } + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Display_nReshape(JNIEnv *env, jclass clazz, jint x, jint y, jint width, jint height) { + if (isFullScreen) { + return; + } + + int exstyle, windowflags; + + if (isFullScreen) { + exstyle = WS_EX_APPWINDOW | WS_EX_TOPMOST; + windowflags = WS_POPUP; + } else if (getBooleanProperty(env, "org.lwjgl.opengl.Window.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: + 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 + ); + + SetWindowPos(display_hwnd, HWND_TOP, x, y, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, SWP_NOZORDER); +} diff --git a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp index a117c7ca..f1b533b2 100755 --- a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp @@ -79,7 +79,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Pbuffer_getPbufferCaps } static HPBUFFERARB createPbuffer(JNIEnv *env, int width, int height, jobject pixel_format, jobject pixelFormatCaps, const int *pBufferAttribs_ptr) { - HWND dummy_hwnd = createWindow(1, 1, false, false); + HWND dummy_hwnd = createWindow(0, 0, 1, 1, false, false); if (dummy_hwnd == NULL) { throwException(env, "Could not create dummy window"); return NULL;