Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorDamien Plisson <damien.plisson@yahoo.fr>2009-10-09 16:48:28 +0400
committerDamien Plisson <damien.plisson@yahoo.fr>2009-10-09 16:48:28 +0400
commitca3e77813446a8fbdd654dff1e4f5739f462543b (patch)
treebaa5de1b6dcbf1a2dd8e7491dfdcaeec2ff68908 /intern
parentae6c08ac5e7009dca591c39569a16802664dd0c4 (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.h3
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm310
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h24
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm378
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)
{