2002-08-15 11:46:18 -04:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2002 Light Weight Java Game Library Project
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are
|
|
|
|
* met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
2002-08-11 07:49:32 -04:00
|
|
|
*
|
2002-08-15 11:46:18 -04:00
|
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2002-08-11 07:49:32 -04:00
|
|
|
*
|
2002-08-15 11:46:18 -04:00
|
|
|
* * Neither the name of 'Light Weight Java Game Library' nor the names of
|
|
|
|
* its contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* $Id$
|
2002-08-11 07:49:32 -04:00
|
|
|
*
|
2002-08-15 11:46:18 -04:00
|
|
|
* Win32 specific library for display handdling.
|
2002-08-11 07:49:32 -04:00
|
|
|
*
|
2002-08-15 11:46:18 -04:00
|
|
|
* @author cix_foo <cix_foo@users.sourceforge.net>
|
|
|
|
* @version $Revision$
|
2002-08-11 07:49:32 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
#include "org_lwjgl_Display.h"
|
2002-08-15 10:53:18 -04:00
|
|
|
|
2002-08-26 14:14:22 -04:00
|
|
|
#undef DIRECTINPUT_VERSION
|
|
|
|
#define DIRECTINPUT_VERSION 0x0300
|
2002-08-15 10:53:18 -04:00
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
#include <dinput.h>
|
|
|
|
|
2002-08-17 10:13:12 -04:00
|
|
|
#define WINDOWCLASSNAME "LWJGLWINDOW"
|
2002-08-11 07:49:32 -04:00
|
|
|
|
2003-02-07 16:54:31 -05:00
|
|
|
extern void handleMessages();
|
2002-12-18 11:40:12 -05:00
|
|
|
extern HINSTANCE dll_handle;
|
2003-02-07 16:54:31 -05:00
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
// Initialise static variables
|
|
|
|
bool oneShotInitialised = false;
|
|
|
|
HWND hwnd = NULL; // Handle to the window
|
|
|
|
HDC hdc = NULL; // Device context
|
|
|
|
LPDIRECTINPUT lpdi = NULL;
|
2003-02-07 16:54:31 -05:00
|
|
|
bool isMinimized = false;
|
|
|
|
bool isFullscreen = false;
|
2002-08-11 07:49:32 -04:00
|
|
|
|
2002-12-19 11:35:35 -05:00
|
|
|
void destroyDI(void)
|
|
|
|
{
|
|
|
|
lpdi->Release();
|
|
|
|
lpdi = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void destroyWindow(void)
|
|
|
|
{
|
|
|
|
// Reset the display if necessary
|
2003-02-07 16:54:31 -05:00
|
|
|
if (isFullscreen)
|
|
|
|
ChangeDisplaySettings(NULL, 0);
|
2002-12-19 11:35:35 -05:00
|
|
|
|
|
|
|
if (hwnd != NULL) {
|
|
|
|
// Vape the window
|
|
|
|
DestroyWindow(hwnd);
|
|
|
|
hwnd = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Destroyed display\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Show the mouse
|
2003-02-07 16:54:31 -05:00
|
|
|
if (isFullscreen)
|
|
|
|
ShowCursor(TRUE);
|
2002-12-19 11:35:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void destroyAll(void)
|
|
|
|
{
|
|
|
|
destroyDI();
|
|
|
|
destroyWindow();
|
|
|
|
}
|
|
|
|
|
2002-12-14 10:23:53 -05:00
|
|
|
void dumpLastError(void) {
|
|
|
|
LPVOID lpMsgBuf;
|
|
|
|
FormatMessage(
|
|
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
|
NULL,
|
|
|
|
GetLastError(),
|
|
|
|
0, // Default language
|
|
|
|
(LPTSTR) &lpMsgBuf,
|
|
|
|
0,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
printf("System error: %s\n", lpMsgBuf);
|
|
|
|
LocalFree(lpMsgBuf);
|
|
|
|
}
|
|
|
|
|
2003-02-07 16:54:31 -05:00
|
|
|
/*
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
/*
|
|
|
|
* A dummy WindowProc which does nothing. Used so we can have an invisible OpenGL window
|
|
|
|
*/
|
|
|
|
LRESULT CALLBACK WindowProc(HWND hWnd,
|
|
|
|
UINT msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam)
|
|
|
|
{
|
2003-02-06 13:26:04 -05:00
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
switch (msg) {
|
|
|
|
// disable screen saver and monitor power down messages which wreak havoc
|
|
|
|
case WM_SYSCOMMAND:
|
|
|
|
{
|
|
|
|
switch (wParam) {
|
|
|
|
case SC_SCREENSAVE:
|
|
|
|
case SC_MONITORPOWER:
|
2003-02-06 13:26:04 -05:00
|
|
|
return 0L;
|
2002-08-11 07:49:32 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-02-07 16:54:31 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// default action
|
|
|
|
return DefWindowProc(hWnd, msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Sets the fullscreen display mode.
|
|
|
|
* Returns 1 for success and -1 for failure.
|
|
|
|
*/
|
|
|
|
int SetDisplayMode(int width, int height, int bpp, int freq)
|
|
|
|
{
|
2003-02-07 16:54:31 -05:00
|
|
|
// Set display mode using OpenGL friendly tactics
|
2002-08-11 07:49:32 -04:00
|
|
|
|
|
|
|
DEVMODE devmode;
|
|
|
|
devmode.dmSize = sizeof(DEVMODE);
|
|
|
|
devmode.dmBitsPerPel = bpp;
|
|
|
|
devmode.dmPelsWidth = width;
|
|
|
|
devmode.dmPelsHeight = height;
|
|
|
|
devmode.dmDisplayFlags = 0;
|
|
|
|
devmode.dmDisplayFrequency = freq;
|
2002-11-24 12:12:36 -05:00
|
|
|
devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS;
|
|
|
|
if (freq != 0)
|
|
|
|
devmode.dmFields |= DM_DISPLAYFREQUENCY;
|
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
|
|
|
|
LONG cdsret = ChangeDisplaySettings(&devmode, CDS_FULLSCREEN);
|
|
|
|
switch (cdsret) {
|
|
|
|
case DISP_CHANGE_BADFLAGS :
|
|
|
|
printf("Failed to set screen mode: bad flags\n");
|
|
|
|
return -1;
|
|
|
|
case DISP_CHANGE_FAILED:
|
|
|
|
printf("Failed to set screen mode: change failed\n");
|
|
|
|
return -1;
|
|
|
|
case DISP_CHANGE_BADMODE:
|
|
|
|
printf("Failed to set screen mode: bad mode\n");
|
|
|
|
return -1;
|
|
|
|
case DISP_CHANGE_SUCCESSFUL :
|
|
|
|
// Success!
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("Failed to set screen mode: unknown error\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Display
|
|
|
|
* Method: getAvailableDisplayModes
|
|
|
|
* Signature: ()[Lorg/lwjgl/DisplayMode;
|
|
|
|
*/
|
|
|
|
JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_Display_getAvailableDisplayModes
|
|
|
|
(JNIEnv * env, jclass clazz)
|
|
|
|
{
|
2002-08-24 17:19:06 -04:00
|
|
|
|
|
|
|
DEVMODE mode;
|
|
|
|
|
|
|
|
// First count the number of display modes.
|
|
|
|
int i = 0, n = 0;
|
|
|
|
while (EnumDisplaySettings(NULL, i ++, &mode) != 0) {
|
|
|
|
// Filter out indexed modes
|
2002-12-23 08:23:29 -05:00
|
|
|
if (mode.dmBitsPerPel <=8) {
|
2002-08-24 17:19:06 -04:00
|
|
|
continue;
|
|
|
|
} else
|
|
|
|
n ++;
|
|
|
|
}
|
|
|
|
|
2002-12-23 08:23:29 -05:00
|
|
|
|
2002-08-24 17:19:06 -04:00
|
|
|
// Allocate an array of DisplayModes big enough
|
|
|
|
jclass displayModeClass = env->FindClass("org/lwjgl/DisplayMode");
|
2002-12-22 14:52:44 -05:00
|
|
|
|
2002-12-23 08:23:29 -05:00
|
|
|
// Note the * 16 - this is because we are manufacturing available alpha/depth/stencil combos.
|
2002-12-22 15:31:22 -05:00
|
|
|
jobjectArray ret = env->NewObjectArray(n * 16, displayModeClass, NULL);
|
2002-12-22 14:52:44 -05:00
|
|
|
jmethodID displayModeConstructor = env->GetMethodID(displayModeClass, "<init>", "(IIIIIII)V");
|
2002-08-24 17:19:06 -04:00
|
|
|
|
|
|
|
i = n = 0;
|
|
|
|
while (EnumDisplaySettings(NULL, i ++, &mode) != 0) {
|
|
|
|
// Filter out indexed modes
|
2002-12-22 14:52:44 -05:00
|
|
|
if (mode.dmBitsPerPel <= 8) {
|
2002-08-24 17:19:06 -04:00
|
|
|
continue;
|
|
|
|
} else {
|
2002-12-22 14:52:44 -05:00
|
|
|
jobject displayMode;
|
|
|
|
|
|
|
|
for (int depthBits = 0; depthBits <= 24; depthBits += 8) {
|
|
|
|
for (int stencilBits = 0; stencilBits <= 8; stencilBits += 8) {
|
|
|
|
for (int alphaBits = 0; alphaBits <= 8; alphaBits += 8) {
|
|
|
|
|
|
|
|
displayMode = env->NewObject(displayModeClass, displayModeConstructor, mode.dmPelsWidth, mode.dmPelsHeight,
|
|
|
|
mode.dmBitsPerPel, mode.dmDisplayFrequency, alphaBits, depthBits, stencilBits);
|
|
|
|
|
|
|
|
env->SetObjectArrayElement(ret, n ++, displayMode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-08-24 17:19:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2002-08-11 07:49:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Display
|
|
|
|
* Method: nCreate
|
|
|
|
* Signature: (IIIIZ)Z
|
|
|
|
*/
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate
|
2002-12-19 11:35:35 -05:00
|
|
|
(JNIEnv * env, jclass clazz, jint width, jint height, jint bpp, jint freq,
|
2003-02-06 13:26:04 -05:00
|
|
|
jint alphaBits, jint depthBits, jint stencilBits, jboolean fullscreen, jstring title)
|
2002-08-11 07:49:32 -04:00
|
|
|
{
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Creating display: size %dx%d %dhz %dbpp...\n", width, height, freq, bpp);
|
|
|
|
#endif
|
2002-08-24 17:19:06 -04:00
|
|
|
if (fullscreen && SetDisplayMode(width, height, bpp, freq) != 1)
|
2002-08-11 07:49:32 -04:00
|
|
|
return JNI_FALSE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Register a window. This window does nothing, it's just a requirement that we get
|
|
|
|
a handle to it so we can do other things
|
|
|
|
*/
|
|
|
|
if (!oneShotInitialised) {
|
|
|
|
WNDCLASS windowClass;
|
|
|
|
|
|
|
|
windowClass.style = CS_GLOBALCLASS | CS_OWNDC;
|
|
|
|
windowClass.lpfnWndProc = WindowProc;
|
|
|
|
windowClass.cbClsExtra = 0;
|
|
|
|
windowClass.cbWndExtra = 0;
|
2002-12-18 11:40:12 -05:00
|
|
|
windowClass.hInstance = dll_handle;
|
2002-08-11 07:49:32 -04:00
|
|
|
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
2003-02-07 18:21:01 -05:00
|
|
|
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
2002-08-11 07:49:32 -04:00
|
|
|
windowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
|
|
|
windowClass.lpszMenuName = NULL;
|
|
|
|
windowClass.lpszClassName = WINDOWCLASSNAME;
|
|
|
|
|
|
|
|
if (RegisterClass(&windowClass) == 0) {
|
2002-12-14 10:23:53 -05:00
|
|
|
dumpLastError();
|
2002-08-11 07:49:32 -04:00
|
|
|
printf("Failed to register window class\n");
|
|
|
|
return JNI_FALSE;
|
|
|
|
}
|
|
|
|
oneShotInitialised = true;
|
|
|
|
}
|
|
|
|
|
2003-02-06 13:26:04 -05:00
|
|
|
int exstyle, windowflags;
|
2002-12-22 14:52:44 -05:00
|
|
|
|
|
|
|
if (fullscreen) {
|
2003-02-06 13:26:04 -05:00
|
|
|
exstyle = WS_EX_TOPMOST;
|
|
|
|
windowflags = WS_POPUP | WS_VISIBLE;
|
2002-12-22 14:52:44 -05:00
|
|
|
} else {
|
2003-02-06 13:26:04 -05:00
|
|
|
exstyle = 0;
|
2003-02-07 20:02:34 -05:00
|
|
|
windowflags = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU;
|
2002-12-22 14:52:44 -05:00
|
|
|
}
|
2003-02-07 16:54:31 -05:00
|
|
|
isFullscreen = fullscreen == JNI_TRUE;
|
2002-12-22 14:52:44 -05:00
|
|
|
|
2003-02-06 13:26:04 -05:00
|
|
|
const char* titleString = env->GetStringUTFChars(title, NULL);
|
|
|
|
|
2003-02-07 16:54:31 -05:00
|
|
|
// 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;
|
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
// Create the window now, using that class:
|
2003-02-06 13:26:04 -05:00
|
|
|
hwnd = CreateWindowEx (
|
|
|
|
exstyle,
|
|
|
|
WINDOWCLASSNAME,
|
|
|
|
titleString,
|
|
|
|
windowflags,
|
2003-02-07 16:54:31 -05:00
|
|
|
0, 0, clientSize.right, clientSize.bottom,
|
2003-02-06 13:26:04 -05:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
dll_handle,
|
|
|
|
NULL);
|
|
|
|
env->ReleaseStringUTFChars(title, titleString);
|
|
|
|
|
2003-02-07 20:02:34 -05:00
|
|
|
// Disable close button
|
|
|
|
HMENU SysMen = GetSystemMenu(hwnd, false);
|
|
|
|
EnableMenuItem(SysMen, SC_CLOSE, MF_BYCOMMAND | MF_DISABLED);
|
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
// And we never look at windowClass again...
|
|
|
|
|
2003-02-07 18:21:01 -05:00
|
|
|
ShowWindow(hwnd, SW_SHOWNORMAL);
|
2002-08-11 07:49:32 -04:00
|
|
|
UpdateWindow(hwnd);
|
2003-02-06 13:26:04 -05:00
|
|
|
SetForegroundWindow(hwnd);
|
|
|
|
SetFocus(hwnd);
|
2002-08-11 07:49:32 -04:00
|
|
|
|
|
|
|
hdc = GetWindowDC(hwnd);
|
|
|
|
|
|
|
|
// Success! Now you need to initialize a GL object, which creates a GL rendering context;
|
|
|
|
// and then to issue commands to it, you need to call gl::makeCurrent().
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Created display\n");
|
|
|
|
#endif
|
|
|
|
|
2003-02-07 16:54:31 -05:00
|
|
|
// Hide the mouse in fullscreen
|
|
|
|
if (fullscreen)
|
|
|
|
ShowCursor(FALSE);
|
|
|
|
|
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
|
|
|
|
// Create input
|
2002-08-17 10:13:12 -04:00
|
|
|
HRESULT ret = DirectInputCreate(GetModuleHandle(NULL), DIRECTINPUT_VERSION, &lpdi, NULL);
|
2002-08-11 07:49:32 -04:00
|
|
|
if (ret != DI_OK && ret != DIERR_BETADIRECTINPUTVERSION ) {
|
2002-08-17 10:13:12 -04:00
|
|
|
printf("Failed to create directinput");
|
|
|
|
switch (ret) {
|
|
|
|
case DIERR_BETADIRECTINPUTVERSION :
|
2002-12-19 11:35:35 -05:00
|
|
|
printf(" - Beta version\n");
|
2002-08-17 10:13:12 -04:00
|
|
|
break;
|
|
|
|
case DIERR_INVALIDPARAM :
|
|
|
|
printf(" - Invalid parameter\n");
|
|
|
|
break;
|
|
|
|
case DIERR_OLDDIRECTINPUTVERSION :
|
|
|
|
printf(" - Old Version\n");
|
|
|
|
break;
|
|
|
|
case DIERR_OUTOFMEMORY :
|
|
|
|
printf(" - Out Of Memory\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("\n");
|
|
|
|
}
|
2002-12-19 11:35:35 -05:00
|
|
|
destroyWindow();
|
|
|
|
return JNI_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int flags = PFD_DRAW_TO_WINDOW | // support window
|
|
|
|
PFD_SUPPORT_OPENGL | // support OpenGL
|
|
|
|
PFD_GENERIC_ACCELERATED |
|
|
|
|
PFD_DOUBLEBUFFER; // double buffered
|
|
|
|
|
|
|
|
PIXELFORMATDESCRIPTOR pfd = {
|
|
|
|
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
|
|
|
|
1, // version number
|
|
|
|
flags, // RGBA type
|
|
|
|
PFD_TYPE_RGBA,
|
|
|
|
(BYTE)bpp,
|
|
|
|
0, 0, 0, 0, 0, 0, // color bits ignored
|
|
|
|
(BYTE)alphaBits,
|
|
|
|
0, // shift bit ignored
|
|
|
|
0, // no accumulation buffer
|
|
|
|
0, 0, 0, 0, // accum bits ignored
|
|
|
|
(BYTE)depthBits,
|
|
|
|
(BYTE)stencilBits,
|
2002-12-22 14:52:44 -05:00
|
|
|
0, // No auxiliary buffer
|
2002-12-19 11:35:35 -05:00
|
|
|
PFD_MAIN_PLANE, // main layer
|
|
|
|
0, // reserved
|
|
|
|
0, 0, 0 // layer masks ignored
|
|
|
|
};
|
|
|
|
|
|
|
|
// Ensure desktop color depth is adequate
|
|
|
|
int availableBitDepth = GetDeviceCaps(hdc, BITSPIXEL);
|
|
|
|
if (availableBitDepth < bpp) {
|
|
|
|
printf("This application requires a greater colour depth.\n");
|
|
|
|
destroyAll();
|
|
|
|
return JNI_FALSE;
|
|
|
|
};
|
|
|
|
|
|
|
|
int iPixelFormat;
|
|
|
|
|
|
|
|
// get the best available match of pixel format for the device context
|
|
|
|
iPixelFormat = ChoosePixelFormat(hdc, &pfd);
|
|
|
|
if (iPixelFormat == 0) {
|
|
|
|
printf("Failed to choose pixel format.\n");
|
|
|
|
destroyAll();
|
|
|
|
return JNI_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PIXELFORMATDESCRIPTOR desc;
|
|
|
|
if (DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &desc) == 0) {
|
|
|
|
printf("Could not describe pixel format\n");
|
|
|
|
destroyAll();
|
|
|
|
return JNI_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (desc.cColorBits < bpp) {
|
|
|
|
printf("This application requires a greater colour depth.\n");
|
|
|
|
destroyAll();
|
|
|
|
return JNI_FALSE;
|
2003-01-31 14:04:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (desc.cAlphaBits < alphaBits) {
|
|
|
|
printf("This application requires a greater alpha depth.\n");
|
|
|
|
destroyAll();
|
|
|
|
return JNI_FALSE;
|
2002-12-19 11:35:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (desc.cStencilBits < stencilBits) {
|
|
|
|
printf("This application requires a greater stencil depth.\n");
|
|
|
|
destroyAll();
|
|
|
|
return JNI_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (desc.cDepthBits < depthBits) {
|
|
|
|
printf("This application requires a greater depth buffer depth.\n");
|
|
|
|
destroyAll();
|
|
|
|
return JNI_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((desc.dwFlags & flags) == 0) {
|
|
|
|
printf("Capabilities not supported.\n");
|
|
|
|
destroyAll();
|
|
|
|
return JNI_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Pixel format is %d\n", iPixelFormat);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// make that the pixel format of the device context
|
|
|
|
if (SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE) {
|
|
|
|
printf("Failed to set pixel format\n");
|
|
|
|
destroyAll();
|
2002-08-11 07:49:32 -04:00
|
|
|
return JNI_FALSE;
|
|
|
|
}
|
|
|
|
|
2002-08-17 10:13:12 -04:00
|
|
|
jfieldID fid_handle = env->GetStaticFieldID(clazz, "handle", "I");
|
|
|
|
env->SetStaticIntField(clazz, fid_handle, (jint) hwnd);
|
|
|
|
|
2002-08-11 07:49:32 -04:00
|
|
|
return JNI_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Display
|
|
|
|
* Method: nDestroy
|
|
|
|
* Signature: ()V
|
|
|
|
*/
|
|
|
|
JNIEXPORT void JNICALL Java_org_lwjgl_Display_nDestroy
|
|
|
|
(JNIEnv * env, jclass clazz)
|
|
|
|
{
|
2002-12-19 11:35:35 -05:00
|
|
|
destroyAll();
|
2002-08-11 07:49:32 -04:00
|
|
|
}
|
2002-12-19 11:35:35 -05:00
|
|
|
|
2003-02-07 16:54:31 -05:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|