From a6ccab4d89f4ea941c3a6bfebd7ffecbd6c13b3b Mon Sep 17 00:00:00 2001 From: rti Date: Wed, 23 Jun 2010 23:37:19 +0200 Subject: [PATCH] Changed: #947 adapted to recent driver changes, some cleanup --- code/nel/include/nel/misc/common.h | 5 +- .../src/3d/driver/opengl/driver_opengl.cpp | 16 +- .../3d/driver/opengl/driver_opengl_window.cpp | 96 +++-- .../src/3d/driver/opengl/mac/cocoa_adapter.h | 47 ++- .../src/3d/driver/opengl/mac/cocoa_adapter.mm | 337 +++++++++--------- code/ryzom/CMakeModules/nel.cmake | 4 + 6 files changed, 294 insertions(+), 211 deletions(-) diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h index 304757add..fc4bb1d3e 100644 --- a/code/nel/include/nel/misc/common.h +++ b/code/nel/include/nel/misc/common.h @@ -45,7 +45,10 @@ #ifdef NL_OS_WINDOWS typedef HWND nlWindow; #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; #define EmptyWindow 0 #endif diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index d4c2fe61c..7c9d7e885 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -867,7 +867,7 @@ bool CDriverGL::swapBuffers() SwapBuffers(_hDC); #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) - NL3D::MAC::swapBuffers(); + NL3D::MAC::swapBuffers(_win); #elif defined (NL_OS_UNIX) glXSwapBuffers(_dpy, _win); @@ -972,9 +972,11 @@ bool CDriverGL::release() void CDriverGL::setupViewport (const class CViewport& viewport) { H_AUTO_OGL(CDriverGL_setupViewport ) -#ifdef NL_OS_WINDOWS + if (_win == EmptyWindow) return; +#ifdef NL_OS_WINDOWS + // Setup gl viewport int clientWidth = _WindowWidth; int clientHeight = _WindowHeight; @@ -982,7 +984,7 @@ void CDriverGL::setupViewport (const class CViewport& viewport) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) uint32 clientWidth, clientHeight; - NL3D::MAC::getWindowSize(clientWidth, clientHeight); + NL3D::MAC::getWindowSize(_win, clientWidth, clientHeight); #elif defined (NL_OS_UNIX) @@ -1052,11 +1054,11 @@ void CDriverGL::setupScissor (const class CScissor& scissor) int clientHeight = _WindowHeight; #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) -# warning "OpenGL Driver: Missing Mac Implementation" - // nlwarning("OpenGL Driver: Temporary Mac Implementation"); - int clientWidth = 1024; - int clientHeight = 768; + uint32 clientWidth = 0; + uint32 clientHeight = 0; + + getWindowSize(clientWidth, clientHeight); #elif defined (NL_OS_UNIX) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index d2c85c715..c09f4045a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -132,7 +132,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l return trapMessage ? 0 : DefWindowProcW(hWnd, message, wParam, lParam); } -#endif // NL_OS_UNIX +#endif // NL_OS_WINDOWS // *************************************************************************** bool CDriverGL::init (uint windowIcon, emptyProc exitFunc) @@ -182,7 +182,11 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc) retrieveATIDriverVersion(); #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) @@ -249,7 +253,11 @@ bool CDriverGL::unInit() #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) @@ -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) - 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) @@ -739,6 +750,10 @@ bool CDriverGL::saveScreenMode() // 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) #if defined(XF86VIDMODE) @@ -766,6 +781,11 @@ bool CDriverGL::restoreScreenMode() 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) #if defined(XF86VIDMODE) @@ -856,7 +876,7 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) #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) @@ -918,7 +938,13 @@ bool CDriverGL::createWindow(const GfxMode &mode) #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) @@ -986,7 +1012,14 @@ bool CDriverGL::destroyWindow() #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) @@ -1072,6 +1105,14 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) // else if (isMaximized && isVisible) // 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) XSetWindowAttributes attr; @@ -1129,7 +1170,7 @@ bool CDriverGL::setMode(const GfxMode& mode) return false; // 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; _WindowHeight = mode.Height; @@ -1139,17 +1180,11 @@ bool CDriverGL::setMode(const GfxMode& mode) _FullScreen = !mode.Windowed; -#if defined(NL_OS_MAC) - -#if defined(NL_MAC_NATIVE) - NL3D::MAC::setMode(mode); -#else +#if defined(NL_OS_MAC) && !defined(NL_MAC_NATIVE) // X11 under Mac OS can't use fullscreen _FullScreen = false; #endif // NL_MAC_NATIVE -#endif // NL_OS_MAC - setWindowSize(mode.Width, mode.Height); return true; @@ -1239,7 +1274,7 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) - NL3D::MAC::getCurrentScreenMode(mode); + NL3D::MAC::getCurrentScreenMode(_win, mode); #elif defined(NL_OS_MAC) /* @@ -1293,7 +1328,7 @@ void CDriverGL::setWindowTitle(const ucstring &title) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) - NL3D::MAC::setWindowTitle(title); + NL3D::MAC::setWindowTitle(_win, title); #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) - NL3D::MAC::setWindowPos(x, y); + NL3D::MAC::setWindowPos(_win, x, y); #elif defined (NL_OS_UNIX) @@ -1341,9 +1376,9 @@ void CDriverGL::showWindow(bool show) #ifdef NL_OS_WINDOWS ShowWindow (_win, show ? SW_SHOW:SW_HIDE); #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) if (show) @@ -1384,10 +1419,11 @@ bool CDriverGL::activate() #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) -# warning "OpenGL Driver: Temporary Mac Implementation" - nlwarning("OpenGL Driver: Temporary Mac Implementation"); - - // already done in setDisplay, not needed here - unclean! FIXME + if(!MAC::activate(_win)) + { + nlwarning("cannot activate"); + return false; + } #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) - NL3D::MAC::setMousePos(x, y); + NL3D::MAC::setMousePos(_win, x, y); #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) - NL3D::MAC::getWindowSize(width, height); + NL3D::MAC::getWindowSize(_win, width, height); #elif defined (NL_OS_UNIX) @@ -1589,7 +1625,11 @@ void CDriverGL::setWindowSize(uint32 width, uint32 height) _WindowX = clientRect.left; _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) XSizeHints size_hints; @@ -1653,7 +1693,7 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y) #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) diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.h b/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.h index a2d0dddf6..457c35793 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.h +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.h @@ -52,41 +52,56 @@ void dtor(); /// mac specific stuff while calling CDriverGL::init() bool init(uint windowIcon = 0, emptyProc exitFunc = 0); -/// mac specific stuff while calling CDriverGL::setDisplay() -bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable); +/// mac specific stuff while calling CDriverGL::unInit() +bool unInit(); -/// mac specific stuff while calling CDriverGL::setMode() -bool setMode(const GfxMode& mode); +/// mac specific stuff while calling CDriverGL::createWindow() +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() -void getCurrentScreenMode(GfxMode& mode); +void getCurrentScreenMode(nlWindow wnd, GfxMode& mode); /// 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() -void getWindowPos(sint32 &x, sint32 &y); +void getWindowPos(nlWindow wnd, sint32 &x, sint32 &y); /// 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() -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() -void swapBuffers(); +void swapBuffers(nlWindow wnd); /// mac specific stuff while calling CDriverGL::setCapture() -void setCapture(bool b); +void setCapture(bool capture); /// mac specific stuff while calling CDriverGL::showCursor() -void showCursor(bool b); +void showCursor(bool show); /// mac specific stuff while calling CDriverGL::setMousePos() -void setMousePos(float x, float y); - -/// mac specific stuff while calling CDriverGL::release() -void release(); +void setMousePos(nlWindow wnd, float x, float y); /// mac specific stuff while calling CCocoaEventEmitter::submitEvents() void submitEvents(NLMISC::CEventServer& server, diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.mm b/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.mm index 6c7629f9a..2f28a29a3 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.mm +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.mm @@ -36,17 +36,8 @@ namespace NL3D { namespace MAC { static NSApplication* g_app = 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; - - -#define UGLY_BACKBUFFER_SIZE_WORKAROUND - -#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND -static int g_bufferSize[2]; -#endif +static int g_bufferSize[2] = { 0, 0 }; void ctor() { @@ -55,13 +46,15 @@ void ctor() // init the application object g_app = [NSApplication sharedApplication]; + + // tell the application that we are running now + [g_app finishLaunching]; } void dtor() { - /* - TODO there might be some more stuff to release ;) - */ + // shut down the application + [g_app terminate:nil]; // release the pool [g_pool release]; @@ -69,40 +62,77 @@ void dtor() bool init(uint windowIcon, emptyProc exitFunc) { - /* - TODO nothing to do here? split other stuff to match api cleanly. - */ 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 + call showWindow() */ /* TODO add menu, on quit send EventDestroyWindowId */ - unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask; + NSWindow* window = (NSWindow*)wnd; - if(resizeable) - styleMask |= NSResizableWindowMask; - - // 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"); + if(wnd == EmptyWindow) + window = (NSWindow*)createWindow(mode); /* TODO use mode.Depth TODO NSOpenGLPFAOffScreen */ + // setup opengl settings NSOpenGLPixelFormatAttribute att[] = { @@ -125,72 +155,45 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable) nlerror("cannot create NSOpenGLPixelFormat"); // create a opengl view with the created format - g_glview = [[CocoaOpenGLView alloc] + NSOpenGLView* view = [[CocoaOpenGLView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat: format]; - if(!g_glview) + if(!view) nlerror("cannot create view"); // put the view into the window - [g_window setContentView:g_glview]; - - // 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]; + [window setContentView: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"); - // 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 [format release]; - // further mode setting, like switching to fullscreen and resolution setup - setMode(mode); - - return true; + return window; } -bool setMode(const GfxMode& mode) +bool setWindowStyle(nlWindow wnd, bool fullscreen) { - // for fullscreen mode, adjust the back buffer size to the desired resolution - if(!mode.Windowed) + if(wnd == EmptyWindow) { - // set the back buffer manually to match the desired rendering resolution - GLint dim[2] = { mode.Width, mode.Height }; - CGLError error = CGLSetParameter((CGLContextObj)[g_glctx CGLContextObj], - kCGLCPSurfaceBackingSize, dim); - - if(error != kCGLNoError) - nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)", - CGLErrorString(error)); + nlwarning("cannot set window style on an empty window"); + return false; } - + + NSWindow* window = (NSWindow*)wnd; + NSOpenGLView* view = [window contentView]; + NSOpenGLContext* ctx = [view openGLContext]; + // 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 // automatically as soon as the view gets resized - CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj], + CGLError error = CGLDisable((CGLContextObj)[ctx CGLContextObj], kCGLCESurfaceBackingSize); if(error != kCGLNoError) @@ -198,14 +201,14 @@ bool setMode(const GfxMode& mode) CGLErrorString(error)); // pull the view back from fullscreen restoring window options - [g_glview exitFullScreenModeWithOptions:nil]; + [view exitFullScreenModeWithOptions:nil]; } // 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 - CGLError error = CGLEnable((CGLContextObj)[g_glctx CGLContextObj], + CGLError error = CGLEnable((CGLContextObj)[ctx CGLContextObj], kCGLCESurfaceBackingSize); 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 // to pop up if the mouse hits the top screen border. // NOTE: withOptions:nil disables + application switching! - [g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions: + [view enterFullScreenMode:[NSScreen mainScreen] withOptions: [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: 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; } -void getCurrentScreenMode(GfxMode& mode) + +void getCurrentScreenMode(nlWindow wnd, GfxMode& mode) { + NSWindow* window = (NSWindow*)wnd; + NSOpenGLView* view = [window contentView]; + // the sceen with the menu bar NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; @@ -247,7 +248,7 @@ void getCurrentScreenMode(GfxMode& mode) mode.Depth = NSBitsPerPixelFromDepth([screen depth]); // in fullscreen mode - if([g_glview isInFullScreenMode]) + if([view isInFullScreenMode]) { // return the size of the back buffer (like having switched monitor mode) mode.Windowed = false; @@ -255,7 +256,7 @@ void getCurrentScreenMode(GfxMode& mode) mode.Height = (uint16)g_bufferSize[1]; } - // in windowes mode + // in windowed mode else { // 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. // 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 @@ -275,11 +280,10 @@ void getWindowSize(uint32 &width, uint32 &height) // That's why, in fullscreen mode, return the resolution of the back buffer, // not the one from the window. -#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND // 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]; height = g_bufferSize[1]; } @@ -288,60 +292,56 @@ void getWindowSize(uint32 &width, uint32 &height) else { // use the size of the view - NSRect rect = [g_glview frame]; + NSRect rect = [view frame]; width = rect.size.width; 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) - nlerror("cannot check kCGLCESurfaceBackingSize state (%s)", - CGLErrorString(error)); - - // if in fullscreen mode (only in fullscreen back buffer sizing is used) - if(surfaceBackingSizeSet) +void setWindowSize(nlWindow wnd, uint32 width, uint32 height) +{ + NSWindow* window = (NSWindow*)wnd; + NSOpenGLView* view = [window contentView]; + NSOpenGLContext* ctx = [view openGLContext]; + + // for fullscreen mode, adjust the back buffer size to the desired resolution + if([view isInFullScreenMode]) { - /* - TODO does not work atm, "invalid enumeration" - */ - // get the back buffer size - GLint dim[2]; - CGLError error = CGLGetParameter((CGLContextObj)[g_glctx CGLContextObj], + // set the back buffer manually to match the desired rendering resolution + GLint dim[2] = { width, height }; + CGLError error = CGLSetParameter((CGLContextObj)[ctx CGLContextObj], kCGLCPSurfaceBackingSize, dim); if(error != kCGLNoError) - nlerror("cannot get kCGLCPSurfaceBackingSize value (%s)", + nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)", CGLErrorString(error)); - - // put size into ref params - width = dim[0]; - height = dim[1]; } - - // if in windowed mode else { - // return the views size - NSRect rect = [g_glview frame]; + // get the windows current frame + NSRect rect = [window frame]; - // put size into ref params - width = rect.size.width; - height = rect.size.height; + // convert the desired content size to window size + rect = [window frameRectForContentRect: + 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 - if([g_glview isInFullScreenMode]) + if([view isInFullScreenMode]) { x = y = 0; return; @@ -351,7 +351,7 @@ void getWindowPos(sint32 &x, sint32 &y) NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; // get the rect (position, size) of the window - NSRect windowRect = [g_window frame]; + NSRect windowRect = [window frame]; // simply return 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; } -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 NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; // 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 y = screenRect.size.height - y; // 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 - [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 - [g_glctx flushBuffer]; + nldebug("show: %d - implement me!", show); } -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 } -void showCursor(bool b) +void showCursor(bool show) { // 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. @@ -403,23 +427,26 @@ void showCursor(bool b) CGDisplayErr error = kCGErrorSuccess; static bool visible = true; - if(b && !visible) + if(show && !visible) { error = CGDisplayShowCursor(kCGDirectMainDisplay); visible = true; } - else if(!b && visible) + else if(!show && visible) { error = CGDisplayHideCursor(kCGDirectMainDisplay); visible = false; } 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 // 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 NSRect windowRect; - if([g_glview isInFullScreenMode]) - windowRect = [[g_window screen] frame]; + if([view isInFullScreenMode]) + windowRect = [[window screen] frame]; else - windowRect = [g_window frame]; + windowRect = [window frame]; // get the gl view's rect for height and width - NSRect viewRect = [g_glview frame]; + NSRect viewRect = [view frame]; // set the cursor position CGDisplayErr error = CGDisplayMoveCursorToPoint( @@ -446,14 +473,6 @@ void setMousePos(float x, float y) 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 mapping on mac x11 as well @@ -675,16 +694,16 @@ void submitEvents(NLMISC::CEventServer& server, if(!event) break; - // get the views size - NSRect rect = [g_glview frame]; + NSRect viewRect = [[[event window] contentView] frame]; // TODO this code assumes, that the view fills the window // convert the mouse position to NeL style (relative) - float mouseX = event.locationInWindow.x / (float)rect.size.width; - float mouseY = event.locationInWindow.y / (float)rect.size.height; + float mouseX = event.locationInWindow.x / (float)viewRect.size.width; + 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(mouseY > 1.0 && event.type != NSKeyDown && event.type != NSKeyUp) + // if the mouse event was placed outside the view, don't tell NeL :) + 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 updateWindows]; diff --git a/code/ryzom/CMakeModules/nel.cmake b/code/ryzom/CMakeModules/nel.cmake index d5209c069..85335132a 100644 --- a/code/ryzom/CMakeModules/nel.cmake +++ b/code/ryzom/CMakeModules/nel.cmake @@ -39,6 +39,7 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS) ### OPTION(WITH_SOUND "Build Sound Support" 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) @@ -88,6 +89,9 @@ MACRO(NL_SETUP_BUILD) SET(NL_RELEASE_CFLAGS "-DNL_RELEASE -O6") SET(NL_RELEASEDEBUG_CFLAGS "-DNL_RELEASE_DEBUG -g -finline-functions -O3 ") SET(NL_NONE_CFLAGS "-DNL_RELEASE -g -finline-functions -O2 ") + IF(WITH_COCOA) + SET(PLATFORM_CFLAGS "-DNL_MAC_NATIVE") + ENDIF(WITH_COCOA) ENDIF(WIN32) # Determine host CPU