Merge for MAINT-3117

master
maksymsproductengine 2013-09-10 20:17:43 +03:00
commit 8a0b7eaadd
69 changed files with 5369 additions and 3540 deletions

View File

@ -56,11 +56,11 @@ a82e5b1e22c7f90e3c7977d146b80588f004ed0d 2.5.0-start
54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f 2.5.0-beta2
54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33--2.5.0beta2
54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33_2.5.0-beta2
b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3
b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
4dede9ae1ec74d41f6887719f6f1de7340d8578d DRTVWR-37_2.5.1-release
@ -464,3 +464,4 @@ f6741d5fe8d632651424484df0fe0cb4a01e9fbe 3.6.2-release
fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release
83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a
91ed595b716f14f07409595b734fda891a59379e 3.6.4-release
bf6d453046011a11de2643fac610cc5258650f82 3.6.5-release

View File

@ -679,6 +679,8 @@ Kagehi Kohn
Kaimen Takahe
Katharine Berry
STORM-1900
STORM-1940
STORM-1941
Keklily Longfall
Ken Lavender
Ken March

View File

@ -134,15 +134,20 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
OUTPUT_VARIABLE XCODE_VERSION )
# To support a different SDK update these Xcode settings:
if (XCODE_VERSION GREATER 4.5)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
set(CMAKE_OSX_SYSROOT macosx10.8)
else (XCODE_VERSION GREATER 4.5)
if (XCODE_VERSION GREATER 4.2)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
set(CMAKE_OSX_SYSROOT macosx10.7)
else (XCODE_VERSION GREATER 4.2)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
set(CMAKE_OSX_SYSROOT macosx10.7)
endif (XCODE_VERSION GREATER 4.2)
endif (XCODE_VERSION GREATER 4.5)
set(CMAKE_OSX_SYSROOT macosx10.6)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
# NOTE: To attempt an i386/PPC Universal build, add this on the configure line:

View File

@ -60,7 +60,8 @@ add_executable(llui_libtest ${llui_libtest_SOURCE_FILES})
# Link with OS-specific libraries for LLWindow dependency
if (DARWIN)
find_library(COCOA_LIBRARY Cocoa)
set(OS_LIBRARIES ${COCOA_LIBRARY})
find_library(IOKIT_LIBRARY IOKit)
set(OS_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY})
elseif (WINDOWS)
#ll_stack_trace needs this now...
list(APPEND WINDOWS_LIBRARIES dbghelp)

View File

@ -310,7 +310,7 @@ LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, con
{
mInternetStreamURL = url;
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_MPEGSEARCH | FMOD_IGNORETAGS, 0, &mInternetStream);
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream);
if (result!= FMOD_OK)
{

View File

@ -67,12 +67,18 @@ using namespace llsd;
# include <sys/sysctl.h>
# include <sys/utsname.h>
# include <stdint.h>
# include <Carbon/Carbon.h>
# include <CoreServices/CoreServices.h>
# include <stdexcept>
# include <mach/host_info.h>
# include <mach/mach_host.h>
# include <mach/task.h>
# include <mach/task_info.h>
// disable warnings about Gestalt calls being deprecated
// until Apple get's on the ball and provides an alternative
//
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif LL_LINUX
# include <errno.h>
# include <sys/utsname.h>
@ -1533,3 +1539,10 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
if (dst != NULL) gzclose(dst);
return retval;
}
#if LL_DARWIN
// disable warnings about Gestalt calls being deprecated
// until Apple get's on the ball and provides an alternative
//
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif

View File

@ -0,0 +1,41 @@
/**
* @file llversionviewer.h
* @brief
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLVERSIONVIEWER_H
#define LL_LLVERSIONVIEWER_H
const S32 LL_VERSION_MAJOR = 3;
const S32 LL_VERSION_MINOR = 4;
const S32 LL_VERSION_PATCH = 6;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";
#if LL_DARWIN
const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
#endif
#endif

View File

@ -802,6 +802,7 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
{
// Scale by 4 to generate proper tex coords.
mProfile[i].mul(scale);
llassert(mProfile[i].isFinite3());
}
if (hollow)
@ -839,6 +840,7 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
{
// Scale by 3 to generate proper tex coords.
mProfile[i].mul(scale);
llassert(mProfile[i].isFinite3());
}
if (path_open)
@ -989,6 +991,7 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
{
mOpen = FALSE;
mProfile.push_back(mProfile[0]);
llassert(mProfile[0].isFinite3());
mTotal++;
}
}
@ -2127,7 +2130,7 @@ BOOL LLVolume::generate()
{
rot_mat.rotate(*profile++, tmp);
dst->setAdd(tmp,offset);
llassert(less_than_max_mag(*dst));
llassert(dst->isFinite3());
++dst;
}
}
@ -2840,6 +2843,8 @@ void LLVolume::sculptGeneratePlaceholder()
p[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS);
p[2] = (F32)(cos(F_PI * v) * RADIUS);
llassert(pt.isFinite3());
}
line += sizeT;
}
@ -2927,6 +2932,8 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8
LLVector4a scale(-1.f,1,1,1);
pt.mul(scale);
}
llassert(pt.isFinite3());
}
line += sizeT;
@ -5552,12 +5559,14 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
tc->mV[0] = (*p)[0]+0.5f;
tc->mV[1] = (*p)[1]+0.5f;
llassert(less_than_max_mag(*src));
llassert(src->isFinite3());
update_min_max(min,max,*src);
update_min_max(min_uv, max_uv, *tc);
*pos = *src;
llassert(pos->isFinite3());
++p;
++tc;
++src;
@ -5577,11 +5586,13 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
tc->mV[0] = (*p)[0]+0.5f;
tc->mV[1] = 0.5f - (*p)[1];
llassert(less_than_max_mag(*src));
llassert(src->isFinite3());
update_min_max(min,max,*src);
update_min_max(min_uv, max_uv, *tc);
*pos = *src;
llassert(pos->isFinite3());
++p;
++tc;
@ -6468,8 +6479,11 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
// mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] }
vector1 = _mm_sub_ps( vector2, _mm_mul_ps( amQ, bmQ ));
llassert(v1.isFinite3());
v1.store4a((F32*) output);
output++;
idx += 3;
}
@ -6498,14 +6512,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
n1.add(c);
n2.add(c);
llassert(llfinite(c.getF32ptr()[0]));
llassert(llfinite(c.getF32ptr()[1]));
llassert(llfinite(c.getF32ptr()[2]));
llassert(!llisnan(c.getF32ptr()[0]));
llassert(!llisnan(c.getF32ptr()[1]));
llassert(!llisnan(c.getF32ptr()[2]));
llassert(c.isFinite3());
//even out quad contributions
switch (i%2+1)
{

View File

@ -1011,12 +1011,7 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
}
#endif
#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1070
#include <OpenGL/gl.h>
#else
#include <AGL/gl.h>
#endif
#endif // LL_MESA / LL_WINDOWS / LL_DARWIN

View File

@ -252,12 +252,15 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
mTex.push_back(tex);
mInternalFormat.push_back(color_fmt);
#if !LL_DARWIN
if (gDebugGL)
{ //bind and unbind to validate target
bindTarget();
flush();
}
#endif
return true;
}

View File

@ -109,11 +109,14 @@ if (DARWIN)
llkeyboardmacosx.cpp
llwindowmacosx.cpp
llwindowmacosx-objc.mm
llopenglview-objc.mm
)
list(APPEND llwindow_HEADER_FILES
llkeyboardmacosx.h
llwindowmacosx.h
llwindowmacosx-objc.h
llopenglview-objc.h
llappdelegate-objc.h
)
# We use a bunch of deprecated system APIs.

View File

@ -0,0 +1,48 @@
/**
* @file llappdelegate-objc.h
* @brief Class interface for the Mac version's application delegate.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#import <Cocoa/Cocoa.h>
#import "llopenglview-objc.h"
@interface LLAppDelegate : NSObject <NSApplicationDelegate> {
LLNSWindow *window;
NSWindow *inputWindow;
LLNonInlineTextView *inputView;
NSTimer *frameTimer;
NSString *currentInputLanguage;
}
@property (assign) IBOutlet LLNSWindow *window;
@property (assign) IBOutlet NSWindow *inputWindow;
@property (assign) IBOutlet LLNonInlineTextView *inputView;
@property (retain) NSString *currentInputLanguage;
- (void) mainLoop;
- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent;
- (void) languageUpdated;
- (bool) romanScript;
@end

View File

@ -82,6 +82,11 @@ public:
virtual BOOL handleKeyUp(const U16 key, MASK mask) = 0;
virtual BOOL handleKeyDown(const U16 key, MASK mask) = 0;
#ifdef LL_DARWIN
// We only actually use this for OS X.
virtual void handleModifier(MASK mask) = 0;
#endif // LL_DARWIN
// Asynchronously poll the control, alt, and shift keys and set the
// appropriate internal key masks.

View File

@ -45,6 +45,13 @@ BOOL LLKeyboardHeadless::handleKeyUp(const U16 key, const U32 mask)
MASK LLKeyboardHeadless::currentMask(BOOL for_mouse_event)
{ return MASK_NONE; }
#ifdef LL_DARWIN
void LLKeyboardHeadless::handleModifier(MASK mask)
{
}
#endif
void LLKeyboardHeadless::scanKeyboard()
{
for (S32 key = 0; key < KEY_COUNT; key++)

View File

@ -40,6 +40,9 @@ public:
/*virtual*/ void resetMaskKeys();
/*virtual*/ MASK currentMask(BOOL for_mouse_event);
/*virtual*/ void scanKeyboard();
#ifdef LL_DARWIN
/*virtual*/ void handleModifier(MASK mask);
#endif
};
#endif

View File

