Merge from viewer-experience

master
Leslie Linden 2011-09-07 13:58:19 -07:00
commit 78821c51a1
362 changed files with 8431 additions and 4831 deletions

11
.hgtags
View File

@ -172,6 +172,15 @@ fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
46a010f4885a9d223b511eac553ba5720284b1dc 3.0.0-start
b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1
b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1
46a010f4885a9d223b511eac553ba5720284b1dc 3.0.0-start
6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start
82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start
364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1
364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1
f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start
1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-78_3.0.0-release
1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1
42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1
e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2
e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2
b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start

View File

@ -42,6 +42,12 @@ snowstorm_viewer-development.viewer_channel = "Second Life Development"
snowstorm_viewer-development.login_channel = "Second Life Development"
snowstorm_viewer-development.build_viewer_update_version_manager = false
snowstorm_viewer-development.email = viewer-development-builds@lists.secondlife.com
snowstorm_viewer-development.build_enforce_coding_policy = true
Snowstorm_viewer-project-review.build_debug_release_separately = true
Snowstorm_viewer-project-review.codeticket_add_context = true
Snowstorm_viewer-project-review.viewer_channel = "Project Viewer - Snowstorm Team"
Snowstorm_viewer-project-review.login_channel = "Project Viewer - Snowstorm Team"
# ========================================
# Viewer Beta
@ -142,6 +148,7 @@ cg_viewer-development_lenny.email = cg@lindenlab.com
oz_viewer-devreview.build_debug_release_separately = true
oz_viewer-devreview.codeticket_add_context = false
oz_viewer-devreview.build_enforce_coding_policy = true
oz_project-1.build_debug_release_separately = true
oz_project-1.codeticket_add_context = false
@ -157,9 +164,6 @@ oz_viewer-beta-review.codeticket_add_context = false
oz_viewer-beta-review.viewer_channel = "Second Life Beta Viewer"
oz_viewer-beta-review.login_channel = "Second Life Beta Viewer"
oz_viewer-poreview.build_debug_release_separately = true
oz_viewer-poreview.codeticket_add_context = false
# =================================================================
# asset delivery 2010 projects
# =================================================================

View File

@ -1110,9 +1110,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>0db10480362168f075c2af0ae302cb74</string>
<string>362654a472ef7368d4c803ae3fb89d95</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/234943/arch/Darwin/installer/llconvexdecomposition-0.1-darwin-20110707.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/238959/arch/Darwin/installer/llconvexdecomposition-0.1-darwin-20110819.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1122,9 +1122,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f3c667dc159c0537a9122ce6e72e16db</string>
<string>c7801d899daec5338fbe95053255b7e7</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/234943/arch/Linux/installer/llconvexdecomposition-0.1-linux-20110707.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/238959/arch/Linux/installer/llconvexdecomposition-0.1-linux-20110819.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1134,9 +1134,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>46cac4d667446bbbc9b5023f2848a5ac</string>
<string>6ecf2f85f03c5ae87fe45769566a5660</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/234943/arch/CYGWIN/installer/llconvexdecomposition-0.1-windows-20110707.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/238959/arch/CYGWIN/installer/llconvexdecomposition-0.1-windows-20110819.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1158,9 +1158,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>bc1388fc28dbb3bba1fe7cb8d09f49b4</string>
<string>a5f53e09f67271fd50f1131ffdda9d27</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/227399/arch/Darwin/installer/llconvexdecompositionstub-0.3-darwin-20110421.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/238958/arch/Darwin/installer/llconvexdecompositionstub-0.3-darwin-20110819.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1170,9 +1170,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>3295bd4a0514b7c15dda9044f40c175e</string>
<string>0006a964f1497f55a5f181b7042d2d22</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/227399/arch/Linux/installer/llconvexdecompositionstub-0.3-linux-20110422.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/238958/arch/Linux/installer/llconvexdecompositionstub-0.3-linux-20110819.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1182,9 +1182,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>92f1dff3249024c1534b55343ed79ea3</string>
<string>b859e7e3bb03ebb467f0309f46422995</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/227399/arch/CYGWIN/installer/llconvexdecompositionstub-0.3-windows-20110421.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/238958/arch/CYGWIN/installer/llconvexdecompositionstub-0.3-windows-20110819.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1206,9 +1206,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>a7c80fd8516df3b879b669b2b220067f</string>
<string>9cd66e879908f047d9af665b92946ecc</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/232420/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20110608.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/239803/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20110830.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1230,9 +1230,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>b9cc0333cc274c9cc40256ab7146b4fc</string>
<string>ab9393795515cbbe9526bde33b41bf2a</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/232420/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20110608.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/239670/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20110829.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1907,12 +1907,12 @@
<map>
<key>build</key>
<map>
<key>command</key>
<string>xcodebuild</string>
<key>filters</key>
<array>
<string>setenv</string>
</array>
<key>command</key>
<string>xcodebuild</string>
<key>options</key>
<array>
<string>-configuration Debug</string>
@ -1961,12 +1961,12 @@
<map>
<key>build</key>
<map>
<key>command</key>
<string>xcodebuild</string>
<key>filters</key>
<array>
<string>setenv</string>
</array>
<key>command</key>
<string>xcodebuild</string>
<key>options</key>
<array>
<string>-configuration RelWithDebInfo</string>
@ -2017,12 +2017,12 @@
<map>
<key>build</key>
<map>
<key>command</key>
<string>xcodebuild</string>
<key>filters</key>
<array>
<string>setenv</string>
</array>
<key>command</key>
<string>xcodebuild</string>
<key>options</key>
<array>
<string>-configuration Release</string>

View File

@ -476,6 +476,7 @@ Identity Euler
Ima Mechanique
OPEN-50
OPEN-61
OPEN-76
STORM-1175
Imnotgoing Sideways
Inma Rau
@ -563,8 +564,13 @@ Jonathan Yap
STORM-1313
STORM-899
STORM-1273
STORM-1276
STORM-1462
STORM-1459
STORM-1522
STORM-1567
STORM-1572
STORM-1574
Kadah Coba
STORM-1060
Jondan Lundquist

View File

@ -379,7 +379,7 @@ namespace
{
/* This pattern, of returning a reference to a static function
variable, is to ensure that this global is constructed before
it is used, no matter what the global initializeation sequence
it is used, no matter what the global initialization sequence
is.
See C++ FAQ Lite, sections 10.12 through 10.14
*/

View File

@ -39,7 +39,7 @@
Information for most users:
Code can log messages with constuctions like this:
Code can log messages with constructions like this:
LL_INFOS("StringTag") << "request to fizzbip agent " << agent_id
<< " denied due to timeout" << LL_ENDL;
@ -47,9 +47,9 @@
Messages can be logged to one of four increasing levels of concern,
using one of four "streams":
LL_DEBUGS("StringTag") - debug messages that are normally supressed
LL_INFOS("StringTag") - informational messages that are normall shown
LL_WARNS("StringTag") - warning messages that singal a problem
LL_DEBUGS("StringTag") - debug messages that are normally suppressed
LL_INFOS("StringTag") - informational messages that are normal shown
LL_WARNS("StringTag") - warning messages that signal a problem
LL_ERRS("StringTag") - error messages that are major, unrecoverable failures
The later (LL_ERRS("StringTag")) automatically crashes the process after the message
@ -90,7 +90,7 @@
WARN: LLFoo::doSomething: called with a big value for i: 283
Which messages are logged and which are supressed can be controled at run
Which messages are logged and which are suppressed can be controlled at run
time from the live file logcontrol.xml based on function, class and/or
source file. See etc/logcontrol-dev.xml for details.
@ -106,7 +106,7 @@ namespace LLError
enum ELevel
{
LEVEL_ALL = 0,
// used to indicate that all messagess should be logged
// used to indicate that all messages should be logged
LEVEL_DEBUG = 0,
LEVEL_INFO = 1,
@ -220,7 +220,7 @@ namespace LLError
// See top of file for example of how to use this
typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// Outside a class declartion, or in class without LOG_CLASS(), this
// Outside a class declaration, or in class without LOG_CLASS(), this
// typedef causes the messages to not be associated with any class.

View File

@ -92,7 +92,7 @@ public:
public:
typedef boost::iterator_facade<key_iter, KEY, boost::forward_traversal_tag> super_t;
key_iter(typename InstanceMap::iterator& it)
key_iter(typename InstanceMap::iterator it)
: mIterator(it)
{
++sIterationNestDepth;

View File

@ -100,12 +100,6 @@ private:
DELETED
} EInitState;
static void deleteSingleton()
{
delete getData().mSingletonInstance;
getData().mSingletonInstance = NULL;
}
// stores pointer to singleton instance
// and tracks initialization state of singleton
struct SingletonInstanceData
@ -120,7 +114,11 @@ private:
~SingletonInstanceData()
{
deleteSingleton();
SingletonInstanceData& data = getData();
if (data.mInitState != DELETED)
{
deleteSingleton();
}
}
};
@ -132,6 +130,14 @@ public:
data.mInitState = DELETED;
}
// Can be used to control when the singleton is deleted. Not normally needed.
static void deleteSingleton()
{
delete getData().mSingletonInstance;
getData().mSingletonInstance = NULL;
getData().mInitState = DELETED;
}
static SingletonInstanceData& getData()
{
// this is static to cache the lookup results

View File

@ -29,7 +29,7 @@
const S32 LL_VERSION_MAJOR = 3;
const S32 LL_VERSION_MINOR = 0;
const S32 LL_VERSION_PATCH = 2;
const S32 LL_VERSION_PATCH = 4;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";

View File

@ -90,79 +90,79 @@ namespace tut
ensure_equals(Keyed::instanceCount(), 0);
}
// template<> template<>
// void object::test<2>()
// {
// ensure_equals(Unkeyed::instanceCount(), 0);
// {
// Unkeyed one;
// ensure_equals(Unkeyed::instanceCount(), 1);
// Unkeyed* found = Unkeyed::getInstance(&one);
// ensure_equals(found, &one);
// {
// boost::scoped_ptr<Unkeyed> two(new Unkeyed);
// ensure_equals(Unkeyed::instanceCount(), 2);
// Unkeyed* found = Unkeyed::getInstance(two.get());
// ensure_equals(found, two.get());
// }
// ensure_equals(Unkeyed::instanceCount(), 1);
// }
// ensure_equals(Unkeyed::instanceCount(), 0);
// }
template<> template<>
void object::test<2>()
{
ensure_equals(Unkeyed::instanceCount(), 0);
{
Unkeyed one;
ensure_equals(Unkeyed::instanceCount(), 1);
Unkeyed* found = Unkeyed::getInstance(&one);
ensure_equals(found, &one);
{
boost::scoped_ptr<Unkeyed> two(new Unkeyed);
ensure_equals(Unkeyed::instanceCount(), 2);
Unkeyed* found = Unkeyed::getInstance(two.get());
ensure_equals(found, two.get());
}
ensure_equals(Unkeyed::instanceCount(), 1);
}
ensure_equals(Unkeyed::instanceCount(), 0);
}
// template<> template<>
// void object::test<3>()
// {
// Keyed one("one"), two("two"), three("three");
// // We don't want to rely on the underlying container delivering keys
// // in any particular order. That allows us the flexibility to
// // reimplement LLInstanceTracker using, say, a hash map instead of a
// // std::map. We DO insist that every key appear exactly once.
// typedef std::vector<std::string> StringVector;
// StringVector keys(Keyed::beginKeys(), Keyed::endKeys());
// std::sort(keys.begin(), keys.end());
// StringVector::const_iterator ki(keys.begin());
// ensure_equals(*ki++, "one");
// ensure_equals(*ki++, "three");
// ensure_equals(*ki++, "two");
// // Use ensure() here because ensure_equals would want to display
// // mismatched values, and frankly that wouldn't help much.
// ensure("didn't reach end", ki == keys.end());
template<> template<>
void object::test<3>()
{
Keyed one("one"), two("two"), three("three");
// We don't want to rely on the underlying container delivering keys
// in any particular order. That allows us the flexibility to
// reimplement LLInstanceTracker using, say, a hash map instead of a
// std::map. We DO insist that every key appear exactly once.
typedef std::vector<std::string> StringVector;
StringVector keys(Keyed::beginKeys(), Keyed::endKeys());
std::sort(keys.begin(), keys.end());
StringVector::const_iterator ki(keys.begin());
ensure_equals(*ki++, "one");
ensure_equals(*ki++, "three");
ensure_equals(*ki++, "two");
// Use ensure() here because ensure_equals would want to display
// mismatched values, and frankly that wouldn't help much.
ensure("didn't reach end", ki == keys.end());
// // Use a somewhat different approach to order independence with
// // beginInstances(): explicitly capture the instances we know in a
// // set, and delete them as we iterate through.
// typedef std::set<Keyed*> InstanceSet;
// InstanceSet instances;
// instances.insert(&one);
// instances.insert(&two);
// instances.insert(&three);
// for (Keyed::instance_iter ii(Keyed::beginInstances()), iend(Keyed::endInstances());
// ii != iend; ++ii)
// {
// Keyed& ref = *ii;
// ensure_equals("spurious instance", instances.erase(&ref), 1);
// }
// ensure_equals("unreported instance", instances.size(), 0);
// }
// Use a somewhat different approach to order independence with
// beginInstances(): explicitly capture the instances we know in a
// set, and delete them as we iterate through.
typedef std::set<Keyed*> InstanceSet;
InstanceSet instances;
instances.insert(&one);
instances.insert(&two);
instances.insert(&three);
for (Keyed::instance_iter ii(Keyed::beginInstances()), iend(Keyed::endInstances());
ii != iend; ++ii)
{
Keyed& ref = *ii;
ensure_equals("spurious instance", instances.erase(&ref), 1);
}
ensure_equals("unreported instance", instances.size(), 0);
}
// template<> template<>
// void object::test<4>()
// {
// Unkeyed one, two, three;
// typedef std::set<Unkeyed*> KeySet;
//
// KeySet instances;
// instances.insert(&one);
// instances.insert(&two);
// instances.insert(&three);
//for (Unkeyed::instance_iter ii(Unkeyed::beginInstances()), iend(Unkeyed::endInstances()); ii != iend; ++ii)
//{
// Unkeyed& ref = *ii;
// ensure_equals("spurious instance", instances.erase(&ref), 1);
//}
// ensure_equals("unreported instance", instances.size(), 0);
// }
template<> template<>
void object::test<4>()
{
Unkeyed one, two, three;
typedef std::set<Unkeyed*> KeySet;
KeySet instances;
instances.insert(&one);
instances.insert(&two);
instances.insert(&three);
for (Unkeyed::instance_iter ii(Unkeyed::beginInstances()), iend(Unkeyed::endInstances()); ii != iend; ++ii)
{
Unkeyed& ref = *ii;
ensure_equals("spurious instance", instances.erase(&ref), 1);
}
ensure_equals("unreported instance", instances.size(), 0);
}
} // namespace tut

