Cocoa port : First pure Cocoa version !
(Mostly for very early testers) Cocoa uses coordinates with y=0 at bottom : updated wm_window.c and wm_event_system.c for COCOA build to avoid double conversions in response to mouse move events and GHOST_getCursorPosition Known limitations: No fullscreen support Font issue in preference panel libSDL uses some Carbon functions
This commit is contained in:
parent
8d54982f37
commit
07aba4f933
@ -46,6 +46,7 @@
|
||||
class GHOST_EventCursor;
|
||||
class GHOST_EventKey;
|
||||
class GHOST_EventWindow;
|
||||
class GHOST_WindowCocoa;
|
||||
|
||||
|
||||
class GHOST_SystemCocoa : public GHOST_System {
|
||||
@ -191,6 +192,13 @@ public:
|
||||
*/
|
||||
virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
|
||||
|
||||
/**
|
||||
* Handles a window event. Called by GHOST_WindowCocoa window delegate
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Initializes the system.
|
||||
@ -220,13 +228,6 @@ protected:
|
||||
*/
|
||||
GHOST_TSuccess handleKeyEvent(void *eventPtr);
|
||||
|
||||
/**
|
||||
* Handles a window event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleWindowEvent(void *eventPtr);
|
||||
|
||||
/**
|
||||
* Handles all basic Mac application stuff for a mouse down event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
@ -250,10 +251,7 @@ protected:
|
||||
* @param tmTask Pointer to the timer task that expired.
|
||||
*/
|
||||
//static void s_timerCallback(TMTaskPtr tmTask);
|
||||
|
||||
/** Cocoa autoReleasePool (void*) used for enablign standard C++ compilation */
|
||||
void* m_autoReleasePool;
|
||||
|
||||
|
||||
/** Event handler reference. */
|
||||
//EventHandlerRef m_handler;
|
||||
|
||||
|
@ -89,7 +89,157 @@ const EventTypeSpec kEvents[] =
|
||||
|
||||
};*/
|
||||
|
||||
static GHOST_TButtonMask convertButton(EventMouseButton button)
|
||||
/* Keycodes from Carbon include file */
|
||||
/*
|
||||
* Summary:
|
||||
* Virtual keycodes
|
||||
*
|
||||
* Discussion:
|
||||
* These constants are the virtual keycodes defined originally in
|
||||
* Inside Mac Volume V, pg. V-191. They identify physical keys on a
|
||||
* keyboard. Those constants with "ANSI" in the name are labeled
|
||||
* according to the key position on an ANSI-standard US keyboard.
|
||||
* For example, kVK_ANSI_A indicates the virtual keycode for the key
|
||||
* with the letter 'A' in the US keyboard layout. Other keyboard
|
||||
* layouts may have the 'A' key label on a different physical key;
|
||||
* in this case, pressing 'A' will generate a different virtual
|
||||
* keycode.
|
||||
*/
|
||||
enum {
|
||||
kVK_ANSI_A = 0x00,
|
||||
kVK_ANSI_S = 0x01,
|
||||
kVK_ANSI_D = 0x02,
|
||||
kVK_ANSI_F = 0x03,
|
||||
kVK_ANSI_H = 0x04,
|
||||
kVK_ANSI_G = 0x05,
|
||||
kVK_ANSI_Z = 0x06,
|
||||
kVK_ANSI_X = 0x07,
|
||||
kVK_ANSI_C = 0x08,
|
||||
kVK_ANSI_V = 0x09,
|
||||
kVK_ANSI_B = 0x0B,
|
||||
kVK_ANSI_Q = 0x0C,
|
||||
kVK_ANSI_W = 0x0D,
|
||||
kVK_ANSI_E = 0x0E,
|
||||
kVK_ANSI_R = 0x0F,
|
||||
kVK_ANSI_Y = 0x10,
|
||||
kVK_ANSI_T = 0x11,
|
||||
kVK_ANSI_1 = 0x12,
|
||||
kVK_ANSI_2 = 0x13,
|
||||
kVK_ANSI_3 = 0x14,
|
||||
kVK_ANSI_4 = 0x15,
|
||||
kVK_ANSI_6 = 0x16,
|
||||
kVK_ANSI_5 = 0x17,
|
||||
kVK_ANSI_Equal = 0x18,
|
||||
kVK_ANSI_9 = 0x19,
|
||||
kVK_ANSI_7 = 0x1A,
|
||||
kVK_ANSI_Minus = 0x1B,
|
||||
kVK_ANSI_8 = 0x1C,
|
||||
kVK_ANSI_0 = 0x1D,
|
||||
kVK_ANSI_RightBracket = 0x1E,
|
||||
kVK_ANSI_O = 0x1F,
|
||||
kVK_ANSI_U = 0x20,
|
||||
kVK_ANSI_LeftBracket = 0x21,
|
||||
kVK_ANSI_I = 0x22,
|
||||
kVK_ANSI_P = 0x23,
|
||||
kVK_ANSI_L = 0x25,
|
||||
kVK_ANSI_J = 0x26,
|
||||
kVK_ANSI_Quote = 0x27,
|
||||
kVK_ANSI_K = 0x28,
|
||||
kVK_ANSI_Semicolon = 0x29,
|
||||
kVK_ANSI_Backslash = 0x2A,
|
||||
kVK_ANSI_Comma = 0x2B,
|
||||
kVK_ANSI_Slash = 0x2C,
|
||||
kVK_ANSI_N = 0x2D,
|
||||
kVK_ANSI_M = 0x2E,
|
||||
kVK_ANSI_Period = 0x2F,
|
||||
kVK_ANSI_Grave = 0x32,
|
||||
kVK_ANSI_KeypadDecimal = 0x41,
|
||||
kVK_ANSI_KeypadMultiply = 0x43,
|
||||
kVK_ANSI_KeypadPlus = 0x45,
|
||||
kVK_ANSI_KeypadClear = 0x47,
|
||||
kVK_ANSI_KeypadDivide = 0x4B,
|
||||
kVK_ANSI_KeypadEnter = 0x4C,
|
||||
kVK_ANSI_KeypadMinus = 0x4E,
|
||||
kVK_ANSI_KeypadEquals = 0x51,
|
||||
kVK_ANSI_Keypad0 = 0x52,
|
||||
kVK_ANSI_Keypad1 = 0x53,
|
||||
kVK_ANSI_Keypad2 = 0x54,
|
||||
kVK_ANSI_Keypad3 = 0x55,
|
||||
kVK_ANSI_Keypad4 = 0x56,
|
||||
kVK_ANSI_Keypad5 = 0x57,
|
||||
kVK_ANSI_Keypad6 = 0x58,
|
||||
kVK_ANSI_Keypad7 = 0x59,
|
||||
kVK_ANSI_Keypad8 = 0x5B,
|
||||
kVK_ANSI_Keypad9 = 0x5C
|
||||
};
|
||||
|
||||
/* keycodes for keys that are independent of keyboard layout*/
|
||||
enum {
|
||||
kVK_Return = 0x24,
|
||||
kVK_Tab = 0x30,
|
||||
kVK_Space = 0x31,
|
||||
kVK_Delete = 0x33,
|
||||
kVK_Escape = 0x35,
|
||||
kVK_Command = 0x37,
|
||||
kVK_Shift = 0x38,
|
||||
kVK_CapsLock = 0x39,
|
||||
kVK_Option = 0x3A,
|
||||
kVK_Control = 0x3B,
|
||||
kVK_RightShift = 0x3C,
|
||||
kVK_RightOption = 0x3D,
|
||||
kVK_RightControl = 0x3E,
|
||||
kVK_Function = 0x3F,
|
||||
kVK_F17 = 0x40,
|
||||
kVK_VolumeUp = 0x48,
|
||||
kVK_VolumeDown = 0x49,
|
||||
kVK_Mute = 0x4A,
|
||||
kVK_F18 = 0x4F,
|
||||
kVK_F19 = 0x50,
|
||||
kVK_F20 = 0x5A,
|
||||
kVK_F5 = 0x60,
|
||||
kVK_F6 = 0x61,
|
||||
kVK_F7 = 0x62,
|
||||
kVK_F3 = 0x63,
|
||||
kVK_F8 = 0x64,
|
||||
kVK_F9 = 0x65,
|
||||
kVK_F11 = 0x67,
|
||||
kVK_F13 = 0x69,
|
||||
kVK_F16 = 0x6A,
|
||||
kVK_F14 = 0x6B,
|
||||
kVK_F10 = 0x6D,
|
||||
kVK_F12 = 0x6F,
|
||||
kVK_F15 = 0x71,
|
||||
kVK_Help = 0x72,
|
||||
kVK_Home = 0x73,
|
||||
kVK_PageUp = 0x74,
|
||||
kVK_ForwardDelete = 0x75,
|
||||
kVK_F4 = 0x76,
|
||||
kVK_End = 0x77,
|
||||
kVK_F2 = 0x78,
|
||||
kVK_PageDown = 0x79,
|
||||
kVK_F1 = 0x7A,
|
||||
kVK_LeftArrow = 0x7B,
|
||||
kVK_RightArrow = 0x7C,
|
||||
kVK_DownArrow = 0x7D,
|
||||
kVK_UpArrow = 0x7E
|
||||
};
|
||||
|
||||
/* ISO keyboards only*/
|
||||
enum {
|
||||
kVK_ISO_Section = 0x0A
|
||||
};
|
||||
|
||||
/* JIS keyboards only*/
|
||||
enum {
|
||||
kVK_JIS_Yen = 0x5D,
|
||||
kVK_JIS_Underscore = 0x5E,
|
||||
kVK_JIS_KeypadComma = 0x5F,
|
||||
kVK_JIS_Eisu = 0x66,
|
||||
kVK_JIS_Kana = 0x68
|
||||
};
|
||||
|
||||
|
||||
static GHOST_TButtonMask convertButton(int button)
|
||||
{
|
||||
switch (button) {
|
||||
case 0:
|
||||
@ -474,8 +624,6 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
|
||||
|
||||
GHOST_SystemCocoa::~GHOST_SystemCocoa()
|
||||
{
|
||||
NSAutoreleasePool* pool = (NSAutoreleasePool *)m_autoReleasePool;
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
|
||||
@ -492,16 +640,18 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
|
||||
SetFrontProcess(&psn);
|
||||
}*/
|
||||
|
||||
m_autoReleasePool = [[NSAutoreleasePool alloc] init];
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
if (NSApp == nil) {
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
if ([NSApp mainMenu] == nil) {
|
||||
NSMenu *mainMenubar = [[NSMenu alloc] init];
|
||||
NSMenuItem *menuItem;
|
||||
NSMenu *windowMenu;
|
||||
NSMenu *appMenu;
|
||||
|
||||
//Create the application menu
|
||||
NSMenu *appMenu = [[NSMenu alloc] initWithTitle:@"Blender"];
|
||||
appMenu = [[NSMenu alloc] initWithTitle:@"Blender"];
|
||||
|
||||
[appMenu addItemWithTitle:@"About Blender" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
|
||||
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||
@ -525,7 +675,7 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
|
||||
[appMenu release];
|
||||
|
||||
//Create the window menu
|
||||
NSMenu *windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
|
||||
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
|
||||
|
||||
menuItem = [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
|
||||
[menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
|
||||
@ -549,7 +699,8 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
|
||||
[appDelegate setSystemCocoa:this];
|
||||
[NSApp setDelegate:appDelegate];
|
||||
}
|
||||
|
||||
|
||||
[pool drain];
|
||||
|
||||
/*
|
||||
* Initialize the cursor to the standard arrow shape (so that we can change it later on).
|
||||
@ -597,12 +748,18 @@ GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const
|
||||
{
|
||||
//Note that OS X supports monitor hot plug
|
||||
// We do not support multiple monitors at the moment
|
||||
return [[NSScreen screens] count];
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
GHOST_TUns8 count = [[NSScreen screens] count];
|
||||
|
||||
[pool drain];
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
//Get visible frame, that is frame excluding dock and top menu bar
|
||||
NSRect frame = [[NSScreen mainScreen] visibleFrame];
|
||||
|
||||
@ -612,6 +769,8 @@ void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns
|
||||
|
||||
width = contentRect.size.width;
|
||||
height = contentRect.size.height;
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
|
||||
@ -627,7 +786,8 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
|
||||
const GHOST_TEmbedderWindowID parentWindow
|
||||
)
|
||||
{
|
||||
GHOST_IWindow* window = 0;
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
GHOST_IWindow* window = 0;
|
||||
|
||||
//Get the available rect for including window contents
|
||||
NSRect frame = [[NSScreen mainScreen] visibleFrame];
|
||||
@ -638,7 +798,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
|
||||
left = left > contentRect.origin.x ? left : contentRect.origin.x;
|
||||
top = top > contentRect.origin.y ? top : contentRect.origin.y;
|
||||
|
||||
window = new GHOST_WindowCocoa (title, left, top, width, height, state, type);
|
||||
window = new GHOST_WindowCocoa (this, title, left, top, width, height, state, type);
|
||||
|
||||
if (window) {
|
||||
if (window->getValid()) {
|
||||
@ -657,6 +817,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
|
||||
else {
|
||||
GHOST_PRINT("GHOST_SystemCocoa::createWindow(): could not create window\n");
|
||||
}
|
||||
[pool drain];
|
||||
return window;
|
||||
}
|
||||
|
||||
@ -713,7 +874,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32
|
||||
|
||||
GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) const
|
||||
{
|
||||
NSUInteger modifiers = [[NSApp currentEvent] modifierFlags];
|
||||
NSUInteger modifiers = [[NSApp currentEvent] modifierFlags];
|
||||
//Direct query to modifierFlags can be used in 10.6
|
||||
|
||||
keys.set(GHOST_kModifierKeyCommand, (modifiers & NSCommandKeyMask) ? true : false);
|
||||
@ -744,16 +905,9 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const
|
||||
*/
|
||||
bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
|
||||
{
|
||||
NSAutoreleasePool* pool = (NSAutoreleasePool*)m_autoReleasePool;
|
||||
//bool anyProcessed = false;
|
||||
bool anyProcessed = false;
|
||||
NSEvent *event;
|
||||
|
||||
//Reinit the AutoReleasePool
|
||||
//This is not done the typical Cocoa way (init at beginning of loop, and drain at the end)
|
||||
//to allow pool to work with other function calls outside this loop (but in same thread)
|
||||
[pool drain];
|
||||
m_autoReleasePool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// SetMouseCoalescingEnabled(false, NULL);
|
||||
//TODO : implement timer ??
|
||||
|
||||
@ -790,14 +944,17 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
|
||||
}*/
|
||||
|
||||
do {
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate distantPast]
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
if (event==nil)
|
||||
if (event==nil) {
|
||||
[pool drain];
|
||||
break;
|
||||
}
|
||||
|
||||
//anyProcessed = true;
|
||||
anyProcessed = true;
|
||||
|
||||
switch ([event type]) {
|
||||
case NSKeyDown:
|
||||
@ -853,47 +1010,42 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
|
||||
}
|
||||
//Resend event to NSApp to ensure Mac wide events are handled
|
||||
[NSApp sendEvent:event];
|
||||
[pool drain];
|
||||
} while (event!= nil);
|
||||
//} while (waitForEvent && !anyProcessed); Needed only for timer implementation
|
||||
|
||||
|
||||
return true; //anyProcessed;
|
||||
|
||||
return anyProcessed;
|
||||
}
|
||||
|
||||
//TODO: To be called from NSWindow delegate
|
||||
GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(void *eventPtr)
|
||||
//Note: called from NSWindow delegate
|
||||
GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window)
|
||||
{
|
||||
/*WindowRef windowRef;
|
||||
GHOST_WindowCocoa *window;
|
||||
|
||||
// Check if the event was send to a GHOST window
|
||||
::GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &windowRef);
|
||||
window = (GHOST_WindowCarbon*) ::GetWRefCon(windowRef);
|
||||
if (!validWindow(window)) {
|
||||
return err;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
//if (!getFullScreen()) {
|
||||
err = noErr;
|
||||
switch([event ])
|
||||
switch(eventType)
|
||||
{
|
||||
case kEventWindowClose:
|
||||
case GHOST_kEventWindowClose:
|
||||
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
|
||||
break;
|
||||
case kEventWindowActivated:
|
||||
case GHOST_kEventWindowActivate:
|
||||
m_windowManager->setActiveWindow(window);
|
||||
window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
|
||||
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) );
|
||||
break;
|
||||
case kEventWindowDeactivated:
|
||||
case GHOST_kEventWindowDeactivate:
|
||||
m_windowManager->setWindowInactive(window);
|
||||
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) );
|
||||
break;
|
||||
case kEventWindowUpdate:
|
||||
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 kEventWindowBoundsChanged:
|
||||
case GHOST_kEventWindowSize:
|
||||
if (!m_ignoreWindowSizedMessages)
|
||||
{
|
||||
window->updateDrawingContext();
|
||||
@ -901,7 +1053,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(void *eventPtr)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = eventNotHandledErr;
|
||||
return GHOST_kFailure;
|
||||
break;
|
||||
}
|
||||
// }
|
||||
@ -910,7 +1062,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(void *eventPtr)
|
||||
//GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen window event, " << window << "\n");
|
||||
//::RemoveEventFromQueue(::GetMainEventQueue(), event);
|
||||
//}
|
||||
*/
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
@ -943,10 +1094,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
|
||||
GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();
|
||||
NSUInteger tabletEvent;
|
||||
|
||||
ct.Pressure = 0;
|
||||
ct.Xtilt = 0;
|
||||
ct.Ytilt = 0;
|
||||
|
||||
//Handle tablet events combined with mouse events
|
||||
switch ([event subtype]) {
|
||||
case NX_SUBTYPE_TABLET_POINT:
|
||||
@ -969,6 +1116,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
|
||||
break;
|
||||
|
||||
case NSTabletProximity:
|
||||
ct.Pressure = 0;
|
||||
ct.Xtilt = 0;
|
||||
ct.Ytilt = 0;
|
||||
if ([event isEnteringProximity])
|
||||
{
|
||||
//pointer is entering tablet area proximity
|
||||
@ -1005,23 +1155,24 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
||||
NSEvent *event = (NSEvent *)eventPtr;
|
||||
GHOST_IWindow* window = m_windowManager->getActiveWindow();
|
||||
|
||||
if (!window) {
|
||||
printf("\nM invalid window");
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
switch ([event type])
|
||||
{
|
||||
case NSLeftMouseDown:
|
||||
case NSRightMouseDown:
|
||||
case NSOtherMouseDown:
|
||||
if (m_windowManager->getActiveWindow()) {
|
||||
pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
|
||||
}
|
||||
pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
|
||||
handleTabletEvent(eventPtr);
|
||||
break;
|
||||
|
||||
case NSLeftMouseUp:
|
||||
case NSRightMouseUp:
|
||||
case NSOtherMouseUp:
|
||||
if (m_windowManager->getActiveWindow()) {
|
||||
pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
|
||||
}
|
||||
pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
|
||||
handleTabletEvent(eventPtr);
|
||||
break;
|
||||
|
||||
@ -1098,16 +1249,16 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
|
||||
case NSFlagsChanged:
|
||||
modifiers = [event modifierFlags];
|
||||
if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
|
||||
pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );
|
||||
pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );
|
||||
}
|
||||
if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {
|
||||
pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) );
|
||||
pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) );
|
||||
}
|
||||
if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {
|
||||
pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) );
|
||||
pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) );
|
||||
}
|
||||
if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {
|
||||
pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) );
|
||||
pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) );
|
||||
}
|
||||
|
||||
m_modifierMask = modifiers;
|
||||
|
@ -40,8 +40,7 @@
|
||||
#include "GHOST_Window.h"
|
||||
#include "STR_String.h"
|
||||
|
||||
#include <AGL/agl.h>
|
||||
|
||||
class GHOST_SystemCocoa;
|
||||
|
||||
/**
|
||||
* Window on Mac OSX/Cocoa.
|
||||
@ -60,6 +59,7 @@ public:
|
||||
* Constructor.
|
||||
* Creates a new window and opens it.
|
||||
* To check if the window was created properly, use the getValid() method.
|
||||
* @param systemCocoa The associated system class to forward events to
|
||||
* @param title The text shown in the title bar of the window.
|
||||
* @param left The coordinate of the left edge of the window.
|
||||
* @param top The coordinate of the top edge of the window.
|
||||
@ -70,6 +70,7 @@ public:
|
||||
* @param stereoVisual Stereo visual for quad buffered stereo.
|
||||
*/
|
||||
GHOST_WindowCocoa(
|
||||
const GHOST_SystemCocoa *systemCocoa,
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left,
|
||||
GHOST_TInt32 top,
|
||||
@ -210,8 +211,8 @@ public:
|
||||
virtual bool getFullScreenDirty();
|
||||
|
||||
/* accessor for fullscreen window */
|
||||
virtual void setMac_windowState(short value);
|
||||
virtual short getMac_windowState();
|
||||
/*virtual void setMac_windowState(short value);
|
||||
virtual short getMac_windowState();*/
|
||||
|
||||
|
||||
const GHOST_TabletData* GetTabletData()
|
||||
@ -260,48 +261,28 @@ protected:
|
||||
|
||||
virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
|
||||
|
||||
/**
|
||||
* Converts a string object to a Mac Pascal string.
|
||||
* @param in The string object to be converted.
|
||||
* @param out The converted string.
|
||||
*/
|
||||
virtual void gen2mac(const STR_String& in, Str255 out) const;
|
||||
|
||||
/**
|
||||
* Converts a Mac Pascal string to a string object.
|
||||
* @param in The string to be converted.
|
||||
* @param out The converted string object.
|
||||
*/
|
||||
virtual void mac2gen(const Str255 in, STR_String& out) const;
|
||||
/** The window containing the OpenGL view */
|
||||
NSWindow *m_window;
|
||||
|
||||
WindowRef m_windowRef;
|
||||
CGrafPtr m_grafPtr;
|
||||
AGLContext m_aglCtx;
|
||||
/** The openGL view */
|
||||
NSOpenGLView *m_openGLView;
|
||||
|
||||
/** 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;
|
||||
//static AGLContext s_firstaglCtx;
|
||||
|
||||
Cursor* m_customCursor;
|
||||
NSCursor* m_customCursor;
|
||||
|
||||
GHOST_TabletData m_tablet;
|
||||
|
||||
/** When running in full-screen this tells whether to refresh the window. */
|
||||
bool m_fullScreenDirty;
|
||||
|
||||
/** specific MacOs X full screen window setting as we use partially system mechanism
|
||||
values : 0 not maximizable default
|
||||
1 normal state
|
||||
2 maximized state
|
||||
|
||||
this will be reworked when rebuilding GHOST carbon to use new OS X apis
|
||||
in order to be unified with GHOST fullscreen/maximised settings
|
||||
|
||||
(lukep)
|
||||
**/
|
||||
|
||||
short mac_windowState;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -21,26 +21,18 @@
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
* Contributor(s): Maarten Gribnau 05/2001
|
||||
Damien Plisson 10/2009
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright (C) 2001 NaN Technologies B.V.
|
||||
* @author Maarten Gribnau
|
||||
* @date May 10, 2001
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
#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;
|
||||
@ -68,7 +60,7 @@ AGL_NONE,
|
||||
WindowRef ugly_hack=NULL;
|
||||
|
||||
const EventTypeSpec kWEvents[] = {
|
||||
{ kEventClassWindow, kEventWindowZoom }, /* for new zoom behaviour */
|
||||
{ kEventClassWindow, kEventWindowZoom }, // for new zoom behaviour
|
||||
};
|
||||
|
||||
static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) {
|
||||
@ -88,9 +80,86 @@ static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event,
|
||||
|
||||
}
|
||||
return eventNotHandledErr;
|
||||
}*/
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
- (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
|
||||
|
||||
GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
const GHOST_SystemCocoa *systemCocoa,
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left,
|
||||
GHOST_TInt32 top,
|
||||
@ -101,17 +170,13 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
const bool stereoVisual
|
||||
) :
|
||||
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
|
||||
m_windowRef(0),
|
||||
m_grafPtr(0),
|
||||
m_aglCtx(0),
|
||||
m_customCursor(0),
|
||||
m_fullScreenDirty(false)
|
||||
{
|
||||
Str255 title255;
|
||||
OSStatus err;
|
||||
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;
|
||||
@ -123,26 +188,77 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
setMac_windowState(1);
|
||||
} else
|
||||
setMac_windowState(0);
|
||||
|
||||
*/
|
||||
if (state != GHOST_kWindowStateFullScreen) {
|
||||
Rect bnds = { top, left, top+height, left+width };
|
||||
// Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/
|
||||
gen2mac(title, title255);
|
||||
|
||||
//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",err);
|
||||
fprintf(stderr," error creating window %i \n",(int)err);
|
||||
} else {
|
||||
|
||||
::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",err);
|
||||
fprintf(stderr," error creating handler %i \n",(int)err);
|
||||
} else {
|
||||
// ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL);
|
||||
::ShowWindow(m_windowRef);
|
||||
@ -162,7 +278,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
ProcessSerialNumber psn;
|
||||
GetCurrentProcess(&psn);
|
||||
SetFrontProcess(&psn);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else {
|
||||
/*
|
||||
@ -179,12 +295,20 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
(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);
|
||||
setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);
|
||||
installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
|
||||
updateDrawingContext();
|
||||
activateDrawingContext();
|
||||
|
||||
m_tablet.Active = GHOST_kTabletModeNone;
|
||||
activateDrawingContext();
|
||||
}
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
@ -192,21 +316,26 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
|
||||
{
|
||||
if (m_customCursor) delete m_customCursor;
|
||||
|
||||
if(ugly_hack==m_windowRef) ugly_hack= NULL;
|
||||
/*if(ugly_hack==m_windowRef) ugly_hack= NULL;
|
||||
|
||||
// printf("GHOST_WindowCocoa::~GHOST_WindowCocoa(): removing drawing context\n");
|
||||
if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);
|
||||
if (m_windowRef) {
|
||||
::DisposeWindow(m_windowRef);
|
||||
m_windowRef = 0;
|
||||
if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);*/
|
||||
|
||||
[m_openGLView release];
|
||||
|
||||
if (m_window) {
|
||||
[m_window close];
|
||||
[m_window release];
|
||||
m_window = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark accessors
|
||||
|
||||
bool GHOST_WindowCocoa::getValid() const
|
||||
{
|
||||
bool valid;
|
||||
if (!m_fullScreen) {
|
||||
valid = (m_windowRef != 0) && (m_grafPtr != 0) && ::IsValidWindowPtr(m_windowRef);
|
||||
valid = (m_window != 0); //&& ::IsValidWindowPtr(m_windowRef);
|
||||
}
|
||||
else {
|
||||
valid = true;
|
||||
@ -218,57 +347,73 @@ bool GHOST_WindowCocoa::getValid() const
|
||||
void GHOST_WindowCocoa::setTitle(const STR_String& title)
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid")
|
||||
Str255 title255;
|
||||
gen2mac(title, title255);
|
||||
::SetWTitle(m_windowRef, title255);
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSString *windowTitle = [[NSString alloc] initWithUTF8String:title];
|
||||
|
||||
[m_window setTitle:windowTitle];
|
||||
|
||||
[windowTitle release];
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::getTitle(STR_String& title) const
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid")
|
||||
Str255 title255;
|
||||
::GetWTitle(m_windowRef, title255);
|
||||
mac2gen(title255, title);
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSString *windowTitle = [m_window title];
|
||||
|
||||
if (windowTitle != nil) {
|
||||
title = [windowTitle UTF8String];
|
||||
}
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const
|
||||
{
|
||||
OSStatus success;
|
||||
Rect rect;
|
||||
NSRect rect;
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid")
|
||||
success = ::GetWindowBounds(m_windowRef, kWindowStructureRgn, &rect);
|
||||
bounds.m_b = rect.bottom;
|
||||
bounds.m_l = rect.left;
|
||||
bounds.m_r = rect.right;
|
||||
bounds.m_t = rect.top;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
|
||||
{
|
||||
Rect rect;
|
||||
NSRect rect;
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid")
|
||||
//::GetPortBounds(m_grafPtr, &rect);
|
||||
::GetWindowBounds(m_windowRef, kWindowContentRgn, &rect);
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSRect screenSize = [[m_window screen] visibleFrame];
|
||||
|
||||
bounds.m_b = rect.bottom;
|
||||
bounds.m_l = rect.left;
|
||||
bounds.m_r = rect.right;
|
||||
bounds.m_t = rect.top;
|
||||
//Max window contents as screen size (excluding title bar...)
|
||||
NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize
|
||||
styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
|
||||
|
||||
// Subtract gutter height from bottom
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
if ((bounds.m_b - bounds.m_t) > s_sizeRectSize)
|
||||
{
|
||||
bounds.m_b -= s_sizeRectSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds.m_t = bounds.m_b;
|
||||
}
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
@ -278,7 +423,10 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
|
||||
GHOST_Rect cBnds, wBnds;
|
||||
getClientBounds(cBnds);
|
||||
if (((GHOST_TUns32)cBnds.getWidth()) != width) {
|
||||
::SizeWindow(m_windowRef, width, cBnds.getHeight(), true);
|
||||
NSSize size;
|
||||
size.width=width;
|
||||
size.height=cBnds.getHeight();
|
||||
[m_window setContentSize:size];
|
||||
}
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@ -289,15 +437,12 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid")
|
||||
GHOST_Rect cBnds, wBnds;
|
||||
getClientBounds(cBnds);
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
if (((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize) {
|
||||
::SizeWindow(m_windowRef, cBnds.getWidth(), height+s_sizeRectSize, true);
|
||||
}
|
||||
#else //GHOST_DRAW_CARBON_GUTTER
|
||||
if (((GHOST_TUns32)cBnds.getHeight()) != height) {
|
||||
::SizeWindow(m_windowRef, cBnds.getWidth(), height, true);
|
||||
NSSize size;
|
||||
size.width=cBnds.getWidth();
|
||||
size.height=height;
|
||||
[m_window setContentSize:size];
|
||||
}
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
@ -307,17 +452,13 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid")
|
||||
GHOST_Rect cBnds, wBnds;
|
||||
getClientBounds(cBnds);
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
|
||||
(((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize)) {
|
||||
::SizeWindow(m_windowRef, width, height+s_sizeRectSize, true);
|
||||
}
|
||||
#else //GHOST_DRAW_CARBON_GUTTER
|
||||
if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
|
||||
(((GHOST_TUns32)cBnds.getHeight()) != height)) {
|
||||
::SizeWindow(m_windowRef, width, height, true);
|
||||
NSSize size;
|
||||
size.width=width;
|
||||
size.height=height;
|
||||
[m_window setContentSize:size];
|
||||
}
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
@ -325,16 +466,18 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32
|
||||
GHOST_TWindowState GHOST_WindowCocoa::getState() const
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid")
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
GHOST_TWindowState state;
|
||||
if (::IsWindowVisible(m_windowRef) == false) {
|
||||
if ([m_window isMiniaturized]) {
|
||||
state = GHOST_kWindowStateMinimized;
|
||||
}
|
||||
else if (::IsWindowInStandardState(m_windowRef, nil, nil)) {
|
||||
else if ([m_window isZoomed]) {
|
||||
state = GHOST_kWindowStateMaximized;
|
||||
}
|
||||
else {
|
||||
state = GHOST_kWindowStateNormal;
|
||||
}
|
||||
[pool drain];
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -342,32 +485,34 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const
|
||||
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")
|
||||
Point point;
|
||||
point.h = inX;
|
||||
point.v = inY;
|
||||
GrafPtr oldPort;
|
||||
::GetPort(&oldPort);
|
||||
::SetPort(m_grafPtr);
|
||||
::GlobalToLocal(&point);
|
||||
::SetPort(oldPort);
|
||||
outX = point.h;
|
||||
outY = point.v;
|
||||
|
||||
NSPoint screenCoord;
|
||||
NSPoint baseCoord;
|
||||
|
||||
screenCoord.x = inX;
|
||||
screenCoord.y = inY;
|
||||
|
||||
baseCoord = [m_window convertScreenToBase:screenCoord];
|
||||
|
||||
outX = baseCoord.x;
|
||||
outY = baseCoord.y;
|
||||
}
|
||||
|
||||
|
||||
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")
|
||||
Point point;
|
||||
point.h = inX;
|
||||
point.v = inY;
|
||||
GrafPtr oldPort;
|
||||
::GetPort(&oldPort);
|
||||
::SetPort(m_grafPtr);
|
||||
::LocalToGlobal(&point);
|
||||
::SetPort(oldPort);
|
||||
outX = point.h;
|
||||
outY = point.v;
|
||||
|
||||
NSPoint screenCoord;
|
||||
NSPoint baseCoord;
|
||||
|
||||
baseCoord.x = inX;
|
||||
baseCoord.y = inY;
|
||||
|
||||
screenCoord = [m_window convertBaseToScreen:baseCoord];
|
||||
|
||||
outX = screenCoord.x;
|
||||
outY = screenCoord.y;
|
||||
}
|
||||
|
||||
|
||||
@ -376,12 +521,17 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid")
|
||||
switch (state) {
|
||||
case GHOST_kWindowStateMinimized:
|
||||
::HideWindow(m_windowRef);
|
||||
[m_window miniaturize:nil];
|
||||
break;
|
||||
case GHOST_kWindowStateMaximized:
|
||||
[m_window zoom:nil];
|
||||
break;
|
||||
case GHOST_kWindowStateNormal:
|
||||
default:
|
||||
::ShowWindow(m_windowRef);
|
||||
if ([m_window isMiniaturized])
|
||||
[m_window deminiaturize:nil];
|
||||
else if ([m_window isZoomed])
|
||||
[m_window zoom:nil];
|
||||
break;
|
||||
}
|
||||
return GHOST_kSuccess;
|
||||
@ -389,11 +539,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges)
|
||||
{
|
||||
if (isUnsavedChanges) {
|
||||
SetWindowModified(m_windowRef, 1);
|
||||
} else {
|
||||
SetWindowModified(m_windowRef, 0);
|
||||
}
|
||||
[m_window setDocumentEdited:isUnsavedChanges];
|
||||
|
||||
return GHOST_Window::setModifiedState(isUnsavedChanges);
|
||||
}
|
||||
@ -404,61 +550,45 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid")
|
||||
if (order == GHOST_kWindowOrderTop) {
|
||||
//::BringToFront(m_windowRef); is wrong, front window should be active for input too
|
||||
::SelectWindow(m_windowRef);
|
||||
[m_window orderFront:nil];
|
||||
}
|
||||
else {
|
||||
/* doesnt work if you do this with a mouseclick */
|
||||
::SendBehind(m_windowRef, nil);
|
||||
[m_window orderBack:nil];
|
||||
}
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
#pragma mark Drawing context
|
||||
|
||||
/*#define WAIT_FOR_VSYNC 1*/
|
||||
#ifdef WAIT_FOR_VSYNC
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#endif
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::swapBuffers()
|
||||
{
|
||||
#ifdef WAIT_FOR_VSYNC
|
||||
/* wait for vsync, to avoid tearing artifacts */
|
||||
long VBL = 1;
|
||||
CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL);
|
||||
#endif
|
||||
|
||||
GHOST_TSuccess succeeded = GHOST_kSuccess;
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_aglCtx) {
|
||||
::aglSwapBuffers(m_aglCtx);
|
||||
}
|
||||
else {
|
||||
succeeded = GHOST_kFailure;
|
||||
if (m_openGLContext != nil) {
|
||||
[m_openGLContext flushBuffer];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
}
|
||||
return succeeded;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::updateDrawingContext()
|
||||
{
|
||||
GHOST_TSuccess succeeded = GHOST_kSuccess;
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_aglCtx) {
|
||||
::aglUpdateContext(m_aglCtx);
|
||||
}
|
||||
else {
|
||||
succeeded = GHOST_kFailure;
|
||||
if (m_openGLContext != nil) {
|
||||
[m_openGLContext update];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
}
|
||||
return succeeded;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
|
||||
{
|
||||
GHOST_TSuccess succeeded = GHOST_kSuccess;
|
||||
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
|
||||
if (m_aglCtx) {
|
||||
::aglSetCurrentContext(m_aglCtx);
|
||||
if (m_openGLContext != nil) {
|
||||
[m_openGLContext makeCurrentContext];
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
// Restrict drawing to non-gutter area
|
||||
::aglEnable(m_aglCtx, AGL_BUFFER_RECT);
|
||||
@ -473,23 +603,44 @@ GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
|
||||
};
|
||||
GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b);
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
}
|
||||
else {
|
||||
succeeded = GHOST_kFailure;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
}
|
||||
return succeeded;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
GHOST_TSuccess success = GHOST_kFailure;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSOpenGLPixelFormat *pixelFormat;
|
||||
NSOpenGLContext *tmpOpenGLContext;
|
||||
|
||||
switch (type) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
{
|
||||
if (!getValid()) break;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
/*
|
||||
AGLPixelFormat pixelFormat;
|
||||
if (!m_fullScreen) {
|
||||
pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow);
|
||||
@ -507,17 +658,16 @@ GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,s
|
||||
//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);
|
||||
}
|
||||
::aglDestroyPixelFormat(pixelFormat);*/
|
||||
break;
|
||||
|
||||
case GHOST_kDrawingContextTypeNone:
|
||||
@ -527,41 +677,34 @@ GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,s
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[pool drain];
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext()
|
||||
{
|
||||
GHOST_TSuccess success = GHOST_kFailure;
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
switch (m_drawingContextType) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
if (m_aglCtx) {
|
||||
aglSetCurrentContext(NULL);
|
||||
aglSetDrawable(m_aglCtx, NULL);
|
||||
//aglDestroyContext(m_aglCtx);
|
||||
if (s_firstaglCtx == m_aglCtx) s_firstaglCtx = NULL;
|
||||
success = ::aglDestroyContext(m_aglCtx) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
m_aglCtx = 0;
|
||||
}
|
||||
break;
|
||||
[m_openGLView clearGLContext];
|
||||
return GHOST_kSuccess;
|
||||
case GHOST_kDrawingContextTypeNone:
|
||||
success = GHOST_kSuccess;
|
||||
return GHOST_kSuccess;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
return success;
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::invalidate()
|
||||
{
|
||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid")
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
if (!m_fullScreen) {
|
||||
Rect rect;
|
||||
::GetPortBounds(m_grafPtr, &rect);
|
||||
::InvalWindowRect(m_windowRef, &rect);
|
||||
[m_openGLView setNeedsDisplay:YES];
|
||||
}
|
||||
else {
|
||||
//EventRef event;
|
||||
@ -574,77 +717,81 @@ GHOST_TSuccess GHOST_WindowCocoa::invalidate()
|
||||
//GHOST_PRINT("GHOST_WindowCocoa::invalidate(): added event to queue " << status << " \n");
|
||||
m_fullScreenDirty = true;
|
||||
}
|
||||
[pool drain];
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
#pragma mark Cursor handling
|
||||
|
||||
void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
|
||||
{
|
||||
static bool systemCursorVisible = true;
|
||||
|
||||
NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSCursor *tmpCursor =nil;
|
||||
|
||||
if (visible != systemCursorVisible) {
|
||||
if (visible) {
|
||||
::ShowCursor();
|
||||
[NSCursor unhide];
|
||||
systemCursorVisible = true;
|
||||
}
|
||||
else {
|
||||
::HideCursor();
|
||||
[NSCursor hide];
|
||||
systemCursorVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
|
||||
::SetCursor( m_customCursor );
|
||||
tmpCursor = m_customCursor;
|
||||
} else {
|
||||
int carbon_cursor;
|
||||
|
||||
#define GCMAP(ghostCursor, carbonCursor) case ghostCursor: carbon_cursor = carbonCursor; break
|
||||
switch (cursor) {
|
||||
default:
|
||||
GCMAP( GHOST_kStandardCursorDefault, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorRightArrow, kThemeAliasArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorLeftArrow, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorInfo, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorDestroy, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorHelp, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorCycle, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorSpray, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorWait, kThemeWatchCursor);
|
||||
GCMAP( GHOST_kStandardCursorText, kThemeIBeamCursor);
|
||||
GCMAP( GHOST_kStandardCursorCrosshair, kThemeCrossCursor);
|
||||
GCMAP( GHOST_kStandardCursorUpDown, kThemeClosedHandCursor);
|
||||
GCMAP( GHOST_kStandardCursorLeftRight, kThemeClosedHandCursor);
|
||||
GCMAP( GHOST_kStandardCursorTopSide, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorBottomSide, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorLeftSide, kThemeResizeLeftCursor);
|
||||
GCMAP( GHOST_kStandardCursorRightSide, kThemeResizeRightCursor);
|
||||
GCMAP( GHOST_kStandardCursorTopLeftCorner, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorTopRightCorner, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorBottomRightCorner, kThemeArrowCursor);
|
||||
GCMAP( GHOST_kStandardCursorBottomLeftCorner, kThemeArrowCursor);
|
||||
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;
|
||||
};
|
||||
#undef GCMAP
|
||||
|
||||
::SetThemeCursor(carbon_cursor);
|
||||
}
|
||||
[tmpCursor set];
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
|
||||
@ -656,7 +803,7 @@ bool GHOST_WindowCocoa::getFullScreenDirty()
|
||||
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
|
||||
{
|
||||
if (::FrontWindow() == m_windowRef) {
|
||||
if ([m_window isVisible]) {
|
||||
loadCursor(visible, getCursorShape());
|
||||
}
|
||||
|
||||
@ -666,11 +813,11 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
|
||||
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
|
||||
{
|
||||
if (m_customCursor) {
|
||||
delete m_customCursor;
|
||||
m_customCursor = 0;
|
||||
[m_customCursor release];
|
||||
m_customCursor = nil;
|
||||
}
|
||||
|
||||
if (::FrontWindow() == m_windowRef) {
|
||||
if ([m_window isVisible]) {
|
||||
loadCursor(getCursorVisibility(), shape);
|
||||
}
|
||||
|
||||
@ -703,14 +850,15 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap
|
||||
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color)
|
||||
{
|
||||
int y;
|
||||
NSPoint hotSpotPoint;
|
||||
NSImage *cursorImage;
|
||||
|
||||
if (m_customCursor) {
|
||||
delete m_customCursor;
|
||||
m_customCursor = 0;
|
||||
[m_customCursor release];
|
||||
m_customCursor = nil;
|
||||
}
|
||||
|
||||
m_customCursor = new Cursor;
|
||||
if (!m_customCursor) return GHOST_kFailure;
|
||||
/*TODO: implement this (but unused inproject at present)
|
||||
cursorImage = [[NSImage alloc] initWithData:bitmap];
|
||||
|
||||
for (y=0; y<16; y++) {
|
||||
#if !defined(__LITTLE_ENDIAN__)
|
||||
@ -723,13 +871,21 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap
|
||||
|
||||
}
|
||||
|
||||
m_customCursor->hotSpot.h = hotX;
|
||||
m_customCursor->hotSpot.v = hotY;
|
||||
|
||||
if (::FrontWindow() == m_windowRef) {
|
||||
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]) {
|
||||
loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
|
||||
}
|
||||
|
||||
*/
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
@ -739,7 +895,9 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[
|
||||
return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1);
|
||||
}
|
||||
|
||||
#pragma mark Old carbon stuff to remove
|
||||
|
||||
#if 0
|
||||
void GHOST_WindowCocoa::setMac_windowState(short value)
|
||||
{
|
||||
mac_windowState = value;
|
||||
@ -749,3 +907,23 @@ short GHOST_WindowCocoa::getMac_windowState()
|
||||
{
|
||||
return mac_windowState;
|
||||
}
|
||||
|
||||
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
|
@ -1569,14 +1569,18 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
|
||||
case GHOST_kEventCursorMove: {
|
||||
if(win->active) {
|
||||
GHOST_TEventCursorData *cd= customdata;
|
||||
#if defined(__APPLE__) && defined(GHOST_COCOA)
|
||||
//Cocoa already uses coordinates with y=0 at bottom, and returns inwindow coordinates on mouse moved event
|
||||
event.type= MOUSEMOVE;
|
||||
event.x= evt->x = cd->x;
|
||||
event.y = evt->y = cd->y;
|
||||
#else
|
||||
int cx, cy;
|
||||
|
||||
GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy);
|
||||
|
||||
event.type= MOUSEMOVE;
|
||||
event.x= evt->x= cx;
|
||||
event.y= evt->y= (win->sizey-1) - cy;
|
||||
|
||||
#endif
|
||||
update_tablet_data(win, &event);
|
||||
wm_event_add(win, &event);
|
||||
}
|
||||
|
@ -608,7 +608,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
|
||||
|
||||
GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
|
||||
win->eventstate->x= cx;
|
||||
|
||||
#if defined(__APPLE__) && defined(GHOST_COCOA)
|
||||
//Cocoa already uses coordinates with y=0 at bottom
|
||||
win->eventstate->y= cy;
|
||||
#else
|
||||
win->eventstate->y= (win->sizey-1) - cy;
|
||||
#endif
|
||||
|
||||
wm_window_make_drawable(C, win);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user