@ -30,7 +30,7 @@
#include "llkeyboardmacosx.h"
#include "llwindowcallbacks.h"
#include <Carbon/Carbon.h>
#include "llwindowmacosx-objc.h"
LLKeyboardMacOSX::LLKeyboardMacOSX()
{
@ -162,23 +162,25 @@ LLKeyboardMacOSX::LLKeyboardMacOSX()
void LLKeyboardMacOSX::resetMaskKeys()
{
U32 mask = GetCurrentEventKeyModifiers();
U32 mask = getModifiers();
// MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
// It looks a bit suspicious, as it won't correct for keys that have been released.
// Is this the way it's supposed to work?
// We apply the modifier masks directly within getModifiers. So check to see which masks we've applied.
if(mask & shiftKey)
if(mask & MAC_SHIFT_KEY)
{
mKeyLevel[KEY_SHIFT] = TRUE;
}
if(mask & (controlKey))
if(mask & MAC_CTRL_KEY)
{
mKeyLevel[KEY_CONTROL] = TRUE;
}
if(mask & optionKey)
if(mask & MAC_ALT_KEY)
{
mKeyLevel[KEY_ALT] = TRUE;
}
@ -196,22 +198,27 @@ static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &out
}
*/
void LLKeyboardMacOSX::handleModifier(MASK mask)
{
updateModifiers(mask);
}
MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
{
// translate the mask
MASK out_mask = 0;
if(mask & shiftKey)
if(mask & MAC_SHIFT_KEY)
{
out_mask |= MASK_SHIFT;
}
if(mask & (controlKey | cmdKey))
if(mask & (MAC_CTRL_KEY | MAC_CMD_KEY))
{
out_mask |= MASK_CONTROL;
}
if(mask & optionKey)
if(mask & MAC_ALT_KEY)
{
out_mask |= MASK_ALT;
}
@ -231,7 +238,7 @@ BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
{
handled = handleTranslatedKeyDown(translated_key, translated_mask);
}
return handled;
}
@ -255,18 +262,18 @@ BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
{
MASK result = MASK_NONE;
U32 mask = GetCurrentEventKeyModifiers();
U32 mask = getModifiers();
if (mask & shiftKey) result |= MASK_SHIFT;
if (mask & controlKey) result |= MASK_CONTROL;
if (mask & optionKey) result |= MASK_ALT;
if (mask & MAC_SHIFT_KEY) result |= MASK_SHIFT;
if (mask & MAC_CTRL_KEY) result |= MASK_CONTROL;
if (mask & MAC_ALT_KEY) result |= MASK_ALT;
// For keyboard events, consider Command equivalent to Control
if (!for_mouse_event)
{
if (mask & cmdKey) result |= MASK_CONTROL;
if (mask & MAC_CMD_KEY) result |= MASK_CONTROL;
}
return result;
}

View File

@ -29,6 +29,15 @@
#include "llkeyboard.h"
// These more or less mirror their equivalents in NSEvent.h.
enum EMacEventKeys {
MAC_SHIFT_KEY = 1 << 17,
MAC_CTRL_KEY = 1 << 18,
MAC_ALT_KEY = 1 << 19,
MAC_CMD_KEY = 1 << 20,
MAC_FN_KEY = 1 << 23
};
class LLKeyboardMacOSX : public LLKeyboard
{
public:
@ -40,6 +49,7 @@ public:
/*virtual*/ void resetMaskKeys();
/*virtual*/ MASK currentMask(BOOL for_mouse_event);
/*virtual*/ void scanKeyboard();
/*virtual*/ void handleModifier(MASK mask);
protected:
MASK updateModifiers(const U32 mask);

View File

@ -0,0 +1,110 @@
/**
* @file llopenglview-objc.h
* @brief Class interfaces for most of the Mac facing window functionality.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LLOpenGLView_H
#define LLOpenGLView_H
#import <Cocoa/Cocoa.h>
#import <IOKit/IOKitLib.h>
#import <CoreFoundation/CFBase.h>
#import <CoreFoundation/CFNumber.h>
#include <string>
@interface LLOpenGLView : NSOpenGLView <NSTextInputClient>
{
std::string mLastDraggedUrl;
unsigned int mModifiers;
float mMousePos[2];
bool mHasMarkedText;
unsigned int mMarkedTextLength;
bool mMarkedTextAllowed;
bool mSimulatedRightClick;
}
- (id) initWithSamples:(NSUInteger)samples;
- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
- (void)commitCurrentPreedit;
// rebuildContext
// Destroys and recreates a context with the view's internal format set via setPixelFormat;
// Use this in event of needing to rebuild a context for whatever reason, without needing to assign a new pixel format.
- (BOOL) rebuildContext;
// rebuildContextWithFormat
// Destroys and recreates a context with the specified pixel format.
- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format;
// These are mostly just for C++ <-> Obj-C interop. We can manipulate the CGLContext from C++ without reprecussions.
- (CGLContextObj) getCGLContextObj;
- (CGLPixelFormatObj*)getCGLPixelFormatObj;
- (unsigned long) getVramSize;
- (void) allowMarkedTextInput:(bool)allowed;
@end
@interface LLUserInputWindow : NSPanel
@end
@interface LLNonInlineTextView : NSTextView
{
LLOpenGLView *glview;
}
- (void) setGLView:(LLOpenGLView*)view;
@end
@interface LLNSWindow : NSWindow
- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view;
- (NSPoint)flipPoint:(NSPoint)aPoint;
@end
@interface NSScreen (PointConversion)
/*
Returns the screen where the mouse resides
*/
+ (NSScreen *)currentScreenForMouseLocation;
/*
Allows you to convert a point from global coordinates to the current screen coordinates.
*/
- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint;
/*
Allows to flip the point coordinates, so y is 0 at the top instead of the bottom. x remains the same
*/
- (NSPoint)flipPoint:(NSPoint)aPoint;
@end
#endif

View File

@ -0,0 +1,686 @@
/**
* @file llopenglview-objc.mm
* @brief Class implementation for most of the Mac facing window functionality.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#import "llopenglview-objc.h"
#include "llwindowmacosx-objc.h"
#import "llappdelegate-objc.h"
@implementation NSScreen (PointConversion)
+ (NSScreen *)currentScreenForMouseLocation
{
NSPoint mouseLocation = [NSEvent mouseLocation];
NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator];
NSScreen *screen;
while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(mouseLocation, screen.frame, NO))
;
return screen;
}
- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint
{
float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x));
float normalizedY = aPoint.y - self.frame.origin.y;
return NSMakePoint(normalizedX, normalizedY);
}
- (NSPoint)flipPoint:(NSPoint)aPoint
{
return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
}
@end
attributedStringInfo getSegments(NSAttributedString *str)
{
attributedStringInfo segments;
segment_lengths seg_lengths;
segment_standouts seg_standouts;
NSRange effectiveRange;
NSRange limitRange = NSMakeRange(0, [str length]);
while (limitRange.length > 0) {
NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange];
limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
if (effectiveRange.length <= 0)
{
effectiveRange.length = 1;
}
if ([attr integerValue] == 2)
{
seg_lengths.push_back(effectiveRange.length);
seg_standouts.push_back(true);
} else
{
seg_lengths.push_back(effectiveRange.length);
seg_standouts.push_back(false);
}
}
segments.seg_lengths = seg_lengths;
segments.seg_standouts = seg_standouts;
return segments;
}
@implementation LLOpenGLView
- (unsigned long)getVramSize
{
CGLRendererInfoObj info = 0;
GLint vram_bytes = 0;
int num_renderers = 0;
CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);
if(0 == the_err)
{
CGLDescribeRenderer (info, 0, kCGLRPTextureMemory, &vram_bytes);
CGLDestroyRendererInfo (info);
}
else
{
vram_bytes = (256 << 20);
}
return (unsigned long)vram_bytes / 1048576; // We need this in megabytes.
}
- (void)viewDidMoveToWindow
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowResized:) name:NSWindowDidResizeNotification
object:[self window]];
}
- (void)windowResized:(NSNotification *)notification;
{
NSSize size = [self frame].size;
callResize(size.width, size.height);
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (id) init
{
return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
}
- (id) initWithSamples:(NSUInteger)samples
{
return [self initWithFrame:[self bounds] withSamples:samples andVsync:TRUE];
}
- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync
{
return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync];
}
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
{
[self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]];
[self initWithFrame:frame];
// Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.
// Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat.
// 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).
NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFANoRecovery,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAClosestPolicy,
NSOpenGLPFAAccelerated,
NSOpenGLPFASampleBuffers, (samples > 0 ? 1 : 0),
NSOpenGLPFASamples, samples,
NSOpenGLPFAStencilSize, 8,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAColorSize, 24,
0
};
NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease];
if (pixelFormat == nil)
{
NSLog(@"Failed to create pixel format!", nil);
return nil;
}
NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
if (glContext == nil)
{
NSLog(@"Failed to create OpenGL context!", nil);
return nil;
}
[self setPixelFormat:pixelFormat];
[self setOpenGLContext:glContext];
[glContext setView:self];
[glContext makeCurrentContext];
if (vsync)
{
[glContext setValues:(const GLint*)1 forParameter:NSOpenGLCPSwapInterval];
} else {
[glContext setValues:(const GLint*)0 forParameter:NSOpenGLCPSwapInterval];
}
return self;
}
- (BOOL) rebuildContext
{
return [self rebuildContextWithFormat:[self pixelFormat]];
}
- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format
{
NSOpenGLContext *ctx = [self openGLContext];
[ctx clearDrawable];
[ctx initWithFormat:format shareContext:nil];
if (ctx == nil)
{
NSLog(@"Failed to create OpenGL context!", nil);
return false;
}
[self setOpenGLContext:ctx];
[ctx setView:self];
[ctx makeCurrentContext];
return true;
}
- (CGLContextObj)getCGLContextObj
{
NSOpenGLContext *ctx = [self openGLContext];
return (CGLContextObj)[ctx CGLContextObj];
}
- (CGLPixelFormatObj*)getCGLPixelFormatObj
{
NSOpenGLPixelFormat *fmt = [self pixelFormat];
return (CGLPixelFormatObj*)[fmt CGLPixelFormatObj];
}
// Various events can be intercepted by our view, thus not reaching our window.
// Intercept these events, and pass them to the window as needed. - Geenz
- (void) mouseDown:(NSEvent *)theEvent
{
// Apparently people still use this?
if ([theEvent modifierFlags] & NSCommandKeyMask &&
!([theEvent modifierFlags] & NSControlKeyMask) &&
!([theEvent modifierFlags] & NSShiftKeyMask) &&
!([theEvent modifierFlags] & NSAlternateKeyMask) &&
!([theEvent modifierFlags] & NSAlphaShiftKeyMask) &&
!([theEvent modifierFlags] & NSFunctionKeyMask) &&
!([theEvent modifierFlags] & NSHelpKeyMask))
{
callRightMouseDown(mMousePos, mModifiers);
mSimulatedRightClick = true;
} else {
if ([theEvent clickCount] >= 2)
{
callDoubleClick(mMousePos, mModifiers);
} else if ([theEvent clickCount] == 1) {
callLeftMouseDown(mMousePos, mModifiers);
}
}
}
- (void) mouseUp:(NSEvent *)theEvent
{
if (mSimulatedRightClick)
{
callRightMouseUp(mMousePos, mModifiers);
mSimulatedRightClick = false;
} else {
callLeftMouseUp(mMousePos, mModifiers);
}
}
- (void) rightMouseDown:(NSEvent *)theEvent
{
callRightMouseDown(mMousePos, mModifiers);
}
- (void) rightMouseUp:(NSEvent *)theEvent
{
callRightMouseUp(mMousePos, mModifiers);
}
- (void)mouseMoved:(NSEvent *)theEvent
{
float mouseDeltas[2] = {
[theEvent deltaX],
[theEvent deltaY]
};
callDeltaUpdate(mouseDeltas, 0);
NSPoint mPoint = [theEvent locationInWindow];
mMousePos[0] = mPoint.x;
mMousePos[1] = mPoint.y;
callMouseMoved(mMousePos, 0);
}
// NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged.
// Use mouseDragged for situations like this to trigger our movement callback instead.
- (void) mouseDragged:(NSEvent *)theEvent
{
// Trust the deltas supplied by NSEvent.
// The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
// NSEvent isn't obsolete, and provides us with the correct deltas.
float mouseDeltas[2] = {
[theEvent deltaX],
[theEvent deltaY]
};
callDeltaUpdate(mouseDeltas, 0);
NSPoint mPoint = [theEvent locationInWindow];
mMousePos[0] = mPoint.x;
mMousePos[1] = mPoint.y;
callMouseMoved(mMousePos, 0);
}
- (void) otherMouseDown:(NSEvent *)theEvent
{
callMiddleMouseDown(mMousePos, mModifiers);
}
- (void) otherMouseUp:(NSEvent *)theEvent
{
callMiddleMouseUp(mMousePos, mModifiers);
}
- (void) otherMouseDragged:(NSEvent *)theEvent
{
}
- (void) scrollWheel:(NSEvent *)theEvent
{
callScrollMoved(-[theEvent deltaY]);
}
- (void) mouseExited:(NSEvent *)theEvent
{
callMouseExit();
}
- (void) keyUp:(NSEvent *)theEvent
{
callKeyUp([theEvent keyCode], mModifiers);
}
- (void) keyDown:(NSEvent *)theEvent
{
uint keycode = [theEvent keyCode];
bool acceptsText = mHasMarkedText ? false : callKeyDown(keycode, mModifiers);
if (acceptsText &&
!mMarkedTextAllowed &&
![(LLAppDelegate*)[NSApp delegate] romanScript] &&
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter &&
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter &&
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDownArrowFunctionKey &&
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSUpArrowFunctionKey &&
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSLeftArrowFunctionKey &&
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSRightArrowFunctionKey)
{
[(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
} else
{
[[self inputContext] handleEvent:theEvent];
}
if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSCarriageReturnCharacter ||
[[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSEnterCharacter)
{
// callKeyDown won't return the value we expect for enter or return. Handle them as a separate case.
[[self inputContext] handleEvent:theEvent];
}
// OS X intentionally does not send us key-up information on cmd-key combinations.
// This behaviour is not a bug, and only applies to cmd-combinations (no others).
// Since SL assumes we receive those, we fake it here.
if (mModifiers & NSCommandKeyMask && !mHasMarkedText)
{
callKeyUp([theEvent keyCode], mModifiers);
}
}
- (void)flagsChanged:(NSEvent *)theEvent {
mModifiers = [theEvent modifierFlags];
callModifier([theEvent modifierFlags]);
}
- (BOOL) acceptsFirstResponder
{
return YES;
}
- (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender
{
NSPasteboard *pboard;
NSDragOperation sourceDragMask;
sourceDragMask = [sender draggingSourceOperationMask];
pboard = [sender draggingPasteboard];
if ([[pboard types] containsObject:NSURLPboardType])
{
if (sourceDragMask & NSDragOperationLink) {
NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0];
mLastDraggedUrl = [[fileUrl absoluteString] UTF8String];
return NSDragOperationLink;
}
}
return NSDragOperationNone;
}
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
{
callHandleDragUpdated(mLastDraggedUrl);
return NSDragOperationLink;
}
- (void) draggingExited:(id<NSDraggingInfo>)sender
{
callHandleDragExited(mLastDraggedUrl);
}
- (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender
{
return YES;
}
- (BOOL) performDragOperation:(id<NSDraggingInfo>)sender
{
callHandleDragDropped(mLastDraggedUrl);
return true;
}
- (BOOL)hasMarkedText
{
return mHasMarkedText;
}
- (NSRange)markedRange
{
int range[2];
getPreeditMarkedRange(&range[0], &range[1]);
return NSMakeRange(range[0], range[1]);
}
- (NSRange)selectedRange
{
int range[2];
getPreeditSelectionRange(&range[0], &range[1]);
return NSMakeRange(range[0], range[1]);
}
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
{
if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
{
if (mMarkedTextAllowed)
{
unsigned int selected[2] = {
selectedRange.location,
selectedRange.length
};
unsigned int replacement[2] = {
replacementRange.location,
replacementRange.length
};
unichar text[[aString length]];
[[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])];
attributedStringInfo segments = getSegments((NSAttributedString *)aString);
setMarkedText(text, selected, replacement, [aString length], segments);
mHasMarkedText = TRUE;
mMarkedTextLength = [aString length];
} else {
if (mHasMarkedText)
{
[self unmarkText];
}
}
}
}
- (void)commitCurrentPreedit
{
if (mHasMarkedText)
{
if ([[self inputContext] respondsToSelector:@selector(commitEditing)])
{
[[self inputContext] commitEditing];
}
}
}
- (void)unmarkText
{
[[self inputContext] discardMarkedText];
resetPreedit();
mHasMarkedText = FALSE;
}
// We don't support attributed strings.
- (NSArray *)validAttributesForMarkedText
{
return [NSArray array];
}
// See above.
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
{
return nil;
}
- (void)insertText:(id)insertString
{
if (insertString != nil)
{
[self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
}
}
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
{
if (!mHasMarkedText)
{
for (NSInteger i = 0; i < [aString length]; i++)
{
callUnicodeCallback([aString characterAtIndex:i], mModifiers);
}
} else {
resetPreedit();
// We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
// But just in case...
for (NSInteger i = 0; i < [aString length]; i++)
{
handleUnicodeCharacter([aString characterAtIndex:i]);
}
mHasMarkedText = FALSE;
}
}
- (void) insertNewline:(id)sender
{
if (!(mModifiers & NSCommandKeyMask) &&
!(mModifiers & NSShiftKeyMask) &&
!(mModifiers & NSAlternateKeyMask))
{
callUnicodeCallback(13, 0);
} else {
callUnicodeCallback(13, mModifiers);
}
}
- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
{
return NSNotFound;
}
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
{
float pos[4] = {0, 0, 0, 0};
getPreeditLocation(pos, mMarkedTextLength);
return NSMakeRect(pos[0], pos[1], pos[2], pos[3]);
}
- (void)doCommandBySelector:(SEL)aSelector
{
if (aSelector == @selector(insertNewline:))
{
[self insertNewline:self];
}
}
- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex
{
return NO;
}
- (void) allowMarkedTextInput:(bool)allowed
{
mMarkedTextAllowed = allowed;
}
@end
@implementation LLUserInputWindow
- (void) close
{
[self orderOut:self];
}
@end
@implementation LLNonInlineTextView
- (void) setGLView:(LLOpenGLView *)view
{
glview = view;
}
- (void) insertText:(id)insertString
{
[[self inputContext] discardMarkedText];
[self setString:@""];
[_window orderOut:_window];
[self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
}
- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
{
[glview insertText:aString replacementRange:replacementRange];
}
- (void) insertNewline:(id)sender
{
[[self textStorage] setValue:@""];
[[self inputContext] discardMarkedText];
[self setString:@""];
}
- (void)doCommandBySelector:(SEL)aSelector
{
if (aSelector == @selector(insertNewline:))
{
[self insertNewline:self];
}
}
@end
@implementation LLNSWindow
- (id) init
{
return self;
}
- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
{
NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
if(currentScreen)
{
NSPoint windowPoint = [view convertPoint:point toView:nil];
NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint];
NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint];
flippedScreenPoint.y += [currentScreen frame].origin.y;
return flippedScreenPoint;
}
return NSZeroPoint;
}
- (NSPoint)flipPoint:(NSPoint)aPoint
{
return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
}
- (BOOL) becomeFirstResponder
{
callFocus();
return true;
}
- (BOOL) resignFirstResponder
{
callFocusLost();
return true;
}
- (void) close
{
callQuitHandler();
}
@end

View File

@ -25,13 +25,121 @@
* $/LicenseInfo$
*/
#include <map>
#include <vector>
typedef std::vector<std::pair<int, bool> > segment_t;
typedef std::vector<int> segment_lengths;
typedef std::vector<int> segment_standouts;
struct attributedStringInfo {
segment_lengths seg_lengths;
segment_standouts seg_standouts;
};
// This will actually hold an NSCursor*, but that type is only available in objective C.
typedef void *CursorRef;
typedef void *NSWindowRef;
typedef void *GLViewRef;
// These are defined in llappviewermacosx.cpp.
bool initViewer();
void handleQuit();
bool runMainLoop();
void initMainLoop();
void cleanupViewer();
/* Defined in llwindowmacosx-objc.mm: */
int createNSApp(int argc, const char **argv);
void setupCocoa();
bool pasteBoardAvailable();
bool copyToPBoard(const unsigned short *str, unsigned int len);
const unsigned short *copyFromPBoard();
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
OSErr releaseImageCursor(CursorRef ref);
OSErr setImageCursor(CursorRef ref);
short releaseImageCursor(CursorRef ref);
short setImageCursor(CursorRef ref);
void setArrowCursor();
void setIBeamCursor();
void setPointingHandCursor();
void setCopyCursor();
void setCrossCursor();
void setNotAllowedCursor();
void hideNSCursor();
void showNSCursor();
void hideNSCursorTillMove(bool hide);
void requestUserAttention();
long showAlert(std::string title, std::string text, int type);
NSWindowRef createNSWindow(int x, int y, int width, int height);
#include <OpenGL/OpenGL.h>
GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync);
void glSwapBuffers(void* context);
CGLContextObj getCGLContextObj(GLViewRef view);
unsigned long getVramSize(GLViewRef view);
void getContentViewBounds(NSWindowRef window, float* bounds);
void getWindowSize(NSWindowRef window, float* size);
void setWindowSize(NSWindowRef window, int width, int height);
void getCursorPos(NSWindowRef window, float* pos);
void makeWindowOrderFront(NSWindowRef window);
void convertScreenToWindow(NSWindowRef window, float *coord);
void convertWindowToScreen(NSWindowRef window, float *coord);
void convertScreenToView(NSWindowRef window, float *coord);
void convertRectToScreen(NSWindowRef window, float *coord);
void convertRectFromScreen(NSWindowRef window, float *coord);
void setWindowPos(NSWindowRef window, float* pos);
void closeWindow(NSWindowRef window);
void removeGLView(GLViewRef view);
void makeFirstResponder(NSWindowRef window, GLViewRef view);
void setupInputWindow(NSWindowRef window, GLViewRef view);
// These are all implemented in llwindowmacosx.cpp.
// This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
bool callKeyUp(unsigned short key, unsigned int mask);
bool callKeyDown(unsigned short key, unsigned int mask);
void callResetKeys();
bool callUnicodeCallback(wchar_t character, unsigned int mask);
void callRightMouseDown(float *pos, unsigned int mask);
void callRightMouseUp(float *pos, unsigned int mask);
void callLeftMouseDown(float *pos, unsigned int mask);
void callLeftMouseUp(float *pos, unsigned int mask);
void callDoubleClick(float *pos, unsigned int mask);
void callResize(unsigned int width, unsigned int height);
void callMouseMoved(float *pos, unsigned int mask);
void callScrollMoved(float delta);
void callMouseExit();
void callWindowFocus();
void callWindowUnfocus();
void callDeltaUpdate(float *delta, unsigned int mask);
void callMiddleMouseDown(float *pos, unsigned int mask);
void callMiddleMouseUp(float *pos, unsigned int mask);
void callFocus();
void callFocusLost();
void callModifier(unsigned int mask);
void callQuitHandler();
void commitCurrentPreedit(GLViewRef glView);
#include <string>
void callHandleDragEntered(std::string url);
void callHandleDragExited(std::string url);
void callHandleDragUpdated(std::string url);
void callHandleDragDropped(std::string url);
// LLPreeditor C bindings.
std::basic_string<wchar_t> getPreeditString();
void getPreeditSelectionRange(int *position, int *length);
void getPreeditMarkedRange(int *position, int *length);
bool handleUnicodeCharacter(wchar_t c);
void updatePreeditor(unsigned short *str);
void setPreeditMarkedRange(int position, int length);
void resetPreedit();
int wstring_length(const std::basic_string<wchar_t> & wstr, const int woffset, const int utf16_length, int *unaligned);
void setMarkedText(unsigned short *text, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments);
void getPreeditLocation(float *location, unsigned int length);
void allowDirectMarkedTextInput(bool allow, GLViewRef glView);
NSWindowRef getMainAppWindow();
GLViewRef getGLView();
unsigned int getModifiers();

View File

@ -1,4 +1,4 @@
/**
/**
* @file llwindowmacosx-objc.mm
* @brief Definition of functions shared between llwindowmacosx.cpp
* and llwindowmacosx-objc.mm.
@ -6,26 +6,30 @@
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include <AppKit/AppKit.h>
#include <Cocoa/Cocoa.h>
#include "llopenglview-objc.h"
#include "llwindowmacosx-objc.h"
#include "llappdelegate-objc.h"
/*
* These functions are broken out into a separate file because the
@ -34,7 +38,10 @@
* linden headers with any objective-C++ source.
*/
#include "llwindowmacosx-objc.h"
int createNSApp(int argc, const char *argv[])
{
return NSApplicationMain(argc, argv);
}
void setupCocoa()
{
@ -45,44 +52,122 @@ void setupCocoa()
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
// when init'ing the Cocoa App window.
// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
// when init'ing the Cocoa App window.
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
// This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
// http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
// Needed for Carbon based applications which call into Cocoa
NSApplicationLoad();
// Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
[[[NSWindow alloc] init] release];
[pool release];
inited = true;
}
}
bool copyToPBoard(const unsigned short *str, unsigned int len)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
[pboard clearContents];
NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil];
[pool release];
return [pboard writeObjects:contentsToPaste];
}
bool pasteBoardAvailable()
{
NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
}
const unsigned short *copyFromPBoard()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
NSString *str = NULL;
BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
if (ok)
{
NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
str = [objToPaste objectAtIndex:0];
}
unichar* temp = (unichar*)calloc([str length], sizeof(unichar));
[str getCharacters:temp];
[pool release];
return temp;
}
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
NSCursor *cursor =
[[[NSCursor alloc]
initWithImage:
[[[NSImage alloc] initWithContentsOfFile:
[NSString stringWithFormat:@"%s", fullpath]
]autorelease]
hotSpot:NSMakePoint(hotspotX, hotspotY)
]retain];
[[[NSCursor alloc]
initWithImage:
[[[NSImage alloc] initWithContentsOfFile:
[NSString stringWithFormat:@"%s", fullpath]
]autorelease]
hotSpot:NSMakePoint(hotspotX, hotspotY)
]retain];
[pool release];
return (CursorRef)cursor;
}
void setArrowCursor()
{
NSCursor *cursor = [NSCursor arrowCursor];
[NSCursor unhide];
[cursor set];
}
void setIBeamCursor()
{
NSCursor *cursor = [NSCursor IBeamCursor];
[cursor set];
}
void setPointingHandCursor()
{
NSCursor *cursor = [NSCursor pointingHandCursor];
[cursor set];
}
void setCopyCursor()
{
NSCursor *cursor = [NSCursor dragCopyCursor];
[cursor set];
}
void setCrossCursor()
{
NSCursor *cursor = [NSCursor crosshairCursor];
[cursor set];
}
void setNotAllowedCursor()
{
NSCursor *cursor = [NSCursor operationNotAllowedCursor];
[cursor set];
}
void hideNSCursor()
{
[NSCursor hide];
}
void showNSCursor()
{
[NSCursor unhide];
}
void hideNSCursorTillMove(bool hide)
{
[NSCursor setHiddenUntilMouseMoves:hide];
}
// 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.
OSErr releaseImageCursor(CursorRef ref)
{
@ -118,3 +203,250 @@ OSErr setImageCursor(CursorRef ref)
return noErr;
}
// Now for some unholy juggling between generic pointers and casting them to Obj-C objects!
// Note: things can get a bit hairy from here. This is not for the faint of heart.
NSWindowRef createNSWindow(int x, int y, int width, int height)
{
LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height)
styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
[window makeKeyAndOrderFront:nil];
[window setAcceptsMouseMovedEvents:TRUE];
return window;
}
GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync)
{
LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:samples andVsync:vsync];
[(LLNSWindow*)window setContentView:glview];
return glview;
}
void glSwapBuffers(void* context)
{
[(NSOpenGLContext*)context flushBuffer];
}
CGLContextObj getCGLContextObj(GLViewRef view)
{
return [(LLOpenGLView *)view getCGLContextObj];
}
CGLPixelFormatObj* getCGLPixelFormatObj(NSWindowRef window)
{
LLOpenGLView *glview = [(LLNSWindow*)window contentView];
return [glview getCGLPixelFormatObj];
}
unsigned long getVramSize(GLViewRef view)
{
return [(LLOpenGLView *)view getVramSize];
}
void getContentViewBounds(NSWindowRef window, float* bounds)
{
bounds[0] = [[(LLNSWindow*)window contentView] bounds].origin.x;
bounds[1] = [[(LLNSWindow*)window contentView] bounds].origin.y;
bounds[2] = [[(LLNSWindow*)window contentView] bounds].size.width;
bounds[3] = [[(LLNSWindow*)window contentView] bounds].size.height;
}
void getWindowSize(NSWindowRef window, float* size)
{
NSRect frame = [(LLNSWindow*)window frame];
size[0] = frame.origin.x;
size[1] = frame.origin.y;
size[2] = frame.size.width;
size[3] = frame.size.height;
}
void setWindowSize(NSWindowRef window, int width, int height)
{
NSRect frame = [(LLNSWindow*)window frame];
frame.size.width = width;
frame.size.height = height;
[(LLNSWindow*)window setFrame:frame display:TRUE];
}
void setWindowPos(NSWindowRef window, float* pos)
{
NSPoint point;
point.x = pos[0];
point.y = pos[1];
[(LLNSWindow*)window setFrameOrigin:point];
}
void getCursorPos(NSWindowRef window, float* pos)
{
NSPoint mLoc;
mLoc = [(LLNSWindow*)window mouseLocationOutsideOfEventStream];
pos[0] = mLoc.x;
pos[1] = mLoc.y;
}
void makeWindowOrderFront(NSWindowRef window)
{
[(LLNSWindow*)window makeKeyAndOrderFront:nil];
}
void convertScreenToWindow(NSWindowRef window, float *coord)
{
NSRect point;
point.origin.x = coord[0];
point.origin.y = coord[1];
point = [(LLNSWindow*)window convertRectFromScreen:point];
coord[0] = point.origin.x;
coord[1] = point.origin.y;
}
void convertRectToScreen(NSWindowRef window, float *coord)
{
NSRect point;
point.origin.x = coord[0];
point.origin.y = coord[1];
point.size.width = coord[2];
point.size.height = coord[3];
point = [(LLNSWindow*)window convertRectToScreen:point];
coord[0] = point.origin.x;
coord[1] = point.origin.y;
coord[2] = point.size.width;
coord[3] = point.size.height;
}
void convertRectFromScreen(NSWindowRef window, float *coord)
{
NSRect point;
point.origin.x = coord[0];
point.origin.y = coord[1];
point.size.width = coord[2];
point.size.height = coord[3];
point = [(LLNSWindow*)window convertRectFromScreen:point];
coord[0] = point.origin.x;
coord[1] = point.origin.y;
coord[2] = point.size.width;
coord[3] = point.size.height;
}
void convertScreenToView(NSWindowRef window, float *coord)
{
NSRect point;
point.origin.x = coord[0];
point.origin.y = coord[1];
point.origin = [(LLNSWindow*)window convertScreenToBase:point.origin];
point.origin = [[(LLNSWindow*)window contentView] convertPoint:point.origin fromView:nil];
}
void convertWindowToScreen(NSWindowRef window, float *coord)
{
NSPoint point;
point.x = coord[0];
point.y = coord[1];
point = [(LLNSWindow*)window convertToScreenFromLocalPoint:point relativeToView:[(LLNSWindow*)window contentView]];
coord[0] = point.x;
coord[1] = point.y;
}
void closeWindow(NSWindowRef window)
{
[(LLNSWindow*)window close];
[(LLNSWindow*)window release];
}
void removeGLView(GLViewRef view)
{
[(LLOpenGLView*)view removeFromSuperview];
[(LLOpenGLView*)view release];
}
void setupInputWindow(NSWindowRef window, GLViewRef glview)
{
[[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview];
}
void commitCurrentPreedit(GLViewRef glView)
{
[(LLOpenGLView*)glView commitCurrentPreedit];
}
void allowDirectMarkedTextInput(bool allow, GLViewRef glView)
{
[(LLOpenGLView*)glView allowMarkedTextInput:allow];
}
NSWindowRef getMainAppWindow()
{
LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
[winRef setAcceptsMouseMovedEvents:TRUE];
return winRef;
}
void makeFirstResponder(NSWindowRef window, GLViewRef view)
{
[(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view];
}
void requestUserAttention()
{
[[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
}
long showAlert(std::string text, std::string title, int type)
{
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
[alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
if (type == 0)
{
[alert addButtonWithTitle:@"Okay"];
} else if (type == 1)
{
[alert addButtonWithTitle:@"Okay"];
[alert addButtonWithTitle:@"Cancel"];
} else if (type == 2)
{
[alert addButtonWithTitle:@"Yes"];
[alert addButtonWithTitle:@"No"];
}
long ret = [alert runModal];
[alert dealloc];
if (ret == NSAlertFirstButtonReturn)
{
if (type == 1)
{
ret = 3;
} else if (type == 2)
{
ret = 0;
}
} else if (ret == NSAlertSecondButtonReturn)
{
if (type == 0 || type == 1)
{
ret = 2;
} else if (type == 2)
{
ret = 1;
}
}
return ret;
}
/*
GLViewRef getGLView()
{
return [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] glview];
}
*/
unsigned int getModifiers()
{
return [NSEvent modifierFlags];
}

File diff suppressed because it is too large Load Diff

View File

@ -29,11 +29,12 @@
#include "llwindow.h"
#include "llwindowcallbacks.h"
#include "llwindowmacosx-objc.h"
#include "lltimer.h"
#include <Carbon/Carbon.h>
#include <AGL/agl.h>
#include <ApplicationServices/ApplicationServices.h>
#include <OpenGL/OpenGL.h>
// AssertMacros.h does bad things.
#include "fix_macros.h"
@ -106,7 +107,6 @@ public:
/*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
/*virtual*/ void *getPlatformWindow();
/*virtual*/ void *getMediaWindow();
/*virtual*/ void bringToFront() {};
/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
@ -117,7 +117,17 @@ public:
// Provide native key event data
/*virtual*/ LLSD getNativeKeyData();
void* getWindow() { return mWindow; }
LLWindowCallbacks* getCallbacks() { return mCallbacks; }
LLPreeditor* getPreeditor() { return mPreeditor; }
void updateMouseDeltas(float* deltas);
void getMouseDeltas(float* delta);
void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action);
bool allowsLanguageInput() { return mLanguageTextInputAllowed; }
protected:
LLWindowMacOSX(LLWindowCallbacks* callbacks,
@ -153,40 +163,33 @@ protected:
BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync);
void destroyContext();
void setupFailure(const std::string& text, const std::string& caption, U32 type);
static pascal OSStatus staticEventHandler (EventHandlerCallRef myHandler, EventRef event, void* userData);
static pascal Boolean staticMoveEventComparator( EventRef event, void* data);
OSStatus eventHandler (EventHandlerCallRef myHandler, EventRef event);
void adjustCursorDecouple(bool warpingMouse = false);
void stopDockTileBounce();
static MASK modifiersToMask(SInt16 modifiers);
static MASK modifiersToMask(S16 modifiers);
#if LL_OS_DRAGDROP_ENABLED
static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
void * handlerRefCon, DragRef theDrag);
static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
OSErr handleDragNDrop(DragRef theDrag, LLWindowCallbacks::DragNDropAction action);
//static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
//static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
#endif // LL_OS_DRAGDROP_ENABLED
//
// Platform specific variables
//
WindowRef mWindow;
AGLContext mContext;
AGLPixelFormat mPixelFormat;
CGDirectDisplayID mDisplay;
CFDictionaryRef mOldDisplayMode;
EventLoopTimerRef mTimer;
EventHandlerUPP mEventHandlerUPP;
EventHandlerRef mGlobalHandlerRef;
EventHandlerRef mWindowHandlerRef;
EventComparatorUPP mMoveEventCampartorUPP;
Rect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
Rect mPreviousWindowRect; // Save previous window for un-maximize event
Str255 mWindowTitle;
// 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.
NSWindowRef mWindow;
GLViewRef mGLView;
CGLContextObj mContext;
CGLPixelFormatObj mPixelFormat;
CGDirectDisplayID mDisplay;
LLRect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
std::string mWindowTitle;
double mOriginalAspectRatio;
BOOL mSimulatedRightClick;
UInt32 mLastModifiers;
U32 mLastModifiers;
BOOL mHandsOffEvents; // When true, temporarially disable CarbonEvent processing.
// Used to allow event processing when putting up dialogs in fullscreen mode.
BOOL mCursorDecoupled;
@ -201,25 +204,16 @@ protected:
U32 mFSAASamples;
BOOL mForceRebuild;
S32 mDragOverrideCursor;
F32 mBounceTime;
NMRec mBounceRec;
LLTimer mBounceTimer;
S32 mDragOverrideCursor;
// Input method management through Text Service Manager.
TSMDocumentID mTSMDocument;
BOOL mLanguageTextInputAllowed;
ScriptCode mTSMScriptCode;
LangCode mTSMLangCode;
LLPreeditor* mPreeditor;
static BOOL sUseMultGL;
friend class LLWindowManager;
static WindowRef sMediaWindow;
EventRef mRawKeyEvent;
};

File diff suppressed because it is too large Load Diff

View File

@ -232,12 +232,8 @@ private:
mMovieHandle = NULL;
};
if ( mGWorldHandle )
{
DisposeGWorld( mGWorldHandle );
mGWorldHandle = NULL;
};
mGWorldHandle = NULL;
setStatus(STATUS_NONE);
return true;
@ -273,6 +269,7 @@ private:
//std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl;
}
}
// sanitize destination size
Rect dest_rect = rectFromSize(mWidth, mHeight);
@ -281,12 +278,10 @@ private:
int depth_bits = mDepth * 8;
long rowbytes = mDepth * mTextureWidth;
GWorldPtr old_gworld_handle = mGWorldHandle;
if(mPixels != NULL)
{
// We have pixels. Set up a GWorld pointing at the texture.
OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
OSErr result = QTNewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
if ( noErr != result )
{
// TODO: unrecoverable?? throw exception? return something?
@ -297,7 +292,7 @@ private:
{
// We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally.
Rect tempRect = rectFromSize(1, 1);
OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
OSErr result = QTNewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
if ( noErr != result )
{
// TODO: unrecoverable?? throw exception? return something?
@ -305,14 +300,8 @@ private:
}
}
SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) );
// If the GWorld was already set up, delete it.
if(old_gworld_handle != NULL)
{
DisposeGWorld( old_gworld_handle );
}
SetMovieGWorld( mMovieHandle, mGWorldHandle, NULL );
// Set up the movie display matrix
{
// scale movie to fit rect and invert vertically to match opengl image format
@ -579,28 +568,7 @@ private:
}
};
int getDataWidth() const
{
if ( mGWorldHandle )
{
int depth = mDepth;
if (depth < 1)
depth = 1;
// ALWAYS use the row bytes from the PixMap if we have a GWorld because
// sometimes it's not the same as mMediaDepth * mMediaWidth !
PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle );
return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth;
}
else
{
// TODO : return LLMediaImplCommon::getaDataWidth();
return 0;
}
};
void seek( F64 time )
{
if ( mMovieController )

View File

@ -35,10 +35,13 @@
#include "volume_catcher.h"
#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#include <AudioUnit/AudioUnit.h>
#if LL_DARWIN
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
struct VolumeCatcherStorage;
class VolumeCatcherImpl
@ -266,3 +269,6 @@ void VolumeCatcher::pump()
// No periodic tasks are necessary for this implementation.
}
#if LL_DARWIN
#pragma GCC diagnostic warning "-Wdeprecated-declarations"
#endif