View File

@ -65,6 +65,7 @@ set(llmessage_SOURCE_FILES
llpacketbuffer.cpp
llpacketring.cpp
llpartdata.cpp
llproxy.cpp
llpumpio.cpp
llregionpresenceverifier.cpp
llsdappservices.cpp
@ -161,6 +162,7 @@ set(llmessage_HEADER_FILES
llpacketring.h
llpartdata.h
llpumpio.h
llproxy.h
llqueryflags.h
llregionflags.h
llregionhandle.h

View File

@ -1,5 +1,5 @@
/**
* @file llcurl.h
* @file llcurl.cpp
* @author Zero / Donovan
* @date 2006-10-15
* @brief Implementation of wrapper around libcurl.
@ -26,7 +26,6 @@
* $/LicenseInfo$
*/
#if LL_WINDOWS
#define SAFE_SSL 1
#elif LL_DARWIN
@ -47,8 +46,9 @@
#endif
#include "llbufferstream.h"
#include "llstl.h"
#include "llproxy.h"
#include "llsdserialize.h"
#include "llstl.h"
#include "llthread.h"
#include "lltimer.h"
@ -209,7 +209,7 @@ namespace boost
void intrusive_ptr_release(LLCurl::Responder* p)
{
if(p && 0 == --p->mReferenceCount)
if (p && 0 == --p->mReferenceCount)
{
delete p;
}
@ -219,73 +219,6 @@ namespace boost
//////////////////////////////////////////////////////////////////////////////
class LLCurl::Easy
{
LOG_CLASS(Easy);
private:
Easy();
public:
static Easy* getEasy();
~Easy();
CURL* getCurlHandle() const { return mCurlEasyHandle; }
void setErrorBuffer();
void setCA();
void setopt(CURLoption option, S32 value);
// These assume the setter does not free value!
void setopt(CURLoption option, void* value);
void setopt(CURLoption option, char* value);
// Copies the string so that it is gauranteed to stick around
void setoptString(CURLoption option, const std::string& value);
void slist_append(const char* str);
void setHeaders();
U32 report(CURLcode);
void getTransferInfo(LLCurl::TransferInfo* info);
void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, S32 time_out = 0, bool post = false);
const char* getErrorBuffer();
std::stringstream& getInput() { return mInput; }
std::stringstream& getHeaderOutput() { return mHeaderOutput; }
LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; }
const LLChannelDescriptors& getChannels() { return mChannels; }
void resetState();
static CURL* allocEasyHandle();
static void releaseEasyHandle(CURL* handle);
private:
friend class LLCurl;
CURL* mCurlEasyHandle;
struct curl_slist* mHeaders;
std::stringstream mRequest;
LLChannelDescriptors mChannels;
LLIOPipe::buffer_ptr_t mOutput;
std::stringstream mInput;
std::stringstream mHeaderOutput;
char mErrorBuffer[CURL_ERROR_SIZE];
// Note: char*'s not strings since we pass pointers to curl
std::vector<char*> mStrings;
ResponderPtr mResponder;
static std::set<CURL*> sFreeHandles;
static std::set<CURL*> sActiveHandles;
static LLMutex* sHandleMutex;
};
std::set<CURL*> LLCurl::Easy::sFreeHandles;
std::set<CURL*> LLCurl::Easy::sActiveHandles;
LLMutex* LLCurl::Easy::sHandleMutex = NULL;
@ -409,11 +342,11 @@ const char* LLCurl::Easy::getErrorBuffer()
void LLCurl::Easy::setCA()
{
if(!sCAPath.empty())
if (!sCAPath.empty())
{
setoptString(CURLOPT_CAPATH, sCAPath);
}
if(!sCAFile.empty())
if (!sCAFile.empty())
{
setoptString(CURLOPT_CAINFO, sCAFile);
}
@ -536,9 +469,12 @@ void LLCurl::Easy::prepRequest(const std::string& url,
if (post) setoptString(CURLOPT_ENCODING, "");
//setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
//setopt(CURLOPT_VERBOSE, 1); // useful for debugging
setopt(CURLOPT_NOSIGNAL, 1);
// Set the CURL options for either Socks or HTTP proxy
LLProxy::getInstance()->applyProxySettings(this);
mOutput.reset(new LLBufferArray);
setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback);
setopt(CURLOPT_WRITEDATA, (void*)this);
@ -550,7 +486,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
setopt(CURLOPT_HEADERDATA, (void*)this);
// Allow up to five redirects
if(responder && responder->followRedir())
if (responder && responder->followRedir())
{
setopt(CURLOPT_FOLLOWLOCATION, 1);
setopt(CURLOPT_MAXREDIRS, MAX_REDIRECTS);
@ -563,7 +499,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
//don't verify host name so urls with scrubbed host names will work (improves DNS performance)
setopt(CURLOPT_SSL_VERIFYHOST, 0);
setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));
setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
setoptString(CURLOPT_URL, url);
@ -584,56 +520,6 @@ void LLCurl::Easy::prepRequest(const std::string& url,
////////////////////////////////////////////////////////////////////////////
class LLCurl::Multi : public LLThread
{
LOG_CLASS(Multi);
public:
typedef enum
{
PERFORM_STATE_READY=0,
PERFORM_STATE_PERFORMING=1,
PERFORM_STATE_COMPLETED=2
} ePerformState;
Multi();
~Multi();
Easy* allocEasy();
bool addEasy(Easy* easy);
void removeEasy(Easy* easy);
S32 process();
void perform();
void doPerform();
virtual void run();
CURLMsg* info_read(S32* msgs_in_queue);
S32 mQueued;
S32 mErrorCount;
S32 mPerformState;
LLCondition* mSignal;
bool mQuitting;
bool mThreaded;
private:
void easyFree(Easy*);
CURLM* mCurlMultiHandle;
typedef std::set<Easy*> easy_active_list_t;
easy_active_list_t mEasyActiveList;
typedef std::map<CURL*, Easy*> easy_active_map_t;
easy_active_map_t mEasyActiveMap;
typedef std::set<Easy*> easy_free_list_t;
easy_free_list_t mEasyFreeList;
};
LLCurl::Multi::Multi()
: LLThread("Curl Multi"),
mQueued(0),
@ -1071,6 +957,8 @@ LLCurlEasyRequest::LLCurlEasyRequest()
{
mEasy->setErrorBuffer();
mEasy->setCA();
// Set proxy settings if configured to do so.
LLProxy::getInstance()->applyProxySettings(mEasy);
}
}

View File

@ -187,6 +187,122 @@ private:
static const unsigned int MAX_REDIRECTS;
};
class LLCurl::Easy
{
LOG_CLASS(Easy);
private:
Easy();
public:
static Easy* getEasy();
~Easy();
CURL* getCurlHandle() const { return mCurlEasyHandle; }
void setErrorBuffer();
void setCA();
void setopt(CURLoption option, S32 value);
// These assume the setter does not free value!
void setopt(CURLoption option, void* value);
void setopt(CURLoption option, char* value);
// Copies the string so that it is guaranteed to stick around
void setoptString(CURLoption option, const std::string& value);
void slist_append(const char* str);
void setHeaders();
U32 report(CURLcode);
void getTransferInfo(LLCurl::TransferInfo* info);
void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, S32 time_out = 0, bool post = false);
const char* getErrorBuffer();
std::stringstream& getInput() { return mInput; }
std::stringstream& getHeaderOutput() { return mHeaderOutput; }
LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; }
const LLChannelDescriptors& getChannels() { return mChannels; }
void resetState();
static CURL* allocEasyHandle();
static void releaseEasyHandle(CURL* handle);
private:
friend class LLCurl;
CURL* mCurlEasyHandle;
struct curl_slist* mHeaders;
std::stringstream mRequest;
LLChannelDescriptors mChannels;
LLIOPipe::buffer_ptr_t mOutput;
std::stringstream mInput;
std::stringstream mHeaderOutput;
char mErrorBuffer[CURL_ERROR_SIZE];
// Note: char*'s not strings since we pass pointers to curl
std::vector<char*> mStrings;
ResponderPtr mResponder;
static std::set<CURL*> sFreeHandles;
static std::set<CURL*> sActiveHandles;
static LLMutex* sHandleMutex;
};
class LLCurl::Multi : public LLThread
{
LOG_CLASS(Multi);
public:
typedef enum
{
PERFORM_STATE_READY=0,
PERFORM_STATE_PERFORMING=1,
PERFORM_STATE_COMPLETED=2
} ePerformState;
Multi();
~Multi();
Easy* allocEasy();
bool addEasy(Easy* easy);
void removeEasy(Easy* easy);
S32 process();
void perform();
void doPerform();
virtual void run();
CURLMsg* info_read(S32* msgs_in_queue);
S32 mQueued;
S32 mErrorCount;
S32 mPerformState;
LLCondition* mSignal;
bool mQuitting;
bool mThreaded;
private:
void easyFree(Easy*);
CURLM* mCurlMultiHandle;
typedef std::set<Easy*> easy_active_list_t;
easy_active_list_t mEasyActiveList;
typedef std::map<CURL*, Easy*> easy_active_map_t;
easy_active_map_t mEasyActiveMap;
typedef std::set<Easy*> easy_free_list_t;
easy_free_list_t mEasyFreeList;
};
namespace boost
{
void intrusive_ptr_add_ref(LLCurl::Responder* p);
@ -243,6 +359,8 @@ public:
bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL);
std::string getErrorString();
LLCurl::Easy* getEasy() const { return mEasy; }
private:
CURLMsg* info_read(S32* queue, LLCurl::TransferInfo* info);
@ -253,4 +371,7 @@ private:
bool mResultReturned;
};
void check_curl_code(CURLcode code);
void check_curl_multi_code(CURLMcode code);
#endif // LL_LLCURL_H

View File

