2009-09-30 08:47:39 +00:00
|
|
|
/**
|
2009-09-30 17:13:57 +00:00
|
|
|
* $Id$
|
2009-09-30 08:47:39 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
*
|
2009-10-06 16:56:22 +00:00
|
|
|
* Contributor(s): Maarten Gribnau 05/2001
|
|
|
|
Damien Plisson 10/2009
|
2009-09-30 08:47:39 +00:00
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
#include <Cocoa/Cocoa.h>
|
2009-09-30 08:47:39 +00:00
|
|
|
|
|
|
|
#include "GHOST_WindowCocoa.h"
|
2009-10-06 16:56:22 +00:00
|
|
|
#include "GHOST_SystemCocoa.h"
|
2009-09-30 08:47:39 +00:00
|
|
|
#include "GHOST_Debug.h"
|
2009-10-06 16:56:22 +00:00
|
|
|
/*
|
2009-09-30 08:47:39 +00:00
|
|
|
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[] = {
|
2009-10-06 16:56:22 +00:00
|
|
|
{ kEventClassWindow, kEventWindowZoom }, // for new zoom behaviour
|
2009-09-30 08:47:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2009-10-06 16:56:22 +00:00
|
|
|
}*/
|
|
|
|
|
|
|
|
#pragma mark Cocoa delegate object
|
|
|
|
@interface CocoaWindowDelegate : NSObject
|
|
|
|
{
|
|
|
|
GHOST_SystemCocoa *systemCocoa;
|
|
|
|
GHOST_WindowCocoa *associatedWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setSystemAndWindowCocoa:(const GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
|
|
|
|
- (void)windowWillClose:(NSNotification *)notification;
|
|
|
|
- (void)windowDidBecomeKey:(NSNotification *)notification;
|
|
|
|
- (void)windowDidResignKey:(NSNotification *)notification;
|
|
|
|
- (void)windowDidUpdate:(NSNotification *)notification;
|
|
|
|
- (void)windowDidResize:(NSNotification *)notification;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation CocoaWindowDelegate : NSObject
|
|
|
|
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa
|
|
|
|
{
|
|
|
|
systemCocoa = sysCocoa;
|
|
|
|
associatedWindow = winCocoa;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)windowWillClose:(NSNotification *)notification
|
|
|
|
{
|
|
|
|
systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)windowDidBecomeKey:(NSNotification *)notification
|
|
|
|
{
|
|
|
|
systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)windowDidResignKey:(NSNotification *)notification
|
|
|
|
{
|
|
|
|
systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)windowDidUpdate:(NSNotification *)notification
|
|
|
|
{
|
|
|
|
systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
- (void)windowDidResize:(NSNotification *)notification
|
|
|
|
{
|
|
|
|
systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
#pragma mark NSOpenGLView subclass
|
|
|
|
//We need to subclass it in order to give Cocoa the feeling key events are trapped
|
|
|
|
@interface CocoaOpenGLView : NSOpenGLView
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation CocoaOpenGLView
|
|
|
|
|
|
|
|
- (BOOL)acceptsFirstResponder
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
//The trick to prevent Cocoa from complaining (beeping)
|
|
|
|
- (void)keyDown:(NSEvent *)theEvent
|
|
|
|
{}
|
|
|
|
|
|
|
|
- (BOOL)isOpaque
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark initialization / finalization
|
|
|
|
|
2009-09-30 08:47:39 +00:00
|
|
|
GHOST_WindowCocoa::GHOST_WindowCocoa(
|
2009-10-06 16:56:22 +00:00
|
|
|
const GHOST_SystemCocoa *systemCocoa,
|
2009-09-30 08:47:39 +00:00
|
|
|
const STR_String& title,
|
|
|
|
GHOST_TInt32 left,
|
|
|
|
GHOST_TInt32 top,
|
|
|
|
GHOST_TUns32 width,
|
|
|
|
GHOST_TUns32 height,
|
|
|
|
GHOST_TWindowState state,
|
|
|
|
GHOST_TDrawingContextType type,
|
|
|
|
const bool stereoVisual
|
|
|
|
) :
|
|
|
|
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
|
|
|
|
m_customCursor(0),
|
|
|
|
m_fullScreenDirty(false)
|
|
|
|
{
|
2009-10-06 16:56:22 +00:00
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
2009-09-30 08:47:39 +00:00
|
|
|
|
|
|
|
//fprintf(stderr," main screen top %i left %i height %i width %i\n", top, left, height, width);
|
2009-10-06 16:56:22 +00:00
|
|
|
/*
|
2009-09-30 08:47:39 +00:00
|
|
|
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);
|
2009-10-06 16:56:22 +00:00
|
|
|
*/
|
2009-09-30 08:47:39 +00:00
|
|
|
if (state != GHOST_kWindowStateFullScreen) {
|
2009-10-06 16:56:22 +00:00
|
|
|
|
|
|
|
//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);
|
2009-09-30 08:47:39 +00:00
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
|
2009-09-30 08:47:39 +00:00
|
|
|
err = ::CreateNewWindow( kDocumentWindowClass,
|
|
|
|
kWindowStandardDocumentAttributes+kWindowLiveResizeAttribute,
|
|
|
|
&bnds,
|
|
|
|
&m_windowRef);
|
|
|
|
|
|
|
|
if ( err != noErr) {
|
2009-10-06 16:56:22 +00:00
|
|
|
fprintf(stderr," error creating window %i \n",(int)err);
|
2009-09-30 08:47:39 +00:00
|
|
|
} else {
|
|
|
|
|
|
|
|
::SetWRefCon(m_windowRef,(SInt32)this);
|
|
|
|
setTitle(title);
|
|
|
|
err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL);
|
|
|
|
if ( err != noErr) {
|
2009-10-06 16:56:22 +00:00
|
|
|
fprintf(stderr," error creating handler %i \n",(int)err);
|
2009-09-30 08:47:39 +00:00
|
|
|
} 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);
|
2009-10-06 16:56:22 +00:00
|
|
|
}*/
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
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");
|
2009-10-06 16:56:22 +00:00
|
|
|
setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);
|
|
|
|
installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
|
2009-09-30 08:47:39 +00:00
|
|
|
updateDrawingContext();
|
2009-10-06 16:56:22 +00:00
|
|
|
activateDrawingContext();
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
m_tablet.Active = GHOST_kTabletModeNone;
|
|
|
|
|
|
|
|
CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init];
|
|
|
|
[windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
|
|
|
|
[m_window setDelegate:windowDelegate];
|
|
|
|
|
|
|
|
[m_window setAcceptsMouseMovedEvents:YES];
|
|
|
|
|
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_WindowCocoa::~GHOST_WindowCocoa()
|
|
|
|
{
|
|
|
|
if (m_customCursor) delete m_customCursor;
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
/*if(ugly_hack==m_windowRef) ugly_hack= NULL;
|
2009-09-30 08:47:39 +00:00
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);*/
|
2009-10-08 15:28:31 +00:00
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_openGLView release];
|
|
|
|
|
|
|
|
if (m_window) {
|
|
|
|
[m_window close];
|
|
|
|
[m_window release];
|
|
|
|
m_window = nil;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
2009-10-08 15:28:31 +00:00
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
#pragma mark accessors
|
|
|
|
|
2009-09-30 08:47:39 +00:00
|
|
|
bool GHOST_WindowCocoa::getValid() const
|
|
|
|
{
|
|
|
|
bool valid;
|
|
|
|
if (!m_fullScreen) {
|
2009-10-06 16:56:22 +00:00
|
|
|
valid = (m_window != 0); //&& ::IsValidWindowPtr(m_windowRef);
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
valid = true;
|
|
|
|
}
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GHOST_WindowCocoa::setTitle(const STR_String& title)
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid")
|
2009-10-06 16:56:22 +00:00
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
|
|
|
|
NSString *windowTitle = [[NSString alloc] initWithUTF8String:title];
|
|
|
|
|
|
|
|
[m_window setTitle:windowTitle];
|
|
|
|
|
|
|
|
[windowTitle release];
|
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GHOST_WindowCocoa::getTitle(STR_String& title) const
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid")
|
2009-10-06 16:56:22 +00:00
|
|
|
|
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
|
|
|
|
NSString *windowTitle = [m_window title];
|
|
|
|
|
|
|
|
if (windowTitle != nil) {
|
|
|
|
title = [windowTitle UTF8String];
|
|
|
|
}
|
|
|
|
|
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const
|
|
|
|
{
|
2009-10-06 16:56:22 +00:00
|
|
|
NSRect rect;
|
2009-09-30 08:47:39 +00:00
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid")
|
2009-10-06 16:56:22 +00:00
|
|
|
|
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
|
|
|
|
NSRect screenSize = [[m_window screen] visibleFrame];
|
|
|
|
|
|
|
|
rect = [m_window frame];
|
|
|
|
|
|
|
|
bounds.m_b = screenSize.size.height - (rect.origin.y -screenSize.origin.y);
|
|
|
|
bounds.m_l = rect.origin.x -screenSize.origin.x;
|
|
|
|
bounds.m_r = rect.origin.x-screenSize.origin.x + rect.size.width;
|
|
|
|
bounds.m_t = screenSize.size.height - (rect.origin.y + rect.size.height -screenSize.origin.y);
|
|
|
|
|
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
|
|
|
|
{
|
2009-10-06 16:56:22 +00:00
|
|
|
NSRect rect;
|
2009-09-30 08:47:39 +00:00
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid")
|
2009-10-06 16:56:22 +00:00
|
|
|
|
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
NSRect screenSize = [[m_window screen] visibleFrame];
|
2009-09-30 08:47:39 +00:00
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
//Max window contents as screen size (excluding title bar...)
|
|
|
|
NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize
|
|
|
|
styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
|
2009-09-30 08:47:39 +00:00
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
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);
|
|
|
|
|
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid")
|
|
|
|
GHOST_Rect cBnds, wBnds;
|
|
|
|
getClientBounds(cBnds);
|
|
|
|
if (((GHOST_TUns32)cBnds.getWidth()) != width) {
|
2009-10-06 16:56:22 +00:00
|
|
|
NSSize size;
|
|
|
|
size.width=width;
|
|
|
|
size.height=cBnds.getHeight();
|
|
|
|
[m_window setContentSize:size];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid")
|
|
|
|
GHOST_Rect cBnds, wBnds;
|
|
|
|
getClientBounds(cBnds);
|
|
|
|
if (((GHOST_TUns32)cBnds.getHeight()) != height) {
|
2009-10-06 16:56:22 +00:00
|
|
|
NSSize size;
|
|
|
|
size.width=cBnds.getWidth();
|
|
|
|
size.height=height;
|
|
|
|
[m_window setContentSize:size];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid")
|
|
|
|
GHOST_Rect cBnds, wBnds;
|
|
|
|
getClientBounds(cBnds);
|
|
|
|
if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
|
|
|
|
(((GHOST_TUns32)cBnds.getHeight()) != height)) {
|
2009-10-06 16:56:22 +00:00
|
|
|
NSSize size;
|
|
|
|
size.width=width;
|
|
|
|
size.height=height;
|
|
|
|
[m_window setContentSize:size];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_TWindowState GHOST_WindowCocoa::getState() const
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid")
|
2009-10-06 16:56:22 +00:00
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
2009-09-30 08:47:39 +00:00
|
|
|
GHOST_TWindowState state;
|
2009-10-06 16:56:22 +00:00
|
|
|
if ([m_window isMiniaturized]) {
|
2009-09-30 08:47:39 +00:00
|
|
|
state = GHOST_kWindowStateMinimized;
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
else if ([m_window isZoomed]) {
|
2009-09-30 08:47:39 +00:00
|
|
|
state = GHOST_kWindowStateMaximized;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
state = GHOST_kWindowStateNormal;
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid")
|
2009-10-06 16:56:22 +00:00
|
|
|
|
|
|
|
NSPoint screenCoord;
|
|
|
|
NSPoint baseCoord;
|
|
|
|
|
|
|
|
screenCoord.x = inX;
|
|
|
|
screenCoord.y = inY;
|
|
|
|
|
|
|
|
baseCoord = [m_window convertScreenToBase:screenCoord];
|
|
|
|
|
|
|
|
outX = baseCoord.x;
|
|
|
|
outY = baseCoord.y;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid")
|
2009-10-06 16:56:22 +00:00
|
|
|
|
|
|
|
NSPoint screenCoord;
|
|
|
|
NSPoint baseCoord;
|
|
|
|
|
|
|
|
baseCoord.x = inX;
|
|
|
|
baseCoord.y = inY;
|
|
|
|
|
|
|
|
screenCoord = [m_window convertBaseToScreen:baseCoord];
|
|
|
|
|
|
|
|
outX = screenCoord.x;
|
|
|
|
outY = screenCoord.y;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid")
|
|
|
|
switch (state) {
|
|
|
|
case GHOST_kWindowStateMinimized:
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_window miniaturize:nil];
|
2009-09-30 08:47:39 +00:00
|
|
|
break;
|
|
|
|
case GHOST_kWindowStateMaximized:
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_window zoom:nil];
|
|
|
|
break;
|
2009-09-30 08:47:39 +00:00
|
|
|
case GHOST_kWindowStateNormal:
|
|
|
|
default:
|
2009-10-06 16:56:22 +00:00
|
|
|
if ([m_window isMiniaturized])
|
|
|
|
[m_window deminiaturize:nil];
|
|
|
|
else if ([m_window isZoomed])
|
|
|
|
[m_window zoom:nil];
|
2009-09-30 08:47:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
|
2009-10-05 12:55:16 +00:00
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges)
|
|
|
|
{
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_window setDocumentEdited:isUnsavedChanges];
|
2009-10-05 12:55:16 +00:00
|
|
|
|
|
|
|
return GHOST_Window::setModifiedState(isUnsavedChanges);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-30 08:47:39 +00:00
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid")
|
|
|
|
if (order == GHOST_kWindowOrderTop) {
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_window orderFront:nil];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_window orderBack:nil];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
#pragma mark Drawing context
|
|
|
|
|
2009-09-30 08:47:39 +00:00
|
|
|
/*#define WAIT_FOR_VSYNC 1*/
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::swapBuffers()
|
|
|
|
{
|
|
|
|
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
2009-10-06 16:56:22 +00:00
|
|
|
if (m_openGLContext != nil) {
|
2009-10-08 15:28:31 +00:00
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_openGLContext flushBuffer];
|
2009-10-08 15:28:31 +00:00
|
|
|
[pool drain];
|
2009-10-06 16:56:22 +00:00
|
|
|
return GHOST_kSuccess;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
return GHOST_kFailure;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::updateDrawingContext()
|
|
|
|
{
|
|
|
|
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
2009-10-06 16:56:22 +00:00
|
|
|
if (m_openGLContext != nil) {
|
2009-10-08 15:28:31 +00:00
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_openGLContext update];
|
2009-10-08 15:28:31 +00:00
|
|
|
[pool drain];
|
2009-10-06 16:56:22 +00:00
|
|
|
return GHOST_kSuccess;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
return GHOST_kFailure;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
|
|
|
|
{
|
|
|
|
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
2009-10-06 16:56:22 +00:00
|
|
|
if (m_openGLContext != nil) {
|
2009-10-08 15:28:31 +00:00
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_openGLContext makeCurrentContext];
|
2009-09-30 08:47:39 +00:00
|
|
|
#ifdef GHOST_DRAW_CARBON_GUTTER
|
|
|
|
// Restrict drawing to non-gutter area
|
|
|
|
::aglEnable(m_aglCtx, AGL_BUFFER_RECT);
|
|
|
|
GHOST_Rect bnds;
|
|
|
|
getClientBounds(bnds);
|
|
|
|
GLint b[4] =
|
|
|
|
{
|
|
|
|
bnds.m_l,
|
|
|
|
bnds.m_t+s_sizeRectSize,
|
|
|
|
bnds.m_r-bnds.m_l,
|
|
|
|
bnds.m_b-bnds.m_t
|
|
|
|
};
|
|
|
|
GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b);
|
|
|
|
#endif //GHOST_DRAW_CARBON_GUTTER
|
2009-10-08 15:28:31 +00:00
|
|
|
[pool drain];
|
2009-10-06 16:56:22 +00:00
|
|
|
return GHOST_kSuccess;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
return GHOST_kFailure;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextType type)
|
|
|
|
{
|
|
|
|
GHOST_TSuccess success = GHOST_kFailure;
|
2009-10-06 16:56:22 +00:00
|
|
|
|
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
|
|
|
|
NSOpenGLPixelFormat *pixelFormat;
|
|
|
|
NSOpenGLContext *tmpOpenGLContext;
|
|
|
|
|
2009-09-30 08:47:39 +00:00
|
|
|
switch (type) {
|
|
|
|
case GHOST_kDrawingContextTypeOpenGL:
|
|
|
|
if (!getValid()) break;
|
2009-10-06 16:56:22 +00:00
|
|
|
|
|
|
|
if(!m_fullScreen)
|
|
|
|
{
|
|
|
|
pixelFormat = [m_openGLView pixelFormat];
|
|
|
|
tmpOpenGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
|
|
|
|
shareContext:m_openGLContext];
|
|
|
|
if (tmpOpenGLContext == nil)
|
|
|
|
break;
|
|
|
|
#ifdef WAIT_FOR_VSYNC
|
|
|
|
/* wait for vsync, to avoid tearing artifacts */
|
|
|
|
[tmpOpenGLContext setValues:1 forParameter:NSOpenGLCPSwapInterval];
|
|
|
|
#endif
|
|
|
|
[m_openGLView setOpenGLContext:tmpOpenGLContext];
|
|
|
|
[tmpOpenGLContext setView:m_openGLView];
|
|
|
|
|
|
|
|
//[m_openGLContext release];
|
|
|
|
m_openGLContext = tmpOpenGLContext;
|
|
|
|
}
|
|
|
|
/*
|
2009-09-30 08:47:39 +00:00
|
|
|
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;
|
2009-10-06 16:56:22 +00:00
|
|
|
|
2009-09-30 08:47:39 +00:00
|
|
|
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");
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
::aglDestroyPixelFormat(pixelFormat);*/
|
2009-09-30 08:47:39 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GHOST_kDrawingContextTypeNone:
|
|
|
|
success = GHOST_kSuccess;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext()
|
|
|
|
{
|
2009-10-06 16:56:22 +00:00
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
2009-09-30 08:47:39 +00:00
|
|
|
switch (m_drawingContextType) {
|
|
|
|
case GHOST_kDrawingContextTypeOpenGL:
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_openGLView clearGLContext];
|
|
|
|
return GHOST_kSuccess;
|
2009-09-30 08:47:39 +00:00
|
|
|
case GHOST_kDrawingContextTypeNone:
|
2009-10-06 16:56:22 +00:00
|
|
|
return GHOST_kSuccess;
|
2009-09-30 08:47:39 +00:00
|
|
|
break;
|
|
|
|
default:
|
2009-10-06 16:56:22 +00:00
|
|
|
return GHOST_kFailure;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::invalidate()
|
|
|
|
{
|
|
|
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid")
|
2009-10-06 16:56:22 +00:00
|
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
2009-09-30 08:47:39 +00:00
|
|
|
if (!m_fullScreen) {
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_openGLView setNeedsDisplay:YES];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
#pragma mark Cursor handling
|
2009-09-30 08:47:39 +00:00
|
|
|
|
|
|
|
void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
|
|
|
|
{
|
|
|
|
static bool systemCursorVisible = true;
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init];
|
|
|
|
|
|
|
|
NSCursor *tmpCursor =nil;
|
|
|
|
|
2009-09-30 08:47:39 +00:00
|
|
|
if (visible != systemCursorVisible) {
|
|
|
|
if (visible) {
|
2009-10-06 16:56:22 +00:00
|
|
|
[NSCursor unhide];
|
2009-09-30 08:47:39 +00:00
|
|
|
systemCursorVisible = true;
|
|
|
|
}
|
|
|
|
else {
|
2009-10-06 16:56:22 +00:00
|
|
|
[NSCursor hide];
|
2009-09-30 08:47:39 +00:00
|
|
|
systemCursorVisible = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
|
2009-10-06 16:56:22 +00:00
|
|
|
tmpCursor = m_customCursor;
|
2009-09-30 08:47:39 +00:00
|
|
|
} else {
|
|
|
|
switch (cursor) {
|
2009-10-06 16:56:22 +00:00
|
|
|
case GHOST_kStandardCursorDestroy:
|
|
|
|
tmpCursor = [NSCursor disappearingItemCursor];
|
|
|
|
break;
|
|
|
|
case GHOST_kStandardCursorText:
|
|
|
|
tmpCursor = [NSCursor IBeamCursor];
|
|
|
|
break;
|
|
|
|
case GHOST_kStandardCursorCrosshair:
|
|
|
|
tmpCursor = [NSCursor crosshairCursor];
|
|
|
|
break;
|
|
|
|
case GHOST_kStandardCursorUpDown:
|
|
|
|
tmpCursor = [NSCursor resizeUpDownCursor];
|
|
|
|
break;
|
|
|
|
case GHOST_kStandardCursorLeftRight:
|
|
|
|
tmpCursor = [NSCursor resizeLeftRightCursor];
|
|
|
|
break;
|
|
|
|
case GHOST_kStandardCursorTopSide:
|
|
|
|
tmpCursor = [NSCursor resizeUpCursor];
|
|
|
|
break;
|
|
|
|
case GHOST_kStandardCursorBottomSide:
|
|
|
|
tmpCursor = [NSCursor resizeDownCursor];
|
|
|
|
break;
|
|
|
|
case GHOST_kStandardCursorLeftSide:
|
|
|
|
tmpCursor = [NSCursor resizeLeftCursor];
|
|
|
|
break;
|
|
|
|
case GHOST_kStandardCursorRightSide:
|
|
|
|
tmpCursor = [NSCursor resizeRightCursor];
|
|
|
|
break;
|
|
|
|
case GHOST_kStandardCursorRightArrow:
|
|
|
|
case GHOST_kStandardCursorInfo:
|
|
|
|
case GHOST_kStandardCursorLeftArrow:
|
|
|
|
case GHOST_kStandardCursorHelp:
|
|
|
|
case GHOST_kStandardCursorCycle:
|
|
|
|
case GHOST_kStandardCursorSpray:
|
|
|
|
case GHOST_kStandardCursorWait:
|
|
|
|
case GHOST_kStandardCursorTopLeftCorner:
|
|
|
|
case GHOST_kStandardCursorTopRightCorner:
|
|
|
|
case GHOST_kStandardCursorBottomRightCorner:
|
|
|
|
case GHOST_kStandardCursorBottomLeftCorner:
|
|
|
|
case GHOST_kStandardCursorDefault:
|
|
|
|
default:
|
|
|
|
tmpCursor = [NSCursor arrowCursor];
|
|
|
|
break;
|
2009-09-30 08:47:39 +00:00
|
|
|
};
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
[tmpCursor set];
|
|
|
|
[pool drain];
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool GHOST_WindowCocoa::getFullScreenDirty()
|
|
|
|
{
|
|
|
|
return m_fullScreen && m_fullScreenDirty;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
|
|
|
|
{
|
2009-10-06 16:56:22 +00:00
|
|
|
if ([m_window isVisible]) {
|
2009-09-30 08:47:39 +00:00
|
|
|
loadCursor(visible, getCursorShape());
|
|
|
|
}
|
|
|
|
|
|
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
|
|
|
|
{
|
|
|
|
if (m_customCursor) {
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_customCursor release];
|
|
|
|
m_customCursor = nil;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
if ([m_window isVisible]) {
|
2009-09-30 08:47:39 +00:00
|
|
|
loadCursor(getCursorVisibility(), shape);
|
|
|
|
}
|
|
|
|
|
|
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/** Reverse the bits in a GHOST_TUns8 */
|
|
|
|
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
|
|
|
|
{
|
|
|
|
ch= ((ch>>1)&0x55) | ((ch<<1)&0xAA);
|
|
|
|
ch= ((ch>>2)&0x33) | ((ch<<2)&0xCC);
|
|
|
|
ch= ((ch>>4)&0x0F) | ((ch<<4)&0xF0);
|
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/** Reverse the bits in a GHOST_TUns16 */
|
|
|
|
static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
|
|
|
|
{
|
|
|
|
shrt= ((shrt>>1)&0x5555) | ((shrt<<1)&0xAAAA);
|
|
|
|
shrt= ((shrt>>2)&0x3333) | ((shrt<<2)&0xCCCC);
|
|
|
|
shrt= ((shrt>>4)&0x0F0F) | ((shrt<<4)&0xF0F0);
|
|
|
|
shrt= ((shrt>>8)&0x00FF) | ((shrt<<8)&0xFF00);
|
|
|
|
return shrt;
|
|
|
|
}
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
|
|
|
|
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color)
|
|
|
|
{
|
|
|
|
int y;
|
2009-10-06 16:56:22 +00:00
|
|
|
NSPoint hotSpotPoint;
|
|
|
|
NSImage *cursorImage;
|
2009-09-30 08:47:39 +00:00
|
|
|
|
|
|
|
if (m_customCursor) {
|
2009-10-06 16:56:22 +00:00
|
|
|
[m_customCursor release];
|
|
|
|
m_customCursor = nil;
|
2009-09-30 08:47:39 +00:00
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
/*TODO: implement this (but unused inproject at present)
|
|
|
|
cursorImage = [[NSImage alloc] initWithData:bitmap];
|
2009-09-30 08:47:39 +00:00
|
|
|
|
|
|
|
for (y=0; y<16; y++) {
|
|
|
|
#if !defined(__LITTLE_ENDIAN__)
|
|
|
|
m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));
|
|
|
|
m_customCursor->mask[y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8));
|
|
|
|
#else
|
|
|
|
m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));
|
|
|
|
m_customCursor->mask[y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
hotSpotPoint.x = hotX;
|
|
|
|
hotSpotPoint.y = hotY;
|
|
|
|
|
|
|
|
m_customCursor = [[NSCursor alloc] initWithImage:cursorImage
|
|
|
|
foregroundColorHint:<#(NSColor *)fg#>
|
|
|
|
backgroundColorHint:<#(NSColor *)bg#>
|
|
|
|
hotSpot:hotSpotPoint];
|
|
|
|
|
|
|
|
[cursorImage release];
|
|
|
|
|
|
|
|
if ([m_window isVisible]) {
|
2009-09-30 08:47:39 +00:00
|
|
|
loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
*/
|
2009-09-30 08:47:39 +00:00
|
|
|
return GHOST_kSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
|
|
|
|
GHOST_TUns8 mask[16][2], int hotX, int hotY)
|
|
|
|
{
|
|
|
|
return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1);
|
|
|
|
}
|
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
#pragma mark Old carbon stuff to remove
|
2009-09-30 08:47:39 +00:00
|
|
|
|
2009-10-06 16:56:22 +00:00
|
|
|
#if 0
|
2009-09-30 08:47:39 +00:00
|
|
|
void GHOST_WindowCocoa::setMac_windowState(short value)
|
|
|
|
{
|
|
|
|
mac_windowState = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
short GHOST_WindowCocoa::getMac_windowState()
|
|
|
|
{
|
|
|
|
return mac_windowState;
|
|
|
|
}
|
2009-10-06 16:56:22 +00:00
|
|
|
|
|
|
|
void GHOST_WindowCocoa::gen2mac(const STR_String& in, Str255 out) const
|
|
|
|
{
|
|
|
|
STR_String tempStr = in;
|
|
|
|
int num = tempStr.Length();
|
|
|
|
if (num > 255) num = 255;
|
|
|
|
::memcpy(out+1, tempStr.Ptr(), num);
|
|
|
|
out[0] = num;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GHOST_WindowCocoa::mac2gen(const Str255 in, STR_String& out) const
|
|
|
|
{
|
|
|
|
char tmp[256];
|
|
|
|
::memcpy(tmp, in+1, in[0]);
|
|
|
|
tmp[in[0]] = '\0';
|
|
|
|
out = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|