View File

@ -1274,6 +1274,11 @@ set_source_files_properties(
if (DARWIN)
LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp)
LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm)
LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h)
# This should be compiled with the viewer.
LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
find_library(AGL_LIBRARY AGL)
find_library(APPKIT_LIBRARY AppKit)
@ -1294,7 +1299,7 @@ if (DARWIN)
macview.r
gpu_table.txt
Info-SecondLife.plist
SecondLife.nib/
SecondLife.xib/
# CMake doesn't seem to support Xcode language variants well just yet
English.lproj/InfoPlist.strings
English.lproj/language.txt
@ -1974,20 +1979,25 @@ if (LINUX)
endif (LINUX)
if (DARWIN)
# These all get set with PROPERTIES
set(product "Second Life")
set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
set_target_properties(
${VIEWER_BINARY_NAME}
PROPERTIES
OUTPUT_NAME "${product}"
MACOSX_BUNDLE_INFO_STRING "Second Life Viewer"
MACOSX_BUNDLE_ICON_FILE "secondlife.icns"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer"
MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}"
MACOSX_BUNDLE_BUNDLE_NAME "Second Life"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}"
MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}"
MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007"
MACOSX_BUNDLE_INFO_PLIST
"${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
)
configure_file(

View File

@ -5,19 +5,33 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>Second Life</string>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>secondlife.icns</string>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>com.secondlife.indra.viewer</string>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>Second Life</string>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSRequiresCarbon</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
@ -59,9 +73,9 @@
<true/>
</dict>
</array>
<key>CFBundleVersion</key>
<string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSPrincipalClass</key>
<string>${MACOSX_BUNDLE_NSPRINCIPAL_CLASS}</string>
<key>NSMainNibFile</key>
<string>${MACOSX_BUNDLE_NSMAIN_NIB_FILE}</string>
</dict>
</plist>

BIN
indra/newview/SecondLife.nib generated Normal file

Binary file not shown.

View File

@ -1,4 +0,0 @@
{
IBClasses = ();
IBVersion = 1;
}

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>85 13 356 240 0 0 1280 1002 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
<string>27 314 247 44 0 0 1280 1002 </string>
</dict>
<key>IBFramework Version</key>
<string>362.0</string>
<key>IBOpenObjects</key>
<array>
<integer>191</integer>
</array>
<key>IBSystem Version</key>
<string>7D24</string>
<key>targetFramework</key>
<string>IBCarbonFramework</string>
</dict>
</plist>

View File

@ -1,259 +0,0 @@
<?xml version="1.0" standalone="yes"?>
<object class="NSIBObjectData">
<string name="targetFramework">IBCarbonFramework</string>
<object name="rootObject" class="NSCustomObject" id="1">
<string name="customClass">NSApplication</string>
</object>
<array count="31" name="allObjects">
<object class="IBCarbonMenu" id="29">
<string name="title">SecondLife</string>
<array count="4" name="items">
<object class="IBCarbonMenuItem" id="182">
<string name="title">Second Life</string>
<object name="submenu" class="IBCarbonMenu" id="181">
<string name="title">Second Life</string>
<array count="1" name="items">
<object class="IBCarbonMenuItem" id="183">
<boolean name="disabled">TRUE</boolean>
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">About Second Life</string>
<int name="keyEquivalentModifier">0</int>
<ostype name="command">abou</ostype>
</object>
</array>
<string name="name">_NSAppleMenu</string>
</object>
</object>
<object class="IBCarbonMenuItem" id="127">
<string name="title">File</string>
<object name="submenu" class="IBCarbonMenu" id="131">
<string name="title">File</string>
</object>
</object>
<object class="IBCarbonMenuItem" id="152">
<string name="title">Edit</string>
<object name="submenu" class="IBCarbonMenu" id="147">
<string name="title">Edit</string>
<array count="10" name="items">
<object class="IBCarbonMenuItem" id="141">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Undo</string>
<string name="keyEquivalent">z</string>
<ostype name="command">undo</ostype>
</object>
<object class="IBCarbonMenuItem" id="146">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Redo</string>
<string name="keyEquivalent">Z</string>
<ostype name="command">redo</ostype>
</object>
<object class="IBCarbonMenuItem" id="142">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="143">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Cut</string>
<string name="keyEquivalent">x</string>
<ostype name="command">cut </ostype>
</object>
<object class="IBCarbonMenuItem" id="149">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Copy</string>
<string name="keyEquivalent">c</string>
<ostype name="command">copy</ostype>
</object>
<object class="IBCarbonMenuItem" id="144">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Paste</string>
<string name="keyEquivalent">v</string>
<ostype name="command">past</ostype>
</object>
<object class="IBCarbonMenuItem" id="151">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Delete</string>
<ostype name="command">clea</ostype>
</object>
<object class="IBCarbonMenuItem" id="148">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Select All</string>
<string name="keyEquivalent">a</string>
<ostype name="command">sall</ostype>
</object>
<object class="IBCarbonMenuItem" id="188">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="187">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Special Characters…</string>
<ostype name="command">chrp</ostype>
</object>
</array>
</object>
</object>
<object class="IBCarbonMenuItem" id="153">
<string name="title">Window</string>
<object name="submenu" class="IBCarbonMenu" id="154">
<string name="title">Window</string>
<array count="6" name="items">
<object class="IBCarbonMenuItem" id="155">
<boolean name="dynamic">TRUE</boolean>
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Minimize Window</string>
<string name="keyEquivalent">m</string>
<ostype name="command">mini</ostype>
</object>
<object class="IBCarbonMenuItem" id="184">
<boolean name="dynamic">TRUE</boolean>
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Minimize All Windows</string>
<string name="keyEquivalent">m</string>
<int name="keyEquivalentModifier">1572864</int>
<ostype name="command">mina</ostype>
</object>
<object class="IBCarbonMenuItem" id="186">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Zoom</string>
<ostype name="command">zoom</ostype>
</object>
<object class="IBCarbonMenuItem" id="156">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="157">
<boolean name="dynamic">TRUE</boolean>
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Bring All to Front</string>
<ostype name="command">bfrt</ostype>
</object>
<object class="IBCarbonMenuItem" id="185">
<boolean name="dynamic">TRUE</boolean>
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Arrange in Front</string>
<int name="keyEquivalentModifier">1572864</int>
<ostype name="command">frnt</ostype>
</object>
</array>
<string name="name">_NSWindowsMenu</string>
</object>
</object>
</array>
<string name="name">_NSMainMenu</string>
</object>
<reference idRef="127"/>
<reference idRef="131"/>
<reference idRef="141"/>
<reference idRef="142"/>
<reference idRef="143"/>
<reference idRef="144"/>
<reference idRef="146"/>
<reference idRef="147"/>
<reference idRef="148"/>
<reference idRef="149"/>
<reference idRef="151"/>
<reference idRef="152"/>
<reference idRef="153"/>
<reference idRef="154"/>
<reference idRef="155"/>
<reference idRef="156"/>
<reference idRef="157"/>
<reference idRef="181"/>
<reference idRef="182"/>
<reference idRef="183"/>
<reference idRef="184"/>
<reference idRef="185"/>
<reference idRef="186"/>
<reference idRef="187"/>
<reference idRef="188"/>
<object class="IBCarbonRootControl" id="190">
<string name="bounds">0 0 482 694 </string>
<string name="viewFrame">0 0 694 482 </string>
<array count="2" name="subviews">
<object class="IBCarbonButton" id="192">
<string name="bounds">442 604 462 674 </string>
<string name="viewFrame">604 442 70 20 </string>
<string name="title">OK</string>
<ostype name="command">ok </ostype>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingBottomKind">2</int>
<int name="bindingRightKind">2</int>
</object>
<int name="buttonType">1</int>
</object>
<object class="IBCarbonScrollView" id="201">
<string name="bounds">20 20 422 674 </string>
<string name="viewFrame">20 20 654 402 </string>
<array count="1" name="subviews">
<object class="IBCarbonTextView" id="200">
<string name="bounds">20 20 422 659 </string>
<string name="viewFrame">0 0 639 402 </string>
<ostype name="controlSignature">text</ostype>
<int name="fontStyle">5</int>
<boolean name="readOnly">TRUE</boolean>
</object>
</array>
<boolean name="scrollHorizontally">FALSE</boolean>
</object>
</array>
</object>
<object class="IBCarbonWindow" id="191">
<string name="windowRect">84 72 566 766 </string>
<string name="title">Release Notes</string>
<reference name="rootControl" idRef="190"/>
<boolean name="receiveUpdates">FALSE</boolean>
<boolean name="hasCloseBox">FALSE</boolean>
<boolean name="hasCollapseBox">FALSE</boolean>
<boolean name="hasHorizontalZoom">FALSE</boolean>
<boolean name="isResizable">FALSE</boolean>
<boolean name="hasVerticalZoom">FALSE</boolean>
<boolean name="liveResize">TRUE</boolean>
<boolean name="compositing">TRUE</boolean>
<int name="carbonWindowClass">4</int>
<int name="windowPosition">1</int>
<boolean name="isConstrained">FALSE</boolean>
</object>
<reference idRef="192"/>
<reference idRef="200"/>
<reference idRef="201"/>
</array>
<array count="31" name="allParents">
<reference idRef="1"/>
<reference idRef="29"/>
<reference idRef="127"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="152"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="29"/>
<reference idRef="29"/>
<reference idRef="153"/>
<reference idRef="154"/>
<reference idRef="154"/>
<reference idRef="154"/>
<reference idRef="182"/>
<reference idRef="29"/>
<reference idRef="181"/>
<reference idRef="154"/>
<reference idRef="154"/>
<reference idRef="154"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="191"/>
<reference idRef="1"/>
<reference idRef="190"/>
<reference idRef="201"/>
<reference idRef="190"/>
</array>
<dictionary count="3" name="nameTable">
<string>Files Owner</string>
<reference idRef="1"/>
<string>MenuBar</string>
<reference idRef="29"/>
<string>Release Notes</string>
<reference idRef="191"/>
</dictionary>
<unsigned_int name="nextObjectID">202</unsigned_int>
</object>

1136
indra/newview/SecondLife.xib Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
3.6.5
3.6.6

View File

@ -94,7 +94,7 @@ PERMISSION_CHANGE_LINKS Passed to llRequestPermissions library function to req
PERMISSION_TRACK_CAMERA Passed to llRequestPermissions library function to request permission to track agent's camera
PERMISSION_CONTROL_CAMERA Passed to llRequestPermissions library function to request permission to change agent's camera
PERMISSION_TELEPORT Passed to llRequestPermissions library function to request permission to teleport agent
SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT Passed to llRequestPermissions library function to request permission to silently modify estate access lists
PERMISSION_SILENT_ESTATE_MANAGEMENT Passed to llRequestPermissions library function to request permission to silently modify estate access lists
PERMISSION_OVERRIDE_ANIMATIONS Passed to llRequestPermissions library function to request permission to override animations on agent
PERMISSION_RETURN_OBJECTS Passed to llRequestPermissions library function to request permission to return objects

View File

@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;

View File

@ -32,6 +32,7 @@ out vec4 frag_color;
//class 1 -- no shadows
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;

View File

@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;

View File

@ -22,8 +22,9 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@ -31,6 +32,8 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
//class 1 -- no shadows
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;

View File

@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;

View File

@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;

View File

@ -1,3 +1,4 @@
//GPU_TABLE - that token on line 1 tags this as a gpu table file
//
// Categorizes graphics chips into various classes by name
//

View File

@ -0,0 +1,144 @@
/**
* @file llappdelegate-objc.mm
* @brief Class implementation for the Mac version's application delegate.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#import "llappdelegate-objc.h"
#include "llwindowmacosx-objc.h"
#include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
@implementation LLAppDelegate
@synthesize window;
@synthesize inputWindow;
@synthesize inputView;
@synthesize currentInputLanguage;
- (void)dealloc
{
[super dealloc];
}
- (void) applicationDidFinishLaunching:(NSNotification *)notification
{
frameTimer = nil;
[self languageUpdated];
if (initViewer())
{
frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES];
} else {
handleQuit();
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
}
- (void) applicationDidBecomeActive:(NSNotification *)notification
{
callWindowFocus();
}
- (void) applicationDidResignActive:(NSNotification *)notification
{
callWindowUnfocus();
}
- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender
{
if (!runMainLoop())
{
handleQuit();
return NSTerminateCancel;
} else {
[frameTimer release];
cleanupViewer();
return NSTerminateNow;
}
}
- (void) mainLoop
{
bool appExiting = runMainLoop();
if (appExiting)
{
[frameTimer release];
[[NSApplication sharedApplication] terminate:self];
}
}
- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent
{
if (![self romanScript])
{
if (show)
{
NSLog(@"Showing input window.");
[inputWindow makeKeyAndOrderFront:inputWindow];
if (textEvent != nil)
{
[[inputView inputContext] discardMarkedText];
[[inputView inputContext] handleEvent:textEvent];
}
} else {
NSLog(@"Hiding input window.");
[inputWindow orderOut:inputWindow];
[window makeKeyAndOrderFront:window];
}
}
}
// This will get called multiple times by NSNotificationCenter.
// It will be called every time that the window focus changes, and every time that the input language gets changed.
// The primary use case for this selector is to update our current input language when the user, for whatever reason, changes the input language.
// This is the more elegant way of handling input language changes instead of checking every time we want to use the input window.
- (void) languageUpdated
{
TISInputSourceRef currentInput = TISCopyCurrentKeyboardInputSource();
CFArrayRef languages = (CFArrayRef)TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages);
#if 0 // In the event of ever needing to add new language sources, change this to 1 and watch the terminal for "languages:"
NSLog(@"languages: %@", TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages));
#endif
// Typically the language we want is going to be the very first result in the array.
currentInputLanguage = (NSString*)CFArrayGetValueAtIndex(languages, 0);
}
- (bool) romanScript
{
// How to add support for new languages with the input window:
// Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.)
NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil];
if ([nonRomanScript containsObject:currentInputLanguage])
{
return false;
}
return true;
}
@end

View File

@ -724,6 +724,11 @@ bool LLAppViewer::init()
// we run the "program crashed last time" error handler below.
//
LLFastTimer::reset();
#ifdef LL_DARWIN
mMainLoopInitialized = false;
#endif
// initialize LLWearableType translation bridge.
// Memory will be cleaned up in ::cleanupClass()
@ -1254,40 +1259,57 @@ LLFastTimer::DeclareTimer FTM_FRAME("Frame", true);
bool LLAppViewer::mainLoop()
{
mMainloopTimeout = new LLWatchdogTimeout();
#ifdef LL_DARWIN
if (!mMainLoopInitialized)
#endif
{
mMainloopTimeout = new LLWatchdogTimeout();
//-------------------------------------------
// Run main loop until time to quit
//-------------------------------------------
// Create IO Pump to use for HTTP Requests.
gServicePump = new LLPumpIO(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
LLCurl::setCAFile(gDirUtilp->getCAFile());
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
LLVoiceChannel::initClass();
LLVoiceClient::getInstance()->init(gServicePump);
LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
joystick = LLViewerJoystick::getInstance();
joystick->setNeedsReset(true);
#ifdef LL_DARWIN
// Ensure that this section of code never gets called again on OS X.
mMainLoopInitialized = true;
#endif
}
// As we do not (yet) send data on the mainloop LLEventPump that varies
// with each frame, no need to instantiate a new LLSD event object each
// time. Obviously, if that changes, just instantiate the LLSD at the
// point of posting.
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD newFrame;
//-------------------------------------------
// Run main loop until time to quit
//-------------------------------------------
// Create IO Pump to use for HTTP Requests.
gServicePump = new LLPumpIO(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
LLCurl::setCAFile(gDirUtilp->getCAFile());
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
LLVoiceChannel::initClass();
LLVoiceClient::getInstance()->init(gServicePump);
LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
LLTimer frameTimer,idleTimer;
LLTimer debugTime;
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
joystick->setNeedsReset(true);
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
// As we do not (yet) send data on the mainloop LLEventPump that varies
// with each frame, no need to instantiate a new LLSD event object each
// time. Obviously, if that changes, just instantiate the LLSD at the
// point of posting.
LLSD newFrame;
//LLPrivateMemoryPoolTester::getInstance()->run(false) ;
//LLPrivateMemoryPoolTester::getInstance()->run(true) ;
//LLPrivateMemoryPoolTester::destroy() ;
// Handle messages
#ifdef LL_DARWIN
if (!LLApp::isExiting())
#else
while (!LLApp::isExiting())
#endif
{
LLFastTimer _(FTM_FRAME);
LLFastTimer::nextFrame();
@ -1563,34 +1585,37 @@ bool LLAppViewer::mainLoop()
}
}
// Save snapshot for next time, if we made it through initialization
if (STATE_STARTED == LLStartUp::getStartupState())
if (LLApp::isExiting())
{
try
// Save snapshot for next time, if we made it through initialization
if (STATE_STARTED == LLStartUp::getStartupState())
{
saveFinalSnapshot();
}
catch(std::bad_alloc)
{
llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
//stop memory leaking simulation
LLFloaterMemLeak* mem_leak_instance =
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
if(mem_leak_instance)
try
{
mem_leak_instance->stop() ;
}
saveFinalSnapshot();
}
catch(std::bad_alloc)
{
llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
//stop memory leaking simulation
LLFloaterMemLeak* mem_leak_instance =
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
if(mem_leak_instance)
{
mem_leak_instance->stop() ;
}
}
}
delete gServicePump;
destroyMainloopTimeout();
llinfos << "Exiting main_loop" << llendflush;
}
delete gServicePump;
destroyMainloopTimeout();
llinfos << "Exiting main_loop" << llendflush;
return true;
return LLApp::isExiting();
}
void LLAppViewer::flushVFSIO()
@ -2670,8 +2695,6 @@ bool LLAppViewer::initConfiguration()
//}
#if LL_DARWIN
// Initialize apple menubar and various callbacks
init_apple_menu(LLTrans::getString("APP_NAME").c_str());
#if __ppc__
// If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further.

View File

@ -42,6 +42,7 @@ class LLImageDecodeThread;
class LLTextureFetch;
class LLWatchdogTimeout;
class LLUpdaterService;
class LLViewerJoystick;
extern LLFastTimer::DeclareTimer FTM_FRAME;
@ -255,6 +256,8 @@ private:
std::string mSerialNumber;
bool mPurgeCache;
bool mPurgeOnExit;
bool mMainLoopInitialized;
LLViewerJoystick* joystick;
bool mSavedFinalSnapshot;
bool mSavePerAccountSettings; // only save per account settings if login succeeded

View File

@ -30,7 +30,10 @@
#error "Use only with Mac OS X"
#endif
#define LL_CARBON_CRASH_HANDLER 1
#include "llappviewermacosx.h"
#include "llwindowmacosx-objc.h"
#include "llcommandlineparser.h"
#include "llviewernetwork.h"
@ -38,7 +41,10 @@
#include "llmd5.h"
#include "llfloaterworldmap.h"
#include "llurldispatcher.h"
#include <ApplicationServices/ApplicationServices.h>
#ifdef LL_CARBON_CRASH_HANDLER
#include <Carbon/Carbon.h>
#endif
#include "lldir.h"
#include <signal.h>
#include <CoreAudio/CoreAudio.h> // for systemwide mute
@ -50,9 +56,9 @@ namespace
// They are not used immediately by the app.
int gArgC;
char** gArgV;
bool sCrashReporterIsRunning = false;
LLAppViewerMacOSX* gViewerAppPtr;
#ifdef LL_CARBON_CRASH_HANDLER
OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
{
OSErr result = noErr;
@ -61,9 +67,10 @@ namespace
return(result);
}
#endif
}
int main( int argc, char **argv )
bool initViewer()
{
#if LL_SOLARIS && defined(__sparc)
asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC
@ -73,43 +80,60 @@ int main( int argc, char **argv )
if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)
{
llwarns << "Could not change directory to "
<< gDirUtilp->getAppRODataDir() << ": " << strerror(errno)
<< llendl;
<< gDirUtilp->getAppRODataDir() << ": " << strerror(errno)
<< llendl;
}
LLAppViewerMacOSX* viewer_app_ptr = new LLAppViewerMacOSX();
viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
// Store off the command line args for use later.
gArgC = argc;
gArgV = argv;
bool ok = viewer_app_ptr->init();
gViewerAppPtr = new LLAppViewerMacOSX();
gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
bool ok = gViewerAppPtr->init();
if(!ok)
{
llwarns << "Application init failed." << llendl;
return -1;
}
return ok;
}
// Run the application main loop
if(!LLApp::isQuitting())
{
viewer_app_ptr->mainLoop();
}
void handleQuit()
{
LLAppViewer::instance()->userQuit();
}
if (!LLApp::isError())
bool runMainLoop()
{
bool ret = LLApp::isQuitting();
if (!ret && gViewerAppPtr != NULL)
{
//
// We don't want to do cleanup here if the error handler got called -
// the assumption is that the error handler is responsible for doing
// app cleanup if there was a problem.
//
viewer_app_ptr->cleanup();
ret = gViewerAppPtr->mainLoop();
} else {
ret = true;
}
delete viewer_app_ptr;
viewer_app_ptr = NULL;
return 0;
return ret;
}
void cleanupViewer()
{
if(!LLApp::isError())
{
gViewerAppPtr->cleanup();
}
delete gViewerAppPtr;
gViewerAppPtr = NULL;
}
int main( int argc, char **argv )
{
// Store off the command line args for use later.
gArgC = argc;
gArgV = argv;
return createNSApp(argc, (const char**)argv);
}
LLAppViewerMacOSX::LLAppViewerMacOSX()
@ -239,23 +263,24 @@ bool LLAppViewerMacOSX::restoreErrorTrap()
return reset_count == 0;
}
static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
EventRef inEvent,
#ifdef LL_CARBON_CRASH_HANDLER
static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
EventRef inEvent,
void* inUserData)
{
ProcessSerialNumber psn;
GetEventParameter(inEvent,
kEventParamProcessID,
typeProcessSerialNumber,
NULL,
sizeof(psn),
NULL,
GetEventParameter(inEvent,
kEventParamProcessID,
typeProcessSerialNumber,
NULL,
sizeof(psn),
NULL,
&psn);
if( GetEventKind(inEvent) == kEventAppTerminated )
if( GetEventKind(inEvent) == kEventAppTerminated )
{
Boolean matching_psn = FALSE;
Boolean matching_psn = FALSE;
OSErr os_result = SameProcess(&psn, (ProcessSerialNumber*)inUserData, &matching_psn);
if(os_result >= 0 && matching_psn)
{
@ -265,48 +290,58 @@ static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
}
return noErr;
}
#endif
void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
{
// This used to use fork&exec, but is switched to LSOpenApplication to
#ifdef LL_CARBON_CRASH_HANDLER
// This used to use fork&exec, but is switched to LSOpenApplication to
// Make sure the crash reporter launches in front of the SL window.
std::string command_str;
//command_str = "open Second Life.app/Contents/Resources/mac-crash-logger.app";
command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger";
CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)command_str.c_str(), strlen(command_str.c_str()), FALSE);
// FSRef apparently isn't deprecated.
// There's other funcitonality that depends on it existing as well that isn't deprecated.
// There doesn't seem to be much to directly verify what the status of FSRef is, outside of some documentation pointing at FSRef being valid, and other documentation pointing to everything in Files.h being deprecated.
// We'll assume it isn't for now, since all non-deprecated functions that use it seem to assume similar.
FSRef appRef;
Boolean isDir = 0;
OSStatus os_result = FSPathMakeRef((UInt8*)command_str.c_str(),
&appRef,
&isDir);
if(os_result >= 0)
Boolean pathstatus = CFURLGetFSRef(urlRef, &appRef);
OSStatus os_result = noErr;
if(pathstatus == true)
{
LSApplicationParameters appParams;
memset(&appParams, 0, sizeof(appParams));
appParams.version = 0;
appParams.flags = kLSLaunchNoParams | kLSLaunchStartClassic;
appParams.application = &appRef;
if(reportFreeze)
{
// Make sure freeze reporting launches the crash logger synchronously, lest
// Make sure freeze reporting launches the crash logger synchronously, lest
// Log files get changed by SL while the logger is running.
// *NOTE:Mani A better way - make a copy of the data that the crash reporter will send
// and let SL go about its business. This way makes the mac work like windows and linux
// and is the smallest patch for the issue.
// and is the smallest patch for the issue.
sCrashReporterIsRunning = false;
ProcessSerialNumber o_psn;
static EventHandlerRef sCarbonEventsRef = NULL;
static const EventTypeSpec kEvents[] =
static const EventTypeSpec kEvents[] =
{
{ kEventClassApplication, kEventAppTerminated }
};
// Install the handler to detect crash logger termination
InstallEventHandler(GetApplicationEventTarget(),
InstallEventHandler(GetApplicationEventTarget(),
(EventHandlerUPP) CarbonEventHandler,
GetEventTypeCount(kEvents),
kEvents,
@ -314,31 +349,31 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
&sCarbonEventsRef
);
// Remove, temporarily the quit handler - which has *crash* behavior before
// Remove, temporarily the quit handler - which has *crash* behavior before
// the mainloop gets running!
AERemoveEventHandler(kCoreEventClass,
kAEQuitApplication,
AERemoveEventHandler(kCoreEventClass,
kAEQuitApplication,
NewAEEventHandlerUPP(AEQuitHandler),
false);
// Launch the crash reporter.
os_result = LSOpenApplication(&appParams, &o_psn);
if(os_result >= 0)
{
{
sCrashReporterIsRunning = true;
}
while(sCrashReporterIsRunning)
{
RunApplicationEventLoop();
}
// Re-install the apps quit handler.
AEInstallEventHandler(kCoreEventClass,
kAEQuitApplication,
AEInstallEventHandler(kCoreEventClass,
kAEQuitApplication,
NewAEEventHandlerUPP(AEQuitHandler),
0,
0,
false);
// Remove the crash reporter quit handler.
@ -348,12 +383,12 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
{
appParams.flags |= kLSLaunchAsync;
clear_signals();
ProcessSerialNumber o_psn;
os_result = LSOpenApplication(&appParams, &o_psn);
}
}
#endif
}
std::string LLAppViewerMacOSX::generateSerialNumber()
@ -486,73 +521,3 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
return(result);
}
OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
{
OSStatus result = eventNotHandledErr;
OSStatus err;
UInt32 evtClass = GetEventClass(event);
UInt32 evtKind = GetEventKind(event);
WindowRef window = (WindowRef)userdata;
if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
{
HICommand cmd;
err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
if(err == noErr)
{
switch(cmd.commandID)
{
case kHICommandOK:
QuitAppModalLoopForWindow(window);
result = noErr;
break;
case kHICommandCancel:
QuitAppModalLoopForWindow(window);
result = userCanceledErr;
break;
}
}
}
return(result);
}
void init_apple_menu(const char* product)
{
// Load up a proper menu bar.
{
OSStatus err;
IBNibRef nib = NULL;
// NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly.
err = CreateNibReference(CFSTR("SecondLife"), &nib);
if(err == noErr)
{
// NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly.
SetMenuBarFromNib(nib, CFSTR("MenuBar"));
}
if(nib != NULL)
{
DisposeNibReference(nib);
}
}
// Install a handler for 'gurl' AppleEvents. This is how secondlife:// URLs get passed to the viewer.
if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr)
{
// Couldn't install AppleEvent handler. This error shouldn't be fatal.
llinfos << "Couldn't install 'GURL' AppleEvent handler. Continuing..." << llendl;
}
// Install a handler for 'quit' AppleEvents. This makes quitting the application from the dock work.
if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr)
{
// Couldn't install AppleEvent handler. This error shouldn't be fatal.
llinfos << "Couldn't install Quit AppleEvent handler. Continuing..." << llendl;
}
}

View File

@ -995,20 +995,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
LLStyle::Params link_params(body_message_params);
link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));
if (from_me)
{ std::string localized_name;
bool is_localized = LLTrans::findString(localized_name, "AgentNameSubst");
mEditor->appendText((is_localized? localized_name:"(You)") + delimiter,
prependNewLineState, link_params);
prependNewLineState = false;
}
else
{
// Add link to avatar's inspector and delimiter to message.
mEditor->appendText(std::string(link_params.link_href) + delimiter,
prependNewLineState, link_params);
prependNewLineState = false;
}
mEditor->appendText(std::string(link_params.link_href) + delimiter,
prependNewLineState, link_params);
prependNewLineState = false;
}
else
{

View File

@ -37,7 +37,7 @@
#include "llwindow.h" // beforeDialog()
#include "llviewercontrol.h"
#if LL_LINUX || LL_SOLARIS
#if LL_LINUX || LL_SOLARIS || LL_DARWIN
# include "llfilepicker.h"
#endif
@ -147,152 +147,36 @@ std::string LLDirPicker::getDirName()
#elif LL_DARWIN
LLDirPicker::LLDirPicker() :
mFileName(NULL),
mLocked(false)
mFileName(NULL),
mLocked(false)
{
mFilePicker = new LLFilePicker();
reset();
memset(&mNavOptions, 0, sizeof(mNavOptions));
OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions);
if (error == noErr)
{
mNavOptions.modality = kWindowModalityAppModal;
}
}
LLDirPicker::~LLDirPicker()
{
// nothing
}
//static
pascal void LLDirPicker::doNavCallbackEvent(NavEventCallbackMessage callBackSelector,
NavCBRecPtr callBackParms, void* callBackUD)
{
switch(callBackSelector)
{
case kNavCBStart:
{
if (!sInstance.mFileName) break;
OSStatus error = noErr;
AEDesc theLocation = {typeNull, NULL};
FSSpec outFSSpec;
//Convert string to a FSSpec
FSRef myFSRef;
const char* filename=sInstance.mFileName->c_str();
error = FSPathMakeRef ((UInt8*)filename, &myFSRef, NULL);
if (error != noErr) break;
error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL);
if (error != noErr) break;
error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation);
if (error != noErr) break;
error = NavCustomControl(callBackParms->context,
kNavCtlSetLocation, (void*)&theLocation);
}
}
}
OSStatus LLDirPicker::doNavChooseDialog()
{
OSStatus error = noErr;
NavDialogRef navRef = NULL;
NavReplyRecord navReply;
memset(&navReply, 0, sizeof(navReply));
// NOTE: we are passing the address of a local variable here.
// This is fine, because the object this call creates will exist for less than the lifetime of this function.
// (It is destroyed by NavDialogDispose() below.)
error = NavCreateChooseFolderDialog(&mNavOptions, &doNavCallbackEvent, NULL, NULL, &navRef);
gViewerWindow->getWindow()->beforeDialog();
if (error == noErr)
error = NavDialogRun(navRef);
gViewerWindow->getWindow()->afterDialog();
if (error == noErr)
error = NavDialogGetReply(navRef, &navReply);
if (navRef)
NavDialogDispose(navRef);
if (error == noErr && navReply.validRecord)
{
FSRef fsRef;
AEKeyword theAEKeyword;
DescType typeCode;
Size actualSize = 0;
char path[LL_MAX_PATH]; /*Flawfinder: ignore*/
memset(&fsRef, 0, sizeof(fsRef));
error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
if (error == noErr)
error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path));
if (error == noErr)
mDir = path;
}
return error;
}
BOOL LLDirPicker::getDir(std::string* filename)
{
if( mLocked ) return FALSE;
BOOL success = FALSE;
OSStatus error = noErr;
// if local file browsing is turned off, return without opening dialog
if ( check_local_file_access_enabled() == false )
{
return FALSE;
}
mFileName = filename;
// mNavOptions.saveFileName
// Modal, so pause agent
send_agent_pause();
{
error = doNavChooseDialog();
}
send_agent_resume();
if (error == noErr)
{
if (mDir.length() > 0)
success = true;
}
// Account for the fact that the app has been stalled.
LLFrameTimer::updateFrameTime();
return success;
}
std::string LLDirPicker::getDirName()
{
return mDir;
delete mFilePicker;
}
void LLDirPicker::reset()
{
mLocked = false;
mDir.clear();
if (mFilePicker)
mFilePicker->reset();
}
//static
BOOL LLDirPicker::getDir(std::string* filename)
{
LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY;
return mFilePicker->getOpenFile(filter, true);
}
std::string LLDirPicker::getDirName()
{
return mFilePicker->getFirstFile();
}
#elif LL_LINUX || LL_SOLARIS

