From 087d0f4ba9c38b71b16aa91629a361bea300a062 Mon Sep 17 00:00:00 2001 From: Brian Matzon Date: Thu, 21 Jul 2011 22:52:16 +0000 Subject: [PATCH] Initial stab at win32 resize api --- src/java/org/lwjgl/opengl/WindowsDisplay.java | 99 +++++++++++++++++-- src/java/org/lwjgl/test/input/MouseTest.java | 4 + src/native/windows/org_lwjgl_opengl_Display.c | 36 +++++++ 3 files changed, 130 insertions(+), 9 deletions(-) diff --git a/src/java/org/lwjgl/opengl/WindowsDisplay.java b/src/java/org/lwjgl/opengl/WindowsDisplay.java index 043b76b9..cfd5cb8e 100644 --- a/src/java/org/lwjgl/opengl/WindowsDisplay.java +++ b/src/java/org/lwjgl/opengl/WindowsDisplay.java @@ -41,6 +41,7 @@ package org.lwjgl.opengl; import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; +import java.nio.LongBuffer; import java.awt.Canvas; import org.lwjgl.LWJGLException; @@ -66,7 +67,10 @@ final class WindowsDisplay implements DisplayImplementation { private static final int WM_MBUTTONDBLCLK = 0x0209; private static final int WM_MOUSEWHEEL = 0x020A; private static final int WM_CAPTURECHANGED = 0x0215; - private static final int WM_MOUSELEAVE = 0x02A3; + private static final int WM_MOUSELEAVE = 0x02A3; + private static final int WM_ENTERSIZEMOVE = 0x0231; + private static final int WM_EXITSIZEMOVE = 0x0232; + private static final int WM_SIZING = 0x0214; private static final int WM_KEYDOWN = 256; private static final int WM_KEYUP = 257; private static final int WM_SYSKEYUP = 261; @@ -115,6 +119,7 @@ final class WindowsDisplay implements DisplayImplementation { private static final int WA_INACTIVE = 0; private static final int WA_ACTIVE = 1; private static final int WA_CLICKACTIVE = 2; + private static final int SW_NORMAL = 1; private static final int SW_SHOWMINNOACTIVE = 7; private static final int SW_SHOWDEFAULT = 10; private static final int SW_RESTORE = 9; @@ -124,6 +129,23 @@ final class WindowsDisplay implements DisplayImplementation { private static final IntBuffer rect_buffer = BufferUtils.createIntBuffer(4); private static final Rect rect = new Rect(); + + private static final long HWND_TOP = 0; + private static final long HWND_BOTTOM = 1; + private static final long HWND_TOPMOST = -1; + private static final long HWND_NOTOPMOST = -2; + + private static final int SWP_NOSIZE = 0x0001; + private static final int SWP_NOMOVE = 0x0002; + private static final int SWP_NOZORDER = 0x0004; + private static final int SWP_FRAMECHANGED = 0x0020; + + private static final int GWL_STYLE = -16; + private static final int GWL_EXSTYLE = -20; + + private static final int WS_THICKFRAME = 0x00040000; + + private static WindowsDisplay current_display; private static boolean cursor_clipped; @@ -147,6 +169,10 @@ final class WindowsDisplay implements DisplayImplementation { private boolean isFocused; private boolean did_maximize; private boolean inAppActivate; + private boolean resized; + private boolean resizable; + private int width; + private int height; private long hwnd; private long hdc; @@ -191,7 +217,13 @@ final class WindowsDisplay implements DisplayImplementation { } peer_info.initDC(getHwnd(), getHdc()); showWindow(getHwnd(), SW_SHOWDEFAULT); + + updateWidthAndHeight(); + if ( parent == null ) { + if(Display.isResizable()) { + setResizable(true); + } setForegroundWindow(getHwnd()); setFocus(getHwnd()); } @@ -201,6 +233,14 @@ final class WindowsDisplay implements DisplayImplementation { throw e; } } + + private void updateWidthAndHeight() { + getClientRect(hwnd, rect_buffer); + rect.copyFromBuffer(rect_buffer); + width = rect.right - rect.left; + height = rect.bottom - rect.top; + } + private static native long nCreateWindow(int x, int y, int width, int height, boolean undecorated, boolean child_window, long parent_hwnd) throws LWJGLException; private static boolean isUndecorated() { @@ -695,6 +735,9 @@ final class WindowsDisplay implements DisplayImplementation { private static native long createIcon(int width, int height, IntBuffer icon); private static native void destroyIcon(long handle); private static native long sendMessage(long hwnd, long msg, long wparam, long lparam); + private static native long setWindowLongPtr(long hwnd, int nindex, long longPtr); + private static native long getWindowLongPtr(long hwnd, int nindex); + private static native boolean setWindowPos(long hwnd, long hwnd_after, int x, int y, int cx, int cy, long uflags); private void handleMouseButton(int button, int state, long millis) { if (mouse != null) { @@ -820,6 +863,14 @@ final class WindowsDisplay implements DisplayImplementation { break; } return defWindowProc(hwnd, msg, wParam, lParam); + case WM_ENTERSIZEMOVE: + return defWindowProc(hwnd, msg, wParam, lParam); + case WM_EXITSIZEMOVE: + return defWindowProc(hwnd, msg, wParam, lParam); + case WM_SIZING: + resized = true; + updateWidthAndHeight(); + return defWindowProc(hwnd, msg, wParam, lParam); case WM_KILLFOCUS: appActivate(false); return 0; @@ -900,10 +951,10 @@ final class WindowsDisplay implements DisplayImplementation { case WM_PAINT: is_dirty = true; return defWindowProc(hwnd, msg, wParam, lParam); - case WM_MOUSELEAVE: - mouseInside = false; - trackingMouse = false; - return defWindowProc(hwnd, msg, wParam, lParam); + case WM_MOUSELEAVE: + mouseInside = false; + trackingMouse = false; + return defWindowProc(hwnd, msg, wParam, lParam); case WM_CANCELMODE: nReleaseCapture(); /* fall through */ @@ -919,11 +970,11 @@ final class WindowsDisplay implements DisplayImplementation { } public int getWidth() { - return Display.getDisplayMode().getWidth(); + return width; } public int getHeight() { - return Display.getDisplayMode().getHeight(); + return height; } private int firstMouseButtonDown() { @@ -942,10 +993,40 @@ final class WindowsDisplay implements DisplayImplementation { } public void setResizable(boolean resizable) { - + if(this.resizable != resizable) { + long style = getWindowLongPtr(hwnd, GWL_STYLE); + long styleex = getWindowLongPtr(hwnd, GWL_EXSTYLE); + + // update frame style + if(resizable) { + setWindowLongPtr(hwnd, GWL_STYLE, style |= WS_THICKFRAME); + } else { + setWindowLongPtr(hwnd, GWL_STYLE, style &= ~WS_THICKFRAME); + } + + // from the existing client rect, determine the new window rect + // based on the style changes - using AdjustWindowRectEx. + getClientRect(hwnd, rect_buffer); + rect.copyFromBuffer(rect_buffer); + adjustWindowRectEx(rect_buffer, style, false, styleex); + rect.copyFromBuffer(rect_buffer); + + // force a frame update and resize accordingly + setWindowPos(hwnd, HWND_TOP, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); + + updateWidthAndHeight(); + resized = false; + } + this.resizable = resizable; } + private native boolean adjustWindowRectEx(IntBuffer rectBuffer, long style, boolean menu, long styleex); + public boolean wasResized() { + if(resized) { + resized = false; + return true; + } return false; } @@ -981,7 +1062,7 @@ final class WindowsDisplay implements DisplayImplementation { } public String toString() { - return "Rect: top = " + top + " bottom = " + bottom + " left = " + left + " right = " + right; + return "Rect: top = " + top + " bottom = " + bottom + " left = " + left + " right = " + right + ", width: " + (right - left) + ", height: " + (bottom - top); } } } diff --git a/src/java/org/lwjgl/test/input/MouseTest.java b/src/java/org/lwjgl/test/input/MouseTest.java index 55b982df..7a42ebc4 100644 --- a/src/java/org/lwjgl/test/input/MouseTest.java +++ b/src/java/org/lwjgl/test/input/MouseTest.java @@ -354,6 +354,10 @@ public class MouseTest { if(Keyboard.getEventKey() == Keyboard.KEY_SPACE && Keyboard.getEventKeyState()) { Mouse.setGrabbed(!Mouse.isGrabbed()); } + + if(Keyboard.getEventKey() == Keyboard.KEY_R && Keyboard.getEventKeyState()) { + Display.setResizable(!Display.isResizable()); + } } } diff --git a/src/native/windows/org_lwjgl_opengl_Display.c b/src/native/windows/org_lwjgl_opengl_Display.c index 9352774b..fdb47c3d 100644 --- a/src/native/windows/org_lwjgl_opengl_Display.c +++ b/src/native/windows/org_lwjgl_opengl_Display.c @@ -427,6 +427,32 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_sendMessage return SendMessage(hwnd, (UINT)msg, (WPARAM)wparam, (LPARAM)lparam); } +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_setWindowLongPtr + (JNIEnv *env, jclass clazz, jlong hwnd_ptr, jint nindex, jlong longPtr) { + + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; + return SetWindowLongPtr(hwnd, nindex, (LONG_PTR) longPtr); +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_getWindowLongPtr + (JNIEnv *env, jclass clazz, jlong hwnd_ptr, jint nindex) { + + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; + jlong result = GetWindowLongPtr(hwnd, nindex); + return result; +} + +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_WindowsDisplay_setWindowPos + (JNIEnv *env, jclass clazz, jlong hwnd_ptr, jlong hwnd_after_ptr, jint x, jint y, jint width, jint height, jlong uflags) { + + jboolean result; + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; + HWND hwnd_after = (HWND)(INT_PTR)hwnd_after_ptr; + + result = SetWindowPos(hwnd, hwnd_after, x, y, width, height, (UINT) uflags); + return result; +} + JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nSetCursorPosition (JNIEnv * env, jclass unused, jint x, jint y) { if (!SetCursorPos(x, y)) @@ -441,6 +467,16 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_getClientRect copyRectToBuffer(env, &clientRect, rect_buffer); } +JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_WindowsDisplay_adjustWindowRectEx + (JNIEnv *env, jclass unused, jobject rect_buffer, jlong style, jboolean menu, jlong styleex) { + jboolean result; + RECT clientRect; + copyBufferToRect(env, rect_buffer, &clientRect); + result = AdjustWindowRectEx(&clientRect, style, menu, styleex); + copyRectToBuffer(env, &clientRect, rect_buffer); + return result; +} + JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nSetNativeCursor (JNIEnv *env, jclass unused, jlong hwnd_int, jobject handle_buffer) {