@ -33,6 +33,7 @@
#include "indra_constants.h"
#include "message.h"
#include "llproxy.h"
#include "llvfile.h"
#include "llvfs.h"
@ -232,6 +233,10 @@ void LLHTTPAssetRequest::setupCurlHandle()
{
// *NOTE: Similar code exists in mapserver/llcurlutil.cpp JC
mCurlHandle = curl_easy_init();
// Apply proxy settings if configured to do so
LLProxy::getInstance()->applyProxySettings(mCurlHandle);
curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(mCurlHandle, CURLOPT_URL, mURLBuffer.c_str());

View File

@ -428,6 +428,9 @@ static LLSD blocking_request(
std::string body_str;
// other request method checks root cert first, we skip?
// Apply configured proxy settings
LLProxy::getInstance()->applyProxySettings(curlp);
// * Set curl handle options
curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts
@ -436,7 +439,7 @@ static LLSD blocking_request(
curl_easy_setopt(curlp, CURLOPT_WRITEDATA, &http_buffer);
curl_easy_setopt(curlp, CURLOPT_URL, url.c_str());
curl_easy_setopt(curlp, CURLOPT_ERRORBUFFER, curl_error_buffer);
// * Setup headers (don't forget to free them after the call!)
curl_slist* headers_list = NULL;
if (headers.isMap())

View File

@ -251,10 +251,12 @@ LLSocket::~LLSocket()
{
ll_debug_socket("Destroying socket", mSocket);
apr_socket_close(mSocket);
mSocket = NULL;
}
if(mPool)
{
apr_pool_destroy(mPool);
mPool = NULL;
}
}

View File

@ -145,13 +145,6 @@ public:
*/
apr_socket_t* getSocket() const { return mSocket; }
protected:
/**
* @brief Protected constructor since should only make sockets
* with one of the two <code>create()</code> calls.
*/
LLSocket(apr_socket_t* socket, apr_pool_t* pool);
/**
* @brief Set default socket options, with SO_NONBLOCK = 0 and a timeout in us.
* @param timeout Number of microseconds to wait on this socket. Any
@ -164,6 +157,13 @@ protected:
*/
void setNonBlocking();
protected:
/**
* @brief Protected constructor since should only make sockets
* with one of the two <code>create()</code> calls.
*/
LLSocket(apr_socket_t* socket, apr_pool_t* pool);
public:
/**
* @brief Do not call this directly.

View File

@ -28,11 +28,20 @@
#include "llpacketring.h"
#if LL_WINDOWS
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#endif
// linden library includes
#include "llerror.h"
#include "lltimer.h"
#include "timing.h"
#include "llproxy.h"
#include "llrand.h"
#include "message.h"
#include "timing.h"
#include "u64.h"
///////////////////////////////////////////////////////////
@ -216,8 +225,32 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
else
{
// no delay, pull straight from net
packet_size = receive_packet(socket, datap);
mLastSender = ::get_sender();
if (LLProxy::isSOCKSProxyEnabled())
{
U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
packet_size = receive_packet(socket, reinterpret_cast<char *>(buffer));
if (packet_size > SOCKS_HEADER_SIZE)
{
// *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE);
proxywrap_t * header = reinterpret_cast<proxywrap_t *>(buffer);
mLastSender.setAddress(header->addr);
mLastSender.setPort(ntohs(header->port));
packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size
}
else
{
packet_size = 0;
}
}
else
{
packet_size = receive_packet(socket, datap);
mLastSender = ::get_sender();
}
mLastReceivingIF = ::get_receiving_interface();
if (packet_size) // did we actually get a packet?
@ -243,7 +276,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
BOOL status = TRUE;
if (!mUseOutThrottle)
{
return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() );
return sendPacketImpl(h_socket, send_buffer, buf_size, host );
}
else
{
@ -264,7 +297,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
mOutBufferLength -= packetp->getSize();
packet_size = packetp->getSize();
status = send_packet(h_socket, packetp->getData(), packet_size, packetp->getHost().getAddress(), packetp->getHost().getPort());
status = sendPacketImpl(h_socket, packetp->getData(), packet_size, packetp->getHost());
delete packetp;
// Update the throttle
@ -273,7 +306,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
else
{
// If the queue's empty, we can just send this packet right away.
status = send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() );
status = sendPacketImpl(h_socket, send_buffer, buf_size, host );
packet_size = buf_size;
// Update the throttle
@ -311,3 +344,23 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
return status;
}
BOOL LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host)
{
if (!LLProxy::isSOCKSProxyEnabled())
{
return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
}
proxywrap_t *socks_header = reinterpret_cast<proxywrap_t *>(&mProxyWrappedSendBuffer);
socks_header->rsv = 0;
socks_header->addr = host.getAddress();
socks_header->port = htons(host.getPort());
socks_header->atype = ADDRESS_IPV4;
socks_header->frag = 0;
memcpy(mProxyWrappedSendBuffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
return send_packet(h_socket, (const char*) mProxyWrappedSendBuffer, buf_size + 10, LLProxy::getInstance()->getUDPProxy().getAddress(), LLProxy::getInstance()->getUDPProxy().getPort());
}

View File

@ -30,11 +30,11 @@
#include <queue>
#include "llpacketbuffer.h"
#include "llhost.h"
#include "net.h"
#include "llpacketbuffer.h"
#include "llproxy.h"
#include "llthrottle.h"
#include "net.h"
class LLPacketRing
{
@ -82,6 +82,12 @@ protected:
LLHost mLastSender;
LLHost mLastReceivingIF;
U8 mProxyWrappedSendBuffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
private:
BOOL sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
};

551
indra/llmessage/llproxy.cpp Normal file
View File

@ -0,0 +1,551 @@
/**
* @file llproxy.cpp
* @brief UDP and HTTP proxy communications
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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 "linden_common.h"
#include "llproxy.h"
#include <string>
#include <curl/curl.h>
#include "llapr.h"
#include "llcurl.h"
#include "llhost.h"
// Static class variable instances
// We want this to be static to avoid excessive indirection on every
// incoming packet just to do a simple bool test. The getter for this
// member is also static
bool LLProxy::sUDPProxyEnabled = false;
// Some helpful TCP static functions.
static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host); // Open a TCP channel to a given host
static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel
LLProxy::LLProxy():
mHTTPProxyEnabled(false),
mProxyMutex(0),
mUDPProxy(),
mTCPProxy(),
mPool(gAPRPoolp),
mHTTPProxy(),
mProxyType(LLPROXY_SOCKS),
mAuthMethodSelected(METHOD_NOAUTH),
mSocksUsername(),
mSocksPassword()
{
}
LLProxy::~LLProxy()
{
stopSOCKSProxy();
sUDPProxyEnabled = false;
mHTTPProxyEnabled = false;
}
/**
* @brief Open the SOCKS 5 TCP control channel.
*
* Perform a SOCKS 5 authentication and UDP association to the proxy server.
*
* @param proxy The SOCKS 5 server to connect to.
* @return SOCKS_OK if successful, otherwise a socks error code from llproxy.h.
*/
S32 LLProxy::proxyHandshake(LLHost proxy)
{
S32 result;
/* SOCKS 5 Auth request */
socks_auth_request_t socks_auth_request;
socks_auth_response_t socks_auth_response;
socks_auth_request.version = SOCKS_VERSION; // SOCKS version 5
socks_auth_request.num_methods = 1; // Sending 1 method.
socks_auth_request.methods = getSelectedAuthMethod(); // Send only the selected method.
result = tcp_handshake(mProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request), (char*)&socks_auth_response, sizeof(socks_auth_response));
if (result != APR_SUCCESS)
{
LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL;
stopSOCKSProxy();
return SOCKS_CONNECT_ERROR;
}
if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE)
{
LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods" << LL_ENDL;
stopSOCKSProxy();
return SOCKS_NOT_ACCEPTABLE;
}
// SOCKS 5 USERNAME/PASSWORD authentication
if (socks_auth_response.method == METHOD_PASSWORD)
{
// The server has requested a username/password combination
std::string socks_username(getSocksUser());
std::string socks_password(getSocksPwd());
U32 request_size = socks_username.size() + socks_password.size() + 3;
char * password_auth = new char[request_size];
password_auth[0] = 0x01;
password_auth[1] = socks_username.size();
memcpy(&password_auth[2], socks_username.c_str(), socks_username.size());
password_auth[socks_username.size() + 2] = socks_password.size();
memcpy(&password_auth[socks_username.size()+3], socks_password.c_str(), socks_password.size());
authmethod_password_reply_t password_reply;
result = tcp_handshake(mProxyControlChannel, password_auth, request_size, (char*)&password_reply, sizeof(password_reply));
delete[] password_auth;
if (result != APR_SUCCESS)
{
LL_WARNS("Proxy") << "SOCKS authentication failed, error on TCP control channel : " << result << LL_ENDL;
stopSOCKSProxy();
return SOCKS_CONNECT_ERROR;
}
if (password_reply.status != AUTH_SUCCESS)
{
LL_WARNS("Proxy") << "SOCKS authentication failed" << LL_ENDL;
stopSOCKSProxy();
return SOCKS_AUTH_FAIL;
}
}
/* SOCKS5 connect request */
socks_command_request_t connect_request;
socks_command_response_t connect_reply;
connect_request.version = SOCKS_VERSION; // SOCKS V5
connect_request.command = COMMAND_UDP_ASSOCIATE; // Associate UDP
connect_request.reserved = FIELD_RESERVED;
connect_request.atype = ADDRESS_IPV4;
connect_request.address = htonl(0); // 0.0.0.0
connect_request.port = htons(0); // 0
// "If the client is not in possession of the information at the time of the UDP ASSOCIATE,
// the client MUST use a port number and address of all zeros. RFC 1928"
result = tcp_handshake(mProxyControlChannel, (char*)&connect_request, sizeof(connect_request), (char*)&connect_reply, sizeof(connect_reply));
if (result != APR_SUCCESS)
{
LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL;
stopSOCKSProxy();
return SOCKS_CONNECT_ERROR;
}
if (connect_reply.reply != REPLY_REQUEST_GRANTED)
{
LL_WARNS("Proxy") << "Connection to SOCKS 5 server failed, UDP forward request not granted" << LL_ENDL;
stopSOCKSProxy();
return SOCKS_UDP_FWD_NOT_GRANTED;
}
mUDPProxy.setPort(ntohs(connect_reply.port)); // reply port is in network byte order
mUDPProxy.setAddress(proxy.getAddress());
// The connection was successful. We now have the UDP port to send requests that need forwarding to.
LL_INFOS("Proxy") << "SOCKS 5 UDP proxy connected on " << mUDPProxy << LL_ENDL;
return SOCKS_OK;
}
/**
* @brief Initiates a SOCKS 5 proxy session.
*
* Performs basic checks on host to verify that it is a valid address. Opens the control channel
* and then negotiates the proxy connection with the server.
*
*
* @param host Socks server to connect to.
* @return SOCKS_OK if successful, otherwise a SOCKS error code defined in llproxy.h.
*/
S32 LLProxy::startSOCKSProxy(LLHost host)
{
S32 status = SOCKS_OK;
if (host.isOk())
{
mTCPProxy = host;
}
else
{
status = SOCKS_INVALID_HOST;
}
if (mProxyControlChannel && status == SOCKS_OK)
{
tcp_close_channel(&mProxyControlChannel);
}
if (status == SOCKS_OK)
{
mProxyControlChannel = tcp_open_channel(mPool, mTCPProxy);
if (!mProxyControlChannel)
{
status = SOCKS_HOST_CONNECT_FAILED;
}
}
if (status == SOCKS_OK)
{
status = proxyHandshake(mTCPProxy);
}
if (status == SOCKS_OK)
{
sUDPProxyEnabled = true;
}
else
{
stopSOCKSProxy();
}
return status;
}
/**
* @brief Stop using the SOCKS 5 proxy.
*
* This will stop sending UDP packets through the SOCKS 5 proxy
* and will also stop the HTTP proxy if it is configured to use SOCKS.
* The proxy control channel will also be disconnected.
*/
void LLProxy::stopSOCKSProxy()
{
sUDPProxyEnabled = false;
// If the SOCKS proxy is requested to stop and we are using that for HTTP as well
// then we must shut down any HTTP proxy operations. But it is allowable if web
// proxy is being used to continue proxying HTTP.
if (LLPROXY_SOCKS == getHTTPProxyType())
{
void disableHTTPProxy();
}
if (mProxyControlChannel)
{
tcp_close_channel(&mProxyControlChannel);
}
}
/**
* @brief Set the proxy's SOCKS authentication method to none.
*/
void LLProxy::setAuthNone()
{
LLMutexLock lock(&mProxyMutex);
mAuthMethodSelected = METHOD_NOAUTH;
}
/**
* @brief Set the proxy's SOCKS authentication method to password.
*
* Check whether the lengths of the supplied username
* and password conform to the lengths allowed by the
* SOCKS protocol.
*
* @param username The SOCKS username to send.
* @param password The SOCKS password to send.
* @return Return true if applying the settings was successful. No changes are made if false.
*
*/
bool LLProxy::setAuthPassword(const std::string &username, const std::string &password)
{
if (username.length() > SOCKSMAXUSERNAMELEN || password.length() > SOCKSMAXPASSWORDLEN ||
username.length() < SOCKSMINUSERNAMELEN || password.length() < SOCKSMINPASSWORDLEN)
{
LL_WARNS("Proxy") << "Invalid SOCKS 5 password or username length." << LL_ENDL;
return false;
}
LLMutexLock lock(&mProxyMutex);
mAuthMethodSelected = METHOD_PASSWORD;
mSocksUsername = username;
mSocksPassword = password;
return true;
}
/**
* @brief Enable the HTTP proxy for either SOCKS or HTTP.
*
* Check the supplied host to see if it is a valid IP and port.
*
* @param httpHost Proxy server to connect to.
* @param type Is the host a SOCKS or HTTP proxy.
* @return Return true if applying the setting was successful. No changes are made if false.
*/
bool LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type)
{
if (!httpHost.isOk())
{
LL_WARNS("Proxy") << "Invalid SOCKS 5 Server" << LL_ENDL;
return false;
}
LLMutexLock lock(&mProxyMutex);
mHTTPProxy = httpHost;
mProxyType = type;
mHTTPProxyEnabled = true;
return true;
}
/**
* @brief Enable the HTTP proxy without changing the proxy settings.
*
* This should not be called unless the proxy has already been set up.
*
* @return Return true only if the current settings are valid and the proxy was enabled.
*/
bool LLProxy::enableHTTPProxy()
{
bool ok;
LLMutexLock lock(&mProxyMutex);
ok = (mHTTPProxy.isOk());
if (ok)
{
mHTTPProxyEnabled = true;
}
return ok;
}
/**
* @brief Disable the HTTP proxy.
*/
void LLProxy::disableHTTPProxy()
{
LLMutexLock lock(&mProxyMutex);
mHTTPProxyEnabled = false;
}
/**
* @brief Get the HTTP proxy address and port
*/
//
LLHost LLProxy::getHTTPProxy() const
{
LLMutexLock lock(&mProxyMutex);
return mHTTPProxy;
}
/**
* @brief Get the currently selected HTTP proxy type
*/
LLHttpProxyType LLProxy::getHTTPProxyType() const
{
LLMutexLock lock(&mProxyMutex);
return mProxyType;
}
/**
* @brief Get the SOCKS 5 password.
*/
std::string LLProxy::getSocksPwd() const
{
LLMutexLock lock(&mProxyMutex);
return mSocksPassword;
}
/**
* @brief Get the SOCKS 5 username.
*/
std::string LLProxy::getSocksUser() const
{
LLMutexLock lock(&mProxyMutex);
return mSocksUsername;
}
/**
* @brief Get the currently selected SOCKS 5 authentication method.
*
* @return Returns either none or password.
*/
LLSocks5AuthType LLProxy::getSelectedAuthMethod() const
{
LLMutexLock lock(&mProxyMutex);
return mAuthMethodSelected;
}
/**
* @brief Stop the LLProxy and make certain that any APR pools and classes are deleted before terminating APR.
*
* Deletes the LLProxy singleton, destroying the APR pool used by the control channel as well as .
*/
//static
void LLProxy::cleanupClass()
{
getInstance()->stopSOCKSProxy();
deleteSingleton();
}
void LLProxy::applyProxySettings(LLCurlEasyRequest* handle)
{
applyProxySettings(handle->getEasy());
}
void LLProxy::applyProxySettings(LLCurl::Easy* handle)
{
applyProxySettings(handle->getCurlHandle());
}
/**
* @brief Apply proxy settings to a CuRL request if an HTTP proxy is enabled.
*
* This method has been designed to be safe to call from
* any thread in the viewer. This allows requests in the
* texture fetch thread to be aware of the proxy settings.
* When the HTTP proxy is enabled, the proxy mutex will
* be locked every time this method is called.
*
* @param handle A pointer to a valid CURL request, before it has been performed.
*/
void LLProxy::applyProxySettings(CURL* handle)
{
// Do a faster unlocked check to see if we are supposed to proxy.
if (mHTTPProxyEnabled)
{
// We think we should proxy, lock the proxy mutex.
LLMutexLock lock(&mProxyMutex);
// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
if (mHTTPProxyEnabled)
{
check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
if (mProxyType == LLPROXY_SOCKS)
{
check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
if (mAuthMethodSelected == METHOD_PASSWORD)
{
std::string auth_string = mSocksUsername + ":" + mSocksPassword;
check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
}
}
else
{
check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
}
}
}
}
/**
* @brief Send one TCP packet and receive one in return.
*
* This operation is done synchronously with a 1000ms timeout. Therefore, it should not be used when a blocking
* operation would impact the operation of the viewer.
*
* @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP.
* @param dataout Data to send.
* @param outlen Length of dataout.
* @param datain Buffer for received data. Undefined if return value is not APR_SUCCESS.
* @param maxinlen Maximum possible length of received data. Short reads are allowed.
* @return Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received.
*/
static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
{
apr_socket_t* apr_socket = handle->getSocket();
apr_status_t rv = APR_SUCCESS;
apr_size_t expected_len = outlen;
handle->setBlocking(1000);
rv = apr_socket_send(apr_socket, dataout, &outlen);
if (APR_SUCCESS != rv)
{
LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << LL_ENDL;
ll_apr_warn_status(rv);
}
else if (expected_len != outlen)
{
LL_WARNS("Proxy") << "Incorrect data length sent. Expected: " << expected_len <<
" Sent: " << outlen << LL_ENDL;
rv = -1;
}
if (APR_SUCCESS == rv)
{
expected_len = maxinlen;
rv = apr_socket_recv(apr_socket, datain, &maxinlen);
if (rv != APR_SUCCESS)
{
LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << LL_ENDL;
ll_apr_warn_status(rv);
}
else if (expected_len < maxinlen)
{
LL_WARNS("Proxy") << "Incorrect data length received. Expected: " << expected_len <<
" Received: " << maxinlen << LL_ENDL;
rv = -1;
}
}
handle->setNonBlocking();
return rv;
}
/**
* @brief Open a LLSocket and do a blocking connect to the chosen host.
*
* Checks for a successful connection, and makes sure the connection is closed if it fails.
*
* @param pool APR pool to pass into the LLSocket.
* @param host The host to open the connection to.
* @return The created socket. Will evaluate as NULL if the connection is unsuccessful.
*/
static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host)
{
LLSocket::ptr_t socket = LLSocket::create(pool, LLSocket::STREAM_TCP);
bool connected = socket->blockingConnect(host);
if (!connected)
{
tcp_close_channel(&socket);
}
return socket;
}
/**
* @brief Close the socket.
*
* @param handle_ptr A pointer-to-pointer to avoid increasing the use count.
*/
static void tcp_close_channel(LLSocket::ptr_t* handle_ptr)
{
LL_DEBUGS("Proxy") << "Resetting proxy LLSocket handle, use_count == " << handle_ptr->use_count() << LL_ENDL;
handle_ptr->reset();
}

