Fixed issue with shared OpenGL context not being activated.

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1183 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
ceylo 2009-07-21 16:56:52 +00:00
parent a430319c43
commit e40eb2e64d
6 changed files with 234 additions and 249 deletions

View File

@ -30,8 +30,6 @@
#import <Cocoa/Cocoa.h>
#define SharedAppController [AppController sharedController]
// Fade operations
enum {
FillScreen,

View File

@ -33,9 +33,6 @@
#import <iostream>
// AppController singleton object
static AppController *shared = nil;
/* setAppleMenu disappeared from the headers in 10.4 */
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
@ -83,6 +80,11 @@ static AppController *shared = nil;
// Make the app autorelease pool
myMainPool = [[NSAutoreleasePool alloc] init];
if (!myMainPool) {
[self release];
throw std::bad_alloc();
}
// Don't go on if the user handles the app
if (![NSApp isRunning])
{
@ -96,7 +98,10 @@ static AppController *shared = nil;
}
// Make the app
[NSApplication sharedApplication];
if (![NSApplication sharedApplication]) {
[self release];
throw std::bad_alloc();
}
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
// I want to go back to the desktop mode
@ -134,7 +139,7 @@ static AppController *shared = nil;
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[myFullscreenWrapper release];
[myMainPool release];
[super dealloc];
}
@ -144,9 +149,8 @@ static AppController *shared = nil;
////////////////////////////////////////////////////////////
+ (AppController *)sharedController
{
if (nil == shared)
shared = [[AppController alloc] init];
// AppController singleton object
static AppController *shared = [[AppController alloc] init];
return shared;
}
@ -216,10 +220,6 @@ static AppController *shared = nil;
{
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];
}
////////////////////////////////////////////////////////////
@ -266,10 +266,10 @@ static AppController *shared = nil;
keyEquivalent:@"h"];
// + 'Hide other' menu item
menuItem = reinterpret_cast <NSMenuItem *> ([appleMenu addItemWithTitle:@"Hide Others"
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"]);
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];
// + 'Show all' menu item
[appleMenu addItemWithTitle:@"Show All"

View File

@ -34,7 +34,7 @@
////////////////////////////////////////////////////////////
@interface GLContext : NSOpenGLContext
{
GLContext *mySharedContext;
}
////////////////////////////////////////////////////////////
@ -94,27 +94,13 @@
@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;
NSWindow *myWindow;
GLView *myView;
sf::VideoMode myFullscreenMode;
bool myIsFullscreen;

View File

@ -29,7 +29,6 @@
#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>
@ -39,26 +38,21 @@
////////////////////////////////////////////////////////////
@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];
}
sf::WindowSettings params;
static GLContext *sharedCtx = [[GLContext alloc] initWithAttributes:params sharedContext:nil];
return sharedCtx;
}
- (void)dealloc
{
[mySharedContext release];
[[GLContext sharedContext] release];
[super dealloc];
}
@ -66,7 +60,7 @@ static GLContext *sharedCtx = nil;
/// Make a new OpenGL context according to the @attribs settings
/// and the shared context @context
////////////////////////////////////////////////////////////
- (id)initWithAttributes:(sf::WindowSettings&)attribs sharedContext:(GLContext *)context
- (id)initWithAttributes:(sf::WindowSettings&)attribs sharedContext:(GLContext *)sharedContext
{
// Note about antialiasing and other context attributes :
// OpenGL context sharing does not allow the shared contexts to use different attributes.
@ -94,15 +88,15 @@ static GLContext *sharedCtx = nil;
// windowed context (even fullscreen mode uses a window)
ctxtAttribs[idx++] = NSOpenGLPFAWindow;
// Color size ; usually 32 bits per pixel
// Color buffer bits ; usually 32 bits per pixel
ctxtAttribs[idx++] = NSOpenGLPFAColorSize;
ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) sf::VideoMode::GetDesktopMode().BitsPerPixel;
// Z-buffer size
// Depth buffer size
ctxtAttribs[idx++] = NSOpenGLPFADepthSize;
ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) attribs.DepthBits;
// Stencil bits (I don't really know what's that...)
// Stencil buffer bits
ctxtAttribs[idx++] = NSOpenGLPFAStencilSize;
ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) attribs.StencilBits;
@ -110,9 +104,7 @@ static GLContext *sharedCtx = nil;
if (myPixelFormat) {
self = [super initWithFormat:myPixelFormat
shareContext:context];
mySharedContext = [context retain];
shareContext:[sharedContext retain]];
// Get the effective properties from our OpenGL context
GLint tmpDepthSize = 0, tmpStencilBits = 0, tmpAntialiasingLevel = 0;
@ -172,7 +164,13 @@ static GLContext *sharedCtx = nil;
[self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
// make the OpenGL context
myGLContext = [[GLContext alloc] initWithAttributes:settings sharedContext:sharedCtx];
myGLContext = [[GLContext alloc] initWithAttributes:settings
sharedContext:[GLContext sharedContext]];
if (!myGLContext) {
[self release];
return nil;
}
// We need to update the OpenGL view when it's resized
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
@ -417,10 +415,10 @@ static GLContext *sharedCtx = nil;
////////////////////////////////////////////////////////////
/// Cocoa window implementation to let fullscreen windows
/// Cocoa window category to let fullscreen windows
/// catch key events
////////////////////////////////////////////////////////////
@implementation GLWindow
@implementation NSWindow (GLWindow)
- (BOOL)canBecomeKeyWindow
{
@ -501,7 +499,7 @@ static GLContext *sharedCtx = nil;
if (self)
{
if (window) {
myWindow = (GLWindow *)[window retain];
myWindow = [window retain];
} else {
assert(title != nil);
@ -563,7 +561,7 @@ static GLContext *sharedCtx = nil;
// 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
myWindow = [[NSWindow alloc] initWithContentRect:frame
styleMask:mask
backing:NSBackingStoreBuffered
defer:NO];
@ -646,7 +644,7 @@ static GLContext *sharedCtx = nil;
////////////////////////////////////////////////////////////
- (void)dealloc
{
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
// Remove the notification observer
[[NSNotificationCenter defaultCenter] removeObserver:self];
@ -654,10 +652,13 @@ static GLContext *sharedCtx = nil;
[self show:false];
// Release the window and view
[myView removeFromSuperviewWithoutNeedingDisplay];
[myView release];
[myWindow release];
[super dealloc];
[localPool release];
}
@ -758,7 +759,7 @@ static GLContext *sharedCtx = nil;
// Wanna open the closed window
if (myIsFullscreen) {
[SharedAppController setFullscreenWindow:self mode:&myFullscreenMode];
[[AppController sharedController] setFullscreenWindow:self mode:&myFullscreenMode];
} else {
// Show the window
[myWindow makeKeyAndOrderFront:nil];
@ -767,7 +768,7 @@ static GLContext *sharedCtx = nil;
// Wanna close the opened window
if (myIsFullscreen) {
[SharedAppController setFullscreenWindow:nil mode:NULL];
[[AppController sharedController] setFullscreenWindow:nil mode:NULL];
} else {
// Close the window
[myWindow close];
@ -849,7 +850,7 @@ static GLContext *sharedCtx = nil;
{
NSWindow *sender = [notification object];
if (!([sender styleMask] & NSTitledWindowMask))
if (myIsFullscreen)
[sender center];
}

View File

@ -33,8 +33,10 @@
#include <string>
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
@class WindowWrapper;
typedef WindowWrapper* WindowWrapperRef;
#else
typedef void* WindowWrapperRef;
#endif
namespace sf
@ -190,13 +192,7 @@ private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
#ifdef __OBJC__
WindowWrapper *myWrapper;
#else
void *myWrapper;
#endif
WindowWrapperRef myWrapper;
bool myUseKeyRepeat;
bool myMouseIn;
float myWheelStatus;

View File

@ -31,9 +31,6 @@
#import <SFML/Window/Cocoa/GLKit.h>
#import <SFML/Window/WindowStyle.hpp>
#import <SFML/System.hpp>
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
#import <CoreFoundation/CoreFoundation.h>
#import <iostream>
@ -54,16 +51,16 @@ __done = 1;\
////////////////////////////////////////////////////////////
/// Private function declarations
////////////////////////////////////////////////////////////
static Key::Code KeyForVirtualCode(unsigned short vCode);
static Key::Code KeyForUnicode(unsigned short uniCode);
static bool IsTextEvent(NSEvent *event);
namespace {
Key::Code KeyForVirtualCode(unsigned short vCode);
Key::Code KeyForUnicode(unsigned short uniCode);
} // anonymous namespace
////////////////////////////////////////////////////////////
/// Default constructor
/// (creates a dummy window to provide a valid OpenGL context)
////////////////////////////////////////////////////////////
static WindowImplCocoa *globalWin = NULL;
WindowImplCocoa::WindowImplCocoa() :
myWrapper(nil),
myUseKeyRepeat(false),
@ -133,7 +130,8 @@ myWheelStatus(0.0f)
{
// Create a new window with given size, title and style
// First we define some objects used for our window
NSString *title = [NSString stringWithUTF8String:(Title.c_str()) ? (Title.c_str()) : ""];
NSString *title = [NSString stringWithCString:(Title.c_str()) ? (Title.c_str()) : ""
encoding:NSASCIIStringEncoding];
// We create the window
myWrapper = [[WindowWrapper alloc] initWithSettings:params
@ -228,18 +226,20 @@ void WindowImplCocoa::HandleKeyDown(void *eventRef)
// 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)
// (as NSUTF32StringEncoding is only being defined in Mac OS X 10.5 and later)
if (!CFStringGetCString ((CFStringRef)[event characters],
(char *)utf32Characters,
sizeof(utf32Characters),
kCFStringEncodingUTF32))
{
const char *utf8Char = NULL;
if ([[event characters] lengthOfBytesUsingEncoding:NSUTF8StringEncoding])
utf8Char = [[event characters] UTF8String];
char asciiChar[3] = {0};
if ([[event characters] lengthOfBytesUsingEncoding:NSASCIIStringEncoding])
[[event characters] getCString:asciiChar
maxLength:3
encoding:NSASCIIStringEncoding];
std::cerr << "Error while converting character to UTF32 : "
<< ((utf8Char) ? utf8Char : "(undefined)") << std::endl;
std::cerr << "Error while converting character to UTF32 : \""
<< asciiChar << "\"" << std::endl;
}
else
{
@ -359,7 +359,9 @@ void WindowImplCocoa::HandleMouseDown(void *eventRef)
{
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
NSPoint loc = {0, 0};
// Get mouse position relative to the window
NSPoint loc = [myWrapper mouseLocation];
unsigned mods = [event modifierFlags];
switch ([event type]) {
@ -373,9 +375,6 @@ void WindowImplCocoa::HandleMouseDown(void *eventRef)
sfEvent.MouseButton.Button = Mouse::Left;
}
// Get mouse position relative to the window
loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
@ -387,9 +386,6 @@ void WindowImplCocoa::HandleMouseDown(void *eventRef)
sfEvent.Type = Event::MouseButtonPressed;
sfEvent.MouseButton.Button = Mouse::Right;
// Get mouse position relative to the window
loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
@ -410,7 +406,9 @@ void WindowImplCocoa::HandleMouseUp(void *eventRef)
{
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
NSPoint loc = {0, 0};
// Get mouse position relative to the window
NSPoint loc = [myWrapper mouseLocation];
unsigned mods = [event modifierFlags];
switch ([event type]) {
@ -424,9 +422,6 @@ void WindowImplCocoa::HandleMouseUp(void *eventRef)
sfEvent.MouseButton.Button = Mouse::Left;
}
// Get mouse position relative to the window
loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
@ -438,9 +433,6 @@ void WindowImplCocoa::HandleMouseUp(void *eventRef)
sfEvent.Type = Event::MouseButtonReleased;
sfEvent.MouseButton.Button = Mouse::Right;
// Get mouse position relative to the window
loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
@ -460,9 +452,7 @@ void WindowImplCocoa::HandleMouseUp(void *eventRef)
void WindowImplCocoa::HandleMouseMove(void *eventRef)
{
Event sfEvent;
NSPoint loc = {0, 0};
loc = [myWrapper mouseLocation];
NSPoint loc = [myWrapper mouseLocation];
sfEvent.Type = Event::MouseMoved;
sfEvent.MouseMove.X = (int) loc.x;
@ -547,7 +537,7 @@ void WindowImplCocoa::Display()
void WindowImplCocoa::ProcessEvents()
{
// Forward event handling call to the application controller
[SharedAppController processEvents];
[[AppController sharedController] processEvents];
}
@ -557,7 +547,18 @@ void WindowImplCocoa::ProcessEvents()
void WindowImplCocoa::SetActive(bool Active) const
{
// Forward the call to the window
if (myWrapper)
[myWrapper setActive:Active];
else {
// Or directly activate the shared OpenGL context if we're not using a window
if (Active) {
if ([NSOpenGLContext currentContext] != [GLContext sharedContext])
[[GLContext sharedContext] makeCurrentContext];
} else {
if ([NSOpenGLContext currentContext] == [GLContext sharedContext])
[NSOpenGLContext clearCurrentContext];
}
}
}
@ -656,10 +657,11 @@ void WindowImplCocoa::SetIcon(unsigned int Width, unsigned int Height, const Uin
}
namespace {
////////////////////////////////////////////////////////////
/// Return the SFML key corresponding to a key code
////////////////////////////////////////////////////////////
static Key::Code KeyForVirtualCode(unsigned short vCode)
Key::Code KeyForVirtualCode(unsigned short vCode)
{
static struct {
unsigned short code;
@ -732,7 +734,7 @@ static Key::Code KeyForVirtualCode(unsigned short vCode)
////////////////////////////////////////////////////////////
/// Return the SFML key corresponding to a unicode code
////////////////////////////////////////////////////////////
static Key::Code KeyForUnicode(unsigned short uniCode)
Key::Code KeyForUnicode(unsigned short uniCode)
{
// TODO: find a better way to get the language independant key
static struct {
@ -815,6 +817,8 @@ static Key::Code KeyForUnicode(unsigned short uniCode)
return result;
}
} // anonymous namespace
} // namespace priv