Merge. Pull in viewer-release after materials viewer release.

Thu, 19 Sep 2013 13:13:37 -0400

author
Monty Brandenberg <monty@lindenlab.com>
date
Thu, 19 Sep 2013 13:13:37 -0400
changeset 40726
ea87b029d00c
parent 40725
3053bf46de4b
parent 38605
69bff4df771c
child 40727
f2b0a9f7b1c0

Merge. Pull in viewer-release after materials viewer release.

NORSPEC-207.patch file | annotate | diff | revisions
autobuild.xml file | annotate | diff | revisions
indra/newview/SecondLife.nib/classes.nib file | annotate | diff | revisions
indra/newview/SecondLife.nib/info.nib file | annotate | diff | revisions
indra/newview/SecondLife.nib/objects.xib file | annotate | diff | revisions
indra/newview/app_settings/settings.xml file | annotate | diff | revisions
indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl file | annotate | diff | revisions
indra/newview/llviewerregion.cpp file | annotate | diff | revisions
     1.1 --- a/.hgtags	Wed Sep 18 18:44:41 2013 -0400
     1.2 +++ b/.hgtags	Thu Sep 19 13:13:37 2013 -0400
     1.3 @@ -56,11 +56,11 @@
     1.4  54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f 2.5.0-beta2
     1.5  54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33--2.5.0beta2
     1.6  54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33_2.5.0-beta2
     1.7 -b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
     1.8  b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3
     1.9  b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
    1.10  b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
    1.11  b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
    1.12 +b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
    1.13  63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
    1.14  4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
    1.15  4dede9ae1ec74d41f6887719f6f1de7340d8578d DRTVWR-37_2.5.1-release
    1.16 @@ -464,3 +464,5 @@
    1.17  fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release
    1.18  83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a
    1.19  91ed595b716f14f07409595b734fda891a59379e 3.6.4-release
    1.20 +bf6d453046011a11de2643fac610cc5258650f82 3.6.5-release
    1.21 +b62e417982d9d4f3ec49d0de3b3c2e37c6d394c1 3.6.6-release
     2.1 --- a/NORSPEC-207.patch	Wed Sep 18 18:44:41 2013 -0400
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,164 +0,0 @@
     2.4 -diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.cpp
     2.5 ---- a/indra/llprimitive/llrendermaterialtable.cpp	Wed May 15 17:57:21 2013 +0000
     2.6 -+++ b/indra/llprimitive/llrendermaterialtable.cpp	Wed May 22 14:23:04 2013 -0700
     2.7 -@@ -184,6 +184,44 @@
     2.8 - 	}
     2.9 - }
    2.10 - 
    2.11 -+// 'v' is an integer value for 100ths of radians (don't ask...)
    2.12 -+//
    2.13 -+void LLRenderMaterialEntry::LLRenderMaterial::setSpecularMapRotation(S32 v) const
    2.14 -+{
    2.15 -+	// Store the fact that we're using the new rotation rep
    2.16 -+	//
    2.17 -+	m_flags |= kNewSpecularMapRotation;
    2.18 -+
    2.19 -+	// Store 'sign bit' in our m_flags
    2.20 -+	//
    2.21 -+	m_flags &= ~kSpecularMapRotationNegative;
    2.22 -+	m_flags |= (specularMapRotation < 0) ? kSpecularMapRotationNegative : 0;
    2.23 -+
    2.24 -+	specularRotation = abs(specularRotation);
    2.25 -+	specularRotation = llmin(specularRotation, MAX_MATERIAL_MAP_ROTATION);
    2.26 -+
    2.27 -+	m_specularRotation = (U16)(abs(specularMapRotation));
    2.28 -+}
    2.29 -+
    2.30 -+// 'v' is an integer value for 100ths of radians (don't ask...)
    2.31 -+//
    2.32 -+void LLRenderMaterialEntry::LLRenderMaterial::setNormalMapRotation(S32 v) const
    2.33 -+{
    2.34 -+
    2.35 -+	// Store the fact that we're using the new rep for this material
    2.36 -+	//
    2.37 -+	m_flags |= kNewNormalMapRotation;
    2.38 -+
    2.39 -+	// Store 'sign bit' in our m_flags
    2.40 -+	//
    2.41 -+	m_flags &= ~kNormalMapRotationNegative;
    2.42 -+	m_flags |= (normalMapRotation < 0) ? kNormalMapRotationNegative : 0;
    2.43 -+
    2.44 -+	normalRotation = abs(normalRotation);
    2.45 -+	normalRotation = llmin(normalRotation, MAX_MATERIAL_MAP_ROTATION);
    2.46 -+
    2.47 -+	m_normalRotation = (U16)(abs(normalMapRotation));
    2.48 -+}
    2.49 - 
    2.50 - void LLRenderMaterialEntry::LLRenderMaterial::asLLSD( LLSD& dest ) const
    2.51 - {
    2.52 -@@ -193,20 +231,45 @@
    2.53 - 	dest["NormOffsetY"] = (S32)m_normalOffsetY;
    2.54 - 	dest["NormRepeatX"] = m_normalRepeatX;
    2.55 - 	dest["NormRepeatY"] = m_normalRepeatY;
    2.56 --	dest["NormRotation"] = (S32)m_normalRotation;
    2.57 -+
    2.58 -+	S32 value = (S32)m_normalMapRotation;
    2.59 -+
    2.60 -+	// If we don't have the flag for new rotations set,
    2.61 -+	// then we need to convert it now
    2.62 -+	if (!(m_flags & kNewNormalMapRotation))
    2.63 -+	{
    2.64 -+		F32 old_radians = ((F32)m_normalMapRotation / 10000.0f)
    2.65 -+		S32 new_val	    = (S32)(old_radians * 100.0f);
    2.66 -+		setNormalMapRotation(new_Val);
    2.67 -+	}
    2.68 -+
    2.69 -+	dest["NormRotation"] = (m_flags & kNormalMapRotationNegative) ? -(S32)m_normalRotation : (S32)m_normalRotation;
    2.70 - 
    2.71 - 	dest["SpecOffsetX"] = (S32)m_specularOffsetX;
    2.72 - 	dest["SpecOffsetY"] = (S32)m_specularOffsetY;
    2.73 - 	dest["SpecRepeatX"] = m_specularRepeatX;
    2.74 - 	dest["SpecRepeatY"] = m_specularRepeatY;
    2.75 --	dest["SpecRotation"] = (S32)m_specularRotation;
    2.76 -+
    2.77 -+
    2.78 -+	value = (S32)m_specularRotation;
    2.79 -+
    2.80 -+	// If we don't have the flag for new rotations set,
    2.81 -+	// then we need to convert it now
    2.82 -+	if (!(m_flags & kNewSpecularMapRotation))
    2.83 -+	{
    2.84 -+		F32 old_radians = ((F32)m_specularMapRotation / 10000.0f)
    2.85 -+		S32 new_val	    = (S32)(old_radians * 100.0f);
    2.86 -+		setSpecularMapRotation(new_Val);
    2.87 -+	}
    2.88 -+
    2.89 -+	dest["SpecRotation"] = (m_flags & kSpecularMapRotationNegative) ? -(S32)m_specularRotation : (S32)m_specularRotation;
    2.90 - 
    2.91 - 	dest["SpecMap"] = m_specularMap;
    2.92 - 	dest["SpecColor"] = m_specularLightColor.getValue();
    2.93 - 	dest["SpecExp"] = (S32)m_specularLightExponent;
    2.94 - 	dest["EnvIntensity"] = (S32)m_environmentIntensity;
    2.95 - 	dest["AlphaMaskCutoff"] = (S32)m_alphaMaskCutoff;
    2.96 --	dest["DiffuseAlphaMode"] = (S32)m_diffuseAlphaMode;
    2.97 -+	dest["DiffuseAlphaMode"] = (S32)(m_diffuseAlphaMode & 0xF);
    2.98 - 	
    2.99 - }
   2.100 - 
   2.101 -@@ -217,7 +280,10 @@
   2.102 - 	m_normalOffsetY = (U16)materialDefinition["NormOffsetY"].asInteger();
   2.103 - 	m_normalRepeatX = materialDefinition["NormRepeatX"].asInteger();
   2.104 - 	m_normalRepeatY = materialDefinition["NormRepeatY"].asInteger();
   2.105 --	m_normalRotation = (U16)materialDefinition["NormRotation"].asInteger();
   2.106 -+
   2.107 -+	S32 normalRotation = materialDefinition["NormRotation"].asInteger();
   2.108 -+
   2.109 -+	setNormalMapRotation(normalRotation);
   2.110 - 
   2.111 - 	m_specularMap = materialDefinition["SpecMap"].asUUID();
   2.112 - 
   2.113 -@@ -225,7 +291,10 @@
   2.114 - 	m_specularOffsetY = (U16)materialDefinition["SpecOffsetY"].asInteger();
   2.115 - 	m_specularRepeatX = materialDefinition["SpecRepeatX"].asInteger();
   2.116 - 	m_specularRepeatY = materialDefinition["SpecRepeatY"].asInteger();
   2.117 --	m_specularRotation = (U16)materialDefinition["SpecRotation"].asInteger();
   2.118 -+
   2.119 -+	S32 specularRotation = materialDefinition["SpecRotation"].asInteger();
   2.120 -+
   2.121 -+	setSpecularMapRotation(specularRotation);
   2.122 - 
   2.123 - 	m_specularLightColor.setValue( materialDefinition["SpecColor"] );
   2.124 - 	m_specularLightExponent = (U8)materialDefinition["SpecExp"].asInteger();
   2.125 -diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.h
   2.126 ---- a/indra/llprimitive/llrendermaterialtable.h	Wed May 15 17:57:21 2013 +0000
   2.127 -+++ b/indra/llprimitive/llrendermaterialtable.h	Wed May 22 14:23:04 2013 -0700
   2.128 -@@ -89,11 +89,17 @@
   2.129 - 
   2.130 - 	void computeID();
   2.131 - 
   2.132 -+
   2.133 - 	struct LLRenderMaterial
   2.134 - 	{
   2.135 - 		void asLLSD( LLSD& dest ) const;
   2.136 - 		void setFromLLSD( const LLSD& materialDefinition );
   2.137 - 
   2.138 -+		void setNormalMapRotation(S32 v);
   2.139 -+		void setSpecularMapRotation(S32 v);
   2.140 -+
   2.141 -+		const S32 MAX_MATERIAL_MAP_ROTATION = 62800;
   2.142 -+
   2.143 - 		// 36 bytes
   2.144 - 		LLUUID m_normalMap;
   2.145 - 		LLUUID m_specularMap;
   2.146 -@@ -119,7 +125,20 @@
   2.147 - 		U8 m_specularLightExponent;
   2.148 - 		U8 m_environmentIntensity;
   2.149 - 		U8 m_alphaMaskCutoff;
   2.150 --		U8 m_diffuseAlphaMode;
   2.151 -+		U8 m_diffuseAlphaMode : 4;
   2.152 -+		U8 m_flags            : 4;
   2.153 -+	};
   2.154 -+
   2.155 -+	// Flags stored in LLRenderMaterial::m_flags to differentiate 'old' rotation format
   2.156 -+	// which doesn't handle negative or large rotations correctly from new format.
   2.157 -+	// All ancient materials will have these flags unset as the values for diffuseAlphaMode
   2.158 -+	// from which the bits were stolen never used more than the bottom 2 bits.
   2.159 -+	//
   2.160 -+	enum RenderMaterialFlags {
   2.161 -+	 kNewNormalMapRotation 		= 0x1,
   2.162 -+	 kNewSpecularMapRotation 	= 0x2,
   2.163 -+	 kNormalMapRotationNegative 	= 0x4,
   2.164 -+	 kSpecularMapRotationNegative   = 0x8
   2.165 - 	};
   2.166 - 
   2.167 - 	friend struct eastl::hash<LLRenderMaterial>;
     3.1 --- a/autobuild.xml	Wed Sep 18 18:44:41 2013 -0400
     3.2 +++ b/autobuild.xml	Thu Sep 19 13:13:37 2013 -0400
     3.3 @@ -2638,7 +2638,6 @@
     3.4                  <array>
     3.5                    <string>/build</string>
     3.6                    <string>"/cfg=Release|Win32"</string>
     3.7 -                  <string>"/CL_ADD=/m:1"</string>
     3.8                  </array>
     3.9                </map>
    3.10                <key>configure</key>
     4.1 --- a/doc/contributions.txt	Wed Sep 18 18:44:41 2013 -0400
     4.2 +++ b/doc/contributions.txt	Thu Sep 19 13:13:37 2013 -0400
     4.3 @@ -679,6 +679,8 @@
     4.4  Kaimen Takahe
     4.5  Katharine Berry
     4.6  	STORM-1900
     4.7 +	STORM-1940
     4.8 +	STORM-1941
     4.9  Keklily Longfall
    4.10  Ken Lavender
    4.11  Ken March
     5.1 --- a/indra/cmake/Variables.cmake	Wed Sep 18 18:44:41 2013 -0400
     5.2 +++ b/indra/cmake/Variables.cmake	Thu Sep 19 13:13:37 2013 -0400
     5.3 @@ -134,15 +134,20 @@
     5.4      OUTPUT_VARIABLE XCODE_VERSION )
     5.5  
     5.6    # To support a different SDK update these Xcode settings:
     5.7 +  if (XCODE_VERSION GREATER 4.5)
     5.8 +    set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
     5.9 +    set(CMAKE_OSX_SYSROOT macosx10.8)
    5.10 +  else (XCODE_VERSION GREATER 4.5)
    5.11    if (XCODE_VERSION GREATER 4.2)
    5.12      set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
    5.13 +    set(CMAKE_OSX_SYSROOT macosx10.7)
    5.14    else (XCODE_VERSION GREATER 4.2)
    5.15 -    set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
    5.16 +    set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
    5.17 +    set(CMAKE_OSX_SYSROOT macosx10.7)
    5.18    endif (XCODE_VERSION GREATER 4.2)
    5.19 +  endif (XCODE_VERSION GREATER 4.5)
    5.20  
    5.21 -  set(CMAKE_OSX_SYSROOT macosx10.6)
    5.22    set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
    5.23 -      
    5.24    set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
    5.25  
    5.26    # NOTE: To attempt an i386/PPC Universal build, add this on the configure line:
     6.1 --- a/indra/integration_tests/llui_libtest/CMakeLists.txt	Wed Sep 18 18:44:41 2013 -0400
     6.2 +++ b/indra/integration_tests/llui_libtest/CMakeLists.txt	Thu Sep 19 13:13:37 2013 -0400
     6.3 @@ -60,7 +60,8 @@
     6.4  # Link with OS-specific libraries for LLWindow dependency
     6.5  if (DARWIN)
     6.6    find_library(COCOA_LIBRARY Cocoa)
     6.7 -  set(OS_LIBRARIES ${COCOA_LIBRARY})
     6.8 +  find_library(IOKIT_LIBRARY IOKit)
     6.9 +  set(OS_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY})
    6.10  elseif (WINDOWS)
    6.11    #ll_stack_trace needs this now...
    6.12    list(APPEND WINDOWS_LIBRARIES dbghelp)
     7.1 --- a/indra/llcommon/llapr.cpp	Wed Sep 18 18:44:41 2013 -0400
     7.2 +++ b/indra/llcommon/llapr.cpp	Thu Sep 19 13:13:37 2013 -0400
     7.3 @@ -226,7 +226,7 @@
     7.4  		llassert_always(mNumActiveRef > 0) ;
     7.5  	}
     7.6  
     7.7 -	llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
     7.8 +	llassert(mNumTotalRef <= (FULL_VOLATILE_APR_POOL << 2)) ;
     7.9  }
    7.10  
    7.11  BOOL LLVolatileAPRPool::isFull()
     8.1 --- a/indra/llcommon/llsys.cpp	Wed Sep 18 18:44:41 2013 -0400
     8.2 +++ b/indra/llcommon/llsys.cpp	Thu Sep 19 13:13:37 2013 -0400
     8.3 @@ -67,12 +67,18 @@
     8.4  #	include <sys/sysctl.h>
     8.5  #	include <sys/utsname.h>
     8.6  #	include <stdint.h>
     8.7 -#	include <Carbon/Carbon.h>
     8.8 +#	include <CoreServices/CoreServices.h>
     8.9  #   include <stdexcept>
    8.10  #	include <mach/host_info.h>
    8.11  #	include <mach/mach_host.h>
    8.12  #	include <mach/task.h>
    8.13  #	include <mach/task_info.h>
    8.14 +
    8.15 +// disable warnings about Gestalt calls being deprecated
    8.16 +// until Apple get's on the ball and provides an alternative
    8.17 +//
    8.18 +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    8.19 +
    8.20  #elif LL_LINUX
    8.21  #	include <errno.h>
    8.22  #	include <sys/utsname.h>
    8.23 @@ -1502,3 +1508,10 @@
    8.24  	if (dst != NULL) gzclose(dst);
    8.25  	return retval;
    8.26  }
    8.27 +
    8.28 +#if LL_DARWIN
    8.29 +// disable warnings about Gestalt calls being deprecated
    8.30 +// until Apple get's on the ball and provides an alternative
    8.31 +//
    8.32 +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    8.33 +#endif
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/indra/llcommon/llversionviewer.h	Thu Sep 19 13:13:37 2013 -0400
     9.3 @@ -0,0 +1,41 @@
     9.4 +/** 
     9.5 + * @file llversionviewer.h
     9.6 + * @brief
     9.7 + *
     9.8 + * $LicenseInfo:firstyear=2002&license=viewerlgpl$
     9.9 + * Second Life Viewer Source Code
    9.10 + * Copyright (C) 2010, Linden Research, Inc.
    9.11 + * 
    9.12 + * This library is free software; you can redistribute it and/or
    9.13 + * modify it under the terms of the GNU Lesser General Public
    9.14 + * License as published by the Free Software Foundation;
    9.15 + * version 2.1 of the License only.
    9.16 + * 
    9.17 + * This library is distributed in the hope that it will be useful,
    9.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.20 + * Lesser General Public License for more details.
    9.21 + * 
    9.22 + * You should have received a copy of the GNU Lesser General Public
    9.23 + * License along with this library; if not, write to the Free Software
    9.24 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    9.25 + * 
    9.26 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    9.27 + * $/LicenseInfo$
    9.28 + */
    9.29 +
    9.30 +#ifndef LL_LLVERSIONVIEWER_H
    9.31 +#define LL_LLVERSIONVIEWER_H
    9.32 +
    9.33 +const S32 LL_VERSION_MAJOR = 3;
    9.34 +const S32 LL_VERSION_MINOR = 4;
    9.35 +const S32 LL_VERSION_PATCH = 6;
    9.36 +const S32 LL_VERSION_BUILD = 0;
    9.37 +
    9.38 +const char * const LL_CHANNEL = "Second Life Developer";
    9.39 +
    9.40 +#if LL_DARWIN
    9.41 +const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
    9.42 +#endif
    9.43 +
    9.44 +#endif
    10.1 --- a/indra/llmath/llvector4a.inl	Wed Sep 18 18:44:41 2013 -0400
    10.2 +++ b/indra/llmath/llvector4a.inl	Thu Sep 19 13:13:37 2013 -0400
    10.3 @@ -409,6 +409,26 @@
    10.4  	mQ = _mm_mul_ps( mQ, approxRsqrt );
    10.5  }
    10.6  
    10.7 +inline void LLVector4a::normalize3fast_checked(LLVector4a* d)
    10.8 +{
    10.9 +	if (!isFinite3())
   10.10 +	{
   10.11 +		*this = d ? *d : LLVector4a(0,1,0,1);
   10.12 +		return;
   10.13 +	}
   10.14 +
   10.15 +	LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this );
   10.16 +
   10.17 +	if (lenSqrd.getF32ptr()[0] <= FLT_EPSILON)
   10.18 +	{
   10.19 +		*this = d ? *d : LLVector4a(0,1,0,1);
   10.20 +		return;
   10.21 +	}
   10.22 +
   10.23 +	const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ);
   10.24 +	mQ = _mm_mul_ps( mQ, approxRsqrt );
   10.25 +}
   10.26 +
   10.27  // Return true if this vector is normalized with respect to x,y,z up to tolerance
   10.28  inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const
   10.29  {
    11.1 --- a/indra/llmath/llvolume.cpp	Wed Sep 18 18:44:41 2013 -0400
    11.2 +++ b/indra/llmath/llvolume.cpp	Thu Sep 19 13:13:37 2013 -0400
    11.3 @@ -136,6 +136,82 @@
    11.4  	return true;
    11.5  }
    11.6  
    11.7 +// Finds tangent vec based on three vertices with texture coordinates.
    11.8 +// Fills in dummy values if the triangle has degenerate texture coordinates.
    11.9 +void calc_tangent_from_triangle(
   11.10 +	LLVector4a&			normal,
   11.11 +	LLVector4a&			tangent_out,
   11.12 +	const LLVector4a& v1,
   11.13 +	const LLVector2&  w1,
   11.14 +	const LLVector4a& v2,
   11.15 +	const LLVector2&  w2,
   11.16 +	const LLVector4a& v3,
   11.17 +	const LLVector2&  w3)
   11.18 +{
   11.19 +	const F32* v1ptr = v1.getF32ptr();
   11.20 +	const F32* v2ptr = v2.getF32ptr();
   11.21 +	const F32* v3ptr = v3.getF32ptr();
   11.22 +
   11.23 +	float x1 = v2ptr[0] - v1ptr[0];
   11.24 +	float x2 = v3ptr[0] - v1ptr[0];
   11.25 +	float y1 = v2ptr[1] - v1ptr[1];
   11.26 +	float y2 = v3ptr[1] - v1ptr[1];
   11.27 +	float z1 = v2ptr[2] - v1ptr[2];
   11.28 +	float z2 = v3ptr[2] - v1ptr[2];
   11.29 +
   11.30 +	float s1 = w2.mV[0] - w1.mV[0];
   11.31 +	float s2 = w3.mV[0] - w1.mV[0];
   11.32 +	float t1 = w2.mV[1] - w1.mV[1];
   11.33 +	float t2 = w3.mV[1] - w1.mV[1];
   11.34 +
   11.35 +	F32 rd = s1*t2-s2*t1;
   11.36 +
   11.37 +	float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero
   11.38 +
   11.39 +	llassert(llfinite(r));
   11.40 +	llassert(!llisnan(r));
   11.41 +
   11.42 +	LLVector4a sdir(
   11.43 +		(t2 * x1 - t1 * x2) * r,
   11.44 +		(t2 * y1 - t1 * y2) * r,
   11.45 +		(t2 * z1 - t1 * z2) * r);
   11.46 +
   11.47 +	LLVector4a tdir(
   11.48 +		(s1 * x2 - s2 * x1) * r,
   11.49 +		(s1 * y2 - s2 * y1) * r,
   11.50 +		(s1 * z2 - s2 * z1) * r);
   11.51 +
   11.52 +	LLVector4a	n = normal;
   11.53 +	LLVector4a	t = sdir;
   11.54 +
   11.55 +	LLVector4a ncrosst;
   11.56 +	ncrosst.setCross3(n,t);
   11.57 +
   11.58 +	// Gram-Schmidt orthogonalize
   11.59 +	n.mul(n.dot3(t).getF32());
   11.60 +
   11.61 +	LLVector4a tsubn;
   11.62 +	tsubn.setSub(t,n);
   11.63 +
   11.64 +	if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
   11.65 +	{
   11.66 +		tsubn.normalize3fast_checked();
   11.67 +
   11.68 +		// Calculate handedness
   11.69 +		F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f;
   11.70 +
   11.71 +		tsubn.getF32ptr()[3] = handedness;
   11.72 +
   11.73 +		tangent_out = tsubn;
   11.74 +	}
   11.75 +	else
   11.76 +	{
   11.77 +		// degenerate, make up a value
   11.78 +		//
   11.79 +		tangent_out.set(0,0,1,1);
   11.80 +	}
   11.81 +
   11.82 +}
   11.83  
   11.84  
   11.85  // intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir.
   11.86 @@ -5908,10 +5984,10 @@
   11.87  		wght = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
   11.88  	}
   11.89  
   11.90 -	LLVector4a* binorm = NULL;
   11.91 +	LLVector4a* tangent = NULL;
   11.92  	if (mTangents)
   11.93  	{
   11.94 -		binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
   11.95 +		tangent = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
   11.96  	}
   11.97  
   11.98  	//allocate mapping of old indices to new indices
   11.99 @@ -5936,7 +6012,7 @@
  11.100  			}
  11.101  			if (mTangents)
  11.102  			{
  11.103 -				binorm[cur_idx] = mTangents[idx];
  11.104 +				tangent[cur_idx] = mTangents[idx];
  11.105  			}
  11.106  
  11.107  			cur_idx++;
  11.108 @@ -5958,7 +6034,7 @@
  11.109  	mNormals = norm;
  11.110  	mTexCoords = tc;
  11.111  	mWeights = wght;
  11.112 -	mTangents = binorm;
  11.113 +	mTangents = tangent;
  11.114  
  11.115  	//std::string result = llformat("ACMR pre/post: %.3f/%.3f  --  %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
  11.116  	//llinfos << result << llendl;
  11.117 @@ -6306,6 +6382,43 @@
  11.118  
  11.119  	cuv = (min_uv + max_uv)*0.5f;
  11.120  
  11.121 +
  11.122 +	LLVector4a tangent;
  11.123 +	calc_tangent_from_triangle(
  11.124 +			*norm,
  11.125 +			tangent,
  11.126 +			*mCenter, cuv,
  11.127 +			pos[0], tc[0],
  11.128 +			pos[1], tc[1]);
  11.129 +
  11.130 +	if (tangent.getLength3() < 0.01)
  11.131 +	{
  11.132 +		tangent.set(1,0,0,1);
  11.133 +	}
  11.134 +	else
  11.135 +	{
  11.136 +		LLVector4a default_tangent;
  11.137 +		default_tangent.set(1,0,0,1);
  11.138 +		tangent.normalize3fast_checked(&default_tangent);
  11.139 +	}
  11.140 +
  11.141 +	LLVector4a normal;
  11.142 +	LLVector4a d0, d1;
  11.143 +
  11.144 +	d0.setSub(*mCenter, pos[0]);
  11.145 +	d1.setSub(*mCenter, pos[1]);
  11.146 +	
  11.147 +	if (mTypeMask & TOP_MASK)
  11.148 +	{
  11.149 +		normal.setCross3(d0, d1);
  11.150 +	}
  11.151 +	else
  11.152 +	{
  11.153 +		normal.setCross3(d1, d0);
  11.154 +	}
  11.155 +
  11.156 +	normal.normalize3fast_checked();
  11.157 +
  11.158  	VertexData vd;
  11.159  	vd.setPosition(*mCenter);
  11.160  	vd.mTexCoord = cuv;
  11.161 @@ -6318,6 +6431,14 @@
  11.162  		num_vertices++;
  11.163  	}
  11.164  		
  11.165 +	allocateTangents(num_vertices);		
  11.166 +
  11.167 +	for (S32 i = 0; i < num_vertices; i++)
  11.168 +	{
  11.169 +		mTangents[i].load4a(tangent.getF32ptr());
  11.170 +		norm[i].load4a(normal.getF32ptr());
  11.171 +	}	
  11.172 +
  11.173  	if (partial_build)
  11.174  	{
  11.175  		return TRUE;
  11.176 @@ -6553,36 +6674,6 @@
  11.177  
  11.178  	}
  11.179  
  11.180 -	LLVector4a d0,d1;
  11.181 -
  11.182 -	d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]);
  11.183 -	d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]);
  11.184 -
  11.185 -	LLVector4a normal;
  11.186 -	normal.setCross3(d0,d1);
  11.187 -
  11.188 -	if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO)
  11.189 -	{
  11.190 -		normal.normalize3fast();
  11.191 -	}
  11.192 -	else
  11.193 -	{ //degenerate, make up a value
  11.194 -		normal.set(0,0,1);
  11.195 -	}
  11.196 -
  11.197 -	llassert(llfinite(normal.getF32ptr()[0]));
  11.198 -	llassert(llfinite(normal.getF32ptr()[1]));
  11.199 -	llassert(llfinite(normal.getF32ptr()[2]));
  11.200 -
  11.201 -	llassert(!llisnan(normal.getF32ptr()[0]));
  11.202 -	llassert(!llisnan(normal.getF32ptr()[1]));
  11.203 -	llassert(!llisnan(normal.getF32ptr()[2]));
  11.204 -	
  11.205 -	for (S32 i = 0; i < num_vertices; i++)
  11.206 -	{
  11.207 -		norm[i].load4a(normal.getF32ptr());
  11.208 -	}
  11.209 -
  11.210  	return TRUE;
  11.211  }
  11.212  
  11.213 @@ -6611,11 +6702,13 @@
  11.214  		CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);
  11.215  
  11.216  		//normalize tangents
  11.217 +		LLVector4a default_norm;
  11.218 +		default_norm.set(0,1,0,1);
  11.219  		for (U32 i = 0; i < mNumVertices; i++) 
  11.220  		{
  11.221 -			//binorm[i].normalize3fast();
  11.222 +			//tangent[i].normalize3fast();
  11.223  			//bump map/planar projection code requires normals to be normalized
  11.224 -			mNormals[i].normalize3fast();
  11.225 +			mNormals[i].normalize3fast_checked();
  11.226  		}
  11.227  	}
  11.228  }
  11.229 @@ -6800,7 +6893,7 @@
  11.230  
  11.231  		//transform appended face normal and store
  11.232  		norm_mat.rotate(src_norm[i], dst_norm[i]);
  11.233 -		dst_norm[i].normalize3fast();
  11.234 +		dst_norm[i].normalize3fast_checked();
  11.235  
  11.236  		//copy appended face texture coordinate
  11.237  		dst_tc[i] = src_tc[i];
  11.238 @@ -7209,11 +7302,61 @@
  11.239  	return TRUE;
  11.240  }
  11.241  
  11.242 +// Finds binormal based on three vertices with texture coordinates.
  11.243 +// Fills in dummy values if the triangle has degenerate texture coordinates.
  11.244 +void calc_binormal_from_triangle(LLVector4a& binormal,
  11.245 +
  11.246 +	const LLVector4a& pos0,
  11.247 +	const LLVector2& tex0,
  11.248 +	const LLVector4a& pos1,
  11.249 +	const LLVector2& tex1,
  11.250 +	const LLVector4a& pos2,
  11.251 +	const LLVector2& tex2)
  11.252 +{
  11.253 +	LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] );
  11.254 +	LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] );
  11.255 +	LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] );
  11.256 +	
  11.257 +	LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] );
  11.258 +	LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] );
  11.259 +	LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] );
  11.260 +
  11.261 +	LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] );
  11.262 +	LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] );
  11.263 +	LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] );
  11.264 +	
  11.265 +	LLVector4a lhs, rhs;
  11.266 +
  11.267 +	LLVector4a r0; 
  11.268 +	lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2);
  11.269 +	r0.setCross3(lhs, rhs);
  11.270 +		
  11.271 +	LLVector4a r1;
  11.272 +	lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2);
  11.273 +	r1.setCross3(lhs, rhs);
  11.274 +
  11.275 +	LLVector4a r2;
  11.276 +	lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2);
  11.277 +	r2.setCross3(lhs, rhs);
  11.278 +
  11.279 +	if( r0[VX] && r1[VX] && r2[VX] )
  11.280 +	{
  11.281 +		binormal.set(
  11.282 +				-r0[VZ] / r0[VX],
  11.283 +				-r1[VZ] / r1[VX],
  11.284 +				-r2[VZ] / r2[VX]);
  11.285 +		// binormal.normVec();
  11.286 +	}
  11.287 +	else
  11.288 +	{
  11.289 +		binormal.set( 0, 1 , 0 );
  11.290 +	}
  11.291 +}
  11.292 +
  11.293  //adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
  11.294  void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
  11.295          const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
  11.296  {
  11.297 -    //LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
  11.298  	LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
  11.299  
  11.300      LLVector4a* tan2 = tan1 + vertexCount;
    12.1 --- a/indra/llprimitive/lltextureentry.cpp	Wed Sep 18 18:44:41 2013 -0400
    12.2 +++ b/indra/llprimitive/lltextureentry.cpp	Thu Sep 19 13:13:37 2013 -0400
    12.3 @@ -545,7 +545,7 @@
    12.4  		{
    12.5  			mMaterialUpdatePending = true;
    12.6  			mMaterialID = pMaterialID;
    12.7 -			return TEM_CHANGE_NONE;
    12.8 +			return TEM_CHANGE_TEXTURE;
    12.9  		}
   12.10  
   12.11  		mMaterialUpdatePending = false;
    13.1 --- a/indra/llrender/llgl.cpp	Wed Sep 18 18:44:41 2013 -0400
    13.2 +++ b/indra/llrender/llgl.cpp	Thu Sep 19 13:13:37 2013 -0400
    13.3 @@ -647,7 +647,8 @@
    13.4  		}
    13.5  #if LL_DARWIN
    13.6  		else if ((mGLRenderer.find("9400M") != std::string::npos)
    13.7 -			  || (mGLRenderer.find("9600M") != std::string::npos))
    13.8 +			  || (mGLRenderer.find("9600M") != std::string::npos)
    13.9 +			  || (mGLRenderer.find("9800M") != std::string::npos))
   13.10  		{
   13.11  			mIsMobileGF = TRUE;
   13.12  		}
   13.13 @@ -1155,7 +1156,7 @@
   13.14  	glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
   13.15  	glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
   13.16  	glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
   13.17 -
   13.18 +	
   13.19  #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
   13.20  	LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
   13.21  	if (mHasVertexBufferObject)
    14.1 --- a/indra/llrender/llglheaders.h	Wed Sep 18 18:44:41 2013 -0400
    14.2 +++ b/indra/llrender/llglheaders.h	Thu Sep 19 13:13:37 2013 -0400
    14.3 @@ -1009,12 +1009,7 @@
    14.4  }
    14.5  #endif
    14.6  
    14.7 -#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1070
    14.8  #include <OpenGL/gl.h>
    14.9 -#else
   14.10 -#include <AGL/gl.h>
   14.11 -#endif
   14.12 -
   14.13  
   14.14  #endif // LL_MESA / LL_WINDOWS / LL_DARWIN
   14.15  
    15.1 --- a/indra/llrender/llglslshader.cpp	Wed Sep 18 18:44:41 2013 -0400
    15.2 +++ b/indra/llrender/llglslshader.cpp	Thu Sep 19 13:13:37 2013 -0400
    15.3 @@ -374,6 +374,11 @@
    15.4  
    15.5  	// Create program
    15.6  	mProgramObject = glCreateProgramObjectARB();
    15.7 +
    15.8 +#if LL_DARWIN
    15.9 +    // work-around missing mix(vec3,vec3,bvec3)
   15.10 +    mDefines["OLD_SELECT"] = "1";
   15.11 +#endif
   15.12  	
   15.13  	//compile new source
   15.14  	vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
    16.1 --- a/indra/llrender/llrender.cpp	Wed Sep 18 18:44:41 2013 -0400
    16.2 +++ b/indra/llrender/llrender.cpp	Thu Sep 19 13:13:37 2013 -0400
    16.3 @@ -1849,35 +1849,36 @@
    16.4  			sUIVerts += mCount;
    16.5  		}
    16.6  		
    16.7 -		if (gDebugGL)
    16.8 +		//store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
    16.9 +		U32 count = mCount;
   16.10 +
   16.11 +		if (mMode == LLRender::QUADS && !sGLCoreProfile)
   16.12  		{
   16.13 -			if (mMode == LLRender::QUADS && !sGLCoreProfile)
   16.14 +			if (mCount%4 != 0)
   16.15  			{
   16.16 -				if (mCount%4 != 0)
   16.17 -				{
   16.18 -					llerrs << "Incomplete quad rendered." << llendl;
   16.19 -				}
   16.20 -			}
   16.21 -			
   16.22 -			if (mMode == LLRender::TRIANGLES)
   16.23 -			{
   16.24 -				if (mCount%3 != 0)
   16.25 -				{
   16.26 -					llerrs << "Incomplete triangle rendered." << llendl;
   16.27 -				}
   16.28 -			}
   16.29 -			
   16.30 -			if (mMode == LLRender::LINES)
   16.31 -			{
   16.32 -				if (mCount%2 != 0)
   16.33 -				{
   16.34 -					llerrs << "Incomplete line rendered." << llendl;
   16.35 -				}
   16.36 +				count -= (mCount % 4);
   16.37 +				llwarns << "Incomplete quad requested." << llendl;
   16.38  			}
   16.39  		}
   16.40  
   16.41 -		//store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
   16.42 -		U32 count = mCount;
   16.43 +		if (mMode == LLRender::TRIANGLES)
   16.44 +		{
   16.45 +			if (mCount%3 != 0)
   16.46 +			{
   16.47 +				count -= (mCount % 3);
   16.48 +				llwarns << "Incomplete triangle requested." << llendl;
   16.49 +			}
   16.50 +		}
   16.51 +
   16.52 +		if (mMode == LLRender::LINES)
   16.53 +		{
   16.54 +			if (mCount%2 != 0)
   16.55 +			{
   16.56 +				count -= (mCount % 2);
   16.57 +				llwarns << "Incomplete line requested." << llendl;
   16.58 +			}
   16.59 +		}
   16.60 +		
   16.61  		mCount = 0;
   16.62  
   16.63  		if (mBuffer->useVBOs() && !mBuffer->isLocked())
    17.1 --- a/indra/llrender/llrendertarget.cpp	Wed Sep 18 18:44:41 2013 -0400
    17.2 +++ b/indra/llrender/llrendertarget.cpp	Thu Sep 19 13:13:37 2013 -0400
    17.3 @@ -79,7 +79,7 @@
    17.4  	release();
    17.5  }
    17.6  
    17.7 -void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
    17.8 +void LLRenderTarget::resize(U32 resx, U32 resy)
    17.9  { 
   17.10  	//for accounting, get the number of pixels added/subtracted
   17.11  	S32 pix_diff = (resx*resy)-(mResX*mResY);
   17.12 @@ -87,10 +87,12 @@
   17.13  	mResX = resx;
   17.14  	mResY = resy;
   17.15  
   17.16 +	llassert(mInternalFormat.size() == mTex.size());
   17.17 +
   17.18  	for (U32 i = 0; i < mTex.size(); ++i)
   17.19  	{ //resize color attachments
   17.20  		gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
   17.21 -		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
   17.22 +		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, mInternalFormat[i], mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
   17.23  		sBytesAllocated += pix_diff*4;
   17.24  	}
   17.25  
   17.26 @@ -252,11 +254,14 @@
   17.27  	mTex.push_back(tex);
   17.28  	mInternalFormat.push_back(color_fmt);
   17.29  
   17.30 +#if !LL_DARWIN
   17.31  	if (gDebugGL)
   17.32  	{ //bind and unbind to validate target
   17.33  		bindTarget();
   17.34  		flush();
   17.35  	}
   17.36 +#endif
   17.37 +    
   17.38  
   17.39  	return true;
   17.40  }
   17.41 @@ -359,36 +364,56 @@
   17.42  
   17.43  		sBytesAllocated -= mResX*mResY*4;
   17.44  	}
   17.45 -	else if (mUseDepth && mFBO)
   17.46 -	{ //detach shared depth buffer
   17.47 +	else if (mFBO)
   17.48 +	{
   17.49  		glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
   17.50 -		if (mStencil)
   17.51 -		{ //attached as a renderbuffer
   17.52 -			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
   17.53 -			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
   17.54 -			mStencil = false;
   17.55 +
   17.56 +		if (mUseDepth)
   17.57 +		{ //detach shared depth buffer
   17.58 +			if (mStencil)
   17.59 +			{ //attached as a renderbuffer
   17.60 +				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
   17.61 +				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
   17.62 +				mStencil = false;
   17.63 +			}
   17.64 +			else
   17.65 +			{ //attached as a texture
   17.66 +				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
   17.67 +			}
   17.68 +			mUseDepth = false;
   17.69  		}
   17.70 -		else
   17.71 -		{ //attached as a texture
   17.72 -			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
   17.73 +	}
   17.74 +
   17.75 +	// Detach any extra color buffers (e.g. SRGB spec buffers)
   17.76 +	//
   17.77 +	if (mFBO && (mTex.size() > 1))
   17.78 +	{		
   17.79 +		S32 z;
   17.80 +		for (z = mTex.size() - 1; z >= 1; z--)
   17.81 +		{
   17.82 +			sBytesAllocated -= mResX*mResY*4;
   17.83 +			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0);
   17.84 +			stop_glerror();
   17.85 +			LLImageGL::deleteTextures(mUsage, mInternalFormat[z], 0, 1, &mTex[z], true);
   17.86  		}
   17.87 -		mUseDepth = false;
   17.88  	}
   17.89  
   17.90  	if (mFBO)
   17.91  	{
   17.92  		glDeleteFramebuffers(1, (GLuint *) &mFBO);
   17.93 +		stop_glerror();
   17.94  		mFBO = 0;
   17.95  	}
   17.96  
   17.97  	if (mTex.size() > 0)
   17.98  	{
   17.99 -		sBytesAllocated -= mResX*mResY*4*mTex.size();
  17.100 -		LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true);
  17.101 -		mTex.clear();
  17.102 -		mInternalFormat.clear();
  17.103 +		sBytesAllocated -= mResX*mResY*4;
  17.104 +		LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, 1, &mTex[0], true);
  17.105  	}
  17.106 -	
  17.107 +
  17.108 +	mTex.clear();
  17.109 +	mInternalFormat.clear();
  17.110 +
  17.111  	mResX = mResY = 0;
  17.112  
  17.113  	sBoundTarget = NULL;
  17.114 @@ -572,8 +597,10 @@
  17.115  {
  17.116  	if (!source.mFBO)
  17.117  	{
  17.118 -		llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
  17.119 +		llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
  17.120 +		return;
  17.121  	}
  17.122 +
  17.123  	{
  17.124  		GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
  17.125  
    18.1 --- a/indra/llrender/llrendertarget.h	Wed Sep 18 18:44:41 2013 -0400
    18.2 +++ b/indra/llrender/llrendertarget.h	Thu Sep 19 13:13:37 2013 -0400
    18.3 @@ -79,7 +79,7 @@
    18.4  	// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
    18.5  	// DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
    18.6  	// DO use for render targets that resize often and aren't likely to ruin someone's day if they break
    18.7 -	void resize(U32 resx, U32 resy, U32 color_fmt);
    18.8 +	void resize(U32 resx, U32 resy);
    18.9  
   18.10  	//add color buffer attachment
   18.11  	//limit of 4 color attachments per render target
    19.1 --- a/indra/llrender/llshadermgr.cpp	Wed Sep 18 18:44:41 2013 -0400
    19.2 +++ b/indra/llrender/llshadermgr.cpp	Thu Sep 19 13:13:37 2013 -0400
    19.3 @@ -1137,11 +1137,13 @@
    19.4  	mReservedUniforms.push_back("projectionMap");
    19.5  	
    19.6  	mReservedUniforms.push_back("global_gamma");
    19.7 -	mReservedUniforms.push_back("texture_gamma");
    19.8 -	
    19.9 +	mReservedUniforms.push_back("texture_gamma");	
   19.10 +
   19.11  	mReservedUniforms.push_back("specular_color");
   19.12  	mReservedUniforms.push_back("env_intensity");
   19.13  
   19.14 +	mReservedUniforms.push_back("display_gamma");
   19.15 +
   19.16  	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
   19.17  
   19.18  	std::set<std::string> dupe_check;
    20.1 --- a/indra/llrender/llshadermgr.h	Wed Sep 18 18:44:41 2013 -0400
    20.2 +++ b/indra/llrender/llshadermgr.h	Thu Sep 19 13:13:37 2013 -0400
    20.3 @@ -167,11 +167,13 @@
    20.4  		DEFERRED_PROJECTION,
    20.5  		
    20.6  		GLOBAL_GAMMA,
    20.7 -		TEXTURE_GAMMA,
    20.8 -		
    20.9 +		TEXTURE_GAMMA,		
   20.10 +
   20.11  		SPECULAR_COLOR,
   20.12  		ENVIRONMENT_INTENSITY,
   20.13  		
   20.14 +		DISPLAY_GAMMA,
   20.15 +
   20.16  		END_RESERVED_UNIFORMS
   20.17  	} eGLSLReservedUniforms;
   20.18  
    21.1 --- a/indra/llrender/llvertexbuffer.cpp	Wed Sep 18 18:44:41 2013 -0400
    21.2 +++ b/indra/llrender/llvertexbuffer.cpp	Thu Sep 19 13:13:37 2013 -0400
    21.3 @@ -753,10 +753,10 @@
    21.4  	U16* idx = ((U16*) getIndicesPointer())+indices_offset;
    21.5  
    21.6  	stop_glerror();
    21.7 -	LLGLSLShader::startProfile();
    21.8 -	glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, 
    21.9 +		LLGLSLShader::startProfile();
   21.10 +		glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, 
   21.11  		idx);
   21.12 -	LLGLSLShader::stopProfile(count, mode);
   21.13 +		LLGLSLShader::stopProfile(count, mode);
   21.14  	stop_glerror();
   21.15  
   21.16  	
   21.17 @@ -2236,10 +2236,41 @@
   21.18  					required_mask |= required;
   21.19  				}
   21.20  			}
   21.21 -
   21.22 +        
   21.23  			if ((data_mask & required_mask) != required_mask)
   21.24  			{
   21.25 -				llwarns << "Shader consumption mismatches data provision." << llendl;
   21.26 +				
   21.27 +				U32 unsatisfied_mask = (required_mask & ~data_mask);
   21.28 +				U32 i = 0;
   21.29 +
   21.30 +				while (i < TYPE_MAX)
   21.31 +				{
   21.32 +                    U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
   21.33 +					switch (unsatisfied_flag)
   21.34 +					{
   21.35 +						case MAP_VERTEX: llinfos << "Missing vert pos" << llendl; break;
   21.36 +						case MAP_NORMAL: llinfos << "Missing normals" << llendl; break;
   21.37 +						case MAP_TEXCOORD0: llinfos << "Missing TC 0" << llendl; break;
   21.38 +						case MAP_TEXCOORD1: llinfos << "Missing TC 1" << llendl; break;
   21.39 +						case MAP_TEXCOORD2: llinfos << "Missing TC 2" << llendl; break;
   21.40 +						case MAP_TEXCOORD3: llinfos << "Missing TC 3" << llendl; break;
   21.41 +						case MAP_COLOR: llinfos << "Missing vert color" << llendl; break;
   21.42 +						case MAP_EMISSIVE: llinfos << "Missing emissive" << llendl; break;
   21.43 +						case MAP_TANGENT: llinfos << "Missing tangent" << llendl; break;
   21.44 +						case MAP_WEIGHT: llinfos << "Missing weight" << llendl; break;
   21.45 +						case MAP_WEIGHT4: llinfos << "Missing weightx4" << llendl; break;
   21.46 +						case MAP_CLOTHWEIGHT: llinfos << "Missing clothweight" << llendl; break;
   21.47 +						case MAP_TEXTURE_INDEX: llinfos << "Missing tex index" << llendl; break;
   21.48 +						default: llinfos << "Missing who effin knows: " << unsatisfied_flag << llendl;
   21.49 +					}					
   21.50 +				}
   21.51 +
   21.52 +            if (unsatisfied_mask & (1 << TYPE_INDEX))
   21.53 +            {
   21.54 +               llinfos << "Missing indices" << llendl;
   21.55 +            }
   21.56 +
   21.57 +				llerrs << "Shader consumption mismatches data provision." << llendl;
   21.58  			}
   21.59  		}
   21.60  	}
    22.1 --- a/indra/llwindow/CMakeLists.txt	Wed Sep 18 18:44:41 2013 -0400
    22.2 +++ b/indra/llwindow/CMakeLists.txt	Thu Sep 19 13:13:37 2013 -0400
    22.3 @@ -109,11 +109,14 @@
    22.4      llkeyboardmacosx.cpp
    22.5      llwindowmacosx.cpp
    22.6      llwindowmacosx-objc.mm
    22.7 +    llopenglview-objc.mm
    22.8      )
    22.9    list(APPEND llwindow_HEADER_FILES
   22.10      llkeyboardmacosx.h
   22.11      llwindowmacosx.h
   22.12      llwindowmacosx-objc.h
   22.13 +    llopenglview-objc.h
   22.14 +    llappdelegate-objc.h
   22.15      )
   22.16  
   22.17    # We use a bunch of deprecated system APIs.
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/indra/llwindow/llappdelegate-objc.h	Thu Sep 19 13:13:37 2013 -0400
    23.3 @@ -0,0 +1,48 @@
    23.4 +/**
    23.5 + * @file llappdelegate-objc.h
    23.6 + * @brief Class interface for the Mac version's application delegate.
    23.7 + *
    23.8 + * $LicenseInfo:firstyear=2000&license=viewerlgpl$
    23.9 + * Second Life Viewer Source Code
   23.10 + * Copyright (C) 2010, Linden Research, Inc.
   23.11 + *
   23.12 + * This library is free software; you can redistribute it and/or
   23.13 + * modify it under the terms of the GNU Lesser General Public
   23.14 + * License as published by the Free Software Foundation;
   23.15 + * version 2.1 of the License only.
   23.16 + *
   23.17 + * This library is distributed in the hope that it will be useful,
   23.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   23.20 + * Lesser General Public License for more details.
   23.21 + *
   23.22 + * You should have received a copy of the GNU Lesser General Public
   23.23 + * License along with this library; if not, write to the Free Software
   23.24 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   23.25 + *
   23.26 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   23.27 + * $/LicenseInfo$
   23.28 + */
   23.29 +
   23.30 +#import <Cocoa/Cocoa.h>
   23.31 +#import "llopenglview-objc.h"
   23.32 +
   23.33 +@interface LLAppDelegate : NSObject <NSApplicationDelegate> {
   23.34 +	LLNSWindow *window;
   23.35 +	NSWindow *inputWindow;
   23.36 +	LLNonInlineTextView *inputView;
   23.37 +	NSTimer *frameTimer;
   23.38 +	NSString *currentInputLanguage;
   23.39 +}
   23.40 +
   23.41 +@property (assign) IBOutlet LLNSWindow *window;
   23.42 +@property (assign) IBOutlet NSWindow *inputWindow;
   23.43 +@property (assign) IBOutlet LLNonInlineTextView *inputView;
   23.44 +
   23.45 +@property (retain) NSString *currentInputLanguage;
   23.46 +
   23.47 +- (void) mainLoop;
   23.48 +- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent;
   23.49 +- (void) languageUpdated;
   23.50 +- (bool) romanScript;
   23.51 +@end
    24.1 --- a/indra/llwindow/llkeyboard.h	Wed Sep 18 18:44:41 2013 -0400
    24.2 +++ b/indra/llwindow/llkeyboard.h	Thu Sep 19 13:13:37 2013 -0400
    24.3 @@ -82,6 +82,11 @@
    24.4  
    24.5  	virtual BOOL	handleKeyUp(const U16 key, MASK mask) = 0;
    24.6  	virtual BOOL	handleKeyDown(const U16 key, MASK mask) = 0;
    24.7 +	
    24.8 +#ifdef LL_DARWIN
    24.9 +	// We only actually use this for OS X.
   24.10 +	virtual void	handleModifier(MASK mask) = 0;
   24.11 +#endif // LL_DARWIN
   24.12  
   24.13  	// Asynchronously poll the control, alt, and shift keys and set the
   24.14  	// appropriate internal key masks.
    25.1 --- a/indra/llwindow/llkeyboardheadless.cpp	Wed Sep 18 18:44:41 2013 -0400
    25.2 +++ b/indra/llwindow/llkeyboardheadless.cpp	Thu Sep 19 13:13:37 2013 -0400
    25.3 @@ -45,6 +45,13 @@
    25.4  MASK LLKeyboardHeadless::currentMask(BOOL for_mouse_event)
    25.5  { return MASK_NONE; }
    25.6  
    25.7 +#ifdef LL_DARWIN
    25.8 +void LLKeyboardHeadless::handleModifier(MASK mask)
    25.9 +{
   25.10 +	
   25.11 +}
   25.12 +#endif
   25.13 +
   25.14  void LLKeyboardHeadless::scanKeyboard()
   25.15  {
   25.16  	for (S32 key = 0; key < KEY_COUNT; key++)
    26.1 --- a/indra/llwindow/llkeyboardheadless.h	Wed Sep 18 18:44:41 2013 -0400
    26.2 +++ b/indra/llwindow/llkeyboardheadless.h	Thu Sep 19 13:13:37 2013 -0400
    26.3 @@ -40,6 +40,9 @@
    26.4  	/*virtual*/ void	resetMaskKeys();
    26.5  	/*virtual*/ MASK	currentMask(BOOL for_mouse_event);
    26.6  	/*virtual*/ void	scanKeyboard();
    26.7 +#ifdef LL_DARWIN
    26.8 +	/*virtual*/ void	handleModifier(MASK mask);
    26.9 +#endif
   26.10  };
   26.11  
   26.12  #endif
    27.1 --- a/indra/llwindow/llkeyboardmacosx.cpp	Wed Sep 18 18:44:41 2013 -0400
    27.2 +++ b/indra/llwindow/llkeyboardmacosx.cpp	Thu Sep 19 13:13:37 2013 -0400
    27.3 @@ -30,7 +30,7 @@
    27.4  #include "llkeyboardmacosx.h"
    27.5  #include "llwindowcallbacks.h"
    27.6  
    27.7 -#include <Carbon/Carbon.h>
    27.8 +#include "llwindowmacosx-objc.h"
    27.9  
   27.10  LLKeyboardMacOSX::LLKeyboardMacOSX()
   27.11  {
   27.12 @@ -162,23 +162,25 @@
   27.13  
   27.14  void LLKeyboardMacOSX::resetMaskKeys()
   27.15  {
   27.16 -	U32 mask = GetCurrentEventKeyModifiers();
   27.17 +	U32 mask = getModifiers();
   27.18  
   27.19  	// MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
   27.20  	//    It looks a bit suspicious, as it won't correct for keys that have been released.
   27.21  	//    Is this the way it's supposed to work?
   27.22 +	
   27.23 +	// We apply the modifier masks directly within getModifiers.  So check to see which masks we've applied.
   27.24  
   27.25 -	if(mask & shiftKey)
   27.26 +	if(mask & MAC_SHIFT_KEY)
   27.27  	{
   27.28  		mKeyLevel[KEY_SHIFT] = TRUE;
   27.29  	}
   27.30  
   27.31 -	if(mask & (controlKey))
   27.32 +	if(mask & MAC_CTRL_KEY)
   27.33  	{
   27.34  		mKeyLevel[KEY_CONTROL] = TRUE;
   27.35  	}
   27.36  
   27.37 -	if(mask & optionKey)
   27.38 +	if(mask & MAC_ALT_KEY)
   27.39  	{
   27.40  		mKeyLevel[KEY_ALT] = TRUE;
   27.41  	}
   27.42 @@ -196,22 +198,27 @@
   27.43  }
   27.44  */
   27.45  
   27.46 +void LLKeyboardMacOSX::handleModifier(MASK mask)
   27.47 +{
   27.48 +	updateModifiers(mask);
   27.49 +}
   27.50 +
   27.51  MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
   27.52  {
   27.53  	// translate the mask
   27.54  	MASK out_mask = 0;
   27.55  
   27.56 -	if(mask & shiftKey)
   27.57 +	if(mask & MAC_SHIFT_KEY)
   27.58  	{
   27.59  		out_mask |= MASK_SHIFT;
   27.60  	}
   27.61  
   27.62 -	if(mask & (controlKey | cmdKey))
   27.63 +	if(mask & (MAC_CTRL_KEY | MAC_CMD_KEY))
   27.64  	{
   27.65  		out_mask |= MASK_CONTROL;
   27.66  	}
   27.67  
   27.68 -	if(mask & optionKey)
   27.69 +	if(mask & MAC_ALT_KEY)
   27.70  	{
   27.71  		out_mask |= MASK_ALT;
   27.72  	}
   27.73 @@ -231,7 +238,7 @@
   27.74  	{
   27.75  		handled = handleTranslatedKeyDown(translated_key, translated_mask);
   27.76  	}
   27.77 -
   27.78 +	
   27.79  	return handled;
   27.80  }
   27.81  
   27.82 @@ -255,18 +262,18 @@
   27.83  MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
   27.84  {
   27.85  	MASK result = MASK_NONE;
   27.86 -	U32 mask = GetCurrentEventKeyModifiers();
   27.87 +	U32 mask = getModifiers();
   27.88  
   27.89 -	if (mask & shiftKey)			result |= MASK_SHIFT;
   27.90 -	if (mask & controlKey)			result |= MASK_CONTROL;
   27.91 -	if (mask & optionKey)			result |= MASK_ALT;
   27.92 +	if (mask & MAC_SHIFT_KEY)			result |= MASK_SHIFT;
   27.93 +	if (mask & MAC_CTRL_KEY)			result |= MASK_CONTROL;
   27.94 +	if (mask & MAC_ALT_KEY)				result |= MASK_ALT;
   27.95  
   27.96  	// For keyboard events, consider Command equivalent to Control
   27.97  	if (!for_mouse_event)
   27.98  	{
   27.99 -		if (mask & cmdKey) result |= MASK_CONTROL;
  27.100 +		if (mask & MAC_CMD_KEY) result |= MASK_CONTROL;
  27.101  	}
  27.102 -
  27.103 +	
  27.104  	return result;
  27.105  }
  27.106  
    28.1 --- a/indra/llwindow/llkeyboardmacosx.h	Wed Sep 18 18:44:41 2013 -0400
    28.2 +++ b/indra/llwindow/llkeyboardmacosx.h	Thu Sep 19 13:13:37 2013 -0400
    28.3 @@ -29,6 +29,15 @@
    28.4  
    28.5  #include "llkeyboard.h"
    28.6  
    28.7 +// These more or less mirror their equivalents in NSEvent.h.
    28.8 +enum EMacEventKeys {
    28.9 +	MAC_SHIFT_KEY = 1 << 17,
   28.10 +	MAC_CTRL_KEY = 1 << 18,
   28.11 +	MAC_ALT_KEY = 1 << 19,
   28.12 +	MAC_CMD_KEY = 1 << 20,
   28.13 +	MAC_FN_KEY = 1 << 23
   28.14 +};
   28.15 +
   28.16  class LLKeyboardMacOSX : public LLKeyboard
   28.17  {
   28.18  public:
   28.19 @@ -40,6 +49,7 @@
   28.20  	/*virtual*/ void	resetMaskKeys();
   28.21  	/*virtual*/ MASK	currentMask(BOOL for_mouse_event);
   28.22  	/*virtual*/ void	scanKeyboard();
   28.23 +	/*virtual*/ void	handleModifier(MASK mask);
   28.24  	
   28.25  protected:
   28.26  	MASK	updateModifiers(const U32 mask);
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/indra/llwindow/llopenglview-objc.h	Thu Sep 19 13:13:37 2013 -0400
    29.3 @@ -0,0 +1,110 @@
    29.4 +/**
    29.5 + * @file llopenglview-objc.h
    29.6 + * @brief Class interfaces for most of the Mac facing window functionality.
    29.7 + *
    29.8 + * $LicenseInfo:firstyear=2000&license=viewerlgpl$
    29.9 + * Second Life Viewer Source Code
   29.10 + * Copyright (C) 2010, Linden Research, Inc.
   29.11 + *
   29.12 + * This library is free software; you can redistribute it and/or
   29.13 + * modify it under the terms of the GNU Lesser General Public
   29.14 + * License as published by the Free Software Foundation;
   29.15 + * version 2.1 of the License only.
   29.16 + *
   29.17 + * This library is distributed in the hope that it will be useful,
   29.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   29.20 + * Lesser General Public License for more details.
   29.21 + *
   29.22 + * You should have received a copy of the GNU Lesser General Public
   29.23 + * License along with this library; if not, write to the Free Software
   29.24 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   29.25 + *
   29.26 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   29.27 + * $/LicenseInfo$
   29.28 + */
   29.29 +
   29.30 +#ifndef LLOpenGLView_H
   29.31 +#define LLOpenGLView_H
   29.32 +
   29.33 +#import <Cocoa/Cocoa.h>
   29.34 +#import <IOKit/IOKitLib.h>
   29.35 +#import <CoreFoundation/CFBase.h>
   29.36 +#import <CoreFoundation/CFNumber.h>
   29.37 +#include <string>
   29.38 +
   29.39 +@interface LLOpenGLView : NSOpenGLView <NSTextInputClient>
   29.40 +{
   29.41 +	std::string mLastDraggedUrl;
   29.42 +	unsigned int mModifiers;
   29.43 +	float mMousePos[2];
   29.44 +	bool mHasMarkedText;
   29.45 +	unsigned int mMarkedTextLength;
   29.46 +    bool mMarkedTextAllowed;
   29.47 +    bool mSimulatedRightClick;
   29.48 +}
   29.49 +- (id) initWithSamples:(NSUInteger)samples;
   29.50 +- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
   29.51 +- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
   29.52 +
   29.53 +- (void)commitCurrentPreedit;
   29.54 +
   29.55 +// rebuildContext
   29.56 +// Destroys and recreates a context with the view's internal format set via setPixelFormat;
   29.57 +// Use this in event of needing to rebuild a context for whatever reason, without needing to assign a new pixel format.
   29.58 +- (BOOL) rebuildContext;
   29.59 +
   29.60 +// rebuildContextWithFormat
   29.61 +// Destroys and recreates a context with the specified pixel format.
   29.62 +- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format;
   29.63 +
   29.64 +// These are mostly just for C++ <-> Obj-C interop.  We can manipulate the CGLContext from C++ without reprecussions.
   29.65 +- (CGLContextObj) getCGLContextObj;
   29.66 +- (CGLPixelFormatObj*)getCGLPixelFormatObj;
   29.67 +
   29.68 +- (unsigned long) getVramSize;
   29.69 +
   29.70 +- (void) allowMarkedTextInput:(bool)allowed;
   29.71 +
   29.72 +@end
   29.73 +
   29.74 +@interface LLUserInputWindow : NSPanel
   29.75 +
   29.76 +@end
   29.77 +
   29.78 +@interface LLNonInlineTextView : NSTextView
   29.79 +{
   29.80 +	LLOpenGLView *glview;
   29.81 +}
   29.82 +
   29.83 +- (void) setGLView:(LLOpenGLView*)view;
   29.84 +
   29.85 +@end
   29.86 +
   29.87 +@interface LLNSWindow : NSWindow
   29.88 +
   29.89 +- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view;
   29.90 +- (NSPoint)flipPoint:(NSPoint)aPoint;
   29.91 +
   29.92 +@end
   29.93 +
   29.94 +@interface NSScreen (PointConversion)
   29.95 +
   29.96 +/*
   29.97 + Returns the screen where the mouse resides
   29.98 + */
   29.99 ++ (NSScreen *)currentScreenForMouseLocation;
  29.100 +
  29.101 +/*
  29.102 + Allows you to convert a point from global coordinates to the current screen coordinates.
  29.103 + */
  29.104 +- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint;
  29.105 +
  29.106 +/*
  29.107 + Allows to flip the point coordinates, so y is 0 at the top instead of the bottom. x remains the same
  29.108 + */
  29.109 +- (NSPoint)flipPoint:(NSPoint)aPoint;
  29.110 +
  29.111 +@end
  29.112 +
  29.113 +#endif
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/indra/llwindow/llopenglview-objc.mm	Thu Sep 19 13:13:37 2013 -0400
    30.3 @@ -0,0 +1,686 @@
    30.4 +/**
    30.5 + * @file llopenglview-objc.mm
    30.6 + * @brief Class implementation for most of the Mac facing window functionality.
    30.7 + *
    30.8 + * $LicenseInfo:firstyear=2000&license=viewerlgpl$
    30.9 + * Second Life Viewer Source Code
   30.10 + * Copyright (C) 2010, Linden Research, Inc.
   30.11 + *
   30.12 + * This library is free software; you can redistribute it and/or
   30.13 + * modify it under the terms of the GNU Lesser General Public
   30.14 + * License as published by the Free Software Foundation;
   30.15 + * version 2.1 of the License only.
   30.16 + *
   30.17 + * This library is distributed in the hope that it will be useful,
   30.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   30.20 + * Lesser General Public License for more details.
   30.21 + *
   30.22 + * You should have received a copy of the GNU Lesser General Public
   30.23 + * License along with this library; if not, write to the Free Software
   30.24 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   30.25 + *
   30.26 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   30.27 + * $/LicenseInfo$
   30.28 + */
   30.29 +
   30.30 +#import "llopenglview-objc.h"
   30.31 +#include "llwindowmacosx-objc.h"
   30.32 +#import "llappdelegate-objc.h"
   30.33 +
   30.34 +@implementation NSScreen (PointConversion)
   30.35 +
   30.36 ++ (NSScreen *)currentScreenForMouseLocation
   30.37 +{
   30.38 +    NSPoint mouseLocation = [NSEvent mouseLocation];
   30.39 +    
   30.40 +    NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator];
   30.41 +    NSScreen *screen;
   30.42 +    while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(mouseLocation, screen.frame, NO))
   30.43 +        ;
   30.44 +    
   30.45 +    return screen;
   30.46 +}
   30.47 +
   30.48 +- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint
   30.49 +{
   30.50 +    float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x));
   30.51 +    float normalizedY = aPoint.y - self.frame.origin.y;
   30.52 +    
   30.53 +    return NSMakePoint(normalizedX, normalizedY);
   30.54 +}
   30.55 +
   30.56 +- (NSPoint)flipPoint:(NSPoint)aPoint
   30.57 +{
   30.58 +    return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
   30.59 +}
   30.60 +
   30.61 +@end
   30.62 +
   30.63 +attributedStringInfo getSegments(NSAttributedString *str)
   30.64 +{
   30.65 +	attributedStringInfo segments;
   30.66 +	segment_lengths seg_lengths;
   30.67 +	segment_standouts seg_standouts;
   30.68 +	NSRange effectiveRange;
   30.69 +	NSRange limitRange = NSMakeRange(0, [str length]);
   30.70 +    
   30.71 +	while (limitRange.length > 0) {
   30.72 +		NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange];
   30.73 +		limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
   30.74 +		
   30.75 +		if (effectiveRange.length <= 0)
   30.76 +		{
   30.77 +			effectiveRange.length = 1;
   30.78 +		}
   30.79 +		
   30.80 +		if ([attr integerValue] == 2)
   30.81 +		{
   30.82 +			seg_lengths.push_back(effectiveRange.length);
   30.83 +			seg_standouts.push_back(true);
   30.84 +		} else
   30.85 +		{
   30.86 +			seg_lengths.push_back(effectiveRange.length);
   30.87 +			seg_standouts.push_back(false);
   30.88 +		}
   30.89 +	}
   30.90 +	segments.seg_lengths = seg_lengths;
   30.91 +	segments.seg_standouts = seg_standouts;
   30.92 +	return segments;
   30.93 +}
   30.94 +
   30.95 +@implementation LLOpenGLView
   30.96 +
   30.97 +- (unsigned long)getVramSize
   30.98 +{
   30.99 +    CGLRendererInfoObj info = 0;
  30.100 +	GLint vram_bytes = 0;
  30.101 +    int num_renderers = 0;
  30.102 +    CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);
  30.103 +    if(0 == the_err)
  30.104 +    {
  30.105 +        CGLDescribeRenderer (info, 0, kCGLRPTextureMemory, &vram_bytes);
  30.106 +        CGLDestroyRendererInfo (info);
  30.107 +    }
  30.108 +    else
  30.109 +    {
  30.110 +        vram_bytes = (256 << 20);
  30.111 +    }
  30.112 +    
  30.113 +	return (unsigned long)vram_bytes / 1048576; // We need this in megabytes.
  30.114 +}
  30.115 +
  30.116 +- (void)viewDidMoveToWindow
  30.117 +{
  30.118 +	[[NSNotificationCenter defaultCenter] addObserver:self
  30.119 +											 selector:@selector(windowResized:) name:NSWindowDidResizeNotification
  30.120 +											   object:[self window]];
  30.121 +}
  30.122 +
  30.123 +- (void)windowResized:(NSNotification *)notification;
  30.124 +{
  30.125 +	NSSize size = [self frame].size;
  30.126 +	
  30.127 +	callResize(size.width, size.height);
  30.128 +}
  30.129 +
  30.130 +- (void)dealloc
  30.131 +{
  30.132 +	[[NSNotificationCenter defaultCenter] removeObserver:self];
  30.133 +	[super dealloc];
  30.134 +}
  30.135 +
  30.136 +- (id) init
  30.137 +{
  30.138 +	return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
  30.139 +}
  30.140 +
  30.141 +- (id) initWithSamples:(NSUInteger)samples
  30.142 +{
  30.143 +	return [self initWithFrame:[self bounds] withSamples:samples andVsync:TRUE];
  30.144 +}
  30.145 +
  30.146 +- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync
  30.147 +{
  30.148 +	return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync];
  30.149 +}
  30.150 +
  30.151 +- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
  30.152 +{
  30.153 +	[self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]];
  30.154 +	[self initWithFrame:frame];
  30.155 +	
  30.156 +	// Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.
  30.157 +	// Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat.
  30.158 +	// 10.7 and 10.8 don't really care if we're defining a profile or not.  If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons).
  30.159 +	NSOpenGLPixelFormatAttribute attrs[] = {
  30.160 +        NSOpenGLPFANoRecovery,
  30.161 +		NSOpenGLPFADoubleBuffer,
  30.162 +		NSOpenGLPFAClosestPolicy,
  30.163 +		NSOpenGLPFAAccelerated,
  30.164 +		NSOpenGLPFASampleBuffers, (samples > 0 ? 1 : 0),
  30.165 +		NSOpenGLPFASamples, samples,
  30.166 +		NSOpenGLPFAStencilSize, 8,
  30.167 +		NSOpenGLPFADepthSize, 24,
  30.168 +		NSOpenGLPFAAlphaSize, 8,
  30.169 +		NSOpenGLPFAColorSize, 24,
  30.170 +		0
  30.171 +    };
  30.172 +	
  30.173 +	NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease];
  30.174 +	
  30.175 +	if (pixelFormat == nil)
  30.176 +	{
  30.177 +		NSLog(@"Failed to create pixel format!", nil);
  30.178 +		return nil;
  30.179 +	}
  30.180 +	
  30.181 +	NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
  30.182 +	
  30.183 +	if (glContext == nil)
  30.184 +	{
  30.185 +		NSLog(@"Failed to create OpenGL context!", nil);
  30.186 +		return nil;
  30.187 +	}
  30.188 +	
  30.189 +	[self setPixelFormat:pixelFormat];
  30.190 +	
  30.191 +	[self setOpenGLContext:glContext];
  30.192 +	
  30.193 +	[glContext setView:self];
  30.194 +	
  30.195 +	[glContext makeCurrentContext];
  30.196 +	
  30.197 +	if (vsync)
  30.198 +	{
  30.199 +		[glContext setValues:(const GLint*)1 forParameter:NSOpenGLCPSwapInterval];
  30.200 +	} else {
  30.201 +		[glContext setValues:(const GLint*)0 forParameter:NSOpenGLCPSwapInterval];
  30.202 +	}
  30.203 +	
  30.204 +	return self;
  30.205 +}
  30.206 +
  30.207 +- (BOOL) rebuildContext
  30.208 +{
  30.209 +	return [self rebuildContextWithFormat:[self pixelFormat]];
  30.210 +}
  30.211 +
  30.212 +- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format
  30.213 +{
  30.214 +	NSOpenGLContext *ctx = [self openGLContext];
  30.215 +	
  30.216 +	[ctx clearDrawable];
  30.217 +	[ctx initWithFormat:format shareContext:nil];
  30.218 +	
  30.219 +	if (ctx == nil)
  30.220 +	{
  30.221 +		NSLog(@"Failed to create OpenGL context!", nil);
  30.222 +		return false;
  30.223 +	}
  30.224 +	
  30.225 +	[self setOpenGLContext:ctx];
  30.226 +	[ctx setView:self];
  30.227 +	[ctx makeCurrentContext];
  30.228 +	return true;
  30.229 +}
  30.230 +
  30.231 +- (CGLContextObj)getCGLContextObj
  30.232 +{
  30.233 +	NSOpenGLContext *ctx = [self openGLContext];
  30.234 +	return (CGLContextObj)[ctx CGLContextObj];
  30.235 +}
  30.236 +
  30.237 +- (CGLPixelFormatObj*)getCGLPixelFormatObj
  30.238 +{
  30.239 +	NSOpenGLPixelFormat *fmt = [self pixelFormat];
  30.240 +	return (CGLPixelFormatObj*)[fmt	CGLPixelFormatObj];
  30.241 +}
  30.242 +
  30.243 +// Various events can be intercepted by our view, thus not reaching our window.
  30.244 +// Intercept these events, and pass them to the window as needed. - Geenz
  30.245 +
  30.246 +- (void) mouseDown:(NSEvent *)theEvent
  30.247 +{
  30.248 +    // Apparently people still use this?
  30.249 +    if ([theEvent modifierFlags] & NSCommandKeyMask &&
  30.250 +        !([theEvent modifierFlags] & NSControlKeyMask) &&
  30.251 +        !([theEvent modifierFlags] & NSShiftKeyMask) &&
  30.252 +        !([theEvent modifierFlags] & NSAlternateKeyMask) &&
  30.253 +        !([theEvent modifierFlags] & NSAlphaShiftKeyMask) &&
  30.254 +        !([theEvent modifierFlags] & NSFunctionKeyMask) &&
  30.255 +        !([theEvent modifierFlags] & NSHelpKeyMask))
  30.256 +    {
  30.257 +        callRightMouseDown(mMousePos, mModifiers);
  30.258 +        mSimulatedRightClick = true;
  30.259 +    } else {
  30.260 +        if ([theEvent clickCount] >= 2)
  30.261 +        {
  30.262 +            callDoubleClick(mMousePos, mModifiers);
  30.263 +        } else if ([theEvent clickCount] == 1) {
  30.264 +            callLeftMouseDown(mMousePos, mModifiers);
  30.265 +        }
  30.266 +    }
  30.267 +}
  30.268 +
  30.269 +- (void) mouseUp:(NSEvent *)theEvent
  30.270 +{
  30.271 +    if (mSimulatedRightClick)
  30.272 +    {
  30.273 +        callRightMouseUp(mMousePos, mModifiers);
  30.274 +        mSimulatedRightClick = false;
  30.275 +    } else {
  30.276 +        callLeftMouseUp(mMousePos, mModifiers);
  30.277 +    }
  30.278 +}
  30.279 +
  30.280 +- (void) rightMouseDown:(NSEvent *)theEvent
  30.281 +{
  30.282 +	callRightMouseDown(mMousePos, mModifiers);
  30.283 +}
  30.284 +
  30.285 +- (void) rightMouseUp:(NSEvent *)theEvent
  30.286 +{
  30.287 +	callRightMouseUp(mMousePos, mModifiers);
  30.288 +}
  30.289 +
  30.290 +- (void)mouseMoved:(NSEvent *)theEvent
  30.291 +{
  30.292 +	float mouseDeltas[2] = {
  30.293 +		[theEvent deltaX],
  30.294 +		[theEvent deltaY]
  30.295 +	};
  30.296 +	
  30.297 +	callDeltaUpdate(mouseDeltas, 0);
  30.298 +	
  30.299 +	NSPoint mPoint = [theEvent locationInWindow];
  30.300 +	mMousePos[0] = mPoint.x;
  30.301 +	mMousePos[1] = mPoint.y;
  30.302 +	callMouseMoved(mMousePos, 0);
  30.303 +}
  30.304 +
  30.305 +// NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged.
  30.306 +// Use mouseDragged for situations like this to trigger our movement callback instead.
  30.307 +
  30.308 +- (void) mouseDragged:(NSEvent *)theEvent
  30.309 +{
  30.310 +	// Trust the deltas supplied by NSEvent.
  30.311 +	// The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
  30.312 +	// NSEvent isn't obsolete, and provides us with the correct deltas.
  30.313 +	float mouseDeltas[2] = {
  30.314 +		[theEvent deltaX],
  30.315 +		[theEvent deltaY]
  30.316 +	};
  30.317 +	
  30.318 +	callDeltaUpdate(mouseDeltas, 0);
  30.319 +	
  30.320 +	NSPoint mPoint = [theEvent locationInWindow];
  30.321 +	mMousePos[0] = mPoint.x;
  30.322 +	mMousePos[1] = mPoint.y;
  30.323 +	callMouseMoved(mMousePos, 0);
  30.324 +}
  30.325 +
  30.326 +- (void) otherMouseDown:(NSEvent *)theEvent
  30.327 +{
  30.328 +	callMiddleMouseDown(mMousePos, mModifiers);
  30.329 +}
  30.330 +
  30.331 +- (void) otherMouseUp:(NSEvent *)theEvent
  30.332 +{
  30.333 +	callMiddleMouseUp(mMousePos, mModifiers);
  30.334 +}
  30.335 +
  30.336 +- (void) otherMouseDragged:(NSEvent *)theEvent
  30.337 +{
  30.338 +	
  30.339 +}
  30.340 +
  30.341 +- (void) scrollWheel:(NSEvent *)theEvent
  30.342 +{
  30.343 +	callScrollMoved(-[theEvent deltaY]);
  30.344 +}
  30.345 +
  30.346 +- (void) mouseExited:(NSEvent *)theEvent
  30.347 +{
  30.348 +	callMouseExit();
  30.349 +}
  30.350 +
  30.351 +- (void) keyUp:(NSEvent *)theEvent
  30.352 +{
  30.353 +	callKeyUp([theEvent keyCode], mModifiers);
  30.354 +}
  30.355 +
  30.356 +- (void) keyDown:(NSEvent *)theEvent
  30.357 +{
  30.358 +    uint keycode = [theEvent keyCode];
  30.359 +    bool acceptsText = mHasMarkedText ? false : callKeyDown(keycode, mModifiers);
  30.360 +    if (acceptsText &&
  30.361 +        !mMarkedTextAllowed &&
  30.362 +        ![(LLAppDelegate*)[NSApp delegate] romanScript] &&
  30.363 +        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter &&
  30.364 +        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter &&
  30.365 +        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDownArrowFunctionKey &&
  30.366 +        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSUpArrowFunctionKey &&
  30.367 +        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSLeftArrowFunctionKey &&
  30.368 +        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSRightArrowFunctionKey)
  30.369 +    {
  30.370 +        [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
  30.371 +    } else
  30.372 +    {
  30.373 +        [[self inputContext] handleEvent:theEvent];
  30.374 +    }
  30.375 +    
  30.376 +    if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSCarriageReturnCharacter ||
  30.377 +        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSEnterCharacter)
  30.378 +    {
  30.379 +        // callKeyDown won't return the value we expect for enter or return.  Handle them as a separate case.
  30.380 +        [[self inputContext] handleEvent:theEvent];
  30.381 +    }
  30.382 +    
  30.383 +    // OS X intentionally does not send us key-up information on cmd-key combinations.
  30.384 +    // This behaviour is not a bug, and only applies to cmd-combinations (no others).
  30.385 +    // Since SL assumes we receive those, we fake it here.
  30.386 +    if (mModifiers & NSCommandKeyMask && !mHasMarkedText)
  30.387 +    {
  30.388 +        callKeyUp([theEvent keyCode], mModifiers);
  30.389 +    }
  30.390 +}
  30.391 +
  30.392 +- (void)flagsChanged:(NSEvent *)theEvent {
  30.393 +	mModifiers = [theEvent modifierFlags];
  30.394 +	callModifier([theEvent modifierFlags]);
  30.395 +}
  30.396 +
  30.397 +- (BOOL) acceptsFirstResponder
  30.398 +{
  30.399 +	return YES;
  30.400 +}
  30.401 +
  30.402 +- (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender
  30.403 +{
  30.404 +	NSPasteboard *pboard;
  30.405 +    NSDragOperation sourceDragMask;
  30.406 +	
  30.407 +	sourceDragMask = [sender draggingSourceOperationMask];
  30.408 +	
  30.409 +	pboard = [sender draggingPasteboard];
  30.410 +	
  30.411 +	if ([[pboard types] containsObject:NSURLPboardType])
  30.412 +	{
  30.413 +		if (sourceDragMask & NSDragOperationLink) {
  30.414 +			NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0];
  30.415 +			mLastDraggedUrl = [[fileUrl absoluteString] UTF8String];
  30.416 +            return NSDragOperationLink;
  30.417 +        }
  30.418 +	}
  30.419 +	return NSDragOperationNone;
  30.420 +}
  30.421 +
  30.422 +- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
  30.423 +{
  30.424 +	callHandleDragUpdated(mLastDraggedUrl);
  30.425 +	
  30.426 +	return NSDragOperationLink;
  30.427 +}
  30.428 +
  30.429 +- (void) draggingExited:(id<NSDraggingInfo>)sender
  30.430 +{
  30.431 +	callHandleDragExited(mLastDraggedUrl);
  30.432 +}
  30.433 +
  30.434 +- (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender
  30.435 +{
  30.436 +	return YES;
  30.437 +}
  30.438 +
  30.439 +- (BOOL) performDragOperation:(id<NSDraggingInfo>)sender
  30.440 +{
  30.441 +	callHandleDragDropped(mLastDraggedUrl);
  30.442 +	return true;
  30.443 +}
  30.444 +
  30.445 +- (BOOL)hasMarkedText
  30.446 +{
  30.447 +	return mHasMarkedText;
  30.448 +}
  30.449 +
  30.450 +- (NSRange)markedRange
  30.451 +{
  30.452 +	int range[2];
  30.453 +	getPreeditMarkedRange(&range[0], &range[1]);
  30.454 +	return NSMakeRange(range[0], range[1]);
  30.455 +}
  30.456 +
  30.457 +- (NSRange)selectedRange
  30.458 +{
  30.459 +	int range[2];
  30.460 +	getPreeditSelectionRange(&range[0], &range[1]);
  30.461 +	return NSMakeRange(range[0], range[1]);
  30.462 +}
  30.463 +
  30.464 +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
  30.465 +{
  30.466 +    if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
  30.467 +    {
  30.468 +        if (mMarkedTextAllowed)
  30.469 +        {
  30.470 +            unsigned int selected[2] = {
  30.471 +                selectedRange.location,
  30.472 +                selectedRange.length
  30.473 +            };
  30.474 +            
  30.475 +            unsigned int replacement[2] = {
  30.476 +                replacementRange.location,
  30.477 +                replacementRange.length
  30.478 +            };
  30.479 +            
  30.480 +            unichar text[[aString length]];
  30.481 +            [[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])];
  30.482 +            attributedStringInfo segments = getSegments((NSAttributedString *)aString);
  30.483 +            setMarkedText(text, selected, replacement, [aString length], segments);
  30.484 +            mHasMarkedText = TRUE;
  30.485 +            mMarkedTextLength = [aString length];
  30.486 +        } else {
  30.487 +            if (mHasMarkedText)
  30.488 +            {
  30.489 +                [self unmarkText];
  30.490 +            }
  30.491 +        }
  30.492 +    }
  30.493 +}
  30.494 +
  30.495 +- (void)commitCurrentPreedit
  30.496 +{
  30.497 +    if (mHasMarkedText)
  30.498 +    {
  30.499 +        if ([[self inputContext] respondsToSelector:@selector(commitEditing)])
  30.500 +        {
  30.501 +            [[self inputContext] commitEditing];
  30.502 +        }
  30.503 +    }
  30.504 +}
  30.505 +
  30.506 +- (void)unmarkText
  30.507 +{
  30.508 +	[[self inputContext] discardMarkedText];
  30.509 +	resetPreedit();
  30.510 +	mHasMarkedText = FALSE;
  30.511 +}
  30.512 +
  30.513 +// We don't support attributed strings.
  30.514 +- (NSArray *)validAttributesForMarkedText
  30.515 +{
  30.516 +	return [NSArray array];
  30.517 +}
  30.518 +
  30.519 +// See above.
  30.520 +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
  30.521 +{
  30.522 +	return nil;
  30.523 +}
  30.524 +
  30.525 +- (void)insertText:(id)insertString
  30.526 +{
  30.527 +    if (insertString != nil)
  30.528 +    {
  30.529 +        [self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
  30.530 +    }
  30.531 +}
  30.532 +
  30.533 +- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
  30.534 +{
  30.535 +	if (!mHasMarkedText)
  30.536 +	{
  30.537 +		for (NSInteger i = 0; i < [aString length]; i++)
  30.538 +		{
  30.539 +			callUnicodeCallback([aString characterAtIndex:i], mModifiers);
  30.540 +		}
  30.541 +	} else {
  30.542 +        resetPreedit();
  30.543 +		// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
  30.544 +		// But just in case...
  30.545 +		
  30.546 +		for (NSInteger i = 0; i < [aString length]; i++)
  30.547 +		{
  30.548 +			handleUnicodeCharacter([aString characterAtIndex:i]);
  30.549 +		}
  30.550 +		mHasMarkedText = FALSE;
  30.551 +	}
  30.552 +}
  30.553 +
  30.554 +- (void) insertNewline:(id)sender
  30.555 +{
  30.556 +	if (!(mModifiers & NSCommandKeyMask) &&
  30.557 +		!(mModifiers & NSShiftKeyMask) &&
  30.558 +		!(mModifiers & NSAlternateKeyMask))
  30.559 +	{
  30.560 +		callUnicodeCallback(13, 0);
  30.561 +	} else {
  30.562 +		callUnicodeCallback(13, mModifiers);
  30.563 +	}
  30.564 +}
  30.565 +
  30.566 +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
  30.567 +{
  30.568 +	return NSNotFound;
  30.569 +}
  30.570 +
  30.571 +- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
  30.572 +{
  30.573 +	float pos[4] = {0, 0, 0, 0};
  30.574 +	getPreeditLocation(pos, mMarkedTextLength);
  30.575 +	return NSMakeRect(pos[0], pos[1], pos[2], pos[3]);
  30.576 +}
  30.577 +
  30.578 +- (void)doCommandBySelector:(SEL)aSelector
  30.579 +{
  30.580 +	if (aSelector == @selector(insertNewline:))
  30.581 +	{
  30.582 +		[self insertNewline:self];
  30.583 +	}
  30.584 +}
  30.585 +
  30.586 +- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex
  30.587 +{
  30.588 +	return NO;
  30.589 +}
  30.590 +
  30.591 +- (void) allowMarkedTextInput:(bool)allowed
  30.592 +{
  30.593 +    mMarkedTextAllowed = allowed;
  30.594 +}
  30.595 +
  30.596 +@end
  30.597 +
  30.598 +@implementation LLUserInputWindow
  30.599 +
  30.600 +- (void) close
  30.601 +{
  30.602 +    [self orderOut:self];
  30.603 +}
  30.604 +
  30.605 +@end
  30.606 +
  30.607 +@implementation LLNonInlineTextView
  30.608 +
  30.609 +- (void) setGLView:(LLOpenGLView *)view
  30.610 +{
  30.611 +	glview = view;
  30.612 +}
  30.613 +
  30.614 +- (void) insertText:(id)insertString
  30.615 +{
  30.616 +	[[self inputContext] discardMarkedText];
  30.617 +    [self setString:@""];
  30.618 +    [_window orderOut:_window];
  30.619 +	[self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
  30.620 +}
  30.621 +
  30.622 +- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
  30.623 +{
  30.624 +	[glview insertText:aString replacementRange:replacementRange];
  30.625 +}
  30.626 +
  30.627 +- (void) insertNewline:(id)sender
  30.628 +{
  30.629 +	[[self textStorage] setValue:@""];
  30.630 +	[[self inputContext] discardMarkedText];
  30.631 +    [self setString:@""];
  30.632 +}
  30.633 +
  30.634 +- (void)doCommandBySelector:(SEL)aSelector
  30.635 +{
  30.636 +	if (aSelector == @selector(insertNewline:))
  30.637 +	{
  30.638 +		[self insertNewline:self];
  30.639 +	}
  30.640 +}
  30.641 +
  30.642 +@end
  30.643 +
  30.644 +@implementation LLNSWindow
  30.645 +
  30.646 +- (id) init
  30.647 +{
  30.648 +	return self;
  30.649 +}
  30.650 +
  30.651 +- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
  30.652 +{
  30.653 +	NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
  30.654 +	if(currentScreen)
  30.655 +	{
  30.656 +		NSPoint windowPoint = [view convertPoint:point toView:nil];
  30.657 +		NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint];
  30.658 +		NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint];
  30.659 +		flippedScreenPoint.y += [currentScreen frame].origin.y;
  30.660 +		
  30.661 +		return flippedScreenPoint;
  30.662 +	}
  30.663 +	
  30.664 +	return NSZeroPoint;
  30.665 +}
  30.666 +
  30.667 +- (NSPoint)flipPoint:(NSPoint)aPoint
  30.668 +{
  30.669 +    return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
  30.670 +}
  30.671 +
  30.672 +- (BOOL) becomeFirstResponder
  30.673 +{
  30.674 +	callFocus();
  30.675 +	return true;
  30.676 +}
  30.677 +
  30.678 +- (BOOL) resignFirstResponder
  30.679 +{
  30.680 +	callFocusLost();
  30.681 +	return true;
  30.682 +}
  30.683 +
  30.684 +- (void) close
  30.685 +{
  30.686 +	callQuitHandler();
  30.687 +}
  30.688 +
  30.689 +@end
    31.1 --- a/indra/llwindow/llwindowmacosx-objc.h	Wed Sep 18 18:44:41 2013 -0400
    31.2 +++ b/indra/llwindow/llwindowmacosx-objc.h	Thu Sep 19 13:13:37 2013 -0400
    31.3 @@ -25,13 +25,121 @@
    31.4   * $/LicenseInfo$
    31.5   */
    31.6  
    31.7 +#include <map>
    31.8 +#include <vector>
    31.9 +
   31.10 +typedef std::vector<std::pair<int, bool> > segment_t;
   31.11 +
   31.12 +typedef std::vector<int> segment_lengths;
   31.13 +typedef std::vector<int> segment_standouts;
   31.14 +
   31.15 +struct attributedStringInfo {
   31.16 +	segment_lengths seg_lengths;
   31.17 +	segment_standouts seg_standouts;
   31.18 +};
   31.19  
   31.20  // This will actually hold an NSCursor*, but that type is only available in objective C.
   31.21  typedef void *CursorRef;
   31.22 +typedef void *NSWindowRef;
   31.23 +typedef void *GLViewRef;
   31.24 +
   31.25 +// These are defined in llappviewermacosx.cpp.
   31.26 +bool initViewer();
   31.27 +void handleQuit();
   31.28 +bool runMainLoop();
   31.29 +void initMainLoop();
   31.30 +void cleanupViewer();
   31.31  
   31.32  /* Defined in llwindowmacosx-objc.mm: */
   31.33 +int createNSApp(int argc, const char **argv);
   31.34  void setupCocoa();
   31.35 +bool pasteBoardAvailable();
   31.36 +bool copyToPBoard(const unsigned short *str, unsigned int len);
   31.37 +const unsigned short *copyFromPBoard();
   31.38  CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
   31.39 -OSErr releaseImageCursor(CursorRef ref);
   31.40 -OSErr setImageCursor(CursorRef ref);
   31.41 +short releaseImageCursor(CursorRef ref);
   31.42 +short setImageCursor(CursorRef ref);
   31.43 +void setArrowCursor();
   31.44 +void setIBeamCursor();
   31.45 +void setPointingHandCursor();
   31.46 +void setCopyCursor();
   31.47 +void setCrossCursor();
   31.48 +void setNotAllowedCursor();
   31.49 +void hideNSCursor();
   31.50 +void showNSCursor();
   31.51 +void hideNSCursorTillMove(bool hide);
   31.52 +void requestUserAttention();
   31.53 +long showAlert(std::string title, std::string text, int type);
   31.54  
   31.55 +NSWindowRef createNSWindow(int x, int y, int width, int height);
   31.56 +
   31.57 +#include <OpenGL/OpenGL.h>
   31.58 +GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync);
   31.59 +void glSwapBuffers(void* context);
   31.60 +CGLContextObj getCGLContextObj(GLViewRef view);
   31.61 +unsigned long getVramSize(GLViewRef view);
   31.62 +void getContentViewBounds(NSWindowRef window, float* bounds);
   31.63 +void getWindowSize(NSWindowRef window, float* size);
   31.64 +void setWindowSize(NSWindowRef window, int width, int height);
   31.65 +void getCursorPos(NSWindowRef window, float* pos);
   31.66 +void makeWindowOrderFront(NSWindowRef window);
   31.67 +void convertScreenToWindow(NSWindowRef window, float *coord);
   31.68 +void convertWindowToScreen(NSWindowRef window, float *coord);
   31.69 +void convertScreenToView(NSWindowRef window, float *coord);
   31.70 +void convertRectToScreen(NSWindowRef window, float *coord);
   31.71 +void convertRectFromScreen(NSWindowRef window, float *coord);
   31.72 +void setWindowPos(NSWindowRef window, float* pos);
   31.73 +void closeWindow(NSWindowRef window);
   31.74 +void removeGLView(GLViewRef view);
   31.75 +void makeFirstResponder(NSWindowRef window, GLViewRef view);
   31.76 +void setupInputWindow(NSWindowRef window, GLViewRef view);
   31.77 +
   31.78 +// These are all implemented in llwindowmacosx.cpp.
   31.79 +// This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
   31.80 +bool callKeyUp(unsigned short key, unsigned int mask);
   31.81 +bool callKeyDown(unsigned short key, unsigned int mask);
   31.82 +void callResetKeys();
   31.83 +bool callUnicodeCallback(wchar_t character, unsigned int mask);
   31.84 +void callRightMouseDown(float *pos, unsigned int mask);
   31.85 +void callRightMouseUp(float *pos, unsigned int mask);
   31.86 +void callLeftMouseDown(float *pos, unsigned int mask);
   31.87 +void callLeftMouseUp(float *pos, unsigned int mask);
   31.88 +void callDoubleClick(float *pos, unsigned int mask);
   31.89 +void callResize(unsigned int width, unsigned int height);
   31.90 +void callMouseMoved(float *pos, unsigned int mask);
   31.91 +void callScrollMoved(float delta);
   31.92 +void callMouseExit();
   31.93 +void callWindowFocus();
   31.94 +void callWindowUnfocus();
   31.95 +void callDeltaUpdate(float *delta, unsigned int mask);
   31.96 +void callMiddleMouseDown(float *pos, unsigned int mask);
   31.97 +void callMiddleMouseUp(float *pos, unsigned int mask);
   31.98 +void callFocus();
   31.99 +void callFocusLost();
  31.100 +void callModifier(unsigned int mask);
  31.101 +void callQuitHandler();
  31.102 +void commitCurrentPreedit(GLViewRef glView);
  31.103 +
  31.104 +#include <string>
  31.105 +void callHandleDragEntered(std::string url);
  31.106 +void callHandleDragExited(std::string url);
  31.107 +void callHandleDragUpdated(std::string url);
  31.108 +void callHandleDragDropped(std::string url);
  31.109 +
  31.110 +// LLPreeditor C bindings.
  31.111 +std::basic_string<wchar_t> getPreeditString();
  31.112 +void getPreeditSelectionRange(int *position, int *length);
  31.113 +void getPreeditMarkedRange(int *position, int *length);
  31.114 +bool handleUnicodeCharacter(wchar_t c);
  31.115 +void updatePreeditor(unsigned short *str);
  31.116 +void setPreeditMarkedRange(int position, int length);
  31.117 +void resetPreedit();
  31.118 +int wstring_length(const std::basic_string<wchar_t> & wstr, const int woffset, const int utf16_length, int *unaligned);
  31.119 +void setMarkedText(unsigned short *text, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments);
  31.120 +void getPreeditLocation(float *location, unsigned int length);
  31.121 +void allowDirectMarkedTextInput(bool allow, GLViewRef glView);
  31.122 +
  31.123 +NSWindowRef getMainAppWindow();
  31.124 +GLViewRef getGLView();
  31.125 +
  31.126 +unsigned int getModifiers();
    32.1 --- a/indra/llwindow/llwindowmacosx-objc.mm	Wed Sep 18 18:44:41 2013 -0400
    32.2 +++ b/indra/llwindow/llwindowmacosx-objc.mm	Thu Sep 19 13:13:37 2013 -0400
    32.3 @@ -1,4 +1,4 @@
    32.4 -/** 
    32.5 +/**
    32.6   * @file llwindowmacosx-objc.mm
    32.7   * @brief Definition of functions shared between llwindowmacosx.cpp
    32.8   * and llwindowmacosx-objc.mm.
    32.9 @@ -6,26 +6,30 @@
   32.10   * $LicenseInfo:firstyear=2006&license=viewerlgpl$
   32.11   * Second Life Viewer Source Code
   32.12   * Copyright (C) 2010, Linden Research, Inc.
   32.13 - * 
   32.14 + *
   32.15   * This library is free software; you can redistribute it and/or
   32.16   * modify it under the terms of the GNU Lesser General Public
   32.17   * License as published by the Free Software Foundation;
   32.18   * version 2.1 of the License only.
   32.19 - * 
   32.20 + *
   32.21   * This library is distributed in the hope that it will be useful,
   32.22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   32.24   * Lesser General Public License for more details.
   32.25 - * 
   32.26 + *
   32.27   * You should have received a copy of the GNU Lesser General Public
   32.28   * License along with this library; if not, write to the Free Software
   32.29   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   32.30 - * 
   32.31 + *
   32.32   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   32.33   * $/LicenseInfo$
   32.34   */
   32.35  
   32.36  #include <AppKit/AppKit.h>
   32.37 +#include <Cocoa/Cocoa.h>
   32.38 +#include "llopenglview-objc.h"
   32.39 +#include "llwindowmacosx-objc.h"
   32.40 +#include "llappdelegate-objc.h"
   32.41  
   32.42  /*
   32.43   * These functions are broken out into a separate file because the
   32.44 @@ -34,7 +38,10 @@
   32.45   * linden headers with any objective-C++ source.
   32.46   */
   32.47  
   32.48 -#include "llwindowmacosx-objc.h"
   32.49 +int createNSApp(int argc, const char *argv[])
   32.50 +{
   32.51 +	return NSApplicationMain(argc, argv);
   32.52 +}
   32.53  
   32.54  void setupCocoa()
   32.55  {
   32.56 @@ -45,44 +52,122 @@
   32.57  		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   32.58  		
   32.59  		// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
   32.60 -		// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' 
   32.61 -		// when init'ing the Cocoa App window.		
   32.62 +		// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
   32.63 +		// when init'ing the Cocoa App window.
   32.64  		[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
   32.65  		
   32.66 -		// This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
   32.67 -		//   http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
   32.68 -		
   32.69 -		//	Needed for Carbon based applications which call into Cocoa
   32.70 -		NSApplicationLoad();
   32.71 -
   32.72 -		//	Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
   32.73 -		[[[NSWindow alloc] init] release];
   32.74 -
   32.75  		[pool release];
   32.76  		
   32.77  		inited = true;
   32.78  	}
   32.79  }
   32.80  
   32.81 +bool copyToPBoard(const unsigned short *str, unsigned int len)
   32.82 +{
   32.83 +	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
   32.84 +	NSPasteboard *pboard = [NSPasteboard generalPasteboard];
   32.85 +	[pboard clearContents];
   32.86 +	
   32.87 +	NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil];
   32.88 +	[pool release];
   32.89 +	return [pboard writeObjects:contentsToPaste];
   32.90 +}
   32.91 +
   32.92 +bool pasteBoardAvailable()
   32.93 +{
   32.94 +	NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
   32.95 +	return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
   32.96 +}
   32.97 +
   32.98 +const unsigned short *copyFromPBoard()
   32.99 +{
  32.100 +	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
  32.101 +	NSPasteboard *pboard = [NSPasteboard generalPasteboard];
  32.102 +	NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
  32.103 +	NSString *str = NULL;
  32.104 +	BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
  32.105 +	if (ok)
  32.106 +	{
  32.107 +		NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
  32.108 +		str = [objToPaste objectAtIndex:0];
  32.109 +	}
  32.110 +	unichar* temp = (unichar*)calloc([str length], sizeof(unichar));
  32.111 +	[str getCharacters:temp];
  32.112 +	[pool release];
  32.113 +	return temp;
  32.114 +}
  32.115 +
  32.116  CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
  32.117  {
  32.118  	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  32.119 -
  32.120 +	
  32.121  	// extra retain on the NSCursor since we want it to live for the lifetime of the app.
  32.122  	NSCursor *cursor =
  32.123 -		[[[NSCursor alloc] 
  32.124 -				initWithImage:
  32.125 -					[[[NSImage alloc] initWithContentsOfFile:
  32.126 -						[NSString stringWithFormat:@"%s", fullpath]
  32.127 -					]autorelease] 
  32.128 -				hotSpot:NSMakePoint(hotspotX, hotspotY)
  32.129 -		]retain];	
  32.130 -		
  32.131 +	[[[NSCursor alloc]
  32.132 +	  initWithImage:
  32.133 +	  [[[NSImage alloc] initWithContentsOfFile:
  32.134 +		[NSString stringWithFormat:@"%s", fullpath]
  32.135 +		]autorelease]
  32.136 +	  hotSpot:NSMakePoint(hotspotX, hotspotY)
  32.137 +	  ]retain];
  32.138 +	
  32.139  	[pool release];
  32.140  	
  32.141  	return (CursorRef)cursor;
  32.142  }
  32.143  
  32.144 +void setArrowCursor()
  32.145 +{
  32.146 +	NSCursor *cursor = [NSCursor arrowCursor];
  32.147 +	[NSCursor unhide];
  32.148 +	[cursor set];
  32.149 +}
  32.150 +
  32.151 +void setIBeamCursor()
  32.152 +{
  32.153 +	NSCursor *cursor = [NSCursor IBeamCursor];
  32.154 +	[cursor set];
  32.155 +}
  32.156 +
  32.157 +void setPointingHandCursor()
  32.158 +{
  32.159 +	NSCursor *cursor = [NSCursor pointingHandCursor];
  32.160 +	[cursor set];
  32.161 +}
  32.162 +
  32.163 +void setCopyCursor()
  32.164 +{
  32.165 +	NSCursor *cursor = [NSCursor dragCopyCursor];
  32.166 +	[cursor set];
  32.167 +}
  32.168 +
  32.169 +void setCrossCursor()
  32.170 +{
  32.171 +	NSCursor *cursor = [NSCursor crosshairCursor];
  32.172 +	[cursor set];
  32.173 +}
  32.174 +
  32.175 +void setNotAllowedCursor()
  32.176 +{
  32.177 +	NSCursor *cursor = [NSCursor operationNotAllowedCursor];
  32.178 +	[cursor set];
  32.179 +}
  32.180 +
  32.181 +void hideNSCursor()
  32.182 +{
  32.183 +	[NSCursor hide];
  32.184 +}
  32.185 +
  32.186 +void showNSCursor()
  32.187 +{
  32.188 +	[NSCursor unhide];
  32.189 +}
  32.190 +
  32.191 +void hideNSCursorTillMove(bool hide)
  32.192 +{
  32.193 +	[NSCursor setHiddenUntilMouseMoves:hide];
  32.194 +}
  32.195 +
  32.196  // This is currently unused, since we want all our cursors to persist for the life of the app, but I've included it for completeness.
  32.197  OSErr releaseImageCursor(CursorRef ref)
  32.198  {
  32.199 @@ -118,3 +203,250 @@
  32.200  	return noErr;
  32.201  }
  32.202  
  32.203 +// Now for some unholy juggling between generic pointers and casting them to Obj-C objects!
  32.204 +// Note: things can get a bit hairy from here.  This is not for the faint of heart.
  32.205 +
  32.206 +NSWindowRef createNSWindow(int x, int y, int width, int height)
  32.207 +{
  32.208 +	LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height)
  32.209 +													  styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
  32.210 +	[window makeKeyAndOrderFront:nil];
  32.211 +	[window setAcceptsMouseMovedEvents:TRUE];
  32.212 +	return window;
  32.213 +}
  32.214 +
  32.215 +GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync)
  32.216 +{
  32.217 +	LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:samples andVsync:vsync];
  32.218 +	[(LLNSWindow*)window setContentView:glview];
  32.219 +	return glview;
  32.220 +}
  32.221 +
  32.222 +void glSwapBuffers(void* context)
  32.223 +{
  32.224 +	[(NSOpenGLContext*)context flushBuffer];
  32.225 +}
  32.226 +
  32.227 +CGLContextObj getCGLContextObj(GLViewRef view)
  32.228 +{
  32.229 +	return [(LLOpenGLView *)view getCGLContextObj];
  32.230 +}
  32.231 +
  32.232 +CGLPixelFormatObj* getCGLPixelFormatObj(NSWindowRef window)
  32.233 +{
  32.234 +	LLOpenGLView *glview = [(LLNSWindow*)window contentView];
  32.235 +	return [glview getCGLPixelFormatObj];
  32.236 +}
  32.237 +
  32.238 +unsigned long getVramSize(GLViewRef view)
  32.239 +{
  32.240 +	return [(LLOpenGLView *)view getVramSize];
  32.241 +}
  32.242 +
  32.243 +void getContentViewBounds(NSWindowRef window, float* bounds)
  32.244 +{
  32.245 +	bounds[0] = [[(LLNSWindow*)window contentView] bounds].origin.x;
  32.246 +	bounds[1] = [[(LLNSWindow*)window contentView] bounds].origin.y;
  32.247 +	bounds[2] = [[(LLNSWindow*)window contentView] bounds].size.width;
  32.248 +	bounds[3] = [[(LLNSWindow*)window contentView] bounds].size.height;
  32.249 +}
  32.250 +
  32.251 +void getWindowSize(NSWindowRef window, float* size)
  32.252 +{
  32.253 +	NSRect frame = [(LLNSWindow*)window frame];
  32.254 +	size[0] = frame.origin.x;
  32.255 +	size[1] = frame.origin.y;
  32.256 +	size[2] = frame.size.width;
  32.257 +	size[3] = frame.size.height;
  32.258 +}
  32.259 +
  32.260 +void setWindowSize(NSWindowRef window, int width, int height)
  32.261 +{
  32.262 +	NSRect frame = [(LLNSWindow*)window frame];
  32.263 +	frame.size.width = width;
  32.264 +	frame.size.height = height;
  32.265 +	[(LLNSWindow*)window setFrame:frame display:TRUE];
  32.266 +}
  32.267 +
  32.268 +void setWindowPos(NSWindowRef window, float* pos)
  32.269 +{
  32.270 +	NSPoint point;
  32.271 +	point.x = pos[0];
  32.272 +	point.y = pos[1];
  32.273 +	[(LLNSWindow*)window setFrameOrigin:point];
  32.274 +}
  32.275 +
  32.276 +void getCursorPos(NSWindowRef window, float* pos)
  32.277 +{
  32.278 +	NSPoint mLoc;
  32.279 +	mLoc = [(LLNSWindow*)window mouseLocationOutsideOfEventStream];
  32.280 +	pos[0] = mLoc.x;
  32.281 +	pos[1] = mLoc.y;
  32.282 +}
  32.283 +
  32.284 +void makeWindowOrderFront(NSWindowRef window)
  32.285 +{
  32.286 +	[(LLNSWindow*)window makeKeyAndOrderFront:nil];
  32.287 +}
  32.288 +
  32.289 +void convertScreenToWindow(NSWindowRef window, float *coord)
  32.290 +{
  32.291 +	NSRect point;
  32.292 +	point.origin.x = coord[0];
  32.293 +	point.origin.y = coord[1];
  32.294 +	point = [(LLNSWindow*)window convertRectFromScreen:point];
  32.295 +	coord[0] = point.origin.x;
  32.296 +	coord[1] = point.origin.y;
  32.297 +}
  32.298 +
  32.299 +void convertRectToScreen(NSWindowRef window, float *coord)
  32.300 +{
  32.301 +	NSRect point;
  32.302 +	point.origin.x = coord[0];
  32.303 +	point.origin.y = coord[1];
  32.304 +	point.size.width = coord[2];
  32.305 +	point.size.height = coord[3];
  32.306 +	
  32.307 +	point = [(LLNSWindow*)window convertRectToScreen:point];
  32.308 +	
  32.309 +	coord[0] = point.origin.x;
  32.310 +	coord[1] = point.origin.y;
  32.311 +	coord[2] = point.size.width;
  32.312 +	coord[3] = point.size.height;
  32.313 +}
  32.314 +
  32.315 +void convertRectFromScreen(NSWindowRef window, float *coord)
  32.316 +{
  32.317 +	NSRect point;
  32.318 +	point.origin.x = coord[0];
  32.319 +	point.origin.y = coord[1];
  32.320 +	point.size.width = coord[2];
  32.321 +	point.size.height = coord[3];
  32.322 +	
  32.323 +	point = [(LLNSWindow*)window convertRectFromScreen:point];
  32.324 +	
  32.325 +	coord[0] = point.origin.x;
  32.326 +	coord[1] = point.origin.y;
  32.327 +	coord[2] = point.size.width;
  32.328 +	coord[3] = point.size.height;
  32.329 +}
  32.330 +
  32.331 +void convertScreenToView(NSWindowRef window, float *coord)
  32.332 +{
  32.333 +	NSRect point;
  32.334 +	point.origin.x = coord[0];
  32.335 +	point.origin.y = coord[1];
  32.336 +	point.origin = [(LLNSWindow*)window convertScreenToBase:point.origin];
  32.337 +	point.origin = [[(LLNSWindow*)window contentView] convertPoint:point.origin fromView:nil];
  32.338 +}
  32.339 +
  32.340 +void convertWindowToScreen(NSWindowRef window, float *coord)
  32.341 +{
  32.342 +	NSPoint point;
  32.343 +	point.x = coord[0];
  32.344 +	point.y = coord[1];
  32.345 +	point = [(LLNSWindow*)window convertToScreenFromLocalPoint:point relativeToView:[(LLNSWindow*)window contentView]];
  32.346 +	coord[0] = point.x;
  32.347 +	coord[1] = point.y;
  32.348 +}
  32.349 +
  32.350 +void closeWindow(NSWindowRef window)
  32.351 +{
  32.352 +	[(LLNSWindow*)window close];
  32.353 +	[(LLNSWindow*)window release];
  32.354 +}
  32.355 +
  32.356 +void removeGLView(GLViewRef view)
  32.357 +{
  32.358 +	[(LLOpenGLView*)view removeFromSuperview];
  32.359 +	[(LLOpenGLView*)view release];
  32.360 +}
  32.361 +
  32.362 +void setupInputWindow(NSWindowRef window, GLViewRef glview)
  32.363 +{
  32.364 +	[[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview];
  32.365 +}
  32.366 +
  32.367 +void commitCurrentPreedit(GLViewRef glView)
  32.368 +{
  32.369 +	[(LLOpenGLView*)glView commitCurrentPreedit];
  32.370 +}
  32.371 +
  32.372 +void allowDirectMarkedTextInput(bool allow, GLViewRef glView)
  32.373 +{
  32.374 +    [(LLOpenGLView*)glView allowMarkedTextInput:allow];
  32.375 +}
  32.376 +
  32.377 +NSWindowRef getMainAppWindow()
  32.378 +{
  32.379 +	LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
  32.380 +	
  32.381 +	[winRef setAcceptsMouseMovedEvents:TRUE];
  32.382 +	return winRef;
  32.383 +}
  32.384 +
  32.385 +void makeFirstResponder(NSWindowRef window, GLViewRef view)
  32.386 +{
  32.387 +	[(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view];
  32.388 +}
  32.389 +
  32.390 +void requestUserAttention()
  32.391 +{
  32.392 +	[[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
  32.393 +}
  32.394 +
  32.395 +long showAlert(std::string text, std::string title, int type)
  32.396 +{
  32.397 +    NSAlert *alert = [[NSAlert alloc] init];
  32.398 +    
  32.399 +    [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
  32.400 +    [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
  32.401 +    if (type == 0)
  32.402 +    {
  32.403 +        [alert addButtonWithTitle:@"Okay"];
  32.404 +    } else if (type == 1)
  32.405 +    {
  32.406 +        [alert addButtonWithTitle:@"Okay"];
  32.407 +        [alert addButtonWithTitle:@"Cancel"];
  32.408 +    } else if (type == 2)
  32.409 +    {
  32.410 +        [alert addButtonWithTitle:@"Yes"];
  32.411 +        [alert addButtonWithTitle:@"No"];
  32.412 +    }
  32.413 +    long ret = [alert runModal];
  32.414 +    [alert dealloc];
  32.415 +    
  32.416 +    if (ret == NSAlertFirstButtonReturn)
  32.417 +    {
  32.418 +        if (type == 1)
  32.419 +        {
  32.420 +            ret = 3;
  32.421 +        } else if (type == 2)
  32.422 +        {
  32.423 +            ret = 0;
  32.424 +        }
  32.425 +    } else if (ret == NSAlertSecondButtonReturn)
  32.426 +    {
  32.427 +        if (type == 0 || type == 1)
  32.428 +        {
  32.429 +            ret = 2;
  32.430 +        } else if (type == 2)
  32.431 +        {
  32.432 +            ret = 1;
  32.433 +        }
  32.434 +    }
  32.435 +    
  32.436 +    return ret;
  32.437 +}
  32.438 +
  32.439 +/*
  32.440 + GLViewRef getGLView()
  32.441 + {
  32.442 + return [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] glview];
  32.443 + }
  32.444 + */
  32.445 +
  32.446 +unsigned int getModifiers()
  32.447 +{
  32.448 +	return [NSEvent modifierFlags];
  32.449 +}
    33.1 --- a/indra/llwindow/llwindowmacosx.cpp	Wed Sep 18 18:44:41 2013 -0400
    33.2 +++ b/indra/llwindow/llwindowmacosx.cpp	Thu Sep 19 13:13:37 2013 -0400
    33.3 @@ -30,7 +30,6 @@
    33.4  
    33.5  #include "llkeyboardmacosx.h"
    33.6  #include "llwindowcallbacks.h"
    33.7 -#include "llwindowmacosx-objc.h"
    33.8  #include "llpreeditor.h"
    33.9  
   33.10  #include "llerror.h"
   33.11 @@ -39,8 +38,8 @@
   33.12  #include "lldir.h"
   33.13  #include "indra_constants.h"
   33.14  
   33.15 -#include <Carbon/Carbon.h>
   33.16  #include <OpenGL/OpenGL.h>
   33.17 +#include <CoreServices/CoreServices.h>
   33.18  
   33.19  extern BOOL gDebugWindowProc;
   33.20  
   33.21 @@ -58,7 +57,6 @@
   33.22  //
   33.23  
   33.24  BOOL LLWindowMacOSX::sUseMultGL = FALSE;
   33.25 -WindowRef LLWindowMacOSX::sMediaWindow = NULL;
   33.26  
   33.27  // Cross-platform bits:
   33.28  
   33.29 @@ -98,105 +96,9 @@
   33.30  // We may want to base this on the setting of _DEBUG...
   33.31  
   33.32  #define CAPTURE_ALL_DISPLAYS 0
   33.33 -static double getDictDouble (CFDictionaryRef refDict, CFStringRef key);
   33.34 +//static double getDictDouble (CFDictionaryRef refDict, CFStringRef key);
   33.35  static long getDictLong (CFDictionaryRef refDict, CFStringRef key);
   33.36  
   33.37 -
   33.38 -
   33.39 -
   33.40 -// CarbonEvents we're interested in.
   33.41 -static EventTypeSpec WindowHandlerEventList[] =
   33.42 -{
   33.43 -	// Window-related events
   33.44 -	{ kEventClassWindow, kEventWindowActivated },
   33.45 -	{ kEventClassWindow, kEventWindowDeactivated },
   33.46 -	{ kEventClassWindow, kEventWindowShown },
   33.47 -	{ kEventClassWindow, kEventWindowHidden },
   33.48 -	{ kEventClassWindow, kEventWindowCollapsed },
   33.49 -	{ kEventClassWindow, kEventWindowExpanded },
   33.50 -	{ kEventClassWindow, kEventWindowGetClickActivation },
   33.51 -	{ kEventClassWindow, kEventWindowClose },
   33.52 -	{ kEventClassWindow, kEventWindowBoundsChanging },
   33.53 -	{ kEventClassWindow, kEventWindowBoundsChanged },
   33.54 -	{ kEventClassWindow, kEventWindowGetIdealSize },
   33.55 -
   33.56 -	// Mouse events
   33.57 -	{ kEventClassMouse, kEventMouseDown },
   33.58 -	{ kEventClassMouse, kEventMouseUp },
   33.59 -	{ kEventClassMouse, kEventMouseDragged },
   33.60 -	{ kEventClassMouse, kEventMouseWheelMoved },
   33.61 -	{ kEventClassMouse, kEventMouseMoved },
   33.62 -
   33.63 -	// Keyboard events
   33.64 -	// No longer handle raw key down events directly.
   33.65 -	// When text input events come in, extract the raw key events from them and process at that point.
   33.66 -	// This allows input methods to eat keystrokes the way they're supposed to.
   33.67 -//	{ kEventClassKeyboard, kEventRawKeyDown },
   33.68 -//	{ kEventClassKeyboard, kEventRawKeyRepeat },
   33.69 -	{ kEventClassKeyboard, kEventRawKeyUp },
   33.70 -	{ kEventClassKeyboard, kEventRawKeyModifiersChanged },
   33.71 -
   33.72 -	// Text input events
   33.73 -	{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
   33.74 -	{ kEventClassTextInput, kEventTextInputUpdateActiveInputArea },
   33.75 -	{ kEventClassTextInput, kEventTextInputOffsetToPos },
   33.76 -	{ kEventClassTextInput, kEventTextInputPosToOffset },
   33.77 -	{ kEventClassTextInput, kEventTextInputShowHideBottomWindow },
   33.78 -	{ kEventClassTextInput, kEventTextInputGetSelectedText },
   33.79 -	{ kEventClassTextInput, kEventTextInputFilterText },
   33.80 -
   33.81 -	// TSM Document Access events (advanced input method support)
   33.82 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength },
   33.83 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange },
   33.84 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters },
   33.85 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetFont },
   33.86 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetGlyphInfo },
   33.87 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessLockDocument },
   33.88 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessUnlockDocument }
   33.89 -};
   33.90 -
   33.91 -static EventTypeSpec GlobalHandlerEventList[] =
   33.92 -{
   33.93 -	// Mouse events
   33.94 -	{ kEventClassMouse, kEventMouseDown },
   33.95 -	{ kEventClassMouse, kEventMouseUp },
   33.96 -	{ kEventClassMouse, kEventMouseDragged },
   33.97 -	{ kEventClassMouse, kEventMouseWheelMoved },
   33.98 -	{ kEventClassMouse, kEventMouseMoved },
   33.99 -
  33.100 -	// Keyboard events
  33.101 -	// No longer handle raw key down events directly.
  33.102 -	// When text input events come in, extract the raw key events from them and process at that point.
  33.103 -	// This allows input methods to eat keystrokes the way they're supposed to.
  33.104 -//	{ kEventClassKeyboard, kEventRawKeyDown },
  33.105 -//	{ kEventClassKeyboard, kEventRawKeyRepeat },
  33.106 -	{ kEventClassKeyboard, kEventRawKeyUp },
  33.107 -	{ kEventClassKeyboard, kEventRawKeyModifiersChanged },
  33.108 -
  33.109 -	// Text input events
  33.110 -	{ kEventClassTextInput, kEventTextInputUpdateActiveInputArea },
  33.111 -	{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
  33.112 -	{ kEventClassTextInput, kEventTextInputOffsetToPos },
  33.113 -	{ kEventClassTextInput, kEventTextInputPosToOffset },
  33.114 -	{ kEventClassTextInput, kEventTextInputShowHideBottomWindow },
  33.115 -	{ kEventClassTextInput, kEventTextInputGetSelectedText },
  33.116 -	{ kEventClassTextInput, kEventTextInputFilterText },
  33.117 -
  33.118 -	// TSM Document Access events (advanced input method support)
  33.119 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength },
  33.120 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange },
  33.121 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters },
  33.122 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetFont },
  33.123 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetGlyphInfo },
  33.124 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessLockDocument },
  33.125 -	{ kEventClassTSMDocumentAccess, kEventTSMDocumentAccessUnlockDocument }
  33.126 -};
  33.127 -
  33.128 -static EventTypeSpec CommandHandlerEventList[] =
  33.129 -{
  33.130 -	{ kEventClassCommand, kEventCommandProcess }
  33.131 -};
  33.132 -
  33.133  // MBW -- HACK ALERT
  33.134  // On the Mac, to put up an OS dialog in full screen mode, we must first switch OUT of full screen mode.
  33.135  // The proper way to do this is to bracket the dialog with calls to beforeDialog() and afterDialog(), but these
  33.136 @@ -204,8 +106,6 @@
  33.137  // This assumes that there will be only one object of this class at any time.  Hopefully this is true.
  33.138  static LLWindowMacOSX *gWindowImplementation = NULL;
  33.139  
  33.140 -
  33.141 -
  33.142  LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
  33.143  							   const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
  33.144  							   S32 height, U32 flags,
  33.145 @@ -233,8 +133,6 @@
  33.146  	mContext = NULL;
  33.147  	mPixelFormat = NULL;
  33.148  	mDisplay = CGMainDisplayID();
  33.149 -	mOldDisplayMode = NULL;
  33.150 -	mTimer = NULL;
  33.151  	mSimulatedRightClick = FALSE;
  33.152  	mLastModifiers = 0;
  33.153  	mHandsOffEvents = FALSE;
  33.154 @@ -246,60 +144,31 @@
  33.155  	mOverrideAspectRatio = 0.f;
  33.156  	mMaximized = FALSE;
  33.157  	mMinimized = FALSE;
  33.158 -	mTSMDocument = NULL; // Just in case.
  33.159  	mLanguageTextInputAllowed = FALSE;
  33.160 -	mTSMScriptCode = 0;
  33.161 -	mTSMLangCode = 0;
  33.162  	mPreeditor = NULL;
  33.163 -	mRawKeyEvent = NULL;
  33.164  	mFSAASamples = fsaa_samples;
  33.165  	mForceRebuild = FALSE;
  33.166  
  33.167 -	// For reasons that aren't clear to me, LLTimers seem to be created in the "started" state.
  33.168 -	// 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.
  33.169 -	mBounceTimer.stop();
  33.170 -
  33.171  	// Get the original aspect ratio of the main device.
  33.172  	mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay);
  33.173  
  33.174  	// Stash the window title
  33.175 -	strcpy((char*)mWindowTitle + 1, title.c_str()); /* Flawfinder: ignore */
  33.176 -	mWindowTitle[0] = title.length();
  33.177 -
  33.178 -	mEventHandlerUPP = NewEventHandlerUPP(staticEventHandler);
  33.179 -	mMoveEventCampartorUPP = NewEventComparatorUPP(staticMoveEventComparator);
  33.180 -	mGlobalHandlerRef = NULL;
  33.181 -	mWindowHandlerRef = NULL;
  33.182 +	mWindowTitle = title;
  33.183 +	//mWindowTitle[0] = title.length();
  33.184  
  33.185  	mDragOverrideCursor = -1;
  33.186  
  33.187 -	// We're not clipping yet
  33.188 -	SetRect( &mOldMouseClip, 0, 0, 0, 0 );
  33.189 -
  33.190  	// Set up global event handlers (the fullscreen case needs this)
  33.191 -	InstallStandardEventHandler(GetApplicationEventTarget());
  33.192 +	//InstallStandardEventHandler(GetApplicationEventTarget());
  33.193  
  33.194  	// Stash an object pointer for OSMessageBox()
  33.195  	gWindowImplementation = this;
  33.196 -
  33.197  	// Create the GL context and set it up for windowed or fullscreen, as appropriate.
  33.198  	if(createContext(x, y, width, height, 32, fullscreen, disable_vsync))
  33.199  	{
  33.200  		if(mWindow != NULL)
  33.201  		{
  33.202 -			// MBW -- XXX -- I think we can now do this here?
  33.203 -			// Constrain the window to the screen it's mostly on, resizing if necessary.
  33.204 -			ConstrainWindowToScreen(
  33.205 -				mWindow,
  33.206 -				kWindowStructureRgn,
  33.207 -				kWindowConstrainMayResize |
  33.208 -				//				kWindowConstrainStandardOptions |
  33.209 -				0,
  33.210 -				NULL,
  33.211 -				NULL);
  33.212 -
  33.213 -			MacShowWindow(mWindow);
  33.214 -			BringToFront(mWindow);
  33.215 +			makeWindowOrderFront(mWindow);
  33.216  		}
  33.217  
  33.218  		if (!gGLManager.initGL())
  33.219 @@ -317,480 +186,390 @@
  33.220  		//start with arrow cursor
  33.221  		initCursors();
  33.222  		setCursor( UI_CURSOR_ARROW );
  33.223 +		
  33.224 +		allowLanguageTextInput(NULL, FALSE);
  33.225  	}
  33.226  
  33.227  	mCallbacks = callbacks;
  33.228  	stop_glerror();
  33.229 +	
  33.230 +	
  33.231 +}
  33.232 +
  33.233 +// These functions are used as wrappers for our internal event handling callbacks.
  33.234 +// It's a good idea to wrap these to avoid reworking more code than we need to within LLWindow.
  33.235 +
  33.236 +bool callKeyUp(unsigned short key, unsigned int mask)
  33.237 +{
  33.238 +	return gKeyboard->handleKeyUp(key, mask);
  33.239 +}
  33.240 +
  33.241 +bool callKeyDown(unsigned short key, unsigned int mask)
  33.242 +{
  33.243 +	return gKeyboard->handleKeyDown(key, mask);
  33.244 +}
  33.245 +
  33.246 +void callResetKeys()
  33.247 +{
  33.248 +	gKeyboard->resetKeys();
  33.249 +}
  33.250 +
  33.251 +bool callUnicodeCallback(wchar_t character, unsigned int mask)
  33.252 +{
  33.253 +	return gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask);
  33.254 +}
  33.255 +
  33.256 +void callFocus()
  33.257 +{
  33.258 +	if (gWindowImplementation)
  33.259 +	{
  33.260 +		gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation);
  33.261 +	}
  33.262 +}
  33.263 +
  33.264 +void callFocusLost()
  33.265 +{
  33.266 +	gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
  33.267 +}
  33.268 +
  33.269 +void callRightMouseDown(float *pos, MASK mask)
  33.270 +{
  33.271 +    if (gWindowImplementation->allowsLanguageInput())
  33.272 +    {
  33.273 +        gWindowImplementation->interruptLanguageTextInput();
  33.274 +    }
  33.275 +    
  33.276 +	LLCoordGL		outCoords;
  33.277 +	outCoords.mX = llround(pos[0]);
  33.278 +	outCoords.mY = llround(pos[1]);
  33.279 +	gWindowImplementation->getCallbacks()->handleRightMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
  33.280 +}
  33.281 +
  33.282 +void callRightMouseUp(float *pos, MASK mask)
  33.283 +{
  33.284 +    if (gWindowImplementation->allowsLanguageInput())
  33.285 +    {
  33.286 +        gWindowImplementation->interruptLanguageTextInput();
  33.287 +    }
  33.288 +    
  33.289 +	LLCoordGL		outCoords;
  33.290 +	outCoords.mX = llround(pos[0]);
  33.291 +	outCoords.mY = llround(pos[1]);
  33.292 +	gWindowImplementation->getCallbacks()->handleRightMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
  33.293 +}
  33.294 +
  33.295 +void callLeftMouseDown(float *pos, MASK mask)
  33.296 +{
  33.297 +    if (gWindowImplementation->allowsLanguageInput())
  33.298 +    {
  33.299 +        gWindowImplementation->interruptLanguageTextInput();
  33.300 +    }
  33.301 +    
  33.302 +	LLCoordGL		outCoords;
  33.303 +	outCoords.mX = llround(pos[0]);
  33.304 +	outCoords.mY = llround(pos[1]);
  33.305 +	gWindowImplementation->getCallbacks()->handleMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
  33.306 +}
  33.307 +
  33.308 +void callLeftMouseUp(float *pos, MASK mask)
  33.309 +{
  33.310 +    if (gWindowImplementation->allowsLanguageInput())
  33.311 +    {
  33.312 +        gWindowImplementation->interruptLanguageTextInput();
  33.313 +    }
  33.314 +    
  33.315 +	LLCoordGL		outCoords;
  33.316 +	outCoords.mX = llround(pos[0]);
  33.317 +	outCoords.mY = llround(pos[1]);
  33.318 +	gWindowImplementation->getCallbacks()->handleMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
  33.319 +	
  33.320 +}
  33.321 +
  33.322 +void callDoubleClick(float *pos, MASK mask)
  33.323 +{
  33.324 +    if (gWindowImplementation->allowsLanguageInput())
  33.325 +    {
  33.326 +        gWindowImplementation->interruptLanguageTextInput();
  33.327 +    }
  33.328 +    
  33.329 +	LLCoordGL	outCoords;
  33.330 +	outCoords.mX = llround(pos[0]);
  33.331 +	outCoords.mY = llround(pos[1]);
  33.332 +	gWindowImplementation->getCallbacks()->handleDoubleClick(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
  33.333 +}
  33.334 +
  33.335 +void callResize(unsigned int width, unsigned int height)
  33.336 +{
  33.337 +	if (gWindowImplementation != NULL)
  33.338 +	{
  33.339 +		gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height);
  33.340 +	}
  33.341 +}
  33.342 +
  33.343 +void callMouseMoved(float *pos, MASK mask)
  33.344 +{
  33.345 +	LLCoordGL		outCoords;
  33.346 +	outCoords.mX = llround(pos[0]);
  33.347 +	outCoords.mY = llround(pos[1]);
  33.348 +	float deltas[2];
  33.349 +	gWindowImplementation->getMouseDeltas(deltas);
  33.350 +	outCoords.mX += deltas[0];
  33.351 +	outCoords.mY += deltas[1];
  33.352 +	gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
  33.353 +	//gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0);
  33.354 +}
  33.355 +
  33.356 +void callScrollMoved(float delta)
  33.357 +{
  33.358 +	gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, delta);
  33.359 +}
  33.360 +
  33.361 +void callMouseExit()
  33.362 +{
  33.363 +	gWindowImplementation->getCallbacks()->handleMouseLeave(gWindowImplementation);
  33.364 +}
  33.365 +
  33.366 +void callWindowFocus()
  33.367 +{
  33.368 +	gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation);
  33.369 +}
  33.370 +
  33.371 +void callWindowUnfocus()
  33.372 +{
  33.373 +	gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
  33.374 +}
  33.375 +
  33.376 +void callDeltaUpdate(float *delta, MASK mask)
  33.377 +{
  33.378 +	gWindowImplementation->updateMouseDeltas(delta);
  33.379 +}
  33.380 +
  33.381 +void callMiddleMouseDown(float *pos, MASK mask)
  33.382 +{
  33.383 +	LLCoordGL		outCoords;
  33.384 +	outCoords.mX = llround(pos[0]);
  33.385 +	outCoords.mY = llround(pos[1]);
  33.386 +	float deltas[2];
  33.387 +	gWindowImplementation->getMouseDeltas(deltas);
  33.388 +	outCoords.mX += deltas[0];
  33.389 +	outCoords.mY += deltas[1];
  33.390 +	gWindowImplementation->getCallbacks()->handleMiddleMouseDown(gWindowImplementation, outCoords, mask);
  33.391 +}
  33.392 +
  33.393 +void callMiddleMouseUp(float *pos, MASK mask)
  33.394 +{
  33.395 +	LLCoordGL outCoords;
  33.396 +	outCoords.mX = llround(pos[0]);
  33.397 +	outCoords.mY = llround(pos[1]);
  33.398 +	float deltas[2];
  33.399 +	gWindowImplementation->getMouseDeltas(deltas);
  33.400 +	outCoords.mX += deltas[0];
  33.401 +	outCoords.mY += deltas[1];
  33.402 +	gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask);
  33.403 +}
  33.404 +
  33.405 +void callModifier(MASK mask)
  33.406 +{
  33.407 +	gKeyboard->handleModifier(mask);
  33.408 +}
  33.409 +
  33.410 +void callHandleDragEntered(std::string url)
  33.411 +{
  33.412 +	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING);
  33.413 +}
  33.414 +
  33.415 +void callHandleDragExited(std::string url)
  33.416 +{
  33.417 +	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING);
  33.418 +}
  33.419 +
  33.420 +void callHandleDragUpdated(std::string url)
  33.421 +{
  33.422 +	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK);
  33.423 +}
  33.424 +
  33.425 +void callHandleDragDropped(std::string url)
  33.426 +{
  33.427 +	gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED);
  33.428 +}
  33.429 +
  33.430 +void callQuitHandler()
  33.431 +{
  33.432 +	if (gWindowImplementation)
  33.433 +	{
  33.434 +		if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation))
  33.435 +		{
  33.436 +			gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation);
  33.437 +		}
  33.438 +	}
  33.439 +}
  33.440 +
  33.441 +void getPreeditSelectionRange(int *position, int *length)
  33.442 +{
  33.443 +	if (gWindowImplementation->getPreeditor())
  33.444 +	{
  33.445 +		gWindowImplementation->getPreeditor()->getSelectionRange(position, length);
  33.446 +	}
  33.447 +}
  33.448 +
  33.449 +void getPreeditMarkedRange(int *position, int *length)
  33.450 +{
  33.451 +	if (gWindowImplementation->getPreeditor())
  33.452 +	{
  33.453 +		gWindowImplementation->getPreeditor()->getPreeditRange(position, length);
  33.454 +	}
  33.455 +}
  33.456 +
  33.457 +void setPreeditMarkedRange(int position, int length)
  33.458 +{
  33.459 +	if (gWindowImplementation->getPreeditor())
  33.460 +	{
  33.461 +		gWindowImplementation->getPreeditor()->markAsPreedit(position, length);
  33.462 +	}
  33.463 +}
  33.464 +
  33.465 +bool handleUnicodeCharacter(wchar_t c)
  33.466 +{
  33.467 +    bool success = false;
  33.468 +	if (gWindowImplementation->getPreeditor())
  33.469 +	{
  33.470 +        success = gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c);
  33.471 +	}
  33.472 +    
  33.473 +    return success;
  33.474 +}
  33.475 +
  33.476 +void resetPreedit()
  33.477 +{
  33.478 +	if (gWindowImplementation->getPreeditor())
  33.479 +	{
  33.480 +		gWindowImplementation->getPreeditor()->resetPreedit();
  33.481 +	}
  33.482 +}
  33.483 +
  33.484 +// For reasons of convenience, handle IME updates here.
  33.485 +// This largely mirrors the old implementation, only sans the carbon parameters.
  33.486 +void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments)
  33.487 +{
  33.488 +	if (gWindowImplementation->getPreeditor())
  33.489 +	{
  33.490 +		LLPreeditor *preeditor = gWindowImplementation->getPreeditor();
  33.491 +		preeditor->resetPreedit();
  33.492 +		// This should be a viable replacement for the kEventParamTextInputSendReplaceRange parameter.
  33.493 +		if (replacementRange[0] < replacementRange[1])
  33.494 +		{
  33.495 +			const LLWString& text = preeditor->getPreeditString();
  33.496 +			const S32 location = wstring_wstring_length_from_utf16_length(text, 0, replacementRange[0]);
  33.497 +			const S32 length = wstring_wstring_length_from_utf16_length(text, location, replacementRange[1]);
  33.498 +			preeditor->markAsPreedit(location, length);
  33.499 +		}
  33.500 +		
  33.501 +		LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len));
  33.502 +		
  33.503 +		S32 caret_position = fix_str.length();
  33.504 +		
  33.505 +		preeditor->updatePreedit(fix_str, segments.seg_lengths, segments.seg_standouts, caret_position);
  33.506 +	}
  33.507 +}
  33.508 +
  33.509 +void getPreeditLocation(float *location, unsigned int length)
  33.510 +{
  33.511 +	if (gWindowImplementation->getPreeditor())
  33.512 +	{
  33.513 +		LLPreeditor *preeditor = gWindowImplementation->getPreeditor();
  33.514 +		LLCoordGL coord;
  33.515 +		LLCoordScreen screen;
  33.516 +		LLRect rect;
  33.517 +		
  33.518 +		preeditor->getPreeditLocation(length, &coord, &rect, NULL);
  33.519 +		
  33.520 +		float c[4] = {coord.mX, coord.mY, 0, 0};
  33.521 +		
  33.522 +		convertRectToScreen(gWindowImplementation->getWindow(), c);
  33.523 +		
  33.524 +		location[0] = c[0];
  33.525 +		location[1] = c[1];
  33.526 +	}
  33.527 +}
  33.528 +
  33.529 +void LLWindowMacOSX::updateMouseDeltas(float* deltas)
  33.530 +{
  33.531 +	if (mCursorDecoupled)
  33.532 +	{
  33.533 +		mCursorLastEventDeltaX = llround(deltas[0]);
  33.534 +		mCursorLastEventDeltaY = llround(-deltas[1]);
  33.535 +		
  33.536 +		if (mCursorIgnoreNextDelta)
  33.537 +		{
  33.538 +			mCursorLastEventDeltaX = 0;
  33.539 +			mCursorLastEventDeltaY = 0;
  33.540 +			mCursorIgnoreNextDelta = FALSE;
  33.541 +		}
  33.542 +	} else {
  33.543 +		mCursorLastEventDeltaX = 0;
  33.544 +		mCursorLastEventDeltaY = 0;
  33.545 +	}
  33.546 +}
  33.547 +
  33.548 +void LLWindowMacOSX::getMouseDeltas(float* delta)
  33.549 +{
  33.550 +	delta[0] = mCursorLastEventDeltaX;
  33.551 +	delta[1] = mCursorLastEventDeltaY;
  33.552  }
  33.553  
  33.554  BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync)
  33.555  {
  33.556 -	OSStatus		err;
  33.557  	BOOL			glNeedsInit = FALSE;
  33.558  
  33.559 -	if(mGlobalHandlerRef == NULL)
  33.560 +	mFullscreen = fullscreen;
  33.561 +	
  33.562 +	if (mWindow == NULL)
  33.563  	{
  33.564 -		InstallApplicationEventHandler(mEventHandlerUPP, GetEventTypeCount (CommandHandlerEventList), CommandHandlerEventList, (void*)this, &mGlobalHandlerRef);
  33.565 -	}
  33.566 -
  33.567 -	mFullscreen = fullscreen;
  33.568 -
  33.569 -	if (mFullscreen && (mOldDisplayMode == NULL))
  33.570 -	{
  33.571 -		LL_INFOS("Window") << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL;
  33.572 -
  33.573 -		// NOTE: The refresh rate will be REPORTED AS 0 for many DVI and notebook displays.  Plan accordingly.
  33.574 -		double refresh = getDictDouble (CGDisplayCurrentMode (mDisplay),  kCGDisplayRefreshRate);
  33.575 -
  33.576 -		// If the requested width or height is 0, find the best default for the monitor.
  33.577 -		if((width == 0) || (height == 0))
  33.578 -		{
  33.579 -			// Scan through the list of modes, looking for one which has:
  33.580 -			//		height between 700 and 800
  33.581 -			//		aspect ratio closest to the user's original mode
  33.582 -			S32 resolutionCount = 0;
  33.583 -			LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount);
  33.584 -
  33.585 -			if(resolutionList != NULL)
  33.586 -			{
  33.587 -				F32 closestAspect = 0;
  33.588 -				U32 closestHeight = 0;
  33.589 -				U32 closestWidth = 0;
  33.590 -				int i;
  33.591 -
  33.592 -				LL_DEBUGS("Window") << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL;
  33.593 -
  33.594 -				for(i=0; i < resolutionCount; i++)
  33.595 -				{
  33.596 -					F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight;
  33.597 -
  33.598 -					LL_DEBUGS("Window") << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL;
  33.599 -
  33.600 -					if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) &&
  33.601 -						(fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio)))
  33.602 -					{
  33.603 -						LL_DEBUGS("Window") << " (new closest mode) " << LL_ENDL;
  33.604 -
  33.605 -						// This is the closest mode we've seen yet.
  33.606 -						closestWidth = resolutionList[i].mWidth;
  33.607 -						closestHeight = resolutionList[i].mHeight;
  33.608 -						closestAspect = aspect;
  33.609 -					}
  33.610 -				}
  33.611 -
  33.612 -				width = closestWidth;
  33.613 -				height = closestHeight;
  33.614 -			}
  33.615 -		}
  33.616 -
  33.617 -		if((width == 0) || (height == 0))
  33.618 -		{
  33.619 -			// Mode search failed for some reason.  Use the old-school default.
  33.620 -			width = 1024;
  33.621 -			height = 768;
  33.622 -		}
  33.623 -
  33.624 -		if (true)
  33.625 -		{
  33.626 -			// Fullscreen support
  33.627 -			CFDictionaryRef refDisplayMode = 0;
  33.628 -			boolean_t exactMatch = false;
  33.629 -
  33.630 -#if CAPTURE_ALL_DISPLAYS
  33.631 -			// Capture all displays (may want to do this for final build)
  33.632 -			CGCaptureAllDisplays ();
  33.633 -#else
  33.634 -			// Capture only the main display (useful for debugging)
  33.635 -			CGDisplayCapture (mDisplay);
  33.636 -#endif
  33.637 -
  33.638 -			// Switch the display to the desired resolution and refresh
  33.639 -			refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate(
  33.640 -				mDisplay,
  33.641 -				BITS_PER_PIXEL,
  33.642 -				width,
  33.643 -				height,
  33.644 -				refresh,
  33.645 -				&exactMatch);
  33.646 -
  33.647 -			if (refDisplayMode)
  33.648 -			{
  33.649 -				LL_DEBUGS("Window") << "createContext: switching display resolution" << LL_ENDL;
  33.650 -				mOldDisplayMode = CGDisplayCurrentMode (mDisplay);
  33.651 -				CGDisplaySwitchToMode (mDisplay, refDisplayMode);
  33.652 -				//				CFRelease(refDisplayMode);
  33.653 -
  33.654 -				AddEventTypesToHandler(mGlobalHandlerRef, GetEventTypeCount (GlobalHandlerEventList), GlobalHandlerEventList);
  33.655 -			}
  33.656 -
  33.657 -
  33.658 -			mFullscreen = TRUE;
  33.659 -			mFullscreenWidth   = CGDisplayPixelsWide(mDisplay);
  33.660 -			mFullscreenHeight  = CGDisplayPixelsHigh(mDisplay);
  33.661 -			mFullscreenBits    = CGDisplayBitsPerPixel(mDisplay);
  33.662 -			mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay),  kCGDisplayRefreshRate));
  33.663 -
  33.664 -			LL_INFOS("Window") << "Running at " << mFullscreenWidth
  33.665 -				<< "x"   << mFullscreenHeight
  33.666 -				<< "x"   << mFullscreenBits
  33.667 -				<< " @ " << mFullscreenRefresh
  33.668 -				<< LL_ENDL;
  33.669 -		}
  33.670 -		else
  33.671 -		{
  33.672 -			// No fullscreen support
  33.673 -			mFullscreen = FALSE;
  33.674 -			mFullscreenWidth   = -1;
  33.675 -			mFullscreenHeight  = -1;
  33.676 -			mFullscreenBits    = -1;
  33.677 -			mFullscreenRefresh = -1;
  33.678 -
  33.679 -			std::string error= llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height);
  33.680 -			OSMessageBox(error, "Error", OSMB_OK);
  33.681 -		}
  33.682 -	}
  33.683 -
  33.684 -	if(!mFullscreen && (mWindow == NULL))
  33.685 -	{
  33.686 -		//int				displayWidth = CGDisplayPixelsWide(mDisplay);
  33.687 -		//int				displayHeight = CGDisplayPixelsHigh(mDisplay);
  33.688 -		//const int		menuBarPlusTitleBar = 44;   // Ugly magic number.
  33.689 -
  33.690 -		LL_DEBUGS("Window") << "createContext: creating window" << LL_ENDL;
  33.691 -
  33.692 -		mPreviousWindowRect.left = (long) x;
  33.693 -		mPreviousWindowRect.right = (long) x + width;
  33.694 -		mPreviousWindowRect.top = (long) y;
  33.695 -		mPreviousWindowRect.bottom = (long) y + height;
  33.696 -
  33.697 -		//-----------------------------------------------------------------------
  33.698 -		// Create the window
  33.699 -		//-----------------------------------------------------------------------
  33.700 -		mWindow = NewCWindow(
  33.701 -			NULL,
  33.702 -			&mPreviousWindowRect,
  33.703 -			mWindowTitle,
  33.704 -			false,				// Create the window invisible.  Whoever calls createContext() should show it after any moving/resizing.
  33.705 -			//		noGrowDocProc,		// Window with no grow box and no zoom box
  33.706 -			zoomDocProc,		// Window with a grow box and a zoom box
  33.707 -			//		zoomNoGrow,			// Window with a zoom box but no grow box
  33.708 -			kFirstWindowOfClass,
  33.709 -			true,
  33.710 -			(long)this);
  33.711 -
  33.712 -		if (!mWindow)
  33.713 -		{
  33.714 -			setupFailure("Window creation error", "Error", OSMB_OK);
  33.715 -			return FALSE;
  33.716 -		}
  33.717 -
  33.718 -		// Turn on live resize.
  33.719 -		// For this to work correctly, we need to be able to call LLViewerWindow::draw from
  33.720 -		// the event handler for kEventWindowBoundsChanged.  It's not clear that we have access from here.
  33.721 -		//	err = ChangeWindowAttributes(mWindow, kWindowLiveResizeAttribute, 0);
  33.722 -
  33.723 -		// Set up window event handlers (some window-related events ONLY go to window handlers.)
  33.724 -		InstallStandardEventHandler(GetWindowEventTarget(mWindow));
  33.725 -		InstallWindowEventHandler(mWindow, mEventHandlerUPP, GetEventTypeCount (WindowHandlerEventList), WindowHandlerEventList, (void*)this, &mWindowHandlerRef); // add event handler
  33.726 -#if LL_OS_DRAGDROP_ENABLED
  33.727 -		InstallTrackingHandler( dragTrackingHandler, mWindow, (void*)this );
  33.728 -		InstallReceiveHandler( dragReceiveHandler, mWindow, (void*)this );
  33.729 -#endif // LL_OS_DRAGDROP_ENABLED
  33.730 -	}
  33.731 -
  33.732 -	{
  33.733 -		// Create and initialize our TSM document for language text input.
  33.734 -		// If an error occured, we can do nothing better than simply ignore it.
  33.735 -		// mTSMDocument will be kept NULL in case.
  33.736 -		if (mTSMDocument)
  33.737 -		{
  33.738 -			DeactivateTSMDocument(mTSMDocument);
  33.739 -			DeleteTSMDocument(mTSMDocument);
  33.740 -			mTSMDocument = NULL;
  33.741 -		}
  33.742 -		static InterfaceTypeList types = { kUnicodeDocument };
  33.743 -		err = NewTSMDocument(1, types, &mTSMDocument, 0);
  33.744 -		if (err != noErr)
  33.745 -		{
  33.746 -			LL_WARNS("Window") << "createContext: couldn't create a TSMDocument (" << err << ")" << LL_ENDL;
  33.747 -		}
  33.748 -		if (mTSMDocument)
  33.749 -		{
  33.750 -			ActivateTSMDocument(mTSMDocument);
  33.751 -			allowLanguageTextInput(NULL, FALSE);
  33.752 -		}
  33.753 +		mWindow = getMainAppWindow();
  33.754  	}
  33.755  
  33.756  	if(mContext == NULL)
  33.757  	{
  33.758 -		AGLRendererInfo rendererInfo = NULL;
  33.759 -
  33.760 -		//-----------------------------------------------------------------------
  33.761 -		// Create GL drawing context
  33.762 -		//-----------------------------------------------------------------------
  33.763 -
  33.764 -		if(mPixelFormat == NULL)
  33.765 -		{
  33.766 -			if(mFullscreen)
  33.767 -			{
  33.768 -				GLint fullscreenAttrib[] =
  33.769 -				{
  33.770 -					AGL_RGBA,
  33.771 -					AGL_FULLSCREEN,
  33.772 -					AGL_NO_RECOVERY,
  33.773 -					AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0,
  33.774 -					AGL_SAMPLES_ARB, mFSAASamples,
  33.775 -					AGL_DOUBLEBUFFER,
  33.776 -					AGL_CLOSEST_POLICY,
  33.777 -					AGL_ACCELERATED,
  33.778 -					AGL_RED_SIZE, 8,
  33.779 -					AGL_GREEN_SIZE, 8,
  33.780 -					AGL_BLUE_SIZE, 8,
  33.781 -					AGL_ALPHA_SIZE, 8,
  33.782 -					AGL_DEPTH_SIZE, 24,
  33.783 -					AGL_STENCIL_SIZE, 8,
  33.784 -					AGL_NONE
  33.785 -				};
  33.786 -
  33.787 -				LL_DEBUGS("Window") << "createContext: creating fullscreen pixelformat" << LL_ENDL;
  33.788 -
  33.789 -				GDHandle gdhDisplay = NULL;
  33.790 -				err = DMGetGDeviceByDisplayID ((DisplayIDType)mDisplay, &gdhDisplay, false);
  33.791 -
  33.792 -				mPixelFormat = aglChoosePixelFormat(&gdhDisplay, 1, fullscreenAttrib);
  33.793 -				rendererInfo = aglQueryRendererInfo(&gdhDisplay, 1);
  33.794 -			}
  33.795 -			else
  33.796 -			{
  33.797 -				// NOTE from Leslie:
  33.798 -				//
  33.799 -				// AGL_NO_RECOVERY, when combined with AGL_ACCELERATED prevents software rendering
  33.800 -				// fallback which means we won't hvae shaders that compile and link but then don't
  33.801 -				// work.  The drawback is that our shader compilation will be a bit more finicky though.
  33.802 -
  33.803 -				GLint windowedAttrib[] =
  33.804 -				{
  33.805 -					AGL_RGBA,
  33.806 -					AGL_NO_RECOVERY,
  33.807 -					AGL_DOUBLEBUFFER,
  33.808 -					AGL_CLOSEST_POLICY,
  33.809 -					AGL_ACCELERATED,
  33.810 -					AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0,
  33.811 -					AGL_SAMPLES_ARB, mFSAASamples,
  33.812 -					AGL_RED_SIZE, 8,
  33.813 -					AGL_GREEN_SIZE, 8,
  33.814 -					AGL_BLUE_SIZE, 8,
  33.815 -					AGL_ALPHA_SIZE, 8,
  33.816 -					AGL_DEPTH_SIZE, 24,
  33.817 -					AGL_STENCIL_SIZE, 8,
  33.818 -					AGL_NONE
  33.819 -				};
  33.820 -
  33.821 -				LL_DEBUGS("Window") << "createContext: creating windowed pixelformat" << LL_ENDL;
  33.822 -
  33.823 -				mPixelFormat = aglChoosePixelFormat(NULL, 0, windowedAttrib);
  33.824 -
  33.825 -				GDHandle gdhDisplay = GetMainDevice();
  33.826 -				rendererInfo = aglQueryRendererInfo(&gdhDisplay, 1);
  33.827 -			}
  33.828 -
  33.829 -			// May want to get the real error text like this:
  33.830 -			// (char *) aglErrorString(aglGetError());
  33.831 -
  33.832 -			if(aglGetError() != AGL_NO_ERROR)
  33.833 -			{
  33.834 -				setupFailure("Can't find suitable pixel format", "Error", OSMB_OK);
  33.835 -				return FALSE;
  33.836 -			}
  33.837 -		}
  33.838 -
  33.839 -		if(mPixelFormat)
  33.840 -		{
  33.841 -			LL_DEBUGS("Window") << "createContext: creating GL context" << LL_ENDL;
  33.842 -			mContext = aglCreateContext(mPixelFormat, NULL);
  33.843 -		}
  33.844 -
  33.845 -		if(mContext == NULL)
  33.846 -		{
  33.847 -			setupFailure("Can't make GL context", "Error", OSMB_OK);
  33.848 -			return FALSE;
  33.849 -		}
  33.850 -
  33.851 -		gGLManager.mVRAM = 0;
  33.852 -
  33.853 -		if(rendererInfo != NULL)
  33.854 -		{
  33.855 -			GLint result;
  33.856 -
  33.857 -			if(aglDescribeRenderer(rendererInfo, AGL_VIDEO_MEMORY, &result))
  33.858 -			{
  33.859 -				//				llinfos << "createContext: aglDescribeRenderer(AGL_VIDEO_MEMORY) returned " << result << llendl;
  33.860 -				gGLManager.mVRAM = result / (1024 * 1024);
  33.861 -			}
  33.862 -			else
  33.863 -			{
  33.864 -				//				llinfos << "createContext: aglDescribeRenderer(AGL_VIDEO_MEMORY) failed." << llendl;
  33.865 -			}
  33.866 -
  33.867 -			// This could be useful at some point, if it takes into account the memory already used by screen buffers, etc...
  33.868 -			if(aglDescribeRenderer(rendererInfo, AGL_TEXTURE_MEMORY, &result))
  33.869 -			{
  33.870 -				//				llinfos << "createContext: aglDescribeRenderer(AGL_TEXTURE_MEMORY) returned " << result << llendl;
  33.871 -			}
  33.872 -			else
  33.873 -			{
  33.874 -				//				llinfos << "createContext: aglDescribeRenderer(AGL_TEXTURE_MEMORY) failed." << llendl;
  33.875 -			}
  33.876 -
  33.877 -			aglDestroyRendererInfo(rendererInfo);
  33.878 -		}
  33.879 -
  33.880 +		// Our OpenGL view is already defined within SecondLife.xib.
  33.881 +		// Get the view instead.
  33.882 +		mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync);
  33.883 +		mContext = getCGLContextObj(mGLView);
  33.884 +		
  33.885  		// Since we just created the context, it needs to be set up.
  33.886  		glNeedsInit = TRUE;
  33.887 +		
  33.888 +		gGLManager.mVRAM = getVramSize(mGLView);
  33.889  	}
  33.890 -
  33.891 +	
  33.892 +	// This sets up our view to recieve text from our non-inline text input window.
  33.893 +	setupInputWindow(mWindow, mGLView);
  33.894 +	
  33.895  	// Hook up the context to a drawable
  33.896 -	if (mFullscreen && (mOldDisplayMode != NULL))
  33.897 -	{
  33.898 -		// We successfully captured the display.  Use a fullscreen drawable
  33.899 -
  33.900 -		LL_DEBUGS("Window") << "createContext: attaching fullscreen drawable" << LL_ENDL;
  33.901 -
  33.902 -#if CAPTURE_ALL_DISPLAYS
  33.903 -		// Capture all displays (may want to do this for final build)
  33.904 -		aglDisable (mContext, AGL_FS_CAPTURE_SINGLE);
  33.905 -#else
  33.906 -		// Capture only the main display (useful for debugging)
  33.907 -		aglEnable (mContext, AGL_FS_CAPTURE_SINGLE);
  33.908 -#endif
  33.909 -
  33.910 -		if (!aglSetFullScreen (mContext, 0, 0, 0, 0))
  33.911 -		{
  33.912 -			setupFailure("Can't set GL fullscreen", "Error", OSMB_OK);
  33.913 -			return FALSE;
  33.914 -		}
  33.915 -	}
  33.916 -	else if(!mFullscreen && (mWindow != NULL))
  33.917 -	{
  33.918 -		LL_DEBUGS("Window") << "createContext: attaching windowed drawable" << LL_ENDL;
  33.919 -
  33.920 -		// We created a window.  Use it as the drawable.
  33.921 -		if(!aglSetDrawable(mContext, GetWindowPort (mWindow)))
  33.922 -		{
  33.923 -			setupFailure("Can't set GL drawable", "Error", OSMB_OK);
  33.924 -			return FALSE;
  33.925 -		}
  33.926 -	}
  33.927 -	else
  33.928 -	{
  33.929 -		setupFailure("Can't get fullscreen or windowed drawable.", "Error", OSMB_OK);
  33.930 -		return FALSE;
  33.931 -	}
  33.932  
  33.933  	if(mContext != NULL)
  33.934  	{
  33.935 -		LL_DEBUGS("Window") << "createContext: setting current context" << LL_ENDL;
  33.936 -
  33.937 -		if (!aglSetCurrentContext(mContext))
  33.938 +		
  33.939 +		
  33.940 +		U32 err = CGLSetCurrentContext(mContext);
  33.941 +		if (err != kCGLNoError)
  33.942  		{
  33.943  			setupFailure("Can't activate GL rendering context", "Error", OSMB_OK);
  33.944  			return FALSE;
  33.945  		}
  33.946  	}
  33.947  
  33.948 -	if(glNeedsInit)
  33.949 -	{
  33.950 -		// Check for some explicitly unsupported cards.
  33.951 -		const char* RENDERER = (const char*) glGetString(GL_RENDERER);
  33.952 -
  33.953 -		const char* CARD_LIST[] =
  33.954 -		{	"RAGE 128",
  33.955 -		"RIVA TNT2",
  33.956 -		"Intel 810",
  33.957 -		"3Dfx/Voodoo3",
  33.958 -		"Radeon 7000",
  33.959 -		"Radeon 7200",
  33.960 -		"Radeon 7500",
  33.961 -		"Radeon DDR",
  33.962 -		"Radeon VE",
  33.963 -		"GDI Generic" };
  33.964 -		const S32 CARD_COUNT = LL_ARRAY_SIZE(CARD_LIST);
  33.965 -
  33.966 -		// Future candidates:
  33.967 -		// ProSavage/Twister
  33.968 -		// SuperSavage
  33.969 -
  33.970 -		S32 i;
  33.971 -		for (i = 0; i < CARD_COUNT; i++)
  33.972 -		{
  33.973 -			if (check_for_card(RENDERER, CARD_LIST[i]))
  33.974 -			{
  33.975 -				close();
  33.976 -				return FALSE;
  33.977 -			}
  33.978 -		}
  33.979 -	}
  33.980 -
  33.981 -	GLint colorBits, alphaBits, depthBits, stencilBits;
  33.982 -
  33.983 -	if(	!aglDescribePixelFormat(mPixelFormat, AGL_BUFFER_SIZE, &colorBits) ||
  33.984 -		!aglDescribePixelFormat(mPixelFormat, AGL_ALPHA_SIZE, &alphaBits) ||
  33.985 -		!aglDescribePixelFormat(mPixelFormat, AGL_DEPTH_SIZE, &depthBits) ||
  33.986 -		!aglDescribePixelFormat(mPixelFormat, AGL_STENCIL_SIZE, &stencilBits))
  33.987 -	{
  33.988 -		close();
  33.989 -		setupFailure("Can't get pixel format description", "Error", OSMB_OK);
  33.990 -		return FALSE;
  33.991 -	}
  33.992 -
  33.993 -	LL_INFOS("GLInit") << "GL buffer: Color Bits " << S32(colorBits)
  33.994 -		<< " Alpha Bits " << S32(alphaBits)
  33.995 -		<< " Depth Bits " << S32(depthBits)
  33.996 -		<< " Stencil Bits" << S32(stencilBits)
  33.997 -		<< LL_ENDL;
  33.998 -
  33.999 -	if (colorBits < 32)
 33.1000 -	{
 33.1001 -		close();
 33.1002 -		setupFailure(
 33.1003 -			"Second Life requires True Color (32-bit) to run in a window.\n"
 33.1004 -			"Please go to Control Panels -> Display -> Settings and\n"
 33.1005 -			"set the screen to 32-bit color.\n"
 33.1006 -			"Alternately, if you choose to run fullscreen, Second Life\n"
 33.1007 -			"will automatically adjust the screen each time it runs.",
 33.1008 -			"Error",
 33.1009 -			OSMB_OK);
 33.1010 -		return FALSE;
 33.1011 -	}
 33.1012 -
 33.1013 -	if (alphaBits < 8)
 33.1014 -	{
 33.1015 -		close();
 33.1016 -		setupFailure(
 33.1017 -			"Second Life is unable to run because it can't get an 8 bit alpha\n"
 33.1018 -			"channel.  Usually this is due to video card driver issues.\n"
 33.1019 -			"Please make sure you have the latest video card drivers installed.\n"
 33.1020 -			"Also be sure your monitor is set to True Color (32-bit) in\n"
 33.1021 -			"Control Panels -> Display -> Settings.\n"
 33.1022 -			"If you continue to receive this message, contact customer service.",
 33.1023 -			"Error",
 33.1024 -			OSMB_OK);
 33.1025 -		return FALSE;
 33.1026 -	}
 33.1027 -
 33.1028  	// Disable vertical sync for swap
 33.1029  	GLint frames_per_swap = 0;
 33.1030  	if (disable_vsync)
 33.1031  	{
 33.1032 -		LL_DEBUGS("GLInit") << "Disabling vertical sync" << LL_ENDL;
 33.1033  		frames_per_swap = 0;
 33.1034  	}
 33.1035  	else
 33.1036  	{
 33.1037 -		LL_DEBUGS("GLinit") << "Keeping vertical sync" << LL_ENDL;
 33.1038  		frames_per_swap = 1;
 33.1039  	}
 33.1040 -	aglSetInteger(mContext, AGL_SWAP_INTERVAL, &frames_per_swap);
 33.1041 +	
 33.1042 +	CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap);
 33.1043  
 33.1044  	//enable multi-threaded OpenGL
 33.1045  	if (sUseMultGL)
 33.1046 @@ -809,109 +588,17 @@
 33.1047  			LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
 33.1048  		}
 33.1049  	}
 33.1050 -
 33.1051 -	// Don't need to get the current gamma, since there's a call that restores it to the system defaults.
 33.1052 +	makeFirstResponder(mWindow, mGLView);
 33.1053 +    
 33.1054  	return TRUE;
 33.1055  }
 33.1056  
 33.1057  
 33.1058 -// changing fullscreen resolution, or switching between windowed and fullscreen mode.
 33.1059 +// We only support OS X 10.7's fullscreen app mode which is literally a full screen window that fills a virtual desktop.
 33.1060 +// This makes this method obsolete.
 33.1061  BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp)
 33.1062  {
 33.1063 -	BOOL needsRebuild = FALSE;
 33.1064 -	BOOL result = true;
 33.1065 -
 33.1066 -	if(fullscreen)
 33.1067 -	{
 33.1068 -		if(mFullscreen)
 33.1069 -		{
 33.1070 -			// Switching resolutions in fullscreen mode.  Don't need to rebuild for this.
 33.1071 -			// Fullscreen support
 33.1072 -			CFDictionaryRef refDisplayMode = 0;
 33.1073 -			boolean_t exactMatch = false;
 33.1074 -
 33.1075 -			// Switch the display to the desired resolution and refresh
 33.1076 -			refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate(
 33.1077 -				mDisplay,
 33.1078 -				BITS_PER_PIXEL,
 33.1079 -				size.mX,
 33.1080 -				size.mY,
 33.1081 -				getDictDouble (CGDisplayCurrentMode (mDisplay),  kCGDisplayRefreshRate),
 33.1082 -				&exactMatch);
 33.1083 -
 33.1084 -			if (refDisplayMode)
 33.1085 -			{
 33.1086 -				CGDisplaySwitchToMode (mDisplay, refDisplayMode);
 33.1087 -				//				CFRelease(refDisplayMode);
 33.1088 -			}
 33.1089 -
 33.1090 -			mFullscreenWidth   = CGDisplayPixelsWide(mDisplay);
 33.1091 -			mFullscreenHeight  = CGDisplayPixelsHigh(mDisplay);
 33.1092 -			mFullscreenBits    = CGDisplayBitsPerPixel(mDisplay);
 33.1093 -			mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay),  kCGDisplayRefreshRate));
 33.1094 -
 33.1095 -			LL_INFOS("Window") << "Switched resolution to " << mFullscreenWidth
 33.1096 -				<< "x"   << mFullscreenHeight
 33.1097 -				<< "x"   << mFullscreenBits
 33.1098 -				<< " @ " << mFullscreenRefresh
 33.1099 -				<< LL_ENDL;
 33.1100 -
 33.1101 -			// Update the GL context to the new screen size
 33.1102 -			if (!aglUpdateContext(mContext))
 33.1103 -			{
 33.1104 -				setupFailure("Can't set GL fullscreen", "Error", OSMB_OK);
 33.1105 -				result = FALSE;
 33.1106 -			}
 33.1107 -		}
 33.1108 -		else
 33.1109 -		{
 33.1110 -			// Switching from windowed to fullscreen
 33.1111 -			needsRebuild = TRUE;
 33.1112 -		}
 33.1113 -	}
 33.1114 -	else
 33.1115 -	{
 33.1116 -		if(mFullscreen)
 33.1117 -		{
 33.1118 -			// Switching from fullscreen to windowed
 33.1119 -			needsRebuild = TRUE;
 33.1120 -		}
 33.1121 -		else
 33.1122 -		{
 33.1123 -			// Windowed to windowed -- not sure why we would be called like this.  Just change the window size.
 33.1124 -			// The bounds changed event handler will do the rest.
 33.1125 -			if(mWindow != NULL)
 33.1126 -			{
 33.1127 -				::SizeWindow(mWindow, size.mX, size.mY, true);
 33.1128 -			}
 33.1129 -		}
 33.1130 -	}
 33.1131 -
 33.1132 -	stop_glerror();
 33.1133 -	if(needsRebuild || mForceRebuild)
 33.1134 -	{
 33.1135 -		mForceRebuild = FALSE;
 33.1136 -		destroyContext();
 33.1137 -		result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync);
 33.1138 -		if (result)
 33.1139 -		{
 33.1140 -			if(mWindow != NULL)
 33.1141 -			{
 33.1142 -				MacShowWindow(mWindow);
 33.1143 -				BringToFront(mWindow);
 33.1144 -			}
 33.1145 -
 33.1146 -			llverify(gGLManager.initGL());
 33.1147 -
 33.1148 -			//start with arrow cursor
 33.1149 -			initCursors();
 33.1150 -			setCursor( UI_CURSOR_ARROW );
 33.1151 -		}
 33.1152 -	}
 33.1153 -
 33.1154 -	stop_glerror();
 33.1155 -
 33.1156 -	return result;
 33.1157 +	return FALSE;
 33.1158  }
 33.1159  
 33.1160  void LLWindowMacOSX::destroyContext()
 33.1161 @@ -925,32 +612,7 @@
 33.1162  	if(mContext != NULL)
 33.1163  	{
 33.1164  		LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL;
 33.1165 -
 33.1166 -		aglSetCurrentContext (NULL);
 33.1167 -		aglSetDrawable(mContext, NULL);
 33.1168 -	}
 33.1169 -
 33.1170 -	// Make sure the display resolution gets restored
 33.1171 -	if(mOldDisplayMode != NULL)
 33.1172 -	{
 33.1173 -		LL_DEBUGS("Window") << "destroyContext: restoring display resolution " << LL_ENDL;
 33.1174 -
 33.1175 -		CGDisplaySwitchToMode (mDisplay, mOldDisplayMode);
 33.1176 -
 33.1177 -#if CAPTURE_ALL_DISPLAYS
 33.1178 -		// Uncapture all displays (may want to do this for final build)
 33.1179 -		CGReleaseAllDisplays ();
 33.1180 -#else
 33.1181 -		// Uncapture only the main display (useful for debugging)
 33.1182 -		CGDisplayRelease (mDisplay);
 33.1183 -#endif
 33.1184 -
 33.1185 -		//		CFRelease(mOldDisplayMode);
 33.1186 -
 33.1187 -		mOldDisplayMode = NULL;
 33.1188 -
 33.1189 -		// Remove the global event handlers the fullscreen case needed
 33.1190 -		RemoveEventTypesFromHandler(mGlobalHandlerRef, GetEventTypeCount (GlobalHandlerEventList), GlobalHandlerEventList);
 33.1191 +		CGLSetCurrentContext(NULL);
 33.1192  	}
 33.1193  
 33.1194  	// Clean up remaining GL state before blowing away window
 33.1195 @@ -959,49 +621,29 @@
 33.1196  	// Clean up the pixel format
 33.1197  	if(mPixelFormat != NULL)
 33.1198  	{
 33.1199 -		LL_DEBUGS("Window") << "destroyContext: destroying pixel format " << LL_ENDL;
 33.1200 -		aglDestroyPixelFormat(mPixelFormat);
 33.1201 +		CGLDestroyPixelFormat(mPixelFormat);
 33.1202  		mPixelFormat = NULL;
 33.1203  	}
 33.1204  
 33.1205 -	// Remove any Carbon Event handlers we installed
 33.1206 -	if(mGlobalHandlerRef != NULL)
 33.1207 -	{
 33.1208 -		LL_DEBUGS("Window") << "destroyContext: removing global event handler" << LL_ENDL;
 33.1209 -		RemoveEventHandler(mGlobalHandlerRef);
 33.1210 -		mGlobalHandlerRef = NULL;
 33.1211 -	}
 33.1212 -
 33.1213 -	if(mWindowHandlerRef != NULL)
 33.1214 -	{
 33.1215 -		LL_DEBUGS("Window") << "destroyContext: removing window event handler" << LL_ENDL;
 33.1216 -		RemoveEventHandler(mWindowHandlerRef);
 33.1217 -		mWindowHandlerRef = NULL;
 33.1218 -	}
 33.1219 -
 33.1220 -	// Cleanup any TSM document we created.
 33.1221 -	if(mTSMDocument != NULL)
 33.1222 -	{
 33.1223 -		LL_DEBUGS("Window") << "destroyContext: deleting TSM document" << LL_ENDL;
 33.1224 -		DeactivateTSMDocument(mTSMDocument);
 33.1225 -		DeleteTSMDocument(mTSMDocument);
 33.1226 -		mTSMDocument = NULL;
 33.1227 -	}
 33.1228 -
 33.1229 -	// Close the window
 33.1230 -	if(mWindow != NULL)
 33.1231 -	{
 33.1232 -		LL_DEBUGS("Window") << "destroyContext: disposing window" << LL_ENDL;
 33.1233 -		DisposeWindow(mWindow);
 33.1234 -		mWindow = NULL;
 33.1235 -	}
 33.1236 -
 33.1237  	// Clean up the GL context
 33.1238  	if(mContext != NULL)
 33.1239  	{
 33.1240 -		LL_DEBUGS("Window") << "destroyContext: destroying GL context" << LL_ENDL;
 33.1241 -		aglDestroyContext(mContext);
 33.1242 -		mContext = NULL;
 33.1243 +		CGLDestroyContext(mContext);
 33.1244 +	}
 33.1245 +	
 33.1246 +	// Destroy our LLOpenGLView
 33.1247 +	if(mGLView != NULL)
 33.1248 +	{
 33.1249 +		removeGLView(mGLView);
 33.1250 +		mGLView = NULL;
 33.1251 +	}
 33.1252 +	
 33.1253 +	// Close the window
 33.1254 +	if(mWindow != NULL)
 33.1255 +	{
 33.1256 +        NSWindowRef dead_window = mWindow;
 33.1257 +        mWindow = NULL;
 33.1258 +		closeWindow(dead_window);
 33.1259  	}
 33.1260  
 33.1261  }
 33.1262 @@ -1022,17 +664,11 @@
 33.1263  
 33.1264  void LLWindowMacOSX::show()
 33.1265  {
 33.1266 -	if(IsWindowCollapsed(mWindow))
 33.1267 -		CollapseWindow(mWindow, false);
 33.1268 -
 33.1269 -	MacShowWindow(mWindow);
 33.1270 -	BringToFront(mWindow);
 33.1271  }
 33.1272  
 33.1273  void LLWindowMacOSX::hide()
 33.1274  {
 33.1275  	setMouseClipping(FALSE);
 33.1276 -	HideWindow(mWindow);
 33.1277  }
 33.1278  
 33.1279  //virtual
 33.1280 @@ -1040,7 +676,6 @@
 33.1281  {
 33.1282  	setMouseClipping(FALSE);
 33.1283  	showCursor();
 33.1284 -	CollapseWindow(mWindow, true);
 33.1285  }
 33.1286  
 33.1287  //virtual
 33.1288 @@ -1086,7 +721,6 @@
 33.1289  		result = TRUE;
 33.1290  	}if (mWindow)
 33.1291  	{
 33.1292 -		if(MacIsWindowVisible(mWindow))
 33.1293  			result = TRUE;
 33.1294  	}
 33.1295  
 33.1296 @@ -1107,7 +741,6 @@
 33.1297  {
 33.1298  	if (mWindow && !mMaximized)
 33.1299  	{
 33.1300 -		ZoomWindow(mWindow, inContent, true);
 33.1301  	}
 33.1302  
 33.1303  	return mMaximized;
 33.1304 @@ -1120,58 +753,13 @@
 33.1305  
 33.1306  void LLWindowMacOSX::gatherInput()
 33.1307  {
 33.1308 -	// stop bouncing icon after fixed period of time
 33.1309 -	if (mBounceTimer.getStarted() && mBounceTimer.getElapsedTimeF32() > mBounceTime)
 33.1310 -	{
 33.1311 -		stopDockTileBounce();
 33.1312 -	}
 33.1313 -
 33.1314 -	// Use the old-school version so we get AppleEvent handler dispatch and menuselect handling.
 33.1315 -	// Anything that has an event handler will get processed inside WaitNextEvent, so we only need to handle
 33.1316 -	// the odd stuff here.
 33.1317 -	EventRecord evt;
 33.1318 -	while(WaitNextEvent(everyEvent, &evt, 0, NULL))
 33.1319 -	{
 33.1320 -		//			printf("WaitNextEvent returned true, event is %d.\n", evt.what);
 33.1321 -		switch(evt.what)
 33.1322 -		{
 33.1323 -		case mouseDown:
 33.1324 -			{
 33.1325 -				short part;
 33.1326 -				WindowRef window;
 33.1327 -				long selectResult;
 33.1328 -				part = FindWindow(evt.where, &window);
 33.1329 -				switch ( part )
 33.1330 -				{
 33.1331 -				case inMenuBar:
 33.1332 -					selectResult = MenuSelect(evt.where);
 33.1333 -
 33.1334 -					HiliteMenu(0);
 33.1335 -					break;
 33.1336 -				}
 33.1337 -			}
 33.1338 -			break;
 33.1339 -
 33.1340 -		case kHighLevelEvent:
 33.1341 -			AEProcessAppleEvent (&evt);
 33.1342 -			break;
 33.1343 -
 33.1344 -		case updateEvt:
 33.1345 -			// We shouldn't be getting these regularly (since our window will be buffered), but we need to handle them correctly...
 33.1346 -			BeginUpdate((WindowRef)evt.message);
 33.1347 -			EndUpdate((WindowRef)evt.message);
 33.1348 -			break;
 33.1349 -
 33.1350 -		}
 33.1351 -	}
 33.1352 -	
 33.1353  	updateCursor();
 33.1354  }
 33.1355  
 33.1356  BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
 33.1357  {
 33.1358 -	Rect window_rect;
 33.1359 -	OSStatus err = -1;
 33.1360 +	float rect[4];
 33.1361 +	S32 err = -1;
 33.1362  
 33.1363  	if(mFullscreen)
 33.1364  	{
 33.1365 @@ -1181,10 +769,10 @@
 33.1366  	}
 33.1367  	else if(mWindow)
 33.1368  	{
 33.1369 -		err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect);
 33.1370 +		getContentViewBounds(mWindow, rect);
 33.1371  
 33.1372 -		position->mX = window_rect.left;
 33.1373 -		position->mY = window_rect.top;
 33.1374 +		position->mX = rect[0];
 33.1375 +		position->mY = rect[1];
 33.1376  	}
 33.1377  	else
 33.1378  	{
 33.1379 @@ -1196,8 +784,8 @@
 33.1380  
 33.1381  BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 33.1382  {
 33.1383 -	Rect window_rect;
 33.1384 -	OSStatus err = -1;
 33.1385 +	float rect[4];
 33.1386 +	S32 err = -1;
 33.1387  
 33.1388  	if(mFullscreen)
 33.1389  	{
 33.1390 @@ -1207,10 +795,10 @@
 33.1391  	}
 33.1392  	else if(mWindow)
 33.1393  	{
 33.1394 -		err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect);
 33.1395 +		getContentViewBounds(mWindow, rect);
 33.1396  
 33.1397 -		size->mX = window_rect.right - window_rect.left;
 33.1398 -		size->mY = window_rect.bottom - window_rect.top;
 33.1399 +		size->mX = rect[2];
 33.1400 +		size->mY = rect[3];
 33.1401  	}
 33.1402  	else
 33.1403  	{
 33.1404 @@ -1222,9 +810,9 @@
 33.1405  
 33.1406  BOOL LLWindowMacOSX::getSize(LLCoordWindow *size)
 33.1407  {
 33.1408 -	Rect window_rect;
 33.1409 -	OSStatus err = -1;
 33.1410 -
 33.1411 +	float rect[4];
 33.1412 +	S32 err = -1;
 33.1413 +	
 33.1414  	if(mFullscreen)
 33.1415  	{
 33.1416  		size->mX = mFullscreenWidth;
 33.1417 @@ -1233,16 +821,16 @@
 33.1418  	}
 33.1419  	else if(mWindow)
 33.1420  	{
 33.1421 -		err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect);
 33.1422 -
 33.1423 -		size->mX = window_rect.right - window_rect.left;
 33.1424 -		size->mY = window_rect.bottom - window_rect.top;
 33.1425 +		getContentViewBounds(mWindow, rect);
 33.1426 +		
 33.1427 +		size->mX = rect[2];
 33.1428 +		size->mY = rect[3];
 33.1429  	}
 33.1430  	else
 33.1431  	{
 33.1432  		llerrs << "LLWindowMacOSX::getPosition(): no window and not fullscreen!" << llendl;
 33.1433  	}
 33.1434 -
 33.1435 +	
 33.1436  	return (err == noErr);
 33.1437  }
 33.1438  
 33.1439 @@ -1250,7 +838,8 @@
 33.1440  {
 33.1441  	if(mWindow)
 33.1442  	{
 33.1443 -		MacMoveWindow(mWindow, position.mX, position.mY, false);
 33.1444 +		float pos[2] = {position.mX, position.mY};
 33.1445 +		setWindowPos(mWindow, pos);
 33.1446  	}
 33.1447  
 33.1448  	return TRUE;
 33.1449 @@ -1260,45 +849,35 @@
 33.1450  {
 33.1451  	if(mWindow)
 33.1452  	{
 33.1453 -		SizeWindow(mWindow, size.mX, size.mY, true);
 33.1454 +        LLCoordWindow to;
 33.1455 +        convertCoords(size, &to);
 33.1456 +		setWindowSize(mWindow, to.mX, to.mY);
 33.1457 +        return TRUE;
 33.1458  	}
 33.1459  
 33.1460 -	return TRUE;
 33.1461 +	return FALSE;
 33.1462  }
 33.1463  
 33.1464  BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size)
 33.1465  {
 33.1466 -	Rect client_rect;
 33.1467  	if (mWindow)
 33.1468  	{
 33.1469 -		OSStatus err = GetWindowBounds(mWindow, kWindowContentRgn, &client_rect);
 33.1470 -		if (err == noErr)
 33.1471 -		{
 33.1472 -			client_rect.right = client_rect.left + size.mX;
 33.1473 -			client_rect.bottom = client_rect.top + size.mY;
 33.1474 -			err = SetWindowBounds(mWindow, kWindowContentRgn, &client_rect);
 33.1475 -		}
 33.1476 -		if (err == noErr)
 33.1477 -		{
 33.1478 -			return TRUE;
 33.1479 -		}
 33.1480 -		else
 33.1481 -		{
 33.1482 -			llinfos << "Error setting size" << err << llendl;
 33.1483 -			return FALSE;
 33.1484 -		}
 33.1485 +        const int titlePadding = 22;
 33.1486 +        setWindowSize(mWindow, size.mX, size.mY + titlePadding);
 33.1487 +        return TRUE;
 33.1488  	}
 33.1489 +    
 33.1490  	return FALSE;
 33.1491  }
 33.1492  
 33.1493  void LLWindowMacOSX::swapBuffers()
 33.1494  {
 33.1495 -	aglSwapBuffers(mContext);
 33.1496 +	CGLFlushDrawable(mContext);
 33.1497  }
 33.1498  
 33.1499  F32 LLWindowMacOSX::getGamma()
 33.1500  {
 33.1501 -	F32 result = 1.8;	// Default to something sane
 33.1502 +	F32 result = 2.2;	// Default to something sane
 33.1503  
 33.1504  	CGGammaValue redMin;
 33.1505  	CGGammaValue redMax;
 33.1506 @@ -1454,39 +1033,15 @@
 33.1507  	return result;
 33.1508  }
 33.1509  
 33.1510 -static void fixOrigin(void)
 33.1511 -{
 33.1512 -	GrafPtr port;
 33.1513 -	Rect portrect;
 33.1514 -
 33.1515 -	::GetPort(&port);
 33.1516 -	::GetPortBounds(port, &portrect);
 33.1517 -	if((portrect.left != 0) || (portrect.top != 0))
 33.1518 -	{
 33.1519 -		// Mozilla sometimes changes our port origin.
 33.1520 -		::SetOrigin(0,0);
 33.1521 -	}
 33.1522 -}
 33.1523 -
 33.1524  BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position)
 33.1525  {
 33.1526 -	Point cursor_point;
 33.1527 +	float cursor_point[2];
 33.1528  	LLCoordScreen screen_pos;
 33.1529 -	GrafPtr save;
 33.1530  
 33.1531  	if(mWindow == NULL)
 33.1532  		return FALSE;
 33.1533 -
 33.1534 -	::GetPort(&save);
 33.1535 -	::SetPort(GetWindowPort(mWindow));
 33.1536 -	fixOrigin();
 33.1537 -
 33.1538 -	// gets the mouse location in local coordinates
 33.1539 -	::GetMouse(&cursor_point);
 33.1540 -
 33.1541 -//	lldebugs << "getCursorPosition(): cursor is at " << cursor_point.h << ", " << cursor_point.v << "  port origin: " << portrect.left << ", " << portrect.top << llendl;
 33.1542 -
 33.1543 -	::SetPort(save);
 33.1544 +	
 33.1545 +	getCursorPos(mWindow, cursor_point);
 33.1546  
 33.1547  	if(mCursorDecoupled)
 33.1548  	{
 33.1549 @@ -1499,12 +1054,12 @@
 33.1550  
 33.1551  		// CGGetLastMouseDelta may behave strangely when the cursor's first captured.
 33.1552  		// Stash in the event handler instead.
 33.1553 -		cursor_point.h += mCursorLastEventDeltaX;
 33.1554 -		cursor_point.v += mCursorLastEventDeltaY;
 33.1555 +		cursor_point[0] += mCursorLastEventDeltaX;
 33.1556 +		cursor_point[1] += mCursorLastEventDeltaY;
 33.1557  	}
 33.1558  
 33.1559 -	position->mX = cursor_point.h;
 33.1560 -	position->mY = cursor_point.v;
 33.1561 +	position->mX = cursor_point[0];
 33.1562 +	position->mY = cursor_point[1];
 33.1563  
 33.1564  	return TRUE;
 33.1565  }
 33.1566 @@ -1521,7 +1076,6 @@
 33.1567  				//			llinfos << "adjustCursorDecouple: decoupling cursor" << llendl;
 33.1568  				CGAssociateMouseAndMouseCursorPosition(false);
 33.1569  				mCursorDecoupled = true;
 33.1570 -				FlushSpecificEventsFromQueue(GetCurrentEventQueue(), mMoveEventCampartorUPP, NULL);
 33.1571  				mCursorIgnoreNextDelta = TRUE;
 33.1572  			}
 33.1573  		}
 33.1574 @@ -1568,179 +1122,46 @@
 33.1575  
 33.1576  // MBW -- XXX -- There's got to be a better way than this.  Find it, please...
 33.1577  
 33.1578 +// Since we're no longer supporting the "typical" fullscreen mode with CGL or NSOpenGL anymore, these are unnecessary. -Geenz
 33.1579  void LLWindowMacOSX::beforeDialog()
 33.1580  {
 33.1581 -	if(mFullscreen)
 33.1582 -	{
 33.1583 -
 33.1584 -#if CAPTURE_ALL_DISPLAYS
 33.1585 -		// Uncapture all displays (may want to do this for final build)
 33.1586 -		CGReleaseAllDisplays ();
 33.1587 -#else
 33.1588 -		// Uncapture only the main display (useful for debugging)
 33.1589 -		CGDisplayRelease (mDisplay);
 33.1590 -#endif
 33.1591 -		// kDocumentWindowClass
 33.1592 -		// kMovableModalWindowClass
 33.1593 -		// kAllWindowClasses
 33.1594 -
 33.1595 -		//		GLint order = 0;
 33.1596 -		//		aglSetInteger(mContext, AGL_ORDER_CONTEXT_TO_FRONT, &order);
 33.1597 -		aglSetDrawable(mContext, NULL);
 33.1598 -		//		GetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), &oldWindowLevel);
 33.1599 -		//		SetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), CGShieldingWindowLevel());
 33.1600 -
 33.1601 -		mHandsOffEvents = TRUE;
 33.1602 -
 33.1603 -	}
 33.1604  }
 33.1605  
 33.1606  void LLWindowMacOSX::afterDialog()
 33.1607  {
 33.1608 -	if(mFullscreen)
 33.1609 -	{
 33.1610 -		mHandsOffEvents = FALSE;
 33.1611 -
 33.1612 -		//		SetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), oldWindowLevel);
 33.1613 -		aglSetFullScreen(mContext, 0, 0, 0, 0);
 33.1614 -		//		GLint order = 1;
 33.1615 -		//		aglSetInteger(mContext, AGL_ORDER_CONTEXT_TO_FRONT, &order);
 33.1616 -
 33.1617 -#if CAPTURE_ALL_DISPLAYS
 33.1618 -		// Capture all displays (may want to do this for final build)
 33.1619 -		CGCaptureAllDisplays ();
 33.1620 -#else
 33.1621 -		// Capture only the main display (useful for debugging)
 33.1622 -		CGDisplayCapture (mDisplay);
 33.1623 -#endif
 33.1624 -	}
 33.1625  }
 33.1626  
 33.1627  
 33.1628  void LLWindowMacOSX::flashIcon(F32 seconds)
 33.1629  {
 33.1630 -	// Don't do this if we're already started, since this would try to install the NMRec twice.
 33.1631 -	if(!mBounceTimer.getStarted())
 33.1632 -	{
 33.1633 -		OSErr err;
 33.1634 -
 33.1635 -		mBounceTime = seconds;
 33.1636 -		memset(&mBounceRec, 0, sizeof(mBounceRec));
 33.1637 -		mBounceRec.qType = nmType;
 33.1638 -		mBounceRec.nmMark = 1;
 33.1639 -		err = NMInstall(&mBounceRec);
 33.1640 -		if(err == noErr)
 33.1641 -		{
 33.1642 -			mBounceTimer.start();
 33.1643 -		}
 33.1644 -		else
 33.1645 -		{
 33.1646 -			// This is very not-fatal (only problem is the icon will not bounce), but we'd like to find out about it somehow...
 33.1647 -			llinfos << "NMInstall failed with error code " << err << llendl;
 33.1648 -		}
 33.1649 -	}
 33.1650 +	// For consistency with OS X conventions, the number of seconds given is ignored and
 33.1651 +	// left up to the OS (which will actually bounce it for one second).
 33.1652 +	requestUserAttention();
 33.1653  }
 33.1654  
 33.1655  BOOL LLWindowMacOSX::isClipboardTextAvailable()
 33.1656  {
 33.1657 -	OSStatus err;
 33.1658 -	ScrapRef scrap;
 33.1659 -	ScrapFlavorFlags flags;
 33.1660 -	BOOL result = false;
 33.1661 -
 33.1662 -	err = GetCurrentScrap(&scrap);
 33.1663 -
 33.1664 -	if(err == noErr)
 33.1665 -	{
 33.1666 -		err = GetScrapFlavorFlags(scrap, kScrapFlavorTypeUnicode, &flags);
 33.1667 -	}
 33.1668 -
 33.1669 -	if(err == noErr)
 33.1670 -		result = true;
 33.1671 -
 33.1672 -	return result;
 33.1673 +	return pasteBoardAvailable();
 33.1674  }
 33.1675  
 33.1676  BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst)
 33.1677 -{
 33.1678 -	OSStatus err;
 33.1679 -	ScrapRef scrap;
 33.1680 -	Size len;
 33.1681 -	BOOL result = false;
 33.1682 -
 33.1683 -	err = GetCurrentScrap(&scrap);
 33.1684 -
 33.1685 -	if(err == noErr)
 33.1686 +{	
 33.1687 +	llutf16string str(copyFromPBoard());
 33.1688 +	dst = utf16str_to_wstring(str);
 33.1689 +	if (dst != L"")
 33.1690  	{
 33.1691 -		err = GetScrapFlavorSize(scrap, kScrapFlavorTypeUnicode, &len);
 33.1692 +		return true;
 33.1693 +	} else {
 33.1694 +		return false;
 33.1695  	}
 33.1696 -
 33.1697 -	if((err == noErr) && (len > 0))
 33.1698 -	{
 33.1699 -		int u16len = len / sizeof(U16);
 33.1700 -		U16 *temp = new U16[u16len + 1];
 33.1701 -		if (temp)
 33.1702 -		{
 33.1703 -			memset(temp, 0, (u16len + 1) * sizeof(temp[0]));
 33.1704 -			err = GetScrapFlavorData(scrap, kScrapFlavorTypeUnicode, &len, temp);
 33.1705 -			if (err == noErr)
 33.1706 -			{
 33.1707 -				// convert \r\n to \n and \r to \n in the incoming text.
 33.1708 -				U16 *s, *d;
 33.1709 -				for(s = d = temp; s[0] != '\0'; s++, d++)
 33.1710 -				{
 33.1711 -					if(s[0] == '\r')
 33.1712 -					{
 33.1713 -						if(s[1] == '\n')
 33.1714 -						{
 33.1715 -							// CRLF, a.k.a. DOS newline.  Collapse to a single '\n'.
 33.1716 -							s++;
 33.1717 -						}
 33.1718 -
 33.1719 -						d[0] = '\n';
 33.1720 -					}
 33.1721 -					else
 33.1722 -					{
 33.1723 -						d[0] = s[0];
 33.1724 -					}
 33.1725 -				}
 33.1726 -
 33.1727 -				d[0] = '\0';
 33.1728 -
 33.1729 -				dst = utf16str_to_wstring(temp);
 33.1730 -
 33.1731 -				result = true;
 33.1732 -			}
 33.1733 -			delete[] temp;
 33.1734 -		}
 33.1735 -	}
 33.1736 -
 33.1737 -	return result;
 33.1738  }
 33.1739  
 33.1740  BOOL LLWindowMacOSX::copyTextToClipboard(const LLWString &s)
 33.1741  {
 33.1742 -	OSStatus err;
 33.1743 -	ScrapRef scrap;
 33.1744 -	//Size len;
 33.1745 -	//char *temp;
 33.1746  	BOOL result = false;
 33.1747 -
 33.1748 -	if (!s.empty())
 33.1749 -	{
 33.1750 -		err = GetCurrentScrap(&scrap);
 33.1751 -		if (err == noErr)
 33.1752 -			err = ClearScrap(&scrap);
 33.1753 -
 33.1754 -		if (err == noErr)
 33.1755 -		{
 33.1756 -			llutf16string utf16str = wstring_to_utf16str(s);
 33.1757 -			size_t u16len = utf16str.length() * sizeof(U16);
 33.1758 -			err = PutScrapFlavor(scrap, kScrapFlavorTypeUnicode, kScrapFlavorMaskNone, u16len, utf16str.data());
 33.1759 -			if (err == noErr)
 33.1760 -				result = true;
 33.1761 -		}
 33.1762 -	}
 33.1763 +	llutf16string utf16str = wstring_to_utf16str(s);
 33.1764 +	
 33.1765 +	result = copyToPBoard(utf16str.data(), utf16str.length());
 33.1766  
 33.1767  	return result;
 33.1768  }
 33.1769 @@ -1806,122 +1227,52 @@
 33.1770  
 33.1771  BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordWindow *to)
 33.1772  {
 33.1773 -	S32		client_height;
 33.1774 -	Rect	client_rect;
 33.1775 -
 33.1776 -	if(mFullscreen)
 33.1777 -	{
 33.1778 -		// In the fullscreen case, the "window" is the entire screen.
 33.1779 -		client_rect.left = 0;
 33.1780 -		client_rect.top = 0;
 33.1781 -		client_rect.right = mFullscreenWidth;
 33.1782 -		client_rect.bottom = mFullscreenHeight;
 33.1783 -	}
 33.1784 -	else if (!mWindow ||
 33.1785 -		(GetWindowBounds(mWindow, kWindowContentRgn, &client_rect) != noErr) ||
 33.1786 -		NULL == to)
 33.1787 -	{
 33.1788 -		return FALSE;
 33.1789 -	}
 33.1790 -
 33.1791  	to->mX = from.mX;
 33.1792 -	client_height = client_rect.bottom - client_rect.top;
 33.1793 -	to->mY = client_height - from.mY - 1;
 33.1794 -
 33.1795 +	to->mY = from.mY;
 33.1796  	return TRUE;
 33.1797  }
 33.1798  
 33.1799  BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordGL* to)
 33.1800  {
 33.1801 -	S32		client_height;
 33.1802 -	Rect	client_rect;
 33.1803 -
 33.1804 -	if(mFullscreen)
 33.1805 -	{
 33.1806 -		// In the fullscreen case, the "window" is the entire screen.
 33.1807 -		client_rect.left = 0;
 33.1808 -		client_rect.top = 0;
 33.1809 -		client_rect.right = mFullscreenWidth;
 33.1810 -		client_rect.bottom = mFullscreenHeight;
 33.1811 -	}
 33.1812 -	else if (!mWindow ||
 33.1813 -		(GetWindowBounds(mWindow, kWindowContentRgn, &client_rect) != noErr) ||
 33.1814 -		NULL == to)
 33.1815 -	{
 33.1816 -		return FALSE;
 33.1817 -	}
 33.1818 -
 33.1819  	to->mX = from.mX;
 33.1820 -	client_height = client_rect.bottom - client_rect.top;
 33.1821 -	to->mY = client_height - from.mY - 1;
 33.1822 -
 33.1823 +	to->mY = from.mY;
 33.1824  	return TRUE;
 33.1825  }
 33.1826  
 33.1827  BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to)
 33.1828  {
 33.1829 -	if(mFullscreen)
 33.1830 +	if(mWindow)
 33.1831  	{
 33.1832 -		// In the fullscreen case, window and screen coordinates are the same.
 33.1833 -		to->mX = from.mX;
 33.1834 -		to->mY = from.mY;
 33.1835 -		return TRUE;
 33.1836 -	}
 33.1837 -	else if(mWindow)
 33.1838 -	{
 33.1839 -		GrafPtr save;
 33.1840 -		Point mouse_point;
 33.1841 +		float mouse_point[2];
 33.1842  
 33.1843 -		mouse_point.h = from.mX;
 33.1844 -		mouse_point.v = from.mY;
 33.1845 +		mouse_point[0] = from.mX;
 33.1846 +		mouse_point[1] = from.mY;
 33.1847 +		
 33.1848 +		convertScreenToWindow(mWindow, mouse_point);
 33.1849  
 33.1850 -		::GetPort(&save);
 33.1851 -		::SetPort(GetWindowPort(mWindow));
 33.1852 -		fixOrigin();
 33.1853 -
 33.1854 -		::GlobalToLocal(&mouse_point);
 33.1855 -
 33.1856 -		to->mX = mouse_point.h;
 33.1857 -		to->mY = mouse_point.v;
 33.1858 -
 33.1859 -		::SetPort(save);
 33.1860 +		to->mX = mouse_point[0];
 33.1861 +		to->mY = mouse_point[1];
 33.1862  
 33.1863  		return TRUE;
 33.1864  	}
 33.1865 -
 33.1866  	return FALSE;
 33.1867  }
 33.1868  
 33.1869  BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to)
 33.1870  {
 33.1871 -	if(mFullscreen)
 33.1872 +	if(mWindow)
 33.1873  	{
 33.1874 -		// In the fullscreen case, window and screen coordinates are the same.
 33.1875 -		to->mX = from.mX;
 33.1876 -		to->mY = from.mY;
 33.1877 -		return TRUE;
 33.1878 -	}
 33.1879 -	else if(mWindow)
 33.1880 -	{
 33.1881 -		GrafPtr save;
 33.1882 -		Point mouse_point;
 33.1883 +		float mouse_point[2];
 33.1884  
 33.1885 -		mouse_point.h = from.mX;
 33.1886 -		mouse_point.v = from.mY;
 33.1887 -		::GetPort(&save);
 33.1888 -		::SetPort(GetWindowPort(mWindow));
 33.1889 -		fixOrigin();
 33.1890 +		mouse_point[0] = from.mX;
 33.1891 +		mouse_point[1] = from.mY;
 33.1892 +		convertWindowToScreen(mWindow, mouse_point);
 33.1893  
 33.1894 -		LocalToGlobal(&mouse_point);
 33.1895 -
 33.1896 -		to->mX = mouse_point.h;
 33.1897 -		to->mY = mouse_point.v;
 33.1898 -
 33.1899 -		::SetPort(save);
 33.1900 +		to->mX = mouse_point[0];
 33.1901 +		to->mY = mouse_point[1];
 33.1902  
 33.1903  		return TRUE;
 33.1904  	}
 33.1905 -
 33.1906  	return FALSE;
 33.1907  }
 33.1908  
 33.1909 @@ -1949,862 +1300,6 @@
 33.1910  	OSMessageBox(text, caption, type);
 33.1911  }
 33.1912  
 33.1913 -pascal Boolean LLWindowMacOSX::staticMoveEventComparator( EventRef event, void* data)
 33.1914 -{
 33.1915 -	UInt32 				evtClass = GetEventClass (event);
 33.1916 -	UInt32 				evtKind = GetEventKind (event);
 33.1917 -
 33.1918 -	if ((evtClass == kEventClassMouse) && ((evtKind == kEventMouseDragged) || (evtKind == kEventMouseMoved)))
 33.1919 -	{
 33.1920 -		return true;
 33.1921 -	}
 33.1922 -
 33.1923 -	else
 33.1924 -	{
 33.1925 -		return false;
 33.1926 -	}
 33.1927 -}
 33.1928 -
 33.1929 -
 33.1930 -pascal OSStatus LLWindowMacOSX::staticEventHandler(EventHandlerCallRef myHandler, EventRef event, void* userData)
 33.1931 -{
 33.1932 -	LLWindowMacOSX *self = (LLWindowMacOSX*)userData;
 33.1933 -
 33.1934 -	return(self->eventHandler(myHandler, event));
 33.1935 -}
 33.1936 -
 33.1937 -OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef event)
 33.1938 -{
 33.1939 -	OSStatus			result = eventNotHandledErr;
 33.1940 -	UInt32 				evtClass = GetEventClass (event);
 33.1941 -	UInt32 				evtKind = GetEventKind (event);
 33.1942 -
 33.1943 -	// Always handle command events, even in hands-off mode.
 33.1944 -	if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
 33.1945 -	{
 33.1946 -		HICommand command;
 33.1947 -		GetEventParameter (event, kEventParamDirectObject, typeHICommand, NULL, sizeof(command), NULL, &command);
 33.1948 -
 33.1949 -		switch(command.commandID)
 33.1950 -		{
 33.1951 -		case kHICommandQuit:
 33.1952 -			if(mCallbacks->handleCloseRequest(this))
 33.1953 -			{
 33.1954 -				// Get the app to initiate cleanup.
 33.1955 -				mCallbacks->handleQuit(this);
 33.1956 -				// The app is responsible for calling destroyWindow when done with GL
 33.1957 -			}
 33.1958 -			result = noErr;
 33.1959 -			break;
 33.1960 -
 33.1961 -		default:
 33.1962 -			// MBW -- XXX -- Should we handle other events here?
 33.1963 -			break;
 33.1964 -		}
 33.1965 -	}
 33.1966 -
 33.1967 -	if(mHandsOffEvents)
 33.1968 -	{
 33.1969 -		return(result);
 33.1970 -	}
 33.1971 -
 33.1972 -	switch (evtClass)
 33.1973 -	{
 33.1974 -	case kEventClassTextInput:
 33.1975 -		{
 33.1976 -			switch (evtKind)
 33.1977 -			{
 33.1978 -			case kEventTextInputUpdateActiveInputArea:
 33.1979 -				{
 33.1980 -					EventParamType param_type;
 33.1981 -
 33.1982 -					long fix_len;
 33.1983 -					UInt32 text_len;
 33.1984 -					if (mPreeditor
 33.1985 -						&& (result = GetEventParameter(event, kEventParamTextInputSendFixLen,
 33.1986 -										typeLongInteger, &param_type, sizeof(fix_len), NULL, &fix_len)) == noErr
 33.1987 -						&& typeLongInteger == param_type
 33.1988 -						&& (result = GetEventParameter(event, kEventParamTextInputSendText,
 33.1989 -										typeUnicodeText, &param_type, 0, &text_len, NULL)) == noErr
 33.1990 -						&& typeUnicodeText == param_type)
 33.1991 -					{
 33.1992 -						// Handle an optional (but essential to facilitate TSMDA) ReplaceRange param.
 33.1993 -						CFRange range;
 33.1994 -						if (GetEventParameter(event, kEventParamTextInputSendReplaceRange,
 33.1995 -								typeCFRange, &param_type, sizeof(range), NULL, &range) == noErr
 33.1996 -							&& typeCFRange == param_type)
 33.1997 -						{
 33.1998 -							// Although the spec. is unclear, replace range should
 33.1999 -							// not present when there is an active preedit.  We just
 33.2000 -							// ignore the case.  markAsPreedit will detect the case and warn it.
 33.2001 -							const LLWString & text = mPreeditor->getPreeditString();
 33.2002 -							const S32 location = wstring_wstring_length_from_utf16_length(text, 0, range.location);
 33.2003 -							const S32 length = wstring_wstring_length_from_utf16_length(text, location, range.length);
 33.2004 -							mPreeditor->markAsPreedit(location, length);
 33.2005 -						}
 33.2006 -						mPreeditor->resetPreedit();
 33.2007 -
 33.2008 -						// Receive the text from input method.
 33.2009 -						U16 *const text = new U16[text_len / sizeof(U16)];
 33.2010 -						GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, NULL, text_len, NULL, text);
 33.2011 -						if (fix_len < 0)
 33.2012 -						{
 33.2013 -							// Do we still need this?  Seems obsolete...
 33.2014 -							fix_len = text_len;
 33.2015 -						}
 33.2016 -						const LLWString fix_string
 33.2017 -								= utf16str_to_wstring(llutf16string(text, fix_len / sizeof(U16)));
 33.2018 -						const LLWString preedit_string
 33.2019 -								= utf16str_to_wstring(llutf16string(text + fix_len / sizeof(U16), (text_len - fix_len) / sizeof(U16)));
 33.2020 -						delete[] text;
 33.2021 -
 33.2022 -						// Handle fixed (comitted) string.
 33.2023 -						if (fix_string.length() > 0)
 33.2024 -						{
 33.2025 -							for (LLWString::const_iterator i = fix_string.begin(); i != fix_string.end(); i++)
 33.2026 -							{
 33.2027 -								mPreeditor->handleUnicodeCharHere(*i);
 33.2028 -							}
 33.2029 -						}
 33.2030 -
 33.2031 -						// Receive the segment info and caret position.
 33.2032 -						LLPreeditor::segment_lengths_t preedit_segment_lengths;
 33.2033 -						LLPreeditor::standouts_t preedit_standouts;
 33.2034 -						S32 caret_position = preedit_string.length();
 33.2035 -						UInt32 text_range_array_size;
 33.2036 -						if (GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray,
 33.2037 -								&param_type, 0, &text_range_array_size, NULL) == noErr
 33.2038 -							&& typeTextRangeArray == param_type
 33.2039 -							&& text_range_array_size > sizeof(TextRangeArray))
 33.2040 -						{
 33.2041 -							// TextRangeArray is a variable-length struct.
 33.2042 -							TextRangeArray * const text_range_array = (TextRangeArray *) new char[text_range_array_size];
 33.2043 -							GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray,
 33.2044 -									NULL, text_range_array_size, NULL, text_range_array);
 33.2045 -
 33.2046 -							// WARNING: We assume ranges are in ascending order,
 33.2047 -							// although the condition is undocumented.  It seems
 33.2048 -							// OK to assume this.  I also assumed
 33.2049 -							// the ranges are contiguous in previous versions, but I
 33.2050 -							// have heard a rumore that older versions os ATOK may
 33.2051 -							// return ranges with some _gap_.  I don't know whether
 33.2052 -							// it is true, but I'm preparing my code for the case.
 33.2053 -
 33.2054 -							const S32 ranges = text_range_array->fNumOfRanges;
 33.2055 -							preedit_segment_lengths.reserve(ranges);
 33.2056 -							preedit_standouts.reserve(ranges);
 33.2057 -
 33.2058 -							S32 last_bytes = 0;
 33.2059 -							S32 last_utf32 = 0;
 33.2060 -							for (S32 i = 0; i < ranges; i++)
 33.2061 -							{
 33.2062 -								const TextRange &range = text_range_array->fRange[i];
 33.2063 -								if (range.fStart > last_bytes)
 33.2064 -								{
 33.2065 -									const S32 length_utf16 = (range.fStart - last_bytes) / sizeof(U16);
 33.2066 -									const S32 length_utf32 = wstring_wstring_length_from_utf16_length(preedit_string, last_utf32, length_utf16);
 33.2067 -									preedit_segment_lengths.push_back(length_utf32);
 33.2068 -									preedit_standouts.push_back(FALSE);
 33.2069 -									last_utf32 += length_utf32;
 33.2070 -								}
 33.2071 -								if (range.fEnd > range.fStart)
 33.2072 -								{
 33.2073 -									const S32 length_utf16 = (range.fEnd - range.fStart) / sizeof(U16);
 33.2074 -									const S32 length_utf32 = wstring_wstring_length_from_utf16_length(preedit_string, last_utf32, length_utf16);
 33.2075 -									preedit_segment_lengths.push_back(length_utf32);
 33.2076 -									preedit_standouts.push_back(
 33.2077 -										kTSMHiliteSelectedRawText == range.fHiliteStyle
 33.2078 -										|| kTSMHiliteSelectedConvertedText ==  range.fHiliteStyle
 33.2079 -										|| kTSMHiliteSelectedText == range.fHiliteStyle);
 33.2080 -									last_utf32 += length_utf32;
 33.2081 -								}
 33.2082 -								if (kTSMHiliteCaretPosition == range.fHiliteStyle)
 33.2083 -								{
 33.2084 -									caret_position = last_utf32;
 33.2085 -								}
 33.2086 -								last_bytes = range.fEnd;
 33.2087 -							}
 33.2088 -							if (preedit_string.length() > last_utf32)
 33.2089 -							{
 33.2090 -								preedit_segment_lengths.push_back(preedit_string.length() - last_utf32);
 33.2091 -								preedit_standouts.push_back(FALSE);
 33.2092 -							}
 33.2093 -
 33.2094 -							delete[] (char *) text_range_array;
 33.2095 -						}
 33.2096 -
 33.2097 -						// Handle preedit string.
 33.2098 -						if (preedit_string.length() == 0)
 33.2099 -						{
 33.2100 -							preedit_segment_lengths.clear();
 33.2101 -							preedit_standouts.clear();
 33.2102 -						}
 33.2103 -						else if (preedit_segment_lengths.size() == 0)
 33.2104 -						{
 33.2105 -							preedit_segment_lengths.push_back(preedit_string.length());
 33.2106 -							preedit_standouts.push_back(FALSE);
 33.2107 -						}
 33.2108 -						mPreeditor->updatePreedit(preedit_string, preedit_segment_lengths, preedit_standouts, caret_position);
 33.2109 -
 33.2110 -						result = noErr;
 33.2111 -					}
 33.2112 -				}
 33.2113 -				break;
 33.2114 -
 33.2115 -			case kEventTextInputUnicodeForKeyEvent:
 33.2116 -				{
 33.2117 -					UInt32 modifiers = 0;
 33.2118 -
 33.2119 -
 33.2120 -					// First, process the raw event.
 33.2121 -					{
 33.2122 -						EventRef rawEvent = NULL;
 33.2123 -
 33.2124 -						// Get the original event and extract the modifier keys, so we can ignore command-key events.
 33.2125 -						if (GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent) == noErr)
 33.2126 -						{
 33.2127 -							// Grab the modifiers for later use in this function...
 33.2128 -							GetEventParameter (rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
 33.2129 -
 33.2130 -							// and call this function recursively to handle the raw key event.
 33.2131 -							eventHandler (myHandler, rawEvent);
 33.2132 -
 33.2133 -							// save the raw event until we're done processing the unicode input as well.
 33.2134 -							mRawKeyEvent = rawEvent;
 33.2135 -						}
 33.2136 -					}
 33.2137 -
 33.2138 -					OSStatus err = noErr;
 33.2139 -					EventParamType actualType = typeUnicodeText;
 33.2140 -					UInt32 actualSize = 0;
 33.2141 -					size_t actualCount = 0;
 33.2142 -					U16 *buffer = NULL;
 33.2143 -
 33.2144 -					// Get the size of the unicode data
 33.2145 -					err = GetEventParameter (event, kEventParamTextInputSendText, typeUnicodeText, &actualType, 0, &actualSize, NULL);
 33.2146 -					if(err == noErr)
 33.2147 -					{
 33.2148 -						// allocate a buffer and get the actual data.
 33.2149 -						actualCount = actualSize / sizeof(U16);
 33.2150 -						buffer = new U16[actualCount];
 33.2151 -						err = GetEventParameter (event, kEventParamTextInputSendText, typeUnicodeText, &actualType, actualSize, &actualSize, buffer);
 33.2152 -					}
 33.2153 -
 33.2154 -					if(err == noErr)
 33.2155 -					{
 33.2156 -						if(modifiers & (cmdKey | controlKey))
 33.2157 -						{
 33.2158 -							// This was a menu key equivalent.  Ignore it.
 33.2159 -						}
 33.2160 -						else
 33.2161 -						{
 33.2162 -							MASK mask = LLWindowMacOSX::modifiersToMask(modifiers);
 33.2163 -
 33.2164 -							llassert( actualType == typeUnicodeText );
 33.2165 -
 33.2166 -							// The result is a UTF16 buffer.  Pass the characters in turn to handleUnicodeChar.
 33.2167 -
 33.2168 -							// Convert to UTF32 and go character-by-character.
 33.2169 -							llutf16string utf16(buffer, actualCount);
 33.2170 -							LLWString utf32 = utf16str_to_wstring(utf16);
 33.2171 -							LLWString::iterator iter;
 33.2172 -
 33.2173 -							for(iter = utf32.begin(); iter != utf32.end(); iter++)
 33.2174 -							{
 33.2175 -								mCallbacks->handleUnicodeChar(*iter, mask);
 33.2176 -							}
 33.2177 -						}
 33.2178 -					}
 33.2179 -
 33.2180 -					if(buffer != NULL)
 33.2181 -					{
 33.2182 -						delete[] buffer;
 33.2183 -					}
 33.2184 -
 33.2185 -					mRawKeyEvent = NULL;
 33.2186 -					result = err;
 33.2187 -				}
 33.2188 -				break;
 33.2189 -
 33.2190 -			case kEventTextInputOffsetToPos:
 33.2191 -				{
 33.2192 -					EventParamType param_type;
 33.2193 -					long offset;
 33.2194 -					if (mPreeditor
 33.2195 -						&& GetEventParameter(event, kEventParamTextInputSendTextOffset, typeLongInteger,
 33.2196 -								&param_type, sizeof(offset), NULL, &offset) == noErr
 33.2197 -						&& typeLongInteger == param_type)
 33.2198 -					{
 33.2199 -						S32 preedit, preedit_length;
 33.2200 -						mPreeditor->getPreeditRange(&preedit, &preedit_length);
 33.2201 -						const LLWString & text = mPreeditor->getPreeditString();
 33.2202 -
 33.2203 -						LLCoordGL caret_coord;
 33.2204 -						LLRect preedit_bounds;
 33.2205 -						if (0 <= offset
 33.2206 -							&& mPreeditor->getPreeditLocation(wstring_wstring_length_from_utf16_length(text, preedit, offset / sizeof(U16)),
 33.2207 -															  &caret_coord, &preedit_bounds, NULL))
 33.2208 -						{
 33.2209 -							LLCoordGL caret_base_coord(caret_coord.mX, preedit_bounds.mBottom);
 33.2210 -							LLCoordScreen caret_base_coord_screen;
 33.2211 -							convertCoords(caret_base_coord, &caret_base_coord_screen);
 33.2212 -							Point qd_point;
 33.2213 -							qd_point.h = caret_base_coord_screen.mX;
 33.2214 -							qd_point.v = caret_base_coord_screen.mY;
 33.2215 -							SetEventParameter(event, kEventParamTextInputReplyPoint, typeQDPoint, sizeof(qd_point), &qd_point);
 33.2216 -
 33.2217 -							short line_height = (short) preedit_bounds.getHeight();
 33.2218 -							SetEventParameter(event, kEventParamTextInputReplyLineHeight, typeShortInteger, sizeof(line_height), &line_height);
 33.2219 -
 33.2220 -							result = noErr;
 33.2221 -						}
 33.2222 -						else
 33.2223 -						{
 33.2224 -							result = errOffsetInvalid;
 33.2225 -						}
 33.2226 -					}
 33.2227 -				}
 33.2228 -				break;
 33.2229 -
 33.2230 -			case kEventTextInputGetSelectedText:
 33.2231 -				{
 33.2232 -					if (mPreeditor)
 33.2233 -					{
 33.2234 -						S32 selection, selection_length;
 33.2235 -						mPreeditor->getSelectionRange(&selection, &selection_length);
 33.2236 -						if (selection_length)
 33.2237 -						{
 33.2238 -							const LLWString text = mPreeditor->getPreeditString().substr(selection, selection_length);
 33.2239 -							const llutf16string text_utf16 = wstring_to_utf16str(text);
 33.2240 -							result = SetEventParameter(event, kEventParamTextInputReplyText, typeUnicodeText,
 33.2241 -										text_utf16.length() * sizeof(U16), text_utf16.c_str());
 33.2242 -						}
 33.2243 -					}
 33.2244 -				}
 33.2245 -				break;
 33.2246 -			}
 33.2247 -		}
 33.2248 -		break;
 33.2249 -
 33.2250 -	case kEventClassKeyboard:
 33.2251 -		{
 33.2252 -			UInt32 keyCode = 0;
 33.2253 -			char charCode = 0;
 33.2254 -			UInt32 modifiers = 0;
 33.2255 -
 33.2256 -			// Some of these may fail for some event types.  That's fine.
 33.2257 -			GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
 33.2258 -			GetEventParameter (event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
 33.2259 -
 33.2260 -			// save the raw event so getNativeKeyData can use it.
 33.2261 -			mRawKeyEvent = event;
 33.2262 -
 33.2263 -			//			printf("key event, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", keyCode, charCode, (char)charCode, modifiers);
 33.2264 -			//			fflush(stdout);
 33.2265 -
 33.2266 -			switch (evtKind)
 33.2267 -			{
 33.2268 -			case kEventRawKeyDown:
 33.2269 -			case kEventRawKeyRepeat:
 33.2270 -				if (gDebugWindowProc)
 33.2271 -				{
 33.2272 -					printf("key down, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n",
 33.2273 -							(unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers);
 33.2274 -					fflush(stdout);
 33.2275 -				}
 33.2276 -				gKeyboard->handleKeyDown(keyCode, modifiers);
 33.2277 -				result = eventNotHandledErr;
 33.2278 -				break;
 33.2279 -
 33.2280 -			case kEventRawKeyUp:
 33.2281 -				if (gDebugWindowProc)
 33.2282 -				{
 33.2283 -					printf("key up,   key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n",
 33.2284 -							(unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers);
 33.2285 -					fflush(stdout);
 33.2286 -				}
 33.2287 -				gKeyboard->handleKeyUp(keyCode, modifiers);
 33.2288 -				result = eventNotHandledErr;
 33.2289 -				break;
 33.2290 -
 33.2291 -			case kEventRawKeyModifiersChanged:
 33.2292 -				// The keyboard input system wants key up/down events for modifier keys.
 33.2293 -				// Mac OS doesn't supply these directly, but can supply events when the collective modifier state changes.
 33.2294 -				// Use these events to generate up/down events for the modifiers.
 33.2295 -
 33.2296 -				if((modifiers & shiftKey) && !(mLastModifiers & shiftKey))
 33.2297 -				{
 33.2298 -					if (gDebugWindowProc) printf("Shift key down event\n");
 33.2299 -					gKeyboard->handleKeyDown(0x38, (modifiers & 0x00FFFFFF) | ((0x38 << 24) & 0xFF000000));
 33.2300 -				}
 33.2301 -				else if(!(modifiers & shiftKey) && (mLastModifiers & shiftKey))
 33.2302 -				{
 33.2303 -					if (gDebugWindowProc) printf("Shift key up event\n");
 33.2304 -					gKeyboard->handleKeyUp(0x38, (modifiers & 0x00FFFFFF) | ((0x38 << 24) & 0xFF000000));
 33.2305 -				}
 33.2306 -
 33.2307 -				if((modifiers & alphaLock) && !(mLastModifiers & alphaLock))
 33.2308 -				{
 33.2309 -					if (gDebugWindowProc) printf("Caps lock down event\n");
 33.2310 -					gKeyboard->handleKeyDown(0x39, (modifiers & 0x00FFFFFF) | ((0x39 << 24) & 0xFF000000));
 33.2311 -				}
 33.2312 -				else if(!(modifiers & alphaLock) && (mLastModifiers & alphaLock))
 33.2313 -				{
 33.2314 -					if (gDebugWindowProc) printf("Caps lock up event\n");
 33.2315 -					gKeyboard->handleKeyUp(0x39, (modifiers & 0x00FFFFFF) | ((0x39 << 24) & 0xFF000000));
 33.2316 -				}
 33.2317 -
 33.2318 -				if((modifiers & controlKey) && !(mLastModifiers & controlKey))
 33.2319 -				{
 33.2320 -					if (gDebugWindowProc) printf("Control key down event\n");
 33.2321 -					gKeyboard->handleKeyDown(0x3b, (modifiers & 0x00FFFFFF) | ((0x3b << 24) & 0xFF000000));
 33.2322 -				}
 33.2323 -				else if(!(modifiers & controlKey) && (mLastModifiers & controlKey))
 33.2324 -				{
 33.2325 -					if (gDebugWindowProc) printf("Control key up event\n");
 33.2326 -					gKeyboard->handleKeyUp(0x3b, (modifiers & 0x00FFFFFF) | ((0x3b << 24) & 0xFF000000));
 33.2327 -				}
 33.2328 -
 33.2329 -				if((modifiers & optionKey) && !(mLastModifiers & optionKey))
 33.2330 -				{
 33.2331 -					if (gDebugWindowProc) printf("Option key down event\n");
 33.2332 -					gKeyboard->handleKeyDown(0x3a, (modifiers & 0x00FFFFFF) | ((0x3a << 24) & 0xFF000000));
 33.2333 -				}
 33.2334 -				else if(!(modifiers & optionKey) && (mLastModifiers & optionKey))
 33.2335 -				{
 33.2336 -					if (gDebugWindowProc) printf("Option key up event\n");
 33.2337 -					gKeyboard->handleKeyUp(0x3a, (modifiers & 0x00FFFFFF) | ((0x3a << 24) & 0xFF000000));
 33.2338 -				}
 33.2339 -
 33.2340 -				// When the state of the 'Fn' key (the one that changes some of the mappings on a powerbook/macbook keyboard
 33.2341 -				// to an embedded keypad) changes, it may subsequently cause a key up event to be lost, which may lead to
 33.2342 -				// a movement key getting "stuck" down.  This is bad.
 33.2343 -				// This is an OS bug -- even the GetKeys() API doesn't tell you the key has been released.
 33.2344 -				// This workaround causes all held-down keys to be reset whenever the state of the Fn key changes.  This isn't
 33.2345 -				// exactly what we want, but it does avoid the case where you get stuck running forward.
 33.2346 -				if((modifiers & kEventKeyModifierFnMask) != (mLastModifiers & kEventKeyModifierFnMask))
 33.2347 -				{
 33.2348 -					if (gDebugWindowProc) printf("Fn key state change event\n");
 33.2349 -					gKeyboard->resetKeys();
 33.2350 -				}
 33.2351 -
 33.2352 -				if (gDebugWindowProc) fflush(stdout);
 33.2353 -
 33.2354 -				mLastModifiers = modifiers;
 33.2355 -				result = eventNotHandledErr;
 33.2356 -				break;
 33.2357 -			}
 33.2358 -
 33.2359 -			mRawKeyEvent = NULL;
 33.2360 -		}
 33.2361 -		break;
 33.2362 -
 33.2363 -	case kEventClassMouse:
 33.2364 -		{
 33.2365 -			result = CallNextEventHandler(myHandler, event);
 33.2366 -			if (eventNotHandledErr == result)
 33.2367 -			{ // only handle events not already handled (prevents wierd resize interaction)
 33.2368 -				EventMouseButton	button = kEventMouseButtonPrimary;
 33.2369 -				HIPoint				location = {0.0f, 0.0f};
 33.2370 -				UInt32				modifiers = 0;
 33.2371 -				UInt32				clickCount = 1;
 33.2372 -				long				wheelDelta = 0;
 33.2373 -				LLCoordScreen		inCoords;
 33.2374 -				LLCoordGL			outCoords;
 33.2375 -				MASK				mask = 0;
 33.2376 -
 33.2377 -				GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
 33.2378 -				GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(location), NULL, &location);
 33.2379 -				GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers);
 33.2380 -				GetEventParameter(event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(wheelDelta), NULL, &wheelDelta);
 33.2381 -				GetEventParameter(event, kEventParamClickCount, typeUInt32, NULL, sizeof(clickCount), NULL, &clickCount);
 33.2382 -
 33.2383 -				inCoords.mX = llround(location.x);
 33.2384 -				inCoords.mY = llround(location.y);
 33.2385 -
 33.2386 -				if(modifiers & shiftKey) { mask |= MASK_SHIFT; }
 33.2387 -				if(modifiers & controlKey) { mask |= MASK_CONTROL; }
 33.2388 -				if(modifiers & optionKey) { mask |= MASK_ALT; }
 33.2389 -
 33.2390 -				if(mCursorDecoupled)
 33.2391 -				{
 33.2392 -					CGMouseDelta x, y;
 33.2393 -
 33.2394 -					// If the cursor's decoupled, we need to read the latest movement delta as well.
 33.2395 -					CGGetLastMouseDelta( &x, &y );
 33.2396 -					mCursorLastEventDeltaX = x;
 33.2397 -					mCursorLastEventDeltaY = y;
 33.2398 -
 33.2399 -					if(mCursorIgnoreNextDelta)
 33.2400 -					{
 33.2401 -						mCursorLastEventDeltaX = 0;
 33.2402 -						mCursorLastEventDeltaY = 0;
 33.2403 -						mCursorIgnoreNextDelta = FALSE;
 33.2404 -					}
 33.2405 -				}
 33.2406 -				else
 33.2407 -				{
 33.2408 -					mCursorLastEventDeltaX = 0;
 33.2409 -					mCursorLastEventDeltaY = 0;
 33.2410 -				}
 33.2411 -
 33.2412 -				inCoords.mX += mCursorLastEventDeltaX;
 33.2413 -				inCoords.mY += mCursorLastEventDeltaY;
 33.2414 -
 33.2415 -				convertCoords(inCoords, &outCoords);
 33.2416 -
 33.2417 -				//				printf("coords in: %d, %d; coords out: %d, %d\n", inCoords.mX, inCoords.mY, outCoords.mX, outCoords.mY);
 33.2418 -				//				fflush(stdout);
 33.2419 -
 33.2420 -
 33.2421 -				switch (evtKind)
 33.2422 -				{
 33.2423 -				case kEventMouseDown:
 33.2424 -					if (mLanguageTextInputAllowed)
 33.2425 -					{
 33.2426 -						// We need to interrupt before handling mouse events,
 33.2427 -						// so that the fixed string from IM are delivered to
 33.2428 -						// the currently focused UI component.
 33.2429 -						interruptLanguageTextInput();
 33.2430 -					}
 33.2431 -					switch(button)
 33.2432 -					{
 33.2433 -					case kEventMouseButtonPrimary:
 33.2434 -						if(modifiers & cmdKey)
 33.2435 -						{
 33.2436 -							// Simulate a right click
 33.2437 -							mSimulatedRightClick = true;
 33.2438 -							mCallbacks->handleRightMouseDown(this, outCoords, mask);
 33.2439 -						}
 33.2440 -						else if(clickCount == 2)
 33.2441 -						{
 33.2442 -							// Windows double-click events replace the second mousedown event in a double-click.
 33.2443 -							mCallbacks->handleDoubleClick(this, outCoords, mask);
 33.2444 -						}
 33.2445 -						else
 33.2446 -						{
 33.2447 -							mCallbacks->handleMouseDown(this, outCoords, mask);
 33.2448 -						}
 33.2449 -						break;
 33.2450 -					case kEventMouseButtonSecondary:
 33.2451 -						mCallbacks->handleRightMouseDown(this, outCoords, mask);
 33.2452 -						break;
 33.2453 -
 33.2454 -					case kEventMouseButtonTertiary:
 33.2455 -						mCallbacks->handleMiddleMouseDown(this, outCoords, mask);
 33.2456 -						break;
 33.2457 -					}
 33.2458 -					result = noErr;
 33.2459 -					break;
 33.2460 -				case kEventMouseUp:
 33.2461 -
 33.2462 -					switch(button)
 33.2463 -					{
 33.2464 -					case kEventMouseButtonPrimary:
 33.2465 -						if(mSimulatedRightClick)
 33.2466 -						{
 33.2467 -							// End of simulated right click
 33.2468 -							mSimulatedRightClick = false;
 33.2469 -							mCallbacks->handleRightMouseUp(this, outCoords, mask);
 33.2470 -						}
 33.2471 -						else
 33.2472 -						{
 33.2473 -							mCallbacks->handleMouseUp(this, outCoords, mask);
 33.2474 -						}
 33.2475 -						break;
 33.2476 -					case kEventMouseButtonSecondary:
 33.2477 -						mCallbacks->handleRightMouseUp(this, outCoords, mask);
 33.2478 -						break;
 33.2479 -
 33.2480 -					case kEventMouseButtonTertiary:
 33.2481 -						mCallbacks->handleMiddleMouseUp(this, outCoords, mask);
 33.2482 -						break;
 33.2483 -					}
 33.2484 -					result = noErr;
 33.2485 -					break;
 33.2486 -
 33.2487 -				case kEventMouseWheelMoved:
 33.2488 -					{
 33.2489 -						static S32  z_delta = 0;
 33.2490 -
 33.2491 -						z_delta += wheelDelta;
 33.2492 -
 33.2493 -						if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta)
 33.2494 -						{
 33.2495 -							mCallbacks->handleScrollWheel(this, -z_delta / WHEEL_DELTA);
 33.2496 -							z_delta = 0;
 33.2497 -						}
 33.2498 -					}
 33.2499 -					result = noErr;
 33.2500 -					break;
 33.2501 -
 33.2502 -				case kEventMouseDragged:
 33.2503 -				case kEventMouseMoved:
 33.2504 -					mCallbacks->handleMouseMove(this, outCoords, mask);
 33.2505 -					result = noErr;
 33.2506 -					break;
 33.2507 -
 33.2508 -				}
 33.2509 -			}
 33.2510 -		}
 33.2511 -		break;
 33.2512 -
 33.2513 -	case kEventClassWindow:
 33.2514 -		switch(evtKind)
 33.2515 -		{
 33.2516 -		case kEventWindowActivated:
 33.2517 -			if (mTSMDocument)
 33.2518 -			{
 33.2519 -				ActivateTSMDocument(mTSMDocument);
 33.2520 -			}
 33.2521 -			mCallbacks->handleFocus(this);
 33.2522 -			break;
 33.2523 -		case kEventWindowDeactivated:
 33.2524 -			if (mTSMDocument)
 33.2525 -			{
 33.2526 -				DeactivateTSMDocument(mTSMDocument);
 33.2527 -			}
 33.2528 -			mCallbacks->handleFocusLost(this);
 33.2529 -			break;
 33.2530 -
 33.2531 -		case kEventWindowBoundsChanging:
 33.2532 -			{
 33.2533 -				// This is where we would constrain move/resize to a particular screen
 33.2534 -
 33.2535 -				const S32 MIN_WIDTH  = mMinWindowWidth;
 33.2536 -				const S32 MIN_HEIGHT = mMinWindowHeight;
 33.2537 -
 33.2538 -				Rect currentBounds;
 33.2539 -				Rect previousBounds;
 33.2540 -
 33.2541 -				GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &currentBounds);
 33.2542 -				GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &previousBounds);
 33.2543 -
 33.2544 -				// Put an offset into window un-maximize operation since the kEventWindowGetIdealSize
 33.2545 -				// event only allows the specification of size and not position.
 33.2546 -				if (mMaximized)
 33.2547 -				{
 33.2548 -					short leftOffset = mPreviousWindowRect.left - currentBounds.left;
 33.2549 -					currentBounds.left += leftOffset;
 33.2550 -					currentBounds.right += leftOffset;
 33.2551 -
 33.2552 -					short topOffset = mPreviousWindowRect.top - currentBounds.top;
 33.2553 -					currentBounds.top += topOffset;
 33.2554 -					currentBounds.bottom += topOffset;
 33.2555 -				}
 33.2556 -				else
 33.2557 -				{
 33.2558 -					// Store off the size for future un-maximize operations
 33.2559 -					mPreviousWindowRect = previousBounds;
 33.2560 -				}
 33.2561 -
 33.2562 -				if ((currentBounds.right - currentBounds.left) < MIN_WIDTH)
 33.2563 -				{
 33.2564 -					currentBounds.right = currentBounds.left + MIN_WIDTH;
 33.2565 -				}
 33.2566 -
 33.2567 -				if ((currentBounds.bottom - currentBounds.top) < MIN_HEIGHT)
 33.2568 -				{
 33.2569 -					currentBounds.bottom = currentBounds.top + MIN_HEIGHT;
 33.2570 -				}
 33.2571 -
 33.2572 -				SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), &currentBounds);
 33.2573 -				result = noErr;
 33.2574 -			}
 33.2575 -			break;
 33.2576 -
 33.2577 -		case kEventWindowBoundsChanged:
 33.2578 -			{
 33.2579 -				// Get new window bounds
 33.2580 -				Rect newBounds;
 33.2581 -				GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &newBounds);
 33.2582 -
 33.2583 -				// Get previous window bounds
 33.2584 -				Rect oldBounds;
 33.2585 -				GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &oldBounds);
 33.2586 -
 33.2587 -				// Determine if the new size is larger than the old
 33.2588 -				bool newBoundsLarger = ((newBounds.right - newBounds.left) >= (oldBounds.right - oldBounds.left));
 33.2589 -				newBoundsLarger &= ((newBounds.bottom - newBounds.top) >= (oldBounds.bottom - oldBounds.top));
 33.2590 -
 33.2591 -				// Check to see if this is a zoom event (+ button on window pane)
 33.2592 -				unsigned int eventParams;
 33.2593 -				GetEventParameter(event, kEventParamAttributes, typeUInt32, NULL, sizeof(int), NULL, &eventParams);
 33.2594 -				bool isZoomEvent = ((eventParams & kWindowBoundsChangeZoom) != 0);
 33.2595 -
 33.2596 -				// Maximized flag is if zoom event and increasing window size
 33.2597 -				mMaximized = (isZoomEvent && newBoundsLarger);
 33.2598 -
 33.2599 -				aglUpdateContext(mContext);
 33.2600 -
 33.2601 -				mCallbacks->handleResize(this, newBounds.right - newBounds.left, newBounds.bottom - newBounds.top);
 33.2602 -			}
 33.2603 -			break;
 33.2604 -
 33.2605 -		case kEventWindowGetIdealSize:
 33.2606 -			// Only recommend a new ideal size when un-maximizing
 33.2607 -			if (mMaximized == TRUE)
 33.2608 -			{
 33.2609 -				Point nonMaximizedSize;
 33.2610 -
 33.2611 -				nonMaximizedSize.v = mPreviousWindowRect.bottom - mPreviousWindowRect.top;
 33.2612 -				nonMaximizedSize.h = mPreviousWindowRect.right - mPreviousWindowRect.left;
 33.2613 -
 33.2614 -				SetEventParameter(event, kEventParamDimensions, typeQDPoint, sizeof(Point), &nonMaximizedSize);
 33.2615 -				result = noErr;
 33.2616 -			}
 33.2617 -			break;
 33.2618 -
 33.2619 -		case kEventWindowClose:
 33.2620 -			if(mCallbacks->handleCloseRequest(this))
 33.2621 -			{
 33.2622 -				// Get the app to initiate cleanup.
 33.2623 -				mCallbacks->handleQuit(this);
 33.2624 -				// The app is responsible for calling destroyWindow when done with GL
 33.2625 -			}
 33.2626 -			result = noErr;
 33.2627 -			break;
 33.2628 -
 33.2629 -		case kEventWindowHidden:
 33.2630 -			//					llinfos << "LLWindowMacOSX: Deactivating on hide" << llendl;
 33.2631 -			mMinimized = TRUE;
 33.2632 -			mCallbacks->handleActivate(this, false);
 33.2633 -			//					result = noErr;
 33.2634 -			break;
 33.2635 -
 33.2636 -		case kEventWindowShown:
 33.2637 -			//					llinfos << "LLWindowMacOSX: Activating on show" << llendl;
 33.2638 -			mMinimized = FALSE;
 33.2639 -			mCallbacks->handleActivate(this, true);
 33.2640 -			//					result = noErr;
 33.2641 -			break;
 33.2642 -
 33.2643 -		case kEventWindowCollapsed:
 33.2644 -			//					llinfos << "LLWindowMacOSX: Deactivating on collapse" << llendl;
 33.2645 -			mMinimized = TRUE;
 33.2646 -			mCallbacks->handleActivate(this, false);
 33.2647 -			//					result = noErr;
 33.2648 -			break;
 33.2649 -
 33.2650 -		case kEventWindowExpanded:
 33.2651 -			//					llinfos << "LLWindowMacOSX: Activating on expand" << llendl;
 33.2652 -			mMinimized = FALSE;
 33.2653 -			mCallbacks->handleActivate(this, true);
 33.2654 -			//					result = noErr;
 33.2655 -			break;
 33.2656 -
 33.2657 -		case kEventWindowGetClickActivation:
 33.2658 -			//					BringToFront(mWindow);
 33.2659 -			//					result = noErr;
 33.2660 -			break;
 33.2661 -		}
 33.2662 -		break;
 33.2663 -
 33.2664 -	case kEventClassTSMDocumentAccess:
 33.2665 -		if (mPreeditor)
 33.2666 -		{
 33.2667 -			switch(evtKind)
 33.2668 -			{
 33.2669 -
 33.2670 -			case kEventTSMDocumentAccessGetLength:
 33.2671 -				{
 33.2672 -					// Return the number of UTF-16 units in the text, excluding those for preedit.
 33.2673 -
 33.2674 -					S32 preedit, preedit_length;
 33.2675 -					mPreeditor->getPreeditRange(&preedit, &preedit_length);
 33.2676 -					const LLWString & text = mPreeditor->getPreeditString();
 33.2677 -					const CFIndex length = wstring_utf16_length(text, 0, preedit)
 33.2678 -						+ wstring_utf16_length(text, preedit + preedit_length, text.length());
 33.2679 -					result = SetEventParameter(event, kEventParamTSMDocAccessCharacterCount, typeCFIndex, sizeof(length), &length);
 33.2680 -				}
 33.2681 -				break;
 33.2682 -
 33.2683 -			case kEventTSMDocumentAccessGetSelectedRange:
 33.2684 -				{
 33.2685 -					// Return the selected range, excluding preedit.
 33.2686 -					// In our preeditor, preedit and selection are exclusive, so,
 33.2687 -					// when it has a preedit, there is no selection and the
 33.2688 -					// insertion point is on the preedit that corrupses into the
 33.2689 -					// beginning of the preedit when the preedit was removed.
 33.2690 -
 33.2691 -					S32 preedit, preedit_length;
 33.2692 -					mPreeditor->getPreeditRange(&preedit, &preedit_length);
 33.2693 -					const LLWString & text = mPreeditor->getPreeditString();
 33.2694 -
 33.2695 -					CFRange range;
 33.2696 -					if (preedit_length)
 33.2697 -					{
 33.2698 -						range.location = wstring_utf16_length(text, 0, preedit);
 33.2699 -						range.length = 0;
 33.2700 -					}
 33.2701 -					else
 33.2702 -					{
 33.2703 -						S32 selection, selection_length;
 33.2704 -						mPreeditor->getSelectionRange(&selection, &selection_length);
 33.2705 -						range.location = wstring_utf16_length(text, 0, selection);
 33.2706 -						range.length = wstring_utf16_length(text, selection, selection_length);
 33.2707 -					}
 33.2708 -
 33.2709 -					result = SetEventParameter(event, kEventParamTSMDocAccessReplyCharacterRange, typeCFRange, sizeof(range), &range);
 33.2710 -				}
 33.2711 -				break;
 33.2712 -
 33.2713 -			case kEventTSMDocumentAccessGetCharacters:
 33.2714 -				{
 33.2715 -					UniChar *target_pointer;
 33.2716 -					CFRange range;
 33.2717 -					EventParamType param_type;
 33.2718 -					if ((result = GetEventParameter(event, kEventParamTSMDocAccessSendCharacterRange,
 33.2719 -										typeCFRange, &param_type, sizeof(range), NULL, &range)) == noErr
 33.2720 -						&& typeCFRange == param_type
 33.2721 -						&& (result = GetEventParameter(event, kEventParamTSMDocAccessSendCharactersPtr,
 33.2722 -										typePtr, &param_type, sizeof(target_pointer), NULL, &target_pointer)) == noErr
 33.2723 -						&& typePtr == param_type)
 33.2724 -					{
 33.2725 -						S32 preedit, preedit_length;
 33.2726 -						mPreeditor->getPreeditRange(&preedit, &preedit_length);
 33.2727 -						const LLWString & text = mPreeditor->getPreeditString();
 33.2728 -
 33.2729 -						// The GetCharacters event of TSMDA has a fundamental flaw;
 33.2730 -						// An input method need to decide the starting offset and length
 33.2731 -						// *before* it actually see the contents, so it is impossible
 33.2732 -						// to guarantee the character-aligned access.  The event reply
 33.2733 -						// has no way to indicate a condition something like "Request
 33.2734 -						// was not fulfilled due to unaligned access.  Please retry."
 33.2735 -						// Any error sent back to the input method stops use of TSMDA
 33.2736 -						// entirely during the session...
 33.2737 -						// We need to simulate very strictly the behaviour as if the
 33.2738 -						// underlying *text engine* holds the contents in UTF-16.
 33.2739 -						// I guess this is the reason why Apple repeats saying "all
 33.2740 -						// text handling application should use UTF-16."  They are
 33.2741 -						// trying to _fix_ the flaw by changing the appliations...
 33.2742 -						// ... or, domination of UTF-16 in the industry may be a part
 33.2743 -						// of the company vision, and Apple is trying to force third
 33.2744 -						// party developers to obey their vision.  Remember that use
 33.2745 -						// of 16 bits per _a_character_ was one of the very fundamental
 33.2746 -						// Unicode design policy on its early days (during late 80s)
 33.2747 -						// and the original Unicode design was by two Apple employees...
 33.2748 -
 33.2749 -						const llutf16string text_utf16
 33.2750 -							= wstring_to_utf16str(text, preedit)
 33.2751 -							+ wstring_to_utf16str(text.substr(preedit + preedit_length));
 33.2752 -
 33.2753 -						llassert_always(sizeof(U16) == sizeof(UniChar));
 33.2754 -						llassert(0 <= range.location && 0 <= range.length && range.location + range.length <= text_utf16.length());
 33.2755 -						memcpy(target_pointer, text_utf16.c_str() + range.location, range.length * sizeof(UniChar));
 33.2756 -
 33.2757 -						// Note that result has already been set above.
 33.2758 -					}
 33.2759 -				}
 33.2760 -				break;
 33.2761 -
 33.2762 -			}
 33.2763 -		}
 33.2764 -		break;
 33.2765 -	}
 33.2766 -	return result;
 33.2767 -}
 33.2768 -
 33.2769  const char* cursorIDToName(int id)
 33.2770  {
 33.2771  	switch (id)
 33.2772 @@ -2876,7 +1371,7 @@
 33.2773  
 33.2774  void LLWindowMacOSX::updateCursor()
 33.2775  {
 33.2776 -	OSStatus result = noErr;
 33.2777 +	S32 result = 0;
 33.2778  
 33.2779  	if (mDragOverrideCursor != -1)
 33.2780  	{
 33.2781 @@ -2909,11 +1404,11 @@
 33.2782  	{
 33.2783  	default:
 33.2784  	case UI_CURSOR_ARROW:
 33.2785 -		InitCursor();
 33.2786 +		setArrowCursor();
 33.2787  		if(mCursorHidden)
 33.2788  		{
 33.2789  			// Since InitCursor resets the hide level, correct for it here.
 33.2790 -			::HideCursor();
 33.2791 +			hideNSCursor();
 33.2792  		}
 33.2793  		break;
 33.2794  
 33.2795 @@ -2921,12 +1416,12 @@
 33.2796  		//    Find out what they look like and replicate them.
 33.2797  
 33.2798  		// These are essentially correct
 33.2799 -	case UI_CURSOR_WAIT:		SetThemeCursor(kThemeWatchCursor);	break;
 33.2800 -	case UI_CURSOR_IBEAM:		SetThemeCursor(kThemeIBeamCursor);	break;
 33.2801 -	case UI_CURSOR_CROSS:		SetThemeCursor(kThemeCrossCursor);	break;
 33.2802 -	case UI_CURSOR_HAND:		SetThemeCursor(kThemePointingHandCursor);	break;
 33.2803 +	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;
 33.2804 +	case UI_CURSOR_IBEAM:		setIBeamCursor();	break;
 33.2805 +	case UI_CURSOR_CROSS:		setCrossCursor();	break;
 33.2806 +	case UI_CURSOR_HAND:		setPointingHandCursor();	break;
 33.2807  		//		case UI_CURSOR_NO:			SetThemeCursor(kThemeNotAllowedCursor);	break;
 33.2808 -	case UI_CURSOR_ARROWCOPY:   SetThemeCursor(kThemeCopyArrowCursor);	break;
 33.2809 +	case UI_CURSOR_ARROWCOPY:   setCopyCursor();	break;
 33.2810  
 33.2811  		// Double-check these
 33.2812  	case UI_CURSOR_NO:
 33.2813 @@ -2969,7 +1464,7 @@
 33.2814  
 33.2815  	if(result != noErr)
 33.2816  	{
 33.2817 -		InitCursor();
 33.2818 +		setArrowCursor();
 33.2819  	}
 33.2820  
 33.2821  	mCurrentCursor = mNextCursor;
 33.2822 @@ -3039,7 +1534,7 @@
 33.2823  		//		llinfos << "hideCursor: hiding" << llendl;
 33.2824  		mCursorHidden = TRUE;
 33.2825  		mHideCursorPermanent = TRUE;
 33.2826 -		::HideCursor();
 33.2827 +		hideNSCursor();
 33.2828  	}
 33.2829  	else
 33.2830  	{
 33.2831 @@ -3056,7 +1551,7 @@
 33.2832  		//		llinfos << "showCursor: showing" << llendl;
 33.2833  		mCursorHidden = FALSE;
 33.2834  		mHideCursorPermanent = FALSE;
 33.2835 -		::ShowCursor();
 33.2836 +		showNSCursor();
 33.2837  	}
 33.2838  	else
 33.2839  	{
 33.2840 @@ -3100,24 +1595,6 @@
 33.2841  void LLSplashScreenMacOSX::showImpl()
 33.2842  {
 33.2843  	// This code _could_ be used to display a spash screen...
 33.2844 -#if 0
 33.2845 -	IBNibRef nib = NULL;
 33.2846 -	OSStatus err;
 33.2847 -
 33.2848 -	err = CreateNibReference(CFSTR("SecondLife"), &nib);
 33.2849 -
 33.2850 -	if(err == noErr)
 33.2851 -	{
 33.2852 -		CreateWindowFromNib(nib, CFSTR("Splash Screen"), &mWindow);
 33.2853 -
 33.2854 -		DisposeNibReference(nib);
 33.2855 -	}
 33.2856 -
 33.2857 -	if(mWindow != NULL)
 33.2858 -	{
 33.2859 -		ShowWindow(mWindow);
 33.2860 -	}
 33.2861 -#endif
 33.2862  }
 33.2863  
 33.2864  void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
 33.2865 @@ -3127,25 +1604,6 @@
 33.2866  		CFStringRef string = NULL;
 33.2867  
 33.2868  		string = CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
 33.2869 -
 33.2870 -		if(string != NULL)
 33.2871 -		{
 33.2872 -			ControlRef progressText = NULL;
 33.2873 -			ControlID id;
 33.2874 -			OSStatus err;
 33.2875 -
 33.2876 -			id.signature = 'what';
 33.2877 -			id.id = 0;
 33.2878 -
 33.2879 -			err = GetControlByID(mWindow, &id, &progressText);
 33.2880 -			if(err == noErr)
 33.2881 -			{
 33.2882 -				err = SetControlData(progressText, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(CFStringRef), (Ptr)&string);
 33.2883 -				Draw1Control(progressText);
 33.2884 -			}
 33.2885 -
 33.2886 -			CFRelease(string);
 33.2887 -		}
 33.2888  	}
 33.2889  }
 33.2890  
 33.2891 @@ -3154,111 +1612,21 @@
 33.2892  {
 33.2893  	if(mWindow != NULL)
 33.2894  	{
 33.2895 -		DisposeWindow(mWindow);
 33.2896  		mWindow = NULL;
 33.2897  	}
 33.2898  }
 33.2899  
 33.2900 -
 33.2901 -
 33.2902  S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type)
 33.2903  {
 33.2904 -	S32 result = OSBTN_CANCEL;
 33.2905 -	SInt16 retval_mac = 1;
 33.2906 -	AlertStdCFStringAlertParamRec params;
 33.2907 -	CFStringRef errorString = NULL;
 33.2908 -	CFStringRef explanationString = NULL;
 33.2909 -	DialogRef alert = NULL;
 33.2910 -	AlertType alertType = kAlertCautionAlert;
 33.2911 -	OSStatus err;
 33.2912 -
 33.2913 -	explanationString = CFStringCreateWithCString(NULL, text.c_str(), kCFStringEncodingUTF8);
 33.2914 -	errorString = CFStringCreateWithCString(NULL, caption.c_str(), kCFStringEncodingUTF8);
 33.2915 -
 33.2916 -	params.version = kStdCFStringAlertVersionOne;
 33.2917 -	params.movable = false;
 33.2918 -	params.helpButton = false;
 33.2919 -	params.defaultText = (CFStringRef)kAlertDefaultOKText;
 33.2920 -	params.cancelText = 0;
 33.2921 -	params.otherText = 0;
 33.2922 -	params.defaultButton = 1;
 33.2923 -	params.cancelButton = 0;
 33.2924 -	params.position = kWindowDefaultPosition;
 33.2925 -	params.flags = 0;
 33.2926 -
 33.2927 -	switch(type)
 33.2928 -	{
 33.2929 -	case OSMB_OK:
 33.2930 -	default:
 33.2931 -		break;
 33.2932 -	case OSMB_OKCANCEL:
 33.2933 -		params.cancelText = (CFStringRef)kAlertDefaultCancelText;
 33.2934 -		params.cancelButton = 2;
 33.2935 -		break;
 33.2936 -	case OSMB_YESNO:
 33.2937 -		alertType = kAlertNoteAlert;
 33.2938 -		params.defaultText = CFSTR("Yes");
 33.2939 -		params.cancelText = CFSTR("No");
 33.2940 -		params.cancelButton = 2;
 33.2941 -		break;
 33.2942 -	}
 33.2943 -
 33.2944 -	if(gWindowImplementation != NULL)
 33.2945 -		gWindowImplementation->beforeDialog();
 33.2946 -
 33.2947 -	err = CreateStandardAlert(
 33.2948 -		alertType,
 33.2949 -		errorString,
 33.2950 -		explanationString,
 33.2951 -		&params,
 33.2952 -		&alert);
 33.2953 -
 33.2954 -	if(err == noErr)
 33.2955 -	{
 33.2956 -		err = RunStandardAlert(
 33.2957 -			alert,
 33.2958 -			NULL,
 33.2959 -			&retval_mac);
 33.2960 -	}
 33.2961 -
 33.2962 -	if(gWindowImplementation != NULL)
 33.2963 -		gWindowImplementation->afterDialog();
 33.2964 -
 33.2965 -	switch(type)
 33.2966 -	{
 33.2967 -	case OSMB_OK:
 33.2968 -	case OSMB_OKCANCEL:
 33.2969 -	default:
 33.2970 -		if(retval_mac == 1)
 33.2971 -			result = OSBTN_OK;
 33.2972 -		else
 33.2973 -			result = OSBTN_CANCEL;
 33.2974 -		break;
 33.2975 -	case OSMB_YESNO:
 33.2976 -		if(retval_mac == 1)
 33.2977 -			result = OSBTN_YES;
 33.2978 -		else
 33.2979 -			result = OSBTN_NO;
 33.2980 -		break;
 33.2981 -	}
 33.2982 -
 33.2983 -	if(errorString != NULL)
 33.2984 -	{
 33.2985 -		CFRelease(errorString);
 33.2986 -	}
 33.2987 -
 33.2988 -	if(explanationString != NULL)
 33.2989 -	{
 33.2990 -		CFRelease(explanationString);
 33.2991 -	}
 33.2992 -
 33.2993 -	return result;
 33.2994 +	return showAlert(text, caption, type);
 33.2995  }
 33.2996  
 33.2997  // Open a URL with the user's default web browser.
 33.2998  // Must begin with protocol identifier.
 33.2999  void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
 33.3000  {
 33.3001 +	// I'm fairly certain that this is all legitimate under Apple's currently supported APIs.
 33.3002 +	
 33.3003  	bool found = false;
 33.3004  	S32 i;
 33.3005  	for (i = 0; i < gURLProtocolWhitelistCount; i++)
 33.3006 @@ -3276,7 +1644,7 @@
 33.3007  		return;
 33.3008  	}
 33.3009  
 33.3010 -	OSStatus result = noErr;
 33.3011 +	S32 result = 0;
 33.3012  	CFURLRef urlRef = NULL;
 33.3013  
 33.3014  	llinfos << "Opening URL " << escaped_url << llendl;
 33.3015 @@ -3313,7 +1681,7 @@
 33.3016  LLSD LLWindowMacOSX::getNativeKeyData()
 33.3017  {
 33.3018  	LLSD result = LLSD::emptyMap();
 33.3019 -
 33.3020 +#if 0
 33.3021  	if(mRawKeyEvent)
 33.3022  	{
 33.3023  		char char_code = 0;
 33.3024 @@ -3335,7 +1703,7 @@
 33.3025  		// This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc)
 33.3026  		// cause llsd serialization to create XML that the llsd deserializer won't parse!
 33.3027  		std::string unicode;
 33.3028 -		OSStatus err = noErr;
 33.3029 +		S32 err = noErr;
 33.3030  		EventParamType actualType = typeUTF8Text;
 33.3031  		UInt32 actualSize = 0;
 33.3032  		char *buffer = NULL;
 33.3033 @@ -3357,7 +1725,7 @@
 33.3034  #endif
 33.3035  
 33.3036  	}
 33.3037 -
 33.3038 +#endif
 33.3039  
 33.3040  	lldebugs << "native key data is: " << result << llendl;
 33.3041  
 33.3042 @@ -3367,34 +1735,9 @@
 33.3043  
 33.3044  BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b)
 33.3045  {
 33.3046 +	// Is this even used anywhere?  Do we really need an OS color picker?
 33.3047  	BOOL	retval = FALSE;
 33.3048 -	OSErr	error = noErr;
 33.3049 -	NColorPickerInfo	info;
 33.3050 -
 33.3051 -	memset(&info, 0, sizeof(info));
 33.3052 -	info.theColor.color.rgb.red = (UInt16)(*r * 65535.f);
 33.3053 -	info.theColor.color.rgb.green = (UInt16)(*g * 65535.f);
 33.3054 -	info.theColor.color.rgb.blue = (UInt16)(*b * 65535.f);
 33.3055 -	info.placeWhere = kCenterOnMainScreen;
 33.3056 -
 33.3057 -	if(gWindowImplementation != NULL)
 33.3058 -		gWindowImplementation->beforeDialog();
 33.3059 -
 33.3060 -	error = NPickColor(&info);
 33.3061 -
 33.3062 -	if(gWindowImplementation != NULL)
 33.3063 -		gWindowImplementation->afterDialog();
 33.3064 -
 33.3065 -	if (error == noErr)
 33.3066 -	{
 33.3067 -		retval = info.newColorChosen;
 33.3068 -		if (info.newColorChosen)
 33.3069 -		{
 33.3070 -			*r = ((float) info.theColor.color.rgb.red) / 65535.0;
 33.3071 -			*g = ((float) info.theColor.color.rgb.green) / 65535.0;
 33.3072 -			*b = ((float) info.theColor.color.rgb.blue) / 65535.0;
 33.3073 -		}
 33.3074 -	}
 33.3075 +	//S32		error = 0;
 33.3076  	return (retval);
 33.3077  }
 33.3078  
 33.3079 @@ -3405,44 +1748,8 @@
 33.3080  	return (void*)mWindow;
 33.3081  }
 33.3082  
 33.3083 -void *LLWindowMacOSX::getMediaWindow()
 33.3084 -{
 33.3085 -	/*
 33.3086 -		Mozilla needs to be initialized with a WindowRef to function properly.
 33.3087 -		(There's no good reason for this, since it shouldn't be interacting with our window in any way, but that's another issue.)
 33.3088 -		If we're in windowed mode, we _could_ hand it our actual window pointer, but a subsequent switch to fullscreen will destroy that window,
 33.3089 -		which trips up Mozilla.
 33.3090 -		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.
 33.3091 -		This satisfies its deep-seated need to latch onto a WindowRef and solves the issue with switching between fullscreen and windowed modes.
 33.3092 -
 33.3093 -		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.
 33.3094 -	*/
 33.3095 -
 33.3096 -	if(sMediaWindow == NULL)
 33.3097 -	{
 33.3098 -		Rect window_rect = {100, 100, 200, 200};
 33.3099 -
 33.3100 -		sMediaWindow = NewCWindow(
 33.3101 -			NULL,
 33.3102 -			&window_rect,
 33.3103 -			(ConstStr255Param) "\p",
 33.3104 -			false,				// Create the window invisible.
 33.3105 -			zoomDocProc,		// Window with a grow box and a zoom box
 33.3106 -			kLastWindowOfClass,		// create it behind other windows
 33.3107 -			false,					// no close box
 33.3108 -			0);
 33.3109 -	}
 33.3110 -
 33.3111 -	return (void*)sMediaWindow;
 33.3112 -}
 33.3113 -
 33.3114 -void LLWindowMacOSX::stopDockTileBounce()
 33.3115 -{
 33.3116 -	NMRemove(&mBounceRec);
 33.3117 -	mBounceTimer.stop();
 33.3118 -}
 33.3119 -
 33.3120  // get a double value from a dictionary
 33.3121 +/*
 33.3122  static double getDictDouble (CFDictionaryRef refDict, CFStringRef key)
 33.3123  {
 33.3124  	double double_value;
 33.3125 @@ -3452,7 +1759,7 @@
 33.3126  	if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &double_value)) // or if cant convert it
 33.3127  		return -1; // fail
 33.3128  	return double_value; // otherwise return the long value
 33.3129 -}
 33.3130 +}*/
 33.3131  
 33.3132  // get a long value from a dictionary
 33.3133  static long getDictLong (CFDictionaryRef refDict, CFStringRef key)
 33.3134 @@ -3468,8 +1775,8 @@
 33.3135  
 33.3136  void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
 33.3137  {
 33.3138 -	ScriptLanguageRecord script_language;
 33.3139 -
 33.3140 +    allowDirectMarkedTextInput(b, mGLView);
 33.3141 +	
 33.3142  	if (preeditor != mPreeditor && !b)
 33.3143  	{
 33.3144  		// This condition may occur by a call to
 33.3145 @@ -3480,9 +1787,7 @@
 33.3146  		// is not disturbed.
 33.3147  		return;
 33.3148  	}
 33.3149 -
 33.3150 -	UseInputWindow(mTSMDocument, !b);
 33.3151 -
 33.3152 +    
 33.3153  	// Take care of old and new preeditors.
 33.3154  	if (preeditor != mPreeditor || !b)
 33.3155  	{
 33.3156 @@ -3495,44 +1800,17 @@
 33.3157  		}
 33.3158  		mPreeditor = (b ? preeditor : NULL);
 33.3159  	}
 33.3160 -
 33.3161 +	
 33.3162  	if (b == mLanguageTextInputAllowed)
 33.3163  	{
 33.3164  		return;
 33.3165  	}
 33.3166  	mLanguageTextInputAllowed = b;
 33.3167 -
 33.3168 -	if (b)
 33.3169 -	{
 33.3170 -		if (mTSMScriptCode != smRoman)
 33.3171 -		{
 33.3172 -			script_language.fScript = mTSMScriptCode;
 33.3173 -			script_language.fLanguage = mTSMLangCode;
 33.3174 -			SetTextServiceLanguage(&script_language);
 33.3175 -		}
 33.3176 -	}
 33.3177 -	else
 33.3178 -	{
 33.3179 -		GetTextServiceLanguage(&script_language);
 33.3180 -		mTSMScriptCode = script_language.fScript;
 33.3181 -		mTSMLangCode = script_language.fLanguage;
 33.3182 -		if (mTSMScriptCode != smRoman)
 33.3183 -		{
 33.3184 -			script_language.fScript = smRoman;
 33.3185 -			script_language.fLanguage = langEnglish;
 33.3186 -			SetTextServiceLanguage(&script_language);
 33.3187 -		}
 33.3188 -	}
 33.3189  }
 33.3190  
 33.3191  void LLWindowMacOSX::interruptLanguageTextInput()
 33.3192  {
 33.3193 -	if (mTSMDocument)
 33.3194 -	{
 33.3195 -		FixTSMDocument(mTSMDocument);
 33.3196 -	}
 33.3197 -	// Don't we need to call resetPreedit here?
 33.3198 -	// Well, if Apple's TSM document is correct, we don't.
 33.3199 +	commitCurrentPreedit(mGLView);
 33.3200  }
 33.3201  
 33.3202  //static
 33.3203 @@ -3543,21 +1821,21 @@
 33.3204  }
 33.3205  
 33.3206  // static
 33.3207 -MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers)
 33.3208 +MASK LLWindowMacOSX::modifiersToMask(S16 modifiers)
 33.3209  {
 33.3210  	MASK mask = 0;
 33.3211 -	if(modifiers & shiftKey) { mask |= MASK_SHIFT; }
 33.3212 -	if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; }
 33.3213 -	if(modifiers & optionKey) { mask |= MASK_ALT; }
 33.3214 +	if(modifiers & MAC_SHIFT_KEY) { mask |= MASK_SHIFT; }
 33.3215 +	if(modifiers & (MAC_CMD_KEY | MAC_CTRL_KEY)) { mask |= MASK_CONTROL; }
 33.3216 +	if(modifiers & MAC_ALT_KEY) { mask |= MASK_ALT; }
 33.3217  	return mask;
 33.3218  }
 33.3219  
 33.3220  #if LL_OS_DRAGDROP_ENABLED
 33.3221 -
 33.3222 -OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
 33.3223 +/*
 33.3224 +S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
 33.3225  						  void * handlerRefCon, DragRef drag)
 33.3226  {
 33.3227 -	OSErr result = noErr;
 33.3228 +	S16 result = 0;
 33.3229  	LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon;
 33.3230  
 33.3231  	lldebugs << "drag tracking handler, message = " << message << llendl;
 33.3232 @@ -3582,7 +1860,6 @@
 33.3233  
 33.3234  	return result;
 33.3235  }
 33.3236 -
 33.3237  OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon,
 33.3238  										 DragRef drag)
 33.3239  {
 33.3240 @@ -3590,126 +1867,69 @@
 33.3241  	return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED);
 33.3242  
 33.3243  }
 33.3244 +*/
 33.3245 +void LLWindowMacOSX::handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action)
 33.3246 +{
 33.3247 +	MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers());
 33.3248  
 33.3249 -OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDropAction action)
 33.3250 -{
 33.3251 -	OSErr result = dragNotAcceptedErr;	// overall function result
 33.3252 -	OSErr err = noErr;	// for local error handling
 33.3253 -
 33.3254 -	// Get the mouse position and modifiers of this drag.
 33.3255 -	SInt16 modifiers, mouseDownModifiers, mouseUpModifiers;
 33.3256 -	::GetDragModifiers(drag, &modifiers, &mouseDownModifiers, &mouseUpModifiers);
 33.3257 -	MASK mask = LLWindowMacOSX::modifiersToMask(modifiers);
 33.3258 -
 33.3259 -	Point mouse_point;
 33.3260 -	// This will return the mouse point in global screen coords
 33.3261 -	::GetDragMouse(drag, &mouse_point, NULL);
 33.3262 -	LLCoordScreen screen_coords(mouse_point.h, mouse_point.v);
 33.3263 +	float mouse_point[2];
 33.3264 +	// This will return the mouse point in window coords
 33.3265 +	getCursorPos(mWindow, mouse_point);
 33.3266 +	LLCoordWindow window_coords(mouse_point[0], mouse_point[1]);
 33.3267  	LLCoordGL gl_pos;
 33.3268 -	convertCoords(screen_coords, &gl_pos);
 33.3269 -
 33.3270 -	// Look at the pasteboard and try to extract an URL from it
 33.3271 -	PasteboardRef   pasteboard;
 33.3272 -	if(GetDragPasteboard(drag, &pasteboard) == noErr)
 33.3273 +	convertCoords(window_coords, &gl_pos);
 33.3274 +	
 33.3275 +	if(!url.empty())
 33.3276  	{
 33.3277 -		ItemCount num_items = 0;
 33.3278 -		// Treat an error here as an item count of 0
 33.3279 -		(void)PasteboardGetItemCount(pasteboard, &num_items);
 33.3280 -
 33.3281 -		// Only deal with single-item drags.
 33.3282 -		if(num_items == 1)
 33.3283 +		LLWindowCallbacks::DragNDropResult res =
 33.3284 +		mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url);
 33.3285 +		
 33.3286 +		switch (res) {
 33.3287 +			case LLWindowCallbacks::DND_NONE:		// No drop allowed
 33.3288 +				if (action == LLWindowCallbacks::DNDA_TRACK)
 33.3289 +				{
 33.3290 +					mDragOverrideCursor = 0;
 33.3291 +				}
 33.3292 +				else {
 33.3293 +					mDragOverrideCursor = -1;
 33.3294 +				}
 33.3295 +				break;
 33.3296 +			case LLWindowCallbacks::DND_MOVE:		// Drop accepted would result in a "move" operation
 33.3297 +				mDragOverrideCursor = UI_CURSOR_NO;
 33.3298 +				break;
 33.3299 +			case LLWindowCallbacks::DND_COPY:		// Drop accepted would result in a "copy" operation
 33.3300 +				mDragOverrideCursor = UI_CURSOR_ARROWCOPY;
 33.3301 +				break;
 33.3302 +			default:
 33.3303 +				mDragOverrideCursor = -1;
 33.3304 +				break;
 33.3305 +		}
 33.3306 +		// This overrides the cursor being set by setCursor.
 33.3307 +		// This is a bit of a hack workaround because lots of areas
 33.3308 +		// within the viewer just blindly set the cursor.
 33.3309 +		if (mDragOverrideCursor == -1)
 33.3310  		{
 33.3311 -			PasteboardItemID item_id = NULL;
 33.3312 -			CFArrayRef flavors = NULL;
 33.3313 -			CFDataRef data = NULL;
 33.3314 -
 33.3315 -			err = PasteboardGetItemIdentifier(pasteboard, 1, &item_id); // Yes, this really is 1-based.
 33.3316 -
 33.3317 -			// Try to extract an URL from the pasteboard
 33.3318 -			if(err == noErr)
 33.3319 -			{
 33.3320 -				err = PasteboardCopyItemFlavors( pasteboard, item_id, &flavors);
 33.3321 -			}
 33.3322 -
 33.3323 -			if(err == noErr)
 33.3324 -			{
 33.3325 -				if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeURL))
 33.3326 -				{
 33.3327 -					// This is an URL.
 33.3328 -					err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeURL, &data);
 33.3329 -				}
 33.3330 -				else if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeUTF8PlainText))
 33.3331 -				{
 33.3332 -					// This is a string that might be an URL.
 33.3333 -					err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeUTF8PlainText, &data);
 33.3334 -				}
 33.3335 -
 33.3336 -			}
 33.3337 -
 33.3338 -			if(flavors != NULL)
 33.3339 -			{
 33.3340 -				CFRelease(flavors);
 33.3341 -			}
 33.3342 -
 33.3343 -			if(data != NULL)
 33.3344 -			{
 33.3345 -				std::string url;
 33.3346 -				url.assign((char*)CFDataGetBytePtr(data), CFDataGetLength(data));
 33.3347 -				CFRelease(data);
 33.3348 -
 33.3349 -				if(!url.empty())
 33.3350 -				{
 33.3351 -					LLWindowCallbacks::DragNDropResult res =
 33.3352 -						mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url);
 33.3353 -
 33.3354 -					switch (res) {
 33.3355 -						case LLWindowCallbacks::DND_NONE:		// No drop allowed
 33.3356 -							if (action == LLWindowCallbacks::DNDA_TRACK)
 33.3357 -							{
 33.3358 -								mDragOverrideCursor = kThemeNotAllowedCursor;
 33.3359 -							}
 33.3360 -							else {
 33.3361 -								mDragOverrideCursor = -1;
 33.3362 -							}
 33.3363 -							break;
 33.3364 -						case LLWindowCallbacks::DND_MOVE:		// Drop accepted would result in a "move" operation
 33.3365 -							mDragOverrideCursor = kThemePointingHandCursor;
 33.3366 -							result = noErr;
 33.3367 -							break;
 33.3368 -						case LLWindowCallbacks::DND_COPY:		// Drop accepted would result in a "copy" operation
 33.3369 -							mDragOverrideCursor = kThemeCopyArrowCursor;
 33.3370 -							result = noErr;
 33.3371 -							break;
 33.3372 -						case LLWindowCallbacks::DND_LINK:		// Drop accepted would result in a "link" operation:
 33.3373 -							mDragOverrideCursor = kThemeAliasArrowCursor;
 33.3374 -							result = noErr;
 33.3375 -							break;
 33.3376 -						default:
 33.3377 -							mDragOverrideCursor = -1;
 33.3378 -							break;
 33.3379 -					}
 33.3380 -					// This overrides the cursor being set by setCursor.
 33.3381 -					// This is a bit of a hack workaround because lots of areas
 33.3382 -					// within the viewer just blindly set the cursor.
 33.3383 -					if (mDragOverrideCursor == -1)
 33.3384 -					{
 33.3385 -						// Restore the cursor
 33.3386 -						ECursorType temp_cursor = mCurrentCursor;
 33.3387 -						// get around the "setting the same cursor" code in setCursor()
 33.3388 -						mCurrentCursor = UI_CURSOR_COUNT;
 33.3389 - 						setCursor(temp_cursor);
 33.3390 -					}
 33.3391 -					else {
 33.3392 -						// Override the cursor
 33.3393 -						SetThemeCursor(mDragOverrideCursor);
 33.3394 -					}
 33.3395 -
 33.3396 -				}
 33.3397 -			}
 33.3398 +			// Restore the cursor
 33.3399 +			ECursorType temp_cursor = mCurrentCursor;
 33.3400 +			// get around the "setting the same cursor" code in setCursor()
 33.3401 +			mCurrentCursor = UI_CURSOR_COUNT;
 33.3402 +			setCursor(temp_cursor);
 33.3403 +		}
 33.3404 +		else {
 33.3405 +			// Override the cursor
 33.3406 +			switch (mDragOverrideCursor) {
 33.3407 +				case 0:
 33.3408 +					setArrowCursor();
 33.3409 +					break;
 33.3410 +				case UI_CURSOR_NO:
 33.3411 +					setNotAllowedCursor();
 33.3412 +				case UI_CURSOR_ARROWCOPY:
 33.3413 +					setCopyCursor();
 33.3414 +				default:
 33.3415 +					break;
 33.3416 +			};
 33.3417  		}
 33.3418  	}
 33.3419 -
 33.3420 -	return result;
 33.3421  }
 33.3422  
 33.3423  #endif // LL_OS_DRAGDROP_ENABLED
    34.1 --- a/indra/llwindow/llwindowmacosx.h	Wed Sep 18 18:44:41 2013 -0400
    34.2 +++ b/indra/llwindow/llwindowmacosx.h	Thu Sep 19 13:13:37 2013 -0400
    34.3 @@ -29,11 +29,12 @@
    34.4  
    34.5  #include "llwindow.h"
    34.6  #include "llwindowcallbacks.h"
    34.7 +#include "llwindowmacosx-objc.h"
    34.8  
    34.9  #include "lltimer.h"
   34.10  
   34.11 -#include <Carbon/Carbon.h>
   34.12 -#include <AGL/agl.h>
   34.13 +#include <ApplicationServices/ApplicationServices.h>
   34.14 +#include <OpenGL/OpenGL.h>
   34.15  
   34.16  // AssertMacros.h does bad things.
   34.17  #include "fix_macros.h"
   34.18 @@ -106,7 +107,6 @@
   34.19  	/*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
   34.20  
   34.21  	/*virtual*/ void *getPlatformWindow();
   34.22 -	/*virtual*/ void *getMediaWindow();
   34.23  	/*virtual*/ void bringToFront() {};
   34.24  	
   34.25  	/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
   34.26 @@ -117,7 +117,17 @@
   34.27  
   34.28  	// Provide native key event data
   34.29  	/*virtual*/ LLSD getNativeKeyData();
   34.30 -
   34.31 +	
   34.32 +	void* getWindow() { return mWindow; }
   34.33 +	LLWindowCallbacks* getCallbacks() { return mCallbacks; }
   34.34 +	LLPreeditor* getPreeditor() { return mPreeditor; }
   34.35 +	
   34.36 +	void updateMouseDeltas(float* deltas);
   34.37 +	void getMouseDeltas(float* delta);
   34.38 +	
   34.39 +	void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action);
   34.40 +    
   34.41 +    bool allowsLanguageInput() { return mLanguageTextInputAllowed; }
   34.42  
   34.43  protected:
   34.44  	LLWindowMacOSX(LLWindowCallbacks* callbacks,
   34.45 @@ -153,40 +163,33 @@
   34.46  	BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync);
   34.47  	void destroyContext();
   34.48  	void setupFailure(const std::string& text, const std::string& caption, U32 type);
   34.49 -	static pascal OSStatus staticEventHandler (EventHandlerCallRef myHandler, EventRef event, void* userData);
   34.50 -	static pascal Boolean staticMoveEventComparator( EventRef event, void* data);
   34.51 -	OSStatus eventHandler (EventHandlerCallRef myHandler, EventRef event);
   34.52  	void adjustCursorDecouple(bool warpingMouse = false);
   34.53 -	void stopDockTileBounce();
   34.54 -	static MASK modifiersToMask(SInt16 modifiers);
   34.55 +	static MASK modifiersToMask(S16 modifiers);
   34.56  	
   34.57  #if LL_OS_DRAGDROP_ENABLED
   34.58 -	static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
   34.59 -									 void * handlerRefCon, DragRef theDrag);
   34.60 -	static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon,	DragRef theDrag);
   34.61 -	OSErr handleDragNDrop(DragRef theDrag, LLWindowCallbacks::DragNDropAction action);
   34.62 +	
   34.63 +	//static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
   34.64 +	//static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon,	DragRef theDrag);
   34.65 +	
   34.66 +	
   34.67  #endif // LL_OS_DRAGDROP_ENABLED
   34.68  	
   34.69  	//
   34.70  	// Platform specific variables
   34.71  	//
   34.72 -	WindowRef		mWindow;
   34.73 -	AGLContext		mContext;
   34.74 -	AGLPixelFormat	mPixelFormat;
   34.75 +	
   34.76 +	// Use generic pointers here.  This lets us do some funky Obj-C interop using Obj-C objects without having to worry about any compilation problems that may arise.
   34.77 +	NSWindowRef			mWindow;
   34.78 +	GLViewRef			mGLView;
   34.79 +	CGLContextObj		mContext;
   34.80 +	CGLPixelFormatObj	mPixelFormat;
   34.81  	CGDirectDisplayID	mDisplay;
   34.82 -	CFDictionaryRef		mOldDisplayMode;
   34.83 -	EventLoopTimerRef	mTimer;
   34.84 -	EventHandlerUPP 	mEventHandlerUPP;
   34.85 -	EventHandlerRef		mGlobalHandlerRef;
   34.86 -	EventHandlerRef		mWindowHandlerRef;
   34.87 -	EventComparatorUPP  mMoveEventCampartorUPP;
   34.88  	
   34.89 -	Rect		mOldMouseClip;  // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
   34.90 -	Rect		mPreviousWindowRect;  // Save previous window for un-maximize event
   34.91 -	Str255 		mWindowTitle;
   34.92 +	LLRect		mOldMouseClip;  // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
   34.93 +	std::string mWindowTitle;
   34.94  	double		mOriginalAspectRatio;
   34.95  	BOOL		mSimulatedRightClick;
   34.96 -	UInt32		mLastModifiers;
   34.97 +	U32			mLastModifiers;
   34.98  	BOOL		mHandsOffEvents;	// When true, temporarially disable CarbonEvent processing.
   34.99  	// Used to allow event processing when putting up dialogs in fullscreen mode.
  34.100  	BOOL		mCursorDecoupled;
  34.101 @@ -201,25 +204,16 @@
  34.102  	U32			mFSAASamples;
  34.103  	BOOL		mForceRebuild;
  34.104  	
  34.105 -	S32			mDragOverrideCursor;
  34.106 -	
  34.107 -	F32			mBounceTime;
  34.108 -	NMRec		mBounceRec;
  34.109 -	LLTimer		mBounceTimer;
  34.110 +	S32	mDragOverrideCursor;
  34.111  
  34.112  	// Input method management through Text Service Manager.
  34.113 -	TSMDocumentID	mTSMDocument;
  34.114  	BOOL		mLanguageTextInputAllowed;
  34.115 -	ScriptCode	mTSMScriptCode;
  34.116 -	LangCode	mTSMLangCode;
  34.117  	LLPreeditor*	mPreeditor;
  34.118  	
  34.119  	static BOOL	sUseMultGL;
  34.120  
  34.121  	friend class LLWindowManager;
  34.122 -	static WindowRef sMediaWindow;
  34.123 -	EventRef 	mRawKeyEvent;
  34.124 -
  34.125 +	
  34.126  };
  34.127  
  34.128  
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/indra/mac_updater/mac_updater.cpp	Thu Sep 19 13:13:37 2013 -0400
    35.3 @@ -0,0 +1,1266 @@
    35.4 +/** 
    35.5 + * @file mac_updater.cpp
    35.6 + * @brief 
    35.7 + *
    35.8 + * $LicenseInfo:firstyear=2006&license=viewerlgpl$
    35.9 + * Second Life Viewer Source Code
   35.10 + * Copyright (C) 2010, Linden Research, Inc.
   35.11 + * 
   35.12 + * This library is free software; you can redistribute it and/or
   35.13 + * modify it under the terms of the GNU Lesser General Public
   35.14 + * License as published by the Free Software Foundation;
   35.15 + * version 2.1 of the License only.
   35.16 + * 
   35.17 + * This library is distributed in the hope that it will be useful,
   35.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   35.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   35.20 + * Lesser General Public License for more details.
   35.21 + * 
   35.22 + * You should have received a copy of the GNU Lesser General Public
   35.23 + * License along with this library; if not, write to the Free Software
   35.24 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   35.25 + * 
   35.26 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   35.27 + * $/LicenseInfo$
   35.28 + */
   35.29 +
   35.30 +#include "linden_common.h"
   35.31 +
   35.32 +#include <boost/format.hpp>
   35.33 +
   35.34 +#include <libgen.h>
   35.35 +#include <sys/types.h>
   35.36 +#include <sys/stat.h>
   35.37 +#include <unistd.h>
   35.38 +
   35.39 +#include <curl/curl.h>
   35.40 +#include <pthread.h>
   35.41 +
   35.42 +#include "llerror.h"
   35.43 +#include "lltimer.h"
   35.44 +#include "lldir.h"
   35.45 +#include "llfile.h"
   35.46 +
   35.47 +#include "llstring.h"
   35.48 +
   35.49 +#include <Carbon/Carbon.h>
   35.50 +
   35.51 +#include "llerrorcontrol.h"
   35.52 +
   35.53 +#if LL_DARWIN
   35.54 +// FSPathMakeRef, FSObjectCopy, deprecations...
   35.55 +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
   35.56 +#endif
   35.57 +
   35.58 +enum
   35.59 +{
   35.60 +	kEventClassCustom = 'Cust',
   35.61 +	kEventCustomProgress = 'Prog',
   35.62 +	kEventParamCustomCurValue = 'Cur ',
   35.63 +	kEventParamCustomMaxValue = 'Max ',
   35.64 +	kEventParamCustomText = 'Text',
   35.65 +	kEventCustomDone = 'Done',
   35.66 +};
   35.67 +
   35.68 +WindowRef gWindow = NULL;
   35.69 +EventHandlerRef gEventHandler = NULL;
   35.70 +OSStatus gFailure = noErr;
   35.71 +Boolean gCancelled = false;
   35.72 +
   35.73 +const char *gUpdateURL;
   35.74 +const char *gProductName;
   35.75 +const char *gBundleID;
   35.76 +const char *gDmgFile;
   35.77 +const char *gMarkerPath;
   35.78 +
   35.79 +void *updatethreadproc(void*);
   35.80 +
   35.81 +pthread_t updatethread;
   35.82 +
   35.83 +OSStatus setProgress(int cur, int max)
   35.84 +{
   35.85 +	OSStatus err;
   35.86 +	ControlRef progressBar = NULL;
   35.87 +	ControlID id;
   35.88 +
   35.89 +	id.signature = 'prog';
   35.90 +	id.id = 0;
   35.91 +
   35.92 +	err = GetControlByID(gWindow, &id, &progressBar);
   35.93 +	if(err == noErr)
   35.94 +	{
   35.95 +		Boolean indeterminate;
   35.96 +		
   35.97 +		if(max == 0)
   35.98 +		{
   35.99 +			indeterminate = true;
  35.100 +			err = SetControlData(progressBar, kControlEntireControl, kControlProgressBarIndeterminateTag, sizeof(Boolean), (Ptr)&indeterminate);
  35.101 +		}
  35.102 +		else
  35.103 +		{
  35.104 +			double percentage = (double)cur / (double)max;
  35.105 +			SetControlMinimum(progressBar, 0);
  35.106 +			SetControlMaximum(progressBar, 100);
  35.107 +			SetControlValue(progressBar, (SInt16)(percentage * 100));
  35.108 +
  35.109 +			indeterminate = false;
  35.110 +			err = SetControlData(progressBar, kControlEntireControl, kControlProgressBarIndeterminateTag, sizeof(Boolean), (Ptr)&indeterminate);
  35.111 +
  35.112 +			Draw1Control(progressBar);
  35.113 +		}
  35.114 +	}
  35.115 +
  35.116 +	return(err);
  35.117 +}
  35.118 +
  35.119 +OSStatus setProgressText(CFStringRef text)
  35.120 +{
  35.121 +	OSStatus err;
  35.122 +	ControlRef progressText = NULL;
  35.123 +	ControlID id;
  35.124 +
  35.125 +	id.signature = 'what';
  35.126 +	id.id = 0;
  35.127 +
  35.128 +	err = GetControlByID(gWindow, &id, &progressText);
  35.129 +	if(err == noErr)
  35.130 +	{
  35.131 +		err = SetControlData(progressText, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(CFStringRef), (Ptr)&text);
  35.132 +		Draw1Control(progressText);
  35.133 +	}
  35.134 +
  35.135 +	return(err);
  35.136 +}
  35.137 +
  35.138 +OSStatus sendProgress(long cur, long max, CFStringRef text = NULL)
  35.139 +{
  35.140 +	OSStatus result;
  35.141 +	EventRef evt;
  35.142 +	
  35.143 +	result = CreateEvent( 
  35.144 +			NULL,
  35.145 +			kEventClassCustom, 
  35.146 +			kEventCustomProgress,
  35.147 +			0, 
  35.148 +			kEventAttributeNone, 
  35.149 +			&evt);
  35.150 +	
  35.151 +	// This event needs to be targeted at the window so it goes to the window's handler.
  35.152 +	if(result == noErr)
  35.153 +	{
  35.154 +		EventTargetRef target = GetWindowEventTarget(gWindow);
  35.155 +		result = SetEventParameter (
  35.156 +			evt,
  35.157 +			kEventParamPostTarget,
  35.158 +			typeEventTargetRef,
  35.159 +			sizeof(target),
  35.160 +			&target);
  35.161 +	}
  35.162 +
  35.163 +	if(result == noErr)
  35.164 +	{
  35.165 +		result = SetEventParameter (
  35.166 +			evt,
  35.167 +			kEventParamCustomCurValue,
  35.168 +			typeLongInteger,
  35.169 +			sizeof(cur),
  35.170 +			&cur);
  35.171 +	}
  35.172 +
  35.173 +	if(result == noErr)
  35.174 +	{
  35.175 +		result = SetEventParameter (
  35.176 +			evt,
  35.177 +			kEventParamCustomMaxValue,
  35.178 +			typeLongInteger,
  35.179 +			sizeof(max),
  35.180 +			&max);
  35.181 +	}
  35.182 +	
  35.183 +	if(result == noErr)
  35.184 +	{
  35.185 +		if(text != NULL)
  35.186 +		{
  35.187 +			result = SetEventParameter (
  35.188 +				evt,
  35.189 +				kEventParamCustomText,
  35.190 +				typeCFStringRef,
  35.191 +				sizeof(text),
  35.192 +				&text);
  35.193 +		}
  35.194 +	}
  35.195 +	
  35.196 +	if(result == noErr)
  35.197 +	{
  35.198 +		// Send the event
  35.199 +		PostEventToQueue(
  35.200 +			GetMainEventQueue(),
  35.201 +			evt,
  35.202 +			kEventPriorityStandard);
  35.203 +
  35.204 +	}
  35.205 +	
  35.206 +	return(result);
  35.207 +}
  35.208 +
  35.209 +OSStatus sendDone(void)
  35.210 +{
  35.211 +	OSStatus result;
  35.212 +	EventRef evt;
  35.213 +	
  35.214 +	result = CreateEvent( 
  35.215 +			NULL,
  35.216 +			kEventClassCustom, 
  35.217 +			kEventCustomDone,
  35.218 +			0, 
  35.219 +			kEventAttributeNone, 
  35.220 +			&evt);
  35.221 +	
  35.222 +	// This event needs to be targeted at the window so it goes to the window's handler.
  35.223 +	if(result == noErr)
  35.224 +	{
  35.225 +		EventTargetRef target = GetWindowEventTarget(gWindow);
  35.226 +		result = SetEventParameter (
  35.227 +			evt,
  35.228 +			kEventParamPostTarget,
  35.229 +			typeEventTargetRef,
  35.230 +			sizeof(target),
  35.231 +			&target);
  35.232 +	}
  35.233 +
  35.234 +	if(result == noErr)
  35.235 +	{
  35.236 +		// Send the event
  35.237 +		PostEventToQueue(
  35.238 +			GetMainEventQueue(),
  35.239 +			evt,
  35.240 +			kEventPriorityStandard);
  35.241 +
  35.242 +	}
  35.243 +	
  35.244 +	return(result);
  35.245 +}
  35.246 +
  35.247 +OSStatus dialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
  35.248 +{
  35.249 +	OSStatus result = eventNotHandledErr;
  35.250 +	OSStatus err;
  35.251 +	UInt32 evtClass = GetEventClass(event);
  35.252 +	UInt32 evtKind = GetEventKind(event);
  35.253 +	
  35.254 +	if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
  35.255 +	{
  35.256 +		HICommand cmd;
  35.257 +		err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
  35.258 +		
  35.259 +		if(err == noErr)
  35.260 +		{
  35.261 +			switch(cmd.commandID)
  35.262 +			{				
  35.263 +				case kHICommandCancel:
  35.264 +					gCancelled = true;
  35.265 +//					QuitAppModalLoopForWindow(gWindow);
  35.266 +					result = noErr;
  35.267 +				break;
  35.268 +			}
  35.269 +		}
  35.270 +	}
  35.271 +	else if((evtClass == kEventClassCustom) && (evtKind == kEventCustomProgress))
  35.272 +	{
  35.273 +		// Request to update the progress dialog
  35.274 +		long cur = 0;
  35.275 +		long max = 0;
  35.276 +		CFStringRef text = NULL;
  35.277 +		(void) GetEventParameter(event, kEventParamCustomCurValue, typeLongInteger, NULL, sizeof(cur), NULL, &cur);
  35.278 +		(void) GetEventParameter(event, kEventParamCustomMaxValue, typeLongInteger, NULL, sizeof(max), NULL, &max);
  35.279 +		(void) GetEventParameter(event, kEventParamCustomText, typeCFStringRef, NULL, sizeof(text), NULL, &text);
  35.280 +		
  35.281 +		err = setProgress(cur, max);
  35.282 +		if(err == noErr)
  35.283 +		{
  35.284 +			if(text != NULL)
  35.285 +			{
  35.286 +				setProgressText(text);
  35.287 +			}
  35.288 +		}
  35.289 +		
  35.290 +		result = noErr;
  35.291 +	}
  35.292 +	else if((evtClass == kEventClassCustom) && (evtKind == kEventCustomDone))
  35.293 +	{
  35.294 +		// We're done.  Exit the modal loop.
  35.295 +		QuitAppModalLoopForWindow(gWindow);
  35.296 +		result = noErr;
  35.297 +	}
  35.298 +	
  35.299 +	return(result);
  35.300 +}
  35.301 +
  35.302 +#if 0
  35.303 +size_t curl_download_callback(void *data, size_t size, size_t nmemb,
  35.304 +										  void *user_data)
  35.305 +{
  35.306 +	S32 bytes = size * nmemb;
  35.307 +	char *cdata = (char *) data;
  35.308 +	for (int i =0; i < bytes; i += 1)
  35.309 +	{
  35.310 +		gServerResponse.append(cdata[i]);
  35.311 +	}
  35.312 +	return bytes;
  35.313 +}
  35.314 +#endif
  35.315 +
  35.316 +int curl_progress_callback_func(void *clientp,
  35.317 +							  double dltotal,
  35.318 +							  double dlnow,
  35.319 +							  double ultotal,
  35.320 +							  double ulnow)
  35.321 +{
  35.322 +	int max = (int)(dltotal / 1024.0);
  35.323 +	int cur = (int)(dlnow / 1024.0);
  35.324 +	sendProgress(cur, max);
  35.325 +	
  35.326 +	if(gCancelled)
  35.327 +		return(1);
  35.328 +
  35.329 +	return(0);
  35.330 +}
  35.331 +
  35.332 +int parse_args(int argc, char **argv)
  35.333 +{
  35.334 +	int j;
  35.335 +
  35.336 +	for (j = 1; j < argc; j++) 
  35.337 +	{
  35.338 +		if ((!strcmp(argv[j], "-url")) && (++j < argc)) 
  35.339 +		{
  35.340 +			gUpdateURL = argv[j];
  35.341 +		}
  35.342 +		else if ((!strcmp(argv[j], "-name")) && (++j < argc)) 
  35.343 +		{
  35.344 +			gProductName = argv[j];
  35.345 +		}
  35.346 +		else if ((!strcmp(argv[j], "-bundleid")) && (++j < argc)) 
  35.347 +		{
  35.348 +			gBundleID = argv[j];
  35.349 +		}
  35.350 +		else if ((!strcmp(argv[j], "-dmg")) && (++j < argc)) 
  35.351 +		{
  35.352 +			gDmgFile = argv[j];
  35.353 +		}
  35.354 +		else if ((!strcmp(argv[j], "-marker")) && (++j < argc)) 
  35.355 +		{
  35.356 +			gMarkerPath = argv[j];;
  35.357 +		}
  35.358 +	}
  35.359 +
  35.360 +	return 0;
  35.361 +}
  35.362 +
  35.363 +int main(int argc, char **argv)
  35.364 +{
  35.365 +	// We assume that all the logs we're looking for reside on the current drive
  35.366 +	gDirUtilp->initAppDirs("SecondLife");
  35.367 +
  35.368 +	LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
  35.369 +
  35.370 +	// Rename current log file to ".old"
  35.371 +	std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log.old");
  35.372 +	std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log");
  35.373 +	LLFile::rename(log_file.c_str(), old_log_file.c_str());
  35.374 +
  35.375 +	// Set the log file to updater.log
  35.376 +	LLError::logToFile(log_file);
  35.377 +
  35.378 +	/////////////////////////////////////////
  35.379 +	//
  35.380 +	// Process command line arguments
  35.381 +	//
  35.382 +	gUpdateURL  = NULL;
  35.383 +	gProductName = NULL;
  35.384 +	gBundleID = NULL;
  35.385 +	gDmgFile = NULL;
  35.386 +	gMarkerPath = NULL;
  35.387 +	parse_args(argc, argv);
  35.388 +	if ((gUpdateURL == NULL) && (gDmgFile == NULL))
  35.389 +	{
  35.390 +		llinfos << "Usage: mac_updater -url <url> | -dmg <dmg file> [-name <product_name>] [-program <program_name>]" << llendl;
  35.391 +		exit(1);
  35.392 +	}
  35.393 +	else
  35.394 +	{
  35.395 +		llinfos << "Update url is: " << gUpdateURL << llendl;
  35.396 +		if (gProductName)
  35.397 +		{
  35.398 +			llinfos << "Product name is: " << gProductName << llendl;
  35.399 +		}
  35.400 +		else
  35.401 +		{
  35.402 +			gProductName = "Second Life";
  35.403 +		}
  35.404 +		if (gBundleID)
  35.405 +		{
  35.406 +			llinfos << "Bundle ID is: " << gBundleID << llendl;
  35.407 +		}
  35.408 +		else
  35.409 +		{
  35.410 +			gBundleID = "com.secondlife.indra.viewer";
  35.411 +		}
  35.412 +	}
  35.413 +	
  35.414 +	llinfos << "Starting " << gProductName << " Updater" << llendl;
  35.415 +
  35.416 +	// Real UI...
  35.417 +	OSStatus err;
  35.418 +	IBNibRef nib = NULL;
  35.419 +	
  35.420 +	err = CreateNibReference(CFSTR("AutoUpdater"), &nib);
  35.421 +
  35.422 +	char windowTitle[MAX_PATH];		/* Flawfinder: ignore */
  35.423 +	snprintf(windowTitle, sizeof(windowTitle), "%s Updater", gProductName);		
  35.424 +	CFStringRef windowTitleRef = NULL;
  35.425 +	windowTitleRef = CFStringCreateWithCString(NULL, windowTitle, kCFStringEncodingUTF8);
  35.426 +	
  35.427 +	if(err == noErr)
  35.428 +	{
  35.429 +		err = CreateWindowFromNib(nib, CFSTR("Updater"), &gWindow);
  35.430 +	}
  35.431 +
  35.432 +	if (err == noErr)
  35.433 +	{
  35.434 +		err = SetWindowTitleWithCFString(gWindow, windowTitleRef);	
  35.435 +	}
  35.436 +	CFRelease(windowTitleRef);
  35.437 +
  35.438 +	if(err == noErr)
  35.439 +	{
  35.440 +		// Set up an event handler for the window.
  35.441 +		EventTypeSpec handlerEvents[] = 
  35.442 +		{
  35.443 +			{ kEventClassCommand, kEventCommandProcess },
  35.444 +			{ kEventClassCustom, kEventCustomProgress },
  35.445 +			{ kEventClassCustom, kEventCustomDone }
  35.446 +		};
  35.447 +		InstallStandardEventHandler(GetWindowEventTarget(gWindow));
  35.448 +		InstallWindowEventHandler(
  35.449 +				gWindow, 
  35.450 +				NewEventHandlerUPP(dialogHandler), 
  35.451 +				GetEventTypeCount (handlerEvents), 
  35.452 +				handlerEvents, 
  35.453 +				0, 
  35.454 +				&gEventHandler);
  35.455 +	}
  35.456 +	
  35.457 +	if(err == noErr)
  35.458 +	{
  35.459 +		ShowWindow(gWindow);
  35.460 +		SelectWindow(gWindow);
  35.461 +	}
  35.462 +		
  35.463 +	if(err == noErr)
  35.464 +	{
  35.465 +		pthread_create(&updatethread, 
  35.466 +                         NULL,
  35.467 +                         &updatethreadproc, 
  35.468 +                         NULL);
  35.469 +						 
  35.470 +	}
  35.471 +	
  35.472 +	if(err == noErr)
  35.473 +	{
  35.474 +		RunAppModalLoopForWindow(gWindow);
  35.475 +	}
  35.476 +
  35.477 +	void *threadresult;
  35.478 +
  35.479 +	pthread_join(updatethread, &threadresult);
  35.480 +
  35.481 +	if(!gCancelled && (gFailure != noErr))
  35.482 +	{
  35.483 +		// Something went wrong.  Since we always just tell the user to download a new version, we don't really care what.
  35.484 +		AlertStdCFStringAlertParamRec params;
  35.485 +		SInt16 retval_mac = 1;
  35.486 +		DialogRef alert = NULL;
  35.487 +		OSStatus err;
  35.488 +
  35.489 +		params.version = kStdCFStringAlertVersionOne;
  35.490 +		params.movable = false;
  35.491 +		params.helpButton = false;
  35.492 +		params.defaultText = (CFStringRef)kAlertDefaultOKText;
  35.493 +		params.cancelText = 0;
  35.494 +		params.otherText = 0;
  35.495 +		params.defaultButton = 1;
  35.496 +		params.cancelButton = 0;
  35.497 +		params.position = kWindowDefaultPosition;
  35.498 +		params.flags = 0;
  35.499 +
  35.500 +		err = CreateStandardAlert(
  35.501 +				kAlertStopAlert,
  35.502 +				CFSTR("Error"),
  35.503 +				CFSTR("An error occurred while updating Second Life.  Please download the latest version from www.secondlife.com."),
  35.504 +				&params,
  35.505 +				&alert);
  35.506 +		
  35.507 +		if(err == noErr)
  35.508 +		{
  35.509 +			err = RunStandardAlert(
  35.510 +					alert,
  35.511 +					NULL,
  35.512 +					&retval_mac);
  35.513 +		}
  35.514 +		
  35.515 +		if(gMarkerPath != 0)
  35.516 +		{
  35.517 +			// Create a install fail marker that can be used by the viewer to
  35.518 +			// detect install problems.
  35.519 +			std::ofstream stream(gMarkerPath);
  35.520 +			if(stream) stream << -1;
  35.521 +		}
  35.522 +		exit(-1);
  35.523 +	} else {
  35.524 +		exit(0);
  35.525 +	}
  35.526 +
  35.527 +	if(gWindow != NULL)
  35.528 +	{
  35.529 +		DisposeWindow(gWindow);
  35.530 +	}
  35.531 +	
  35.532 +	if(nib != NULL)
  35.533 +	{
  35.534 +		DisposeNibReference(nib);
  35.535 +	}
  35.536 +	
  35.537 +	return 0;
  35.538 +}
  35.539 +
  35.540 +bool isDirWritable(FSRef &dir)
  35.541 +{
  35.542 +	bool result = false;
  35.543 +	
  35.544 +	// Test for a writable directory by creating a directory, then deleting it again.
  35.545 +	// This is kinda lame, but will pretty much always give the right answer.
  35.546 +	
  35.547 +	OSStatus err = noErr;
  35.548 +	char temp[PATH_MAX] = "";		/* Flawfinder: ignore */
  35.549 +
  35.550 +	err = FSRefMakePath(&dir, (UInt8*)temp, sizeof(temp));
  35.551 +
  35.552 +	if(err == noErr)
  35.553 +	{
  35.554 +		strncat(temp, "/.test_XXXXXX", (sizeof(temp) - strlen(temp)) - 1);
  35.555 +		
  35.556 +		if(mkdtemp(temp) != NULL)
  35.557 +		{
  35.558 +			// We were able to make the directory.  This means the directory is writable.
  35.559 +			result = true;
  35.560 +			
  35.561 +			// Clean up.
  35.562 +			rmdir(temp);
  35.563 +		}
  35.564 +	}
  35.565 +
  35.566 +#if 0
  35.567 +	// This seemed like a good idea, but won't tell us if we're on a volume mounted read-only.
  35.568 +	UInt8 perm;
  35.569 +	err = FSGetUserPrivilegesPermissions(&targetParentRef, &perm, NULL);
  35.570 +	if(err == noErr)
  35.571 +	{
  35.572 +		if(perm & kioACUserNoMakeChangesMask)
  35.573 +		{
  35.574 +			// Parent directory isn't writable.
  35.575 +			llinfos << "Target parent directory not writable." << llendl;
  35.576 +			err = -1;
  35.577 +			replacingTarget = false;
  35.578 +		}
  35.579 +	}
  35.580 +#endif
  35.581 +
  35.582 +	return result;
  35.583 +}
  35.584 +
  35.585 +static std::string HFSUniStr255_to_utf8str(const HFSUniStr255* src)
  35.586 +{
  35.587 +	llutf16string string16((U16*)&(src->unicode), src->length);
  35.588 +	std::string result = utf16str_to_utf8str(string16);
  35.589 +	return result;
  35.590 +}
  35.591 +
  35.592 +int restoreObject(const char* aside, const char* target, const char* path, const char* object)
  35.593 +{
  35.594 +	char source[PATH_MAX] = "";		/* Flawfinder: ignore */
  35.595 +	char dest[PATH_MAX] = "";		/* Flawfinder: ignore */
  35.596 +	snprintf(source, sizeof(source), "%s/%s/%s", aside, path, object);		
  35.597 +	snprintf(dest, sizeof(dest), "%s/%s", target, path);		
  35.598 +	FSRef sourceRef;
  35.599 +	FSRef destRef;
  35.600 +	OSStatus err;
  35.601 +	err = FSPathMakeRef((UInt8 *)source, &sourceRef, NULL);
  35.602 +	if(err != noErr) return false;
  35.603 +	err = FSPathMakeRef((UInt8 *)dest, &destRef, NULL);
  35.604 +	if(err != noErr) return false;
  35.605 +
  35.606 +	llinfos << "Copying " << source << " to " << dest << llendl;
  35.607 +
  35.608 +	err = FSCopyObjectSync(
  35.609 +			&sourceRef,
  35.610 +			&destRef,
  35.611 +			NULL,
  35.612 +			NULL,
  35.613 +			kFSFileOperationOverwrite);
  35.614 +
  35.615 +	if(err != noErr) return false;
  35.616 +	return true;
  35.617 +}
  35.618 +
  35.619 +// Replace any mention of "Second Life" with the product name.
  35.620 +void filterFile(const char* filename)
  35.621 +{
  35.622 +	char temp[PATH_MAX] = "";		/* Flawfinder: ignore */
  35.623 +	// First copy the target's version, so we can run it through sed.
  35.624 +	snprintf(temp, sizeof(temp), "cp '%s' '%s.tmp'", filename, filename);		
  35.625 +	system(temp);		/* Flawfinder: ignore */
  35.626 +
  35.627 +	// Now run it through sed.
  35.628 +	snprintf(temp, sizeof(temp), 		
  35.629 +			"sed 's/Second Life/%s/g' '%s.tmp' > '%s'", gProductName, filename, filename);
  35.630 +	system(temp);		/* Flawfinder: ignore */
  35.631 +}
  35.632 +
  35.633 +static bool isFSRefViewerBundle(FSRef *targetRef)
  35.634 +{
  35.635 +	bool result = false;
  35.636 +	CFURLRef targetURL = NULL;
  35.637 +	CFBundleRef targetBundle = NULL;
  35.638 +	CFStringRef targetBundleID = NULL;
  35.639 +	CFStringRef sourceBundleID = NULL;
  35.640 +
  35.641 +	targetURL = CFURLCreateFromFSRef(NULL, targetRef);
  35.642 +
  35.643 +	if(targetURL == NULL)
  35.644 +	{
  35.645 +		llinfos << "Error creating target URL." << llendl;
  35.646 +	}
  35.647 +	else
  35.648 +	{
  35.649 +		targetBundle = CFBundleCreate(NULL, targetURL);
  35.650 +	}
  35.651 +	
  35.652 +	if(targetBundle == NULL)
  35.653 +	{
  35.654 +		llinfos << "Failed to create target bundle." << llendl;
  35.655 +	}
  35.656 +	else
  35.657 +	{
  35.658 +		targetBundleID = CFBundleGetIdentifier(targetBundle);
  35.659 +	}
  35.660 +	
  35.661 +	if(targetBundleID == NULL)
  35.662 +	{
  35.663 +		llinfos << "Couldn't retrieve target bundle ID." << llendl;
  35.664 +	}
  35.665 +	else
  35.666 +	{
  35.667 +		sourceBundleID = CFStringCreateWithCString(NULL, gBundleID, kCFStringEncodingUTF8);
  35.668 +		if(CFStringCompare(sourceBundleID, targetBundleID, 0) == kCFCompareEqualTo)
  35.669 +		{
  35.670 +			// This is the bundle we're looking for.
  35.671 +			result = true;
  35.672 +		}
  35.673 +		else
  35.674 +		{
  35.675 +			llinfos << "Target bundle ID mismatch." << llendl;
  35.676 +		}
  35.677 +	}
  35.678 +	
  35.679 +	// Don't release targetBundleID -- since we don't retain it, it's released when targetBundle is released.
  35.680 +	if(targetURL != NULL)
  35.681 +		CFRelease(targetURL);
  35.682 +	if(targetBundle != NULL)
  35.683 +		CFRelease(targetBundle);
  35.684 +	
  35.685 +	return result;
  35.686 +}
  35.687 +
  35.688 +// Search through the directory specified by 'parent' for an item that appears to be a Second Life viewer.
  35.689 +static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app)
  35.690 +{
  35.691 +	FSIterator		iterator;
  35.692 +	bool			found = false;
  35.693 +
  35.694 +	OSErr err = FSOpenIterator( parent, kFSIterateFlat, &iterator );
  35.695 +	if(!err)
  35.696 +	{
  35.697 +		do
  35.698 +		{
  35.699 +			ItemCount actualObjects = 0;
  35.700 +			Boolean containerChanged = false;
  35.701 +			FSCatalogInfo info;
  35.702 +			FSRef ref;
  35.703 +			HFSUniStr255 unicodeName;
  35.704 +			err = FSGetCatalogInfoBulk( 
  35.705 +					iterator, 
  35.706 +					1, 
  35.707 +					&actualObjects, 
  35.708 +					&containerChanged,
  35.709 +					kFSCatInfoNodeFlags, 
  35.710 +					&info, 
  35.711 +					&ref,
  35.712 +					NULL, 
  35.713 +					&unicodeName );
  35.714 +			
  35.715 +			if(actualObjects == 0)
  35.716 +				break;
  35.717 +				
  35.718 +			if(!err)
  35.719 +			{
  35.720 +				// Call succeeded and not done with the iteration.
  35.721 +				std::string name = HFSUniStr255_to_utf8str(&unicodeName);
  35.722 +
  35.723 +				llinfos << "Considering \"" << name << "\"" << llendl;
  35.724 +
  35.725 +				if(info.nodeFlags & kFSNodeIsDirectoryMask)
  35.726 +				{
  35.727 +					// This is a directory.  See if it's a .app
  35.728 +					if(name.find(".app") != std::string::npos)
  35.729 +					{
  35.730 +						// Looks promising.  Check to see if it has the right bundle identifier.
  35.731 +						if(isFSRefViewerBundle(&ref))
  35.732 +						{
  35.733 +							llinfos << name << " is the one" << llendl;
  35.734 +							// This is the one.  Return it.
  35.735 +							*app = ref;
  35.736 +							found = true;
  35.737 +							break;
  35.738 +						} else {
  35.739 +							llinfos << name << " is not the bundle we are looking for; move along" << llendl;
  35.740 +						}
  35.741 +
  35.742 +					}
  35.743 +				}
  35.744 +			}
  35.745 +		}
  35.746 +		while(!err);
  35.747 +		
  35.748 +		llinfos << "closing the iterator" << llendl;
  35.749 +		
  35.750 +		FSCloseIterator(iterator);
  35.751 +		
  35.752 +		llinfos << "closed" << llendl;
  35.753 +	}
  35.754 +	
  35.755 +	if(!err && !found)
  35.756 +		err = fnfErr;
  35.757 +		
  35.758 +	return err;
  35.759 +}
  35.760 +
  35.761 +void *updatethreadproc(void*)
  35.762 +{
  35.763 +	char tempDir[PATH_MAX] = "";		/* Flawfinder: ignore */
  35.764 +	FSRef tempDirRef;
  35.765 +	char temp[PATH_MAX] = "";	/* Flawfinder: ignore */
  35.766 +	// *NOTE: This buffer length is used in a scanf() below.
  35.767 +	char deviceNode[1024] = "";	/* Flawfinder: ignore */
  35.768 +	LLFILE *downloadFile = NULL;
  35.769 +	OSStatus err;
  35.770 +	ProcessSerialNumber psn;
  35.771 +	char target[PATH_MAX] = "";		/* Flawfinder: ignore */
  35.772 +	FSRef targetRef;
  35.773 +	FSRef targetParentRef;
  35.774 +	FSVolumeRefNum targetVol;
  35.775 +	FSRef trashFolderRef;
  35.776 +	Boolean replacingTarget = false;
  35.777 +
  35.778 +	memset(&tempDirRef, 0, sizeof(tempDirRef));
  35.779 +	memset(&targetRef, 0, sizeof(targetRef));
  35.780 +	memset(&targetParentRef, 0, sizeof(targetParentRef));
  35.781 +	
  35.782 +	try
  35.783 +	{
  35.784 +		// Attempt to get a reference to the Second Life application bundle containing this updater.
  35.785 +		// Any failures during this process will cause us to default to updating /Applications/Second Life.app
  35.786 +		{
  35.787 +			FSRef myBundle;
  35.788 +
  35.789 +			err = GetCurrentProcess(&psn);
  35.790 +			if(err == noErr)
  35.791 +			{
  35.792 +				err = GetProcessBundleLocation(&psn, &myBundle);
  35.793 +			}
  35.794 +
  35.795 +			if(err == noErr)
  35.796 +			{
  35.797 +				// Sanity check:  Make sure the name of the item referenced by targetRef is "Second Life.app".
  35.798 +				FSRefMakePath(&myBundle, (UInt8*)target, sizeof(target));
  35.799 +				
  35.800 +				llinfos << "Updater bundle location: " << target << llendl;
  35.801 +			}
  35.802 +			
  35.803 +			// Our bundle should be in Second Life.app/Contents/Resources/AutoUpdater.app
  35.804 +			// so we need to go up 3 levels to get the path to the main application bundle.
  35.805 +			if(err == noErr)
  35.806 +			{
  35.807 +				err = FSGetCatalogInfo(&myBundle, kFSCatInfoNone, NULL, NULL, NULL, &targetRef);
  35.808 +			}
  35.809 +			if(err == noErr)
  35.810 +			{
  35.811 +				err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetRef);
  35.812 +			}
  35.813 +			if(err == noErr)
  35.814 +			{
  35.815 +				err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetRef);
  35.816 +			}
  35.817 +			
  35.818 +			// And once more to get the parent of the target
  35.819 +			if(err == noErr)
  35.820 +			{
  35.821 +				err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetParentRef);
  35.822 +			}
  35.823 +			
  35.824 +			if(err == noErr)
  35.825 +			{
  35.826 +				FSRefMakePath(&targetRef, (UInt8*)target, sizeof(target));
  35.827 +				llinfos << "Path to target: " << target << llendl;
  35.828 +			}
  35.829 +			
  35.830 +			// Sanity check: make sure the target is a bundle with the right identifier
  35.831 +			if(err == noErr)
  35.832 +			{
  35.833 +				// Assume the worst...
  35.834 +				err = -1;
  35.835 +
  35.836 +				if(isFSRefViewerBundle(&targetRef))
  35.837 +				{
  35.838 +					// This is the bundle we're looking for.
  35.839 +					err = noErr;
  35.840 +					replacingTarget = true;
  35.841 +				}
  35.842 +			}
  35.843 +			
  35.844 +			// Make sure the target's parent directory is writable.
  35.845 +			if(err == noErr)
  35.846 +			{
  35.847 +				if(!isDirWritable(targetParentRef))
  35.848 +				{
  35.849 +					// Parent directory isn't writable.
  35.850 +					llinfos << "Target parent directory not writable." << llendl;
  35.851 +					err = -1;
  35.852 +					replacingTarget = false;
  35.853 +				}
  35.854 +			}
  35.855 +
  35.856 +			if(err != noErr)
  35.857 +			{
  35.858 +				Boolean isDirectory;
  35.859 +				llinfos << "Target search failed, defaulting to /Applications/" << gProductName << ".app." << llendl;
  35.860 +				
  35.861 +				// Set up the parent directory
  35.862 +				err = FSPathMakeRef((UInt8*)"/Applications", &targetParentRef, &isDirectory);
  35.863 +				if((err != noErr) || (!isDirectory))
  35.864 +				{
  35.865 +					// We're so hosed.
  35.866 +					llinfos << "Applications directory not found, giving up." << llendl;
  35.867 +					throw 0;
  35.868 +				}
  35.869 +				
  35.870 +				snprintf(target, sizeof(target), "/Applications/%s.app", gProductName);		
  35.871 +
  35.872 +				memset(&targetRef, 0, sizeof(targetRef));
  35.873 +				err = FSPathMakeRef((UInt8*)target, &targetRef, NULL);
  35.874 +				if(err == fnfErr)
  35.875 +				{
  35.876 +					// This is fine, just means we're not replacing anything.
  35.877 +					err = noErr;
  35.878 +					replacingTarget = false;
  35.879 +				}
  35.880 +				else
  35.881 +				{
  35.882 +					replacingTarget = true;
  35.883 +				}
  35.884 +
  35.885 +				// Make sure the target's parent directory is writable.
  35.886 +				if(err == noErr)
  35.887 +				{
  35.888 +					if(!isDirWritable(targetParentRef))
  35.889 +					{
  35.890 +						// Parent directory isn't writable.
  35.891 +						llinfos << "Target parent directory not writable." << llendl;
  35.892 +						err = -1;
  35.893 +						replacingTarget = false;
  35.894 +					}
  35.895 +				}
  35.896 +
  35.897 +			}
  35.898 +			
  35.899 +			// If we haven't fixed all problems by this point, just bail.
  35.900 +			if(err != noErr)
  35.901 +			{
  35.902 +				llinfos << "Unable to pick a target, giving up." << llendl;
  35.903 +				throw 0;
  35.904 +			}
  35.905 +		}
  35.906 +		
  35.907 +		// Find the volID of the volume the target resides on
  35.908 +		{
  35.909 +			FSCatalogInfo info;
  35.910 +			err = FSGetCatalogInfo(
  35.911 +				&targetParentRef,
  35.912 +				kFSCatInfoVolume,
  35.913 +				&info,
  35.914 +				NULL, 
  35.915 +				NULL,  
  35.916 +				NULL);
  35.917 +				
  35.918 +			if(err != noErr)
  35.919 +				throw 0;
  35.920 +			
  35.921 +			targetVol = info.volume;
  35.922 +		}
  35.923 +
  35.924 +		// Find the temporary items and trash folders on that volume.
  35.925 +		err = FSFindFolder(
  35.926 +			targetVol,
  35.927 +			kTrashFolderType,
  35.928 +			true,
  35.929 +			&trashFolderRef);
  35.930 +
  35.931 +		if(err != noErr)
  35.932 +			throw 0;
  35.933 +
  35.934 +#if 0 // *HACK for DEV-11935 see below for details.
  35.935 +
  35.936 +		FSRef tempFolderRef;
  35.937 +
  35.938 +		err = FSFindFolder(
  35.939 +			targetVol,
  35.940 +			kTemporaryFolderType,
  35.941 +			true,
  35.942 +			&tempFolderRef);
  35.943 +		
  35.944 +		if(err != noErr)
  35.945 +			throw 0;
  35.946 +		
  35.947 +		err = FSRefMakePath(&tempFolderRef, (UInt8*)temp, sizeof(temp));
  35.948 +
  35.949 +		if(err != noErr)
  35.950 +			throw 0;
  35.951 +
  35.952 +#else		
  35.953 +
  35.954 +		// *HACK for DEV-11935  the above kTemporaryFolderType query was giving
  35.955 +		// back results with path names that seem to be too long to be used as
  35.956 +		// mount points.  I suspect this incompatibility was introduced in the
  35.957 +		// Leopard 10.5.2 update, but I have not verified this. 
  35.958 +		char const HARDCODED_TMP[] = "/tmp";
  35.959 +		strncpy(temp, HARDCODED_TMP, sizeof(HARDCODED_TMP));
  35.960 +
  35.961 +#endif // 0 *HACK for DEV-11935
  35.962 +		
  35.963 +		// Skip downloading the file if the dmg was passed on the command line.
  35.964 +		std::string dmgName;
  35.965 +		if(gDmgFile != NULL) {
  35.966 +			dmgName = basename((char *)gDmgFile);
  35.967 +			char * dmgDir = dirname((char *)gDmgFile);
  35.968 +			strncpy(tempDir, dmgDir, sizeof(tempDir));
  35.969 +			err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL);
  35.970 +			if(err != noErr) throw 0;
  35.971 +			chdir(tempDir);
  35.972 +			goto begin_install;
  35.973 +		} else {
  35.974 +			// Continue on to download file.
  35.975 +			dmgName = "SecondLife.dmg";
  35.976 +		}
  35.977 +
  35.978 +		
  35.979 +		strncat(temp, "/SecondLifeUpdate_XXXXXX", (sizeof(temp) - strlen(temp)) - 1);
  35.980 +		if(mkdtemp(temp) == NULL)
  35.981 +		{
  35.982 +			throw 0;
  35.983 +		}
  35.984 +		
  35.985 +		strncpy(tempDir, temp, sizeof(tempDir));
  35.986 +		temp[sizeof(tempDir) - 1] = '\0';
  35.987 +		
  35.988 +		llinfos << "tempDir is " << tempDir << llendl;
  35.989 +
  35.990 +		err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL);
  35.991 +
  35.992 +		if(err != noErr)
  35.993 +			throw 0;
  35.994 +				
  35.995 +		chdir(tempDir);
  35.996 +		
  35.997 +		snprintf(temp, sizeof(temp), "SecondLife.dmg");		
  35.998 +		
  35.999 +		downloadFile = LLFile::fopen(temp, "wb");		/* Flawfinder: ignore */
 35.1000 +		if(downloadFile == NULL)
 35.1001 +		{
 35.1002 +			throw 0;
 35.1003 +		}
 35.1004 +
 35.1005 +		{
 35.1006 +			CURL *curl = curl_easy_init();
 35.1007 +
 35.1008 +			curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
 35.1009 +	//		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curl_download_callback);
 35.1010 +			curl_easy_setopt(curl, CURLOPT_FILE, downloadFile);
 35.1011 +			curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
 35.1012 +			curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, &curl_progress_callback_func);
 35.1013 +			curl_easy_setopt(curl, CURLOPT_URL,	gUpdateURL);
 35.1014 +			curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
 35.1015 +			
 35.1016 +			sendProgress(0, 1, CFSTR("Downloading..."));
 35.1017 +			
 35.1018 +			CURLcode result = curl_easy_perform(curl);
 35.1019 +			
 35.1020 +			curl_easy_cleanup(curl);
 35.1021 +			
 35.1022 +			if(gCancelled)
 35.1023 +			{
 35.1024 +				llinfos << "User cancel, bailing out."<< llendl;
 35.1025 +				throw 0;
 35.1026 +			}
 35.1027 +			
 35.1028 +			if(result != CURLE_OK)
 35.1029 +			{
 35.1030 +				llinfos << "Error " << result << " while downloading disk image."<< llendl;
 35.1031 +				throw 0;
 35.1032 +			}
 35.1033 +			
 35.1034 +			fclose(downloadFile);
 35.1035 +			downloadFile = NULL;
 35.1036 +		}
 35.1037 +
 35.1038 +	begin_install:
 35.1039 +		sendProgress(0, 0, CFSTR("Mounting image..."));
 35.1040 +		LLFile::mkdir("mnt", 0700);
 35.1041 +		
 35.1042 +		// NOTE: we could add -private at the end of this command line to keep the image from showing up in the Finder,
 35.1043 +		//		but if our cleanup fails, this makes it much harder for the user to unmount the image.
 35.1044 +		std::string mountOutput;
 35.1045 +		boost::format cmdFormat("hdiutil attach %s -mountpoint mnt");
 35.1046 +		cmdFormat % dmgName;
 35.1047 +		FILE* mounter = popen(cmdFormat.str().c_str(), "r");		/* Flawfinder: ignore */
 35.1048 +		
 35.1049 +		if(mounter == NULL)
 35.1050 +		{
 35.1051 +			llinfos << "Failed to mount disk image, exiting."<< llendl;
 35.1052 +			throw 0;
 35.1053 +		}
 35.1054 +		
 35.1055 +		// We need to scan the output from hdiutil to find the device node it uses to attach the disk image.
 35.1056 +		// If we don't have this information, we can't detach it later.
 35.1057 +		while(mounter != NULL)
 35.1058 +		{
 35.1059 +			size_t len = fread(temp, 1, sizeof(temp)-1, mounter);
 35.1060 +			temp[len] = 0;
 35.1061 +			mountOutput.append(temp);
 35.1062 +			if(len < sizeof(temp)-1)
 35.1063 +			{
 35.1064 +				// End of file or error.
 35.1065 +				int result = pclose(mounter);
 35.1066 +				if(result != 0)
 35.1067 +				{
 35.1068 +					// NOTE: We used to abort here, but pclose() started returning 
 35.1069 +					// -1, possibly when the size of the DMG passed a certain point 
 35.1070 +					llinfos << "Unexpected result closing pipe: " << result << llendl; 
 35.1071 +				}
 35.1072 +				mounter = NULL;
 35.1073 +			}
 35.1074 +		}
 35.1075 +		
 35.1076 +		if(!mountOutput.empty())
 35.1077 +		{
 35.1078 +			const char *s = mountOutput.c_str();
 35.1079 +			const char *prefix = "/dev/";
 35.1080 +			char *sub = strstr(s, prefix);
 35.1081 +			
 35.1082 +			if(sub != NULL)
 35.1083 +			{
 35.1084 +				sub += strlen(prefix);	/* Flawfinder: ignore */
 35.1085 +				sscanf(sub, "%1023s", deviceNode);	/* Flawfinder: ignore */
 35.1086 +			}
 35.1087 +		}
 35.1088 +		
 35.1089 +		if(deviceNode[0] != 0)
 35.1090 +		{
 35.1091 +			llinfos << "Disk image attached on /dev/" << deviceNode << llendl;
 35.1092 +		}
 35.1093 +		else
 35.1094 +		{
 35.1095 +			llinfos << "Disk image device node not found!" << llendl;
 35.1096 +			throw 0; 
 35.1097 +		}
 35.1098 +		
 35.1099 +		// Get an FSRef to the new application on the disk image
 35.1100 +		FSRef sourceRef;
 35.1101 +		FSRef mountRef;
 35.1102 +		snprintf(temp, sizeof(temp), "%s/mnt", tempDir);		
 35.1103 +
 35.1104 +		llinfos << "Disk image mount point is: " << temp << llendl;
 35.1105 +
 35.1106 +		err = FSPathMakeRef((UInt8 *)temp, &mountRef, NULL);
 35.1107 +		if(err != noErr)
 35.1108 +		{
 35.1109 +			llinfos << "Couldn't make FSRef to disk image mount point." << llendl;
 35.1110 +			throw 0;
 35.1111 +		}
 35.1112 +
 35.1113 +		sendProgress(0, 0, CFSTR("Searching for the app bundle..."));
 35.1114 +		err = findAppBundleOnDiskImage(&mountRef, &sourceRef);
 35.1115 +		if(err != noErr)
 35.1116 +		{
 35.1117 +			llinfos << "Couldn't find application bundle on mounted disk image." << llendl;
 35.1118 +			throw 0;
 35.1119 +		}
 35.1120 +		else
 35.1121 +		{
 35.1122 +			llinfos << "found the bundle." << llendl;
 35.1123 +		}
 35.1124 +
 35.1125 +		sendProgress(0, 0, CFSTR("Preparing to copy files..."));
 35.1126 +		
 35.1127 +		FSRef asideRef;
 35.1128 +		char aside[MAX_PATH];		/* Flawfinder: ignore */
 35.1129 +		
 35.1130 +		// this will hold the name of the destination target
 35.1131 +		CFStringRef appNameRef;
 35.1132 +
 35.1133 +		if(replacingTarget)
 35.1134 +		{
 35.1135 +			// Get the name of the target we're replacing
 35.1136 +			HFSUniStr255 appNameUniStr;
 35.1137 +			err = FSGetCatalogInfo(&targetRef, 0, NULL, &appNameUniStr, NULL, NULL);
 35.1138 +			if(err != noErr)
 35.1139 +				throw 0;
 35.1140 +			appNameRef = FSCreateStringFromHFSUniStr(NULL, &appNameUniStr);
 35.1141 +			
 35.1142 +			// Move aside old version (into work directory)
 35.1143 +			err = FSMoveObject(&targetRef, &tempDirRef, &asideRef);
 35.1144 +			if(err != noErr)
 35.1145 +			{
 35.1146 +				llwarns << "failed to move aside old version (error code " << 
 35.1147 +					err << ")" << llendl;
 35.1148 +				throw 0;
 35.1149 +			}
 35.1150 +
 35.1151 +			// Grab the path for later use.
 35.1152 +			err = FSRefMakePath(&asideRef, (UInt8*)aside, sizeof(aside));
 35.1153 +		}
 35.1154 +		else
 35.1155 +		{
 35.1156 +			// Construct the name of the target based on the product name
 35.1157 +			char appName[MAX_PATH];		/* Flawfinder: ignore */
 35.1158 +			snprintf(appName, sizeof(appName), "%s.app", gProductName);		
 35.1159 +			appNameRef = CFStringCreateWithCString(NULL, appName, kCFStringEncodingUTF8);
 35.1160 +		}
 35.1161 +		
 35.1162 +		sendProgress(0, 0, CFSTR("Copying files..."));
 35.1163 +		
 35.1164 +		llinfos << "Starting copy..." << llendl;
 35.1165 +
 35.1166 +		// Copy the new version from the disk image to the target location.
 35.1167 +		err = FSCopyObjectSync(
 35.1168 +				&sourceRef,
 35.1169 +				&targetParentRef,
 35.1170 +				appNameRef,
 35.1171 +				&targetRef,
 35.1172 +				kFSFileOperationDefaultOptions);
 35.1173 +		
 35.1174 +		// Grab the path for later use.
 35.1175 +		err = FSRefMakePath(&targetRef, (UInt8*)target, sizeof(target));
 35.1176 +		if(err != noErr)
 35.1177 +			throw 0;
 35.1178 +
 35.1179 +		llinfos << "Copy complete. Target = " << target << llendl;
 35.1180 +
 35.1181 +		if(err != noErr)
 35.1182 +		{
 35.1183 +			// Something went wrong during the copy.  Attempt to put the old version back and bail.
 35.1184 +			(void)FSDeleteObject(&targetRef);
 35.1185 +			if(replacingTarget)
 35.1186 +			{
 35.1187 +				(void)FSMoveObject(&asideRef, &targetParentRef, NULL);
 35.1188 +			}
 35.1189 +			throw 0;
 35.1190 +		}
 35.1191 +		else
 35.1192 +		{
 35.1193 +			// The update has succeeded.  Clear the cache directory.
 35.1194 +
 35.1195 +			sendProgress(0, 0, CFSTR("Clearing cache..."));
 35.1196 +	
 35.1197 +			llinfos << "Clearing cache..." << llendl;
 35.1198 +			
 35.1199 +			gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
 35.1200 +			
 35.1201 +			llinfos << "Clear complete." << llendl;
 35.1202 +
 35.1203 +		}
 35.1204 +	}
 35.1205 +	catch(...)
 35.1206 +	{
 35.1207 +		if(!gCancelled)
 35.1208 +			if(gFailure == noErr)
 35.1209 +				gFailure = -1;
 35.1210 +	}
 35.1211 +
 35.1212 +	// Failures from here on out are all non-fatal and not reported.
 35.1213 +	sendProgress(0, 3, CFSTR("Cleaning up..."));
 35.1214 +
 35.1215 +	// Close disk image file if necessary
 35.1216 +	if(downloadFile != NULL)
 35.1217 +	{
 35.1218 +		llinfos << "Closing download file." << llendl;
 35.1219 +
 35.1220 +		fclose(downloadFile);
 35.1221 +		downloadFile = NULL;
 35.1222 +	}
 35.1223 +
 35.1224 +	sendProgress(1, 3);
 35.1225 +	// Unmount image
 35.1226 +	if(deviceNode[0] != 0)
 35.1227 +	{
 35.1228 +		llinfos << "Detaching disk image." << llendl;
 35.1229 +
 35.1230 +		snprintf(temp, sizeof(temp), "hdiutil detach '%s'", deviceNode);		
 35.1231 +		system(temp);		/* Flawfinder: ignore */
 35.1232 +	}
 35.1233 +
 35.1234 +	sendProgress(2, 3);
 35.1235 +
 35.1236 +	// Move work directory to the trash
 35.1237 +	if(tempDir[0] != 0)
 35.1238 +	{
 35.1239 +		llinfos << "Moving work directory to the trash." << llendl;
 35.1240 +
 35.1241 +		FSRef trashRef;
 35.1242 +		OSStatus err = FSMoveObjectToTrashSync(&tempDirRef, &trashRef, 0); 
 35.1243 +		if(err != noErr) {
 35.1244 +			llwarns << "failed to move files to trash, (error code " <<
 35.1245 +				err << ")" << llendl;
 35.1246 +		}
 35.1247 +	}
 35.1248 +	
 35.1249 +	if(!gCancelled  && !gFailure && (target[0] != 0))
 35.1250 +	{
 35.1251 +		llinfos << "Touching application bundle." << llendl;
 35.1252 +
 35.1253 +		snprintf(temp, sizeof(temp), "touch '%s'", target);		
 35.1254 +		system(temp);		/* Flawfinder: ignore */
 35.1255 +
 35.1256 +		llinfos << "Launching updated application." << llendl;
 35.1257 +
 35.1258 +		snprintf(temp, sizeof(temp), "open '%s'", target);		
 35.1259 +		system(temp);		/* Flawfinder: ignore */
 35.1260 +	}
 35.1261 +
 35.1262 +	sendDone();
 35.1263 +	
 35.1264 +	return(NULL);
 35.1265 +}
 35.1266 +
 35.1267 +#if LL_DARWIN
 35.1268 +#pragma GCC diagnostic warning "-Wdeprecated-declarations"
 35.1269 +#endif
    36.1 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp	Wed Sep 18 18:44:41 2013 -0400
    36.2 +++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp	Thu Sep 19 13:13:37 2013 -0400
    36.3 @@ -232,12 +232,8 @@
    36.4  			mMovieHandle = NULL;
    36.5  		};
    36.6  
    36.7 -		if ( mGWorldHandle )
    36.8 -		{
    36.9 -			DisposeGWorld( mGWorldHandle );
   36.10 -			mGWorldHandle = NULL;
   36.11 -		};
   36.12 -
   36.13 +        mGWorldHandle = NULL;
   36.14 +        
   36.15  		setStatus(STATUS_NONE);
   36.16  
   36.17  		return true;
   36.18 @@ -273,6 +269,7 @@
   36.19  				//std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl;
   36.20  			}
   36.21  		}
   36.22 +        
   36.23  
   36.24  		// sanitize destination size
   36.25  		Rect dest_rect = rectFromSize(mWidth, mHeight);
   36.26 @@ -281,12 +278,10 @@
   36.27  		int depth_bits = mDepth * 8;
   36.28  		long rowbytes = mDepth * mTextureWidth;
   36.29  
   36.30 -		GWorldPtr old_gworld_handle = mGWorldHandle;
   36.31 -
   36.32  		if(mPixels != NULL)
   36.33  		{
   36.34  			// We have pixels.  Set up a GWorld pointing at the texture.
   36.35 -			OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
   36.36 +			OSErr result = QTNewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
   36.37  			if ( noErr != result )
   36.38  			{
   36.39  				// TODO: unrecoverable??  throw exception?  return something?
   36.40 @@ -297,7 +292,7 @@
   36.41  		{
   36.42  			// We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally.
   36.43  			Rect tempRect = rectFromSize(1, 1);
   36.44 -			OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
   36.45 +			OSErr result = QTNewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
   36.46  			if ( noErr != result )
   36.47  			{
   36.48  				// TODO: unrecoverable??  throw exception?  return something?
   36.49 @@ -305,14 +300,8 @@
   36.50  			}
   36.51  		}
   36.52  
   36.53 -		SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) );
   36.54 -
   36.55 -		// If the GWorld was already set up, delete it.
   36.56 -		if(old_gworld_handle != NULL)
   36.57 -		{
   36.58 -			DisposeGWorld( old_gworld_handle );
   36.59 -		}
   36.60 -
   36.61 +		SetMovieGWorld( mMovieHandle, mGWorldHandle, NULL );
   36.62 +        
   36.63  		// Set up the movie display matrix
   36.64  		{
   36.65  			// scale movie to fit rect and invert vertically to match opengl image format
   36.66 @@ -579,28 +568,7 @@
   36.67  		}
   36.68  
   36.69  	};
   36.70 -
   36.71 -	int getDataWidth() const
   36.72 -	{
   36.73 -		if ( mGWorldHandle )
   36.74 -		{
   36.75 -			int depth = mDepth;
   36.76 -
   36.77 -			if (depth < 1)
   36.78 -				depth = 1;
   36.79 -
   36.80 -			// ALWAYS use the row bytes from the PixMap if we have a GWorld because
   36.81 -			// sometimes it's not the same as mMediaDepth * mMediaWidth !
   36.82 -			PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle );
   36.83 -			return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth;
   36.84 -		}
   36.85 -		else
   36.86 -		{
   36.87 -			// TODO :   return LLMediaImplCommon::getaDataWidth();
   36.88 -			return 0;
   36.89 -		}
   36.90 -	};
   36.91 -
   36.92 +    
   36.93  	void seek( F64 time )
   36.94  	{
   36.95  		if ( mMovieController )
    37.1 --- a/indra/media_plugins/webkit/mac_volume_catcher.cpp	Wed Sep 18 18:44:41 2013 -0400
    37.2 +++ b/indra/media_plugins/webkit/mac_volume_catcher.cpp	Thu Sep 19 13:13:37 2013 -0400
    37.3 @@ -35,10 +35,13 @@
    37.4  
    37.5  #include "volume_catcher.h"
    37.6  
    37.7 -#include <Carbon/Carbon.h>
    37.8  #include <QuickTime/QuickTime.h>
    37.9  #include <AudioUnit/AudioUnit.h>
   37.10  
   37.11 +#if LL_DARWIN
   37.12 +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
   37.13 +#endif
   37.14 +
   37.15  struct VolumeCatcherStorage;
   37.16  
   37.17  class VolumeCatcherImpl
   37.18 @@ -266,3 +269,6 @@
   37.19  	// No periodic tasks are necessary for this implementation.
   37.20  }
   37.21  
   37.22 +#if LL_DARWIN
   37.23 +#pragma GCC diagnostic warning "-Wdeprecated-declarations"
   37.24 +#endif
    38.1 --- a/indra/newview/CMakeLists.txt	Wed Sep 18 18:44:41 2013 -0400
    38.2 +++ b/indra/newview/CMakeLists.txt	Thu Sep 19 13:13:37 2013 -0400
    38.3 @@ -1272,6 +1272,11 @@
    38.4  
    38.5  if (DARWIN)
    38.6    LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp)
    38.7 +  LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm)
    38.8 +  LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h)
    38.9 +
   38.10 +  # This should be compiled with the viewer.
   38.11 +  LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
   38.12  
   38.13    find_library(AGL_LIBRARY AGL)
   38.14    find_library(APPKIT_LIBRARY AppKit)
   38.15 @@ -1292,7 +1297,7 @@
   38.16      macview.r
   38.17      gpu_table.txt
   38.18      Info-SecondLife.plist
   38.19 -    SecondLife.nib/
   38.20 +    SecondLife.xib/
   38.21      # CMake doesn't seem to support Xcode language variants well just yet
   38.22      English.lproj/InfoPlist.strings
   38.23      English.lproj/language.txt
   38.24 @@ -1972,20 +1977,25 @@
   38.25  endif (LINUX)
   38.26  
   38.27  if (DARWIN)
   38.28 +  # These all get set with PROPERTIES
   38.29    set(product "Second Life")
   38.30 -
   38.31 +  set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
   38.32 +  set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
   38.33 +  set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
   38.34 +  set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   38.35 +  set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
   38.36 +  set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
   38.37 +  set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
   38.38 +  set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
   38.39 +  set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
   38.40 +  set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
   38.41 +  
   38.42    set_target_properties(
   38.43      ${VIEWER_BINARY_NAME}
   38.44      PROPERTIES
   38.45      OUTPUT_NAME "${product}"
   38.46 -    MACOSX_BUNDLE_INFO_STRING "Second Life Viewer"
   38.47 -    MACOSX_BUNDLE_ICON_FILE "secondlife.icns"
   38.48 -    MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer"
   38.49 -    MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}"
   38.50 -    MACOSX_BUNDLE_BUNDLE_NAME "Second Life"
   38.51 -    MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}"
   38.52 -    MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}"
   38.53 -    MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007"
   38.54 +    MACOSX_BUNDLE_INFO_PLIST
   38.55 +    "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
   38.56      )
   38.57  
   38.58    configure_file(
    39.1 --- a/indra/newview/Info-SecondLife.plist	Wed Sep 18 18:44:41 2013 -0400
    39.2 +++ b/indra/newview/Info-SecondLife.plist	Thu Sep 19 13:13:37 2013 -0400
    39.3 @@ -5,19 +5,33 @@
    39.4  	<key>CFBundleDevelopmentRegion</key>
    39.5  	<string>English</string>
    39.6  	<key>CFBundleExecutable</key>
    39.7 -	<string>Second Life</string>
    39.8 +	<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
    39.9 +	<key>CFBundleGetInfoString</key>
   39.10 +	<string>${MACOSX_BUNDLE_INFO_STRING}</string>
   39.11  	<key>CFBundleIconFile</key>
   39.12 -	<string>secondlife.icns</string>
   39.13 +	<string>${MACOSX_BUNDLE_ICON_FILE}</string>
   39.14  	<key>CFBundleIdentifier</key>
   39.15 -	<string>com.secondlife.indra.viewer</string>
   39.16 +	<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
   39.17  	<key>CFBundleInfoDictionaryVersion</key>
   39.18  	<string>6.0</string>
   39.19 +	<key>CFBundleLongVersionString</key>
   39.20 +	<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
   39.21  	<key>CFBundleName</key>
   39.22 -	<string>Second Life</string>
   39.23 +	<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
   39.24  	<key>CFBundlePackageType</key>
   39.25  	<string>APPL</string>
   39.26 +	<key>CFBundleShortVersionString</key>
   39.27 +	<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
   39.28  	<key>CFBundleSignature</key>
   39.29  	<string>????</string>
   39.30 +	<key>CFBundleVersion</key>
   39.31 +	<string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>
   39.32 +	<key>CSResourcesFileMapped</key>
   39.33 +	<true/>
   39.34 +	<key>LSRequiresCarbon</key>
   39.35 +	<true/>
   39.36 +	<key>NSHumanReadableCopyright</key>
   39.37 +	<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
   39.38  	<key>CFBundleDocumentTypes</key>
   39.39  	<array>
   39.40  		<dict>
   39.41 @@ -59,9 +73,9 @@
   39.42  			<true/>
   39.43  		</dict>
   39.44  	</array>
   39.45 -	<key>CFBundleVersion</key>
   39.46 -	<string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>
   39.47 -	<key>CSResourcesFileMapped</key>
   39.48 -	<true/>
   39.49 +	<key>NSPrincipalClass</key>
   39.50 +	<string>${MACOSX_BUNDLE_NSPRINCIPAL_CLASS}</string>
   39.51 +	<key>NSMainNibFile</key>
   39.52 +	<string>${MACOSX_BUNDLE_NSMAIN_NIB_FILE}</string>
   39.53  </dict>
   39.54  </plist>
    40.1 Binary file indra/newview/SecondLife.nib has changed
    41.1 --- a/indra/newview/SecondLife.nib/classes.nib	Wed Sep 18 18:44:41 2013 -0400
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,4 +0,0 @@
    41.4 -{
    41.5 -IBClasses = ();
    41.6 -IBVersion = 1;
    41.7 -}
    42.1 --- a/indra/newview/SecondLife.nib/info.nib	Wed Sep 18 18:44:41 2013 -0400
    42.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.3 @@ -1,23 +0,0 @@
    42.4 -<?xml version="1.0" encoding="UTF-8"?>
    42.5 -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    42.6 -<plist version="1.0">
    42.7 -<dict>
    42.8 -	<key>IBDocumentLocation</key>
    42.9 -	<string>85 13 356 240 0 0 1280 1002 </string>
   42.10 -	<key>IBEditorPositions</key>
   42.11 -	<dict>
   42.12 -		<key>29</key>
   42.13 -		<string>27 314 247 44 0 0 1280 1002 </string>
   42.14 -	</dict>
   42.15 -	<key>IBFramework Version</key>
   42.16 -	<string>362.0</string>
   42.17 -	<key>IBOpenObjects</key>
   42.18 -	<array>
   42.19 -		<integer>191</integer>
   42.20 -	</array>
   42.21 -	<key>IBSystem Version</key>
   42.22 -	<string>7D24</string>
   42.23 -	<key>targetFramework</key>
   42.24 -	<string>IBCarbonFramework</string>
   42.25 -</dict>
   42.26 -</plist>
    43.1 --- a/indra/newview/SecondLife.nib/objects.xib	Wed Sep 18 18:44:41 2013 -0400
    43.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.3 @@ -1,259 +0,0 @@
    43.4 -<?xml version="1.0" standalone="yes"?>
    43.5 -<object class="NSIBObjectData">
    43.6 -  <string name="targetFramework">IBCarbonFramework</string>
    43.7 -  <object name="rootObject" class="NSCustomObject" id="1">
    43.8 -    <string name="customClass">NSApplication</string>
    43.9 -  </object>
   43.10 -  <array count="31" name="allObjects">
   43.11 -    <object class="IBCarbonMenu" id="29">
   43.12 -      <string name="title">SecondLife</string>
   43.13 -      <array count="4" name="items">
   43.14 -        <object class="IBCarbonMenuItem" id="182">
   43.15 -          <string name="title">Second Life</string>
   43.16 -          <object name="submenu" class="IBCarbonMenu" id="181">
   43.17 -            <string name="title">Second Life</string>
   43.18 -            <array count="1" name="items">
   43.19 -              <object class="IBCarbonMenuItem" id="183">
   43.20 -                <boolean name="disabled">TRUE</boolean>
   43.21 -                <boolean name="updateSingleItem">TRUE</boolean>
   43.22 -                <string name="title">About Second Life</string>
   43.23 -                <int name="keyEquivalentModifier">0</int>
   43.24 -                <ostype name="command">abou</ostype>
   43.25 -              </object>
   43.26 -            </array>
   43.27 -            <string name="name">_NSAppleMenu</string>
   43.28 -          </object>
   43.29 -        </object>
   43.30 -        <object class="IBCarbonMenuItem" id="127">
   43.31 -          <string name="title">File</string>
   43.32 -          <object name="submenu" class="IBCarbonMenu" id="131">
   43.33 -            <string name="title">File</string>
   43.34 -          </object>
   43.35 -        </object>
   43.36 -        <object class="IBCarbonMenuItem" id="152">
   43.37 -          <string name="title">Edit</string>
   43.38 -          <object name="submenu" class="IBCarbonMenu" id="147">
   43.39 -            <string name="title">Edit</string>
   43.40 -            <array count="10" name="items">
   43.41 -              <object class="IBCarbonMenuItem" id="141">
   43.42 -                <boolean name="updateSingleItem">TRUE</boolean>
   43.43 -                <string name="title">Undo</string>
   43.44 -                <string name="keyEquivalent">z</string>
   43.45 -                <ostype name="command">undo</ostype>
   43.46 -              </object>
   43.47 -              <object class="IBCarbonMenuItem" id="146">
   43.48 -                <boolean name="updateSingleItem">TRUE</boolean>
   43.49 -                <string name="title">Redo</string>
   43.50 -                <string name="keyEquivalent">Z</string>
   43.51 -                <ostype name="command">redo</ostype>
   43.52 -              </object>
   43.53 -              <object class="IBCarbonMenuItem" id="142">
   43.54 -                <boolean name="separator">TRUE</boolean>
   43.55 -              </object>
   43.56 -              <object class="IBCarbonMenuItem" id="143">
   43.57 -                <boolean name="updateSingleItem">TRUE</boolean>
   43.58 -                <string name="title">Cut</string>
   43.59 -                <string name="keyEquivalent">x</string>
   43.60 -                <ostype name="command">cut </ostype>
   43.61 -              </object>
   43.62 -              <object class="IBCarbonMenuItem" id="149">
   43.63 -                <boolean name="updateSingleItem">TRUE</boolean>
   43.64 -                <string name="title">Copy</string>
   43.65 -                <string name="keyEquivalent">c</string>
   43.66 -                <ostype name="command">copy</ostype>
   43.67 -              </object>
   43.68 -              <object class="IBCarbonMenuItem" id="144">
   43.69 -                <boolean name="updateSingleItem">TRUE</boolean>
   43.70 -                <string name="title">Paste</string>
   43.71 -                <string name="keyEquivalent">v</string>
   43.72 -                <ostype name="command">past</ostype>
   43.73 -              </object>
   43.74 -              <object class="IBCarbonMenuItem" id="151">
   43.75 -                <boolean name="updateSingleItem">TRUE</boolean>
   43.76 -                <string name="title">Delete</string>
   43.77 -                <ostype name="command">clea</ostype>
   43.78 -              </object>
   43.79 -              <object class="IBCarbonMenuItem" id="148">
   43.80 -                <boolean name="updateSingleItem">TRUE</boolean>
   43.81 -                <string name="title">Select All</string>
   43.82 -                <string name="keyEquivalent">a</string>
   43.83 -                <ostype name="command">sall</ostype>
   43.84 -              </object>
   43.85 -              <object class="IBCarbonMenuItem" id="188">
   43.86 -                <boolean name="separator">TRUE</boolean>
   43.87 -              </object>
   43.88 -              <object class="IBCarbonMenuItem" id="187">
   43.89 -                <boolean name="updateSingleItem">TRUE</boolean>
   43.90 -                <string name="title">Special Characters…</string>
   43.91 -                <ostype name="command">chrp</ostype>
   43.92 -              </object>
   43.93 -            </array>
   43.94 -          </object>
   43.95 -        </object>
   43.96 -        <object class="IBCarbonMenuItem" id="153">
   43.97 -          <string name="title">Window</string>
   43.98 -          <object name="submenu" class="IBCarbonMenu" id="154">
   43.99 -            <string name="title">Window</string>
  43.100 -            <array count="6" name="items">
  43.101 -              <object class="IBCarbonMenuItem" id="155">
  43.102 -                <boolean name="dynamic">TRUE</boolean>
  43.103 -                <boolean name="updateSingleItem">TRUE</boolean>
  43.104 -                <string name="title">Minimize Window</string>
  43.105 -                <string name="keyEquivalent">m</string>
  43.106 -                <ostype name="command">mini</ostype>
  43.107 -              </object>
  43.108 -              <object class="IBCarbonMenuItem" id="184">
  43.109 -                <boolean name="dynamic">TRUE</boolean>
  43.110 -                <boolean name="updateSingleItem">TRUE</boolean>
  43.111 -                <string name="title">Minimize All Windows</string>
  43.112 -                <string name="keyEquivalent">m</string>
  43.113 -                <int name="keyEquivalentModifier">1572864</int>
  43.114 -                <ostype name="command">mina</ostype>
  43.115 -              </object>
  43.116 -              <object class="IBCarbonMenuItem" id="186">
  43.117 -                <boolean name="updateSingleItem">TRUE</boolean>
  43.118 -                <string name="title">Zoom</string>
  43.119 -                <ostype name="command">zoom</ostype>
  43.120 -              </object>
  43.121 -              <object class="IBCarbonMenuItem" id="156">
  43.122 -                <boolean name="separator">TRUE</boolean>
  43.123 -              </object>
  43.124 -              <object class="IBCarbonMenuItem" id="157">
  43.125 -                <boolean name="dynamic">TRUE</boolean>
  43.126 -                <boolean name="updateSingleItem">TRUE</boolean>
  43.127 -                <string name="title">Bring All to Front</string>
  43.128 -                <ostype name="command">bfrt</ostype>
  43.129 -              </object>
  43.130 -              <object class="IBCarbonMenuItem" id="185">
  43.131 -                <boolean name="dynamic">TRUE</boolean>
  43.132 -                <boolean name="updateSingleItem">TRUE</boolean>
  43.133 -                <string name="title">Arrange in Front</string>
  43.134 -                <int name="keyEquivalentModifier">1572864</int>
  43.135 -                <ostype name="command">frnt</ostype>
  43.136 -              </object>
  43.137 -            </array>
  43.138 -            <string name="name">_NSWindowsMenu</string>
  43.139 -          </object>
  43.140 -        </object>
  43.141 -      </array>
  43.142 -      <string name="name">_NSMainMenu</string>
  43.143 -    </object>
  43.144 -    <reference idRef="127"/>
  43.145 -    <reference idRef="131"/>
  43.146 -    <reference idRef="141"/>
  43.147 -    <reference idRef="142"/>
  43.148 -    <reference idRef="143"/>
  43.149 -    <reference idRef="144"/>
  43.150 -    <reference idRef="146"/>
  43.151 -    <reference idRef="147"/>
  43.152 -    <reference idRef="148"/>
  43.153 -    <reference idRef="149"/>
  43.154 -    <reference idRef="151"/>
  43.155 -    <reference idRef="152"/>
  43.156 -    <reference idRef="153"/>
  43.157 -    <reference idRef="154"/>
  43.158 -    <reference idRef="155"/>
  43.159 -    <reference idRef="156"/>
  43.160 -    <reference idRef="157"/>
  43.161 -    <reference idRef="181"/>
  43.162 -    <reference idRef="182"/>
  43.163 -    <reference idRef="183"/>
  43.164 -    <reference idRef="184"/>
  43.165 -    <reference idRef="185"/>
  43.166 -    <reference idRef="186"/>
  43.167 -    <reference idRef="187"/>
  43.168 -    <reference idRef="188"/>
  43.169 -    <object class="IBCarbonRootControl" id="190">
  43.170 -      <string name="bounds">0 0 482 694 </string>
  43.171 -      <string name="viewFrame">0 0 694 482 </string>
  43.172 -      <array count="2" name="subviews">
  43.173 -        <object class="IBCarbonButton" id="192">
  43.174 -          <string name="bounds">442 604 462 674 </string>
  43.175 -          <string name="viewFrame">604 442 70 20 </string>
  43.176 -          <string name="title">OK</string>
  43.177 -          <ostype name="command">ok  </ostype>
  43.178 -          <object name="layoutInfo" class="IBCarbonHILayoutInfo">
  43.179 -            <int name="bindingBottomKind">2</int>
  43.180 -            <int name="bindingRightKind">2</int>
  43.181 -          </object>
  43.182 -          <int name="buttonType">1</int>
  43.183 -        </object>
  43.184 -        <object class="IBCarbonScrollView" id="201">
  43.185 -          <string name="bounds">20 20 422 674 </string>
  43.186 -          <string name="viewFrame">20 20 654 402 </string>
  43.187 -          <array count="1" name="subviews">
  43.188 -            <object class="IBCarbonTextView" id="200">
  43.189 -              <string name="bounds">20 20 422 659 </string>
  43.190 -              <string name="viewFrame">0 0 639 402 </string>
  43.191 -              <ostype name="controlSignature">text</ostype>
  43.192 -              <int name="fontStyle">5</int>
  43.193 -              <boolean name="readOnly">TRUE</boolean>
  43.194 -            </object>
  43.195 -          </array>
  43.196 -          <boolean name="scrollHorizontally">FALSE</boolean>
  43.197 -        </object>
  43.198 -      </array>
  43.199 -    </object>
  43.200 -    <object class="IBCarbonWindow" id="191">
  43.201 -      <string name="windowRect">84 72 566 766 </string>
  43.202 -      <string name="title">Release Notes</string>
  43.203 -      <reference name="rootControl" idRef="190"/>
  43.204 -      <boolean name="receiveUpdates">FALSE</boolean>
  43.205 -      <boolean name="hasCloseBox">FALSE</boolean>
  43.206 -      <boolean name="hasCollapseBox">FALSE</boolean>
  43.207 -      <boolean name="hasHorizontalZoom">FALSE</boolean>
  43.208 -      <boolean name="isResizable">FALSE</boolean>
  43.209 -      <boolean name="hasVerticalZoom">FALSE</boolean>
  43.210 -      <boolean name="liveResize">TRUE</boolean>
  43.211 -      <boolean name="compositing">TRUE</boolean>
  43.212 -      <int name="carbonWindowClass">4</int>
  43.213 -      <int name="windowPosition">1</int>
  43.214 -      <boolean name="isConstrained">FALSE</boolean>
  43.215 -    </object>
  43.216 -    <reference idRef="192"/>
  43.217 -    <reference idRef="200"/>
  43.218 -    <reference idRef="201"/>
  43.219 -  </array>
  43.220 -  <array count="31" name="allParents">
  43.221 -    <reference idRef="1"/>
  43.222 -    <reference idRef="29"/>
  43.223 -    <reference idRef="127"/>
  43.224 -    <reference idRef="147"/>
  43.225 -    <reference idRef="147"/>
  43.226 -    <reference idRef="147"/>
  43.227 -    <reference idRef="147"/>
  43.228 -    <reference idRef="147"/>
  43.229 -    <reference idRef="152"/>
  43.230 -    <reference idRef="147"/>
  43.231 -    <reference idRef="147"/>
  43.232 -    <reference idRef="147"/>
  43.233 -    <reference idRef="29"/>
  43.234 -    <reference idRef="29"/>
  43.235 -    <reference idRef="153"/>
  43.236 -    <reference idRef="154"/>
  43.237 -    <reference idRef="154"/>
  43.238 -    <reference idRef="154"/>
  43.239 -    <reference idRef="182"/>
  43.240 -    <reference idRef="29"/>
  43.241 -    <reference idRef="181"/>
  43.242 -    <reference idRef="154"/>
  43.243 -    <reference idRef="154"/>
  43.244 -    <reference idRef="154"/>
  43.245 -    <reference idRef="147"/>
  43.246 -    <reference idRef="147"/>
  43.247 -    <reference idRef="191"/>
  43.248 -    <reference idRef="1"/>
  43.249 -    <reference idRef="190"/>
  43.250 -    <reference idRef="201"/>
  43.251 -    <reference idRef="190"/>
  43.252 -  </array>
  43.253 -  <dictionary count="3" name="nameTable">
  43.254 -    <string>Files Owner</string>
  43.255 -    <reference idRef="1"/>
  43.256 -    <string>MenuBar</string>
  43.257 -    <reference idRef="29"/>
  43.258 -    <string>Release Notes</string>
  43.259 -    <reference idRef="191"/>
  43.260 -  </dictionary>
  43.261 -  <unsigned_int name="nextObjectID">202</unsigned_int>
  43.262 -</object>
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/indra/newview/SecondLife.xib	Thu Sep 19 13:13:37 2013 -0400
    44.3 @@ -0,0 +1,1136 @@
    44.4 +<?xml version="1.0" encoding="UTF-8"?>
    44.5 +<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
    44.6 +	<data>
    44.7 +		<int key="IBDocument.SystemTarget">1060</int>
    44.8 +		<string key="IBDocument.SystemVersion">12E55</string>
    44.9 +		<string key="IBDocument.InterfaceBuilderVersion">4457.6</string>
   44.10 +		<string key="IBDocument.AppKitVersion">1187.39</string>
   44.11 +		<string key="IBDocument.HIToolboxVersion">626.00</string>
   44.12 +		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
   44.13 +			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
   44.14 +			<string key="NS.object.0">4457.6</string>
   44.15 +		</object>
   44.16 +		<array key="IBDocument.IntegratedClassDependencies">
   44.17 +			<string>NSCustomObject</string>
   44.18 +			<string>NSMenu</string>
   44.19 +			<string>NSMenuItem</string>
   44.20 +			<string>NSScrollView</string>
   44.21 +			<string>NSScroller</string>
   44.22 +			<string>NSTextView</string>
   44.23 +			<string>NSView</string>
   44.24 +			<string>NSWindowTemplate</string>
   44.25 +		</array>
   44.26 +		<array key="IBDocument.PluginDependencies">
   44.27 +			<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
   44.28 +		</array>
   44.29 +		<object class="NSMutableDictionary" key="IBDocument.Metadata">
   44.30 +			<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
   44.31 +			<integer value="1" key="NS.object.0"/>
   44.32 +		</object>
   44.33 +		<array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
   44.34 +			<object class="NSCustomObject" id="1021">
   44.35 +				<string key="NSClassName">NSApplication</string>
   44.36 +			</object>
   44.37 +			<object class="NSCustomObject" id="1014">
   44.38 +				<string key="NSClassName">FirstResponder</string>
   44.39 +			</object>
   44.40 +			<object class="NSCustomObject" id="1050">
   44.41 +				<string key="NSClassName">NSApplication</string>
   44.42 +			</object>
   44.43 +			<object class="NSMenu" id="649796088">
   44.44 +				<string key="NSTitle">Main Menu</string>
   44.45 +				<array class="NSMutableArray" key="NSMenuItems">
   44.46 +					<object class="NSMenuItem" id="694149608">
   44.47 +						<reference key="NSMenu" ref="649796088"/>
   44.48 +						<string key="NSTitle">Second Life</string>
   44.49 +						<string key="NSKeyEquiv"/>
   44.50 +						<int key="NSMnemonicLoc">2147483647</int>
   44.51 +						<object class="NSCustomResource" key="NSOnImage" id="353210768">
   44.52 +							<string key="NSClassName">NSImage</string>
   44.53 +							<string key="NSResourceName">NSMenuCheckmark</string>
   44.54 +						</object>
   44.55 +						<object class="NSCustomResource" key="NSMixedImage" id="549394948">
   44.56 +							<string key="NSClassName">NSImage</string>
   44.57 +							<string key="NSResourceName">NSMenuMixedState</string>
   44.58 +						</object>
   44.59 +						<string key="NSAction">submenuAction:</string>
   44.60 +						<object class="NSMenu" key="NSSubmenu" id="110575045">
   44.61 +							<string key="NSTitle">Second Life</string>
   44.62 +							<array class="NSMutableArray" key="NSMenuItems">
   44.63 +								<object class="NSMenuItem" id="238522557">
   44.64 +									<reference key="NSMenu" ref="110575045"/>
   44.65 +									<string key="NSTitle">About Second Life</string>
   44.66 +									<string key="NSKeyEquiv"/>
   44.67 +									<int key="NSMnemonicLoc">2147483647</int>
   44.68 +									<reference key="NSOnImage" ref="353210768"/>
   44.69 +									<reference key="NSMixedImage" ref="549394948"/>
   44.70 +								</object>
   44.71 +								<object class="NSMenuItem" id="304266470">
   44.72 +									<reference key="NSMenu" ref="110575045"/>
   44.73 +									<bool key="NSIsDisabled">YES</bool>
   44.74 +									<bool key="NSIsSeparator">YES</bool>
   44.75 +									<string key="NSTitle"/>
   44.76 +									<string key="NSKeyEquiv"/>
   44.77 +									<int key="NSMnemonicLoc">2147483647</int>
   44.78 +									<reference key="NSOnImage" ref="353210768"/>
   44.79 +									<reference key="NSMixedImage" ref="549394948"/>
   44.80 +								</object>
   44.81 +								<object class="NSMenuItem" id="609285721">
   44.82 +									<reference key="NSMenu" ref="110575045"/>
   44.83 +									<string key="NSTitle">Preferences…</string>
   44.84 +									<string key="NSKeyEquiv">,</string>
   44.85 +									<int key="NSKeyEquivModMask">1048576</int>
   44.86 +									<int key="NSMnemonicLoc">2147483647</int>
   44.87 +									<reference key="NSOnImage" ref="353210768"/>
   44.88 +									<reference key="NSMixedImage" ref="549394948"/>
   44.89 +								</object>
   44.90 +								<object class="NSMenuItem" id="481834944">
   44.91 +									<reference key="NSMenu" ref="110575045"/>
   44.92 +									<bool key="NSIsDisabled">YES</bool>
   44.93 +									<bool key="NSIsSeparator">YES</bool>
   44.94 +									<string key="NSTitle"/>
   44.95 +									<string key="NSKeyEquiv"/>
   44.96 +									<int key="NSMnemonicLoc">2147483647</int>
   44.97 +									<reference key="NSOnImage" ref="353210768"/>
   44.98 +									<reference key="NSMixedImage" ref="549394948"/>
   44.99 +								</object>
  44.100 +								<object class="NSMenuItem" id="1046388886">
  44.101 +									<reference key="NSMenu" ref="110575045"/>
  44.102 +									<string key="NSTitle">Services</string>
  44.103 +									<string key="NSKeyEquiv"/>
  44.104 +									<int key="NSMnemonicLoc">2147483647</int>
  44.105 +									<reference key="NSOnImage" ref="353210768"/>
  44.106 +									<reference key="NSMixedImage" ref="549394948"/>
  44.107 +									<string key="NSAction">submenuAction:</string>
  44.108 +									<object class="NSMenu" key="NSSubmenu" id="752062318">
  44.109 +										<string key="NSTitle">Services</string>
  44.110 +										<array class="NSMutableArray" key="NSMenuItems"/>
  44.111 +										<string key="NSName">_NSServicesMenu</string>
  44.112 +									</object>
  44.113 +								</object>
  44.114 +								<object class="NSMenuItem" id="646227648">
  44.115 +									<reference key="NSMenu" ref="110575045"/>
  44.116 +									<bool key="NSIsDisabled">YES</bool>
  44.117 +									<bool key="NSIsSeparator">YES</bool>
  44.118 +									<string key="NSTitle"/>
  44.119 +									<string key="NSKeyEquiv"/>
  44.120 +									<int key="NSMnemonicLoc">2147483647</int>
  44.121 +									<reference key="NSOnImage" ref="353210768"/>
  44.122 +									<reference key="NSMixedImage" ref="549394948"/>
  44.123 +								</object>
  44.124 +								<object class="NSMenuItem" id="755159360">
  44.125 +									<reference key="NSMenu" ref="110575045"/>
  44.126 +									<string key="NSTitle">Hide NewApplication</string>
  44.127 +									<string key="NSKeyEquiv">h</string>
  44.128 +									<int key="NSKeyEquivModMask">1048576</int>
  44.129 +									<int key="NSMnemonicLoc">2147483647</int>
  44.130 +									<reference key="NSOnImage" ref="353210768"/>
  44.131 +									<reference key="NSMixedImage" ref="549394948"/>
  44.132 +								</object>
  44.133 +								<object class="NSMenuItem" id="342932134">
  44.134 +									<reference key="NSMenu" ref="110575045"/>
  44.135 +									<string key="NSTitle">Hide Others</string>
  44.136 +									<string key="NSKeyEquiv">h</string>
  44.137 +									<int key="NSKeyEquivModMask">1572864</int>
  44.138 +									<int key="NSMnemonicLoc">2147483647</int>
  44.139 +									<reference key="NSOnImage" ref="353210768"/>
  44.140 +									<reference key="NSMixedImage" ref="549394948"/>
  44.141 +								</object>
  44.142 +								<object class="NSMenuItem" id="908899353">
  44.143 +									<reference key="NSMenu" ref="110575045"/>
  44.144 +									<string key="NSTitle">Show All</string>
  44.145 +									<string key="NSKeyEquiv"/>
  44.146 +									<int key="NSMnemonicLoc">2147483647</int>
  44.147 +									<reference key="NSOnImage" ref="353210768"/>
  44.148 +									<reference key="NSMixedImage" ref="549394948"/>
  44.149 +								</object>
  44.150 +								<object class="NSMenuItem" id="1056857174">
  44.151 +									<reference key="NSMenu" ref="110575045"/>
  44.152 +									<bool key="NSIsDisabled">YES</bool>
  44.153 +									<bool key="NSIsSeparator">YES</bool>
  44.154 +									<string key="NSTitle"/>
  44.155 +									<string key="NSKeyEquiv"/>
  44.156 +									<int key="NSMnemonicLoc">2147483647</int>
  44.157 +									<reference key="NSOnImage" ref="353210768"/>
  44.158 +									<reference key="NSMixedImage" ref="549394948"/>
  44.159 +								</object>
  44.160 +								<object class="NSMenuItem" id="632727374">
  44.161 +									<reference key="NSMenu" ref="110575045"/>
  44.162 +									<string key="NSTitle">Quit Second Life</string>
  44.163 +									<string key="NSKeyEquiv">q</string>
  44.164 +									<int key="NSKeyEquivModMask">1048576</int>
  44.165 +									<int key="NSMnemonicLoc">2147483647</int>
  44.166 +									<reference key="NSOnImage" ref="353210768"/>
  44.167 +									<reference key="NSMixedImage" ref="549394948"/>
  44.168 +								</object>
  44.169 +							</array>
  44.170 +							<string key="NSName">_NSAppleMenu</string>
  44.171 +						</object>
  44.172 +					</object>
  44.173 +					<object class="NSMenuItem" id="725688984">
  44.174 +						<reference key="NSMenu" ref="649796088"/>
  44.175 +						<string key="NSTitle">Edit</string>
  44.176 +						<string key="NSKeyEquiv"/>
  44.177 +						<int key="NSMnemonicLoc">2147483647</int>
  44.178 +						<reference key="NSOnImage" ref="353210768"/>
  44.179 +						<reference key="NSMixedImage" ref="549394948"/>
  44.180 +						<string key="NSAction">submenuAction:</string>
  44.181 +						<object class="NSMenu" key="NSSubmenu" id="701759256">
  44.182 +							<string key="NSTitle">Edit</string>
  44.183 +							<array class="NSMutableArray" key="NSMenuItems">
  44.184 +								<object class="NSMenuItem" id="521487141">
  44.185 +									<reference key="NSMenu" ref="701759256"/>
  44.186 +									<string key="NSTitle">Undo</string>
  44.187 +									<string key="NSKeyEquiv">z</string>
  44.188 +									<int key="NSKeyEquivModMask">1048576</int>
  44.189 +									<int key="NSMnemonicLoc">2147483647</int>
  44.190 +									<reference key="NSOnImage" ref="353210768"/>
  44.191 +									<reference key="NSMixedImage" ref="549394948"/>
  44.192 +								</object>
  44.193 +								<object class="NSMenuItem" id="668936019">
  44.194 +									<reference key="NSMenu" ref="701759256"/>
  44.195 +									<string key="NSTitle">Redo</string>
  44.196 +									<string key="NSKeyEquiv">Z</string>
  44.197 +									<int key="NSKeyEquivModMask">1048576</int>
  44.198 +									<int key="NSMnemonicLoc">2147483647</int>
  44.199 +									<reference key="NSOnImage" ref="353210768"/>
  44.200 +									<reference key="NSMixedImage" ref="549394948"/>
  44.201 +								</object>
  44.202 +								<object class="NSMenuItem" id="383018193">
  44.203 +									<reference key="NSMenu" ref="701759256"/>
  44.204 +									<bool key="NSIsDisabled">YES</bool>
  44.205 +									<bool key="NSIsSeparator">YES</bool>
  44.206 +									<string key="NSTitle"/>
  44.207 +									<string key="NSKeyEquiv"/>
  44.208 +									<int key="NSMnemonicLoc">2147483647</int>
  44.209 +									<reference key="NSOnImage" ref="353210768"/>
  44.210 +									<reference key="NSMixedImage" ref="549394948"/>
  44.211 +								</object>
  44.212 +								<object class="NSMenuItem" id="984623395">
  44.213 +									<reference key="NSMenu" ref="701759256"/>
  44.214 +									<string key="NSTitle">Cut</string>
  44.215 +									<string key="NSKeyEquiv">x</string>
  44.216 +									<int key="NSKeyEquivModMask">1048576</int>
  44.217 +									<int key="NSMnemonicLoc">2147483647</int>
  44.218 +									<reference key="NSOnImage" ref="353210768"/>
  44.219 +									<reference key="NSMixedImage" ref="549394948"/>
  44.220 +								</object>
  44.221 +								<object class="NSMenuItem" id="656529582">
  44.222 +									<reference key="NSMenu" ref="701759256"/>
  44.223 +									<string key="NSTitle">Copy</string>
  44.224 +									<string key="NSKeyEquiv">c</string>
  44.225 +									<int key="NSKeyEquivModMask">1048576</int>
  44.226 +									<int key="NSMnemonicLoc">2147483647</int>
  44.227 +									<reference key="NSOnImage" ref="353210768"/>
  44.228 +									<reference key="NSMixedImage" ref="549394948"/>
  44.229 +								</object>
  44.230 +								<object class="NSMenuItem" id="1032676691">
  44.231 +									<reference key="NSMenu" ref="701759256"/>
  44.232 +									<string key="NSTitle">Paste</string>
  44.233 +									<string key="NSKeyEquiv">v</string>
  44.234 +									<int key="NSKeyEquivModMask">1048576</int>
  44.235 +									<int key="NSMnemonicLoc">2147483647</int>
  44.236 +									<reference key="NSOnImage" ref="353210768"/>
  44.237 +									<reference key="NSMixedImage" ref="549394948"/>
  44.238 +								</object>
  44.239 +								<object class="NSMenuItem" id="538907583">
  44.240 +									<reference key="NSMenu" ref="701759256"/>
  44.241 +									<string key="NSTitle">Select All</string>
  44.242 +									<string key="NSKeyEquiv">a</string>
  44.243 +									<int key="NSKeyEquivModMask">1048576</int>
  44.244 +									<int key="NSMnemonicLoc">2147483647</int>
  44.245 +									<reference key="NSOnImage" ref="353210768"/>
  44.246 +									<reference key="NSMixedImage" ref="549394948"/>
  44.247 +								</object>
  44.248 +							</array>
  44.249 +						</object>
  44.250 +					</object>
  44.251 +					<object class="NSMenuItem" id="713487014">
  44.252 +						<reference key="NSMenu" ref="649796088"/>
  44.253 +						<string key="NSTitle">Window</string>
  44.254 +						<string key="NSKeyEquiv"/>
  44.255 +						<int key="NSMnemonicLoc">2147483647</int>
  44.256 +						<reference key="NSOnImage" ref="353210768"/>
  44.257 +						<reference key="NSMixedImage" ref="549394948"/>
  44.258 +						<string key="NSAction">submenuAction:</string>
  44.259 +						<object class="NSMenu" key="NSSubmenu" id="835318025">
  44.260 +							<string key="NSTitle">Window</string>
  44.261 +							<array class="NSMutableArray" key="NSMenuItems">
  44.262 +								<object class="NSMenuItem" id="1011231497">
  44.263 +									<reference key="NSMenu" ref="835318025"/>
  44.264 +									<string key="NSTitle">Minimize</string>
  44.265 +									<string key="NSKeyEquiv">m</string>
  44.266 +									<int key="NSKeyEquivModMask">1048576</int>
  44.267 +									<int key="NSMnemonicLoc">2147483647</int>
  44.268 +									<reference key="NSOnImage" ref="353210768"/>
  44.269 +									<reference key="NSMixedImage" ref="549394948"/>
  44.270 +								</object>
  44.271 +								<object class="NSMenuItem" id="575023229">
  44.272 +									<reference key="NSMenu" ref="835318025"/>
  44.273 +									<string key="NSTitle">Zoom</string>
  44.274 +									<string key="NSKeyEquiv"/>
  44.275 +									<int key="NSMnemonicLoc">2147483647</int>
  44.276 +									<reference key="NSOnImage" ref="353210768"/>
  44.277 +									<reference key="NSMixedImage" ref="549394948"/>
  44.278 +								</object>
  44.279 +								<object class="NSMenuItem" id="86356408">
  44.280 +									<reference key="NSMenu" ref="835318025"/>
  44.281 +									<string key="NSTitle">Enter Full Screen</string>
  44.282 +									<string key="NSKeyEquiv">f</string>
  44.283 +									<int key="NSKeyEquivModMask">1310720</int>
  44.284 +									<int key="NSMnemonicLoc">2147483647</int>
  44.285 +									<reference key="NSOnImage" ref="353210768"/>
  44.286 +									<reference key="NSMixedImage" ref="549394948"/>
  44.287 +								</object>
  44.288 +								<object class="NSMenuItem" id="299356726">
  44.289 +									<reference key="NSMenu" ref="835318025"/>
  44.290 +									<bool key="NSIsDisabled">YES</bool>
  44.291 +									<bool key="NSIsSeparator">YES</bool>
  44.292 +									<string key="NSTitle"/>
  44.293 +									<string key="NSKeyEquiv"/>
  44.294 +									<int key="NSMnemonicLoc">2147483647</int>
  44.295 +									<reference key="NSOnImage" ref="353210768"/>
  44.296 +									<reference key="NSMixedImage" ref="549394948"/>
  44.297 +								</object>
  44.298 +								<object class="NSMenuItem" id="625202149">
  44.299 +									<reference key="NSMenu" ref="835318025"/>
  44.300 +									<string key="NSTitle">Bring All to Front</string>
  44.301 +									<string key="NSKeyEquiv"/>
  44.302 +									<int key="NSMnemonicLoc">2147483647</int>
  44.303 +									<reference key="NSOnImage" ref="353210768"/>
  44.304 +									<reference key="NSMixedImage" ref="549394948"/>
  44.305 +								</object>
  44.306 +							</array>
  44.307 +							<string key="NSName">_NSWindowsMenu</string>
  44.308 +						</object>
  44.309 +					</object>
  44.310 +					<object class="NSMenuItem" id="391199113">
  44.311 +						<reference key="NSMenu" ref="649796088"/>
  44.312 +						<string key="NSTitle">Help</string>
  44.313 +						<string key="NSKeyEquiv"/>
  44.314 +						<int key="NSMnemonicLoc">2147483647</int>