From 65d608cdac701ab10f84bd8dc4a6c0be7eef26f1 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 5 Aug 2016 14:02:12 -0400 Subject: [PATCH 01/21] MAINT-6584: Clarify LLKDUMessageError::flush() throwing exception. --- indra/llkdu/llimagej2ckdu.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 9347e51b85..2adb90320c 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -165,6 +165,12 @@ struct LLKDUMessageError : public LLKDUMessage // terminating handler→flush call." // So throwing an exception here isn't arbitrary: we MUST throw an // exception if we want to recover from a KDU error. + // Because this confused me: the above quote specifically refers to + // the kdu_error class, which is constructed internally within KDU at + // the point where a fatal error is discovered and reported. It is NOT + // talking about the kdu_message subclass passed to + // kdu_customize_errors(). Destroying this static object at program + // shutdown will NOT engage the behavior described above. if (end_of_message) { throw "KDU throwing an exception"; From a5ce63eb3c4a3f3ea57ca2a353954a2afd43fc72 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 5 Aug 2016 17:44:13 -0400 Subject: [PATCH 02/21] MAINT-6584: Add explanatory comments to LLImageJ2CKDU implementation. These comments are inherently fragile, in that they enumerate all present callers of certain methods. Adding, removing or relocating calls would invalidate these comments. However, the LLImageJ2CKDU implementation is probably pretty stable by now. --- indra/llkdu/llimagej2ckdu.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 2adb90320c..1201170f6d 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -202,6 +202,10 @@ LLImageJ2CKDU::~LLImageJ2CKDU() // Stuff for new simple decode void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision); +// This is called by the real (private) initDecode() (keep_codestream true) +// and getMetadata() methods (keep_codestream false). As far as nat can tell, +// mode is always MODE_FAST. It was called by findDiscardLevelsBoundaries() +// as well, when that still existed, with keep_codestream true and MODE_FAST. void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode) { S32 data_size = base.getDataSize(); @@ -212,6 +216,12 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod // mCodeStreamp.reset(); + // It's not clear to nat under what circumstances we would reuse a + // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of + // two U32s and a pointer, so it's not as if it would be a huge overhead + // to allocate a new one every time. + // Also -- why is base.getData() tested specifically here? If that returns + // NULL, shouldn't we bail out of the whole method? if (!mInputp && base.getData()) { // The compressed data has been loaded @@ -301,6 +311,9 @@ void LLImageJ2CKDU::cleanupCodeStream() mTileIndicesp.reset(); } +// This is the protected virtual method called by LLImageJ2C::initDecode(). +// However, as far as nat can tell, LLImageJ2C::initDecode() is called only by +// llimage_libtest.cpp's load_image() function. No detectable production use. bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) { return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region); @@ -333,6 +346,9 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc return true; } +// This is the real (private) initDecode() called both by the protected +// initDecode() method and by decodeImpl(). As far as nat can tell, only the +// decodeImpl() usage matters for production. bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region) { base.resetLastError(); From 80adc9b6aa9814c74fd0c67c5de9d1765a089925 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 5 Aug 2016 17:57:24 -0400 Subject: [PATCH 03/21] MAINT-6584: Introduce KDUError exception from other viewer project. Specifically, manually apply changesets b4db8a8 and b98371d from nat_linden/viewer-mac-mainloop. We need to throw from a new place, but if we threw const char* (current convention), the new throw wouldn't be patched when we merge to new exception convention. --- indra/llkdu/llimagej2ckdu.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 1201170f6d..ba1560ec56 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -34,6 +34,15 @@ #include "kdu_block_coding.h" +#include + +namespace { +struct KDUError: public std::runtime_error +{ + KDUError(const std::string& msg): std::runtime_error(msg) {} +}; +} // anonymous namespace + class kdc_flow_control { public: @@ -173,7 +182,7 @@ struct LLKDUMessageError : public LLKDUMessage // shutdown will NOT engage the behavior described above. if (end_of_message) { - throw "KDU throwing an exception"; + throw KDUError("LLKDUMessageError::flush()"); } } }; @@ -406,9 +415,9 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco mTPosp->x = 0; } } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return false; } catch (...) @@ -502,9 +511,9 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco return false; } } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); base.decodeFailed(); cleanupCodeStream(); return true; // done @@ -695,9 +704,9 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co base.updateData(); // set width, height delete[] output_buffer; } - catch(const char* msg) + catch(const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return false; } catch( ... ) @@ -719,9 +728,9 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) setupCodeStream(base, false, MODE_FAST); return true; } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return false; } catch (...) From 1773f44b6d9fffa7f5d0b2449184b2998e99be5a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 6 Aug 2016 11:39:11 -0400 Subject: [PATCH 04/21] MAINT-6584: Don't crash on inconsistent dims in a JPEG-2000 image. Previous code would crump with LL_ERRS. But a bad image file should fail only the image load -- not crash the viewer. While at it, validate all components present, not just 0, 1, 2. While at it, make the failure message report which component and what the mismatched dimensions are, not just "Components don't have matching dimensions!" --- indra/llkdu/llimagej2ckdu.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index ba1560ec56..025c77b85e 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -31,18 +31,31 @@ #include "llpointer.h" #include "llmath.h" #include "llkdumem.h" +#include "stringize.h" #include "kdu_block_coding.h" #include +#include namespace { +// exception used to keep KDU from terminating entire program -- see comments +// in LLKDUMessageError::flush() struct KDUError: public std::runtime_error { - KDUError(const std::string& msg): std::runtime_error(msg) {} + KDUError(const std::string& msg): std::runtime_error(msg) {} }; } // anonymous namespace +// stream kdu_dims to std::ostream +// Turns out this must NOT be in the anonymous namespace! +inline +std::ostream& operator<<(std::ostream& out, const kdu_dims& dims) +{ + return out << "(" << dims.pos.x << "," << dims.pos.y << ")," + "[" << dims.size.x << "x" << dims.size.y << "]"; +} + class kdc_flow_control { public: @@ -287,13 +300,19 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod S32 components = mCodeStreamp->get_num_components(); - if (components >= 3) - { // Check that components have consistent dimensions (for PPM file) - kdu_dims dims1; mCodeStreamp->get_dims(1,dims1); - kdu_dims dims2; mCodeStreamp->get_dims(2,dims2); - if ((dims1 != dims) || (dims2 != dims)) + // Check that components have consistent dimensions (for PPM file) + for (int idx = 1; idx < components; ++idx) + { + kdu_dims other_dims; + mCodeStreamp->get_dims(idx, other_dims); + if (other_dims != dims) { - LL_ERRS() << "Components don't have matching dimensions!" << LL_ENDL; + // This method is only called from methods that catch KDUError. + // We want to fail the image load, not crash the viewer. + throw KDUError(STRINGIZE("Component " << idx << " dimensions " + << other_dims + << " do not match component 0 dimensions " + << dims << "!")); } } From d4b1db277ca538781661bf474b733296156e5728 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Tue, 9 Aug 2016 05:07:39 +0300 Subject: [PATCH 05/21] MAINT-6618 Fixed the crash in LLImageRaw::scale() + some additional checks --- indra/llimage/llimage.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 91fa8c6ad1..c7f02a6b1a 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -942,6 +942,12 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a) { llassert( getComponents() <= 4 ); // This is fairly bogus, but it'll do for now. + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } + U8 *pos = getData(); U32 x, y; for (x = 0; x < getWidth(); x++) @@ -1136,7 +1142,6 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src ) llassert( (3 == src->getComponents()) || (4 == src->getComponents()) ); llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); - U8* src_data = src->getData(); U8* dst_data = dst->getData(); S32 pixels = getWidth() * getHeight(); @@ -1193,6 +1198,12 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) // Fill the buffer with a constant color void LLImageRaw::fill( const LLColor4U& color ) { + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } + S32 pixels = getWidth() * getHeight(); if( 4 == getComponents() ) { @@ -1403,6 +1414,12 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data ) { llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) ); + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return false; + } + S32 old_width = getWidth(); S32 old_height = getHeight(); From 5e02d304f03dd6adcb99f422e3a9a67eb262b2a1 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Tue, 9 Aug 2016 19:26:30 +0300 Subject: [PATCH 06/21] MAINT-6618 More checks --- indra/llimage/llimage.cpp | 41 +++++++++++++++++++++++++++++++++++---- indra/llimage/llimage.h | 3 +++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index c7f02a6b1a..feb97ec2ab 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1075,6 +1075,11 @@ void LLImageRaw::composite( LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + if (!validateSrcAndDst("LLImageRaw::composite", src, dst)) + { + return; + } + llassert(3 == src->getComponents()); llassert(3 == dst->getComponents()); @@ -1176,6 +1181,11 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) { LLImageRaw* dst = this; // Just for clarity. + if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst)) + { + return; + } + llassert( 1 == src->getComponents() ); llassert( 4 == dst->getComponents() ); llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); @@ -1242,14 +1252,13 @@ LLPointer LLImageRaw::duplicate() // Src and dst can be any size. Src and dst can each have 3 or 4 components. void LLImageRaw::copy(LLImageRaw* src) { - if (!src) + LLImageRaw* dst = this; // Just for clarity. + + if (!validateSrcAndDst("LLImageRaw::copy", src, dst)) { - LL_WARNS() << "LLImageRaw::copy called with a null src pointer" << LL_ENDL; return; } - LLImageRaw* dst = this; // Just for clarity. - if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) { // No scaling needed @@ -1376,6 +1385,11 @@ void LLImageRaw::copyScaled( LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst)) + { + return; + } + llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) ); llassert_always( src->getComponents() == dst->getComponents() ); @@ -1709,6 +1723,25 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3 } } +bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst) +{ + if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid()) + { + LL_WARNS() << func << ": Source: "; + if (!src) LL_CONT << "Null pointer"; + else if (src->isBufferInvalid()) LL_CONT << "Invalid buffer"; + else LL_CONT << "OK"; + + LL_CONT << "; Destination: "; + if (!dst) LL_CONT << "Null pointer"; + else if (dst->isBufferInvalid()) LL_CONT << "Invalid buffer"; + else LL_CONT << "OK"; + LL_CONT << "." << LL_ENDL; + + return false; + } + return true; +} //---------------------------------------------------------------------------- diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index adc650d360..9cc7431a9c 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -277,6 +277,9 @@ protected: public: static S32 sGlobalRawMemory; static S32 sRawImageCount; + +private: + bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst); }; // Compressed representation of image. From e3c58f74781186f084f60b35b931c5bb5d75e1ba Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 10 Aug 2016 19:02:57 +0300 Subject: [PATCH 07/21] MAINT-6554 reducing log spam --- indra/newview/llvovolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 50ccb2f74a..4aef6480cb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4451,7 +4451,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LL_RECORD_BLOCK_TIME(FTM_REGISTER_FACE); if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)) { - LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; + LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; } if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) From 529778219388a445075880e86bc0e846004952c7 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 15 Aug 2016 17:05:23 +0300 Subject: [PATCH 08/21] MAINT-6634 "My graphics driver is out of date" was listed 3 times in Alerts --- indra/newview/llappviewer.cpp | 12 +++-- .../skins/default/xui/en/notifications.xml | 45 ++----------------- .../newview/skins/default/xui/en/strings.xml | 6 +++ 3 files changed, 18 insertions(+), 45 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 950692a788..e1242513e1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1124,17 +1124,23 @@ bool LLAppViewer::init() #if LL_WINDOWS if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion()) { + std::string url; if (gGLManager.mIsIntel) { - LLNotificationsUtil::add("IntelOldDriver"); + url = LLTrans::getString("IntelDriverPage"); } else if (gGLManager.mIsNVIDIA) { - LLNotificationsUtil::add("NVIDIAOldDriver"); + url = LLTrans::getString("NVIDIADriverPage"); } else if (gGLManager.mIsATI) { - LLNotificationsUtil::add("AMDOldDriver"); + url = LLTrans::getString("AMDDriverPage"); + } + + if (!url.empty()) + { + LLNotificationsUtil::add("OldGPUDriver", LLSD().with("URL", url)); } } #endif diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 54e90ac496..6fdeedc8ae 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1638,14 +1638,14 @@ Visit [_URL] for more information? There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. - Visit [_URL] to check for driver updates? + Visit [URL] to check for driver updates? confirm - http://www.intel.com/p/en_US/support/detect/graphics + [URL] fail - - There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. - - Visit [_URL] to check for driver updates? - confirm - - http://support.amd.com/us/Pages/AMDSupportHub.aspx - - - fail - - - - There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. - - Visit [_URL] to check for driver updates? - confirm - - http://www.nvidia.com/Download/index.aspx?lang=en-us - - - fail - - - Multiple Media Play/Pause Media + + http://www.intel.com/p/en_US/support/detect/graphics + http://www.nvidia.com/Download/index.aspx?lang=en-us + http://support.amd.com/us/Pages/AMDSupportHub.aspx + + An error was found parsing the command line. From 5b94ed9f4e8bff5d2079b012434d16df4ab27397 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 15 Aug 2016 20:01:56 +0300 Subject: [PATCH 09/21] MAINT-6634 fixed string --- indra/newview/llappviewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e1242513e1..64bc7fb2c4 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1131,7 +1131,7 @@ bool LLAppViewer::init() } else if (gGLManager.mIsNVIDIA) { - url = LLTrans::getString("NVIDIADriverPage"); + url = LLTrans::getString("NvidiaDriverPage"); } else if (gGLManager.mIsATI) { From b25ee9095deca0cd0c7eedafda89e021734d0ca7 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 15 Aug 2016 14:13:56 -0400 Subject: [PATCH 10/21] Remove VSTool, its build info and all invocations. VSTool manipulates the SecondLife.sln solution file for the convenience of a developer subsequently running Visual Studio interactively. But the cost of having it sometimes break TeamCity automated builds is too high -- especially since we never expect to run Visual Studio interactively on a TC build host. Also remove the CMake UNATTENDED variable that controlled it. --- autobuild.xml | 34 -- indra/cmake/Variables.cmake | 1 - indra/newview/CMakeLists.txt | 15 - indra/tools/vstool/DispatchUtility.cs | 271 ---------- indra/tools/vstool/README.txt | 9 - indra/tools/vstool/VSTool.csproj | 98 ---- indra/tools/vstool/VSTool.exe | Bin 24576 -> 0 bytes indra/tools/vstool/VSTool.sln | 19 - indra/tools/vstool/app.config | 3 - indra/tools/vstool/main.cs | 729 -------------------------- 10 files changed, 1179 deletions(-) delete mode 100644 indra/tools/vstool/DispatchUtility.cs delete mode 100644 indra/tools/vstool/README.txt delete mode 100755 indra/tools/vstool/VSTool.csproj delete mode 100755 indra/tools/vstool/VSTool.exe delete mode 100755 indra/tools/vstool/VSTool.sln delete mode 100644 indra/tools/vstool/app.config delete mode 100755 indra/tools/vstool/main.cs diff --git a/autobuild.xml b/autobuild.xml index 072dfa678a..5a91ba15f5 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -2617,14 +2617,6 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - RelWithDebInfo - --startup - secondlife-bin options @@ -2663,20 +2655,11 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - RelWithDebInfo - --startup - secondlife-bin options -G "Visual Studio 12" - -DUNATTENDED:BOOL=ON -DINSTALL_PROPRIETARY=FALSE -DUSE_KDU=FALSE @@ -2705,14 +2688,6 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - Release - --startup - secondlife-bin options @@ -2749,20 +2724,11 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - Release - --startup - secondlife-bin options -G "Visual Studio 12" - -DUNATTENDED:BOOL=ON -DINSTALL_PROPRIETARY=FALSE -DUSE_KDU=FALSE diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 63e296b556..8292a0c63d 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -164,7 +164,6 @@ set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside") set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.") -set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.") set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.") diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index dce0ea73cd..586a56b49a 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1799,21 +1799,6 @@ if (WINDOWS) windows-crash-logger ) - # sets the 'working directory' for debugging from visual studio. - if (NOT UNATTENDED) - add_custom_command( - TARGET ${VIEWER_BINARY_NAME} POST_BUILD - COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe - ARGS - --solution - ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln - --workingdir - ${VIEWER_BINARY_NAME} - "${CMAKE_CURRENT_SOURCE_DIR}" - COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging." - ) - endif (NOT UNATTENDED) - if (PACKAGE) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2 diff --git a/indra/tools/vstool/DispatchUtility.cs b/indra/tools/vstool/DispatchUtility.cs deleted file mode 100644 index 6056ac55a1..0000000000 --- a/indra/tools/vstool/DispatchUtility.cs +++ /dev/null @@ -1,271 +0,0 @@ -#region Using Directives - -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; -using System.Reflection; -using System.Security.Permissions; - -#endregion - -namespace TestDispatchUtility -{ - /// - /// Provides helper methods for working with COM IDispatch objects that have a registered type library. - /// - public static class DispatchUtility - { - #region Private Constants - - private const int S_OK = 0; //From WinError.h - private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800 - - #endregion - - #region Public Methods - - /// - /// Gets whether the specified object implements IDispatch. - /// - /// An object to check. - /// True if the object implements IDispatch. False otherwise. - public static bool ImplementsIDispatch(object obj) - { - bool result = obj is IDispatchInfo; - return result; - } - - /// - /// Gets a Type that can be used with reflection. - /// - /// An object that implements IDispatch. - /// Whether an exception should be thrown if a Type can't be obtained. - /// A .NET Type that can be used with reflection. - /// If doesn't implement IDispatch. - [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] - public static Type GetType(object obj, bool throwIfNotFound) - { - RequireReference(obj, "obj"); - Type result = GetType((IDispatchInfo)obj, throwIfNotFound); - return result; - } - - /// - /// Tries to get the DISPID for the requested member name. - /// - /// An object that implements IDispatch. - /// The name of a member to lookup. - /// If the method returns true, this holds the DISPID on output. - /// If the method returns false, this value should be ignored. - /// True if the member was found and resolved to a DISPID. False otherwise. - /// If doesn't implement IDispatch. - [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] - public static bool TryGetDispId(object obj, string name, out int dispId) - { - RequireReference(obj, "obj"); - bool result = TryGetDispId((IDispatchInfo)obj, name, out dispId); - return result; - } - - /// - /// Invokes a member by DISPID. - /// - /// An object that implements IDispatch. - /// The DISPID of a member. This can be obtained using - /// . - /// The arguments to pass to the member. - /// The member's return value. - /// - /// This can invoke a method or a property get accessor. - /// - public static object Invoke(object obj, int dispId, object[] args) - { - string memberName = "[DispId=" + dispId + "]"; - object result = Invoke(obj, memberName, args); - return result; - } - - /// - /// Invokes a member by name. - /// - /// An object. - /// The name of the member to invoke. - /// The arguments to pass to the member. - /// The member's return value. - /// - /// This can invoke a method or a property get accessor. - /// - public static object Invoke(object obj, string memberName, object[] args) - { - RequireReference(obj, "obj"); - Type type = obj.GetType(); - object result = type.InvokeMember(memberName, BindingFlags.InvokeMethod | BindingFlags.GetProperty, - null, obj, args, null); - return result; - } - - #endregion - - #region Private Methods - - /// - /// Requires that the value is non-null. - /// - /// The type of the value. - /// The value to check. - /// The name of the value. - private static void RequireReference(T value, string name) where T : class - { - if (value == null) - { - throw new ArgumentNullException(name); - } - } - - /// - /// Gets a Type that can be used with reflection. - /// - /// An object that implements IDispatch. - /// Whether an exception should be thrown if a Type can't be obtained. - /// A .NET Type that can be used with reflection. - private static Type GetType(IDispatchInfo dispatch, bool throwIfNotFound) - { - RequireReference(dispatch, "dispatch"); - - Type result = null; - int typeInfoCount; - int hr = dispatch.GetTypeInfoCount(out typeInfoCount); - if (hr == S_OK && typeInfoCount > 0) - { - // Type info isn't usually culture-aware for IDispatch, so we might as well pass - // the default locale instead of looking up the current thread's LCID each time - // (via CultureInfo.CurrentCulture.LCID). - dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result); - } - - if (result == null && throwIfNotFound) - { - // If the GetTypeInfoCount called failed, throw an exception for that. - Marshal.ThrowExceptionForHR(hr); - - // Otherwise, throw the same exception that Type.GetType would throw. - throw new TypeLoadException(); - } - - return result; - } - - /// - /// Tries to get the DISPID for the requested member name. - /// - /// An object that implements IDispatch. - /// The name of a member to lookup. - /// If the method returns true, this holds the DISPID on output. - /// If the method returns false, this value should be ignored. - /// True if the member was found and resolved to a DISPID. False otherwise. - private static bool TryGetDispId(IDispatchInfo dispatch, string name, out int dispId) - { - RequireReference(dispatch, "dispatch"); - RequireReference(name, "name"); - - bool result = false; - - // Members names aren't usually culture-aware for IDispatch, so we might as well - // pass the default locale instead of looking up the current thread's LCID each time - // (via CultureInfo.CurrentCulture.LCID). - Guid iidNull = Guid.Empty; - int hr = dispatch.GetDispId(ref iidNull, ref name, 1, LOCALE_SYSTEM_DEFAULT, out dispId); - - const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006); //From WinError.h - const int DISPID_UNKNOWN = -1; //From OAIdl.idl - if (hr == S_OK) - { - result = true; - } - else if (hr == DISP_E_UNKNOWNNAME && dispId == DISPID_UNKNOWN) - { - // This is the only supported "error" case because it means IDispatch - // is saying it doesn't know the member we asked about. - result = false; - } - else - { - // The other documented result codes are all errors. - Marshal.ThrowExceptionForHR(hr); - } - - return result; - } - - #endregion - - #region Private Interfaces - - /// - /// A partial declaration of IDispatch used to lookup Type information and DISPIDs. - /// - /// - /// This interface only declares the first three methods of IDispatch. It omits the - /// fourth method (Invoke) because there are already plenty of ways to do dynamic - /// invocation in .NET. But the first three methods provide dynamic type metadata - /// discovery, which .NET doesn't provide normally if you have a System.__ComObject - /// RCW instead of a strongly-typed RCW. - /// - /// Note: The original declaration of IDispatch is in OAIdl.idl. - /// - [ComImport] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [Guid("00020400-0000-0000-C000-000000000046")] - private interface IDispatchInfo - { - /// - /// Gets the number of Types that the object provides (0 or 1). - /// - /// Returns 0 or 1 for the number of Types provided by . - /// - /// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85) - /// - [PreserveSig] - int GetTypeInfoCount(out int typeInfoCount); - - /// - /// Gets the Type information for an object if returned 1. - /// - /// Must be 0. - /// Typically, LOCALE_SYSTEM_DEFAULT (2048). - /// Returns the object's Type information. - /// - /// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85) - /// - void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler, - MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo); - - /// - /// Gets the DISPID of the specified member name. - /// - /// Must be IID_NULL. Pass a copy of Guid.Empty. - /// The name of the member to look up. - /// Must be 1. - /// Typically, LOCALE_SYSTEM_DEFAULT (2048). - /// If a member with the requested - /// is found, this returns its DISPID and the method's return value is 0. - /// If the method returns a non-zero value, then this parameter's output value is - /// undefined. - /// Zero for success. Non-zero for failure. - /// - /// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85) - /// - [PreserveSig] - int GetDispId(ref Guid riid, ref string name, int nameCount, int lcid, out int dispId); - - // NOTE: The real IDispatch also has an Invoke method next, but we don't need it. - // We can invoke methods using .NET's Type.InvokeMember method with the special - // [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo - // and invoke methods on that through reflection. - // Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx - } - - #endregion - } -} diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt deleted file mode 100644 index e419180031..0000000000 --- a/indra/tools/vstool/README.txt +++ /dev/null @@ -1,9 +0,0 @@ -VSTool is a command line utility to manipulate VisualStudio settings. - -The windows cmake project configuration uses VSTool.exe - -A handy upgrade: - figure out how to make cmake build this csharp app - - or write the app using script (jscript?!?) so it doesn't need to be built. - - diff --git a/indra/tools/vstool/VSTool.csproj b/indra/tools/vstool/VSTool.csproj deleted file mode 100755 index 7f431e85c7..0000000000 --- a/indra/tools/vstool/VSTool.csproj +++ /dev/null @@ -1,98 +0,0 @@ - - - - Local - 8.0.50727 - 2.0 - {96943E2D-1373-4617-A117-D0F997A94919} - Debug - AnyCPU - - - - - VSTool - - - JScript - Grid - IE50 - false - Exe - VSTool - Always - VSTool.VSToolMain - - - - - v2.0 - 2.0 - - - .\ - false - 285212672 - false - - - DEBUG;TRACE - - - true - 4096 - false - - - false - false - false - false - 4 - full - prompt - - - .\ - false - 285212672 - false - - - TRACE - - - false - 4096 - false - - - true - false - false - false - 4 - none - prompt - - - - System - - - System.Data - - - - - Code - - - - - - - - - - \ No newline at end of file diff --git a/indra/tools/vstool/VSTool.exe b/indra/tools/vstool/VSTool.exe deleted file mode 100755 index 854290b90ad1c9ed8676919a9c144d05330cb245..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24576 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 diff --git a/indra/tools/vstool/VSTool.sln b/indra/tools/vstool/VSTool.sln deleted file mode 100755 index 21e3d75971..0000000000 --- a/indra/tools/vstool/VSTool.sln +++ /dev/null @@ -1,19 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSTool", "VSTool.csproj", "{96943E2D-1373-4617-A117-D0F997A94919}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.Build.0 = Debug|Any CPU - {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.ActiveCfg = Release|Any CPU - {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/indra/tools/vstool/app.config b/indra/tools/vstool/app.config deleted file mode 100644 index 8494f728ff..0000000000 --- a/indra/tools/vstool/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/indra/tools/vstool/main.cs b/indra/tools/vstool/main.cs deleted file mode 100755 index ef2e582b90..0000000000 --- a/indra/tools/vstool/main.cs +++ /dev/null @@ -1,729 +0,0 @@ -// Code about getting running instances visual studio -// was borrowed from -// http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx - - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; -using Microsoft.CSharp; - -namespace VSTool -{ - // The MessageFilter class comes from: - // http://msdn.microsoft.com/en-us/library/ms228772(VS.80).aspx - // It allows vstool to get timing error messages from - // visualstudio and handle them. - public class MessageFilter : IOleMessageFilter - { - // - // Class containing the IOleMessageFilter - // thread error-handling functions. - - // Start the filter. - public static void Register() - { - IOleMessageFilter newFilter = new MessageFilter(); - IOleMessageFilter oldFilter = null; - CoRegisterMessageFilter(newFilter, out oldFilter); - } - - // Done with the filter, close it. - public static void Revoke() - { - IOleMessageFilter oldFilter = null; - CoRegisterMessageFilter(null, out oldFilter); - } - - // - // IOleMessageFilter functions. - // Handle incoming thread requests. - int IOleMessageFilter.HandleInComingCall(int dwCallType, - System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr - lpInterfaceInfo) - { - //Return the flag SERVERCALL_ISHANDLED. - return 0; - } - - // Thread call was rejected, so try again. - int IOleMessageFilter.RetryRejectedCall(System.IntPtr - hTaskCallee, int dwTickCount, int dwRejectType) - { - if (dwRejectType == 2) - // flag = SERVERCALL_RETRYLATER. - { - // Retry the thread call immediately if return >=0 & - // <100. - return 99; - } - // Too busy; cancel call. - return -1; - } - - int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, - int dwTickCount, int dwPendingType) - { - //Return the flag PENDINGMSG_WAITDEFPROCESS. - return 2; - } - - // Implement the IOleMessageFilter interface. - [DllImport("Ole32.dll")] - private static extern int - CoRegisterMessageFilter(IOleMessageFilter newFilter, out - IOleMessageFilter oldFilter); - } - - [ComImport(), Guid("00000016-0000-0000-C000-000000000046"), - InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] - interface IOleMessageFilter - { - [PreserveSig] - int HandleInComingCall( - int dwCallType, - IntPtr hTaskCaller, - int dwTickCount, - IntPtr lpInterfaceInfo); - - [PreserveSig] - int RetryRejectedCall( - IntPtr hTaskCallee, - int dwTickCount, - int dwRejectType); - - [PreserveSig] - int MessagePending( - IntPtr hTaskCallee, - int dwTickCount, - int dwPendingType); - } - - class ViaCOM - { - public static object GetProperty(object from_obj, string prop_name) - { - try - { - Type objType = from_obj.GetType(); - return objType.InvokeMember( - prop_name, - BindingFlags.GetProperty, null, - from_obj, - null); - } - catch (Exception e) - { - Console.WriteLine("Error getting property: \"{0}\"", prop_name); - Console.WriteLine(e.Message); - throw e; - } - } - - public static object SetProperty(object from_obj, string prop_name, object new_value) - { - try - { - object[] args = { new_value }; - Type objType = from_obj.GetType(); - return objType.InvokeMember( - prop_name, - BindingFlags.DeclaredOnly | - BindingFlags.Public | - BindingFlags.NonPublic | - BindingFlags.Instance | - BindingFlags.SetProperty, - null, - from_obj, - args); - } - catch (Exception e) - { - Console.WriteLine("Error setting property: \"{0}\"", prop_name); - Console.WriteLine(e.Message); - throw e; - } - } - - public static object CallMethod(object from_obj, string method_name, params object[] args) - { - try - { - Type objType = from_obj.GetType(); - return objType.InvokeMember( - method_name, - BindingFlags.DeclaredOnly | - BindingFlags.Public | - BindingFlags.NonPublic | - BindingFlags.Instance | - BindingFlags.InvokeMethod, - null, - from_obj, - args); - } - catch (Exception e) - { - Console.WriteLine("Error calling method \"{0}\"", method_name); - Console.WriteLine(e.Message); - throw e; - } - } - }; - - /// - /// The main entry point class for VSTool. - /// - class VSToolMain - { - #region Interop imports - [DllImport("ole32.dll")] - public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); - - [DllImport("ole32.dll")] - public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc); - #endregion - - static System.Boolean ignore_case = true; - - static string solution_name = null; - static bool use_new_vs = false; - static Hashtable projectDict = new Hashtable(); - static string startup_project = null; - static string config = null; - - static object dte = null; - static object solution = null; - - /// - /// The main entry point for the application. - /// - [STAThread] - static int Main(string[] args) - { - int retVal = 0; - bool need_save = false; - - try - { - parse_command_line(args); - - Console.WriteLine("Editing solution: {0}", solution_name); - - bool found_open_solution = GetDTEAndSolution(); - - if (dte == null || solution == null) - { - retVal = 1; - } - else - { - MessageFilter.Register(); - - // Walk through all of the projects in the solution - // and list the type of each project. - foreach (DictionaryEntry p in projectDict) - { - string project_name = (string)p.Key; - string working_dir = (string)p.Value; - if (SetProjectWorkingDir(solution, project_name, working_dir)) - { - need_save = true; - } - } - - if (config != null) - { - need_save = SetActiveConfig(config); - } - - if (startup_project != null) - { - need_save = SetStartupProject(startup_project); - } - - if (need_save) - { - if (found_open_solution == false) - { - ViaCOM.CallMethod(solution, "Close", null); - } - } - } - } - catch (Exception e) - { - Console.WriteLine(e.Message); - retVal = 1; - } - finally - { - if (solution != null) - { - Marshal.ReleaseComObject(solution); - solution = null; - } - - if (dte != null) - { - Marshal.ReleaseComObject(dte); - dte = null; - } - - MessageFilter.Revoke(); - } - return retVal; - } - - public static bool parse_command_line(string[] args) - { - string options_desc = - "--solution : MSVC solution name. (required)\n" + - "--use_new_vs : Ignore running versions of visual studio.\n" + - "--workingdir : Set working dir of a VC project.\n" + - "--config : Set the active config for the solution.\n" + - "--startup : Set the startup project for the solution.\n"; - - try - { - // Command line param parsing loop. - int i = 0; - for (; i < args.Length; ++i) - { - if ("--solution" == args[i]) - { - if (solution_name != null) - { - throw new ApplicationException("Found second --solution option"); - } - solution_name = args[++i]; - } - else if ("--use_new_vs" == args[i]) - { - use_new_vs = true; - } - - else if ("--workingdir" == args[i]) - { - string project_name = args[++i]; - string working_dir = args[++i]; - projectDict.Add(project_name, working_dir); - } - else if ("--config" == args[i]) - { - if (config != null) - { - throw new ApplicationException("Found second --config option"); - } - config = args[++i]; - } - else if ("--startup" == args[i]) - { - if (startup_project != null) - { - throw new ApplicationException("Found second --startup option"); - } - startup_project = args[++i]; - } - else - { - throw new ApplicationException("Found unrecognized token on command line: " + args[i]); - } - } - - if (solution_name == null) - { - throw new ApplicationException("The --solution option is required."); - } - } - catch(ApplicationException e) - { - - Console.WriteLine("Oops! " + e.Message); - Console.Write("Command line:"); - foreach (string arg in args) - { - Console.Write(" " + arg); - } - Console.Write("\n\n"); - Console.WriteLine("VSTool command line usage"); - Console.Write(options_desc); - throw e; - } - return true; - } - - public static bool GetDTEAndSolution() - { - bool found_open_solution = true; - - Console.WriteLine("Looking for existing VisualStudio instance..."); - - // Get an instance of the currently running Visual Studio .NET IDE. - // dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1"); - string full_solution_name = System.IO.Path.GetFullPath(solution_name); - if (false == use_new_vs) - { - dte = GetIDEInstance(full_solution_name); - } - - if (dte == null) - { - try - { - Console.WriteLine(" Didn't find open solution, starting new background VisualStudio instance..."); - Console.WriteLine(" Reading .sln file version..."); - string version = GetSolutionVersion(full_solution_name); - - Console.WriteLine(" Using version: {0}...", version); - string progid = GetVSProgID(version); - - Type objType = Type.GetTypeFromProgID(progid); - dte = System.Activator.CreateInstance(objType); - Console.WriteLine(" Reading solution: \"{0}\"", full_solution_name); - - solution = ViaCOM.GetProperty(dte, "Solution"); - object[] openArgs = { full_solution_name }; - ViaCOM.CallMethod(solution, "Open", openArgs); - } - catch (Exception e) - { - Console.WriteLine(e.Message); - Console.WriteLine("Quitting do to error opening: {0}", full_solution_name); - solution = null; - dte = null; - return found_open_solution; - } - found_open_solution = false; - } - - if (solution == null) - { - solution = ViaCOM.GetProperty(dte, "Solution"); - } - - return found_open_solution; - } - - /// - /// Get the DTE object for the instance of Visual Studio IDE that has - /// the specified solution open. - /// - /// The absolute filename of the solution - /// Corresponding DTE object or null if no such IDE is running - public static object GetIDEInstance( string solutionFile ) - { - Hashtable runningInstances = GetIDEInstances( true ); - IDictionaryEnumerator enumerator = runningInstances.GetEnumerator(); - - while ( enumerator.MoveNext() ) - { - try - { - object ide = enumerator.Value; - if (ide != null) - { - object sol = ViaCOM.GetProperty(ide, "Solution"); - if (0 == string.Compare((string)ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case)) - { - return ide; - } - } - } - catch{} - } - - return null; - } - - /// - /// Get a table of the currently running instances of the Visual Studio .NET IDE. - /// - /// Only return instances that have opened a solution - /// A hashtable mapping the name of the IDE in the running object table to the corresponding DTE object - public static Hashtable GetIDEInstances( bool openSolutionsOnly ) - { - Hashtable runningIDEInstances = new Hashtable(); - Hashtable runningObjects = GetRunningObjectTable(); - - IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator(); - while ( rotEnumerator.MoveNext() ) - { - string candidateName = (string) rotEnumerator.Key; - if (!candidateName.StartsWith("!VisualStudio.DTE")) - continue; - - object ide = rotEnumerator.Value; - if (ide == null) - continue; - - if (openSolutionsOnly) - { - try - { - object sol = ViaCOM.GetProperty(ide, "Solution"); - string solutionFile = (string)ViaCOM.GetProperty(sol, "FullName"); - if (solutionFile != String.Empty) - { - runningIDEInstances[ candidateName ] = ide; - } - } - catch {} - } - else - { - runningIDEInstances[ candidateName ] = ide; - } - } - return runningIDEInstances; - } - - /// - /// Get a snapshot of the running object table (ROT). - /// - /// A hashtable mapping the name of the object in the ROT to the corresponding object - [STAThread] - public static Hashtable GetRunningObjectTable() - { - Hashtable result = new Hashtable(); - - int numFetched = 0; - IRunningObjectTable runningObjectTable; - IEnumMoniker monikerEnumerator; - IMoniker[] monikers = new IMoniker[1]; - - GetRunningObjectTable(0, out runningObjectTable); - runningObjectTable.EnumRunning(out monikerEnumerator); - monikerEnumerator.Reset(); - - while (monikerEnumerator.Next(1, monikers, new IntPtr(numFetched)) == 0) - { - IBindCtx ctx; - CreateBindCtx(0, out ctx); - - string runningObjectName; - monikers[0].GetDisplayName(ctx, null, out runningObjectName); - - object runningObjectVal; - runningObjectTable.GetObject( monikers[0], out runningObjectVal); - - result[ runningObjectName ] = runningObjectVal; - } - - return result; - } - - public static string GetSolutionVersion(string solutionFullFileName) - { - string version; - System.IO.StreamReader solutionStreamReader = null; - string firstLine; - string format; - - try - { - solutionStreamReader = new System.IO.StreamReader(solutionFullFileName); - do - { - firstLine = solutionStreamReader.ReadLine(); - } - while (firstLine == ""); - - format = firstLine.Substring(firstLine.LastIndexOf(" ")).Trim(); - - switch(format) - { - case "7.00": - version = "VC70"; - break; - - case "8.00": - version = "VC71"; - break; - - case "9.00": - version = "VC80"; - break; - - case "10.00": - version = "VC90"; - break; - - case "11.00": - version = "VC100"; - break; - - case "12.00": - version = "VC120"; - break; - - default: - throw new ApplicationException("Unknown .sln version: " + format); - } - } - finally - { - if(solutionStreamReader != null) - { - solutionStreamReader.Close(); - } - } - - return version; - } - - public static string GetVSProgID(string version) - { - string progid = null; - switch(version) - { - case "VC70": - progid = "VisualStudio.DTE.7"; - break; - - case "VC71": - progid = "VisualStudio.DTE.7.1"; - break; - - case "VC80": - progid = "VisualStudio.DTE.8.0"; - break; - - case "VC90": - progid = "VisualStudio.DTE.9.0"; - break; - - case "VC100": - progid = "VisualStudio.DTE.10.0"; - break; - - case "VC120": - progid = "VisualStudio.DTE.12.0"; - break; - - default: - throw new ApplicationException("Can't handle VS version: " + version); - } - - return progid; - } - - public static bool SetProjectWorkingDir(object sol, string project_name, string working_dir) - { - bool made_change = false; - Console.WriteLine("Looking for project {0}...", project_name); - try - { - object prjs = ViaCOM.GetProperty(sol, "Projects"); - object count = ViaCOM.GetProperty(prjs, "Count"); - for(int i = 1; i <= (int)count; ++i) - { - object[] prjItemArgs = { (object)i }; - object prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs); - string name = (string)ViaCOM.GetProperty(prj, "Name"); - if (0 == string.Compare(name, project_name, ignore_case)) - { - Console.WriteLine("Found project: {0}", project_name); - Console.WriteLine("Setting working directory"); - - string full_project_name = (string)ViaCOM.GetProperty(prj, "FullName"); - Console.WriteLine(full_project_name); - - // *NOTE:Mani Thanks to incompatibilities between different versions of the - // VCProjectEngine.dll assembly, we can't cast the objects recevied from the DTE to - // the VCProjectEngine types from a different version than the one built - // with. ie, VisualStudio.DTE.7.1 objects can't be converted in a project built - // in VS 8.0. To avoid this problem, we can use the com object interfaces directly, - // without the type casting. Its tedious code, but it seems to work. - - // oCfgs should be assigned to a 'Project.Configurations' collection. - object oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations"); - - // oCount will be assigned to the number of configs present in oCfgs. - object oCount = ViaCOM.GetProperty(oCfgs, "Count"); - - for (int cfgIndex = 1; cfgIndex <= (int)oCount; ++cfgIndex) - { - object[] itemArgs = {(object)cfgIndex}; - object oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs); - object oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings"); - ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", (object)working_dir); - } - - break; - } - } - made_change = true; - } - catch( Exception e ) - { - Console.WriteLine(e.Message); - Console.WriteLine("Failed to set working dir for project, {0}.", project_name); - } - - return made_change; - } - - public static bool SetStartupProject(string startup_project) - { - bool result = false; - try - { - // You need the 'unique name of the project to set StartupProjects. - // find the project by generic name. - Console.WriteLine("Trying to set \"{0}\" to the startup project", startup_project); - object prjs = ViaCOM.GetProperty(solution, "Projects"); - object count = ViaCOM.GetProperty(prjs, "Count"); - for (int i = 1; i <= (int)count; ++i) - { - object[] itemArgs = { (object)i }; - object prj = ViaCOM.CallMethod(prjs, "Item", itemArgs); - object prjName = ViaCOM.GetProperty(prj, "Name"); - if (0 == string.Compare((string)prjName, startup_project, ignore_case)) - { - object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild"); - ViaCOM.SetProperty(solBuild, "StartupProjects", ViaCOM.GetProperty(prj, "UniqueName")); - Console.WriteLine(" Success!"); - result = true; - break; - } - } - - if (result == false) - { - Console.WriteLine(" Could not find project \"{0}\" in the solution.", startup_project); - } - } - catch (Exception e) - { - Console.WriteLine(" Failed to set the startup project!"); - Console.WriteLine(e.Message); - } - return result; - } - - public static bool SetActiveConfig(string config) - { - bool result = false; - try - { - Console.WriteLine("Trying to set active config to \"{0}\"", config); - object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild"); - object solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations"); - object[] itemArgs = { (object)config }; - object solCfg = ViaCOM.CallMethod(solCfgs, "Item", itemArgs); - ViaCOM.CallMethod(solCfg, "Activate", null); - Console.WriteLine(" Success!"); - result = true; - } - catch (Exception e) - { - Console.WriteLine(" Failed to set \"{0}\" as the active config.", config); - Console.WriteLine(e.Message); - } - return result; - } - } -} From 454da876dc648d34aacf27217952e640f4fdaa88 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 15 Aug 2016 17:12:37 -0400 Subject: [PATCH 11/21] Backed out changeset e187a6b45ce6: restored VSTool et al. --- autobuild.xml | 34 ++ indra/cmake/Variables.cmake | 1 + indra/newview/CMakeLists.txt | 15 + indra/tools/vstool/DispatchUtility.cs | 271 ++++++++++ indra/tools/vstool/README.txt | 9 + indra/tools/vstool/VSTool.csproj | 98 ++++ indra/tools/vstool/VSTool.exe | Bin 0 -> 24576 bytes indra/tools/vstool/VSTool.sln | 19 + indra/tools/vstool/app.config | 3 + indra/tools/vstool/main.cs | 729 ++++++++++++++++++++++++++ 10 files changed, 1179 insertions(+) create mode 100644 indra/tools/vstool/DispatchUtility.cs create mode 100644 indra/tools/vstool/README.txt create mode 100755 indra/tools/vstool/VSTool.csproj create mode 100755 indra/tools/vstool/VSTool.exe create mode 100755 indra/tools/vstool/VSTool.sln create mode 100644 indra/tools/vstool/app.config create mode 100755 indra/tools/vstool/main.cs diff --git a/autobuild.xml b/autobuild.xml index 5a91ba15f5..072dfa678a 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -2617,6 +2617,14 @@ arguments ..\indra + && + ..\indra\tools\vstool\VSTool.exe + --solution + SecondLife.sln + --config + RelWithDebInfo + --startup + secondlife-bin options @@ -2655,11 +2663,20 @@ arguments ..\indra + && + ..\indra\tools\vstool\VSTool.exe + --solution + SecondLife.sln + --config + RelWithDebInfo + --startup + secondlife-bin options -G "Visual Studio 12" + -DUNATTENDED:BOOL=ON -DINSTALL_PROPRIETARY=FALSE -DUSE_KDU=FALSE @@ -2688,6 +2705,14 @@ arguments ..\indra + && + ..\indra\tools\vstool\VSTool.exe + --solution + SecondLife.sln + --config + Release + --startup + secondlife-bin options @@ -2724,11 +2749,20 @@ arguments ..\indra + && + ..\indra\tools\vstool\VSTool.exe + --solution + SecondLife.sln + --config + Release + --startup + secondlife-bin options -G "Visual Studio 12" + -DUNATTENDED:BOOL=ON -DINSTALL_PROPRIETARY=FALSE -DUSE_KDU=FALSE diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 8292a0c63d..63e296b556 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -164,6 +164,7 @@ set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside") set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.") +set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.") set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.") diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 586a56b49a..dce0ea73cd 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1799,6 +1799,21 @@ if (WINDOWS) windows-crash-logger ) + # sets the 'working directory' for debugging from visual studio. + if (NOT UNATTENDED) + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe + ARGS + --solution + ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln + --workingdir + ${VIEWER_BINARY_NAME} + "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging." + ) + endif (NOT UNATTENDED) + if (PACKAGE) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2 diff --git a/indra/tools/vstool/DispatchUtility.cs b/indra/tools/vstool/DispatchUtility.cs new file mode 100644 index 0000000000..6056ac55a1 --- /dev/null +++ b/indra/tools/vstool/DispatchUtility.cs @@ -0,0 +1,271 @@ +#region Using Directives + +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Reflection; +using System.Security.Permissions; + +#endregion + +namespace TestDispatchUtility +{ + /// + /// Provides helper methods for working with COM IDispatch objects that have a registered type library. + /// + public static class DispatchUtility + { + #region Private Constants + + private const int S_OK = 0; //From WinError.h + private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800 + + #endregion + + #region Public Methods + + /// + /// Gets whether the specified object implements IDispatch. + /// + /// An object to check. + /// True if the object implements IDispatch. False otherwise. + public static bool ImplementsIDispatch(object obj) + { + bool result = obj is IDispatchInfo; + return result; + } + + /// + /// Gets a Type that can be used with reflection. + /// + /// An object that implements IDispatch. + /// Whether an exception should be thrown if a Type can't be obtained. + /// A .NET Type that can be used with reflection. + /// If doesn't implement IDispatch. + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + public static Type GetType(object obj, bool throwIfNotFound) + { + RequireReference(obj, "obj"); + Type result = GetType((IDispatchInfo)obj, throwIfNotFound); + return result; + } + + /// + /// Tries to get the DISPID for the requested member name. + /// + /// An object that implements IDispatch. + /// The name of a member to lookup. + /// If the method returns true, this holds the DISPID on output. + /// If the method returns false, this value should be ignored. + /// True if the member was found and resolved to a DISPID. False otherwise. + /// If doesn't implement IDispatch. + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + public static bool TryGetDispId(object obj, string name, out int dispId) + { + RequireReference(obj, "obj"); + bool result = TryGetDispId((IDispatchInfo)obj, name, out dispId); + return result; + } + + /// + /// Invokes a member by DISPID. + /// + /// An object that implements IDispatch. + /// The DISPID of a member. This can be obtained using + /// . + /// The arguments to pass to the member. + /// The member's return value. + /// + /// This can invoke a method or a property get accessor. + /// + public static object Invoke(object obj, int dispId, object[] args) + { + string memberName = "[DispId=" + dispId + "]"; + object result = Invoke(obj, memberName, args); + return result; + } + + /// + /// Invokes a member by name. + /// + /// An object. + /// The name of the member to invoke. + /// The arguments to pass to the member. + /// The member's return value. + /// + /// This can invoke a method or a property get accessor. + /// + public static object Invoke(object obj, string memberName, object[] args) + { + RequireReference(obj, "obj"); + Type type = obj.GetType(); + object result = type.InvokeMember(memberName, BindingFlags.InvokeMethod | BindingFlags.GetProperty, + null, obj, args, null); + return result; + } + + #endregion + + #region Private Methods + + /// + /// Requires that the value is non-null. + /// + /// The type of the value. + /// The value to check. + /// The name of the value. + private static void RequireReference(T value, string name) where T : class + { + if (value == null) + { + throw new ArgumentNullException(name); + } + } + + /// + /// Gets a Type that can be used with reflection. + /// + /// An object that implements IDispatch. + /// Whether an exception should be thrown if a Type can't be obtained. + /// A .NET Type that can be used with reflection. + private static Type GetType(IDispatchInfo dispatch, bool throwIfNotFound) + { + RequireReference(dispatch, "dispatch"); + + Type result = null; + int typeInfoCount; + int hr = dispatch.GetTypeInfoCount(out typeInfoCount); + if (hr == S_OK && typeInfoCount > 0) + { + // Type info isn't usually culture-aware for IDispatch, so we might as well pass + // the default locale instead of looking up the current thread's LCID each time + // (via CultureInfo.CurrentCulture.LCID). + dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result); + } + + if (result == null && throwIfNotFound) + { + // If the GetTypeInfoCount called failed, throw an exception for that. + Marshal.ThrowExceptionForHR(hr); + + // Otherwise, throw the same exception that Type.GetType would throw. + throw new TypeLoadException(); + } + + return result; + } + + /// + /// Tries to get the DISPID for the requested member name. + /// + /// An object that implements IDispatch. + /// The name of a member to lookup. + /// If the method returns true, this holds the DISPID on output. + /// If the method returns false, this value should be ignored. + /// True if the member was found and resolved to a DISPID. False otherwise. + private static bool TryGetDispId(IDispatchInfo dispatch, string name, out int dispId) + { + RequireReference(dispatch, "dispatch"); + RequireReference(name, "name"); + + bool result = false; + + // Members names aren't usually culture-aware for IDispatch, so we might as well + // pass the default locale instead of looking up the current thread's LCID each time + // (via CultureInfo.CurrentCulture.LCID). + Guid iidNull = Guid.Empty; + int hr = dispatch.GetDispId(ref iidNull, ref name, 1, LOCALE_SYSTEM_DEFAULT, out dispId); + + const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006); //From WinError.h + const int DISPID_UNKNOWN = -1; //From OAIdl.idl + if (hr == S_OK) + { + result = true; + } + else if (hr == DISP_E_UNKNOWNNAME && dispId == DISPID_UNKNOWN) + { + // This is the only supported "error" case because it means IDispatch + // is saying it doesn't know the member we asked about. + result = false; + } + else + { + // The other documented result codes are all errors. + Marshal.ThrowExceptionForHR(hr); + } + + return result; + } + + #endregion + + #region Private Interfaces + + /// + /// A partial declaration of IDispatch used to lookup Type information and DISPIDs. + /// + /// + /// This interface only declares the first three methods of IDispatch. It omits the + /// fourth method (Invoke) because there are already plenty of ways to do dynamic + /// invocation in .NET. But the first three methods provide dynamic type metadata + /// discovery, which .NET doesn't provide normally if you have a System.__ComObject + /// RCW instead of a strongly-typed RCW. + /// + /// Note: The original declaration of IDispatch is in OAIdl.idl. + /// + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("00020400-0000-0000-C000-000000000046")] + private interface IDispatchInfo + { + /// + /// Gets the number of Types that the object provides (0 or 1). + /// + /// Returns 0 or 1 for the number of Types provided by . + /// + /// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85) + /// + [PreserveSig] + int GetTypeInfoCount(out int typeInfoCount); + + /// + /// Gets the Type information for an object if returned 1. + /// + /// Must be 0. + /// Typically, LOCALE_SYSTEM_DEFAULT (2048). + /// Returns the object's Type information. + /// + /// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85) + /// + void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler, + MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo); + + /// + /// Gets the DISPID of the specified member name. + /// + /// Must be IID_NULL. Pass a copy of Guid.Empty. + /// The name of the member to look up. + /// Must be 1. + /// Typically, LOCALE_SYSTEM_DEFAULT (2048). + /// If a member with the requested + /// is found, this returns its DISPID and the method's return value is 0. + /// If the method returns a non-zero value, then this parameter's output value is + /// undefined. + /// Zero for success. Non-zero for failure. + /// + /// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85) + /// + [PreserveSig] + int GetDispId(ref Guid riid, ref string name, int nameCount, int lcid, out int dispId); + + // NOTE: The real IDispatch also has an Invoke method next, but we don't need it. + // We can invoke methods using .NET's Type.InvokeMember method with the special + // [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo + // and invoke methods on that through reflection. + // Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx + } + + #endregion + } +} diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt new file mode 100644 index 0000000000..e419180031 --- /dev/null +++ b/indra/tools/vstool/README.txt @@ -0,0 +1,9 @@ +VSTool is a command line utility to manipulate VisualStudio settings. + +The windows cmake project configuration uses VSTool.exe + +A handy upgrade: + figure out how to make cmake build this csharp app + - or write the app using script (jscript?!?) so it doesn't need to be built. + + diff --git a/indra/tools/vstool/VSTool.csproj b/indra/tools/vstool/VSTool.csproj new file mode 100755 index 0000000000..7f431e85c7 --- /dev/null +++ b/indra/tools/vstool/VSTool.csproj @@ -0,0 +1,98 @@ + + + + Local + 8.0.50727 + 2.0 + {96943E2D-1373-4617-A117-D0F997A94919} + Debug + AnyCPU + + + + + VSTool + + + JScript + Grid + IE50 + false + Exe + VSTool + Always + VSTool.VSToolMain + + + + + v2.0 + 2.0 + + + .\ + false + 285212672 + false + + + DEBUG;TRACE + + + true + 4096 + false + + + false + false + false + false + 4 + full + prompt + + + .\ + false + 285212672 + false + + + TRACE + + + false + 4096 + false + + + true + false + false + false + 4 + none + prompt + + + + System + + + System.Data + + + + + Code + + + + + + + + + + \ No newline at end of file diff --git a/indra/tools/vstool/VSTool.exe b/indra/tools/vstool/VSTool.exe new file mode 100755 index 0000000000000000000000000000000000000000..854290b90ad1c9ed8676919a9c144d05330cb245 GIT binary patch literal 24576 zcmeHOeQ+Dcb$@pN?hXJ6=>UopEm8(4iH1ZHA|>n7qAi-F6eN;Ki5`? zBbz=u^1K=bjw|vB_pBA(!_-m!z%whY*bqOW-d z+XNwK6dvEZ37HP)9p~CkX6a(`m&ADyswnf%&+o-0{JF;!V zfJV1M9^X-zs*UdiA`vZ+}NYi3_)WL9-K&ly}ZpToj)^PQHW1GUy!MNJn zsXYO+Sl=jUJnEZm522fq2%5px;A3VmBK1f0Kyr7I^=m?Z^J06GGqj}NsOdNE4=?H8 zy0xZ%wY|GBP>UL@**m|a?-lH=;SiucXbHjY)<|nqO#x-C$N3BtT?CjxG5Hjxs5M>G zLHFqw@%=-vUvG=-{WvC^!i=?xD1tWp8cFEAx0$*PC6OoEfI@RTz?~!2^#T%5ElX5L zXflIlDAf)neQH}2UDu(#|4WPOOnnwyC1IFGpKcm4`PeJQhj3+cxtD)Q$S)|3?Laa|pr(kfTr)7cXC+BL4o6qOz zr!bE8ytYkAajYGpSG|{DFkeA>{`(Z?SWr>_#jj{Lb2khG=ud$!>^7Yr!5Uz^_XRXK z9|}-K)gMU#m`L9yfpuTh`82pL<{i0T)!SaXCHlw$J7F(>edheEzDKle0kIq0`xo4z z1?zNe^m;aV_h#W8BWwemNbh}4vR*jpA?oY^clp2!b?=={ak;pJ+gVs8&JDc@=S!YA zoD-4yFpsFNzPE5k_{x2P#nHl zk5378sKYuAP!KeHZMH?6FZ=!FTIhtP=tai8KdN&iYYQ9{B1-mu4l0}u%^T49qF>WF zezYd%*I*c8IT`G9tvQ_92z{IW`U5 zLM|bv1R>xd<9yrlICsu3X_TSeA_meD`r^&45xJOKt~Qpo&D6a-w3FWUByE#Shf>&6v>xml zkC>sBxMo9l#9%V6+r6mwz&0dEwkF(W26eX&HM<{0-(@yr1IFzHScn$0C91kr&`nINa ziTdwRZ}aN9L6!Ah-9)|Jt9PP)lULu0`UX*dIkCWMJ?&-?Ge(Y#^xbWS#&|6v(=ldZ zpGU4DxS235>K$-)K}n={pL2(}4>}of-|9??dzbS@ac_4D;%+*#xQ9i4kU3~EqW5XK zy$1szc|#}X03MG&Yk--F50A|k`|o+&aSFg$LfsPG_cSP&4S_mP*d`wow#x^FZSz54 z`+QK?MjsTma|sky>uJ{!9s-jIc-w^jf=a=HX)#(f~zsor+?(L2%?xyn* z+|@crG@O9~bQ1GM+Q8oLdX(#j^Y$+^6wr`c?Fz6UCpg6FXiBiK|T zX2c9X!IK>PWbfK=+iRP{h9GbM@0YJ!!5LyhB4);FrwZo^6v!DZ5+cptYXA!M1MB_x zV4oqGOM~=N)MFC=lTmgM1Z7gbwhtaeA8&qPGrZ)3@O6E_iEUN>-78N?pTfvukKsMk z`35NX;Kx2wqTyU&n*GxjSq{W~*w!^{>Fb(&`xkFY7|tw6>9x9}t-wU)c9ov_2fE4M zQx-5MDCanQdP&a;>ky0KX3x?l4*<-nRej9Vnx$jI(yvJN&K`(*N56X8;joaCL7Rly z4Ap$c#`(5obF_hN`{%X=cr4hmfJ6~&6-O?y{owq=Tt4))EbvK5?y7Q!U3$vEi?PX9 z->HbF9{CP!Zby0`y=!344x}PJbr(?<(SOrLyo1E{O>cB3PVvILF}> zL;d(LpUuFKj6FXKiG0X>uJfHgoEha^qc_n>=y_NvC>lK_%82@F)GL9z0~-BxfLmV^ z>_P{WwXw$?K-#ii1HDg?fggm^SVZD#z`?#IZyW3 zB|yE7u-T%{e`_fXDufzb59)wNVYdY};!%tv(Q%v#LpZB!#Ix?R$~ekJhpQD2ApZ737;J^fiFK>_1gVafu1Eo3d>&(sC%j|e+lOuY+~K@&-)KR|y@ z?b!V*9`%@@-XW+TC?AKGD81XGoLh@l6 zRqvrqWZ?Y9S~BW1ZKfwTOX?o=EMoWD9KL8Pt3^-~J(7Ary^nh6C69VSIS(IH*aFX4p6)Fn_UdVH&-KB@i*ZKcgPQgPd5^&QkleK<=o^(|2S^s=Dj9Mbf4K|Q>_ z(`ZKwa6J4F%S@#gPzLCCD1)S7!6?**Lx6M8;}LkSPi4<2;D~CL|)lRkJ4A@ z!^%U*7!T4z^kq?gHIP94Ih<1!jChNZQKpr7I7DL}fGD}cOQQ*Lv=?R4$*+pN)J-C42UUu1c8|XbU3KY+2<_Zyj7;9 zucF+W%4*rwqh3>Vg*hX(Z_siK(z&Yb&|#}O;n)?+sm{}6U7aU()T*Af^ByAUW3%OI zp=6~qWz5a4Oj^!dA!oU1Kr=O8v0TbPq6`2ebW_>sqQ&a3!p+=SDCbA27ih$>vQ^8c z3NvNfu}hdHS1JoE2lgj*OrR$uJcP^5?zy6coVp z)`wlpdo>yP*YY!s&sK-4I2KON0>LwmT{>k?-%CKZB7G$MlP%6#R1$F`xmgFN$cZd| zH8<=y+4-6V$8r%tR-QFfsZyEFE%_YwScI4?`;fZh<>Gv;dA3+&k-IoD<~+0!FRY1S zlmnlaK%dGp(qc_7%?uG+L4U^&VUmn2N7FH@n7trsZp~IN^jQo|(}iN8S~nB0Go^~{ z)WLIjwvexNU-A$`Ut@DWUQ6sd;gksvlgYwNO=`4QT&W#7Zs(449=S+#L!gPfKTGS3 zw=#$q7J}_iF$*U!f#AuMIVl~rO4A?^X8_KklTM*(9pT6yyO6Ug3a2KV)^RL^Z+%y!RWaymETkgw{2|B_ zBBqYobJkt_!@|sH!L8V?SnjfFVHrE_*(|5#qJ`uEV7>H>*c`iWHp~8^;Yy`g$O+fh zCOMqXGYDWy4E#{Zj3a2PXL%7HLb&;L#`zFJ9}AY3wOFiTwla||r3Voyj)iF;2e~H; z&@@)6zz7(WDOPuH9G-JAJ1>GCq&HCn(nQrE zfe^5>vZZ725fn}VGq1`w;o~D&x0*pPTo^w?le5#V#Cpmpl<2^OQyH&`v!)0?(QEO-m|O!*4;Y>`iF-H_V(}EdFP>BgS&4X*gHJ>fVZ41 z=de}gV6f_9#f#Cp?41@;g~3`17&-W}@k!DQSyaVefe_uGE25g9@US$H6;-k^8}6 zLs+{-=W(9{E%jfo=LZ?k4-X8G>NtK0winw6TC>$x$Dlyz5&S7qoBX2bsHWx??z=gQR8-#b)y!Lo}UM~f@9~2`~ z1?L>(S zG9U0PICHRH%D~S;hTuP1_%JWOQ8ee#fbVTU@$!_Qu`48~E0e91V%v_vf-J1_$4Fz`BJ7iP7SYOyus%V0Q`^qHk3-t;xm=2uwcJHK z`JGoAZRNbVSKaPtP6|iX_9hCCdzjJ4-EboBV>S2WAuWS7DJ=H)WFKc~Y0WY+4?zd- zns)&M-mqv>7ZPqQ?bkaw4L?rN7=IxY-UH_j;E%$4muma`T67RCUOVc8b#)vXyndY4 z_XrKLhWC?UuI*jo?c-XMd91Hi-@*0%qNjsMlWT`FncO0HOAsTS zJOph8fvCS#$c^=S$D1>vw|_eJ?c}WIBTC1ognmD}@OU-7wH)EE_uAp4esf$o0&Q5C zQSKC3q=*biH}h(*9bi^@a~-d_f;gI5wT!Wj^V%e|dax_ z#gR5Aq7k|G%hA+qcet5?TkU48YHEINi^b}Lfix$V})u*3@;oMH5OE0VKAvE1{bld3T@`+ zQ9P0E?&q5%fe7OeLo4f%s7TXh&2Jb#{naX9xE=4hfcGtBsB|de~4^^Nq1s{Am1m+=3D{77Ha+ zrGpj5VzDOOh#6=u#X4gKPjZN-3XSN>?eQU~KdN@(2V()qsbM`7H{-`UIxrfh-lXdw z!H6-)n9kbx1L0&qi8sgR*T(cD95KJP!+>v$&iMTLwYm{Ejd(cz0H}C#jFlKM6fwil z*2NbdR%3?l-(h8f5{i*j)da0gC=p$Y#TVWNql}OqK)GHw;aj5!O*ZA3tKkU0G<80LoPIGt;5cV7t`o}#!&z$x9b74w6jb3w{Tg80j2{kXyo>j;$pVjI)F$Tjx ziNE$L0mULLYjDV``z4GtCV&7ONE?cyY`uCf6gxL z&$^}b++cSSFG&k$EVt^t=9HsBRWiAxER)BJ1H5usW)XgL2CMjO?ojv9`MQ@e>1?Ia zyZ(nBnf$d8m zK;Xc3-$NkS+l{M%Km&mW0u2Nj2s99AAkaXdfj|R+t0Hhv{=ZA*z*Sot%mxAt1R4l5 f5NIIKK%jv@1Aztt4FnnpG!SSY&_Lji0D=Dj2A)o8 literal 0 HcmV?d00001 diff --git a/indra/tools/vstool/VSTool.sln b/indra/tools/vstool/VSTool.sln new file mode 100755 index 0000000000..21e3d75971 --- /dev/null +++ b/indra/tools/vstool/VSTool.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSTool", "VSTool.csproj", "{96943E2D-1373-4617-A117-D0F997A94919}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/indra/tools/vstool/app.config b/indra/tools/vstool/app.config new file mode 100644 index 0000000000..8494f728ff --- /dev/null +++ b/indra/tools/vstool/app.config @@ -0,0 +1,3 @@ + + + diff --git a/indra/tools/vstool/main.cs b/indra/tools/vstool/main.cs new file mode 100755 index 0000000000..ef2e582b90 --- /dev/null +++ b/indra/tools/vstool/main.cs @@ -0,0 +1,729 @@ +// Code about getting running instances visual studio +// was borrowed from +// http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx + + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using Microsoft.CSharp; + +namespace VSTool +{ + // The MessageFilter class comes from: + // http://msdn.microsoft.com/en-us/library/ms228772(VS.80).aspx + // It allows vstool to get timing error messages from + // visualstudio and handle them. + public class MessageFilter : IOleMessageFilter + { + // + // Class containing the IOleMessageFilter + // thread error-handling functions. + + // Start the filter. + public static void Register() + { + IOleMessageFilter newFilter = new MessageFilter(); + IOleMessageFilter oldFilter = null; + CoRegisterMessageFilter(newFilter, out oldFilter); + } + + // Done with the filter, close it. + public static void Revoke() + { + IOleMessageFilter oldFilter = null; + CoRegisterMessageFilter(null, out oldFilter); + } + + // + // IOleMessageFilter functions. + // Handle incoming thread requests. + int IOleMessageFilter.HandleInComingCall(int dwCallType, + System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr + lpInterfaceInfo) + { + //Return the flag SERVERCALL_ISHANDLED. + return 0; + } + + // Thread call was rejected, so try again. + int IOleMessageFilter.RetryRejectedCall(System.IntPtr + hTaskCallee, int dwTickCount, int dwRejectType) + { + if (dwRejectType == 2) + // flag = SERVERCALL_RETRYLATER. + { + // Retry the thread call immediately if return >=0 & + // <100. + return 99; + } + // Too busy; cancel call. + return -1; + } + + int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, + int dwTickCount, int dwPendingType) + { + //Return the flag PENDINGMSG_WAITDEFPROCESS. + return 2; + } + + // Implement the IOleMessageFilter interface. + [DllImport("Ole32.dll")] + private static extern int + CoRegisterMessageFilter(IOleMessageFilter newFilter, out + IOleMessageFilter oldFilter); + } + + [ComImport(), Guid("00000016-0000-0000-C000-000000000046"), + InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + interface IOleMessageFilter + { + [PreserveSig] + int HandleInComingCall( + int dwCallType, + IntPtr hTaskCaller, + int dwTickCount, + IntPtr lpInterfaceInfo); + + [PreserveSig] + int RetryRejectedCall( + IntPtr hTaskCallee, + int dwTickCount, + int dwRejectType); + + [PreserveSig] + int MessagePending( + IntPtr hTaskCallee, + int dwTickCount, + int dwPendingType); + } + + class ViaCOM + { + public static object GetProperty(object from_obj, string prop_name) + { + try + { + Type objType = from_obj.GetType(); + return objType.InvokeMember( + prop_name, + BindingFlags.GetProperty, null, + from_obj, + null); + } + catch (Exception e) + { + Console.WriteLine("Error getting property: \"{0}\"", prop_name); + Console.WriteLine(e.Message); + throw e; + } + } + + public static object SetProperty(object from_obj, string prop_name, object new_value) + { + try + { + object[] args = { new_value }; + Type objType = from_obj.GetType(); + return objType.InvokeMember( + prop_name, + BindingFlags.DeclaredOnly | + BindingFlags.Public | + BindingFlags.NonPublic | + BindingFlags.Instance | + BindingFlags.SetProperty, + null, + from_obj, + args); + } + catch (Exception e) + { + Console.WriteLine("Error setting property: \"{0}\"", prop_name); + Console.WriteLine(e.Message); + throw e; + } + } + + public static object CallMethod(object from_obj, string method_name, params object[] args) + { + try + { + Type objType = from_obj.GetType(); + return objType.InvokeMember( + method_name, + BindingFlags.DeclaredOnly | + BindingFlags.Public | + BindingFlags.NonPublic | + BindingFlags.Instance | + BindingFlags.InvokeMethod, + null, + from_obj, + args); + } + catch (Exception e) + { + Console.WriteLine("Error calling method \"{0}\"", method_name); + Console.WriteLine(e.Message); + throw e; + } + } + }; + + /// + /// The main entry point class for VSTool. + /// + class VSToolMain + { + #region Interop imports + [DllImport("ole32.dll")] + public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); + + [DllImport("ole32.dll")] + public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc); + #endregion + + static System.Boolean ignore_case = true; + + static string solution_name = null; + static bool use_new_vs = false; + static Hashtable projectDict = new Hashtable(); + static string startup_project = null; + static string config = null; + + static object dte = null; + static object solution = null; + + /// + /// The main entry point for the application. + /// + [STAThread] + static int Main(string[] args) + { + int retVal = 0; + bool need_save = false; + + try + { + parse_command_line(args); + + Console.WriteLine("Editing solution: {0}", solution_name); + + bool found_open_solution = GetDTEAndSolution(); + + if (dte == null || solution == null) + { + retVal = 1; + } + else + { + MessageFilter.Register(); + + // Walk through all of the projects in the solution + // and list the type of each project. + foreach (DictionaryEntry p in projectDict) + { + string project_name = (string)p.Key; + string working_dir = (string)p.Value; + if (SetProjectWorkingDir(solution, project_name, working_dir)) + { + need_save = true; + } + } + + if (config != null) + { + need_save = SetActiveConfig(config); + } + + if (startup_project != null) + { + need_save = SetStartupProject(startup_project); + } + + if (need_save) + { + if (found_open_solution == false) + { + ViaCOM.CallMethod(solution, "Close", null); + } + } + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + retVal = 1; + } + finally + { + if (solution != null) + { + Marshal.ReleaseComObject(solution); + solution = null; + } + + if (dte != null) + { + Marshal.ReleaseComObject(dte); + dte = null; + } + + MessageFilter.Revoke(); + } + return retVal; + } + + public static bool parse_command_line(string[] args) + { + string options_desc = + "--solution : MSVC solution name. (required)\n" + + "--use_new_vs : Ignore running versions of visual studio.\n" + + "--workingdir : Set working dir of a VC project.\n" + + "--config : Set the active config for the solution.\n" + + "--startup : Set the startup project for the solution.\n"; + + try + { + // Command line param parsing loop. + int i = 0; + for (; i < args.Length; ++i) + { + if ("--solution" == args[i]) + { + if (solution_name != null) + { + throw new ApplicationException("Found second --solution option"); + } + solution_name = args[++i]; + } + else if ("--use_new_vs" == args[i]) + { + use_new_vs = true; + } + + else if ("--workingdir" == args[i]) + { + string project_name = args[++i]; + string working_dir = args[++i]; + projectDict.Add(project_name, working_dir); + } + else if ("--config" == args[i]) + { + if (config != null) + { + throw new ApplicationException("Found second --config option"); + } + config = args[++i]; + } + else if ("--startup" == args[i]) + { + if (startup_project != null) + { + throw new ApplicationException("Found second --startup option"); + } + startup_project = args[++i]; + } + else + { + throw new ApplicationException("Found unrecognized token on command line: " + args[i]); + } + } + + if (solution_name == null) + { + throw new ApplicationException("The --solution option is required."); + } + } + catch(ApplicationException e) + { + + Console.WriteLine("Oops! " + e.Message); + Console.Write("Command line:"); + foreach (string arg in args) + { + Console.Write(" " + arg); + } + Console.Write("\n\n"); + Console.WriteLine("VSTool command line usage"); + Console.Write(options_desc); + throw e; + } + return true; + } + + public static bool GetDTEAndSolution() + { + bool found_open_solution = true; + + Console.WriteLine("Looking for existing VisualStudio instance..."); + + // Get an instance of the currently running Visual Studio .NET IDE. + // dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1"); + string full_solution_name = System.IO.Path.GetFullPath(solution_name); + if (false == use_new_vs) + { + dte = GetIDEInstance(full_solution_name); + } + + if (dte == null) + { + try + { + Console.WriteLine(" Didn't find open solution, starting new background VisualStudio instance..."); + Console.WriteLine(" Reading .sln file version..."); + string version = GetSolutionVersion(full_solution_name); + + Console.WriteLine(" Using version: {0}...", version); + string progid = GetVSProgID(version); + + Type objType = Type.GetTypeFromProgID(progid); + dte = System.Activator.CreateInstance(objType); + Console.WriteLine(" Reading solution: \"{0}\"", full_solution_name); + + solution = ViaCOM.GetProperty(dte, "Solution"); + object[] openArgs = { full_solution_name }; + ViaCOM.CallMethod(solution, "Open", openArgs); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + Console.WriteLine("Quitting do to error opening: {0}", full_solution_name); + solution = null; + dte = null; + return found_open_solution; + } + found_open_solution = false; + } + + if (solution == null) + { + solution = ViaCOM.GetProperty(dte, "Solution"); + } + + return found_open_solution; + } + + /// + /// Get the DTE object for the instance of Visual Studio IDE that has + /// the specified solution open. + /// + /// The absolute filename of the solution + /// Corresponding DTE object or null if no such IDE is running + public static object GetIDEInstance( string solutionFile ) + { + Hashtable runningInstances = GetIDEInstances( true ); + IDictionaryEnumerator enumerator = runningInstances.GetEnumerator(); + + while ( enumerator.MoveNext() ) + { + try + { + object ide = enumerator.Value; + if (ide != null) + { + object sol = ViaCOM.GetProperty(ide, "Solution"); + if (0 == string.Compare((string)ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case)) + { + return ide; + } + } + } + catch{} + } + + return null; + } + + /// + /// Get a table of the currently running instances of the Visual Studio .NET IDE. + /// + /// Only return instances that have opened a solution + /// A hashtable mapping the name of the IDE in the running object table to the corresponding DTE object + public static Hashtable GetIDEInstances( bool openSolutionsOnly ) + { + Hashtable runningIDEInstances = new Hashtable(); + Hashtable runningObjects = GetRunningObjectTable(); + + IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator(); + while ( rotEnumerator.MoveNext() ) + { + string candidateName = (string) rotEnumerator.Key; + if (!candidateName.StartsWith("!VisualStudio.DTE")) + continue; + + object ide = rotEnumerator.Value; + if (ide == null) + continue; + + if (openSolutionsOnly) + { + try + { + object sol = ViaCOM.GetProperty(ide, "Solution"); + string solutionFile = (string)ViaCOM.GetProperty(sol, "FullName"); + if (solutionFile != String.Empty) + { + runningIDEInstances[ candidateName ] = ide; + } + } + catch {} + } + else + { + runningIDEInstances[ candidateName ] = ide; + } + } + return runningIDEInstances; + } + + /// + /// Get a snapshot of the running object table (ROT). + /// + /// A hashtable mapping the name of the object in the ROT to the corresponding object + [STAThread] + public static Hashtable GetRunningObjectTable() + { + Hashtable result = new Hashtable(); + + int numFetched = 0; + IRunningObjectTable runningObjectTable; + IEnumMoniker monikerEnumerator; + IMoniker[] monikers = new IMoniker[1]; + + GetRunningObjectTable(0, out runningObjectTable); + runningObjectTable.EnumRunning(out monikerEnumerator); + monikerEnumerator.Reset(); + + while (monikerEnumerator.Next(1, monikers, new IntPtr(numFetched)) == 0) + { + IBindCtx ctx; + CreateBindCtx(0, out ctx); + + string runningObjectName; + monikers[0].GetDisplayName(ctx, null, out runningObjectName); + + object runningObjectVal; + runningObjectTable.GetObject( monikers[0], out runningObjectVal); + + result[ runningObjectName ] = runningObjectVal; + } + + return result; + } + + public static string GetSolutionVersion(string solutionFullFileName) + { + string version; + System.IO.StreamReader solutionStreamReader = null; + string firstLine; + string format; + + try + { + solutionStreamReader = new System.IO.StreamReader(solutionFullFileName); + do + { + firstLine = solutionStreamReader.ReadLine(); + } + while (firstLine == ""); + + format = firstLine.Substring(firstLine.LastIndexOf(" ")).Trim(); + + switch(format) + { + case "7.00": + version = "VC70"; + break; + + case "8.00": + version = "VC71"; + break; + + case "9.00": + version = "VC80"; + break; + + case "10.00": + version = "VC90"; + break; + + case "11.00": + version = "VC100"; + break; + + case "12.00": + version = "VC120"; + break; + + default: + throw new ApplicationException("Unknown .sln version: " + format); + } + } + finally + { + if(solutionStreamReader != null) + { + solutionStreamReader.Close(); + } + } + + return version; + } + + public static string GetVSProgID(string version) + { + string progid = null; + switch(version) + { + case "VC70": + progid = "VisualStudio.DTE.7"; + break; + + case "VC71": + progid = "VisualStudio.DTE.7.1"; + break; + + case "VC80": + progid = "VisualStudio.DTE.8.0"; + break; + + case "VC90": + progid = "VisualStudio.DTE.9.0"; + break; + + case "VC100": + progid = "VisualStudio.DTE.10.0"; + break; + + case "VC120": + progid = "VisualStudio.DTE.12.0"; + break; + + default: + throw new ApplicationException("Can't handle VS version: " + version); + } + + return progid; + } + + public static bool SetProjectWorkingDir(object sol, string project_name, string working_dir) + { + bool made_change = false; + Console.WriteLine("Looking for project {0}...", project_name); + try + { + object prjs = ViaCOM.GetProperty(sol, "Projects"); + object count = ViaCOM.GetProperty(prjs, "Count"); + for(int i = 1; i <= (int)count; ++i) + { + object[] prjItemArgs = { (object)i }; + object prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs); + string name = (string)ViaCOM.GetProperty(prj, "Name"); + if (0 == string.Compare(name, project_name, ignore_case)) + { + Console.WriteLine("Found project: {0}", project_name); + Console.WriteLine("Setting working directory"); + + string full_project_name = (string)ViaCOM.GetProperty(prj, "FullName"); + Console.WriteLine(full_project_name); + + // *NOTE:Mani Thanks to incompatibilities between different versions of the + // VCProjectEngine.dll assembly, we can't cast the objects recevied from the DTE to + // the VCProjectEngine types from a different version than the one built + // with. ie, VisualStudio.DTE.7.1 objects can't be converted in a project built + // in VS 8.0. To avoid this problem, we can use the com object interfaces directly, + // without the type casting. Its tedious code, but it seems to work. + + // oCfgs should be assigned to a 'Project.Configurations' collection. + object oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations"); + + // oCount will be assigned to the number of configs present in oCfgs. + object oCount = ViaCOM.GetProperty(oCfgs, "Count"); + + for (int cfgIndex = 1; cfgIndex <= (int)oCount; ++cfgIndex) + { + object[] itemArgs = {(object)cfgIndex}; + object oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs); + object oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings"); + ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", (object)working_dir); + } + + break; + } + } + made_change = true; + } + catch( Exception e ) + { + Console.WriteLine(e.Message); + Console.WriteLine("Failed to set working dir for project, {0}.", project_name); + } + + return made_change; + } + + public static bool SetStartupProject(string startup_project) + { + bool result = false; + try + { + // You need the 'unique name of the project to set StartupProjects. + // find the project by generic name. + Console.WriteLine("Trying to set \"{0}\" to the startup project", startup_project); + object prjs = ViaCOM.GetProperty(solution, "Projects"); + object count = ViaCOM.GetProperty(prjs, "Count"); + for (int i = 1; i <= (int)count; ++i) + { + object[] itemArgs = { (object)i }; + object prj = ViaCOM.CallMethod(prjs, "Item", itemArgs); + object prjName = ViaCOM.GetProperty(prj, "Name"); + if (0 == string.Compare((string)prjName, startup_project, ignore_case)) + { + object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild"); + ViaCOM.SetProperty(solBuild, "StartupProjects", ViaCOM.GetProperty(prj, "UniqueName")); + Console.WriteLine(" Success!"); + result = true; + break; + } + } + + if (result == false) + { + Console.WriteLine(" Could not find project \"{0}\" in the solution.", startup_project); + } + } + catch (Exception e) + { + Console.WriteLine(" Failed to set the startup project!"); + Console.WriteLine(e.Message); + } + return result; + } + + public static bool SetActiveConfig(string config) + { + bool result = false; + try + { + Console.WriteLine("Trying to set active config to \"{0}\"", config); + object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild"); + object solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations"); + object[] itemArgs = { (object)config }; + object solCfg = ViaCOM.CallMethod(solCfgs, "Item", itemArgs); + ViaCOM.CallMethod(solCfg, "Activate", null); + Console.WriteLine(" Success!"); + result = true; + } + catch (Exception e) + { + Console.WriteLine(" Failed to set \"{0}\" as the active config.", config); + Console.WriteLine(e.Message); + } + return result; + } + } +} From b0c434fadfb7085fa93d13b3f61f29d48c610834 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 15 Aug 2016 17:15:31 -0400 Subject: [PATCH 12/21] Set CMake UNATTENDED variable to suppress VSTool in TC builds. --- build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sh b/build.sh index cd2a9ebf5e..ab7a1faa37 100755 --- a/build.sh +++ b/build.sh @@ -97,6 +97,7 @@ pre_build() "$autobuild" configure --quiet -c $variant -- \ -DPACKAGE:BOOL=ON \ + -DUNATTENDED:BOOL=ON \ -DRELEASE_CRASH_REPORTING:BOOL=ON \ -DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \ -DGRID:STRING="\"$viewer_grid\"" \ From b240c494c43912b4b57e0efc0867997faa18b327 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 16 Aug 2016 11:03:03 -0400 Subject: [PATCH 13/21] Re-delete VSTool.exe invocations from autobuild.xml. The CMake invocations are controlled by UNATTENDED -- these were not. Let CMake do it if it must be done. --- autobuild.xml | 34 ---------------------------------- 1 file changed, 34 deletions(-) mode change 100755 => 100644 autobuild.xml diff --git a/autobuild.xml b/autobuild.xml old mode 100755 new mode 100644 index 072dfa678a..5a91ba15f5 --- a/autobuild.xml +++ b/autobuild.xml @@ -2617,14 +2617,6 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - RelWithDebInfo - --startup - secondlife-bin options @@ -2663,20 +2655,11 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - RelWithDebInfo - --startup - secondlife-bin options -G "Visual Studio 12" - -DUNATTENDED:BOOL=ON -DINSTALL_PROPRIETARY=FALSE -DUSE_KDU=FALSE @@ -2705,14 +2688,6 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - Release - --startup - secondlife-bin options @@ -2749,20 +2724,11 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - Release - --startup - secondlife-bin options -G "Visual Studio 12" - -DUNATTENDED:BOOL=ON -DINSTALL_PROPRIETARY=FALSE -DUSE_KDU=FALSE From 57060fa0ebfacf3705ec2d9770e83aab3c86b894 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 2 Aug 2016 21:57:04 +0300 Subject: [PATCH 14/21] MAINT-4124 Warning user about render-heavy set of HUDs --- indra/newview/app_settings/settings.xml | 55 ++++++++ indra/newview/llavatarrendernotifier.cpp | 130 ++++++++++++++++++ indra/newview/llavatarrendernotifier.h | 36 +++++ indra/newview/llvoavatar.cpp | 65 ++++++++- .../skins/default/xui/en/notifications.xml | 14 ++ .../newview/skins/default/xui/en/strings.xml | 7 + 6 files changed, 302 insertions(+), 5 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ca81696a50..00c769607f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10092,6 +10092,17 @@ Value 10 + ComplexityChangesPopUpDelay + + Comment + Delay before viewer will show avatar complexity notice again + Persist + 1 + Type + U32 + Value + 300 + RenderAvatarMaxComplexity Comment @@ -10104,6 +10115,50 @@ Value 0 + RenderHUDObjectsWarning + + Comment + Viewer will warn user about HUD containing to many objects if objects count is above this value + Persist + 1 + Type + U32 + Value + 1000 + + RenderHUDTexturesWarning + + Comment + Viewer will warn user about HUD containing to many textures if texture count is above this value + Persist + 1 + Type + U32 + Value + 200 + + RenderHUDOversizedTexturesWarning + + Comment + How many textures with size 1024 * 1024 or bigger HUD can contain before notifying user + Persist + 1 + Type + U32 + Value + 6 + + RenderHUDTexturesVirtualMemoryWarning + + Comment + Viewer will warn user about HUD textures using memory above this value (Virtual memory, in pixels) + Persist + 1 + Type + U32 + Value + 10000000 + RenderAutoMuteSurfaceAreaLimit Comment diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp index 24934fdb73..f7a1ef1621 100644 --- a/indra/newview/llavatarrendernotifier.cpp +++ b/indra/newview/llavatarrendernotifier.cpp @@ -51,6 +51,11 @@ static const F32 RENDER_ALLOWED_CHANGE_PCT = 0.1; // wait seconds before processing over limit updates after last complexity change static const U32 OVER_LIMIT_UPDATE_DELAY = 70; +static const U32 WARN_HUD_OBJECTS_LIMIT = 1000; +static const U32 WARN_HUD_TEXTURES_LIMIT = 200; +static const U32 WARN_HUD_OVERSIZED_TEXTURES_LIMIT = 6; +static const U32 WARN_HUD_TEXTURE_MEMORY_LIMIT = 10000000; // in pixels + LLAvatarRenderNotifier::LLAvatarRenderNotifier() : mAgentsCount(0), @@ -264,3 +269,128 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity) } } +// LLHUDRenderNotifier + +LLHUDRenderNotifier::LLHUDRenderNotifier() +{ +} + +LLHUDRenderNotifier::~LLHUDRenderNotifier() +{ +} + +void LLHUDRenderNotifier::updateNotificationHUD(LLHUDComplexity new_complexity) +{ + if (!isAgentAvatarValid()) + { + // data not ready. + return; + } + + static const char* hud_memory = "hud_render_memory_warning"; + static const char* hud_cost = "hud_render_cost_warning"; + static const char* hud_heavy = "hud_render_heavy_textures_warning"; + static const char* hud_cramped = "hud_render_cramped_warning"; + static const char* hud_textures = "hud_render_textures_warning"; + + static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); // ties max HUD cost to avatar cost + static LLCachedControl max_objects_count(gSavedSettings, "RenderHUDObjectsWarning", WARN_HUD_OBJECTS_LIMIT); + static LLCachedControl max_textures_count(gSavedSettings, "RenderHUDTexturesWarning", WARN_HUD_TEXTURES_LIMIT); + static LLCachedControl max_oversized_count(gSavedSettings, "RenderHUDOversizedTexturesWarning", WARN_HUD_OVERSIZED_TEXTURES_LIMIT); + static LLCachedControl max_texture_memory(gSavedSettings, "RenderHUDTexturesVirtualMemoryWarning", WARN_HUD_TEXTURE_MEMORY_LIMIT); + + if (mHUDPopUpDelayTimer.hasExpired()) + { + // Show warning with highest importance (5m delay between warnings by default) + // TODO: + // Consider showing message with list of issues. + // For now shows one after another if update arrives and timer expired, so + // consider showing only one most important or consider triggering not + // only in case of update + if (mReportedHUDComplexity.texturesSizeTotal < new_complexity.texturesSizeTotal + && new_complexity.texturesSizeTotal > max_texture_memory) + { + displayHUDNotification(hud_memory); + LL_DEBUGS("HUDdetail") << "HUD memory usage over limit," + << " was " << mReportedHUDComplexity.texturesSizeTotal + << " is " << new_complexity.texturesSizeTotal << LL_ENDL; + mReportedHUDComplexity.texturesSizeTotal = new_complexity.texturesSizeTotal; + } + else if ((mReportedHUDComplexity.objectsCost < new_complexity.objectsCost + || mReportedHUDComplexity.texturesCost < new_complexity.texturesCost) + && max_render_cost > 0 + && new_complexity.objectsCost + new_complexity.texturesCost > max_render_cost) + { + LL_DEBUGS("HUDdetail") << "HUD complexity over limit," + << " HUD textures cost: " << new_complexity.texturesCost + << " HUD objects cost: " << new_complexity.objectsCost << LL_ENDL; + displayHUDNotification(hud_cost); + mReportedHUDComplexity.objectsCost = new_complexity.objectsCost; + mReportedHUDComplexity.texturesCost = new_complexity.texturesCost; + } + else if (mReportedHUDComplexity.largeTexturesCount < new_complexity.largeTexturesCount + && new_complexity.largeTexturesCount > max_oversized_count) + { + LL_DEBUGS("HUDdetail") << "HUD contains to many large textures: " + << new_complexity.largeTexturesCount << LL_ENDL; + displayHUDNotification(hud_heavy); + mReportedHUDComplexity.largeTexturesCount = new_complexity.largeTexturesCount; + } + else if (mReportedHUDComplexity.texturesCount < new_complexity.texturesCount + && new_complexity.texturesCount > max_textures_count) + { + LL_DEBUGS("HUDdetail") << "HUD contains too many textures: " + << new_complexity.texturesCount << LL_ENDL; + displayHUDNotification(hud_cramped); + mReportedHUDComplexity.texturesCount = new_complexity.texturesCount; + } + else if (mReportedHUDComplexity.objectsCount < new_complexity.objectsCount + && new_complexity.objectsCount > max_objects_count) + { + LL_DEBUGS("HUDdetail") << "HUD contains too many objects: " + << new_complexity.objectsCount << LL_ENDL; + displayHUDNotification(hud_textures); + mReportedHUDComplexity.objectsCount = new_complexity.objectsCount; + } + else + { + // all warnings displayed, just store everything so that we will + // be able to reduce values and show warnings again later + mReportedHUDComplexity = new_complexity; + } + } + + if (mLatestHUDComplexity.objectsCost != new_complexity.objectsCost + || mLatestHUDComplexity.objectsCount != new_complexity.objectsCount + || mLatestHUDComplexity.texturesCost != new_complexity.texturesCost + || mLatestHUDComplexity.texturesCount != new_complexity.texturesCount + || mLatestHUDComplexity.largeTexturesCount != new_complexity.largeTexturesCount + || mLatestHUDComplexity.texturesSizeTotal != new_complexity.texturesSizeTotal) + { + LL_INFOS("HUDdetail") << "HUD textures count: " << new_complexity.texturesCount + << " HUD textures cost: " << new_complexity.texturesCost + << " Large textures: " << new_complexity.largeTexturesCount + << " HUD objects cost: " << new_complexity.objectsCost + << " HUD objects count: " << new_complexity.objectsCount << LL_ENDL; + + mLatestHUDComplexity = new_complexity; + } + +} + +void LLHUDRenderNotifier::displayHUDNotification(const char* message) +{ + static LLCachedControl pop_up_delay(gSavedSettings, "ComplexityChangesPopUpDelay", 300); + static LLCachedControl expire_delay(gSavedSettings, "ShowMyComplexityChanges", 20); + LLDate expire_date(LLDate::now().secondsSinceEpoch() + expire_delay); + + LLSD args; + args["HUD_REASON"] = LLTrans::getString(message); + + LLNotifications::instance().add(LLNotification::Params() + .name("HUDComplexityWarning") + .expiry(expire_date) + .substitutions(args)); + mHUDPopUpDelayTimer.resetWithExpiry(pop_up_delay); +} + diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h index 2a2704de28..959bebef02 100644 --- a/indra/newview/llavatarrendernotifier.h +++ b/indra/newview/llavatarrendernotifier.h @@ -33,6 +33,25 @@ class LLViewerRegion; +struct LLHUDComplexity +{ + LLHUDComplexity() + { + objectsCost = 0; + objectsCount = 0; + texturesCost = 0; + texturesCount = 0; + largeTexturesCount = 0; + texturesSizeTotal = 0; + } + U32 objectsCost; + U32 objectsCount; + U32 texturesCost; + U32 texturesCount; + U32 largeTexturesCount; + F64 texturesSizeTotal; +}; + // Class to notify user about drastic changes in agent's render weights or if other agents // reported that user's agent is too 'heavy' for their settings class LLAvatarRenderNotifier : public LLSingleton @@ -81,4 +100,21 @@ private: S32 mLastOutfitRezStatus; }; +// Class to notify user about heavy set of HUD +class LLHUDRenderNotifier : public LLSingleton +{ +public: + LLHUDRenderNotifier(); + ~LLHUDRenderNotifier(); + + void updateNotificationHUD(LLHUDComplexity new_complexity); + +private: + void displayHUDNotification(const char* message); + + LLHUDComplexity mReportedHUDComplexity; + LLHUDComplexity mLatestHUDComplexity; + LLFrameTimer mHUDPopUpDelayTimer; +}; + #endif /* ! defined(LL_llavatarrendernotifier_H) */ diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index cdc7e20c2c..aebc066507 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -186,6 +186,7 @@ const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f; const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f; const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0; +const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024; enum ERenderName { @@ -8356,6 +8357,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() { U32 cost = VISUAL_COMPLEXITY_UNKNOWN; LLVOVolume::texture_cost_t textures; + LLHUDComplexity hud_complexity; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { @@ -8432,6 +8434,55 @@ void LLVOAvatar::calculateUpdateRenderComplexity() } } } + if (isSelf() + && attached_object + && attached_object->isHUDAttachment() + && attached_object->mDrawable) + { + textures.clear(); + + const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); + if (volume) + { + // get cost and individual textures + hud_complexity.objectsCost += volume->getRenderCost(textures); + hud_complexity.objectsCount++; + + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* childp = *iter; + const LLVOVolume* chld_volume = dynamic_cast(childp); + if (chld_volume) + { + // get cost and individual textures + hud_complexity.objectsCost += chld_volume->getRenderCost(textures); + hud_complexity.objectsCount++; + } + } + + hud_complexity.texturesCount += textures.size(); + + for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); + volume_texture != textures.end(); + ++volume_texture) + { + // add the cost of each individual texture (ignores duplicates) + hud_complexity.texturesCost += volume_texture->second; + LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first); + if (tex) + { + F64 size = tex->getMaxVirtualSize(); // in pixels + hud_complexity.texturesSizeTotal += size; + if (size >= HUD_OVERSIZED_TEXTURE_DATA_SIZE) + { + hud_complexity.largeTexturesCount++; + } + } + } + } + } } } @@ -8493,11 +8544,15 @@ void LLVOAvatar::calculateUpdateRenderComplexity() static LLCachedControl show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20); - if (isSelf() && show_my_complexity_changes) - { - LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity); - } - } + if (isSelf() && show_my_complexity_changes) + { + // Avatar complexity + LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity); + + // HUD complexity + LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity); + } + } } void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set) diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 6fdeedc8ae..102ce0ddc0 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3319,6 +3319,20 @@ Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Renderin Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] is [AGENT_COMPLEXITY]. + + + HUDComplexityWarning + + [HUD_REASON], it is likely to negatively affect your performance. + + + You may not be rendered by most of those around you. You may not be rendered by anyone around you. + + Your HUD uses a lot of texture memory + Your HUD contains a lot of expensive objects and textures + Your HUD contains a lot of large textures + Your HUD contains too many objects + Your HUD contains too many textures +