View File

@ -34,11 +34,10 @@
#include "stdtypes.h"
#if LL_DARWIN
#include <Carbon/Carbon.h>
// AssertMacros.h does bad things.
#include "fix_macros.h"
#undef verify
#undef check
#undef require
#include <vector>
@ -77,15 +76,7 @@ private:
void buildDirname( void );
bool check_local_file_access_enabled();
#if LL_DARWIN
NavDialogCreationOptions mNavOptions;
static pascal void doNavCallbackEvent(NavEventCallbackMessage callBackSelector,
NavCBRecPtr callBackParms, void* callBackUD);
OSStatus doNavChooseDialog();
#endif
#if LL_LINUX || LL_SOLARIS
#if LL_LINUX || LL_SOLARIS || LL_DARWIN
// On Linux we just implement LLDirPicker on top of LLFilePicker
LLFilePicker *mFilePicker;
#endif

View File

@ -261,7 +261,7 @@ BOOL LLFeatureManager::maskFeatures(const std::string& name)
return maskList(*maskp);
}
BOOL LLFeatureManager::loadFeatureTables()
bool LLFeatureManager::loadFeatureTables()
{
// *TODO - if I or anyone else adds something else to the skipped list
// make this data driven. Put it in the feature table and parse it
@ -302,28 +302,36 @@ BOOL LLFeatureManager::loadFeatureTables()
// use HTTP table if it exists
std::string path;
bool parse_ok = false;
if (gDirUtilp->fileExists(http_path))
{
path = http_path;
}
else
{
path = app_path;
parse_ok = parseFeatureTable(http_path);
if (!parse_ok)
{
// the HTTP table failed to parse, so delete it
LLFile::remove(http_path);
LL_WARNS("RenderInit") << "Removed invalid feature table '" << http_path << "'" << LL_ENDL;
}
}
return parseFeatureTable(path);
if (!parse_ok)
{
parse_ok = parseFeatureTable(app_path);
}
return parse_ok;
}
BOOL LLFeatureManager::parseFeatureTable(std::string filename)
bool LLFeatureManager::parseFeatureTable(std::string filename)
{
llinfos << "Looking for feature table in " << filename << llendl;
LL_INFOS("RenderInit") << "Attempting to parse feature table from " << filename << LL_ENDL;
llifstream file;
std::string name;
U32 version;
cleanupFeatureTables(); // in case an earlier attempt left partial results
file.open(filename); /*Flawfinder: ignore*/
if (!file)
@ -338,13 +346,14 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)
if (name != "version")
{
LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL;
return FALSE;
return false;
}
mTableVersion = version;
LLFeatureList *flp = NULL;
while (file >> name)
bool parse_ok = true;
while (file >> name && parse_ok)
{
char buffer[MAX_STRING]; /*Flawfinder: ignore*/
@ -357,39 +366,58 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)
if (name == "list")
{
LL_DEBUGS("RenderInit") << "Before new list" << std::endl;
if (flp)
{
//flp->dump();
flp->dump();
}
else
{
LL_CONT << "No current list";
}
LL_CONT << LL_ENDL;
// It's a new mask, create it.
file >> name;
if (mMaskList.count(name))
if (!mMaskList.count(name))
{
LL_ERRS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL;
flp = new LLFeatureList(name);
mMaskList[name] = flp;
}
else
{
LL_WARNS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL;
parse_ok = false;
}
flp = new LLFeatureList(name);
mMaskList[name] = flp;
}
else
{
if (!flp)
{
LL_ERRS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
return FALSE;
S32 available;
F32 recommended;
file >> available >> recommended;
flp->addFeature(name, available, recommended);
}
else
{
LL_WARNS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
parse_ok = false;
}
S32 available;
F32 recommended;
file >> available >> recommended;
flp->addFeature(name, available, recommended);
}
}
file.close();
return TRUE;
if (!parse_ok)
{
LL_WARNS("RenderInit") << "Discarding feature table data from " << filename << LL_ENDL;
cleanupFeatureTables();
}
return parse_ok;
}
void LLFeatureManager::loadGPUClass()
bool LLFeatureManager::loadGPUClass()
{
// defaults
mGPUClass = GPU_CLASS_UNKNOWN;
@ -407,29 +435,49 @@ void LLFeatureManager::loadGPUClass()
// use HTTP table if it exists
std::string path;
bool parse_ok = false;
if (gDirUtilp->fileExists(http_path))
{
path = http_path;
}
else
{
path = app_path;
parse_ok = parseGPUTable(http_path);
if (!parse_ok)
{
// the HTTP table failed to parse, so delete it
LLFile::remove(http_path);
LL_WARNS("RenderInit") << "Removed invalid gpu table '" << http_path << "'" << LL_ENDL;
}
}
parseGPUTable(path);
if (!parse_ok)
{
parse_ok = parseGPUTable(app_path);
}
return parse_ok; // indicates that the file parsed correctly, not that the gpu was recognized
}
void LLFeatureManager::parseGPUTable(std::string filename)
bool LLFeatureManager::parseGPUTable(std::string filename)
{
llifstream file;
LL_INFOS("RenderInit") << "Attempting to parse GPU table from " << filename << LL_ENDL;
file.open(filename);
if (!file)
if (file)
{
const char recognizer[] = "//GPU_TABLE";
char first_line[MAX_STRING];
file.getline(first_line, MAX_STRING);
if (0 != strncmp(first_line, recognizer, strlen(recognizer)))
{
LL_WARNS("RenderInit") << "Invalid GPU table: " << filename << "!" << LL_ENDL;
return false;
}
}
else
{
LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL;
return;
return false;
}
std::string rawRenderer = gGLManager.getRawGLString();
@ -556,6 +604,7 @@ void LLFeatureManager::parseGPUTable(std::string filename)
#if LL_DARWIN // never go over "Mid" settings by default on OS X
mGPUClass = llmin(mGPUClass, GPU_CLASS_2);
#endif
return true;
}
// responder saves table into file

