summaryrefslogtreecommitdiff
path: root/src/SFML/Window
diff options
context:
space:
mode:
authorChristoph Egger <Christoph.Egger@gmx.de>2009-06-14 21:52:32 +0200
committerChristoph Egger <Christoph.Egger@gmx.de>2009-06-14 21:52:32 +0200
commitaf202195872d59432cb74db74696bf1e57906663 (patch)
tree6606f4a90e91811e940f9fbc2e88a43154271939 /src/SFML/Window
parent9f9ee9c9f37ae026eb06e897a313aa26f68bf612 (diff)
Imported Upstream version 1.5+repack1
Diffstat (limited to 'src/SFML/Window')
-rwxr-xr-xsrc/SFML/Window/Cocoa/AppController.h76
-rwxr-xr-xsrc/SFML/Window/Cocoa/AppController.mm488
-rwxr-xr-xsrc/SFML/Window/Cocoa/GLKit.h209
-rwxr-xr-xsrc/SFML/Window/Cocoa/GLKit.mm854
-rwxr-xr-xsrc/SFML/Window/Cocoa/Joystick.cpp2
-rwxr-xr-xsrc/SFML/Window/Cocoa/Joystick.hpp2
-rwxr-xr-xsrc/SFML/Window/Cocoa/VideoModeSupport.cpp2
-rwxr-xr-xsrc/SFML/Window/Cocoa/VideoModeSupport.hpp2
-rwxr-xr-xsrc/SFML/Window/Cocoa/WindowController.mm157
-rwxr-xr-xsrc/SFML/Window/Cocoa/WindowImplCocoa.hpp64
-rwxr-xr-xsrc/SFML/Window/Cocoa/WindowImplCocoa.mm1002
-rwxr-xr-xsrc/SFML/Window/Context.cpp2
-rwxr-xr-xsrc/SFML/Window/Input.cpp2
-rwxr-xr-xsrc/SFML/Window/Joystick.hpp4
-rwxr-xr-xsrc/SFML/Window/Linux/Joystick.cpp52
-rwxr-xr-xsrc/SFML/Window/Linux/Joystick.hpp2
-rwxr-xr-xsrc/SFML/Window/Linux/VideoModeSupport.cpp33
-rwxr-xr-xsrc/SFML/Window/Linux/VideoModeSupport.hpp2
-rwxr-xr-xsrc/SFML/Window/Linux/WindowImplX11.cpp88
-rwxr-xr-xsrc/SFML/Window/Linux/WindowImplX11.hpp31
-rwxr-xr-xsrc/SFML/Window/Template for new ports/Joystick.cpp (renamed from src/SFML/Window/Cocoa/WindowController.h)147
-rwxr-xr-xsrc/SFML/Window/Template for new ports/Joystick.hpp82
-rwxr-xr-xsrc/SFML/Window/Template for new ports/VideoModeSupport.cpp60
-rwxr-xr-xsrc/SFML/Window/Template for new ports/VideoModeSupport.hpp69
-rwxr-xr-xsrc/SFML/Window/Template for new ports/WindowImplXXX.cpp231
-rwxr-xr-xsrc/SFML/Window/Template for new ports/WindowImplXXX.hpp167
-rwxr-xr-xsrc/SFML/Window/VideoMode.cpp2
-rwxr-xr-xsrc/SFML/Window/VideoModeSupport.hpp4
-rwxr-xr-xsrc/SFML/Window/Win32/Joystick.cpp4
-rwxr-xr-xsrc/SFML/Window/Win32/Joystick.hpp2
-rwxr-xr-xsrc/SFML/Window/Win32/VideoModeSupport.cpp2
-rwxr-xr-xsrc/SFML/Window/Win32/WindowImplWin32.cpp40
-rwxr-xr-xsrc/SFML/Window/Win32/WindowImplWin32.hpp2
-rwxr-xr-xsrc/SFML/Window/Window.cpp63
-rwxr-xr-xsrc/SFML/Window/WindowImpl.cpp512
-rwxr-xr-xsrc/SFML/Window/WindowImpl.hpp8
36 files changed, 2719 insertions, 1750 deletions
diff --git a/src/SFML/Window/Cocoa/AppController.h b/src/SFML/Window/Cocoa/AppController.h
index 365afc9..f56db4e 100755
--- a/src/SFML/Window/Cocoa/AppController.h
+++ b/src/SFML/Window/Cocoa/AppController.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Lucas Soltic (elmerod@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 Lucas Soltic (ceylow@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.
@@ -26,12 +26,8 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
-#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
#import <SFML/Window/VideoMode.hpp>
-#import <SFML/System/Clock.hpp>
#import <Cocoa/Cocoa.h>
-#import <vector>
-#import <iostream>
#define SharedAppController [AppController sharedController]
@@ -42,80 +38,50 @@ enum {
CleanScreen
};
-
+@class WindowWrapper;
@interface AppController : NSObject {
- // Note: objc allocation doesn't call C++ constructor
- std::vector <sf::priv::WindowImplCocoa *> *windows;
-
- NSAutoreleasePool *mainPool;
- sf::Clock *cleaner;
- sf::VideoMode desktopMode;
- sf::VideoMode prevMode;
+ BOOL myOwningEventLoop;
+ WindowWrapper *myFullscreenWrapper;
+ NSAutoreleasePool *myMainPool;
+ sf::VideoMode myDesktopMode;
+ sf::VideoMode myPrevMode;
}
////////////////////////////////////////////////////////////
-/// Return the shared AppController object. Makes one if needed
+/// Return the shared AppController instance. Make one if needed.
////////////////////////////////////////////////////////////
+ (AppController *)sharedController;
////////////////////////////////////////////////////////////
-/// Reallocate main pool to release autoreleased objects
-////////////////////////////////////////////////////////////
-- (void)resetPool;
-
-////////////////////////////////////////////////////////////
-/// Register our application and launch it if needed
-////////////////////////////////////////////////////////////
-- (void)runApplication;
-
-////////////////////////////////////////////////////////////
-/// Terminate the current running application
-////////////////////////////////////////////////////////////
-- (void)quitApplication:(id)sender;
-
-////////////////////////////////////////////////////////////
-/// Make menu bar
+/// Make the menu bar
////////////////////////////////////////////////////////////
- (void)makeMenuBar;
////////////////////////////////////////////////////////////
-/// Get the events and put them into an array for each window
+/// Process all the events and send them to the application
+/// No event is processed if the AppController instance is
+/// not the owner of the event loop (ie: user made his own loop)
////////////////////////////////////////////////////////////
- (void)processEvents;
////////////////////////////////////////////////////////////
-/// Add the 'windowImplObj' object to the list of known windows
+/// Set @window as the current fullscreen window
+/// Change the screen resolution if needed according to @window and @fullscreenMode
////////////////////////////////////////////////////////////
-- (void)registerWindow:(sf::priv::WindowImplCocoa *)windowImplObj;
-
-////////////////////////////////////////////////////////////
-/// Remove the 'windowImplObj' object from the list of known windows
-////////////////////////////////////////////////////////////
-- (void)unregisterWindow:(sf::priv::WindowImplCocoa *)windowImplObj;
-
-////////////////////////////////////////////////////////////
-/// Return true is one of the registered window is a full screen one
-////////////////////////////////////////////////////////////
-- (bool)isUsingFullscreen;
+- (void)setFullscreenWindow:(WindowWrapper *)window mode:(sf::VideoMode *)fullscreenMode;
////////////////////////////////////////////////////////////
/// Perform fade operation where 'operation' is one of { FillScreen, CleanScreen}
/// and 'time' is the time during which you wish the operation to be performed.
/// Set 'sync' to true if you do not want the method to end before the end
-/// of the fade operation. Pass the last used token or a new one if you are
-/// using this method for the first time. This lets the method release some
-/// resources when doing CleanScreen operation.
+/// of the fade operation.
////////////////////////////////////////////////////////////
-- (void)doFadeOperation:(int)operation time:(float)time sync:(bool)sync token:(CGDisplayFadeReservationToken *)prevToken;
-
-@end
-
+- (void)doFadeOperation:(int)operation time:(float)time sync:(bool)sync;
////////////////////////////////////////////////////////////
-/// check that ptr is valid, otherwise print msg in
-/// std::cerr and throw std::bad_alloc.
-/// Must be used to check alloc results
+/// Return the desktop video mode (made at the instance initialization)
////////////////////////////////////////////////////////////
-template <typename T>
-T *massert(T *ptr);
+- (const sf::VideoMode&)desktopMode;
+
+@end
diff --git a/src/SFML/Window/Cocoa/AppController.mm b/src/SFML/Window/Cocoa/AppController.mm
index a6b7310..8d07eaf 100755
--- a/src/SFML/Window/Cocoa/AppController.mm
+++ b/src/SFML/Window/Cocoa/AppController.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Lucas Soltic (elmerod@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 Lucas Soltic (ceylow@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.
@@ -27,14 +27,13 @@
// Headers
////////////////////////////////////////////////////////////
#import <SFML/Window/Cocoa/AppController.h>
-#import <SFML/Window/Cocoa/WindowController.h>
-#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
+#import <SFML/Window/Cocoa/GLKit.h>
#import <SFML/System.hpp>
#import <ApplicationServices/ApplicationServices.h>
#import <iostream>
-// AppController singleton
+// AppController singleton object
static AppController *shared = nil;
@@ -45,6 +44,8 @@ static AppController *shared = nil;
@end
#endif
+#define ENABLE_FADE_OPERATIONS 1
+
@implementation NSApplication (SFML)
- (void)setRunning:(BOOL)flag
@@ -61,160 +62,120 @@ static AppController *shared = nil;
@implementation AppController
+
+////////////////////////////////////////////////////////////
+/// Return an initialized AppController instance
+/// Save the desktop mode
+/// Make the main autorelease pool
+/// Set the application observer
+////////////////////////////////////////////////////////////
- (id)init
{
self = [super init];
if (self != nil) {
- windows = new std::vector <sf::priv::WindowImplCocoa *>;
- cleaner = new sf::Clock;
+ myOwningEventLoop = NO;
+
+ // Save the desktop mode
+ myDesktopMode = sf::VideoMode::GetDesktopMode();
+ myPrevMode = myDesktopMode;
+
+ // Make the app autorelease pool
+ myMainPool = [[NSAutoreleasePool alloc] init];
+
+ // Don't go on if the user handles the app
+ if (![NSApp isRunning])
+ {
+ // Force our application to appear in the Dock and make it able
+ // to get focus (even when it's a raw executable)
+ ProcessSerialNumber psn;
+
+ if (!GetCurrentProcess(&psn)) {
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ SetFrontProcess(&psn);
+ }
+
+ // Make the app
+ [NSApplication sharedApplication];
+
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+ // I want to go back to the desktop mode
+ // if we've a fullscreen window when hiding
+ [nc addObserver:self
+ selector:@selector(applicationWillHide:)
+ name:NSApplicationWillHideNotification
+ object:NSApp];
+
+ // And restore de fullscreen mode when unhiding
+ [nc addObserver:self
+ selector:@selector(applicationWillUnhide:)
+ name:NSApplicationWillUnhideNotification
+ object:NSApp];
+
+ // Go back to desktop mode before exit
+ [nc addObserver:self
+ selector:@selector(applicationWillTerminate:)
+ name:NSApplicationWillTerminateNotification
+ object:NSApp];
+
+ if ([NSApp mainMenu] == nil) {
+ [self makeMenuBar];
+ }
+ }
}
return self;
}
+////////////////////////////////////////////////////////////
+/// Clean the controller
+////////////////////////////////////////////////////////////
- (void)dealloc
{
- delete windows;
- delete cleaner;
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [myFullscreenWrapper release];
[super dealloc];
}
////////////////////////////////////////////////////////////
-/// Return the shared AppController object. Makes one if needed
+/// Return the shared AppController instance. Make one if needed.
////////////////////////////////////////////////////////////
+ (AppController *)sharedController
{
- if (nil == shared) {
- shared = [massert([AppController alloc]) init];
- }
+ if (nil == shared)
+ shared = [[AppController alloc] init];
return shared;
}
////////////////////////////////////////////////////////////
-/// Reallocate main pool to release autoreleased objects
-////////////////////////////////////////////////////////////
-- (void)resetPool
-{
- [mainPool release];
-
- mainPool = [massert([NSAutoreleasePool alloc]) init];
-}
-
-
-////////////////////////////////////////////////////////////
-/// Register our application and launch it if needed
-////////////////////////////////////////////////////////////
-- (void)runApplication
-{
- if ([NSApp isRunning])
- return;
-
- // We want our application to appear in the Dock and be able
- // to get focus
- ProcessSerialNumber psn;
-
- if (!GetCurrentProcess(&psn)) {
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
- SetFrontProcess(&psn);
- }
-
- if (NSApp == nil) {
- massert([NSApplication sharedApplication]);
- }
-
- if ([NSApp mainMenu] == nil) {
- [self makeMenuBar];
- }
-
- [NSApp finishLaunching];
- [NSApp setRunning:YES];
- [NSApp setDelegate:self];
-
- desktopMode = sf::VideoMode::GetDesktopMode();
-}
-
-
-////////////////////////////////////////////////////////////
-/// Terminate the current running application
-////////////////////////////////////////////////////////////
-- (void)quitApplication:(id)sender
-{
- // Close all windows
- // SFML user has to detect when all windows are closed
- NSWindow *current = nil;
- sf::priv::WindowImplCocoa *priv = NULL;
-
- while (windows->size()) {
- priv = windows->at(0);
- current = static_cast <NSWindow *> (priv->CocoaWindow());
- [current close];
- windows->erase(windows->begin());
- }
-}
-
-
-////////////////////////////////////////////////////////////
-/// Returns the first full screen window found or nil
-////////////////////////////////////////////////////////////
-- (SFWindow *)fullscreenWindow
-{
- SFWindow *window = nil;
- std::vector<sf::priv::WindowImplCocoa *>::size_type sz = windows->size();
- std::vector<sf::priv::WindowImplCocoa *>::size_type idx;
-
- for (idx = 0; idx < sz; idx++) {
- sf::priv::WindowImplCocoa *win = windows->at(idx);
- if (win && win->IsFullscreen()) {
- window = static_cast <SFWindow *> (win->CocoaWindow());
- break;
- }
- }
-
- return window;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Hide all the fullscreen windows and switch to desktop display mode
+/// Hide all the fullscreen windows and switch back to the desktop display mode
////////////////////////////////////////////////////////////
- (void)applicationWillHide:(NSNotification *)aNotification
{
- if ([self isUsingFullscreen]) {
- prevMode = sf::VideoMode::GetDesktopMode();
+ if (myFullscreenWrapper) {
+ myPrevMode = sf::VideoMode::GetDesktopMode();
CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay,
- desktopMode.BitsPerPixel,
- desktopMode.Width,
- desktopMode.Height,
+ myDesktopMode.BitsPerPixel,
+ myDesktopMode.Width,
+ myDesktopMode.Height,
NULL);
- CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
-
// Fade to black screen
- [SharedAppController doFadeOperation:FillScreen time:0.2f sync:true token:&token];
+ [self doFadeOperation:FillScreen time:0.2f sync:true];
- // Make all the full screen SFML windows unvisible
- std::vector<sf::priv::WindowImplCocoa *>::size_type sz = windows->size();
- std::vector<sf::priv::WindowImplCocoa *>::size_type idx;
-
- for (idx = 0; idx < sz; idx++) {
- sf::priv::WindowImplCocoa *win = windows->at(idx);
-
- if (win->IsFullscreen()) {
- [static_cast <SFWindow *> (win->CocoaWindow()) setAlphaValue:0.0f];
- }
- }
+ // Make the full screen window unvisible
+ [[myFullscreenWrapper window] setAlphaValue:0.0f];
// Switch to the wished display mode
CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
// Fade to normal screen
- [SharedAppController doFadeOperation:CleanScreen time:0.5f sync:false token:&token];
+ [self doFadeOperation:CleanScreen time:0.5f sync:false];
}
}
@@ -224,41 +185,43 @@ static AppController *shared = nil;
////////////////////////////////////////////////////////////
- (void)applicationWillUnhide:(NSNotification *)aNotification
{
- if ([self isUsingFullscreen]) {
+ if (myFullscreenWrapper) {
CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay,
- prevMode.BitsPerPixel,
- prevMode.Width,
- prevMode.Height,
+ myPrevMode.BitsPerPixel,
+ myPrevMode.Width,
+ myPrevMode.Height,
NULL);
- CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
-
// Fade to a black screen
- [SharedAppController doFadeOperation:FillScreen time:0.5f sync:true token:&token];
+ [self doFadeOperation:FillScreen time:0.5f sync:true];
[NSMenu setMenuBarVisible:NO];
// Switch to the wished display mode
CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
- // Make all the SFML windows visible
- std::vector<sf::priv::WindowImplCocoa *>::size_type sz = windows->size();
- std::vector<sf::priv::WindowImplCocoa *>::size_type idx;
-
- for (idx = 0; idx < sz; idx++) {
- sf::priv::WindowImplCocoa *win = windows->at(idx);
-
- if (win->IsFullscreen()) {
- [static_cast <SFWindow *> (win->CocoaWindow()) setAlphaValue:1.0f];
- [static_cast <SFWindow *> (win->CocoaWindow()) center];
- }
+ // Show the fullscreen window if existing
+ if (myFullscreenWrapper)
+ {
+ [[myFullscreenWrapper window] setAlphaValue:1.0f];
+ [[myFullscreenWrapper window] center];
}
// Fade to normal screen
- [SharedAppController doFadeOperation:CleanScreen time:0.5f sync:false token:&token];
+ [self doFadeOperation:CleanScreen time:0.5f sync:false];
}
}
+- (void)applicationWillTerminate:(NSNotification *)aNotification
+{
+ if (myFullscreenWrapper)
+ [self setFullscreenWindow:nil mode:NULL];
+
+ // FIXME: should I really do this ? what about the user owned windows ?
+ // And is this really useful as the application is about to exit ?
+ [NSApp makeWindowsPerform:@selector(close) inOrder:NO];
+}
+
////////////////////////////////////////////////////////////
/// Make menu bar
////////////////////////////////////////////////////////////
@@ -282,10 +245,10 @@ static AppController *shared = nil;
// Create the main menu bar
- [NSApp setMainMenu:[massert([NSMenu alloc]) init]];
+ [NSApp setMainMenu:[[NSMenu alloc] init]];
// Create the application menu
- appleMenu = [massert([NSMenu alloc]) initWithTitle:@""];
+ appleMenu = [[NSMenu alloc] initWithTitle:@""];
// Put menu items
// + 'About' menu item
@@ -303,7 +266,7 @@ static AppController *shared = nil;
keyEquivalent:@"h"];
// + 'Hide other' menu item
- menuItem = static_cast <NSMenuItem *> ([appleMenu addItemWithTitle:@"Hide Others"
+ menuItem = reinterpret_cast <NSMenuItem *> ([appleMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"]);
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
@@ -317,15 +280,15 @@ static AppController *shared = nil;
// + 'Quit' menu item
title = [@"Quit " stringByAppendingString:appName];
- quitMenuItem = [[massert([NSMenuItem alloc])
+ quitMenuItem = [[[NSMenuItem alloc]
initWithTitle:title
- action:@selector(quitApplication:)
+ action:@selector(terminate:)
keyEquivalent:@"q"] autorelease];
- [quitMenuItem setTarget:self];
+ //[quitMenuItem setTarget:self];
[appleMenu addItem:quitMenuItem];
// Put the menu into the menubar
- menuItem = [massert([NSMenuItem alloc])
+ menuItem = [[NSMenuItem alloc]
initWithTitle:@""
action:nil
keyEquivalent:@""];
@@ -338,11 +301,11 @@ static AppController *shared = nil;
[appleMenu release];
// 'File' menu
- fileMenu = [massert([NSMenu alloc])
+ fileMenu = [[NSMenu alloc]
initWithTitle:@"File"];
// + 'Close' menu item
- menuItem = [massert([NSMenuItem alloc])
+ menuItem = [[NSMenuItem alloc]
initWithTitle:@"Close"
action:@selector(performClose:)
keyEquivalent:@"w"];
@@ -350,7 +313,7 @@ static AppController *shared = nil;
[menuItem release];
// + 'File' menu item (head)
- menuItem = [massert([NSMenuItem alloc])
+ menuItem = [[NSMenuItem alloc]
initWithTitle:@"File"
action:nil
keyEquivalent:@""];
@@ -359,11 +322,11 @@ static AppController *shared = nil;
[menuItem release];
// 'Window' menu
- windowMenu = [massert([NSMenu alloc])
+ windowMenu = [[NSMenu alloc]
initWithTitle:@"Window"];
// + 'Minimize' menu item
- menuItem = [massert([NSMenuItem alloc])
+ menuItem = [[NSMenuItem alloc]
initWithTitle:@"Minimize"
action:@selector(performMiniaturize:)
keyEquivalent:@"m"];
@@ -371,7 +334,7 @@ static AppController *shared = nil;
[menuItem release];
// + 'Window' menu item (head)
- menuItem = [massert([NSMenuItem alloc])
+ menuItem = [[NSMenuItem alloc]
initWithTitle:@"Window"
action:nil keyEquivalent:@""];
[menuItem setSubmenu:windowMenu];
@@ -385,143 +348,143 @@ static AppController *shared = nil;
////////////////////////////////////////////////////////////
-/// Delegate method in order to prevent usual -terminate:
-////////////////////////////////////////////////////////////
-- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
-{
- [self quitApplication:nil];
- return NSTerminateCancel;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Get the events and put them into an array for each window
+/// Process all the events and send them to the application
+/// No event is processed if the AppController instance is
+/// not the owner of the event loop (ie: user made his own loop)
////////////////////////////////////////////////////////////
- (void)processEvents
{
- // Release the main autorelease pool every second
- if (cleaner->GetElapsedTime() > 1.0f) {
- cleaner->Reset();
- [self resetPool];
+ // Check there is a run loop
+ if (![NSApp isRunning])
+ {
+ // Get the ownershipt of event handling if not and run
+ [NSApp finishLaunching];
+ [NSApp setRunning:YES];
+ myOwningEventLoop = YES;
}
+ // Clean the autorelease pool
+ [myMainPool release];
+ myMainPool = [[NSAutoreleasePool alloc] init];
+
NSEvent *event = nil;
- while (nil != (event = [NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:nil
- inMode:NSEventTrackingRunLoopMode
- dequeue:YES])) {
- NSWindow *keyWindow = [NSApp keyWindow];
-
- if (keyWindow == nil) {
- // Is there a fullscreen WindowImpl object ?
+ if (myOwningEventLoop)
+ {
+ // Minimal event loop
+ while (nil != (event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:nil
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES]))
+ {
[NSApp sendEvent:event];
- } else {
-
- std::vector<sf::priv::WindowImplCocoa *>::size_type cnt = windows->size();
- std::vector<sf::priv::WindowImplCocoa *>::size_type idx;
-
- // is the key window a SFML window ?
- for (idx = 0;idx < cnt; idx++) {
- sf::priv::WindowImplCocoa *ptr = windows->at(idx);;
-
- if (ptr->CocoaWindow() == keyWindow) {
- // yup, it is
- ptr->HandleEvent(static_cast <void *> (event));
- break;
- }
- }
-
- // nop, it isn't
- if (idx == cnt) {
- [NSApp sendEvent:event];
- }
}
}
}
////////////////////////////////////////////////////////////
-/// Add the 'windowImplObj' object to the list of known windows
+/// Set @window as the current fullscreen window
+/// Change the screen resolution if needed according to @window and @fullscreenMode
////////////////////////////////////////////////////////////
-- (void)registerWindow:(sf::priv::WindowImplCocoa *)windowImplObj
+- (void)setFullscreenWindow:(WindowWrapper *)aWrapper mode:(sf::VideoMode *)fullscreenMode
{
-
- if (windowImplObj != NULL) {
- std::vector<sf::priv::WindowImplCocoa *>::size_type sz = windows->size();
- std::vector<sf::priv::WindowImplCocoa *>::size_type idx;
+ // If we have a fullscreen window and want to remove it
+ if (aWrapper == nil && myFullscreenWrapper)
+ {
+ // Get the CoreGraphics display mode according to the desktop mode
+ CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay,
+ myDesktopMode.BitsPerPixel,
+ myDesktopMode.Width,
+ myDesktopMode.Height,
+ NULL);
- for (idx = 0; idx < sz; idx++) {
- if (windows->at(idx) == windowImplObj) {
- break;
- }
- }
+#if ENABLE_FADE_OPERATIONS
+ // Fade to black screen
+ [self doFadeOperation:FillScreen time:0.2f sync:true];
+#endif
+ // Switch to the desktop display mode
+ CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
- // Register window only if not already registered
- if (sz == idx) {
- windows->push_back(windowImplObj);
- }
+ // Close the window
+ [[myFullscreenWrapper window] close];
+
+ // Show the menu bar
+ [NSMenu setMenuBarVisible:YES];
+
+#if ENABLE_FADE_OPERATIONS
+ // Fade to normal screen
+ [self doFadeOperation:CleanScreen time:0.5f sync:true];
+#endif
+
+ // Release the saved window wrapper
+ myFullscreenWrapper = nil;
}
-}
-
-
-////////////////////////////////////////////////////////////
-/// Remove the 'windowImplObj' object from the list of known windows
-////////////////////////////////////////////////////////////
-- (void)unregisterWindow:(sf::priv::WindowImplCocoa *)windowImplObj
-{
- if (windowImplObj != NULL) {
- std::vector<sf::priv::WindowImplCocoa *>::size_type sz = windows->size();
- std::vector<sf::priv::WindowImplCocoa *>::size_type idx;
+ else if (aWrapper)
+ {
+ assert(fullscreenMode != NULL);
- for (idx = 0; idx < sz; idx++) {
- if (windows->at(idx) == windowImplObj) {
- break;
- }
+ // Get the CoreGraphics display mode according to the given sf mode
+ CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay,
+ fullscreenMode->BitsPerPixel,
+ fullscreenMode->Width,
+ fullscreenMode->Height,
+ NULL);
+
+#if ENABLE_FADE_OPERATIONS
+ // Fade to a black screen
+ [self doFadeOperation:FillScreen time:0.5f sync:true];
+#endif
+
+ if (!myFullscreenWrapper)
+ {
+ // Hide the main menu bar
+ [NSMenu setMenuBarVisible:NO];
}
- if (idx < sz) {
- windows->erase(windows->begin() + idx);
+ if (myPrevMode != *fullscreenMode)
+ {
+ // Switch to the wished display mode
+ CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
}
- }
-}
-
-
-////////////////////////////////////////////////////////////
-/// Return true is one of the registered window is a full screen one
-////////////////////////////////////////////////////////////
-- (bool)isUsingFullscreen
-{
- bool isUsing = false;
- std::vector<sf::priv::WindowImplCocoa *>::size_type sz = windows->size();
- std::vector<sf::priv::WindowImplCocoa *>::size_type idx;
-
- for (idx = 0; idx < sz; idx++) {
- sf::priv::WindowImplCocoa *win = windows->at(idx);
- if (win && win->IsFullscreen()) {
- isUsing = true;
- break;
+
+ if (myFullscreenWrapper)
+ {
+ [[myFullscreenWrapper window] close];
}
+
+ // Open and center the window
+ [[aWrapper window] makeKeyAndOrderFront:nil];
+ [[aWrapper window] center];
+
+#if ENABLE_FADE_OPERATIONS
+ // Fade to normal screen
+ [self doFadeOperation:CleanScreen time:0.2f sync:false];
+#endif
+
+ // Save the fullscreen wrapper
+ myFullscreenWrapper = aWrapper;
+ }
+ else
+ {
+ std::cerr << "Inconcistency error for arguments given to -[AppController setFullscreenWindow:mode:]" << std::endl;
}
-
- return isUsing;
}
////////////////////////////////////////////////////////////
-/// Perform fade operation where 'operation' is one of { FillScreen, CleanScreen}
+/// Perform fade operation where 'operation' is one of {FillScreen, CleanScreen}
/// and 'time' is the time during which you wish the operation to be performed.
/// Set 'sync' to true if you do not want the method to end before the end
/// of the fade operation. Pass the last used token or a new one if you are
/// using this method for the first time. This lets the method release some
/// resources when doing CleanScreen operation.
////////////////////////////////////////////////////////////
-- (void) doFadeOperation:(int)operation time:(float)time sync:(bool)sync token:(CGDisplayFadeReservationToken *)prevToken
+- (void) doFadeOperation:(int)operation time:(float)time sync:(bool)sync
{
- CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
- if (prevToken)
- token = *prevToken;
+ static CGDisplayFadeReservationToken prevToken = kCGDisplayFadeReservationInvalidToken;
+ CGDisplayFadeReservationToken token = prevToken;
CGError result = 0, capture = 0;
@@ -539,7 +502,7 @@ static AppController *shared = nil;
CGDisplayFade(token, time,
kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor,
- 0.0, 0.0, 0.0, sync);
+ 0.0f, 0.0f, 0.0f, sync);
// Now, release the non black-filling capture
CGDisplayRelease(kCGDirectMainDisplay);
@@ -549,8 +512,7 @@ static AppController *shared = nil;
CGDisplayCaptureWithOptions(kCGDirectMainDisplay, kCGCaptureNoOptions);
}
- if (prevToken)
- *prevToken = token;
+ prevToken = token;
}
} else if (operation == CleanScreen) {
// Get access for the fade operation
@@ -569,14 +531,13 @@ static AppController *shared = nil;
CGDisplayFade(token, time,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal,
- 0.0, 0.0, 0.0, sync);
+ 0.0f, 0.0f, 0.0f, sync);
// Release the fade operation token
CGReleaseDisplayFadeReservation(token);
// Invalidate the given token
- if (prevToken)
- *prevToken = kCGDisplayFadeReservationInvalidToken;
+ prevToken = kCGDisplayFadeReservationInvalidToken;
}
// Release the captured display
@@ -585,15 +546,14 @@ static AppController *shared = nil;
}
}
-@end
-
-template <typename T>
-T *massert(T *ptr)
+////////////////////////////////////////////////////////////
+/// Return the desktop video mode (made at the instance initialization)
+////////////////////////////////////////////////////////////
+- (const sf::VideoMode&)desktopMode
{
- if (NULL == ptr) {
- throw std::bad_alloc();
- }
-
- return ptr;
+ return myDesktopMode;
}
+
+@end
+
diff --git a/src/SFML/Window/Cocoa/GLKit.h b/src/SFML/Window/Cocoa/GLKit.h
new file mode 100755
index 0000000..ac12252
--- /dev/null
+++ b/src/SFML/Window/Cocoa/GLKit.h
@@ -0,0 +1,209 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Lucas Soltic (ceylow@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 <Cocoa/Cocoa.h>
+#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
+
+
+////////////////////////////////////////////////////////////
+/// Window independant OpenGL context class
+////////////////////////////////////////////////////////////
+@interface GLContext : NSOpenGLContext
+{
+ GLContext *mySharedContext;
+}
+
+////////////////////////////////////////////////////////////
+/// Return the shared OpenGL context instance (making one if needed)
+////////////////////////////////////////////////////////////
++ (id)sharedContext;
+
+////////////////////////////////////////////////////////////
+/// Make a new OpenGL context according to the @attribs settings
+/// and the shared context @context
+////////////////////////////////////////////////////////////
+- (id)initWithAttributes:(sf::WindowSettings&)attribs
+ sharedContext:(GLContext *)context;
+
+@end
+
+
+////////////////////////////////////////////////////////////
+/// Customized Cocoa OpenGL view
+////////////////////////////////////////////////////////////
+@interface GLView : NSOpenGLView
+{
+ sf::priv::WindowImplCocoa *myDelegate;
+ GLContext *myGLContext;
+}
+
+////////////////////////////////////////////////////////////
+/// Make a new view according the the rect @frame,
+/// the video mode @mode, the window settings @settings
+/// and the sf window delegate @delegate
+/// @delegate must not be null
+////////////////////////////////////////////////////////////
+- (id)initWithFrame:(NSRect)frame
+ mode:(const sf::VideoMode&)mode
+ settings:(sf::WindowSettings&)settings
+ delegate:(sf::priv::WindowImplCocoa *)delegate;
+
+////////////////////////////////////////////////////////////
+/// Finish view setting (after having added it to the window)
+////////////////////////////////////////////////////////////
+- (void)finishInitialization;
+
+////////////////////////////////////////////////////////////
+/// Forward call to en/disable vertical synchronization
+////////////////////////////////////////////////////////////
+- (void)enableVerticalSync:(bool)flag;
+
+////////////////////////////////////////////////////////////
+/// Forward call to set the OpenGL context as active according to @flag
+////////////////////////////////////////////////////////////
+- (void)setActive:(bool)flag;
+
+////////////////////////////////////////////////////////////
+/// Forward call to flush the OpenGL context
+////////////////////////////////////////////////////////////
+- (void)flushBuffer;
+
+@end
+
+////////////////////////////////////////////////////////////
+/// Cocoa window implementation to let fullscreen windows
+/// catch key events
+////////////////////////////////////////////////////////////
+@interface GLWindow : NSWindow
+
+////////////////////////////////////////////////////////////
+/// Technical note: this class must neither contain new members
+/// nor methods. It is used transparently as a NSWindow object
+/// by WindowWrapper. Not following this rule could result
+/// in a segmentation fault or data corruption.
+////////////////////////////////////////////////////////////
+
+@end
+
+////////////////////////////////////////////////////////////
+/// WindowWrapper class : handles both imported and self-built windows
+////////////////////////////////////////////////////////////
+@interface WindowWrapper : NSObject
+{
+ GLWindow *myWindow;
+ GLView *myView;
+ sf::VideoMode myFullscreenMode;
+ bool myIsFullscreen;
+}
+
+////////////////////////////////////////////////////////////
+/// Make a new window wrapper according to the window settings @attribs,
+/// the video mode @mode, the window style @style, the window title @title
+/// and the sf window implementation delegate @delegate
+////////////////////////////////////////////////////////////
+- (id)initWithSettings:(sf::WindowSettings&)attribs
+ videoMode:(sf::VideoMode&)mode
+ style:(unsigned long)style
+ title:(NSString *)title
+ delegate:(sf::priv::WindowImplCocoa *)delegate;
+
+////////////////////////////////////////////////////////////
+/// Make a new window wrapper by importing @window and according to
+/// the window settings @params and the sf window implementation delegate
+/// @delegate
+/// @window and @delegate must not be null
+////////////////////////////////////////////////////////////
+- (id)initWithWindow:(NSWindow *)window
+ settings:(sf::WindowSettings&)params
+ delegate:(sf::priv::WindowImplCocoa *)delegate;
+
+////////////////////////////////////////////////////////////
+/// Make a new window wrapper by importing @window if it's not null and according to
+/// the window settings @params and the sf window implementation delegate
+/// @delegate; or by creating a new window if @window is null. In this case @title
+/// must therefore not be null and @params must be valid.
+/// @delegate must never be null
+////////////////////////////////////////////////////////////
+- (id)initWithWindow:(NSWindow *)window
+ settings:(sf::WindowSettings&)params
+ videoMode:(sf::VideoMode&)mode
+ style:(unsigned long)style
+ title:(NSString *)title
+ delegate:(sf::priv::WindowImplCocoa *)delegate;
+
+////////////////////////////////////////////////////////////
+/// Return a reference to the internal Cocoa window
+////////////////////////////////////////////////////////////
+- (NSWindow *)window;
+
+////////////////////////////////////////////////////////////
+/// Return a reference to the internal Cocoa OpenGL view
+////////////////////////////////////////////////////////////
+- (GLView *)glView;
+
+////////////////////////////////////////////////////////////
+/// Forward call to set the window position on screen
+////////////////////////////////////////////////////////////
+- (void)setPosition:(NSPoint)pos;
+
+////////////////////////////////////////////////////////////
+/// Forward call to set the window size
+////////////////////////////////////////////////////////////
+- (void)setSize:(NSSize)size;
+
+////////////////////////////////////////////////////////////
+/// Return the mouse location relative to the internal window
+////////////////////////////////////////////////////////////
+- (NSPoint)mouseLocation;
+
+////////////////////////////////////////////////////////////
+/// Return whether the mouse is on our window
+////////////////////////////////////////////////////////////
+- (BOOL)mouseInside;
+
+////////////////////////////////////////////////////////////
+/// Close or open the window
+////////////////////////////////////////////////////////////
+- (void)show:(bool)flag;
+
+////////////////////////////////////////////////////////////
+/// Forward call to en/disable the OpenGL view vertical synchronization
+////////////////////////////////////////////////////////////
+- (void)enableVerticalSync:(bool)flag;
+
+////////////////////////////////////////////////////////////
+/// Forward 'setActive' call the the OpenGL view
+////////////////////////////////////////////////////////////
+- (void)setActive:(bool)flag;
+
+////////////////////////////////////////////////////////////
+/// Forward call to flush the OpenGL view
+////////////////////////////////////////////////////////////
+- (void)flushBuffer;
+
+@end
+
diff --git a/src/SFML/Window/Cocoa/GLKit.mm b/src/SFML/Window/Cocoa/GLKit.mm
new file mode 100755
index 0000000..a570f44
--- /dev/null
+++ b/src/SFML/Window/Cocoa/GLKit.mm
@@ -0,0 +1,854 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 Lucas Soltic (ceylow@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/Cocoa/GLKit.h>
+#import <SFML/Window/Cocoa/AppController.h>
+#import <SFML/Window/VideoMode.hpp>
+#import <SFML/Window/WindowStyle.hpp>
+#import <SFML/System/Sleep.hpp>
+#import <OpenGL/gl.h>
+#import <iostream>
+
+
+////////////////////////////////////////////////////////////
+/// Window independant OpenGL context class
+////////////////////////////////////////////////////////////
+@implementation GLContext
+
+static GLContext *sharedCtx = nil;
+
+////////////////////////////////////////////////////////////
+/// Return the shared OpenGL context instance (making one if needed)
+////////////////////////////////////////////////////////////
++ (id)sharedContext
+{
+ if (sharedCtx == nil)
+ {
+ // Make a new context with the default parameters
+ sf::WindowSettings params(0, 0, 0);
+ sharedCtx = [[GLContext alloc] initWithAttributes:params sharedContext:nil];
+ }
+
+ return sharedCtx;
+}
+
+- (void)dealloc
+{
+ [mySharedContext release];
+ [super dealloc];
+}
+
+////////////////////////////////////////////////////////////
+/// Make a new OpenGL context according to the @attribs settings
+/// and the shared context @context
+////////////////////////////////////////////////////////////
+- (id)initWithAttributes:(sf::WindowSettings&)attribs sharedContext:(GLContext *)context
+{
+ // Note about antialiasing and other context attributes :
+ // OpenGL context sharing does not allow the shared contexts to use different attributes.
+ // The point is that the default shared global OpenGL context uses default parameters.
+ // That means that all the other context *should* use the same paramaters.
+ // Fortunately some values parameters for some parameters are compatible, but some are not
+ // among which : the antialising level.
+ //
+ // I've no way to fix this for now.
+
+ if (attribs.AntialiasingLevel)
+ std::cerr << "Warning: antialiasing settings are inhibited under Mac OS X for technical reasons" << std::endl;
+
+ NSOpenGLPixelFormat *myPixelFormat = nil;
+ unsigned idx = 0;
+
+ // Attributes list
+ NSOpenGLPixelFormatAttribute ctxtAttribs[15] = {(NSOpenGLPixelFormatAttribute) 0};
+
+ // Accelerated, double buffered
+ ctxtAttribs[idx++] = NSOpenGLPFAClosestPolicy;
+ ctxtAttribs[idx++] = NSOpenGLPFADoubleBuffer;
+ ctxtAttribs[idx++] = NSOpenGLPFAAccelerated;
+
+ // windowed context (even fullscreen mode uses a window)
+ ctxtAttribs[idx++] = NSOpenGLPFAWindow;
+
+ // Color size ; usually 32 bits per pixel
+ ctxtAttribs[idx++] = NSOpenGLPFAColorSize;
+ ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) sf::VideoMode::GetDesktopMode().BitsPerPixel;
+
+ // Z-buffer size
+ ctxtAttribs[idx++] = NSOpenGLPFADepthSize;
+ ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) attribs.DepthBits;
+
+ // Stencil bits (I don't really know what's that...)
+ ctxtAttribs[idx++] = NSOpenGLPFAStencilSize;
+ ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) attribs.StencilBits;
+
+ myPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:ctxtAttribs];
+
+ if (myPixelFormat) {
+ self = [super initWithFormat:myPixelFormat
+ shareContext:context];
+
+ mySharedContext = [context retain];
+
+ // Get the effective properties from our OpenGL context
+ GLint tmpDepthSize = 0, tmpStencilBits = 0, tmpAntialiasingLevel = 0;
+
+ if (self) {
+ [myPixelFormat getValues:&tmpDepthSize
+ forAttribute:NSOpenGLPFADepthSize
+ forVirtualScreen:[self currentVirtualScreen]];
+
+ [myPixelFormat getValues:&tmpStencilBits
+ forAttribute:NSOpenGLPFAStencilSize
+ forVirtualScreen:[self currentVirtualScreen]];
+
+ [myPixelFormat getValues:&tmpAntialiasingLevel
+ forAttribute:NSOpenGLPFASamples
+ forVirtualScreen:[self currentVirtualScreen]];
+ }
+
+
+ attribs.DepthBits = (unsigned) tmpDepthSize;
+ attribs.StencilBits = (unsigned) tmpStencilBits;
+ attribs.AntialiasingLevel = (unsigned) tmpAntialiasingLevel;
+
+ [myPixelFormat release];
+ }
+
+ return self;
+}
+
+@end
+
+
+////////////////////////////////////////////////////////////
+/// Customized Cocoa OpenGL view
+////////////////////////////////////////////////////////////
+@implementation GLView
+
+////////////////////////////////////////////////////////////
+/// Make a new view according the the rect @frame,
+/// the video mode @mode, the window settings @settings
+/// and the sf window delegate @delegate
+/// @delegate must not be null
+////////////////////////////////////////////////////////////
+- (id)initWithFrame:(NSRect)frame
+ mode:(const sf::VideoMode&)mode
+ settings:(sf::WindowSettings&)settings
+ delegate:(sf::priv::WindowImplCocoa *)delegate
+{
+ assert(delegate != NULL);
+
+ // make the view
+ self = [super initWithFrame:frame pixelFormat:nil];
+
+ if (self)
+ {
+ // enabled auto-resizing
+ [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+
+ // make the OpenGL context
+ myGLContext = [[GLContext alloc] initWithAttributes:settings sharedContext:sharedCtx];
+
+ // We need to update the OpenGL view when it's resized
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+ [nc addObserver:self
+ selector:@selector(viewFrameDidChange:)
+ name:NSViewFrameDidChangeNotification
+ object:self];
+
+ // Save the delegate
+ myDelegate = delegate;
+ }
+
+ return self;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Clean the instance
+////////////////////////////////////////////////////////////
+- (void)dealloc
+{
+ // Remove the observer and release the OpenGL context
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [myGLContext release];
+
+ [super dealloc];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Finish view setting (after having added it to the window)
+////////////////////////////////////////////////////////////
+- (void)finishInitialization
+{
+ assert([self superview] != nil);
+ assert(myGLContext != nil);
+
+ // Attach the OpenGL context to our view
+ [self clearGLContext];
+ [self setOpenGLContext:myGLContext];
+ [myGLContext setView:self];
+
+ // Make our view the first responder
+ [[self window] makeFirstResponder:self];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Forward call to en/disable vertical synchronization
+////////////////////////////////////////////////////////////
+- (void)enableVerticalSync:(bool)flag
+{
+ GLint enable = (flag) ? 1 : 0;
+ [[self openGLContext] setValues:&enable forParameter:NSOpenGLCPSwapInterval];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Forward call to set the OpenGL context as active according to @flag
+////////////////////////////////////////////////////////////
+- (void)setActive:(bool)flag
+{
+ if (flag) {
+ if ([NSOpenGLContext currentContext] != [self openGLContext])
+ [[self openGLContext] makeCurrentContext];
+ } else {
+ if ([NSOpenGLContext currentContext] == [self openGLContext])
+ [NSOpenGLContext clearCurrentContext];
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Forward call to flush the OpenGL context
+////////////////////////////////////////////////////////////
+- (void)flushBuffer
+{
+ [[self openGLContext] flushBuffer];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send event to the linked window
+////////////////////////////////////////////////////////////
+- (void)pushEvent:(sf::Event)sfEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleNotifiedEvent(sfEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Notification method receiver when OpenGL view size changes
+////////////////////////////////////////////////////////////
+- (void)viewFrameDidChange:(NSNotification *)notification
+{
+ [self update];
+
+ sf::Event ev;
+ ev.Type = sf::Event::Resized;
+ ev.Size.Width = (unsigned) [self frame].size.width;
+ ev.Size.Height = (unsigned) [self frame].size.height;
+
+ [self pushEvent:ev];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when a key is pressed
+////////////////////////////////////////////////////////////
+- (void)keyDown:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+
+ NSText *field = [[self window] fieldEditor:YES forObject:nil];
+ [field interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
+ [field setString:@""];
+
+ myDelegate->HandleKeyDown(theEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when a key is released
+////////////////////////////////////////////////////////////
+- (void)keyUp:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleKeyUp(theEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when a modifier flag has changed
+////////////////////////////////////////////////////////////
+- (void)flagsChanged:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleModifierKey(theEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when the mouse wheel has been used
+////////////////////////////////////////////////////////////
+- (void)scrollWheel:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleMouseWheel(theEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when left mouse click is pressed
+////////////////////////////////////////////////////////////
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleMouseDown(theEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when right mouse click is pressed
+////////////////////////////////////////////////////////////
+- (void)rightMouseDown:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleMouseDown(theEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when left mouse click is released
+////////////////////////////////////////////////////////////
+- (void)mouseUp:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleMouseUp(theEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when right mouse click is released
+////////////////////////////////////////////////////////////
+- (void)rightMouseUp:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleMouseUp(theEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when mouse moves
+////////////////////////////////////////////////////////////
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleMouseMove(theEvent);
+}
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when mouse is pressed (on left button) and moves
+////////////////////////////////////////////////////////////
+- (void)mouseDragged:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleMouseMove(theEvent);
+}
+
+////////////////////////////////////////////////////////////
+/// Receiver method called when mouse is pressed (on right button) and moves
+////////////////////////////////////////////////////////////
+- (void)rightMouseDragged:(NSEvent *)theEvent
+{
+ assert(myDelegate != NULL);
+ myDelegate->HandleMouseMove(theEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Tells that the view can be focused
+////////////////////////////////////////////////////////////
+- (BOOL)acceptsFirstResponder
+{
+ return YES;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Tells that the view can become the key responder (ie. can catch key events)
+////////////////////////////////////////////////////////////
+- (BOOL)canBecomeKeyView
+{
+ return YES;
+}
+
+@end
+
+
+////////////////////////////////////////////////////////////
+/// Cocoa window implementation to let fullscreen windows
+/// catch key events
+////////////////////////////////////////////////////////////
+@implementation GLWindow
+
+- (BOOL)canBecomeKeyWindow
+{
+ return YES;
+}
+
+- (BOOL)canBecomeMainWindow
+{
+ return YES;
+}
+
+@end
+
+
+////////////////////////////////////////////////////////////
+/// WindowWrapper class : handles both imported and self-built windows
+////////////////////////////////////////////////////////////
+@implementation WindowWrapper
+
+////////////////////////////////////////////////////////////
+/// Make a new window wrapper according to the window settings @attribs,
+/// the video mode @mode, the window style @style, the window title @title
+/// and the sf window implementation delegate @delegate
+////////////////////////////////////////////////////////////
+- (id)initWithSettings:(sf::WindowSettings&)params
+ videoMode:(sf::VideoMode&)mode
+ style:(unsigned long)style
+ title:(NSString *)title
+ delegate:(sf::priv::WindowImplCocoa *)delegate
+{
+ return [self initWithWindow:nil
+ settings:params
+ videoMode:mode
+ style:style
+ title:title
+ delegate:delegate];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Make a new window wrapper by importing @window and according to
+/// the window settings @params and the sf window implementation delegate
+/// @delegate
+/// @window and @delegate must not be null
+////////////////////////////////////////////////////////////
+- (id)initWithWindow:(NSWindow *)window
+ settings:(sf::WindowSettings&)params
+ delegate:(sf::priv::WindowImplCocoa *)delegate
+{
+ sf::VideoMode mode([[myWindow contentView] frame].size.width, [[myWindow contentView] frame].size.height);
+ return [self initWithWindow:window
+ settings:params
+ videoMode:mode
+ style:0
+ title:nil
+ delegate:delegate];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Make a new window wrapper by importing @window if it's not null and according to
+/// the window settings @params and the sf window implementation delegate
+/// @delegate; or by creating a new window if @window is null. In this case @title
+/// must therefore not be null and @params must be valid.
+/// @delegate must never be null
+////////////////////////////////////////////////////////////
+- (id)initWithWindow:(NSWindow *)window
+ settings:(sf::WindowSettings&)params
+ videoMode:(sf::VideoMode&)mode
+ style:(unsigned long)style
+ title:(NSString *)title
+ delegate:(sf::priv::WindowImplCocoa *)delegate
+{
+ assert(delegate != NULL);
+
+ self = [super init];
+
+ if (self)
+ {
+ if (window) {
+ myWindow = (GLWindow *)[window retain];
+ } else {
+ assert(title != nil);
+
+ NSRect frame = NSMakeRect (0.0f, 0.0f, (float) mode.Width, (float) mode.Height);
+ unsigned int mask = 0;
+
+ if (style & sf::Style::Fullscreen) {
+ myIsFullscreen = true;
+
+ // 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) {
+ std::cerr << "Unable to get a display mode with the given parameters" << std::endl;
+ [self autorelease];
+ 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);
+
+ }
+ }
+
+ // We grab options from WindowStyle and add them to our window mask
+ if (style & sf::Style::None || style & sf::Style::Fullscreen) {
+ mask |= NSBorderlessWindowMask;
+
+
+
+ } else {
+ if (style & sf::Style::Titlebar) {
+ mask |= NSTitledWindowMask;
+ mask |= NSMiniaturizableWindowMask;
+ }
+
+ if (style & sf::Style::Resize) {
+ mask |= NSTitledWindowMask;
+ mask |= NSMiniaturizableWindowMask;
+ mask |= NSResizableWindowMask;
+ }
+
+ if (style & sf::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
+ myWindow = [[GLWindow alloc] initWithContentRect:frame
+ styleMask:mask
+ backing:NSBackingStoreBuffered
+ defer:NO];
+
+ if (myWindow) {
+ // We set title and window position
+ [myWindow setTitle:title];
+ [myWindow center];
+ } else {
+ std::cerr << "Unable to create the Cocoa window" << std::endl;
+ [self autorelease];
+ return nil;
+ }
+ }
+
+ // Make the OpenGL view
+ myView = [[GLView alloc] initWithFrame:[[myWindow contentView] frame]
+ mode:mode
+ settings:params
+ delegate:delegate];
+
+ if (myView) {
+ // Finish setting up the view and window
+ // Add the view to our window and tell it to the view
+ [[myWindow contentView] addSubview:myView];
+ [myView finishInitialization];
+
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+
+ // We want to know when our window got the focus
+ [nc addObserver:self
+ selector:@selector(windowDidBecomeMain:)
+ name:NSWindowDidBecomeMainNotification
+ object:myWindow];
+
+ // We want to know when our window lost the focus
+ [nc addObserver:self
+ selector:@selector(windowDidResignMain:)
+ name:NSWindowDidResignMainNotification
+ object:myWindow];
+
+ // We want to know when the user closes the window
+ [nc addObserver:self
+ selector:@selector(windowWillClose:)
+ name:NSWindowWillCloseNotification
+ object:myWindow];
+
+ // I want to re-center the window if it's a full screen one and moved by Spaces
+ [nc addObserver:self
+ selector:@selector(windowDidMove:)
+ name:NSWindowDidMoveNotification
+ object:myWindow];
+
+ // Needed not to make application crash when releasing the window in our destructor
+ // (I prefer to take control of everything :P)
+ [myWindow setReleasedWhenClosed:NO];
+ [myWindow setAcceptsMouseMovedEvents:YES];
+
+ } else {
+ std::cerr << "Unable to create the OpenGL view" << std::endl;
+ [self autorelease];
+ return nil;
+ }
+
+ if (myIsFullscreen) {
+ myFullscreenMode = mode;
+
+ // Using this because full screen window was not always
+ // in front of the other application windows when unhiding app
+ [myWindow setLevel:NSFloatingWindowLevel];
+ }
+ }
+
+ return self;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Clean the window wrapper
+////////////////////////////////////////////////////////////
+- (void)dealloc
+{
+
+ // Remove the notification observer
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ // Close the window
+ [self show:false];
+
+ // Release the window and view
+ [myView release];
+ [myWindow release];
+
+ [super dealloc];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Return a reference to the internal Cocoa window
+////////////////////////////////////////////////////////////
+- (NSWindow *)window
+{
+ return myWindow;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Return a reference to the internal Cocoa OpenGL view
+////////////////////////////////////////////////////////////
+- (GLView *)glView
+{
+ return myView;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Forward call to set the window position on screen
+////////////////////////////////////////////////////////////
+- (void)setPosition:(NSPoint)pos
+{
+ assert(myWindow != nil);
+
+ if (!myIsFullscreen) {
+ // Flip Y and set window position
+ pos.y = [[myWindow screen] frame].size.height - pos.y;
+ [myWindow setFrameTopLeftPoint:pos];
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Forward call to set the window size
+////////////////////////////////////////////////////////////
+- (void)setSize:(NSSize)size
+{
+ assert(myWindow != nil);
+
+ if (!myIsFullscreen) {
+ [myWindow setFrame:NSMakeRect([myWindow frame].origin.x,
+ [myWindow frame].origin.y,
+ size.width, size.height)
+ display:YES];
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Return the mouse location relative to the internal window
+////////////////////////////////////////////////////////////
+- (NSPoint)mouseLocation
+{
+ assert(myWindow != nil);
+
+ NSPoint relativeLocation = [myWindow convertScreenToBase:[NSEvent mouseLocation]];
+ relativeLocation.y = [[self glView] frame].size.height - relativeLocation.y;
+ return relativeLocation;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Return whether the mouse is on our window
+////////////////////////////////////////////////////////////
+- (BOOL)mouseInside
+{
+ assert(myWindow != nil);
+ assert(myView != nil);
+
+ BOOL flag = NO;
+
+ if ([myWindow isVisible]) {
+ NSPoint relativeToWindow = [myWindow mouseLocationOutsideOfEventStream];
+ NSPoint relativeToView = [myView convertPoint:relativeToWindow fromView:nil];
+
+ if (NSPointInRect (relativeToView, [myView bounds]))
+ {
+ flag = YES;
+ }
+ }
+
+ return flag;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Close or open the window
+////////////////////////////////////////////////////////////
+- (void)show:(bool)flag
+{
+ assert(myWindow != nil);
+
+ if (flag && ![myWindow isVisible]) {
+ // Wanna open the closed window
+
+ if (myIsFullscreen) {
+ [SharedAppController setFullscreenWindow:self mode:&myFullscreenMode];
+ } else {
+ // Show the window
+ [myWindow makeKeyAndOrderFront:nil];
+ }
+ } else if (!flag && [myWindow isVisible]) {
+ // Wanna close the opened window
+
+ if (myIsFullscreen) {
+ [SharedAppController setFullscreenWindow:nil mode:NULL];
+ } else {
+ // Close the window
+ [myWindow close];
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Forward call to en/disable the OpenGL view vertical synchronization
+////////////////////////////////////////////////////////////
+- (void)enableVerticalSync:(bool)flag
+{
+ assert(myView != nil);
+ [myView enableVerticalSync:flag];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Forward 'setActive' call the the OpenGL view
+////////////////////////////////////////////////////////////
+- (void)setActive:(bool)flag
+{
+ assert(myView != nil);
+ [myView setActive:flag];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Forward call to flush the OpenGL view
+////////////////////////////////////////////////////////////
+- (void)flushBuffer
+{
+ assert(myView != nil);
+ [myView flushBuffer];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Notification method receiver when the window gains focus
+////////////////////////////////////////////////////////////
+- (void)windowDidBecomeMain:(NSNotification *)notification
+{
+ sf::Event ev;
+ ev.Type = sf::Event::GainedFocus;
+
+ [myView pushEvent:ev];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Notification method receiver when the window loses focus
+////////////////////////////////////////////////////////////
+- (void)windowDidResignMain:(NSNotification *)notification
+{
+ sf::Event ev;
+ ev.Type = sf::Event::LostFocus;
+
+ [myView pushEvent:ev];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Notification method receiver when the window closes
+////////////////////////////////////////////////////////////
+- (void)windowWillClose:(NSNotification *)notification
+{
+ sf::Event ev;
+ ev.Type = sf::Event::Closed;
+
+ [myView pushEvent:ev];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Notification method receiver when the window finish moving
+////////////////////////////////////////////////////////////
+- (void)windowDidMove:(NSNotification *)notification
+{
+ NSWindow *sender = [notification object];
+
+ if (!([sender styleMask] & NSTitledWindowMask))
+ [sender center];
+}
+
+@end
+
diff --git a/src/SFML/Window/Cocoa/Joystick.cpp b/src/SFML/Window/Cocoa/Joystick.cpp
index 6b456a1..4ade09c 100755
--- a/src/SFML/Window/Cocoa/Joystick.cpp
+++ b/src/SFML/Window/Cocoa/Joystick.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Cocoa/Joystick.hpp b/src/SFML/Window/Cocoa/Joystick.hpp
index 7a78c93..4259075 100755
--- a/src/SFML/Window/Cocoa/Joystick.hpp
+++ b/src/SFML/Window/Cocoa/Joystick.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Cocoa/VideoModeSupport.cpp b/src/SFML/Window/Cocoa/VideoModeSupport.cpp
index 75f5d8e..9b5ebd0 100755
--- a/src/SFML/Window/Cocoa/VideoModeSupport.cpp
+++ b/src/SFML/Window/Cocoa/VideoModeSupport.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Cocoa/VideoModeSupport.hpp b/src/SFML/Window/Cocoa/VideoModeSupport.hpp
index 2b64685..4892fe5 100755
--- a/src/SFML/Window/Cocoa/VideoModeSupport.hpp
+++ b/src/SFML/Window/Cocoa/VideoModeSupport.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Cocoa/WindowController.mm b/src/SFML/Window/Cocoa/WindowController.mm
deleted file mode 100755
index 286a3ed..0000000
--- a/src/SFML/Window/Cocoa/WindowController.mm
+++ /dev/null
@@ -1,157 +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/Cocoa/WindowController.h>
-#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
-#import <SFML/Window/Cocoa/AppController.h>
-#import <OpenGL/gl.h>
-#import <iostream>
-
-@implementation WindowController
-
-////////////////////////////////////////////////////////////
-/// Forbide use of WindowController without any linked WindowImplCocoa object
-////////////////////////////////////////////////////////////
-- (id)init
-{
- return [self initWithWindow:NULL];
-}
-
-////////////////////////////////////////////////////////////
-/// Initialize a new WindowController object and link it
-/// to the 'window' object.
-////////////////////////////////////////////////////////////
-- (WindowController *)initWithWindow:(sf::priv::WindowImplCocoa *)window
-{
- if (window == NULL) {
- std::cerr << "-[WindowController initWithWindow:NULL] -- initialization without any linked window is forbidden ; nil returned" << std::endl;
- [self release];
- return nil;
- }
-
- self = [super init];
-
- if (self != nil) {
- parentWindow = window;
- }
-
- return self;
-}
-
-////////////////////////////////////////////////////////////
-/// Return a new autoreleased WindowController object linked
-/// to the 'window' WindowImplCocoa object.
-////////////////////////////////////////////////////////////
-+ (WindowController *)controllerWithWindow:(sf::priv::WindowImplCocoa *)window
-{
- WindowController *ctrl =
- massert([WindowController alloc]);
- return [[ctrl initWithWindow:window] autorelease];
-}
-
-////////////////////////////////////////////////////////////
-/// Send event to the linked window
-////////////////////////////////////////////////////////////
-- (void)pushEvent:(sf::Event)sfEvent
-{
- if (parentWindow != NULL) {
- parentWindow->HandleNotifiedEvent(sfEvent);
- }
-}
-
-////////////////////////////////////////////////////////////
-/// Notification method receiver when OpenGL view size changes
-////////////////////////////////////////////////////////////
-- (void)viewFrameDidChange:(NSNotification *)notification
-{
- NSOpenGLView *glView = [notification object];
- [[glView openGLContext] update];
-
- sf::Event ev;
- ev.Type = sf::Event::Resized;
- ev.Size.Width = (unsigned) [glView frame].size.width;
- ev.Size.Height = (unsigned) [glView frame].size.height;
-
- [self pushEvent:ev];
-}
-
-////////////////////////////////////////////////////////////
-/// Notification method receiver when the window gains focus
-////////////////////////////////////////////////////////////
-- (void)windowDidBecomeMain:(NSNotification *)notification
-{
- sf::Event ev;
- ev.Type = sf::Event::GainedFocus;
-
- [self pushEvent:ev];
-}
-
-////////////////////////////////////////////////////////////
-/// Notification method receiver when the window loses focus
-////////////////////////////////////////////////////////////
-- (void)windowDidResignMain:(NSNotification *)notification
-{
- sf::Event ev;
- ev.Type = sf::Event::LostFocus;
-
- [self pushEvent:ev];
-}
-
-////////////////////////////////////////////////////////////
-/// Notification method receiver when the window closes
-////////////////////////////////////////////////////////////
-- (void)windowWillClose:(NSNotification *)notification
-{
- sf::Event ev;
- ev.Type = sf::Event::Closed;
-
- [self pushEvent:ev];
-}
-
-- (void)windowDidMove:(NSNotification *)notification
-{
- NSWindow *sender = [notification object];
-
- if (!([sender styleMask] & NSTitledWindowMask))
- [sender center];
-}
-
-@end
-
-
-@implementation SFWindow
-- (BOOL)canBecomeKeyWindow
-{
- return YES;
-}
-
-- (BOOL)canBecomeMainWindow
-{
- return YES;
-}
-@end
diff --git a/src/SFML/Window/Cocoa/WindowImplCocoa.hpp b/src/SFML/Window/Cocoa/WindowImplCocoa.hpp
index 1b2e96b..bc93d54 100755
--- a/src/SFML/Window/Cocoa/WindowImplCocoa.hpp
+++ b/src/SFML/Window/Cocoa/WindowImplCocoa.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Lucas Soltic (elmerod@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 Lucas Soltic (ceylow@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.
@@ -32,13 +32,16 @@
#include <SFML/Window/WindowImpl.hpp>
#include <string>
+#ifdef __OBJC__
+#import <Cocoa/Cocoa.h>
+@class WindowWrapper;
+#endif
+
namespace sf
{
namespace priv
{
-typedef struct objc_members objc_members;
-
////////////////////////////////////////////////////////////
/// WindowImplCocoa is the Cocoa implementation of WindowImpl
////////////////////////////////////////////////////////////
@@ -89,24 +92,22 @@ public :
static bool IsContextActive();
////////////////////////////////////////////////////////////
- /// Handle Cocoa NSEvent
- ////////////////////////////////////////////////////////////
- void HandleEvent(void *eventRef);
-
- ////////////////////////////////////////////////////////////
/// Handle an event sent by the default NSNotificationCenter
////////////////////////////////////////////////////////////
void HandleNotifiedEvent(Event& eventRef);
////////////////////////////////////////////////////////////
- /// Return a pointer to the NSWindow (objc->windowHandle) object
+ /// Event handling for every event type.
+ /// 'eventRef' is a NSEvent.
////////////////////////////////////////////////////////////
- void *CocoaWindow(void);
+ void HandleKeyDown(void *eventRef);
+ void HandleKeyUp(void *eventRef);
+ void HandleModifierKey(void *eventRef);
+ void HandleMouseDown(void *eventRef);
+ void HandleMouseUp(void *eventRef);
+ void HandleMouseMove(void *eventRef);
+ void HandleMouseWheel(void *eventRef);
- ////////////////////////////////////////////////////////////
- /// Return whether the window is in full screen mode
- ////////////////////////////////////////////////////////////
- bool IsFullscreen(void);
private :
////////////////////////////////////////////////////////////
@@ -183,37 +184,18 @@ private :
////////////////////////////////////////////////////////////
- /// Event handling for every event type.
- /// 'eventRef' is a NSEvent.
- ////////////////////////////////////////////////////////////
- int HandleKeyDown(void *eventRef);
- int HandleKeyUp(void *eventRef);
- int HandleModifierKey(void *eventRef);
- int HandleMouseDown(void *eventRef);
- int HandleMouseUp(void *eventRef);
- int HandleMouseMove(void *eventRef);
- int HandleMouseWheel(void *eventRef);
-
- ////////////////////////////////////////////////////////////
- /// Make some allocations and initializations
- ////////////////////////////////////////////////////////////
- void Initialize(void);
-
-
- ////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
- // An opaque structure that contains all obj-C objects
- objc_members *members;
-
- bool useKeyRepeat;
- bool mouseIn;
- float wheelStatus;
+#ifdef __OBJC__
+ WindowWrapper *myWrapper;
+#else
+ void *myWrapper;
+#endif
- bool fullscreen;
- VideoMode fullscreenMode;
- VideoMode desktopMode;
+ bool myUseKeyRepeat;
+ bool myMouseIn;
+ float myWheelStatus;
};
} // namespace priv
diff --git a/src/SFML/Window/Cocoa/WindowImplCocoa.mm b/src/SFML/Window/Cocoa/WindowImplCocoa.mm
index 7950ab2..3b66bbc 100755
--- a/src/SFML/Window/Cocoa/WindowImplCocoa.mm
+++ b/src/SFML/Window/Cocoa/WindowImplCocoa.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Lucas Soltic (elmerod@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 Lucas Soltic (ceylow@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.
@@ -27,38 +27,16 @@
// Headers
////////////////////////////////////////////////////////////
#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
-#import <SFML/Window/Cocoa/WindowController.h>
#import <SFML/Window/Cocoa/AppController.h>
+#import <SFML/Window/Cocoa/GLKit.h>
#import <SFML/Window/WindowStyle.hpp>
#import <SFML/System.hpp>
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
-#import <Cocoa/Cocoa.h>
+#import <CoreFoundation/CoreFoundation.h>
#import <iostream>
-#pragma mark Notes
-
-// ENABLE_ANTIALIASING macro :
-//
-// I use this to prevent the use of antialiasing
-// as OpenGL context sharing does not allow only one of the
-// shared OpenGL context to be shared. That means
-// antialiasing could not be used without re-compiling
-// the whole sfml-window library.
-//
-// I've no way to fix this for now.
-
-// ENABLE_WINDOWIMPORT macro :
-//
-// I use this to disable the import of Cocoa windows
-// as it does not work fine for now and is not
-// a high priority.
-
-
-
-
-
namespace sf
{
namespace priv
@@ -72,75 +50,34 @@ make;\
__done = 1;\
} }
-// Has the event been used or not ? If not, it must be sent to NSApp
-enum {
- UsedEvent,
- 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;
- SFWindow *window;
- NSOpenGLContext *context;
- NSOpenGLView *view;
-};
-
-////////////////////////////////////////////////////////////
-/// Pointer to the shared OpenGL context
-////////////////////////////////////////////////////////////
-static NSOpenGLContext *sharedContext = nil;
-
////////////////////////////////////////////////////////////
/// Private function declarations
////////////////////////////////////////////////////////////
-static SFWindow * MakeWindow(WindowSettings& params, unsigned long style, VideoMode& mode, NSString *title);
-static NSOpenGLContext *MakeOpenGLContext(WindowSettings& params);
-static NSOpenGLView * MakeOpenGLView(SFWindow *window, NSOpenGLContext *context, WindowSettings& params);
-static void ConfigureWindow(SFWindow *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(SFWindow *window, NSView *view);
-static NSPoint MouseLocation(SFWindow *window);
////////////////////////////////////////////////////////////
/// Default constructor
/// (creates a dummy window to provide a valid OpenGL context)
////////////////////////////////////////////////////////////
+ static WindowImplCocoa *globalWin = NULL;
WindowImplCocoa::WindowImplCocoa() :
-members(NULL),
-useKeyRepeat(false),
-mouseIn(false),
-wheelStatus(0.0f),
-fullscreen(false),
-fullscreenMode(0, 0, 0),
-desktopMode(0, 0, 0)
+myWrapper(nil),
+myUseKeyRepeat(false),
+myMouseIn(false),
+myWheelStatus(0.0f)
{
- Initialize();
-
- // 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);
+ [AppController sharedController];
- if (members->context != nil) {
- // Increase the reference counter for the shared OpenGL context
- sharedContext = [members->context retain];
-
+ // Create the shared OpenGL context
+ if ([GLContext sharedContext]) {
// Then we make it the current active OpenGL context
SetActive();
} else {
- std::cerr << "*** SFML: Unable to make the main shared OpenGL context" << std::endl;
+ std::cerr << "Unable to make the main shared OpenGL context" << std::endl;
}
}
@@ -149,53 +86,39 @@ desktopMode(0, 0, 0)
/// 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)
+myWrapper(NULL),
+myUseKeyRepeat(false),
+myMouseIn(false),
+myWheelStatus(0.0f)
{
- Initialize();
-
-#if ENABLE_WINDOWIMPORT
- // 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 <SFWindow *> (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) {
+ if (Handle)
+ {
+ if (![(NSWindow *)Handle isKindOfClass:[NSWindow class]])
+ std::cerr << "Cannot import this Window Handle because it is not a <NSWindow *> object"
+ << "(or one of its subclasses). You gave a <"
+ << [[(NSWindow *)Handle className] UTF8String]
+ << "> object." << std::endl;
+ else
+ {
+
+ // We create the window according to the given handle
+ myWrapper = [[WindowWrapper alloc] initWithWindow:(NSWindow *)Handle
+ settings:params
+ delegate:this];
+
+ if (myWrapper)
+ {
// initial mouse state
- mouseIn = MouseInside(members->window, members->view);
+ myMouseIn = [myWrapper mouseInside];
- // 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;
+ // We set the myWidth and myHeight members to the correct values
+ myWidth = (int) [[myWrapper glView] frame].size.width;
+ myHeight = (int) [[myWrapper glView] frame].size.height;
} else {
- //error(__FILE__, __LINE__, "failed to make the OpenGL view for the public window");
+ std::cerr << "Failed to make the public window" << std::endl;
}
- } else {
- //error(__FILE__, __LINE__, "failed to make the OpenGL context for the public window");
}
- } else {
- //error(__FILE__, __LINE__, "invalid imported window");
}
-#else
- std::cerr << "*** SFML: making a sf::Window from a Cocoa one is not available in this version of the SFML" << std::endl;
-#endif
}
@@ -203,65 +126,32 @@ desktopMode(0, 0, 0)
/// 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)
+myWrapper(NULL),
+myUseKeyRepeat(false),
+myMouseIn(false),
+myWheelStatus(0.0f)
{
- 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 = massert([NSString stringWithUTF8String:Title.c_str()]);
+ NSString *title = [NSString stringWithUTF8String:(Title.c_str()) ? (Title.c_str()) : ""];
// We create the window
- members->window = MakeWindow(params, WindowStyle, Mode, title);
-
+ myWrapper = [[WindowWrapper alloc] initWithSettings:params
+ videoMode:Mode
+ style:WindowStyle
+ title:title
+ delegate:this];
- if (members->window != nil) {
- members->context = MakeOpenGLContext(params);
+ if (myWrapper)
+ {
+ // initial mouse state
+ myMouseIn = [myWrapper mouseInside];
- 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;
-
- // Using this because full screen window was not always
- // in front of the other application windows when unhiding app
- [members->window setLevel:NSFloatingWindowLevel];
- }
- } else {
- std::cerr << "*** SFML: failed to make the OpenGL view for the public window" << std::endl;
- [members->context release], members->context = nil;
- [sharedContext release];
- [members->window release], members->window = nil;
- }
- } else {
- std::cerr << "*** SFML: failed to make the OpenGL context for the public window" << std::endl;
- [members->window release], members->window = nil;
- }
+ // We set the myWidth and myHeight members to the correct values
+ myWidth = Mode.Width;
+ myHeight = Mode.Height;
} else {
- std::cerr << "*** SFML: failed to make the public window" << std::endl;
+ std::cerr << "Failed to make the public window" << std::endl;
}
}
@@ -271,26 +161,8 @@ desktopMode(0, 0, 0)
////////////////////////////////////////////////////////////
WindowImplCocoa::~WindowImplCocoa()
{
- // Destroy the OpenGL context, the window and every resource allocated by this class
- Show(false);
-
- if (members) {
- if (members->window)
- [[NSNotificationCenter defaultCenter] removeObserver:members->window];
- if (members->view)
- [[NSNotificationCenter defaultCenter] removeObserver:members->view];
- [members->controller release];
- }
-
- [sharedContext release];
- if (members) {
- [members->context release];
- [members->view release];
- [members->window release];
- }
-
- [[AppController sharedController] unregisterWindow:this];
- free (members);
+ // Release the window wrapper
+ [myWrapper release];
}
@@ -304,63 +176,6 @@ bool WindowImplCocoa::IsContextActive()
////////////////////////////////////////////////////////////
-/// Handle a Cocoa NSEvent
-////////////////////////////////////////////////////////////
-void WindowImplCocoa::HandleEvent(void *eventRef)
-{
- if (eventRef == nil) {
- std::cerr << "*** SFML: cannot handle a NULL event. Returning." << std::endl;
- return;
- }
-
- NSEvent *event = static_cast <NSEvent *> (eventRef);
- int eventStatus = UnusedEvent;
-
- switch ([event type]) {
- case NSKeyDown:
- eventStatus = HandleKeyDown(eventRef);
- break;
-
- case NSKeyUp:
- eventStatus = HandleKeyUp(eventRef);
- break;
-
- case NSFlagsChanged:
- eventStatus = HandleModifierKey(eventRef);
- break;
-
- case NSScrollWheel:
- eventStatus = HandleMouseWheel(eventRef);
- break;
-
- case NSLeftMouseDown:
- case NSRightMouseDown:
- eventStatus = HandleMouseDown(eventRef);
- break;
-
- case NSLeftMouseUp:
- case NSRightMouseUp:
- eventStatus = HandleMouseUp(eventRef);
- break;
-
- case NSMouseMoved:
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- eventStatus = HandleMouseMove(eventRef);
- break;
-
- default:
- break;
- }
-
- if (eventStatus == UnusedEvent) {
- [NSApp sendEvent:event];
- }
-}
-
-
-////////////////////////////////////////////////////////////
/// Handle event sent by the default NSNotificationCenter
////////////////////////////////////////////////////////////
void WindowImplCocoa::HandleNotifiedEvent(Event& event)
@@ -385,143 +200,133 @@ void WindowImplCocoa::HandleNotifiedEvent(Event& event)
////////////////////////////////////////////////////////////
/// Handle a key down event (NSEvent)
////////////////////////////////////////////////////////////
-int WindowImplCocoa::HandleKeyDown(void *eventRef)
+void WindowImplCocoa::HandleKeyDown(void *eventRef)
{
- NSEvent *event = static_cast <NSEvent *> (eventRef);
+ NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
unichar chr = 0, rawchr = 0;
+ unsigned long length = [[event characters] length];
unsigned mods = [event modifierFlags];
- if ([[event characters] length]) {
+ if (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 UsedEvent;
- }
-
-#if 1
- // Is it also a text event ?
- if (IsTextEvent(event)) {
- sfEvent.Type = Event::TextEntered;
- sfEvent.Text.Unicode = chr;
-
- SendEvent(sfEvent);
- }
-#else
- // Is it also a text event ?
- if (IsTextEvent(event)) {
- static NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:1];
- sfEvent.Type = Event::TextEntered;
- sfEvent.Text.Unicode = chr;
+ // Don't handle repeated events if we chose not to send them
+ if (!myUseKeyRepeat && [event isARepeat])
+ return;
+
+ // Is it also a text event ?
+ if (IsTextEvent(event)) {
+ // buffer for the UTF-32 characters
+ Uint32 utf32Characters[2] = {0};
+
+ // convert the characters
+ // note: using CFString in order to keep compatibility with Mac OS X 10.4
+ // (NSUTF32StringEncoding only defined since Mac OS X 10.5)
+ if (!CFStringGetCString ((CFStringRef)[event characters],
+ (char *)utf32Characters,
+ sizeof(utf32Characters),
+ kCFStringEncodingUTF32))
+ {
+ const char *utf8Char = NULL;
+ if ([[event characters] lengthOfBytesUsingEncoding:NSUTF8StringEncoding])
+ utf8Char = [[event characters] UTF8String];
+
+ std::cerr << "Error while converting character to UTF32 : "
+ << ((utf8Char) ? utf8Char : "(undefined)") << std::endl;
+ }
+ else
+ {
+ sfEvent.Type = Event::TextEntered;
+ sfEvent.Text.Unicode = utf32Characters[0];
+
+ SendEvent(sfEvent);
+ }
+ }
- NSText *field = [members->window fieldEditor:YES forObject:nil];
- [arr addObject:event];
- [field interpretKeyEvents:arr];
+ // Anyway it's also a KeyPressed event
+ sfEvent.Type = Event::KeyPressed;
- if ([[field string] length]) {
- unichar unichr = [[field string] characterAtIndex:0];
- sfEvent.Text.Unicode = unichr;
- SendEvent(sfEvent);
-
- unichar str[2] = {unichr, 0};
- NSLog(@"Char::%@", [NSString stringWithCharacters:str length:2]);
-
- [field setString:@""];
- [arr removeAllObjects];
+ // Get the keys
+ if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(rawchr))) {
+ sfEvent.Key.Code = KeyForVirtualCode([event keyCode]);
}
+ // Get the modifiers
+ sfEvent.Key.Alt = mods & NSAlternateKeyMask;
+ sfEvent.Key.Control = mods & NSControlKeyMask;
+ sfEvent.Key.Shift = mods & NSShiftKeyMask;
+ // Send the event
+ SendEvent(sfEvent);
}
-#endif
-
- // 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;
-
- // Send the event
- SendEvent(sfEvent);
-
- return UsedEvent;
}
////////////////////////////////////////////////////////////
/// Handle a key up event (NSEvent)
////////////////////////////////////////////////////////////
-int WindowImplCocoa::HandleKeyUp(void *eventRef)
+void WindowImplCocoa::HandleKeyUp(void *eventRef)
{
- NSEvent *event = static_cast <NSEvent *> (eventRef);
+ NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
unsigned mods = [event modifierFlags];
- unichar chr = 0;
+ unichar chr = 0, rawchr = 0;
if ([[event characters] length]) {
chr = [[event characters] characterAtIndex:0];
+
+ if ([[event charactersIgnoringModifiers] length])
+ rawchr = [[event charactersIgnoringModifiers] characterAtIndex:0];
+
+ sfEvent.Type = Event::KeyReleased;
+
+ // Get the code
+ if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(rawchr))) {
+ sfEvent.Key.Code = KeyForVirtualCode([event keyCode]);
+ }
+
+ // Get the modifiers
+ sfEvent.Key.Alt = mods & NSAlternateKeyMask;
+ sfEvent.Key.Control = mods & NSControlKeyMask;
+ sfEvent.Key.Shift = mods & NSShiftKeyMask;
+
+ // Send the event
+ SendEvent(sfEvent);
}
-
- 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 UsedEvent;
}
////////////////////////////////////////////////////////////
/// Handle a key modifier event [Command, Option, Control, Shift]
////////////////////////////////////////////////////////////
-int WindowImplCocoa::HandleModifierKey(void *eventRef)
+void WindowImplCocoa::HandleModifierKey(void *eventRef)
{
- NSEvent *event = static_cast <NSEvent *> (eventRef);
+ NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
unsigned mods = [event modifierFlags];
sfEvent.Type = Event::KeyPressed;
+
+ // Get the code
sfEvent.Key.Code = KeyForVirtualCode([event keyCode]);
+ // Get the modifiers
sfEvent.Key.Alt = mods & NSAlternateKeyMask;
sfEvent.Key.Control = mods & NSControlKeyMask;
sfEvent.Key.Shift = mods & NSShiftKeyMask;
+ // Guess whether it's a pressed or released event
+ // Note: this does not work fine is both left and right modifiers are pressed
+ // I did not find any way to fix this.
+ // TODO: fix handling of modifier flags for use of left and right key at the same time
if (!(mods & NSAlternateKeyMask) &&
(sfEvent.Key.Code == Key::LAlt || sfEvent.Key.Code == Key::RAlt)) {
sfEvent.Type = Event::KeyReleased;
@@ -542,18 +347,17 @@ int WindowImplCocoa::HandleModifierKey(void *eventRef)
sfEvent.Type = Event::KeyReleased;
}
+ // Send the event
SendEvent(sfEvent);
-
- return UnusedEvent;
}
////////////////////////////////////////////////////////////
/// Handle a mouse down event (NSEvent)
////////////////////////////////////////////////////////////
-int WindowImplCocoa::HandleMouseDown(void *eventRef)
+void WindowImplCocoa::HandleMouseDown(void *eventRef)
{
- NSEvent *event = static_cast <NSEvent *> (eventRef);
+ NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
NSPoint loc = {0, 0};
unsigned mods = [event modifierFlags];
@@ -562,18 +366,20 @@ int WindowImplCocoa::HandleMouseDown(void *eventRef)
case NSLeftMouseDown:
sfEvent.Type = Event::MouseButtonPressed;
+ // Guess whether it's a mouse left or mouse right event
if (mods & NSControlKeyMask) {
sfEvent.MouseButton.Button = Mouse::Right;
} else {
sfEvent.MouseButton.Button = Mouse::Left;
}
- // Get mouse position
- loc = MouseLocation(members->window);
+ // Get mouse position relative to the window
+ loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
+ // Send the event
SendEvent(sfEvent);
break;
@@ -581,30 +387,28 @@ int WindowImplCocoa::HandleMouseDown(void *eventRef)
sfEvent.Type = Event::MouseButtonPressed;
sfEvent.MouseButton.Button = Mouse::Right;
- // Get mouse position
- loc = MouseLocation(members->window);
+ // Get mouse position relative to the window
+ loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
+ // Send the event
SendEvent(sfEvent);
break;
default:
break;
}
-
- return UnusedEvent;
-
}
////////////////////////////////////////////////////////////
/// Handle a mouse up event (NSEvent)
////////////////////////////////////////////////////////////
-int WindowImplCocoa::HandleMouseUp(void *eventRef)
+void WindowImplCocoa::HandleMouseUp(void *eventRef)
{
- NSEvent *event = static_cast <NSEvent *> (eventRef);
+ NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
NSPoint loc = {0, 0};
unsigned mods = [event modifierFlags];
@@ -613,18 +417,20 @@ int WindowImplCocoa::HandleMouseUp(void *eventRef)
case NSLeftMouseUp:
sfEvent.Type = Event::MouseButtonReleased;
+ // Guess whether it's a mouse left or mouse right event
if (mods & NSControlKeyMask) {
sfEvent.MouseButton.Button = Mouse::Right;
} else {
sfEvent.MouseButton.Button = Mouse::Left;
}
- // Get mouse position
- loc = MouseLocation(members->window);
+ // Get mouse position relative to the window
+ loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
+ // Send the event
SendEvent(sfEvent);
break;
@@ -632,32 +438,31 @@ int WindowImplCocoa::HandleMouseUp(void *eventRef)
sfEvent.Type = Event::MouseButtonReleased;
sfEvent.MouseButton.Button = Mouse::Right;
- // Get mouse position
- loc = MouseLocation(members->window);
+ // Get mouse position relative to the window
+ loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
+ // Send the event
SendEvent(sfEvent);
break;
default:
break;
}
-
- return UnusedEvent;
}
////////////////////////////////////////////////////////////
/// Handle a mouse move event (NSEvent)
////////////////////////////////////////////////////////////
-int WindowImplCocoa::HandleMouseMove(void *eventRef)
+void WindowImplCocoa::HandleMouseMove(void *eventRef)
{
Event sfEvent;
NSPoint loc = {0, 0};
- loc = MouseLocation(members->window);
+ loc = [myWrapper mouseLocation];
sfEvent.Type = Event::MouseMoved;
sfEvent.MouseMove.X = (int) loc.x;
@@ -665,65 +470,55 @@ int WindowImplCocoa::HandleMouseMove(void *eventRef)
SendEvent(sfEvent);
- // MouseEntered and MouseLeft events
- if (MouseInside(members->window, members->view) && !mouseIn) {
+ if ([myWrapper mouseInside] && !myMouseIn) {
+ // If mouse IS inside but WAS not inside last time
sfEvent.Type = Event::MouseEntered;
- mouseIn = true;
+ myMouseIn = true;
+
SendEvent(sfEvent);
- } else if (!MouseInside(members->window, members->view) && mouseIn) {
+ } else if (![myWrapper mouseInside] && myMouseIn) {
+ // Is mouse WAS not inside but IS now inside
sfEvent.Type = Event::MouseLeft;
- mouseIn = false;
+ myMouseIn = false;
+
SendEvent(sfEvent);
}
-
- return UnusedEvent;
}
////////////////////////////////////////////////////////////
/// Handle a mouse wheel event (NSEvent)
////////////////////////////////////////////////////////////
-int WindowImplCocoa::HandleMouseWheel(void *eventRef)
+void WindowImplCocoa::HandleMouseWheel(void *eventRef)
{
- NSEvent *event = static_cast <NSEvent *> (eventRef);
+ NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
- wheelStatus += [event deltaY];
+ // SFML uses integer values for delta but Cocoa uses float and it is mostly fewer than 1.0
+ // Therefore I chose to add the float value to a 'wheel status' and
+ // send a sf event only when it's greater than 1.0
+ myWheelStatus += [event deltaY];
- if (fabs(wheelStatus) > 1.0f) {
+ if (fabs(myWheelStatus) > 1.0f) {
+ // Make the event and send it
Event sfEvent;
sfEvent.Type = Event::MouseWheelMoved;
- sfEvent.MouseWheel.Delta = (int) wheelStatus;
+ sfEvent.MouseWheel.Delta = (int) myWheelStatus;
SendEvent(sfEvent);
- wheelStatus -= (int) wheelStatus;
+ // Remove as much integer units as the one that have been put in the event
+ // (was a mistake to set this to 0)
+ myWheelStatus -= (int) myWheelStatus;
}
-
- return UnusedEvent;
}
-
-
-////////////////////////////////////////////////////////////
-/// Return a pointer to the SFWindow object
-////////////////////////////////////////////////////////////
-void *WindowImplCocoa::CocoaWindow(void)
-{
- return static_cast <void *> (members->window);
-}
-
-////////////////////////////////////////////////////////////
-/// Return whether the window is in full screen mode
-////////////////////////////////////////////////////////////
-bool WindowImplCocoa::IsFullscreen(void)
-{
- return fullscreen;
-}
-
+
+
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::Display
////////////////////////////////////////////////////////////
void WindowImplCocoa::Display()
{
- [members->context flushBuffer];
+ // Forward flush call to the window
+ [myWrapper flushBuffer];
}
@@ -732,10 +527,8 @@ void WindowImplCocoa::Display()
////////////////////////////////////////////////////////////
void WindowImplCocoa::ProcessEvents()
{
- if (![NSApp isRunning])
- return;
-
- [[AppController sharedController] processEvents];
+ // Forward event handling call to the application controller
+ [SharedAppController processEvents];
}
@@ -744,13 +537,8 @@ void WindowImplCocoa::ProcessEvents()
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetActive(bool Active) const
{
- if (Active) {
- if ([NSOpenGLContext currentContext] != members->context)
- [members->context makeCurrentContext];
- } else {
- if ([NSOpenGLContext currentContext] == members->context)
- [NSOpenGLContext clearCurrentContext];
- }
+ // Forward the call to the window
+ [myWrapper setActive:Active];
}
@@ -759,8 +547,8 @@ void WindowImplCocoa::SetActive(bool Active) const
////////////////////////////////////////////////////////////
void WindowImplCocoa::UseVerticalSync(bool Enabled)
{
- GLint enable = (Enabled) ? 1 : 0;
- [members->context setValues:&enable forParameter:NSOpenGLCPSwapInterval];
+ // Forward the call to the window
+ [myWrapper enableVerticalSync:Enabled];
}
@@ -784,24 +572,21 @@ void WindowImplCocoa::SetCursorPosition(unsigned int Left, unsigned int Top)
{
NSPoint pos = NSMakePoint ((float) Left, (float) Top);
- if (members->window) {
+ if (myWrapper) {
// Flip for SFML window coordinate system
- pos.y = [members->window frame].size.height - pos.y;
+ pos.y = [[myWrapper 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;
+ pos.y -= [[myWrapper window] frame].size.height - [[myWrapper glView] frame].size.height;
// Convert to screen coordinates
- NSPoint absolute = [members->window convertBaseToScreen:pos];
+ NSPoint absolute = [[myWrapper window] convertBaseToScreen:pos];
// Flip screen coodinates
absolute.y = [[NSScreen mainScreen] frame].size.height - absolute.y;
// Move cursor
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, CGPointMake(absolute.x, absolute.y));
- } else {
- std::cerr << "*** SFML: uninitialized 'members->window' member (objc_members) in "
- << this << " (sf::priv::WindowImplCocoa)" << std::endl;
}
}
@@ -811,16 +596,7 @@ void WindowImplCocoa::SetCursorPosition(unsigned int Left, unsigned int Top)
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetPosition(int Left, int Top)
{
- if (members->window) {
- if (!fullscreen) {
- // Change the window position
- Top = (int) [[members->window screen] frame].size.height - Top;
- [members->window setFrameTopLeftPoint:NSMakePoint(Left, Top)];
- }
- } else {
- std::cerr << "*** SFML: uninitialized 'members->window' member (objc_members) in "
- << this << " (sf::priv::WindowImplCocoa)";
- }
+ [myWrapper setPosition:NSMakePoint(Left, Top)];
}
@@ -830,17 +606,7 @@ void WindowImplCocoa::SetPosition(int Left, int Top)
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetSize(unsigned int Width, unsigned int Height)
{
- if (members->window) {
- if (!fullscreen) {
- [members->window setFrame:NSMakeRect([members->window frame].origin.x,
- [members->window frame].origin.y,
- (float) Width, (float) Height)
- display:YES];
- }
- } else {
- std::cerr << "*** SFML: uninitialized 'members->window' member (objc_members) in "
- << this << " (sf::priv::WindowImplCocoa)" << std::endl;
- }
+ [myWrapper setSize:NSMakeSize(Width, Height)];
}
@@ -849,83 +615,7 @@ void WindowImplCocoa::SetSize(unsigned int Width, unsigned int Height)
////////////////////////////////////////////////////////////
void WindowImplCocoa::Show(bool State)
{
- if (State && ![members->window isVisible]) {
- // Wanna open the closed window
-
- // Register ourselves for event handling
- [[AppController sharedController] registerWindow:this];
-
- if (fullscreen) {
- desktopMode = VideoMode::GetDesktopMode();
-
- CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay,
- fullscreenMode.BitsPerPixel,
- fullscreenMode.Width,
- fullscreenMode.Height,
- NULL);
-
- CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
-
- // Fade to a black screen
- [SharedAppController doFadeOperation:FillScreen time:0.5f sync:true token:&token];
- [NSMenu setMenuBarVisible:NO];
-
- // Switch to the wished display mode
- CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
-
- // Open the window
- [members->window makeKeyAndOrderFront:nil];
- [members->window center];
-
- // Fade to normal screen
- [SharedAppController doFadeOperation:CleanScreen time:0.2f sync:false token:&token];
-
- } else {
- // Show the window
- // Note: using these two lines instead of -[NSWindow makeKeyAndOrderFront:]
- // in order to prevent the standard window buttons from not displaying
- // the "mouse over" icons
- [members->window orderFront:nil];
- [members->window makeKeyWindow];
-
- }
- } else if (!State && [members->window isVisible]) {
- // Wanna close the opened window
-
- if (fullscreen) {
- CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay,
- desktopMode.BitsPerPixel,
- desktopMode.Width,
- desktopMode.Height,
- NULL);
-
- CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
-
- // Fade to black screen
- [SharedAppController doFadeOperation:FillScreen time:0.2f sync:true token:&token];
-
- // Switch to the wished display mode
- CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
-
- // Close the window
- [members->window close];
- [NSMenu setMenuBarVisible:YES];
-
- // Fade to normal screen
- [SharedAppController doFadeOperation:CleanScreen time:0.5f sync:false token:&token];
-
- // Do not sync but sleep so that the Dock and the Finder desktop go back to normal
- // state before the end of the fade operation
- sf::Sleep(0.5f);
- } else {
- // Close the window
- [members->window close];
-
- }
-
- // Unregister ourselves from the event handler
- [[AppController sharedController] unregisterWindow:this];
- }
+ [myWrapper show:State];
}
@@ -934,7 +624,7 @@ void WindowImplCocoa::Show(bool State)
////////////////////////////////////////////////////////////
void WindowImplCocoa::EnableKeyRepeat(bool Enabled)
{
- useKeyRepeat = Enabled;
+ myUseKeyRepeat = Enabled;
}
@@ -948,270 +638,6 @@ void WindowImplCocoa::SetIcon(unsigned int Width, unsigned int Height, const Uin
////////////////////////////////////////////////////////////
-/// Make some allocations and initializations
-////////////////////////////////////////////////////////////
-void WindowImplCocoa::Initialize(void)
-{
- // Allocate mem for the private objc members
- members = new objc_members;
- bzero(members, sizeof(*members));
-
- // Needed to always have an autorelease pool as soon as application is launched
- ONCE([SharedAppController resetPool]);
-
- // Register application if needed and launch it
- ONCE([SharedAppController runApplication]);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Make the window
-////////////////////////////////////////////////////////////
-static SFWindow *MakeWindow(WindowSettings& params, unsigned long style, VideoMode& mode, NSString *title)
-{
- SFWindow *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) {
- std::cerr << "*** SFML: unable to get a display mode with the given parameters" << std::endl;
- 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 =[massert([SFWindow 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;
-#if ENABLE_ANTIALIASING
- unsigned samplesIdx = 0;
-#endif
-
- // 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;
-
-#if ENABLE_ANTIALIASING
- // Antialiasing settings
- if (params.AntialiasingLevel) {
- samplesIdx = idx;
-
- attribs[idx++] = NSOpenGLPFASamples;
- attribs[idx++] = (NSOpenGLPixelFormatAttribute) params.AntialiasingLevel;
-
- attribs[idx++] = NSOpenGLPFASampleBuffers;
- attribs[idx++] = (NSOpenGLPixelFormatAttribute) GL_TRUE;
- }
-#endif
-
- pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
-
-#if ENABLE_ANTIALIASING
- // 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];
- }
-#endif
-
- if (pixFormat) {
- context = [[NSOpenGLContext alloc] initWithFormat:pixFormat
- shareContext:[sharedContext retain]];
-
- // Get the effective properties from our OpenGL context
- GLint tmpDepthSize = 0, tmpStencilBits = 0, tmpAntialiasingLevel = 0;
-
- if (context) {
- [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(SFWindow *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];
- }
-
- return view;
-}
-
-
-static void ConfigureWindow(SFWindow *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)
@@ -1268,7 +694,7 @@ static Key::Code KeyForVirtualCode(unsigned short vCode)
{0x36, Key::RSystem}, //< Right Command
{0x3C, Key::RShift}, //< Right Shift
- {0x39, Key::Code(0)} //< Caps Lock
+ {0x39, Key::Code(0)} //< Caps Lock (not handled by SFML for now)
};
Key::Code result = Key::Code(0);
@@ -1289,6 +715,7 @@ static Key::Code KeyForVirtualCode(unsigned short vCode)
////////////////////////////////////////////////////////////
static Key::Code KeyForUnicode(unsigned short uniCode)
{
+ // TODO: find a better way to get the language independant key
static struct {
unsigned short character;
Key::Code sfKey;
@@ -1388,43 +815,6 @@ static bool IsTextEvent(NSEvent *event)
return res;
}
-
-////////////////////////////////////////////////////////////
-/// Return whether the mouse is on our OpenGL view
-////////////////////////////////////////////////////////////
-static bool MouseInside(SFWindow *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;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Return the mouse location in the SFML coordinates according to 'window'
-////////////////////////////////////////////////////////////
-static NSPoint MouseLocation(SFWindow *window)
-{
- NSPoint location = [NSEvent mouseLocation];
- NSPoint relativeLocation = {0, 0};
-
- if (window) {
- [window convertScreenToBase:location];
- relativeLocation.y = [[window contentView] frame].size.height - relativeLocation.y;
- } else {
- std::cerr << "*** SFML: tried to get mouse location from no window" << std::endl;
- }
-
- return relativeLocation;
-}
} // namespace priv
diff --git a/src/SFML/Window/Context.cpp b/src/SFML/Window/Context.cpp
index 5f4cd74..107bc6e 100755
--- a/src/SFML/Window/Context.cpp
+++ b/src/SFML/Window/Context.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Input.cpp b/src/SFML/Window/Input.cpp
index d5fac6e..7b10270 100755
--- a/src/SFML/Window/Input.cpp
+++ b/src/SFML/Window/Input.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Joystick.hpp b/src/SFML/Window/Joystick.hpp
index 6bb1f2a..4a17f4e 100755
--- a/src/SFML/Window/Joystick.hpp
+++ b/src/SFML/Window/Joystick.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -56,7 +56,7 @@ struct JoystickState
#include <SFML/Window/Win32/Joystick.hpp>
-#elif defined(SFML_SYSTEM_LINUX)
+#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
#include <SFML/Window/Linux/Joystick.hpp>
diff --git a/src/SFML/Window/Linux/Joystick.cpp b/src/SFML/Window/Linux/Joystick.cpp
index ba85ccd..509bc53 100755
--- a/src/SFML/Window/Linux/Joystick.cpp
+++ b/src/SFML/Window/Linux/Joystick.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -26,15 +26,22 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Joystick.hpp>
-#include <linux/joystick.h>
-#include <fcntl.h>
#include <sstream>
+#if defined(SFML_SYSTEM_LINUX)
+ #include <linux/joystick.h>
+ #include <fcntl.h>
+#elif defined(SFML_SYSTEM_FREEBSD)
+ // #include <sys/joystick.h> ?
+#endif
+
namespace sf
{
namespace priv
{
+#if defined(SFML_SYSTEM_LINUX)
+
////////////////////////////////////////////////////////////
/// Initialize the instance and bind it to a physical joystick
////////////////////////////////////////////////////////////
@@ -120,6 +127,45 @@ unsigned int Joystick::GetButtonsCount() const
}
+#elif defined(SFML_SYSTEM_FREEBSD)
+
+
+////////////////////////////////////////////////////////////
+/// Initialize the instance and bind it to a physical joystick
+////////////////////////////////////////////////////////////
+void Joystick::Initialize(unsigned int Index)
+{
+}
+
+
+////////////////////////////////////////////////////////////
+/// Update the current joystick and return its new state
+////////////////////////////////////////////////////////////
+JoystickState Joystick::UpdateState()
+{
+ return JoystickState();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the number of axes supported by the joystick
+////////////////////////////////////////////////////////////
+unsigned int Joystick::GetAxesCount() const
+{
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the number of buttons supported by the joystick
+////////////////////////////////////////////////////////////
+unsigned int Joystick::GetButtonsCount() const
+{
+ return 0;
+}
+
+#endif // defined(SFML_SYSTEM_FREEBSD)
+
} // namespace priv
} // namespace sf
diff --git a/src/SFML/Window/Linux/Joystick.hpp b/src/SFML/Window/Linux/Joystick.hpp
index 1c1e4a2..a035f61 100755
--- a/src/SFML/Window/Linux/Joystick.hpp
+++ b/src/SFML/Window/Linux/Joystick.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Linux/VideoModeSupport.cpp b/src/SFML/Window/Linux/VideoModeSupport.cpp
index d328702..add99b2 100755
--- a/src/SFML/Window/Linux/VideoModeSupport.cpp
+++ b/src/SFML/Window/Linux/VideoModeSupport.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -45,7 +45,7 @@ void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
// First, clear array to fill
Modes.clear();
- // Get the display and screen from sfWindowImplUnix
+ // Get the display and screen from WindowImplUnix
WindowImplX11::OpenDisplay(false);
Display* Disp = WindowImplX11::ourDisplay;
int Screen = WindowImplX11::ourScreen;
@@ -63,15 +63,24 @@ void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
XRRScreenSize* Sizes = XRRConfigSizes(Config, &NbSizes);
if (Sizes && (NbSizes > 0))
{
- // Add them to the video modes array
- for (int i = 0; i < NbSizes; ++i)
+ // Get the list of supported depths
+ int NbDepths = 0;
+ int* Depths = XListDepths(Disp, Screen, &NbDepths);
+ if (Depths && (NbDepths > 0))
{
- // Convert to sfVideoMode
- VideoMode Mode(Sizes[i].width, Sizes[i].height, 32);
-
- // Add it only if it is not already in the array
- if (std::find(Modes.begin(), Modes.end(), Mode) == Modes.end())
- Modes.push_back(Mode);
+ // Combine depths and sizes to fill the array of supported modes
+ for (int i = 0; i < NbDepths; ++i)
+ {
+ for (int j = 0; j < NbSizes; ++j)
+ {
+ // Convert to VideoMode
+ VideoMode Mode(Sizes[j].width, Sizes[j].height, Depths[i]);
+
+ // Add it only if it is not already in the array
+ if (std::find(Modes.begin(), Modes.end(), Mode) == Modes.end())
+ Modes.push_back(Mode);
+ }
+ }
}
}
@@ -99,7 +108,7 @@ VideoMode VideoModeSupport::GetDesktopVideoMode()
{
VideoMode DesktopMode;
- // Get the display and screen from sfWindowImplUnix
+ // Get the display and screen from WindowImplUnix
WindowImplX11::OpenDisplay(false);
Display* Disp = WindowImplX11::ourDisplay;
int Screen = WindowImplX11::ourScreen;
@@ -120,7 +129,7 @@ VideoMode VideoModeSupport::GetDesktopVideoMode()
int NbSizes;
XRRScreenSize* Sizes = XRRConfigSizes(Config, &NbSizes);
if (Sizes && (NbSizes > 0))
- DesktopMode = VideoMode(Sizes[CurrentMode].width, Sizes[CurrentMode].height, 32);
+ DesktopMode = VideoMode(Sizes[CurrentMode].width, Sizes[CurrentMode].height, DefaultDepth(Disp, Screen));
// Free the configuration instance
XRRFreeScreenConfigInfo(Config);
diff --git a/src/SFML/Window/Linux/VideoModeSupport.hpp b/src/SFML/Window/Linux/VideoModeSupport.hpp
index 87291fc..9160ff5 100755
--- a/src/SFML/Window/Linux/VideoModeSupport.hpp
+++ b/src/SFML/Window/Linux/VideoModeSupport.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Linux/WindowImplX11.cpp b/src/SFML/Window/Linux/WindowImplX11.cpp
index 0659089..fa0bd8e 100755
--- a/src/SFML/Window/Linux/WindowImplX11.cpp
+++ b/src/SFML/Window/Linux/WindowImplX11.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -37,6 +37,19 @@
#include <vector>
+namespace
+{
+ ////////////////////////////////////////////////////////////
+ /// Filter the events received by windows
+ /// (only allow those matching a specific window)
+ ////////////////////////////////////////////////////////////
+ Bool CheckEvent(::Display*, XEvent* Event, XPointer UserData)
+ {
+ // Just check if the event matches the window
+ return Event->xany.window == reinterpret_cast< ::Window >(UserData);
+ }
+}
+
namespace sf
{
namespace priv
@@ -340,7 +353,16 @@ WindowImplX11::~WindowImplX11()
////////////////////////////////////////////////////////////
/// Check if there's an active context on the current thread
+////////////////////
+////////////////////////////////////////////////////////////
+/// Filter the received events
+/// (only allow those matching a specific window)
////////////////////////////////////////////////////////////
+Bool CheckEvent(::Display*, XEvent* Event, XPointer UserData)
+{
+ // Just check if the event matches our window
+ return Event->xany.window == reinterpret_cast< ::Window >(UserData);
+}////////////////////////////////////////
bool WindowImplX11::IsContextActive()
{
return glXGetCurrentContext() != NULL;
@@ -362,30 +384,53 @@ void WindowImplX11::Display()
////////////////////////////////////////////////////////////
void WindowImplX11::ProcessEvents()
{
+ // This function implements a workaround to properly discard
+ // repeated key events when necessary. The problem is that the
+ // system's key events policy doesn't match SFML's one: X server will generate
+ // both repeated KeyPress and KeyRelease events when maintaining a key down, while
+ // SFML only wants repeated KeyPress events. Thus, we have to:
+ // - Discard duplicated KeyRelease events when EnableKeyRepeat is true
+ // - Discard both duplicated KeyPress and KeyRelease events when EnableKeyRepeat is false
+
+
// Process any event in the queue matching our window
XEvent Event;
- while (XCheckIfEvent(ourDisplay, &Event, &WindowImplX11::CheckEvent, reinterpret_cast<XPointer>(myWindow)))
+ while (XCheckIfEvent(ourDisplay, &Event, &CheckEvent, reinterpret_cast<XPointer>(myWindow)))
{
- // Filter repeated key events
- if (Event.type == KeyRelease)
+ // Detect repeated key events
+ if ((Event.type == KeyPress) || (Event.type == KeyRelease))
{
- if (XPending(ourDisplay))
+ if (Event.xkey.keycode < 256)
{
- XEvent NextEvent;
- XPeekEvent(ourDisplay, &NextEvent);
- if ((NextEvent.type == KeyPress) &&
- (NextEvent.xkey.keycode == Event.xkey.keycode) &&
- (NextEvent.xkey.time == Event.xkey.time))
+ // To detect if it is a repeated key event, we check the current state of the key.
+ // - If the state is "down", KeyReleased events must obviously be discarded.
+ // - KeyPress events are a little bit harder to handle: they depend on the EnableKeyRepeat state,
+ // and we need to properly forward the first one.
+ char Keys[32];
+ XQueryKeymap(ourDisplay, Keys);
+ if (Keys[Event.xkey.keycode >> 3] & (1 << (Event.xkey.keycode % 8)))
{
- if (!myKeyRepeat)
- XNextEvent(ourDisplay, &NextEvent);
- continue;
+ // KeyRelease event + key down = repeated event --> discard
+ if (Event.type == KeyRelease)
+ {
+ myLastKeyReleaseEvent = Event;
+ continue;
+ }
+
+ // KeyPress event + key repeat disabled + matching KeyRelease event = repeated event --> discard
+ if ((Event.type == KeyPress) && !myKeyRepeat &&
+ (myLastKeyReleaseEvent.xkey.keycode == Event.xkey.keycode) &&
+ (myLastKeyReleaseEvent.xkey.time == Event.xkey.time))
+ {
+ continue;
+ }
}
}
}
+ // Process the event
ProcessEvent(Event);
- }
+ }
}
@@ -649,7 +694,6 @@ bool WindowImplX11::CreateContext(const VideoMode& Mode, XVisualInfo& ChosenVisu
{
BestScore = Score;
BestVisual = &Visuals[i];
- break;
}
}
@@ -710,6 +754,9 @@ bool WindowImplX11::CreateContext(const VideoMode& Mode, XVisualInfo& ChosenVisu
////////////////////////////////////////////////////////////
void WindowImplX11::Initialize()
{
+ // Make sure the "last key release" is initialized with invalid values
+ myLastKeyReleaseEvent.type = -1;
+
// Get the atom defining the close event
myAtomClose = XInternAtom(ourDisplay, "WM_DELETE_WINDOW", false);
XSetWMProtocols(ourDisplay, myWindow, &myAtomClose, 1);
@@ -804,17 +851,6 @@ void WindowImplX11::CleanUp()
////////////////////////////////////////////////////////////
-/// Filter the received events
-/// (only allow those matching a specific window)
-////////////////////////////////////////////////////////////
-Bool WindowImplX11::CheckEvent(::Display*, XEvent* Event, XPointer UserData)
-{
- // Just check if the event matches our window
- return Event->xany.window == reinterpret_cast< ::Window >(UserData);
-}
-
-
-////////////////////////////////////////////////////////////
/// Process an incoming event from the window
////////////////////////////////////////////////////////////
void WindowImplX11::ProcessEvent(XEvent WinEvent)
diff --git a/src/SFML/Window/Linux/WindowImplX11.hpp b/src/SFML/Window/Linux/WindowImplX11.hpp
index b4506fc..9fd4e0e 100755
--- a/src/SFML/Window/Linux/WindowImplX11.hpp
+++ b/src/SFML/Window/Linux/WindowImplX11.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -201,18 +201,6 @@ private :
void CleanUp();
////////////////////////////////////////////////////////////
- /// Filter the received events
- /// (only allow those matching a specific window)
- ///
- /// \param Event : Event to filter
- /// \param UserData : Data passed to the function (here : the window to compare)
- ///
- /// \return True if the event belongs to the specified window
- ///
- ////////////////////////////////////////////////////////////
- static Bool CheckEvent(::Display*, XEvent* Event, XPointer UserData);
-
- ////////////////////////////////////////////////////////////
/// Process an incoming event from the window
///
/// \param WinEvent : Event which has been received
@@ -259,14 +247,15 @@ private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
- ::Window myWindow; ///< X11 structure defining our window
- bool myIsExternal; ///< Tell whether the window has been created externally or by SFML
- GLXContext myGLContext; ///< OpenGL context attached to the window
- Atom myAtomClose; ///< Atom used to identify the close event
- int myOldVideoMode; ///< Video mode in use before we switch to fullscreen
- Cursor myHiddenCursor; ///< As X11 doesn't provide cursor hidding, we must create a transparent one
- XIC myInputContext; ///< Input context used to get unicode input in our window
- bool myKeyRepeat; ///< Is the KeyRepeat feature enabled ?
+ ::Window myWindow; ///< X11 structure defining our window
+ bool myIsExternal; ///< Tell whether the window has been created externally or by SFML
+ GLXContext myGLContext; ///< OpenGL context attached to the window
+ Atom myAtomClose; ///< Atom used to identify the close event
+ int myOldVideoMode; ///< Video mode in use before we switch to fullscreen
+ Cursor myHiddenCursor; ///< As X11 doesn't provide cursor hidding, we must create a transparent one
+ XIC myInputContext; ///< Input context used to get unicode input in our window
+ bool myKeyRepeat; ///< Is the KeyRepeat feature enabled ?
+ XEvent myLastKeyReleaseEvent; ///< Last key release event we received (needed for discarding repeated key events)
};
} // namespace priv
diff --git a/src/SFML/Window/Cocoa/WindowController.h b/src/SFML/Window/Template for new ports/Joystick.cpp
index 4c40825..442e329 100755
--- a/src/SFML/Window/Cocoa/WindowController.h
+++ b/src/SFML/Window/Template for new ports/Joystick.cpp
@@ -1,73 +1,74 @@
-////////////////////////////////////////////////////////////
-//
-// 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 <Cocoa/Cocoa.h>
-#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
-#import <SFML/Window/Event.hpp>
-
-
-////////////////////////////////////////////////////////////
-/// WindowController is a Cocoa notification receiver
-////////////////////////////////////////////////////////////
-@interface WindowController : NSObject {
- sf::priv::WindowImplCocoa *parentWindow;
-}
-
-////////////////////////////////////////////////////////////
-/// Return a new autoreleased WindowController object linked
-/// to the 'window' WindowImplCocoa object.
-////////////////////////////////////////////////////////////
-+ (WindowController *)controllerWithWindow:(sf::priv::WindowImplCocoa *)window;
-- (WindowController *)initWithWindow:(sf::priv::WindowImplCocoa *)window;
-
-////////////////////////////////////////////////////////////
-/// Notification method receiver when OpenGL view size changes
-////////////////////////////////////////////////////////////
-- (void)viewFrameDidChange:(NSNotification *)notification;
-
-////////////////////////////////////////////////////////////
-/// Notification method receiver when the window gains focus
-////////////////////////////////////////////////////////////
-- (void)windowDidBecomeMain:(NSNotification *)notification;
-
-////////////////////////////////////////////////////////////
-/// Notification method receiver when the window loses focus
-////////////////////////////////////////////////////////////
-- (void)windowDidResignMain:(NSNotification *)notification;
-
-////////////////////////////////////////////////////////////
-/// Notification method receiver when the window closes
-////////////////////////////////////////////////////////////
-- (void)windowWillClose:(NSNotification *)notification;
-
-@end
-
-// NSWindow subclass used to allow full screen windows to receive events
-@interface SFWindow : NSWindow
-@end
-
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 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 <SFML/xxx/Joystick.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// Initialize the instance and bind it to a physical joystick
+////////////////////////////////////////////////////////////
+void Joystick::Initialize(unsigned int Index)
+{
+ // Reset the joystick state
+
+ // Initialize the Index-th available joystick
+}
+
+
+////////////////////////////////////////////////////////////
+/// Update the current joystick and return its new state
+////////////////////////////////////////////////////////////
+JoystickState Joystick::UpdateState()
+{
+ // Fill a JoystickState instance with the current joystick state
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the number of axes supported by the joystick
+////////////////////////////////////////////////////////////
+unsigned int Joystick::GetAxesCount() const
+{
+ // Return number of supported axes
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the number of buttons supported by the joystick
+////////////////////////////////////////////////////////////
+unsigned int Joystick::GetButtonsCount() const
+{
+ // Return number of supported buttons
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Template for new ports/Joystick.hpp b/src/SFML/Window/Template for new ports/Joystick.hpp
new file mode 100755
index 0000000..bb5243a
--- /dev/null
+++ b/src/SFML/Window/Template for new ports/Joystick.hpp
@@ -0,0 +1,82 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 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_JOYSTICKXXX_HPP
+#define SFML_JOYSTICKXXX_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// Linux implementation of Joystick
+////////////////////////////////////////////////////////////
+class Joystick
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Initialize the instance and bind it to a physical joystick
+ ///
+ /// \param Index : Index of the physical joystick to bind to
+ ///
+ ////////////////////////////////////////////////////////////
+ void Initialize(unsigned int Index);
+
+ ////////////////////////////////////////////////////////////
+ /// Update the current joystick and return its new state
+ ///
+ /// \return Current state of the joystick
+ ///
+ ////////////////////////////////////////////////////////////
+ JoystickState UpdateState();
+
+ ////////////////////////////////////////////////////////////
+ /// Get the number of axes supported by the joystick
+ ///
+ /// \return Number of axis
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int GetAxesCount() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the number of buttons supported by the joystick
+ ///
+ /// \return Number of buttons
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int GetButtonsCount() const;
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_JOYSTICKXXX_HPP
diff --git a/src/SFML/Window/Template for new ports/VideoModeSupport.cpp b/src/SFML/Window/Template for new ports/VideoModeSupport.cpp
new file mode 100755
index 0000000..0057992
--- /dev/null
+++ b/src/SFML/Window/Template for new ports/VideoModeSupport.cpp
@@ -0,0 +1,60 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 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 <SFML/Window/XXX/VideoModeSupport.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// Get supported video modes
+////////////////////////////////////////////////////////////
+void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
+{
+ // Get all the supported fullscreen modes and put them in Modes array
+
+ // Just care about width, height and bpp (ignore frequency and other attributes)
+
+ // You must remove duplicates
+
+ // Order doesn't matter (the array will be sorted later)
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get current desktop video mode
+////////////////////////////////////////////////////////////
+VideoMode VideoModeSupport::GetDesktopVideoMode()
+{
+ // Return the current desktop video mode
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Template for new ports/VideoModeSupport.hpp b/src/SFML/Window/Template for new ports/VideoModeSupport.hpp
new file mode 100755
index 0000000..9d46f78
--- /dev/null
+++ b/src/SFML/Window/Template for new ports/VideoModeSupport.hpp
@@ -0,0 +1,69 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 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_VIDEOMODESUPPORTXXX_HPP
+#define SFML_VIDEOMODESUPPORTXXX_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/VideoMode.hpp>
+#include <vector>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// XXX implementation of VideoModeSupport
+/// Give access to video mode related OS-specific functions
+////////////////////////////////////////////////////////////
+class VideoModeSupport
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Get supported video modes
+ ///
+ /// \param Modes : Array to fill with available video modes
+ ///
+ ////////////////////////////////////////////////////////////
+ static void GetSupportedVideoModes(std::vector<VideoMode>& Modes);
+
+ ////////////////////////////////////////////////////////////
+ /// Get current desktop video mode
+ ///
+ /// \return Current desktop video mode
+ ///
+ ////////////////////////////////////////////////////////////
+ static VideoMode GetDesktopVideoMode();
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_VIDEOMODESUPPORTXXX_HPP
diff --git a/src/SFML/Window/Template for new ports/WindowImplXXX.cpp b/src/SFML/Window/Template for new ports/WindowImplXXX.cpp
new file mode 100755
index 0000000..46f5d2d
--- /dev/null
+++ b/src/SFML/Window/Template for new ports/WindowImplXXX.cpp
@@ -0,0 +1,231 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 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 <SFML/Window/XXX/WindowImplXXX.hpp>
+#include <SFML/Window/WindowStyle.hpp>
+#include <GL/gl.h>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// Default constructor
+/// (creates a dummy window to provide a valid OpenGL context)
+////////////////////////////////////////////////////////////
+WindowImplXXX::WindowImplXXX()
+{
+ // Create a dummy window (with the fewest attributes -- it's just to have a valid support for an OpenGL context)
+
+ // Initialize myWidth and myHeight members from base class with the window size
+
+ // Create an OpenGL context in this window and DO NOT make it active
+}
+
+
+////////////////////////////////////////////////////////////
+/// Create the window implementation from an existing control
+////////////////////////////////////////////////////////////
+WindowImplXXX::WindowImplXXX(WindowHandle Handle, WindowSettings& Params)
+{
+ // Make sure we'll be able to catch all the events of the given window
+
+ // Initialize myWidth and myHeight members from base class with the window size
+
+ // Create an OpenGL context in this window and make it active
+}
+
+
+////////////////////////////////////////////////////////////
+/// Create the window implementation
+////////////////////////////////////////////////////////////
+WindowImplXXX::WindowImplXXX(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params) :
+{
+ // Create a new window with given size, title and style
+
+ // Initialize myWidth and myHeight members from base class with the window size
+
+ // Create an OpenGL context in this window and make it active
+}
+
+
+////////////////////////////////////////////////////////////
+/// Destructor
+////////////////////////////////////////////////////////////
+WindowImplXXX::~WindowImplXXX()
+{
+ // Destroy the OpenGL context, the window and every resource allocated by this class
+}
+
+
+////////////////////////////////////////////////////////////
+/// Check if there's an active context on the current thread
+////////////////////////////////////////////////////////////
+bool WindowImplXXX::IsContextActive()
+{
+ // Should return whether xxxGetCurrentContext() is NULL or not;
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::Display
+////////////////////////////////////////////////////////////
+void WindowImplXXX::Display()
+{
+ // Swap OpenGL buffers (should be a call to xxxSwapBuffers)
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::ProcessEvents
+////////////////////////////////////////////////////////////
+void WindowImplXXX::ProcessEvents()
+{
+ // Process every event for this window
+
+ // Generate a sf::Event and call SendEvent(Evt) for each event
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::SetActive
+////////////////////////////////////////////////////////////
+void WindowImplXXX::SetActive(bool Active) const
+{
+ // Bind / unbind OpenGL context (should be a call to xxxMakeCurrent)
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::UseVerticalSync
+////////////////////////////////////////////////////////////
+void WindowImplXXX::UseVerticalSync(bool Enabled)
+{
+ // Activate / deactivate vertical synchronization
+ // usually using an OpenGL extension (should be a call to xxxSwapInterval)
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::ShowMouseCursor
+////////////////////////////////////////////////////////////
+void WindowImplXXX::ShowMouseCursor(bool Show)
+{
+ // Show or hide the system cursor in this window
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::SetCursorPosition
+////////////////////////////////////////////////////////////
+void WindowImplXXX::SetCursorPosition(unsigned int Left, unsigned int Top)
+{
+ // Change the cursor position (Left and Top are relative to this window)
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::SetPosition
+////////////////////////////////////////////////////////////
+void WindowImplXXX::SetPosition(int Left, int Top)
+{
+ // Change the window position
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::SetSize
+////////////////////////////////////////////////////////////
+void WindowImplWin32::SetSize(unsigned int Width, unsigned int Height)
+{
+ // Change the window size
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::Show
+////////////////////////////////////////////////////////////
+void WindowImplXXX::Show(bool State)
+{
+ // Show or hide the window
+}
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::EnableKeyRepeat
+////////////////////////////////////////////////////////////
+void WindowImplXXX::EnableKeyRepeat(bool Enabled)
+{
+ // Enable or disable automatic key-repeat for keydown events
+}
+
+
+////////////////////////////////////////////////////////////
+/// /see WindowImpl::SetIcon
+////////////////////////////////////////////////////////////
+void WindowImplXXX::SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixels)
+{
+ // Change all the necessary icons of the window (titlebar, task bar, ...) with the
+ // provided array of 32 bits RGBA pixels
+}
+
+
+/*===========================================================
+ STRATEGY FOR OPENGL CONTEXT CREATION
+
+- If the requested level of anti-aliasing is not supported and is greater than 2, try with 2
+ --> if level 2 fails, disable anti-aliasing
+ --> it's important not to generate an error if anti-aliasing is not supported
+
+- Use a matching pixel mode, or the best of all available pixel modes if no perfect match ;
+ You should use the function EvaluateConfig to get a score for a given configuration
+
+- Don't forget to fill Params (see constructors) back with the actual parameters we got from the chosen pixel format
+
+- IMPORTANT : all OpenGL contexts must be shared (usually a call to xxxShareLists)
+
+===========================================================*/
+
+
+/*===========================================================
+ STRATEGY FOR EVENT HANDLING
+
+- Process any event matching with the ones in sf::Event::EventType
+ --> Create a sf::Event, fill the members corresponding to the event type
+ --> No need to handle joystick events, they are handled by WindowImpl::ProcessJoystickEvents
+ --> Event::TextEntered must provide UTF-16 characters
+ (see http://www.unicode.org/Public/PROGRAMS/CVTUTF/ for unicode conversions)
+ --> Don't forget to process any destroy-like event (ie. when the window is destroyed externally)
+
+- Use SendEvent function from base class to propagate the created events
+
+===========================================================*/
+
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Template for new ports/WindowImplXXX.hpp b/src/SFML/Window/Template for new ports/WindowImplXXX.hpp
new file mode 100755
index 0000000..e5dee89
--- /dev/null
+++ b/src/SFML/Window/Template for new ports/WindowImplXXX.hpp
@@ -0,0 +1,167 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 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_WINDOWIMPLXXX_HPP
+#define SFML_WINDOWIMPLXXX_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Event.hpp>
+#include <SFML/Window/WindowImpl.hpp>
+#include <string>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// WindowImplXXX is the XXX implementation of WindowImpl
+////////////////////////////////////////////////////////////
+class WindowImplXXX : public WindowImpl
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ /// (creates a dummy window to provide a valid OpenGL context)
+ ///
+ ////////////////////////////////////////////////////////////
+ WindowImplXXX();
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the window implementation from an existing control
+ ///
+ /// \param Handle : Platform-specific handle of the control
+ /// \param Params : Creation parameters
+ ///
+ ////////////////////////////////////////////////////////////
+ WindowImplXXX(WindowHandle Handle, WindowSettings& Params);
+
+ ////////////////////////////////////////////////////////////
+ /// Create the window implementation
+ ///
+ /// \param Mode : Video mode to use
+ /// \param Title : Title of the window
+ /// \param WindowStyle : Window style
+ /// \param Params : Creation parameters
+ ///
+ ////////////////////////////////////////////////////////////
+ WindowImplXXX(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params);
+
+ ////////////////////////////////////////////////////////////
+ /// Destructor
+ ///
+ ////////////////////////////////////////////////////////////
+ ~WindowImplXXX();
+
+ ////////////////////////////////////////////////////////////
+ /// Check if there's an active context on the current thread
+ ///
+ /// \return True if there's a context bound to the current thread
+ ///
+ ////////////////////////////////////////////////////////////
+ static bool IsContextActive();
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::Display
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void Display();
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::ProcessEvents
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void ProcessEvents();
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::SetActive
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void SetActive(bool Active = true) const;
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::IsActive
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual bool IsActive() const;
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::UseVerticalSync
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void UseVerticalSync(bool Enabled);
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::ShowMouseCursor
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void ShowMouseCursor(bool Show);
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::SetCursorPosition
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void SetCursorPosition(unsigned int Left, unsigned int Top);
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::SetPosition
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void SetPosition(int Left, int Top);
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::SetSize
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void SetSize(unsigned int Width, unsigned int Height);
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::Show
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void Show(bool State);
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::EnableKeyRepeat
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void EnableKeyRepeat(bool Enabled);
+
+ ////////////////////////////////////////////////////////////
+ /// /see WindowImpl::SetIcon
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixels);
+};
+
+} // namespace priv
+
+} // namespace sf
+
+#endif // SFML_WINDOWIMPLXXX_HPP
diff --git a/src/SFML/Window/VideoMode.cpp b/src/SFML/Window/VideoMode.cpp
index 8efff0f..3ed77bc 100755
--- a/src/SFML/Window/VideoMode.cpp
+++ b/src/SFML/Window/VideoMode.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/VideoModeSupport.hpp b/src/SFML/Window/VideoModeSupport.hpp
index 63ee1e9..caa94aa 100755
--- a/src/SFML/Window/VideoModeSupport.hpp
+++ b/src/SFML/Window/VideoModeSupport.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -35,7 +35,7 @@
#include <SFML/Window/Win32/VideoModeSupport.hpp>
-#elif defined(SFML_SYSTEM_LINUX)
+#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
#include <SFML/Window/Linux/VideoModeSupport.hpp>
diff --git a/src/SFML/Window/Win32/Joystick.cpp b/src/SFML/Window/Win32/Joystick.cpp
index 9cf195f..10bb0d6 100755
--- a/src/SFML/Window/Win32/Joystick.cpp
+++ b/src/SFML/Window/Win32/Joystick.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -49,6 +49,8 @@ void Joystick::Initialize(unsigned int Index)
// Get the Index-th connected joystick
MMRESULT Error;
JOYINFOEX JoyInfo;
+ JoyInfo.dwSize = sizeof(JoyInfo);
+ JoyInfo.dwFlags = JOY_RETURNALL;
for (unsigned int NbFound = 0; (Error = joyGetPosEx(myIndex, &JoyInfo)) != JOYERR_PARMS; myIndex++)
{
// Check if the current joystick is connected
diff --git a/src/SFML/Window/Win32/Joystick.hpp b/src/SFML/Window/Win32/Joystick.hpp
index 95019cb..8303a7e 100755
--- a/src/SFML/Window/Win32/Joystick.hpp
+++ b/src/SFML/Window/Win32/Joystick.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Win32/VideoModeSupport.cpp b/src/SFML/Window/Win32/VideoModeSupport.cpp
index cd5f650..8b98e74 100755
--- a/src/SFML/Window/Win32/VideoModeSupport.cpp
+++ b/src/SFML/Window/Win32/VideoModeSupport.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Win32/WindowImplWin32.cpp b/src/SFML/Window/Win32/WindowImplWin32.cpp
index e07eeab..9148774 100755
--- a/src/SFML/Window/Win32/WindowImplWin32.cpp
+++ b/src/SFML/Window/Win32/WindowImplWin32.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -355,6 +355,13 @@ void WindowImplWin32::SetPosition(int Left, int Top)
////////////////////////////////////////////////////////////
void WindowImplWin32::SetSize(unsigned int Width, unsigned int Height)
{
+ // SetWindowPos wants the total size of the window (including title bar and borders),
+ // so we have to compute it
+ RECT Rect = {0, 0, Width, Height};
+ AdjustWindowRect(&Rect, GetWindowLong(myHandle, GWL_STYLE), false);
+ Width = Rect.right - Rect.left;
+ Height = Rect.bottom - Rect.top;
+
SetWindowPos(myHandle, NULL, 0, 0, Width, Height, SWP_NOMOVE | SWP_NOZORDER);
}
@@ -753,11 +760,22 @@ void WindowImplWin32::ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam)
{
Event Evt;
Evt.Type = Event::KeyPressed;
- Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(true) : VirtualKeyCodeToSF(WParam, LParam);
Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
- SendEvent(Evt);
+
+ if (WParam != VK_SHIFT)
+ {
+ Evt.Key.Code = VirtualKeyCodeToSF(WParam, LParam);
+ SendEvent(Evt);
+ }
+ else
+ {
+ // Special case for shift, its state can't be retrieved directly
+ Evt.Key.Code = GetShiftState(true);
+ if (Evt.Key.Code != 0)
+ SendEvent(Evt);
+ }
}
break;
}
@@ -768,11 +786,23 @@ void WindowImplWin32::ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam)
{
Event Evt;
Evt.Type = Event::KeyReleased;
- Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(false) : VirtualKeyCodeToSF(WParam, LParam);
Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
- SendEvent(Evt);
+
+ if (WParam != VK_SHIFT)
+ {
+ Evt.Key.Code = VirtualKeyCodeToSF(WParam, LParam);
+ SendEvent(Evt);
+ }
+ else
+ {
+ // Special case for shift, its state can't be retrieved directly
+ Evt.Key.Code = GetShiftState(false);
+ if (Evt.Key.Code != 0)
+ SendEvent(Evt);
+ }
+
break;
}
diff --git a/src/SFML/Window/Win32/WindowImplWin32.hpp b/src/SFML/Window/Win32/WindowImplWin32.hpp
index 7b6a425..75c1c59 100755
--- a/src/SFML/Window/Win32/WindowImplWin32.hpp
+++ b/src/SFML/Window/Win32/WindowImplWin32.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp
index 7539bde..cfaae84 100755
--- a/src/SFML/Window/Window.cpp
+++ b/src/SFML/Window/Window.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -32,19 +32,27 @@
#include <iostream>
+////////////////////////////////////////////////////////////
+// Private data
+////////////////////////////////////////////////////////////
+namespace
+{
+ const sf::Window* FullscreenWindow = NULL;
+}
+
+
namespace sf
{
////////////////////////////////////////////////////////////
/// Default constructor
-///
////////////////////////////////////////////////////////////
Window::Window() :
myWindow (NULL),
myLastFrameTime (0.f),
myIsExternal (false),
myFramerateLimit(0),
-mySetCursorPosX (-1),
-mySetCursorPosY (-1)
+mySetCursorPosX (0xFFFF),
+mySetCursorPosY (0xFFFF)
{
}
@@ -73,8 +81,8 @@ myWindow (NULL),
myLastFrameTime (0.f),
myIsExternal (true),
myFramerateLimit(0),
-mySetCursorPosX (-1),
-mySetCursorPosY (-1)
+mySetCursorPosX (0xFFFF),
+mySetCursorPosY (0xFFFF)
{
Create(Handle, Params);
}
@@ -95,20 +103,36 @@ Window::~Window()
////////////////////////////////////////////////////////////
void Window::Create(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, const WindowSettings& Params)
{
- // Check validity of video mode
- if ((WindowStyle & Style::Fullscreen) && !Mode.IsValid())
+ // Destroy the previous window implementation
+ Close();
+
+ // Fullscreen style requires some tests
+ if (WindowStyle & Style::Fullscreen)
{
- std::cerr << "The requested video mode is not available, switching to a valid mode" << std::endl;
- Mode = VideoMode::GetMode(0);
+ // Make sure there's not already a fullscreen window (only one is allowed)
+ if (FullscreenWindow)
+ {
+ std::cerr << "Creating two fullscreen windows is not allowed, switching to windowed mode" << std::endl;
+ WindowStyle &= ~Style::Fullscreen;
+ }
+ else
+ {
+ // Make sure the chosen video mode is compatible
+ if (!Mode.IsValid())
+ {
+ std::cerr << "The requested video mode is not available, switching to a valid mode" << std::endl;
+ Mode = VideoMode::GetMode(0);
+ }
+
+ // Update the fullscreen window
+ FullscreenWindow = this;
+ }
}
// Check validity of style
if ((WindowStyle & Style::Close) || (WindowStyle & Style::Resize))
WindowStyle |= Style::Titlebar;
- // Destroy the previous window implementation
- delete myWindow;
-
// Activate the global context
Context::GetGlobal().SetActive(true);
@@ -123,7 +147,7 @@ void Window::Create(VideoMode Mode, const std::string& Title, unsigned long Wind
void Window::Create(WindowHandle Handle, const WindowSettings& Params)
{
// Destroy the previous window implementation
- delete myWindow;
+ Close();
// Activate the global context
Context::GetGlobal().SetActive(true);
@@ -143,6 +167,10 @@ void Window::Close()
// Delete the window implementation
delete myWindow;
myWindow = NULL;
+
+ // Update the fullscreen window
+ if (this == FullscreenWindow)
+ FullscreenWindow = NULL;
}
@@ -413,11 +441,12 @@ void Window::OnEvent(const Event& EventReceived)
////////////////////////////////////////////////////////////
void Window::Initialize(priv::WindowImpl* Window)
{
- // Assign new window and listen to its events
+ // Assign and initialize the new window
myWindow = Window;
- myWindow->AddListener(this);
+ myWindow->Initialize();
- // Attach input to the window
+ // Listen to events from the new window
+ myWindow->AddListener(this);
myWindow->AddListener(&myInput);
// Setup default behaviours (to get a consistent behaviour across different implementations)
diff --git a/src/SFML/Window/WindowImpl.cpp b/src/SFML/Window/WindowImpl.cpp
index fde2d44..bc60543 100755
--- a/src/SFML/Window/WindowImpl.cpp
+++ b/src/SFML/Window/WindowImpl.cpp
@@ -1,252 +1,260 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 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 <SFML/Window/WindowImpl.hpp>
-#include <SFML/Window/Event.hpp>
-#include <SFML/Window/WindowListener.hpp>
-#include <algorithm>
-#include <cmath>
-
-#if defined(SFML_SYSTEM_WINDOWS)
-
- #include <SFML/Window/Win32/WindowImplWin32.hpp>
- typedef sf::priv::WindowImplWin32 WindowImplType;
-
-#elif defined(SFML_SYSTEM_LINUX)
-
- #include <SFML/Window/Linux/WindowImplX11.hpp>
- typedef sf::priv::WindowImplX11 WindowImplType;
-
-#elif defined(SFML_SYSTEM_MACOS)
-
- #include <SFML/Window/Cocoa/WindowImplCocoa.hpp>
- typedef sf::priv::WindowImplCocoa WindowImplType;
-
-#endif
-
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-/// Create a new window depending on the current OS
-////////////////////////////////////////////////////////////
-WindowImpl* WindowImpl::New()
-{
- return new WindowImplType();
-}
-
-
-////////////////////////////////////////////////////////////
-/// Create a new window depending on the current OS
-////////////////////////////////////////////////////////////
-WindowImpl* WindowImpl::New(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params)
-{
- return new WindowImplType(Mode, Title, WindowStyle, Params);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Create a new window depending on the current OS
-////////////////////////////////////////////////////////////
-WindowImpl* WindowImpl::New(WindowHandle Handle, WindowSettings& Params)
-{
- return new WindowImplType(Handle, Params);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Default constructor
-////////////////////////////////////////////////////////////
-WindowImpl::WindowImpl() :
-myWidth (0),
-myHeight (0),
-myJoyThreshold(0.1f)
-{
- // Initialize the joysticks
- for (unsigned int i = 0; i < JoysticksCount; ++i)
- {
- myJoysticks[i].Initialize(i);
- myJoyStates[i] = myJoysticks[i].UpdateState();
- }
-}
-
-
-////////////////////////////////////////////////////////////
-/// Destructor
-////////////////////////////////////////////////////////////
-WindowImpl::~WindowImpl()
-{
- // Nothing to do
-}
-
-
-////////////////////////////////////////////////////////////
-/// Add a listener to the window
-////////////////////////////////////////////////////////////
-void WindowImpl::AddListener(WindowListener* Listener)
-{
- if (Listener)
- myListeners.insert(Listener);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Remove a listener from the window
-////////////////////////////////////////////////////////////
-void WindowImpl::RemoveListener(WindowListener* Listener)
-{
- myListeners.erase(Listener);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Get the client width of the window
-////////////////////////////////////////////////////////////
-unsigned int WindowImpl::GetWidth() const
-{
- return myWidth;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Get the client height of the window
-////////////////////////////////////////////////////////////
-unsigned int WindowImpl::GetHeight() const
-{
- return myHeight;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Change the joystick threshold, ie. the value below which
-/// no move event will be generated
-////////////////////////////////////////////////////////////
-void WindowImpl::SetJoystickThreshold(float Threshold)
-{
- myJoyThreshold = Threshold;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Process incoming events from operating system
-////////////////////////////////////////////////////////////
-void WindowImpl::DoEvents()
-{
- // Read the joysticks state and generate the appropriate events
- ProcessJoystickEvents();
-
- // Let the derived class process other events
- ProcessEvents();
-}
-
-
-////////////////////////////////////////////////////////////
-/// Check if there's an active context on the current thread
-////////////////////////////////////////////////////////////
-bool WindowImpl::IsContextActive()
-{
- return WindowImplType::IsContextActive();
-}
-
-
-////////////////////////////////////////////////////////////
-/// Send an event to listeners
-////////////////////////////////////////////////////////////
-void WindowImpl::SendEvent(const Event& EventToSend)
-{
- for (std::set<WindowListener*>::iterator i = myListeners.begin(); i != myListeners.end(); ++i)
- {
- (*i)->OnEvent(EventToSend);
- }
-}
-
-
-////////////////////////////////////////////////////////////
-/// Evaluate a pixel format configuration.
-/// This functions can be used by implementations that have
-/// several valid formats and want to get the best one
-////////////////////////////////////////////////////////////
-int WindowImpl::EvaluateConfig(const VideoMode& Mode, const WindowSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing)
-{
- return abs(static_cast<int>(Mode.BitsPerPixel - ColorBits)) +
- abs(static_cast<int>(Settings.DepthBits - DepthBits)) +
- abs(static_cast<int>(Settings.StencilBits - StencilBits)) +
- abs(static_cast<int>(Settings.AntialiasingLevel - Antialiasing));
-}
-
-
-////////////////////////////////////////////////////////////
-/// Read the joysticks state and generate the appropriate events
-////////////////////////////////////////////////////////////
-void WindowImpl::ProcessJoystickEvents()
-{
- for (unsigned int i = 0; i < JoysticksCount; ++i)
- {
- // Copy the previous state of the joystick and get the new one
- JoystickState PreviousState = myJoyStates[i];
- myJoyStates[i] = myJoysticks[i].UpdateState();
-
- // Axis
- for (unsigned int j = 0; j < myJoysticks[i].GetAxesCount(); ++j)
- {
- float PrevPos = PreviousState.Axis[j];
- float CurrPos = myJoyStates[i].Axis[j];
- if (fabs(CurrPos - PrevPos) >= myJoyThreshold)
- {
- Event Event;
- Event.Type = Event::JoyMoved;
- Event.JoyMove.JoystickId = i;
- Event.JoyMove.Axis = static_cast<Joy::Axis>(j);
- Event.JoyMove.Position = CurrPos;
- SendEvent(Event);
- }
- }
-
- // Buttons
- for (unsigned int j = 0; j < myJoysticks[i].GetButtonsCount(); ++j)
- {
- bool PrevPressed = PreviousState.Buttons[j];
- bool CurrPressed = myJoyStates[i].Buttons[j];
-
- if ((!PrevPressed && CurrPressed) || (PrevPressed && !CurrPressed))
- {
- Event Event;
- Event.Type = CurrPressed ? Event::JoyButtonPressed : Event::JoyButtonReleased;
- Event.JoyButton.JoystickId = i;
- Event.JoyButton.Button = j;
- SendEvent(Event);
- }
- }
- }
-}
-
-
-} // namespace priv
-
-} // namespace sf
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2009 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 <SFML/Window/WindowImpl.hpp>
+#include <SFML/Window/Event.hpp>
+#include <SFML/Window/WindowListener.hpp>
+#include <algorithm>
+#include <cmath>
+
+#if defined(SFML_SYSTEM_WINDOWS)
+
+ #include <SFML/Window/Win32/WindowImplWin32.hpp>
+ typedef sf::priv::WindowImplWin32 WindowImplType;
+
+#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
+
+ #include <SFML/Window/Linux/WindowImplX11.hpp>
+ typedef sf::priv::WindowImplX11 WindowImplType;
+
+#elif defined(SFML_SYSTEM_MACOS)
+
+ #include <SFML/Window/Cocoa/WindowImplCocoa.hpp>
+ typedef sf::priv::WindowImplCocoa WindowImplType;
+
+#endif
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// Create a new window depending on the current OS
+////////////////////////////////////////////////////////////
+WindowImpl* WindowImpl::New()
+{
+ return new WindowImplType();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Create a new window depending on the current OS
+////////////////////////////////////////////////////////////
+WindowImpl* WindowImpl::New(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params)
+{
+ return new WindowImplType(Mode, Title, WindowStyle, Params);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Create a new window depending on the current OS
+////////////////////////////////////////////////////////////
+WindowImpl* WindowImpl::New(WindowHandle Handle, WindowSettings& Params)
+{
+ return new WindowImplType(Handle, Params);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+WindowImpl::WindowImpl() :
+myWidth (0),
+myHeight (0),
+myJoyThreshold(0.1f)
+{
+}
+
+
+////////////////////////////////////////////////////////////
+/// Destructor
+////////////////////////////////////////////////////////////
+WindowImpl::~WindowImpl()
+{
+ // Nothing to do
+}
+
+
+////////////////////////////////////////////////////////////
+/// Add a listener to the window
+////////////////////////////////////////////////////////////
+void WindowImpl::AddListener(WindowListener* Listener)
+{
+ if (Listener)
+ myListeners.insert(Listener);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Remove a listener from the window
+////////////////////////////////////////////////////////////
+void WindowImpl::RemoveListener(WindowListener* Listener)
+{
+ myListeners.erase(Listener);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Initialize window's states that can't be done at construction
+////////////////////////////////////////////////////////////
+void WindowImpl::Initialize()
+{
+ // Initialize the joysticks
+ for (unsigned int i = 0; i < JoysticksCount; ++i)
+ {
+ myJoysticks[i].Initialize(i);
+ myJoyStates[i] = myJoysticks[i].UpdateState();
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the client width of the window
+////////////////////////////////////////////////////////////
+unsigned int WindowImpl::GetWidth() const
+{
+ return myWidth;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the client height of the window
+////////////////////////////////////////////////////////////
+unsigned int WindowImpl::GetHeight() const
+{
+ return myHeight;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Change the joystick threshold, ie. the value below which
+/// no move event will be generated
+////////////////////////////////////////////////////////////
+void WindowImpl::SetJoystickThreshold(float Threshold)
+{
+ myJoyThreshold = Threshold;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Process incoming events from operating system
+////////////////////////////////////////////////////////////
+void WindowImpl::DoEvents()
+{
+ // Read the joysticks state and generate the appropriate events
+ ProcessJoystickEvents();
+
+ // Let the derived class process other events
+ ProcessEvents();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Check if there's an active context on the current thread
+////////////////////////////////////////////////////////////
+bool WindowImpl::IsContextActive()
+{
+ return WindowImplType::IsContextActive();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send an event to listeners
+////////////////////////////////////////////////////////////
+void WindowImpl::SendEvent(const Event& EventToSend)
+{
+ for (std::set<WindowListener*>::iterator i = myListeners.begin(); i != myListeners.end(); ++i)
+ {
+ (*i)->OnEvent(EventToSend);
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Evaluate a pixel format configuration.
+/// This functions can be used by implementations that have
+/// several valid formats and want to get the best one
+////////////////////////////////////////////////////////////
+int WindowImpl::EvaluateConfig(const VideoMode& Mode, const WindowSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing)
+{
+ return abs(static_cast<int>(Mode.BitsPerPixel - ColorBits)) +
+ abs(static_cast<int>(Settings.DepthBits - DepthBits)) +
+ abs(static_cast<int>(Settings.StencilBits - StencilBits)) +
+ abs(static_cast<int>(Settings.AntialiasingLevel - Antialiasing));
+}
+
+
+////////////////////////////////////////////////////////////
+/// Read the joysticks state and generate the appropriate events
+////////////////////////////////////////////////////////////
+void WindowImpl::ProcessJoystickEvents()
+{
+ for (unsigned int i = 0; i < JoysticksCount; ++i)
+ {
+ // Copy the previous state of the joystick and get the new one
+ JoystickState PreviousState = myJoyStates[i];
+ myJoyStates[i] = myJoysticks[i].UpdateState();
+
+ // Axis
+ for (unsigned int j = 0; j < myJoysticks[i].GetAxesCount(); ++j)
+ {
+ float PrevPos = PreviousState.Axis[j];
+ float CurrPos = myJoyStates[i].Axis[j];
+ if (fabs(CurrPos - PrevPos) >= myJoyThreshold)
+ {
+ Event Event;
+ Event.Type = Event::JoyMoved;
+ Event.JoyMove.JoystickId = i;
+ Event.JoyMove.Axis = static_cast<Joy::Axis>(j);
+ Event.JoyMove.Position = CurrPos;
+ SendEvent(Event);
+ }
+ }
+
+ // Buttons
+ for (unsigned int j = 0; j < myJoysticks[i].GetButtonsCount(); ++j)
+ {
+ bool PrevPressed = PreviousState.Buttons[j];
+ bool CurrPressed = myJoyStates[i].Buttons[j];
+
+ if ((!PrevPressed && CurrPressed) || (PrevPressed && !CurrPressed))
+ {
+ Event Event;
+ Event.Type = CurrPressed ? Event::JoyButtonPressed : Event::JoyButtonReleased;
+ Event.JoyButton.JoystickId = i;
+ Event.JoyButton.Button = j;
+ SendEvent(Event);
+ }
+ }
+ }
+}
+
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp
index e231ff3..15d29ec 100755
--- a/src/SFML/Window/WindowImpl.hpp
+++ b/src/SFML/Window/WindowImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2009 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.
@@ -109,6 +109,12 @@ public :
void RemoveListener(WindowListener* Listener);
////////////////////////////////////////////////////////////
+ /// Initialize window's states that can't be done at construction
+ ///
+ ////////////////////////////////////////////////////////////
+ void Initialize();
+
+ ////////////////////////////////////////////////////////////
/// Get the client width of the window
///
/// \return Width of the window in pixels