From 2a7f8555b8b3cb3f2cb4e855e255fa8a92833a2b Mon Sep 17 00:00:00 2001 From: rti Date: Mon, 18 Oct 2010 22:33:10 +0200 Subject: [PATCH 1/2] Changed: #1060 Implement getWndProc() on Mac OS X --- .../src/3d/driver/opengl/driver_opengl.cpp | 7 +- code/nel/src/3d/driver/opengl/driver_opengl.h | 7 +- .../3d/driver/opengl/driver_opengl_window.cpp | 22 +- .../driver/opengl/mac/cocoa_event_emitter.cpp | 372 ++++++++++-------- .../driver/opengl/mac/cocoa_event_emitter.h | 27 +- 5 files changed, 250 insertions(+), 185 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 5ab7c7475..ff87095bc 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -873,8 +873,11 @@ bool CDriverGL::swapBuffers() #elif defined(NL_OS_MAC) // TODO: maybe do this somewhere else? - [_autoreleasePool release]; - _autoreleasePool = [[NSAutoreleasePool alloc] init]; + if(_DestroyWindow) + { + [_autoreleasePool release]; + _autoreleasePool = [[NSAutoreleasePool alloc] init]; + } [_ctx flushBuffer]; [containerView() display]; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index cf4f93a22..3bab224bb 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -116,8 +116,7 @@ bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM #elif defined (NL_OS_MAC) -// TODO: change that -bool GlWndProc(CDriverGL *driver); +bool GlWndProc(CDriverGL *driver, NSEvent* e); #elif defined (NL_OS_UNIX) @@ -703,9 +702,11 @@ private: #elif defined(NL_OS_MAC) + friend bool GlWndProc(CDriverGL* driver, NSEvent* e); + NLMISC::CCocoaEventEmitter _EventEmitter; NSOpenGLContext* _ctx; - NSOpenGLView* _glView; + CocoaOpenGLView* _glView; NSAutoreleasePool* _autoreleasePool; uint16 _backBufferHeight; uint16 _backBufferWidth; 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 f82fbe746..ef14c83f0 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -164,8 +164,22 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l #elif defined (NL_OS_MAC) -bool GlWndProc(CDriverGL *driver) +bool GlWndProc(CDriverGL *driver, NSEvent* e) { + H_AUTO_OGL(GlWndProc) + + if(!driver) + return false; + + // NSLog(@"NSEvent in GlWndProc %@", e); + + switch([e type]) + { + /* TODO handle window move, resize, activate, close, etc. */ + default: + return driver->_EventEmitter.processMessage(e); + } + return false; } @@ -951,6 +965,8 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re [_ctx flushBuffer]; [containerView() display]; + _EventEmitter.init(this, _glView); + #elif defined(NL_OS_UNIX) static int sAttribList16bpp[] = @@ -2164,7 +2180,7 @@ void CDriverGL::showWindow(bool show) #elif defined(NL_OS_MAC) - // TODO implement me +# warning "OpenGL Driver: Missing Mac Implementation for showWindow" #elif defined (NL_OS_UNIX) @@ -2601,7 +2617,7 @@ bool CDriverGL::isActive() res = (IsWindow(_win) != FALSE); #elif defined(NL_OS_MAC) -# warning "OpenGL Driver: Missing Mac Implementation for isActive" +# warning "OpenGL Driver: Missing Mac Implementation for isActive (always true if a window is set)" #elif defined (NL_OS_UNIX) #endif // NL_OS_UNIX diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp index 86014e6cb..5b9912fb6 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp @@ -16,13 +16,6 @@ #include "cocoa_event_emitter.h" -#include "nel/misc/event_server.h" -#include "nel/misc/events.h" -#include "nel/misc/game_device_events.h" - -#include -#import - namespace NLMISC { @@ -217,6 +210,194 @@ static bool isTextKeyEvent(NSEvent* event) return false; } +void CCocoaEventEmitter::init(NL3D::IDriver* driver, CocoaOpenGLView* glView) +{ + _driver = driver; + _glView = glView; +} + +bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) +{ + if(!server && !_server) + nlerror("no server to post events to"); + + if(!server) + server = _server; + + NSRect viewRect = [_glView 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)viewRect.size.width; + float mouseY = event.locationInWindow.y / (float)viewRect.size.height; + + // 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) + { + [NSApp sendEvent:event]; + return false; + } + + // convert the modifiers for nel to pass them with the events + NLMISC::TKeyButton modifiers = + modifierFlagsToNelKeyButton([event modifierFlags]); + + switch(event.type) + { + case NSLeftMouseDown: + { + server->postEvent(new NLMISC::CEventMouseDown( + mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); + } + break; + case NSLeftMouseUp: + { + server->postEvent(new NLMISC::CEventMouseUp( + mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); + break; + } + case NSRightMouseDown: + { + server->postEvent(new NLMISC::CEventMouseDown( + mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this)); + break; + } + case NSRightMouseUp: + { + server->postEvent(new NLMISC::CEventMouseUp( + mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this)); + break; + } + case NSMouseMoved: + { + NLMISC::CEvent* nelEvent; + + // when emulating raw mode, send the delta in a CGDMouseMove event + if(_emulateRawMode) + nelEvent = new NLMISC::CGDMouseMove( + this, NULL /* no mouse device */, event.deltaX, -event.deltaY); + + // normally send position in a CEventMouseMove + else + nelEvent = new NLMISC::CEventMouseMove( + mouseX, mouseY, (NLMISC::TMouseButton)modifiers, this); + + server->postEvent(nelEvent); + break; + } + case NSLeftMouseDragged: + { + NLMISC::CEvent* nelEvent; + + // when emulating raw mode, send the delta in a CGDMouseMove event + if(_emulateRawMode) + nelEvent = new NLMISC::CGDMouseMove( + this, NULL /* no mouse device */, event.deltaX, -event.deltaY); + + // normally send position in a CEventMouseMove + else + nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this); + + server->postEvent(nelEvent); + break; + } + case NSRightMouseDragged: + { + NLMISC::CEvent* nelEvent; + + // when emulating raw mode, send the delta in a CGDMouseMove event + if(_emulateRawMode) + nelEvent = new NLMISC::CGDMouseMove( + this, NULL /* no mouse device */, event.deltaX, -event.deltaY); + + // normally send position in a CEventMouseMove + else + nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this); + + server->postEvent(nelEvent); + break; + } + case NSMouseEntered:break; + case NSMouseExited:break; + case NSKeyDown: + { + // push the key press event to the event server + server->postEvent(new NLMISC::CEventKeyDown( + virtualKeycodeToNelKey([event keyCode]), + modifierFlagsToNelKeyButton([event modifierFlags]), + [event isARepeat] == NO, this)); + + // if this was a text event + if(isTextKeyEvent(event)) + { + ucstring ucstr; + + // get the string associated with the key press event + ucstr.fromUtf8([[event characters] UTF8String]); + + // push the text event to event server as well + server->postEvent(new NLMISC::CEventChar( + ucstr[0], NLMISC::noKeyButton, this)); + } + break; + } + case NSKeyUp: + { + // push the key release event to the event server + server->postEvent(new NLMISC::CEventKeyUp( + virtualKeycodeToNelKey([event keyCode]), + modifierFlagsToNelKeyButton([event modifierFlags]), this)); + break; + } + case NSFlagsChanged:break; + case NSAppKitDefined:break; + case NSSystemDefined:break; + case NSApplicationDefined:break; + case NSPeriodic:break; + case NSCursorUpdate:break; + case NSScrollWheel: + { + if(fabs(event.deltaY) > 0.1) + server->postEvent(new NLMISC::CEventMouseWheel( + mouseX, mouseY, (NLMISC::TMouseButton)modifiers, + (event.deltaY > 0), this)); + + break; + } + case NSTabletPoint:break; + case NSTabletProximity:break; + case NSOtherMouseDown:break; + case NSOtherMouseUp:break; + case NSOtherMouseDragged:break; +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + case NSEventTypeGesture:break; + case NSEventTypeMagnify:break; + case NSEventTypeSwipe:break; + case NSEventTypeRotate:break; + case NSEventTypeBeginGesture:break; + case NSEventTypeEndGesture:break; +#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + default: + { + nlwarning("Unknown event type. dropping."); + // NSLog(@"%@", event); + break; + } + } + + [NSApp sendEvent:event]; + return true; +} + +typedef bool (*cocoaProc)(NL3D::IDriver*, void* e); + void CCocoaEventEmitter::submitEvents(CEventServer& server, bool /* allWins */) { // break if there was no event to handle @@ -231,177 +412,22 @@ void CCocoaEventEmitter::submitEvents(CEventServer& server, bool /* allWins */) if(!event) break; - NSView* glView = [[[[event window] contentView] subviews] lastObject]; - NSRect viewRect = [glView 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)viewRect.size.width; - float mouseY = event.locationInWindow.y / (float)viewRect.size.height; - - // 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) + if(_driver) { - [NSApp sendEvent:event]; - continue; + cocoaProc proc = (cocoaProc)_driver->getWindowProc(); + + if(proc) + proc(_driver, event); } - - // convert the modifiers for nel to pass them with the events - NLMISC::TKeyButton modifiers = - modifierFlagsToNelKeyButton([event modifierFlags]); - - switch(event.type) + else { - case NSLeftMouseDown: - { - server.postEvent(new NLMISC::CEventMouseDown( - mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); + processMessage(event, &server); } - break; - case NSLeftMouseUp: - { - server.postEvent(new NLMISC::CEventMouseUp( - mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); - break; - } - case NSRightMouseDown: - { - server.postEvent(new NLMISC::CEventMouseDown( - mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this)); - break; - } - case NSRightMouseUp: - { - server.postEvent(new NLMISC::CEventMouseUp( - mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this)); - break; - } - case NSMouseMoved: - { - NLMISC::CEvent* nelEvent; - - // when emulating raw mode, send the delta in a CGDMouseMove event - if(_emulateRawMode) - nelEvent = new NLMISC::CGDMouseMove( - this, NULL /* no mouse device */, event.deltaX, -event.deltaY); - - // normally send position in a CEventMouseMove - else - nelEvent = new NLMISC::CEventMouseMove( - mouseX, mouseY, (NLMISC::TMouseButton)modifiers, this); - - server.postEvent(nelEvent); - break; - } - case NSLeftMouseDragged: - { - NLMISC::CEvent* nelEvent; - - // when emulating raw mode, send the delta in a CGDMouseMove event - if(_emulateRawMode) - nelEvent = new NLMISC::CGDMouseMove( - this, NULL /* no mouse device */, event.deltaX, -event.deltaY); - - // normally send position in a CEventMouseMove - else - nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this); - - server.postEvent(nelEvent); - break; - } - case NSRightMouseDragged: - { - NLMISC::CEvent* nelEvent; - - // when emulating raw mode, send the delta in a CGDMouseMove event - if(_emulateRawMode) - nelEvent = new NLMISC::CGDMouseMove( - this, NULL /* no mouse device */, event.deltaX, -event.deltaY); - - // normally send position in a CEventMouseMove - else - nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this); - - server.postEvent(nelEvent); - break; - } - case NSMouseEntered:break; - case NSMouseExited:break; - case NSKeyDown: - { - // push the key press event to the event server - server.postEvent(new NLMISC::CEventKeyDown( - virtualKeycodeToNelKey([event keyCode]), - modifierFlagsToNelKeyButton([event modifierFlags]), - [event isARepeat] == NO, this)); - - // if this was a text event - if(isTextKeyEvent(event)) - { - ucstring ucstr; - - // get the string associated with the key press event - ucstr.fromUtf8([[event characters] UTF8String]); - - // push the text event to event server as well - server.postEvent(new NLMISC::CEventChar( - ucstr[0], NLMISC::noKeyButton, this)); - } - break; - } - case NSKeyUp: - { - // push the key release event to the event server - server.postEvent(new NLMISC::CEventKeyUp( - virtualKeycodeToNelKey([event keyCode]), - modifierFlagsToNelKeyButton([event modifierFlags]), this)); - break; - } - case NSFlagsChanged:break; - case NSAppKitDefined:break; - case NSSystemDefined:break; - case NSApplicationDefined:break; - case NSPeriodic:break; - case NSCursorUpdate:break; - case NSScrollWheel: - { - if(fabs(event.deltaY) > 0.1) - server.postEvent(new NLMISC::CEventMouseWheel( - mouseX, mouseY, (NLMISC::TMouseButton)modifiers, - (event.deltaY > 0), this)); - - break; - } - case NSTabletPoint:break; - case NSTabletProximity:break; - case NSOtherMouseDown:break; - case NSOtherMouseUp:break; - case NSOtherMouseDragged:break; -#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - case NSEventTypeGesture:break; - case NSEventTypeMagnify:break; - case NSEventTypeSwipe:break; - case NSEventTypeRotate:break; - case NSEventTypeBeginGesture:break; - case NSEventTypeEndGesture:break; -#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - default: - { - nlwarning("Unknown event type. dropping."); - // NSLog(@"%@", event); - break; - } - } - - [NSApp sendEvent:event]; } + + // TODO like internal server in unix event emitter... review! + _server = &server; + // _server->pump(); } void CCocoaEventEmitter::emulateMouseRawMode(bool enable) diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h index 72bfbb718..34b25d9bd 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h @@ -17,19 +17,38 @@ #ifndef NL_COCOA_EVENT_EMITTER_H #define NL_COCOA_EVENT_EMITTER_H -#include +#include "nel/misc/event_emitter.h" +#include "nel/misc/event_server.h" +#include "nel/misc/events.h" +#include "nel/misc/game_device_events.h" +#include "nel/3d/driver.h" +#import "cocoa_opengl_view.h" + +#include +#import namespace NLMISC { class CCocoaEventEmitter : public IEventEmitter { - bool _emulateRawMode; + bool _emulateRawMode; + NL3D::IDriver* _driver; + CocoaOpenGLView* _glView; + + // TODO like internal server in unix event emitter... review! + CEventServer* _server; public: - CCocoaEventEmitter() : _emulateRawMode(false) { } + CCocoaEventEmitter() : + _emulateRawMode(false), + _driver(NULL), + _glView(nil), + _server(NULL) { } - virtual void submitEvents(CEventServer & server, bool allWindows); + void init(NL3D::IDriver* driver, CocoaOpenGLView* glView); + bool processMessage(NSEvent* event, CEventServer* server = NULL); + virtual void submitEvents(CEventServer& server, bool allWindows); virtual void emulateMouseRawMode(bool enable); }; From 053232af065e53dfa93563d3f8f9fca9d172aab6 Mon Sep 17 00:00:00 2001 From: rti Date: Sat, 30 Oct 2010 22:36:20 +0200 Subject: [PATCH 2/2] Changed: #1060 Implement getWndProc() on Mac OS X --- .../src/3d/driver/opengl/driver_opengl.cpp | 9 +- code/nel/src/3d/driver/opengl/driver_opengl.h | 4 +- .../driver/opengl/driver_opengl_extension.h | 1 + .../3d/driver/opengl/driver_opengl_window.cpp | 86 +++++-------------- .../driver/opengl/mac/cocoa_event_emitter.cpp | 4 +- .../driver/opengl/mac/cocoa_event_emitter.h | 4 +- .../3d/driver/opengl/mac/cocoa_opengl_view.h | 12 ++- .../3d/driver/opengl/mac/cocoa_opengl_view.m | 54 +++++++++--- .../driver/opengl/mac/cocoa_window_delegate.h | 35 ++++++++ .../opengl/mac/cocoa_window_delegate.mm | 62 +++++++++++++ 10 files changed, 186 insertions(+), 85 deletions(-) create mode 100644 code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.h create mode 100644 code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.mm diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index f4ea1f084..39017a5b6 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -185,11 +185,10 @@ CDriverGL::CDriverGL() #elif defined(NL_OS_MAC) - _ctx = nil; - _glView = nil; - - _backBufferHeight = 0; - _backBufferWidth = 0; + _ctx = nil; + _glView = nil; + _backBufferHeight = 0; + _backBufferWidth = 0; // autorelease pool for memory management _autoreleasePool = [[NSAutoreleasePool alloc] init]; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 54071bd0f..3af14a1d5 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -705,7 +705,9 @@ private: #elif defined(NL_OS_MAC) - friend bool GlWndProc(CDriverGL* driver, NSEvent* e); + friend bool GlWndProc(CDriverGL*, NSEvent*); + friend void windowDidMove(NSWindow*, CDriverGL*); + friend void viewDidResize(NSView*, CDriverGL*); NLMISC::CCocoaEventEmitter _EventEmitter; NSOpenGLContext* _ctx; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h index 134e0bd6b..a4d71ec08 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h @@ -19,6 +19,7 @@ #include "nel/misc/types_nl.h" +#include "nel/misc/string_common.h" #ifdef NL_OS_WINDOWS # define WIN32_LEAN_AND_MEAN 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 1583fb8ac..f65979873 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -25,6 +25,7 @@ #ifdef NL_OS_WINDOWS # include #elif defined(NL_OS_MAC) +# import "mac/cocoa_window_delegate.h" #elif defined (NL_OS_UNIX) # include # include @@ -168,14 +169,14 @@ bool GlWndProc(CDriverGL *driver, NSEvent* e) { H_AUTO_OGL(GlWndProc) + // NSLog(@"NSEvent in GlWndProc %@", e); + if(!driver) return false; - - // NSLog(@"NSEvent in GlWndProc %@", e); switch([e type]) { - /* TODO handle window move, resize, activate, close, etc. */ + /* TODO handle window activate, close, etc. */ default: return driver->_EventEmitter.processMessage(e); } @@ -941,6 +942,9 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re if(!_glView) nlerror("cannot create view"); + // tell the view about the driver so the view is able to update "window" size + [_glView setDriver:this]; + // make the view automatically fit the super view [_glView setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; @@ -1401,6 +1405,9 @@ bool CDriverGL::createWindow(const GfxMode &mode) nlerror("cannot create cocoa window"); return false; } + + // set the delegate which will handle window move events + [cocoa_window setDelegate:[[CocoaWindowDelegate alloc] initWithDriver:this]]; // set the window to non transparent [cocoa_window setOpaque:YES]; @@ -1502,8 +1509,9 @@ bool CDriverGL::destroyWindow() if(_DestroyWindow) { - [containerView() release]; [[containerView() window] release]; + [containerView() release]; + [_glView release]; } _ctx = nil; @@ -2134,9 +2142,6 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y) SetWindowPos(_win, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); #elif defined(NL_OS_MAC) - - nldebug("setting window pos to %d %d", x, y); - // get the rect (position, size) of the screen with menu bar NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; @@ -2416,38 +2421,6 @@ void CDriverGL::getWindowSize(uint32 &width, uint32 &height) { H_AUTO_OGL(CDriverGL_getWindowSize) -#ifdef NL_OS_MAC - - // TODO set them in windowproc, so no special impl is needed here - - // 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 - // the image from the rendered resolution to the view's resolution is done - // by cocoa automatically while flushing buffers. - // That's why, in fullscreen mode, return the resolution of the back buffer, - // not the one from the window. - - // in fullscreen mode - if([containerView() isInFullScreenMode]) - { - // use the size stored in setWindowSize() - width = _backBufferWidth; - height = _backBufferHeight; - } - - // in windowed mode - else - { - // use the size of the view - NSRect rect = [containerView() frame]; - width = rect.size.width; - height = rect.size.height; - } - -#else // NL_OS_MAC - - // Off-screen rendering ? if (_OffScreen) { #ifdef NL_OS_WINDOWS @@ -2460,11 +2433,17 @@ void CDriverGL::getWindowSize(uint32 &width, uint32 &height) } else { +#ifdef NL_OS_MAC + if([containerView() isInFullScreenMode]) + { + width = _backBufferWidth; + height = _backBufferHeight; + return; + } +#endif width = _WindowWidth; height = _WindowHeight; } - -#endif // NL_OS_MAC } void CDriverGL::setWindowSize(uint32 width, uint32 height) @@ -2497,14 +2476,14 @@ void CDriverGL::setWindowSize(uint32 width, uint32 height) #elif defined(NL_OS_MAC) - // for fullscreen mode, adjust the back buffer size to the desired resolution + // for fullscreen mode, adjust the back buffer size to desired resolution if([containerView() isInFullScreenMode]) { // disable and re-enable fullscreen // fixes #1062 (http://dev.ryzom.com/issues/1062) setWindowStyle(EWSWindowed); setWindowStyle(EWSFullscreen); - + // set the back buffer manually to match the desired rendering resolution GLint dim[2] = { width, height }; CGLError error = CGLSetParameter( @@ -2515,8 +2494,8 @@ void CDriverGL::setWindowSize(uint32 width, uint32 height) nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)", CGLErrorString(error)); - _backBufferWidth = width; _backBufferHeight = height; + _backBufferWidth = width; } else { @@ -2568,23 +2547,6 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y) { H_AUTO_OGL(CDriverGL_getWindowPos) -#ifdef NL_OS_MAC - // TODO set them in window proc so no special impl is needed here - - // 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 = [[containerView() window] frame]; - - // simply return x - x = windowRect.origin.x; - - // map y from cocoa to NeL coordinates before returning - y = screenRect.size.height - windowRect.size.height - windowRect.origin.y; - -#else // NL_OS_MAC - // Off-screen rendering ? if (_OffScreen) { @@ -2598,8 +2560,6 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y) y = _WindowY; } } - -#endif // NL_OS_MAC } // -------------------------------------------------- diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp index 9d126deea..f1c5e2ad9 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp @@ -149,11 +149,13 @@ static NLMISC::TKey virtualKeycodeToNelKey(unsigned short keycode) bool CCocoaEventEmitter::pasteTextFromClipboard(ucstring &text) { +#warning "OpenGL Driver: Missing Mac Implementation for pasteTextFromClipboard" return false; } bool CCocoaEventEmitter::copyTextToClipboard(const ucstring &text) { +#warning "OpenGL Driver: Missing Mac Implementation for copyTextToClipboard" return false; } @@ -406,7 +408,7 @@ bool CCocoaEventEmitter::processMessage(NSEvent* event, CEventServer* server) return true; } -typedef bool (*cocoaProc)(NL3D::IDriver*, void* e); +typedef bool (*cocoaProc)(NL3D::IDriver*, NSEvent* e); void CCocoaEventEmitter::submitEvents(CEventServer& server, bool /* allWins */) { diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h index 1ba60d77b..806bb4d2c 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h @@ -52,7 +52,9 @@ public: virtual void emulateMouseRawMode(bool enable); virtual bool copyTextToClipboard(const ucstring &text); - virtual bool pasteTextFromClipboard(ucstring &text);}; + virtual bool pasteTextFromClipboard(ucstring &text); +}; + } #endif diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.h b/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.h index 1a4bc76f0..f314d203f 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.h +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.h @@ -18,14 +18,22 @@ #import +namespace NL3D { + class CDriverGL; + void viewDidResize(NSView*, CDriverGL*); +} + @interface CocoaOpenGLView : NSOpenGLView { - NSMutableAttributedString* characterStorage; - NSRange markedRange; + NSMutableAttributedString* _characterStorage; + NSRange _markedRange; + NL3D::CDriverGL* _driver; } -(id)initWithFrame:(NSRect)frame; -(void)dealloc; -(void)keyDown:(NSEvent*)event; +-(void)setDriver:(NL3D::CDriverGL*)driver; +-(void)resizeWithOldSuperviewSize:(NSSize)oldBoundsSize; @end diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.m b/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.m index cc0a83800..ab014f5c3 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.m +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.m @@ -16,15 +16,30 @@ // along with this program. If not, see . */ +#include "../driver_opengl.h" + #import "cocoa_opengl_view.h" +#include + +namespace NL3D { + void viewDidResize(NSView* view, CDriverGL* driver) + { + NSRect rect = [[view superview] frame]; + driver->_WindowWidth = rect.size.width; + driver->_WindowHeight = rect.size.height; + } +} + + @implementation CocoaOpenGLView -(id)initWithFrame:(NSRect)frame { if((self = [super initWithFrame:frame])) { - characterStorage = [[NSMutableAttributedString alloc] initWithString:@""]; + _characterStorage = [[NSMutableAttributedString alloc] initWithString:@""]; + _driver = nil; return self; } return nil; @@ -32,7 +47,7 @@ -(void)dealloc { - [characterStorage release]; + [_characterStorage release]; [super dealloc]; } @@ -43,17 +58,32 @@ #endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER } +-(void)setDriver:(NL3D::CDriverGL*)driver +{ + _driver = driver; +} + +-(void)resizeWithOldSuperviewSize:(NSSize)oldBoundsSize +{ + [super resizeWithOldSuperviewSize:oldBoundsSize]; + + if(!_driver) + return; + + NL3D::viewDidResize(self, _driver); +} + /******************************************************************************/ /* NSTextInputClient Protocol */ -(BOOL)hasMarkedText { - return (markedRange.location == NSNotFound ? NO : YES); + return (_markedRange.location == NSNotFound ? NO : YES); } -(NSRange)markedRange { - return markedRange; + return _markedRange; } -(NSRange)selectedRange @@ -66,24 +96,24 @@ replacementRange:(NSRange)replacementRange { if(replacementRange.location == NSNotFound) - replacementRange = markedRange; + replacementRange = _markedRange; if([aString length] == 0) { - [characterStorage deleteCharactersInRange:replacementRange]; + [_characterStorage deleteCharactersInRange:replacementRange]; [self unmarkText]; } else { - markedRange = NSMakeRange(replacementRange.location, [aString length]); - [characterStorage replaceCharactersInRange:replacementRange + _markedRange = NSMakeRange(replacementRange.location, [aString length]); + [_characterStorage replaceCharactersInRange:replacementRange withString:aString]; } } -(void)unmarkText { - markedRange = NSMakeRange(NSNotFound, 0); + _markedRange = NSMakeRange(NSNotFound, 0); [[self inputContext] discardMarkedText]; } @@ -96,16 +126,16 @@ -(NSAttributedString*)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { - return [characterStorage attributedSubstringFromRange:aRange]; + return [_characterStorage attributedSubstringFromRange:aRange]; } -(void)insertText:(id)aString replacementRange:(NSRange)replacementRange { if(replacementRange.location == NSNotFound) - replacementRange = markedRange; + replacementRange = _markedRange; - [characterStorage replaceCharactersInRange:replacementRange + [_characterStorage replaceCharactersInRange:replacementRange withString:aString]; } diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.h b/code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.h new file mode 100644 index 000000000..c439c363d --- /dev/null +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.h @@ -0,0 +1,35 @@ +/* +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ + +#import + +namespace NL3D { + class CDriverGL; + void windowDidMove(NSWindow*, NL3D::CDriverGL*); +} + + +@interface CocoaWindowDelegate : NSObject +{ + NL3D::CDriverGL* _driver; +} + +- (id)initWithDriver:(NL3D::CDriverGL*)driver; +- (void)windowDidMove:(NSNotification*)notification; + +@end diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.mm b/code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.mm new file mode 100644 index 000000000..6a7ce4c4c --- /dev/null +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.mm @@ -0,0 +1,62 @@ +/* +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ + +#include "../driver_opengl.h" + +#import "cocoa_window_delegate.h" + +namespace NL3D { + void windowDidMove(NSWindow* window, NL3D::CDriverGL* driver) + { + // 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 = [window frame]; + + // set x in driver + driver->_WindowX = windowRect.origin.x; + + // map y from cocoa to NeL coordinates before setting in driver + driver->_WindowY = + screenRect.size.height - windowRect.size.height - windowRect.origin.y; + } +} + +@implementation CocoaWindowDelegate + +-(id)initWithDriver:(NL3D::CDriverGL*)driver +{ + if((self = [super init])) + { + _driver = driver; + return self; + } + + return nil; +} + +-(void)windowDidMove:(NSNotification *)notification +{ + if(!_driver) + return; + + NL3D::windowDidMove([notification object], _driver); +} + +@end