Merge from viewer-experience
commit
78821c51a1
11
.hgtags
11
.hgtags
|
|
@ -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
|
||||
|
|
|
|||
10
BuildParams
10
BuildParams
|
|
@ -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
|
||||
# =================================================================
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public:
|
|||
show_label("show_label", FALSE),
|
||||
display_children("display_children", TRUE)
|
||||
{
|
||||
mouse_opaque(false);
|
||||
changeDefault(mouse_opaque, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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&);
|
||||
|
|
|
|||
|
|
@ -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&);
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ LLFloater::Params::Params()
|
|||
open_callback("open_callback"),
|
||||
close_callback("close_callback")
|
||||
{
|
||||
visible = false;
|
||||
changeDefault(visible, false);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
///============================================================================
|
||||
|
|
|
|||
|
|
@ -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& );
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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&);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public:
|
|||
Params()
|
||||
: setting("setting")
|
||||
{
|
||||
follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
|
||||
changeDefault(follows.flags, FOLLOWS_TOP | FOLLOWS_LEFT);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -141,7 +141,6 @@ LLAvatarIconCtrl::Params::Params()
|
|||
draw_tooltip("draw_tooltip", true),
|
||||
default_icon_name("default_icon_name")
|
||||
{
|
||||
name = "avatar_icon";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue