Synchronized with trunk
git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1068 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
commit
b194b9969a
81 changed files with 4492 additions and 2174 deletions
|
@ -175,6 +175,17 @@ void Sound::SetPosition(const Vector3f& Position)
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Make the sound's position relative to the listener's
|
||||
/// position, or absolute.
|
||||
/// The default value is false (absolute)
|
||||
////////////////////////////////////////////////////////////
|
||||
void Sound::SetRelativeToListener(bool Relative)
|
||||
{
|
||||
ALCheck(alSourcei(mySource, AL_SOURCE_RELATIVE, Relative));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Set the minimum distance - closer than this distance,
|
||||
/// the listener will hear the sound at its maximum volume.
|
||||
|
@ -263,6 +274,19 @@ Vector3f Sound::GetPosition() const
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Tell if the sound's position is relative to the listener's
|
||||
/// position, or if it's absolute
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Sound::IsRelativeToListener() const
|
||||
{
|
||||
ALint Relative;
|
||||
ALCheck(alGetSourcei(mySource, AL_SOURCE_RELATIVE, &Relative));
|
||||
|
||||
return Relative != 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get the minimum distance
|
||||
////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -2037,7 +2037,6 @@ void dct_iv_slow(float *buffer, int n)
|
|||
//acc += x[j] * cos(M_PI / n * (i + 0.5) * (j + 0.5));
|
||||
buffer[i] = acc;
|
||||
}
|
||||
free(x);
|
||||
}
|
||||
|
||||
void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)
|
||||
|
@ -3504,8 +3503,8 @@ static int start_decoder(vorb *f)
|
|||
#else
|
||||
for (j=0; j < (int) c->lookup_values; ++j)
|
||||
c->multiplicands[j] = mults[j] * c->delta_value + c->minimum_value;
|
||||
setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
|
||||
#endif
|
||||
setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
|
||||
}
|
||||
skip:;
|
||||
|
||||
|
@ -3812,6 +3811,7 @@ static void vorbis_deinit(stb_vorbis *p)
|
|||
setup_free(p, p->B[i]);
|
||||
setup_free(p, p->C[i]);
|
||||
setup_free(p, p->window[i]);
|
||||
setup_free(p, p->bit_reverse[i]);
|
||||
}
|
||||
#ifndef STB_VORBIS_NO_STDIO
|
||||
if (p->close_on_free) fclose(p->f);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 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.
|
||||
|
|
|
@ -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;
|
||||
- (void)doFadeOperation:(int)operation time:(float)time sync:(bool)sync;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the desktop video mode (made at the instance initialization)
|
||||
////////////////////////////////////////////////////////////
|
||||
- (const sf::VideoMode&)desktopMode;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// check that ptr is valid, otherwise print msg in
|
||||
/// std::cerr and throw std::bad_alloc.
|
||||
/// Must be used to check alloc results
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
T *massert(T *ptr);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
@ -61,160 +60,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 +183,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 +243,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 +264,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 +278,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 +299,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 +311,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 +320,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 +332,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,127 +346,109 @@ 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 (myFullscreenWrapper && aWrapper == nil)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// Fade to black screen
|
||||
[self doFadeOperation:FillScreen time:0.2f sync:true];
|
||||
|
||||
// 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];
|
||||
|
||||
// Fade to normal screen
|
||||
[self doFadeOperation:CleanScreen time:0.5f sync:true];
|
||||
|
||||
// Release the saved window wrapper
|
||||
[myFullscreenWrapper release], 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 (myFullscreenWrapper == nil && 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 (idx < sz) {
|
||||
windows->erase(windows->begin() + idx);
|
||||
}
|
||||
// Fade to a black screen
|
||||
[self doFadeOperation:FillScreen time:0.5f sync:true];
|
||||
|
||||
// Hide to the main menu bar
|
||||
[NSMenu setMenuBarVisible:NO];
|
||||
|
||||
// Switch to the wished display mode
|
||||
CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode);
|
||||
|
||||
// Open and center the window
|
||||
[[aWrapper window] makeKeyAndOrderFront:nil];
|
||||
[[aWrapper window] center];
|
||||
|
||||
// Fade to normal screen
|
||||
[self doFadeOperation:CleanScreen time:0.2f sync:false];
|
||||
|
||||
// Save the fullscreen wrapper
|
||||
myFullscreenWrapper = [aWrapper retain];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Inconcistency error for arguments given to -[AppController setFullscreenWindow:mode:]" << std::endl;
|
||||
}
|
||||
|
||||
return isUsing;
|
||||
}
|
||||
|
||||
|
||||
|
@ -517,11 +460,10 @@ static AppController *shared = nil;
|
|||
/// 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 +481,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 +491,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 +510,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 +525,14 @@ static AppController *shared = nil;
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the desktop video mode (made at the instance initialization)
|
||||
////////////////////////////////////////////////////////////
|
||||
- (const sf::VideoMode&)desktopMode
|
||||
{
|
||||
return myDesktopMode;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
template <typename T>
|
||||
T *massert(T *ptr)
|
||||
{
|
||||
if (NULL == ptr) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
|
216
src/SFML/Window/Cocoa/GLKit.h
Normal file
216
src/SFML/Window/Cocoa/GLKit.h
Normal file
|
@ -0,0 +1,216 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Finish the window setup (without knowing whether it's a imported
|
||||
/// window)
|
||||
////////////////////////////////////////////////////////////
|
||||
/* - (void)setupGLViewAndWindow; */
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// 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
|
||||
|
1024
src/SFML/Window/Cocoa/GLKit.mm
Normal file
1024
src/SFML/Window/Cocoa/GLKit.mm
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,73 +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 <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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -88,25 +91,23 @@ 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 :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -182,38 +183,19 @@ 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;
|
||||
#ifdef __OBJC__
|
||||
WindowWrapper *myWrapper;
|
||||
#else
|
||||
void *myWrapper;
|
||||
#endif
|
||||
|
||||
bool useKeyRepeat;
|
||||
bool mouseIn;
|
||||
float wheelStatus;
|
||||
|
||||
bool fullscreen;
|
||||
VideoMode fullscreenMode;
|
||||
VideoMode desktopMode;
|
||||
bool myUseKeyRepeat;
|
||||
bool myMouseIn;
|
||||
float myWheelStatus;
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -61,15 +61,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +125,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);
|
||||
|
|
|
@ -44,6 +44,16 @@ namespace
|
|||
unsigned long EventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
||||
PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask |
|
||||
EnterWindowMask | LeaveWindowMask;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -255,30 +265,53 @@ WindowImplX11::~WindowImplX11()
|
|||
////////////////////////////////////////////////////////////
|
||||
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(myDisplay, &Event, &WindowImplX11::CheckEvent, reinterpret_cast<XPointer>(myWindow)))
|
||||
while (XCheckIfEvent(myDisplay, &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(myDisplay))
|
||||
if (Event.xkey.keycode < 256)
|
||||
{
|
||||
XEvent NextEvent;
|
||||
XPeekEvent(myDisplay, &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(myDisplay, Keys);
|
||||
if (Keys[Event.xkey.keycode >> 3] & (1 << (Event.xkey.keycode % 8)))
|
||||
{
|
||||
if (!myKeyRepeat)
|
||||
XNextEvent(myDisplay, &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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -467,6 +500,9 @@ void WindowImplX11::SwitchToFullscreen(const VideoMode& Mode)
|
|||
////////////////////////////////////////////////////////////
|
||||
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(myDisplay, "WM_DELETE_WINDOW", false);
|
||||
XSetWMProtocols(myDisplay, myWindow, &myAtomClose, 1);
|
||||
|
@ -551,17 +587,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
|
||||
////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -155,18 +155,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
|
||||
///
|
||||
|
@ -188,16 +176,17 @@ private :
|
|||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
DisplayRef myDisplayRef; ///< Connection to the X server
|
||||
::Window myWindow; ///< X11 structure defining our window
|
||||
::Display* myDisplay; ///< Pointer to the display
|
||||
int myScreen; ///< Screen identifier
|
||||
bool myIsExternal; ///< Tell whether the window has been created externally or by SFML
|
||||
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 ?
|
||||
DisplayRef myDisplayRef; ///< Connection to the X server
|
||||
::Window myWindow; ///< X11 structure defining our window
|
||||
::Display* myDisplay; ///< Pointer to the display
|
||||
int myScreen; ///< Screen identifier
|
||||
bool myIsExternal; ///< Tell whether the window has been created externally or by SFML
|
||||
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
|
||||
|
|
|
@ -32,11 +32,19 @@
|
|||
#include <iostream>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Private data
|
||||
////////////////////////////////////////////////////////////
|
||||
namespace
|
||||
{
|
||||
const sf::Window* FullscreenWindow = NULL;
|
||||
}
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Window::Window() :
|
||||
myWindow (NULL),
|
||||
|
@ -97,11 +105,30 @@ Window::~Window()
|
|||
////////////////////////////////////////////////////////////
|
||||
void Window::Create(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, const ContextSettings& Settings)
|
||||
{
|
||||
// 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
|
||||
|
@ -131,7 +158,7 @@ void Window::Create(VideoMode Mode, const std::string& Title, unsigned long Wind
|
|||
void Window::Create(WindowHandle Handle, const ContextSettings& Settings)
|
||||
{
|
||||
// Recreate the window implementation
|
||||
delete myWindow;
|
||||
Close();
|
||||
myWindow = priv::WindowImpl::New(Handle);
|
||||
|
||||
// Make sure another context is bound, so that:
|
||||
|
@ -170,6 +197,10 @@ void Window::Close()
|
|||
delete myWindow;
|
||||
myWindow = NULL;
|
||||
}
|
||||
|
||||
// Update the fullscreen window
|
||||
if (this == FullscreenWindow)
|
||||
FullscreenWindow = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue