From bd152c1fb75c4a8d4b9271896c44243ca8759e58 Mon Sep 17 00:00:00 2001 From: Geenz Date: Sat, 29 Dec 2012 06:59:43 -0500 Subject: Huge amount of refactoring to use Cocoa here: - Updated to .xib format. To produce a new nib (which is required after changing the xib file), use "ibtool SecondLife.xib --compile SecondLife.nib" within the newview directory. - xib file now defines the viewer's window. VIews are still being pragmatically added to the main window. This may change in the future. - LLAppViewer's main loop has been slightly refactored to be executed on a timer for OS X. This probably needs a bit more work. - Event handling still needs more work to work within a timer based event loop. It works fairly sporadically at the moment, as if events are being dropped between timer executions, at least for the mouse. - Carbon has been purged from the viewer's startup, and from LLWindow entirely. There's likely still a few odds and ends fragmented throughout the viewer and its dependencies. Need to track these down. - LLAppViewerMacOSX now uses NSApplicationMain, and also implements the NSApplicationDelegate protocol in LLAppDelegate. - Fullscreen support has been implemented for OS X 10.7+ This is still a work in progress, however at this stage everything needed for a functional viewer is (mostly) complete. From here, it's mostly just bug hunting and fixing. --- indra/newview/llappviewermacosx.cpp | 234 ++++++------------------------------ 1 file changed, 39 insertions(+), 195 deletions(-) (limited to 'indra/newview/llappviewermacosx.cpp') diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index c2916717bd..a1c8b7699d 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -31,6 +31,7 @@ #endif #include "llappviewermacosx.h" +#include "llappviewermacosx-objc.h" #include "llcommandlineparser.h" #include "llmemtype.h" @@ -53,7 +54,7 @@ namespace int gArgC; char** gArgV; - bool sCrashReporterIsRunning = false; + LLAppViewerMacOSX* gViewerAppPtr; OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) { @@ -65,55 +66,61 @@ namespace } } -int main( int argc, char **argv ) +bool initViewer() { LLMemType mt1(LLMemType::MTYPE_STARTUP); - -#if LL_SOLARIS && defined(__sparc) - asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC -#endif - + // Set the working dir to /Contents/Resources if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1) { llwarns << "Could not change directory to " - << gDirUtilp->getAppRODataDir() << ": " << strerror(errno) - << llendl; + << gDirUtilp->getAppRODataDir() << ": " << strerror(errno) + << llendl; } - - LLAppViewerMacOSX* viewer_app_ptr = new LLAppViewerMacOSX(); - - viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); - - // Store off the command line args for use later. - gArgC = argc; - gArgV = argv; - bool ok = viewer_app_ptr->init(); + gViewerAppPtr = new LLAppViewerMacOSX(); + + gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash); + + + + bool ok = gViewerAppPtr->init(); if(!ok) { llwarns << "Application init failed." << llendl; - return -1; } + + return ok; +} - // Run the application main loop - if(!LLApp::isQuitting()) +void handleQuit() +{ + if(!LLApp::isError()) { - viewer_app_ptr->mainLoop(); + gViewerAppPtr->cleanup(); } + + delete gViewerAppPtr; + gViewerAppPtr = NULL; +} - if (!LLApp::isError()) +bool runMainLoop() +{ + bool ret = LLApp::isQuitting(); + if (!ret) { - // - // We don't want to do cleanup here if the error handler got called - - // the assumption is that the error handler is responsible for doing - // app cleanup if there was a problem. - // - viewer_app_ptr->cleanup(); + ret = gViewerAppPtr->mainLoop(); } - delete viewer_app_ptr; - viewer_app_ptr = NULL; - return 0; + + return ret; +} + +int main( int argc, char **argv ) +{ + // Store off the command line args for use later. + gArgC = argc; + gArgV = argv; + return createNSApp(argc, (const char**)argv); } LLAppViewerMacOSX::LLAppViewerMacOSX() @@ -258,33 +265,6 @@ bool LLAppViewerMacOSX::restoreErrorTrap() return reset_count == 0; } -static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, - EventRef inEvent, - void* inUserData) -{ - ProcessSerialNumber psn; - - GetEventParameter(inEvent, - kEventParamProcessID, - typeProcessSerialNumber, - NULL, - sizeof(psn), - NULL, - &psn); - - if( GetEventKind(inEvent) == kEventAppTerminated ) - { - Boolean matching_psn = FALSE; - OSErr os_result = SameProcess(&psn, (ProcessSerialNumber*)inUserData, &matching_psn); - if(os_result >= 0 && matching_psn) - { - sCrashReporterIsRunning = false; - QuitApplicationEventLoop(); - } - } - return noErr; -} - void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) { // This used to use fork&exec, but is switched to LSOpenApplication to @@ -306,72 +286,6 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) appParams.version = 0; appParams.flags = kLSLaunchNoParams | kLSLaunchStartClassic; appParams.application = &appRef; - - if(reportFreeze) - { - // Make sure freeze reporting launches the crash logger synchronously, lest - // Log files get changed by SL while the logger is running. - - // *NOTE:Mani A better way - make a copy of the data that the crash reporter will send - // and let SL go about its business. This way makes the mac work like windows and linux - // and is the smallest patch for the issue. - sCrashReporterIsRunning = false; - ProcessSerialNumber o_psn; - - static EventHandlerRef sCarbonEventsRef = NULL; - static const EventTypeSpec kEvents[] = - { - { kEventClassApplication, kEventAppTerminated } - }; - - // Install the handler to detect crash logger termination - InstallEventHandler(GetApplicationEventTarget(), - (EventHandlerUPP) CarbonEventHandler, - GetEventTypeCount(kEvents), - kEvents, - &o_psn, - &sCarbonEventsRef - ); - - // Remove, temporarily the quit handler - which has *crash* behavior before - // the mainloop gets running! - AERemoveEventHandler(kCoreEventClass, - kAEQuitApplication, - NewAEEventHandlerUPP(AEQuitHandler), - false); - - // Launch the crash reporter. - os_result = LSOpenApplication(&appParams, &o_psn); - - if(os_result >= 0) - { - sCrashReporterIsRunning = true; - } - - while(sCrashReporterIsRunning) - { - RunApplicationEventLoop(); - } - - // Re-install the apps quit handler. - AEInstallEventHandler(kCoreEventClass, - kAEQuitApplication, - NewAEEventHandlerUPP(AEQuitHandler), - 0, - false); - - // Remove the crash reporter quit handler. - RemoveEventHandler(sCarbonEventsRef); - } - else - { - appParams.flags |= kLSLaunchAsync; - clear_signals(); - - ProcessSerialNumber o_psn; - os_result = LSOpenApplication(&appParams, &o_psn); - } - } } @@ -505,73 +419,3 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) return(result); } - -OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata) -{ - OSStatus result = eventNotHandledErr; - OSStatus err; - UInt32 evtClass = GetEventClass(event); - UInt32 evtKind = GetEventKind(event); - WindowRef window = (WindowRef)userdata; - - if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess)) - { - HICommand cmd; - err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd); - - if(err == noErr) - { - switch(cmd.commandID) - { - case kHICommandOK: - QuitAppModalLoopForWindow(window); - result = noErr; - break; - - case kHICommandCancel: - QuitAppModalLoopForWindow(window); - result = userCanceledErr; - break; - } - } - } - - return(result); -} - -void init_apple_menu(const char* product) -{ - // Load up a proper menu bar. - { - OSStatus err; - IBNibRef nib = NULL; - // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly. - err = CreateNibReference(CFSTR("SecondLife"), &nib); - - if(err == noErr) - { - // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly. - SetMenuBarFromNib(nib, CFSTR("MenuBar")); - } - - if(nib != NULL) - { - DisposeNibReference(nib); - } - } - - // Install a handler for 'gurl' AppleEvents. This is how secondlife:// URLs get passed to the viewer. - - if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr) - { - // Couldn't install AppleEvent handler. This error shouldn't be fatal. - llinfos << "Couldn't install 'GURL' AppleEvent handler. Continuing..." << llendl; - } - - // Install a handler for 'quit' AppleEvents. This makes quitting the application from the dock work. - if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr) - { - // Couldn't install AppleEvent handler. This error shouldn't be fatal. - llinfos << "Couldn't install Quit AppleEvent handler. Continuing..." << llendl; - } -} -- cgit v1.3 From ddb48d51d996b18063b111faa3b7e709160074d9 Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 1 Jan 2013 11:32:53 -0500 Subject: More things in this commit: - Removed the callback system in favor of simply defining functions in a header to later be implemented in whichever file is most convenient for what we want to do (i.e., calling LLWindow callbacks within LLWindowMacOSX, setting cursors in llwindowmacosx-objc.mm, etc.) - Viewer shutdown now works appropriately - Added a bit of debugging code to test if a key has been handled by the UI or not (useful for tracking down the mystery of the enter key not being handled) - Setup a cocoa quit handler within the application delegate that intercepts any termination requests --- indra/llwindow/llopenglview-objc.h | 30 ---- indra/llwindow/llopenglview-objc.mm | 214 ++++++++++------------------ indra/llwindow/llwindowmacosx-objc.h | 38 +++-- indra/llwindow/llwindowmacosx-objc.mm | 74 ++-------- indra/llwindow/llwindowmacosx.cpp | 73 +++++++--- indra/llwindow/llwindowmacosx.h | 2 +- indra/newview/llappviewermacosx-delegate.mm | 18 ++- indra/newview/llappviewermacosx-objc.h | 2 +- indra/newview/llappviewermacosx.cpp | 32 ++--- indra/newview/llviewerkeyboard.cpp | 2 +- 10 files changed, 201 insertions(+), 284 deletions(-) (limited to 'indra/newview/llappviewermacosx.cpp') diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h index 6b055bc665..20589e321d 100644 --- a/indra/llwindow/llopenglview-objc.h +++ b/indra/llwindow/llopenglview-objc.h @@ -15,7 +15,6 @@ @interface LLOpenGLView : NSOpenGLView { NSPoint mousePos; - ResizeCallback mResizeCallback; } - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync; @@ -33,42 +32,13 @@ - (CGLContextObj) getCGLContextObj; - (CGLPixelFormatObj*)getCGLPixelFormatObj; -- (void) registerResizeCallback:(ResizeCallback)callback; @end @interface LLNSWindow : NSWindow { float mMousePos[2]; unsigned int mModifiers; - - KeyCallback mKeyDownCallback; - KeyCallback mKeyUpCallback; - UnicodeCallback mUnicodeCallback; - ModifierCallback mModifierCallback; - MouseCallback mMouseDownCallback; - MouseCallback mMouseUpCallback; - MouseCallback mMouseDoubleClickCallback; - MouseCallback mRightMouseDownCallback; - MouseCallback mRightMouseUpCallback; - MouseCallback mMouseMovedCallback; - ScrollWheelCallback mScrollWhellCallback; - VoidCallback mMouseExitCallback; - MouseCallback mDeltaUpdateCallback; } -- (void) registerKeyDownCallback:(KeyCallback)callback; -- (void) registerKeyUpCallback:(KeyCallback)callback; -- (void) registerUnicodeCallback:(UnicodeCallback)callback; -- (void) registerModifierCallback:(ModifierCallback)callback; -- (void) registerMouseDownCallback:(MouseCallback)callback; -- (void) registerMouseUpCallback:(MouseCallback)callback; -- (void) registerRightMouseDownCallback:(MouseCallback)callback; -- (void) registerRightMouseUpCallback:(MouseCallback)callback; -- (void) registerDoubleClickCallback:(MouseCallback)callback; -- (void) registerMouseMovedCallback:(MouseCallback)callback; -- (void) registerScrollCallback:(ScrollWheelCallback)callback; -- (void) registerMouseExitCallback:(VoidCallback)callback; -- (void) registerDeltaUpdateCallback:(MouseCallback)callback; - @end void setLLNSWindowRef(LLNSWindow* window); diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 7c148f4acd..cb8d7b315f 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -19,12 +19,9 @@ - (void)windowResized:(NSNotification *)notification; { - if (mResizeCallback != nil) - { - NSSize size = [[self window] frame].size; - - mResizeCallback(size.width, size.height); - } + NSSize size = [self frame].size; + + callResize(size.width, size.height); } - (void)dealloc @@ -125,11 +122,6 @@ return (CGLPixelFormatObj*)[fmt CGLPixelFormatObj]; } -- (void) registerResizeCallback:(ResizeCallback)callback -{ - mResizeCallback = callback; -} - // Various events can be intercepted by our view, thus not reaching our window. // Intercept these events, and pass them to the window as needed. - Geenz @@ -183,6 +175,16 @@ [super flagsChanged:theEvent]; } +- (BOOL) becomeFirstResponder +{ + return [super becomeFirstResponder]; +} + +- (BOOL) resignFirstResponder +{ + return [super resignFirstResponder]; +} + @end // We use a custom NSWindow for our event handling. @@ -196,30 +198,19 @@ return self; } -- (void) keyDown:(NSEvent *)theEvent { - if (mKeyDownCallback != nil && mUnicodeCallback != nil) +- (void) keyDown:(NSEvent *)theEvent +{ + callKeyDown([theEvent keyCode], [theEvent modifierFlags]); + + NSString *chars = [theEvent characters]; + for (uint i = 0; i < [chars length]; i++) { - mKeyDownCallback([theEvent keyCode], [theEvent modifierFlags]); - - NSString *chars = [theEvent charactersIgnoringModifiers]; - for (uint i = 0; i < [chars length]; i++) - { - mUnicodeCallback([chars characterAtIndex:i], [theEvent modifierFlags]); - } - - // The viewer expects return to be submitted separately as a unicode character. - if ([theEvent keyCode] == 3 || [theEvent keyCode] == 13) - { - mUnicodeCallback([theEvent keyCode], [theEvent modifierFlags]); - } + callUnicodeCallback([chars characterAtIndex:i], [theEvent modifierFlags]); } } - (void) keyUp:(NSEvent *)theEvent { - if (mKeyUpCallback != nil) - { - mKeyUpCallback([theEvent keyCode], [theEvent modifierFlags]); - } + callKeyUp([theEvent keyCode], [theEvent modifierFlags]); } - (void)flagsChanged:(NSEvent *)theEvent { @@ -228,59 +219,42 @@ - (void) mouseDown:(NSEvent *)theEvent { - if (mMouseDoubleClickCallback != nil && mMouseDownCallback != nil) + if ([theEvent clickCount] >= 2) { - if ([theEvent clickCount] == 2) - { - mMouseDoubleClickCallback(mMousePos, [theEvent modifierFlags]); - } else if ([theEvent clickCount] == 1) { - mMouseDownCallback(mMousePos, [theEvent modifierFlags]); - } + callDoubleClick(mMousePos, [theEvent modifierFlags]); + } else if ([theEvent clickCount] == 1) { + callLeftMouseDown(mMousePos, [theEvent modifierFlags]); } } - (void) mouseUp:(NSEvent *)theEvent { - if (mMouseUpCallback != nil) - { - mMouseUpCallback(mMousePos, [theEvent modifierFlags]); - } + callLeftMouseUp(mMousePos, [theEvent modifierFlags]); } - (void) rightMouseDown:(NSEvent *)theEvent { - if (mRightMouseDownCallback != nil) - { - mRightMouseDownCallback(mMousePos, [theEvent modifierFlags]); - } + callRightMouseDown(mMousePos, [theEvent modifierFlags]); } - (void) rightMouseUp:(NSEvent *)theEvent { - if (mRightMouseUpCallback != nil) - { - mRightMouseUpCallback(mMousePos, [theEvent modifierFlags]); - } + callRightMouseUp(mMousePos, [theEvent modifierFlags]); } -- (void)mouseMoved:(NSEvent *)theEvent { - if (mDeltaUpdateCallback != nil && mMouseMovedCallback != nil) - { - float mouseDeltas[2] = { - [theEvent deltaX], - [theEvent deltaZ] - }; - - mDeltaUpdateCallback(mouseDeltas, 0); - - NSPoint mPoint = [theEvent locationInWindow]; - mMousePos[0] = mPoint.x; - mMousePos[1] = mPoint.y; - if (mMouseMovedCallback != nil) - { - mMouseMovedCallback(mMousePos, 0); - } - } +- (void)mouseMoved:(NSEvent *)theEvent +{ + float mouseDeltas[2] = { + [theEvent deltaX], + [theEvent deltaY] + }; + + callDeltaUpdate(mouseDeltas, 0); + + NSPoint mPoint = [theEvent locationInWindow]; + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; + callMouseMoved(mMousePos, 0); } // NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged. @@ -288,101 +262,59 @@ - (void) mouseDragged:(NSEvent *)theEvent { - if (mDeltaUpdateCallback != nil && mMouseMovedCallback != nil) - { - float mouseDeltas[2] = { - [theEvent deltaX], - [theEvent deltaZ] - }; - - mDeltaUpdateCallback(mouseDeltas, 0); - - NSPoint mPoint = [theEvent locationInWindow]; - mMousePos[0] = mPoint.x; - mMousePos[1] = mPoint.y; - mMouseMovedCallback(mMousePos, 0); - } -} - -- (void) scrollWheel:(NSEvent *)theEvent -{ - if (mScrollWhellCallback != nil) - { - mScrollWhellCallback(-[theEvent deltaY]); - } -} - -- (void) mouseExited:(NSEvent *)theEvent -{ - if (mMouseExitCallback != nil) - { - mMouseExitCallback(); - } -} - -- (void) registerKeyDownCallback:(KeyCallback)callback -{ - mKeyDownCallback = callback; -} - -- (void) registerKeyUpCallback:(KeyCallback)callback -{ - mKeyUpCallback = callback; -} - -- (void) registerUnicodeCallback:(UnicodeCallback)callback -{ - mUnicodeCallback = callback; -} - -- (void) registerModifierCallback:(ModifierCallback)callback -{ - mModifierCallback = callback; -} - -- (void) registerMouseDownCallback:(MouseCallback)callback -{ - mMouseDownCallback = callback; -} - -- (void) registerMouseUpCallback:(MouseCallback)callback -{ - mMouseUpCallback = callback; + // Trust the deltas supplied by NSEvent. + // The old CoreGraphics APIs we previously relied on are now flagged as obsolete. + // NSEvent isn't obsolete, and provides us with the correct deltas. + float mouseDeltas[2] = { + [theEvent deltaX], + [theEvent deltaY] + }; + + callDeltaUpdate(mouseDeltas, 0); + + NSPoint mPoint = [theEvent locationInWindow]; + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; + callMouseMoved(mMousePos, 0); } -- (void) registerRightMouseDownCallback:(MouseCallback)callback +- (void) otherMouseDown:(NSEvent *)theEvent { - mRightMouseDownCallback = callback; + callMiddleMouseDown(mMousePos, 0); } -- (void) registerRightMouseUpCallback:(MouseCallback)callback +- (void) otherMouseUp:(NSEvent *)theEvent { - mRightMouseUpCallback = callback; + callMiddleMouseUp(mMousePos, 0); } -- (void) registerDoubleClickCallback:(MouseCallback)callback +- (void) otherMouseDragged:(NSEvent *)theEvent { - mMouseDoubleClickCallback = callback; + } -- (void) registerMouseMovedCallback:(MouseCallback)callback +- (void) scrollWheel:(NSEvent *)theEvent { - mMouseMovedCallback = callback; + callScrollMoved(-[theEvent deltaY]); } -- (void) registerScrollCallback:(ScrollWheelCallback)callback +- (void) mouseExited:(NSEvent *)theEvent { - mScrollWhellCallback = callback; + callMouseExit(); } -- (void) registerMouseExitCallback:(VoidCallback)callback +- (BOOL) becomeFirstResponder { - mMouseExitCallback = callback; + NSLog(@"Window gained focus!"); + callFocus(); + return true; } -- (void) registerDeltaUpdateCallback:(MouseCallback)callback +- (BOOL) resignFirstResponder { - mDeltaUpdateCallback = callback; + NSLog(@"Window lost focus!"); + callFocus(); + return true; } @end diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index abaeda1f91..655d63ac12 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -65,21 +65,33 @@ void getCursorPos(NSWindowRef window, float* pos); void makeWindowOrderFront(NSWindowRef window); void convertScreenToWindow(NSWindowRef window, float *coord); void convertWindowToScreen(NSWindowRef window, float *coord); +void convertScreenToView(NSWindowRef window, float *coord); void setWindowPos(NSWindowRef window, float* pos); +void closeWindow(NSWindowRef window); +void removeGLView(GLViewRef view); + +// These are all implemented in llwindowmacosx.cpp. +// This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict) +void callKeyUp(unsigned short key, unsigned int mask); +void callKeyDown(unsigned short key, unsigned int mask); +void callUnicodeCallback(wchar_t character, unsigned int mask); +void callRightMouseDown(float *pos, unsigned int mask); +void callRightMouseUp(float *pos, unsigned int mask); +void callLeftMouseDown(float *pos, unsigned int mask); +void callLeftMouseUp(float *pos, unsigned int mask); +void callDoubleClick(float *pos, unsigned int mask); +void callResize(unsigned int width, unsigned int height); +void callMouseMoved(float *pos, unsigned int mask); +void callScrollMoved(float delta); +void callMouseExit(); +void callWindowFocus(); +void callWindowUnfocus(); +void callDeltaUpdate(float *delta, unsigned int mask); +void callMiddleMouseDown(float *pos, unsigned int mask); +void callMiddleMouseUp(float *pos, unsigned int mask); +void callFocus(); +void callFocusLost(); -void registerKeyUpCallback(NSWindowRef window, KeyCallback callback); -void registerKeyDownCallback(NSWindowRef window, KeyCallback callback); -void registerUnicodeCallback(NSWindowRef window, UnicodeCallback callback); -void registerMouseUpCallback(NSWindowRef window, MouseCallback callback); -void registerMouseDownCallback(NSWindowRef window, MouseCallback callback); -void registerRightMouseUpCallback(NSWindowRef window, MouseCallback callback); -void registerRightMouseDownCallback(NSWindowRef window, MouseCallback callback); -void registerDoubleClickCallback(NSWindowRef window, MouseCallback callback); -void registerResizeEventCallback(GLViewRef window, ResizeCallback callback); -void registerMouseMovedCallback(NSWindowRef window, MouseCallback callback); -void registerScrollCallback(NSWindowRef window, ScrollWheelCallback callback); -void registerMouseExitCallback(NSWindowRef window, VoidCallback callback); -void registerDeltaUpdateCallback(NSWindowRef window, MouseCallback callback); NSWindowRef getMainAppWindow(); GLViewRef getGLView(NSWindowRef window); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 07efc25ea6..f3972303f1 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -255,6 +255,15 @@ void convertScreenToWindow(NSWindowRef window, float *coord) coord[1] = point.y; } +void convertScreenToView(NSWindowRef window, float *coord) +{ + NSRect point; + point.origin.x = coord[0]; + point.origin.y = coord[1]; + point.origin = [(LLNSWindow*)window convertScreenToBase:point.origin]; + point.origin = [[(LLNSWindow*)window contentView] convertPoint:point.origin fromView:nil]; +} + void convertWindowToScreen(NSWindowRef window, float *coord) { NSPoint point; @@ -265,73 +274,20 @@ void convertWindowToScreen(NSWindowRef window, float *coord) coord[1] = point.y; } -void registerKeyUpCallback(NSWindowRef window, std::tr1::function callback) -{ - [(LLNSWindow*)window registerKeyUpCallback:callback]; -} - -void registerKeyDownCallback(NSWindowRef window, std::tr1::function callback) -{ - [(LLNSWindow*)window registerKeyDownCallback:callback]; -} - -void registerUnicodeCallback(NSWindowRef window, std::tr1::function callback) -{ - [(LLNSWindow*)window registerUnicodeCallback:callback]; -} - -void registerMouseUpCallback(NSWindowRef window, MouseCallback callback) -{ - [(LLNSWindow*)window registerMouseUpCallback:callback]; -} - -void registerMouseDownCallback(NSWindowRef window, MouseCallback callback) -{ - [(LLNSWindow*)window registerMouseDownCallback:callback]; -} - -void registerRightMouseUpCallback(NSWindowRef window, MouseCallback callback) -{ - [(LLNSWindow*)window registerRightMouseUpCallback:callback]; -} - -void registerRightMouseDownCallback(NSWindowRef window, MouseCallback callback) -{ - [(LLNSWindow*)window registerRightMouseDownCallback:callback]; -} - -void registerDoubleClickCallback(NSWindowRef window, MouseCallback callback) -{ - [(LLNSWindow*)window registerDoubleClickCallback:callback]; -} - -void registerResizeEventCallback(GLViewRef glview, ResizeCallback callback) -{ - [(LLOpenGLView*)glview registerResizeCallback:callback]; -} - -void registerMouseMovedCallback(NSWindowRef window, MouseCallback callback) -{ - [(LLNSWindow*)window registerMouseMovedCallback:callback]; -} - -void registerScrollCallback(NSWindowRef window, ScrollWheelCallback callback) -{ - [(LLNSWindow*)window registerScrollCallback:callback]; -} - -void registerMouseExitCallback(NSWindowRef window, VoidCallback callback) +void closeWindow(NSWindowRef window) { - [(LLNSWindow*)window registerMouseExitCallback:callback]; + [(LLNSWindow*)window close]; } -void registerDeltaUpdateCallback(NSWindowRef window, MouseCallback callback) +void removeGLView(GLViewRef view) { - [(LLNSWindow*)window registerDeltaUpdateCallback:callback]; + [(LLOpenGLView*)view removeFromSuperview]; + [(LLOpenGLView*)view release]; } NSWindowRef getMainAppWindow() { + [(LLNSWindow*)winRef setAcceptsMouseMovedEvents:TRUE]; return winRef; } diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index a616b2df2d..cfdfbe2138 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -198,7 +198,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, } -// These functions are used as callbacks for event handling within Cocoa. +// These functions are used as wrappers for our internal event handling callbacks. // It's a good idea to wrap these to avoid reworking more code than we need to within LLWindow. void callKeyUp(unsigned short key, unsigned int mask) @@ -216,9 +216,14 @@ void callUnicodeCallback(wchar_t character, unsigned int mask) gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask); } -void callModifierCallback(unsigned int mask) +void callFocus() { - + gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); +} + +void callFocusLost() +{ + gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); } void callRightMouseDown(float *pos, MASK mask) @@ -302,17 +307,41 @@ void callWindowUnfocus() void callDeltaUpdate(float *delta, MASK mask) { - gWindowImplementation->updateMouseDeltas(); + gWindowImplementation->updateMouseDeltas(delta); +} + +void callMiddleMouseDown(float *pos, MASK mask) +{ + LLCoordGL outCoords; + outCoords.mX = llround(pos[0]); + outCoords.mY = llround(pos[1]); + float deltas[2]; + gWindowImplementation->getMouseDeltas(deltas); + outCoords.mX += deltas[0]; + outCoords.mY += deltas[1]; + gWindowImplementation->getCallbacks()->handleMiddleMouseDown(gWindowImplementation, outCoords, mask); +} + +void callMiddleMouseUp(float *pos, MASK mask) +{ + LLCoordGL outCoords; + outCoords.mX = llround(pos[0]); + outCoords.mY = llround(pos[1]); + float deltas[2]; + gWindowImplementation->getMouseDeltas(deltas); + outCoords.mX += deltas[0]; + outCoords.mY += deltas[1]; + gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask); } -void LLWindowMacOSX::updateMouseDeltas() +void LLWindowMacOSX::updateMouseDeltas(float* deltas) { if (mCursorDecoupled) { - CGMouseDelta x, y; - CGGetLastMouseDelta( &x, &y ); - mCursorLastEventDeltaX = x; - mCursorLastEventDeltaY = y; + mCursorLastEventDeltaX = llround(deltas[0]); + mCursorLastEventDeltaY = llround(-deltas[1]); + + if (mCursorIgnoreNextDelta) { @@ -320,6 +349,7 @@ void LLWindowMacOSX::updateMouseDeltas() mCursorLastEventDeltaY = 0; mCursorIgnoreNextDelta = FALSE; } + LL_INFOS("Delta Update") << "Last event delta: " << mCursorLastEventDeltaX << ", " << mCursorLastEventDeltaY << LL_ENDL; } else { mCursorLastEventDeltaX = 0; mCursorLastEventDeltaY = 0; @@ -342,6 +372,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits { LL_INFOS("Window") << "Creating window..." << LL_ENDL; mWindow = getMainAppWindow(); + /* LL_INFOS("Window") << "Registering key callbacks..." << LL_ENDL; registerKeyDownCallback(mWindow, callKeyDown); registerKeyUpCallback(mWindow, callKeyUp); @@ -355,6 +386,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits registerScrollCallback(mWindow, callScrollMoved); registerDeltaUpdateCallback(mWindow, callDeltaUpdate); registerMouseExitCallback(mWindow, callMouseExit); + */ } if(mContext == NULL) @@ -363,7 +395,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // Our OpenGL view is already defined within SecondLife.xib. // Get the view instead. mGLView = createOpenGLView(mWindow); - registerResizeEventCallback(mGLView, callResize); + //registerResizeEventCallback(mGLView, callResize); mContext = getCGLContextObj(mGLView); // Since we just created the context, it needs to be set up. glNeedsInit = TRUE; @@ -439,9 +471,7 @@ void LLWindowMacOSX::destroyContext() if(mContext != NULL) { LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL; - CGLSetCurrentContext(NULL); - mContext = NULL; } // Clean up remaining GL state before blowing away window @@ -454,16 +484,25 @@ void LLWindowMacOSX::destroyContext() mPixelFormat = NULL; } - // Close the window - if(mWindow != NULL) - { - } - // Clean up the GL context if(mContext != NULL) { CGLDestroyContext(mContext); } + + // Destroy our LLOpenGLView + if(mGLView != NULL) + { + removeGLView(mGLView); + mGLView = NULL; + } + + // Close the window + if(mWindow != NULL) + { + closeWindow(mWindow); + mWindow = NULL; + } } diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 487af7658f..c5e1b2290b 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -121,7 +121,7 @@ public: void* getWindow() { return mWindow; } LLWindowCallbacks* getCallbacks() { return mCallbacks; } - void updateMouseDeltas(); + void updateMouseDeltas(float* deltas); void getMouseDeltas(float* delta); diff --git a/indra/newview/llappviewermacosx-delegate.mm b/indra/newview/llappviewermacosx-delegate.mm index 80cc1010e9..2e25997d32 100644 --- a/indra/newview/llappviewermacosx-delegate.mm +++ b/indra/newview/llappviewermacosx-delegate.mm @@ -23,17 +23,26 @@ frameTimer = nil; setLLNSWindowRef([self window]); - setLLOpenGLViewRef([self glview]); + //setLLOpenGLViewRef([self glview]); if (initViewer()) { - frameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/60 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; + frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; } else { handleQuit(); } } -- (void) applicationWillTerminate:(NSNotification *)notification +- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender { + if (!runMainLoop()) + { + handleQuit(); + return NSTerminateCancel; + } else { + [frameTimer release]; + cleanupViewer(); + return NSTerminateNow; + } } - (void) mainLoop @@ -42,7 +51,8 @@ if (appExiting) { [frameTimer release]; - handleQuit(); + cleanupViewer(); + [[NSApplication sharedApplication] terminate:self]; } } diff --git a/indra/newview/llappviewermacosx-objc.h b/indra/newview/llappviewermacosx-objc.h index 9ece6a1a6a..ed9017ca5d 100644 --- a/indra/newview/llappviewermacosx-objc.h +++ b/indra/newview/llappviewermacosx-objc.h @@ -16,4 +16,4 @@ bool initViewer(); void handleQuit(); bool runMainLoop(); void initMainLoop(); -void destroyMainLoop(); \ No newline at end of file +void cleanupViewer(); \ No newline at end of file diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index a1c8b7699d..6e7b91347b 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -55,15 +55,6 @@ namespace char** gArgV; LLAppViewerMacOSX* gViewerAppPtr; - - OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) - { - OSErr result = noErr; - - LLAppViewer::instance()->userQuit(); - - return(result); - } } bool initViewer() @@ -95,26 +86,33 @@ bool initViewer() void handleQuit() { - if(!LLApp::isError()) - { - gViewerAppPtr->cleanup(); - } - - delete gViewerAppPtr; - gViewerAppPtr = NULL; + LLAppViewer::instance()->userQuit(); } bool runMainLoop() { bool ret = LLApp::isQuitting(); - if (!ret) + if (!ret && gViewerAppPtr != NULL) { ret = gViewerAppPtr->mainLoop(); + } else { + ret = true; } return ret; } +void cleanupViewer() +{ + if(!LLApp::isError()) + { + gViewerAppPtr->cleanup(); + } + + delete gViewerAppPtr; + gViewerAppPtr = NULL; +} + int main( int argc, char **argv ) { // Store off the command line args for use later. diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 6d91dad70e..92d8f2937e 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -654,7 +654,6 @@ BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated) { LL_INFOS("Keyboard Handling") << "Handling key " << translated_key << LL_ENDL; - LL_INFOS("Keyboard Handling") << "Keyboard has focus? " << gFocusMgr.getKeyboardFocus() << LL_ENDL; // check for re-map EKeyboardMode mode = gViewerKeyboard.getMode(); U32 keyidx = (translated_mask<<16) | translated_key; @@ -677,6 +676,7 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end()) { mKeyHandledByUI[translated_key] = FALSE; + LL_INFOS("Keyboard Handling") << "Key wasn't handled by UI!" << LL_ENDL; } else { -- cgit v1.3 From 09b07e3619a71f142c1a3af41244d756e1230142 Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 8 Jan 2013 16:22:54 -0500 Subject: Big change set: - LLAppDelegate header relocated to LLWindow. Definition is still present in secondlife-bin (for compatibility reasons when loading a nib). - Return key handling fixed. - Command key now acts the same as the control key by issuing control character codes when the command key is pressed. - We now retrieve the window pointer directly from the app delegate in LLWindow. --- indra/llwindow/CMakeLists.txt | 1 + indra/llwindow/llappdelegate-objc.h | 22 ++++++ indra/llwindow/llkeyboardmacosx.cpp | 35 ++------- indra/llwindow/llopenglview-objc.h | 5 -- indra/llwindow/llopenglview-objc.mm | 113 +++++++++++++++++++--------- indra/llwindow/llwindowmacosx-objc.h | 11 +++ indra/llwindow/llwindowmacosx-objc.mm | 56 ++++++++++---- indra/llwindow/llwindowmacosx.cpp | 22 +++--- indra/newview/CMakeLists.txt | 8 +- indra/newview/llappdelegate-objc.mm | 55 ++++++++++++++ indra/newview/llappviewermacosx-delegate.h | 22 ------ indra/newview/llappviewermacosx-delegate.mm | 57 -------------- indra/newview/llappviewermacosx-objc.h | 19 ----- indra/newview/llappviewermacosx-objc.mm | 20 ----- indra/newview/llappviewermacosx.cpp | 2 +- 15 files changed, 232 insertions(+), 216 deletions(-) create mode 100644 indra/llwindow/llappdelegate-objc.h create mode 100644 indra/newview/llappdelegate-objc.mm delete mode 100644 indra/newview/llappviewermacosx-delegate.h delete mode 100644 indra/newview/llappviewermacosx-delegate.mm delete mode 100644 indra/newview/llappviewermacosx-objc.h delete mode 100644 indra/newview/llappviewermacosx-objc.mm (limited to 'indra/newview/llappviewermacosx.cpp') diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 8a38db751e..84e0169826 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -82,6 +82,7 @@ if (DARWIN) llwindowmacosx.h llwindowmacosx-objc.h llopenglview-objc.h + llappdelegate-objc.h ) # We use a bunch of deprecated system APIs. diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h new file mode 100644 index 0000000000..56b7a30797 --- /dev/null +++ b/indra/llwindow/llappdelegate-objc.h @@ -0,0 +1,22 @@ +// +// LLAppDelegate.h +// SecondLife +// +// Created by Geenz on 12/16/12. +// +// + +#import +#import "llopenglview-objc.h" +#include "llwindowmacosx-objc.h" + +@interface LLAppDelegate : NSObject { + LLNSWindow *window; + NSTimer *frameTimer; +} + +@property (assign) IBOutlet LLNSWindow *window; + +- (void) mainLoop; + +@end diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp index 077ebea909..3db94e8835 100644 --- a/indra/llwindow/llkeyboardmacosx.cpp +++ b/indra/llwindow/llkeyboardmacosx.cpp @@ -167,13 +167,15 @@ void LLKeyboardMacOSX::resetMaskKeys() // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys(). // It looks a bit suspicious, as it won't correct for keys that have been released. // Is this the way it's supposed to work? + + // We apply the modifier masks directly within getModifiers. So check to see which masks we've applied. if(mask & MAC_SHIFT_KEY) { mKeyLevel[KEY_SHIFT] = TRUE; } - if(mask & (MAC_CTRL_KEY)) + if(mask & MAC_CTRL_KEY) { mKeyLevel[KEY_CONTROL] = TRUE; } @@ -198,25 +200,9 @@ static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &out MASK LLKeyboardMacOSX::updateModifiers(const U32 mask) { - // translate the mask - MASK out_mask = 0; - - if(mask & MAC_SHIFT_KEY) - { - out_mask |= MASK_SHIFT; - } - - if(mask & MAC_CTRL_KEY || mask & MAC_CMD_KEY) - { - out_mask |= MASK_CONTROL; - } - - if(mask & MAC_ALT_KEY) - { - out_mask |= MASK_ALT; - } - - return out_mask; + // This is handled for us in LLNSWindow on OS X. + + return mask; } BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask) @@ -231,12 +217,7 @@ BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask) { handled = handleTranslatedKeyDown(translated_key, translated_mask); } - if (!handled) - { - LL_INFOS("Keyboard") << "Unhandled key: " << mTranslateKeyMap[key] << LL_ENDL; - } else { - LL_INFOS("Keyboard") << "Handled key: " << mTranslateKeyMap[key] << LL_ENDL; - } + return handled; } @@ -272,7 +253,7 @@ MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event) if (mask & MAC_CMD_KEY) result |= MASK_CONTROL; } - return result; + return mask; } void LLKeyboardMacOSX::scanKeyboard() diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h index 20589e321d..8412621392 100644 --- a/indra/llwindow/llopenglview-objc.h +++ b/indra/llwindow/llopenglview-objc.h @@ -40,8 +40,3 @@ } @end - -void setLLNSWindowRef(LLNSWindow* window); -void setLLOpenGLViewRef(LLOpenGLView* view); -LLNSWindow* winRef; -LLOpenGLView* glviewRef; diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index e5e198b856..d91601152b 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -132,62 +132,72 @@ - (void) mouseDragged:(NSEvent *)theEvent { - [super mouseDragged:theEvent]; + [_window mouseDragged:theEvent]; } - (void) scrollWheel:(NSEvent *)theEvent { - [super scrollWheel:theEvent]; + [_window scrollWheel:theEvent]; } - (void) mouseDown:(NSEvent *)theEvent { - [super mouseDown:theEvent]; + [_window mouseDown:theEvent]; } - (void) mouseUp:(NSEvent *)theEvent { - [super mouseUp:theEvent]; + [_window mouseUp:theEvent]; } - (void) rightMouseDown:(NSEvent *)theEvent { - [super rightMouseDown:theEvent]; + [_window rightMouseDown:theEvent]; } - (void) rightMouseUp:(NSEvent *)theEvent { - [super rightMouseUp:theEvent]; + [_window rightMouseUp:theEvent]; +} + +- (void) otherMouseDown:(NSEvent *)theEvent +{ + [_window otherMouseDown:theEvent]; +} + +- (void) otherMouseUp:(NSEvent *)theEvent +{ + [_window otherMouseUp:theEvent]; } - (void) keyUp:(NSEvent *)theEvent { - [super keyUp:theEvent]; + [_window keyUp:theEvent]; } - (void) keyDown:(NSEvent *)theEvent { - [super keyDown:theEvent]; + [_window keyDown:theEvent]; } - (void) mouseMoved:(NSEvent *)theEvent { - [super mouseMoved:theEvent]; + [_window mouseMoved:theEvent]; } - (void) flagsChanged:(NSEvent *)theEvent { - [super flagsChanged:theEvent]; + [_window flagsChanged:theEvent]; } - (BOOL) becomeFirstResponder { - return [super becomeFirstResponder]; + return [_window becomeFirstResponder]; } - (BOOL) resignFirstResponder { - return [super resignFirstResponder]; + return [_window resignFirstResponder]; } @end @@ -200,58 +210,99 @@ - (id) init { + //[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType, nil]]; return self; } - (void) keyDown:(NSEvent *)theEvent { - callKeyDown([theEvent keyCode], [theEvent modifierFlags]); - + callKeyDown([theEvent keyCode], mModifiers); NSString *chars = [theEvent characters]; for (uint i = 0; i < [chars length]; i++) { // Enter and Return are special cases. unichar returntest = [chars characterAtIndex:i]; - if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) && !([theEvent modifierFlags] & NSCommandKeyMask) && !([theEvent modifierFlags] & NSAlternateKeyMask) && !([theEvent modifierFlags] & NSControlKeyMask)) + if ((returntest == NSCarriageReturnCharacter || returntest == NSEnterCharacter) && + !([theEvent modifierFlags] & NSCommandKeyMask) && + !([theEvent modifierFlags] & NSAlternateKeyMask) && + !([theEvent modifierFlags] & NSControlKeyMask)) { - callUnicodeCallback(returntest, 0); + callUnicodeCallback(13, 0); } else { - callUnicodeCallback([chars characterAtIndex:i], [theEvent modifierFlags]); + // The command key being pressed is also a special case. + // Control + produces an ASCII control character code. + // Command + produces just the character's code. + // Check to see if the command key is pressed, then filter through the different character ranges that are relevant to control characters, and subtract the appropriate range. + if ([theEvent modifierFlags] & NSCommandKeyMask) + { + if (returntest >= 64 && returntest <= 95) + { + callUnicodeCallback(returntest - 63, mModifiers); + } else if (returntest >= 97 && returntest <= 122) + { + callUnicodeCallback(returntest - 96, mModifiers); + } + } else { + callUnicodeCallback(returntest, mModifiers); + } } } } - (void) keyUp:(NSEvent *)theEvent { - callKeyUp([theEvent keyCode], [theEvent modifierFlags]); + callKeyUp([theEvent keyCode], mModifiers); } - (void)flagsChanged:(NSEvent *)theEvent { - mModifiers = [theEvent modifierFlags]; + uint modifiers = [theEvent modifierFlags]; + + // Filter through our modifier keys, and only pick out the ones we care about. + + mModifiers = 0; + if (modifiers & NSCommandKeyMask) + { + mModifiers |= 0x0001; + } + + if (modifiers & NSAlternateKeyMask) + { + mModifiers |= 0x0002; + } + + if (modifiers & NSShiftKeyMask) + { + mModifiers |= 0x0004; + } + + if (modifiers & NSControlKeyMask) + { + mModifiers |= 0x0001; + } } - (void) mouseDown:(NSEvent *)theEvent { if ([theEvent clickCount] >= 2) { - callDoubleClick(mMousePos, [theEvent modifierFlags]); + callDoubleClick(mMousePos, mModifiers); } else if ([theEvent clickCount] == 1) { - callLeftMouseDown(mMousePos, [theEvent modifierFlags]); + callLeftMouseDown(mMousePos, mModifiers); } } - (void) mouseUp:(NSEvent *)theEvent { - callLeftMouseUp(mMousePos, [theEvent modifierFlags]); + callLeftMouseUp(mMousePos, mModifiers); } - (void) rightMouseDown:(NSEvent *)theEvent { - callRightMouseDown(mMousePos, [theEvent modifierFlags]); + callRightMouseDown(mMousePos, mModifiers); } - (void) rightMouseUp:(NSEvent *)theEvent { - callRightMouseUp(mMousePos, [theEvent modifierFlags]); + callRightMouseUp(mMousePos, mModifiers); } - (void)mouseMoved:(NSEvent *)theEvent @@ -292,12 +343,12 @@ - (void) otherMouseDown:(NSEvent *)theEvent { - callMiddleMouseDown(mMousePos, 0); + callMiddleMouseDown(mMousePos, mModifiers); } - (void) otherMouseUp:(NSEvent *)theEvent { - callMiddleMouseUp(mMousePos, 0); + callMiddleMouseUp(mMousePos, mModifiers); } - (void) otherMouseDragged:(NSEvent *)theEvent @@ -330,13 +381,3 @@ } @end - -void setLLNSWindowRef(LLNSWindow* window) -{ - winRef = window; -} - -void setLLOpenGLViewRef(LLOpenGLView* view) -{ - glviewRef = view; -} diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index 414491f948..57b3d11296 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -38,8 +38,19 @@ typedef void *CursorRef; typedef void *NSWindowRef; typedef void *GLViewRef; +// These are defined in llappviewermacosx.cpp. +bool initViewer(); +void handleQuit(); +bool runMainLoop(); +void initMainLoop(); +void cleanupViewer(); + /* Defined in llwindowmacosx-objc.mm: */ +int createNSApp(int argc, const char **argv); void setupCocoa(); +bool pasteBoardAvailable(); +bool copyToPBoard(const unsigned short *str, unsigned int len); +const unsigned short *copyFromPBoard(); CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY); short releaseImageCursor(CursorRef ref); short setImageCursor(CursorRef ref); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 5a024eda46..1a64c94b2d 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -29,6 +29,7 @@ #include #include "llwindowmacosx-objc.h" #include "llopenglview-objc.h" +#include "llappdelegate-objc.h" /* * These functions are broken out into a separate file because the @@ -37,6 +38,11 @@ * linden headers with any objective-C++ source. */ +int createNSApp(int argc, const char *argv[]) +{ + return NSApplicationMain(argc, argv); +} + void setupCocoa() { static bool inited = false; @@ -49,15 +55,6 @@ void setupCocoa() // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' // when init'ing the Cocoa App window. [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; - - // This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor": - // http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html - - // Needed for Carbon based applications which call into Cocoa - // NSApplicationLoad(); - - // Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image - //[[[NSWindow alloc] init] release]; [pool release]; @@ -65,6 +62,38 @@ void setupCocoa() } } +bool copyToPBoard(const unsigned short *str, unsigned int len) +{ + NSPasteboard *pboard = [NSPasteboard generalPasteboard]; + [pboard clearContents]; + + NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil]; + + return [pboard writeObjects:contentsToPaste]; +} + +bool pasteBoardAvailable() +{ + NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; + return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; +} + +const unsigned short *copyFromPBoard() +{ + NSPasteboard *pboard = [NSPasteboard generalPasteboard]; + NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; + NSString *str = NULL; + BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; + if (ok) + { + NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]]; + str = [objToPaste objectAtIndex:0]; + } + unichar* temp = (unichar*)calloc([str length], sizeof(unichar)); + [str getCharacters:temp]; + return temp; +} + CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -287,15 +316,12 @@ void removeGLView(GLViewRef view) NSWindowRef getMainAppWindow() { - [(LLNSWindow*)winRef setAcceptsMouseMovedEvents:TRUE]; + LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window]; + + [winRef setAcceptsMouseMovedEvents:TRUE]; return winRef; } -GLViewRef getGLView() -{ - return glviewRef; -} - unsigned int getModifiers() { return [NSEvent modifierFlags]; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 902391e170..93b9f4c484 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1029,25 +1029,27 @@ void LLWindowMacOSX::flashIcon(F32 seconds) BOOL LLWindowMacOSX::isClipboardTextAvailable() { - BOOL result = false; - // TODO: Clipboard support. - return result; + return pasteBoardAvailable(); } BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst) -{ - BOOL result = false; - - // TODO: Clipboard support. - - return result; +{ + llutf16string str(copyFromPBoard()); + dst = utf16str_to_wstring(str); + if (dst != L"") + { + return true; + } else { + return false; + } } BOOL LLWindowMacOSX::copyTextToClipboard(const LLWString &s) { BOOL result = false; + llutf16string utf16str = wstring_to_utf16str(s); - // TODO: Clipboard support. + result = copyToPBoard(utf16str.data(), utf16str.length()); return result; } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 73f5ecc38c..c60940f93c 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1231,10 +1231,9 @@ source_group("CMake Rules" FILES ViewerInstall.cmake) if (DARWIN) LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp) - LIST(APPEND viewer_SOURCE_FILES llappviewermacosx-objc.h) - LIST(APPEND viewer_SOURCE_FILES llappviewermacosx-objc.mm) - LIST(APPEND viewer_SOURCE_FILES llappviewermacosx-delegate.h) - LIST(APPEND viewer_SOURCE_FILES llappviewermacosx-delegate.mm) + + # This should be compiled with the viewer. + LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm) find_library(AGL_LIBRARY AGL) find_library(APPKIT_LIBRARY AppKit) @@ -1532,6 +1531,7 @@ if (FMOD) if (DARWIN) set(fmodwrapper_SOURCE_FILES fmodwrapper.cpp) add_library(fmodwrapper SHARED ${fmodwrapper_SOURCE_FILES}) + find_library(CARBON_LIBRARY Carbon) set(fmodwrapper_needed_LIBRARIES ${FMOD_LIBRARY} ${CARBON_LIBRARY}) set_target_properties( fmodwrapper diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm new file mode 100644 index 0000000000..f5143d7578 --- /dev/null +++ b/indra/newview/llappdelegate-objc.mm @@ -0,0 +1,55 @@ +// +// LLAppDelegate.m +// SecondLife +// +// Created by Geenz on 12/16/12. +// +// + +#import "llappdelegate-objc.h" + +@implementation LLAppDelegate + +@synthesize window; + +- (void)dealloc +{ + [super dealloc]; +} + +- (void) applicationDidFinishLaunching:(NSNotification *)notification +{ + frameTimer = nil; + + if (initViewer()) + { + frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; + } else { + handleQuit(); + } +} + +- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender +{ + if (!runMainLoop()) + { + handleQuit(); + return NSTerminateCancel; + } else { + [frameTimer release]; + cleanupViewer(); + return NSTerminateNow; + } +} + +- (void) mainLoop +{ + bool appExiting = runMainLoop(); + if (appExiting) + { + [frameTimer release]; + [[NSApplication sharedApplication] terminate:self]; + } +} + +@end diff --git a/indra/newview/llappviewermacosx-delegate.h b/indra/newview/llappviewermacosx-delegate.h deleted file mode 100644 index 848ccbde62..0000000000 --- a/indra/newview/llappviewermacosx-delegate.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// LLAppDelegate.h -// SecondLife -// -// Created by Geenz on 12/16/12. -// -// - -#import -#import "llopenglview-objc.h" -#include "llappviewermacosx-objc.h" - -@interface LLAppDelegate : NSObject { - LLNSWindow *window; - NSTimer *frameTimer; -} - -@property (assign) IBOutlet LLNSWindow *window; - -- (void) mainLoop; - -@end diff --git a/indra/newview/llappviewermacosx-delegate.mm b/indra/newview/llappviewermacosx-delegate.mm deleted file mode 100644 index 7baeeb1de8..0000000000 --- a/indra/newview/llappviewermacosx-delegate.mm +++ /dev/null @@ -1,57 +0,0 @@ -// -// LLAppDelegate.m -// SecondLife -// -// Created by Geenz on 12/16/12. -// -// - -#import "llappviewermacosx-delegate.h" - -@implementation LLAppDelegate - -@synthesize window; - -- (void)dealloc -{ - [super dealloc]; -} - -- (void) applicationDidFinishLaunching:(NSNotification *)notification -{ - frameTimer = nil; - - setLLNSWindowRef([self window]); - - if (initViewer()) - { - frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; - } else { - handleQuit(); - } -} - -- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender -{ - if (!runMainLoop()) - { - handleQuit(); - return NSTerminateCancel; - } else { - [frameTimer release]; - cleanupViewer(); - return NSTerminateNow; - } -} - -- (void) mainLoop -{ - bool appExiting = runMainLoop(); - if (appExiting) - { - [frameTimer release]; - [[NSApplication sharedApplication] terminate:self]; - } -} - -@end diff --git a/indra/newview/llappviewermacosx-objc.h b/indra/newview/llappviewermacosx-objc.h deleted file mode 100644 index ed9017ca5d..0000000000 --- a/indra/newview/llappviewermacosx-objc.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// NSObject_llappviewermacosx_objc.h -// SecondLife -// -// Created by Geenz on 12/16/12. -// -// - -#include -typedef std::tr1::function VoidCallback; -typedef void* ViewerAppRef; - -int createNSApp(int argc, const char **argv); - -bool initViewer(); -void handleQuit(); -bool runMainLoop(); -void initMainLoop(); -void cleanupViewer(); \ No newline at end of file diff --git a/indra/newview/llappviewermacosx-objc.mm b/indra/newview/llappviewermacosx-objc.mm deleted file mode 100644 index ca2090b790..0000000000 --- a/indra/newview/llappviewermacosx-objc.mm +++ /dev/null @@ -1,20 +0,0 @@ -// -// llappviewermacosx.m -// SecondLife -// -// Created by Geenz on 12/12/12. -// -// - -#import -#import -#include "llappviewermacosx-objc.h" -#import "llappviewermacosx-delegate.h" - -int createNSApp(int argc, const char *argv[]) -{ - return NSApplicationMain(argc, argv); -} - - - diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 6e7b91347b..b199405a66 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -31,7 +31,7 @@ #endif #include "llappviewermacosx.h" -#include "llappviewermacosx-objc.h" +#include "llwindowmacosx-objc.h" #include "llcommandlineparser.h" #include "llmemtype.h" -- cgit v1.3 From 29e747c4f17818816c502a3aa653b828e689be4a Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 22 Jan 2013 15:37:01 -0500 Subject: And thus, the demonic mouse position conversions from view space to screen space were tamed. --- indra/llcommon/llsys.cpp | 2 +- indra/llwindow/llopenglview-objc.h | 22 +++++++++++++++ indra/llwindow/llopenglview-objc.mm | 50 +++++++++++++++++++++++++++++++++++ indra/llwindow/llwindowmacosx-objc.mm | 2 +- indra/newview/llappviewermacosx.cpp | 2 +- 5 files changed, 75 insertions(+), 3 deletions(-) (limited to 'indra/newview/llappviewermacosx.cpp') diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index c96f2191f3..2a8eea88b6 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -67,7 +67,7 @@ using namespace llsd; # include # include # include -# include +# include # include # include # include diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h index 8412621392..dd2f35aafc 100644 --- a/indra/llwindow/llopenglview-objc.h +++ b/indra/llwindow/llopenglview-objc.h @@ -39,4 +39,26 @@ unsigned int mModifiers; } +- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view; +- (NSPoint)flipPoint:(NSPoint)aPoint; + +@end + +@interface NSScreen (PointConversion) + +/* + Returns the screen where the mouse resides + */ ++ (NSScreen *)currentScreenForMouseLocation; + +/* + Allows you to convert a point from global coordinates to the current screen coordinates. + */ +- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint; + +/* + Allows to flip the point coordinates, so y is 0 at the top instead of the bottom. x remains the same + */ +- (NSPoint)flipPoint:(NSPoint)aPoint; + @end diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 25669b25d3..ca66143b78 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -8,6 +8,35 @@ #import "llopenglview-objc.h" +@implementation NSScreen (PointConversion) + ++ (NSScreen *)currentScreenForMouseLocation +{ + NSPoint mouseLocation = [NSEvent mouseLocation]; + + NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator]; + NSScreen *screen; + while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(mouseLocation, screen.frame, NO)) + ; + + return screen; +} + +- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint +{ + float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x)); + float normalizedY = aPoint.y - self.frame.origin.y; + + return NSMakePoint(normalizedX, normalizedY); +} + +- (NSPoint)flipPoint:(NSPoint)aPoint +{ + return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y); +} + +@end + @implementation LLOpenGLView - (void)viewDidMoveToWindow @@ -349,6 +378,27 @@ callMouseExit(); } +- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view +{ + NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation]; + if(currentScreen) + { + NSPoint windowPoint = [view convertPoint:point toView:nil]; + NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint]; + NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint]; + flippedScreenPoint.y += [currentScreen frame].origin.y; + + return flippedScreenPoint; + } + + return NSZeroPoint; +} + +- (NSPoint)flipPoint:(NSPoint)aPoint +{ + return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y); +} + - (BOOL) becomeFirstResponder { NSLog(@"Window gained focus!"); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 1a64c94b2d..b6e5767203 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -298,7 +298,7 @@ void convertWindowToScreen(NSWindowRef window, float *coord) NSPoint point; point.x = coord[0]; point.y = coord[1]; - point = [(LLNSWindow*)window convertBaseToScreen:point]; + point = [(LLNSWindow*)window convertToScreenFromLocalPoint:point relativeToView:[(LLNSWindow*)window contentView]]; coord[0] = point.x; coord[1] = point.y; } diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index b199405a66..6e0becb518 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -41,7 +41,7 @@ #include "llmd5.h" #include "llfloaterworldmap.h" #include "llurldispatcher.h" -#include +#include #include "lldir.h" #include #include // for systemwide mute -- cgit v1.3 From bf1e9124f1530339bfa35652a3b3e329b32a3240 Mon Sep 17 00:00:00 2001 From: Geenz Date: Sat, 2 Feb 2013 12:49:39 -0500 Subject: Restore the old Carbon crash handler, and more deprecated API removal. --- indra/llwindow/llwindowmacosx.cpp | 4 +- indra/newview/llappviewermacosx.cpp | 116 +++++++++++++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 4 deletions(-) (limited to 'indra/newview/llappviewermacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index f25fc82896..2e86759ec0 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1350,7 +1350,7 @@ void LLWindowMacOSX::updateCursor() { default: case UI_CURSOR_ARROW: - InitCursor(); + setArrowCursor(); if(mCursorHidden) { // Since InitCursor resets the hide level, correct for it here. @@ -1410,7 +1410,7 @@ void LLWindowMacOSX::updateCursor() if(result != noErr) { - InitCursor(); + setArrowCursor(); } mCurrentCursor = mNextCursor; diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 28210d18dd..4141f16647 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -30,6 +30,8 @@ #error "Use only with Mac OS X" #endif +#define LL_CARBON_CRASH_HANDLER 1 + #include "llappviewermacosx.h" #include "llwindowmacosx-objc.h" #include "llcommandlineparser.h" @@ -40,6 +42,9 @@ #include "llfloaterworldmap.h" #include "llurldispatcher.h" #include +#ifdef LL_CARBON_CRASH_HANDLER +#include +#endif #include "lldir.h" #include #include // for systemwide mute @@ -51,8 +56,18 @@ namespace // They are not used immediately by the app. int gArgC; char** gArgV; - + bool sCrashReporterIsRunning = false; LLAppViewerMacOSX* gViewerAppPtr; +#ifdef LL_CARBON_CRASH_HANDLER + OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) + { + OSErr result = noErr; + + LLAppViewer::instance()->userQuit(); + + return(result); + } +#endif } bool initViewer() @@ -263,9 +278,39 @@ bool LLAppViewerMacOSX::restoreErrorTrap() return reset_count == 0; } +#ifdef LL_CARBON_CRASH_HANDLER +static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, + EventRef inEvent, + void* inUserData) +{ + ProcessSerialNumber psn; + + GetEventParameter(inEvent, + kEventParamProcessID, + typeProcessSerialNumber, + NULL, + sizeof(psn), + NULL, + &psn); + + if( GetEventKind(inEvent) == kEventAppTerminated ) + { + Boolean matching_psn = FALSE; + OSErr os_result = SameProcess(&psn, (ProcessSerialNumber*)inUserData, &matching_psn); + if(os_result >= 0 && matching_psn) + { + sCrashReporterIsRunning = false; + QuitApplicationEventLoop(); + } + } + return noErr; +} +#endif + void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) { - // This used to use fork&exec, but is switched to LSOpenApplication to +#ifdef LL_CARBON_CRASH_HANDLER + // This used to use fork&exec, but is switched to LSOpenApplication to // Make sure the crash reporter launches in front of the SL window. std::string command_str; @@ -283,8 +328,75 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) memset(&appParams, 0, sizeof(appParams)); appParams.version = 0; appParams.flags = kLSLaunchNoParams | kLSLaunchStartClassic; + appParams.application = &appRef; + + if(reportFreeze) + { + // Make sure freeze reporting launches the crash logger synchronously, lest + // Log files get changed by SL while the logger is running. + + // *NOTE:Mani A better way - make a copy of the data that the crash reporter will send + // and let SL go about its business. This way makes the mac work like windows and linux + // and is the smallest patch for the issue. + sCrashReporterIsRunning = false; + ProcessSerialNumber o_psn; + + static EventHandlerRef sCarbonEventsRef = NULL; + static const EventTypeSpec kEvents[] = + { + { kEventClassApplication, kEventAppTerminated } + }; + + // Install the handler to detect crash logger termination + InstallEventHandler(GetApplicationEventTarget(), + (EventHandlerUPP) CarbonEventHandler, + GetEventTypeCount(kEvents), + kEvents, + &o_psn, + &sCarbonEventsRef + ); + + // Remove, temporarily the quit handler - which has *crash* behavior before + // the mainloop gets running! + AERemoveEventHandler(kCoreEventClass, + kAEQuitApplication, + NewAEEventHandlerUPP(AEQuitHandler), + false); + + // Launch the crash reporter. + os_result = LSOpenApplication(&appParams, &o_psn); + + if(os_result >= 0) + { + sCrashReporterIsRunning = true; + } + + while(sCrashReporterIsRunning) + { + RunApplicationEventLoop(); + } + + // Re-install the apps quit handler. + AEInstallEventHandler(kCoreEventClass, + kAEQuitApplication, + NewAEEventHandlerUPP(AEQuitHandler), + 0, + false); + + // Remove the crash reporter quit handler. + RemoveEventHandler(sCarbonEventsRef); + } + else + { + appParams.flags |= kLSLaunchAsync; + clear_signals(); + + ProcessSerialNumber o_psn; + os_result = LSOpenApplication(&appParams, &o_psn); + } } +#endif } std::string LLAppViewerMacOSX::generateSerialNumber() -- cgit v1.3 From f3ef69ec19c3fb54d53aba1aa2ac49bc8140b591 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 4 Feb 2013 18:27:47 -0500 Subject: Updated the crash handler to produce a CFURL which gets converted into a FSRef due to the Files.h deprecation. --- indra/newview/llappviewermacosx.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'indra/newview/llappviewermacosx.cpp') diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 4141f16647..47c82975d8 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -317,12 +317,19 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) //command_str = "open Second Life.app/Contents/Resources/mac-crash-logger.app"; command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger"; + CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)command_str.c_str(), strlen(command_str.c_str()), FALSE); + + // FSRef apparently isn't deprecated. + // There's other funcitonality that depends on it existing as well that isn't deprecated. + // There doesn't seem to be much to directly verify what the status of FSRef is, outside of some documentation pointing at FSRef being valid, and other documentation pointing to everything in Files.h being deprecated. + // We'll assume it isn't for now, since all non-deprecated functions that use it seem to assume similar. + FSRef appRef; - Boolean isDir = 0; - OSStatus os_result = FSPathMakeRef((UInt8*)command_str.c_str(), - &appRef, - &isDir); - if(os_result >= 0) + Boolean pathstatus = CFURLGetFSRef(urlRef, &appRef); + + OSStatus os_result = noErr; + + if(pathstatus == true) { LSApplicationParameters appParams; memset(&appParams, 0, sizeof(appParams)); -- cgit v1.3