From bcb909f5a94db86cab843494c269826efaecf791 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Wed, 30 Apr 2008 16:40:14 +0000 Subject: [PATCH] Windows: Moved hwnd and hdc to java --- .../org/lwjgl/WindowsSysImplementation.java | 48 +++++++++- src/java/org/lwjgl/opengl/WindowsDisplay.java | 48 +++++++--- src/native/windows/Window.h | 3 - src/native/windows/org_lwjgl_Sys.c | 11 ++- src/native/windows/org_lwjgl_opengl_Display.c | 93 ++++++++----------- 5 files changed, 122 insertions(+), 81 deletions(-) diff --git a/src/java/org/lwjgl/WindowsSysImplementation.java b/src/java/org/lwjgl/WindowsSysImplementation.java index 64ab673c..03d90087 100644 --- a/src/java/org/lwjgl/WindowsSysImplementation.java +++ b/src/java/org/lwjgl/WindowsSysImplementation.java @@ -31,6 +31,12 @@ */ package org.lwjgl; +import java.security.PrivilegedExceptionAction; +import java.security.PrivilegedActionException; +import java.security.AccessController; +import java.lang.reflect.Method; + +import org.lwjgl.opengl.Display; /** *

@@ -39,7 +45,7 @@ package org.lwjgl; * $Id$ */ final class WindowsSysImplementation extends DefaultSysImplementation { - private final static int JNI_VERSION = 16; + private final static int JNI_VERSION = 17; static { Sys.initialize(); @@ -53,9 +59,40 @@ final class WindowsSysImplementation extends DefaultSysImplementation { return 1000; } - public native long getTime(); + public long getTime() { + return nGetTime(); + } + private static native long nGetTime(); - public native void alert(String title, String message); + private static long getHwnd() { + /* Use reflection since we can't make Display.getImplementation + * public + */ + try { + Long hwnd_obj = (Long)AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + Method getImplementation_method = Display.class.getDeclaredMethod("getImplementation", null); + getImplementation_method.setAccessible(true); + Object display_impl = getImplementation_method.invoke(null, null); + if (display_impl == null) + return null; + Class WindowsDisplay_class = Class.forName("org.lwjgl.opengl.WindowsDisplay"); + Method getHwnd_method = WindowsDisplay_class.getDeclaredMethod("getHwnd", null); + getHwnd_method.setAccessible(true); + Long hwnd = (Long)getHwnd_method.invoke(display_impl, null); + return hwnd; + } + }); + return hwnd_obj.longValue(); + } catch (PrivilegedActionException e) { + throw new Error(e); + } + } + + public void alert(String title, String message) { + nAlert(getHwnd(), title, message); + } + private static native void nAlert(long parent_hwnd, String title, String message); public boolean openURL(final String url) { try { @@ -67,5 +104,8 @@ final class WindowsSysImplementation extends DefaultSysImplementation { } } - public native String getClipboard(); + public String getClipboard() { + return nGetClipboard(); + } + private static native String nGetClipboard(); } diff --git a/src/java/org/lwjgl/opengl/WindowsDisplay.java b/src/java/org/lwjgl/opengl/WindowsDisplay.java index 94cc1ae8..e58a27d0 100644 --- a/src/java/org/lwjgl/opengl/WindowsDisplay.java +++ b/src/java/org/lwjgl/opengl/WindowsDisplay.java @@ -140,6 +140,9 @@ final class WindowsDisplay implements DisplayImplementation { private boolean did_maximize; private boolean inAppActivate; + private long hwnd; + private long hdc; + public WindowsDisplay() { current_display = this; } @@ -154,7 +157,15 @@ final class WindowsDisplay implements DisplayImplementation { this.parent = parent; long parent_hwnd = parent != null ? getHwnd(parent) : 0; boolean isUndecorated = isUndecorated(); - nCreateWindow(mode, fullscreen, x, y, isUndecorated, parent != null, parent_hwnd); + this.hwnd = nCreateWindow(mode, fullscreen, x, y, isUndecorated, parent != null, parent_hwnd); + if (hwnd == 0) { + throw new LWJGLException("Failed to create window"); + } + this.hdc = getDC(hwnd); + if (hdc == 0) { + nDestroyWindow(hwnd, hdc); + throw new LWJGLException("Failed to get dc"); + } peer_info.initDC(getHwnd(), getHdc()); showWindow(getHwnd(), SW_SHOWDEFAULT); if (parent == null) { @@ -162,7 +173,7 @@ final class WindowsDisplay implements DisplayImplementation { setFocus(getHwnd()); } } - private native void nCreateWindow(DisplayMode mode, boolean fullscreen, int x, int y, boolean undecorated, boolean child_window, long parent_hwnd) throws LWJGLException; + private native long nCreateWindow(DisplayMode mode, boolean fullscreen, int x, int y, boolean undecorated, boolean child_window, long parent_hwnd) throws LWJGLException; private static boolean isUndecorated() { return Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated"); @@ -180,10 +191,10 @@ final class WindowsDisplay implements DisplayImplementation { } public void destroyWindow() { - nDestroyWindow(); + nDestroyWindow(hwnd, hdc); resetCursorClipping(); } - private static native void nDestroyWindow(); + private static native void nDestroyWindow(long hwnd, long hdc); static void resetCursorClipping() { if (cursor_clipped) { try { @@ -338,7 +349,10 @@ final class WindowsDisplay implements DisplayImplementation { } private static native DisplayMode getCurrentDisplayMode() throws LWJGLException; - public native void setTitle(String title); + public void setTitle(String title) { + nSetTitle(hwnd, title); + } + private static native void nSetTitle(long hwnd, String title); public boolean isCloseRequested() { boolean saved = close_requested; @@ -467,11 +481,19 @@ final class WindowsDisplay implements DisplayImplementation { static native int getSystemMetrics(int index); private static native long getDllInstance(); - private static native long getHwnd(); - private static native long getHdc(); + + private long getHwnd() { + return hwnd; + } + + private long getHdc() { + return hdc; + } + + private static native long getDC(long hwnd); private static native long getDesktopWindow(); static void centerCursor(long hwnd) { - getGlobalClientRect(getHwnd(), rect); + getGlobalClientRect(hwnd, rect); int local_offset_x = rect.left; int local_offset_y = rect.top; getGlobalClientRect(getDesktopWindow(), rect2); @@ -482,7 +504,7 @@ final class WindowsDisplay implements DisplayImplementation { int local_x = center_x - local_offset_x; int local_y = center_y - local_offset_y; if (current_display != null) - current_display.setMousePosition(local_x, transformY(getHwnd(), local_y)); + current_display.setMousePosition(local_x, transformY(hwnd, local_y)); } private void setMousePosition(int x, int y) { @@ -582,12 +604,12 @@ final class WindowsDisplay implements DisplayImplementation { int size = icons[i].limit() / 4; if ((((int) Math.sqrt(size)) == small_icon_size) && (!done_small)) { - nSetWindowIconSmall(small_icon_size, small_icon_size, icons[i].asIntBuffer()); + nSetWindowIconSmall(hwnd, small_icon_size, small_icon_size, icons[i].asIntBuffer()); used++; done_small = true; } if ((((int) Math.sqrt(size)) == large_icon_size) && (!done_large)) { - nSetWindowIconLarge(large_icon_size, large_icon_size, icons[i].asIntBuffer()); + nSetWindowIconLarge(hwnd, large_icon_size, large_icon_size, icons[i].asIntBuffer()); used++; done_large = true; } @@ -596,9 +618,9 @@ final class WindowsDisplay implements DisplayImplementation { return used; } - private static native int nSetWindowIconSmall(int width, int height, IntBuffer icon); + private static native int nSetWindowIconSmall(long hwnd, int width, int height, IntBuffer icon); - private static native int nSetWindowIconLarge(int width, int height, IntBuffer icon); + private static native int nSetWindowIconLarge(long hwnd, int width, int height, IntBuffer icon); private void handleMouseButton(int button, int state, long millis) { if (mouse != null) diff --git a/src/native/windows/Window.h b/src/native/windows/Window.h index f7401189..28fd0ad5 100644 --- a/src/native/windows/Window.h +++ b/src/native/windows/Window.h @@ -62,7 +62,4 @@ #define WINDOW_H_API extern #endif /* _PRIVATE_WINDOW_H_ */ - WINDOW_H_API HDC getCurrentHDC(); - - WINDOW_H_API HWND getCurrentHWND(); #endif /* _LWJGL_WINDOW_H_INCLUDED_ */ diff --git a/src/native/windows/org_lwjgl_Sys.c b/src/native/windows/org_lwjgl_Sys.c index 68964a32..78cc85d3 100644 --- a/src/native/windows/org_lwjgl_Sys.c +++ b/src/native/windows/org_lwjgl_Sys.c @@ -45,7 +45,7 @@ #include "common_tools.h" #include -JNIEXPORT jlong JNICALL Java_org_lwjgl_WindowsSysImplementation_getTime(JNIEnv * env, jobject ignored) { +JNIEXPORT jlong JNICALL Java_org_lwjgl_WindowsSysImplementation_nGetTime(JNIEnv * env, jclass unused) { DWORD time; timeBeginPeriod(1); @@ -55,10 +55,11 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_WindowsSysImplementation_getTime(JNIEnv * return time; } -JNIEXPORT void JNICALL Java_org_lwjgl_WindowsSysImplementation_alert(JNIEnv * env, jobject ignored, jstring title, jstring message) { +JNIEXPORT void JNICALL Java_org_lwjgl_WindowsSysImplementation_nAlert(JNIEnv * env, jclass unused, jlong hwnd_ptr, jstring title, jstring message) { + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; char * eMessageText = GetStringNativeChars(env, message); char * cTitleBarText = GetStringNativeChars(env, title); - MessageBox(getCurrentHWND(), eMessageText, cTitleBarText, MB_OK | MB_TOPMOST); + MessageBox(hwnd, eMessageText, cTitleBarText, MB_OK | MB_TOPMOST); printfDebugJava(env, "*** Alert ***%s\n%s\n", cTitleBarText, eMessageText); @@ -66,8 +67,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_WindowsSysImplementation_alert(JNIEnv * en free(cTitleBarText); } -JNIEXPORT jstring JNICALL Java_org_lwjgl_WindowsSysImplementation_getClipboard - (JNIEnv * env, jobject ignored) +JNIEXPORT jstring JNICALL Java_org_lwjgl_WindowsSysImplementation_nGetClipboard + (JNIEnv * env, jclass unused) { // Check to see if there's text available in the clipboard BOOL textAvailable = IsClipboardFormatAvailable(CF_TEXT); diff --git a/src/native/windows/org_lwjgl_opengl_Display.c b/src/native/windows/org_lwjgl_opengl_Display.c index 5da1641d..5a59c491 100644 --- a/src/native/windows/org_lwjgl_opengl_Display.c +++ b/src/native/windows/org_lwjgl_opengl_Display.c @@ -52,20 +52,9 @@ static HICON small_icon = NULL; static HICON large_icon = NULL; -static HWND display_hwnd = NULL; // Handle to the window -static HDC display_hdc = NULL; // Device context - // has recovered from minimized #define WINDOWCLASSNAME "LWJGL" -HDC getCurrentHDC() { - return display_hdc; -} - -HWND getCurrentHWND() { - return display_hwnd; -} - static void freeLargeIcon() { if (large_icon != NULL) { DestroyIcon(large_icon); @@ -140,33 +129,29 @@ static void handleMessages(JNIEnv *env) { * work properly */ MSG msg; - if (display_hwnd != NULL) { - while (!(*env)->ExceptionOccurred(env) && PeekMessage( - &msg, // message information - NULL, // handle to window - 0, // first message - 0, // last message - PM_REMOVE // removal options - )) - { - DispatchMessage(&msg); - TranslateMessage(&msg); - } + while (!(*env)->ExceptionOccurred(env) && PeekMessage( + &msg, // message information + NULL, // handle to window + 0, // first message + 0, // last message + PM_REMOVE // removal options + )) + { + DispatchMessage(&msg); + TranslateMessage(&msg); } } -JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_getHdc(JNIEnv *env, jclass unused) { - return (INT_PTR)display_hdc; +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_getDC(JNIEnv *env, jclass unused, jlong hwnd_ptr) { + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; + return (INT_PTR)GetDC(hwnd); } -JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_getHwnd(JNIEnv *env, jclass unused) { - return (INT_PTR)display_hwnd; -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_setTitle - (JNIEnv * env, jobject self, jstring title_obj) { +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nSetTitle + (JNIEnv * env, jclass unused, jlong hwnd_ptr, jstring title_obj) { + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; char * title = GetStringNativeChars(env, title_obj); - SetWindowText(display_hwnd, title); + SetWindowText(hwnd, title); free(title); } @@ -183,45 +168,39 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_DefaultSysImplementation_getJNIVersion return org_lwjgl_WindowsSysImplementation_JNI_VERSION; } -static void destroyWindow(JNIEnv *env) { - jclass display_class_global = (jclass)(LONG_PTR)GetWindowLongPtr(display_hwnd, GWLP_USERDATA); - closeWindow(&display_hwnd, &display_hdc); +static void destroyWindow(JNIEnv *env, HWND *hwnd, HDC *hdc) { + jclass display_class_global = (jclass)(LONG_PTR)GetWindowLongPtr(*hwnd, GWLP_USERDATA); + closeWindow(hwnd, hdc); if (display_class_global != NULL) (*env)->DeleteGlobalRef(env, display_class_global); freeLargeIcon(); freeSmallIcon(); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nCreateWindow(JNIEnv *env, jobject self, jobject mode, jboolean fullscreen, jint x, jint y, jboolean undecorated, jboolean child_window, jlong parent_hwnd) { +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nCreateWindow(JNIEnv *env, jobject self, jobject mode, jboolean fullscreen, jint x, jint y, jboolean undecorated, jboolean child_window, jlong parent_hwnd) { 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); + HWND hwnd; static bool oneShotInitialised = false; if (!oneShotInitialised) { if (!registerWindow(lwjglWindowProc, WINDOWCLASSNAME)) { throwException(env, "Could not register window class"); - return; + return 0; } oneShotInitialised = true; } - display_hwnd = createWindow(WINDOWCLASSNAME, x, y, width, height, fullscreen, undecorated, child_window, (HWND)parent_hwnd); - if (display_hwnd == NULL) { - throwException(env, "Failed to create the window."); - return; - } - display_hdc = GetDC(display_hwnd); - if (display_hdc == NULL) { - destroyWindow(env); - throwException(env, "Failed to get the window DC."); - return; - } + hwnd = createWindow(WINDOWCLASSNAME, x, y, width, height, fullscreen, undecorated, child_window, (HWND)parent_hwnd); + return (INT_PTR)hwnd; } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nDestroyWindow(JNIEnv *env, jclass clazz) { - destroyWindow(env); +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nDestroyWindow(JNIEnv *env, jclass clazz, jlong hwnd_ptr, jlong hdc_ptr) { + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; + HDC hdc = (HDC)(INT_PTR)hdc_ptr; + destroyWindow(env, &hwnd, &hdc); } JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_clientToScreen(JNIEnv *env, jclass unused, jlong hwnd_int, jobject buffer_handle) { @@ -475,15 +454,16 @@ static HICON createWindowIcon(JNIEnv *env, jint *pixels, jint width, jint height } JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nSetWindowIconSmall - (JNIEnv *env, jclass clazz, jint width, jint height, jobject iconBuffer) + (JNIEnv *env, jclass clazz, jlong hwnd_ptr, jint width, jint height, jobject iconBuffer) { + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; jint *imgData = (jint *)(*env)->GetDirectBufferAddress(env, iconBuffer); freeSmallIcon(); small_icon = createWindowIcon(env, imgData, width, height); if (small_icon != NULL) { - if (display_hwnd != NULL) { - SendMessage(display_hwnd, WM_SETICON, ICON_SMALL, (LPARAM) (small_icon)); + if (hwnd != NULL) { + SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) (small_icon)); return 0; } @@ -493,15 +473,16 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nSetWindowIconSmall } JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nSetWindowIconLarge - (JNIEnv *env, jclass clazz, jint width, jint height, jobject iconBuffer) + (JNIEnv *env, jclass clazz, jlong hwnd_ptr, jint width, jint height, jobject iconBuffer) { + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; jint *imgData = (jint *)(*env)->GetDirectBufferAddress(env, iconBuffer); freeLargeIcon(); large_icon = createWindowIcon(env, imgData, width, height); if (large_icon != NULL) { - if (display_hwnd != NULL) { - SendMessage(display_hwnd, WM_SETICON, ICON_BIG, (LPARAM) (large_icon)); + if (hwnd != NULL) { + SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) (large_icon)); return 0; }