342
indra/llmessage/llproxy.h Normal file
View File

@ -0,0 +1,342 @@
/**
* @file llproxy.h
* @brief UDP and HTTP proxy communications
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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_PROXY_H
#define LL_PROXY_H
#include "llcurl.h"
#include "llhost.h"
#include "lliosocket.h"
#include "llmemory.h"
#include "llsingleton.h"
#include "llthread.h"
#include <string>
// SOCKS error codes returned from the StartProxy method
#define SOCKS_OK 0
#define SOCKS_CONNECT_ERROR (-1)
#define SOCKS_NOT_PERMITTED (-2)
#define SOCKS_NOT_ACCEPTABLE (-3)
#define SOCKS_AUTH_FAIL (-4)
#define SOCKS_UDP_FWD_NOT_GRANTED (-5)
#define SOCKS_HOST_CONNECT_FAILED (-6)
#define SOCKS_INVALID_HOST (-7)
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */
#endif
#define SOCKSMAXUSERNAMELEN 255
#define SOCKSMAXPASSWORDLEN 255
#define SOCKSMINUSERNAMELEN 1
#define SOCKSMINPASSWORDLEN 1
#define SOCKS_VERSION 0x05 // we are using SOCKS 5
#define SOCKS_HEADER_SIZE 10
// SOCKS 5 address/hostname types
#define ADDRESS_IPV4 0x01
#define ADDRESS_HOSTNAME 0x03
#define ADDRESS_IPV6 0x04
// Lets just use our own ipv4 struct rather than dragging in system
// specific headers
union ipv4_address_t {
U8 octets[4];
U32 addr32;
};
// SOCKS 5 control channel commands
#define COMMAND_TCP_STREAM 0x01
#define COMMAND_TCP_BIND 0x02
#define COMMAND_UDP_ASSOCIATE 0x03
// SOCKS 5 command replies
#define REPLY_REQUEST_GRANTED 0x00
#define REPLY_GENERAL_FAIL 0x01
#define REPLY_RULESET_FAIL 0x02
#define REPLY_NETWORK_UNREACHABLE 0x03
#define REPLY_HOST_UNREACHABLE 0x04
#define REPLY_CONNECTION_REFUSED 0x05
#define REPLY_TTL_EXPIRED 0x06
#define REPLY_PROTOCOL_ERROR 0x07
#define REPLY_TYPE_NOT_SUPPORTED 0x08
#define FIELD_RESERVED 0x00
// The standard SOCKS 5 request packet
// Push current alignment to stack and set alignment to 1 byte boundary
// This enabled us to use structs directly to set up and receive network packets
// into the correct fields, without fear of boundary alignment causing issues
#pragma pack(push,1)
// SOCKS 5 command packet
struct socks_command_request_t {
U8 version;
U8 command;
U8 reserved;
U8 atype;
U32 address;
U16 port;
};
// Standard SOCKS 5 reply packet
struct socks_command_response_t {
U8 version;
U8 reply;
U8 reserved;
U8 atype;
U8 add_bytes[4];
U16 port;
};
#define AUTH_NOT_ACCEPTABLE 0xFF // reply if preferred methods are not available
#define AUTH_SUCCESS 0x00 // reply if authentication successful
// SOCKS 5 authentication request, stating which methods the client supports
struct socks_auth_request_t {
U8 version;
U8 num_methods;
U8 methods; // We are only using a single method currently
};
// SOCKS 5 authentication response packet, stating server preferred method
struct socks_auth_response_t {
U8 version;
U8 method;
};
// SOCKS 5 password reply packet
struct authmethod_password_reply_t {
U8 version;
U8 status;
};
// SOCKS 5 UDP packet header
struct proxywrap_t {
U16 rsv;
U8 frag;
U8 atype;
U32 addr;
U16 port;
};
#pragma pack(pop) /* restore original alignment from stack */
// Currently selected HTTP proxy type
enum LLHttpProxyType
{
LLPROXY_SOCKS = 0,
LLPROXY_HTTP = 1
};
// Auth types
enum LLSocks5AuthType
{
METHOD_NOAUTH = 0x00, // Client supports no auth
METHOD_GSSAPI = 0x01, // Client supports GSSAPI (Not currently supported)
METHOD_PASSWORD = 0x02 // Client supports username/password
};
/**
* @brief Manage SOCKS 5 UDP proxy and HTTP proxy.
*
* This class is responsible for managing two interconnected tasks,
* connecting to a SOCKS 5 proxy for use by LLPacketRing to send UDP
* packets and managing proxy settings for HTTP requests.
*
* <h1>Threading:</h1>
* Because HTTP requests can be generated in threads outside the
* main thread, it is necessary for some of the information stored
* by this class to be available to other threads. The members that
* need to be read across threads are in a labeled section below.
* To protect those members, a mutex, mProxyMutex should be locked
* before reading or writing those members. Methods that can lock
* mProxyMutex are in a labeled section below. Those methods should
* not be called while the mutex is already locked.
*
* There is also a LLAtomic type flag (mHTTPProxyEnabled) that is used
* to track whether the HTTP proxy is currently enabled. This allows
* for faster unlocked checks to see if the proxy is enabled. This
* allows us to cut down on the performance hit when the proxy is
* disabled compared to before this class was introduced.
*
* <h1>UDP Proxying:</h1>
* UDP datagrams are proxied via a SOCKS 5 proxy with the UDP associate
* command. To initiate the proxy, a TCP socket connection is opened
* to the SOCKS 5 host, and after a handshake exchange, the server
* returns a port and address to send the UDP traffic that is to be
* proxied to. The LLProxy class tracks this address and port after the
* exchange and provides it to LLPacketRing when required to. All UDP
* proxy management occurs in the main thread.
*
* <h1>HTTP Proxying:</h1>
* This class allows all viewer HTTP packets to be sent through a proxy.
* The user can select whether to send HTTP packets through a standard
* "web" HTTP proxy, through a SOCKS 5 proxy, or to not proxy HTTP
* communication. This class does not manage the integrated web browser
* proxy, which is handled in llviewermedia.cpp.
*
* The implementation of HTTP proxying is handled by libcurl. LLProxy
* is responsible for managing the HTTP proxy options and provides a
* thread-safe method to apply those options to a curl request
* (LLProxy::applyProxySettings()). This method is overloaded
* to accommodate the various abstraction libcurl layers that exist
* throughout the viewer (LLCurlEasyRequest, LLCurl::Easy, and CURL).
*
* If you are working with LLCurl or LLCurlEasyRequest objects,
* the configured proxy settings will be applied in the constructors
* of those request handles. If you are working with CURL objects
* directly, you will need to pass the handle of the request to
* applyProxySettings() before issuing the request.
*
* To ensure thread safety, all LLProxy members that relate to the HTTP
* proxy require the LLProxyMutex to be locked before accessing.
*/
class LLProxy: public LLSingleton<LLProxy>
{
LOG_CLASS(LLProxy);
public:
// METHODS THAT DO NOT LOCK mProxyMutex!
LLProxy();
// static check for enabled status for UDP packets
static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
// check for enabled status for HTTP packets
// mHTTPProxyEnabled is atomic, so no locking is required for thread safety.
bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; }
// Get the UDP proxy address and port
LLHost getUDPProxy() const { return mUDPProxy; }
// Get the SOCKS 5 TCP control channel address and port
LLHost getTCPProxy() const { return mTCPProxy; }
// END OF NON-LOCKING METHODS
// METHODS THAT DO LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
~LLProxy();
// Start a connection to the SOCKS 5 proxy
S32 startSOCKSProxy(LLHost host);
// Disconnect and clean up any connection to the SOCKS 5 proxy
void stopSOCKSProxy();
// Delete LLProxy singleton, destroying the APR pool used by the control channel.
static void cleanupClass();
// Set up to use Password auth when connecting to the SOCKS proxy
bool setAuthPassword(const std::string &username, const std::string &password);
// Set up to use No Auth when connecting to the SOCKS proxy
void setAuthNone();
// Get the currently selected auth method.
LLSocks5AuthType getSelectedAuthMethod() const;
// Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy
// as specified in type
bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type);
bool enableHTTPProxy();
// Stop proxying HTTP packets
void disableHTTPProxy();
// Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
void applyProxySettings(CURL* handle);
void applyProxySettings(LLCurl::Easy* handle);
void applyProxySettings(LLCurlEasyRequest* handle);
// Get the HTTP proxy address and port
LLHost getHTTPProxy() const;
// Get the currently selected HTTP proxy type
LLHttpProxyType getHTTPProxyType() const;
std::string getSocksPwd() const;
std::string getSocksUser() const;
// END OF LOCKING METHODS
private:
// Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort
S32 proxyHandshake(LLHost proxy);
private:
// Is the HTTP proxy enabled?
// Safe to read in any thread, do not write directly,
// use enableHTTPProxy() and disableHTTPProxy() instead.
mutable LLAtomic32<bool> mHTTPProxyEnabled;
// Mutex to protect shared members in non-main thread calls to applyProxySettings()
mutable LLMutex mProxyMutex;
// MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE!
// Is the UDP proxy enabled?
static bool sUDPProxyEnabled;
// UDP proxy address and port
LLHost mUDPProxy;
// TCP proxy control channel address and port
LLHost mTCPProxy;
// socket handle to proxy TCP control channel
LLSocket::ptr_t mProxyControlChannel;
// APR pool for the socket
apr_pool_t* mPool;
// END OF UNSHARED MEMBERS
// MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex!
// HTTP proxy address and port
LLHost mHTTPProxy;
// Currently selected HTTP proxy type. Can be web or socks.
LLHttpProxyType mProxyType;
// SOCKS 5 auth method selected
LLSocks5AuthType mAuthMethodSelected;
// SOCKS 5 username
std::string mSocksUsername;
// SOCKS 5 password
std::string mSocksPassword;
// END OF SHARED MEMBERS
};
#endif

