diff options
author | Damien Plisson <damien.plisson@yahoo.fr> | 2009-10-09 16:48:28 +0400 |
---|---|---|
committer | Damien Plisson <damien.plisson@yahoo.fr> | 2009-10-09 16:48:28 +0400 |
commit | ca3e77813446a8fbdd654dff1e4f5739f462543b (patch) | |
tree | baa5de1b6dcbf1a2dd8e7491dfdcaeec2ff68908 /intern | |
parent | ae6c08ac5e7009dca591c39569a16802664dd0c4 (diff) |
Cocoa port :
- Fullscreen mode is back!
- Cleaner fix for tablet events handling
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.h | 3 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.mm | 310 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowCocoa.h | 24 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowCocoa.mm | 378 |
4 files changed, 204 insertions, 511 deletions
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index eab5a5b28aa..ee7f9d8ed37 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -210,9 +210,10 @@ protected: /** * Handles a tablet event. * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) + * @param eventType The type of the event. It needs to be passed separately as it can be either directly in the event type, or as a subtype if combined with a mouse button event * @return Indication whether the event was handled. */ - GHOST_TSuccess handleTabletEvent(void *eventPtr); + GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType); /** * Handles a mouse event. diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 7f98f67a1ba..481dd705265 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -51,43 +51,6 @@ #pragma mark KeyMap, mouse converters -//TODO: remove (kept as reminder to implement window events) -/* -const EventTypeSpec kEvents[] = -{ - { kEventClassAppleEvent, kEventAppleEvent }, - -// { kEventClassApplication, kEventAppActivated }, -// { kEventClassApplication, kEventAppDeactivated }, - - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyRepeat }, - { kEventClassKeyboard, kEventRawKeyUp }, - { kEventClassKeyboard, kEventRawKeyModifiersChanged }, - - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseUp }, - { kEventClassMouse, kEventMouseMoved }, - { kEventClassMouse, kEventMouseDragged }, - { kEventClassMouse, kEventMouseWheelMoved }, - - { kEventClassWindow, kEventWindowClickZoomRgn } , // for new zoom behaviour - { kEventClassWindow, kEventWindowZoom }, // for new zoom behaviour - { kEventClassWindow, kEventWindowExpand } , // for new zoom behaviour - { kEventClassWindow, kEventWindowExpandAll }, // for new zoom behaviour - - { kEventClassWindow, kEventWindowClose }, - { kEventClassWindow, kEventWindowActivated }, - { kEventClassWindow, kEventWindowDeactivated }, - { kEventClassWindow, kEventWindowUpdate }, - { kEventClassWindow, kEventWindowBoundsChanged }, - - { kEventClassBlender, kEventBlenderNdofAxis }, - { kEventClassBlender, kEventBlenderNdofButtons } - - - -};*/ /* Keycodes from Carbon include file */ /* @@ -701,25 +664,6 @@ GHOST_TSuccess GHOST_SystemCocoa::init() } [pool drain]; - - /* - * Initialize the cursor to the standard arrow shape (so that we can change it later on). - * This initializes the cursor's visibility counter to 0. - */ - /*::InitCursor(); - - MenuRef windMenu; - ::CreateStandardWindowMenu(0, &windMenu); - ::InsertMenu(windMenu, 0); - ::DrawMenuBar(); - - ::InstallApplicationEventHandler(sEventHandlerProc, GetEventTypeCount(kEvents), kEvents, this, &m_handler); - - ::AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, sAEHandlerLaunch, (SInt32) this, false); - ::AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, sAEHandlerOpenDocs, (SInt32) this, false); - ::AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, sAEHandlerPrintDocs, (SInt32) this, false); - ::AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, sAEHandlerQuit, (SInt32) this, false); - */ } return success; } @@ -789,6 +733,13 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_IWindow* window = 0; + //First check if we are in fullscreen mode + //If so, exit it before creating a new window + window = m_windowManager->getActiveWindow(); + if (window && (window->getState() == GHOST_kWindowStateFullScreen)) + window->setState(GHOST_kWindowStateNormal); + window = NULL; + //Get the available rect for including window contents NSRect frame = [[NSScreen mainScreen] visibleFrame]; NSRect contentRect = [NSWindow contentRectForFrameRect:frame @@ -826,27 +777,18 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( GHOST_TSuccess GHOST_SystemCocoa::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual) { - GHOST_TSuccess success = GHOST_kFailure; + GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow(); - //TODO: update this method - // need yo make this Carbon all on 10.5 for fullscreen to work correctly - CGCaptureAllDisplays(); - - success = GHOST_System::beginFullScreen( setting, window, stereoVisual); + *window = currentWindow; - if( success != GHOST_kSuccess ) { - // fullscreen failed for other reasons, release - CGReleaseAllDisplays(); - } - - return success; + return currentWindow->setState(GHOST_kWindowStateFullScreen); } GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void) { - //TODO: update this method - CGReleaseAllDisplays(); - return GHOST_System::endFullScreen(); + GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow(); + + return currentWindow->setState(GHOST_kWindowStateNormal); } @@ -936,8 +878,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) anyProcessed = true; } - //TODO: check fullscreen redrawing issues - if (getFullScreen()) { + if (getFullScreen()) { // Check if the full-screen window is dirty GHOST_IWindow* window = m_windowManager->getFullScreenWindow(); if (((GHOST_WindowCarbon*)window)->getFullScreenDirty()) { @@ -987,7 +928,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) case NSTabletPoint: case NSTabletProximity: - handleTabletEvent(event); + handleTabletEvent(event,[event type]); break; /* Trackpad features, will need OS X 10.6 for implementation @@ -1028,8 +969,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, if (!validWindow(window)) { return GHOST_kFailure; } - - //if (!getFullScreen()) { switch(eventType) { case GHOST_kEventWindowClose: @@ -1045,7 +984,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) ); break; case GHOST_kEventWindowUpdate: - //if (getFullScreen()) GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen update event\n"); pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) ); break; case GHOST_kEventWindowSize: @@ -1059,12 +997,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, return GHOST_kFailure; break; } -// } - //else { - //window = (GHOST_WindowCarbon*) m_windowManager->getFullScreenWindow(); - //GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen window event, " << window << "\n"); - //::RemoveEventFromQueue(::GetMainEventQueue(), event); - //} return GHOST_kSuccess; } @@ -1073,6 +1005,13 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest() //Check open windows if some changes are not saved if (m_windowManager->getAnyModifiedState()) { + //First check if we are in fullscreen mode + //If so, exit it before creating a new window + GHOST_IWindow *window = m_windowManager->getActiveWindow(); + if (window && (window->getState() == GHOST_kWindowStateFullScreen)) + window->setState(GHOST_kWindowStateNormal); + window = NULL; + int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved. Do you really want to quit ?", @"Cancel", @"Quit anyway", nil); if (shouldQuit == NSAlertAlternateReturn) @@ -1090,35 +1029,13 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest() } -GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) +GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventType) { NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData(); - NSUInteger tabletEvent; - - //Handle tablet events combined with mouse events - @try { - switch ([event subtype]) { - case NX_SUBTYPE_TABLET_POINT: - tabletEvent = NSTabletPoint; - break; - case NX_SUBTYPE_TABLET_PROXIMITY: - tabletEvent = NSTabletProximity; - break; - - default: - tabletEvent = [event type]; - break; - } - } - @catch (NSException * e) { - //FIXME: check why we get such exceptions when using a tablet - return GHOST_kFailure; - } - - switch (tabletEvent) { + switch (eventType) { case NSTabletPoint: ct.Pressure = [event tangentialPressure]; ct.Xtilt = [event tilt].x; @@ -1175,20 +1092,53 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSRightMouseDown: case NSOtherMouseDown: pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber]))); - handleTabletEvent(eventPtr); + //Handle tablet events combined with mouse events + switch ([event subtype]) { + case NX_SUBTYPE_TABLET_POINT: + handleTabletEvent(eventPtr, NSTabletPoint); + break; + case NX_SUBTYPE_TABLET_PROXIMITY: + handleTabletEvent(eventPtr, NSTabletProximity); + break; + default: + //No tablet event included : do nothing + break; + } break; case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber]))); - handleTabletEvent(eventPtr); + //Handle tablet events combined with mouse events + switch ([event subtype]) { + case NX_SUBTYPE_TABLET_POINT: + handleTabletEvent(eventPtr, NSTabletPoint); + break; + case NX_SUBTYPE_TABLET_PROXIMITY: + handleTabletEvent(eventPtr, NSTabletProximity); + break; + default: + //No tablet event included : do nothing + break; + } break; case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: - handleTabletEvent(eventPtr); + //Handle tablet events combined with mouse events + switch ([event subtype]) { + case NX_SUBTYPE_TABLET_POINT: + handleTabletEvent(eventPtr, NSTabletPoint); + break; + case NX_SUBTYPE_TABLET_PROXIMITY: + handleTabletEvent(eventPtr, NSTabletProximity); + break; + default: + //No tablet event included : do nothing + break; + } case NSMouseMoved: { NSPoint mousePos = [event locationInWindow]; @@ -1227,6 +1177,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) * the window go away and we still get an HKey up. */ if (!window) { + printf("\nW failure"); return GHOST_kFailure; } @@ -1246,7 +1197,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask)) break; //Cmd-Q is directly handled by Cocoa - + if ([event type] == NSKeyDown) { pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, keyCode, ascii) ); //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii); @@ -1282,143 +1233,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) } -/* System wide mouse clicks are handled directly through systematic event forwarding to Cocoa -bool GHOST_SystemCarbon::handleMouseDown(void *eventPtr) -{ - NSEvent *event = (NSEvent *)eventPtr; - WindowPtr window; - short part; - BitMap screenBits; - bool handled = true; - GHOST_WindowCarbon* ghostWindow; - Point mousePos = {0 , 0}; - - ::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mousePos); - - part = ::FindWindow(mousePos, &window); - ghostWindow = (GHOST_WindowCarbon*) ::GetWRefCon(window); - - switch (part) { - case inMenuBar: - handleMenuCommand(::MenuSelect(mousePos)); - break; - - case inDrag: - // * - // * The DragWindow() routine creates a lot of kEventWindowBoundsChanged - // * events. By setting m_ignoreWindowSizedMessages these are suppressed. - // * @see GHOST_SystemCarbon::handleWindowEvent(EventRef event) - // * - // even worse: scale window also generates a load of events, and nothing - // is handled (read: client's event proc called) until you release mouse (ton) - - GHOST_ASSERT(validWindow(ghostWindow), "GHOST_SystemCarbon::handleMouseDown: invalid window"); - m_ignoreWindowSizedMessages = true; - ::DragWindow(window, mousePos, &GetQDGlobalsScreenBits(&screenBits)->bounds); - m_ignoreWindowSizedMessages = false; - - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, ghostWindow) ); - - break; - - case inContent: - if (window != ::FrontWindow()) { - ::SelectWindow(window); - // - // * We add a mouse down event on the newly actived window - // * - //GHOST_PRINT("GHOST_SystemCarbon::handleMouseDown(): adding mouse down event, " << ghostWindow << "\n"); - EventMouseButton button; - ::GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button); - pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonDown, ghostWindow, convertButton(button))); - } else { - handled = false; - } - break; - - case inGoAway: - GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0"); - if (::TrackGoAway(window, mousePos)) - { - // todo: add option-close, because itÿs in the HIG - // if (event.modifiers & optionKey) { - // Close the clean documents, others will be confirmed one by one. - //} - // else { - pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, ghostWindow)); - //} - } - break; - - case inGrow: - GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0"); - ::ResizeWindow(window, mousePos, NULL, NULL); - break; - - case inZoomIn: - case inZoomOut: - GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0"); - if (::TrackBox(window, mousePos, part)) { - int macState; - - macState = ghostWindow->getMac_windowState(); - if ( macState== 0) - ::ZoomWindow(window, part, true); - else - if (macState == 2) { // always ok - ::ZoomWindow(window, part, true); - ghostWindow->setMac_windowState(1); - } else { // need to force size again - // GHOST_TUns32 scr_x,scr_y; //unused - Rect outAvailableRect; - - ghostWindow->setMac_windowState(2); - ::GetAvailableWindowPositioningBounds ( GetMainDevice(), &outAvailableRect); - - //this->getMainDisplayDimensions(scr_x,scr_y); - ::SizeWindow (window, outAvailableRect.right-outAvailableRect.left,outAvailableRect.bottom-outAvailableRect.top-1,false); - ::MoveWindow (window, outAvailableRect.left, outAvailableRect.top,true); - } - - } - break; - - default: - handled = false; - break; - } - - return handled; -} - - -bool GHOST_SystemCarbon::handleMenuCommand(GHOST_TInt32 menuResult) -{ - short menuID; - short menuItem; - UInt32 command; - bool handled; - OSErr err; - - menuID = HiWord(menuResult); - menuItem = LoWord(menuResult); - - err = ::GetMenuItemCommandID(::GetMenuHandle(menuID), menuItem, &command); - - handled = false; - - if (err || command == 0) { - } - else { - switch(command) { - } - } - - ::HiliteMenu(0); - return handled; -}*/ - - #pragma mark Clipboard get/set diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 5ff205d964f..8c2919d1ce2 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -70,7 +70,7 @@ public: * @param stereoVisual Stereo visual for quad buffered stereo. */ GHOST_WindowCocoa( - const GHOST_SystemCocoa *systemCocoa, + GHOST_SystemCocoa *systemCocoa, const STR_String& title, GHOST_TInt32 left, GHOST_TInt32 top, @@ -204,16 +204,6 @@ public: virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const; - /** - * Returns the dirty state of the window when in full-screen mode. - * @return Whether it is dirty. - */ - virtual bool getFullScreenDirty(); - - /* accessor for fullscreen window */ - /*virtual void setMac_windowState(short value); - virtual short getMac_windowState();*/ - const GHOST_TabletData* GetTabletData() { return &m_tablet; } @@ -270,19 +260,13 @@ protected: /** The opgnGL drawing context */ NSOpenGLContext *m_openGLContext; - //CGrafPtr m_grafPtr; - //AGLContext m_aglCtx; - - /** The first created OpenGL context (for sharing display lists) */ - //static AGLContext s_firstaglCtx; - + /** The mother SystemCocoa class to send events */ + GHOST_SystemCocoa *m_systemCocoa; + NSCursor* m_customCursor; GHOST_TabletData m_tablet; - /** When running in full-screen this tells whether to refresh the window. */ - bool m_fullScreenDirty; - /** * The width/height of the size rectangle in the lower right corner of a * Mac/Carbon window. This is also the height of the gutter area. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index a185aa036b1..f4c9172c668 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -32,57 +32,20 @@ #include "GHOST_WindowCocoa.h" #include "GHOST_SystemCocoa.h" #include "GHOST_Debug.h" -/* -AGLContext GHOST_WindowCocoa::s_firstaglCtx = NULL; -#ifdef GHOST_DRAW_CARBON_GUTTER -const GHOST_TInt32 GHOST_WindowCocoa::s_sizeRectSize = 16; -#endif //GHOST_DRAW_CARBON_GUTTER - -static const GLint sPreferredFormatWindow[8] = { -AGL_RGBA, -AGL_DOUBLEBUFFER, -AGL_ACCELERATED, -AGL_DEPTH_SIZE, 32, -AGL_NONE, -}; - -static const GLint sPreferredFormatFullScreen[9] = { -AGL_RGBA, -AGL_DOUBLEBUFFER, -AGL_ACCELERATED, -AGL_FULLSCREEN, -AGL_DEPTH_SIZE, 32, -AGL_NONE, -}; - -WindowRef ugly_hack=NULL; - -const EventTypeSpec kWEvents[] = { - { kEventClassWindow, kEventWindowZoom }, // for new zoom behaviour +// Pixel Format Attributes for the windowed NSOpenGLContext +static const NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = +{ + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAAccelerated, + NSOpenGLPFAAllowOfflineRenderers, // NOTE: Needed to connect to secondary GPUs + NSOpenGLPFADepthSize, 32, + 0 }; -static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) { - WindowRef mywindow; - GHOST_WindowCocoa *ghost_window; - OSStatus err; - int theState; - - if (::GetEventKind(event) == kEventWindowZoom) { - err = ::GetEventParameter (event,kEventParamDirectObject,typeWindowRef,NULL,sizeof(mywindow),NULL, &mywindow); - ghost_window = (GHOST_WindowCocoa *) GetWRefCon(mywindow); - theState = ghost_window->getMac_windowState(); - if (theState == 1) - ghost_window->setMac_windowState(2); - else if (theState == 2) - ghost_window->setMac_windowState(1); - - } - return eventNotHandledErr; -}*/ - #pragma mark Cocoa delegate object + @interface CocoaWindowDelegate : NSObject { GHOST_SystemCocoa *systemCocoa; @@ -116,7 +79,10 @@ static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, - (void)windowDidResignKey:(NSNotification *)notification { - systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow); + //The window is no more key when its own view becomes fullscreen + //but ghost doesn't know the view/window difference, so hide this fact + if (associatedWindow->getState() != GHOST_kWindowStateFullScreen) + systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow); } - (void)windowDidUpdate:(NSNotification *)notification @@ -159,7 +125,7 @@ static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, #pragma mark initialization / finalization GHOST_WindowCocoa::GHOST_WindowCocoa( - const GHOST_SystemCocoa *systemCocoa, + GHOST_SystemCocoa *systemCocoa, const STR_String& title, GHOST_TInt32 left, GHOST_TInt32 top, @@ -170,136 +136,55 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( const bool stereoVisual ) : GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone), - m_customCursor(0), - m_fullScreenDirty(false) + m_customCursor(0) { + m_systemCocoa = systemCocoa; + m_fullScreen = false; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - //fprintf(stderr," main screen top %i left %i height %i width %i\n", top, left, height, width); - /* - if (state >= GHOST_kWindowState8Normal ) { - if(state == GHOST_kWindowState8Normal) state= GHOST_kWindowStateNormal; - else if(state == GHOST_kWindowState8Maximized) state= GHOST_kWindowStateMaximized; - else if(state == GHOST_kWindowState8Minimized) state= GHOST_kWindowStateMinimized; - else if(state == GHOST_kWindowState8FullScreen) state= GHOST_kWindowStateFullScreen; - - // state = state - 8; this was the simple version of above code, doesnt work in gcc 4.0 - - setMac_windowState(1); - } else - setMac_windowState(0); -*/ - if (state != GHOST_kWindowStateFullScreen) { - - //Creates the window - NSRect rect; - - rect.origin.x = left; - rect.origin.y = top; - rect.size.width = width; - rect.size.height = height; - - m_window = [[NSWindow alloc] initWithContentRect:rect - styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask - backing:NSBackingStoreBuffered defer:NO]; - if (m_window == nil) { - [pool drain]; - return; - } - - [m_window setTitle:[NSString stringWithUTF8String:title]]; - - - //Creates the OpenGL View inside the window - NSOpenGLPixelFormatAttribute attributes[] = - { - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAAccelerated, - NSOpenGLPFAAllowOfflineRenderers, // NOTE: Needed to connect to secondary GPUs - NSOpenGLPFADepthSize, 32, - 0 - }; - - NSOpenGLPixelFormat *pixelFormat = - [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - - m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect - pixelFormat:pixelFormat]; - - [pixelFormat release]; - - m_openGLContext = [m_openGLView openGLContext]; - - [m_window setContentView:m_openGLView]; - [m_window setInitialFirstResponder:m_openGLView]; - - [m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window - - [m_window makeKeyAndOrderFront:nil]; - - setDrawingContextType(type); - updateDrawingContext(); - activateDrawingContext(); - - // Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/ - /*gen2mac(title, title255); - - - err = ::CreateNewWindow( kDocumentWindowClass, - kWindowStandardDocumentAttributes+kWindowLiveResizeAttribute, - &bnds, - &m_windowRef); - - if ( err != noErr) { - fprintf(stderr," error creating window %i \n",(int)err); - } else { + + //Creates the window + NSRect rect; + + rect.origin.x = left; + rect.origin.y = top; + rect.size.width = width; + rect.size.height = height; + + m_window = [[NSWindow alloc] initWithContentRect:rect + styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask + backing:NSBackingStoreBuffered defer:NO]; + if (m_window == nil) { + [pool drain]; + return; + } + + [m_window setTitle:[NSString stringWithUTF8String:title]]; + - ::SetWRefCon(m_windowRef,(SInt32)this); - setTitle(title); - err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL); - if ( err != noErr) { - fprintf(stderr," error creating handler %i \n",(int)err); - } else { - // ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL); - ::ShowWindow(m_windowRef); - ::MoveWindow (m_windowRef, left, top,true); - - } - } - if (m_windowRef) { - m_grafPtr = ::GetWindowPort(m_windowRef); - setDrawingContextType(type); - updateDrawingContext(); - activateDrawingContext(); - } - if(ugly_hack==NULL) { - ugly_hack= m_windowRef; - // when started from commandline, window remains in the back... also for play anim - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - SetFrontProcess(&psn); - }*/ - } - else { - /* - Rect bnds = { top, left, top+height, left+width }; - gen2mac("", title255); - m_windowRef = ::NewCWindow( - nil, // Storage - &bnds, // Bounding rectangle of the window - title255, // Title of the window - 0, // Window initially visible - plainDBox, // procID - (WindowRef)-1L, // Put window before all other windows - 0, // Window has minimize box - (SInt32)this); // Store a pointer to the class in the refCon - */ - //GHOST_PRINT("GHOST_WindowCocoa::GHOST_WindowCocoa(): creating full-screen OpenGL context\n"); - setDrawingContextType(GHOST_kDrawingContextTypeOpenGL); - installDrawingContext(GHOST_kDrawingContextTypeOpenGL); - updateDrawingContext(); - activateDrawingContext(); - } + //Creates the OpenGL View inside the window + NSOpenGLPixelFormat *pixelFormat = + [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow]; + + m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect + pixelFormat:pixelFormat]; + + [pixelFormat release]; + + m_openGLContext = [m_openGLView openGLContext]; + + [m_window setContentView:m_openGLView]; + [m_window setInitialFirstResponder:m_openGLView]; + + [m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window + + [m_window makeKeyAndOrderFront:nil]; + + setDrawingContextType(type); + updateDrawingContext(); + activateDrawingContext(); + m_tablet.Active = GHOST_kTabletModeNone; CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init]; @@ -308,6 +193,9 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( [m_window setAcceptsMouseMovedEvents:YES]; + if (state == GHOST_kWindowStateFullScreen) + setState(GHOST_kWindowStateFullScreen); + [pool drain]; } @@ -401,19 +289,30 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid") NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSRect screenSize = [[m_window screen] visibleFrame]; + + if (!m_fullScreen) + { + NSRect screenSize = [[m_window screen] visibleFrame]; - //Max window contents as screen size (excluding title bar...) - NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize - styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; + //Max window contents as screen size (excluding title bar...) + NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize + styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; - rect = [m_window contentRectForFrameRect:[m_window frame]]; - - bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y); - bounds.m_l = rect.origin.x -contentRect.origin.x; - bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width; - bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y); - + rect = [m_window contentRectForFrameRect:[m_window frame]]; + + bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y); + bounds.m_l = rect.origin.x -contentRect.origin.x; + bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width; + bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y); + } + else { + NSRect screenSize = [[m_window screen] frame]; + + bounds.m_b = screenSize.origin.y + screenSize.size.height; + bounds.m_l = screenSize.origin.x; + bounds.m_r = screenSize.origin.x + screenSize.size.width; + bounds.m_t = screenSize.origin.y; + } [pool drain]; } @@ -469,7 +368,10 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid") NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_TWindowState state; - if ([m_window isMiniaturized]) { + if (m_fullScreen) { + state = GHOST_kWindowStateFullScreen; + } + else if ([m_window isMiniaturized]) { state = GHOST_kWindowStateMinimized; } else if ([m_window isZoomed]) { @@ -521,15 +423,50 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid") switch (state) { - case GHOST_kWindowStateMinimized: + case GHOST_kWindowStateMinimized: [m_window miniaturize:nil]; break; - case GHOST_kWindowStateMaximized: + case GHOST_kWindowStateMaximized: [m_window zoom:nil]; break; - case GHOST_kWindowStateNormal: + + case GHOST_kWindowStateFullScreen: + if (!m_fullScreen) + { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + //This status change needs to be done before Cocoa call to enter fullscreen mode + //to give window delegate hint not to forward its deactivation to ghost wm that doesn't know view/window difference + m_fullScreen = true; + + //Only 10.6 API will enable to manage several display in fullscreen mode, and topmenu autoshow + [m_openGLView enterFullScreenMode:[m_window screen] withOptions:nil]; + + //Tell WM of view new size + m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this); + + [pool drain]; + } + break; + case GHOST_kWindowStateNormal: default: - if ([m_window isMiniaturized]) + if (m_fullScreen) + { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + m_fullScreen = false; + + //Exit fullscreen + [m_openGLView exitFullScreenModeWithOptions:nil]; + + [m_window makeKeyAndOrderFront:nil]; + [m_window makeFirstResponder:m_openGLView]; + + //Tell WM of view new size + m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this); + + [pool drain]; + } + else if ([m_window isMiniaturized]) [m_window deminiaturize:nil]; else if ([m_window isZoomed]) [m_window zoom:nil]; @@ -540,8 +477,11 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [m_window setDocumentEdited:isUnsavedChanges]; + [pool drain]; return GHOST_Window::setModifiedState(isUnsavedChanges); } @@ -631,12 +571,11 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp case GHOST_kDrawingContextTypeOpenGL: if (!getValid()) break; - if(!m_fullScreen) - { pixelFormat = [m_openGLView pixelFormat]; tmpOpenGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:m_openGLContext]; if (tmpOpenGLContext == nil) + success = GHOST_kFailure; break; #ifdef WAIT_FOR_VSYNC /* wait for vsync, to avoid tearing artifacts */ @@ -645,37 +584,8 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp [m_openGLView setOpenGLContext:tmpOpenGLContext]; [tmpOpenGLContext setView:m_openGLView]; - //[m_openGLContext release]; + [m_openGLContext release]; m_openGLContext = tmpOpenGLContext; - } - /* - AGLPixelFormat pixelFormat; - if (!m_fullScreen) { - pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow); - m_aglCtx = ::aglCreateContext(pixelFormat, s_firstaglCtx); - if (!m_aglCtx) break; - if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx; - success = ::aglSetDrawable(m_aglCtx, m_grafPtr) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure; - } - else { - //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL\n"); -GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,sPreferredFormatFullScreen); - m_aglCtx = ::aglCreateContext(pixelFormat, 0); - if (!m_aglCtx) break; - if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx; - //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): created OpenGL context\n"); - //::CGGetActiveDisplayList(0, NULL, &m_numDisplays) - success = ::aglSetFullScreen(m_aglCtx, m_fullScreenWidth, m_fullScreenHeight, 75, 0) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure; - - if (success == GHOST_kSuccess) { - GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL succeeded\n"); - } - else { - GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL failed\n"); - } - - } - ::aglDestroyPixelFormat(pixelFormat);*/ break; case GHOST_kDrawingContextTypeNone: @@ -696,14 +606,16 @@ GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext() switch (m_drawingContextType) { case GHOST_kDrawingContextTypeOpenGL: [m_openGLView clearGLContext]; + [pool drain]; return GHOST_kSuccess; case GHOST_kDrawingContextTypeNone: + [pool drain]; return GHOST_kSuccess; break; default: + [pool drain]; return GHOST_kFailure; } - [pool drain]; } @@ -711,20 +623,7 @@ GHOST_TSuccess GHOST_WindowCocoa::invalidate() { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid") NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if (!m_fullScreen) { - [m_openGLView setNeedsDisplay:YES]; - } - else { - //EventRef event; - //OSStatus status = ::CreateEvent(NULL, kEventClassWindow, kEventWindowUpdate, 0, 0, &event); - //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): created event " << status << " \n"); - //status = ::SetEventParameter(event, kEventParamDirectObject, typeWindowRef, sizeof(WindowRef), this); - //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): set event parameter " << status << " \n"); - //status = ::PostEventToQueue(::GetMainEventQueue(), event, kEventPriorityStandard); - //status = ::SendEventToEventTarget(event, ::GetApplicationEventTarget()); - //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): added event to queue " << status << " \n"); - m_fullScreenDirty = true; - } + [m_openGLView setNeedsDisplay:YES]; [pool drain]; return GHOST_kSuccess; } @@ -803,11 +702,6 @@ void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) c } -bool GHOST_WindowCocoa::getFullScreenDirty() -{ - return m_fullScreen && m_fullScreenDirty; -} - GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) { |