summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Lihatskiy <andreylproductengine@lindenlab.com>2018-06-11 14:28:30 +0300
committerAndrey Lihatskiy <andreylproductengine@lindenlab.com>2018-06-11 14:28:30 +0300
commit1b236217560aeb81d5eea5a6b67b1f9896b005a8 (patch)
treeb69705b8ef9831b4725fa3023626d87ec4b1809a /indra
parent546fc96f01298fe16f1cb0454e65569c77c44090 (diff)
parent2761c1c7c2fdb6cbfe610be7e2f4f8753271d36f (diff)
Merged lindenlab/viewer-neko into default
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llcoros.cpp19
-rw-r--r--indra/llcommon/llcoros.h4
-rw-r--r--indra/llcommon/llerror.cpp24
-rw-r--r--indra/llcorehttp/_httpservice.cpp8
-rw-r--r--indra/llrender/llvertexbuffer.cpp8
-rw-r--r--indra/llui/llscrolllistctrl.cpp1
-rw-r--r--indra/newview/CMakeLists.txt7
-rw-r--r--indra/newview/app_settings/settings.xml6
-rw-r--r--indra/newview/llagentcamera.cpp44
-rw-r--r--indra/newview/llagentcamera.h2
-rw-r--r--indra/newview/llappviewer.cpp5
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp6
-rw-r--r--indra/newview/llfeaturemanager.cpp91
-rw-r--r--indra/newview/llfeaturemanager.h5
-rw-r--r--indra/newview/lltooldraganddrop.cpp17
-rw-r--r--indra/newview/lltooldraganddrop.h2
16 files changed, 101 insertions, 148 deletions
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index c5ba23f68c..4bab669046 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -35,6 +35,7 @@
// external library headers
#include <boost/bind.hpp>
// other Linden headers
+#include "lltimer.h"
#include "llevents.h"
#include "llerror.h"
#include "stringize.h"
@@ -280,6 +281,21 @@ void LLCoros::setStackSize(S32 stacksize)
mStackSize = stacksize;
}
+void LLCoros::printActiveCoroutines()
+{
+ LL_INFOS("LLCoros") << "-------------- List of active coroutines ------------";
+ CoroMap::iterator iter;
+ CoroMap::iterator end = mCoros.end();
+ F64 time = LLTimer::getTotalSeconds();
+ for (iter = mCoros.begin(); iter != end; iter++)
+ {
+ F64 life_time = time - iter->second->mCreationTime;
+ LL_CONT << LL_NEWLINE << "Name: " << iter->first << " life: " << life_time;
+ }
+ LL_CONT << LL_ENDL;
+ LL_INFOS("LLCoros") << "-----------------------------------------------------" << LL_ENDL;
+}
+
#if LL_WINDOWS
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
@@ -375,7 +391,8 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name,
mCoro(boost::bind(toplevel, _1, this, callable), stacksize),
// don't consume events unless specifically directed
mConsuming(false),
- mSelf(0)
+ mSelf(0),
+ mCreationTime(LLTimer::getTotalSeconds())
{
}
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 884d6b159c..8fb27af6a4 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -151,6 +151,9 @@ public:
/// for delayed initialization
void setStackSize(S32 stacksize);
+ /// for delayed initialization
+ void printActiveCoroutines();
+
/// get the current coro::self& for those who really really care
static coro::self& get_self();
@@ -223,6 +226,7 @@ private:
// function signature down to that point -- and of course through every
// other caller of every such function.
LLCoros::coro::self* mSelf;
+ F64 mCreationTime; // since epoch
};
typedef boost::ptr_map<std::string, CoroData> CoroMap;
CoroMap mCoros;
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index f31a054139..29de79dc64 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -249,23 +249,13 @@ namespace LLError
{
#ifdef __GNUC__
// GCC: type_info::name() returns a mangled class name,st demangle
-
- static size_t abi_name_len = 100;
- static char* abi_name_buf = (char*)malloc(abi_name_len);
- // warning: above is voodoo inferred from the GCC manual,
- // do NOT change
-
- int status;
- // We don't use status, and shouldn't have to pass apointer to it
- // but gcc 3.3 libstc++'s implementation of demangling is broken
- // and fails without.
-
- char* name = abi::__cxa_demangle(mangled,
- abi_name_buf, &abi_name_len, &status);
- // this call can realloc the abi_name_buf pointer (!)
-
- return name ? name : mangled;
-
+ // passing nullptr, 0 forces allocation of a unique buffer we can free
+ // fixing MAINT-8724 on OSX 10.14
+ int status = -1;
+ char* name = abi::__cxa_demangle(mangled, nullptr, 0, &status);
+ std::string result(name ? name : mangled);
+ free(name);
+ return result;
#elif LL_WINDOWS
// DevStudio: type_info::name() includes the text "class " at the start
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 49d865cbfa..0b72b53186 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -95,10 +95,12 @@ HttpService::~HttpService()
if (! mThread->timedJoin(250))
{
// Failed to join, expect problems ahead so do a hard termination.
- mThread->cancel();
+ LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems." << LL_NEWLINE
+ << "State: " << S32(sState)
+ << " Last policy: " << U32(mLastPolicy)
+ << LL_ENDL;
- LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems."
- << LL_ENDL;
+ mThread->cancel();
}
}
}
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index e3e605d040..1312f6afda 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -192,7 +192,13 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
ret = (U8*) ll_aligned_malloc<64>(size);
if (!ret)
{
- LL_ERRS() << "Failed to allocate for LLVBOPool buffer" << LL_ENDL;
+ LL_ERRS() << "Failed to allocate "<< size << " bytes for LLVBOPool buffer " << name <<"." << LL_NEWLINE
+ << "Free list size: " << mFreeList.size() // this happens if we are out of memory so a solution might be to clear some from freelist
+ << " Allocated Bytes: " << LLVertexBuffer::sAllocatedBytes
+ << " Allocated Index Bytes: " << LLVertexBuffer::sAllocatedIndexBytes
+ << " Pooled Bytes: " << sBytesPooled
+ << " Pooled Index Bytes: " << sIndexBytesPooled
+ << LL_ENDL;
}
}
}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 212e27477b..ed65b1e45f 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -2784,7 +2784,6 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
}
// if this column is the primary sort key, reverse the direction
- sort_column_t cur_sort_column;
if (!parent->mSortColumns.empty() && parent->mSortColumns.back().first == column_index)
{
ascending = !parent->mSortColumns.back().second;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b7a860aae0..367d4577ca 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2055,7 +2055,12 @@ if (DARWIN)
# These all get set with PROPERTIES
set(product "Second Life")
# this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
- set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
+ if (PACKAGE)
+ set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
+ else (PACKAGE)
+ # force the name of the actual executable to allow running it within Xcode for debugging
+ set(MACOSX_WRAPPER_EXECUTABLE_NAME "../Resources/Second Life Viewer.app/Contents/MacOS/Second Life")
+ endif (PACKAGE)
set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f0782e0bf7..a01435626f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -3703,13 +3703,13 @@
<key>FeatureManagerHTTPTable</key>
<map>
<key>Comment</key>
- <string>Base directory for HTTP feature/gpu table fetches</string>
+ <string>Deprecated</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>http://viewer-settings.secondlife.com</string>
+ <string></string>
</map>
<key>FPSLogFrequency</key>
<map>
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 5b9f1b9d4f..92a3026096 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -76,6 +76,8 @@ const F32 AVATAR_ZOOM_MIN_Y_FACTOR = 0.7f;
const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 1.15f;
const F32 MAX_CAMERA_DISTANCE_FROM_AGENT = 50.f;
+const F32 MAX_CAMERA_DISTANCE_FROM_OBJECT = 496.f;
+const F32 CAMERA_FUDGE_FROM_OBJECT = 16.f;
const F32 MAX_CAMERA_SMOOTH_DISTANCE = 50.0f;
@@ -738,10 +740,7 @@ F32 LLAgentCamera::getCameraZoomFraction()
else
{
F32 min_zoom;
- const F32 DIST_FUDGE = 16.f; // meters
- F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE,
- LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
- MAX_CAMERA_DISTANCE_FROM_AGENT);
+ F32 max_zoom = getCameraMaxZoomDistance();
F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
if (mFocusObject.notNull())
@@ -787,23 +786,17 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
else
{
F32 min_zoom = LAND_MIN_ZOOM;
- const F32 DIST_FUDGE = 16.f; // meters
- F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE,
- LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
- MAX_CAMERA_DISTANCE_FROM_AGENT);
+ F32 max_zoom = getCameraMaxZoomDistance();
if (mFocusObject.notNull())
{
- if (mFocusObject.notNull())
+ if (mFocusObject->isAvatar())
{
- if (mFocusObject->isAvatar())
- {
- min_zoom = AVATAR_MIN_ZOOM;
- }
- else
- {
- min_zoom = OBJECT_MIN_ZOOM;
- }
+ min_zoom = AVATAR_MIN_ZOOM;
+ }
+ else
+ {
+ min_zoom = OBJECT_MIN_ZOOM;
}
}
@@ -909,10 +902,7 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
new_distance = llmax(new_distance, min_zoom);
- // Don't zoom too far back
- const F32 DIST_FUDGE = 16.f; // meters
- F32 max_distance = llmin(mDrawDistance - DIST_FUDGE,
- LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
+ F32 max_distance = getCameraMaxZoomDistance();
max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154
@@ -978,10 +968,7 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
new_distance = llmax(new_distance, min_zoom);
- // Don't zoom too far back
- const F32 DIST_FUDGE = 16.f; // meters
- F32 max_distance = llmin(mDrawDistance - DIST_FUDGE,
- LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
+ F32 max_distance = getCameraMaxZoomDistance();
if (new_distance > max_distance)
{
@@ -1946,6 +1933,13 @@ LLVector3 LLAgentCamera::getCameraOffsetInitial()
return convert_from_llsd<LLVector3>(mCameraOffsetInitial[mCameraPreset]->get(), TYPE_VEC3, "");
}
+F32 LLAgentCamera::getCameraMaxZoomDistance()
+{
+ // Ignore "DisableCameraConstraints", we don't want to be out of draw range when we focus onto objects or avatars
+ return llmin(MAX_CAMERA_DISTANCE_FROM_OBJECT,
+ mDrawDistance - 1, // convenience, don't hit draw limit when focusing on something
+ LLWorld::getInstance()->getRegionWidthInMeters() - CAMERA_FUDGE_FROM_OBJECT);
+}
//-----------------------------------------------------------------------------
// handleScrollWheel()
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index ab793ff316..d087de1e2f 100644
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
@@ -112,6 +112,8 @@ public:
private:
/** Determines default camera offset depending on the current camera preset */
LLVector3 getCameraOffsetInitial();
+ /** Determines maximum camera distance from target for mouselook, opposite to LAND_MIN_ZOOM */
+ F32 getCameraMaxZoomDistance();
/** Camera preset in Third Person Mode */
ECameraPreset mCameraPreset;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f705084bdb..b9e2657351 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1082,6 +1082,8 @@ bool LLAppViewer::init()
}
}
+// don't nag developers who need to run the executable directly
+#if LL_RELEASE_FOR_DOWNLOAD
// MAINT-8305: If we're processing a SLURL, skip the launcher check.
if (gSavedSettings.getString("CmdLineLoginLocation").empty())
{
@@ -1098,6 +1100,7 @@ bool LLAppViewer::init()
LLNotificationsUtil::add("RunLauncher");
}
}
+#endif
#if LL_WINDOWS
if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
@@ -1794,6 +1797,8 @@ bool LLAppViewer::cleanup()
// (Deleted observers should have already removed themselves)
gInventory.cleanupInventory();
+ LLCoros::getInstance()->printActiveCoroutines();
+
LL_INFOS() << "Cleaning up Selections" << LL_ENDL;
// Clean up selection managers after UI is destroyed, as UI may be observing them.
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index 7413dbed20..7c7f55f68c 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -286,6 +286,9 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
&& regionp->getRenderInfoReportTimer().hasExpired() // Time to make request)
)
{
+ // make sure we won't re-report, coro will update timer with correct time later
+ regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS);
+
std::string coroname =
LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
@@ -306,6 +309,9 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
<< " from " << url
<< LL_ENDL;
+ // make sure we won't re-request, coro will update timer with correct time later
+ regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);
+
// First send a request to get the latest data
std::string coroname =
LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 8f1641e908..487496df9a 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -62,13 +62,10 @@
#if LL_DARWIN
const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_mac.%s.txt";
#elif LL_LINUX
const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_linux.%s.txt";
#else
const char FEATURE_TABLE_FILENAME[] = "featuretable.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable.%s.txt";
#endif
#if 0 // consuming code in #if 0 below
@@ -273,33 +270,11 @@ bool LLFeatureManager::loadFeatureTables()
app_path += gDirUtilp->getDirDelimiter();
std::string filename;
- std::string http_filename;
filename = FEATURE_TABLE_FILENAME;
- http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
app_path += filename;
- // second table is downloaded with HTTP - note that this will only be used on the run _after_ it is downloaded
- std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
-
- // use HTTP table if it exists
- std::string path;
- bool parse_ok = false;
- if (gDirUtilp->fileExists(http_path))
- {
- parse_ok = parseFeatureTable(http_path);
- if (!parse_ok)
- {
- // the HTTP table failed to parse, so delete it
- LLFile::remove(http_path);
- LL_WARNS("RenderInit") << "Removed invalid feature table '" << http_path << "'" << LL_ENDL;
- }
- }
-
- if (!parse_ok)
- {
- parse_ok = parseFeatureTable(app_path);
- }
+ bool parse_ok = parseFeatureTable(app_path);
return parse_ok;
}
@@ -495,70 +470,6 @@ bool LLFeatureManager::loadGPUClass()
return true; // indicates that a gpu value was established
}
-void LLFeatureManager::fetchFeatureTableCoro(std::string tableName)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FeatureManagerHTTPTable", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-
- const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
-
-
-#if LL_WINDOWS
- std::string os_string = LLOSInfo::instance().getOSStringSimple();
- std::string filename;
-
- if (os_string.find("Microsoft Windows XP") == 0)
- {
- filename = llformat(tableName.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
- }
- else
- {
- filename = llformat(tableName.c_str(), "", LLVersionInfo::getVersion().c_str());
- }
-#else
- const std::string filename = llformat(tableName.c_str(), LLVersionInfo::getVersion().c_str());
-#endif
-
- std::string url = base + "/" + filename;
- // testing url below
- //url = "http://viewer-settings.secondlife.com/featuretable.2.1.1.208406.txt";
- const std::string path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
-
-
- LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL;
-
- LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status)
- { // There was a newer feature table on the server. We've grabbed it and now should write it.
- // write to file
- const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
-
- LL_INFOS() << "writing feature table to " << path << LL_ENDL;
-
- S32 size = raw.size();
- if (size > 0)
- {
- // write to file
- LLAPRFile out(path, LL_APR_WB);
- out.write(raw.data(), size);
- out.close();
- }
- }
-}
-
-// fetch table(s) from a website (S3)
-void LLFeatureManager::fetchHTTPTables()
-{
- LLCoros::instance().launch("LLFeatureManager::fetchFeatureTableCoro",
- boost::bind(&LLFeatureManager::fetchFeatureTableCoro, this, FEATURE_TABLE_VER_FILENAME));
-}
-
void LLFeatureManager::cleanupFeatureTables()
{
std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 54bd07329a..f77861a1a7 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -145,9 +145,6 @@ public:
// in the skip list if true
void applyFeatures(bool skipFeatures);
- // load the dynamic GPU/feature table from a website
- void fetchHTTPTables();
-
LLSD getRecommendedSettingsMap();
protected:
@@ -158,8 +155,6 @@ protected:
void initBaseMask();
- void fetchFeatureTableCoro(std::string name);
-
std::map<std::string, LLFeatureList *> mMaskList;
std::set<std::string> mSkippedFeatures;
BOOL mInited;
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 9fb53dc9ab..0f38cca56f 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -263,7 +263,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
addEntry(DAD_CLOTHING, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_OBJECT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv, &LLToolDragAndDrop::dad3dGiveInventoryObject, &LLToolDragAndDrop::dad3dRezObjectOnObject, &LLToolDragAndDrop::dad3dRezObjectOnLand));
addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dUpdateInventoryCategory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dRezCategoryOnObject, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
@@ -2335,6 +2335,21 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory(
return rv;
}
+
+EAcceptance LLToolDragAndDrop::dad3dRezCategoryOnObject(
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ if ((mask & MASK_CONTROL))
+ {
+ return dad3dUpdateInventoryCategory(obj, face, mask, drop);
+ }
+ else
+ {
+ return ACCEPT_NO;
+ }
+}
+
+
BOOL LLToolDragAndDrop::dadUpdateInventoryCategory(LLViewerObject* obj,
BOOL drop)
{
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 2d99de2244..24a712029c 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -162,6 +162,8 @@ protected:
MASK mask, BOOL drop);
EAcceptance dad3dRezObjectOnObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
+ EAcceptance dad3dRezCategoryOnObject(LLViewerObject* obj, S32 face,
+ MASK mask, BOOL drop);
EAcceptance dad3dRezScript(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face,