View File

@ -35,6 +35,7 @@
#include "llcurl.h"
#include "llioutil.h"
#include "llmemtype.h"
#include "llproxy.h"
#include "llpumpio.h"
#include "llsd.h"
#include "llstring.h"
@ -227,8 +228,7 @@ void LLURLRequest::useProxy(bool use_proxy)
}
}
lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl;
LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << LL_ENDL;
if (env_proxy && use_proxy)
{

View File

@ -50,7 +50,6 @@
#include "lltimer.h"
#include "indra_constants.h"
// Globals
#if LL_WINDOWS
@ -174,7 +173,7 @@ U32 ip_string_to_u32(const char* ip_string)
// use wildcard addresses. -Ambroff
U32 ip = inet_addr(ip_string);
if (ip == INADDR_NONE
&& strncmp(ip_string, BROADCAST_ADDRESS_STRING, MAXADDRSTR) != 0)
&& strncmp(ip_string, BROADCAST_ADDRESS_STRING, MAXADDRSTR) != 0)
{
llwarns << "ip_string_to_u32() failed, Error: Invalid IP string '" << ip_string << "'" << llendl;
return INVALID_HOST_IP_ADDRESS;
@ -188,11 +187,11 @@ U32 ip_string_to_u32(const char* ip_string)
//////////////////////////////////////////////////////////////////////////////////////////
#if LL_WINDOWS
S32 start_net(S32& socket_out, int& nPort)
{
// Create socket, make non-blocking
// Init WinSock
// Init WinSock
int nRet;
int hSocket;
@ -201,7 +200,7 @@ S32 start_net(S32& socket_out, int& nPort)
int buff_size = 4;
// Initialize windows specific stuff
if(WSAStartup(0x0202, &stWSAData))
if (WSAStartup(0x0202, &stWSAData))
{
S32 err = WSAGetLastError();
WSACleanup();
@ -210,8 +209,8 @@ S32 start_net(S32& socket_out, int& nPort)
}
// Get a datagram socket
hSocket = (int)socket(AF_INET, SOCK_DGRAM, 0);
if (hSocket == INVALID_SOCKET)
hSocket = (int)socket(AF_INET, SOCK_DGRAM, 0);
if (hSocket == INVALID_SOCKET)
{
S32 err = WSAGetLastError();
WSACleanup();
@ -304,7 +303,7 @@ S32 start_net(S32& socket_out, int& nPort)
// Setup a destination address
stDstAddr.sin_family = AF_INET;
stDstAddr.sin_addr.s_addr = INVALID_HOST_IP_ADDRESS;
stDstAddr.sin_port = htons(nPort);
stDstAddr.sin_port = htons(nPort);
socket_out = hSocket;
return 0;
@ -393,10 +392,10 @@ S32 start_net(S32& socket_out, int& nPort)
int rec_size = RECEIVE_BUFFER_SIZE;
socklen_t buff_size = 4;
// Create socket
hSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (hSocket < 0)
hSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (hSocket < 0)
{
llwarns << "socket() failed" << llendl;
return 1;
@ -429,7 +428,7 @@ S32 start_net(S32& socket_out, int& nPort)
}
else
{
// Name the socket (assign the local port number to receive on)
// Name the socket (assign the local port number to receive on)
stLclAddr.sin_family = AF_INET;
stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
stLclAddr.sin_port = htons(nPort);
@ -474,7 +473,7 @@ S32 start_net(S32& socket_out, int& nPort)
nPort = attempt_port;
}
// Set socket to be non-blocking
fcntl(hSocket, F_SETFL, O_NONBLOCK);
fcntl(hSocket, F_SETFL, O_NONBLOCK);
// set a large receive buffer
nRet = setsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, buff_size);
if (nRet)
@ -510,8 +509,8 @@ S32 start_net(S32& socket_out, int& nPort)
// Setup a destination address
char achMCAddr[MAXADDRSTR] = "127.0.0.1"; /* Flawfinder: ignore */
stDstAddr.sin_family = AF_INET;
stDstAddr.sin_addr.s_addr = ip_string_to_u32(achMCAddr);
stDstAddr.sin_port = htons(nPort);
stDstAddr.sin_addr.s_addr = ip_string_to_u32(achMCAddr);
stDstAddr.sin_port = htons(nPort);
socket_out = hSocket;
return 0;
@ -537,7 +536,7 @@ static int recvfrom_destip( int socket, void *buf, int len, struct sockaddr *fro
iov[0].iov_base = buf;
iov[0].iov_len = len;
memset( &msg, 0, sizeof msg );
memset(&msg, 0, sizeof msg);
msg.msg_name = from;
msg.msg_namelen = *fromlen;
msg.msg_iov = iov;
@ -545,14 +544,14 @@ static int recvfrom_destip( int socket, void *buf, int len, struct sockaddr *fro
msg.msg_control = &cmsg;
msg.msg_controllen = sizeof(cmsg);
size = recvmsg( socket, &msg, 0 );
size = recvmsg(socket, &msg, 0);
if( size == -1 )
if (size == -1)
{
return -1;
}
for( cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR( &msg, cmsgptr ) )
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR( &msg, cmsgptr))
{
if( cmsgptr->cmsg_level == SOL_IP && cmsgptr->cmsg_type == IP_PKTINFO )
{
@ -650,7 +649,7 @@ BOOL send_packet(int hSocket, const char * sendBuffer, int size, U32 recipient,
}
}
}
while ( resend && send_attempts < 3);
while (resend && send_attempts < 3);
if (send_attempts >= 3)
{

View File

@ -46,10 +46,10 @@ S32 receive_packet(int hSocket, char * receiveBuffer);
BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, int nPort); // Returns TRUE on success.
//void get_sender(char * tmp);
LLHost get_sender();
LLHost get_sender();
U32 get_sender_port();
U32 get_sender_ip(void);
LLHost get_receiving_interface();
LLHost get_receiving_interface();
U32 get_receiving_interface_ip(void);
const char* u32_to_ip_string(U32 ip); // Returns pointer to internal string buffer, "(bad IP addr)" on failure, cannot nest calls

File diff suppressed because it is too large Load Diff

View File

@ -41,16 +41,16 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
LOG_CLASS(LLPluginClassMedia);
public:
LLPluginClassMedia(LLPluginClassMediaOwner *owner);
virtual ~LLPluginClassMedia();
~LLPluginClassMedia();
// local initialization, called by the media manager when creating a source
virtual bool init(const std::string &launcher_filename,
bool init(const std::string &launcher_filename,
const std::string &plugin_dir,
const std::string &plugin_filename,
bool debug);
// undoes everything init() didm called by the media manager when destroying a source
virtual void reset();
void reset();
void idle(void);
@ -118,6 +118,9 @@ public:
void scrollEvent(int x, int y, MASK modifiers);
// enable/disable media plugin debugging messages and info spam
void enableMediaPluginDebugging( bool enable );
// Javascript <-> viewer events
void jsEnableObject( bool enable );
void jsAgentLocationEvent( double x, double y, double z );
@ -209,6 +212,7 @@ public:
void browse_forward();
void browse_back();
void setBrowserUserAgent(const std::string& user_agent);
void showWebInspector( bool show );
void proxyWindowOpened(const std::string &target, const std::string &uuid);
void proxyWindowClosed(const std::string &uuid);
void ignore_ssl_cert_errors(bool ignore);
@ -244,6 +248,10 @@ public:
// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
std::string getClickUUID() const { return mClickUUID; };
// These are valid during MEDIA_EVENT_DEBUG_MESSAGE
std::string getDebugMessageText() const { return mDebugMessageText; };
std::string getDebugMessageLevel() const { return mDebugMessageLevel; };
// This is valid after MEDIA_EVENT_NAVIGATE_ERROR_PAGE
S32 getStatusCode() const { return mStatusCode; };
@ -395,6 +403,8 @@ protected:
std::string mClickNavType;
std::string mClickTarget;
std::string mClickUUID;
std::string mDebugMessageText;
std::string mDebugMessageLevel;
S32 mGeometryX;
S32 mGeometryY;
S32 mGeometryWidth;

View File

@ -64,6 +64,8 @@ public:
MEDIA_EVENT_AUTH_REQUEST, // The plugin wants to display an auth dialog
MEDIA_EVENT_DEBUG_MESSAGE, // plugin sending back debug information for host to process
MEDIA_EVENT_LINK_HOVERED // Got a "link hovered" event from the plugin
} EMediaEvent;

View File

@ -39,7 +39,7 @@
class LLPluginInstanceMessageListener
{
public:
virtual ~LLPluginInstanceMessageListener();
~LLPluginInstanceMessageListener();
/** Plugin receives message from plugin loader shell. */
virtual void receivePluginMessage(const std::string &message) = 0;
};

View File

@ -40,7 +40,8 @@ class LLPluginMessagePipeOwner
LOG_CLASS(LLPluginMessagePipeOwner);
public:
LLPluginMessagePipeOwner();
virtual ~LLPluginMessagePipeOwner();
~LLPluginMessagePipeOwner();
// called with incoming messages
virtual void receiveMessageRaw(const std::string &message) = 0;
// called when the socket has an error

View File

@ -41,7 +41,7 @@
class LLPluginProcessParentOwner
{
public:
virtual ~LLPluginProcessParentOwner();
~LLPluginProcessParentOwner();
virtual void receivePluginMessage(const LLPluginMessage &message) = 0;
virtual bool receivePluginMessageEarly(const LLPluginMessage &message) {return false;};
// This will only be called when the plugin has died unexpectedly

View File

@ -48,6 +48,7 @@
#include "llstacktrace.h"
#include "llglheaders.h"
#include "llglslshader.h"
#ifdef _DEBUG
//#define GL_STATE_VERIFY
@ -1781,6 +1782,16 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
LLGLState::LLGLState(LLGLenum state, S32 enabled) :
mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
{
if (LLGLSLShader::sNoFixedFunction)
{ //always disable state that's deprecated post GL 3.0
switch (state)
{
case GL_ALPHA_TEST:
enabled = 0;
break;
}
}
stop_glerror();
if (state)
{

View File

@ -49,6 +49,7 @@ using std::make_pair;
using std::string;
GLhandleARB LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
bool LLGLSLShader::sNoFixedFunction = false;
//UI shader -- declared here so llui_libtest will link properly
@ -63,7 +64,8 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
LLShaderFeatures::LLShaderFeatures()
: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false)
hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false),
hasAlphaMask(false)
{
}
@ -386,6 +388,7 @@ void LLGLSLShader::bind()
{
glUseProgramObjectARB(mProgramObject);
sCurBoundShader = mProgramObject;
sCurBoundShaderPtr = this;
if (mUniformsDirty)
{
LLShaderMgr::instance()->updateShaderUniforms(this);
@ -410,6 +413,7 @@ void LLGLSLShader::unbind()
}
glUseProgramObjectARB(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
stop_glerror();
}
}
@ -418,6 +422,7 @@ void LLGLSLShader::bindNoShader(void)
{
glUseProgramObjectARB(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
}
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
@ -979,3 +984,9 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
glVertexAttrib4fvARB(mAttribute[index], v);
}
}
void LLGLSLShader::setAlphaRange(F32 minimum, F32 maximum)
{
uniform1f("minimum_alpha", minimum);
uniform1f("maximum_alpha", maximum);
}

View File

@ -47,6 +47,7 @@ public:
bool hasGamma;
S32 mIndexedTextureChannels;
bool disableTextureIndex;
bool hasAlphaMask;
// char numLights;
@ -67,6 +68,8 @@ public:
LLGLSLShader();
static GLhandleARB sCurBoundShader;
static LLGLSLShader* sCurBoundShaderPtr;
static bool sNoFixedFunction;
void unload();
@ -105,6 +108,8 @@ public:
void uniformMatrix3fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
void uniformMatrix4fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
void setAlphaRange(F32 minimum, F32 maximum);
void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void vertexAttrib4fv(U32 index, GLfloat* v);

View File

@ -1424,7 +1424,7 @@ void LLImageGL::deleteDeadTextures()
{
LLTexUnit* tex_unit = gGL.getTexUnit(i);
if (tex_unit->getCurrTexture() == tex)
if (tex_unit && tex_unit->getCurrTexture() == tex)
{
tex_unit->unbind(tex_unit->getCurrType());
stop_glerror();
@ -1887,6 +1887,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
void LLImageGL::setCategory(S32 category)
{
#if 0 //turn this off temporarily because it is not in use now.
if(!gAuditTexture)
{
return ;
@ -1907,6 +1908,7 @@ void LLImageGL::setCategory(S32 category)
mCategory = -1 ;
}
}
#endif
}
//for debug use

View File

@ -1168,6 +1168,11 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
{
flush();
if (LLGLSLShader::sNoFixedFunction)
{ //glAlphaFunc is deprecated in OpenGL 3.3
return;
}
if (mCurrAlphaFunc != func ||
mCurrAlphaFuncVal != value)
{
@ -1182,6 +1187,30 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
glAlphaFunc(sGLCompareFunc[func], value);
}
}
if (gDebugGL)
{ //make sure cached state is correct
GLint cur_func = 0;
glGetIntegerv(GL_ALPHA_TEST_FUNC, &cur_func);
if (func == CF_DEFAULT)
{
func = CF_GREATER;
}
if (cur_func != sGLCompareFunc[func])
{
llerrs << "Alpha test function corrupted!" << llendl;
}
F32 ref = 0.f;
glGetFloatv(GL_ALPHA_TEST_REF, &ref);
if (ref != value)
{
llerrs << "Alpha test value corrupted!" << llendl;
}
}
}
void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)

View File

@ -206,21 +206,40 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->hasLighting)
{
if (features->hasWaterFog)
{
if (features->disableTextureIndex)
{
if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl"))
if (features->hasAlphaMask)
{
return FALSE;
if (!shader->attachObject("lighting/lightWaterAlphaMaskNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl"))
{
return FALSE;
}
}
}
else
{
if (!shader->attachObject("lighting/lightWaterF.glsl"))
if (features->hasAlphaMask)
{
return FALSE;
if (!shader->attachObject("lighting/lightWaterAlphaMaskF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightWaterF.glsl"))
{
return FALSE;
}
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
@ -230,16 +249,36 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->disableTextureIndex)
{
if (!shader->attachObject("lighting/lightNonIndexedF.glsl"))
if (features->hasAlphaMask)
{
return FALSE;
if (!shader->attachObject("lighting/lightAlphaMaskNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightNonIndexedF.glsl"))
{
return FALSE;
}
}
}
else
{
if (!shader->attachObject("lighting/lightF.glsl"))
if (features->hasAlphaMask)
{
return FALSE;
if (!shader->attachObject("lighting/lightAlphaMaskF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightF.glsl"))
{
return FALSE;
}
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
@ -272,14 +311,28 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->disableTextureIndex)
{
if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
if (features->hasAlphaMask)
{
if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl"))
{
return FALSE;
}
}
else if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
if (features->hasAlphaMask)
{
if (!shader->attachObject("lighting/lightFullbrightWaterAlphaMaskF.glsl"))
{
return FALSE;
}
}
else if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
{
return FALSE;
}
@ -310,16 +363,37 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->disableTextureIndex)
{
if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl"))
if (features->hasAlphaMask)
{
return FALSE;
if (!shader->attachObject("lighting/lightFullbrightNonIndexedAlphaMaskF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl"))
{
return FALSE;
}
}
}
else
{
if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
if (features->hasAlphaMask)
{
return FALSE;
if (!shader->attachObject("lighting/lightFullbrightAlphaMaskF.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
{
return FALSE;
}
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
}
@ -406,7 +480,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
}
}
}
}
GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
{

View File

@ -339,7 +339,7 @@ LLAccordionCtrlTab::Params::Params()
,fit_panel("fit_panel",true)
,selection_enabled("selection_enabled", false)
{
mouse_opaque(false);
changeDefault(mouse_opaque, false);
}
LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p)

View File

@ -55,10 +55,7 @@ LLBadge::Params::Params()
, location_percent_vcenter("location_percent_vcenter")
, padding_horiz("padding_horiz")
, padding_vert("padding_vert")
{
// We set a name here so the name isn't necessary in any xml files that use badges
name = "badge";
}
{}
bool LLBadge::Params::equals(const Params& a) const
{

View File

@ -104,8 +104,7 @@ LLButton::Params::Params()
handle_right_mouse("handle_right_mouse")
{
addSynonym(is_toggle, "toggle");
held_down_delay.seconds = 0.5f;
initial_value.set(LLSD(false), false);
changeDefault(initial_value, LLSD(false));
}

View File

@ -54,7 +54,7 @@ public:
persist_time("persist_time", 0.f), // forever
font_size_index("font_size_index")
{
mouse_opaque(false);
changeDefault(mouse_opaque, false);
}
};
protected:

View File

@ -50,7 +50,7 @@ public:
show_label("show_label", FALSE),
display_children("display_children", TRUE)
{
mouse_opaque(false);
changeDefault(mouse_opaque, false);
}
};

View File

@ -51,8 +51,8 @@ public:
drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")),
drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark"))
{
mouse_opaque(true);
follows.flags(FOLLOWS_ALL);
changeDefault(mouse_opaque, true);
changeDefault(follows.flags, FOLLOWS_ALL);
}
};
void initFromParams(const Params&);

View File

@ -42,12 +42,7 @@ class LLFilterEditor : public LLSearchEditor
{
public:
struct Params : public LLInitParam::Block<Params, LLSearchEditor::Params>
{
Params()
{
name = "filter_editor";
}
};
{};
protected:
LLFilterEditor(const Params&);

View File

@ -182,7 +182,7 @@ LLFloater::Params::Params()
open_callback("open_callback"),
close_callback("close_callback")
{
visible = false;
changeDefault(visible, false);
}

View File

@ -46,7 +46,7 @@ public:
: action_button("action_button"),
allow_text_entry("allow_text_entry")
{
LLComboBox::Params::allow_text_entry = false;
changeDefault(LLComboBox::Params::allow_text_entry, false);
}
};

View File

@ -103,7 +103,7 @@ public:
}
else
{
llwarns << "tried to find '" << name << "' in LLFunctorRegistry, but it wasn't there." << llendl;
lldebugs << "tried to find '" << name << "' in LLFunctorRegistry, but it wasn't there." << llendl;
return mMap[LOGFUNCTOR];
}
}
@ -115,7 +115,7 @@ private:
static void log_functor(const LLSD& notification, const LLSD& payload)
{
llwarns << "log_functor called with payload: " << payload << llendl;
lldebugs << "log_functor called with payload: " << payload << llendl;
}
static void do_nothing(const LLSD& notification, const LLSD& payload)

