2003-08-04 06:09:40 -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.
|
|
|
|
*
|
|
|
|
* * 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.
|
|
|
|
*
|
|
|
|
* * 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$
|
|
|
|
*
|
|
|
|
* Base Win32 window
|
|
|
|
*
|
|
|
|
* @author cix_foo <cix_foo@users.sourceforge.net>
|
|
|
|
* @version $Revision$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define _PRIVATE_WINDOW_H_
|
|
|
|
#include "Window.h"
|
|
|
|
#include "org_lwjgl_opengl_Window.h"
|
|
|
|
|
|
|
|
bool oneShotInitialised = false; // Registers the LWJGL window class
|
|
|
|
HWND hwnd = NULL; // Handle to the window
|
|
|
|
HDC hdc = NULL; // Device context
|
|
|
|
HGLRC hglrc = NULL; // OpenGL context
|
|
|
|
LPDIRECTINPUT lpdi = NULL; // DirectInput
|
|
|
|
bool isFullScreen = false; // Whether we're fullscreen or not
|
|
|
|
bool isMinimized = false; // Whether we're minimized or not
|
|
|
|
/*JNIEnv * environment = NULL; // Cached environment
|
|
|
|
jclass window; // Cached Java Window class*/
|
|
|
|
extern HINSTANCE dll_handle; // Handle to the LWJGL dll
|
|
|
|
RECT clientSize;
|
|
|
|
|
|
|
|
static bool closerequested;
|
|
|
|
static bool minimized;
|
|
|
|
static bool focused;
|
|
|
|
static bool dirty;
|
|
|
|
|
|
|
|
//CAS: commented these out as no longer used
|
|
|
|
//extern void tempRestoreDisplayMode();
|
|
|
|
//extern void tempResetDisplayMode();
|
|
|
|
|
|
|
|
#define WINDOWCLASSNAME "LWJGL"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Utility function to throw an Exception
|
|
|
|
*/
|
|
|
|
void throwException(JNIEnv * env, const char * err)
|
|
|
|
{
|
|
|
|
jclass cls = env->FindClass("java/lang/Exception");
|
|
|
|
env->ThrowNew(cls, err);
|
|
|
|
env->DeleteLocalRef(cls);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Utility function to throw a RuntimeException
|
|
|
|
*/
|
|
|
|
void throwRuntimeException(JNIEnv * env, const char * err)
|
|
|
|
{
|
|
|
|
jclass cls = env->FindClass("java/lang/RuntimeException");
|
|
|
|
env->ThrowNew(cls, err);
|
|
|
|
env->DeleteLocalRef(cls);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Find an appropriate pixel format
|
|
|
|
*/
|
|
|
|
static int findPixelFormat(JNIEnv *env, unsigned int flags, int bpp, int alpha, int depth, int stencil)
|
|
|
|
{
|
|
|
|
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)alpha,
|
|
|
|
0, // shift bit ignored
|
|
|
|
0, // no accumulation buffer
|
|
|
|
0, 0, 0, 0, // accum bits ignored
|
|
|
|
(BYTE)depth,
|
|
|
|
(BYTE)stencil,
|
|
|
|
0, // No auxiliary buffer
|
|
|
|
PFD_MAIN_PLANE, // main layer
|
|
|
|
0, // reserved
|
|
|
|
0, 0, 0 // layer masks ignored
|
|
|
|
};
|
|
|
|
|
|
|
|
// get the best available match of pixel format for the device context
|
|
|
|
int iPixelFormat = ChoosePixelFormat(hdc, &pfd);
|
|
|
|
if (iPixelFormat == 0) {
|
|
|
|
throwException(env, "Failed to choose pixel format");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#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");
|
|
|
|
throwException(env, "Failed to choose pixel format");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3. Check the chosen format matches or exceeds our specifications
|
|
|
|
PIXELFORMATDESCRIPTOR desc;
|
|
|
|
if (DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &desc) == 0) {
|
|
|
|
throwException(env, "Could not describe pixel format");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (desc.cColorBits < bpp) {
|
|
|
|
throwException(env, "This application requires a greater colour depth");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (desc.cAlphaBits < alpha) {
|
|
|
|
throwException(env, "This application requires a greater alpha depth");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (desc.cStencilBits < stencil) {
|
|
|
|
throwException(env, "This application requires a greater stencil depth");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (desc.cDepthBits < depth) {
|
|
|
|
throwException(env, "This application requires a greater depth buffer depth");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((desc.dwFlags & PFD_GENERIC_FORMAT) != 0 || (desc.dwFlags & PFD_GENERIC_ACCELERATED) != 0) {
|
|
|
|
throwException(env, "Mode not supported by hardware");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((desc.dwFlags & flags) != flags) {
|
|
|
|
throwException(env, "Capabilities not supported");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 4. Initialise other things now
|
|
|
|
if (extgl_Open() != 0) {
|
|
|
|
throwException(env, "Failed to open extgl");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return iPixelFormat;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Create DirectInput.
|
|
|
|
* Returns true for success, or false for failure
|
|
|
|
*/
|
|
|
|
static bool createDirectInput()
|
|
|
|
{
|
|
|
|
// Create input
|
|
|
|
HRESULT ret = DirectInputCreate(dll_handle, DIRECTINPUT_VERSION, &lpdi, NULL);
|
|
|
|
if (ret != DI_OK && ret != DIERR_BETADIRECTINPUTVERSION ) {
|
|
|
|
printf("Failed to create directinput");
|
|
|
|
switch (ret) {
|
|
|
|
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(" - Unknown failure\n");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Close the window
|
|
|
|
*/
|
|
|
|
static void closeWindow()
|
|
|
|
{
|
|
|
|
// Release DirectInput
|
|
|
|
if (lpdi != NULL) {
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Destroying directinput\n");
|
|
|
|
#endif
|
|
|
|
lpdi->Release();
|
|
|
|
lpdi = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release device context
|
|
|
|
if (hdc != NULL && hwnd != NULL) {
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Releasing DC\n");
|
|
|
|
#endif
|
|
|
|
ReleaseDC(hwnd, hdc);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close the window
|
|
|
|
if (hwnd != NULL) {
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Destroy window\n");
|
|
|
|
#endif
|
|
|
|
// Vape the window
|
|
|
|
DestroyWindow(hwnd);
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Destroyed window\n");
|
|
|
|
#endif
|
|
|
|
hwnd = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Called when the application is alt-tabbed to or from
|
|
|
|
*/
|
|
|
|
static void appActivate(bool active)
|
|
|
|
{
|
|
|
|
// if (!active) {
|
|
|
|
// tempResetDisplayMode();
|
|
|
|
// }
|
|
|
|
if (active) {
|
|
|
|
SetForegroundWindow(hwnd);
|
|
|
|
ShowWindow(hwnd, SW_RESTORE);
|
|
|
|
} else if (isFullScreen) {
|
|
|
|
ShowWindow(hwnd, SW_MINIMIZE);
|
|
|
|
}
|
|
|
|
// if (active) {
|
|
|
|
// tempRestoreDisplayMode();
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* WindowProc for the GL window.
|
|
|
|
*/
|
|
|
|
LRESULT CALLBACK lwjglWindowProc(HWND hWnd,
|
|
|
|
UINT msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch (msg) {
|
|
|
|
// disable screen saver and monitor power down messages which wreak havoc
|
|
|
|
case WM_SYSCOMMAND:
|
|
|
|
{
|
|
|
|
switch (wParam) {
|
|
|
|
case SC_SCREENSAVE:
|
|
|
|
case SC_MONITORPOWER:
|
|
|
|
return 0L;
|
|
|
|
case SC_MINIMIZE:
|
|
|
|
minimized = true;
|
|
|
|
appActivate(false);
|
|
|
|
break;
|
|
|
|
case SC_RESTORE:
|
|
|
|
minimized = false;
|
|
|
|
appActivate(true);
|
|
|
|
break;
|
|
|
|
case SC_CLOSE:
|
|
|
|
closerequested = true;
|
|
|
|
//don't continue processing this command since this
|
|
|
|
//would shutdown the window, which the application might not want to
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_ACTIVATE:
|
|
|
|
{
|
|
|
|
switch(LOWORD(wParam)) {
|
|
|
|
case WA_ACTIVE:
|
|
|
|
case WA_CLICKACTIVE:
|
|
|
|
minimized = false;
|
|
|
|
isMinimized = false;
|
|
|
|
|
|
|
|
break;
|
|
|
|
case WA_INACTIVE:
|
|
|
|
minimized = true;
|
|
|
|
isMinimized = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
appActivate(!isMinimized);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_QUIT:
|
|
|
|
{
|
|
|
|
closerequested = true;
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
case WM_PAINT:
|
|
|
|
{
|
|
|
|
dirty = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// default action
|
|
|
|
return DefWindowProc(hWnd, msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Register the LWJGL window class.
|
|
|
|
* Returns true for success, or false for failure
|
|
|
|
*/
|
|
|
|
static bool registerWindow()
|
|
|
|
{
|
|
|
|
if (!oneShotInitialised) {
|
|
|
|
WNDCLASS windowClass;
|
|
|
|
|
|
|
|
windowClass.style = CS_GLOBALCLASS | CS_OWNDC;
|
|
|
|
windowClass.lpfnWndProc = lwjglWindowProc;
|
|
|
|
windowClass.cbClsExtra = 0;
|
|
|
|
windowClass.cbWndExtra = 0;
|
|
|
|
windowClass.hInstance = dll_handle;
|
|
|
|
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
|
|
|
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
windowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
|
|
|
windowClass.lpszMenuName = NULL;
|
|
|
|
windowClass.lpszClassName = WINDOWCLASSNAME;
|
|
|
|
|
|
|
|
if (RegisterClass(&windowClass) == 0) {
|
|
|
|
printf("Failed to register window class\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Window registered\n");
|
|
|
|
#endif
|
|
|
|
oneShotInitialised = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Handle native Win32 messages
|
|
|
|
*/
|
|
|
|
static void handleMessages(JNIEnv * env, jclass clazz)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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_REMOVE // removal options
|
|
|
|
))
|
|
|
|
{
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a window with the specified title, position, size, and
|
|
|
|
* fullscreen attribute. The window will have DirectInput associated
|
|
|
|
* with it.
|
|
|
|
*
|
|
|
|
* Returns true for success, or false for failure
|
|
|
|
*/
|
|
|
|
static bool createWindow(const char * title, int x, int y, int width, int height, bool fullscreen)
|
|
|
|
{
|
|
|
|
// 1. Register window class if necessary
|
|
|
|
if (!registerWindow())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// 2. Create the window
|
|
|
|
int exstyle, windowflags;
|
|
|
|
|
|
|
|
if (fullscreen) {
|
|
|
|
exstyle = WS_EX_APPWINDOW | WS_EX_TOPMOST;
|
|
|
|
windowflags = WS_POPUP | WS_VISIBLE;
|
|
|
|
} else {
|
|
|
|
exstyle = WS_EX_APPWINDOW;
|
|
|
|
windowflags = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we're not a fullscreen window, adjust the height to account for the
|
|
|
|
// height of the title bar:
|
|
|
|
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
|
|
|
|
);
|
|
|
|
|
|
|
|
// Create the window now, using that class:
|
|
|
|
hwnd = CreateWindowEx (
|
|
|
|
exstyle,
|
|
|
|
WINDOWCLASSNAME,
|
|
|
|
title,
|
|
|
|
windowflags,
|
|
|
|
x, y, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
dll_handle,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (hwnd == NULL) {
|
|
|
|
printf("Failed to create window\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Created window\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// ShowWindow(hwnd, SW_SHOWNORMAL);
|
|
|
|
ShowWindow(hwnd, SW_SHOW);
|
|
|
|
UpdateWindow(hwnd);
|
|
|
|
SetForegroundWindow(hwnd);
|
|
|
|
SetFocus(hwnd);
|
|
|
|
|
|
|
|
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().
|
|
|
|
|
|
|
|
// 3. Hide the mouse if necessary
|
|
|
|
isFullScreen = fullscreen == JNI_TRUE;
|
|
|
|
|
|
|
|
// 4. Create DirectInput
|
|
|
|
if (!createDirectInput()) {
|
|
|
|
// Close the window
|
|
|
|
closeWindow();
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Window
|
|
|
|
* Method: nSetTitle
|
|
|
|
* Signature: ()V
|
|
|
|
*/
|
|
|
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetTitle
|
|
|
|
(JNIEnv * env, jclass clazz, jstring title_obj)
|
|
|
|
{
|
|
|
|
const char * title = env->GetStringUTFChars(title_obj, NULL);
|
|
|
|
SetWindowText(hwnd, title);
|
|
|
|
env->ReleaseStringUTFChars(title_obj, title);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Window
|
|
|
|
* Method: tick
|
|
|
|
* Signature: ()V
|
|
|
|
*/
|
|
|
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_tick
|
|
|
|
(JNIEnv * env, jclass clazz)
|
|
|
|
{
|
|
|
|
handleMessages(env, clazz);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Window
|
|
|
|
* Method: minimize
|
|
|
|
* Signature: ()V
|
|
|
|
*/
|
|
|
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_minimize
|
|
|
|
(JNIEnv * env, jclass clazz)
|
|
|
|
{
|
|
|
|
if (isMinimized)
|
|
|
|
return;
|
|
|
|
ShowWindow(hwnd, SW_MINIMIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Window
|
|
|
|
* Method: minimize
|
|
|
|
* Signature: ()V
|
|
|
|
*/
|
|
|
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_restore
|
|
|
|
(JNIEnv * env, jclass clazz)
|
|
|
|
{
|
|
|
|
if (!isMinimized)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ShowWindow(hwnd, SW_RESTORE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Window
|
|
|
|
* Method: swapBuffers
|
|
|
|
* Signature: ()V
|
|
|
|
*/
|
|
|
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_swapBuffers
|
|
|
|
(JNIEnv * env, jclass clazz)
|
|
|
|
{
|
|
|
|
dirty = false;
|
|
|
|
wglSwapLayerBuffers(hdc, WGL_SWAP_MAIN_PLANE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Window
|
|
|
|
* Method: nCreate
|
|
|
|
* Signature: (Ljava/lang/String;IIIIZIIII)V
|
|
|
|
*/
|
|
|
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nCreate
|
|
|
|
(JNIEnv * env, jclass clazz, jstring title, jint x, jint y, jint width, jint height, jboolean fullscreen, jint bpp, jint alpha, jint depth, jint stencil)
|
|
|
|
{
|
|
|
|
closerequested = false;
|
|
|
|
minimized = false;
|
|
|
|
focused = true;
|
|
|
|
dirty = true;
|
|
|
|
|
|
|
|
// 1. Create a window
|
|
|
|
const char * titleString = env->GetStringUTFChars(title, NULL);
|
|
|
|
if (!createWindow(titleString, x, y, width, height, fullscreen == JNI_TRUE ? true : false)) {
|
|
|
|
env->ReleaseStringUTFChars((jstring) title, titleString);
|
|
|
|
closeWindow();
|
|
|
|
throwException(env, "Failed to create the window.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
env->ReleaseStringUTFChars(title, titleString);
|
|
|
|
|
|
|
|
// 2. Choose a pixel format and set it
|
|
|
|
unsigned int flags = PFD_DRAW_TO_WINDOW | // support window
|
|
|
|
PFD_SUPPORT_OPENGL | // support OpenGL
|
|
|
|
PFD_DOUBLEBUFFER; // double buffered
|
|
|
|
|
|
|
|
int iPixelFormat = findPixelFormat(env, flags, bpp, alpha, depth, stencil);
|
|
|
|
if (iPixelFormat == -1) {
|
|
|
|
closeWindow();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Create a rendering context
|
|
|
|
hglrc = wglCreateContext(hdc);
|
|
|
|
if (hglrc == NULL) {
|
|
|
|
throwException(env, "Failed to create OpenGL rendering context");
|
|
|
|
closeWindow();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Automatically make it the current context
|
|
|
|
wglMakeCurrent(hdc, hglrc);
|
|
|
|
|
|
|
|
// Initialise GL extensions
|
|
|
|
if (extgl_Initialize() != 0) {
|
|
|
|
closeWindow();
|
|
|
|
throwException(env, "Failed to initialize GL extensions");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_Window
|
|
|
|
* Method: doDestroy
|
|
|
|
* Signature: ()V
|
|
|
|
*/
|
|
|
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nDestroy
|
|
|
|
(JNIEnv * env, jclass clazz)
|
|
|
|
{
|
|
|
|
wglMakeCurrent(NULL, NULL);
|
|
|
|
|
|
|
|
// Delete the rendering context
|
|
|
|
if (hglrc != NULL) {
|
|
|
|
#ifdef _DEBUG
|
|
|
|
printf("Delete GL context\n");
|
|
|
|
#endif
|
|
|
|
wglDeleteContext(hglrc);
|
|
|
|
hglrc = NULL;
|
|
|
|
}
|
|
|
|
closeWindow();
|
|
|
|
extgl_Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_opengl_Window
|
|
|
|
* Method: nIsDirty
|
|
|
|
* Signature: ()Z
|
|
|
|
*/
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsDirty
|
|
|
|
(JNIEnv *env, jclass clazz) {
|
|
|
|
return dirty;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_opengl_Window
|
|
|
|
* Method: nIsMinimized
|
|
|
|
* Signature: ()Z
|
|
|
|
*/
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsMinimized
|
|
|
|
(JNIEnv *env, jclass clazz) {
|
|
|
|
return minimized;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_opengl_Window
|
|
|
|
* Method: nIsCloseRequested
|
|
|
|
* Signature: ()Z
|
|
|
|
*/
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsCloseRequested
|
|
|
|
(JNIEnv *, jclass) {
|
|
|
|
bool saved = closerequested;
|
|
|
|
closerequested = false;
|
|
|
|
return saved;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Class: org_lwjgl_opengl_Window
|
|
|
|
* Method: nIsFocused
|
|
|
|
* Signature: ()Z
|
|
|
|
*/
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsFocused
|
|
|
|
(JNIEnv *env, jclass clazz) {
|
|
|
|
return focused;
|
|
|
|
}
|