From 2e3f28b029213f7186bff96a0a8ab6899ae8e032 Mon Sep 17 00:00:00 2001 From: Caspian Rychlik-Prince Date: Fri, 7 Feb 2003 21:54:31 +0000 Subject: [PATCH] *** empty log message *** --- src/java/org/lwjgl/Display.java | 14 ++- src/native/common/org_lwjgl_Display.h | 11 ++- src/native/win32/org_lwjgl_Display.cpp | 87 +++++++++++++++++-- src/native/win32/org_lwjgl_input_Keyboard.cpp | 2 + src/native/win32/org_lwjgl_input_Mouse.cpp | 5 +- src/native/win32/org_lwjgl_opengl_BaseGL.cpp | 36 ++++++++ 6 files changed, 142 insertions(+), 13 deletions(-) diff --git a/src/java/org/lwjgl/Display.java b/src/java/org/lwjgl/Display.java index 4948737a..fd7c5ec5 100644 --- a/src/java/org/lwjgl/Display.java +++ b/src/java/org/lwjgl/Display.java @@ -55,9 +55,9 @@ public final class Display { /** The current display mode, if created */ private static DisplayMode mode; - /** A pointer to the native display window */ + /** A pointer to the native display window. On Windows this will be an hWnd. */ private static int handle; - + /** * No construction allowed. */ @@ -205,4 +205,14 @@ public final class Display { return created; } + /** + * Determines if the display is minimized. When the display is minimized it is + * effectively invisible, and you need perform no rendering in your game loop. + * On the native side, when the application is switched to some other application, + * the display window will minimize; when focus is regained, it will maximize and + * automatically gain focus and become the foreground window again. + * @return true if the display is minimized + */ + public static native boolean isMinimized(); + } diff --git a/src/native/common/org_lwjgl_Display.h b/src/native/common/org_lwjgl_Display.h index 8adec589..7c025277 100644 --- a/src/native/common/org_lwjgl_Display.h +++ b/src/native/common/org_lwjgl_Display.h @@ -23,7 +23,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_Display_getAvailableDisplayModes /* * Class: org_lwjgl_Display * Method: nCreate - * Signature: (IIIIZ)Z + * Signature: (IIIIIIIZLjava/lang/String;)Z */ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate (JNIEnv *, jclass, jint, jint, jint, jint, jint, jint, jint, jboolean, jstring); @@ -36,6 +36,15 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate JNIEXPORT void JNICALL Java_org_lwjgl_Display_nDestroy (JNIEnv *, jclass); +/* + * Class: org_lwjgl_Display + * Method: isMinimized + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_isMinimized + (JNIEnv *, jclass); + + #ifdef __cplusplus } #endif diff --git a/src/native/win32/org_lwjgl_Display.cpp b/src/native/win32/org_lwjgl_Display.cpp index a3ace8c2..74278bbf 100644 --- a/src/native/win32/org_lwjgl_Display.cpp +++ b/src/native/win32/org_lwjgl_Display.cpp @@ -49,12 +49,16 @@ #define WINDOWCLASSNAME "LWJGLWINDOW" +extern void handleMessages(); extern HINSTANCE dll_handle; + // Initialise static variables bool oneShotInitialised = false; HWND hwnd = NULL; // Handle to the window HDC hdc = NULL; // Device context LPDIRECTINPUT lpdi = NULL; +bool isMinimized = false; +bool isFullscreen = false; void destroyDI(void) { @@ -65,7 +69,8 @@ void destroyDI(void) void destroyWindow(void) { // Reset the display if necessary - ChangeDisplaySettings(NULL, 0); + if (isFullscreen) + ChangeDisplaySettings(NULL, 0); if (hwnd != NULL) { // Vape the window @@ -78,7 +83,8 @@ void destroyWindow(void) #endif // Show the mouse - ShowCursor(TRUE); + if (isFullscreen) + ShowCursor(TRUE); } void destroyAll(void) @@ -104,6 +110,19 @@ void dumpLastError(void) { LocalFree(lpMsgBuf); } +/* + * Called when the application is alt-tabbed to or from + */ +void appActivate(bool active) +{ + if (active) { + SetForegroundWindow(hwnd); + ShowWindow(hwnd, SW_RESTORE); + } else if (isFullscreen) + ShowWindow(hwnd, SW_MINIMIZE); +} + + /* * A dummy WindowProc which does nothing. Used so we can have an invisible OpenGL window */ @@ -126,6 +145,17 @@ LRESULT CALLBACK WindowProc(HWND hWnd, break; } } + case WM_ACTIVATE: + { + int fActive, fMinimized; + + fActive = LOWORD(wParam); + fMinimized = (BOOL) HIWORD(wParam); + + appActivate(fActive != WA_INACTIVE && !fMinimized); + isMinimized = fMinimized == TRUE || (fActive == WA_INACTIVE && isFullscreen); + } + } // default action @@ -138,7 +168,7 @@ LRESULT CALLBACK WindowProc(HWND hWnd, */ int SetDisplayMode(int width, int height, int bpp, int freq) { - // Step 2: set display mode using OpenGL friendly tactics + // Set display mode using OpenGL friendly tactics DEVMODE devmode; devmode.dmSize = sizeof(DEVMODE); @@ -277,16 +307,35 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate exstyle = 0; windowflags = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_VISIBLE; } + isFullscreen = fullscreen == JNI_TRUE; const char* titleString = env->GetStringUTFChars(title, NULL); + // If we're not a fullscreen window, adjust the height to account for the + // height of the title bar: + RECT clientSize; + 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 + ); + + clientSize.bottom -= clientSize.top; + clientSize.right -= clientSize.left; + // Create the window now, using that class: hwnd = CreateWindowEx ( exstyle, WINDOWCLASSNAME, titleString, windowflags, - 0, 0, width, height, + 0, 0, clientSize.right, clientSize.bottom, NULL, NULL, dll_handle, @@ -308,8 +357,14 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate printf("Created display\n"); #endif - // Hide the mouse - ShowCursor(FALSE); + // Hide the mouse in fullscreen + if (fullscreen) + ShowCursor(FALSE); + else { + SetCursor(LoadCursor(dll_handle, MAKEINTRESOURCE(IDC_ARROW))); + } + + // Create input HRESULT ret = DirectInputCreate(GetModuleHandle(NULL), DIRECTINPUT_VERSION, &lpdi, NULL); @@ -442,3 +497,23 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Display_nDestroy destroyAll(); } +/* + * Class: org_lwjgl_Display + * Method: isMinimized + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_isMinimized + (JNIEnv * env, jclass clazz) +{ + // Make sure that messages are being processed. Because + // you shouldn't be calling swapBuffers when the window is + // minimized, you won't get your window messages processed + // there, so we'll do it here too, just to be sure. + + if (isMinimized) + handleMessages(); + + return isMinimized ? JNI_TRUE : JNI_FALSE; +} + + diff --git a/src/native/win32/org_lwjgl_input_Keyboard.cpp b/src/native/win32/org_lwjgl_input_Keyboard.cpp index dc74ea1e..9a11b80c 100644 --- a/src/native/win32/org_lwjgl_input_Keyboard.cpp +++ b/src/native/win32/org_lwjgl_input_Keyboard.cpp @@ -196,6 +196,8 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nRead do { ret = lpdiKeyboard->Acquire(); + if (ret != DI_OK && ret != S_FALSE) + return 0; } while (ret != DI_OK && ret != S_FALSE); ret = lpdiKeyboard->GetDeviceData( diff --git a/src/native/win32/org_lwjgl_input_Mouse.cpp b/src/native/win32/org_lwjgl_input_Mouse.cpp index 819bfc51..5bbe5021 100644 --- a/src/native/win32/org_lwjgl_input_Mouse.cpp +++ b/src/native/win32/org_lwjgl_input_Mouse.cpp @@ -121,7 +121,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nCreate } // Grab non-exclusive foreground access to device - if (lpdiMouse->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND) != DI_OK) { + if (lpdiMouse->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK) { printf("Failed to set mouse coop\n"); return JNI_FALSE; } @@ -169,9 +169,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll while (ret = lpdiMouse->GetDeviceState(sizeof(diMouseState), &diMouseState) != DI_OK) { ret = lpdiMouse->Acquire(); if (ret != DI_OK && ret != S_FALSE) { -#ifdef _DEBUG - printf("Failed to acquire mouse\n"); -#endif return; } } diff --git a/src/native/win32/org_lwjgl_opengl_BaseGL.cpp b/src/native/win32/org_lwjgl_opengl_BaseGL.cpp index c5d1ddf5..52fd50c1 100644 --- a/src/native/win32/org_lwjgl_opengl_BaseGL.cpp +++ b/src/native/win32/org_lwjgl_opengl_BaseGL.cpp @@ -47,6 +47,39 @@ HGLRC hglrc = NULL; // OpenGL rendering context extern HDC hdc; extern HWND hwnd; + + +/* + * Handle windowing messages sent by the operating system + */ +void handleMessages() +{ + /* + * Now's our chance to deal with Windows messages that are + * otherwise just piling up and causing everything not to + * work properly + */ + MSG msg; + while (PeekMessage( + &msg, // message information + hwnd, // handle to window + 0, // first message + 0, // last message + PM_NOREMOVE // removal options + )) { + + if (GetMessage (&msg, NULL, 0, 0) <= 0) { +#ifdef _DEBUG + printf("We should quit here...\n"); +#endif + return; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + }; +} + + /* * Class: org_lwjgl_opengl_BaseGL * Method: nCreate @@ -112,6 +145,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nDestroy JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_swapBuffers (JNIEnv *, jobject) { + // Handle OS messages here + handleMessages(); + // Then do the flip wglSwapLayerBuffers(hdc, WGL_SWAP_MAIN_PLANE); }