Changed: #1060 Implement getWndProc() on Mac OS X
This commit is contained in:
parent
254fb2ce97
commit
a4c9a84d1e
10 changed files with 186 additions and 85 deletions
|
@ -187,7 +187,6 @@ CDriverGL::CDriverGL()
|
|||
|
||||
_ctx = nil;
|
||||
_glView = nil;
|
||||
|
||||
_backBufferHeight = 0;
|
||||
_backBufferWidth = 0;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#ifdef NL_OS_WINDOWS
|
||||
# include <windowsx.h>
|
||||
#elif defined(NL_OS_MAC)
|
||||
# import "mac/cocoa_window_delegate.h"
|
||||
#elif defined (NL_OS_UNIX)
|
||||
# include <GL/gl.h>
|
||||
# include <GL/glx.h>
|
||||
|
@ -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];
|
||||
|
||||
|
@ -1402,6 +1406,9 @@ bool CDriverGL::createWindow(const GfxMode &mode)
|
|||
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,7 +2476,7 @@ 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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
|
|
|
@ -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 */)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,14 +18,22 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
namespace NL3D {
|
||||
class CDriverGL;
|
||||
void viewDidResize(NSView*, CDriverGL*);
|
||||
}
|
||||
|
||||
@interface CocoaOpenGLView : NSOpenGLView<NSTextInputClient>
|
||||
{
|
||||
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
|
||||
|
|
|
@ -16,15 +16,30 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../driver_opengl.h"
|
||||
|
||||
#import "cocoa_opengl_view.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
|
|
35
code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.h
Normal file
35
code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
namespace NL3D {
|
||||
class CDriverGL;
|
||||
void windowDidMove(NSWindow*, NL3D::CDriverGL*);
|
||||
}
|
||||
|
||||
|
||||
@interface CocoaWindowDelegate : NSObject<NSWindowDelegate>
|
||||
{
|
||||
NL3D::CDriverGL* _driver;
|
||||
}
|
||||
|
||||
- (id)initWithDriver:(NL3D::CDriverGL*)driver;
|
||||
- (void)windowDidMove:(NSNotification*)notification;
|
||||
|
||||
@end
|
62
code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.mm
Normal file
62
code/nel/src/3d/driver/opengl/mac/cocoa_window_delegate.mm
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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
|
Loading…
Reference in a new issue