lwjgl2-arm64/src/native/macosx/org_lwjgl_opengl_Window.cpp
2003-10-06 14:00:44 +00:00

292 lines
8.9 KiB
C++

/*
* 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 OSX functionality for GL.
*
* @author Elias Naur <elias_naur@sourceforge.net>
* @version $Revision$
*/
#include "Window.h"
#include <QuickTime/Movies.h>
#include "org_lwjgl_opengl_Window.h"
#include "extgl.h"
#include "tools.h"
static WindowRef win_ref;
static AGLContext context;
static bool close_requested;
static Ptr fullscreen_ptr;
static bool current_fullscreen;
static bool miniaturized;
static bool activated;
static void setWindowTitle(JNIEnv *env, jstring title_obj) {
const char* title = env->GetStringUTFChars(title_obj, NULL);
CFStringRef cf_title = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
if (cf_title == NULL) {
#ifdef _DEBUG
printf("Could not set window title\n");
#endif
return;
}
SetWindowTitleWithCFString(win_ref, cf_title);
CFRelease(cf_title);
env->ReleaseStringUTFChars(title_obj, title);
}
void setQuitRequested(void) {
lock();
close_requested = true;
unlock();
}
static pascal OSStatus doMiniaturized(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
lock();
miniaturized = true;
unlock();
return noErr;
}
static pascal OSStatus doMaximize(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
lock();
miniaturized = false;
unlock();
return noErr;
}
static pascal OSStatus doActivate(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
lock();
miniaturized = false;
activated = true;
unlock();
return noErr;
}
static pascal OSStatus doDeactivate(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
lock();
activated = false;
unlock();
return noErr;
}
static pascal OSStatus doQuit(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
setQuitRequested();
return noErr;
}
static bool registerWindowHandler(JNIEnv* env, EventHandlerProcPtr func, UInt32 event_kind) {
EventTypeSpec event_type;
OSStatus err;
EventHandlerUPP handler_upp = NewEventHandlerUPP(func);
event_type.eventClass = kEventClassWindow;
event_type.eventKind = event_kind;
err = InstallWindowEventHandler(win_ref, handler_upp, 1, &event_type, NULL, NULL);
DisposeEventHandlerUPP(handler_upp);
if (noErr != err) {
throwException(env, "Could not register window event handler");
return true;
}
return false;
}
static bool registerEventHandlers(JNIEnv *env) {
bool error;
error = registerWindowHandler(env, doQuit, kEventWindowClose);
error = error || registerWindowHandler(env, doActivate, kEventWindowActivated);
error = error || registerWindowHandler(env, doDeactivate, kEventWindowDeactivated);
error = error || registerWindowHandler(env, doMiniaturized, kEventWindowCollapsed);
error = error || registerWindowHandler(env, doMaximize, kEventWindowExpanded);
if (error)
return false;
else
return registerKeyboardHandler(env, win_ref);
}
static void destroyWindow(void) {
if (current_fullscreen)
EndFullScreen(fullscreen_ptr, 0);
else
DisposeWindow(win_ref);
}
static void destroy(void) {
destroyLock();
aglSetCurrentContext(NULL);
aglDestroyContext(context);
destroyWindow();
extgl_Close();
}
static bool createContext(JNIEnv *env, jint bpp, jint alpha, jint depth, jint stencil) {
AGLDrawable drawable = GetWindowPort(win_ref);
SetPort(drawable);
GLint attrib[] = {AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_ACCELERATED,
AGL_NO_RECOVERY,
AGL_MINIMUM_POLICY,
AGL_PIXEL_SIZE, bpp,
AGL_DEPTH_SIZE, depth,
AGL_ALPHA_SIZE, alpha,
AGL_STENCIL_SIZE, stencil,
AGL_NONE};
AGLPixelFormat format = aglChoosePixelFormat(NULL, 0, attrib);
if (format == NULL) {
throwException(env, "Could not find matching pixel format");
return false;
}
context = aglCreateContext (format, NULL);
aglDestroyPixelFormat(format);
if (context == NULL) {
throwException(env, "Could not create context");
return false;
}
if (aglSetDrawable(context, drawable) == GL_FALSE) {
aglDestroyContext(context);
throwException(env, "Could not attach context");
return false;
}
if (aglSetCurrentContext(context) == GL_FALSE) {
aglDestroyContext(context);
throwException(env, "Could not set current context");
return false;
}
return true;
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsCloseRequested(JNIEnv *, jclass) {
lock();
const bool saved = close_requested;
close_requested = false;
unlock();
return saved;
}
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, jobject ext_set) {
Rect rect;
OSStatus status;
const WindowAttributes window_attr = kWindowCloseBoxAttribute|
kWindowCollapseBoxAttribute|
kWindowStandardHandlerAttribute;
SetRect(&rect, x, y, x + width, y + height);
current_fullscreen = fullscreen == JNI_TRUE;
miniaturized = false;
activated = true;
close_requested = false;
if (!extgl_Open()) {
throwException(env, "Could not load gl library");
return;
}
if (!extgl_InitAGL(env, ext_set)) {
throwException(env, "Could not load agl symbols");
return;
}
if (current_fullscreen)
status = BeginFullScreen(&fullscreen_ptr, NULL, 0, 0, &win_ref, NULL, 0);
else
status = CreateNewWindow(kDocumentWindowClass, window_attr, &rect, &win_ref);
if (noErr != status) {
extgl_Close();
throwException(env, "Could not create window");
return;
}
if (!registerEventHandlers(env)) {
destroyWindow();
extgl_Close();
return;
}
if (!initLock(env)) {
destroyWindow();
extgl_Close();
return;
}
setWindowTitle(env, title);
const RGBColor background_color = {0, 0, 0};
SetWindowContentColor(win_ref, &background_color);
if (!createContext(env, bpp, alpha, depth, stencil)) {
destroyLock();
destroyWindow();
extgl_Close();
return;
}
if (!extgl_Initialize(env, ext_set)) {
destroy();
throwException(env, "Could not load gl function pointers");
return;
}
ShowWindow(win_ref);
SelectWindow(win_ref);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nSetTitle(JNIEnv * env, jclass clazz, jstring title_obj) {
setWindowTitle(env, title_obj);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_update(JNIEnv *env, jclass clazz) {
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_swapBuffers(JNIEnv * env, jclass clazz) {
aglSwapBuffers(context);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_minimize(JNIEnv *env, jclass clazz) {
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_restore(JNIEnv *env, jclass clazz) {
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nDestroy(JNIEnv *env, jclass clazz) {
destroy();
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsFocused(JNIEnv *env, jclass clazz) {
lock();
bool result = activated;
unlock();
return result;
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsDirty(JNIEnv *env, jclass clazz) {
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Window_nIsMinimized(JNIEnv *env, jclass clazz) {
lock();
bool result = miniaturized;
unlock();
return result;
}