View File

@ -43,10 +43,7 @@ LLIconCtrl::Params::Params()
color("color"),
use_draw_context_alpha("use_draw_context_alpha", true),
scale_image("scale_image")
{
tab_stop = false;
mouse_opaque = false;
}
{}
LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
: LLUICtrl(p),

View File

@ -115,9 +115,7 @@ LLLayoutStack::Params::Params()
open_time_constant("open_time_constant", 0.02f),
close_time_constant("close_time_constant", 0.03f),
border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0))
{
name="stack";
}
{}
LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)
: LLView(p),

View File

@ -103,7 +103,7 @@ LLLineEditor::Params::Params()
text_pad_right("text_pad_right"),
default_text("default_text")
{
mouse_opaque = true;
changeDefault(mouse_opaque, true);
addSynonym(select_on_focus, "select_all_on_focus_received");
addSynonym(border, "border");
addSynonym(label, "watermark_text");

View File

@ -90,7 +90,6 @@ const S32 TEAROFF_SEPARATOR_HEIGHT_PIXELS = 10;
const S32 MENU_ITEM_PADDING = 4;
const std::string SEPARATOR_NAME("separator");
const std::string SEPARATOR_LABEL( "-----------" );
const std::string VERTICAL_SEPARATOR_LABEL( "|" );
const std::string LLMenuGL::BOOLEAN_TRUE_PREFIX( "\xE2\x9C\x94" ); // U+2714 HEAVY CHECK MARK
@ -149,7 +148,7 @@ LLMenuItemGL::Params::Params()
highlight_bg_color("highlight_bg_color"),
highlight_fg_color("highlight_fg_color")
{
mouse_opaque = true;
changeDefault(mouse_opaque, true);
}
// Default constructor
@ -566,8 +565,6 @@ void LLMenuItemGL::handleVisibilityChange(BOOL new_visibility)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LLMenuItemSeparatorGL::Params::Params()
{
name = "separator";
label = SEPARATOR_LABEL;
}
LLMenuItemSeparatorGL::LLMenuItemSeparatorGL(const LLMenuItemSeparatorGL::Params& p) :
@ -755,30 +752,6 @@ U32 LLMenuItemTearOffGL::getNominalHeight( void ) const
return TEAROFF_SEPARATOR_HEIGHT_PIXELS;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemBlankGL
//
// This class represents a blank, non-functioning item.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLMenuItemBlankGL : public LLMenuItemGL
{
public:
struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
{
Params()
{
name="";
enabled = false;
}
};
LLMenuItemBlankGL( const Params& p ) : LLMenuItemGL( p )
{}
virtual void draw( void ) {}
};
///============================================================================
/// Class LLMenuItemCallGL
///============================================================================

View File

@ -381,8 +381,6 @@ public:
{
addSynonym(bg_visible, "opaque");
addSynonym(bg_color, "color");
name = "menu";
}
};
@ -650,7 +648,7 @@ public:
{
Params()
{
visible = false;
changeDefault(visible, false);
}
};
@ -698,16 +696,7 @@ class LLMenuBarGL : public LLMenuGL
{
public:
struct Params : public LLInitParam::Block<Params, LLMenuGL::Params>
{
Params()
{
can_tear_off = false;
keep_fixed_size = true;
horizontal_layout = true;
visible = true;
drop_shadow = false;
}
};
{};
LLMenuBarGL( const Params& p );
virtual ~LLMenuBarGL();
@ -825,13 +814,7 @@ class LLMenuItemTearOffGL : public LLMenuItemGL
{
public:
struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
{
Params()
{
name = "tear off";
label = "~~~~~~~~~~~";
}
};
{};
LLMenuItemTearOffGL( const Params& );

View File

@ -66,11 +66,7 @@ LLMultiSlider::Params::Params()
mouse_up_callback("mouse_up_callback"),
thumb_width("thumb_width"),
sliders("slider")
{
name = "multi_slider_bar";
mouse_opaque(true);
follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
}
{}
LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
: LLF32UICtrl(p),

View File

@ -90,7 +90,6 @@ LLPanel::Params::Params()
visible_callback("visible_callback"),
accepts_badge("accepts_badge")
{
name = "panel";
addSynonym(background_visible, "bg_visible");
addSynonym(has_border, "border_visible");
addSynonym(label, "title");

View File

@ -74,9 +74,6 @@ LLRadioGroup::Params::Params()
{
addSynonym(items, "radio_item");
name = "radio_group";
mouse_opaque = true;
follows.flags = FOLLOWS_LEFT | FOLLOWS_TOP;
// radio items are not tabbable until they are selected
tab_stop = false;
}
@ -96,7 +93,10 @@ void LLRadioGroup::initFromParams(const Params& p)
{
LLRadioGroup::ItemParams item_params(*it);
item_params.font.setIfNotProvided(mFont); // apply radio group font by default
if (!item_params.font.isProvided())
{
item_params.font = mFont; // apply radio group font by default
}
item_params.commit_callback.function = boost::bind(&LLRadioGroup::onClickButton, this, _1);
item_params.from_xui = p.from_xui;
if (p.from_xui)

View File

@ -63,9 +63,7 @@ LLScrollbar::Params::Params()
right_button("right_button"),
bg_visible("bg_visible", false),
bg_color("bg_color", LLColor4::black)
{
tab_stop = false;
}
{}
LLScrollbar::LLScrollbar(const Params & p)
: LLUICtrl(p),

View File

@ -74,8 +74,7 @@ LLScrollContainer::Params::Params()
min_auto_scroll_rate("min_auto_scroll_rate", 100),
max_auto_scroll_rate("max_auto_scroll_rate", 1000),
reserve_scroll_corner("reserve_scroll_corner", false)
{
}
{}
// Default constructor

View File

@ -51,12 +51,7 @@ class LLScrollingPanelList : public LLUICtrl
{
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Params()
{
name = "scrolling_panel_list";
}
};
{};
LLScrollingPanelList(const Params& p)
: LLUICtrl(p)
{}

View File

@ -46,10 +46,7 @@ static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(&typeid
//---------------------------------------------------------------------------
LLScrollColumnHeader::Params::Params()
: column("column")
{
name = "column_header";
tab_stop(false);
}
{}
LLScrollColumnHeader::LLScrollColumnHeader(const LLScrollColumnHeader::Params& p)

View File

@ -135,7 +135,7 @@ public:
halign("halign", LLFontGL::LEFT)
{
// default choice to "dynamic_width"
width.dynamic_width = true;
changeDefault(width.dynamic_width, true);
addSynonym(sort_column, "sort");
}

View File

@ -147,12 +147,9 @@ LLScrollListCtrl::Params::Params()
highlighted_color("highlighted_color"),
contents(""),
scroll_bar_bg_visible("scroll_bar_bg_visible"),
scroll_bar_bg_color("scroll_bar_bg_color")
, border("border")
{
name = "scroll_list";
mouse_opaque = true;
}
scroll_bar_bg_color("scroll_bar_bg_color"),
border("border")
{}
LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
: LLUICtrl(p),
@ -2813,7 +2810,10 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS
}
S32 index = columnp->mIndex;
cell_p.width.setIfNotProvided(columnp->getWidth());
if (!cell_p.width.isProvided())
{
cell_p.width = columnp->getWidth();
}
LLScrollListCell* cell = LLScrollListCell::create(cell_p);

View File

@ -55,9 +55,7 @@ public:
search_button_visible("search_button_visible"),
clear_button("clear_button"),
clear_button_visible("clear_button_visible")
{
name = "search_editor";
}
{}
};
void setCommitOnFocusLost(BOOL b) { if (mSearchEditor) mSearchEditor->setCommitOnFocusLost(b); }

View File

@ -54,9 +54,7 @@ LLSlider::Params::Params()
track_highlight_vertical_image("track_highlight_vertical_image"),
mouse_down_callback("mouse_down_callback"),
mouse_up_callback("mouse_up_callback")
{
follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
}
{}
LLSlider::LLSlider(const LLSlider::Params& p)
: LLF32UICtrl(p),

View File

@ -76,8 +76,14 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
}
LLRect label_rect( left, top, label_width, bottom );
LLTextBox::Params params(p.slider_label);
params.rect.setIfNotProvided(label_rect);
params.font.setIfNotProvided(p.font);
if (!params.rect.isProvided())
{
params.rect = label_rect;
}
if (!params.font.isProvided())
{
params.font = p.font;
}
params.initial_value(p.label());
mLabelBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mLabelBox);
@ -113,15 +119,33 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
S32 slider_left = label_width ? label_width + sliderctrl_spacing : 0;
LLSlider::Params slider_p(p.slider_bar);
slider_p.name("slider_bar");
slider_p.rect.setIfNotProvided(LLRect(slider_left,top,slider_right,bottom));
slider_p.initial_value.setIfNotProvided(p.initial_value().asReal());
slider_p.min_value.setIfNotProvided(p.min_value);
slider_p.max_value.setIfNotProvided(p.max_value);
slider_p.increment.setIfNotProvided(p.increment);
slider_p.orientation.setIfNotProvided(p.orientation);
if (!slider_p.rect.isProvided())
{
slider_p.rect = LLRect(slider_left,top,slider_right,bottom);
}
if (!slider_p.initial_value.isProvided())
{
slider_p.initial_value = p.initial_value().asReal();
}
if (!slider_p.min_value.isProvided())
{
slider_p.min_value = p.min_value;
}
if (!slider_p.max_value.isProvided())
{
slider_p.max_value = p.max_value;
}
if (!slider_p.increment.isProvided())
{
slider_p.increment = p.increment;
}
if (!slider_p.orientation.isProvided())
{
slider_p.orientation = p.orientation;
}
slider_p.commit_callback.function(&LLSliderCtrl::onSliderCommit);
slider_p.control_name(p.control_name);
slider_p.commit_callback.function = &LLSliderCtrl::onSliderCommit;
slider_p.control_name = p.control_name;
slider_p.mouse_down_callback( p.mouse_down_callback );
slider_p.mouse_up_callback( p.mouse_up_callback );
mSlider = LLUICtrlFactory::create<LLSlider> (slider_p);
@ -134,8 +158,15 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
if( p.can_edit_text() )
{
LLLineEditor::Params line_p(p.value_editor);
line_p.rect.setIfNotProvided(text_rect);
line_p.font.setIfNotProvided(p.font);
if (!line_p.rect.isProvided())
{
line_p.rect = text_rect;
}
if (!line_p.font.isProvided())
{
line_p.font = p.font;
}
line_p.commit_callback.function(&LLSliderCtrl::onEditorCommit);
line_p.prevalidate_callback(&LLTextValidate::validateFloat);
mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p);
@ -149,8 +180,14 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
else
{
LLTextBox::Params text_p(p.value_text);
text_p.rect.setIfNotProvided(text_rect);
text_p.font.setIfNotProvided(p.font);
if (!text_p.rect.isProvided())
{
text_p.rect = text_rect;
}
if (!text_p.font.isProvided())
{
text_p.font = p.font;
}
mTextBox = LLUICtrlFactory::create<LLTextBox>(text_p);
addChild(mTextBox);
}

View File

@ -65,7 +65,7 @@ public:
show_mean("show_mean", TRUE),
stat("stat")
{
follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
changeDefault(follows.flags, FOLLOWS_TOP | FOLLOWS_LEFT);
}
};
LLStatBar(const Params&);

