From f664148e27b478787f6be549cd57eb0098c00db0 Mon Sep 17 00:00:00 2001 From: mantognini Date: Wed, 9 Feb 2011 11:50:25 +0000 Subject: [PATCH] Fix GetFullscreenModes : no more returns only desktop mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix fullscreen window by setting up a desktop-wide window and resizing the context's backbuffer. Fix mouse coordinate for fullscreen window. Fix window sending 5 event when resized. Better fix for TextEntered event – no more relies on documentation but on current implementation of the system. Update some obj-classes structures. (Mostly improved the code structure.) Update © date and some comments. git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1792 4e206d99-4929-0410-ac5d-dfc041789085 --- .../Graphics/OSX/RenderImageImplPBuffer.cpp | 2 +- .../Graphics/OSX/RenderImageImplPBuffer.hpp | 2 +- src/SFML/Window/CMakeLists.txt | 4 +- src/SFML/Window/OSX/Joystick.cpp | 2 +- src/SFML/Window/OSX/Joystick.hpp | 2 +- src/SFML/Window/OSX/SFApplication.h | 4 +- src/SFML/Window/OSX/SFApplication.m | 2 +- src/SFML/Window/OSX/SFContext.hpp | 8 +- src/SFML/Window/OSX/SFContext.mm | 17 +- src/SFML/Window/OSX/SFOpenGLView.h | 39 +++- src/SFML/Window/OSX/SFOpenGLView.mm | 216 ++++++++++++++---- src/SFML/Window/OSX/SFWindow.h | 16 +- src/SFML/Window/OSX/SFWindow.m | 2 +- src/SFML/Window/OSX/SFWindowController.h | 24 +- src/SFML/Window/OSX/SFWindowController.mm | 126 +++++++--- src/SFML/Window/OSX/VideoModeImpl.cpp | 107 ++++----- src/SFML/Window/OSX/WindowImplCocoa.hpp | 164 +++++++++++-- src/SFML/Window/OSX/WindowImplCocoa.mm | 12 +- .../Window/OSX/WindowImplDelegateProtocol.h | 48 +++- src/SFML/Window/OSX/cg_sf_conversion.cpp | 181 +++++++++++++++ src/SFML/Window/OSX/cg_sf_conversion.hpp | 82 +++++++ src/SFML/Window/OSX/cpp_objc_conversion.h | 3 +- src/SFML/Window/OSX/cpp_objc_conversion.mm | 2 +- 23 files changed, 862 insertions(+), 203 deletions(-) create mode 100644 src/SFML/Window/OSX/cg_sf_conversion.cpp create mode 100644 src/SFML/Window/OSX/cg_sf_conversion.hpp diff --git a/src/SFML/Graphics/OSX/RenderImageImplPBuffer.cpp b/src/SFML/Graphics/OSX/RenderImageImplPBuffer.cpp index daff1fb57..4b193e48f 100644 --- a/src/SFML/Graphics/OSX/RenderImageImplPBuffer.cpp +++ b/src/SFML/Graphics/OSX/RenderImageImplPBuffer.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. diff --git a/src/SFML/Graphics/OSX/RenderImageImplPBuffer.hpp b/src/SFML/Graphics/OSX/RenderImageImplPBuffer.hpp index 22ffdcac2..a4b3572c3 100644 --- a/src/SFML/Graphics/OSX/RenderImageImplPBuffer.hpp +++ b/src/SFML/Graphics/OSX/RenderImageImplPBuffer.hpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index d8b8b0842..ba306d76a 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -51,7 +51,9 @@ else() # MACOSX set(SRC ${SRC} ${SRCROOT}/OSX/cpp_objc_conversion.h - ${SRCROOT}/OSX/cpp_objc_conversion.mm + ${SRCROOT}/OSX/cpp_objc_conversion.mm + ${SRCROOT}/OSX/cg_sf_conversion.hpp + ${SRCROOT}/OSX/cg_sf_conversion.cpp ${SRCROOT}/OSX/Joystick.cpp ${SRCROOT}/OSX/Joystick.hpp ${SRCROOT}/OSX/SFApplication.h diff --git a/src/SFML/Window/OSX/Joystick.cpp b/src/SFML/Window/OSX/Joystick.cpp index 8a1d375c0..88c0c92cf 100644 --- a/src/SFML/Window/OSX/Joystick.cpp +++ b/src/SFML/Window/OSX/Joystick.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. diff --git a/src/SFML/Window/OSX/Joystick.hpp b/src/SFML/Window/OSX/Joystick.hpp index ec616164c..51920fd2d 100644 --- a/src/SFML/Window/OSX/Joystick.hpp +++ b/src/SFML/Window/OSX/Joystick.hpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. diff --git a/src/SFML/Window/OSX/SFApplication.h b/src/SFML/Window/OSX/SFApplication.h index 2cfe04ed2..92338fea3 100644 --- a/src/SFML/Window/OSX/SFApplication.h +++ b/src/SFML/Window/OSX/SFApplication.h @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -30,6 +30,7 @@ //////////////////////////////////////////////////////////// /// \brief Event processing +/// //////////////////////////////////////////////////////////// @interface SFApplication : NSObject @@ -38,6 +39,7 @@ /// \brief Event processing /// /// \param block blocking mode means at least one event is proccessed. +/// //////////////////////////////////////////////////////////// +(void)processEventWithBlockingMode:(BOOL)block; diff --git a/src/SFML/Window/OSX/SFApplication.m b/src/SFML/Window/OSX/SFApplication.m index 4c2d49eba..0cee6045b 100644 --- a/src/SFML/Window/OSX/SFApplication.m +++ b/src/SFML/Window/OSX/SFApplication.m @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. diff --git a/src/SFML/Window/OSX/SFContext.hpp b/src/SFML/Window/OSX/SFContext.hpp index a7f81f245..19483335c 100644 --- a/src/SFML/Window/OSX/SFContext.hpp +++ b/src/SFML/Window/OSX/SFContext.hpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -122,13 +122,13 @@ private: /// \note Must only be called from Ctor. /// /// \param shared Context to share the new one with (can be NULL) - /// \param settings Creation parameters /// \param bitsPerPixel bpp + /// \param settings Creation parameters /// //////////////////////////////////////////////////////////// void CreateContext(SFContext* shared, - const ContextSettings& settings, - unsigned int bitsPerPixel); + unsigned int bitsPerPixel, + const ContextSettings& settings); //////////////////////////////////////////////////////////// // Member data diff --git a/src/SFML/Window/OSX/SFContext.mm b/src/SFML/Window/OSX/SFContext.mm index deb2a4122..3e5b120cf 100644 --- a/src/SFML/Window/OSX/SFContext.mm +++ b/src/SFML/Window/OSX/SFContext.mm @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -56,7 +56,7 @@ SFContext::SFContext(SFContext* shared) myPool = [[NSAutoreleasePool alloc] init]; // Create the context - CreateContext(shared, ContextSettings(0, 0, 0), 0); + CreateContext(shared, 0, ContextSettings(0, 0, 0)); } @@ -67,7 +67,7 @@ SFContext::SFContext(SFContext* shared, const WindowImpl* owner, myPool = [[NSAutoreleasePool alloc] init]; // Create the context. - CreateContext(shared, settings, bitsPerPixel); + CreateContext(shared, bitsPerPixel, settings); // Apply context. WindowImplCocoa const * ownerCocoa = static_cast(owner); @@ -82,7 +82,7 @@ SFContext::~SFContext() [myPool drain]; // [A] /* - [A] : Produce sometimes "*** attempt to pop an unknown autorelease pool" + * [A] : Produce sometimes "*** attempt to pop an unknown autorelease pool" */ } @@ -117,16 +117,15 @@ void SFContext::EnableVerticalSync(bool enabled) //////////////////////////////////////////////////////////// -void SFContext::CreateContext(SFContext* shared, - const ContextSettings& settings, - unsigned int bitsPerPixel) +void SFContext::CreateContext(SFContext* shared, + unsigned int bitsPerPixel, + const ContextSettings& settings) { // Choose the attributs of OGL context. std::vector attrs; attrs.reserve(20); // max attributs (estimation). - // These casts are safe. C++ is much more stric than Obj-C. - + // These casts are safe. C++ is much more strict than Obj-C. attrs.push_back(NSOpenGLPFAClosestPolicy); attrs.push_back(NSOpenGLPFADoubleBuffer); diff --git a/src/SFML/Window/OSX/SFOpenGLView.h b/src/SFML/Window/OSX/SFOpenGLView.h index 82e21835c..a27d7e652 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.h +++ b/src/SFML/Window/OSX/SFOpenGLView.h @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -38,23 +38,48 @@ namespace sf { /// \brief Spesialized NSOpenGLView /// /// Handle event and send them back to the requester. +/// +/// In order to send correct mouse coordonate to the requester when +/// the window is in fullscreen we use myRealSize to represent the +/// back buffer size (see SFWindowController). If 'myRealSize' is +/// bound to its default value we don't recompute the mouse position +/// and assume it's correct. +/// //////////////////////////////////////////////////////////// @interface SFOpenGLView : NSOpenGLView { sf::priv::WindowImplCocoa* myRequester; BOOL myUseKeyRepeat; NSTrackingRectTag myTrackingTag; BOOL myMouseIsIn; + NSSize myRealSize; } - +//////////////////////////////////////////////////////////// +/// Create the SFML opengl view to fit the given area. +/// +//////////////////////////////////////////////////////////// -(id)initWithFrame:(NSRect)frameRect; --(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester; +//////////////////////////////////////////////////////////// +/// Apply the given resquester to the view. +/// +//////////////////////////////////////////////////////////// +-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester; + +//////////////////////////////////////////////////////////// +/// Set the real size of view (it should be the back buffer size). +/// If not set, or set to its default value NSZeroSize, the view +/// won't recompute the mouse coordinates before sending them +/// to the requester. +/// +//////////////////////////////////////////////////////////// +-(void)setRealSize:(NSSize)newSize; + +//////////////////////////////////////////////////////////// +/// Adjust key repeat configuration. +/// +//////////////////////////////////////////////////////////// -(void)enableKeyRepeat; -(void)disableKeyRepeat; --(void)frameDidChange:(NSNotification*)notification; - --(BOOL)isMouseInside; - @end diff --git a/src/SFML/Window/OSX/SFOpenGLView.mm b/src/SFML/Window/OSX/SFOpenGLView.mm index 7a078de71..90995ae34 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.mm +++ b/src/SFML/Window/OSX/SFOpenGLView.mm @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -30,6 +30,26 @@ #import +//////////////////////////////////////////////////////////// +/// SFOpenGLView class : Privates Methods Declaration +/// +//////////////////////////////////////////////////////////// +@interface SFOpenGLView () + +//////////////////////////////////////////////////////////// +/// Handle view resized event. +/// +//////////////////////////////////////////////////////////// +-(void)frameDidChange:(NSNotification *)notification; + +//////////////////////////////////////////////////////////// +/// Establish if the mouse is inside or outside the OpenGL view. +/// +//////////////////////////////////////////////////////////// +-(BOOL)isMouseInside; + +@end + @implementation SFOpenGLView #pragma mark @@ -42,6 +62,8 @@ [self setRequesterTo:0]; [self enableKeyRepeat]; + myRealSize = NSZeroSize; + // Register for mouse-move event myMouseIsIn = [self isMouseInside]; myTrackingTag = [self addTrackingRect:[self frame] @@ -51,10 +73,10 @@ // Register for resize event NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center addObserver:self + [center addObserver:self selector:@selector(frameDidChange:) name:NSViewFrameDidChangeNotification - object:nil]; + object:self]; } return self; @@ -62,12 +84,19 @@ //////////////////////////////////////////////////////// --(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester +-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester { myRequester = requester; } +//////////////////////////////////////////////////////// +-(void)setRealSize:(NSSize)newSize +{ + myRealSize = newSize; +} + + //////////////////////////////////////////////////////// -(void)enableKeyRepeat { @@ -83,7 +112,7 @@ //////////////////////////////////////////////////////// --(void)frameDidChange:(NSNotification*)notification +-(void)frameDidChange:(NSNotification *)notification { // Adapt tracking area for mouse mouse event. [self removeTrackingRect:myTrackingTag]; @@ -154,11 +183,12 @@ //////////////////////////////////////////////////////// --(void)mouseDown:(NSEvent*)theEvent +-(void)mouseDown:(NSEvent *)theEvent { if (myRequester == 0) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + // Don't forget to change to SFML coord system. float h = [self frame].size.height; myRequester->MouseDownAt(sf::Mouse::Left, loc.x, h - loc.y); @@ -166,19 +196,28 @@ //////////////////////////////////////////////////////// --(void)mouseUp:(NSEvent*)theEvent +-(void)mouseUp:(NSEvent *)theEvent { if (myRequester == 0) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseUpAt(sf::Mouse::Left, loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseUpAt(sf::Mouse::Left, loc.x, loc.y); } //////////////////////////////////////////////////////// --(void)mouseMoved:(NSEvent*)theEvent +-(void)mouseMoved:(NSEvent *)theEvent { if (myRequester == 0) return; @@ -186,26 +225,44 @@ if (!myMouseIsIn) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseMovedAt(loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseMovedAt(loc.x, loc.y); } //////////////////////////////////////////////////////// --(void)scrollWheel:(NSEvent*)theEvent +-(void)scrollWheel:(NSEvent *)theEvent { if (myRequester == 0) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseWheelScrolledAt([theEvent deltaY], loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseWheelScrolledAt([theEvent deltaY], loc.x, loc.y); } //////////////////////////////////////////////////////// --(void)mouseEntered:(NSEvent*)theEvent +-(void)mouseEntered:(NSEvent *)theEvent { myMouseIsIn = YES; @@ -216,7 +273,7 @@ //////////////////////////////////////////////////////// --(void)mouseExited:(NSEvent*)theEvent +-(void)mouseExited:(NSEvent *)theEvent { myMouseIsIn = NO; @@ -227,35 +284,54 @@ //////////////////////////////////////////////////////// --(void)rightMouseDown:(NSEvent*)theEvent +-(void)rightMouseDown:(NSEvent *)theEvent { if (myRequester == 0) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseDownAt(sf::Mouse::Right, loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseDownAt(sf::Mouse::Right, loc.x, loc.y); } //////////////////////////////////////////////////////// --(void)rightMouseUp:(NSEvent*)theEvent +-(void)rightMouseUp:(NSEvent *)theEvent { if (myRequester == 0) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseUpAt(sf::Mouse::Right, loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseUpAt(sf::Mouse::Right, loc.x, loc.y); } //////////////////////////////////////////////////////// --(void)otherMouseDown:(NSEvent*)theEvent +-(void)otherMouseDown:(NSEvent *)theEvent { if (myRequester == 0) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + sf::Mouse::Button button; switch ([theEvent buttonNumber]) { case 2: @@ -270,18 +346,28 @@ default: break; } + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseDownAt(button, loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseDownAt(button, loc.x, loc.y); } //////////////////////////////////////////////////////// --(void)otherMouseUp:(NSEvent*)theEvent +-(void)otherMouseUp:(NSEvent *)theEvent { if (myRequester == 0) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + sf::Mouse::Button button; switch ([theEvent buttonNumber]) { case 2: @@ -296,14 +382,23 @@ default: break; } + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseUpAt(button, loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseUpAt(button, loc.x, loc.y); } //////////////////////////////////////////////////////// --(void)rightMouseDragged:(NSEvent*)theEvent +-(void)rightMouseDragged:(NSEvent *)theEvent { if (myRequester == 0) return; @@ -311,14 +406,23 @@ if (!myMouseIsIn) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseMovedAt(loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseMovedAt(loc.x, loc.y); } //////////////////////////////////////////////////////// --(void)mouseDragged:(NSEvent*)theEvent +-(void)mouseDragged:(NSEvent *)theEvent { if (myRequester == 0) return; @@ -326,14 +430,23 @@ if (!myMouseIsIn) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseMovedAt(loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseMovedAt(loc.x, loc.y); } //////////////////////////////////////////////////////// --(void)otherMouseDragged:(NSEvent*)theEvent +-(void)otherMouseDragged:(NSEvent *)theEvent { if (myRequester == 0) return; @@ -341,9 +454,18 @@ if (!myMouseIsIn) return; NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + // Don't forget to change to SFML coord system. float h = [self frame].size.height; - myRequester->MouseMovedAt(loc.x, h - loc.y); + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + myRequester->MouseMovedAt(loc.x, loc.y); } @@ -352,36 +474,42 @@ //////////////////////////////////////////////////////// --(void)keyDown:(NSEvent*)theEvent +-(void)keyDown:(NSEvent *)theEvent { if (myRequester == 0) return; if (myUseKeyRepeat || ![theEvent isARepeat]) myRequester->KeyDown([theEvent keyCode], [theEvent modifierFlags]); - - if ((myUseKeyRepeat || ![theEvent isARepeat]) && [[theEvent characters] length] > 0) { - /// From NSEvent.h : - /* - * Unicodes we reserve for function keys on the keyboard, - * OpenStep reserves the range 0xF700-0xF8FF for this purpose. - * The availability of various keys will be system dependent. - */ - /// And 0x35 is the Escape key. - unichar ch = [[theEvent characters] characterAtIndex:0]; - if ([theEvent keyCode] != 0x35 && - (ch < 0xf700 || ch > 0xf8ff)) { - myRequester->TextEntered(ch); - } + + if (myUseKeyRepeat || ![theEvent isARepeat]) { + // Let's see if its a valid text. + // -interpretKeyEvents: will call -insertText: if theEvent is a valid caracter. + [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; } } //////////////////////////////////////////////////////// --(void)keyUp:(NSEvent*)theEvent +-(void)keyUp:(NSEvent *)theEvent { if (myRequester == 0) return; myRequester->KeyUp([theEvent keyCode], [theEvent modifierFlags]); } + +//////////////////////////////////////////////////////// +-(void)insertText:(id)aString +{ + // aString can be either a NSString or a NSAttributedString. + if ([aString isKindOfClass:[NSAttributedString class]]) { + aString = [aString string]; // We want a NSString. + } + + if (myRequester == 0 || [aString length] == 0) return; + + // It's a valid TextEntered event. + myRequester->TextEntered([aString characterAtIndex:0]); +} + @end diff --git a/src/SFML/Window/OSX/SFWindow.h b/src/SFML/Window/OSX/SFWindow.h index 7575a06a4..eb988f810 100644 --- a/src/SFML/Window/OSX/SFWindow.h +++ b/src/SFML/Window/OSX/SFWindow.h @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -29,17 +29,19 @@ #import //////////////////////////////////////////////////////////// -/// Here we redefine some methods to allow grabing fullscreen events. +/// \brief Here we redefine some methods to allow grabing fullscreen events. +/// //////////////////////////////////////////////////////////// @interface SFWindow : NSWindow { } -/* - These two methods must return YES to grab fullscreen events. - See http://stackoverflow.com/questions/999464/fullscreen-key-down-actions - for more informations - */ +//////////////////////////////////////////////////////////// +/// These two methods must return YES to grab fullscreen events. +/// See http://stackoverflow.com/questions/999464/fullscreen-key-down-actions +/// for more informations +/// +//////////////////////////////////////////////////////////// -(BOOL)acceptsFirstResponder; -(BOOL)canBecomeKeyWindow; diff --git a/src/SFML/Window/OSX/SFWindow.m b/src/SFML/Window/OSX/SFWindow.m index a4fc488fb..f6ba6e8a7 100644 --- a/src/SFML/Window/OSX/SFWindow.m +++ b/src/SFML/Window/OSX/SFWindow.m @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. diff --git a/src/SFML/Window/OSX/SFWindowController.h b/src/SFML/Window/OSX/SFWindowController.h index 50d754f34..642a25b00 100644 --- a/src/SFML/Window/OSX/SFWindowController.h +++ b/src/SFML/Window/OSX/SFWindowController.h @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -27,7 +27,7 @@ // Headers //////////////////////////////////////////////////////////// #import - +#include //////////////////////////////////////////////////////////// /// Predefine some classes @@ -36,7 +36,6 @@ namespace sf { namespace priv { class WindowImplCocoa; } - class VideoMode; } @class SFOpenGLView; @@ -49,6 +48,9 @@ namespace sf { /// /// Used when SFML handle everything and when a NSWindow* is given /// as handle to WindowImpl. +/// +/// myFullscreenMode is bind to default video mode if we don't need to change screen size. +/// //////////////////////////////////////////////////////////// #if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 // NSWindowDelegate is only define since 10.6 @@ -59,13 +61,19 @@ namespace sf { NSWindow* myWindow; SFOpenGLView* myOGLView; sf::priv::WindowImplCocoa* myRequester; + sf::VideoMode myFullscreenMode; } --(id)initWithWindow:(NSWindow*)window; --(id)initWithMode:(sf::VideoMode const*)mode andStyle:(unsigned long)style; --(void)dealloc; +//////////////////////////////////////////////////////////// +/// Create the SFML window with an external Cocoa window. +/// +//////////////////////////////////////////////////////////// +-(id)initWithWindow:(NSWindow *)window; --(float)screenHeight; --(float)titlebarHeight; +//////////////////////////////////////////////////////////// +/// Create the SFML window "from scratch" (full SFML handling). +/// +//////////////////////////////////////////////////////////// +-(id)initWithMode:(sf::VideoMode const &)mode andStyle:(unsigned long)style; @end diff --git a/src/SFML/Window/OSX/SFWindowController.mm b/src/SFML/Window/OSX/SFWindowController.mm index e8676e698..a256ff063 100644 --- a/src/SFML/Window/OSX/SFWindowController.mm +++ b/src/SFML/Window/OSX/SFWindowController.mm @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -31,20 +31,40 @@ #include #include #include +#include #import #import #import #import +//////////////////////////////////////////////////////////// +/// SFWindowController class : Privates Methods Declaration +/// +//////////////////////////////////////////////////////////// +@interface SFWindowController () + +//////////////////////////////////////////////////////////// +/// Retrieves the screen height. +/// +//////////////////////////////////////////////////////////// +-(float)screenHeight; + +//////////////////////////////////////////////////////////// +/// Retrives the title bar height. +/// +//////////////////////////////////////////////////////////// +-(float)titlebarHeight; + +@end + @implementation SFWindowController #pragma mark #pragma mark SFWindowController's methods - //////////////////////////////////////////////////////// --(id)initWithWindow:(NSWindow*)window +-(id)initWithWindow:(NSWindow *)window { if (self = [super init]) { myRequester = 0; @@ -83,13 +103,25 @@ //////////////////////////////////////////////////////// --(id)initWithMode:(sf::VideoMode const*)mode andStyle:(unsigned long)style -{ +-(id)initWithMode:(sf::VideoMode const &)mode andStyle:(unsigned long)style +{ if (self = [super init]) { myRequester = 0; // Create our window size. - NSRect rect = NSMakeRect(0, 0, mode->Width, mode->Height); + NSRect rect = NSZeroRect; + if (style & sf::Style::Fullscreen && mode != sf::VideoMode::GetDesktopMode()) { + // We use desktop mode to size the window + // but we set the back buffer size to 'mode' in applyContext method. + + myFullscreenMode = mode; + + sf::VideoMode dm = sf::VideoMode::GetDesktopMode(); + rect = NSMakeRect(0, 0, dm.Width, dm.Height); + + } else { // no fullscreen requested. + rect = NSMakeRect(0, 0, mode.Width, mode.Height); + } // Convert the SFML window style to Cocoa window style. unsigned int nsStyle = NSBorderlessWindowMask; @@ -119,21 +151,23 @@ */ if (myWindow == nil) { - sf::Err() << "Could not create an instance of NSWindow " << "in (SFWindowController -initWithMode:andStyle:)." << std::endl; - + return self; } // Apply special feature for fullscreen window. - if (style & sf::Style::Fullscreen) { + if (style & sf::Style::Fullscreen) { // We place the window above everything else. - [myWindow setLevel:NSMainMenuWindowLevel+1]; [myWindow setOpaque:YES]; [myWindow setHidesOnDeactivate:YES]; + [myWindow setLevel:NSMainMenuWindowLevel+1]; + + // And hide the menu bar + [NSMenu setMenuBarVisible:NO]; /* --------------------------- * | Note for future version | @@ -143,16 +177,15 @@ * a new method -enterFullScreenMode:withOptions: * which could be a good alternative. */ - } else { - // Center the window to be cool =) - [myWindow center]; } + + // Center the window to be cool =) + [myWindow center]; // Create the view. myOGLView = [[SFOpenGLView alloc] initWithFrame:[[myWindow contentView] frame]]; if (myOGLView == nil) { - sf::Err() << "Could not create an instance of NSOpenGLView " << "in (SFWindowController -initWithMode:andStyle:)." @@ -161,6 +194,12 @@ return self; } + // If a fullscreen window was requested... + if (style & sf::Style::Fullscreen && mode != sf::VideoMode::GetDesktopMode()) { + /// ... we set the "read size" of the view (that is the back buffer size). + [myOGLView setRealSize:NSMakeSize(myFullscreenMode.Width, myFullscreenMode.Height)]; + } + // Set the view to the window as its content view. [myWindow setContentView:myOGLView]; @@ -194,7 +233,7 @@ //////////////////////////////////////////////////////// --(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester +-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester { // Forward to the view. [myOGLView setRequesterTo:requester]; @@ -226,9 +265,9 @@ //////////////////////////////////////////////////////// -(void)setCursorPositionToX:(unsigned int)x Y:(unsigned int)y { - // Create a SFML event. if (myRequester == 0) return; + // Create a SFML event. myRequester->MouseMovedAt(x, y); // Flip for SFML window coordinate system @@ -284,7 +323,7 @@ //////////////////////////////////////////////////////// --(void)changeTitle:(NSString*)title +-(void)changeTitle:(NSString *)title { [myWindow setTitle:title]; } @@ -330,21 +369,21 @@ //////////////////////////////////////////////////////// -(void)setIconTo:(unsigned int)width by:(unsigned int)height - with:(sf::Uint8 const*)pixels + with:(sf::Uint8 const *)pixels { // Create an empty image representation. NSBitmapImageRep* bitmap = - [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:0 // if 0 : only allocate memory - pixelsWide:width - pixelsHigh:height - bitsPerSample:8 // The number of bits used to specify - // one pixel in a single component of the data. - samplesPerPixel:4 // 3 if no alpha, 4 with it - hasAlpha:YES - isPlanar:NO // I don't know what it is but it works - colorSpaceName:NSCalibratedRGBColorSpace - bytesPerRow:0 // 0 == determine automatically - bitsPerPixel:0]; // 0 == determine automatically + [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:0 // if 0 : only allocate memory + pixelsWide:width + pixelsHigh:height + bitsPerSample:8 // The number of bits used to specify + // one pixel in a single component of the data. + samplesPerPixel:4 // 3 if no alpha, 4 with it + hasAlpha:YES + isPlanar:NO // I don't know what it is but it works + colorSpaceName:NSCalibratedRGBColorSpace + bytesPerRow:0 // 0 == determine automatically + bitsPerPixel:0]; // 0 == determine automatically // Load data pixels. #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 // We may need to define NSUInteger. @@ -383,10 +422,22 @@ //////////////////////////////////////////////////////// --(void)applyContext:(NSOpenGLContext*)context +-(void)applyContext:(NSOpenGLContext *)context { [myOGLView setOpenGLContext:context]; [context setView:myOGLView]; + + // If fullscreen was requested and the mode used to create the window + // was not the desktop mode, we change the back buffer size of the + // context. + if (myFullscreenMode != sf::VideoMode()) { + CGLContextObj cgcontext = (CGLContextObj)[context CGLContextObj]; + + GLint dim[2] = {myFullscreenMode.Width, myFullscreenMode.Height}; + + CGLSetParameter(cgcontext, kCGLCPSurfaceBackingSize, dim); + CGLEnable(cgcontext, kCGLCESurfaceBackingSize); + } } @@ -405,7 +456,9 @@ //////////////////////////////////////////////////////// --(void)windowDidBecomeKey:(NSNotification*)notification { +-(void)windowDidBecomeKey:(NSNotification *)notification +{ + // Send event. if (myRequester == 0) return; myRequester->WindowGainedFocus(); @@ -413,7 +466,9 @@ //////////////////////////////////////////////////////// --(void)windowDidResignKey:(NSNotification*)notification { +-(void)windowDidResignKey:(NSNotification *)notification +{ + // Send event. if (myRequester == 0) return; myRequester->WindowLostFocus(); @@ -424,7 +479,8 @@ #pragma mark Other methods //////////////////////////////////////////////////////// --(float)screenHeight { +-(float)screenHeight +{ // With Mac OS X 10.4 and 10.5, there is a shift upwards // (about 22px – that is the apple menu bar height). With 10.6 and later // we have a workaround : we hide the dock and get the visibleFrame of the @@ -460,8 +516,10 @@ #endif } + //////////////////////////////////////////////////////// --(float)titlebarHeight { +-(float)titlebarHeight +{ return NSHeight([myWindow frame]) - NSHeight([[myWindow contentView] frame]); } diff --git a/src/SFML/Window/OSX/VideoModeImpl.cpp b/src/SFML/Window/OSX/VideoModeImpl.cpp index a8856cb69..54eb8867e 100644 --- a/src/SFML/Window/OSX/VideoModeImpl.cpp +++ b/src/SFML/Window/OSX/VideoModeImpl.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -27,79 +27,80 @@ // Headers //////////////////////////////////////////////////////////// #include +#include #include #include -#import - namespace sf { namespace priv -{ +{ //////////////////////////////////////////////////////////// -/// \brief Get bpp for all OS X version -/// -/// This function use only non-deprecated way to get the -/// display bits per pixel information. -//////////////////////////////////////////////////////////// -size_t DisplayBitsPerPixel(CGDirectDisplayID displayId) -{ -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 - - return CGDisplayBitsPerPixel(displayId); - -#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 - - CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId); - - CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode); - if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - return 32; - else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - return 16; - else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - return 8; - - return 0; // no match - -#endif -} - - +/// Note : +/// Starting with 10.6, CGDisplayModeRef and CGDisplayCopyAllDisplayModes +/// should be used instead of CFDictionaryRef and CGDisplayAvailableModes. +/// //////////////////////////////////////////////////////////// std::vector VideoModeImpl::GetFullscreenModes() { +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 + std::vector modes; - CGDisplayCount count = 0; - int err = CGGetActiveDisplayList(0, NULL, &count); + // Retrieve array of dictionaries representing display modes. + CFArrayRef displayModes = CGDisplayAvailableModes(CGMainDisplayID()); - if (err != 0) { - sf::Err() << "Error when retrieving displays count"; + if (displayModes == NULL) { + sf::Err() << "Couldn't get VideoMode for main display."; return modes; } - CGDirectDisplayID* displays = new CGDirectDisplayID[count]; - err = CGGetActiveDisplayList(count, displays, &count); - - if (err != 0) { - sf::Err() << "Error when retrieving displays array"; - return modes; - } - - for (int i = 0; i < count; ++i) { - VideoMode mode(CGDisplayPixelsWide(displays[i]), - CGDisplayPixelsHigh(displays[i]), - DisplayBitsPerPixel(displays[i])); + // Loop on each mode and convert it into a sf::VideoMode object. + CFIndex const modesCount = CFArrayGetCount(displayModes); + for (CFIndex i = 0; i < modesCount; i++) { + CFDictionaryRef dictionary = (CFDictionaryRef)CFArrayGetValueAtIndex(displayModes, i); - // Add it only if it isn't already in the array. - if (std::find(modes.begin(), modes.end(), mode) == modes.end()) + VideoMode mode = ConvertCGModeToSFMode(dictionary); + + // If not yet listed we add it to our modes array. + if (std::find(modes.begin(), modes.end(), mode) == modes.end()) { modes.push_back(mode); + } } - delete[] displays; - return modes; + +#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 + + std::vector modes; + + // Retrieve all modes available for main screen only. + CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); + + if (cgmodes == NULL) { + sf::Err() << "Couldn't get VideoMode for main display."; + return modes; + } + + // Loop on each mode and convert it into a sf::VideoMode object. + CFIndex const modesCount = CFArrayGetCount(cgmodes); + for (CFIndex i = 0; i < modesCount; i++) { + CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i); + + VideoMode mode = ConvertCGModeToSFMode(cgmode); + + // If not yet listed we add it to our modes array. + if (std::find(modes.begin(), modes.end(), mode) == modes.end()) { + modes.push_back(mode); + } + } + + // Clean up memory. + CFRelease(cgmodes); + + return modes; + +#endif } diff --git a/src/SFML/Window/OSX/WindowImplCocoa.hpp b/src/SFML/Window/OSX/WindowImplCocoa.hpp index 5af94773f..ad38a64df 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.hpp +++ b/src/SFML/Window/OSX/WindowImplCocoa.hpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -48,6 +48,8 @@ typedef NSOpenGLContext* NSOpenGLContextRef; #else // If C++ +typedef unsigned short unichar; // See NSString.h + typedef void* WindowImplDelegateRef; typedef void* NSAutoreleasePoolRef; typedef void* NSOpenGLContextRef; @@ -89,29 +91,155 @@ public: //////////////////////////////////////////////////////////// ~WindowImplCocoa(); - /// Events + //////////////////////////////////////////////////////////// + /// \brief Window Closed Event – called by the cocoa window object. + /// + /// Send the event to SFML WindowImpl class. + /// + //////////////////////////////////////////////////////////// void WindowClosed(void); - void WindowResized(unsigned int width, unsigned int height); - void WindowLostFocus(void); - void WindowGainedFocus(void); - void MouseDownAt(Mouse::Button button, int x, int y); - void MouseUpAt(Mouse::Button button, int x, int y); - void MouseMovedAt(int x, int y); - void MouseWheelScrolledAt(float delta, int x, int y); - void MouseMovedIn(void); - void MouseMovedOut(void); - void KeyDown(unsigned short keycode, unsigned int modifierFlags); - void KeyUp(unsigned short keycode, unsigned int modifierFlags); - void TextEntered(Uint32 charcode); - - static Key::Code NSKeyCodeToSFMLKeyCode(unsigned short rawchar); //////////////////////////////////////////////////////////// - /// + /// \brief Window Resized Event – called by the cocoa window object. + /// + /// Send the event to SFML WindowImpl class. + /// + /// \param width + /// \param height + /// + //////////////////////////////////////////////////////////// + void WindowResized(unsigned int width, unsigned int height); + + //////////////////////////////////////////////////////////// + /// \brief Window Lost Focus Event – called by the cocoa window object. + /// + /// Send the event to SFML WindowImpl class. + /// + //////////////////////////////////////////////////////////// + void WindowLostFocus(void); + + //////////////////////////////////////////////////////////// + /// \brief Window Get Focus Event – called by the cocoa window object. + /// + /// Send the event to SFML WindowImpl class. + /// + //////////////////////////////////////////////////////////// + void WindowGainedFocus(void); + + //////////////////////////////////////////////////////////// + /// \brief Mouse Down Event – called by the cocoa view object. + /// + /// Send the event to SFML WindowImpl class. + /// + /// \param button + /// \param x + /// \param y + /// + //////////////////////////////////////////////////////////// + void MouseDownAt(Mouse::Button button, int x, int y); + + //////////////////////////////////////////////////////////// + /// \brief Mouse Up Event – called by the cocoa view object. + /// + /// Send the event to SFML WindowImpl class. + /// + /// \param button + /// \param x + /// \param y + /// + //////////////////////////////////////////////////////////// + void MouseUpAt(Mouse::Button button, int x, int y); + + //////////////////////////////////////////////////////////// + /// \brief Mouse Moved Event – called by the cocoa view object. + /// + /// Send the event to SFML WindowImpl class. + /// + /// \param x + /// \param y + /// + //////////////////////////////////////////////////////////// + void MouseMovedAt(int x, int y); + + //////////////////////////////////////////////////////////// + /// \brief Mouse Wheel Scrolled Event – called by the cocoa view object. + /// + /// Send the event to SFML WindowImpl class. + /// + /// \param delta + /// \param x + /// \param y + /// + //////////////////////////////////////////////////////////// + void MouseWheelScrolledAt(float delta, int x, int y); + + //////////////////////////////////////////////////////////// + /// \brief Mouse In Event – called by the cocoa view object. + /// + /// Send the event to SFML WindowImpl class. + /// + //////////////////////////////////////////////////////////// + void MouseMovedIn(void); + + //////////////////////////////////////////////////////////// + /// \brief Mouse Out Event – called by the cocoa view object. + /// + /// Send the event to SFML WindowImpl class. + /// + //////////////////////////////////////////////////////////// + void MouseMovedOut(void); + + //////////////////////////////////////////////////////////// + /// \brief Key Down Event – called by the cocoa view object. + /// + /// Send the event to SFML WindowImpl class. + /// + /// \param keycode + /// \param modifierFlags + /// + //////////////////////////////////////////////////////////// + void KeyDown(unsigned short keycode, unsigned int modifierFlags); + + //////////////////////////////////////////////////////////// + /// \brief Key Up Event – called by the cocoa view object. + /// + /// Send the event to SFML WindowImpl class. + /// + /// \param keycode + /// \param modifierFlags + /// + //////////////////////////////////////////////////////////// + void KeyUp(unsigned short keycode, unsigned int modifierFlags); + + //////////////////////////////////////////////////////////// + /// \brief Text Entred Event – called by the cocoa view object. + /// + /// Send the event to SFML WindowImpl class. + /// + /// \param charcode Input unicode + /// + //////////////////////////////////////////////////////////// + void TextEntered(unichar charcode); + + //////////////////////////////////////////////////////////// + /// \brief Apply the context to the view. + /// + /// Called by the SFML context object to finalize its creation. + /// + /// \param context The context to bind to the window + /// //////////////////////////////////////////////////////////// void ApplyContext(NSOpenGLContextRef context) const; private: + //////////////////////////////////////////////////////////// + /// \brief Convert Cocoa keycode to SFML keycode. + /// + /// \param rawchar Cocoa keycode to convert + /// + //////////////////////////////////////////////////////////// + static Key::Code NSKeyCodeToSFMLKeyCode(unichar rawchar); + //////////////////////////////////////////////////////////// /// \brief Process incoming events from the operating system /// @@ -199,11 +327,13 @@ private: //////////////////////////////////////////////////////////// /// \brief Construct the pool after ensuring NSApp is valid. + /// //////////////////////////////////////////////////////////// void SetUpPoolAndApplication(void); //////////////////////////////////////////////////////////// /// \brief Change the type of the current process to become a full GUI app. + /// //////////////////////////////////////////////////////////// static void SetUpProcessAsApplication(void); diff --git a/src/SFML/Window/OSX/WindowImplCocoa.mm b/src/SFML/Window/OSX/WindowImplCocoa.mm index 6aa68a196..3f5f017b4 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.mm +++ b/src/SFML/Window/OSX/WindowImplCocoa.mm @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -92,7 +92,7 @@ WindowImplCocoa::WindowImplCocoa(VideoMode mode, myWidth = mode.Width; myHeight = mode.Height; - myDelegate = [[SFWindowController alloc] initWithMode:&mode andStyle:style]; + myDelegate = [[SFWindowController alloc] initWithMode:mode andStyle:style]; [myDelegate changeTitle:stringToNSString(title)]; [myDelegate setRequesterTo:this]; } @@ -108,13 +108,13 @@ WindowImplCocoa::~WindowImplCocoa() } -//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// void WindowImplCocoa::ApplyContext(NSOpenGLContextRef context) const { [myDelegate applyContext:context]; } - - + + #pragma mark #pragma mark WindowImplCocoa's window-event methods @@ -281,7 +281,7 @@ void WindowImplCocoa::KeyUp(unsigned short keycode, unsigned int modifierFlags) //////////////////////////////////////////////////////////// -void WindowImplCocoa::TextEntered(Uint32 charcode) +void WindowImplCocoa::TextEntered(unichar charcode) { Event event; event.Type = Event::TextEntered; diff --git a/src/SFML/Window/OSX/WindowImplDelegateProtocol.h b/src/SFML/Window/OSX/WindowImplDelegateProtocol.h index 567924611..0986c3d83 100644 --- a/src/SFML/Window/OSX/WindowImplDelegateProtocol.h +++ b/src/SFML/Window/OSX/WindowImplDelegateProtocol.h @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -58,51 +58,91 @@ namespace sf { /// /// Note : Joystick are not bound to a view or window /// thus they're not managed by a class implementing this protocol. +/// //////////////////////////////////////////////////////////// @protocol WindowImplDelegateProtocol +//////////////////////////////////////////////////////////// /// Set the WindowImpl who requested this delegate /// (This would be a ctor in C++ or Java where we can prohibit the /// construction of an object.) --(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester; +/// +//////////////////////////////////////////////////////////// +-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester; +//////////////////////////////////////////////////////////// /// Return the main view or window. +/// +//////////////////////////////////////////////////////////// -(sf::WindowHandle)getSystemHandle; +//////////////////////////////////////////////////////////// /// Hide or show the mouse cursor. +/// +//////////////////////////////////////////////////////////// -(void)hideMouseCursor; -(void)showMouseCursor; +//////////////////////////////////////////////////////////// /// Move the mouse cursor to (x,y) (SFML Coordinates). +/// +//////////////////////////////////////////////////////////// -(void)setCursorPositionToX:(unsigned int)x Y:(unsigned int)y; +//////////////////////////////////////////////////////////// /// Move the window (not the view if we handle not a window) (SFML Coordinates). +/// +//////////////////////////////////////////////////////////// -(void)setWindowPositionToX:(unsigned int)x Y:(unsigned int)y; +//////////////////////////////////////////////////////////// /// Resize the window/view. +/// +//////////////////////////////////////////////////////////// -(void)resizeTo:(unsigned int)width by:(unsigned int)height; +//////////////////////////////////////////////////////////// /// Set the title (does nothing if we manage a view). --(void)changeTitle:(NSString*)title; +/// +//////////////////////////////////////////////////////////// +-(void)changeTitle:(NSString *)title; +//////////////////////////////////////////////////////////// /// Hide or show the window (does nothing if we manage a view). +/// +//////////////////////////////////////////////////////////// -(void)hideWindow; -(void)showWindow; +//////////////////////////////////////////////////////////// /// Close the window (does nothing if we manage a view). +/// +//////////////////////////////////////////////////////////// -(void)closeWindow; +//////////////////////////////////////////////////////////// /// Enable or disable key repeat. +/// +//////////////////////////////////////////////////////////// -(void)enableKeyRepeat; -(void)disableKeyRepeat; +//////////////////////////////////////////////////////////// /// Set an icon to the application. +/// +//////////////////////////////////////////////////////////// -(void)setIconTo:(unsigned int)width by:(unsigned int)height with:(sf::Uint8 const*)pixels; +//////////////////////////////////////////////////////////// /// Fetch new event +/// +//////////////////////////////////////////////////////////// -(void)processEventWithBlockingMode:(BOOL)block; +//////////////////////////////////////////////////////////// /// Apply a given context to an OpenGL view. --(void)applyContext:(NSOpenGLContext*)context; +/// +//////////////////////////////////////////////////////////// +-(void)applyContext:(NSOpenGLContext *)context; @end diff --git a/src/SFML/Window/OSX/cg_sf_conversion.cpp b/src/SFML/Window/OSX/cg_sf_conversion.cpp new file mode 100644 index 000000000..d8d5810d5 --- /dev/null +++ b/src/SFML/Window/OSX/cg_sf_conversion.cpp @@ -0,0 +1,181 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), +// Laurent Gomila (laurent.gom@gmail.com), +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + +namespace sf +{ +namespace priv +{ + +//////////////////////////////////////////////////////////// +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 +size_t ModeBitsPerPixel(CGDisplayModeRef mode) +{ + size_t bpp = 0; // no match + + // Compare encoding. + CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode); + if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + + bpp = 32; + + } else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + + bpp = 16; + + } else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + + bpp = 8; + + } + + // Clean up memory. + CFRelease(pixEnc); + + return bpp; +} +#endif + + + +//////////////////////////////////////////////////////////// +size_t DisplayBitsPerPixel(CGDirectDisplayID displayId) +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 + + return CGDisplayBitsPerPixel(displayId); + +#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 + + // Get the display mode. + CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId); + + // Get bpp for the mode. + size_t const bpp = ModeBitsPerPixel(mode); + + // Clean up Memory. + CGDisplayModeRelease(mode); + + return bpp; + +#endif +} + + +//////////////////////////////////////////////////////////// +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 + +VideoMode ConvertCGModeToSFMode(CFDictionaryRef dictionary) +{ + VideoMode sfmode; + + CFNumberRef cfnumber = (CFNumberRef)CFDictionaryGetValue(CurrentMode, kCGDisplayWidth); + CFNumberGetValue(cfnumber, kCFNumberIntType, &(mode.Width)); + + cfnumber = (CFNumberRef)CFDictionaryGetValue(CurrentMode, kCGDisplayHeight); + CFNumberGetValue(cfnumber, kCFNumberIntType, &(mode.Height)); + + cfnumber = (CFNumberRef)CFDictionaryGetValue(CurrentMode, kCGDisplayBitsPerPixel); + CFNumberGetValue(cfnumber, kCFNumberIntType, &(mode.BitsPerPixel)); + + return sfmode; +} + +#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 + +VideoMode ConvertCGModeToSFMode(CGDisplayModeRef cgmode) +{ + return VideoMode(CGDisplayModeGetWidth(cgmode), + CGDisplayModeGetHeight(cgmode), + ModeBitsPerPixel(cgmode)); +} + +#endif + +//////////////////////////////////////////////////////////// +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 + +CFDictionaryRef ConvertSFModeToCGMode(VideoMode sfmode) +{ + // If sfmode is in VideoMode::GetFullscreenModes + // then this should be an exact match (see NULL parameter doc). + return CGDisplayBestModeForParameters(CGMainDisplayID(), + sfmode.BitsPerPixel, + sfmode.Width, + sfmode.Height + NULL); +} + +#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 + +CGDisplayModeRef ConvertSFModeToCGMode(VideoMode sfmode) +{ + // Starting with 10.6 we should query the display all the modes and + // search for the best one. + + // Will return NULL if sfmode is not in VideoMode::GetFullscreenModes. + CGDisplayModeRef cgbestMode = NULL; + + // Retrieve all modes available for main screen only. + CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); + + if (cgmodes == NULL) { // Should not happen but anyway... + sf::Err() << "Couldn't get VideoMode for main display."; + return NULL; + } + + // Loop on each mode and convert it into a sf::VideoMode object. + CFIndex const modesCount = CFArrayGetCount(cgmodes); + for (CFIndex i = 0; i < modesCount; i++) { + CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i); + + VideoMode mode = ConvertCGModeToSFMode(cgmode); + + if (mode == sfmode) { + cgbestMode = cgmode; + } + } + + // Clean up memory. + CFRelease(cgmodes); + + if (cgbestMode == NULL) { + sf::Err() + << "Couldn't convert the given sf:VideoMode into a CGDisplayMode." + << std::endl; + } + + return cgbestMode; +} + +#endif + +} // namespace priv +} // namespace sf diff --git a/src/SFML/Window/OSX/cg_sf_conversion.hpp b/src/SFML/Window/OSX/cg_sf_conversion.hpp new file mode 100644 index 000000000..6ecccce4e --- /dev/null +++ b/src/SFML/Window/OSX/cg_sf_conversion.hpp @@ -0,0 +1,82 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), +// Laurent Gomila (laurent.gom@gmail.com), +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_CG_SF_CONVERSION_HPP +#define SFML_CG_SF_CONVERSION_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + +namespace sf +{ +namespace priv +{ +//////////////////////////////////////////////////////////// +/// \brief Get bpp of a video mode for OS 10.6 or later. +/// +/// With OS 10.6 and later, Quartz doesn't use anymore dictionaries +/// to represent video mode. Instead it uses a CGDisplayMode opaque type. +/// +//////////////////////////////////////////////////////////// +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 +size_t ModeBitsPerPixel(CGDisplayModeRef mode); +#endif + +//////////////////////////////////////////////////////////// +/// \brief Get bpp for all OS X version. +/// +/// This function use only non-deprecated way to get the +/// display bits per pixel information for a given display id. +/// +//////////////////////////////////////////////////////////// +size_t DisplayBitsPerPixel(CGDirectDisplayID displayId); + +//////////////////////////////////////////////////////////// +/// \brief Convert a Quartz video mode into a sf::VideoMode object. +/// +//////////////////////////////////////////////////////////// +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 +VideoMode ConvertCGModeToSFMode(CFDictionaryRef dictionary); +#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 +VideoMode ConvertCGModeToSFMode(CGDisplayModeRef cgmode); +#endif + +//////////////////////////////////////////////////////////// +/// \brief Convert a sf::VideoMode object into a Quartz video mode. +/// +//////////////////////////////////////////////////////////// +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 +CFDictionaryRef ConvertSFModeToCGMode(VideoMode sfmode); +#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 +CGDisplayModeRef ConvertSFModeToCGMode(VideoMode sfmode); +#endif + +} // namespace priv +} // namespace sf + +#endif diff --git a/src/SFML/Window/OSX/cpp_objc_conversion.h b/src/SFML/Window/OSX/cpp_objc_conversion.h index bea69b052..e9261594b 100644 --- a/src/SFML/Window/OSX/cpp_objc_conversion.h +++ b/src/SFML/Window/OSX/cpp_objc_conversion.h @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty. @@ -32,6 +32,7 @@ //////////////////////////////////////////////////////////// /// \brief Returns a NSString construct with +stringWithCString:encoding:. +/// //////////////////////////////////////////////////////////// NSString* stringToNSString(std::string const& string); diff --git a/src/SFML/Window/OSX/cpp_objc_conversion.mm b/src/SFML/Window/OSX/cpp_objc_conversion.mm index ef0e94685..d34249aa7 100644 --- a/src/SFML/Window/OSX/cpp_objc_conversion.mm +++ b/src/SFML/Window/OSX/cpp_objc_conversion.mm @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2010 Marco Antognini (antognini.marco@gmail.com), +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), // Laurent Gomila (laurent.gom@gmail.com), // // This software is provided 'as-is', without any express or implied warranty.