Changed: #947 adapted to recent driver changes, some cleanup

This commit is contained in:
rti 2010-06-23 23:37:19 +02:00
parent a362e280ca
commit 60dae3bfd0
6 changed files with 294 additions and 211 deletions

View file

@ -45,7 +45,10 @@
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
typedef HWND nlWindow; typedef HWND nlWindow;
#define EmptyWindow NULL #define EmptyWindow NULL
#else #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
typedef void* nlWindow;
#define EmptyWindow NULL
#elif defined(NL_OS_UNIX)
typedef int nlWindow; typedef int nlWindow;
#define EmptyWindow 0 #define EmptyWindow 0
#endif #endif

View file

@ -867,7 +867,7 @@ bool CDriverGL::swapBuffers()
SwapBuffers(_hDC); SwapBuffers(_hDC);
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::swapBuffers(); NL3D::MAC::swapBuffers(_win);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
glXSwapBuffers(_dpy, _win); glXSwapBuffers(_dpy, _win);
@ -972,9 +972,11 @@ bool CDriverGL::release()
void CDriverGL::setupViewport (const class CViewport& viewport) void CDriverGL::setupViewport (const class CViewport& viewport)
{ {
H_AUTO_OGL(CDriverGL_setupViewport ) H_AUTO_OGL(CDriverGL_setupViewport )
#ifdef NL_OS_WINDOWS
if (_win == EmptyWindow) return; if (_win == EmptyWindow) return;
#ifdef NL_OS_WINDOWS
// Setup gl viewport // Setup gl viewport
int clientWidth = _WindowWidth; int clientWidth = _WindowWidth;
int clientHeight = _WindowHeight; int clientHeight = _WindowHeight;
@ -982,7 +984,7 @@ void CDriverGL::setupViewport (const class CViewport& viewport)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
uint32 clientWidth, clientHeight; uint32 clientWidth, clientHeight;
NL3D::MAC::getWindowSize(clientWidth, clientHeight); NL3D::MAC::getWindowSize(_win, clientWidth, clientHeight);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1052,11 +1054,11 @@ void CDriverGL::setupScissor (const class CScissor& scissor)
int clientHeight = _WindowHeight; int clientHeight = _WindowHeight;
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
# warning "OpenGL Driver: Missing Mac Implementation"
// nlwarning("OpenGL Driver: Temporary Mac Implementation");
int clientWidth = 1024; uint32 clientWidth = 0;
int clientHeight = 768; uint32 clientHeight = 0;
getWindowSize(clientWidth, clientHeight);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)

View file

@ -132,7 +132,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
return trapMessage ? 0 : DefWindowProcW(hWnd, message, wParam, lParam); return trapMessage ? 0 : DefWindowProcW(hWnd, message, wParam, lParam);
} }
#endif // NL_OS_UNIX #endif // NL_OS_WINDOWS
// *************************************************************************** // ***************************************************************************
bool CDriverGL::init (uint windowIcon, emptyProc exitFunc) bool CDriverGL::init (uint windowIcon, emptyProc exitFunc)
@ -182,7 +182,11 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc)
retrieveATIDriverVersion(); retrieveATIDriverVersion();
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
return NL3D::MAC::init(windowIcon, exitFunc); if(!NL3D::MAC::init(windowIcon, exitFunc))
{
nldebug("cannot init");
return false;
}
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -249,7 +253,11 @@ bool CDriverGL::unInit()
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::release(); if(!NL3D::MAC::unInit())
{
nldebug("cannot uninit");
return false;
}
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -635,7 +643,10 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::setDisplay(wnd, mode, show, resizeable); _win = NL3D::MAC::setDisplay(wnd, mode, show, resizeable);
if(_win != EmptyWindow)
_DestroyWindow = true;
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -739,6 +750,10 @@ bool CDriverGL::saveScreenMode()
// don't need to save it because Windows will use default desktop resolution // don't need to save it because Windows will use default desktop resolution
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
// no need to store because the screen mode is never really changed
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
#if defined(XF86VIDMODE) #if defined(XF86VIDMODE)
@ -766,6 +781,11 @@ bool CDriverGL::restoreScreenMode()
res = (ChangeDisplaySettings(NULL, 0) == DISP_CHANGE_SUCCESSFUL); res = (ChangeDisplaySettings(NULL, 0) == DISP_CHANGE_SUCCESSFUL);
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
// no need to restore because the screen mode was never really changed
res = true;
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
#if defined(XF86VIDMODE) #if defined(XF86VIDMODE)
@ -856,7 +876,7 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
// TODO // no need to do anything here, on mac os, the screen mode is never changed
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
@ -918,7 +938,13 @@ bool CDriverGL::createWindow(const GfxMode &mode)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
// TODO window = NL3D::MAC::createWindow(mode);
if(window == EmptyWindow)
{
nldebug("cannot create window");
return false;
}
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -986,7 +1012,14 @@ bool CDriverGL::destroyWindow()
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
// TODO if(_DestroyWindow)
{
if(!NL3D::MAC::destroyWindow(_win))
{
nldebug("cannot destroy window");
return false;
}
}
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1072,6 +1105,14 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
// else if (isMaximized && isVisible) // else if (isMaximized && isVisible)
// ShowWindow(_hWnd, SW_RESTORE); // ShowWindow(_hWnd, SW_RESTORE);
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
if(!NL3D::MAC::setWindowStyle(_win, windowStyle == EWSFullscreen))
{
nldebug("cannot set window style");
return false;
}
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
XSetWindowAttributes attr; XSetWindowAttributes attr;
@ -1129,7 +1170,7 @@ bool CDriverGL::setMode(const GfxMode& mode)
return false; return false;
// when changing window style, it's possible system change window size too // when changing window style, it's possible system change window size too
setWindowStyle(mode.Windowed ? EWSWindowed:EWSFullscreen); setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen);
_WindowWidth = mode.Width; _WindowWidth = mode.Width;
_WindowHeight = mode.Height; _WindowHeight = mode.Height;
@ -1139,17 +1180,11 @@ bool CDriverGL::setMode(const GfxMode& mode)
_FullScreen = !mode.Windowed; _FullScreen = !mode.Windowed;
#if defined(NL_OS_MAC) #if defined(NL_OS_MAC) && !defined(NL_MAC_NATIVE)
#if defined(NL_MAC_NATIVE)
NL3D::MAC::setMode(mode);
#else
// X11 under Mac OS can't use fullscreen // X11 under Mac OS can't use fullscreen
_FullScreen = false; _FullScreen = false;
#endif // NL_MAC_NATIVE #endif // NL_MAC_NATIVE
#endif // NL_OS_MAC
setWindowSize(mode.Width, mode.Height); setWindowSize(mode.Width, mode.Height);
return true; return true;
@ -1239,7 +1274,7 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::getCurrentScreenMode(mode); NL3D::MAC::getCurrentScreenMode(_win, mode);
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
/* /*
@ -1293,7 +1328,7 @@ void CDriverGL::setWindowTitle(const ucstring &title)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::setWindowTitle(title); NL3D::MAC::setWindowTitle(_win, title);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1320,7 +1355,7 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::setWindowPos(x, y); NL3D::MAC::setWindowPos(_win, x, y);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1341,8 +1376,8 @@ void CDriverGL::showWindow(bool show)
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
ShowWindow (_win, show ? SW_SHOW:SW_HIDE); ShowWindow (_win, show ? SW_SHOW:SW_HIDE);
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation"); MAC::showWindow(show);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1384,10 +1419,11 @@ bool CDriverGL::activate()
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
# warning "OpenGL Driver: Temporary Mac Implementation" if(!MAC::activate(_win))
nlwarning("OpenGL Driver: Temporary Mac Implementation"); {
nlwarning("cannot activate");
// already done in setDisplay, not needed here - unclean! FIXME return false;
}
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1513,7 +1549,7 @@ void CDriverGL::setMousePos(float x, float y)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::setMousePos(x, y); NL3D::MAC::setMousePos(_win, x, y);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1552,7 +1588,7 @@ void CDriverGL::getWindowSize(uint32 &width, uint32 &height)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::getWindowSize(width, height); NL3D::MAC::getWindowSize(_win, width, height);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1589,7 +1625,11 @@ void CDriverGL::setWindowSize(uint32 width, uint32 height)
_WindowX = clientRect.left; _WindowX = clientRect.left;
_WindowY = clientRect.top; _WindowY = clientRect.top;
#elif defined(NL_OS_UNIX) && !defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::setWindowSize(_win, width, height);
#elif defined(NL_OS_UNIX)
// Update WM hints (update size and allow resizing) // Update WM hints (update size and allow resizing)
XSizeHints size_hints; XSizeHints size_hints;
@ -1653,7 +1693,7 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::getWindowPos(x, y); NL3D::MAC::getWindowPos(_win, x, y);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)

View file

@ -52,41 +52,56 @@ void dtor();
/// mac specific stuff while calling CDriverGL::init() /// mac specific stuff while calling CDriverGL::init()
bool init(uint windowIcon = 0, emptyProc exitFunc = 0); bool init(uint windowIcon = 0, emptyProc exitFunc = 0);
/// mac specific stuff while calling CDriverGL::setDisplay() /// mac specific stuff while calling CDriverGL::unInit()
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable); bool unInit();
/// mac specific stuff while calling CDriverGL::setMode() /// mac specific stuff while calling CDriverGL::createWindow()
bool setMode(const GfxMode& mode); nlWindow createWindow(const GfxMode& mode);
/// mac specific stuff while calling CDriverGL::destroyWindow()
bool destroyWindow(nlWindow wnd);
/// mac specific stuff while calling CDriverGL::setDisplay()
nlWindow setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable);
/// mac specific stuff while calling CDriverGL::setWindowStyle()
bool setWindowStyle(nlWindow wnd, bool fullscreen);
/// mac specific stuff while calling CDriverGL::getCurrentScreenMode() /// mac specific stuff while calling CDriverGL::getCurrentScreenMode()
void getCurrentScreenMode(GfxMode& mode); void getCurrentScreenMode(nlWindow wnd, GfxMode& mode);
/// mac specific stuff while calling CDriverGL::getWindowSize() /// mac specific stuff while calling CDriverGL::getWindowSize()
void getWindowSize(uint32 &width, uint32 &height); void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height);
/// mac specific stuff while calling CDriverGL::setWindowSize()
void setWindowSize(nlWindow wnd, uint32 width, uint32 height);
/// mac specific stuff while calling CDriverGL::getWindowPos() /// mac specific stuff while calling CDriverGL::getWindowPos()
void getWindowPos(sint32 &x, sint32 &y); void getWindowPos(nlWindow wnd, sint32 &x, sint32 &y);
/// mac specific stuff while calling CDriverGL::setWindowPos() /// mac specific stuff while calling CDriverGL::setWindowPos()
void setWindowPos(sint32 x, sint32 y); void setWindowPos(nlWindow wnd, sint32 x, sint32 y);
/// mac specific stuff while calling CDriverGL::setWindowTitle() /// mac specific stuff while calling CDriverGL::setWindowTitle()
void setWindowTitle(const ucstring &title); void setWindowTitle(nlWindow wnd, const ucstring& title);
/// mac specific stuff while calling CDriverGL::showWindow()
void showWindow(bool show);
/// mac specific stuff while calling CDriverGL::activate()
bool activate(nlWindow wnd);
/// mac specific stuff while calling CDriverGL::swapBuffers() /// mac specific stuff while calling CDriverGL::swapBuffers()
void swapBuffers(); void swapBuffers(nlWindow wnd);
/// mac specific stuff while calling CDriverGL::setCapture() /// mac specific stuff while calling CDriverGL::setCapture()
void setCapture(bool b); void setCapture(bool capture);
/// mac specific stuff while calling CDriverGL::showCursor() /// mac specific stuff while calling CDriverGL::showCursor()
void showCursor(bool b); void showCursor(bool show);
/// mac specific stuff while calling CDriverGL::setMousePos() /// mac specific stuff while calling CDriverGL::setMousePos()
void setMousePos(float x, float y); void setMousePos(nlWindow wnd, float x, float y);
/// mac specific stuff while calling CDriverGL::release()
void release();
/// mac specific stuff while calling CCocoaEventEmitter::submitEvents() /// mac specific stuff while calling CCocoaEventEmitter::submitEvents()
void submitEvents(NLMISC::CEventServer& server, void submitEvents(NLMISC::CEventServer& server,

View file

@ -36,17 +36,8 @@ namespace NL3D { namespace MAC {
static NSApplication* g_app = nil; static NSApplication* g_app = nil;
static NSAutoreleasePool* g_pool = nil; static NSAutoreleasePool* g_pool = nil;
static CocoaWindow* g_window = nil;
static CocoaOpenGLView* g_glview = nil;
static NSOpenGLContext* g_glctx = nil;
static bool g_emulateRawMode = false; static bool g_emulateRawMode = false;
static int g_bufferSize[2] = { 0, 0 };
#define UGLY_BACKBUFFER_SIZE_WORKAROUND
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
static int g_bufferSize[2];
#endif
void ctor() void ctor()
{ {
@ -55,13 +46,15 @@ void ctor()
// init the application object // init the application object
g_app = [NSApplication sharedApplication]; g_app = [NSApplication sharedApplication];
// tell the application that we are running now
[g_app finishLaunching];
} }
void dtor() void dtor()
{ {
/* // shut down the application
TODO there might be some more stuff to release ;) [g_app terminate:nil];
*/
// release the pool // release the pool
[g_pool release]; [g_pool release];
@ -69,40 +62,77 @@ void dtor()
bool init(uint windowIcon, emptyProc exitFunc) bool init(uint windowIcon, emptyProc exitFunc)
{ {
/*
TODO nothing to do here? split other stuff to match api cleanly.
*/
return true; return true;
} }
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable) bool unInit()
{
return true;
}
nlWindow createWindow(const GfxMode& mode)
{
unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask;
// create a cocoa window with the size provided by the mode parameter
CocoaWindow* window = [[CocoaWindow alloc]
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
styleMask:styleMask backing:NSBackingStoreBuffered defer:NO];
if(!window)
nlerror("cannot create window");
// set the window to non transparent
[window setOpaque:YES];
// enable mouse move events, NeL wants them
[window setAcceptsMouseMovedEvents:YES];
// there are no overlapping subviews, so we can use the magical optimization!
[window useOptimizedDrawing:YES];
// put the window to the front and make it the key window
[window makeKeyAndOrderFront:nil];
// this is our main window
[window makeMainWindow];
return window;
}
bool destroyWindow(nlWindow wnd)
{
NSWindow* window = (NSWindow*)wnd;
NSOpenGLView* view = [window contentView];
[view release];
[window release];
return true;
}
nlWindow setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
{ {
/* /*
TODO use show TODO use show
call showWindow()
*/ */
/* /*
TODO add menu, on quit send EventDestroyWindowId TODO add menu, on quit send EventDestroyWindowId
*/ */
unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | NSWindow* window = (NSWindow*)wnd;
NSMiniaturizableWindowMask;
if(resizeable) if(wnd == EmptyWindow)
styleMask |= NSResizableWindowMask; window = (NSWindow*)createWindow(mode);
// create a cocoa window with the size provided by the mode parameter
g_window = [[CocoaWindow alloc]
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
styleMask:styleMask backing:NSBackingStoreBuffered defer:NO];
if(!g_window)
nlerror("cannot create window");
/* /*
TODO use mode.Depth TODO use mode.Depth
TODO NSOpenGLPFAOffScreen TODO NSOpenGLPFAOffScreen
*/ */
// setup opengl settings // setup opengl settings
NSOpenGLPixelFormatAttribute att[] = NSOpenGLPixelFormatAttribute att[] =
{ {
@ -125,72 +155,45 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
nlerror("cannot create NSOpenGLPixelFormat"); nlerror("cannot create NSOpenGLPixelFormat");
// create a opengl view with the created format // create a opengl view with the created format
g_glview = [[CocoaOpenGLView alloc] NSOpenGLView* view = [[CocoaOpenGLView alloc]
initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat: format]; initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat: format];
if(!g_glview) if(!view)
nlerror("cannot create view"); nlerror("cannot create view");
// put the view into the window // put the view into the window
[g_window setContentView:g_glview]; [window setContentView:view];
// set the window to non transparent
[g_window setOpaque:YES];
// enable mouse move events, NeL wants them
[g_window setAcceptsMouseMovedEvents:YES];
// there are no overlapping subviews, so we can use the magical optimization!
[g_window useOptimizedDrawing:YES];
// create a opengl context for the view // create a opengl context for the view
g_glctx = [g_glview openGLContext]; NSOpenGLContext* ctx = [view openGLContext];
if(!g_glctx) if(!ctx)
nlerror("cannot create context"); nlerror("cannot create context");
// make the view's opengl context the currrent one
[g_glctx makeCurrentContext];
// put the window to the front and make it the key window
[g_window makeKeyAndOrderFront:nil];
// this is our main window
[g_window makeMainWindow];
// tell the application that we are running now
[g_app finishLaunching];
// free the pixel format object // free the pixel format object
[format release]; [format release];
// further mode setting, like switching to fullscreen and resolution setup return window;
setMode(mode);
return true;
} }
bool setMode(const GfxMode& mode) bool setWindowStyle(nlWindow wnd, bool fullscreen)
{ {
// for fullscreen mode, adjust the back buffer size to the desired resolution if(wnd == EmptyWindow)
if(!mode.Windowed)
{ {
// set the back buffer manually to match the desired rendering resolution nlwarning("cannot set window style on an empty window");
GLint dim[2] = { mode.Width, mode.Height }; return false;
CGLError error = CGLSetParameter((CGLContextObj)[g_glctx CGLContextObj],
kCGLCPSurfaceBackingSize, dim);
if(error != kCGLNoError)
nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)",
CGLErrorString(error));
} }
NSWindow* window = (NSWindow*)wnd;
NSOpenGLView* view = [window contentView];
NSOpenGLContext* ctx = [view openGLContext];
// leave fullscreen mode, enter windowed mode // leave fullscreen mode, enter windowed mode
if(mode.Windowed && [g_glview isInFullScreenMode]) if(!fullscreen && [view isInFullScreenMode])
{ {
// disable manual setting of back buffer size, cocoa handles this // disable manual setting of back buffer size, cocoa handles this
// automatically as soon as the view gets resized // automatically as soon as the view gets resized
CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj], CGLError error = CGLDisable((CGLContextObj)[ctx CGLContextObj],
kCGLCESurfaceBackingSize); kCGLCESurfaceBackingSize);
if(error != kCGLNoError) if(error != kCGLNoError)
@ -198,14 +201,14 @@ bool setMode(const GfxMode& mode)
CGLErrorString(error)); CGLErrorString(error));
// pull the view back from fullscreen restoring window options // pull the view back from fullscreen restoring window options
[g_glview exitFullScreenModeWithOptions:nil]; [view exitFullScreenModeWithOptions:nil];
} }
// enter fullscreen, leave windowed mode // enter fullscreen, leave windowed mode
else if(!mode.Windowed && ![g_glview isInFullScreenMode]) else if(fullscreen && ![view isInFullScreenMode])
{ {
// enable manual back buffer size for mode setting in fullscreen // enable manual back buffer size for mode setting in fullscreen
CGLError error = CGLEnable((CGLContextObj)[g_glctx CGLContextObj], CGLError error = CGLEnable((CGLContextObj)[ctx CGLContextObj],
kCGLCESurfaceBackingSize); kCGLCESurfaceBackingSize);
if(error != kCGLNoError) if(error != kCGLNoError)
@ -215,7 +218,7 @@ bool setMode(const GfxMode& mode)
// put the view in fullscreen mode, hiding the dock but enabling the menubar // put the view in fullscreen mode, hiding the dock but enabling the menubar
// to pop up if the mouse hits the top screen border. // to pop up if the mouse hits the top screen border.
// NOTE: withOptions:nil disables <CMD>+<Tab> application switching! // NOTE: withOptions:nil disables <CMD>+<Tab> application switching!
[g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions: [view enterFullScreenMode:[NSScreen mainScreen] withOptions:
[NSDictionary dictionaryWithObjectsAndKeys: [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: [NSNumber numberWithInt:
NSApplicationPresentationHideDock | NSApplicationPresentationHideDock |
@ -228,17 +231,15 @@ bool setMode(const GfxMode& mode)
*/ */
} }
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
// due to a back buffer size reading problem, just store the size
g_bufferSize[0] = mode.Width;
g_bufferSize[1] = mode.Height;
#endif
return true; return true;
} }
void getCurrentScreenMode(GfxMode& mode)
void getCurrentScreenMode(nlWindow wnd, GfxMode& mode)
{ {
NSWindow* window = (NSWindow*)wnd;
NSOpenGLView* view = [window contentView];
// the sceen with the menu bar // the sceen with the menu bar
NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
@ -247,7 +248,7 @@ void getCurrentScreenMode(GfxMode& mode)
mode.Depth = NSBitsPerPixelFromDepth([screen depth]); mode.Depth = NSBitsPerPixelFromDepth([screen depth]);
// in fullscreen mode // in fullscreen mode
if([g_glview isInFullScreenMode]) if([view isInFullScreenMode])
{ {
// return the size of the back buffer (like having switched monitor mode) // return the size of the back buffer (like having switched monitor mode)
mode.Windowed = false; mode.Windowed = false;
@ -255,7 +256,7 @@ void getCurrentScreenMode(GfxMode& mode)
mode.Height = (uint16)g_bufferSize[1]; mode.Height = (uint16)g_bufferSize[1];
} }
// in windowes mode // in windowed mode
else else
{ {
// return the size of the screen with menu bar // return the size of the screen with menu bar
@ -265,8 +266,12 @@ void getCurrentScreenMode(GfxMode& mode)
} }
} }
void getWindowSize(uint32 &width, uint32 &height) void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height)
{ {
NSWindow* window = (NSWindow*)wnd;
NSOpenGLView* view = [window contentView];
NSOpenGLContext* ctx = [view openGLContext];
// A cocoa fullscreen view stays at the native resolution of the display. // A cocoa fullscreen view stays at the native resolution of the display.
// When changing the rendering resolution, the size of the back buffer gets // When changing the rendering resolution, the size of the back buffer gets
// changed, but the view still stays at full resolution. So the scaling of // changed, but the view still stays at full resolution. So the scaling of
@ -275,11 +280,10 @@ void getWindowSize(uint32 &width, uint32 &height)
// That's why, in fullscreen mode, return the resolution of the back buffer, // That's why, in fullscreen mode, return the resolution of the back buffer,
// not the one from the window. // not the one from the window.
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
// in fullscreen mode // in fullscreen mode
if([g_glview isInFullScreenMode]) if([view isInFullScreenMode])
{ {
// use the size stored in setMode() // use the size stored in setWindowSize()
width = g_bufferSize[0]; width = g_bufferSize[0];
height = g_bufferSize[1]; height = g_bufferSize[1];
} }
@ -288,60 +292,56 @@ void getWindowSize(uint32 &width, uint32 &height)
else else
{ {
// use the size of the view // use the size of the view
NSRect rect = [g_glview frame]; NSRect rect = [view frame];
width = rect.size.width; width = rect.size.width;
height = rect.size.height; height = rect.size.height;
} }
#else }
/*
TODO does not work atm, "invalid enumeration"
*/
// check if manual back buffer sizing is enabled (thats only in fullscreen)
GLint surfaceBackingSizeSet = 0;
CGLError error = CGLIsEnabled((CGLContextObj)[g_glctx CGLContextObj],
kCGLCESurfaceBackingSize, &surfaceBackingSizeSet);
if(error != kCGLNoError) void setWindowSize(nlWindow wnd, uint32 width, uint32 height)
nlerror("cannot check kCGLCESurfaceBackingSize state (%s)", {
CGLErrorString(error)); NSWindow* window = (NSWindow*)wnd;
NSOpenGLView* view = [window contentView];
NSOpenGLContext* ctx = [view openGLContext];
// if in fullscreen mode (only in fullscreen back buffer sizing is used) // for fullscreen mode, adjust the back buffer size to the desired resolution
if(surfaceBackingSizeSet) if([view isInFullScreenMode])
{ {
/* // set the back buffer manually to match the desired rendering resolution
TODO does not work atm, "invalid enumeration" GLint dim[2] = { width, height };
*/ CGLError error = CGLSetParameter((CGLContextObj)[ctx CGLContextObj],
// get the back buffer size
GLint dim[2];
CGLError error = CGLGetParameter((CGLContextObj)[g_glctx CGLContextObj],
kCGLCPSurfaceBackingSize, dim); kCGLCPSurfaceBackingSize, dim);
if(error != kCGLNoError) if(error != kCGLNoError)
nlerror("cannot get kCGLCPSurfaceBackingSize value (%s)", nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)",
CGLErrorString(error)); CGLErrorString(error));
// put size into ref params
width = dim[0];
height = dim[1];
} }
// if in windowed mode
else else
{ {
// return the views size // get the windows current frame
NSRect rect = [g_glview frame]; NSRect rect = [window frame];
// put size into ref params // convert the desired content size to window size
width = rect.size.width; rect = [window frameRectForContentRect:
height = rect.size.height; NSMakeRect(rect.origin.x, rect.origin.y, width, height)];
// update window dimensions
[window setFrame:rect display:YES];
} }
#endif
// store the size
g_bufferSize[0] = width;
g_bufferSize[1] = height;
} }
void getWindowPos(sint32 &x, sint32 &y)
void getWindowPos(nlWindow wnd, sint32 &x, sint32 &y)
{ {
NSWindow* window = (NSWindow*)wnd;
NSOpenGLView* view = [window contentView];
// for IDriver conformity // for IDriver conformity
if([g_glview isInFullScreenMode]) if([view isInFullScreenMode])
{ {
x = y = 0; x = y = 0;
return; return;
@ -351,7 +351,7 @@ void getWindowPos(sint32 &x, sint32 &y)
NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame];
// get the rect (position, size) of the window // get the rect (position, size) of the window
NSRect windowRect = [g_window frame]; NSRect windowRect = [window frame];
// simply return x // simply return x
x = windowRect.origin.x; x = windowRect.origin.x;
@ -360,39 +360,63 @@ void getWindowPos(sint32 &x, sint32 &y)
y = screenRect.size.height - windowRect.size.height - windowRect.origin.y; y = screenRect.size.height - windowRect.size.height - windowRect.origin.y;
} }
void setWindowPos(sint32 x, sint32 y) void setWindowPos(nlWindow wnd, sint32 x, sint32 y)
{ {
NSWindow* window = (NSWindow*)wnd;
// get the rect (position, size) of the screen with menu bar // get the rect (position, size) of the screen with menu bar
NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame];
// get the rect (position, size) of the window // get the rect (position, size) of the window
NSRect windowRect = [g_window frame]; NSRect windowRect = [window frame];
// convert y from NeL coordinates to cocoa coordinates // convert y from NeL coordinates to cocoa coordinates
y = screenRect.size.height - y; y = screenRect.size.height - y;
// tell cocoa to move the window // tell cocoa to move the window
[g_window setFrameTopLeftPoint:NSMakePoint(x, y)]; [window setFrameTopLeftPoint:NSMakePoint(x, y)];
} }
void setWindowTitle(const ucstring &title) void setWindowTitle(nlWindow wnd, const ucstring& title)
{ {
NSWindow* window = (NSWindow*)wnd;
// well... set the title of the window // well... set the title of the window
[g_window setTitle:[NSString stringWithUTF8String:title.toUtf8().c_str()]]; [window setTitle:[NSString stringWithUTF8String:title.toUtf8().c_str()]];
} }
void swapBuffers() void showWindow(bool show)
{ {
// make cocoa draw buffer contents to the view nldebug("show: %d - implement me!", show);
[g_glctx flushBuffer];
} }
void setCapture(bool b) bool activate(nlWindow wnd)
{
NSWindow* window = (NSWindow*)wnd;
NSOpenGLContext* ctx = [[window contentView] openGLContext];
// if our context is not the current one, make it the current
if([NSOpenGLContext currentContext] != ctx)
[ctx makeCurrentContext];
return true;
}
void swapBuffers(nlWindow wnd)
{
NSWindow* window = (NSWindow*)wnd;
NSOpenGLContext* ctx = [[window contentView] openGLContext];
// make cocoa draw buffer contents to the view
[ctx flushBuffer];
}
void setCapture(bool capture)
{ {
// no need to capture // no need to capture
} }
void showCursor(bool b) void showCursor(bool show)
{ {
// Mac OS manages a show/hide counter for the cursor, so hiding the cursor // Mac OS manages a show/hide counter for the cursor, so hiding the cursor
// twice requires two calls to "show" to make the cursor visible again. // twice requires two calls to "show" to make the cursor visible again.
@ -403,23 +427,26 @@ void showCursor(bool b)
CGDisplayErr error = kCGErrorSuccess; CGDisplayErr error = kCGErrorSuccess;
static bool visible = true; static bool visible = true;
if(b && !visible) if(show && !visible)
{ {
error = CGDisplayShowCursor(kCGDirectMainDisplay); error = CGDisplayShowCursor(kCGDirectMainDisplay);
visible = true; visible = true;
} }
else if(!b && visible) else if(!show && visible)
{ {
error = CGDisplayHideCursor(kCGDirectMainDisplay); error = CGDisplayHideCursor(kCGDirectMainDisplay);
visible = false; visible = false;
} }
if(error != kCGErrorSuccess) if(error != kCGErrorSuccess)
nlerror("cannot capture / un-capture cursor"); nlerror("cannot show / hide cursor");
} }
void setMousePos(float x, float y) void setMousePos(nlWindow wnd, float x, float y)
{ {
NSWindow* window = (NSWindow*)wnd;
NSOpenGLView* view = [window contentView];
// CG wants absolute coordinates related to first screen's top left // CG wants absolute coordinates related to first screen's top left
// get the first screen's (conaints menubar) rect (this is not mainScreen) // get the first screen's (conaints menubar) rect (this is not mainScreen)
@ -427,13 +454,13 @@ void setMousePos(float x, float y)
// get the rect (position, size) of the window // get the rect (position, size) of the window
NSRect windowRect; NSRect windowRect;
if([g_glview isInFullScreenMode]) if([view isInFullScreenMode])
windowRect = [[g_window screen] frame]; windowRect = [[window screen] frame];
else else
windowRect = [g_window frame]; windowRect = [window frame];
// get the gl view's rect for height and width // get the gl view's rect for height and width
NSRect viewRect = [g_glview frame]; NSRect viewRect = [view frame];
// set the cursor position // set the cursor position
CGDisplayErr error = CGDisplayMoveCursorToPoint( CGDisplayErr error = CGDisplayMoveCursorToPoint(
@ -446,14 +473,6 @@ void setMousePos(float x, float y)
nlerror("cannot set mouse position"); nlerror("cannot set mouse position");
} }
void release()
{
/*
TODO release some stuff
*/
nlwarning("not implemented");
}
/* /*
TODO: this function has to be moved to a more central place to handle key TODO: this function has to be moved to a more central place to handle key
mapping on mac x11 as well mapping on mac x11 as well
@ -675,16 +694,16 @@ void submitEvents(NLMISC::CEventServer& server,
if(!event) if(!event)
break; break;
// get the views size NSRect viewRect = [[[event window] contentView] frame];
NSRect rect = [g_glview frame];
// TODO this code assumes, that the view fills the window // TODO this code assumes, that the view fills the window
// convert the mouse position to NeL style (relative) // convert the mouse position to NeL style (relative)
float mouseX = event.locationInWindow.x / (float)rect.size.width; float mouseX = event.locationInWindow.x / (float)viewRect.size.width;
float mouseY = event.locationInWindow.y / (float)rect.size.height; float mouseY = event.locationInWindow.y / (float)viewRect.size.height;
// if the mouse event was placed on the window's titlebar, don't tell NeL :) // if the mouse event was placed outside the view, don't tell NeL :)
if(mouseY > 1.0 && event.type != NSKeyDown && event.type != NSKeyUp) if((mouseX < 0.0 || mouseX > 1.0 || mouseY < 0.0 || mouseY > 1.0) &&
event.type != NSKeyDown && event.type != NSKeyUp)
{ {
[g_app sendEvent:event]; [g_app sendEvent:event];
[g_app updateWindows]; [g_app updateWindows];

View file

@ -39,6 +39,7 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS)
### ###
OPTION(WITH_SOUND "Build Sound Support" OFF) OPTION(WITH_SOUND "Build Sound Support" OFF)
OPTION(BUILD_DASHBOARD "Build to the CDash dashboard" OFF) OPTION(BUILD_DASHBOARD "Build to the CDash dashboard" OFF)
OPTION(WITH_COCOA "Build with native Mac OS X Cocoa support" OFF)
ENDMACRO(NL_SETUP_DEFAULT_OPTIONS) ENDMACRO(NL_SETUP_DEFAULT_OPTIONS)
@ -88,6 +89,9 @@ MACRO(NL_SETUP_BUILD)
SET(NL_RELEASE_CFLAGS "-DNL_RELEASE -O6") SET(NL_RELEASE_CFLAGS "-DNL_RELEASE -O6")
SET(NL_RELEASEDEBUG_CFLAGS "-DNL_RELEASE_DEBUG -g -finline-functions -O3 ") SET(NL_RELEASEDEBUG_CFLAGS "-DNL_RELEASE_DEBUG -g -finline-functions -O3 ")
SET(NL_NONE_CFLAGS "-DNL_RELEASE -g -finline-functions -O2 ") SET(NL_NONE_CFLAGS "-DNL_RELEASE -g -finline-functions -O2 ")
IF(WITH_COCOA)
SET(PLATFORM_CFLAGS "-DNL_MAC_NATIVE")
ENDIF(WITH_COCOA)
ENDIF(WIN32) ENDIF(WIN32)
# Determine host CPU # Determine host CPU