Changed: #947 showCursor, setMousePos, improved window move, useOptimizedDrawing:YES, cleaned up comments

This commit is contained in:
rti 2010-06-09 23:15:14 +02:00
parent b9e7923226
commit cfecd694b9
7 changed files with 145 additions and 28 deletions

View file

@ -1006,8 +1006,8 @@ bool CDriverGL::release()
} }
#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"); NL3D::MAC::release();
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
if(_FullScreen) if(_FullScreen)

View file

@ -1288,8 +1288,8 @@ void CDriverGL::showCursor(bool b)
; ;
} }
#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"); NL3D::MAC::showCursor(b);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
@ -1335,8 +1335,8 @@ void CDriverGL::setMousePos(float x, float y)
SetCursorPos(pt.x, pt.y); SetCursorPos(pt.x, pt.y);
} }
#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"); NL3D::MAC::setMousePos(x, y);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
XWindowAttributes xwa; XWindowAttributes xwa;
@ -1459,8 +1459,8 @@ void CDriverGL::setCapture (bool b)
*/ */
#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"); NL3D::MAC::setCapture(b);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)

View file

@ -73,6 +73,18 @@ void setWindowTitle(const ucstring &title);
/// mac specific stuff while calling CDriverGL::swapBuffers() /// mac specific stuff while calling CDriverGL::swapBuffers()
void swapBuffers(); void swapBuffers();
/// mac specific stuff while calling CDriverGL::setCapture()
void setCapture(bool b);
/// mac specific stuff while calling CDriverGL::showCursor()
void showCursor(bool b);
/// mac specific stuff while calling CDriverGL::setMousePos()
void setMousePos(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,
bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter); bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter);

View file

@ -74,6 +74,10 @@ bool init(uint windowIcon, emptyProc exitFunc)
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable) bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
{ {
/*
TODO use show and resizable flags
*/
// create a cocoa window with the size provided by the mode parameter // create a cocoa window with the size provided by the mode parameter
g_window = [[CocoaWindow alloc] g_window = [[CocoaWindow alloc]
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height) initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
@ -126,6 +130,9 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
// enable mouse move events, NeL wants them // enable mouse move events, NeL wants them
[g_window setAcceptsMouseMovedEvents:YES]; [g_window setAcceptsMouseMovedEvents:YES];
// there are no overlapping subview, 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]; g_glctx = [g_glview openGLContext];
@ -138,6 +145,9 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
// put the window to the front and make it the key window // put the window to the front and make it the key window
[g_window makeKeyAndOrderFront:nil]; [g_window makeKeyAndOrderFront:nil];
// this is our main window
[g_window makeMainWindow];
// tell the application that we are running now // tell the application that we are running now
[g_app finishLaunching]; [g_app finishLaunching];
@ -168,11 +178,11 @@ bool setMode(const GfxMode& mode)
// leave fullscreen mode, enter windowed mode // leave fullscreen mode, enter windowed mode
if(mode.Windowed && [g_glview isInFullScreenMode]) if(mode.Windowed && [g_glview isInFullScreenMode])
{ {
// pull the view back from fullscreen restoring windows options // pull the view back from fullscreen restoring window options
[g_glview exitFullScreenModeWithOptions:nil]; [g_glview exitFullScreenModeWithOptions:nil];
// 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 window gets resized // automatically as soon as the view gets resized
CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj], CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj],
kCGLCESurfaceBackingSize); kCGLCESurfaceBackingSize);
@ -197,7 +207,7 @@ bool setMode(const GfxMode& mode)
// NOTE: withOptions:nil disables <CMD>+<Tab> application switching! // NOTE: withOptions:nil disables <CMD>+<Tab> application switching!
/* /*
TODO check if simply using NSView enterFullScreenMode is a good idea. TODO check if simply using NSView enterFullScreenMode is a good idea.
the context can be set to full screen as well? performance differences? the context can be set to full screen as well, performance differences?
*/ */
[g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions: [g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions:
[NSDictionary dictionaryWithObjectsAndKeys: [NSDictionary dictionaryWithObjectsAndKeys:
@ -207,8 +217,8 @@ bool setMode(const GfxMode& mode)
NSFullScreenModeApplicationPresentationOptions, nil]]; NSFullScreenModeApplicationPresentationOptions, nil]];
} }
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND #ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
// due to the back buffer size reading problem, just store the size
g_bufferSize[0] = mode.Width; g_bufferSize[0] = mode.Width;
g_bufferSize[1] = mode.Height; g_bufferSize[1] = mode.Height;
#endif #endif
@ -226,11 +236,9 @@ void getWindowSize(uint32 &width, uint32 &height)
// 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
// the image from the rendered resolution to the view's resolution is done // the image from the rendered resolution to the view's resolution is done
// by cocoa automatically while flushing buffers. // by cocoa automatically while flushing buffers.
// That's why, in fullscreen mode, return the resolution from 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.
// check if manual back buffer sizing is enabled (thats only in fullscreen)
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND #ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
if([g_glview isInFullScreenMode]) if([g_glview isInFullScreenMode])
{ {
@ -244,10 +252,10 @@ void getWindowSize(uint32 &width, uint32 &height)
height = rect.size.height; height = rect.size.height;
} }
#else #else
/* /*
TODO does not work atm, "invalid enumeration" TODO does not work atm, "invalid enumeration"
*/ */
// check if manual back buffer sizing is enabled (thats only in fullscreen)
GLint surfaceBackingSizeSet = 0; GLint surfaceBackingSizeSet = 0;
CGLError error = CGLIsEnabled((CGLContextObj)[g_glctx CGLContextObj], CGLError error = CGLIsEnabled((CGLContextObj)[g_glctx CGLContextObj],
kCGLCESurfaceBackingSize, &surfaceBackingSizeSet); kCGLCESurfaceBackingSize, &surfaceBackingSizeSet);
@ -291,10 +299,10 @@ void getWindowSize(uint32 &width, uint32 &height)
void getWindowPos(uint32 &x, uint32 &y) void getWindowPos(uint32 &x, uint32 &y)
{ {
// get the size of the screen // get the rect (position, size) of the screen
NSRect screenRect = [[g_window screen] frame]; NSRect screenRect = [[g_window screen] frame];
// get the size of the window // get the rect (position, size) of the window
NSRect windowRect = [g_window frame]; NSRect windowRect = [g_window frame];
// simply return x // simply return x
@ -331,6 +339,92 @@ void swapBuffers()
[g_glctx flushBuffer]; [g_glctx flushBuffer];
} }
void setCapture(bool b)
{
/*
TODO implement capture cursor, no need to fake using pull back to 0.5 / 0.5
set a flag and then act accordingly in event loop?
// no screen bounds...
void CGGetLastMouseDelta(CGMouseDelta* deltaX, CGMouseDelta* deltaY);
*/
nlwarning("not implemented");
}
void showCursor(bool b)
{
// 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.
// Since other platforms seem to not do this, the functionality is masked here
// by only calling hide if the cursor is visible and only calling show if
// the cursor was hidden.
CGDisplayErr error = kCGErrorSuccess;
static bool visible = true;
if(b && !visible)
{
error = CGDisplayShowCursor(kCGDirectMainDisplay);
visible = true;
}
else if(!b && visible)
{
error = CGDisplayHideCursor(kCGDirectMainDisplay);
visible = false;
}
if(error != kCGErrorSuccess)
nlerror("cannot get capture / un-capture cursor");
}
void setMousePos(float x, float y)
{
// CG wants absolute coordinates related to screen top left
CGFloat fromScreenLeft = 0.0;
CGFloat fromScreenTop = 0.0;
// get the gl view's rect for height and width
NSRect viewRect = [g_glview frame];
// if the view is not fullscreen, window top left is needed as offset
if(![g_glview isInFullScreenMode])
{
// get the rect (position, size) of the screen
NSRect screenRect = [[g_window screen] frame];
// get the rect (position, size) of the window
NSRect windowRect = [g_window frame];
// window's x is ok
fromScreenLeft = windowRect.origin.x;
// TODO this code assumes, that the view fills the window
// map window bottom to view top
fromScreenTop = screenRect.size.height -
viewRect.size.height - windowRect.origin.y;
}
// position inside the view
fromScreenLeft += (viewRect.size.width * x);
fromScreenTop += (viewRect.size.height * (1 - y));
// actually set the mouse position
CGDisplayErr error = CGDisplayMoveCursorToPoint(
kCGDirectMainDisplay, CGPointMake(fromScreenLeft, fromScreenTop));
if(error != kCGErrorSuccess)
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
@ -552,10 +646,19 @@ void submitEvents(NLMISC::CEventServer& server,
// get the views size // get the views size
NSRect rect = [g_glview frame]; NSRect rect = [g_glview frame];
// 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)rect.size.width;
float mouseY = event.locationInWindow.y / (float)rect.size.height; float mouseY = event.locationInWindow.y / (float)rect.size.height;
// if the mouse event was placed on the window's titlebar, ignore it
if(mouseY > 1.0 && event.type != NSKeyDown && event.type != NSKeyUp)
{
[g_app sendEvent:event];
[g_app updateWindows];
continue;
}
switch(event.type) switch(event.type)
{ {
case NSLeftMouseDown: case NSLeftMouseDown:
@ -597,6 +700,8 @@ void submitEvents(NLMISC::CEventServer& server,
/* /*
TODO modifiers with mouse events TODO modifiers with mouse events
*/ */
// nldebug("mouse left drag %f %f", mouseX, mouseY);
server.postEvent(new NLMISC::CEventMouseMove( server.postEvent(new NLMISC::CEventMouseMove(
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter)); mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
break; break;

View file

@ -35,6 +35,7 @@
[characterStorage release]; [characterStorage release];
[super dealloc]; [super dealloc];
} }
-(BOOL)acceptsFirstResponder -(BOOL)acceptsFirstResponder
{ {
return YES; return YES;

View file

@ -66,7 +66,7 @@ bool SetMousePosFirstTime = true;
uint DownMouseButtons = 0; uint DownMouseButtons = 0;
#ifdef NL_OS_UNIX #ifdef NL_OS_UNIX
// on X11, store whether the mouse was captured or not // on X11 and cocoa, store whether the mouse was captured or not
bool MouseCapture = false; bool MouseCapture = false;
#endif #endif
@ -251,8 +251,8 @@ void SetMouseFreeLook ()
} }
#ifdef NL_OS_UNIX #ifdef NL_OS_UNIX
// on X11 the mouse needs to get pulled into the middle each update, else // on X11 and cocoa the mouse needs to get pulled into the middle each update,
// the cursor would reach the border of the window / desktop // else the cursor would reach the border of the window / desktop
// and freelook would hang // and freelook would hang
Driver->setMousePos(0.5f, 0.5f); Driver->setMousePos(0.5f, 0.5f);
#endif #endif
@ -373,7 +373,7 @@ void CaptureSystemCursor()
if (!drvWnd) return; if (!drvWnd) return;
SetCapture(drvWnd); SetCapture(drvWnd);
#else #else
// on X11, set driver mouse capture on and store it locally as well // on X11 and cocoa, set driver mouse capture on and store it locally as well
Driver->setCapture(MouseCapture = true); Driver->setCapture(MouseCapture = true);
#endif #endif
} }
@ -392,7 +392,7 @@ void ReleaseSystemCursor()
} }
ReleaseCapture(); ReleaseCapture();
#else #else
// on X11, set driver mouse capture off and store it locally as well // on X11 and cocoa, set driver mouse capture off and store it locally as well
Driver->setCapture(MouseCapture = false); Driver->setCapture(MouseCapture = false);
#endif #endif
} }

View file

@ -458,25 +458,24 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy)
{ {
float dmpx, dmpy; float dmpx, dmpy;
#ifndef NL_MAC_NATIVE // On X11 and Cocoa in free look mode, the mouse is pulled back to (0.5, 0.5)
// On X11 in free look mode, the mouse is pulled back to (0.5, 0.5)
// every update to prevent reaching a border and get stuck. // every update to prevent reaching a border and get stuck.
if(IsMouseFreeLook()) if(IsMouseFreeLook())
{ {
/* /*
TODO use setCapture to not fake it TODO on X11, use setCapture to not fake it, capture on mac?
*/ */
dmpx = EventsListener.getMousePosX() - 0.5; dmpx = EventsListener.getMousePosX() - 0.5;
dmpy = EventsListener.getMousePosY() - 0.5; dmpy = EventsListener.getMousePosY() - 0.5;
} }
else else
#endif
{ {
dmpx = EventsListener.getMousePosX() - _LastFrameMousePosX; dmpx = EventsListener.getMousePosX() - _LastFrameMousePosX;
dmpy = EventsListener.getMousePosY() - _LastFrameMousePosY; dmpy = EventsListener.getMousePosY() - _LastFrameMousePosY;
} }
// TODO: read desktop mouse speed value on X11 / implement X11MouseDevice // TODO: read desktop mouse speed value on X11 and Cocoa
// implement X11MouseDevice/CocoaMouseDevice?
dmpx *= 450.0f; dmpx *= 450.0f;
dmpy *= 450.0f; dmpy *= 450.0f;