From c8aa1fb7c8ed44886599ea4e04eed403392e2e34 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 17 Dec 2012 18:00:30 -0500 Subject: LLWindow: Move to using Cocoa for window and view creation along with setting up callbacks for event handling as such. --- indra/llwindow/llwindowmacosx.cpp | 2632 +++++++------------------------------ 1 file changed, 466 insertions(+), 2166 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 97637c937f..1fb8bea802 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -30,7 +30,6 @@ #include "llkeyboardmacosx.h" #include "llwindowcallbacks.h" -#include "llwindowmacosx-objc.h" #include "llpreeditor.h" #include "llerror.h" @@ -58,7 +57,6 @@ const S32 MAX_NUM_RESOLUTIONS = 32; // BOOL LLWindowMacOSX::sUseMultGL = FALSE; -WindowRef LLWindowMacOSX::sMediaWindow = NULL; // Cross-platform bits: @@ -98,105 +96,9 @@ BOOL check_for_card(const char* RENDERER, const char* bad_card) // We may want to base this on the setting of _DEBUG... #define CAPTURE_ALL_DISPLAYS 0 -static double getDictDouble (CFDictionaryRef refDict, CFStringRef key); +//static double getDictDouble (CFDictionaryRef refDict, CFStringRef key); static long getDictLong (CFDictionaryRef refDict, CFStringRef key); - - - -// CarbonEvents we're interested in. -static EventTypeSpec WindowHandlerEventList[] = -{ - // Window-related events - { kEventClassWindow, kEventWindowActivated }, - { kEventClassWindow, kEventWindowDeactivated }, - { kEventClassWindow, kEventWindowShown }, - { kEventClassWindow, kEventWindowHidden }, - { kEventClassWindow, kEventWindowCollapsed }, - { kEventClassWindow, kEventWindowExpanded }, - { kEventClassWindow, kEventWindowGetClickActivation }, - { kEventClassWindow, kEventWindowClose }, - { kEventClassWindow, kEventWindowBoundsChanging }, - { kEventClassWindow, kEventWindowBoundsChanged }, - { kEventClassWindow, kEventWindowGetIdealSize }, - - // Mouse events - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseUp }, - { kEventClassMouse, kEventMouseDragged }, - { kEventClassMouse, kEventMouseWheelMoved }, - { kEventClassMouse, kEventMouseMoved }, - - // Keyboard events - // No longer handle raw key down events directly. - // When text input events come in, extract the raw key events from them and process at that point. - // This allows input methods to eat keystrokes the way they're supposed to. -// { kEventClassKeyboard, kEventRawKeyDown }, -// { kEventClassKeyboard, kEventRawKeyRepeat }, - { kEventClassKeyboard, kEventRawKeyUp }, - { kEventClassKeyboard, kEventRawKeyModifiersChanged }, - - // Text input events - { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent }, - { kEventClassTextInput, kEventTextInputUpdateActiveInputArea }, - { kEventClassTextInput, kEventTextInputOffsetToPos }, - { kEventClassTextInput, kEventTextInputPosToOffset }, - { kEventClassTextInput, kEventTextInputShowHideBottomWindow }, - { kEventClassTextInput, kEventTextInputGetSelectedText }, - { kEventClassTextInput, kEventTextInputFilterText }, - - // TSM Document Access events (advanced input method support) - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetFont }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetGlyphInfo }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessLockDocument }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessUnlockDocument } -}; - -static EventTypeSpec GlobalHandlerEventList[] = -{ - // Mouse events - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseUp }, - { kEventClassMouse, kEventMouseDragged }, - { kEventClassMouse, kEventMouseWheelMoved }, - { kEventClassMouse, kEventMouseMoved }, - - // Keyboard events - // No longer handle raw key down events directly. - // When text input events come in, extract the raw key events from them and process at that point. - // This allows input methods to eat keystrokes the way they're supposed to. -// { kEventClassKeyboard, kEventRawKeyDown }, -// { kEventClassKeyboard, kEventRawKeyRepeat }, - { kEventClassKeyboard, kEventRawKeyUp }, - { kEventClassKeyboard, kEventRawKeyModifiersChanged }, - - // Text input events - { kEventClassTextInput, kEventTextInputUpdateActiveInputArea }, - { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent }, - { kEventClassTextInput, kEventTextInputOffsetToPos }, - { kEventClassTextInput, kEventTextInputPosToOffset }, - { kEventClassTextInput, kEventTextInputShowHideBottomWindow }, - { kEventClassTextInput, kEventTextInputGetSelectedText }, - { kEventClassTextInput, kEventTextInputFilterText }, - - // TSM Document Access events (advanced input method support) - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetFont }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetGlyphInfo }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessLockDocument }, - { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessUnlockDocument } -}; - -static EventTypeSpec CommandHandlerEventList[] = -{ - { kEventClassCommand, kEventCommandProcess } -}; - // MBW -- HACK ALERT // On the Mac, to put up an OS dialog in full screen mode, we must first switch OUT of full screen mode. // The proper way to do this is to bracket the dialog with calls to beforeDialog() and afterDialog(), but these @@ -204,8 +106,6 @@ static EventTypeSpec CommandHandlerEventList[] = // This assumes that there will be only one object of this class at any time. Hopefully this is true. static LLWindowMacOSX *gWindowImplementation = NULL; - - LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, @@ -233,8 +133,6 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mContext = NULL; mPixelFormat = NULL; mDisplay = CGMainDisplayID(); - mOldDisplayMode = NULL; - mTimer = NULL; mSimulatedRightClick = FALSE; mLastModifiers = 0; mHandsOffEvents = FALSE; @@ -246,12 +144,8 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mOverrideAspectRatio = 0.f; mMaximized = FALSE; mMinimized = FALSE; - mTSMDocument = NULL; // Just in case. mLanguageTextInputAllowed = FALSE; - mTSMScriptCode = 0; - mTSMLangCode = 0; mPreeditor = NULL; - mRawKeyEvent = NULL; mFSAASamples = fsaa_samples; mForceRebuild = FALSE; @@ -263,43 +157,23 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay); // Stash the window title - strcpy((char*)mWindowTitle + 1, title.c_str()); /* Flawfinder: ignore */ - mWindowTitle[0] = title.length(); - - mEventHandlerUPP = NewEventHandlerUPP(staticEventHandler); - mMoveEventCampartorUPP = NewEventComparatorUPP(staticMoveEventComparator); - mGlobalHandlerRef = NULL; - mWindowHandlerRef = NULL; + mWindowTitle = title; + //mWindowTitle[0] = title.length(); mDragOverrideCursor = -1; - // We're not clipping yet - SetRect( &mOldMouseClip, 0, 0, 0, 0 ); - // Set up global event handlers (the fullscreen case needs this) - InstallStandardEventHandler(GetApplicationEventTarget()); + //InstallStandardEventHandler(GetApplicationEventTarget()); // Stash an object pointer for OSMessageBox() gWindowImplementation = this; - // Create the GL context and set it up for windowed or fullscreen, as appropriate. + LL_INFOS("Window") << "Creating context..." << LL_ENDL; if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) { if(mWindow != NULL) { - // MBW -- XXX -- I think we can now do this here? - // Constrain the window to the screen it's mostly on, resizing if necessary. - ConstrainWindowToScreen( - mWindow, - kWindowStructureRgn, - kWindowConstrainMayResize | - // kWindowConstrainStandardOptions | - 0, - NULL, - NULL); - - MacShowWindow(mWindow); - BringToFront(mWindow); + makeWindowOrderFront(mWindow); } if (!gGLManager.initGL()) @@ -321,463 +195,193 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mCallbacks = callbacks; stop_glerror(); + + } -BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) -{ - OSStatus err; - BOOL glNeedsInit = FALSE; - - if(mGlobalHandlerRef == NULL) - { - InstallApplicationEventHandler(mEventHandlerUPP, GetEventTypeCount (CommandHandlerEventList), CommandHandlerEventList, (void*)this, &mGlobalHandlerRef); - } - - mFullscreen = fullscreen; - - if (mFullscreen && (mOldDisplayMode == NULL)) - { - LL_INFOS("Window") << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; - - // NOTE: The refresh rate will be REPORTED AS 0 for many DVI and notebook displays. Plan accordingly. - double refresh = getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate); +// These functions are used as callbacks for event handling within Cocoa. +// It's a good idea to wrap these to avoid reworking more code than we need to within LLWindow. - // If the requested width or height is 0, find the best default for the monitor. - if((width == 0) || (height == 0)) - { - // Scan through the list of modes, looking for one which has: - // height between 700 and 800 - // aspect ratio closest to the user's original mode - S32 resolutionCount = 0; - LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount); +void callKeyUp(unsigned short key, unsigned int mask) +{ + gKeyboard->handleKeyUp(key, mask); +} - if(resolutionList != NULL) - { - F32 closestAspect = 0; - U32 closestHeight = 0; - U32 closestWidth = 0; - int i; +void callKeyDown(unsigned short key, unsigned int mask) +{ + gKeyboard->handleKeyDown(key, mask); +} - LL_DEBUGS("Window") << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL; +void callUnicodeCallback(wchar_t character, unsigned int mask) +{ + gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask); +} - for(i=0; i < resolutionCount; i++) - { - F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight; +void callModifierCallback(unsigned int mask) +{ + +} - LL_DEBUGS("Window") << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL; +void callRightMouseDown(float *pos, MASK mask) +{ + LLCoordGL outCoords; + outCoords.mX = llround(pos[0]); + outCoords.mY = llround(pos[1]); + gWindowImplementation->getCallbacks()->handleRightMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); +} - if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) && - (fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio))) - { - LL_DEBUGS("Window") << " (new closest mode) " << LL_ENDL; +void callRightMouseUp(float *pos, MASK mask) +{ + LLCoordGL outCoords; + outCoords.mX = llround(pos[0]); + outCoords.mY = llround(pos[1]); + gWindowImplementation->getCallbacks()->handleRightMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); +} - // This is the closest mode we've seen yet. - closestWidth = resolutionList[i].mWidth; - closestHeight = resolutionList[i].mHeight; - closestAspect = aspect; - } - } +void callLeftMouseDown(float *pos, MASK mask) +{ + LLCoordGL outCoords; + outCoords.mX = llround(pos[0]); + outCoords.mY = llround(pos[1]); + gWindowImplementation->getCallbacks()->handleMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); + LL_INFOS("Window") << outCoords.mX << ", " << outCoords.mY << LL_ENDL; +} - width = closestWidth; - height = closestHeight; - } - } +void callLeftMouseUp(float *pos, MASK mask) +{ + LLCoordGL outCoords; + outCoords.mX = llround(pos[0]); + outCoords.mY = llround(pos[1]); + gWindowImplementation->getCallbacks()->handleMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); + +} - if((width == 0) || (height == 0)) - { - // Mode search failed for some reason. Use the old-school default. - width = 1024; - height = 768; - } +void callDoubleClick(float *pos, MASK mask) +{ + LLCoordGL outCoords; + outCoords.mX = llround(pos[0]); + outCoords.mY = llround(pos[1]); + gWindowImplementation->getCallbacks()->handleDoubleClick(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); +} - if (true) - { - // Fullscreen support - CFDictionaryRef refDisplayMode = 0; - boolean_t exactMatch = false; - -#if CAPTURE_ALL_DISPLAYS - // Capture all displays (may want to do this for final build) - CGCaptureAllDisplays (); -#else - // Capture only the main display (useful for debugging) - CGDisplayCapture (mDisplay); -#endif +void callResize(unsigned int width, unsigned int height) +{ + gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height); +} - // Switch the display to the desired resolution and refresh - refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate( - mDisplay, - BITS_PER_PIXEL, - width, - height, - refresh, - &exactMatch); +void callMouseMoved(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()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); +} - if (refDisplayMode) - { - LL_DEBUGS("Window") << "createContext: switching display resolution" << LL_ENDL; - mOldDisplayMode = CGDisplayCurrentMode (mDisplay); - CGDisplaySwitchToMode (mDisplay, refDisplayMode); - // CFRelease(refDisplayMode); +void callScrollMoved(float delta) +{ + gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, delta); +} - AddEventTypesToHandler(mGlobalHandlerRef, GetEventTypeCount (GlobalHandlerEventList), GlobalHandlerEventList); - } +void callMouseExit() +{ + gWindowImplementation->getCallbacks()->handleMouseLeave(gWindowImplementation); +} +void callWindowFocus() +{ + gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); +} - mFullscreen = TRUE; - mFullscreenWidth = CGDisplayPixelsWide(mDisplay); - mFullscreenHeight = CGDisplayPixelsHigh(mDisplay); - mFullscreenBits = CGDisplayBitsPerPixel(mDisplay); - mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate)); +void callWindowUnfocus() +{ + gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); +} - LL_INFOS("Window") << "Running at " << mFullscreenWidth - << "x" << mFullscreenHeight - << "x" << mFullscreenBits - << " @ " << mFullscreenRefresh - << LL_ENDL; - } - else - { - // No fullscreen support - mFullscreen = FALSE; - mFullscreenWidth = -1; - mFullscreenHeight = -1; - mFullscreenBits = -1; - mFullscreenRefresh = -1; - - std::string error= llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height); - OSMessageBox(error, "Error", OSMB_OK); - } - } +void callDeltaUpdate(float *delta, MASK mask) +{ + gWindowImplementation->updateMouseDeltas(); +} - if(!mFullscreen && (mWindow == NULL)) +void LLWindowMacOSX::updateMouseDeltas() +{ + if (mCursorDecoupled) { - //int displayWidth = CGDisplayPixelsWide(mDisplay); - //int displayHeight = CGDisplayPixelsHigh(mDisplay); - //const int menuBarPlusTitleBar = 44; // Ugly magic number. - - LL_DEBUGS("Window") << "createContext: creating window" << LL_ENDL; - - mPreviousWindowRect.left = (long) x; - mPreviousWindowRect.right = (long) x + width; - mPreviousWindowRect.top = (long) y; - mPreviousWindowRect.bottom = (long) y + height; - - //----------------------------------------------------------------------- - // Create the window - //----------------------------------------------------------------------- - mWindow = NewCWindow( - NULL, - &mPreviousWindowRect, - mWindowTitle, - false, // Create the window invisible. Whoever calls createContext() should show it after any moving/resizing. - // noGrowDocProc, // Window with no grow box and no zoom box - zoomDocProc, // Window with a grow box and a zoom box - // zoomNoGrow, // Window with a zoom box but no grow box - kFirstWindowOfClass, - true, - (long)this); - - if (!mWindow) + CGMouseDelta x, y; + CGGetLastMouseDelta( &x, &y ); + mCursorLastEventDeltaX = x; + mCursorLastEventDeltaY = y; + + if (mCursorIgnoreNextDelta) { - setupFailure("Window creation error", "Error", OSMB_OK); - return FALSE; + mCursorLastEventDeltaX = 0; + mCursorLastEventDeltaY = 0; + mCursorIgnoreNextDelta = FALSE; } + } else { + mCursorLastEventDeltaX = 0; + mCursorLastEventDeltaY = 0; + } +} - // Turn on live resize. - // For this to work correctly, we need to be able to call LLViewerWindow::draw from - // the event handler for kEventWindowBoundsChanged. It's not clear that we have access from here. - // err = ChangeWindowAttributes(mWindow, kWindowLiveResizeAttribute, 0); +void LLWindowMacOSX::getMouseDeltas(float* delta) +{ + delta[0] = mCursorLastEventDeltaX; + delta[1] = mCursorLastEventDeltaY; +} - // Set up window event handlers (some window-related events ONLY go to window handlers.) - InstallStandardEventHandler(GetWindowEventTarget(mWindow)); - InstallWindowEventHandler(mWindow, mEventHandlerUPP, GetEventTypeCount (WindowHandlerEventList), WindowHandlerEventList, (void*)this, &mWindowHandlerRef); // add event handler -#if LL_OS_DRAGDROP_ENABLED - InstallTrackingHandler( dragTrackingHandler, mWindow, (void*)this ); - InstallReceiveHandler( dragReceiveHandler, mWindow, (void*)this ); -#endif // LL_OS_DRAGDROP_ENABLED - } +BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) +{ + BOOL glNeedsInit = FALSE; - { - // Create and initialize our TSM document for language text input. - // If an error occured, we can do nothing better than simply ignore it. - // mTSMDocument will be kept NULL in case. - if (mTSMDocument) - { - DeactivateTSMDocument(mTSMDocument); - DeleteTSMDocument(mTSMDocument); - mTSMDocument = NULL; - } - static InterfaceTypeList types = { kUnicodeDocument }; - err = NewTSMDocument(1, types, &mTSMDocument, 0); - if (err != noErr) - { - LL_WARNS("Window") << "createContext: couldn't create a TSMDocument (" << err << ")" << LL_ENDL; - } - if (mTSMDocument) - { - ActivateTSMDocument(mTSMDocument); - allowLanguageTextInput(NULL, FALSE); - } + mFullscreen = fullscreen; + + if (mWindow == NULL) + { + LL_INFOS("Window") << "Creating window..." << LL_ENDL; + mWindow = createNSWindow(x, y, width, height); + LL_INFOS("Window") << "Registering key callbacks..." << LL_ENDL; + registerKeyDownCallback(mWindow, callKeyDown); + registerKeyUpCallback(mWindow, callKeyUp); + registerUnicodeCallback(mWindow, callUnicodeCallback); + registerMouseDownCallback(mWindow, callLeftMouseDown); + registerMouseUpCallback(mWindow, callLeftMouseUp); + registerRightMouseDownCallback(mWindow, callRightMouseDown); + registerRightMouseUpCallback(mWindow, callRightMouseUp); + registerDoubleClickCallback(mWindow, callDoubleClick); + registerMouseMovedCallback(mWindow, callMouseMoved); + registerScrollCallback(mWindow, callScrollMoved); + registerDeltaUpdateCallback(mWindow, callDeltaUpdate); + registerMouseExitCallback(mWindow, callMouseExit); } if(mContext == NULL) { - AGLRendererInfo rendererInfo = NULL; - - //----------------------------------------------------------------------- - // Create GL drawing context - //----------------------------------------------------------------------- - - if(mPixelFormat == NULL) - { - if(mFullscreen) - { - GLint fullscreenAttrib[] = - { - AGL_RGBA, - AGL_FULLSCREEN, - AGL_NO_RECOVERY, - AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0, - AGL_SAMPLES_ARB, mFSAASamples, - AGL_DOUBLEBUFFER, - AGL_CLOSEST_POLICY, - AGL_ACCELERATED, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_ALPHA_SIZE, 8, - AGL_DEPTH_SIZE, 24, - AGL_STENCIL_SIZE, 8, - AGL_NONE - }; - - LL_DEBUGS("Window") << "createContext: creating fullscreen pixelformat" << LL_ENDL; - - GDHandle gdhDisplay = NULL; - err = DMGetGDeviceByDisplayID ((DisplayIDType)mDisplay, &gdhDisplay, false); - - mPixelFormat = aglChoosePixelFormat(&gdhDisplay, 1, fullscreenAttrib); - rendererInfo = aglQueryRendererInfo(&gdhDisplay, 1); - } - else - { - // NOTE from Leslie: - // - // AGL_NO_RECOVERY, when combined with AGL_ACCELERATED prevents software rendering - // fallback which means we won't hvae shaders that compile and link but then don't - // work. The drawback is that our shader compilation will be a bit more finicky though. - - GLint windowedAttrib[] = - { - AGL_RGBA, - AGL_NO_RECOVERY, - AGL_DOUBLEBUFFER, - AGL_CLOSEST_POLICY, - AGL_ACCELERATED, - AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0, - AGL_SAMPLES_ARB, mFSAASamples, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_ALPHA_SIZE, 8, - AGL_DEPTH_SIZE, 24, - AGL_STENCIL_SIZE, 8, - AGL_NONE - }; - - LL_DEBUGS("Window") << "createContext: creating windowed pixelformat" << LL_ENDL; - - mPixelFormat = aglChoosePixelFormat(NULL, 0, windowedAttrib); - - GDHandle gdhDisplay = GetMainDevice(); - rendererInfo = aglQueryRendererInfo(&gdhDisplay, 1); - } - - // May want to get the real error text like this: - // (char *) aglErrorString(aglGetError()); - - if(aglGetError() != AGL_NO_ERROR) - { - setupFailure("Can't find suitable pixel format", "Error", OSMB_OK); - return FALSE; - } - } - - if(mPixelFormat) - { - LL_DEBUGS("Window") << "createContext: creating GL context" << LL_ENDL; - mContext = aglCreateContext(mPixelFormat, NULL); - } - - if(mContext == NULL) - { - setupFailure("Can't make GL context", "Error", OSMB_OK); - return FALSE; - } - - gGLManager.mVRAM = 0; - - if(rendererInfo != NULL) - { - GLint result; - - if(aglDescribeRenderer(rendererInfo, AGL_VIDEO_MEMORY, &result)) - { - // llinfos << "createContext: aglDescribeRenderer(AGL_VIDEO_MEMORY) returned " << result << llendl; - gGLManager.mVRAM = result / (1024 * 1024); - } - else - { - // llinfos << "createContext: aglDescribeRenderer(AGL_VIDEO_MEMORY) failed." << llendl; - } - - // This could be useful at some point, if it takes into account the memory already used by screen buffers, etc... - if(aglDescribeRenderer(rendererInfo, AGL_TEXTURE_MEMORY, &result)) - { - // llinfos << "createContext: aglDescribeRenderer(AGL_TEXTURE_MEMORY) returned " << result << llendl; - } - else - { - // llinfos << "createContext: aglDescribeRenderer(AGL_TEXTURE_MEMORY) failed." << llendl; - } - - aglDestroyRendererInfo(rendererInfo); - } - + LL_INFOS("Window") << "Creating GL view..." << LL_ENDL; + mGLView = createOpenGLView(mWindow); + registerResizeEventCallback(mGLView, callResize); + mContext = getCGLContextObj(mWindow); // Since we just created the context, it needs to be set up. glNeedsInit = TRUE; } // Hook up the context to a drawable - if (mFullscreen && (mOldDisplayMode != NULL)) - { - // We successfully captured the display. Use a fullscreen drawable - - LL_DEBUGS("Window") << "createContext: attaching fullscreen drawable" << LL_ENDL; - -#if CAPTURE_ALL_DISPLAYS - // Capture all displays (may want to do this for final build) - aglDisable (mContext, AGL_FS_CAPTURE_SINGLE); -#else - // Capture only the main display (useful for debugging) - aglEnable (mContext, AGL_FS_CAPTURE_SINGLE); -#endif - - if (!aglSetFullScreen (mContext, 0, 0, 0, 0)) - { - setupFailure("Can't set GL fullscreen", "Error", OSMB_OK); - return FALSE; - } - } - else if(!mFullscreen && (mWindow != NULL)) - { - LL_DEBUGS("Window") << "createContext: attaching windowed drawable" << LL_ENDL; - - // We created a window. Use it as the drawable. - if(!aglSetDrawable(mContext, GetWindowPort (mWindow))) - { - setupFailure("Can't set GL drawable", "Error", OSMB_OK); - return FALSE; - } - } - else - { - setupFailure("Can't get fullscreen or windowed drawable.", "Error", OSMB_OK); - return FALSE; - } if(mContext != NULL) { + LL_INFOS("Window") << "Setting CGL Context..." << LL_ENDL; LL_DEBUGS("Window") << "createContext: setting current context" << LL_ENDL; - - if (!aglSetCurrentContext(mContext)) + U32 err = CGLSetCurrentContext(mContext); + if (err != kCGLNoError) { setupFailure("Can't activate GL rendering context", "Error", OSMB_OK); return FALSE; } } - if(glNeedsInit) - { - // Check for some explicitly unsupported cards. - const char* RENDERER = (const char*) glGetString(GL_RENDERER); - - const char* CARD_LIST[] = - { "RAGE 128", - "RIVA TNT2", - "Intel 810", - "3Dfx/Voodoo3", - "Radeon 7000", - "Radeon 7200", - "Radeon 7500", - "Radeon DDR", - "Radeon VE", - "GDI Generic" }; - const S32 CARD_COUNT = LL_ARRAY_SIZE(CARD_LIST); - - // Future candidates: - // ProSavage/Twister - // SuperSavage - - S32 i; - for (i = 0; i < CARD_COUNT; i++) - { - if (check_for_card(RENDERER, CARD_LIST[i])) - { - close(); - return FALSE; - } - } - } - - GLint colorBits, alphaBits, depthBits, stencilBits; - - if( !aglDescribePixelFormat(mPixelFormat, AGL_BUFFER_SIZE, &colorBits) || - !aglDescribePixelFormat(mPixelFormat, AGL_ALPHA_SIZE, &alphaBits) || - !aglDescribePixelFormat(mPixelFormat, AGL_DEPTH_SIZE, &depthBits) || - !aglDescribePixelFormat(mPixelFormat, AGL_STENCIL_SIZE, &stencilBits)) - { - close(); - setupFailure("Can't get pixel format description", "Error", OSMB_OK); - return FALSE; - } - - LL_INFOS("GLInit") << "GL buffer: Color Bits " << S32(colorBits) - << " Alpha Bits " << S32(alphaBits) - << " Depth Bits " << S32(depthBits) - << " Stencil Bits" << S32(stencilBits) - << LL_ENDL; - - if (colorBits < 32) - { - close(); - setupFailure( - "Second Life requires True Color (32-bit) to run in a window.\n" - "Please go to Control Panels -> Display -> Settings and\n" - "set the screen to 32-bit color.\n" - "Alternately, if you choose to run fullscreen, Second Life\n" - "will automatically adjust the screen each time it runs.", - "Error", - OSMB_OK); - return FALSE; - } - - if (alphaBits < 8) - { - close(); - setupFailure( - "Second Life is unable to run because it can't get an 8 bit alpha\n" - "channel. Usually this is due to video card driver issues.\n" - "Please make sure you have the latest video card drivers installed.\n" - "Also be sure your monitor is set to True Color (32-bit) in\n" - "Control Panels -> Display -> Settings.\n" - "If you continue to receive this message, contact customer service.", - "Error", - OSMB_OK); - return FALSE; - } - // Disable vertical sync for swap GLint frames_per_swap = 0; if (disable_vsync) @@ -790,7 +394,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits LL_DEBUGS("GLinit") << "Keeping vertical sync" << LL_ENDL; frames_per_swap = 1; } - aglSetInteger(mContext, AGL_SWAP_INTERVAL, &frames_per_swap); + + CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap); //enable multi-threaded OpenGL if (sUseMultGL) @@ -809,109 +414,17 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; } } - + LL_INFOS("Window") << "Completed context creation." << LL_ENDL; // Don't need to get the current gamma, since there's a call that restores it to the system defaults. return TRUE; } -// changing fullscreen resolution, or switching between windowed and fullscreen mode. +// We only support OS X 10.7's fullscreen app mode which is literally a full screen window that fills a virtual desktop. +// This makes this method obsolete. BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) { - BOOL needsRebuild = FALSE; - BOOL result = true; - - if(fullscreen) - { - if(mFullscreen) - { - // Switching resolutions in fullscreen mode. Don't need to rebuild for this. - // Fullscreen support - CFDictionaryRef refDisplayMode = 0; - boolean_t exactMatch = false; - - // Switch the display to the desired resolution and refresh - refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate( - mDisplay, - BITS_PER_PIXEL, - size.mX, - size.mY, - getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate), - &exactMatch); - - if (refDisplayMode) - { - CGDisplaySwitchToMode (mDisplay, refDisplayMode); - // CFRelease(refDisplayMode); - } - - mFullscreenWidth = CGDisplayPixelsWide(mDisplay); - mFullscreenHeight = CGDisplayPixelsHigh(mDisplay); - mFullscreenBits = CGDisplayBitsPerPixel(mDisplay); - mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate)); - - LL_INFOS("Window") << "Switched resolution to " << mFullscreenWidth - << "x" << mFullscreenHeight - << "x" << mFullscreenBits - << " @ " << mFullscreenRefresh - << LL_ENDL; - - // Update the GL context to the new screen size - if (!aglUpdateContext(mContext)) - { - setupFailure("Can't set GL fullscreen", "Error", OSMB_OK); - result = FALSE; - } - } - else - { - // Switching from windowed to fullscreen - needsRebuild = TRUE; - } - } - else - { - if(mFullscreen) - { - // Switching from fullscreen to windowed - needsRebuild = TRUE; - } - else - { - // Windowed to windowed -- not sure why we would be called like this. Just change the window size. - // The bounds changed event handler will do the rest. - if(mWindow != NULL) - { - ::SizeWindow(mWindow, size.mX, size.mY, true); - } - } - } - - stop_glerror(); - if(needsRebuild || mForceRebuild) - { - mForceRebuild = FALSE; - destroyContext(); - result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); - if (result) - { - if(mWindow != NULL) - { - MacShowWindow(mWindow); - BringToFront(mWindow); - } - - llverify(gGLManager.initGL()); - - //start with arrow cursor - initCursors(); - setCursor( UI_CURSOR_ARROW ); - } - } - - stop_glerror(); - - return result; + return FALSE; } void LLWindowMacOSX::destroyContext() @@ -926,31 +439,8 @@ void LLWindowMacOSX::destroyContext() { LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL; - aglSetCurrentContext (NULL); - aglSetDrawable(mContext, NULL); - } - - // Make sure the display resolution gets restored - if(mOldDisplayMode != NULL) - { - LL_DEBUGS("Window") << "destroyContext: restoring display resolution " << LL_ENDL; - - CGDisplaySwitchToMode (mDisplay, mOldDisplayMode); - -#if CAPTURE_ALL_DISPLAYS - // Uncapture all displays (may want to do this for final build) - CGReleaseAllDisplays (); -#else - // Uncapture only the main display (useful for debugging) - CGDisplayRelease (mDisplay); -#endif - - // CFRelease(mOldDisplayMode); - - mOldDisplayMode = NULL; - - // Remove the global event handlers the fullscreen case needed - RemoveEventTypesFromHandler(mGlobalHandlerRef, GetEventTypeCount (GlobalHandlerEventList), GlobalHandlerEventList); + CGLSetCurrentContext(NULL); + mContext = NULL; } // Clean up remaining GL state before blowing away window @@ -959,49 +449,19 @@ void LLWindowMacOSX::destroyContext() // Clean up the pixel format if(mPixelFormat != NULL) { - LL_DEBUGS("Window") << "destroyContext: destroying pixel format " << LL_ENDL; - aglDestroyPixelFormat(mPixelFormat); + CGLDestroyPixelFormat(mPixelFormat); mPixelFormat = NULL; } - // Remove any Carbon Event handlers we installed - if(mGlobalHandlerRef != NULL) - { - LL_DEBUGS("Window") << "destroyContext: removing global event handler" << LL_ENDL; - RemoveEventHandler(mGlobalHandlerRef); - mGlobalHandlerRef = NULL; - } - - if(mWindowHandlerRef != NULL) - { - LL_DEBUGS("Window") << "destroyContext: removing window event handler" << LL_ENDL; - RemoveEventHandler(mWindowHandlerRef); - mWindowHandlerRef = NULL; - } - - // Cleanup any TSM document we created. - if(mTSMDocument != NULL) - { - LL_DEBUGS("Window") << "destroyContext: deleting TSM document" << LL_ENDL; - DeactivateTSMDocument(mTSMDocument); - DeleteTSMDocument(mTSMDocument); - mTSMDocument = NULL; - } - // Close the window if(mWindow != NULL) { - LL_DEBUGS("Window") << "destroyContext: disposing window" << LL_ENDL; - DisposeWindow(mWindow); - mWindow = NULL; } // Clean up the GL context if(mContext != NULL) { - LL_DEBUGS("Window") << "destroyContext: destroying GL context" << LL_ENDL; - aglDestroyContext(mContext); - mContext = NULL; + CGLDestroyContext(mContext); } } @@ -1022,17 +482,11 @@ LLWindowMacOSX::~LLWindowMacOSX() void LLWindowMacOSX::show() { - if(IsWindowCollapsed(mWindow)) - CollapseWindow(mWindow, false); - - MacShowWindow(mWindow); - BringToFront(mWindow); } void LLWindowMacOSX::hide() { setMouseClipping(FALSE); - HideWindow(mWindow); } //virtual @@ -1040,7 +494,6 @@ void LLWindowMacOSX::minimize() { setMouseClipping(FALSE); showCursor(); - CollapseWindow(mWindow, true); } //virtual @@ -1086,7 +539,6 @@ BOOL LLWindowMacOSX::getVisible() result = TRUE; }if (mWindow) { - if(MacIsWindowVisible(mWindow)) result = TRUE; } @@ -1107,7 +559,6 @@ BOOL LLWindowMacOSX::maximize() { if (mWindow && !mMaximized) { - ZoomWindow(mWindow, inContent, true); } return mMaximized; @@ -1125,17 +576,14 @@ void LLWindowMacOSX::gatherInput() { stopDockTileBounce(); } - - // Use the old-school version so we get AppleEvent handler dispatch and menuselect handling. - // Anything that has an event handler will get processed inside WaitNextEvent, so we only need to handle - // the odd stuff here. + EventRecord evt; while(WaitNextEvent(everyEvent, &evt, 0, NULL)) { // printf("WaitNextEvent returned true, event is %d.\n", evt.what); switch(evt.what) { - case mouseDown: + case mouseDown: { short part; WindowRef window; @@ -1143,35 +591,125 @@ void LLWindowMacOSX::gatherInput() part = FindWindow(evt.where, &window); switch ( part ) { - case inMenuBar: - selectResult = MenuSelect(evt.where); - - HiliteMenu(0); - break; + case inMenuBar: + selectResult = MenuSelect(evt.where); + + HiliteMenu(0); + break; } } - break; - - case kHighLevelEvent: - AEProcessAppleEvent (&evt); - break; - - case updateEvt: - // We shouldn't be getting these regularly (since our window will be buffered), but we need to handle them correctly... - BeginUpdate((WindowRef)evt.message); - EndUpdate((WindowRef)evt.message); - break; - + break; + + case kHighLevelEvent: + AEProcessAppleEvent (&evt); + break; + + case updateEvt: + // We shouldn't be getting these regularly (since our window will be buffered), but we need to handle them correctly... + BeginUpdate((WindowRef)evt.message); + EndUpdate((WindowRef)evt.message); + break; + } } + /* + U32 event = getLatestEvent(mWindow); + switch (event) { + case 0: + // Nothing's happened since our last handled event. + break; + + case 1: + { + gKeyboard->handleKeyDown(getKeyDown(mWindow), getModifiers(mWindow)); + mCallbacks->handleUnicodeChar(getLastCharacter(mWindow), gKeyboard->currentMask(FALSE)); // currentMask has the appropriately translated modifiers. + mLastModifiers = gKeyboard->currentMask(FALSE); + } + break; + + case 2: + gKeyboard->handleKeyUp(getKeyUp(mWindow), getModifiers(mWindow)); + mLastModifiers = gKeyboard->currentMask(FALSE); + break; + + case 3: + break; + + case 4: + { + LLCoordScreen inCoords; + LLCoordGL outCoords; + float* mouseCoords = getMouseDown(mWindow); + inCoords.mX = llround(mouseCoords[0]); + inCoords.mY = llround(mouseCoords[1]); + convertCoords(inCoords, &outCoords); + mCallbacks->handleMouseDown(this, outCoords, getModifiers(mWindow)); + mLastModifiers = gKeyboard->currentMask(FALSE); + } + break; + case 5: + { + LLCoordScreen inCoords; + LLCoordGL outCoords; + float* mouseCoords = getMouseUp(mWindow); + inCoords.mX = llround(mouseCoords[0]); + inCoords.mY = llround(mouseCoords[1]); + convertCoords(inCoords, &outCoords); + mCallbacks->handleMouseUp(this, outCoords, getModifiers(mWindow)); + mLastModifiers = gKeyboard->currentMask(FALSE); + } + break; + case 6: + { + LLCoordScreen inCoords; + LLCoordGL outCoords; + float* mouseCoords = getRightMouseDown(mWindow); + inCoords.mX = llround(mouseCoords[0]); + inCoords.mY = llround(mouseCoords[1]); + convertCoords(inCoords, &outCoords); + mCallbacks->handleRightMouseDown(this, outCoords, getModifiers(mWindow)); + mLastModifiers = gKeyboard->currentMask(FALSE); + } + break; + case 7: + { + LLCoordScreen inCoords; + LLCoordGL outCoords; + float* mouseCoords = getRightMouseDown(mWindow); + inCoords.mX = llround(mouseCoords[0]); + inCoords.mY = llround(mouseCoords[1]); + convertCoords(inCoords, &outCoords); + mCallbacks->handleRightMouseDown(this, outCoords, getModifiers(mWindow)); + mLastModifiers = gKeyboard->currentMask(FALSE); + } + break; + case 8: // Double click + { + LLCoordScreen inCoords; + LLCoordGL outCoords; + float* mouseCoords = getRightMouseDown(mWindow); + inCoords.mX = llround(mouseCoords[0]); + inCoords.mY = llround(mouseCoords[1]); + convertCoords(inCoords, &outCoords); + mCallbacks->handleDoubleClick(this, outCoords, getModifiers(mWindow)); + mLastModifiers = gKeyboard->currentMask(FALSE); + } + break; + case 10: // Text input (for IMEs) + + break; + default: + break; + + }*/ updateCursor(); } BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position) { - Rect window_rect; - OSStatus err = -1; + float rect[4]; + S32 err = -1; if(mFullscreen) { @@ -1181,10 +719,10 @@ BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position) } else if(mWindow) { - err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect); + getContentViewBounds(mWindow, rect); - position->mX = window_rect.left; - position->mY = window_rect.top; + position->mX = rect[0]; + position->mY = rect[1]; } else { @@ -1196,8 +734,8 @@ BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position) BOOL LLWindowMacOSX::getSize(LLCoordScreen *size) { - Rect window_rect; - OSStatus err = -1; + float rect[4]; + S32 err = -1; if(mFullscreen) { @@ -1207,10 +745,10 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size) } else if(mWindow) { - err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect); + getContentViewBounds(mWindow, rect); - size->mX = window_rect.right - window_rect.left; - size->mY = window_rect.bottom - window_rect.top; + size->mX = rect[2]; + size->mY = rect[3]; } else { @@ -1222,9 +760,9 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size) BOOL LLWindowMacOSX::getSize(LLCoordWindow *size) { - Rect window_rect; - OSStatus err = -1; - + float rect[4]; + S32 err = -1; + if(mFullscreen) { size->mX = mFullscreenWidth; @@ -1233,16 +771,16 @@ BOOL LLWindowMacOSX::getSize(LLCoordWindow *size) } else if(mWindow) { - err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect); - - size->mX = window_rect.right - window_rect.left; - size->mY = window_rect.bottom - window_rect.top; + getContentViewBounds(mWindow, rect); + + size->mX = rect[2]; + size->mY = rect[3]; } else { llerrs << "LLWindowMacOSX::getPosition(): no window and not fullscreen!" << llendl; } - + return (err == noErr); } @@ -1250,7 +788,8 @@ BOOL LLWindowMacOSX::setPosition(const LLCoordScreen position) { if(mWindow) { - MacMoveWindow(mWindow, position.mX, position.mY, false); + float pos[2] = {position.mX, position.mY}; + setWindowPos(mWindow, pos); } return TRUE; @@ -1260,7 +799,7 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size) { if(mWindow) { - SizeWindow(mWindow, size.mX, size.mY, true); + setWindowSize(mWindow, size.mX, size.mY); } return TRUE; @@ -1268,15 +807,16 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size) BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size) { - Rect client_rect; + float client_rect[4]; if (mWindow) { - OSStatus err = GetWindowBounds(mWindow, kWindowContentRgn, &client_rect); + S32 err = noErr; + getContentViewBounds(mWindow, client_rect); if (err == noErr) { - client_rect.right = client_rect.left + size.mX; - client_rect.bottom = client_rect.top + size.mY; - err = SetWindowBounds(mWindow, kWindowContentRgn, &client_rect); + client_rect[2] += size.mX; + client_rect[3] += size.mY; + setWindowSize(mWindow, client_rect[2], client_rect[3]); } if (err == noErr) { @@ -1293,7 +833,7 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size) void LLWindowMacOSX::swapBuffers() { - aglSwapBuffers(mContext); + CGLFlushDrawable(mContext); } F32 LLWindowMacOSX::getGamma() @@ -1453,7 +993,7 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position) return result; } - +/* static void fixOrigin(void) { GrafPtr port; @@ -1467,26 +1007,16 @@ static void fixOrigin(void) ::SetOrigin(0,0); } } - +*/ BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position) { - Point cursor_point; + float cursor_point[2]; LLCoordScreen screen_pos; - GrafPtr save; if(mWindow == NULL) return FALSE; - - ::GetPort(&save); - ::SetPort(GetWindowPort(mWindow)); - fixOrigin(); - - // gets the mouse location in local coordinates - ::GetMouse(&cursor_point); - -// lldebugs << "getCursorPosition(): cursor is at " << cursor_point.h << ", " << cursor_point.v << " port origin: " << portrect.left << ", " << portrect.top << llendl; - - ::SetPort(save); + + getCursorPos(mWindow, cursor_point); if(mCursorDecoupled) { @@ -1499,12 +1029,12 @@ BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position) // CGGetLastMouseDelta may behave strangely when the cursor's first captured. // Stash in the event handler instead. - cursor_point.h += mCursorLastEventDeltaX; - cursor_point.v += mCursorLastEventDeltaY; + cursor_point[0] += mCursorLastEventDeltaX; + cursor_point[1] += mCursorLastEventDeltaY; } - position->mX = cursor_point.h; - position->mY = cursor_point.v; + position->mX = cursor_point[0]; + position->mY = cursor_point[1]; return TRUE; } @@ -1521,7 +1051,6 @@ void LLWindowMacOSX::adjustCursorDecouple(bool warpingMouse) // llinfos << "adjustCursorDecouple: decoupling cursor" << llendl; CGAssociateMouseAndMouseCursorPosition(false); mCursorDecoupled = true; - FlushSpecificEventsFromQueue(GetCurrentEventQueue(), mMoveEventCampartorUPP, NULL); mCursorIgnoreNextDelta = TRUE; } } @@ -1568,52 +1097,13 @@ F32 LLWindowMacOSX::getPixelAspectRatio() // MBW -- XXX -- There's got to be a better way than this. Find it, please... +// Since we're no longer supporting the "typical" fullscreen mode with CGL or NSOpenGL anymore, these are unnecessary. -Geenz void LLWindowMacOSX::beforeDialog() { - if(mFullscreen) - { - -#if CAPTURE_ALL_DISPLAYS - // Uncapture all displays (may want to do this for final build) - CGReleaseAllDisplays (); -#else - // Uncapture only the main display (useful for debugging) - CGDisplayRelease (mDisplay); -#endif - // kDocumentWindowClass - // kMovableModalWindowClass - // kAllWindowClasses - - // GLint order = 0; - // aglSetInteger(mContext, AGL_ORDER_CONTEXT_TO_FRONT, &order); - aglSetDrawable(mContext, NULL); - // GetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), &oldWindowLevel); - // SetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), CGShieldingWindowLevel()); - - mHandsOffEvents = TRUE; - - } } void LLWindowMacOSX::afterDialog() { - if(mFullscreen) - { - mHandsOffEvents = FALSE; - - // SetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), oldWindowLevel); - aglSetFullScreen(mContext, 0, 0, 0, 0); - // GLint order = 1; - // aglSetInteger(mContext, AGL_ORDER_CONTEXT_TO_FRONT, &order); - -#if CAPTURE_ALL_DISPLAYS - // Capture all displays (may want to do this for final build) - CGCaptureAllDisplays (); -#else - // Capture only the main display (useful for debugging) - CGDisplayCapture (mDisplay); -#endif - } } @@ -1622,14 +1112,10 @@ void LLWindowMacOSX::flashIcon(F32 seconds) // Don't do this if we're already started, since this would try to install the NMRec twice. if(!mBounceTimer.getStarted()) { - OSErr err; - + S32 err = 0; + // TODO: Implement icon bouncing mBounceTime = seconds; - memset(&mBounceRec, 0, sizeof(mBounceRec)); - mBounceRec.qType = nmType; - mBounceRec.nmMark = 1; - err = NMInstall(&mBounceRec); - if(err == noErr) + if(err == 0) { mBounceTimer.start(); } @@ -1643,104 +1129,25 @@ void LLWindowMacOSX::flashIcon(F32 seconds) BOOL LLWindowMacOSX::isClipboardTextAvailable() { - OSStatus err; - ScrapRef scrap; - ScrapFlavorFlags flags; BOOL result = false; - - err = GetCurrentScrap(&scrap); - - if(err == noErr) - { - err = GetScrapFlavorFlags(scrap, kScrapFlavorTypeUnicode, &flags); - } - - if(err == noErr) - result = true; - + // TODO: Clipboard support. return result; } BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst) { - OSStatus err; - ScrapRef scrap; - Size len; BOOL result = false; - - err = GetCurrentScrap(&scrap); - - if(err == noErr) - { - err = GetScrapFlavorSize(scrap, kScrapFlavorTypeUnicode, &len); - } - - if((err == noErr) && (len > 0)) - { - int u16len = len / sizeof(U16); - U16 *temp = new U16[u16len + 1]; - if (temp) - { - memset(temp, 0, (u16len + 1) * sizeof(temp[0])); - err = GetScrapFlavorData(scrap, kScrapFlavorTypeUnicode, &len, temp); - if (err == noErr) - { - // convert \r\n to \n and \r to \n in the incoming text. - U16 *s, *d; - for(s = d = temp; s[0] != '\0'; s++, d++) - { - if(s[0] == '\r') - { - if(s[1] == '\n') - { - // CRLF, a.k.a. DOS newline. Collapse to a single '\n'. - s++; - } - - d[0] = '\n'; - } - else - { - d[0] = s[0]; - } - } - - d[0] = '\0'; - - dst = utf16str_to_wstring(temp); - - result = true; - } - delete[] temp; - } - } + + // TODO: Clipboard support. return result; } BOOL LLWindowMacOSX::copyTextToClipboard(const LLWString &s) { - OSStatus err; - ScrapRef scrap; - //Size len; - //char *temp; BOOL result = false; - - if (!s.empty()) - { - err = GetCurrentScrap(&scrap); - if (err == noErr) - err = ClearScrap(&scrap); - - if (err == noErr) - { - llutf16string utf16str = wstring_to_utf16str(s); - size_t u16len = utf16str.length() * sizeof(U16); - err = PutScrapFlavor(scrap, kScrapFlavorTypeUnicode, kScrapFlavorMaskNone, u16len, utf16str.data()); - if (err == noErr) - result = true; - } - } + + // TODO: Clipboard support. return result; } @@ -1761,1048 +1168,162 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r CFArrayRef modes = CGDisplayAvailableModes(mDisplay); if(modes != NULL) - { - CFIndex index, cnt; - - mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; - mNumSupportedResolutions = 0; - - // Examine each mode - cnt = CFArrayGetCount( modes ); - - for ( index = 0; (index < cnt) && (mNumSupportedResolutions < MAX_NUM_RESOLUTIONS); index++ ) - { - // Pull the mode dictionary out of the CFArray - CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex( modes, index ); - long width = getDictLong(mode, kCGDisplayWidth); - long height = getDictLong(mode, kCGDisplayHeight); - long bits = getDictLong(mode, kCGDisplayBitsPerPixel); - - if(bits == BITS_PER_PIXEL && width >= 800 && height >= 600) - { - BOOL resolution_exists = FALSE; - for(S32 i = 0; i < mNumSupportedResolutions; i++) - { - if (mSupportedResolutions[i].mWidth == width && - mSupportedResolutions[i].mHeight == height) - { - resolution_exists = TRUE; - } - } - if (!resolution_exists) - { - mSupportedResolutions[mNumSupportedResolutions].mWidth = width; - mSupportedResolutions[mNumSupportedResolutions].mHeight = height; - mNumSupportedResolutions++; - } - } - } - } - } - - num_resolutions = mNumSupportedResolutions; - return mSupportedResolutions; -} - -BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordWindow *to) -{ - S32 client_height; - Rect client_rect; - - if(mFullscreen) - { - // In the fullscreen case, the "window" is the entire screen. - client_rect.left = 0; - client_rect.top = 0; - client_rect.right = mFullscreenWidth; - client_rect.bottom = mFullscreenHeight; - } - else if (!mWindow || - (GetWindowBounds(mWindow, kWindowContentRgn, &client_rect) != noErr) || - NULL == to) - { - return FALSE; - } - - to->mX = from.mX; - client_height = client_rect.bottom - client_rect.top; - to->mY = client_height - from.mY - 1; - - return TRUE; -} - -BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordGL* to) -{ - S32 client_height; - Rect client_rect; - - if(mFullscreen) - { - // In the fullscreen case, the "window" is the entire screen. - client_rect.left = 0; - client_rect.top = 0; - client_rect.right = mFullscreenWidth; - client_rect.bottom = mFullscreenHeight; - } - else if (!mWindow || - (GetWindowBounds(mWindow, kWindowContentRgn, &client_rect) != noErr) || - NULL == to) - { - return FALSE; - } - - to->mX = from.mX; - client_height = client_rect.bottom - client_rect.top; - to->mY = client_height - from.mY - 1; - - return TRUE; -} - -BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to) -{ - if(mFullscreen) - { - // In the fullscreen case, window and screen coordinates are the same. - to->mX = from.mX; - to->mY = from.mY; - return TRUE; - } - else if(mWindow) - { - GrafPtr save; - Point mouse_point; - - mouse_point.h = from.mX; - mouse_point.v = from.mY; - - ::GetPort(&save); - ::SetPort(GetWindowPort(mWindow)); - fixOrigin(); - - ::GlobalToLocal(&mouse_point); - - to->mX = mouse_point.h; - to->mY = mouse_point.v; - - ::SetPort(save); - - return TRUE; - } - - return FALSE; -} - -BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to) -{ - if(mFullscreen) - { - // In the fullscreen case, window and screen coordinates are the same. - to->mX = from.mX; - to->mY = from.mY; - return TRUE; - } - else if(mWindow) - { - GrafPtr save; - Point mouse_point; - - mouse_point.h = from.mX; - mouse_point.v = from.mY; - ::GetPort(&save); - ::SetPort(GetWindowPort(mWindow)); - fixOrigin(); - - LocalToGlobal(&mouse_point); - - to->mX = mouse_point.h; - to->mY = mouse_point.v; - - ::SetPort(save); - - return TRUE; - } - - return FALSE; -} - -BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordGL *to) -{ - LLCoordWindow window_coord; - - return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); -} - -BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to) -{ - LLCoordWindow window_coord; - - return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); -} - - - - -void LLWindowMacOSX::setupFailure(const std::string& text, const std::string& caption, U32 type) -{ - destroyContext(); - - OSMessageBox(text, caption, type); -} - -pascal Boolean LLWindowMacOSX::staticMoveEventComparator( EventRef event, void* data) -{ - UInt32 evtClass = GetEventClass (event); - UInt32 evtKind = GetEventKind (event); - - if ((evtClass == kEventClassMouse) && ((evtKind == kEventMouseDragged) || (evtKind == kEventMouseMoved))) - { - return true; - } - - else - { - return false; - } -} - - -pascal OSStatus LLWindowMacOSX::staticEventHandler(EventHandlerCallRef myHandler, EventRef event, void* userData) -{ - LLWindowMacOSX *self = (LLWindowMacOSX*)userData; - - return(self->eventHandler(myHandler, event)); -} - -OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef event) -{ - OSStatus result = eventNotHandledErr; - UInt32 evtClass = GetEventClass (event); - UInt32 evtKind = GetEventKind (event); - - // Always handle command events, even in hands-off mode. - if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess)) - { - HICommand command; - GetEventParameter (event, kEventParamDirectObject, typeHICommand, NULL, sizeof(command), NULL, &command); - - switch(command.commandID) - { - case kHICommandQuit: - if(mCallbacks->handleCloseRequest(this)) - { - // Get the app to initiate cleanup. - mCallbacks->handleQuit(this); - // The app is responsible for calling destroyWindow when done with GL - } - result = noErr; - break; - - default: - // MBW -- XXX -- Should we handle other events here? - break; - } - } - - if(mHandsOffEvents) - { - return(result); - } - - switch (evtClass) - { - case kEventClassTextInput: - { - switch (evtKind) - { - case kEventTextInputUpdateActiveInputArea: - { - EventParamType param_type; - - long fix_len; - UInt32 text_len; - if (mPreeditor - && (result = GetEventParameter(event, kEventParamTextInputSendFixLen, - typeLongInteger, ¶m_type, sizeof(fix_len), NULL, &fix_len)) == noErr - && typeLongInteger == param_type - && (result = GetEventParameter(event, kEventParamTextInputSendText, - typeUnicodeText, ¶m_type, 0, &text_len, NULL)) == noErr - && typeUnicodeText == param_type) - { - // Handle an optional (but essential to facilitate TSMDA) ReplaceRange param. - CFRange range; - if (GetEventParameter(event, kEventParamTextInputSendReplaceRange, - typeCFRange, ¶m_type, sizeof(range), NULL, &range) == noErr - && typeCFRange == param_type) - { - // Although the spec. is unclear, replace range should - // not present when there is an active preedit. We just - // ignore the case. markAsPreedit will detect the case and warn it. - const LLWString & text = mPreeditor->getPreeditString(); - const S32 location = wstring_wstring_length_from_utf16_length(text, 0, range.location); - const S32 length = wstring_wstring_length_from_utf16_length(text, location, range.length); - mPreeditor->markAsPreedit(location, length); - } - mPreeditor->resetPreedit(); - - // Receive the text from input method. - U16 *const text = new U16[text_len / sizeof(U16)]; - GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, NULL, text_len, NULL, text); - if (fix_len < 0) - { - // Do we still need this? Seems obsolete... - fix_len = text_len; - } - const LLWString fix_string - = utf16str_to_wstring(llutf16string(text, fix_len / sizeof(U16))); - const LLWString preedit_string - = utf16str_to_wstring(llutf16string(text + fix_len / sizeof(U16), (text_len - fix_len) / sizeof(U16))); - delete[] text; - - // Handle fixed (comitted) string. - if (fix_string.length() > 0) - { - for (LLWString::const_iterator i = fix_string.begin(); i != fix_string.end(); i++) - { - mPreeditor->handleUnicodeCharHere(*i); - } - } - - // Receive the segment info and caret position. - LLPreeditor::segment_lengths_t preedit_segment_lengths; - LLPreeditor::standouts_t preedit_standouts; - S32 caret_position = preedit_string.length(); - UInt32 text_range_array_size; - if (GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray, - ¶m_type, 0, &text_range_array_size, NULL) == noErr - && typeTextRangeArray == param_type - && text_range_array_size > sizeof(TextRangeArray)) - { - // TextRangeArray is a variable-length struct. - TextRangeArray * const text_range_array = (TextRangeArray *) new char[text_range_array_size]; - GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray, - NULL, text_range_array_size, NULL, text_range_array); - - // WARNING: We assume ranges are in ascending order, - // although the condition is undocumented. It seems - // OK to assume this. I also assumed - // the ranges are contiguous in previous versions, but I - // have heard a rumore that older versions os ATOK may - // return ranges with some _gap_. I don't know whether - // it is true, but I'm preparing my code for the case. - - const S32 ranges = text_range_array->fNumOfRanges; - preedit_segment_lengths.reserve(ranges); - preedit_standouts.reserve(ranges); - - S32 last_bytes = 0; - S32 last_utf32 = 0; - for (S32 i = 0; i < ranges; i++) - { - const TextRange &range = text_range_array->fRange[i]; - if (range.fStart > last_bytes) - { - const S32 length_utf16 = (range.fStart - last_bytes) / sizeof(U16); - const S32 length_utf32 = wstring_wstring_length_from_utf16_length(preedit_string, last_utf32, length_utf16); - preedit_segment_lengths.push_back(length_utf32); - preedit_standouts.push_back(FALSE); - last_utf32 += length_utf32; - } - if (range.fEnd > range.fStart) - { - const S32 length_utf16 = (range.fEnd - range.fStart) / sizeof(U16); - const S32 length_utf32 = wstring_wstring_length_from_utf16_length(preedit_string, last_utf32, length_utf16); - preedit_segment_lengths.push_back(length_utf32); - preedit_standouts.push_back( - kTSMHiliteSelectedRawText == range.fHiliteStyle - || kTSMHiliteSelectedConvertedText == range.fHiliteStyle - || kTSMHiliteSelectedText == range.fHiliteStyle); - last_utf32 += length_utf32; - } - if (kTSMHiliteCaretPosition == range.fHiliteStyle) - { - caret_position = last_utf32; - } - last_bytes = range.fEnd; - } - if (preedit_string.length() > last_utf32) - { - preedit_segment_lengths.push_back(preedit_string.length() - last_utf32); - preedit_standouts.push_back(FALSE); - } - - delete[] (char *) text_range_array; - } - - // Handle preedit string. - if (preedit_string.length() == 0) - { - preedit_segment_lengths.clear(); - preedit_standouts.clear(); - } - else if (preedit_segment_lengths.size() == 0) - { - preedit_segment_lengths.push_back(preedit_string.length()); - preedit_standouts.push_back(FALSE); - } - mPreeditor->updatePreedit(preedit_string, preedit_segment_lengths, preedit_standouts, caret_position); - - result = noErr; - } - } - break; - - case kEventTextInputUnicodeForKeyEvent: - { - UInt32 modifiers = 0; - - - // First, process the raw event. - { - EventRef rawEvent = NULL; - - // Get the original event and extract the modifier keys, so we can ignore command-key events. - if (GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent) == noErr) - { - // Grab the modifiers for later use in this function... - GetEventParameter (rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); - - // and call this function recursively to handle the raw key event. - eventHandler (myHandler, rawEvent); - - // save the raw event until we're done processing the unicode input as well. - mRawKeyEvent = rawEvent; - } - } - - OSStatus err = noErr; - EventParamType actualType = typeUnicodeText; - UInt32 actualSize = 0; - size_t actualCount = 0; - U16 *buffer = NULL; - - // Get the size of the unicode data - err = GetEventParameter (event, kEventParamTextInputSendText, typeUnicodeText, &actualType, 0, &actualSize, NULL); - if(err == noErr) - { - // allocate a buffer and get the actual data. - actualCount = actualSize / sizeof(U16); - buffer = new U16[actualCount]; - err = GetEventParameter (event, kEventParamTextInputSendText, typeUnicodeText, &actualType, actualSize, &actualSize, buffer); - } - - if(err == noErr) - { - if(modifiers & (cmdKey | controlKey)) - { - // This was a menu key equivalent. Ignore it. - } - else - { - MASK mask = LLWindowMacOSX::modifiersToMask(modifiers); - - llassert( actualType == typeUnicodeText ); - - // The result is a UTF16 buffer. Pass the characters in turn to handleUnicodeChar. - - // Convert to UTF32 and go character-by-character. - llutf16string utf16(buffer, actualCount); - LLWString utf32 = utf16str_to_wstring(utf16); - LLWString::iterator iter; - - for(iter = utf32.begin(); iter != utf32.end(); iter++) - { - mCallbacks->handleUnicodeChar(*iter, mask); - } - } - } - - if(buffer != NULL) - { - delete[] buffer; - } - - mRawKeyEvent = NULL; - result = err; - } - break; - - case kEventTextInputOffsetToPos: - { - EventParamType param_type; - long offset; - if (mPreeditor - && GetEventParameter(event, kEventParamTextInputSendTextOffset, typeLongInteger, - ¶m_type, sizeof(offset), NULL, &offset) == noErr - && typeLongInteger == param_type) - { - S32 preedit, preedit_length; - mPreeditor->getPreeditRange(&preedit, &preedit_length); - const LLWString & text = mPreeditor->getPreeditString(); - - LLCoordGL caret_coord; - LLRect preedit_bounds; - if (0 <= offset - && mPreeditor->getPreeditLocation(wstring_wstring_length_from_utf16_length(text, preedit, offset / sizeof(U16)), - &caret_coord, &preedit_bounds, NULL)) - { - LLCoordGL caret_base_coord(caret_coord.mX, preedit_bounds.mBottom); - LLCoordScreen caret_base_coord_screen; - convertCoords(caret_base_coord, &caret_base_coord_screen); - Point qd_point; - qd_point.h = caret_base_coord_screen.mX; - qd_point.v = caret_base_coord_screen.mY; - SetEventParameter(event, kEventParamTextInputReplyPoint, typeQDPoint, sizeof(qd_point), &qd_point); - - short line_height = (short) preedit_bounds.getHeight(); - SetEventParameter(event, kEventParamTextInputReplyLineHeight, typeShortInteger, sizeof(line_height), &line_height); - - result = noErr; - } - else - { - result = errOffsetInvalid; - } - } - } - break; - - case kEventTextInputGetSelectedText: - { - if (mPreeditor) - { - S32 selection, selection_length; - mPreeditor->getSelectionRange(&selection, &selection_length); - if (selection_length) - { - const LLWString text = mPreeditor->getPreeditString().substr(selection, selection_length); - const llutf16string text_utf16 = wstring_to_utf16str(text); - result = SetEventParameter(event, kEventParamTextInputReplyText, typeUnicodeText, - text_utf16.length() * sizeof(U16), text_utf16.c_str()); - } - } - } - break; - } - } - break; - - case kEventClassKeyboard: - { - UInt32 keyCode = 0; - char charCode = 0; - UInt32 modifiers = 0; - - // Some of these may fail for some event types. That's fine. - GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode); - GetEventParameter (event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); - - // save the raw event so getNativeKeyData can use it. - mRawKeyEvent = event; - - // printf("key event, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", keyCode, charCode, (char)charCode, modifiers); - // fflush(stdout); - - switch (evtKind) - { - case kEventRawKeyDown: - case kEventRawKeyRepeat: - if (gDebugWindowProc) - { - printf("key down, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", - (unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers); - fflush(stdout); - } - gKeyboard->handleKeyDown(keyCode, modifiers); - result = eventNotHandledErr; - break; - - case kEventRawKeyUp: - if (gDebugWindowProc) - { - printf("key up, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", - (unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers); - fflush(stdout); - } - gKeyboard->handleKeyUp(keyCode, modifiers); - result = eventNotHandledErr; - break; - - case kEventRawKeyModifiersChanged: - // The keyboard input system wants key up/down events for modifier keys. - // Mac OS doesn't supply these directly, but can supply events when the collective modifier state changes. - // Use these events to generate up/down events for the modifiers. - - if((modifiers & shiftKey) && !(mLastModifiers & shiftKey)) - { - if (gDebugWindowProc) printf("Shift key down event\n"); - gKeyboard->handleKeyDown(0x38, (modifiers & 0x00FFFFFF) | ((0x38 << 24) & 0xFF000000)); - } - else if(!(modifiers & shiftKey) && (mLastModifiers & shiftKey)) - { - if (gDebugWindowProc) printf("Shift key up event\n"); - gKeyboard->handleKeyUp(0x38, (modifiers & 0x00FFFFFF) | ((0x38 << 24) & 0xFF000000)); - } - - if((modifiers & alphaLock) && !(mLastModifiers & alphaLock)) - { - if (gDebugWindowProc) printf("Caps lock down event\n"); - gKeyboard->handleKeyDown(0x39, (modifiers & 0x00FFFFFF) | ((0x39 << 24) & 0xFF000000)); - } - else if(!(modifiers & alphaLock) && (mLastModifiers & alphaLock)) - { - if (gDebugWindowProc) printf("Caps lock up event\n"); - gKeyboard->handleKeyUp(0x39, (modifiers & 0x00FFFFFF) | ((0x39 << 24) & 0xFF000000)); - } - - if((modifiers & controlKey) && !(mLastModifiers & controlKey)) - { - if (gDebugWindowProc) printf("Control key down event\n"); - gKeyboard->handleKeyDown(0x3b, (modifiers & 0x00FFFFFF) | ((0x3b << 24) & 0xFF000000)); - } - else if(!(modifiers & controlKey) && (mLastModifiers & controlKey)) - { - if (gDebugWindowProc) printf("Control key up event\n"); - gKeyboard->handleKeyUp(0x3b, (modifiers & 0x00FFFFFF) | ((0x3b << 24) & 0xFF000000)); - } - - if((modifiers & optionKey) && !(mLastModifiers & optionKey)) - { - if (gDebugWindowProc) printf("Option key down event\n"); - gKeyboard->handleKeyDown(0x3a, (modifiers & 0x00FFFFFF) | ((0x3a << 24) & 0xFF000000)); - } - else if(!(modifiers & optionKey) && (mLastModifiers & optionKey)) - { - if (gDebugWindowProc) printf("Option key up event\n"); - gKeyboard->handleKeyUp(0x3a, (modifiers & 0x00FFFFFF) | ((0x3a << 24) & 0xFF000000)); - } - - // When the state of the 'Fn' key (the one that changes some of the mappings on a powerbook/macbook keyboard - // to an embedded keypad) changes, it may subsequently cause a key up event to be lost, which may lead to - // a movement key getting "stuck" down. This is bad. - // This is an OS bug -- even the GetKeys() API doesn't tell you the key has been released. - // This workaround causes all held-down keys to be reset whenever the state of the Fn key changes. This isn't - // exactly what we want, but it does avoid the case where you get stuck running forward. - if((modifiers & kEventKeyModifierFnMask) != (mLastModifiers & kEventKeyModifierFnMask)) - { - if (gDebugWindowProc) printf("Fn key state change event\n"); - gKeyboard->resetKeys(); - } - - if (gDebugWindowProc) fflush(stdout); - - mLastModifiers = modifiers; - result = eventNotHandledErr; - break; - } - - mRawKeyEvent = NULL; - } - break; - - case kEventClassMouse: - { - result = CallNextEventHandler(myHandler, event); - if (eventNotHandledErr == result) - { // only handle events not already handled (prevents wierd resize interaction) - EventMouseButton button = kEventMouseButtonPrimary; - HIPoint location = {0.0f, 0.0f}; - UInt32 modifiers = 0; - UInt32 clickCount = 1; - long wheelDelta = 0; - LLCoordScreen inCoords; - LLCoordGL outCoords; - MASK mask = 0; - - GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button); - GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(location), NULL, &location); - GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers); - GetEventParameter(event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(wheelDelta), NULL, &wheelDelta); - GetEventParameter(event, kEventParamClickCount, typeUInt32, NULL, sizeof(clickCount), NULL, &clickCount); - - inCoords.mX = llround(location.x); - inCoords.mY = llround(location.y); - - if(modifiers & shiftKey) { mask |= MASK_SHIFT; } - if(modifiers & controlKey) { mask |= MASK_CONTROL; } - if(modifiers & optionKey) { mask |= MASK_ALT; } - - if(mCursorDecoupled) - { - CGMouseDelta x, y; - - // If the cursor's decoupled, we need to read the latest movement delta as well. - CGGetLastMouseDelta( &x, &y ); - mCursorLastEventDeltaX = x; - mCursorLastEventDeltaY = y; - - if(mCursorIgnoreNextDelta) - { - mCursorLastEventDeltaX = 0; - mCursorLastEventDeltaY = 0; - mCursorIgnoreNextDelta = FALSE; - } - } - else - { - mCursorLastEventDeltaX = 0; - mCursorLastEventDeltaY = 0; - } - - inCoords.mX += mCursorLastEventDeltaX; - inCoords.mY += mCursorLastEventDeltaY; - - convertCoords(inCoords, &outCoords); - - // printf("coords in: %d, %d; coords out: %d, %d\n", inCoords.mX, inCoords.mY, outCoords.mX, outCoords.mY); - // fflush(stdout); - - - switch (evtKind) - { - case kEventMouseDown: - if (mLanguageTextInputAllowed) - { - // We need to interrupt before handling mouse events, - // so that the fixed string from IM are delivered to - // the currently focused UI component. - interruptLanguageTextInput(); - } - switch(button) - { - case kEventMouseButtonPrimary: - if(modifiers & cmdKey) - { - // Simulate a right click - mSimulatedRightClick = true; - mCallbacks->handleRightMouseDown(this, outCoords, mask); - } - else if(clickCount == 2) - { - // Windows double-click events replace the second mousedown event in a double-click. - mCallbacks->handleDoubleClick(this, outCoords, mask); - } - else - { - mCallbacks->handleMouseDown(this, outCoords, mask); - } - break; - case kEventMouseButtonSecondary: - mCallbacks->handleRightMouseDown(this, outCoords, mask); - break; - - case kEventMouseButtonTertiary: - mCallbacks->handleMiddleMouseDown(this, outCoords, mask); - break; - } - result = noErr; - break; - case kEventMouseUp: - - switch(button) - { - case kEventMouseButtonPrimary: - if(mSimulatedRightClick) - { - // End of simulated right click - mSimulatedRightClick = false; - mCallbacks->handleRightMouseUp(this, outCoords, mask); - } - else - { - mCallbacks->handleMouseUp(this, outCoords, mask); - } - break; - case kEventMouseButtonSecondary: - mCallbacks->handleRightMouseUp(this, outCoords, mask); - break; + { + CFIndex index, cnt; - case kEventMouseButtonTertiary: - mCallbacks->handleMiddleMouseUp(this, outCoords, mask); - break; - } - result = noErr; - break; + mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; + mNumSupportedResolutions = 0; - case kEventMouseWheelMoved: - { - static S32 z_delta = 0; + // Examine each mode + cnt = CFArrayGetCount( modes ); - z_delta += wheelDelta; + for ( index = 0; (index < cnt) && (mNumSupportedResolutions < MAX_NUM_RESOLUTIONS); index++ ) + { + // Pull the mode dictionary out of the CFArray + CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex( modes, index ); + long width = getDictLong(mode, kCGDisplayWidth); + long height = getDictLong(mode, kCGDisplayHeight); + long bits = getDictLong(mode, kCGDisplayBitsPerPixel); - if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta) + if(bits == BITS_PER_PIXEL && width >= 800 && height >= 600) + { + BOOL resolution_exists = FALSE; + for(S32 i = 0; i < mNumSupportedResolutions; i++) + { + if (mSupportedResolutions[i].mWidth == width && + mSupportedResolutions[i].mHeight == height) { - mCallbacks->handleScrollWheel(this, -z_delta / WHEEL_DELTA); - z_delta = 0; + resolution_exists = TRUE; } } - result = noErr; - break; - - case kEventMouseDragged: - case kEventMouseMoved: - mCallbacks->handleMouseMove(this, outCoords, mask); - result = noErr; - break; - + if (!resolution_exists) + { + mSupportedResolutions[mNumSupportedResolutions].mWidth = width; + mSupportedResolutions[mNumSupportedResolutions].mHeight = height; + mNumSupportedResolutions++; + } } } } - break; - - case kEventClassWindow: - switch(evtKind) - { - case kEventWindowActivated: - if (mTSMDocument) - { - ActivateTSMDocument(mTSMDocument); - } - mCallbacks->handleFocus(this); - break; - case kEventWindowDeactivated: - if (mTSMDocument) - { - DeactivateTSMDocument(mTSMDocument); - } - mCallbacks->handleFocusLost(this); - break; - - case kEventWindowBoundsChanging: - { - // This is where we would constrain move/resize to a particular screen - - const S32 MIN_WIDTH = mMinWindowWidth; - const S32 MIN_HEIGHT = mMinWindowHeight; - - Rect currentBounds; - Rect previousBounds; - - GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, ¤tBounds); - GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &previousBounds); - - // Put an offset into window un-maximize operation since the kEventWindowGetIdealSize - // event only allows the specification of size and not position. - if (mMaximized) - { - short leftOffset = mPreviousWindowRect.left - currentBounds.left; - currentBounds.left += leftOffset; - currentBounds.right += leftOffset; + } - short topOffset = mPreviousWindowRect.top - currentBounds.top; - currentBounds.top += topOffset; - currentBounds.bottom += topOffset; - } - else - { - // Store off the size for future un-maximize operations - mPreviousWindowRect = previousBounds; - } + num_resolutions = mNumSupportedResolutions; + return mSupportedResolutions; +} - if ((currentBounds.right - currentBounds.left) < MIN_WIDTH) - { - currentBounds.right = currentBounds.left + MIN_WIDTH; - } +BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordWindow *to) +{ + S32 client_height; + float client_rect[4]; + getContentViewBounds(mWindow, client_rect); + if (!mWindow || + NULL == to) + { + return FALSE; + } - if ((currentBounds.bottom - currentBounds.top) < MIN_HEIGHT) - { - currentBounds.bottom = currentBounds.top + MIN_HEIGHT; - } + to->mX = from.mX; + client_height = client_rect[3]; + to->mY = from.mY - 1; - SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), ¤tBounds); - result = noErr; - } - break; + return TRUE; +} - case kEventWindowBoundsChanged: - { - // Get new window bounds - Rect newBounds; - GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &newBounds); +BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordGL* to) +{ + S32 client_height; + float client_rect[4]; + + getContentViewBounds(mWindow, client_rect); + + if (!mWindow || + NULL == to) + { + return FALSE; + } - // Get previous window bounds - Rect oldBounds; - GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &oldBounds); + to->mX = from.mX; + client_height = client_rect[3]; + to->mY = from.mY - 1; - // Determine if the new size is larger than the old - bool newBoundsLarger = ((newBounds.right - newBounds.left) >= (oldBounds.right - oldBounds.left)); - newBoundsLarger &= ((newBounds.bottom - newBounds.top) >= (oldBounds.bottom - oldBounds.top)); + return TRUE; +} - // Check to see if this is a zoom event (+ button on window pane) - unsigned int eventParams; - GetEventParameter(event, kEventParamAttributes, typeUInt32, NULL, sizeof(int), NULL, &eventParams); - bool isZoomEvent = ((eventParams & kWindowBoundsChangeZoom) != 0); +BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to) +{ + if(mFullscreen) + { + // In the fullscreen case, window and screen coordinates are the same. + to->mX = from.mX; + to->mY = from.mY; + return TRUE; + } + else if(mWindow) + { + float mouse_point[2]; - // Maximized flag is if zoom event and increasing window size - mMaximized = (isZoomEvent && newBoundsLarger); + mouse_point[0] = from.mX; + mouse_point[1] = from.mY; + + convertScreenToWindow(mWindow, mouse_point); - aglUpdateContext(mContext); + to->mX = mouse_point[0]; + to->mY = mouse_point[1]; - mCallbacks->handleResize(this, newBounds.right - newBounds.left, newBounds.bottom - newBounds.top); - } - break; + return TRUE; + } - case kEventWindowGetIdealSize: - // Only recommend a new ideal size when un-maximizing - if (mMaximized == TRUE) - { - Point nonMaximizedSize; + return FALSE; +} - nonMaximizedSize.v = mPreviousWindowRect.bottom - mPreviousWindowRect.top; - nonMaximizedSize.h = mPreviousWindowRect.right - mPreviousWindowRect.left; +BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to) +{ + if(mFullscreen) + { + // In the fullscreen case, window and screen coordinates are the same. + to->mX = from.mX; + to->mY = from.mY; + return TRUE; + } + else if(mWindow) + { + float mouse_point[2]; - SetEventParameter(event, kEventParamDimensions, typeQDPoint, sizeof(Point), &nonMaximizedSize); - result = noErr; - } - break; + mouse_point[0] = from.mX; + mouse_point[1] = from.mY; + convertWindowToScreen(mWindow, mouse_point); - case kEventWindowClose: - if(mCallbacks->handleCloseRequest(this)) - { - // Get the app to initiate cleanup. - mCallbacks->handleQuit(this); - // The app is responsible for calling destroyWindow when done with GL - } - result = noErr; - break; + to->mX = mouse_point[0]; + to->mY = mouse_point[1]; - case kEventWindowHidden: - // llinfos << "LLWindowMacOSX: Deactivating on hide" << llendl; - mMinimized = TRUE; - mCallbacks->handleActivate(this, false); - // result = noErr; - break; + return TRUE; + } - case kEventWindowShown: - // llinfos << "LLWindowMacOSX: Activating on show" << llendl; - mMinimized = FALSE; - mCallbacks->handleActivate(this, true); - // result = noErr; - break; + return FALSE; +} - case kEventWindowCollapsed: - // llinfos << "LLWindowMacOSX: Deactivating on collapse" << llendl; - mMinimized = TRUE; - mCallbacks->handleActivate(this, false); - // result = noErr; - break; +BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordGL *to) +{ + LLCoordWindow window_coord; - case kEventWindowExpanded: - // llinfos << "LLWindowMacOSX: Activating on expand" << llendl; - mMinimized = FALSE; - mCallbacks->handleActivate(this, true); - // result = noErr; - break; + return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); +} - case kEventWindowGetClickActivation: - // BringToFront(mWindow); - // result = noErr; - break; - } - break; +BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to) +{ + LLCoordWindow window_coord; - case kEventClassTSMDocumentAccess: - if (mPreeditor) - { - switch(evtKind) - { + return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); +} - case kEventTSMDocumentAccessGetLength: - { - // Return the number of UTF-16 units in the text, excluding those for preedit. - - S32 preedit, preedit_length; - mPreeditor->getPreeditRange(&preedit, &preedit_length); - const LLWString & text = mPreeditor->getPreeditString(); - const CFIndex length = wstring_utf16_length(text, 0, preedit) - + wstring_utf16_length(text, preedit + preedit_length, text.length()); - result = SetEventParameter(event, kEventParamTSMDocAccessCharacterCount, typeCFIndex, sizeof(length), &length); - } - break; - case kEventTSMDocumentAccessGetSelectedRange: - { - // Return the selected range, excluding preedit. - // In our preeditor, preedit and selection are exclusive, so, - // when it has a preedit, there is no selection and the - // insertion point is on the preedit that corrupses into the - // beginning of the preedit when the preedit was removed. - - S32 preedit, preedit_length; - mPreeditor->getPreeditRange(&preedit, &preedit_length); - const LLWString & text = mPreeditor->getPreeditString(); - - CFRange range; - if (preedit_length) - { - range.location = wstring_utf16_length(text, 0, preedit); - range.length = 0; - } - else - { - S32 selection, selection_length; - mPreeditor->getSelectionRange(&selection, &selection_length); - range.location = wstring_utf16_length(text, 0, selection); - range.length = wstring_utf16_length(text, selection, selection_length); - } - result = SetEventParameter(event, kEventParamTSMDocAccessReplyCharacterRange, typeCFRange, sizeof(range), &range); - } - break; - case kEventTSMDocumentAccessGetCharacters: - { - UniChar *target_pointer; - CFRange range; - EventParamType param_type; - if ((result = GetEventParameter(event, kEventParamTSMDocAccessSendCharacterRange, - typeCFRange, ¶m_type, sizeof(range), NULL, &range)) == noErr - && typeCFRange == param_type - && (result = GetEventParameter(event, kEventParamTSMDocAccessSendCharactersPtr, - typePtr, ¶m_type, sizeof(target_pointer), NULL, &target_pointer)) == noErr - && typePtr == param_type) - { - S32 preedit, preedit_length; - mPreeditor->getPreeditRange(&preedit, &preedit_length); - const LLWString & text = mPreeditor->getPreeditString(); - - // The GetCharacters event of TSMDA has a fundamental flaw; - // An input method need to decide the starting offset and length - // *before* it actually see the contents, so it is impossible - // to guarantee the character-aligned access. The event reply - // has no way to indicate a condition something like "Request - // was not fulfilled due to unaligned access. Please retry." - // Any error sent back to the input method stops use of TSMDA - // entirely during the session... - // We need to simulate very strictly the behaviour as if the - // underlying *text engine* holds the contents in UTF-16. - // I guess this is the reason why Apple repeats saying "all - // text handling application should use UTF-16." They are - // trying to _fix_ the flaw by changing the appliations... - // ... or, domination of UTF-16 in the industry may be a part - // of the company vision, and Apple is trying to force third - // party developers to obey their vision. Remember that use - // of 16 bits per _a_character_ was one of the very fundamental - // Unicode design policy on its early days (during late 80s) - // and the original Unicode design was by two Apple employees... - - const llutf16string text_utf16 - = wstring_to_utf16str(text, preedit) - + wstring_to_utf16str(text.substr(preedit + preedit_length)); - - llassert_always(sizeof(U16) == sizeof(UniChar)); - llassert(0 <= range.location && 0 <= range.length && range.location + range.length <= text_utf16.length()); - memcpy(target_pointer, text_utf16.c_str() + range.location, range.length * sizeof(UniChar)); - - // Note that result has already been set above. - } - } - break; +void LLWindowMacOSX::setupFailure(const std::string& text, const std::string& caption, U32 type) +{ + destroyContext(); - } - } - break; - } - return result; + OSMessageBox(text, caption, type); } const char* cursorIDToName(int id) @@ -2876,7 +1397,7 @@ static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY) void LLWindowMacOSX::updateCursor() { - OSStatus result = noErr; + S32 result = 0; if (mDragOverrideCursor != -1) { @@ -2913,7 +1434,7 @@ void LLWindowMacOSX::updateCursor() if(mCursorHidden) { // Since InitCursor resets the hide level, correct for it here. - ::HideCursor(); + hideNSCursor(); } break; @@ -2921,12 +1442,12 @@ void LLWindowMacOSX::updateCursor() // Find out what they look like and replicate them. // These are essentially correct - case UI_CURSOR_WAIT: SetThemeCursor(kThemeWatchCursor); break; - case UI_CURSOR_IBEAM: SetThemeCursor(kThemeIBeamCursor); break; - case UI_CURSOR_CROSS: SetThemeCursor(kThemeCrossCursor); break; - case UI_CURSOR_HAND: SetThemeCursor(kThemePointingHandCursor); break; + case UI_CURSOR_WAIT: /* Apple purposely doesn't allow us to set the beachball cursor manually. */ break; + case UI_CURSOR_IBEAM: setIBeamCursor(); break; + case UI_CURSOR_CROSS: setCrossCursor(); break; + case UI_CURSOR_HAND: setPointingHandCursor(); break; // case UI_CURSOR_NO: SetThemeCursor(kThemeNotAllowedCursor); break; - case UI_CURSOR_ARROWCOPY: SetThemeCursor(kThemeCopyArrowCursor); break; + case UI_CURSOR_ARROWCOPY: setCopyCursor(); break; // Double-check these case UI_CURSOR_NO: @@ -3039,7 +1560,7 @@ void LLWindowMacOSX::hideCursor() // llinfos << "hideCursor: hiding" << llendl; mCursorHidden = TRUE; mHideCursorPermanent = TRUE; - ::HideCursor(); + hideNSCursor(); } else { @@ -3056,7 +1577,7 @@ void LLWindowMacOSX::showCursor() // llinfos << "showCursor: showing" << llendl; mCursorHidden = FALSE; mHideCursorPermanent = FALSE; - ::ShowCursor(); + showNSCursor(); } else { @@ -3102,7 +1623,7 @@ void LLSplashScreenMacOSX::showImpl() // This code _could_ be used to display a spash screen... #if 0 IBNibRef nib = NULL; - OSStatus err; + S32 err; err = CreateNibReference(CFSTR("SecondLife"), &nib); @@ -3127,25 +1648,6 @@ void LLSplashScreenMacOSX::updateImpl(const std::string& mesg) CFStringRef string = NULL; string = CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8); - - if(string != NULL) - { - ControlRef progressText = NULL; - ControlID id; - OSStatus err; - - id.signature = 'what'; - id.id = 0; - - err = GetControlByID(mWindow, &id, &progressText); - if(err == noErr) - { - err = SetControlData(progressText, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(CFStringRef), (Ptr)&string); - Draw1Control(progressText); - } - - CFRelease(string); - } } } @@ -3154,7 +1656,6 @@ void LLSplashScreenMacOSX::hideImpl() { if(mWindow != NULL) { - DisposeWindow(mWindow); mWindow = NULL; } } @@ -3163,102 +1664,16 @@ void LLSplashScreenMacOSX::hideImpl() S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type) { - S32 result = OSBTN_CANCEL; - SInt16 retval_mac = 1; - AlertStdCFStringAlertParamRec params; - CFStringRef errorString = NULL; - CFStringRef explanationString = NULL; - DialogRef alert = NULL; - AlertType alertType = kAlertCautionAlert; - OSStatus err; - - explanationString = CFStringCreateWithCString(NULL, text.c_str(), kCFStringEncodingUTF8); - errorString = CFStringCreateWithCString(NULL, caption.c_str(), kCFStringEncodingUTF8); - - params.version = kStdCFStringAlertVersionOne; - params.movable = false; - params.helpButton = false; - params.defaultText = (CFStringRef)kAlertDefaultOKText; - params.cancelText = 0; - params.otherText = 0; - params.defaultButton = 1; - params.cancelButton = 0; - params.position = kWindowDefaultPosition; - params.flags = 0; - - switch(type) - { - case OSMB_OK: - default: - break; - case OSMB_OKCANCEL: - params.cancelText = (CFStringRef)kAlertDefaultCancelText; - params.cancelButton = 2; - break; - case OSMB_YESNO: - alertType = kAlertNoteAlert; - params.defaultText = CFSTR("Yes"); - params.cancelText = CFSTR("No"); - params.cancelButton = 2; - break; - } - - if(gWindowImplementation != NULL) - gWindowImplementation->beforeDialog(); - - err = CreateStandardAlert( - alertType, - errorString, - explanationString, - ¶ms, - &alert); - - if(err == noErr) - { - err = RunStandardAlert( - alert, - NULL, - &retval_mac); - } - - if(gWindowImplementation != NULL) - gWindowImplementation->afterDialog(); - - switch(type) - { - case OSMB_OK: - case OSMB_OKCANCEL: - default: - if(retval_mac == 1) - result = OSBTN_OK; - else - result = OSBTN_CANCEL; - break; - case OSMB_YESNO: - if(retval_mac == 1) - result = OSBTN_YES; - else - result = OSBTN_NO; - break; - } - - if(errorString != NULL) - { - CFRelease(errorString); - } - - if(explanationString != NULL) - { - CFRelease(explanationString); - } - - return result; + // TODO: Implement a native NSAlert function that replicates all of this. + return 0; } // Open a URL with the user's default web browser. // Must begin with protocol identifier. void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async) { + // I'm fairly certain that this is all legitimate under Apple's currently supported APIs. + bool found = false; S32 i; for (i = 0; i < gURLProtocolWhitelistCount; i++) @@ -3276,7 +1691,7 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async) return; } - OSStatus result = noErr; + S32 result = 0; CFURLRef urlRef = NULL; llinfos << "Opening URL " << escaped_url << llendl; @@ -3313,7 +1728,7 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async) LLSD LLWindowMacOSX::getNativeKeyData() { LLSD result = LLSD::emptyMap(); - +#if 0 if(mRawKeyEvent) { char char_code = 0; @@ -3335,7 +1750,7 @@ LLSD LLWindowMacOSX::getNativeKeyData() // This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc) // cause llsd serialization to create XML that the llsd deserializer won't parse! std::string unicode; - OSStatus err = noErr; + S32 err = noErr; EventParamType actualType = typeUTF8Text; UInt32 actualSize = 0; char *buffer = NULL; @@ -3357,7 +1772,7 @@ LLSD LLWindowMacOSX::getNativeKeyData() #endif } - +#endif lldebugs << "native key data is: " << result << llendl; @@ -3367,34 +1782,9 @@ LLSD LLWindowMacOSX::getNativeKeyData() BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b) { + // Is this even used anywhere? Do we really need an OS color picker? BOOL retval = FALSE; - OSErr error = noErr; - NColorPickerInfo info; - - memset(&info, 0, sizeof(info)); - info.theColor.color.rgb.red = (UInt16)(*r * 65535.f); - info.theColor.color.rgb.green = (UInt16)(*g * 65535.f); - info.theColor.color.rgb.blue = (UInt16)(*b * 65535.f); - info.placeWhere = kCenterOnMainScreen; - - if(gWindowImplementation != NULL) - gWindowImplementation->beforeDialog(); - - error = NPickColor(&info); - - if(gWindowImplementation != NULL) - gWindowImplementation->afterDialog(); - - if (error == noErr) - { - retval = info.newColorChosen; - if (info.newColorChosen) - { - *r = ((float) info.theColor.color.rgb.red) / 65535.0; - *g = ((float) info.theColor.color.rgb.green) / 65535.0; - *b = ((float) info.theColor.color.rgb.blue) / 65535.0; - } - } + //S32 error = 0; return (retval); } @@ -3405,44 +1795,13 @@ void *LLWindowMacOSX::getPlatformWindow() return (void*)mWindow; } -void *LLWindowMacOSX::getMediaWindow() -{ - /* - Mozilla needs to be initialized with a WindowRef to function properly. - (There's no good reason for this, since it shouldn't be interacting with our window in any way, but that's another issue.) - If we're in windowed mode, we _could_ hand it our actual window pointer, but a subsequent switch to fullscreen will destroy that window, - which trips up Mozilla. - Instead of using our actual window, we create an invisible window which will persist for the lifetime of the application and pass that to Mozilla. - This satisfies its deep-seated need to latch onto a WindowRef and solves the issue with switching between fullscreen and windowed modes. - - Note that we will never destroy this window (by design!), but since only one will ever be created per run of the application, that's okay. - */ - - if(sMediaWindow == NULL) - { - Rect window_rect = {100, 100, 200, 200}; - - sMediaWindow = NewCWindow( - NULL, - &window_rect, - (ConstStr255Param) "\p", - false, // Create the window invisible. - zoomDocProc, // Window with a grow box and a zoom box - kLastWindowOfClass, // create it behind other windows - false, // no close box - 0); - } - - return (void*)sMediaWindow; -} - void LLWindowMacOSX::stopDockTileBounce() { - NMRemove(&mBounceRec); mBounceTimer.stop(); } // get a double value from a dictionary +/* static double getDictDouble (CFDictionaryRef refDict, CFStringRef key) { double double_value; @@ -3452,7 +1811,7 @@ static double getDictDouble (CFDictionaryRef refDict, CFStringRef key) if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &double_value)) // or if cant convert it return -1; // fail return double_value; // otherwise return the long value -} +}*/ // get a long value from a dictionary static long getDictLong (CFDictionaryRef refDict, CFStringRef key) @@ -3468,71 +1827,12 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key) void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) { - ScriptLanguageRecord script_language; - - if (preeditor != mPreeditor && !b) - { - // This condition may occur by a call to - // setEnabled(BOOL) against LLTextEditor or LLLineEditor - // when the control is not focused. - // We need to silently ignore the case so that - // the language input status of the focused control - // is not disturbed. - return; - } - - UseInputWindow(mTSMDocument, !b); - - // Take care of old and new preeditors. - if (preeditor != mPreeditor || !b) - { - // We need to interrupt before updating mPreeditor, - // so that the fix string from input method goes to - // the old preeditor. - if (mLanguageTextInputAllowed) - { - interruptLanguageTextInput(); - } - mPreeditor = (b ? preeditor : NULL); - } - - if (b == mLanguageTextInputAllowed) - { - return; - } - mLanguageTextInputAllowed = b; - - if (b) - { - if (mTSMScriptCode != smRoman) - { - script_language.fScript = mTSMScriptCode; - script_language.fLanguage = mTSMLangCode; - SetTextServiceLanguage(&script_language); - } - } - else - { - GetTextServiceLanguage(&script_language); - mTSMScriptCode = script_language.fScript; - mTSMLangCode = script_language.fLanguage; - if (mTSMScriptCode != smRoman) - { - script_language.fScript = smRoman; - script_language.fLanguage = langEnglish; - SetTextServiceLanguage(&script_language); - } - } + // TODO: IME support } void LLWindowMacOSX::interruptLanguageTextInput() { - if (mTSMDocument) - { - FixTSMDocument(mTSMDocument); - } - // Don't we need to call resetPreedit here? - // Well, if Apple's TSM document is correct, we don't. + // TODO: IME support } //static @@ -3543,21 +1843,21 @@ std::vector LLWindowMacOSX::getDynamicFallbackFontList() } // static -MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers) +MASK LLWindowMacOSX::modifiersToMask(S16 modifiers) { MASK mask = 0; - if(modifiers & shiftKey) { mask |= MASK_SHIFT; } - if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; } - if(modifiers & optionKey) { mask |= MASK_ALT; } + if(modifiers & MAC_SHIFT_KEY) { mask |= MASK_SHIFT; } + if(modifiers & (MAC_CMD_KEY | MAC_CTRL_KEY)) { mask |= MASK_CONTROL; } + if(modifiers & MAC_ALT_KEY) { mask |= MASK_ALT; } return mask; } #if LL_OS_DRAGDROP_ENABLED - -OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, +/* +S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef drag) { - OSErr result = noErr; + S16 result = 0; LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; lldebugs << "drag tracking handler, message = " << message << llendl; @@ -3711,5 +2011,5 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop return result; } - +*/ #endif // LL_OS_DRAGDROP_ENABLED -- cgit v1.2.3 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/llwindow/llwindowmacosx.cpp | 133 ++------------------------------------ 1 file changed, 4 insertions(+), 129 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 1fb8bea802..a616b2df2d 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -38,7 +38,6 @@ #include "lldir.h" #include "indra_constants.h" -#include #include extern BOOL gDebugWindowProc; @@ -342,7 +341,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits if (mWindow == NULL) { LL_INFOS("Window") << "Creating window..." << LL_ENDL; - mWindow = createNSWindow(x, y, width, height); + mWindow = getMainAppWindow(); LL_INFOS("Window") << "Registering key callbacks..." << LL_ENDL; registerKeyDownCallback(mWindow, callKeyDown); registerKeyUpCallback(mWindow, callKeyUp); @@ -361,9 +360,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits if(mContext == NULL) { LL_INFOS("Window") << "Creating GL view..." << LL_ENDL; + // Our OpenGL view is already defined within SecondLife.xib. + // Get the view instead. mGLView = createOpenGLView(mWindow); registerResizeEventCallback(mGLView, callResize); - mContext = getCGLContextObj(mWindow); + mContext = getCGLContextObj(mGLView); // Since we just created the context, it needs to be set up. glNeedsInit = TRUE; } @@ -577,132 +578,6 @@ void LLWindowMacOSX::gatherInput() stopDockTileBounce(); } - EventRecord evt; - while(WaitNextEvent(everyEvent, &evt, 0, NULL)) - { - // printf("WaitNextEvent returned true, event is %d.\n", evt.what); - switch(evt.what) - { - case mouseDown: - { - short part; - WindowRef window; - long selectResult; - part = FindWindow(evt.where, &window); - switch ( part ) - { - case inMenuBar: - selectResult = MenuSelect(evt.where); - - HiliteMenu(0); - break; - } - } - break; - - case kHighLevelEvent: - AEProcessAppleEvent (&evt); - break; - - case updateEvt: - // We shouldn't be getting these regularly (since our window will be buffered), but we need to handle them correctly... - BeginUpdate((WindowRef)evt.message); - EndUpdate((WindowRef)evt.message); - break; - - } - } - /* - U32 event = getLatestEvent(mWindow); - switch (event) { - case 0: - // Nothing's happened since our last handled event. - break; - - case 1: - { - gKeyboard->handleKeyDown(getKeyDown(mWindow), getModifiers(mWindow)); - mCallbacks->handleUnicodeChar(getLastCharacter(mWindow), gKeyboard->currentMask(FALSE)); // currentMask has the appropriately translated modifiers. - mLastModifiers = gKeyboard->currentMask(FALSE); - } - break; - - case 2: - gKeyboard->handleKeyUp(getKeyUp(mWindow), getModifiers(mWindow)); - mLastModifiers = gKeyboard->currentMask(FALSE); - break; - - case 3: - break; - - case 4: - { - LLCoordScreen inCoords; - LLCoordGL outCoords; - float* mouseCoords = getMouseDown(mWindow); - inCoords.mX = llround(mouseCoords[0]); - inCoords.mY = llround(mouseCoords[1]); - convertCoords(inCoords, &outCoords); - mCallbacks->handleMouseDown(this, outCoords, getModifiers(mWindow)); - mLastModifiers = gKeyboard->currentMask(FALSE); - } - break; - case 5: - { - LLCoordScreen inCoords; - LLCoordGL outCoords; - float* mouseCoords = getMouseUp(mWindow); - inCoords.mX = llround(mouseCoords[0]); - inCoords.mY = llround(mouseCoords[1]); - convertCoords(inCoords, &outCoords); - mCallbacks->handleMouseUp(this, outCoords, getModifiers(mWindow)); - mLastModifiers = gKeyboard->currentMask(FALSE); - } - break; - case 6: - { - LLCoordScreen inCoords; - LLCoordGL outCoords; - float* mouseCoords = getRightMouseDown(mWindow); - inCoords.mX = llround(mouseCoords[0]); - inCoords.mY = llround(mouseCoords[1]); - convertCoords(inCoords, &outCoords); - mCallbacks->handleRightMouseDown(this, outCoords, getModifiers(mWindow)); - mLastModifiers = gKeyboard->currentMask(FALSE); - } - break; - case 7: - { - LLCoordScreen inCoords; - LLCoordGL outCoords; - float* mouseCoords = getRightMouseDown(mWindow); - inCoords.mX = llround(mouseCoords[0]); - inCoords.mY = llround(mouseCoords[1]); - convertCoords(inCoords, &outCoords); - mCallbacks->handleRightMouseDown(this, outCoords, getModifiers(mWindow)); - mLastModifiers = gKeyboard->currentMask(FALSE); - } - break; - case 8: // Double click - { - LLCoordScreen inCoords; - LLCoordGL outCoords; - float* mouseCoords = getRightMouseDown(mWindow); - inCoords.mX = llround(mouseCoords[0]); - inCoords.mY = llround(mouseCoords[1]); - convertCoords(inCoords, &outCoords); - mCallbacks->handleDoubleClick(this, outCoords, getModifiers(mWindow)); - mLastModifiers = gKeyboard->currentMask(FALSE); - } - break; - case 10: // Text input (for IMEs) - - break; - default: - break; - - }*/ - updateCursor(); } -- cgit v1.2.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/llwindowmacosx.cpp | 73 ++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 17 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') 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; + } } -- cgit v1.2.3 From 2b0f50dd821848d18ab35095623c3bdbcdeb910c Mon Sep 17 00:00:00 2001 From: Geenz Date: Wed, 2 Jan 2013 15:57:21 -0500 Subject: Crash on exit fix + general code cleanup in LLWindowMacOSX. --- indra/llwindow/llwindowmacosx.cpp | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index cfdfbe2138..cc0959edf8 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -283,6 +283,7 @@ void callMouseMoved(float *pos, MASK mask) outCoords.mX += deltas[0]; outCoords.mY += deltas[1]; gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); + } void callScrollMoved(float delta) @@ -339,9 +340,7 @@ void LLWindowMacOSX::updateMouseDeltas(float* deltas) if (mCursorDecoupled) { mCursorLastEventDeltaX = llround(deltas[0]); - mCursorLastEventDeltaY = llround(-deltas[1]); - - + mCursorLastEventDeltaY = llround(deltas[1]); if (mCursorIgnoreNextDelta) { @@ -372,21 +371,6 @@ 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); - registerUnicodeCallback(mWindow, callUnicodeCallback); - registerMouseDownCallback(mWindow, callLeftMouseDown); - registerMouseUpCallback(mWindow, callLeftMouseUp); - registerRightMouseDownCallback(mWindow, callRightMouseDown); - registerRightMouseUpCallback(mWindow, callRightMouseUp); - registerDoubleClickCallback(mWindow, callDoubleClick); - registerMouseMovedCallback(mWindow, callMouseMoved); - registerScrollCallback(mWindow, callScrollMoved); - registerDeltaUpdateCallback(mWindow, callDeltaUpdate); - registerMouseExitCallback(mWindow, callMouseExit); - */ } if(mContext == NULL) @@ -395,7 +379,6 @@ 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); mContext = getCGLContextObj(mGLView); // Since we just created the context, it needs to be set up. glNeedsInit = TRUE; -- cgit v1.2.3 From 9ce3ab1a5248423eeea4d843bfb8407ed62b305e Mon Sep 17 00:00:00 2001 From: Geenz Date: Wed, 2 Jan 2013 18:53:44 -0500 Subject: Fixed the enter and return keys not being sent appropriately as unicode characters. --- indra/llwindow/llwindowmacosx.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index cc0959edf8..902391e170 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -270,7 +270,10 @@ void callDoubleClick(float *pos, MASK mask) void callResize(unsigned int width, unsigned int height) { - gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height); + if (gWindowImplementation != NULL) + { + gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height); + } } void callMouseMoved(float *pos, MASK mask) -- cgit v1.2.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/llwindowmacosx.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') 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; } -- cgit v1.2.3 From 1bbbaf8dd69a08a3e7c570e6ad14f57a4f6e91cb Mon Sep 17 00:00:00 2001 From: Geenz Date: Fri, 18 Jan 2013 13:16:12 -0500 Subject: Partial workaround for mouse delta issue. --- indra/llwindow/llwindowmacosx.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 93b9f4c484..95ad87d58f 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -285,8 +285,9 @@ void callMouseMoved(float *pos, MASK mask) gWindowImplementation->getMouseDeltas(deltas); outCoords.mX += deltas[0]; outCoords.mY += deltas[1]; + LL_INFOS("Mouse Movement") << "Moved coords: " << outCoords.mX << ", " << outCoords.mY << LL_ENDL; gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); - + gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0); } void callScrollMoved(float delta) @@ -343,7 +344,7 @@ void LLWindowMacOSX::updateMouseDeltas(float* deltas) if (mCursorDecoupled) { mCursorLastEventDeltaX = llround(deltas[0]); - mCursorLastEventDeltaY = llround(deltas[1]); + mCursorLastEventDeltaY = llround(-deltas[1]); if (mCursorIgnoreNextDelta) { @@ -351,7 +352,6 @@ void LLWindowMacOSX::updateMouseDeltas(float* deltas) mCursorLastEventDeltaY = 0; mCursorIgnoreNextDelta = FALSE; } - LL_INFOS("Delta Update") << "Last event delta: " << mCursorLastEventDeltaX << ", " << mCursorLastEventDeltaY << LL_ENDL; } else { mCursorLastEventDeltaX = 0; mCursorLastEventDeltaY = 0; @@ -738,7 +738,7 @@ void LLWindowMacOSX::swapBuffers() F32 LLWindowMacOSX::getGamma() { - F32 result = 1.8; // Default to something sane + F32 result = 2.2; // Default to something sane CGGammaValue redMin; CGGammaValue redMax; -- cgit v1.2.3 From 461ab912a58b67579fffdf70ec7e38d682927185 Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 22 Jan 2013 19:59:49 -0500 Subject: Initial Cocoa drag and drop support. --- indra/llwindow/llwindowmacosx.cpp | 186 +++++++++++++++----------------------- 1 file changed, 73 insertions(+), 113 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 95ad87d58f..f25fc82896 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -248,7 +248,6 @@ void callLeftMouseDown(float *pos, MASK mask) outCoords.mX = llround(pos[0]); outCoords.mY = llround(pos[1]); gWindowImplementation->getCallbacks()->handleMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); - LL_INFOS("Window") << outCoords.mX << ", " << outCoords.mY << LL_ENDL; } void callLeftMouseUp(float *pos, MASK mask) @@ -285,7 +284,6 @@ void callMouseMoved(float *pos, MASK mask) gWindowImplementation->getMouseDeltas(deltas); outCoords.mX += deltas[0]; outCoords.mY += deltas[1]; - LL_INFOS("Mouse Movement") << "Moved coords: " << outCoords.mX << ", " << outCoords.mY << LL_ENDL; gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0); } @@ -339,6 +337,26 @@ void callMiddleMouseUp(float *pos, MASK mask) gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask); } +void callHandleDragEntered(std::string url) +{ + gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING); +} + +void callHandleDragExited(std::string url) +{ + gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING); +} + +void callHandleDragUpdated(std::string url) +{ + gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK); +} + +void callHandleDragDropped(std::string url) +{ + gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED); +} + void LLWindowMacOSX::updateMouseDeltas(float* deltas) { if (mCursorDecoupled) @@ -1784,7 +1802,6 @@ S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef t return result; } - OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef drag) { @@ -1792,126 +1809,69 @@ OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefC return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED); } - -OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDropAction action) +*/ +void LLWindowMacOSX::handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action) { - OSErr result = dragNotAcceptedErr; // overall function result - OSErr err = noErr; // for local error handling - - // Get the mouse position and modifiers of this drag. - SInt16 modifiers, mouseDownModifiers, mouseUpModifiers; - ::GetDragModifiers(drag, &modifiers, &mouseDownModifiers, &mouseUpModifiers); - MASK mask = LLWindowMacOSX::modifiersToMask(modifiers); + MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers()); - Point mouse_point; + float mouse_point[2]; // This will return the mouse point in global screen coords - ::GetDragMouse(drag, &mouse_point, NULL); - LLCoordScreen screen_coords(mouse_point.h, mouse_point.v); + getCursorPos(mWindow, mouse_point); + LLCoordScreen screen_coords(mouse_point[0], mouse_point[1]); LLCoordGL gl_pos; convertCoords(screen_coords, &gl_pos); - - // Look at the pasteboard and try to extract an URL from it - PasteboardRef pasteboard; - if(GetDragPasteboard(drag, &pasteboard) == noErr) + + if(!url.empty()) { - ItemCount num_items = 0; - // Treat an error here as an item count of 0 - (void)PasteboardGetItemCount(pasteboard, &num_items); - - // Only deal with single-item drags. - if(num_items == 1) - { - PasteboardItemID item_id = NULL; - CFArrayRef flavors = NULL; - CFDataRef data = NULL; - - err = PasteboardGetItemIdentifier(pasteboard, 1, &item_id); // Yes, this really is 1-based. - - // Try to extract an URL from the pasteboard - if(err == noErr) - { - err = PasteboardCopyItemFlavors( pasteboard, item_id, &flavors); - } - - if(err == noErr) - { - if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeURL)) - { - // This is an URL. - err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeURL, &data); - } - else if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeUTF8PlainText)) + LLWindowCallbacks::DragNDropResult res = + mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url); + + switch (res) { + case LLWindowCallbacks::DND_NONE: // No drop allowed + if (action == LLWindowCallbacks::DNDA_TRACK) { - // This is a string that might be an URL. - err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeUTF8PlainText, &data); + mDragOverrideCursor = 0; } - - } - - if(flavors != NULL) - { - CFRelease(flavors); - } - - if(data != NULL) - { - std::string url; - url.assign((char*)CFDataGetBytePtr(data), CFDataGetLength(data)); - CFRelease(data); - - if(!url.empty()) - { - LLWindowCallbacks::DragNDropResult res = - mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url); - - switch (res) { - case LLWindowCallbacks::DND_NONE: // No drop allowed - if (action == LLWindowCallbacks::DNDA_TRACK) - { - mDragOverrideCursor = kThemeNotAllowedCursor; - } - else { - mDragOverrideCursor = -1; - } - break; - case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation - mDragOverrideCursor = kThemePointingHandCursor; - result = noErr; - break; - case LLWindowCallbacks::DND_COPY: // Drop accepted would result in a "copy" operation - mDragOverrideCursor = kThemeCopyArrowCursor; - result = noErr; - break; - case LLWindowCallbacks::DND_LINK: // Drop accepted would result in a "link" operation: - mDragOverrideCursor = kThemeAliasArrowCursor; - result = noErr; - break; - default: - mDragOverrideCursor = -1; - break; - } - // This overrides the cursor being set by setCursor. - // This is a bit of a hack workaround because lots of areas - // within the viewer just blindly set the cursor. - if (mDragOverrideCursor == -1) - { - // Restore the cursor - ECursorType temp_cursor = mCurrentCursor; - // get around the "setting the same cursor" code in setCursor() - mCurrentCursor = UI_CURSOR_COUNT; - setCursor(temp_cursor); - } - else { - // Override the cursor - SetThemeCursor(mDragOverrideCursor); - } - + else { + mDragOverrideCursor = -1; } - } + break; + case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation + mDragOverrideCursor = UI_CURSOR_NO; + break; + case LLWindowCallbacks::DND_COPY: // Drop accepted would result in a "copy" operation + mDragOverrideCursor = UI_CURSOR_ARROWCOPY; + break; + default: + mDragOverrideCursor = -1; + break; + } + // This overrides the cursor being set by setCursor. + // This is a bit of a hack workaround because lots of areas + // within the viewer just blindly set the cursor. + if (mDragOverrideCursor == -1) + { + // Restore the cursor + ECursorType temp_cursor = mCurrentCursor; + // get around the "setting the same cursor" code in setCursor() + mCurrentCursor = UI_CURSOR_COUNT; + setCursor(temp_cursor); + } + else { + // Override the cursor + switch (mDragOverrideCursor) { + case 0: + setArrowCursor(); + break; + case UI_CURSOR_NO: + setNotAllowedCursor(); + case UI_CURSOR_ARROWCOPY: + setCopyCursor(); + default: + break; + }; } } - - return result; } -*/ + #endif // LL_OS_DRAGDROP_ENABLED -- cgit v1.2.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 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.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; -- cgit v1.2.3 From 4a935b68151f9d6951a1d1312a3437a8e8150f41 Mon Sep 17 00:00:00 2001 From: Geenz Date: Fri, 22 Feb 2013 16:41:49 -0500 Subject: Fix inconsistent handling of Control, Alt, and Shift keys through a new modifier update callback. --- indra/llwindow/llwindowmacosx.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 2e86759ec0..9ce19bd977 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -337,6 +337,11 @@ void callMiddleMouseUp(float *pos, MASK mask) gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask); } +void callModifier(MASK mask) +{ + gKeyboard->handleModifier(mask); +} + void callHandleDragEntered(std::string url) { gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING); -- cgit v1.2.3 From e19db5668853b7d3be2ed6af289a3c35bd213bca Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 25 Feb 2013 15:35:21 -0500 Subject: Fix for antialiasing and VSync not being enabled properly. --- indra/llwindow/llwindowmacosx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 9ce19bd977..ac0fa54a68 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -404,7 +404,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits LL_INFOS("Window") << "Creating GL view..." << LL_ENDL; // Our OpenGL view is already defined within SecondLife.xib. // Get the view instead. - mGLView = createOpenGLView(mWindow); + mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync); mContext = getCGLContextObj(mGLView); // Since we just created the context, it needs to be set up. glNeedsInit = TRUE; -- cgit v1.2.3 From 21aa4b9c2494aab408fffa6c21010b6ca0a9a626 Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 26 Feb 2013 16:18:42 -0500 Subject: Setup the quit handler for when the user attempts to close the window. This restores the previous functionality of asking the user if they want to quit. --- indra/llwindow/llwindowmacosx.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index ac0fa54a68..24f73c5631 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -362,6 +362,14 @@ void callHandleDragDropped(std::string url) gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED); } +void callQuitHandler() +{ + if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) + { + gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation); + } +} + void LLWindowMacOSX::updateMouseDeltas(float* deltas) { if (mCursorDecoupled) -- cgit v1.2.3 From f5516e0fc0e6c22b25f9dca2b9b24ebd7618332a Mon Sep 17 00:00:00 2001 From: "Graham Madarasz (Graham Linden)" Date: Wed, 27 Feb 2013 06:46:53 -0800 Subject: For MAINT-2404 Fixes detection of VRAM on OSX removed along with other AGL code. Code Review: callum --- indra/llwindow/llwindowmacosx.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index ac0fa54a68..abb3c1e50c 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -408,6 +408,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits mContext = getCGLContextObj(mGLView); // Since we just created the context, it needs to be set up. glNeedsInit = TRUE; + + gGLManager.mVRAM = getVramSize(mGLView); } // Hook up the context to a drawable -- cgit v1.2.3 From d046e606575b2c3714a88e321c88e05441cba4a8 Mon Sep 17 00:00:00 2001 From: "Graham Madarasz (Graham Linden)" Date: Wed, 27 Feb 2013 14:39:26 -0800 Subject: Fix max VRAM detection on some cards and issues with sequencing of application of mem multiplier --- indra/llwindow/llwindowmacosx.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index abb3c1e50c..2faebe5dd9 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -511,8 +511,9 @@ void LLWindowMacOSX::destroyContext() // Close the window if(mWindow != NULL) { - closeWindow(mWindow); - mWindow = NULL; + NSWindowRef dead_window = mWindow; + mWindow = NULL; + closeWindow(dead_window); } } -- cgit v1.2.3 From 5caa7a465e73fc9cf70f5f2c5d147a509bd5e185 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 11 Mar 2013 10:16:22 -0400 Subject: Bug fixing and prep-work for IME support (along with refactored text input in general). --- indra/llwindow/llwindowmacosx.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 24f73c5631..2f6c2101ef 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -211,6 +211,11 @@ void callKeyDown(unsigned short key, unsigned int mask) gKeyboard->handleKeyDown(key, mask); } +void callResetKeys() +{ + gKeyboard->resetKeys(); +} + void callUnicodeCallback(wchar_t character, unsigned int mask) { gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask); @@ -370,6 +375,26 @@ void callQuitHandler() } } +std::basic_string getPreeditString() +{ + return gWindowImplementation->getPreeditor()->getPreeditString(); +} + +void getPreeditSelectionRange(int *position, int *length) +{ + gWindowImplementation->getPreeditor()->getSelectionRange(position, length); +} + +void getPreeditMarkedRange(int *position, int *length) +{ + gWindowImplementation->getPreeditor()->getPreeditRange(position, length); +} + +void handleUnicodeCharacter(wchar_t c) +{ + gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c); +} + void LLWindowMacOSX::updateMouseDeltas(float* deltas) { if (mCursorDecoupled) -- cgit v1.2.3 From ad26f3c39002b6043e5fc4e00f9793e0f0e4941c Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 19 Mar 2013 05:50:50 -0400 Subject: IME support (and revamped text input support) semi-working. --- indra/llwindow/llwindowmacosx.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 34cc371526..08612bace4 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -223,7 +223,10 @@ void callUnicodeCallback(wchar_t character, unsigned int mask) void callFocus() { - gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); + if (gWindowImplementation) + { + gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); + } } void callFocusLost() @@ -369,9 +372,12 @@ void callHandleDragDropped(std::string url) void callQuitHandler() { - if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) + if (gWindowImplementation) { - gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation); + if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) + { + gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation); + } } } -- cgit v1.2.3 From 64c0455db568e6818c483785cff0fcd9cfa47aff Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 19 Mar 2013 23:02:47 -0400 Subject: More LLPreeditor work. --- indra/llwindow/llwindowmacosx.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 08612bace4..7e4b9a84a1 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -383,22 +383,37 @@ void callQuitHandler() std::basic_string getPreeditString() { - return gWindowImplementation->getPreeditor()->getPreeditString(); + std::basic_string str; + if (gWindowImplementation->getPreeditor()) + { + str = gWindowImplementation->getPreeditor()->getPreeditString(); + } + + return str; } void getPreeditSelectionRange(int *position, int *length) { - gWindowImplementation->getPreeditor()->getSelectionRange(position, length); + if (gWindowImplementation->getPreeditor()) + { + gWindowImplementation->getPreeditor()->getSelectionRange(position, length); + } } void getPreeditMarkedRange(int *position, int *length) { - gWindowImplementation->getPreeditor()->getPreeditRange(position, length); + if (gWindowImplementation->getPreeditor()) + { + gWindowImplementation->getPreeditor()->getPreeditRange(position, length); + } } void handleUnicodeCharacter(wchar_t c) { - gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c); + if (gWindowImplementation->getPreeditor()) + { + gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c); + } } void LLWindowMacOSX::updateMouseDeltas(float* deltas) @@ -498,6 +513,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits } } LL_INFOS("Window") << "Completed context creation." << LL_ENDL; + makeFirstResponder(mWindow, mGLView); // Don't need to get the current gamma, since there's a call that restores it to the system defaults. return TRUE; } -- cgit v1.2.3 From 258b77b64777a5ce5fef0ef066aa52b34b43ba65 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 25 Mar 2013 05:26:55 -0400 Subject: Additional IME support. LLPreeditor is largely good to go at this point, but there's still some work to do in getSegments. --- indra/llwindow/llwindowmacosx.cpp | 126 ++++++++++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 12 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 7e4b9a84a1..4e8934b149 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -381,30 +381,27 @@ void callQuitHandler() } } -std::basic_string getPreeditString() +void getPreeditSelectionRange(int *position, int *length) { - std::basic_string str; if (gWindowImplementation->getPreeditor()) { - str = gWindowImplementation->getPreeditor()->getPreeditString(); + gWindowImplementation->getPreeditor()->getSelectionRange(position, length); } - - return str; } -void getPreeditSelectionRange(int *position, int *length) +void getPreeditMarkedRange(int *position, int *length) { if (gWindowImplementation->getPreeditor()) { - gWindowImplementation->getPreeditor()->getSelectionRange(position, length); + gWindowImplementation->getPreeditor()->getPreeditRange(position, length); } } -void getPreeditMarkedRange(int *position, int *length) +void setPreeditMarkedRange(int position, int length) { if (gWindowImplementation->getPreeditor()) { - gWindowImplementation->getPreeditor()->getPreeditRange(position, length); + gWindowImplementation->getPreeditor()->markAsPreedit(position, length); } } @@ -416,6 +413,69 @@ void handleUnicodeCharacter(wchar_t c) } } +void resetPreedit() +{ + if (gWindowImplementation->getPreeditor()) + { + gWindowImplementation->getPreeditor()->resetPreedit(); + } +} + +// For reasons of convenience, handle IME updates here. +// This largely mirrors the old implementation, only sans the carbon parameters. +void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, segment_t segments) +{ + if (gWindowImplementation->getPreeditor()) + { + LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); + + // This should be a viable replacement for the kEventParamTextInputSendReplaceRange parameter. + if (replacementRange[0] < replacementRange[1]) + { + const LLWString& text = preeditor->getPreeditString(); + const S32 location = wstring_wstring_length_from_utf16_length(text, 0, replacementRange[0]); + const S32 length = wstring_wstring_length_from_utf16_length(text, location, replacementRange[1]); + preeditor->markAsPreedit(location, length); + } + + preeditor->resetPreedit(); + + LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len)); + + LLPreeditor::segment_lengths_t preedit_segment_lengths; + LLPreeditor::standouts_t preedit_standouts; + S32 caret_position = fix_str.length(); + + for (segment_t::iterator i = segments.begin(); i != segments.end(); i++) + { + preedit_segment_lengths.push_back(i->first); + preedit_standouts.push_back(i->second); + } + + preeditor->updatePreedit(fix_str, preedit_segment_lengths, preedit_standouts, caret_position); + } +} + +void getPreeditLocation(float *location, unsigned int length) +{ + if (gWindowImplementation->getPreeditor()) + { + LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); + LLCoordGL coord; + LLCoordScreen screen; + LLRect rect; + + preeditor->getPreeditLocation(length, &coord, &rect, NULL); + + float c[4] = {coord.mX, coord.mY, 0, 0}; + + convertRectToScreen(gWindowImplementation->getWindow(), c); + + location[0] = c[0]; + location[1] = c[1]; + } +} + void LLWindowMacOSX::updateMouseDeltas(float* deltas) { if (mCursorDecoupled) @@ -1295,8 +1355,22 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordGL *to) BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to) { LLCoordWindow window_coord; + if (mFullscreen) + { + to->mX = from.mX; + to->mY = from.mY; + return TRUE; + } else if (mWindow) + { + convertCoords(from, &window_coord); + convertCoords(window_coord, to); + + LL_INFOS("Coords") << to->mX << ", " << to->mY << LL_ENDL; + + return TRUE; + } - return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); + return FALSE; } @@ -1425,7 +1499,7 @@ void LLWindowMacOSX::updateCursor() // Find out what they look like and replicate them. // These are essentially correct - case UI_CURSOR_WAIT: /* Apple purposely doesn't allow us to set the beachball cursor manually. */ break; + case UI_CURSOR_WAIT: /* Apple purposely doesn't allow us to set the beachball cursor manually. Let NSApp figure out when to do this. */ break; case UI_CURSOR_IBEAM: setIBeamCursor(); break; case UI_CURSOR_CROSS: setCrossCursor(); break; case UI_CURSOR_HAND: setPointingHandCursor(); break; @@ -1810,7 +1884,35 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key) void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) { - // TODO: IME support + if (preeditor != mPreeditor && !b) + { + // This condition may occur by a call to + // setEnabled(BOOL) against LLTextEditor or LLLineEditor + // when the control is not focused. + // We need to silently ignore the case so that + // the language input status of the focused control + // is not disturbed. + return; + } + + // Take care of old and new preeditors. + if (preeditor != mPreeditor || !b) + { + // We need to interrupt before updating mPreeditor, + // so that the fix string from input method goes to + // the old preeditor. + if (mLanguageTextInputAllowed) + { + interruptLanguageTextInput(); + } + mPreeditor = (b ? preeditor : NULL); + } + + if (b == mLanguageTextInputAllowed) + { + return; + } + mLanguageTextInputAllowed = b; } void LLWindowMacOSX::interruptLanguageTextInput() -- cgit v1.2.3 From 80a79e5d7b4f37f862b312e848b1d1e7f85b0fa9 Mon Sep 17 00:00:00 2001 From: Geenz Date: Wed, 27 Mar 2013 08:49:45 -0400 Subject: IME support is pretty much finished at this point. --- indra/llwindow/llwindowmacosx.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 4e8934b149..6f66da66a4 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -39,6 +39,7 @@ #include "indra_constants.h" #include +#include extern BOOL gDebugWindowProc; @@ -423,7 +424,7 @@ void resetPreedit() // For reasons of convenience, handle IME updates here. // This largely mirrors the old implementation, only sans the carbon parameters. -void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, segment_t segments) +void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments) { if (gWindowImplementation->getPreeditor()) { @@ -442,17 +443,9 @@ void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigne LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len)); - LLPreeditor::segment_lengths_t preedit_segment_lengths; - LLPreeditor::standouts_t preedit_standouts; S32 caret_position = fix_str.length(); - for (segment_t::iterator i = segments.begin(); i != segments.end(); i++) - { - preedit_segment_lengths.push_back(i->first); - preedit_standouts.push_back(i->second); - } - - preeditor->updatePreedit(fix_str, preedit_segment_lengths, preedit_standouts, caret_position); + preeditor->updatePreedit(fix_str, segments.seg_lengths, segments.seg_standouts, caret_position); } } -- cgit v1.2.3 From 2656b1f405dcf3b67d644bf47b02a64886ef2ca4 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 1 Apr 2013 08:15:12 -0400 Subject: First pass at adding a viable replacement for TSM's old UseInputWindow method (which is now deprecated with seemingly no Cocoa replacement). --- indra/llwindow/llwindowmacosx.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 6f66da66a4..2d0f981b3e 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -191,6 +191,8 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, //start with arrow cursor initCursors(); setCursor( UI_CURSOR_ARROW ); + + allowLanguageTextInput(NULL, FALSE); } mCallbacks = callbacks; @@ -513,18 +515,22 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // Get the view instead. mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync); mContext = getCGLContextObj(mGLView); + // Since we just created the context, it needs to be set up. glNeedsInit = TRUE; gGLManager.mVRAM = getVramSize(mGLView); } - + + // This sets up our view to recieve text from our non-inline text input window. + setupInputWindow(mWindow, mGLView); + // Hook up the context to a drawable if(mContext != NULL) { - LL_INFOS("Window") << "Setting CGL Context..." << LL_ENDL; - LL_DEBUGS("Window") << "createContext: setting current context" << LL_ENDL; + + U32 err = CGLSetCurrentContext(mContext); if (err != kCGLNoError) { @@ -1888,6 +1894,8 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) return; } + showInputWindow(!b); + // Take care of old and new preeditors. if (preeditor != mPreeditor || !b) { -- cgit v1.2.3 From 5098d43a9be5b9638a8806918e9bb82a096c000f Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 1 Apr 2013 08:25:11 -0400 Subject: STORM-1941: Cocoa project viewer: some coordinate conversions are off (Katharine Berry) --- indra/llwindow/llwindowmacosx.cpp | 70 +++++---------------------------------- 1 file changed, 8 insertions(+), 62 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 2d0f981b3e..4f6ae5c799 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1255,52 +1255,21 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordWindow *to) { - S32 client_height; - float client_rect[4]; - getContentViewBounds(mWindow, client_rect); - if (!mWindow || - NULL == to) - { - return FALSE; - } - to->mX = from.mX; - client_height = client_rect[3]; - to->mY = from.mY - 1; - + to->mY = from.mY; return TRUE; } BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordGL* to) { - S32 client_height; - float client_rect[4]; - - getContentViewBounds(mWindow, client_rect); - - if (!mWindow || - NULL == to) - { - return FALSE; - } - to->mX = from.mX; - client_height = client_rect[3]; - to->mY = from.mY - 1; - + to->mY = from.mY; return TRUE; } BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to) { - if(mFullscreen) - { - // In the fullscreen case, window and screen coordinates are the same. - to->mX = from.mX; - to->mY = from.mY; - return TRUE; - } - else if(mWindow) + if(mWindow) { float mouse_point[2]; @@ -1314,20 +1283,12 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to) return TRUE; } - return FALSE; } BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to) { - if(mFullscreen) - { - // In the fullscreen case, window and screen coordinates are the same. - to->mX = from.mX; - to->mY = from.mY; - return TRUE; - } - else if(mWindow) + if(mWindow) { float mouse_point[2]; @@ -1340,7 +1301,6 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to) return TRUE; } - return FALSE; } @@ -1354,22 +1314,8 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordGL *to) BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to) { LLCoordWindow window_coord; - if (mFullscreen) - { - to->mX = from.mX; - to->mY = from.mY; - return TRUE; - } else if (mWindow) - { - convertCoords(from, &window_coord); - convertCoords(window_coord, to); - - LL_INFOS("Coords") << to->mX << ", " << to->mY << LL_ENDL; - - return TRUE; - } - return FALSE; + return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); } @@ -1981,11 +1927,11 @@ void LLWindowMacOSX::handleDragNDrop(std::string url, LLWindowCallbacks::DragNDr MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers()); float mouse_point[2]; - // This will return the mouse point in global screen coords + // This will return the mouse point in window coords getCursorPos(mWindow, mouse_point); - LLCoordScreen screen_coords(mouse_point[0], mouse_point[1]); + LLCoordWindow window_coords(mouse_point[0], mouse_point[1]); LLCoordGL gl_pos; - convertCoords(screen_coords, &gl_pos); + convertCoords(window_coords, &gl_pos); if(!url.empty()) { -- cgit v1.2.3 From aa0cb35db561004c205c7aac2570407ae88ad472 Mon Sep 17 00:00:00 2001 From: Geenz Date: Sun, 7 Apr 2013 11:33:39 -0400 Subject: Support the committing of the current pre edit string when language input is interrupted per the viewer's original pre edit functionality. --- indra/llwindow/llwindowmacosx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 4f6ae5c799..e1220c83f4 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1864,7 +1864,7 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) void LLWindowMacOSX::interruptLanguageTextInput() { - // TODO: IME support + commitCurrentPreedit(mGLView); } //static -- cgit v1.2.3 From cda10266ae91e28f2ac60b8472d6b8592f877d65 Mon Sep 17 00:00:00 2001 From: Geenz Date: Thu, 23 May 2013 08:50:05 -0400 Subject: Only show the input window when we attempt to add marked text, *and* we can't submit marked text directly to the viewer. --- indra/llwindow/llwindowmacosx.cpp | 42 ++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index e1220c83f4..16fd7e3382 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -204,14 +204,14 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, // 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) +bool callKeyUp(unsigned short key, unsigned int mask) { - gKeyboard->handleKeyUp(key, mask); + return gKeyboard->handleKeyUp(key, mask); } -void callKeyDown(unsigned short key, unsigned int mask) +bool callKeyDown(unsigned short key, unsigned int mask) { - gKeyboard->handleKeyDown(key, mask); + return gKeyboard->handleKeyDown(key, mask); } void callResetKeys() @@ -219,9 +219,9 @@ void callResetKeys() gKeyboard->resetKeys(); } -void callUnicodeCallback(wchar_t character, unsigned int mask) +bool callUnicodeCallback(wchar_t character, unsigned int mask) { - gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask); + return gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask); } void callFocus() @@ -408,12 +408,15 @@ void setPreeditMarkedRange(int position, int length) } } -void handleUnicodeCharacter(wchar_t c) +bool handleUnicodeCharacter(wchar_t c) { + bool success = false; if (gWindowImplementation->getPreeditor()) { - gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c); + success = gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c); } + + return success; } void resetPreedit() @@ -1033,21 +1036,7 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position) return result; } -/* -static void fixOrigin(void) -{ - GrafPtr port; - Rect portrect; - ::GetPort(&port); - ::GetPortBounds(port, &portrect); - if((portrect.left != 0) || (portrect.top != 0)) - { - // Mozilla sometimes changes our port origin. - ::SetOrigin(0,0); - } -} -*/ BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position) { float cursor_point[2]; @@ -1840,7 +1829,14 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) return; } - showInputWindow(!b); + if (preeditor == NULL) { + // If we don't have a pre editor, then we can't accept direct marked text input. + // We needs an input window (which is handled internally by LLOpenGLView) + allowDirectMarkedTextInput(false); + } else { + // If we have a preeditor, then accept direct marked text input. + allowDirectMarkedTextInput(true); + } // Take care of old and new preeditors. if (preeditor != mPreeditor || !b) -- cgit v1.2.3 From 2837ca7a474f92bb363a2a31d184431b636d2809 Mon Sep 17 00:00:00 2001 From: Geenz Date: Mon, 17 Jun 2013 17:08:48 -0400 Subject: This seems to be on par with viewer-release at this point. --- indra/llwindow/llwindowmacosx.cpp | 42 +++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 16fd7e3382..737ecba368 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -239,6 +239,11 @@ void callFocusLost() void callRightMouseDown(float *pos, MASK mask) { + if (gWindowImplementation->allowsLanguageInput()) + { + gWindowImplementation->interruptLanguageTextInput(); + } + LLCoordGL outCoords; outCoords.mX = llround(pos[0]); outCoords.mY = llround(pos[1]); @@ -247,6 +252,11 @@ void callRightMouseDown(float *pos, MASK mask) void callRightMouseUp(float *pos, MASK mask) { + if (gWindowImplementation->allowsLanguageInput()) + { + gWindowImplementation->interruptLanguageTextInput(); + } + LLCoordGL outCoords; outCoords.mX = llround(pos[0]); outCoords.mY = llround(pos[1]); @@ -255,6 +265,11 @@ void callRightMouseUp(float *pos, MASK mask) void callLeftMouseDown(float *pos, MASK mask) { + if (gWindowImplementation->allowsLanguageInput()) + { + gWindowImplementation->interruptLanguageTextInput(); + } + LLCoordGL outCoords; outCoords.mX = llround(pos[0]); outCoords.mY = llround(pos[1]); @@ -263,6 +278,11 @@ void callLeftMouseDown(float *pos, MASK mask) void callLeftMouseUp(float *pos, MASK mask) { + if (gWindowImplementation->allowsLanguageInput()) + { + gWindowImplementation->interruptLanguageTextInput(); + } + LLCoordGL outCoords; outCoords.mX = llround(pos[0]); outCoords.mY = llround(pos[1]); @@ -272,6 +292,11 @@ void callLeftMouseUp(float *pos, MASK mask) void callDoubleClick(float *pos, MASK mask) { + if (gWindowImplementation->allowsLanguageInput()) + { + gWindowImplementation->interruptLanguageTextInput(); + } + LLCoordGL outCoords; outCoords.mX = llround(pos[0]); outCoords.mY = llround(pos[1]); @@ -434,7 +459,7 @@ void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigne if (gWindowImplementation->getPreeditor()) { LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); - + preeditor->resetPreedit(); // This should be a viable replacement for the kEventParamTextInputSendReplaceRange parameter. if (replacementRange[0] < replacementRange[1]) { @@ -444,8 +469,6 @@ void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigne preeditor->markAsPreedit(location, length); } - preeditor->resetPreedit(); - LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len)); S32 caret_position = fix_str.length(); @@ -1818,6 +1841,8 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key) void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) { + allowDirectMarkedTextInput(b, mGLView); + if (preeditor != mPreeditor && !b) { // This condition may occur by a call to @@ -1828,16 +1853,7 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) // is not disturbed. return; } - - if (preeditor == NULL) { - // If we don't have a pre editor, then we can't accept direct marked text input. - // We needs an input window (which is handled internally by LLOpenGLView) - allowDirectMarkedTextInput(false); - } else { - // If we have a preeditor, then accept direct marked text input. - allowDirectMarkedTextInput(true); - } - + // Take care of old and new preeditors. if (preeditor != mPreeditor || !b) { -- cgit v1.2.3 From b2bec3f99c74d21bb1c2c68d73854f3990db26d5 Mon Sep 17 00:00:00 2001 From: Geenz Date: Thu, 11 Jul 2013 19:37:08 -0400 Subject: STORM-1942: dock icon bouncing unimplemented --- indra/llwindow/llwindowmacosx.cpp | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 737ecba368..e5556c23d4 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -149,10 +149,6 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mFSAASamples = fsaa_samples; mForceRebuild = FALSE; - // For reasons that aren't clear to me, LLTimers seem to be created in the "started" state. - // Since the started state of this one is used to track whether the NMRec has been installed, it wants to start out in the "stopped" state. - mBounceTimer.stop(); - // Get the original aspect ratio of the main device. mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay); @@ -763,12 +759,6 @@ BOOL LLWindowMacOSX::getFullscreen() void LLWindowMacOSX::gatherInput() { - // stop bouncing icon after fixed period of time - if (mBounceTimer.getStarted() && mBounceTimer.getElapsedTimeF32() > mBounceTime) - { - stopDockTileBounce(); - } - updateCursor(); } @@ -1161,22 +1151,9 @@ void LLWindowMacOSX::afterDialog() void LLWindowMacOSX::flashIcon(F32 seconds) { - // Don't do this if we're already started, since this would try to install the NMRec twice. - if(!mBounceTimer.getStarted()) - { - S32 err = 0; - // TODO: Implement icon bouncing - mBounceTime = seconds; - if(err == 0) - { - mBounceTimer.start(); - } - else - { - // This is very not-fatal (only problem is the icon will not bounce), but we'd like to find out about it somehow... - llinfos << "NMInstall failed with error code " << err << llendl; - } - } + // For consistency with OS X conventions, the number of seconds given is ignored and + // left up to the OS (which will actually bounce it for one second). + requestUserAttention(); } BOOL LLWindowMacOSX::isClipboardTextAvailable() @@ -1809,11 +1786,6 @@ void *LLWindowMacOSX::getPlatformWindow() return (void*)mWindow; } -void LLWindowMacOSX::stopDockTileBounce() -{ - mBounceTimer.stop(); -} - // get a double value from a dictionary /* static double getDictDouble (CFDictionaryRef refDict, CFStringRef key) -- cgit v1.2.3 From dc7d287717ed42d1d8aa8b57cfd740ca75fe9e7b Mon Sep 17 00:00:00 2001 From: Geenz Date: Thu, 11 Jul 2013 19:41:57 -0400 Subject: OPEN-170: "Set Window Size" always increases window size by specified size --- indra/llwindow/llwindowmacosx.cpp | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index e5556c23d4..d657c629b9 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -863,26 +863,11 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size) BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size) { - float client_rect[4]; if (mWindow) { - S32 err = noErr; - getContentViewBounds(mWindow, client_rect); - if (err == noErr) - { - client_rect[2] += size.mX; - client_rect[3] += size.mY; - setWindowSize(mWindow, client_rect[2], client_rect[3]); - } - if (err == noErr) - { - return TRUE; - } - else - { - llinfos << "Error setting size" << err << llendl; - return FALSE; - } + LLCoordScreen screen_size; + convertCoords(size, &screen_size); + return setSizeImpl(screen_size); } return FALSE; } -- cgit v1.2.3 From a787e272c31d8e535dae75e4d95365d17cec78db Mon Sep 17 00:00:00 2001 From: Geenz Date: Thu, 11 Jul 2013 21:31:17 -0400 Subject: Alert box support! --- indra/llwindow/llwindowmacosx.cpp | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index d657c629b9..beb9ebe8e0 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1597,24 +1597,6 @@ LLSplashScreenMacOSX::~LLSplashScreenMacOSX() void LLSplashScreenMacOSX::showImpl() { // This code _could_ be used to display a spash screen... -#if 0 - IBNibRef nib = NULL; - S32 err; - - err = CreateNibReference(CFSTR("SecondLife"), &nib); - - if(err == noErr) - { - CreateWindowFromNib(nib, CFSTR("Splash Screen"), &mWindow); - - DisposeNibReference(nib); - } - - if(mWindow != NULL) - { - ShowWindow(mWindow); - } -#endif } void LLSplashScreenMacOSX::updateImpl(const std::string& mesg) @@ -1636,12 +1618,9 @@ void LLSplashScreenMacOSX::hideImpl() } } - - S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type) { - // TODO: Implement a native NSAlert function that replicates all of this. - return 0; + return showAlert(text, caption, type); } // Open a URL with the user's default web browser. -- cgit v1.2.3 From 2f680eec93f1b06620c04af04116fe49d577cf8f Mon Sep 17 00:00:00 2001 From: Geenz Date: Thu, 11 Jul 2013 21:46:10 -0400 Subject: A bit of cleanup and make the return of showAlert match the OSBTN return types in llwindow.h. --- indra/llwindow/llwindowmacosx.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index beb9ebe8e0..a3e88ea7dc 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -164,7 +164,6 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, // Stash an object pointer for OSMessageBox() gWindowImplementation = this; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - LL_INFOS("Window") << "Creating context..." << LL_ENDL; if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) { if(mWindow != NULL) @@ -526,13 +525,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits if (mWindow == NULL) { - LL_INFOS("Window") << "Creating window..." << LL_ENDL; mWindow = getMainAppWindow(); } if(mContext == NULL) { - LL_INFOS("Window") << "Creating GL view..." << LL_ENDL; // Our OpenGL view is already defined within SecondLife.xib. // Get the view instead. mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync); @@ -565,12 +562,10 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits GLint frames_per_swap = 0; if (disable_vsync) { - LL_DEBUGS("GLInit") << "Disabling vertical sync" << LL_ENDL; frames_per_swap = 0; } else { - LL_DEBUGS("GLinit") << "Keeping vertical sync" << LL_ENDL; frames_per_swap = 1; } @@ -593,9 +588,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; } } - LL_INFOS("Window") << "Completed context creation." << LL_ENDL; makeFirstResponder(mWindow, mGLView); - // Don't need to get the current gamma, since there's a call that restores it to the system defaults. + return TRUE; } -- cgit v1.2.3 From 6ca0bbe3365b3d554789915ac143a87d2d39fdfa Mon Sep 17 00:00:00 2001 From: Geenz Date: Tue, 23 Jul 2013 10:39:32 -0400 Subject: Fix for BUG-3364 --- indra/llwindow/llwindowmacosx.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index a3e88ea7dc..56472e6b45 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -316,7 +316,7 @@ void callMouseMoved(float *pos, MASK mask) outCoords.mX += deltas[0]; outCoords.mY += deltas[1]; gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); - gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0); + //gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0); } void callScrollMoved(float delta) @@ -849,20 +849,24 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size) { if(mWindow) { - setWindowSize(mWindow, size.mX, size.mY); + LLCoordWindow to; + convertCoords(size, &to); + setWindowSize(mWindow, to.mX, to.mY); + return TRUE; } - return TRUE; + return FALSE; } BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size) { if (mWindow) { - LLCoordScreen screen_size; - convertCoords(size, &screen_size); - return setSizeImpl(screen_size); + const int titlePadding = 22; + setWindowSize(mWindow, size.mX, size.mY + titlePadding); + return TRUE; } + return FALSE; } -- cgit v1.2.3