Back to index

libsfml  1.6+dfsg2
GLKit.mm
Go to the documentation of this file.
00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #import <SFML/Window/Cocoa/GLKit.h>
00029 #import <SFML/Window/Cocoa/AppController.h>
00030 #import <SFML/Window/VideoMode.hpp>
00031 #import <SFML/Window/WindowStyle.hpp>
00032 #import <OpenGL/gl.h>
00033 #import <iostream>
00034 
00035 
00036 @interface sfPrivWindow (Protected)
00037 
00041 - (void)setWindow:(NSWindow *)aWindow;
00042 
00046 - (void)putOpenGLView:(sfPrivGLView *)aView;
00047 
00051 - (void)setView:(sfPrivGLView *)aView;
00052 
00053 @end
00054 
00055 @interface sfPrivOwnedWindow (Private)
00056 
00060 - (void)setFullscreen:(BOOL)aFlag;
00061 
00062 @end
00063 
00064 
00068 @implementation sfPrivGLContext
00069 
00070 
00074 + (id)sharedContext
00075 {
00076        // Make a new context with the default parameters
00077        sf::WindowSettings params;
00078        sf::VideoMode m;
00079        static sfPrivGLContext *sharedCtx = [[sfPrivGLContext alloc] initWithAttributes:params
00080                                                                                                                                         mode:m
00081                                                                                                                          sharedContext:nil];
00082        return sharedCtx;
00083 }
00084 
00085 - (void)dealloc
00086 {
00087        [[sfPrivGLContext sharedContext] release];
00088        [super dealloc];
00089 }
00090 
00095 - (id)initWithAttributes:(sf::WindowSettings&)attribs mode:(const sf::VideoMode&)mode sharedContext:(sfPrivGLContext *)sharedContext
00096 {
00097        // Note about antialiasing and other context attributes :
00098        // OpenGL context sharing does not allow the shared contexts to use different attributes.
00099        // The point is that the default shared global OpenGL context uses default parameters.
00100        // That means that all the other context *should* use the same paramaters.
00101        // Fortunately some values parameters for some parameters are compatible, but some are not
00102        // among which : the antialising level.
00103        //
00104        // I've no way to fix this for now.
00105        
00106        if (attribs.AntialiasingLevel) {
00107               NSLog(@"Warning: antialiasing settings are inhibited on Mac OS X for technical reasons");
00108        }
00109        
00110        if (attribs.StencilBits != 8) {
00111               NSLog(@"Warning: stencil bits settings are inhibited on Mac OS X for technical reasons");
00112        }
00113        
00114        NSOpenGLPixelFormat *myPixelFormat = nil;
00115        unsigned idx = 0;
00116        
00117        // Attributes list
00118        NSOpenGLPixelFormatAttribute ctxtAttribs[15] = {(NSOpenGLPixelFormatAttribute) 0};
00119        
00120        // Accelerated, double buffered
00121        ctxtAttribs[idx++] = NSOpenGLPFAClosestPolicy;
00122        ctxtAttribs[idx++] = NSOpenGLPFADoubleBuffer;
00123        ctxtAttribs[idx++] = NSOpenGLPFAAccelerated;
00124        
00125        // Force use of first screen
00126        //ctxtAttribs[idx++] = NSOpenGLPFAScreenMask;
00127        //ctxtAttribs[idx++] = CGDisplayIDToOpenGLDisplayMask([sfPrivAppController primaryScreen]);
00128        
00129        // windowed context (even fullscreen mode uses a window)
00130        ctxtAttribs[idx++] = NSOpenGLPFAWindow;
00131        
00132        // Color buffer bits ; usually 32 bits per pixel
00133        ctxtAttribs[idx++] = NSOpenGLPFAColorSize;
00134        
00135        // well.. whatever I put here, the color size is always 24 bits on my computer..
00136        ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) mode.BitsPerPixel;
00137        
00138        // Alpha buffer size
00139        // FIXME: I don't really remember whether I can safely use the user video mode settings
00140        // to set this attribute (because of the shared context attributes conflicts)
00141        if (mode.BitsPerPixel > 24) {
00142               ctxtAttribs[idx++] = NSOpenGLPFAAlphaSize;
00143               ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) 8;
00144        }
00145        
00146        // Depth buffer size
00147        ctxtAttribs[idx++] = NSOpenGLPFADepthSize;
00148        ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) attribs.DepthBits;
00149        
00150        // Stencil buffer bits
00151        // Note: even with "NSOpenGLPFAClosestPolicy" set, the NSOpenGLPFAStencilSize value must be an valid and exact one
00152        // I've been looking for possible diffferent default stencil bits values among different Apple computers
00153        // but I can't again get the website I found oneaday
00154        // (describing all the graphic cards used by Apple, the supported extensions, etc).
00155        ctxtAttribs[idx++] = NSOpenGLPFAStencilSize;
00156        ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) /* attribs.StencilBits */ 8;
00157        
00158        myPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:ctxtAttribs];
00159        
00160        if (myPixelFormat) {
00161               self = [super initWithFormat:myPixelFormat
00162                                           shareContext:[sharedContext retain]];
00163               
00164               // Get the effective properties from our OpenGL context
00165               GLint tmpDepthSize = 0, tmpStencilBits = 0, tmpAntialiasingLevel = 0;
00166               
00167               if (self) {
00168                      [myPixelFormat getValues:&tmpDepthSize
00169                                    forAttribute:NSOpenGLPFADepthSize
00170                             forVirtualScreen:[self currentVirtualScreen]];
00171                      
00172                      [myPixelFormat getValues:&tmpStencilBits
00173                                    forAttribute:NSOpenGLPFAStencilSize
00174                             forVirtualScreen:[self currentVirtualScreen]];
00175                      
00176                      [myPixelFormat getValues:&tmpAntialiasingLevel
00177                                    forAttribute:NSOpenGLPFASamples
00178                             forVirtualScreen:[self currentVirtualScreen]];
00179               }
00180               
00181               
00182               attribs.DepthBits = (unsigned) tmpDepthSize;
00183               attribs.StencilBits = (unsigned) tmpStencilBits;
00184               attribs.AntialiasingLevel = (unsigned) tmpAntialiasingLevel;
00185               
00186               [myPixelFormat release];
00187        } else {
00188               NSLog(@"NSOpenGLPixelFormat creation failed! (invalid video settings ?)");
00189        }
00190        
00191        return self;
00192 }
00193 
00194 @end
00195 
00196 
00200 @implementation sfPrivGLView
00201 
00208 - (id)initWithFrame:(NSRect)frame
00209                         mode:(const sf::VideoMode&)mode
00210                  settings:(sf::WindowSettings&)settings
00211 {
00212        // make the view
00213        self = [super initWithFrame:frame pixelFormat:nil];
00214        
00215        if (self)
00216        {
00217               // enabled auto-resizing
00218               [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
00219               
00220               // make the OpenGL context
00221               myGLContext = [[sfPrivGLContext alloc] initWithAttributes:settings
00222                                                                                                           mode:mode
00223                                                                                sharedContext:[sfPrivGLContext sharedContext]];
00224               
00225               if (!myGLContext) {
00226                      [self release];
00227                      return nil;
00228               }
00229               
00230               // We need to update the OpenGL view when it's resized
00231               NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
00232               [nc addObserver:self
00233                         selector:@selector(viewFrameDidChange:)
00234                                name:NSViewFrameDidChangeNotification
00235                              object:self];
00236        }
00237        
00238        return self;
00239 }
00240 
00241 
00245 - (void)dealloc
00246 {
00247        // Remove the observer and release the OpenGL context
00248        [[NSNotificationCenter defaultCenter] removeObserver:self];
00249        [myGLContext release];
00250        
00251        [super dealloc];
00252 }
00253 
00257 - (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate
00258 {
00259        myDelegate = aDelegate;
00260 }
00261 
00265 - (sf::priv::WindowImplCocoa *)delegate
00266 {
00267        return myDelegate;
00268 }
00269 
00270 
00274 - (void)finishInitialization
00275 {
00276        assert([self superview] != nil);
00277        assert(myGLContext != nil);
00278        
00279        // Attach the OpenGL context to our view
00280        [self clearGLContext];
00281        [self setOpenGLContext:myGLContext];
00282        [myGLContext setView:self];
00283        
00284        // Make our view the first responder
00285        [[self window] makeFirstResponder:self];
00286 }
00287 
00288 
00292 - (void)enableVerticalSync:(bool)flag
00293 {
00294        GLint enable = (flag) ? 1 : 0;
00295        [[self openGLContext] setValues:&enable forParameter:NSOpenGLCPSwapInterval];
00296 }
00297 
00298 
00302 - (void)setActive:(bool)flag
00303 {
00304        if (flag) {
00305               if ([NSOpenGLContext currentContext] != [self openGLContext])
00306                      [[self openGLContext] makeCurrentContext];
00307        } else {
00308               if ([NSOpenGLContext currentContext] == [self openGLContext])
00309                      [NSOpenGLContext clearCurrentContext];
00310        }
00311 }
00312 
00313 
00317 - (void)flushBuffer
00318 {
00319        [[self openGLContext] flushBuffer];
00320 }
00321 
00322 
00326 - (void)pushEvent:(sf::Event)sfEvent
00327 {
00328        assert(myDelegate != NULL);
00329        myDelegate->HandleNotifiedEvent(sfEvent);
00330 }
00331 
00332 
00336 - (void)viewFrameDidChange:(NSNotification *)notification
00337 {
00338        [self update];
00339        
00340        sf::Event ev;
00341        ev.Type = sf::Event::Resized;
00342        ev.Size.Width = (unsigned) [self frame].size.width;
00343        ev.Size.Height = (unsigned) [self frame].size.height;
00344        
00345        [self pushEvent:ev];
00346 }
00347 
00348 
00352 - (void)keyDown:(NSEvent *)theEvent
00353 {
00354        assert(myDelegate != NULL);
00355        
00356        if (sf::priv::WindowImplCocoa::IsTextEvent((void *)theEvent))
00357        {
00358               NSText *field = [[self window] fieldEditor:YES forObject:nil];
00359               [field interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
00360               [field setString:@""];
00361        }
00362        
00363        myDelegate->HandleKeyDown(theEvent);
00364 }
00365 
00366 
00370 - (void)keyUp:(NSEvent *)theEvent
00371 {
00372        assert(myDelegate != NULL);
00373        myDelegate->HandleKeyUp(theEvent);
00374 }
00375 
00376 
00380 - (void)flagsChanged:(NSEvent *)theEvent
00381 {
00382        assert(myDelegate != NULL);
00383        myDelegate->HandleModifierKey(theEvent);
00384 }
00385 
00386 
00390 - (void)scrollWheel:(NSEvent *)theEvent
00391 {
00392        assert(myDelegate != NULL);
00393        myDelegate->HandleMouseWheel(theEvent);
00394 }
00395 
00396 
00400 - (void)mouseDown:(NSEvent *)theEvent
00401 {
00402        assert(myDelegate != NULL);
00403        myDelegate->HandleMouseDown(theEvent);
00404 }
00405 
00406 
00410 - (void)rightMouseDown:(NSEvent *)theEvent
00411 {
00412        assert(myDelegate != NULL);
00413        myDelegate->HandleMouseDown(theEvent);
00414 }
00415 
00416 
00420 - (void)mouseUp:(NSEvent *)theEvent
00421 {
00422        assert(myDelegate != NULL);
00423        myDelegate->HandleMouseUp(theEvent);
00424 }
00425 
00426 
00430 - (void)rightMouseUp:(NSEvent *)theEvent
00431 {
00432        assert(myDelegate != NULL);
00433        myDelegate->HandleMouseUp(theEvent);
00434 }
00435 
00436 
00440 - (void)mouseMoved:(NSEvent *)theEvent
00441 {
00442        assert(myDelegate != NULL);
00443        myDelegate->HandleMouseMove(theEvent);
00444 }
00445 
00449 - (void)mouseDragged:(NSEvent *)theEvent
00450 {
00451        assert(myDelegate != NULL);
00452        myDelegate->HandleMouseMove(theEvent);
00453 }
00454 
00458 - (void)rightMouseDragged:(NSEvent *)theEvent
00459 {
00460        assert(myDelegate != NULL);
00461        myDelegate->HandleMouseMove(theEvent);
00462 }
00463 
00464 
00468 - (BOOL)acceptsFirstResponder
00469 {
00470        return YES;
00471 }
00472 
00473 
00477 - (BOOL)canBecomeKeyView
00478 {
00479        return YES;
00480 }
00481 
00482 @end
00483 
00484 
00489 @implementation NSWindow (GLWindow)
00490 
00491 - (BOOL)canBecomeKeyWindow
00492 {
00493        return YES;
00494 }
00495 
00496 - (BOOL)canBecomeMainWindow
00497 {
00498        return YES;
00499 }
00500 
00501 @end
00502 
00503 
00504 
00505 @implementation sfPrivWindow
00506 
00507 - (void)dealloc
00508 {
00509        NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
00510        // Remove the notification observer
00511        [[NSNotificationCenter defaultCenter] removeObserver:self];
00512        
00513        // Close the window
00514        [self show:false];
00515        
00516        // Release the window and view
00517        [[self view] removeFromSuperviewWithoutNeedingDisplay];
00518        
00519        [self setWindow:nil];
00520        [self setView:nil];
00521        [self setDelegate:nil];
00522        
00523        [super dealloc];
00524        [localPool release];
00525 }
00526 
00530 - (void)setWindow:(NSWindow *)aWindow
00531 {
00532        if (myWindow != aWindow)
00533        {
00534               NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
00535               
00536               // Drop the observers on the previously set window
00537               if ([self window]) {
00538                      [nc removeObserver:self 
00539                                             name:NSWindowDidBecomeMainNotification
00540                                           object:[self window]];
00541                      [nc removeObserver:self 
00542                                             name:NSWindowDidResignMainNotification
00543                                           object:[self window]];
00544                      [nc removeObserver:self 
00545                                             name:NSWindowWillCloseNotification
00546                                           object:[self window]];
00547               }
00548               
00549               [myWindow release];
00550               myWindow = [aWindow retain];
00551               
00552               // Set the new observers
00553               // We want to know when our window got the focus
00554               [nc addObserver:self
00555                         selector:@selector(windowDidBecomeMain:)
00556                                name:NSWindowDidBecomeMainNotification
00557                              object:[self window]];
00558               
00559               // We want to know when our window lost the focus
00560               [nc addObserver:self
00561                         selector:@selector(windowDidResignMain:)
00562                                name:NSWindowDidResignMainNotification
00563                              object:[self window]];
00564               
00565               // We want to know when the user closes the window
00566               [nc addObserver:self
00567                         selector:@selector(windowWillClose:)
00568                                name:NSWindowWillCloseNotification
00569                              object:[self window]];
00570               
00571        }
00572 }
00573 
00577 - (NSWindow *)window
00578 {
00579        return [[myWindow retain] autorelease];
00580 }
00581 
00582 
00586 - (void)putOpenGLView:(sfPrivGLView *)aView
00587 {
00588        [self setView:aView];
00589        
00590        // Finish setting up the view and window
00591        // Add the view to our window and tell it to the view
00592        [[[self window] contentView] addSubview:[self view]];
00593        [[self view] finishInitialization];
00594 }
00595 
00599 - (void)setView:(sfPrivGLView *)aView
00600 {
00601        if (myView != aView)
00602        {
00603               [myView release];
00604               myView = [aView retain];
00605        }
00606 }
00607 
00611 - (sfPrivGLView *)view
00612 {
00613        return [[myView retain] autorelease];
00614 }
00615 
00619 - (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate
00620 {
00621        [[self view] setDelegate:aDelegate];
00622 }
00623 
00627 - (sf::priv::WindowImplCocoa *)delegate
00628 {
00629        return [[self view] delegate];
00630 }
00631 
00635 - (void)setPosition:(NSPoint)pos
00636 {
00637        NSAssert([self window] != nil, @"expected valid window");
00638        
00639        // Flip Y and set window position
00640        pos.y = [[[self window] screen] frame].size.height - pos.y;
00641        [[self window] setFrameTopLeftPoint:pos];
00642 }
00643 
00647 - (void)setSize:(NSSize)size
00648 {
00649        NSAssert([self window] != nil, @"expected valid window");
00650        
00651        [[self window] setFrame:NSMakeRect([[self window] frame].origin.x,
00652                                                                   [[self window] frame].origin.y,
00653                                                                   size.width, size.height)
00654                                    display:YES];
00655 }
00656 
00660 - (NSPoint)mouseLocation
00661 {
00662        NSAssert([self view] != nil, @"expected valid window");
00663        
00664        NSPoint windowPoint = [[self window] convertScreenToBase:[NSEvent mouseLocation]];
00665        NSPoint viewPoint = [[self view] convertPoint:windowPoint fromView:[[[self window] contentView] superview]];
00666        
00667        viewPoint.y = [[self view] frame].size.height - viewPoint.y;
00668        return viewPoint;
00669 }
00670 
00674 - (BOOL)mouseInside
00675 {
00676        NSAssert([self window] != nil, @"expected valid window");
00677        NSAssert([self view] != nil, @"expected valid OpenGL view");
00678        
00679        BOOL flag = NO;
00680        
00681        if ([[self window] isVisible]) {
00682               NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
00683               NSPoint relativeToView = [[self view] convertPoint:relativeToWindow fromView:nil];
00684               
00685               if (NSPointInRect (relativeToView, [[self view] bounds]))
00686               {
00687                      flag = YES;
00688               }
00689        }
00690        
00691        return flag;
00692 }
00693 
00697 - (void)show:(bool)flag
00698 {
00699        NSAssert([self window] != nil, @"expected valid window");
00700        
00701        if (flag && ![[self window] isVisible]) {
00702               // Wanna open the closed window
00703               
00704               // Show the window
00705               [[self window] makeKeyAndOrderFront:nil];
00706        } else if (!flag && [[self window] isVisible]) {
00707               // Wanna close the opened window
00708               
00709               // Close the window
00710               [[self window] close];
00711        }      
00712 }
00713 
00714 
00718 - (void)enableVerticalSync:(bool)flag
00719 {
00720        NSAssert([self view] != nil, @"expected valid OpenGL view");
00721        [[self view] enableVerticalSync:flag];
00722 }
00723 
00727 - (void)setActive:(bool)flag
00728 {
00729        NSAssert([self view] != nil, @"expected valid OpenGL view");
00730        [[self view] setActive:flag];
00731 }
00732 
00736 - (void)flushBuffer
00737 {
00738        NSAssert([self view] != nil, @"expected valid OpenGL view");
00739        [[self view] flushBuffer];
00740 }
00741 
00745 - (void)windowDidBecomeMain:(NSNotification *)notification
00746 {
00747        sf::Event ev;
00748        ev.Type = sf::Event::GainedFocus;
00749        
00750        [[self view] pushEvent:ev];
00751 }
00752 
00753 
00757 - (void)windowDidResignMain:(NSNotification *)notification
00758 {
00759        sf::Event ev;
00760        ev.Type = sf::Event::LostFocus;
00761        
00762        [[self view] pushEvent:ev];
00763 }
00764 
00765 
00769 - (void)windowWillClose:(NSNotification *)notification
00770 {
00771        sf::Event ev;
00772        ev.Type = sf::Event::Closed;
00773        
00774        [[self view] pushEvent:ev];
00775 }
00776 
00777 
00778 @end
00779 
00780 
00781 @implementation sfPrivOwnedWindow
00782 
00783 - (id)initWithVideoMode:(sf::VideoMode&)aMode
00784                         settings:(sf::WindowSettings&)someSettings
00785                               style:(unsigned long)aStyle
00786                               title:(NSString *)aTitle
00787 {
00788        self = [super init];
00789        if (self)
00790        {
00791               if (aStyle & sf::Style::Fullscreen) {
00792                      [self setFullscreen:YES];
00793               }
00794               
00795               NSRect frame = NSMakeRect (0.0f, 0.0f, (float) aMode.Width, (float) aMode.Height);
00796               unsigned int mask = 0;
00797               
00798               if (aStyle & sf::Style::Fullscreen) {
00799                      // Check display mode and put new values in 'mode' if needed
00800                      boolean_t exact = true;
00801                      
00802                      CFDictionaryRef properties =
00803                      CGDisplayBestModeForParameters([sfPrivAppController primaryScreen],
00804                                                                          aMode.BitsPerPixel,
00805                                                                          aMode.Width,
00806                                                                          aMode.Height,
00807                                                                          &exact);
00808                      
00809                      if (!properties) {
00810                             std::cerr 
00811                             << "Unable to get a display mode with the given parameters" 
00812                             << std::endl;
00813                             
00814                             [self autorelease];
00815                             return nil;
00816                      }
00817                      
00818                      if (exact == false) {
00819                             CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties,
00820                                                                                                                        kCGDisplayWidth),
00821                                                          kCFNumberIntType, &aMode.Width);
00822                             
00823                             CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties,
00824                                                                                                                        kCGDisplayHeight),
00825                                                          kCFNumberIntType, &aMode.Height);
00826                             
00827                             CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties,
00828                                                                                                                        kCGDisplayBitsPerPixel),
00829                                                          kCFNumberIntType, &aMode.BitsPerPixel);
00830                             
00831                      }
00832               }
00833               
00834               // We grab options from WindowStyle and add them to our window mask
00835               if (aStyle & sf::Style::None || aStyle & sf::Style::Fullscreen) {
00836                      mask |= NSBorderlessWindowMask;
00837               } else {
00838                      if (aStyle & sf::Style::Titlebar) {
00839                             mask |= NSTitledWindowMask;
00840                             mask |= NSMiniaturizableWindowMask;
00841                      }
00842                      
00843                      if (aStyle & sf::Style::Resize) {
00844                             mask |= NSTitledWindowMask;
00845                             mask |= NSMiniaturizableWindowMask;
00846                             mask |= NSResizableWindowMask;
00847                      }
00848                      
00849                      if (aStyle & sf::Style::Close) {
00850                             mask |= NSTitledWindowMask;
00851                             mask |= NSClosableWindowMask;
00852                             mask |= NSMiniaturizableWindowMask;
00853                      }
00854               }
00855               
00856               // Now we make the window with the values we got
00857               // Note: defer flag set to NO to be able to use OpenGL in our window
00858               NSWindow *newWindow = [[NSWindow alloc]
00859                                                     initWithContentRect:frame
00860                                                     styleMask:mask
00861                                                     backing:NSBackingStoreBuffered
00862                                                     defer:NO];
00863               
00864               if (newWindow) {
00865                      [self setWindow:[newWindow autorelease]];
00866               } else {
00867                      std::cerr << "Unable to create the Cocoa window" << std::endl;
00868                      [self autorelease];
00869                      return nil;
00870               }
00871               
00872               // We set title and window position
00873               [[self window] setTitle:aTitle != nil ? aTitle : @""];
00874               [[self window] center];
00875               
00876               // Make the OpenGL view
00877               sfPrivGLView *newView = [[sfPrivGLView alloc]
00878                                              initWithFrame:[[[self window] contentView] frame]
00879                                              mode:aMode
00880                                              settings:someSettings];
00881               
00882               if (!newView) {
00883                      std::cerr << "Unable to create the OpenGL view" << std::endl;
00884                      [self autorelease];
00885                      return nil;
00886               }
00887               
00888               // Put our view in the window 
00889               [self putOpenGLView:[newView autorelease]];
00890               
00891               // I want to re-center the window if it's a full screen one and moved by Spaces
00892               [[NSNotificationCenter defaultCenter]
00893                addObserver:self
00894                selector:@selector(windowDidMove:)
00895                name:NSWindowDidMoveNotification
00896                object:[self window]];
00897               
00898               // Needed not to make application crash when releasing the window in our destructor
00899               // (I prefer to take control of everything :P)
00900               [[self window] setReleasedWhenClosed:NO];
00901               [[self window] setAcceptsMouseMovedEvents:YES];
00902               
00903               if ([self isFullscreen]) {
00904                      myFullscreenMode = aMode;
00905                      
00906                      // Using this because full screen window was not always
00907                      // in front of the other application windows when unhiding app
00908                      [[self window] setLevel:NSFloatingWindowLevel];
00909               }
00910        }
00911        return self;
00912 }
00913 
00914 - (void)dealloc
00915 {
00916        [[NSNotificationCenter defaultCenter]
00917         removeObserver:self 
00918         name:NSWindowDidMoveNotification
00919         object:[self window]];
00920        [super dealloc];
00921 }
00922 
00926 - (void)setFullscreen:(BOOL)aFlag
00927 {
00928        myIsFullscreen = aFlag;
00929 }
00930 
00934 - (BOOL)isFullscreen
00935 {
00936        return myIsFullscreen;
00937 }
00938 
00942 - (void)windowDidMove:(NSNotification *)notification
00943 {
00944        NSWindow *sender = [notification object];
00945        
00946        if (myIsFullscreen)
00947               [sender center];
00948 }
00949 
00953 - (void)show:(bool)flag
00954 {
00955        NSAssert([self window] != nil, @"expected valid window");
00956        
00957        if (flag && ![[self window] isVisible]) {
00958               // Wanna open the closed window
00959               
00960               if ([self isFullscreen]) {
00961                      [[sfPrivAppController sharedController]
00962                       setFullscreenWindow:self
00963                       mode:&myFullscreenMode];
00964               } else {
00965                      // Show the window
00966                      [[self window] makeKeyAndOrderFront:nil];
00967               }
00968        } else if (!flag && [[self window] isVisible]) {
00969               // Wanna close the opened window
00970               
00971               if ([self isFullscreen]) {
00972                      [[sfPrivAppController sharedController]
00973                       setFullscreenWindow:nil
00974                       mode:NULL];
00975               } else {
00976                      // Close the window
00977                      [[self window] close];
00978               }
00979        }      
00980 }
00981 
00985 - (void)setPosition:(NSPoint)aPosition
00986 {
00987        if (![self isFullscreen]) {
00988               [super setPosition:aPosition];
00989        }
00990 }
00991 
00995 - (void)setSize:(NSSize)size
00996 {
00997        if (![self isFullscreen]) {
00998               [super setSize:size];
00999        }
01000 }
01001 
01002 @end
01003 
01004 
01005 @implementation sfPrivImportedWindow
01006 
01007 - (id)initWithWindow:(NSWindow *)aWindow
01008                      settings:(sf::WindowSettings&)someSettings
01009 {
01010        self = [super init];
01011        
01012        if (self) {
01013               [self setWindow:aWindow];
01014               
01015               // Make the OpenGL view
01016               sf::VideoMode mode([[[self window] contentView] frame].size.width,
01017                                              [[[self window] contentView] frame].size.height);
01018               sfPrivGLView *newView = [[sfPrivGLView alloc]
01019                                              initWithFrame:[[[self window] contentView] frame]
01020                                              mode:mode
01021                                              settings:someSettings];
01022               
01023               if (!newView) {
01024                      std::cerr << "Unable to create the OpenGL view" << std::endl;
01025                      [self autorelease];
01026                      return nil;
01027               }
01028               
01029               [self putOpenGLView:[newView autorelease]];
01030               
01031               [[self window] setAcceptsMouseMovedEvents:YES];
01032        }
01033        
01034        return self;
01035 }
01036 
01037 @end
01038 
01039 
01040 @implementation sfPrivImportedView
01041 
01042 
01043 - (id)initWithView:(NSView *)aView
01044                 settings:(sf::WindowSettings&)someSettings
01045 {      
01046        self = [super init];
01047        if (self)
01048        {
01049               parentView = [aView retain];
01050               [self setWindow:[parentView window]];
01051               
01052               // Make the OpenGL view
01053               sf::VideoMode mode([parentView bounds].size.width,
01054                                              [parentView bounds].size.height);
01055               sfPrivGLView *newView = [[sfPrivGLView alloc]
01056                                              initWithFrame:[parentView bounds]
01057                                              mode:mode
01058                                              settings:someSettings];
01059               
01060               if (!newView) {
01061                      std::cerr << "Unable to create the OpenGL view" << std::endl;
01062                      [self autorelease];
01063                      return nil;
01064               }
01065               
01066               [self putOpenGLView:[newView autorelease]];
01067               [[self window] setAcceptsMouseMovedEvents:YES];
01068        }
01069        return self;
01070 }
01071 
01072 - (void)dealloc
01073 {
01074        [parentView release];
01075        [super dealloc];
01076 }
01077 
01081 - (void)putOpenGLView:(sfPrivGLView *)aView
01082 {
01083        [self setView:aView];
01084        
01085        // Finish setting up the view and window
01086        NSRect originalFrame = [[self window] frame];
01087        NSRect tmpFrame = originalFrame;
01088        originalFrame.origin.x++;
01089        
01090        [[self window] setFrame:tmpFrame display:YES];
01091        [[self window] setFrame:originalFrame display:YES];
01092        
01093        
01094        // Add the view to our *parent view* and tell it to the view
01095        [parentView addSubview:[self view]];
01096        [[self view] finishInitialization];
01097 }
01098 
01102 - (void)setPosition:(NSPoint)aPosition
01103 {
01104        std::cerr
01105        << "Warning: called Window::SetPosition() on a window imported from a widget. "
01106        << "This method has been disabled in this case and has no effect. "
01107        << "Directly use the widget if you want to move it."
01108        << std::endl;
01109 }
01110 
01114 - (void)setSize:(NSSize)size
01115 {
01116        std::cerr
01117        << "Warning: called Window::SetSize() on a window imported from a widget. "
01118        << "This method has been disabled in this case and has no effect. "
01119        << "Directly use the widget if you want to resize it."
01120        << std::endl;
01121 }
01122 
01123 @end
01124