Changeset 19884

Show
Ignore:
Timestamp:
03/25/07 18:07:21 (1 year ago)
Author:
patrick
Message:

Here is almost everything that I have been working on for adding Cocoa
support to VR Juggler. At this point, the pending bugs in Ticket #3 still
exist, but I have workarounds in place for those related to OpenGL views.
The code is not yet hooked up to the build, and pending changes to
vrj::Kernel to use the new CocoaWrapper? class have not been committed.
Furthermore, an important change to vpr::Thread still needs some work, and
without that, this code will not compile let alone function. Finally, there
are some minor changes that need to be made to the test and sample
applications that are not included with this revision.

Ultimately, I wanted to get some revision control behind these files since
I have been working on them for many weeks without it.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • juggler/trunk/modules/vrjuggler/mtree/VJ.data.dist.in

    r19729 r19884  
    3333. 
    3434    data 
     35        bundle 
     36            MainMenu.nib 
     37            .. 
     38        .. 
    3539        configFiles 
    3640        .. 
  • juggler/trunk/modules/vrjuggler/vrj/Draw/OGL/GlDrawManager.cpp

    r19877 r19884  
    496496#  include <vrj/Draw/OGL/GlWindowWin32.h> 
    497497#elif defined(VPR_OS_Darwin) && ! defined(VRJ_USE_X11) 
    498 #  include <vrj/Draw/OGL/GlWindowOSX.h> 
     498#  include <vrj/Draw/OGL/GlWindowCocoa.h> 
    499499#else 
    500500#  include <vrj/Draw/OGL/GlWindowXWin.h> 
     
    509509   return GlWindowPtr(new vrj::GlWindowWin32); 
    510510#elif defined(VPR_OS_Darwin) && ! defined(VRJ_USE_X11) 
    511    return GlWindowPtr(new vrj::GlWindowOSX); 
     511   return GlWindowPtr(new vrj::GlWindowCocoa); 
    512512#else 
    513513   return GlWindowPtr(new vrj::GlWindowXWin); 
  • juggler/trunk/modules/vrjuggler/vrj/Draw/OGL/GlExtensionLoader.cpp

    r19729 r19884  
    2626 
    2727#include <vrj/Draw/OGL/GlExtensionLoader.h> 
    28 #include <vpr/vprConfig.h> 
     28 
     29#include <vpr/vpr.h> 
    2930#include <vpr/Util/Debug.h> 
    3031 
    31 #include <GL/gl.h> 
     32#if defined(VPR_OS_Darwin) && defined(VPR_USE_COCOA) 
     33#  include <OpenGL/gl.h> 
     34#else 
     35#  include <GL/gl.h> 
     36#endif 
    3237 
    3338#if !defined(WIN32) && !defined(VPR_OS_Darwin) 
  • juggler/trunk/modules/vrjuggler/vrj/Draw/OGL/GlViewCocoa.h

    r19845 r19884  
    3636 
    3737/** 
    38  * A custom Cocoa view class used for managing an OpenGL context. It is 
    39  * designed to be used as a subview for InputViewCocoa from Gadgeteer. This 
    40  * holds a pointer back to the vrj::GlWindowCocoa object that keeps track of 
    41  * an NSWindow instance for which this object is a view. This view will updat
    42  * the state of the vrj:GlWindowCocoa object as appropriate, usually as a 
    43  * result of resize events. 
     38 * A custom Cocoa view class used for managing an OpenGL context. It must be 
     39 * the content view for an NSWindow instance. This holds a pointer back to the 
     40 * vrj::GlWindowCocoa object that keeps track of an NSWindow instance for 
     41 * which this object is a view. This view will update the state of th
     42 * vrj:GlWindowCocoa object as appropriate, usually as a result of resize 
     43 * events. 
    4444 * 
    45  * @since 2.1.18 
     45 * @since 2.1.21 
    4646 */ 
    4747@interface GlViewCocoa : NSOpenGLView 
    4848{ 
    4949   vrj::GlWindowCocoa* mVrjWindow;      /**< The window using this view. */ 
     50 
     51   /** @name Full Screen State */ 
     52   //@{ 
     53   /** Indicates whether this view is in a full screen window. */ 
     54   BOOL mFullScreen; 
     55 
     56   /** 
     57    * The Core Graphics display ID for the screen on which this view is 
     58    * rendered. 
     59    */ 
     60   CGDirectDisplayID mDisplayID; 
     61 
     62   NSDictionary* mOrigDisplayMode; 
     63   //@} 
     64 
     65   /** 
     66    * Indicates whether this view should handle keyboard and mouse events. 
     67    * If so, they are handed off to \c mVrjWindow (as subclass of 
     68    * gadget::InputAreaCocoa). 
     69    */ 
     70   BOOL mHandleInput; 
     71 
     72   /** 
     73    * Indicates whether the mouse cursor should be hidden whenever the mouse 
     74    * is within the tracking rectnagle of this view. 
     75    */ 
     76   BOOL mShouldHideCursor; 
    5077 
    5178   /** 
     
    6491    * use of the NSOpenGLView initWithFrame:pixelFormat: initializer. 
    6592    * 
    66     * @param frameFrect The frame rectangle for this view. In general, this 
    67     *                   should be identifical to the frame rectangle used for 
    68     *                   the containing NSWindow. 
    69     * @param window     The vrj::GlWindowCocoa instance to be associated with 
    70     *                   this view. 
    71     * @param screen     The screen on which this view will be used. 
     93    * @param frameFrect  The frame rectangle for this view. In general, this 
     94    *                    should be identifical to the frame rectangle used for 
     95    *                    the containing NSWindow. 
     96    * @param window      The vrj::GlWindowCocoa instance to be associated with 
     97    *                    this view. 
     98    * @param screen      The screen on which this view will be used. 
     99    * @param handleInput A Boolean flag indicating whether this view should 
     100    *                    handle keyboard and mouse input events. 
    72101    * 
    73102    * @return self on successful initialization or nil on failure. 
     
    78107   -(id) initWithFrame:(NSRect) frameRect 
    79108              glWindow:(vrj::GlWindowCocoa*) window 
    80                 screen:(NSScreen*) screen; 
     109                screen:(NSScreen*) screen 
     110         inputHandling:(BOOL) handleInput; 
    81111@end 
  • juggler/trunk/modules/vrjuggler/vrj/Draw/OGL/GlViewCocoa.mm

    r19845 r19884  
    3535#import <AppKit/NSOpenGL.h> 
    3636#import <AppKit/NSScreen.h> 
     37#import <AppKit/NSWindow.h> 
    3738#import <AGL/agl.h> 
    3839 
     
    4647   -(void) clearTrackingRect; 
    4748   -(void) resetTrackingRect; 
    48    -(NSOpenGLPixelFormat*) createPixelFormat:(NSScreen*) screen; 
     49   -(NSOpenGLPixelFormat*) createPixelFormat; 
     50   -(CGDirectDisplayID) getDisplayID:(NSScreen*) screen; 
    4951@end 
    5052 
     
    5456              glWindow:(vrj::GlWindowCocoa*) window 
    5557                screen:(NSScreen*) screen 
    56    { 
    57       mVrjWindow = window; 
    58       mTrackingRect = 0; 
    59  
    60       NSOpenGLPixelFormat* pixel_format = [self createPixelFormat:screen]; 
     58         inputHandling:(BOOL) handleInput 
     59   { 
     60      vrj::DisplayPtr display = window->getDisplay(); 
     61 
     62      mVrjWindow        = window; 
     63      mFullScreen       = display->isFullScreen(); 
     64      mDisplayID        = [self getDisplayID:screen]; 
     65      mOrigDisplayMode  = (NSDictionary*) CGDisplayCurrentMode(mDisplayID); 
     66      mHandleInput      = handleInput; 
     67      mShouldHideCursor = display->shouldHideMouse(); 
     68      mTrackingRect     = 0; 
     69 
     70      [mOrigDisplayMode retain]; 
     71 
     72      NSOpenGLPixelFormat* pixel_format = [self createPixelFormat]; 
    6173 
    6274      if ( pixel_format == nil ) 
     
    7587 
    7688      vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 
    77          << "Visual ID: " << std::hex << renderer_id << std::dec 
    78          << std::endl << vprDEBUG_FLUSH; 
     89         << "Visual ID: " << std::hex << renderer_id << std::dec << std::endl 
     90         << vprDEBUG_FLUSH; 
    7991 
    8092      self = [super initWithFrame:frameRect 
    8193                      pixelFormat:pixel_format]; 
    82  
    83       if ( self && mVrjWindow->getDisplay()->isFullScreen() ) 
    84       { 
     94      [pixel_format release]; 
     95      pixel_format = nil; 
     96 
     97      if ( self && mFullScreen ) 
     98      { 
     99         CGDisplayErr err = CGDisplayCapture(mDisplayID); 
     100 
     101         if ( err != CGDisplayNoErr ) 
     102         { 
     103            NSException* ex = 
     104               [NSException exceptionWithName:@"DisplayCaptureException" 
     105                                       reason:@"Coult not capture displays" 
     106                                     userInfo:nil]; 
     107            @throw ex; 
     108         } 
     109 
     110         // This has the side effect of creating the OpenGL context if it did 
     111         // not already exist. 
    85112         [[self openGLContext] setFullScreen]; 
    86113      } 
    87114 
    88115      return self; 
     116   } 
     117 
     118   -(void) dealloc 
     119   { 
     120      [mOrigDisplayMode release]; 
     121      [super dealloc]; 
     122   } 
     123 
     124   -(void) reshape 
     125   { 
    89126   } 
    90127/* 
     
    98135//      mVrjWindow->updateOriginSize(bounds.origin.x, bounds.origin.y, 
    99136//                                   bounds.size.width, bounds.size.height); 
     137//      mVrjWindow->setDirtyViewport(true); 
    100138   } 
    101139*/ 
     140   /** @name NSResponder overrides */ 
     141   //@{ 
    102142   /** 
    103143    * Indicates whether this object can take on the first responder role for 
     
    134174 
    135175   /** 
    136     * Removes the tracking rectangle for this view if it has one. 
     176    * Removes the tracking rectangle for this view (if it has one) before it 
     177    * gets assigned to a new window. 
     178    * 
     179    * @post \c mTrackingRerct is 0. 
    137180    */ 
    138181   -(void) viewWillMoveToWindow:(NSWindow*) newWindow 
     
    144187   /** 
    145188    * Adds a tracking rectangle to this view if it needs one for mouse cursor 
    146     * hiding
     189    * hiding and/or input handling
    147190    */ 
    148191   -(void) viewDidMoveToWindow 
     
    150193      [super viewDidMoveToWindow]; 
    151194      [self resetTrackingRect]; 
     195 
     196      // If this view was moved to a new window, determine if the mouse is 
     197      // currently within the bounds of this view. If it is, then we post a 
     198      // fake mouseEntered event to inform this view that the mouse is within 
     199      // it. Without this, the user would have to move the mouse out of the 
     200      // window and back in to get the mouseEntered event to be posted. 
     201      if ( [self window] ) 
     202      { 
     203         const NSPoint mouse_loc = 
     204            [[self window] mouseLocationOutsideOfEventStream]; 
     205         const NSRect bounds = [self bounds]; 
     206 
     207         if ( [self mouse:mouse_loc inRect:bounds] ) 
     208         { 
     209            [self mouseEntered:nil]; 
     210         } 
     211      } 
     212      // This view has been removed from its window, so we need to clean up 
     213      // its state. 
     214      else 
     215      { 
     216         [NSOpenGLContext clearCurrentContext]; 
     217         [[self openGLContext] clearDrawable]; 
     218 
     219         if ( mFullScreen ) 
     220         { 
     221            CGDisplaySwitchToMode(mDisplayID, 
     222                                  (CFDictionaryRef) mOrigDisplayMode); 
     223            CGDisplayErr err = CGDisplayRelease(mDisplayID); 
     224 
     225            if ( err != CGDisplayNoErr ) 
     226            { 
     227               vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL) 
     228                  << "GlViewCocoa failed to release display " 
     229                  << std::hex << mDisplayID << std::dec << std::endl 
     230                  << vprDEBUG_FLUSH; 
     231            } 
     232         } 
     233      } 
    152234   } 
    153235 
     
    158240   -(void) viewWillStartLiveResize 
    159241   { 
     242      mVrjWindow->acquireRenderLock(); 
     243 
    160244      [super viewWillStartLiveResize]; 
    161245 
    162       if ( mVrjWindow->getDisplay()->shouldHideMouse()
     246      if ( mShouldHideCursor
    163247      { 
    164248         [NSCursor unhide]; 
    165249      } 
     250   } 
     251 
     252   -(void) viewDidEndLiveResize 
     253   { 
     254      vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) 
     255         << "GlViewCocoa viewDidEndLiveResize" << std::endl << vprDEBUG_FLUSH; 
     256      mVrjWindow->releaseRenderLock(); 
     257      [super viewDidEndLiveResize]; 
    166258   } 
    167259 
     
    172264   -(void) mouseEntered:(NSEvent*) theEvent 
    173265   { 
    174       [NSCursor hide]; 
     266      [[self window] setAcceptsMouseMovedEvents:mHandleInput]; 
     267 
     268      if ( mShouldHideCursor ) 
     269      { 
     270         [NSCursor hide]; 
     271      } 
     272 
    175273      [super mouseEntered:theEvent]; 
    176274   } 
     
    182280   -(void) mouseExited:(NSEvent*) theEvent 
    183281   { 
    184       [NSCursor unhide]; 
     282      if ( mHandleInput ) 
     283      { 
     284         [[self window] setAcceptsMouseMovedEvents:NO]; 
     285      } 
     286 
     287      if ( mShouldHideCursor ) 
     288      { 
     289         [NSCursor unhide]; 
     290      } 
     291 
    185292      [super mouseExited:theEvent]; 
    186293   } 
    187294 
     295   /** 
     296    * Responds to mouse movement. This is only invoked if the mouse is inside 
     297    * the tracking rectangle for this view and \c mHandleInput is YES. 
     298    */ 
     299   -(void) mouseMoved:(NSEvent*) theEvent 
     300   { 
     301      mVrjWindow->addMouseMoveEvent(theEvent); 
     302   } 
     303 
     304   /** 
     305    * Responds to mouse movement while the left button is pressed. This is 
     306    * only invoked if the mouse is inside the tracking rectangle for this view 
     307    * and \c mHandleInput is YES. 
     308    */ 
     309   -(void) mouseDragged:(NSEvent*) theEvent 
     310   { 
     311      mVrjWindow->addMouseMoveEvent(theEvent); 
     312   } 
     313 
     314   /** 
     315    * Responds to mouse left button press. 
     316    */ 
     317   -(void) mouseDown:(NSEvent*) theEvent 
     318   { 
     319      if ( mHandleInput ) 
     320      { 
     321         mVrjWindow->addMouseButtonEvent(gadget::MBUTTON1, 
     322                                         gadget::MouseButtonPressEvent, 
     323                                         theEvent); 
     324      } 
     325      else 
     326      { 
     327         [super mouseDown:theEvent]; 
     328      } 
     329   } 
     330 
     331   /** 
     332    * Responds to mouse left button release. 
     333    */ 
     334   -(void) mouseUp:(NSEvent*) theEvent 
     335   { 
     336      if ( mHandleInput ) 
     337      { 
     338         mVrjWindow->addMouseButtonEvent(gadget::MBUTTON1, 
     339                                         gadget::MouseButtonReleaseEvent, 
     340                                         theEvent); 
     341      } 
     342      else 
     343      { 
     344         [super mouseUp:theEvent]; 
     345      } 
     346   } 
     347 
     348   /** 
     349    * Responds to mouse movement while the right button is pressed. This is 
     350    * only invoked if the mouse is inside the tracking rectangle for this view 
     351    * and \c mHandleInput is YES. 
     352    */ 
     353   -(void) rightMouseDragged:(NSEvent*) theEvent 
     354   { 
     355      mVrjWindow->addMouseMoveEvent(theEvent); 
     356   } 
     357 
     358   /** 
     359    * Responds to mouse right button press. 
     360    */ 
     361   -(void) rightMouseDown:(NSEvent*) theEvent 
     362   { 
     363      if ( mHandleInput ) 
     364      { 
     365         mVrjWindow->addMouseButtonEvent(gadget::MBUTTON2, 
     366                                         gadget::MouseButtonPressEvent, 
     367                                         theEvent); 
     368      } 
     369      else 
     370      { 
     371         [super rightMouseDown:theEvent]; 
     372      } 
     373   } 
     374 
     375   /** 
     376    * Responds to mouse right button release. 
     377    */ 
     378   -(void) rightMouseUp:(NSEvent*) theEvent 
     379   { 
     380      if ( mHandleInput ) 
     381      { 
     382         mVrjWindow->addMouseButtonEvent(gadget::MBUTTON2, 
     383                                         gadget::MouseButtonReleaseEvent, 
     384                                         theEvent); 
     385      } 
     386      else 
     387      { 
     388         [super rightMouseUp:theEvent]; 
     389      } 
     390   } 
     391 
     392   /** 
     393    * Responds to mouse movement while a button other than the left or the 
     394    * right is pressed. This is only invoked if the mouse is inside the 
     395    * tracking rectangle for this view and \c mHandleInput is YES. 
     396    */ 
     397   -(void) otherMouseDragged:(NSEvent*) theEvent 
     398   { 
     399      mVrjWindow->addMouseMoveEvent(theEvent); 
     400   } 
     401 
     402   /** 
     403    * Responds to mouse button press other than the right or the left. 
     404    */ 
     405   -(void) otherMouseDown:(NSEvent*) theEvent 
     406   { 
     407      if ( mHandleInput ) 
     408      { 
     409         mVrjWindow->addMouseButtonEvent(gadget::MouseButtonPressEvent, 
     410                                         theEvent); 
     411      } 
     412      else 
     413      { 
     414         [super otherMouseDown:theEvent]; 
     415      } 
     416   } 
     417 
     418   /** 
     419    * Responds to mouse button release other than the right or the left. 
     420    */ 
     421   -(void) otherMouseUp:(NSEvent*) theEvent 
     422   { 
     423      if ( mHandleInput ) 
     424      { 
     425         mVrjWindow->addMouseButtonEvent(gadget::MouseButtonReleaseEvent, 
     426                                         theEvent); 
     427      } 
     428      else 
     429      { 
     430         [super otherMouseUp:theEvent]; 
     431      } 
     432   } 
     433 
     434   /** 
     435    * Responds to scroll wheel use. 
     436    */ 
     437   -(void) scrollWheel:(NSEvent*) theEvent 
     438   { 
     439      // Add a mouse button event. 
     440   } 
     441 
     442   /** 
     443    * Responds to a key press. 
     444    */ 
     445   -(void) keyDown:(NSEvent*) theEvent 
     446   { 
     447      if ( mHandleInput ) 
     448      { 
     449         mVrjWindow->addKeyEvent(gadget::KeyPressEvent, theEvent); 
     450      } 
     451      else 
     452      { 
     453         [super keyDown:theEvent]; 
     454      } 
     455   } 
     456 
     457   /** 
     458    * Responds to a key release. 
     459    */ 
     460   -(void) keyUp:(NSEvent*) theEvent 
     461   { 
     462      if ( mHandleInput ) 
     463      { 
     464         mVrjWindow->addKeyEvent(gadget::KeyReleaseEvent, theEvent); 
     465      } 
     466      else 
     467      { 
     468         [super keyUp:theEvent]; 
     469      } 
     470   } 
     471 
     472   /** 
     473    * Responds to a change in the keyboard modifier flags. 
     474    */ 
     475   -(void) flagsChanged:(NSEvent*) theEvent 
     476   { 
     477      if ( mHandleInput ) 
     478      { 
     479         mVrjWindow->flagsChanged(theEvent); 
     480      } 
     481      else 
     482      { 
     483         [super flagsChanged:theEvent]; 
     484      } 
     485   } 
     486   //@} 
     487 
     488   /** 
     489    * Invoked whenever the window containing this view is moved or resized. 
     490    * The job of this method is to update the tracking rectangle for this 
     491    * view. 
     492    */ 
    188493   -(void) resetCursorRects 
    189494   { 
    190495      vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) 
    191496         << "GlViewCocoa resetCursorRects" << std::endl << vprDEBUG_FLUSH; 
     497//      mVrjWindow->acquireRenderLock(); 
    192498      [super resetCursorRects]; 
     499 
     500      // Clear the current tracking rectnagle and define a new one based on 
     501      // our new bounds. 
    193502      [self resetTrackingRect]; 
    194 //      NSRect bounds = [self bounds]; 
    195 //      mVrjWindow->updateOriginSize(bounds.origin.x, bounds.origin.y, 
    196 //                                   bounds.size.width, bounds.size.height); 
    197    } 
    198  
     503 
     504      NSRect bounds = [self bounds]; 
     505      mVrjWindow->updateOriginSize(bounds.origin.x, bounds.origin.y, 
     506                                   bounds.size.width, bounds.size.height); 
     507//      mVrjWindow->releaseRenderLock(); 
     508      mVrjWindow->setDirtyViewport(true); 
     509   } 
     510 
     511   /** @name Private Methods */ 
     512   //@{ 
     513   /** 
     514    * Removes the current tracking rectangle for this view (if it has one). 
     515    * 
     516    * @post This view has no tracking rectangle associated with it. 
     517    *       \c mTrackingRect is 0. 
     518    */ 
    199519   -(void) clearTrackingRect 
    200520   { 
     
    206526   } 
    207527 
     528   /** 
     529    * Sets a new tracking rectangle for this view. If this view already has a 
     530    * tracking rectangle, the existing one is removed first. 
     531    * 
     532    * @post This view has a tracking rectangle whose ID is stored in 
     533    *       \c mTrackingRect. 
     534    */ 
    208535   -(void) resetTrackingRect 
    209536   { 
    210537      [self clearTrackingRect]; 
    211538 
    212       // If the mouse pointer should be hidden when inside this view, then w
    213       // create a tracking rectangle that is the size of this view. Then, th
    214       // NSResponder overrides of -mouseEntered: and -mouseExited: will be 
    215       // invoked. 
    216       if ( mVrjWindow->getDisplay()->shouldHideMouse()
     539      // If the mouse pointer should be hidden when inside this view or we ar
     540      // handling input, then we create a tracking rectangle that is the siz
     541      // of this view. Then, the NSResponder overrides of -mouseEntered: and 
     542      // -mouseExited: will be invoked. 
     543      if ( mShouldHideCursor || mHandleInput
    217544      { 
    218545         mTrackingRect = [self addTrackingRect:[self visibleRect] 
     
    228555    * vrj::Display object associated with \c mVrjWindow. 
    229556    */ 
    230    -(NSOpenGLPixelFormat*) createPixelFormat:(NSScreen*) screen 
    231    { 
    232       vrj::Display* display = mVrjWindow->getDisplay(); 
     557   -(NSOpenGLPixelFormat*) createPixelFormat 
     558   { 
     559      vrj::DisplayPtr display = mVrjWindow->getDisplay(); 
    233560      jccl::ConfigElementPtr gl_fb_elt = display->getGlFrameBufferConfig(); 
    234561 
     
    356683      } 
    357684 
    358       const bool full_screen = display->isFullScreen(); 
    359  
    360685      std::vector<NSOpenGLPixelFormatAttribute> attr_vec; 
    361686 
    362       if ( full_screen ) 
     687      if ( mFullScreen ) 
    363688      { 
    364689         attr_vec.push_back(NSOpenGLPFAFullScreen); 
    365690         attr_vec.push_back(NSOpenGLPFAScreenMask); 
    366          NSNumber* screen_num = 
    367             [[screen deviceDescription] objectForKey:@"NSScreeNumber"]; 
    368          _CGDirectDisplayID* gl_id = 
    369             reinterpret_cast<_CGDirectDisplayID*>([screen_num intValue]); 
    370691         attr_vec.push_back( 
    371692            static_cast<NSOpenGLPixelFormatAttribute>( 
    372                CGDisplayIDToOpenGLDisplayMask(gl_id
     693               CGDisplayIDToOpenGLDisplayMask(mDisplayID
    373694            ) 
    374695         ); 
     696         attr_vec.push_back(NSOpenGLPFAAllRenderers); 
    375697      } 
    376698      else 
     
    380702 
    381703      attr_vec.push_back(NSOpenGLPFADoubleBuffer); 
     704      attr_vec.push_back(NSOpenGLPFAAccelerated); 
    382705      attr_vec.push_back(NSOpenGLPFAColorSize); 
    383706      attr_vec.push_back( 
     
    454777            mVrjWindow->setInStereo(true); 
    455778         } 
     779 
     780         // If we reached this point, we still do not have a usable pixel 
     781         // format. Disabling the alpha channel may give us something usable. 
     782         vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 
     783            << "WARNING: Could not get an OpenGL visual with a color buffer\n"; 
     784         vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 
     785            << "         alpha channel; trying without.\n" << vprDEBUG_FLUSH; 
     786 
     787         attr_vec[alpha_attrib_index] = 
     788            static_cast<NSOpenGLPixelFormatAttribute>(0); 
     789 
     790         pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; 
     791 
     792         if ( pixel_format != nil ) 
     793         { 
     794            return pixel_format; 
     795         } 
    456796      } 
    457797 
    458798      return pixel_format; 
    459799   } 
     800 
     801   -(CGDirectDisplayID) getDisplayID:(NSScreen*) screen 
     802   { 
     803      NSNumber* screen_num = 
     804         [[screen deviceDescription] objectForKey:@"NSScreeNumber"]; 
     805      return reinterpret_cast<CGDirectDisplayID>([screen_num intValue]); 
     806   } 
     807   //@} 
    460808@end