changed: gcc8 base update
[opensg.git] / Source / Contrib / ComplexSceneManager / Native-Cocoa / OSGCSMNativeWindow.mm
blob34e332bc845e98e6d4cf03a260147a9f5788d450
1 /*---------------------------------------------------------------------------*\
2  *                                OpenSG                                     *
3  *                                                                           *
4  *                                                                           *
5  *               Copyright (C) 2000-2006 by the OpenSG Forum                 *
6  *                                                                           *
7  *                            www.opensg.org                                 *
8  *                                                                           *
9  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
10  *                                                                           *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13  *                                License                                    *
14  *                                                                           *
15  * This library is free software; you can redistribute it and/or modify it   *
16  * under the terms of the GNU Library General Public License as published    *
17  * by the Free Software Foundation, version 2.                               *
18  *                                                                           *
19  * This library is distributed in the hope that it will be useful, but       *
20  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
22  * Library General Public License for more details.                          *
23  *                                                                           *
24  * You should have received a copy of the GNU Library General Public         *
25  * License along with this library; if not, write to the Free Software       *
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
27  *                                                                           *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30  *                                Changes                                    *
31  *                                                                           *
32  *                                                                           *
33  *                                                                           *
34  *                                                                           *
35  *                                                                           *
36  *                                                                           *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 //  Includes
41 //---------------------------------------------------------------------------
43 #include <cstdlib>
44 #include <cstdio>
46 #include "OSGConfig.h"
47 #include "OSGGL.h"
49 #import <Cocoa/Cocoa.h>
51 #ifdef check
52 # undef check
53 #endif
55 #include "OSGCSMNativeWindow.h"
56 #include "OSGCSMDrawManager.h"
57 #include "OSGCSMDrawer.h"
58 #include "OSGComplexSceneManager.h"
59 #include "OSGShaderCache.h"
60 #include "OSGGLFuncProtos.h"
62 /***************************************************************************\
63  *                           local support classes                         *
64 \***************************************************************************/
66 @interface CSMOpenGLView: NSOpenGLView
68     OSG::CSMNativeWindow *_pWin;
70 - (BOOL) acceptsFirstResponder;
72 - (void) keyDown:           (NSEvent*) event;
74 - (void) handleMouseEvent:  (NSEvent*) event;
76 - (void) mouseDown:         (NSEvent*) event;
77 - (void) mouseDragged:      (NSEvent*) event;
78 - (void) mouseUp:           (NSEvent*) event;
79 - (void) rightMouseDown:    (NSEvent*) event;
80 - (void) rightMouseDragged: (NSEvent*) event;
81 - (void) rightMouseUp:      (NSEvent*) event;
82 - (void) otherMouseDown:    (NSEvent*) event;
83 - (void) otherMouseDragged: (NSEvent*) event;
84 - (void) otherMouseUp:      (NSEvent*) event;
87 - (void) setWindow: (OSG::CSMNativeWindow *) pWin;
89 - (void) reshape;
90 - (void) drawRect: (NSRect) bounds;
92 - (void) frame: (id) userInfo;
94 @end
96 @implementation CSMOpenGLView
98 - (BOOL) acceptsFirstResponder
100     return YES;
103 - (void) keyDown: (NSEvent*) event
105     if ([[event characters] length] != 1)
106         return;
108     switch ([[event characters] characterAtIndex: 0])
109     {
110         case 27:
111             [NSApp stop:nil];
112             break;
113         default:
114             OSG::ComplexSceneManager::the()->key(
115                 0,
116                 0,
117                 OSG::CSMKeyData::ButtonDown,
118                 [[event characters] characterAtIndex: 0]);
119             break;
120     }
123 - (void) handleMouseEvent: (NSEvent*) event
125     int          buttonNumber  = [event buttonNumber];
126     unsigned int modifierFlags = [event modifierFlags];
128     // Traditionally, Apple mice just have one button. It is common practice
129     // to simulate the middle and the right button by pressing the option or
130     // the control key. 
132     if(buttonNumber == 0)
133     {
134         if(modifierFlags & NSAlternateKeyMask)
135             buttonNumber = 2;
137         if(modifierFlags & NSControlKeyMask)
138             buttonNumber = 1;
139     }
141     NSPoint location = [event locationInWindow];
143     OSG::UInt32 uiHeight = _pWin->getWindow()->getHeight();
145     switch ([event type])
146     {
147         case NSLeftMouseDown:
148         case NSRightMouseDown:
149         case NSOtherMouseDown:
150         {
151             switch (buttonNumber)
152             {
153                 case 0: // left button
154                     _pWin->mouse(OSG::MouseData::LeftButton,
155                                  OSG::MouseData::ButtonDown,
156                                  OSG::MouseData::NoModifier,
157                                  location.x,
158                                  uiHeight - location.y);
159                     break;
160                 case 1: // right button
161                     _pWin->mouse(OSG::MouseData::RightButton,
162                                  OSG::MouseData::ButtonDown,
163                                  OSG::MouseData::NoModifier,
164                                  location.x,
165                                  uiHeight - location.y);
166                     break;
167                 case 2: // middle button
168                     _pWin->mouse(OSG::MouseData::MiddleButton,
169                                  OSG::MouseData::ButtonDown,
170                                  OSG::MouseData::NoModifier,
171                                  location.x,
172                                  uiHeight - location.y);
173                     break;
174             }
175             break;
176         }
177    
178         case NSLeftMouseUp:
179         case NSRightMouseUp:
180         case NSOtherMouseUp:
181         {
182             switch (buttonNumber)
183             {
184                 case 0: // left button
185                     _pWin->mouse(OSG::MouseData::LeftButton,
186                                  OSG::MouseData::ButtonUp,
187                                  OSG::MouseData::NoModifier,
188                                  location.x,
189                                  uiHeight - location.y);
190                     break;
191                 case 1: // right button
192                     _pWin->mouse(OSG::MouseData::RightButton,
193                                  OSG::MouseData::ButtonUp,
194                                  OSG::MouseData::NoModifier,
195                                  location.x,
196                                  uiHeight - location.y);
197                     break;
198                 case 2: // middle button
199                     _pWin->mouse(OSG::MouseData::MiddleButton,
200                                  OSG::MouseData::ButtonUp,
201                                  OSG::MouseData::NoModifier,
202                                  location.x,
203                                  uiHeight - location.y);
204                     break;
205             }
206             break;
207         }
208             
209         case NSLeftMouseDragged:
210         case NSRightMouseDragged:
211         case NSOtherMouseDragged:
212         {
213             _pWin->motion(location.x, uiHeight - location.y, 0);
215             break;
216         }
217    
218         default:
219             break;
220     }
223 - (void) mouseDown: (NSEvent*) event
225     [self handleMouseEvent: event];
228 - (void) mouseDragged: (NSEvent*) event
230     [self handleMouseEvent: event];
233 - (void) mouseUp: (NSEvent*) event
235     [self handleMouseEvent: event];
238 - (void) rightMouseDown: (NSEvent*) event
240     [self handleMouseEvent: event];
243 - (void) rightMouseDragged: (NSEvent*) event
245     [self handleMouseEvent: event];
248 - (void) rightMouseUp: (NSEvent*) event
250     [self handleMouseEvent: event];
253 - (void) otherMouseDown: (NSEvent*) event
255     [self handleMouseEvent: event];
258 - (void) otherMouseDragged: (NSEvent*) event
260     [self handleMouseEvent: event];
263 - (void) otherMouseUp: (NSEvent*) event
265     [self handleMouseEvent: event];
268 - (void) setWindow: (OSG::CSMNativeWindow *) pWin
270     _pWin = pWin;
273 - (void) reshape
275     [self update];
277     NSRect frame = [self bounds];
279     _pWin->reshape(static_cast<int>(frame.size.width), 
280                    static_cast<int>(frame.size.height));
283 - (void) drawRect: (NSRect) bounds
285     [self frame: nil];
288 - (void) frame: (id) userInfo
290     if(OSG::CSMNativeWindow::isRunning() == true)
291     {
292         OSG::ComplexSceneManager::the()->frame();
293         
294         OSG::Thread::getCurrentChangeList()->commitChangesAndClear();
295     }
298 @end
300 OSG_BEGIN_NAMESPACE
302 // Documentation for this class is emitted in the
303 // OSGCSMNativeWindowBase.cpp file.
304 // To modify it, please change the .fcd file (OSGCSMNativeWindow.fcd) and
305 // regenerate the base file.
307 /***************************************************************************\
308  *                           Class variables                               *
309 \***************************************************************************/
311 NSAutoreleasePool *CSMNativeWindow::_pPool = NULL;
312 bool               CSMNativeWindow::_bRun  = false;
314 /***************************************************************************\
315  *                           Class methods                                 *
316 \***************************************************************************/
318 void CSMNativeWindow::initMethod(InitPhase ePhase)
320     Inherited::initMethod(ePhase);
322     if(ePhase == TypeObject::SystemPost)
323     {
324     }
327 void CSMNativeWindow::cocoaMainLoop(void)
329     _bRun = true;
331     [NSApp run];
333     _bRun = false;
335     ComplexSceneManager::the()->terminate();
337     [_pPool release];
340 /***************************************************************************\
341  *                           Instance methods                              *
342 \***************************************************************************/
344 /*-------------------------------------------------------------------------*\
345  -  private                                                                 -
346 \*-------------------------------------------------------------------------*/
348 /*----------------------- constructors & destructors ----------------------*/
350 CSMNativeWindow::CSMNativeWindow(void) :
351      Inherited    (    ),
352     _pCocoaWindow (NULL),
353     _pGLView      (NULL)
357 CSMNativeWindow::CSMNativeWindow(const CSMNativeWindow &source) :
358      Inherited    (source),
359     _pCocoaWindow (NULL  ),
360     _pGLView      (NULL  )
364 CSMNativeWindow::~CSMNativeWindow(void)
368 /*----------------------------- class specific ----------------------------*/
370 void CSMNativeWindow::changed(ConstFieldMaskArg whichField, 
371                               UInt32            origin,
372                               BitVector         details)
374     Inherited::changed(whichField, origin, details);
377 void CSMNativeWindow::dump(      UInt32    ,
378                          const BitVector ) const
380     SLOG << "Dump CSMNativeWindow NI" << std::endl;
383 void CSMNativeWindow::resolveLinks(void)
385     if(_pCocoaWindow != NULL)
386     {
387         _pCocoaWindow->setContext(NULL);
388     }
390     _pCocoaWindow = NULL;
392     Inherited::resolveLinks();
395 void CSMNativeWindow::terminateGLContext(void)
397     if(_pCocoaWindow != NULL)
398     {
399         _pCocoaWindow->terminate();
400     }
402     _pGLView = NULL;
405 // A magic method that allows applications to react to events even
406 // when they are not organized in a bundle
407 static void osx_AllowForeground(void)
409     ProcessSerialNumber psn = { 0, kCurrentProcess };
410     TransformProcessType(&psn, kProcessTransformToForegroundApplication);
411     SetFrontProcess(&psn);
414 bool CSMNativeWindow::init(void)
416     osx_AllowForeground();
418     if(_pPool == NULL)
419     {
420         // Create application
421         [NSApplication sharedApplication];
423         _pPool = [[NSAutoreleasePool alloc] init];
424     }
426     UInt32 uiWidth;
427     UInt32 uiHeight;
429     Int32  iXPos = 0;
430     Int32  iYPos = 0;
432     
433     if(this->getXPos() > 0.f && this->getYPos() > 0.f)
434     {
435         iXPos = Int32(this->getXPos());
436         iYPos = Int32(this->getYPos());
437     }
438    
439     if(this->getXSize() >= 1.f) 
440     {
441         uiWidth = UInt32(this->getXSize());
442     }
443     else if(this->getXSize() <= 0.f)
444     {
445         uiWidth = 300; //DisplayWidth(_pDisplay, vi->screen);
446     }
447     else
448     {
449         uiWidth = 300; //UInt32(Real32(DisplayWidth(_pDisplay, vi->screen)) *
450                        //       this->getXSize());
451     }
453     if(this->getYSize() >= 1.f)
454     {
455         uiHeight = UInt32(this->getYSize());
456     }
457     else if(this->getYSize() <= 0.f)
458     {
459         uiHeight = 300; //DisplayHeight(_pDisplay, vi->screen);
460     }
461     else
462     {
463         uiHeight = 300; //UInt32(Real32(DisplayHeight(_pDisplay, vi->screen)) *
464                         //              this->getYSize());
465     }
467     NSRect nsScreenRect = [[NSScreen mainScreen] frame];
469     iYPos = nsScreenRect.size.height - iYPos - uiHeight;
471     // Create the window
472     NSWindow *window = [NSWindow alloc];
473     NSRect    rect   = { { 0, 0 }, { 300, 300 } };
475     rect.origin.x = iXPos;
476     rect.origin.y = iYPos;
478     rect.size.height = uiHeight;
479     rect.size.width  = uiWidth;
481     [window initWithContentRect: rect 
482             styleMask: (NSTitledWindowMask         | 
483                         NSClosableWindowMask       | 
484                         NSMiniaturizableWindowMask | 
485                         NSResizableWindowMask) 
486              backing: NSBackingStoreBuffered 
487              defer: YES];
489     [window setTitle: @"OpenSG - CSM"];
490     [window setReleasedWhenClosed: NO];
492     _pGLView = [[CSMOpenGLView alloc] autorelease];
494     rect.origin.x = 0;
495     rect.origin.y = 0;
497     [_pGLView initWithFrame: rect];
498     [_pGLView setAutoresizingMask: (NSViewMaxXMargin   | 
499                                     NSViewWidthSizable | 
500                                     NSViewMaxYMargin   | 
501                                     NSViewHeightSizable )];
503     [[window contentView] addSubview: _pGLView];
505     std::vector<NSOpenGLPixelFormatAttribute> attrs;
507     attrs.push_back(NSOpenGLPFAWindow);
508     attrs.push_back(NSOpenGLPFADoubleBuffer);
510     attrs.push_back(NSOpenGLPFADepthSize);
511     attrs.push_back(NSOpenGLPixelFormatAttribute(16));
512     
514     if(_sfRequestSamples.getValue() > 0)
515     {
516         attrs.push_back(NSOpenGLPFAMultisample);
518         attrs.push_back(NSOpenGLPFASampleBuffers);
519         attrs.push_back(1);
521         attrs.push_back(NSOpenGLPFASamples);
522         attrs.push_back(
523             NSOpenGLPixelFormatAttribute(_sfRequestSamples.getValue()));
524     }
526     if(this->requestStereoVisual() == true)
527     {
528         fprintf(stderr, "Choose stereo format\n");
529         attrs.push_back(NSOpenGLPFAStereo); 
530     }
533     attrs.push_back(NSOpenGLPixelFormatAttribute(0));
535     NSOpenGLPixelFormat *pixFmt = 
536         [[NSOpenGLPixelFormat alloc] initWithAttributes: &(attrs.front())];
538     if(pixFmt == NULL) 
539     {
540         fprintf(stderr, "no RGB visual with depth buffer : :0.0");
542         exit(0);
543     }
545     [_pGLView setPixelFormat: pixFmt];
548     // Create OpenSG window
549     CocoaWindowUnrecPtr pCocoaWindow = CocoaWindow::create();
551     pCocoaWindow->setContext([_pGLView openGLContext]);
552     pCocoaWindow->init      (                        );
553     pCocoaWindow->resize    (uiWidth, uiHeight       );
555     _pCocoaWindow = pCocoaWindow;
556     _pWindow      = pCocoaWindow;
558     [_pGLView setWindow: this];
560         // Show the window
561     [window makeKeyAndOrderFront: nil];
562     [window makeFirstResponder:_pGLView];
565     NSTimer *timer = [NSTimer timerWithTimeInterval: 0.0f
566                      target: _pGLView
567                      selector: @selector( frame: )
568                      userInfo: nil
569                      repeats: YES];
571     [[NSRunLoop currentRunLoop] addTimer: timer
572                                 forMode: NSDefaultRunLoopMode];
576     if(ComplexSceneManager::the() != NULL)
577     {
578         ComplexSceneManager::the()->setMainloop(
579             &CSMNativeWindow::cocoaMainLoop);
580     }
582     Inherited::init();
584     return true;
587 void CSMNativeWindow::initWindowSystemThreading(void)
591 void CSMNativeWindow::reshape(Int32 w, 
592                               Int32 h)
594     Inherited::reshape(w, h);
597 void CSMNativeWindow::mouse(Int32 iButton, 
598                             Int32 iState,
599                             Int32 iModifier,
600                             Int32 x,       
601                             Int32 y        )
603     Inherited::mouse(iButton, iState, iModifier, x, y);
606 void CSMNativeWindow::motion (Int32 x, 
607                               Int32 y,
608                               Int32 iModifier)
610     Inherited::motion(x, y, iModifier);
613 OSG_END_NAMESPACE