View File

@ -46,7 +46,7 @@ public:
Params()
: setting("setting")
{
follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
changeDefault(follows.flags, FOLLOWS_TOP | FOLLOWS_LEFT);
}
};

View File

@ -217,10 +217,7 @@ LLTabContainer::Params::Params()
tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0),
use_ellipses("use_ellipses"),
font_halign("halign")
{
name(std::string("tab_container"));
mouse_opaque = false;
}
{}
LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
: LLPanel(p),

View File

@ -55,7 +55,7 @@ static LLDefaultChildRegistry::Register<LLToolTipView> register_tooltip_view("to
LLToolTipView::Params::Params()
{
mouse_opaque = false;
changeDefault(mouse_opaque, false);
}
LLToolTipView::LLToolTipView(const LLToolTipView::Params& p)
@ -156,7 +156,7 @@ LLToolTip::Params::Params()
web_based_media("web_based_media", false),
media_playing("media_playing", false)
{
chrome = true;
changeDefault(chrome, true);
}
LLToolTip::LLToolTip(const LLToolTip::Params& p)
@ -402,12 +402,12 @@ void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)
LLToolTip::Params tooltip_params(params);
// block mouse events if there is a click handler registered (specifically, hover)
if (params.click_callback.isProvided())
if (params.click_callback.isProvided() && !params.mouse_opaque.isProvided())
{
// set mouse_opaque to true if it wasn't already set to something else
// this prevents mouse down from going "through" the tooltip and ultimately
// causing the tooltip to disappear
tooltip_params.mouse_opaque.setIfNotProvided(true);
tooltip_params.mouse_opaque = true;
}
tooltip_params.rect = LLRect (0, 1, 1, 0);

View File

@ -104,14 +104,17 @@ private:
public:
ParamDefaults()
{
// recursively initialize from base class param block
((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get());
// after initializing base classes, look up template file for this param block
// look up template file for this param block...
const std::string* param_block_tag = getWidgetTag(&typeid(PARAM_BLOCK));
if (param_block_tag)
{
LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, mPrototype);
{ // ...and if it exists, back fill values using the most specific template first
PARAM_BLOCK params;
LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params);
mPrototype.fillFrom(params);
}
// recursively fill from base class param block
((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get());
}
const PARAM_BLOCK& get() { return mPrototype; }

View File

@ -2485,7 +2485,7 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
{
LLRect parent_rect = parent->getLocalRect();
// overwrite uninitialized rect params, using context
LLRect last_rect = parent->getLocalRect();
LLRect default_rect = parent->getLocalRect();
bool layout_topleft = (p.layout() == "topleft");
@ -2509,15 +2509,13 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
p.rect.height = MIN_WIDGET_HEIGHT;
}
last_rect.translate(0, last_rect.getHeight());
default_rect.translate(0, default_rect.getHeight());
// If there was a recently constructed child, use its rectangle
get_last_child_rect(parent, &last_rect);
get_last_child_rect(parent, &default_rect);
if (layout_topleft)
{
p.bottom_delta.setIfNotProvided(0, false);
// Invert the sense of bottom_delta for topleft layout
if (p.bottom_delta.isProvided())
{
@ -2530,33 +2528,44 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
else if (p.top_delta.isProvided())
{
p.bottom_delta =
-(p.top_delta + p.rect.height - last_rect.getHeight());
-(p.top_delta + p.rect.height - default_rect.getHeight());
}
else if (!p.bottom_delta.isProvided()
&& !p.left_delta.isProvided()
&& !p.top_pad.isProvided()
else if (!p.left_delta.isProvided()
&& !p.left_pad.isProvided())
{
// set default position is just below last rect
p.bottom_delta.set(-(p.rect.height + VPAD), false);
}
else
{
p.bottom_delta.set(0, false);
}
// default to same left edge
p.left_delta.setIfNotProvided(0, false);
if (!p.left_delta.isProvided())
{
p.left_delta.set(0, false);
}
if (p.left_pad.isProvided())
{
// left_pad is based on prior widget's right edge
p.left_delta.set(p.left_pad + last_rect.getWidth(), false);
p.left_delta.set(p.left_pad + default_rect.getWidth(), false);
}
last_rect.translate(p.left_delta, p.bottom_delta);
default_rect.translate(p.left_delta, p.bottom_delta);
}
else
{
// set default position is just below last rect
p.bottom_delta.setIfNotProvided(-(p.rect.height + VPAD), false);
p.left_delta.setIfNotProvided(0, false);
last_rect.translate(p.left_delta, p.bottom_delta);
if (!p.bottom_delta.isProvided())
{
p.bottom_delta.set(-(p.rect.height + VPAD), false);
}
if (!p.left_delta.isProvided())
{
p.left_delta.set(0, false);
}
default_rect.translate(p.left_delta, p.bottom_delta);
}
// this handles case where *both* x and x_delta are provided
@ -2567,12 +2576,30 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
// selectively apply rectangle defaults, making sure that
// params are not flagged as having been "provided"
// as rect params are overconstrained and rely on provided flags
p.rect.left.setIfNotProvided(last_rect.mLeft, false);
p.rect.bottom.setIfNotProvided(last_rect.mBottom, false);
p.rect.top.setIfNotProvided(last_rect.mTop, false);
p.rect.right.setIfNotProvided(last_rect.mRight, false);
p.rect.width.setIfNotProvided(last_rect.getWidth(), false);
p.rect.height.setIfNotProvided(last_rect.getHeight(), false);
if (!p.rect.left.isProvided())
{
p.rect.left.set(default_rect.mLeft, false);
}
if (!p.rect.bottom.isProvided())
{
p.rect.bottom.set(default_rect.mBottom, false);
}
if (!p.rect.top.isProvided())
{
p.rect.top.set(default_rect.mTop, false);
}
if (!p.rect.right.isProvided())
{
p.rect.right.set(default_rect.mRight, false);
}
if (!p.rect.width.isProvided())
{
p.rect.width.set(default_rect.getWidth(), false);
}
if (!p.rect.height.isProvided())
{
p.rect.height.set(default_rect.getHeight(), false);
}
}
}

View File

@ -57,9 +57,6 @@ LLViewBorder::Params::Params()
{
addSynonym(border_thickness, "thickness");
addSynonym(render_style, "style");
name = "view_border";
mouse_opaque = false;
follows.flags = FOLLOWS_ALL;
}

View File

@ -43,7 +43,7 @@ LLWindowShade::Params::Params()
text_color("text_color"),
can_close("can_close", true)
{
mouse_opaque = false;
changeDefault(mouse_opaque, false);
}
LLWindowShade::LLWindowShade(const LLWindowShade::Params& params)

View File

@ -1172,8 +1172,39 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
// First we try and get a 32 bit depth pixel format
BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
while(!result && mFSAASamples > 0)
{
llwarns << "FSAASamples: " << mFSAASamples << " not supported." << llendl ;
mFSAASamples /= 2 ; //try to decrease sample pixel number until to disable anti-aliasing
if(mFSAASamples < 2)
{
mFSAASamples = 0 ;
}
if (mFSAASamples > 0)
{
attrib_list[end_attrib + 3] = mFSAASamples;
}
else
{
cur_attrib = end_attrib ;
end_attrib = 0 ;
attrib_list[cur_attrib++] = 0 ; //end
}
result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats);
if(result)
{
llwarns << "Only support FSAASamples: " << mFSAASamples << llendl ;
}
}
if (!result)
{
llwarns << "mFSAASamples: " << mFSAASamples << llendl ;
close();
show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit");
return FALSE;

View File

@ -717,14 +717,6 @@ namespace LLInitParam
Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
{
if (!isProvided())
{
set(val, flag_as_provided);
}
}
// implicit conversion
operator value_assignment_t() const { return param_value_t::getValue(); }
// explicit conversion
@ -869,14 +861,6 @@ namespace LLInitParam
Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
{
if (!isProvided())
{
set(val, flag_as_provided);
}
}
// propagate changed status up to enclosing block
/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
@ -1033,15 +1017,6 @@ namespace LLInitParam
Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
{
if (!isProvided())
{
set(val, flag_as_provided);
}
}
value_t& add()
{
mValues.push_back(param_value_t(value_t()));
@ -1232,14 +1207,6 @@ namespace LLInitParam
Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
{
if (!isProvided())
{
set(val, flag_as_provided);
}
}
value_t& add()
{
mValues.push_back(value_t());
@ -1719,6 +1686,17 @@ namespace LLInitParam
static BlockDescriptor sBlockDescriptor;
return sBlockDescriptor;
}
template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param,
typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
{
if (!param.isProvided())
{
param.set(value, false);
}
}
};
template<typename T>

File diff suppressed because it is too large Load Diff

View File

@ -1798,7 +1798,7 @@ if (LINUX)
set(product SecondLife-${ARCH}-${viewer_VERSION})
# These are the generated targets that are copied to package/
set(COPY_INPUT_DEPENDENCIES
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
linux-crash-logger
linux-updater

View File

@ -798,6 +798,61 @@
<key>Value</key>
<integer>5</integer>
</map>
<key>Socks5ProxyEnabled</key>
<map>
<key>Comment</key>
<string>Use Socks5 Proxy</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>HttpProxyType</key>
<map>
<key>Comment</key>
<string>Proxy type to use for HTTP operations</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>Socks</string>
</map>
<key>Socks5ProxyHost</key>
<map>
<key>Comment</key>
<string>Socks 5 Proxy Host</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string></string>
</map>
<key>Socks5ProxyPort</key>
<map>
<key>Comment</key>
<string>Socks 5 Proxy Port</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1080</integer>
</map>
<key>Socks5AuthType</key>
<map>
<key>Comment</key>
<string>Selected Auth mechanism for Socks5</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>None</string>
</map>
<key>BuildAxisDeadZone0</key>
<map>
<key>Comment</key>
@ -1629,17 +1684,6 @@
<string />
</array>
</map>
<key>CompressSnapshotsToDisk</key>
<map>
<key>Comment</key>
<string>Compress snapshots saved to disk (Using JPEG 2000)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>ConnectAsGod</key>
<map>
<key>Comment</key>
@ -1814,7 +1858,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
<integer>0</integer>
</map>
<key>Cursor3D</key>
<map>
@ -4004,7 +4048,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>http://search-beta.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]</string>
<string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]</string>
</map>
<key>WebProfileURL</key>
<map>
@ -5448,6 +5492,17 @@
<key>Value</key>
<real>60.0</real>
</map>
<key>MediaPluginDebugging</key>
<map>
<key>Comment</key>
<string>Turn on debugging messages that may help diagnosing media issues (WARNING: May reduce performance).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>MediaControlFadeTime</key>
<map>
<key>Comment</key>

View File

@ -0,0 +1,48 @@
/**
* @file diffuseF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
uniform sampler2D diffuseMap;
varying vec3 vary_normal;
void main()
{
vec4 col = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color;
if (col.a < minimum_alpha || col.a > maximum_alpha)
{
discard;
}
gl_FragData[0] = vec4(col.rgb, 0.0);
gl_FragData[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}

View File

@ -0,0 +1,44 @@
/**
* @file diffuseAlphaMaskIndexedF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
varying vec3 vary_normal;
uniform float minimum_alpha;
uniform float maximum_alpha;
void main()
{
vec4 col = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
if (col.a < minimum_alpha || col.a > maximum_alpha)
{
discard;
}
gl_FragData[0] = vec4(col.rgb, 0.0);
gl_FragData[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}

View File

@ -1,7 +1,7 @@
/**
* @file impostorF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
*
@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
uniform sampler2D diffuseMap;
@ -32,6 +34,12 @@ uniform sampler2D specularMap;
void main()
{
vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
if (col.a < minimum_alpha || col.a > maximum_alpha)
{
discard;
}
gl_FragData[0] = vec4(col.rgb, col.a * 0.005);
gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy);
gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, 0.0);

View File

@ -0,0 +1,45 @@
/**
* @file shadowAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
uniform sampler2D diffuseMap;
varying vec4 post_pos;
void main()
{
float alpha = texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a;
if (alpha < minimum_alpha || alpha > maximum_alpha)
{
discard;
}
gl_FragColor = vec4(1,1,1,1);
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
}

View File

@ -0,0 +1,41 @@
/**
* @file shadowAlphaMaskV.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
varying vec4 post_pos;
void main()
{
//transform vertex
vec4 pos = gl_ModelViewProjectionMatrix*gl_Vertex;
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
}

View File

@ -1,7 +1,7 @@
/**
* @file shadowF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
*
@ -25,13 +25,11 @@
uniform sampler2D diffuseMap;
varying vec4 post_pos;
void main()
{
gl_FragColor = vec4(1,1,1,texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a);
gl_FragColor = vec4(1,1,1,1);
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
}

View File

@ -1,7 +1,7 @@
/**
* @file shadowV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
*
@ -35,7 +35,4 @@ void main()
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
}

View File

@ -0,0 +1,44 @@
/**
* @file impostorF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
uniform sampler2D diffuseMap;
void main()
{
vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
if (color.a < minimum_alpha || color.a > maximum_alpha)
{
discard;
}
gl_FragColor = color;
}

View File

@ -0,0 +1,34 @@
/**
* @file impostorV.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
void main()
{
//transform vertex
gl_Position = ftransform();
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
}

View File

@ -0,0 +1,48 @@
/**
* @file lightAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
void default_lighting()
{
vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
if (color.a < minimum_alpha || color.a > maximum_alpha)
{
discard;
}
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
gl_FragColor = color;
}

View File

@ -0,0 +1,51 @@
/**
* @file lightAlphaMaskNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
uniform sampler2D diffuseMap;
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
void default_lighting()
{
vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
if (color.a < minimum_alpha || color.a > maximum_alpha)
{
discard;
}
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
gl_FragColor = color;
}

View File

@ -0,0 +1,47 @@
/**
* @file lightFullbrightAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
void fullbright_lighting()
{
vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
if (color.a < minimum_alpha || color.a > maximum_alpha)
{
discard;
}
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
gl_FragColor = color;
}

View File

@ -0,0 +1,49 @@
/**
* @file lightFullbrightNonIndexedAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
uniform sampler2D diffuseMap;
void fullbright_lighting()
{
vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
if (color.a < minimum_alpha || color.a > maximum_alpha)
{
discard;
}
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
gl_FragColor = color;
}

View File

@ -0,0 +1,47 @@
/**
* @file lightFullbrightWaterAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
vec4 diffuseLookup(vec2 texcoord);
vec3 fullbrightAtmosTransport(vec3 light);
vec4 applyWaterFog(vec4 color);
void fullbright_lighting_water()
{
vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
if (color.a < minimum_alpha || color.a > maximum_alpha)
{
discard;
}
color.rgb = fullbrightAtmosTransport(color.rgb);
gl_FragColor = applyWaterFog(color);
}

View File

@ -0,0 +1,47 @@
/**
* @file lightFullbrightWaterNonIndexedAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
uniform sampler2D diffuseMap;
vec3 fullbrightAtmosTransport(vec3 light);
vec4 applyWaterFog(vec4 color);
void fullbright_lighting_water()
{
vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color;
if (color.a < minimum_alpha || color.a > maximum_alpha)
{
discard;
}
color.rgb = fullbrightAtmosTransport(color.rgb);
gl_FragColor = applyWaterFog(color);
}

View File

@ -0,0 +1,45 @@
/**
* @file lightWaterAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
vec3 atmosLighting(vec3 light);
vec4 applyWaterFog(vec4 color);
void default_lighting_water()
{
vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
if (color.a < minimum_alpha || color.a > maximum_alpha)
{
discard;
}
color.rgb = atmosLighting(color.rgb);
gl_FragColor = applyWaterFog(color);
}

View File

@ -0,0 +1,49 @@
/**
* @file lightWaterAlphaMaskNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, 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$
*/
uniform float minimum_alpha;
uniform float maximum_alpha;
uniform sampler2D diffuseMap;
vec3 atmosLighting(vec3 light);
vec4 applyWaterFog(vec4 color);
void default_lighting_water()
{
vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
if (color.a < minimum_alpha || color.a > maximum_alpha)
{
discard;
}
color.rgb = atmosLighting(color.rgb);
color = applyWaterFog(color);
gl_FragColor = color;
}

View File

@ -1692,37 +1692,6 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty
}
}
// static
void LLAgentWearables::userRemoveAllClothes()
{
// We have to do this up front to avoid having to deal with the case of multiple wearables being dirty.
if (gAgentCamera.cameraCustomizeAvatar())
{
// switching to outfit editor should automagically save any currently edited wearable
LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit"));
}
userRemoveAllClothesStep2(TRUE);
}
// static
void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed)
{
if (proceed)
{
gAgentWearables.removeWearable(LLWearableType::WT_SHIRT,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_PANTS,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_SHOES,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_SOCKS,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_JACKET,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_GLOVES,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_UNDERSHIRT,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_UNDERPANTS,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_SKIRT,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_ALPHA,true,0);
gAgentWearables.removeWearable(LLWearableType::WT_TATTOO,true,0);
}
}
// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to
// get attachments into desired state with minimal number of adds/removes.
void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)