View File

@ -75,7 +75,7 @@ public:
void setFeatureAvailable(const std::string& name, const BOOL available);
void setRecommendedLevel(const std::string& name, const F32 level);
BOOL loadFeatureList(LLFILE *fp);
bool loadFeatureList(LLFILE *fp);
BOOL maskList(LLFeatureList &mask);
@ -114,7 +114,7 @@ public:
void maskCurrentList(const std::string& name); // Mask the current feature list with the named list
BOOL loadFeatureTables();
bool loadFeatureTables();
EGPUClass getGPUClass() { return mGPUClass; }
std::string& getGPUString() { return mGPUString; }
@ -157,9 +157,14 @@ public:
void fetchHTTPTables();
protected:
void loadGPUClass();
BOOL parseFeatureTable(std::string filename);
void parseGPUTable(std::string filename);
bool loadGPUClass();
bool parseFeatureTable(std::string filename);
///< @returns TRUE is file parsed correctly, FALSE if not
bool parseGPUTable(std::string filename);
///< @returns true if file parsed correctly, false if not - does not reflect whether or not the gpu was recognized
void initBaseMask();

View File

@ -62,6 +62,11 @@ LLFilePicker LLFilePicker::sInstance;
#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0"
#endif
#ifdef LL_DARWIN
#include "llfilepicker_mac.h"
//#include <boost/algorithm/string/predicate.hpp>
#endif
//
// Implementation
//
@ -94,14 +99,6 @@ LLFilePicker::LLFilePicker()
mFilesW[0] = '\0';
#endif
#if LL_DARWIN
memset(&mNavOptions, 0, sizeof(mNavOptions));
OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions);
if (error == noErr)
{
mNavOptions.modality = kWindowModalityAppModal;
}
#endif
}
LLFilePicker::~LLFilePicker()
@ -559,215 +556,107 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
#elif LL_DARWIN
Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
{
Boolean result = true;
ELoadFilter filter = *((ELoadFilter*) callBackUD);
OSStatus error = noErr;
if (filterMode == kNavFilteringBrowserList && filter != FFLOAD_ALL && (theItem->descriptorType == typeFSRef || theItem->descriptorType == typeFSS))
{
// navInfo is only valid for typeFSRef and typeFSS
NavFileOrFolderInfo *navInfo = (NavFileOrFolderInfo*) info;
if (!navInfo->isFolder)
{
AEDesc desc;
error = AECoerceDesc(theItem, typeFSRef, &desc);
if (error == noErr)
{
FSRef fileRef;
error = AEGetDescData(&desc, &fileRef, sizeof(fileRef));
if (error == noErr)
{
LSItemInfoRecord fileInfo;
error = LSCopyItemInfoForRef(&fileRef, kLSRequestExtension | kLSRequestTypeCreator, &fileInfo);
if (error == noErr)
{
if (filter == FFLOAD_IMAGE)
{
if (fileInfo.filetype != 'JPEG' && fileInfo.filetype != 'JPG ' &&
fileInfo.filetype != 'BMP ' && fileInfo.filetype != 'TGA ' &&
fileInfo.filetype != 'BMPf' && fileInfo.filetype != 'TPIC' &&
fileInfo.filetype != 'PNG ' &&
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("jpeg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
CFStringCompare(fileInfo.extension, CFSTR("jpg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
CFStringCompare(fileInfo.extension, CFSTR("bmp"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
CFStringCompare(fileInfo.extension, CFSTR("tga"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
CFStringCompare(fileInfo.extension, CFSTR("png"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
)
{
result = false;
}
}
else if (filter == FFLOAD_WAV)
{
if (fileInfo.filetype != 'WAVE' && fileInfo.filetype != 'WAV ' &&
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("wave"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
CFStringCompare(fileInfo.extension, CFSTR("wav"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
)
{
result = false;
}
}
else if (filter == FFLOAD_ANIM)
{
if (fileInfo.filetype != 'BVH ' &&
fileInfo.filetype != 'ANIM' &&
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("bvh"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) &&
fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("anim"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
)
{
result = false;
}
}
else if (filter == FFLOAD_COLLADA)
{
if (fileInfo.filetype != 'DAE ' &&
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dae"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
)
{
result = false;
}
}
std::vector<std::string> *allowedv = new std::vector< std::string >;
switch(filter)
{
case FFLOAD_ALL:
allowedv->push_back("wav");
allowedv->push_back("bvh");
allowedv->push_back("anim");
allowedv->push_back("dae");
allowedv->push_back("raw");
allowedv->push_back("lsl");
allowedv->push_back("dic");
allowedv->push_back("xcu");
case FFLOAD_IMAGE:
allowedv->push_back("jpg");
allowedv->push_back("jpeg");
allowedv->push_back("bmp");
allowedv->push_back("tga");
allowedv->push_back("bmpf");
allowedv->push_back("tpic");
allowedv->push_back("png");
break;
case FFLOAD_WAV:
allowedv->push_back("wav");
break;
case FFLOAD_ANIM:
allowedv->push_back("bvh");
allowedv->push_back("anim");
break;
case FFLOAD_COLLADA:
allowedv->push_back("dae");
break;
#ifdef _CORY_TESTING
else if (filter == FFLOAD_GEOMETRY)
{
if (fileInfo.filetype != 'SLG ' &&
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("slg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
)
{
result = false;
}
}
case FFLOAD_GEOMETRY:
allowedv->push_back("slg");
break;
#endif
else if (filter == FFLOAD_SLOBJECT)
{
llwarns << "*** navOpenFilterProc: FFLOAD_SLOBJECT NOT IMPLEMENTED ***" << llendl;
}
else if (filter == FFLOAD_RAW)
{
if (fileInfo.filetype != '\?\?\?\?' &&
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("raw"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
)
{
result = false;
}
}
else if (filter == FFLOAD_SCRIPT)
{
if (fileInfo.filetype != 'LSL ' &&
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("lsl"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) )
{
result = false;
}
}
else if (filter == FFLOAD_DICTIONARY)
{
if (fileInfo.filetype != 'DIC ' &&
fileInfo.filetype != 'XCU ' &&
(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dic"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) &&
fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("xcu"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)))
{
result = false;
}
}
if (fileInfo.extension)
{
CFRelease(fileInfo.extension);
}
}
}
AEDisposeDesc(&desc);
}
}
}
return result;
case FFLOAD_RAW:
allowedv->push_back("raw");
break;
case FFLOAD_SCRIPT:
allowedv->push_back("lsl");
break;
case FFLOAD_DICTIONARY:
allowedv->push_back("dic");
allowedv->push_back("xcu");
break;
case FFLOAD_DIRECTORY:
break;
default:
llwarns << "Unsupported format." << llendl;
}
return allowedv;
}
OSStatus LLFilePicker::doNavChooseDialog(ELoadFilter filter)
bool LLFilePicker::doNavChooseDialog(ELoadFilter filter)
{
OSStatus error = noErr;
NavDialogRef navRef = NULL;
NavReplyRecord navReply;
// if local file browsing is turned off, return without opening dialog
if ( check_local_file_access_enabled() == false )
{
return FALSE;
return false;
}
memset(&navReply, 0, sizeof(navReply));
// NOTE: we are passing the address of a local variable here.
// This is fine, because the object this call creates will exist for less than the lifetime of this function.
// (It is destroyed by NavDialogDispose() below.)
error = NavCreateChooseFileDialog(&mNavOptions, NULL, NULL, NULL, navOpenFilterProc, (void*)(&filter), &navRef);
gViewerWindow->getWindow()->beforeDialog();
if (error == noErr)
error = NavDialogRun(navRef);
std::vector<std::string> *allowed_types=navOpenFilterProc(filter);
std::vector<std::string> *filev = doLoadDialog(allowed_types,
mPickOptions);
gViewerWindow->getWindow()->afterDialog();
if (error == noErr)
error = NavDialogGetReply(navRef, &navReply);
if (navRef)
NavDialogDispose(navRef);
if (error == noErr && navReply.validRecord)
{
SInt32 count = 0;
SInt32 index;
// AE indexes are 1 based...
error = AECountItems(&navReply.selection, &count);
for (index = 1; index <= count; index++)
{
FSRef fsRef;
AEKeyword theAEKeyword;
DescType typeCode;
Size actualSize = 0;
char path[MAX_PATH]; /*Flawfinder: ignore*/
memset(&fsRef, 0, sizeof(fsRef));
error = AEGetNthPtr(&navReply.selection, index, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
if (error == noErr)
error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path));
if (error == noErr)
mFiles.push_back(std::string(path));
}
}
if (filev && filev->size() > 0)
{
mFiles.insert(mFiles.end(), filev->begin(), filev->end());
return true;
}
return error;
return false;
}
OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
{
OSStatus error = noErr;
NavDialogRef navRef = NULL;
NavReplyRecord navReply;
memset(&navReply, 0, sizeof(navReply));
// Setup the type, creator, and extension
OSType type, creator;
CFStringRef extension = NULL;
std::string extension, type, creator;
switch (filter)
{
case FFSAVE_WAV:
type = 'WAVE';
creator = 'TVOD';
extension = CFSTR(".wav");
type = "WAVE";
creator = "TVOD";
extension = "wav";
break;
case FFSAVE_TGA:
type = 'TPIC';
creator = 'prvw';
extension = CFSTR(".tga");
type = "TPIC";
creator = "prvw";
extension = "tga";
break;
case FFSAVE_TGAPNG:
type = 'PNG';
@ -775,156 +664,92 @@ OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& fi
extension = CFSTR(".png");
break;
case FFSAVE_BMP:
type = 'BMPf';
creator = 'prvw';
extension = CFSTR(".bmp");
type = "BMPf";
creator = "prvw";
extension = "bmp";
break;
case FFSAVE_JPEG:
type = 'JPEG';
creator = 'prvw';
extension = CFSTR(".jpeg");
type = "JPEG";
creator = "prvw";
extension = "jpeg";
break;
case FFSAVE_PNG:
type = 'PNG ';
creator = 'prvw';
extension = CFSTR(".png");
type = "PNG ";
creator = "prvw";
extension = "png";
break;
case FFSAVE_AVI:
type = '\?\?\?\?';
creator = '\?\?\?\?';
extension = CFSTR(".mov");
type = "\?\?\?\?";
creator = "\?\?\?\?";
extension = "mov";
break;
case FFSAVE_ANIM:
type = '\?\?\?\?';
creator = '\?\?\?\?';
extension = CFSTR(".xaf");
type = "\?\?\?\?";
creator = "\?\?\?\?";
extension = "xaf";
break;
#ifdef _CORY_TESTING
case FFSAVE_GEOMETRY:
type = '\?\?\?\?';
creator = '\?\?\?\?';
extension = CFSTR(".slg");
type = "\?\?\?\?";
creator = "\?\?\?\?";
extension = "slg";
break;
#endif
case FFSAVE_RAW:
type = '\?\?\?\?';
creator = '\?\?\?\?';
extension = CFSTR(".raw");
type = "\?\?\?\?";
creator = "\?\?\?\?";
extension = "raw";
break;
case FFSAVE_J2C:
type = '\?\?\?\?';
creator = 'prvw';
extension = CFSTR(".j2c");
type = "\?\?\?\?";
creator = "prvw";
extension = "j2c";
break;
case FFSAVE_SCRIPT:
type = 'LSL ';
creator = '\?\?\?\?';
extension = CFSTR(".lsl");
type = "LSL ";
creator = "\?\?\?\?";
extension = "lsl";
break;
case FFSAVE_ALL:
default:
type = '\?\?\?\?';
creator = '\?\?\?\?';
extension = CFSTR("");
type = "\?\?\?\?";
creator = "\?\?\?\?";
extension = "";
break;
}
// Create the dialog
error = NavCreatePutFileDialog(&mNavOptions, type, creator, NULL, NULL, &navRef);
if (error == noErr)
{
CFStringRef nameString = NULL;
bool hasExtension = true;
// Create a CFString of the initial file name
if (!filename.empty())
nameString = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8);
else
nameString = CFSTR("Untitled");
// Add the extension if one was not provided
if (nameString && !CFStringHasSuffix(nameString, extension))
{
CFStringRef tempString = nameString;
hasExtension = false;
nameString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), tempString, extension);
CFRelease(tempString);
}
// Set the name in the dialog
if (nameString)
{
error = NavDialogSetSaveFileName(navRef, nameString);
CFRelease(nameString);
}
else
{
error = paramErr;
}
}
std::string namestring = filename;
if (namestring.empty()) namestring="Untitled";
// if (! boost::algorithm::ends_with(namestring, extension) )
// {
// namestring = namestring + "." + extension;
//
// }
gViewerWindow->getWindow()->beforeDialog();
// Run the dialog
if (error == noErr)
error = NavDialogRun(navRef);
std::string* filev = doSaveDialog(&namestring,
&type,
&creator,
&extension,
mPickOptions);
gViewerWindow->getWindow()->afterDialog();
if (error == noErr)
error = NavDialogGetReply(navRef, &navReply);
if (navRef)
NavDialogDispose(navRef);
if (error == noErr && navReply.validRecord)
if ( filev && !filev->empty() )
{
SInt32 count = 0;
// AE indexes are 1 based...
error = AECountItems(&navReply.selection, &count);
if (count > 0)
{
// Get the FSRef to the containing folder
FSRef fsRef;
AEKeyword theAEKeyword;
DescType typeCode;
Size actualSize = 0;
memset(&fsRef, 0, sizeof(fsRef));
error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
if (error == noErr)
{
char path[PATH_MAX]; /*Flawfinder: ignore*/
char newFileName[SINGLE_FILENAME_BUFFER_SIZE]; /*Flawfinder: ignore*/
error = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX);
if (error == noErr)
{
if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8))
{
mFiles.push_back(std::string(path) + "/" + std::string(newFileName));
}
else
{
error = paramErr;
}
}
else
{
error = paramErr;
}
}
}
}
mFiles.push_back(*filev);
return true;
}
return error;
return false;
}
BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
@ -940,16 +765,21 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
return FALSE;
}
OSStatus error = noErr;
reset();
mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
mPickOptions &= ~F_MULTIPLE;
mPickOptions |= F_FILE;
if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker.
{
mPickOptions |= ( F_NAV_SUPPORT | F_DIRECTORY );
mPickOptions &= ~F_FILE;
}
if(filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful
{
// mNavOptions.optionFlags |= kNavAllowOpenPackages;
mNavOptions.optionFlags |= kNavSupportPackages;
mPickOptions &= F_NAV_SUPPORT;
}
if (blocking)
@ -958,14 +788,13 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
send_agent_pause();
}
success = doNavChooseDialog(filter);
if (success)
{
error = doNavChooseDialog(filter);
}
if (error == noErr)
{
if (getFileCount())
success = true;
if (!getFileCount())
success = false;
}
if (blocking)
@ -991,21 +820,22 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
return FALSE;
}
OSStatus error = noErr;
reset();
mNavOptions.optionFlags |= kNavAllowMultipleFiles;
mPickOptions |= F_FILE;
mPickOptions |= F_MULTIPLE;
// Modal, so pause agent
send_agent_pause();
success = doNavChooseDialog(filter);
send_agent_resume();
if (success)
{
error = doNavChooseDialog(filter);
}
send_agent_resume();
if (error == noErr)
{
if (getFileCount())
success = true;
if (!getFileCount())
success = false;
if (getFileCount() > 1)
mLocked = true;
}
@ -1017,37 +847,37 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
{
if( mLocked )
return FALSE;
BOOL success = FALSE;
OSStatus error = noErr;
return false;
BOOL success = false;
// if local file browsing is turned off, return without opening dialog
if ( check_local_file_access_enabled() == false )
{
return FALSE;
return false;
}
reset();
mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
mPickOptions &= ~F_MULTIPLE;
// Modal, so pause agent
send_agent_pause();
success = doNavSaveDialog(filter, filename);
if (success)
{
error = doNavSaveDialog(filter, filename);
}
send_agent_resume();
if (error == noErr)
{
if (getFileCount())
success = true;
if (!getFileCount())
success = false;
}
// Account for the fact that the app has been stalled.
LLFrameTimer::updateFrameTime();
return success;
}
//END LL_DARWIN
#elif LL_LINUX || LL_SOLARIS
@ -1602,4 +1432,4 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
return FALSE;
}
#endif
#endif // LL_LINUX || LL_SOLARIS

View File

@ -39,8 +39,8 @@
#include <Carbon/Carbon.h>
// AssertMacros.h does bad things.
#include "fix_macros.h"
#undef verify
#undef check
#undef require
#include <vector>
@ -85,7 +85,8 @@ public:
FFLOAD_MODEL = 9,
FFLOAD_COLLADA = 10,
FFLOAD_SCRIPT = 11,
FFLOAD_DICTIONARY = 12
FFLOAD_DICTIONARY = 12,
FFLOAD_DIRECTORY = 13 //To call from lldirpicker.
};
enum ESaveFilter
@ -159,15 +160,14 @@ private:
#endif
#if LL_DARWIN
NavDialogCreationOptions mNavOptions;
S32 mPickOptions;
std::vector<std::string> mFileVector;
UInt32 mFileIndex;
OSStatus doNavChooseDialog(ELoadFilter filter);
OSStatus doNavSaveDialog(ESaveFilter filter, const std::string& filename);
void getFilePath(SInt32 index);
void getFileName(SInt32 index);
static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode);
bool doNavChooseDialog(ELoadFilter filter);
bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
//static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode);
std::vector<std::string>* navOpenFilterProc(ELoadFilter filter);
#endif
#if LL_GTK

View File

@ -0,0 +1,58 @@
/**
* @file llfilepicker_mac.h
* @brief OS-specific file picker
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// OS specific file selection dialog. This is implemented as a
// singleton class, so call the instance() method to get the working
// instance. When you call getMultipleOpenFile(), it locks the picker
// until you iterate to the end of the list of selected files with
// getNextFile() or call reset().
#ifndef LL_LLFILEPICKER_MAC_H
#define LL_LLFILEPICKER_MAC_H
#if LL_DARWIN
#include <string>
#include <vector>
//void modelessPicker();
std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,
unsigned int flags);
std::string* doSaveDialog(const std::string* file,
const std::string* type,
const std::string* creator,
const std::string* extension,
unsigned int flags);
enum {
F_FILE = 0x00000001,
F_DIRECTORY = 0x00000002,
F_MULTIPLE = 0x00000004,
F_NAV_SUPPORT=0x00000008
};
#endif
#endif

View File

@ -0,0 +1,132 @@
/**
* @file llfilepicker_mac.cpp
* @brief OS-specific file picker
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifdef LL_DARWIN
#import <Cocoa/Cocoa.h>
#include <iostream>
#include "llfilepicker_mac.h"
std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,
unsigned int flags)
{
int i, result;
//Aura TODO: We could init a small window and release it at the end of this routine
//for a modeless interface.
NSOpenPanel *panel = [NSOpenPanel openPanel];
//NSString *fileName = nil;
NSMutableArray *fileTypes = nil;
if ( allowed_types && !allowed_types->empty())
{
fileTypes = [[NSMutableArray alloc] init];
for (i=0;i<allowed_types->size();++i)
{
[fileTypes addObject:
[NSString stringWithCString:(*allowed_types)[i].c_str()
encoding:[NSString defaultCStringEncoding]]];
}
}
//[panel setMessage:@"Import one or more files or directories."];
[panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ];
[panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ];
[panel setCanCreateDirectories: true];
[panel setResolvesAliases: true];
[panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
std::vector<std::string>* outfiles = NULL;
if (fileTypes)
{
[panel setAllowedFileTypes:fileTypes];
result = [panel runModal];
}
else
{
// I suggest it's better to open the last path and let this default to home dir as necessary
// for consistency with other OS X apps
//
//[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
result = [panel runModal];
}
if (result == NSOKButton)
{
NSArray *filesToOpen = [panel URLs];
int i, count = [filesToOpen count];
if (count > 0)
{
outfiles = new std::vector<std::string>;
}
for (i=0; i<count; i++) {
NSString *aFile = [[filesToOpen objectAtIndex:i] path];
std::string *afilestr = new std::string([aFile UTF8String]);
outfiles->push_back(*afilestr);
}
}
return outfiles;
}
std::string* doSaveDialog(const std::string* file,
const std::string* type,
const std::string* creator,
const std::string* extension,
unsigned int flags)
{
NSSavePanel *panel = [NSSavePanel savePanel];
NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
NSArray *fileType = [[NSArray alloc] initWithObjects:extensionns,nil];
//[panel setMessage:@"Save Image File"];
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
[panel setCanSelectHiddenExtension:true];
[panel setAllowedFileTypes:fileType];
NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
std::string *outfile = NULL;
NSURL* url = [NSURL fileURLWithPath:fileName];
[panel setDirectoryURL: url];
if([panel runModal] ==
NSFileHandlingPanelOKButton)
{
NSURL* url = [panel URL];
NSString* p = [url path];
outfile = new std::string( [p UTF8String] );
// write the file
}
return outfile;
}
#endif

View File

@ -99,7 +99,7 @@ void LLFloaterConversationPreview::setPages(std::list<LLSD>& messages, const std
{
if(file_name == mChatHistoryFileName)
{
// additional protection to avoid changes of mMessages in setPages
// additional protection to avoid changes of mMessages in setPages()
LLMutexLock lock(&mMutex);
mMessages = messages;
mCurrentPage = (mMessages.size() ? (mMessages.size() - 1) / mPageSize : 0);
@ -111,10 +111,9 @@ void LLFloaterConversationPreview::setPages(std::list<LLSD>& messages, const std
std::string total_page_num = llformat("/ %d", mCurrentPage+1);
getChild<LLTextBox>("page_num_label")->setValue(total_page_num);
mChatHistoryLoaded = true;
}
}
void LLFloaterConversationPreview::draw()
{
if(mChatHistoryLoaded)
@ -148,7 +147,6 @@ void LLFloaterConversationPreview::showHistory()
}
mChatHistory->clear();
std::ostringstream message;
std::list<LLSD>::const_iterator iter = mMessages.begin();
std::advance(iter, mCurrentPage * mPageSize);
@ -198,7 +196,6 @@ void LLFloaterConversationPreview::showHistory()
mChatHistory->appendMessage(chat,chat_args);
}
}
void LLFloaterConversationPreview::onMoreHistoryBtnClick()

View File

@ -151,12 +151,17 @@ BOOL LLFloaterHardwareSettings::postBuild()
{
childSetAction("OK", onBtnOK, this);
// Don't do this on Mac as their braindead GL versioning
// sets this when 8x and 16x are indeed available
//
#if !LL_DARWIN
if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
{ //remove FSAA settings above "4x"
LLComboBox* combo = getChild<LLComboBox>("fsaa");
combo->remove("8x");
combo->remove("16x");
}
#endif
refresh();
center();

View File

@ -674,13 +674,18 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
void LLFloaterIMContainer::getDetachedConversationFloaters(floater_list_t& floaters)
{
typedef conversations_widgets_map::value_type conv_pair;
LLFloaterIMNearbyChat *nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
BOOST_FOREACH(conv_pair item, mConversationsWidgets)
{
LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(item.second);
if (widget)
{
LLFloater* session_floater = widget->getSessionFloater();
if (session_floater && session_floater->isDetachedAndNotMinimized())
// Exclude nearby chat from output, as it should be handled separately
if (session_floater && session_floater->isDetachedAndNotMinimized()
&& session_floater != nearby_chat)
{
floaters.push_back(session_floater);
}

View File

@ -2670,7 +2670,8 @@ void LLIMMgr::addMessage(
name_is_setted = true;
}
bool skip_message = false;
if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
bool from_linden = LLMuteList::getInstance()->isLinden(from);
if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden)
{
// Evaluate if we need to skip this message when that setting is true (default is false)
skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL); // Skip non friends...
@ -2716,7 +2717,7 @@ void LLIMMgr::addMessage(
// Logically it would make more sense to reject the session sooner, in another area of the
// code, but the session has to be established inside the server before it can be left.
if (LLMuteList::getInstance()->isMuted(other_participant_id) && !LLMuteList::getInstance()->isLinden(from))
if (LLMuteList::getInstance()->isMuted(other_participant_id) && !from_linden)
{
llwarns << "Leaving IM session from initiating muted resident " << from << llendl;
if(!gIMMgr->leaveSession(new_session_id))

View File

@ -125,25 +125,30 @@ void log_name_callback(const std::string& full_name, const std::string& from_nam
// static
void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
{
LLUUID from_id = notification->getPayload()["from_id"];
if (from_id.isNull())
{
// Normal behavior for system generated messages, don't spam.
// llwarns << " from_id for notification " << notification->getName() << " is null " << llendl;
return;
}
if(to_file_only)
{
gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
}
else
{
gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
}
if (!gCacheName)
{
return;
}
LLUUID from_id = notification->getPayload()["from_id"];
if (from_id.isNull())
{
// Normal behavior for system generated messages, don't spam.
// llwarns << " from_id for notification " << notification->getName() << " is null " << llendl;
return;
}
if(to_file_only)
{
gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
}
else
{
gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
}
}
// static
void LLHandlerUtil::logGroupNoticeToIMGroup(
const LLNotificationPtr& notification)

View File

@ -676,6 +676,7 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL
if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end())
{
mKeyHandledByUI[translated_key] = FALSE;
LL_INFOS("Keyboard Handling") << "Key wasn't handled by UI!" << LL_ENDL;
}
else
{

View File

@ -1073,8 +1073,6 @@ class LLAdvancedCheckInfoDisplay : public view_listener_t
U32 info_display = info_display_from_string( userdata.asString() );
bool new_value = false;
LL_INFOS("ViewerMenu") << "check " << userdata.asString() << LL_ENDL;
if ( info_display != 0 )
{
new_value = LLPipeline::toggleRenderDebugControl( (void*)info_display );

View File

@ -2362,7 +2362,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
BOOL is_owned_by_me = FALSE;
BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
LLMuteList::getInstance()->isLinden(name);
chat.mMuted = is_muted;
chat.mFromID = from_id;
chat.mFromName = name;
@ -2462,7 +2464,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
bool mute_im = is_muted;
if(accept_im_from_only_friend&&!is_friend)
if(accept_im_from_only_friend && !is_friend && !is_linden)
{
if (!gIMMgr->isNonFriendSessionNotified(session_id))
{

View File

@ -160,7 +160,11 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_agent, const F32 bo
}
mVOPartGroupp->setViewerPartGroup(this);
mVOPartGroupp->setPositionAgent(getCenterAgent());
mBoxSide = box_side;
F32 scale = box_side * 0.5f;
mVOPartGroupp->setScale(LLVector3(scale,scale,scale));
//gPipeline.addObject(mVOPartGroupp);

View File

@ -105,6 +105,9 @@ public:
void shift(const LLVector3 &offset);
F32 getBoxRadius() { return mBoxRadius; }
F32 getBoxSide() { return mBoxSide; }
typedef std::vector<LLViewerPart*> part_list_t;
part_list_t mParticles;
@ -125,6 +128,7 @@ public:
protected:
LLVector3 mCenterAgent;
F32 mBoxRadius;
F32 mBoxSide;
LLVector3 mMinObjPos;
LLVector3 mMaxObjPos;

View File

@ -176,24 +176,28 @@ BOOL LLVOPartGroup::isActive() const
F32 LLVOPartGroup::getBinRadius()
{
return mScale.mV[0]*2.f;
return mViewerPartGroupp->getBoxSide();
}
void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
{
const LLVector3& pos_agent = getPositionAgent();
newMin.load3( (pos_agent - mScale).mV);
newMax.load3( (pos_agent + mScale).mV);
LLVector4a scale;
LLVector4a p;
p.load3(pos_agent.mV);
scale.splat(mScale.mV[0]+mViewerPartGroupp->getBoxSide()*0.5f);
newMin.setSub(p, scale);
newMax.setAdd(p,scale);
llassert(newMin.isFinite3());
llassert(newMax.isFinite3());
LLVector4a pos;
pos.load3(pos_agent.mV);
llassert(pos.isFinite3());
mDrawable->setPositionGroup(pos);
llassert(p.isFinite3());
mDrawable->setPositionGroup(p);
}
void LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
@ -459,6 +463,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
}
//record max scale (used to stretch bounding box for visibility culling)
mScale.set(max_scale, max_scale, max_scale);
mDrawable->movePartition();

View File

@ -32,7 +32,6 @@
*
*/
#include <Carbon/Carbon.h>
#include "fix_macros.h"
#undef verify

View File

@ -207,7 +207,7 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBas
std::string const & platform_version,
unsigned char uniqueid[MD5HEX_STR_SIZE],
bool willing_to_test)
{
{
LLSD path;
path.append(mProtocol);
path.append(channel);

View File

@ -73,6 +73,10 @@ die "Must specify a --gpu-table <gpu_table.txt> value"
open(GPUS, "<$GpuTable")
|| die "Failed to open gpu table '$GpuTable':\n\t$!\n";
my $FirstLine = <GPUS>;
die "First line of gpu table does not begin with '//GPU_TABLE'"
unless $FirstLine =~ m|^//GPU_TABLE|;
# Parse the GPU table into these tables, indexed by the name
my %NameLine; # name -> line number on which a given name was found (catches duplicate names)
my %RecognizerLine; # name -> line number on which a given name was found (catches duplicate names)