fixed: gcc8 compile issues
[opensg.git] / Source / Contrib / ComplexSceneManager / Native-Carbon / OSGCSMNativeWindow.cpp
blob1ad0dcc9e0e76bdeb54103ad9851870711c66c95
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 #include "OSGCSMNativeWindow.h"
50 #include "OSGCSMDrawManager.h"
51 #include "OSGCSMDrawer.h"
52 #include "OSGComplexSceneManager.h"
53 #include "OSGShaderCache.h"
54 #include "OSGGLFuncProtos.h"
56 OSG_BEGIN_NAMESPACE
58 // Documentation for this class is emitted in the
59 // OSGCSMNativeWindowBase.cpp file.
60 // To modify it, please change the .fcd file (OSGCSMNativeWindow.fcd) and
61 // regenerate the base file.
63 /***************************************************************************\
64 * Class variables *
65 \***************************************************************************/
67 bool CSMNativeWindow::_bRun = false;
69 /***************************************************************************\
70 * Class methods *
71 \***************************************************************************/
73 void CSMNativeWindow::initMethod(InitPhase ePhase)
75 Inherited::initMethod(ePhase);
77 if(ePhase == TypeObject::SystemPost)
82 OSStatus CSMNativeWindow::handleMouseEvent(EventHandlerCallRef nextHandler,
83 EventRef event )
85 OSStatus err;
87 // Get the window
88 WindowRef window;
89 err = GetEventParameter(event,
90 kEventParamWindowRef,
91 typeWindowRef, 0,
92 sizeof(window), 0, &window);
94 if (err != noErr)
95 return err;
97 // Get the window rectangle
98 Rect portRect;
99 GetWindowPortBounds(window, &portRect);
101 // Get the pressed mouse button
102 EventMouseButton mouseButton;
103 err = GetEventParameter(event,
104 kEventParamMouseButton,
105 typeMouseButton, 0,
106 sizeof(mouseButton), 0, &mouseButton);
108 if (err != noErr)
109 return err;
111 // Get the modifier keys
112 ::UInt32 modifierKeys;
113 err = GetEventParameter(event,
114 kEventParamKeyModifiers,
115 typeUInt32, 0,
116 sizeof(modifierKeys), 0, &modifierKeys);
118 if (err != noErr)
119 return err;
121 // Traditionally, Apple mice just have one button. It is common practice
122 // to simulate the middle and the right button by pressing the option or
123 // the control key.
125 if(mouseButton == kEventMouseButtonPrimary)
127 if(modifierKeys & optionKey)
128 mouseButton = kEventMouseButtonTertiary;
130 if(modifierKeys & controlKey)
131 mouseButton = kEventMouseButtonSecondary;
134 // Get the location of the mouse pointer
135 ::Point location;
136 err = GetEventParameter(event,
137 kEventParamMouseLocation,
138 typeQDPoint, 0,
139 sizeof(location), 0, &location);
141 if (err != noErr)
142 return err;
144 // The location of the mouse pointer is in screen coordinates, so
145 // we have to transform it into the local coordinate system of the
146 // window content area.
147 SetPortWindowPort(window );
148 GlobalToLocal (&location);
150 // Handle the different kinds of events
151 ::UInt32 eventKind = GetEventKind(event);
153 switch (eventKind)
155 // mouse button pressed
156 case kEventMouseDown:
158 switch (mouseButton)
160 case kEventMouseButtonPrimary: // left button
161 this->mouse(MouseData::LeftButton,
162 MouseData::ButtonDown,
164 location.h,
165 location.v);
166 break;
167 case kEventMouseButtonSecondary: // right button
168 this->mouse(MouseData::RightButton,
169 MouseData::ButtonDown,
171 location.h,
172 location.v);
173 break;
174 case kEventMouseButtonTertiary: // middle button
175 this->mouse(MouseData::MiddleButton,
176 MouseData::ButtonDown,
178 location.h,
179 location.v);
180 break;
183 break;
185 // mouse button released
186 case kEventMouseUp:
188 switch (mouseButton)
190 case kEventMouseButtonPrimary: // left button
191 this->mouse(MouseData::LeftButton,
192 MouseData::ButtonUp,
194 location.h,
195 location.v);
196 break;
197 case kEventMouseButtonSecondary: // right button
198 this->mouse(MouseData::RightButton,
199 MouseData::ButtonUp,
201 location.h,
202 location.v);
203 break;
204 case kEventMouseButtonTertiary: // middle button
205 this->mouse(MouseData::MiddleButton,
206 MouseData::ButtonUp,
208 location.h,
209 location.v);
210 break;
213 break;
215 // mouse moved while a button is pressed
216 case kEventMouseDragged:
218 this->motion(location.h, location.v, 0);
220 // Redraw the whole window
221 InvalWindowRect(window, &portRect);
223 break;
226 // We have to return eventNotHandledErr, otherwise the system is
227 // not able to operate the menu and the window border
228 return eventNotHandledErr;
231 OSStatus CSMNativeWindow::handleKeyEvent(EventHandlerCallRef nextHandler,
232 EventRef event )
234 OSStatus err;
236 // Try to determine the size of the text input
237 ::UInt32 actualSize;
239 err = GetEventParameter(event,
240 kEventParamTextInputSendText,
241 typeUnicodeText, 0, 0, &actualSize, 0);
243 if (err != noErr)
244 return err;
246 // The input can actually consist of more than one character.
247 // We are only interested in single character input
248 if (actualSize == sizeof(UniChar))
250 // Get the character unicode
251 UniChar c;
253 err = GetEventParameter(event,
254 kEventParamTextInputSendText,
255 typeUnicodeText, 0,
256 sizeof(UniChar), 0, &c);
258 if (err != noErr)
259 return err;
261 switch (c)
263 case kEscapeCharCode:
264 //QuitApplicationEventLoop();
265 _bRun = false;
266 break;
268 default:
269 ComplexSceneManager::the()->key(
272 CSMKeyData::ButtonDown,
274 break;
278 return noErr;
281 OSStatus CSMNativeWindow::handleWindowEvent(EventHandlerCallRef nextHandler,
282 EventRef event )
284 OSStatus err;
286 // Get the window
287 WindowRef window;
289 err = GetEventParameter(event,
290 kEventParamDirectObject,
291 typeWindowRef, 0, sizeof(window), 0, &window);
293 if (err != noErr)
294 return err;
296 // Handle the different kinds of events
297 ::UInt32 eventKind = GetEventKind(event);
299 switch (eventKind)
301 // Quit the application when the user closes the window
302 case kEventWindowClose:
303 //QuitApplicationEventLoop();
304 _bRun = false;
305 return noErr;
307 // Draw the contents of the window
308 case kEventWindowDrawContent:
309 //ComplexSceneManager::the()->frame();
311 //Thread::getCurrentChangeList()->commitChangesAndClear();
312 return noErr;
314 case kEventWindowBoundsChanged:
316 // Update the GL context
317 // WARNING this crap might crash later
318 aglUpdateContext(_pCarbWindow->getContext());
320 // Find out if we have a move or a resize situation
321 ::UInt32 attributes;
322 GetEventParameter(event,
323 kEventParamAttributes,
324 typeUInt32,
326 sizeof(attributes),
328 &attributes);
330 if ((attributes & kWindowBoundsChangeSizeChanged) != 0)
332 // Get the new bounds of the window
333 Rect bounds;
334 GetEventParameter(event,
335 kEventParamCurrentBounds,
336 typeQDRectangle,
338 sizeof(Rect),
340 &bounds);
342 // Resize the OpenSG Window
343 GLsizei width = bounds.right - bounds.left;
344 GLsizei height = bounds.bottom - bounds.top;
346 this->reshape(width, height);
348 // Redraw the whole window
349 Rect portRect;
350 GetWindowPortBounds(window, &portRect);
351 InvalWindowRect (window, &portRect);
354 return noErr;
357 default:
358 return eventNotHandledErr;
362 static pascal OSStatus eventHandler(EventHandlerCallRef nextHandler,
363 EventRef event,
364 void *userData )
366 ::UInt32 eventClass = GetEventClass(event);
368 CSMNativeWindow *pWin = reinterpret_cast<CSMNativeWindow *>(userData);
370 OSG_ASSERT(pWin != NULL);
372 switch (eventClass)
374 // Mouse events
375 case kEventClassMouse:
376 return pWin->handleMouseEvent(nextHandler, event);
378 // Key press events
379 case kEventClassTextInput:
380 return pWin->handleKeyEvent(nextHandler, event);
382 // Window events
383 case kEventClassWindow:
384 return pWin->handleWindowEvent(nextHandler, event);
386 default:
387 return eventNotHandledErr;
391 void CSMNativeWindow::carbonMainLoop(void)
393 EventRef pEvent;
394 EventTargetRef pTarget = GetEventDispatcherTarget();
396 while(_bRun == true)
398 while(ReceiveNextEvent(0,
399 NULL,
400 0, //kEventDurationForever,
401 true,
402 &pEvent) == noErr)
404 SendEventToEventTarget(pEvent, pTarget);
405 ReleaseEvent (pEvent );
408 ComplexSceneManager::the()->frame();
410 Thread::getCurrentChangeList()->commitChangesAndClear();
413 ComplexSceneManager::the()->terminate();
416 #if 0
417 static UInt32 mapModifier(int iState)
419 if(0x0000 != (iState & ShiftMask))
421 return MouseData::ShiftActive;
423 else if(0x0000 != (iState & ControlMask))
425 return MouseData::CtrlActive;
427 else if(0x0000 != (iState & Mod1Mask))
429 return MouseData::AltActive;
432 return 0x0001;
434 #endif
436 /***************************************************************************\
437 * Instance methods *
438 \***************************************************************************/
440 /*-------------------------------------------------------------------------*\
441 - private -
442 \*-------------------------------------------------------------------------*/
444 /*----------------------- constructors & destructors ----------------------*/
446 CSMNativeWindow::CSMNativeWindow(void) :
447 Inherited ( ),
448 _pCarbWindow (NULL),
449 _pContext (NULL),
450 _pLocalWindow (NULL),
451 _pEventHandler(NULL)
456 CSMNativeWindow::CSMNativeWindow(const CSMNativeWindow &source) :
457 Inherited (source),
458 _pCarbWindow (NULL ),
459 _pContext (NULL ),
460 _pLocalWindow (NULL ),
461 _pEventHandler(NULL )
465 CSMNativeWindow::~CSMNativeWindow(void)
469 /*----------------------------- class specific ----------------------------*/
471 void CSMNativeWindow::changed(ConstFieldMaskArg whichField,
472 UInt32 origin,
473 BitVector details)
475 Inherited::changed(whichField, origin, details);
478 void CSMNativeWindow::dump( UInt32 ,
479 const BitVector ) const
481 SLOG << "Dump CSMNativeWindow NI" << std::endl;
484 void CSMNativeWindow::resolveLinks(void)
486 if(_pCarbWindow != NULL)
488 _pCarbWindow->setContext(NULL);
491 if(_pContext != NULL)
492 aglDestroyContext(_pContext);
494 if(_pLocalWindow != NULL)
495 DisposeWindow(_pLocalWindow);
497 if(_pEventHandler != NULL)
498 DisposeEventHandlerUPP(_pEventHandler);
500 Inherited::resolveLinks();
503 void CSMNativeWindow::terminateGLContext(void)
507 // A magic method that allows applications to react to events even
508 // when they are not organized in a bundle
509 static void osx_AllowForeground(void)
511 ProcessSerialNumber psn = { 0, kCurrentProcess };
512 TransformProcessType(&psn, kProcessTransformToForegroundApplication);
513 SetFrontProcess(&psn);
516 bool CSMNativeWindow::init(void)
518 osx_AllowForeground();
520 CSMDrawer *pDrawer = this->getParent();
522 CarbonWindowUnrecPtr pCarbonWindow = OSG::CarbonWindow::create();
523 AGLPixelFormat pixelFormat = NULL;
525 std::vector<int> pfForm;
527 pfForm.push_back(AGL_RGBA);
528 pfForm.push_back(AGL_DEPTH_SIZE);
529 pfForm.push_back(16);
530 pfForm.push_back(AGL_DOUBLEBUFFER);
532 if(_sfRequestSamples.getValue() > 0)
534 pfForm.push_back(AGL_SAMPLE_BUFFERS_ARB);
535 pfForm.push_back(1);
537 pfForm.push_back(AGL_SAMPLES_ARB);
538 pfForm.push_back(_sfRequestSamples.getValue());
541 if(this->requestStereoVisual() == true)
543 fprintf(stderr, "Choose stereo format\n");
544 pfForm.push_back(AGL_STEREO);
547 pfForm.push_back(AGL_NONE);
549 pixelFormat = aglChoosePixelFormat(NULL, 0, &(pfForm.front()));
551 fprintf(stderr, "Got pf : %p\n", pixelFormat);
553 if(pixelFormat == NULL)
555 fprintf(stderr, "no RGB visual with depth buffer : :0.0");
557 exit(0);
560 _pContext = aglCreateContext(pixelFormat, 0);
562 aglDestroyPixelFormat(pixelFormat);
564 UInt32 uiWidth;
565 UInt32 uiHeight;
567 Int32 iXPos = 0;
568 Int32 iYPos = 0;
571 if(this->getXPos() > 0.f && this->getYPos() > 0.f)
573 iXPos = Int32(this->getXPos());
574 iYPos = Int32(this->getYPos());
577 if(this->getXSize() >= 1.f)
579 uiWidth = UInt32(this->getXSize());
581 else if(this->getXSize() <= 0.f)
583 uiWidth = 300; //DisplayWidth(_pDisplay, vi->screen);
585 else
587 uiWidth = 300; //UInt32(Real32(DisplayWidth(_pDisplay, vi->screen)) *
588 // this->getXSize());
591 if(this->getYSize() >= 1.f)
593 uiHeight = UInt32(this->getYSize());
595 else if(this->getYSize() <= 0.f)
597 uiHeight = 300; //DisplayHeight(_pDisplay, vi->screen);
599 else
601 uiHeight = 300; //UInt32(Real32(DisplayHeight(_pDisplay, vi->screen)) *
602 // this->getYSize());
605 WindowAttributes windowAttrs = (kWindowStandardDocumentAttributes |
606 kWindowLiveResizeAttribute |
607 kWindowStandardHandlerAttribute );
608 Rect contentRect;
609 SetRect(&contentRect, iXPos, iYPos, iXPos + uiWidth, iYPos + uiHeight);
611 CreateNewWindow(kDocumentWindowClass, windowAttrs, &contentRect,
612 &_pLocalWindow);
614 SetWindowTitleWithCFString(_pLocalWindow, CFSTR("OpenSG - CSM"));
616 // Install event handler
617 _pEventHandler = NewEventHandlerUPP(eventHandler);
619 EventTypeSpec eventList[] =
621 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
622 { kEventClassMouse, kEventMouseDown },
623 { kEventClassMouse, kEventMouseUp },
624 { kEventClassMouse, kEventMouseDragged },
625 { kEventClassWindow, kEventWindowClose },
626 { kEventClassWindow, kEventWindowDrawContent },
627 { kEventClassWindow, kEventWindowBoundsChanged }
630 InstallWindowEventHandler(_pLocalWindow, _pEventHandler,
631 GetEventTypeCount(eventList),
632 eventList, this, 0);
634 aglSetWindowRef(_pContext, _pLocalWindow);
636 _pCarbWindow = pCarbonWindow;
638 _pCarbWindow->setContext(_pContext);
639 _pCarbWindow->init ( );
640 _pCarbWindow->resize ( uiWidth,
641 uiHeight);
643 std::string windowName(" OpenSG - CSM - ");
645 _pCarbWindow->activate();
647 windowName += reinterpret_cast<const char *>(glGetString(GL_VERSION));
648 windowName += " - ";
649 windowName += reinterpret_cast<const char *>(glGetString(GL_RENDERER));
651 _pCarbWindow->deactivate();
653 SetWTitle(_pLocalWindow,
654 reinterpret_cast<const unsigned char *>(windowName.c_str()));
656 // Show window
657 RepositionWindow(_pLocalWindow, 0, kWindowCascadeOnMainScreen);
658 ShowWindow (_pLocalWindow );
660 if(ComplexSceneManager::the() != NULL &&
661 this->getRegisterMainLoop() == true )
663 ComplexSceneManager::the()->setMainloop(
664 &CSMNativeWindow::carbonMainLoop);
667 _pWindow = _pCarbWindow;
669 _bRun = true;
671 Inherited::init();
673 return true;
676 void CSMNativeWindow::initWindowSystemThreading(void)
680 OSG_END_NAMESPACE