summaryrefslogtreecommitdiff
path: root/indra/llwindow/llwindowmacosx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llwindow/llwindowmacosx.cpp')
-rw-r--r--indra/llwindow/llwindowmacosx.cpp655
1 files changed, 455 insertions, 200 deletions
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index a1d97429e1..affd7276cc 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -2,54 +2,45 @@
* @file llwindowmacosx.cpp
* @brief Platform-dependent implementation of llwindow
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2007, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#if LL_DARWIN
-
#include "linden_common.h"
-#include <Carbon/Carbon.h>
-#include <OpenGL/OpenGL.h>
-
#include "llwindowmacosx.h"
+
#include "llkeyboardmacosx.h"
+#include "llwindowcallbacks.h"
+#include "llwindowmacosx-objc.h"
+#include "llpreeditor.h"
+
#include "llerror.h"
#include "llgl.h"
#include "llstring.h"
#include "lldir.h"
-#include "llviewercontrol.h"
-
-#include "llglheaders.h"
-
#include "indra_constants.h"
-#include "llwindowmacosx-objc.h"
-#include "llpreeditor.h"
+#include <Carbon/Carbon.h>
+#include <OpenGL/OpenGL.h>
extern BOOL gDebugWindowProc;
@@ -66,37 +57,16 @@ const S32 MAX_NUM_RESOLUTIONS = 32;
// LLWindowMacOSX
//
-// Cross-platform bits:
+BOOL LLWindowMacOSX::sUseMultGL = FALSE;
+WindowRef LLWindowMacOSX::sMediaWindow = NULL;
-void show_window_creation_error(const char* title)
-{
- llwarns << title << llendl;
- /*
- OSMessageBox(
- "Second Life is unable to run because it can't set up your display.\n"
- "We need to be able to make a 32-bit color window at 1024x768, with\n"
- "an 8 bit alpha channel.\n"
- "\n"
- "First, be sure your monitor is set to True Color (32-bit) in\n"
- "Start -> Control Panels -> Display -> Settings.\n"
- "\n"
- "Otherwise, this may be due to video card driver issues.\n"
- "Please make sure you have the latest video card drivers installed.\n"
- "ATI drivers are available at http://www.ati.com/\n"
- "nVidia drivers are available at http://www.nvidia.com/\n"
- "\n"
- "If you continue to receive this message, contact customer service.",
- title,
- OSMB_OK);
- */
-}
+// Cross-platform bits:
BOOL check_for_card(const char* RENDERER, const char* bad_card)
{
if (!strnicmp(RENDERER, bad_card, strlen(bad_card)))
{
- char buffer[1024];/* Flawfinder: ignore */
- snprintf(buffer, sizeof(buffer),
+ std::string buffer = llformat(
"Your video card appears to be a %s, which Second Life does not support.\n"
"\n"
"Second Life requires a video card with 32 Mb of memory or more, as well as\n"
@@ -110,7 +80,7 @@ BOOL check_for_card(const char* RENDERER, const char* bad_card)
"You can try to run Second Life, but it will probably crash or run\n"
"very slowly. Try anyway?",
bad_card);
- S32 button = OSMessageBox(buffer, "Unsupported video card", OSMB_YESNO);
+ S32 button = OSMessageBox(buffer.c_str(), "Unsupported video card", OSMB_YESNO);
if (OSBTN_YES == button)
{
return FALSE;
@@ -124,8 +94,6 @@ BOOL check_for_card(const char* RENDERER, const char* bad_card)
return FALSE;
}
-
-
// Switch to determine whether we capture all displays, or just the main one.
// We may want to base this on the setting of _DEBUG...
@@ -242,18 +210,27 @@ static LLWindowMacOSX *gWindowImplementation = NULL;
-LLWindowMacOSX::LLWindowMacOSX(char *title, char *name, S32 x, S32 y, S32 width,
+LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
+ const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
S32 height, U32 flags,
BOOL fullscreen, BOOL clearBg,
BOOL disable_vsync, BOOL use_gl,
- BOOL ignore_pixel_depth)
- : LLWindow(fullscreen, flags)
-{
+ BOOL ignore_pixel_depth,
+ U32 fsaa_samples)
+ : LLWindow(NULL, fullscreen, flags)
+{
+ // *HACK: During window construction we get lots of OS events for window
+ // reshape, activate, etc. that the viewer isn't ready to handle.
+ // Route them to a dummy callback structure until the end of constructor.
+ LLWindowCallbacks null_callbacks;
+ mCallbacks = &null_callbacks;
+
// Voodoo for calling cocoa from carbon (see llwindowmacosx-objc.mm).
setupCocoa();
// Initialize the keyboard
gKeyboard = new LLKeyboardMacOSX();
+ gKeyboard->setCallbacks(callbacks);
// Ignore use_gl for now, only used for drones on PC
mWindow = NULL;
@@ -277,6 +254,9 @@ LLWindowMacOSX::LLWindowMacOSX(char *title, char *name, S32 x, S32 y, S32 width,
mTSMScriptCode = 0;
mTSMLangCode = 0;
mPreeditor = NULL;
+ mRawKeyEvent = NULL;
+ 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.
@@ -286,12 +266,15 @@ LLWindowMacOSX::LLWindowMacOSX(char *title, char *name, S32 x, S32 y, S32 width,
mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay);
// Stash the window title
- strcpy((char*)mWindowTitle + 1, title); /* Flawfinder: ignore */
- mWindowTitle[0] = strlen(title); /* Flawfinder: ignore */
+ strcpy((char*)mWindowTitle + 1, title.c_str()); /* Flawfinder: ignore */
+ mWindowTitle[0] = title.length();
mEventHandlerUPP = NewEventHandlerUPP(staticEventHandler);
+ mMoveEventCampartorUPP = NewEventComparatorUPP(staticMoveEventComparator);
mGlobalHandlerRef = NULL;
mWindowHandlerRef = NULL;
+
+ mDragOverrideCursor = -1;
// We're not clipping yet
SetRect( &mOldMouseClip, 0, 0, 0, 0 );
@@ -339,6 +322,7 @@ LLWindowMacOSX::LLWindowMacOSX(char *title, char *name, S32 x, S32 y, S32 width,
setCursor( UI_CURSOR_ARROW );
}
+ mCallbacks = callbacks;
stop_glerror();
}
@@ -356,7 +340,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
if (mFullscreen && (mOldDisplayMode == NULL))
{
- llinfos << "createContext: setting up fullscreen " << width << "x" << height << llendl;
+ 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);
@@ -377,18 +361,18 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
U32 closestWidth = 0;
int i;
- llinfos << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << llendl;
+ LL_DEBUGS("Window") << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL;
for(i=0; i < resolutionCount; i++)
{
F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight;
- llinfos << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << llendl;
+ LL_DEBUGS("Window") << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL;
if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) &&
(fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio)))
{
- llinfos << " (new closest mode) " << llendl;
+ LL_DEBUGS("Window") << " (new closest mode) " << LL_ENDL;
// This is the closest mode we've seen yet.
closestWidth = resolutionList[i].mWidth;
@@ -434,7 +418,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
if (refDisplayMode)
{
- llinfos << "createContext: switching display resolution" << llendl;
+ LL_DEBUGS("Window") << "createContext: switching display resolution" << LL_ENDL;
mOldDisplayMode = CGDisplayCurrentMode (mDisplay);
CGDisplaySwitchToMode (mDisplay, refDisplayMode);
// CFRelease(refDisplayMode);
@@ -449,11 +433,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
mFullscreenBits = CGDisplayBitsPerPixel(mDisplay);
mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate));
- llinfos << "Running at " << mFullscreenWidth
+ LL_INFOS("Window") << "Running at " << mFullscreenWidth
<< "x" << mFullscreenHeight
<< "x" << mFullscreenBits
<< " @ " << mFullscreenRefresh
- << llendl;
+ << LL_ENDL;
}
else
{
@@ -464,8 +448,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
mFullscreenBits = -1;
mFullscreenRefresh = -1;
- char error[256]; /* Flawfinder: ignore */
- snprintf(error, sizeof(error), "Unable to run fullscreen at %d x %d.\nRunning in window.", width, height);
+ std::string error= llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height);
OSMessageBox(error, "Error", OSMB_OK);
}
}
@@ -477,7 +460,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
//int displayHeight = CGDisplayPixelsHigh(mDisplay);
//const int menuBarPlusTitleBar = 44; // Ugly magic number.
- llinfos << "createContext: creating window" << llendl;
+ LL_DEBUGS("Window") << "createContext: creating window" << LL_ENDL;
window_rect.left = (long) x;
window_rect.right = (long) x + width;
@@ -513,8 +496,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
// 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
-
+ 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
}
{
@@ -531,12 +517,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
err = NewTSMDocument(1, types, &mTSMDocument, 0);
if (err != noErr)
{
- llwarns << "createContext: couldn't create a TSMDocument (" << err << ")" << llendl;
+ LL_WARNS("Window") << "createContext: couldn't create a TSMDocument (" << err << ")" << LL_ENDL;
}
if (mTSMDocument)
{
ActivateTSMDocument(mTSMDocument);
- UseInputWindow(mTSMDocument, FALSE);
allowLanguageTextInput(NULL, FALSE);
}
}
@@ -558,6 +543,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
AGL_RGBA,
AGL_FULLSCREEN,
// AGL_NO_RECOVERY, // MBW -- XXX -- Not sure if we want this attribute
+ AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0,
+ AGL_SAMPLES_ARB, mFSAASamples,
AGL_DOUBLEBUFFER,
AGL_CLOSEST_POLICY,
AGL_ACCELERATED,
@@ -570,7 +557,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
AGL_NONE
};
- llinfos << "createContext: creating fullscreen pixelformat" << llendl;
+ LL_DEBUGS("Window") << "createContext: creating fullscreen pixelformat" << LL_ENDL;
GDHandle gdhDisplay = NULL;
err = DMGetGDeviceByDisplayID ((DisplayIDType)mDisplay, &gdhDisplay, false);
@@ -586,6 +573,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
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,
@@ -595,7 +584,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
AGL_NONE
};
- llinfos << "createContext: creating windowed pixelformat" << llendl;
+ LL_DEBUGS("Window") << "createContext: creating windowed pixelformat" << LL_ENDL;
mPixelFormat = aglChoosePixelFormat(NULL, 0, windowedAttrib);
@@ -615,7 +604,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
if(mPixelFormat)
{
- llinfos << "createContext: creating GL context" << llendl;
+ LL_DEBUGS("Window") << "createContext: creating GL context" << LL_ENDL;
mContext = aglCreateContext(mPixelFormat, NULL);
}
@@ -663,7 +652,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
{
// We successfully captured the display. Use a fullscreen drawable
- llinfos << "createContext: attaching fullscreen drawable" << llendl;
+ LL_DEBUGS("Window") << "createContext: attaching fullscreen drawable" << LL_ENDL;
#if CAPTURE_ALL_DISPLAYS
// Capture all displays (may want to do this for final build)
@@ -681,7 +670,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
}
else if(!mFullscreen && (mWindow != NULL))
{
- llinfos << "createContext: attaching windowed drawable" << llendl;
+ LL_DEBUGS("Window") << "createContext: attaching windowed drawable" << LL_ENDL;
// We created a window. Use it as the drawable.
if(!aglSetDrawable(mContext, GetWindowPort (mWindow)))
@@ -698,7 +687,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
if(mContext != NULL)
{
- llinfos << "createContext: setting current context" << llendl;
+ LL_DEBUGS("Window") << "createContext: setting current context" << LL_ENDL;
if (!aglSetCurrentContext(mContext))
{
@@ -723,7 +712,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
"Radeon DDR",
"Radeon VE",
"GDI Generic" };
- const S32 CARD_COUNT = sizeof(CARD_LIST)/sizeof(char*);
+ const S32 CARD_COUNT = LL_ARRAY_SIZE(CARD_LIST);
// Future candidates:
// ProSavage/Twister
@@ -752,11 +741,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
return FALSE;
}
- llinfos << "GL buffer: Color Bits " << S32(colorBits)
+ LL_INFOS("GLInit") << "GL buffer: Color Bits " << S32(colorBits)
<< " Alpha Bits " << S32(alphaBits)
<< " Depth Bits " << S32(depthBits)
<< " Stencil Bits" << S32(stencilBits)
- << llendl;
+ << LL_ENDL;
if (colorBits < 32)
{
@@ -791,18 +780,18 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
GLint frames_per_swap = 0;
if (disable_vsync)
{
- llinfos << "Disabling vertical sync" << llendl;
+ LL_DEBUGS("GLInit") << "Disabling vertical sync" << LL_ENDL;
frames_per_swap = 0;
}
else
{
- llinfos << "Keeping vertical sync" << llendl;
+ LL_DEBUGS("GLinit") << "Keeping vertical sync" << LL_ENDL;
frames_per_swap = 1;
}
aglSetInteger(mContext, AGL_SWAP_INTERVAL, &frames_per_swap);
//enable multi-threaded OpenGL
- if (gSavedSettings.getBOOL("RenderAppleUseMultGL"))
+ if (sUseMultGL)
{
CGLError cgl_err;
CGLContextObj ctx = CGLGetCurrentContext();
@@ -811,11 +800,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
if (cgl_err != kCGLNoError )
{
- llinfos << "Multi-threaded OpenGL not available." << llendl;
+ LL_DEBUGS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL;
}
else
{
- llinfos << "Multi-threaded OpenGL enabled." << llendl;
+ LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
}
}
@@ -825,7 +814,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
// changing fullscreen resolution, or switching between windowed and fullscreen mode.
-BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync)
+BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp)
{
BOOL needsRebuild = FALSE;
BOOL result = true;
@@ -859,11 +848,11 @@ BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL dis
mFullscreenBits = CGDisplayBitsPerPixel(mDisplay);
mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate));
- llinfos << "Switched resolution to " << mFullscreenWidth
+ LL_INFOS("Window") << "Switched resolution to " << mFullscreenWidth
<< "x" << mFullscreenHeight
<< "x" << mFullscreenBits
<< " @ " << mFullscreenRefresh
- << llendl;
+ << LL_ENDL;
// Update the GL context to the new screen size
if (!aglUpdateContext(mContext))
@@ -897,8 +886,9 @@ BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL dis
}
stop_glerror();
- if(needsRebuild)
+ if(needsRebuild || mForceRebuild)
{
+ mForceRebuild = FALSE;
destroyContext();
result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync);
if (result)
@@ -932,7 +922,7 @@ void LLWindowMacOSX::destroyContext()
// Unhook the GL context from any drawable it may have
if(mContext != NULL)
{
- llinfos << "destroyContext: unhooking drawable " << llendl;
+ LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL;
aglSetCurrentContext (NULL);
aglSetDrawable(mContext, NULL);
@@ -941,7 +931,7 @@ void LLWindowMacOSX::destroyContext()
// Make sure the display resolution gets restored
if(mOldDisplayMode != NULL)
{
- llinfos << "destroyContext: restoring display resolution " << llendl;
+ LL_DEBUGS("Window") << "destroyContext: restoring display resolution " << LL_ENDL;
CGDisplaySwitchToMode (mDisplay, mOldDisplayMode);
@@ -967,7 +957,7 @@ void LLWindowMacOSX::destroyContext()
// Clean up the pixel format
if(mPixelFormat != NULL)
{
- llinfos << "destroyContext: destroying pixel format " << llendl;
+ LL_DEBUGS("Window") << "destroyContext: destroying pixel format " << LL_ENDL;
aglDestroyPixelFormat(mPixelFormat);
mPixelFormat = NULL;
}
@@ -975,14 +965,14 @@ void LLWindowMacOSX::destroyContext()
// Remove any Carbon Event handlers we installed
if(mGlobalHandlerRef != NULL)
{
- llinfos << "destroyContext: removing global event handler" << llendl;
+ LL_DEBUGS("Window") << "destroyContext: removing global event handler" << LL_ENDL;
RemoveEventHandler(mGlobalHandlerRef);
mGlobalHandlerRef = NULL;
}
if(mWindowHandlerRef != NULL)
{
- llinfos << "destroyContext: removing window event handler" << llendl;
+ LL_DEBUGS("Window") << "destroyContext: removing window event handler" << LL_ENDL;
RemoveEventHandler(mWindowHandlerRef);
mWindowHandlerRef = NULL;
}
@@ -990,7 +980,7 @@ void LLWindowMacOSX::destroyContext()
// Cleanup any TSM document we created.
if(mTSMDocument != NULL)
{
- llinfos << "destroyContext: deleting TSM document" << llendl;
+ LL_DEBUGS("Window") << "destroyContext: deleting TSM document" << LL_ENDL;
DeactivateTSMDocument(mTSMDocument);
DeleteTSMDocument(mTSMDocument);
mTSMDocument = NULL;
@@ -999,7 +989,7 @@ void LLWindowMacOSX::destroyContext()
// Close the window
if(mWindow != NULL)
{
- llinfos << "destroyContext: disposing window" << llendl;
+ LL_DEBUGS("Window") << "destroyContext: disposing window" << LL_ENDL;
DisposeWindow(mWindow);
mWindow = NULL;
}
@@ -1007,7 +997,7 @@ void LLWindowMacOSX::destroyContext()
// Clean up the GL context
if(mContext != NULL)
{
- llinfos << "destroyContext: destroying GL context" << llendl;
+ LL_DEBUGS("Window") << "destroyContext: destroying GL context" << LL_ENDL;
aglDestroyContext(mContext);
mContext = NULL;
}
@@ -1043,6 +1033,7 @@ void LLWindowMacOSX::hide()
HideWindow(mWindow);
}
+//virtual
void LLWindowMacOSX::minimize()
{
setMouseClipping(FALSE);
@@ -1050,6 +1041,7 @@ void LLWindowMacOSX::minimize()
CollapseWindow(mWindow, true);
}
+//virtual
void LLWindowMacOSX::restore()
{
show();
@@ -1318,6 +1310,17 @@ F32 LLWindowMacOSX::getGamma()
return result;
}
+U32 LLWindowMacOSX::getFSAASamples()
+{
+ return mFSAASamples;
+}
+
+void LLWindowMacOSX::setFSAASamples(const U32 samples)
+{
+ mFSAASamples = samples;
+ mForceRebuild = TRUE;
+}
+
BOOL LLWindowMacOSX::restoreGamma()
{
CGDisplayRestoreColorSyncSettings();
@@ -1387,11 +1390,11 @@ void LLWindowMacOSX::setMouseClipping( BOOL b )
if(b)
{
- // llinfos << "setMouseClipping(TRUE)" << llendl
+ // llinfos << "setMouseClipping(TRUE)" << llendl;
}
else
{
- // llinfos << "setMouseClipping(FALSE)" << llendl
+ // llinfos << "setMouseClipping(FALSE)" << llendl;
}
adjustCursorDecouple();
@@ -1409,7 +1412,7 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)
CGPoint newPosition;
- // llinfos << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << llendl
+ // llinfos << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << llendl;
newPosition.x = screen_pos.mX;
newPosition.y = screen_pos.mY;
@@ -1423,6 +1426,11 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)
// Under certain circumstances, this will trigger us to decouple the cursor.
adjustCursorDecouple(true);
+ // trigger mouse move callback
+ LLCoordGL gl_pos;
+ convertCoords(position, &gl_pos);
+ mCallbacks->handleMouseMove(this, gl_pos, (MASK)0);
+
return result;
}
@@ -1435,7 +1443,7 @@ static void fixOrigin(void)
::GetPortBounds(port, &portrect);
if((portrect.left != 0) || (portrect.top != 0))
{
- // Mozilla sometimes changes our port origin. Fuckers.
+ // Mozilla sometimes changes our port origin.
::SetOrigin(0,0);
}
}
@@ -1493,6 +1501,7 @@ void LLWindowMacOSX::adjustCursorDecouple(bool warpingMouse)
// llinfos << "adjustCursorDecouple: decoupling cursor" << llendl;
CGAssociateMouseAndMouseCursorPosition(false);
mCursorDecoupled = true;
+ FlushSpecificEventsFromQueue(GetCurrentEventQueue(), mMoveEventCampartorUPP, NULL);
mCursorIgnoreNextDelta = TRUE;
}
}
@@ -1588,11 +1597,6 @@ void LLWindowMacOSX::afterDialog()
}
-S32 LLWindowMacOSX::stat(const char* file_name, struct stat* stat_info)
-{
- return ::stat( file_name, stat_info );
-}
-
void LLWindowMacOSX::flashIcon(F32 seconds)
{
// Don't do this if we're already started, since this would try to install the NMRec twice.
@@ -1722,15 +1726,6 @@ BOOL LLWindowMacOSX::copyTextToClipboard(const LLWString &s)
}
-BOOL LLWindowMacOSX::sendEmail(const char* address, const char* subject, const char* body_text,
- const char* attachment, const char* attachment_displayed_name )
-{
- // MBW -- XXX -- Um... yeah. I'll get to this later.
-
- return false;
-}
-
-
// protected
BOOL LLWindowMacOSX::resetDisplayResolution()
{
@@ -1927,13 +1922,30 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordScreen *to)
-void LLWindowMacOSX::setupFailure(const char* text, const char* caption, U32 type)
+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;
@@ -2005,7 +2017,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
// 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->getWText();
+ 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);
@@ -2031,7 +2043,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
{
for (LLWString::const_iterator i = fix_string.begin(); i != fix_string.end(); i++)
{
- mPreeditor->handleUnicodeCharHere(*i, FALSE);
+ mPreeditor->handleUnicodeCharHere(*i);
}
}
@@ -2123,10 +2135,11 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
{
UInt32 modifiers = 0;
+
// First, process the raw event.
{
- EventRef rawEvent;
-
+ 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)
{
@@ -2135,6 +2148,9 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
// 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;
}
}
@@ -2162,11 +2178,8 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
}
else
{
- MASK mask = 0;
- if(modifiers & shiftKey) { mask |= MASK_SHIFT; }
- if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; }
- if(modifiers & optionKey) { mask |= MASK_ALT; }
-
+ MASK mask = LLWindowMacOSX::modifiersToMask(modifiers);
+
llassert( actualType == typeUnicodeText );
// The result is a UTF16 buffer. Pass the characters in turn to handleUnicodeChar.
@@ -2188,6 +2201,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
delete[] buffer;
}
+ mRawKeyEvent = NULL;
result = err;
}
break;
@@ -2203,7 +2217,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
{
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
- const LLWString & text = mPreeditor->getWText();
+ const LLWString & text = mPreeditor->getPreeditString();
LLCoordGL caret_coord;
LLRect preedit_bounds;
@@ -2240,7 +2254,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
mPreeditor->getSelectionRange(&selection, &selection_length);
if (selection_length)
{
- const LLWString text = mPreeditor->getWText().substr(selection, 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());
@@ -2262,6 +2276,9 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
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);
@@ -2357,6 +2374,8 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
result = eventNotHandledErr;
break;
}
+
+ mRawKeyEvent = NULL;
}
break;
@@ -2527,19 +2546,33 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
}
mCallbacks->handleFocusLost(this);
break;
+
case kEventWindowBoundsChanging:
{
+ // This is where we would constrain move/resize to a particular screen
+
+ const S32 MIN_WIDTH = 320;
+ const S32 MIN_HEIGHT = 240;
+
Rect currentBounds;
Rect previousBounds;
GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &currentBounds);
GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &previousBounds);
- // This is where we would constrain move/resize to a particular screen
- if(0)
+
+ if ((currentBounds.right - currentBounds.left) < MIN_WIDTH)
+ {
+ currentBounds.right = currentBounds.left + MIN_WIDTH;
+ }
+
+ if ((currentBounds.bottom - currentBounds.top) < MIN_HEIGHT)
{
- SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), &currentBounds);
+ currentBounds.bottom = currentBounds.top + MIN_HEIGHT;
}
+
+ SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), &currentBounds);
+ result = noErr;
}
break;
@@ -2597,7 +2630,6 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
// BringToFront(mWindow);
// result = noErr;
break;
-
}
break;
@@ -2613,7 +2645,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
- const LLWString & text = mPreeditor->getWText();
+ 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);
@@ -2630,7 +2662,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
- const LLWString & text = mPreeditor->getWText();
+ const LLWString & text = mPreeditor->getPreeditString();
CFRange range;
if (preedit_length)
@@ -2664,7 +2696,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
{
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
- const LLWString & text = mPreeditor->getWText();
+ 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
@@ -2739,14 +2771,13 @@ const char* cursorIDToName(int id)
case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN";
case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN";
case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3";
- case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT";
- case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY";
- case UI_CURSOR_TOOLPAY: return "UI_CURSOR_TOOLPAY";
- case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN";
case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY";
case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE";
case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN";
case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE";
+ case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT";
+ case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY";
+ case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN";
}
llerrs << "cursorIDToName: unknown cursor id" << id << llendl;
@@ -2774,6 +2805,14 @@ void LLWindowMacOSX::setCursor(ECursorType cursor)
{
OSStatus result = noErr;
+ if (mDragOverrideCursor != -1)
+ {
+ // A drag is in progress...remember the requested cursor and we'll
+ // restore it when it is done
+ mCurrentCursor = cursor;
+ return;
+ }
+
if (cursor == UI_CURSOR_ARROW
&& mBusyCount > 0)
{
@@ -2838,13 +2877,12 @@ void LLWindowMacOSX::setCursor(ECursorType cursor)
case UI_CURSOR_TOOLPAN:
case UI_CURSOR_TOOLZOOMIN:
case UI_CURSOR_TOOLPICKOBJECT3:
- case UI_CURSOR_TOOLSIT:
- case UI_CURSOR_TOOLBUY:
- case UI_CURSOR_TOOLPAY:
- case UI_CURSOR_TOOLOPEN:
case UI_CURSOR_TOOLPLAY:
case UI_CURSOR_TOOLPAUSE:
case UI_CURSOR_TOOLMEDIAOPEN:
+ case UI_CURSOR_TOOLSIT:
+ case UI_CURSOR_TOOLBUY:
+ case UI_CURSOR_TOOLOPEN:
result = setImageCursor(gCursors[cursor]);
break;
@@ -2858,7 +2896,7 @@ void LLWindowMacOSX::setCursor(ECursorType cursor)
mCurrentCursor = cursor;
}
-ECursorType LLWindowMacOSX::getCursor()
+ECursorType LLWindowMacOSX::getCursor() const
{
return mCurrentCursor;
}
@@ -2883,13 +2921,12 @@ void LLWindowMacOSX::initCursors()
initPixmapCursor(UI_CURSOR_TOOLPAN, 7, 6);
initPixmapCursor(UI_CURSOR_TOOLZOOMIN, 7, 6);
initPixmapCursor(UI_CURSOR_TOOLPICKOBJECT3, 1, 1);
- initPixmapCursor(UI_CURSOR_TOOLSIT, 1, 1);
- initPixmapCursor(UI_CURSOR_TOOLBUY, 1, 1);
- initPixmapCursor(UI_CURSOR_TOOLPAY, 1, 1);
- initPixmapCursor(UI_CURSOR_TOOLOPEN, 1, 1);
initPixmapCursor(UI_CURSOR_TOOLPLAY, 1, 1);
initPixmapCursor(UI_CURSOR_TOOLPAUSE, 1, 1);
initPixmapCursor(UI_CURSOR_TOOLMEDIAOPEN, 1, 1);
+ initPixmapCursor(UI_CURSOR_TOOLSIT, 20, 15);
+ initPixmapCursor(UI_CURSOR_TOOLBUY, 20, 15);
+ initPixmapCursor(UI_CURSOR_TOOLOPEN, 20, 15);
initPixmapCursor(UI_CURSOR_SIZENWSE, 10, 10);
initPixmapCursor(UI_CURSOR_SIZENESW, 10, 10);
@@ -2998,20 +3035,13 @@ void LLSplashScreenMacOSX::showImpl()
#endif
}
-void LLSplashScreenMacOSX::updateImpl(const char* mesg)
+void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
{
if(mWindow != NULL)
{
CFStringRef string = NULL;
- if(mesg != NULL)
- {
- string = CFStringCreateWithCString(NULL, mesg, kCFStringEncodingUTF8);
- }
- else
- {
- string = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8);
- }
+ string = CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
if(string != NULL)
{
@@ -3046,7 +3076,7 @@ void LLSplashScreenMacOSX::hideImpl()
-S32 OSMessageBoxMacOSX(const char* text, const char* caption, U32 type)
+S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type)
{
S32 result = OSBTN_CANCEL;
SInt16 retval_mac = 1;
@@ -3057,23 +3087,8 @@ S32 OSMessageBoxMacOSX(const char* text, const char* caption, U32 type)
AlertType alertType = kAlertCautionAlert;
OSStatus err;
- if(text != NULL)
- {
- explanationString = CFStringCreateWithCString(NULL, text, kCFStringEncodingUTF8);
- }
- else
- {
- explanationString = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8);
- }
-
- if(caption != NULL)
- {
- errorString = CFStringCreateWithCString(NULL, caption, kCFStringEncodingUTF8);
- }
- else
- {
- errorString = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8);
- }
+ explanationString = CFStringCreateWithCString(NULL, text.c_str(), kCFStringEncodingUTF8);
+ errorString = CFStringCreateWithCString(NULL, caption.c_str(), kCFStringEncodingUTF8);
params.version = kStdCFStringAlertVersionOne;
params.movable = false;
@@ -3157,15 +3172,13 @@ S32 OSMessageBoxMacOSX(const char* text, const char* caption, U32 type)
// Open a URL with the user's default web browser.
// Must begin with protocol identifier.
-void spawn_web_browser(const char* escaped_url)
+void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
{
bool found = false;
S32 i;
for (i = 0; i < gURLProtocolWhitelistCount; i++)
{
- S32 len = strlen(gURLProtocolWhitelist[i]); /* Flawfinder: ignore */
- if (!strncmp(escaped_url, gURLProtocolWhitelist[i], len)
- && escaped_url[len] == ':')
+ if (escaped_url.find(gURLProtocolWhitelist[i]) != std::string::npos)
{
found = true;
break;
@@ -3174,7 +3187,7 @@ void spawn_web_browser(const char* escaped_url)
if (!found)
{
- llwarns << "spawn_web_browser() called for url with protocol not on whitelist: " << escaped_url << llendl;
+ llwarns << "spawn_web_browser called for url with protocol not on whitelist: " << escaped_url << llendl;
return;
}
@@ -3183,7 +3196,7 @@ void spawn_web_browser(const char* escaped_url)
llinfos << "Opening URL " << escaped_url << llendl;
- CFStringRef stringRef = CFStringCreateWithCString(NULL, escaped_url, kCFStringEncodingUTF8);
+ CFStringRef stringRef = CFStringCreateWithCString(NULL, escaped_url.c_str(), kCFStringEncodingUTF8);
if (stringRef)
{
// This will succeed if the string is a full URL, including the http://
@@ -3212,8 +3225,62 @@ void spawn_web_browser(const char* escaped_url)
}
}
+LLSD LLWindowMacOSX::getNativeKeyData()
+{
+ LLSD result = LLSD::emptyMap();
+
+ if(mRawKeyEvent)
+ {
+ char char_code = 0;
+ UInt32 key_code = 0;
+ UInt32 modifiers = 0;
+ UInt32 keyboard_type = 0;
+
+ GetEventParameter (mRawKeyEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &char_code);
+ GetEventParameter (mRawKeyEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &key_code);
+ GetEventParameter (mRawKeyEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+ GetEventParameter (mRawKeyEvent, kEventParamKeyboardType, typeUInt32, NULL, sizeof(UInt32), NULL, &keyboard_type);
+
+ result["char_code"] = (S32)char_code;
+ result["key_code"] = (S32)key_code;
+ result["modifiers"] = (S32)modifiers;
+ result["keyboard_type"] = (S32)keyboard_type;
+
+#if 0
+ // 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;
+ EventParamType actualType = typeUTF8Text;
+ UInt32 actualSize = 0;
+ char *buffer = NULL;
+
+ err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, 0, &actualSize, NULL);
+ if(err == noErr)
+ {
+ // allocate a buffer and get the actual data.
+ buffer = new char[actualSize];
+ err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, actualSize, &actualSize, buffer);
+ if(err == noErr)
+ {
+ unicode.assign(buffer, actualSize);
+ }
+ delete[] buffer;
+ }
+
+ result["unicode"] = unicode;
+#endif
+
+ }
+
+
+ lldebugs << "native key data is: " << result << llendl;
+
+ return result;
+}
+
-BOOL LLWindowMacOSX::dialog_color_picker ( F32 *r, F32 *g, F32 *b)
+BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b)
{
BOOL retval = FALSE;
OSErr error = noErr;
@@ -3246,25 +3313,34 @@ BOOL LLWindowMacOSX::dialog_color_picker ( F32 *r, F32 *g, F32 *b)
return (retval);
}
-static WindowRef dummywindowref = NULL;
void *LLWindowMacOSX::getPlatformWindow()
{
- if(mWindow != NULL)
- return (void*)mWindow;
+ // NOTE: this will be NULL in fullscreen mode. Plan accordingly.
+ 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.
- // If we're in fullscreen mode, there's no window pointer available.
- // Since Mozilla needs one to function, create a dummy window here.
- // Note that we will never destroy it, but since only one will be created per run of the application, that's okay.
+ 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(dummywindowref == NULL)
+ if(sMediaWindow == NULL)
{
Rect window_rect = {100, 100, 200, 200};
- dummywindowref = NewCWindow(
+ sMediaWindow = NewCWindow(
NULL,
&window_rect,
- "\p",
+ (ConstStr255Param) "\p",
false, // Create the window invisible.
zoomDocProc, // Window with a grow box and a zoom box
kLastWindowOfClass, // create it behind other windows
@@ -3272,7 +3348,7 @@ void *LLWindowMacOSX::getPlatformWindow()
0);
}
- return (void*)dummywindowref;
+ return (void*)sMediaWindow;
}
void LLWindowMacOSX::stopDockTileBounce()
@@ -3320,6 +3396,8 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
return;
}
+ UseInputWindow(mTSMDocument, !b);
+
// Take care of old and new preeditors.
if (preeditor != mPreeditor || !b)
{
@@ -3372,4 +3450,181 @@ void LLWindowMacOSX::interruptLanguageTextInput()
// Well, if Apple's TSM document is correct, we don't.
}
-#endif // LL_DARWIN
+//static
+std::vector<std::string> LLWindowMacOSX::getDynamicFallbackFontList()
+{
+ // Fonts previously in getFontListSans() have moved to fonts.xml.
+ return std::vector<std::string>();
+}
+
+// static
+MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers)
+{
+ MASK mask = 0;
+ if(modifiers & shiftKey) { mask |= MASK_SHIFT; }
+ if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; }
+ if(modifiers & optionKey) { mask |= MASK_ALT; }
+ return mask;
+}
+
+#if LL_OS_DRAGDROP_ENABLED
+
+OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
+ void * handlerRefCon, DragRef drag)
+{
+ OSErr result = noErr;
+ LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon;
+
+ lldebugs << "drag tracking handler, message = " << message << llendl;
+
+ switch(message)
+ {
+ case kDragTrackingInWindow:
+ result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_TRACK);
+ break;
+
+ case kDragTrackingEnterHandler:
+ result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_START_TRACKING);
+ break;
+
+ case kDragTrackingLeaveHandler:
+ result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_STOP_TRACKING);
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon,
+ DragRef drag)
+{
+ LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon;
+ return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED);
+
+}
+
+OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, 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);
+
+ Point mouse_point;
+ // This will return the mouse point in global screen coords
+ ::GetDragMouse(drag, &mouse_point, NULL);
+ LLCoordScreen screen_coords(mouse_point.h, mouse_point.v);
+ 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)
+ {
+ 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))
+ {
+ // This is a string that might be an URL.
+ err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeUTF8PlainText, &data);
+ }
+
+ }
+
+ 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);
+ }
+
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+#endif // LL_OS_DRAGDROP_ENABLED