View File

@ -165,7 +165,6 @@ private:
void removeWearableFinal(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
protected:
static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response);
static void userRemoveAllClothesStep2(BOOL proceed); // userdata is NULL
//--------------------------------------------------------------------
// Server Communication
@ -211,7 +210,6 @@ public:
public:
static void userRemoveWearable(const LLWearableType::EType &type, const U32 &index);
static void userRemoveWearablesOfType(const LLWearableType::EType &type);
static void userRemoveAllClothes();
typedef std::vector<LLViewerObject*> llvo_vec_t;

View File

@ -2285,7 +2285,9 @@ void LLAppearanceMgr::autopopulateOutfits()
void LLAppearanceMgr::onFirstFullyVisible()
{
gAgentAvatarp->debugAvatarVisible();
autopopulateOutfits();
// The auto-populate is failing at the point of generating outfits
// folders, so don't do the library copy until that is resolved.
// autopopulateOutfits();
}
bool LLAppearanceMgr::updateBaseOutfit()

View File

@ -137,6 +137,7 @@
#include "lltoolmgr.h"
#include "llassetstorage.h"
#include "llpolymesh.h"
#include "llproxy.h"
#include "llaudioengine.h"
#include "llstreamingaudio.h"
#include "llviewermenu.h"
@ -321,6 +322,41 @@ static std::string gLaunchFileOnQuit;
// Used on Win32 for other apps to identify our window (eg, win_setup)
const char* const VIEWER_WINDOW_CLASSNAME = "Second Life";
//-- LLDeferredTaskList ------------------------------------------------------
/**
* A list of deferred tasks.
*
* We sometimes need to defer execution of some code until the viewer gets idle,
* e.g. removing an inventory item from within notifyObservers() may not work out.
*
* Tasks added to this list will be executed in the next LLAppViewer::idle() iteration.
* All tasks are executed only once.
*/
class LLDeferredTaskList: public LLSingleton<LLDeferredTaskList>
{
LOG_CLASS(LLDeferredTaskList);
friend class LLAppViewer;
typedef boost::signals2::signal<void()> signal_t;
void addTask(const signal_t::slot_type& cb)
{
mSignal.connect(cb);
}
void run()
{
if (!mSignal.empty())
{
mSignal();
mSignal.disconnect_all_slots();
}
}
signal_t mSignal;
};
//----------------------------------------------------------------------------
// List of entries from strings.xml to always replace
@ -731,6 +767,23 @@ bool LLAppViewer::init()
initThreads();
LL_INFOS("InitInfo") << "Threads initialized." << LL_ENDL ;
// Initialize settings early so that the defaults for ignorable dialogs are
// picked up and then correctly re-saved after launching the updater (STORM-1268).
LLUI::settings_map_t settings_map;
settings_map["config"] = &gSavedSettings;
settings_map["ignores"] = &gWarningSettings;
settings_map["floater"] = &gSavedSettings; // *TODO: New settings file
settings_map["account"] = &gSavedPerAccountSettings;
LLUI::initClass(settings_map,
LLUIImageList::getInstance(),
ui_audio_callback,
&LLUI::sGLScaleFactor);
LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
LLNotifications::instance();
LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
writeSystemInfo();
// Initialize updater service (now that we have an io pump)
@ -772,19 +825,8 @@ bool LLAppViewer::init()
{
LLError::setPrintLocation(true);
}
// Widget construction depends on LLUI being initialized
LLUI::settings_map_t settings_map;
settings_map["config"] = &gSavedSettings;
settings_map["ignores"] = &gWarningSettings;
settings_map["floater"] = &gSavedSettings; // *TODO: New settings file
settings_map["account"] = &gSavedPerAccountSettings;
LLUI::initClass(settings_map,
LLUIImageList::getInstance(),
ui_audio_callback,
&LLUI::sGLScaleFactor);
// Setup paths and LLTrans after LLUI::initClass has been called
LLUI::setupPaths();
LLTransUtil::parseStrings("strings.xml", default_trans_args);
@ -1840,6 +1882,8 @@ bool LLAppViewer::cleanup()
LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
llinfos << "File launched." << llendflush;
}
llinfos << "Cleaning up LLProxy." << llendl;
LLProxy::cleanupClass();
LLMainLoopRepeater::instance().stop();
@ -3820,6 +3864,11 @@ bool LLAppViewer::initCache()
}
}
void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
{
LLDeferredTaskList::instance().addTask(cb);
}
void LLAppViewer::purgeCache()
{
LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
@ -4413,6 +4462,9 @@ void LLAppViewer::idle()
gAudiop->idle(max_audio_decode_time);
}
}
// Execute deferred tasks.
LLDeferredTaskList::instance().run();
// Handle shutdown process, for example,
// wait for floaters to close, send quit message,

View File

@ -164,6 +164,8 @@ public:
login_completed_signal_t mOnLoginCompleted;
boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); }
void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle
void purgeCache(); // Clear the local cache.
// mute/unmute the system's master audio

View File

@ -141,7 +141,6 @@ LLAvatarIconCtrl::Params::Params()
draw_tooltip("draw_tooltip", true),
default_icon_name("default_icon_name")
{
name = "avatar_icon";
}

View File

@ -43,7 +43,7 @@ namespace LLNotificationsUI
*/
class LLChannelManager : public LLSingleton<LLChannelManager>
{
public:
public:
struct Params
{
LLUUID id;
@ -51,7 +51,8 @@ public:
EToastAlignment toast_align;
EChannelAlignment channel_align;
Params(): id(LLUUID("")), display_toasts_always(false), toast_align(NA_BOTTOM), channel_align(CA_LEFT)
Params()
: id(LLUUID("")), display_toasts_always(false), toast_align(NA_BOTTOM), channel_align(CA_LEFT)
{}
};

Some files were not shown because too many files have changed in this diff Show More