Windows: Moved gamma and display modes settings and more boolean state to java side.

This commit is contained in:
Elias Naur 2006-07-08 21:57:20 +00:00
parent 3fd8ea895e
commit c208833e25
6 changed files with 321 additions and 232 deletions

View File

@ -87,30 +87,145 @@ final class Win32Display implements DisplayImplementation {
private final static int SM_CXCURSOR = 13; private final static int SM_CXCURSOR = 13;
private static Win32DisplayPeerInfo peer_info; private final static int SIZE_RESTORED = 0;
private final static int SIZE_MINIMIZED = 1;
private final static int SIZE_MAXIMIZED = 2;
private final static int WM_SIZE = 0x0005;
private final static int WM_ACTIVATE = 0x0006;
private final static int WA_INACTIVE = 0;
private final static int WA_ACTIVE = 1;
private final static int WA_CLICKACTIVE = 2;
private final static int SW_SHOWMINNOACTIVE = 7;
private final static int SW_RESTORE = 9;
private static WindowsKeyboard keyboard; private static Win32Display current_display;
private static WindowsMouse mouse;
private static boolean close_requested; private Win32DisplayPeerInfo peer_info;
private static boolean is_dirty;
private WindowsKeyboard keyboard;
private WindowsMouse mouse;
private boolean close_requested;
private boolean is_dirty;
private ByteBuffer current_gamma;
private ByteBuffer saved_gamma;
private DisplayMode current_mode;
private boolean mode_set;
private boolean isFullscreen;
private boolean isMinimized;
private boolean isFocused;
private boolean did_maximize;
private boolean inAppActivate;
public Win32Display() {
current_display = this;
}
public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException { public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException {
close_requested = false; close_requested = false;
is_dirty = false; is_dirty = false;
isFullscreen = fullscreen;
isMinimized = false;
isFocused = false;
did_maximize = false;
nCreateWindow(mode, fullscreen, x, y); nCreateWindow(mode, fullscreen, x, y);
peer_info.initDC(); peer_info.initDC();
} }
private native void nCreateWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException; 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 void destroyWindow() {
public native void resetDisplayMode(); nDestroyWindow();
if (isFullscreen)
resetCursorClipping();
}
private static native void nDestroyWindow();
private static native void resetCursorClipping();
private static native void setupCursorClipping(long hwnd) throws LWJGLException;
public void switchDisplayMode(DisplayMode mode) throws LWJGLException {
nSwitchDisplayMode(mode);
current_mode = mode;
mode_set = true;
}
private static native void nSwitchDisplayMode(DisplayMode mode) throws LWJGLException;
/*
* Called when the application is alt-tabbed to or from
*/
private void appActivate(boolean active) {
if (inAppActivate) {
return;
}
inAppActivate = true;
isFocused = active;
if (active) {
if (isFullscreen) {
restoreDisplayMode();
}
showWindow(getHwnd(), SW_RESTORE);
setForegroundWindow(getHwnd());
setFocus(getHwnd());
did_maximize = true;
} else if (isFullscreen) {
showWindow(getHwnd(), SW_SHOWMINNOACTIVE);
resetDisplayMode();
}
inAppActivate = false;
}
private static native void showWindow(long hwnd, int mode);
private static native void setForegroundWindow(long hwnd);
private static native void setFocus(long hwnd);
private void restoreDisplayMode() {
try {
doSetGammaRamp(current_gamma);
} catch (LWJGLException e) {
LWJGLUtil.log("Failed to restore gamma: " + e.getMessage());
}
if (!mode_set) {
mode_set = true;
try {
nSwitchDisplayMode(current_mode);
} catch (LWJGLException e) {
LWJGLUtil.log("Failed to restore display mode: " + e.getMessage());
}
}
}
public void resetDisplayMode() {
try {
doSetGammaRamp(saved_gamma);
} catch (LWJGLException e) {
LWJGLUtil.log("Failed to reset gamma ramp: " + e.getMessage());
}
current_gamma = saved_gamma;
if (mode_set) {
mode_set = false;
nResetDisplayMode();
}
resetCursorClipping();
}
private static native void nResetDisplayMode();
public int getGammaRampLength() { public int getGammaRampLength() {
return GAMMA_LENGTH; return GAMMA_LENGTH;
} }
public native void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException; public void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException {
doSetGammaRamp(convertToNativeRamp(gammaRamp));
}
private static native ByteBuffer convertToNativeRamp(FloatBuffer gamma_ramp) throws LWJGLException;
private static native ByteBuffer getCurrentGammaRamp() throws LWJGLException;
private void doSetGammaRamp(ByteBuffer native_gamma) throws LWJGLException {
nSetGammaRamp(native_gamma);
current_gamma = native_gamma;
}
private static native void nSetGammaRamp(ByteBuffer native_ramp) throws LWJGLException;
public String getAdapter() { public String getAdapter() {
try { try {
String adapter_string = Win32Registry.queryRegistrationKey( String adapter_string = Win32Registry.queryRegistrationKey(
@ -139,7 +254,13 @@ final class Win32Display implements DisplayImplementation {
return null; return null;
} }
private native String nGetVersion(String driver); private native String nGetVersion(String driver);
public native DisplayMode init() throws LWJGLException;
public DisplayMode init() throws LWJGLException {
current_gamma = saved_gamma = getCurrentGammaRamp();
return current_mode = getCurrentDisplayMode();
}
private static native DisplayMode getCurrentDisplayMode() throws LWJGLException;
public native void setTitle(String title); public native void setTitle(String title);
public boolean isCloseRequested() { public boolean isCloseRequested() {
@ -148,8 +269,13 @@ final class Win32Display implements DisplayImplementation {
return saved; return saved;
} }
public native boolean isVisible(); public boolean isVisible() {
public native boolean isActive(); return !isMinimized;
}
public boolean isActive() {
return isFocused;
}
public boolean isDirty() { public boolean isDirty() {
boolean saved = is_dirty; boolean saved = is_dirty;
@ -163,7 +289,8 @@ final class Win32Display implements DisplayImplementation {
} }
public void update() { public void update() {
nUpdate(); nUpdate();
if (didMaximize()) { if (did_maximize) {
did_maximize = false;
/** /**
* WORKAROUND: * WORKAROUND:
* Making the context current (redundantly) when the window * Making the context current (redundantly) when the window
@ -177,10 +304,13 @@ final class Win32Display implements DisplayImplementation {
} }
} }
} }
private native void nUpdate(); private static native void nUpdate();
private native boolean didMaximize();
public native void reshape(int x, int y, int width, int height); public void reshape(int x, int y, int width, int height) {
if (!isFullscreen)
nReshape(getHwnd(), x, y, width, height);
}
private static native void nReshape(long hwnd, int x, int y, int width, int height);
public native DisplayMode[] getAvailableDisplayModes() throws LWJGLException; public native DisplayMode[] getAvailableDisplayModes() throws LWJGLException;
/* Mouse */ /* Mouse */
@ -219,7 +349,10 @@ final class Win32Display implements DisplayImplementation {
return Cursor.CURSOR_ONE_BIT_TRANSPARENCY; return Cursor.CURSOR_ONE_BIT_TRANSPARENCY;
} }
public native void setCursorPosition(int x, int y); public void setCursorPosition(int x, int y) {
nSetCursorPosition(x, y, isFullscreen);
}
private static native void nSetCursorPosition(int x, int y, boolean fullscreen);
public native void setNativeCursor(Object handle) throws LWJGLException; public native void setNativeCursor(Object handle) throws LWJGLException;
@ -338,17 +471,17 @@ final class Win32Display implements DisplayImplementation {
private static native int nSetWindowIcon32(IntBuffer icon); private static native int nSetWindowIcon32(IntBuffer icon);
private static void handleMouseButton(int button, int state, long millis) { private void handleMouseButton(int button, int state, long millis) {
if (mouse != null) if (mouse != null)
mouse.handleMouseButton((byte)button, (byte)state, millis); mouse.handleMouseButton((byte)button, (byte)state, millis);
} }
private static void handleMouseMoved(int x, int y, long millis) { private void handleMouseMoved(int x, int y, long millis) {
if (mouse != null) if (mouse != null)
mouse.handleMouseMoved(x, y, millis); mouse.handleMouseMoved(x, y, millis);
} }
private static void handleMouseScrolled(int amount, long millis) { private void handleMouseScrolled(int amount, long millis) {
if (mouse != null) if (mouse != null)
mouse.handleMouseScrolled(amount, millis); mouse.handleMouseScrolled(amount, millis);
} }
@ -356,7 +489,44 @@ final class Win32Display implements DisplayImplementation {
private static native int transformY(long hwnd, int y); private static native int transformY(long hwnd, int y);
private static boolean handleMessage(long hwnd, int msg, long wParam, long lParam, long millis) { private static boolean handleMessage(long hwnd, int msg, long wParam, long lParam, long millis) {
if (current_display != null)
return current_display.doHandleMessage(hwnd, msg, wParam, lParam, millis);
else
return false;
}
private boolean doHandleMessage(long hwnd, int msg, long wParam, long lParam, long millis) {
if (isFullscreen && !isMinimized && isFocused) {
try {
setupCursorClipping(getHwnd());
} catch (LWJGLException e) {
LWJGLUtil.log("setupCursorClipping failed: " + e.getMessage());
}
}
switch (msg) { switch (msg) {
// disable screen saver and monitor power down messages which wreak havoc
case WM_ACTIVATE:
switch ((int)wParam) {
case WA_ACTIVE:
case WA_CLICKACTIVE:
appActivate(true);
break;
case WA_INACTIVE:
appActivate(false);
break;
}
return true;
case WM_SIZE:
switch ((int)wParam) {
case SIZE_RESTORED:
case SIZE_MAXIMIZED:
isMinimized = false;
break;
case SIZE_MINIMIZED:
isMinimized = true;
break;
}
return false;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
int xPos = (int)(short)(lParam & 0xFFFF); int xPos = (int)(short)(lParam & 0xFFFF);
int yPos = transformY(getHwnd(), (int)(short)((lParam >> 16) & 0xFFFF)); int yPos = transformY(getHwnd(), (int)(short)((lParam >> 16) & 0xFFFF));

View File

@ -230,10 +230,14 @@ public class DisplayTest {
* @param time milliseconds to sleep * @param time milliseconds to sleep
*/ */
private void pause(long time) { private void pause(long time) {
try { int SLEEP_DELAY = 100;
Thread.sleep(time); for (int i = 0; i < time; i += SLEEP_DELAY) {
} catch (InterruptedException inte) { try {
} Display.processMessages();
Thread.sleep(SLEEP_DELAY);
} catch (InterruptedException inte) {
}
}
} }
/** /**

View File

@ -56,9 +56,7 @@
#define WINDOW_H_API extern #define WINDOW_H_API extern
#endif /* _PRIVATE_WINDOW_H_ */ #endif /* _PRIVATE_WINDOW_H_ */
WINDOW_H_API HWND getCurrentHWND();
WINDOW_H_API HDC getCurrentHDC(); WINDOW_H_API HDC getCurrentHDC();
WINDOW_H_API bool getCurrentFullscreen(); WINDOW_H_API HWND getCurrentHWND();
#endif /* _LWJGL_WINDOW_H_INCLUDED_ */ #endif /* _LWJGL_WINDOW_H_INCLUDED_ */

View File

@ -42,18 +42,13 @@
#include <windows.h> #include <windows.h>
// Multimon.h enables multi monitor emulation on win95 and winnt4 // Multimon.h enables multi monitor emulation on win95 and winnt4
// So we only need the extended, multi-monitor aware path // So we only need the extended, multi-monitor aware path
#define COMPILE_MULTIMON_STUBS //#define COMPILE_MULTIMON_STUBS
#include <Multimon.h> //#include <Multimon.h>
#include <jni.h> #include <jni.h>
#include "org_lwjgl_opengl_Win32Display.h" #include "org_lwjgl_opengl_Win32Display.h"
#include "display.h" #include "display.h"
#include "common_tools.h" #include "common_tools.h"
static bool modeSet = false; // Whether we've done a display mode change
static WORD originalGamma[3*org_lwjgl_opengl_Win32Display_GAMMA_LENGTH]; // Original gamma settings
static WORD currentGamma[3*org_lwjgl_opengl_Win32Display_GAMMA_LENGTH]; // Current gamma settings
static DEVMODE devmode; // Now we'll remember this value for the future
static jobject createDisplayMode(JNIEnv *env, DEVMODE *devmode) { static jobject createDisplayMode(JNIEnv *env, DEVMODE *devmode) {
jclass displayModeClass; jclass displayModeClass;
@ -127,8 +122,9 @@ jobjectArray getAvailableDisplayModes(JNIEnv * env) {
return ret; return ret;
} }
void switchDisplayMode(JNIEnv * env, jobject mode) void switchDisplayMode(JNIEnv * env, jobject mode) {
{ DEVMODE devmode;
jclass cls_displayMode = (*env)->GetObjectClass(env, mode); jclass cls_displayMode = (*env)->GetObjectClass(env, mode);
jfieldID fid_width = (*env)->GetFieldID(env, cls_displayMode, "width", "I"); jfieldID fid_width = (*env)->GetFieldID(env, cls_displayMode, "width", "I");
jfieldID fid_height = (*env)->GetFieldID(env, cls_displayMode, "height", "I"); jfieldID fid_height = (*env)->GetFieldID(env, cls_displayMode, "height", "I");
@ -165,99 +161,85 @@ void switchDisplayMode(JNIEnv * env, jobject mode)
return; return;
// } // }
} }
modeSet = true;
} }
void setGammaRamp(JNIEnv * env, jobject gammaRampBuffer) static jobject createNativeGammaBuffer(JNIEnv *env) {
{ return newJavaManagedByteBuffer(env, sizeof(WORD)*3*org_lwjgl_opengl_Win32Display_GAMMA_LENGTH);
int i; }
float scaledRampEntry;
WORD rampEntry;
HDC screenDC;
const float *gammaRamp = (const float *)(*env)->GetDirectBufferAddress(env, gammaRampBuffer);
// Turn array of floats into array of RGB WORDs
for (i = 0; i < org_lwjgl_opengl_Win32Display_GAMMA_LENGTH; i ++) { jobject getCurrentGammaRamp(JNIEnv *env) {
scaledRampEntry = gammaRamp[i]*0xffff; jobject gamma_buffer;
rampEntry = (WORD)scaledRampEntry; WORD *gamma;
currentGamma[i] = rampEntry; HDC screenDC;
currentGamma[i + org_lwjgl_opengl_Win32Display_GAMMA_LENGTH] = rampEntry;
currentGamma[i + 2*org_lwjgl_opengl_Win32Display_GAMMA_LENGTH] = rampEntry; gamma_buffer = createNativeGammaBuffer(env);
} if (gamma_buffer == NULL)
return NULL;
gamma = (WORD *)(*env)->GetDirectBufferAddress(env, gamma_buffer);
// Get the screen
screenDC = GetDC(NULL); screenDC = GetDC(NULL);
if (SetDeviceGammaRamp(screenDC, currentGamma) == FALSE) { if (screenDC == NULL) {
throwException(env, "Couldn't get screen DC!");
return NULL;
}
// Get the default gamma ramp
if (GetDeviceGammaRamp(screenDC, gamma) == FALSE) {
printfDebugJava(env, "Failed to get initial device gamma");
}
ReleaseDC(NULL, screenDC);
return gamma_buffer;
}
void setGammaRamp(JNIEnv * env, jobject gammaRampBuffer) {
HDC screenDC;
WORD *gammaRamp = (WORD *)(*env)->GetDirectBufferAddress(env, gammaRampBuffer);
screenDC = GetDC(NULL);
if (SetDeviceGammaRamp(screenDC, gammaRamp) == FALSE) {
throwException(env, "Failed to set device gamma."); throwException(env, "Failed to set device gamma.");
} }
ReleaseDC(NULL, screenDC); ReleaseDC(NULL, screenDC);
} }
jobject convertToNativeRamp(JNIEnv *env, jobject float_gamma_obj) {
int i;
float scaledRampEntry;
WORD rampEntry;
HDC screenDC;
const float *gammaRamp = (const float *)(*env)->GetDirectBufferAddress(env, float_gamma_obj);
jint gamma_ramp_length = (*env)->GetDirectBufferCapacity(env, float_gamma_obj);
jobject native_ramp;
WORD *native_ramp_buffer;
jobject initDisplay(JNIEnv * env) native_ramp = createNativeGammaBuffer(env);
{ if (native_ramp == NULL)
DEVMODE devmode;
jobject newMode;
// Get the screen
HDC screenDC = GetDC(NULL);
if (!screenDC) {
throwException(env, "Couldn't get screen DC!");
return NULL; return NULL;
} native_ramp_buffer = (WORD *)(*env)->GetDirectBufferAddress(env, native_ramp);
// Get the default gamma ramp // Turn array of floats into array of RGB WORDs
if (GetDeviceGammaRamp(screenDC, originalGamma) == FALSE) {
printfDebugJava(env, "Failed to get initial device gamma");
}
memcpy(currentGamma, originalGamma, sizeof(WORD)*3*org_lwjgl_opengl_Win32Display_GAMMA_LENGTH);
ReleaseDC(NULL, screenDC);
for (i = 0; i < gamma_ramp_length; i++) {
scaledRampEntry = gammaRamp[i]*0xffff;
rampEntry = (WORD)scaledRampEntry;
native_ramp_buffer[i] = rampEntry;
native_ramp_buffer[i + org_lwjgl_opengl_Win32Display_GAMMA_LENGTH] = rampEntry;
native_ramp_buffer[i + 2*org_lwjgl_opengl_Win32Display_GAMMA_LENGTH] = rampEntry;
}
return native_ramp;
}
jobject getCurrentDisplayMode(JNIEnv * env) {
DEVMODE devmode;
if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode)) { if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode)) {
throwFormattedException(env, "Couldn't get current display settings (%ld)", GetLastError()); throwFormattedException(env, "Couldn't get current display settings (%ld)", GetLastError());
return NULL; return NULL;
} }
newMode = createDisplayMode(env, &devmode); return createDisplayMode(env, &devmode);
return newMode;
} }
void resetDisplayMode(JNIEnv * env) { void resetDisplayMode(JNIEnv * env) {
// Return device gamma to normal // Under Win32, all we have to do is:
HDC screenDC = GetDC(NULL); ChangeDisplaySettings(NULL, 0);
if (!SetDeviceGammaRamp(screenDC, originalGamma)) {
printfDebugJava(env, "Could not reset device gamma");
}
ReleaseDC(NULL, screenDC);
if (modeSet) {
modeSet = false;
// Under Win32, all we have to do is:
ChangeDisplaySettings(NULL, 0);
// And we'll call init() again to put the correct mode back in Display
if (env != NULL)
initDisplay(env);
}
}
/*
* Put display settings back to what they were when the window is maximized.
*/
void restoreDisplayMode(void) {
// Restore gamma
HDC screenDC = GetDC(NULL);
LONG cdsret;
if (!SetDeviceGammaRamp(screenDC, currentGamma)) {
printfDebug("Could not restore device gamma\n");
}
ReleaseDC(NULL, screenDC);
if (!modeSet) {
printfDebug("Attempting to restore the display mode\n");
modeSet = true;
cdsret = ChangeDisplaySettings(&devmode, CDS_FULLSCREEN);
if (cdsret != DISP_CHANGE_SUCCESSFUL) {
printfDebug("Failed to restore display mode\n");
}
}
} }
jstring getVersion(JNIEnv * env, char *driver) jstring getVersion(JNIEnv * env, char *driver)

View File

@ -49,7 +49,9 @@ extern void switchDisplayMode(JNIEnv * env, jobject mode);
extern void resetDisplayMode(JNIEnv * env); extern void resetDisplayMode(JNIEnv * env);
extern void restoreDisplayMode(void); extern void restoreDisplayMode(void);
extern void setGammaRamp(JNIEnv * env, jobject gammaRampBuffer); extern void setGammaRamp(JNIEnv * env, jobject gammaRampBuffer);
extern jobject initDisplay(JNIEnv * env); extern jobject getCurrentGammaRamp(JNIEnv *env);
extern jobject getCurrentDisplayMode(JNIEnv * env);
extern jstring getVersion(JNIEnv * env, char *driver); extern jstring getVersion(JNIEnv * env, char *driver);
extern jobject convertToNativeRamp(JNIEnv *env, jobject float_gamma_obj);
#endif #endif

View File

@ -53,18 +53,10 @@ static HICON small_icon = NULL;
static HICON large_icon = NULL; static HICON large_icon = NULL;
static HWND display_hwnd = NULL; // Handle to the window static HWND display_hwnd = NULL; // Handle to the window
static HDC display_hdc = NULL; // Device context static HDC display_hdc = NULL; // Device 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 did_maximize = false; // A flag to tell when a window
// has recovered from minimized // has recovered from minimized
#define WINDOWCLASSNAME "LWJGL" #define WINDOWCLASSNAME "LWJGL"
bool getCurrentFullscreen() {
return isFullScreen;
}
HDC getCurrentHDC() { HDC getCurrentHDC() {
return display_hdc; return display_hdc;
} }
@ -73,45 +65,6 @@ HWND getCurrentHWND() {
return display_hwnd; return display_hwnd;
} }
static void setupCursorClipping() {
RECT hwnd_client;
if (display_hwnd != NULL && GetWindowRect(display_hwnd, &hwnd_client) != 0) {
if (ClipCursor(&hwnd_client) == 0)
printfDebug("ClipCursor failed\n");
}
}
static void resetDisplayModeAndClipping(JNIEnv *env) {
resetDisplayMode(env);
ClipCursor(NULL);
}
/*
* Called when the application is alt-tabbed to or from
*/
static void appActivate(bool active)
{
static bool inAppActivate = false;
if (inAppActivate) {
return;
}
inAppActivate = true;
isFocused = active;
if (active) {
if (isFullScreen) {
restoreDisplayMode();
}
ShowWindow(display_hwnd, SW_RESTORE);
SetForegroundWindow(display_hwnd);
SetFocus(display_hwnd);
did_maximize = true;
} else if (isFullScreen) {
ShowWindow(display_hwnd, SW_SHOWMINNOACTIVE);
resetDisplayModeAndClipping(NULL);
}
inAppActivate = false;
}
static void freeLargeIcon() { static void freeLargeIcon() {
if (large_icon != NULL) { if (large_icon != NULL) {
DestroyIcon(large_icon); DestroyIcon(large_icon);
@ -126,13 +79,6 @@ static void freeSmallIcon() {
} }
} }
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. * WindowProc for the GL window.
*/ */
@ -145,34 +91,6 @@ static LRESULT CALLBACK lwjglWindowProc(HWND hWnd,
jclass display_class; jclass display_class;
jmethodID handleMessage_method; jmethodID handleMessage_method;
LONG message_time; LONG message_time;
if (isFullScreen && !isMinimized && isFocused)
setupCursorClipping();
switch (msg) {
// disable screen saver and monitor power down messages which wreak havoc
case WM_ACTIVATE:
switch (wParam) {
case WA_ACTIVE:
case WA_CLICKACTIVE:
appActivate(true);
break;
case WA_INACTIVE:
appActivate(false);
break;
}
return 0L;
case WM_SIZE:
switch (wParam) {
case SIZE_RESTORED:
case SIZE_MAXIMIZED:
isMinimized = false;
break;
case SIZE_MINIMIZED:
isMinimized = true;
break;
}
break;
}
env = (JNIEnv *)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA); env = (JNIEnv *)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (env != NULL && !(*env)->ExceptionOccurred(env)) { if (env != NULL && !(*env)->ExceptionOccurred(env)) {
display_class = (*env)->FindClass(env, "org/lwjgl/opengl/Win32Display"); display_class = (*env)->FindClass(env, "org/lwjgl/opengl/Win32Display");
@ -231,29 +149,16 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_Win32Display_getHwnd(JNIEnv *env,
* Signature: ()V * Signature: ()V
*/ */
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setTitle JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setTitle
(JNIEnv * env, jobject self, jstring title_obj) (JNIEnv * env, jobject self, jstring title_obj) {
{
char * title = GetStringNativeChars(env, title_obj); char * title = GetStringNativeChars(env, title_obj);
SetWindowText(display_hwnd, title); SetWindowText(display_hwnd, title);
free(title); free(title);
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nUpdate JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nUpdate(JNIEnv * env, jclass class) {
(JNIEnv * env, jobject self)
{
handleMessages(env); handleMessages(env);
} }
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Win32Display_isVisible
(JNIEnv *env, jobject self) {
return isMinimized ? JNI_FALSE : JNI_TRUE;
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Win32Display_isActive
(JNIEnv *env, jobject self) {
return isFocused;
}
JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_Win32Display_getAvailableDisplayModes(JNIEnv *env, jobject self) { JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_Win32Display_getAvailableDisplayModes(JNIEnv *env, jobject self) {
return getAvailableDisplayModes(env); return getAvailableDisplayModes(env);
} }
@ -275,11 +180,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nCreateWindow(JNIEnv *
oneShotInitialised = true; oneShotInitialised = true;
} }
isMinimized = false;
isFocused = false;
isFullScreen = fullscreen == JNI_TRUE;
isUndecorated = getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated"); isUndecorated = getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated");
display_hwnd = createWindow(WINDOWCLASSNAME, x, y, width, height, isFullScreen, isUndecorated); display_hwnd = createWindow(WINDOWCLASSNAME, x, y, width, height, fullscreen, isUndecorated);
if (display_hwnd == NULL) { if (display_hwnd == NULL) {
throwException(env, "Failed to create the window."); throwException(env, "Failed to create the window.");
return; return;
@ -292,26 +194,64 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nCreateWindow(JNIEnv *
SetFocus(display_hwnd); SetFocus(display_hwnd);
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_destroyWindow(JNIEnv *env, jobject self) { JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nDestroyWindow(JNIEnv *env, jclass clazz) {
closeWindow(&display_hwnd, &display_hdc); closeWindow(&display_hwnd, &display_hdc);
if (isFullScreen)
ClipCursor(NULL);
freeLargeIcon(); freeLargeIcon();
freeSmallIcon(); freeSmallIcon();
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_switchDisplayMode(JNIEnv *env, jobject self, jobject mode) { JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_resetCursorClipping(JNIEnv *env, jclass unused) {
ClipCursor(NULL);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setupCursorClipping(JNIEnv *env, jclass unused, jlong hwnd_ptr) {
HWND hwnd = (HWND)(INT_PTR)hwnd_ptr;
RECT hwnd_client;
if (display_hwnd != NULL && GetWindowRect(hwnd, &hwnd_client) != 0) {
if (ClipCursor(&hwnd_client) == 0)
throwFormattedException(env, "ClipCursor failed (%d)", GetLastError());
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nSwitchDisplayMode(JNIEnv *env, jobject self, jobject mode) {
switchDisplayMode(env, mode); switchDisplayMode(env, mode);
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_resetDisplayMode(JNIEnv *env, jobject self) { JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nResetDisplayMode(JNIEnv *env, jobject self) {
resetDisplayModeAndClipping(env); resetDisplayMode(env);
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setGammaRamp(JNIEnv *env, jobject self, jobject gamma_buffer) { JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Win32Display_getCurrentDisplayMode(JNIEnv *env, jclass unused) {
return getCurrentDisplayMode(env);
}
JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Win32Display_convertToNativeRamp(JNIEnv *env, jclass unused, jobject float_ramp) {
return convertToNativeRamp(env, float_ramp);
}
JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Win32Display_getCurrentGammaRamp(JNIEnv *env, jclass unused) {
return getCurrentGammaRamp(env);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nSetGammaRamp(JNIEnv *env, jclass unused, jobject gamma_buffer) {
setGammaRamp(env, gamma_buffer); setGammaRamp(env, gamma_buffer);
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_showWindow(JNIEnv *env, jclass unused, jlong hwnd_ptr, jint mode) {
HWND hwnd = (HWND)(INT_PTR)hwnd_ptr;
ShowWindow(hwnd, mode);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setForegroundWindow(JNIEnv *env, jclass unused, jlong hwnd_ptr) {
HWND hwnd = (HWND)(INT_PTR)hwnd_ptr;
SetForegroundWindow(hwnd);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setFocus(JNIEnv *env, jclass unused, jlong hwnd_ptr) {
HWND hwnd = (HWND)(INT_PTR)hwnd_ptr;
SetFocus(hwnd);
}
JNIEXPORT jstring JNICALL Java_org_lwjgl_opengl_Win32Display_nGetVersion(JNIEnv *env, jobject self, jstring driver) { JNIEXPORT jstring JNICALL Java_org_lwjgl_opengl_Win32Display_nGetVersion(JNIEnv *env, jobject self, jstring driver) {
char *driver_str; char *driver_str;
jstring result; jstring result;
@ -323,19 +263,12 @@ JNIEXPORT jstring JNICALL Java_org_lwjgl_opengl_Win32Display_nGetVersion(JNIEnv
return result; return result;
} }
JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_Win32Display_init(JNIEnv *env, jobject self) { JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nReshape(JNIEnv *env, jclass unused, jlong hwnd_ptr, jint x, jint y, jint width, jint height) {
return initDisplay(env); HWND hwnd = (HWND)(INT_PTR)hwnd_ptr;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_reshape(JNIEnv *env, jobject self, jint x, jint y, jint width, jint height) {
DWORD exstyle, windowflags; DWORD exstyle, windowflags;
RECT clientSize; RECT clientSize;
if (isFullScreen) { getWindowFlags(&windowflags, &exstyle, false, getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated"));
return;
}
getWindowFlags(&windowflags, &exstyle, isFullScreen, getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated"));
// If we're not a fullscreen window, adjust the height to account for the // If we're not a fullscreen window, adjust the height to account for the
// height of the title bar: // height of the title bar:
@ -351,7 +284,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_reshape(JNIEnv *env, j
exstyle // extended window style exstyle // extended window style
); );
SetWindowPos(display_hwnd, HWND_TOP, x, y, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, SWP_NOZORDER); SetWindowPos(hwnd, HWND_TOP, x, y, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, SWP_NOZORDER);
} }
static HICON createWindowIcon(JNIEnv *env, jint *pixels, jint width, jint height) { static HICON createWindowIcon(JNIEnv *env, jint *pixels, jint width, jint height) {
@ -513,7 +446,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_nSetWindowIcon32
} }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setCursorPosition JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setCursorPosition
(JNIEnv * env, jobject self, jint x, jint y) { (JNIEnv * env, jclass unused, jint x, jint y, jboolean fullscreen) {
DWORD windowflags, exstyle; DWORD windowflags, exstyle;
int transformed_x, transformed_y; int transformed_x, transformed_y;
RECT window_rect; RECT window_rect;
@ -523,7 +456,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setCursorPosition
int left_border_width; int left_border_width;
int bottom_border_width; int bottom_border_width;
getWindowFlags(&windowflags, &exstyle, getCurrentFullscreen(), getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated")); getWindowFlags(&windowflags, &exstyle, fullscreen, getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated"));
if (!GetClientRect(getCurrentHWND(), &client_rect)) { if (!GetClientRect(getCurrentHWND(), &client_rect)) {
printfDebugJava(env, "GetClientRect failed"); printfDebugJava(env, "GetClientRect failed");
return; return;