diff options
Diffstat (limited to 'src/SFML/Window/OSXCocoa/.svn/text-base/WindowImplCocoa.mm.svn-base')
-rw-r--r-- | src/SFML/Window/OSXCocoa/.svn/text-base/WindowImplCocoa.mm.svn-base | 1298 |
1 files changed, 0 insertions, 1298 deletions
diff --git a/src/SFML/Window/OSXCocoa/.svn/text-base/WindowImplCocoa.mm.svn-base b/src/SFML/Window/OSXCocoa/.svn/text-base/WindowImplCocoa.mm.svn-base deleted file mode 100644 index 070194d..0000000 --- a/src/SFML/Window/OSXCocoa/.svn/text-base/WindowImplCocoa.mm.svn-base +++ /dev/null @@ -1,1298 +0,0 @@ -//////////////////////////////////////////////////////////// -// -// SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2008 Lucas Soltic (elmerod@gmail.com) and 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 -//////////////////////////////////////////////////////////// -#import <SFML/Window/OSXCocoa/WindowImplCocoa.hpp> -#import <SFML/Window/OSXCocoa/WindowController.h> -#import <SFML/Window/OSXCocoa/AppController.h> -#import <SFML/Window/WindowStyle.hpp> -#import <OpenGL/OpenGL.h> -#import <OpenGL/gl.h> -#import <Cocoa/Cocoa.h> -#import <iostream> - - -@implementation NSWindow (SFML) -- (BOOL)canBecomeKeyWindow -{ - return YES; -} -@end - - -namespace sf -{ -namespace priv -{ - - -#define ONCE(make) \ -{ static int __done = 0;\ -if (!__done) {\ -make;\ -__done = 1;\ -} } - - -enum { - ConsumedEvent, - UnusedEvent -}; - - -//////////////////////////////////////////////////////////// -/// Structure containing all the members I can't directly put in the class definition -/// because I would have to hide them in a #ifdef __OBJC__ block and the object -/// allocator would allocate space for it as it would be called from a C++ code -/// that wouldn't see these members -//////////////////////////////////////////////////////////// -struct objc_members { - WindowController *controller; - NSWindow *window; - NSOpenGLContext *context; - NSOpenGLView *view; -}; - -//////////////////////////////////////////////////////////// -/// Pointer to the shared OpenGL context -//////////////////////////////////////////////////////////// -static NSOpenGLContext *sharedContext = nil; - - -//////////////////////////////////////////////////////////// -/// Private function declarations -//////////////////////////////////////////////////////////// -static NSWindow * MakeWindow(WindowSettings& params, unsigned long style, VideoMode& mode, NSString *title); -static NSOpenGLContext *MakeOpenGLContext(WindowSettings& params); -static NSOpenGLView * MakeOpenGLView(NSWindow *window, NSOpenGLContext *context, WindowSettings& params); -static void ConfigureWindow(NSWindow *window, NSOpenGLView *view, WindowController *controller); -static Key::Code KeyForVirtualCode(unsigned short vCode); -static Key::Code KeyForUnicode(unsigned short uniCode); -static bool IsTextEvent(NSEvent *event); -static bool MouseInside(NSWindow *window, NSView *view); - - -//////////////////////////////////////////////////////////// -/// Default constructor -/// (creates a dummy window to provide a valid OpenGL context) -//////////////////////////////////////////////////////////// -WindowImplCocoa::WindowImplCocoa() : -members(NULL), -useKeyRepeat(false), -mouseIn(false), -wheelStatus(0.0f), -fullscreen(false), -fullscreenMode(0, 0, 0), -desktopMode(0, 0, 0) -{ - Initialize(); - - // -- Ceylo -- - // We just want to have a valid support for an OpenGL context - - // So we create the OpenGL context - WindowSettings params(0, 0, 0); - members->context = MakeOpenGLContext(params); - - if (members->context != nil) { - sharedContext = [members->context retain]; - - // And we make it the current active OpenGL context - SetActive(); - } else { - error(__FILE__, __LINE__, "unable to make the main shared OpenGL context"); - } -} - - -//////////////////////////////////////////////////////////// -/// Create the window implementation from an existing control -//////////////////////////////////////////////////////////// -WindowImplCocoa::WindowImplCocoa(WindowHandle Handle, WindowSettings& params) : -members(NULL), -useKeyRepeat(false), -mouseIn(false), -wheelStatus(0.0f), -fullscreen(false), -fullscreenMode(0, 0, 0), -desktopMode(0, 0, 0) -{ - Initialize(); - - // Register ourselves for event handling - [[AppController sharedController] registerWindow:this]; - - // Make a WindowController to handle notifications - members->controller = [[WindowController controllerWithWindow:this] retain]; - - // Use existing window - members->window = [static_cast <NSWindow *> (Handle) retain]; - - if (members->window != nil) { - // We make the OpenGL context, associate it to the OpenGL view - // and add the view to our window - members->context = MakeOpenGLContext(params); - - if (members->context != nil) { - members->view = MakeOpenGLView(members->window, members->context, params); - - if (members->view != nil) { - // initial mouse state - mouseIn = MouseInside(members->window, members->view); - - // Initialize myWidth and myHeight members from base class with the window size - myWidth = (unsigned) [members->window frame].size.width; - myHeight = (unsigned) [members->window frame].size.height; - } else { - error(__FILE__, __LINE__, "failed to make OpenGL view for public window"); - } - } else { - error(__FILE__, __LINE__, "failed to make OpenGL context for public window"); - } - } else { - error(__FILE__, __LINE__, "invalid imported window"); - } -} - - -//////////////////////////////////////////////////////////// -/// Create the window implementation -//////////////////////////////////////////////////////////// -WindowImplCocoa::WindowImplCocoa(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& params) : -members(NULL), -useKeyRepeat(false), -mouseIn(false), -wheelStatus(0.0f), -fullscreen(WindowStyle & Style::Fullscreen), -fullscreenMode(0, 0, 0), -desktopMode(0, 0, 0) -{ - Initialize(); - - // Make a WindowController to handle notifications - members->controller = [[WindowController controllerWithWindow:this] retain]; - - // Create a new window with given size, title and style - // First we define some objects used for our window - NSString *title = [NSString stringWithUTF8String:Title.c_str()]; - - // We create the window - members->window = MakeWindow(params, WindowStyle, Mode, title); - - - if (members->window != nil) { - members->context = MakeOpenGLContext(params); - - if (members->context != nil) { - // We make the OpenGL context, associate it to the OpenGL view - // and add the view to our window - members->view = MakeOpenGLView(members->window, members->context, params); - - if (members->view != nil) { - // Set observers and some window settings - ConfigureWindow(members->window, members->view, members->controller); - - // initial mouse state - mouseIn = MouseInside(members->window, members->view); - - // We set the myWidth and myHeight members to the correct values - myWidth = Mode.Width; - myHeight = Mode.Height; - - if (WindowStyle & Style::Fullscreen) { - fullscreenMode = Mode; - } - } else { - error(__FILE__, __LINE__, "failed to make OpenGL view for public window"); - } - } else { - error(__FILE__, __LINE__, "failed to make OpenGL context for public window"); - } - } else { - error(__FILE__, __LINE__, "failed to make window"); - } -} - - -//////////////////////////////////////////////////////////// -/// Destructor -//////////////////////////////////////////////////////////// -WindowImplCocoa::~WindowImplCocoa() -{ - // Destroy the OpenGL context, the window and every resource allocated by this class - Show(false); - - [[NSNotificationCenter defaultCenter] removeObserver:members->window]; - [[NSNotificationCenter defaultCenter] removeObserver:members->view]; - [members->controller release]; - - [sharedContext release]; - [members->context release]; - [members->view release]; - [members->window release]; - - [[AppController sharedController] unregisterWindow:this]; - free (members); -} - - -//////////////////////////////////////////////////////////// -/// Check if there's an active context on the current thread -//////////////////////////////////////////////////////////// -bool WindowImplCocoa::IsContextActive() -{ - return ([NSOpenGLContext currentContext] != NULL); -} - - -//////////////////////////////////////////////////////////// -/// Handle a Cocoa NSEvent -//////////////////////////////////////////////////////////// -void WindowImplCocoa::HandleEvent(void *eventPtr) -{ - NSEvent *event = static_cast <NSEvent *> (eventPtr); - int eventStatus = UnusedEvent; - - switch ([event type]) { - case NSKeyDown: - eventStatus = HandleKeyDown(eventPtr); - break; - - case NSKeyUp: - eventStatus = HandleKeyUp(eventPtr); - break; - - case NSFlagsChanged: - eventStatus = HandleModifierKey(eventPtr); - break; - - case NSScrollWheel: - eventStatus = HandleMouseWheel(eventPtr); - break; - - case NSLeftMouseDown: - case NSRightMouseDown: - eventStatus = HandleMouseDown(eventPtr); - break; - - case NSLeftMouseUp: - case NSRightMouseUp: - eventStatus = HandleMouseUp(eventPtr); - break; - - case NSMouseMoved: - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - eventStatus = HandleMouseMove(eventPtr); - break; - - default: - break; - } - - if (eventStatus == UnusedEvent) { - [NSApp sendEvent:event]; - } -} - - -//////////////////////////////////////////////////////////// -/// Handle event sent by the default NSNotificationCenter -//////////////////////////////////////////////////////////// -void WindowImplCocoa::HandleNotifiedEvent(Event& event) -{ - // Set myWidth and myHeight to correct value if - // window size changed - switch (event.Type) { - case Event::Resized: - myWidth = event.Size.Width; - myHeight = event.Size.Height; - break; - - default: - break; - } - - // And send the event - SendEvent(event); -} - - -//////////////////////////////////////////////////////////// -/// Handle a key down event (NSEvent) -//////////////////////////////////////////////////////////// -int WindowImplCocoa::HandleKeyDown(void *eventPtr) -{ - NSEvent *event = static_cast <NSEvent *> (eventPtr); - - Event sfEvent; - unichar chr = 0, rawchr = 0; - unsigned mods = [event modifierFlags]; - - if ([[event characters] length]) { - chr = [[event characters] characterAtIndex:0]; - - // Note : I got a crash (out of bounds exception) while typing so now I test... - if ([[event charactersIgnoringModifiers] length]) - rawchr = [[event charactersIgnoringModifiers] characterAtIndex:0]; - - } - - if (mods & NSCommandKeyMask) { - // Application commands - [NSApp sendEvent:event]; - } - - // User events - - if (!useKeyRepeat && [event isARepeat]) { - return ConsumedEvent; - } - - // Is it also a text event ? - if (IsTextEvent(event)) { - sfEvent.Type = Event::TextEntered; - sfEvent.Text.Unicode = chr; - - SendEvent(sfEvent); - } - - // Anyway it's also a KeyPressed event - sfEvent.Type = Event::KeyPressed; - - // Get the keys - if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(chr))) { - sfEvent.Key.Code = KeyForVirtualCode([event keyCode]); - } - - // Get the modifiers - sfEvent.Key.Alt = mods & NSAlternateKeyMask; - sfEvent.Key.Control = mods & NSControlKeyMask; - sfEvent.Key.Shift = mods & NSShiftKeyMask; - - SendEvent(sfEvent); - - return ConsumedEvent; -} - - -//////////////////////////////////////////////////////////// -/// Handle a key up event (NSEvent) -//////////////////////////////////////////////////////////// -int WindowImplCocoa::HandleKeyUp(void *eventPtr) -{ - NSEvent *event = static_cast <NSEvent *> (eventPtr); - - Event sfEvent; - unsigned mods = [event modifierFlags]; - unichar chr = 0; - - if ([[event characters] length]) { - chr = [[event characters] characterAtIndex:0]; - } - - if (mods & NSCommandKeyMask) { - [NSApp sendEvent:event]; - } - - sfEvent.Type = Event::KeyReleased; - - // Get the code - if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(chr))) { - sfEvent.Key.Code = KeyForVirtualCode([event keyCode]); - } - - // Get the modifiers - sfEvent.Key.Alt = mods & NSAlternateKeyMask; - sfEvent.Key.Control = mods & NSControlKeyMask; - sfEvent.Key.Shift = mods & NSShiftKeyMask; - - SendEvent(sfEvent); - - return ConsumedEvent; -} - - -//////////////////////////////////////////////////////////// -/// Handle a key modifier event [Command, Option, Control, Shift] -//////////////////////////////////////////////////////////// -int WindowImplCocoa::HandleModifierKey(void *eventPtr) -{ - NSEvent *event = static_cast <NSEvent *> (eventPtr); - Event sfEvent; - unsigned mods = [event modifierFlags]; - - sfEvent.Type = Event::KeyPressed; - sfEvent.Key.Code = KeyForVirtualCode([event keyCode]); - - sfEvent.Key.Alt = mods & NSAlternateKeyMask; - sfEvent.Key.Control = mods & NSControlKeyMask; - sfEvent.Key.Shift = mods & NSShiftKeyMask; - - if (!(mods & NSAlternateKeyMask) && - (sfEvent.Key.Code == Key::LAlt || sfEvent.Key.Code == Key::RAlt)) { - sfEvent.Type = Event::KeyReleased; - } - - if (!(mods & NSControlKeyMask) && - (sfEvent.Key.Code == Key::LControl || sfEvent.Key.Code == Key::RControl)) { - sfEvent.Type = Event::KeyReleased; - } - - if (!(mods & NSShiftKeyMask) && - (sfEvent.Key.Code == Key::LShift || sfEvent.Key.Code == Key::RShift)) { - sfEvent.Type = Event::KeyReleased; - } - - if (!(mods & NSCommandKeyMask) && - (sfEvent.Key.Code == Key::LSystem || sfEvent.Key.Code == Key::RSystem)) { - sfEvent.Type = Event::KeyReleased; - } - - SendEvent(sfEvent); - - return UnusedEvent; -} - - -//////////////////////////////////////////////////////////// -/// Handle a mouse down event (NSEvent) -//////////////////////////////////////////////////////////// -int WindowImplCocoa::HandleMouseDown(void *eventPtr) -{ - NSEvent *event = static_cast <NSEvent *> (eventPtr); - Event sfEvent; - NSPoint loc = {0, 0}, relativeLoc = {0, 0}; - unsigned mods = [event modifierFlags]; - - switch ([event type]) { - case NSLeftMouseDown: - sfEvent.Type = Event::MouseButtonPressed; - - if (mods & NSControlKeyMask) { - sfEvent.MouseButton.Button = Mouse::Right; - } else { - sfEvent.MouseButton.Button = Mouse::Left; - } - - // Get mouse position - loc = [NSEvent mouseLocation]; - - relativeLoc = [members->window convertScreenToBase:loc]; - relativeLoc.y = [[members->window contentView] frame].size.height - relativeLoc.y; - - sfEvent.MouseButton.X = (int) relativeLoc.x; - sfEvent.MouseButton.Y = (int) relativeLoc.y; - - SendEvent(sfEvent); - break; - - case NSRightMouseDown: - sfEvent.Type = Event::MouseButtonPressed; - sfEvent.MouseButton.Button = Mouse::Right; - - // Get mouse position - loc = [NSEvent mouseLocation]; - - relativeLoc = [members->window convertScreenToBase:loc]; - relativeLoc.y = [[members->window contentView] frame].size.height - relativeLoc.y; - - sfEvent.MouseButton.X = (int) relativeLoc.x; - sfEvent.MouseButton.Y = (int) relativeLoc.y; - - SendEvent(sfEvent); - break; - - default: - break; - } - - return UnusedEvent; - -} - - -//////////////////////////////////////////////////////////// -/// Handle a mouse up event (NSEvent) -//////////////////////////////////////////////////////////// -int WindowImplCocoa::HandleMouseUp(void *eventPtr) -{ - NSEvent *event = static_cast <NSEvent *> (eventPtr); - Event sfEvent; - NSPoint loc = {0, 0}, relativeLoc = {0, 0}; - unsigned mods = [event modifierFlags]; - - switch ([event type]) { - case NSLeftMouseUp: - sfEvent.Type = Event::MouseButtonReleased; - - if (mods & NSControlKeyMask) { - sfEvent.MouseButton.Button = Mouse::Right; - } else { - sfEvent.MouseButton.Button = Mouse::Left; - } - - // Get mouse position - loc = [NSEvent mouseLocation]; - - relativeLoc = [members->window convertScreenToBase:loc]; - relativeLoc.y = [[members->window contentView] frame].size.height - relativeLoc.y; - - sfEvent.MouseButton.X = (int) relativeLoc.x; - sfEvent.MouseButton.Y = (int) relativeLoc.y; - - SendEvent(sfEvent); - break; - - case NSRightMouseUp: - sfEvent.Type = Event::MouseButtonReleased; - sfEvent.MouseButton.Button = Mouse::Right; - - // Get mouse position - loc = [NSEvent mouseLocation]; - relativeLoc = [members->window convertScreenToBase:loc]; - relativeLoc.y = [[members->window contentView] frame].size.height - relativeLoc.y; - - sfEvent.MouseButton.X = (int) relativeLoc.x; - sfEvent.MouseButton.Y = (int) relativeLoc.y; - - SendEvent(sfEvent); - break; - - default: - break; - } - - return UnusedEvent; -} - - -//////////////////////////////////////////////////////////// -/// Handle a mouse move event (NSEvent) -//////////////////////////////////////////////////////////// -int WindowImplCocoa::HandleMouseMove(void *eventPtr) -{ - Event sfEvent; - NSPoint loc = {0, 0}, relativeLoc = {0, 0}; - - loc = [NSEvent mouseLocation]; - relativeLoc = [members->window convertScreenToBase:loc]; - relativeLoc.y = [[members->window contentView] frame].size.height - relativeLoc.y; - sfEvent.Type = Event::MouseMoved; - - sfEvent.MouseMove.X = (int) relativeLoc.x; - sfEvent.MouseMove.Y = (int) relativeLoc.y; - - SendEvent(sfEvent); - - // MouseEntered and MouseLeft events - if (MouseInside(members->window, members->view) && !mouseIn) { - sfEvent.Type = Event::MouseEntered; - mouseIn = true; - SendEvent(sfEvent); - } else if (!MouseInside(members->window, members->view) && mouseIn) { - sfEvent.Type = Event::MouseLeft; - mouseIn = false; - SendEvent(sfEvent); - } - - return UnusedEvent; -} - - -//////////////////////////////////////////////////////////// -/// Handle a mouse wheel event (NSEvent) -//////////////////////////////////////////////////////////// -int WindowImplCocoa::HandleMouseWheel(void *eventPtr) -{ - NSEvent *event = static_cast <NSEvent *> (eventPtr); - - wheelStatus += [event deltaY]; - - if (wheelStatus > 1.0f || wheelStatus < -1.0f) { - Event sfEvent; - sfEvent.Type = Event::MouseWheelMoved; - sfEvent.MouseWheel.Delta = (int)wheelStatus; - SendEvent(sfEvent); - - wheelStatus -= (int)wheelStatus; - } - - return UnusedEvent; -} - - -//////////////////////////////////////////////////////////// -/// Return a pointer to the NSWindow object -//////////////////////////////////////////////////////////// -void *WindowImplCocoa::CocoaWindow(void) -{ - return static_cast <void *> (members->window); -} - - -//////////////////////////////////////////////////////////// -/// /see sfWindowImpl::Display -//////////////////////////////////////////////////////////// -void WindowImplCocoa::Display() -{ - [members->context flushBuffer]; -} - - -//////////////////////////////////////////////////////////// -/// /see sfWindowImpl::ProcessEvents -//////////////////////////////////////////////////////////// -void WindowImplCocoa::ProcessEvents() -{ - if (![NSApp isRunning]) - return; - - [[AppController sharedController] processEvents]; -} - - -//////////////////////////////////////////////////////////// -/// /see sfWindowImpl::MakeActive -//////////////////////////////////////////////////////////// -void WindowImplCocoa::SetActive(bool Active) const -{ - if (Active) { - if ([NSOpenGLContext currentContext] != members->context) - [members->context makeCurrentContext]; - } else { - if ([NSOpenGLContext currentContext] == members->context) - [NSOpenGLContext clearCurrentContext]; - } -} - - -//////////////////////////////////////////////////////////// -/// /see sfWindowImpl::UseVerticalSync -//////////////////////////////////////////////////////////// -void WindowImplCocoa::UseVerticalSync(bool Enabled) -{ - GLint enable = (Enabled) ? 1 : 0; - [members->context setValues:&enable forParameter:NSOpenGLCPSwapInterval]; -} - - -//////////////////////////////////////////////////////////// -/// /see sfWindowImpl::ShowMouseCursor -//////////////////////////////////////////////////////////// -void WindowImplCocoa::ShowMouseCursor(bool flag) -{ - if (flag) { - [NSCursor unhide]; - } else { - [NSCursor hide]; - } -} - - -//////////////////////////////////////////////////////////// -/// /see sfWindowImpl::SetCursorPosition -//////////////////////////////////////////////////////////// -void WindowImplCocoa::SetCursorPosition(unsigned int Left, unsigned int Top) -{ - // Change the cursor position (Left and Top are relative to this window) - NSPoint pos = NSMakePoint ((float) Left, (float) Top); - - // Flip for SFML window coordinate system - pos.y = [members->window frame].size.height - pos.y; - - // Adjust for view reference instead of window - pos.y -= [members->window frame].size.height - [members->view frame].size.height; - - // Convert to screen coordinates - NSPoint absolute = [members->window convertBaseToScreen:pos]; - - // Flip screen coodinates - absolute.y = [[NSScreen mainScreen] frame].size.height - absolute.y; - - // Move cursor - CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, CGPointMake(absolute.x, absolute.y)); -} - - -//////////////////////////////////////////////////////////// -/// /see sfWindowImpl::SetPosition -//////////////////////////////////////////////////////////// -void WindowImplCocoa::SetPosition(int Left, int Top) -{ - if (!fullscreen) { - // Change the window position - Top = (int) [[members->window screen] frame].size.height - Top; - [members->window setFrameTopLeftPoint:NSMakePoint(Left, Top)]; - } -} - - -//////////////////////////////////////////////////////////// -/// /see WindowImpl::SetSize -/// -//////////////////////////////////////////////////////////// -void WindowImplCocoa::SetSize(unsigned int Width, unsigned int Height) -{ - if (!fullscreen) { - [members->window setFrame:NSMakeRect([members->window frame].origin.x, - [members->window frame].origin.y, - (float) Width, (float) Height) - display:YES]; - } -} - - -//////////////////////////////////////////////////////////// -/// /see sfWindowImpl::Show -//////////////////////////////////////////////////////////// -void WindowImplCocoa::Show(bool State) -{ - if (State) { - // Register ourselves for event handling - [[AppController sharedController] registerWindow:this]; - - if (fullscreen) { - desktopMode = VideoMode::GetDesktopMode(); - [NSMenu setMenuBarVisible:NO]; - - CFDictionaryRef bestMode = CGDisplayBestModeForParameters (CGMainDisplayID(), - fullscreenMode.BitsPerPixel, - fullscreenMode.Width, - fullscreenMode.Height, - NULL); - - CGDisplaySwitchToMode(CGMainDisplayID(), bestMode); - [members->window center]; - } - - // Show the window - [members->window makeKeyAndOrderFront:nil]; - } else { - // Close the window - [members->window close]; - - if (fullscreen) { - CFDictionaryRef bestMode = CGDisplayBestModeForParameters (CGMainDisplayID(), - desktopMode.BitsPerPixel, - desktopMode.Width, - desktopMode.Height, - NULL); - - CGDisplaySwitchToMode(CGMainDisplayID(), bestMode); - [NSMenu setMenuBarVisible:YES]; - } - - // Unregister ourselves from the event handler - [[AppController sharedController] unregisterWindow:this]; - } -} - - -//////////////////////////////////////////////////////////// -/// /see sfWindowImpl::EnableKeyRepeat -//////////////////////////////////////////////////////////// -void WindowImplCocoa::EnableKeyRepeat(bool Enabled) -{ - useKeyRepeat = Enabled; -} - - -//////////////////////////////////////////////////////////// -/// see WindowImpl::SetIcon -//////////////////////////////////////////////////////////// -void WindowImplCocoa::SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixels) -{ - // Nothing to do -} - - -//////////////////////////////////////////////////////////// -/// Make some allocations and initializations -//////////////////////////////////////////////////////////// -void WindowImplCocoa::Initialize(void) -{ - // Allocate mem for the private objc members - members = new objc_members; - if (!members) { - error(__FILE__, __LINE__, "couldn't allocate private objc members structure"); - } - bzero(members, sizeof(*members)); - - // Needed to always have an autorelease pool as soon as application is launched - [SharedAppController resetPool]; - - // Register application if needed and launch it - [SharedAppController runApplication]; -} - - -//////////////////////////////////////////////////////////// -/// Make the window -//////////////////////////////////////////////////////////// -static NSWindow *MakeWindow(WindowSettings& params, unsigned long style, VideoMode& mode, NSString *title) -{ - NSWindow *window = nil; - - NSRect frame = NSMakeRect (0.0f, 0.0f, (float) mode.Width, (float) mode.Height); - unsigned int mask = 0; - - // We grab options from WindowStyle and add them to our window mask - if (style & Style::None || style & Style::Fullscreen) { - mask |= NSBorderlessWindowMask; - - if (style & style & Style::Fullscreen) { - // Check display mode and put new values in 'mode' if needed - boolean_t exact = true; - CFDictionaryRef properties = CGDisplayBestModeForParameters(kCGDirectMainDisplay, mode.BitsPerPixel, - mode.Width, mode.Height, &exact); - - if (!properties) - return nil; - - if (exact == false) { - CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayWidth), - kCFNumberIntType, &mode.Width); - - CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayHeight), - kCFNumberIntType, &mode.Height); - - CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayBitsPerPixel), - kCFNumberIntType, &mode.BitsPerPixel); - } - } - - } else { - if (style & Style::Titlebar) { - mask |= NSTitledWindowMask; - mask |= NSMiniaturizableWindowMask; - } - - if (style & Style::Resize) { - mask |= NSTitledWindowMask; - mask |= NSMiniaturizableWindowMask; - mask |= NSResizableWindowMask; - } - - if (style & Style::Close) { - mask |= NSTitledWindowMask; - mask |= NSClosableWindowMask; - mask |= NSMiniaturizableWindowMask; - } - } - - // Now we make the window with the values we got - // Note: defer flag set to NO to be able to use OpenGL in our window - window = [[NSWindow alloc] initWithContentRect:frame - styleMask:mask - backing:NSBackingStoreBuffered - defer:NO]; - - if (window != nil) { - // We set title and window position - [window setTitle:title]; - [window center]; - } - - return window; -} - - -//////////////////////////////////////////////////////////// -/// Make the OpenGL pixel format from the given attributes -//////////////////////////////////////////////////////////// -static NSOpenGLContext *MakeOpenGLContext(WindowSettings& params) -{ - NSOpenGLPixelFormat *pixFormat = nil; - NSOpenGLContext *context = nil; - unsigned idx = 0, samplesIdx = 0; - - // Attributes list - NSOpenGLPixelFormatAttribute attribs[15] = {(NSOpenGLPixelFormatAttribute) 0}; - - // Accelerated, double buffered - attribs[idx++] = NSOpenGLPFAClosestPolicy; - attribs[idx++] = NSOpenGLPFADoubleBuffer; - attribs[idx++] = NSOpenGLPFAAccelerated; - - // windowed context - attribs[idx++] = NSOpenGLPFAWindow; - - // Color size ; usually 32 bits per pixel - attribs[idx++] = NSOpenGLPFAColorSize; - attribs[idx++] = (NSOpenGLPixelFormatAttribute) VideoMode::GetDesktopMode().BitsPerPixel; - - // Z-buffer size - attribs[idx++] = NSOpenGLPFADepthSize; - attribs[idx++] = (NSOpenGLPixelFormatAttribute) params.DepthBits; - - // Stencil bits (I don't really know what's that...) - attribs[idx++] = NSOpenGLPFAStencilSize; - attribs[idx++] = (NSOpenGLPixelFormatAttribute) params.StencilBits; - - // Antialiasing settings - if (params.AntialiasingLevel) { - samplesIdx = idx; - - attribs[idx++] = NSOpenGLPFASamples; - attribs[idx++] = (NSOpenGLPixelFormatAttribute) params.AntialiasingLevel; - - attribs[idx++] = NSOpenGLPFASampleBuffers; - attribs[idx++] = (NSOpenGLPixelFormatAttribute) GL_TRUE; - } - - pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; - - // If pixel format creation fails and antialiasing level is - // greater than 2, we set it to 2. - if (pixFormat == nil && params.AntialiasingLevel > 2) { - std::cerr << "Failed to find a pixel format supporting " << params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl; - params.AntialiasingLevel = attribs[samplesIdx + 1] = (NSOpenGLPixelFormatAttribute) 2; - - pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; - } - - // If pixel format creation fails and antialiasing is enabled, - // we disable it. - if (pixFormat == nil && params.AntialiasingLevel > 0) { - std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl; - attribs[samplesIdx] = (NSOpenGLPixelFormatAttribute) nil; - - pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; - } - - if (pixFormat) { - context = [[NSOpenGLContext alloc] initWithFormat:pixFormat - shareContext:[sharedContext retain]]; - - // Grab the effective properties from our OpenGL context - GLint tmpColorSize = 0, tmpDepthSize = 0, tmpStencilBits = 0, tmpAntialiasingLevel = 0; - - if (context) { - [pixFormat getValues:&tmpColorSize - forAttribute:NSOpenGLPFAColorSize - forVirtualScreen:[context currentVirtualScreen]]; - - [pixFormat getValues:&tmpDepthSize - forAttribute:NSOpenGLPFADepthSize - forVirtualScreen:[context currentVirtualScreen]]; - - [pixFormat getValues:&tmpStencilBits - forAttribute:NSOpenGLPFAStencilSize - forVirtualScreen:[context currentVirtualScreen]]; - - [pixFormat getValues:&tmpAntialiasingLevel - forAttribute:NSOpenGLPFASamples - forVirtualScreen:[context currentVirtualScreen]]; - } - - - params.DepthBits = (unsigned) tmpDepthSize; - params.StencilBits = (unsigned) tmpStencilBits; - params.AntialiasingLevel = (unsigned) tmpAntialiasingLevel; - - [pixFormat release]; - } - - return context; -} - - -static NSOpenGLView * MakeOpenGLView(NSWindow *window, NSOpenGLContext *context, WindowSettings& params) -{ - assert(window != nil); - assert(context != nil); - - NSOpenGLView *view = nil; - - - // We make the NSOpenGLView - view = [[NSOpenGLView alloc] initWithFrame:[[window contentView] bounds] - pixelFormat:nil]; - - if (view) { - // We add the NSOpenGLView to the window - [[window contentView] addSubview:view]; - - [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [view clearGLContext]; - [view setOpenGLContext:context]; - [context setView:view]; - } else { - error(__FILE__, __LINE__, "failed to make view"); - } - - return view; -} - - -static void ConfigureWindow(NSWindow *window, NSOpenGLView *view, WindowController *controller) -{ - assert(window != nil); - assert(view != nil); - assert(controller != nil); - - // We need to update the OpenGL view when it changes - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:controller - selector:@selector(viewFrameDidChange:) - name:NSViewFrameDidChangeNotification - object:view]; - - // We want to know when our window got the focus - [nc addObserver:controller - selector:@selector(windowDidBecomeMain:) - name:NSWindowDidBecomeMainNotification - object:window]; - - // We want to know when our window lost the focus - [nc addObserver:controller - selector:@selector(windowDidResignMain:) - name:NSWindowDidResignMainNotification - object:window]; - - // We want to know when the user closes the window - [nc addObserver:controller - selector:@selector(windowWillClose:) - name:NSWindowWillCloseNotification - object:window]; - - // I want to re-center the window if it's a full screen one and moved by Spaces - [nc addObserver:controller - selector:@selector(windowDidMove:) - name:NSWindowDidMoveNotification - object:window]; - - - // Needed not to make application crash when releasing the window in our destructor - // (I prefer to take control of everything :P) - [window setReleasedWhenClosed:NO]; - [window setAcceptsMouseMovedEvents:YES]; -} - - -//////////////////////////////////////////////////////////// -/// Return the SFML key corresponding to a key code -//////////////////////////////////////////////////////////// -static Key::Code KeyForVirtualCode(unsigned short vCode) -{ - static struct { - unsigned short code; - Key::Code sfKey; - } virtualTable[] = - { - {0x35, Key::Escape}, - {0x31, Key::Space}, - {0x24, Key::Return}, // main Return key - {0x4C, Key::Return}, // pav Return key - {0x33, Key::Back}, - {0x30, Key::Tab}, - {0x74, Key::PageUp}, - {0x79, Key::PageDown}, - {0x77, Key::End}, - {0x73, Key::Home}, - {0x72, Key::Insert}, - {0x75, Key::Delete}, - {0x45, Key::Add}, - {0x4E, Key::Subtract}, - {0x43, Key::Multiply}, - {0x4B, Key::Divide}, - - {0x7A, Key::F1}, {0x78, Key::F2}, {0x63, Key::F3}, - {0x76, Key::F4}, {0x60, Key::F5}, {0x61, Key::F6}, - {0x62, Key::F7}, {0x64, Key::F8}, {0x65, Key::F9}, - {0x6D, Key::F10}, {0x67, Key::F11}, {0x6F, Key::F12}, - {0x69, Key::F13}, {0x6B, Key::F14}, {0x71, Key::F15}, - - {0x7B, Key::Left}, - {0x7C, Key::Right}, - {0x7E, Key::Up}, - {0x7D, Key::Down}, - - {0x52, Key::Numpad0}, {0x53, Key::Numpad1}, {0x54, Key::Numpad2}, - {0x55, Key::Numpad3}, {0x56, Key::Numpad4}, {0x57, Key::Numpad5}, - {0x58, Key::Numpad6}, {0x59, Key::Numpad7}, {0x5B, Key::Numpad8}, - {0x5C, Key::Numpad9}, - - {0x1D, Key::Num0}, {0x12, Key::Num1}, {0x13, Key::Num2}, - {0x14, Key::Num3}, {0x15, Key::Num4}, {0x17, Key::Num5}, - {0x16, Key::Num6}, {0x1A, Key::Num7}, {0x1C, Key::Num8}, - {0x19, Key::Num9}, - - {0x3B, Key::LControl}, //< Left Ctrl - {0x3A, Key::LAlt}, //< Left Option/Alt - {0x37, Key::LSystem}, //< Left Command - {0x38, Key::LShift}, //< Left Shift - {0x3E, Key::RControl}, //< Right Ctrl - {0x3D, Key::RAlt}, //< Right Option/Alt - {0x36, Key::RSystem}, //< Right Command - {0x3C, Key::RShift}, //< Right Shift - - {0x39, Key::Code(0)} //< Caps Lock - }; - - Key::Code result = Key::Code(0); - - for (unsigned i = 0;virtualTable[i].code;i++) { - if (virtualTable[i].code == vCode) { - result = virtualTable[i].sfKey; - break; - } - } - - return result; -} - - -//////////////////////////////////////////////////////////// -/// Return the SFML key corresponding to a unicode code -//////////////////////////////////////////////////////////// -static Key::Code KeyForUnicode(unsigned short uniCode) -{ - static struct { - unsigned short character; - Key::Code sfKey; - } unicodeTable[] = - { - {'!', Key::Code(0)}, //< No Key for this code - {'"', Key::Code(0)}, //< No Key for this code - {'#', Key::Code(0)}, //< No Key for this code - {'$', Key::Code(0)}, //< No Key for this code - {'%', Key::Code(0)}, //< No Key for this code - {'&', Key::Code(0)}, //< No Key for this code - {'\'', Key::Quote}, - {'(', Key::Code(0)}, //< No Key for this code - {')', Key::Code(0)}, //< No Key for this code - {'*', Key::Multiply}, - {'+', Key::Add}, - {',', Key::Comma}, - {'-', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'.', Key::Period}, - {'/', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'0', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'1', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'2', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'3', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'4', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'5', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'6', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'7', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'8', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {'9', Key::Code(0)}, //< Handled by KeyForVirtualCode() - {':', Key::Code(0)}, //< No Key for this code - {';', Key::SemiColon}, - {'<', Key::Code(0)}, //< No Key for this code - {'=', Key::Equal}, - {'>', Key::Code(0)}, //< No Key for this code - {'?', Key::Code(0)}, //< No Key for this code - {'@', Key::Code(0)}, //< No Key for this code - {'A', Key::A}, {'B', Key::B}, {'C', Key::C}, - {'D', Key::D}, {'E', Key::E}, {'F', Key::F}, - {'G', Key::G}, {'H', Key::H}, {'I', Key::I}, - {'J', Key::J}, {'K', Key::K}, {'L', Key::L}, - {'M', Key::M}, {'N', Key::N}, {'O', Key::O}, - {'P', Key::P}, {'Q', Key::Q}, {'R', Key::R}, - {'S', Key::S}, {'T', Key::T}, {'U', Key::U}, - {'V', Key::V}, {'W', Key::W}, {'X', Key::X}, - {'Y', Key::Y}, {'Z', Key::Z}, - {'[', Key::LBracket}, - {'\\', Key::BackSlash}, - {']', Key::RBracket}, - {'^', Key::Code(0)}, //< No Key for this code - {'_', Key::Code(0)}, //< No Key for this code - {'`', Key::Code(0)}, //< No Key for this code - {'a', Key::A}, {'b', Key::B}, {'c', Key::C}, - {'d', Key::D}, {'e', Key::E}, {'f', Key::F}, - {'g', Key::G}, {'h', Key::H}, {'i', Key::I}, - {'j', Key::J}, {'k', Key::K}, {'l', Key::L}, - {'m', Key::M}, {'n', Key::N}, {'o', Key::O}, - {'p', Key::P}, {'q', Key::Q}, {'r', Key::R}, - {'s', Key::S}, {'t', Key::T}, {'u', Key::U}, - {'v', Key::V}, {'w', Key::W}, {'x', Key::X}, - {'y', Key::Y}, {'z', Key::Z}, - {'{', Key::Code(0)}, //< No Key for this code - {'|', Key::Code(0)}, //< No Key for this code - {'}', Key::Code(0)}, //< No Key for this code - {'~', Key::Tilde}, - {0, Key::Code(0)} - }; - - Key::Code result = Key::Code(0); - - for (unsigned i = 0;unicodeTable[i].character;i++) { - if (unicodeTable[i].character == uniCode) { - result = unicodeTable[i].sfKey; - break; - } - } - - return result; -} - - -//////////////////////////////////////////////////////////// -/// Return whether 'ev' must be considered as a TextEntered event -//////////////////////////////////////////////////////////// -static bool IsTextEvent(NSEvent *event) -{ - bool res = false; - - if (event && [event type] == NSKeyDown && [[event characters] length]) { - unichar code = [[event characters] characterAtIndex:0]; - - // Codes from 0xF700 to 0xF8FF are non text keys (see NSEvent.h) - if (code < 0xF700 || code > 0xF8FF) - res = true; - } - - return res; -} - - -//////////////////////////////////////////////////////////// -/// Return whether the mouse is on our OpenGL view -//////////////////////////////////////////////////////////// -static bool MouseInside(NSWindow *window, NSView *view) -{ - bool res = false; - - if (window && view && [window isVisible]) { - NSPoint relativeToWindow = [window mouseLocationOutsideOfEventStream]; - NSPoint relativeToView = [view convertPoint:relativeToWindow fromView:nil]; - - if (NSPointInRect (relativeToView, [view bounds])) - res = true; - } - - return res; -} - -} // namespace priv - -} // namespace sf - |