diff options
47 files changed, 707 insertions, 119 deletions
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 48461df6ae..840d09d970 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -36,6 +36,10 @@ // pull in the actual class definition #include "llfasttimer_class.h" +// +// Important note: These implementations must be FAST! +// + #if LL_WINDOWS // // Windows implementation of CPU clock @@ -99,15 +103,17 @@ inline U64 LLFastTimer::getCPUClockCount64() #endif -#if LL_LINUX || LL_SOLARIS +#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) // -// Linux and Solaris implementation of CPU clock - all architectures. +// Linux and Solaris implementation of CPU clock - non-x86. +// This is accurate but SLOW! Only use out of desperation. // // Try to use the MONOTONIC clock if available, this is a constant time counter -// with nanosecond resolution (but not necessarily accuracy) and attempts are made -// to synchronize this value between cores at kernel start. It should not be affected -// by CPU frequency. If not available use the REALTIME clock, but this may be affected by -// NTP adjustments or other user activity affecting the system time. +// with nanosecond resolution (but not necessarily accuracy) and attempts are +// made to synchronize this value between cores at kernel start. It should not +// be affected by CPU frequency. If not available use the REALTIME clock, but +// this may be affected by NTP adjustments or other user activity affecting +// the system time. inline U64 LLFastTimer::getCPUClockCount64() { struct timespec tp; @@ -124,12 +130,12 @@ inline U32 LLFastTimer::getCPUClockCount32() { return (U32)(LLFastTimer::getCPUClockCount64() >> 8); } -#endif // (LL_LINUX || LL_SOLARIS)) +#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) -#if (LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) +#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) // -// Mac x86 implementation of CPU clock +// Mac+Linux+Solaris FAST x86 implementation of CPU clock inline U32 LLFastTimer::getCPUClockCount32() { U64 x; diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index 2e5edb1f3b..f39a4e6619 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -230,17 +230,17 @@ void LLFastTimer::DeclareTimer::updateCachedPointers() } //static -#if LL_LINUX || LL_SOLARIS || ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__)) ) +#if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer { return sClockResolution >> 8; } -#else // windows or x86-mac +#else // windows or x86-mac or x86-linux or x86-solaris U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer { static U64 sCPUClockFrequency = U64(CProcessor().GetCPUFrequency(50)); - // we drop the low-order byte in out timers, so report a lower frequency + // we drop the low-order byte in our timers, so report a lower frequency return sCPUClockFrequency >> 8; } #endif diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 8a4a4a8f9a..f6ab55a6b5 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -60,6 +60,10 @@ # include <windows.h> #endif +#if LL_LINUX +#include "llsys.h" +#endif // LL_LINUX + #if !LL_DARWIN && !LL_SOLARIS #ifdef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE @@ -116,6 +120,11 @@ CProcessor::CProcessor() //////////////////////////////////////////////////////////////////////////// F64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs) { +#if LL_LINUX + // use the shinier LLCPUInfo interface + return 1000000.0F * gSysCPU.getMHz(); +#endif + #ifndef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE return 0; #else @@ -781,7 +790,7 @@ bool CProcessor::AnalyzeAMDProcessor() case 5: // Family = 5: K5 / K6 processor family switch (CPUInfo.uiModel) { - case 0: // Model = 0: K5 SSA 5 (Pentium Rating *ggg* 75, 90 and 100 Mhz) + case 0: // Model = 0: K5 SSA 5 (Pentium Rating *ggg* 75, 90 and 100 MHz) strcpy(CPUInfo.strModel, "AMD K5 SSA5 (PR75, PR90, PR100)"); /* Flawfinder: ignore */ strncat(strCPUName, "AMD K5 SSA5 (PR75, PR90, PR100)", sizeof(strCPUName) - strlen(strCPUName) -1); /* Flawfinder: ignore */ break; diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 0272c55db2..52b1b63209 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -519,15 +519,15 @@ LLCPUInfo::LLCPUInfo() mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions; mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions; mHasAltivec = info->_Ext.Altivec_Extensions; - mCPUMhz = (S32)(proc.GetCPUFrequency(50)/1000000.0); + mCPUMHz = (F64)(proc.GetCPUFrequency(50)/1000000.0F); mFamily.assign( info->strFamily ); mCPUString = "Unknown"; #if LL_WINDOWS || LL_DARWIN || LL_SOLARIS out << proc.strCPUName; - if (200 < mCPUMhz && mCPUMhz < 10000) // *NOTE: cpu speed is often way wrong, do a sanity check + if (200 < mCPUMHz && mCPUMHz < 10000) // *NOTE: cpu speed is often way wrong, do a sanity check { - out << " (" << mCPUMhz << " MHz)"; + out << " (" << mCPUMHz << " MHz)"; } mCPUString = out.str(); @@ -572,7 +572,7 @@ LLCPUInfo::LLCPUInfo() if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) && 200.0 < mhz && mhz < 10000.0) { - mCPUMhz = (S32)llrint(mhz); + mCPUMHz = (F64)(mhz); } if (!cpuinfo["model name"].empty()) mCPUString = cpuinfo["model name"]; @@ -595,9 +595,9 @@ bool LLCPUInfo::hasSSE2() const return mHasSSE2; } -S32 LLCPUInfo::getMhz() const +F64 LLCPUInfo::getMHz() const { - return mCPUMhz; + return mCPUMHz; } std::string LLCPUInfo::getCPUString() const @@ -644,7 +644,7 @@ void LLCPUInfo::stream(std::ostream& s) const s << "->mHasSSE: " << (U32)mHasSSE << std::endl; s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl; s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl; - s << "->mCPUMhz: " << mCPUMhz << std::endl; + s << "->mCPUMHz: " << mCPUMHz << std::endl; s << "->mCPUString: " << mCPUString << std::endl; } diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index c2c45bec9a..0b34951149 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -81,7 +81,7 @@ public: bool hasAltivec() const; bool hasSSE() const; bool hasSSE2() const; - S32 getMhz() const; + F64 getMHz() const; // Family is "AMD Duron" or "Intel Pentium Pro" const std::string& getFamily() const { return mFamily; } @@ -90,7 +90,7 @@ private: bool mHasSSE; bool mHasSSE2; bool mHasAltivec; - S32 mCPUMhz; + F64 mCPUMHz; std::string mFamily; std::string mCPUString; }; diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 25b768079b..6111db2bfa 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -209,7 +209,7 @@ F64 calc_clock_frequency(U32 uiMeasureMSecs) // Both Linux and Mac use gettimeofday for accurate time F64 calc_clock_frequency(unsigned int uiMeasureMSecs) { - return 1000000.0; // microseconds, so 1 Mhz. + return 1000000.0; // microseconds, so 1 MHz. } U64 get_clock_count() diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 35f5a6bbb9..82f054c4b7 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -504,7 +504,68 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask) //*TODO find a better place for that enforcing stuff if (mKeepOneItemSelected && numSelected() == 1 && !select_item) return; - + + if ( (mask & MASK_SHIFT) && !(mask & MASK_CONTROL) + && mMultipleSelection && !mSelectedItemPairs.empty() ) + { + item_pair_t* last_selected_pair = mSelectedItemPairs.back(); + + // If item_pair is already selected - do nothing + if (last_selected_pair == item_pair) + return; + + bool grab_items = false; + pairs_list_t pairs_to_select; + + // Pick out items from list between last selected and current clicked item_pair. + for (pairs_iterator_t + iter = mItemPairs.begin(), + iter_end = mItemPairs.end(); + iter != iter_end; ++iter) + { + item_pair_t* cur = *iter; + if (cur == last_selected_pair || cur == item_pair) + { + grab_items = !grab_items; + // Skip last selected and current clicked item pairs. + continue; + } + if (!cur->first->getVisible()) + { + // Skip invisible item pairs. + continue; + } + if (grab_items) + { + pairs_to_select.push_back(cur); + } + } + + if (select_item) + { + pairs_to_select.push_back(item_pair); + } + + for (pairs_iterator_t + iter = pairs_to_select.begin(), + iter_end = pairs_to_select.end(); + iter != iter_end; ++iter) + { + item_pair_t* pair_to_select = *iter; + selectItemPair(pair_to_select, true); + } + + if (!select_item) + { + // Item was already selected but there is a need to update last selected item and its border. + // Do it here to prevent extra mCommitOnSelectionChange in selectItemPair(). + mSelectedItemPairs.remove(item_pair); + mSelectedItemPairs.push_back(item_pair); + mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1)); + } + return; + } + if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection(); selectItemPair(item_pair, select_item); } diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 80ee5d0984..04958075db 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -63,7 +63,8 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p) mCanEditText(p.can_edit_text), mPrecision(p.decimal_digits), mTextEnabledColor(p.text_color()), - mTextDisabledColor(p.text_disabled_color()) + mTextDisabledColor(p.text_disabled_color()), + mLabelWidth(p.label_width) { S32 top = getRect().getHeight(); S32 bottom = 0; @@ -86,6 +87,7 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p) params.initial_value(p.label()); mLabelBox = LLUICtrlFactory::create<LLTextBox> (params); addChild(mLabelBox); + mLabelFont = params.font(); } if (p.show_text && !p.text_width.isProvided()) @@ -186,9 +188,9 @@ BOOL LLSliderCtrl::setLabelArg( const std::string& key, const LLStringExplicit& if (mLabelBox) { res = mLabelBox->setTextArg(key, text); - if (res && mLabelWidth == 0) + if (res && mLabelFont && mLabelWidth == 0) { - S32 label_width = mFont->getWidth(mLabelBox->getText()); + S32 label_width = mLabelFont->getWidth(mLabelBox->getText()); LLRect rect = mLabelBox->getRect(); S32 prev_right = rect.mRight; rect.mRight = rect.mLeft + label_width; diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h index c425849782..482c81a0f4 100644 --- a/indra/llui/llsliderctrl.h +++ b/indra/llui/llsliderctrl.h @@ -141,6 +141,7 @@ private: void reportInvalidData(); const LLFontGL* mFont; + const LLFontGL* mLabelFont; BOOL mShowText; BOOL mCanEditText; @@ -158,3 +159,4 @@ private: }; #endif // LL_LLSLIDERCTRL_H + diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index a1cae4bb98..4fd62045e8 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -713,7 +713,8 @@ BOOL LLTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask) { setFocus(TRUE); } - if (!LLTextBase::handleRightMouseDown(x, y, mask)) + // Prefer editor menu if it has selection. See EXT-6806. + if (hasSelection() || !LLTextBase::handleRightMouseDown(x, y, mask)) { if(getShowContextMenu()) { diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt index 4f183cddeb..1a559ed39c 100644 --- a/indra/media_plugins/webkit/CMakeLists.txt +++ b/indra/media_plugins/webkit/CMakeLists.txt @@ -36,6 +36,10 @@ set(media_plugin_webkit_SOURCE_FILES media_plugin_webkit.cpp ) +set(media_plugin_webkit_HEADER_FILES + volume_catcher.h + ) + set(media_plugin_webkit_LINK_LIBRARIES ${LLPLUGIN_LIBRARIES} ${MEDIA_PLUGIN_BASE_LIBRARIES} @@ -59,11 +63,18 @@ elseif (DARWIN) ${CORESERVICES_LIBRARY} # for Component Manager calls ${AUDIOUNIT_LIBRARY} # for AudioUnit calls ) +elseif (WINDOWS) + list(APPEND media_plugin_webkit_SOURCE_FILES windows_volume_catcher.cpp) else (LINUX AND PULSEAUDIO) # All other platforms use the dummy volume catcher for now. list(APPEND media_plugin_webkit_SOURCE_FILES dummy_volume_catcher.cpp) endif (LINUX AND PULSEAUDIO) +set_source_files_properties(${media_plugin_webkit_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND media_plugin_webkit_SOURCE_FILES ${media_plugin_webkit_HEADER_FILES}) + add_library(media_plugin_webkit SHARED ${media_plugin_webkit_SOURCE_FILES} diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/webkit/windows_volume_catcher.cpp new file mode 100644 index 0000000000..1c1ef0b42f --- /dev/null +++ b/indra/media_plugins/webkit/windows_volume_catcher.cpp @@ -0,0 +1,316 @@ +/** + * @file windows_volume_catcher.cpp + * @brief A Windows implementation of volume level control of all audio channels opened by a process. + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * @endcond + */ + +#include "volume_catcher.h" +#include <windows.h> + +// +// Abstracts a Win32 mixer line and associated state +// for muting and changing volume on a given output +// +class Mixer +{ +public: + static Mixer* create(U32 index); + ~Mixer(); + + void setMute(bool mute); + void setVolume(F32 volume_left, F32 volume_right); + +private: + // use create(index) to create a Mixer + Mixer(HMIXER handle, U32 mute_control_id, U32 volume_control_id, U32 min_volume, U32 max_volume); + + HMIXER mHandle; + U32 mMuteControlID; // handle to mixer controller for muting + U32 mVolumeControlID; // handle to mixer controller for changing volume + U32 mMinVolume; // value that specifies minimum volume as reported by mixer + U32 mMaxVolume; // value that specifies maximum volume as reported by mixer +}; + +// factory function that attempts to create a Mixer object associated with a given mixer line index +// returns NULL if creation failed +// static +Mixer* Mixer::create(U32 index) +{ + // get handle to mixer object + HMIXER mixer_handle; + MMRESULT result = mixerOpen( &mixer_handle, + index, + 0, // HWND to call when state changes - not used + 0, // user data for callback - not used + MIXER_OBJECTF_MIXER ); + + if (result == MMSYSERR_NOERROR) + { + MIXERLINE mixer_line; + mixer_line.cbStruct = sizeof( MIXERLINE ); + + // try speakers first + mixer_line.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; + + MMRESULT result = mixerGetLineInfo( reinterpret_cast< HMIXEROBJ >( mixer_handle ), + &mixer_line, + MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE ); + if (result != MMSYSERR_NOERROR) + { // failed - try headphones next + mixer_line.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_HEADPHONES; + result = mixerGetLineInfo( reinterpret_cast< HMIXEROBJ >( mixer_handle ), + &mixer_line, + MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE ); + } + + if (result == MMSYSERR_NOERROR) + { // successfully found mixer line object, now use it to get volume and mute controls + + // reuse these objects to query for both volume and mute controls + MIXERCONTROL mixer_control; + MIXERLINECONTROLS mixer_line_controls; + mixer_line_controls.cbStruct = sizeof( MIXERLINECONTROLS ); + mixer_line_controls.dwLineID = mixer_line.dwLineID; + mixer_line_controls.cControls = 1; + mixer_line_controls.cbmxctrl = sizeof( MIXERCONTROL ); + mixer_line_controls.pamxctrl = &mixer_control; + + // first, query for mute + mixer_line_controls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE; + + // get control id for mute controls + result = mixerGetLineControls( reinterpret_cast< HMIXEROBJ >( mixer_handle ), + &mixer_line_controls, + MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE ); + if (result == MMSYSERR_NOERROR ) + { // we have a mute controls. Remember the mute control id and then query for + // volume controls using the same struct, but different dwControlType + + U32 mute_control_id = mixer_control.dwControlID; + mixer_line_controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; + result = mixerGetLineControls( reinterpret_cast< HMIXEROBJ >( mixer_handle ), + &mixer_line_controls, + MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE ); + + if (result == MMSYSERR_NOERROR) + { // we have both mute and volume controls for this mixer, so we're keeping it + return new Mixer(mixer_handle, + mute_control_id, + mixer_control.dwControlID, + mixer_control.Bounds.dwMinimum, + mixer_control.Bounds.dwMaximum); + } + } + } + } + + // if we got here, we didn't successfully create a Mixer object + mixerClose(mixer_handle); + return NULL; +} + +Mixer::Mixer(HMIXER handle, U32 mute_control_id, U32 volume_control_id, U32 min_volume, U32 max_volume) +: mHandle(handle), + mMuteControlID(mute_control_id), + mVolumeControlID(volume_control_id), + mMinVolume(min_volume), + mMaxVolume(max_volume) +{} + +Mixer::~Mixer() +{} + +// toggle mute for this mixer +// if mute is set, then volume level will be ignored +void Mixer::setMute(bool mute) +{ + MIXERCONTROLDETAILS_BOOLEAN mixer_control_details_bool = { mute }; + MIXERCONTROLDETAILS mixer_control_details; + mixer_control_details.cbStruct = sizeof( MIXERCONTROLDETAILS ); + mixer_control_details.dwControlID = mMuteControlID; + mixer_control_details.cChannels = 1; + mixer_control_details.cMultipleItems = 0; + mixer_control_details.cbDetails = sizeof( MIXERCONTROLDETAILS_BOOLEAN ); + mixer_control_details.paDetails = &mixer_control_details_bool; + + mixerSetControlDetails( reinterpret_cast< HMIXEROBJ >( mHandle ), + &mixer_control_details, + MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE ); +} + +// set individual volume levels for left and right channels +// if mute is set, then these values will apply once mute is unset +void Mixer::setVolume(F32 volume_left, F32 volume_right) +{ + // assuming pan is in range [-1, 1] set volume levels accordingly + // if pan == -1 then volume_left_mixer = volume_left && volume_right_mixer = 0 + // if pan == 0 then volume_left_mixer = volume_left && volume_right_mixer = volume_right + // if pan == 1 then volume_left_mixer = 0 && volume_right_mixer = volume_right + U32 volume_left_mixer = (U32) + ((F32)mMinVolume + + (volume_left * ((F32)mMaxVolume - (F32)mMinVolume))); + U32 volume_right_mixer = (U32) + ((F32)mMinVolume + + (volume_right * ((F32)mMaxVolume - (F32)mMinVolume))); + + // pass volume levels on to mixer + MIXERCONTROLDETAILS_UNSIGNED mixer_control_details_unsigned[ 2 ] = { volume_left_mixer, volume_right_mixer }; + MIXERCONTROLDETAILS mixer_control_details; + mixer_control_details.cbStruct = sizeof( MIXERCONTROLDETAILS ); + mixer_control_details.dwControlID = mVolumeControlID; + mixer_control_details.cChannels = 2; + mixer_control_details.cMultipleItems = 0; + mixer_control_details.cbDetails = sizeof( MIXERCONTROLDETAILS_UNSIGNED ); + mixer_control_details.paDetails = &mixer_control_details_unsigned; + + mixerSetControlDetails( reinterpret_cast< HMIXEROBJ >( mHandle ), + &mixer_control_details, + MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE ); +} + +class VolumeCatcherImpl +{ +public: + + void setVolume(F32 volume); + void setPan(F32 pan); + + static VolumeCatcherImpl *getInstance(); +private: + // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. + VolumeCatcherImpl(); + ~VolumeCatcherImpl(); + + static VolumeCatcherImpl *sInstance; + + F32 mVolume; + F32 mPan; + typedef std::vector<Mixer*> mixer_vector_t; + mixer_vector_t mMixers; +}; + +VolumeCatcherImpl *VolumeCatcherImpl::sInstance = NULL; + +VolumeCatcherImpl *VolumeCatcherImpl::getInstance() +{ + if(!sInstance) + { + sInstance = new VolumeCatcherImpl; + } + + return sInstance; +} + +VolumeCatcherImpl::VolumeCatcherImpl() +: mVolume(1.0f), // default volume is max + mPan(0.f) // default pan is centered +{ + // for each reported mixer "device", create a proxy object and add to list + U32 num_mixers = mixerGetNumDevs(); + for (U32 mixer_index = 0; mixer_index < num_mixers; ++mixer_index) + { + Mixer* mixerp = Mixer::create(mixer_index); + if (mixerp) + { + mMixers.push_back(mixerp); + } + } +} + +VolumeCatcherImpl::~VolumeCatcherImpl() +{ + for(mixer_vector_t::iterator it = mMixers.begin(), end_it = mMixers.end(); + it != end_it; + ++it) + { + delete *it; + *it = NULL; + } +} + + +void VolumeCatcherImpl::setVolume(F32 volume) +{ + F32 left_volume = volume * min(1.f, 1.f - mPan); + F32 right_volume = volume * max(0.f, 1.f + mPan); + + for(mixer_vector_t::iterator it = mMixers.begin(), end_it = mMixers.end(); + it != end_it; + ++it) + { // set volume levels and mute for each mixer + // note that a muted mixer will ignore this volume level + + (*it)->setVolume(left_volume, right_volume); + + if (volume == 0.f && mVolume != 0.f) + { + (*it)->setMute(true); + } + else if (mVolume == 0.f && volume != 0.f) + { + (*it)->setMute(false); + } + + } + mVolume = volume; +} + +void VolumeCatcherImpl::setPan(F32 pan) +{ // remember pan for calculating individual channel levels later + mPan = pan; +} + +///////////////////////////////////////////////////// + +VolumeCatcher::VolumeCatcher() +{ + pimpl = VolumeCatcherImpl::getInstance(); +} + +VolumeCatcher::~VolumeCatcher() +{ + // Let the instance persist until exit. +} + +void VolumeCatcher::setVolume(F32 volume) +{ + pimpl->setVolume(volume); +} + +void VolumeCatcher::setPan(F32 pan) +{ + pimpl->setPan(pan); +} + +void VolumeCatcher::pump() +{ + // No periodic tasks are necessary for this implementation. +} + diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index ec465358fa..8bcf680876 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1295,6 +1295,8 @@ void LLAgent::stopAutoPilot(BOOL user_cancel) { resetAxes(mAutoPilotTargetFacing); } + // Restore previous flying state before invoking mAutoPilotFinishedCallback to allow + // callback function to change the flying state (like in near_sit_down_point()). // If the user cancelled, don't change the fly state if (!user_cancel) { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7a381d05ad..cc44a96675 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -864,7 +864,7 @@ bool LLAppViewer::init() minSpecs += "\n"; unsupported = true; } - if(gSysCPU.getMhz() < minCPU) + if(gSysCPU.getMHz() < minCPU) { minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU"); minSpecs += "\n"; @@ -2550,7 +2550,7 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString(); gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily(); - gDebugInfo["CPUInfo"]["CPUMhz"] = gSysCPU.getMhz(); + gDebugInfo["CPUInfo"]["CPUMhz"] = (S32)gSysCPU.getMHz(); gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec(); gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE(); gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2(); @@ -2563,7 +2563,7 @@ void LLAppViewer::writeSystemInfo() // which may have been the intended grid. This can b gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel(); - // *FIX:Mani - move this ddown in llappviewerwin32 + // *FIX:Mani - move this down in llappviewerwin32 #ifdef LL_WINDOWS DWORD thread_id = GetCurrentThreadId(); gDebugInfo["MainloopThreadID"] = (S32)thread_id; diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index ba92c33d59..4c1e3461a5 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -75,7 +75,9 @@ public: mPosY(0), mPosZ(0), mLoaded(false) - {} + { + mHandle.bind(this); + } void setLandmarkID(const LLUUID& id) { mLandmarkID = id; } const LLUUID& getLandmarkId() const { return mLandmarkID; } @@ -122,17 +124,21 @@ private: if(LLLandmarkActions::getLandmarkGlobalPos(mLandmarkID, g_pos)) { LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(g_pos, - boost::bind(&LLLandmarkInfoGetter::landmarkNameCallback, this, _1, _2, _3, _4)); + boost::bind(&LLLandmarkInfoGetter::landmarkNameCallback, static_cast<LLHandle<LLLandmarkInfoGetter> >(mHandle), _1, _2, _3, _4)); } } - void landmarkNameCallback(const std::string& name, S32 x, S32 y, S32 z) + static void landmarkNameCallback(LLHandle<LLLandmarkInfoGetter> handle, const std::string& name, S32 x, S32 y, S32 z) { - mPosX = x; - mPosY = y; - mPosZ = z; - mName = name; - mLoaded = true; + LLLandmarkInfoGetter* getter = handle.get(); + if (getter) + { + getter->mPosX = x; + getter->mPosY = y; + getter->mPosZ = z; + getter->mName = name; + getter->mLoaded = true; + } } LLUUID mLandmarkID; @@ -141,6 +147,7 @@ private: S32 mPosY; S32 mPosZ; bool mLoaded; + LLRootHandle<LLLandmarkInfoGetter> mHandle; }; /** diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index fbb90c69f3..50b08f782a 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -621,9 +621,9 @@ void LLFeatureManager::applyBaseMasks() #if LL_SOLARIS && defined(__sparc) // even low MHz SPARCs are fast #error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here? - if (gSysCPU.getMhz() < 800) + if (gSysCPU.getMHz() < 800) #else - if (gSysCPU.getMhz() < 1100) + if (gSysCPU.getMHz() < 1100) #endif { maskFeatures("CPUSlow"); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 8d4d6a178a..c492bfcef1 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1416,8 +1416,8 @@ void LLFolderView::startRenamingSelectedItem( void ) mRenamer->setVisible( TRUE ); // set focus will fail unless item is visible mRenamer->setFocus( TRUE ); - mRenamer->setTopLostCallback(boost::bind(onRenamerLost, _1)); - mRenamer->setFocusLostCallback(boost::bind(onRenamerLost, _1)); + mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this, _1)); + mRenamer->setFocusLostCallback(boost::bind(&LLFolderView::onRenamerLost, this, _1)); gViewerWindow->addPopup(mRenamer); } } @@ -2386,9 +2386,9 @@ S32 LLFolderView::notify(const LLSD& info) /// Local function definitions ///---------------------------------------------------------------------------- -//static void LLFolderView::onRenamerLost( LLFocusableElement* renamer) { + mRenameItem = NULL; LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(renamer); if (uictrl) { diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 42390dfd17..874723bb1a 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -279,7 +279,7 @@ protected: LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container. void commitRename( const LLSD& data ); - static void onRenamerLost( LLFocusableElement* renamer); + void onRenamerLost( LLFocusableElement* renamer); void finishRenamingItem( void ); void closeRenamer( void ); diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index 325c9c260c..5b653638f2 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -78,7 +78,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, LLVector3 up_axis; if (orthographic) { - right_axis.setVec(0.f, -1.f / gViewerWindow->getWorldViewWidthRaw(), 0.f); + right_axis.setVec(0.f, -1.f / gViewerWindow->getWorldViewHeightRaw(), 0.f); up_axis.setVec(0.f, 0.f, 1.f / gViewerWindow->getWorldViewHeightRaw()); } else diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 10146ee9d3..4357c7d426 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1459,7 +1459,13 @@ void LLCallDialogManager::onVoiceChannelChanged(const LLUUID &session_id) } sSession = session; - sSession->mVoiceChannel->setStateChangedCallback(boost::bind(LLCallDialogManager::onVoiceChannelStateChanged, _1, _2, _3, _4)); + + static boost::signals2::connection prev_channel_state_changed_connection; + // disconnect previously connected callback to avoid have invalid sSession in onVoiceChannelStateChanged() + prev_channel_state_changed_connection.disconnect(); + prev_channel_state_changed_connection = + sSession->mVoiceChannel->setStateChangedCallback(boost::bind(LLCallDialogManager::onVoiceChannelStateChanged, _1, _2, _3, _4)); + if(sCurrentSessionlName != session->mName) { sPreviousSessionlName = sCurrentSessionlName; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a62c759ace..9762897491 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2692,6 +2692,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { // This is the lost+found folder. mItems.push_back(std::string("Empty Lost And Found")); + + mDisabledItems.push_back(std::string("New Folder")); + mDisabledItems.push_back(std::string("New Script")); + mDisabledItems.push_back(std::string("New Note")); + mDisabledItems.push_back(std::string("New Gesture")); + mDisabledItems.push_back(std::string("New Clothes")); + mDisabledItems.push_back(std::string("New Body Parts")); } if(trash_id == mUUID) diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 0ddc4efc81..2f22512aba 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -200,7 +200,11 @@ void LLFloaterMove::setFlyingMode(BOOL fly) if (instance) { instance->setFlyingModeImpl(fly); - BOOL is_sitting = isAgentAvatarValid() && gAgentAvatarp->isSitting(); + LLVOAvatarSelf* avatar_object = gAgentAvatarp; + bool is_sitting = avatar_object + && (avatar_object->getRegion() != NULL) + && (!avatar_object->isDead()) + && avatar_object->isSitting(); instance->showModeButtons(!fly && !is_sitting); } if (fly) diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index 93ebae334f..79786c06d9 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -1010,7 +1010,7 @@ void LLPanelNearByMedia::updateControls() if (NULL == impl) { // Just means it hasn't started yet - showBasicControls(false, false, false); + showBasicControls(false, false, false, false, 0); } else if (impl->isMediaTimeBased()) { @@ -1022,7 +1022,11 @@ void LLPanelNearByMedia::updateControls() } else { // non-time-based parcel media - showBasicControls(LLViewerMedia::isParcelMediaPlaying(), false, false); + showBasicControls(LLViewerMedia::isParcelMediaPlaying(), + false, + false, + impl->getVolume() == 0.0, + impl->getVolume()); } } } @@ -1045,19 +1049,28 @@ void LLPanelNearByMedia::updateControls() else { showBasicControls(!impl->isMediaDisabled(), ! impl->isParcelMedia(), // include_zoom - LLViewerMediaFocus::getInstance()->isZoomed()); + LLViewerMediaFocus::getInstance()->isZoomed(), + impl->getVolume() == 0.0, + impl->getVolume()); } } } } -void LLPanelNearByMedia::showBasicControls(bool playing, bool include_zoom, bool is_zoomed) +void LLPanelNearByMedia::showBasicControls(bool playing, bool include_zoom, bool is_zoomed, bool muted, F32 volume) { mStopCtrl->setVisible(playing); mPlayCtrl->setVisible(!playing); mPauseCtrl->setVisible(false); - mMuteCtrl->setVisible(false); +#ifdef PER_MEDIA_VOLUME + mVolumeSliderCtrl->setVisible(true); + mMuteCtrl->setVisible(true); + mMuteBtn->setValue(muted); + mVolumeSlider->setValue(volume); +#else mVolumeSliderCtrl->setVisible(false); + mMuteCtrl->setVisible(false); +#endif mZoomCtrl->setVisible(include_zoom && !is_zoomed); mUnzoomCtrl->setVisible(include_zoom && is_zoomed); mStopCtrl->setEnabled(true); @@ -1156,7 +1169,7 @@ void LLPanelNearByMedia::onClickSelectedMediaMute() else { LLViewerMediaImpl* impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? ((LLViewerMediaImpl*)LLViewerParcelMedia::getParcelMedia()) : LLViewerMedia::getMediaImplFromTextureID(selected_media_id); - if (NULL != impl && impl->isMediaTimeBased()) + if (NULL != impl) { F32 volume = impl->getVolume(); if(volume > 0.0) @@ -1187,7 +1200,7 @@ void LLPanelNearByMedia::onCommitSelectedMediaVolume() else { LLViewerMediaImpl* impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? ((LLViewerMediaImpl*)LLViewerParcelMedia::getParcelMedia()) : LLViewerMedia::getMediaImplFromTextureID(selected_media_id); - if (NULL != impl && impl->isMediaTimeBased()) + if (NULL != impl) { impl->setVolume(mVolumeSlider->getValueF32()); } diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index 7c07867df3..3cecf8e40c 100644 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -140,7 +140,7 @@ private: bool shouldShow(LLViewerMediaImpl* impl); - void showBasicControls(bool playing, bool include_zoom, bool is_zoomed); + void showBasicControls(bool playing, bool include_zoom, bool is_zoomed, bool muted, F32 volume); void showTimeBasedControls(bool playing, bool include_zoom, bool is_zoomed, bool muted, F32 volume); void showDisabledControls(); void updateControls(); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index d78a448acb..ba6473839a 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -133,10 +133,6 @@ mRemoveFromOutfitBtn(NULL), mLookObserver(NULL) mLookItemTypes.push_back(LLLookItemType()); } - // TODO: make these strings translatable - mLookItemTypes[LIT_ALL] = LLLookItemType("All Items", ALL_ITEMS_MASK); - mLookItemTypes[LIT_WEARABLE] = LLLookItemType("Shape & Clothing", WEARABLE_MASK); - mLookItemTypes[LIT_ATTACHMENT] = LLLookItemType("Attachments", ATTACHMENT_MASK); } @@ -159,10 +155,15 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit() BOOL LLPanelOutfitEdit::postBuild() { // gInventory.isInventoryUsable() no longer needs to be tested per Richard's fix for race conditions between inventory and panels - + + mLookItemTypes[LIT_ALL] = LLLookItemType(getString("Filter.All"), ALL_ITEMS_MASK); + mLookItemTypes[LIT_WEARABLE] = LLLookItemType(getString("Filter.Clothes/Body"), WEARABLE_MASK); + mLookItemTypes[LIT_ATTACHMENT] = LLLookItemType(getString("Filter.Objects"), ATTACHMENT_MASK); + mCurrentOutfitName = getChild<LLTextBox>("curr_outfit_name"); childSetCommitCallback("add_btn", boost::bind(&LLPanelOutfitEdit::showAddWearablesPanel, this), NULL); + childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL); mLookContents = getChild<LLScrollListCtrl>("look_items_list"); mLookContents->sortByColumn("look_item_sort", TRUE); @@ -174,7 +175,7 @@ BOOL LLPanelOutfitEdit::postBuild() mInventoryItemsPanel->setSelectCallback(boost::bind(&LLPanelOutfitEdit::onInventorySelectionChange, this, _1, _2)); mInventoryItemsPanel->getRootFolder()->setReshapeCallback(boost::bind(&LLPanelOutfitEdit::onInventorySelectionChange, this, _1, _2)); - LLComboBox* type_filter = getChild<LLComboBox>("inventory_filter"); + LLComboBox* type_filter = getChild<LLComboBox>("filter_wearables_combobox"); type_filter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onTypeFilterChanged, this, _1)); type_filter->removeall(); for (U32 i = 0; i < mLookItemTypes.size(); ++i) @@ -236,6 +237,11 @@ void LLPanelOutfitEdit::showAddWearablesPanel() childSetVisible("add_wearables_panel", childGetValue("add_btn")); } +void LLPanelOutfitEdit::showWearablesFilter() +{ + childSetVisible("filter_combobox_panel", childGetValue("filter_button")); +} + void LLPanelOutfitEdit::saveOutfit(bool as_new) { if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit()) @@ -457,20 +463,18 @@ void LLPanelOutfitEdit::onInventorySelectionChange(const std::deque<LLFolderView void LLPanelOutfitEdit::onOutfitItemSelectionChange(void) { - S32 left_offset = -4; - S32 top_offset = -10; LLScrollListItem* item = mLookContents->getLastSelectedItem(); if (!item) return; - LLRect rect = item->getRect(); - LLRect btn_rect( - left_offset + rect.mRight - 50, - top_offset + rect.mTop, - left_offset + rect.mRight - 30, - top_offset + rect.mBottom); + LLRect item_rect; + mLookContents->localRectToOtherView(item->getRect(), &item_rect, getChild<LLUICtrl>("outfit_wearables_panel")); + + // TODO button(and item list) should be removed (when new widget is ready) + LLRect btn_rect = mEditWearableBtn->getRect(); + btn_rect.set(item_rect.mRight - btn_rect.getWidth(), item_rect.mTop, item_rect.mRight, item_rect.mBottom); - mEditWearableBtn->setRect(btn_rect); + mEditWearableBtn->setShape(btn_rect); mEditWearableBtn->setEnabled(TRUE); if (!mEditWearableBtn->getVisible()) diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index fa92d4c314..69e8016534 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -87,6 +87,7 @@ public: // only update the location if there is none already available. void showAddWearablesPanel(); + void showWearablesFilter(); void saveOutfit(bool as_new = false); void showSaveMenu(); diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 83244edb8e..5209d50755 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -66,10 +66,6 @@ #include "llwindow.h" #include "llfloatertools.h" // to enable hide if build tools are up -#if defined(LL_DARWIN) || (defined(LL_WINDOW) && (! defined(LL_RELEASE_FOR_DOWNLOAD)) ) -#define PER_MEDIA_VOLUME -#endif - // Functions pulled from pipeline.cpp glh::matrix4f glh_get_current_modelview(); glh::matrix4f glh_get_current_projection(); @@ -467,10 +463,21 @@ void LLPanelPrimMediaControls::updateShape() mSkipBackCtrl->setEnabled(FALSE); #ifdef PER_MEDIA_VOLUME + // these should be pulled up above the pluginSupportsMediaTime + // if check once we always have PER_MEDIA_VOLUME turned on mVolumeCtrl->setVisible(has_focus); mVolumeCtrl->setEnabled(has_focus); mVolumeSliderCtrl->setEnabled(has_focus && shouldVolumeSliderBeVisible()); mVolumeSliderCtrl->setVisible(has_focus && shouldVolumeSliderBeVisible()); + + if(media_impl->getVolume() <= 0.0) + { + mMuteBtn->setToggleState(true); + } + else + { + mMuteBtn->setToggleState(false); + } #else mVolumeCtrl->setVisible(FALSE); mVolumeSliderCtrl->setVisible(FALSE); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index a9bbee784d..ae244cd8a1 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -1267,6 +1267,7 @@ bool LLToolPie::handleMediaClick(const LLPickInfo& pick) if (!parcel || objectp.isNull() || + objectp->isHUDAttachment() || pick.mObjectFace < 0 || pick.mObjectFace >= objectp->getNumTEs()) { diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index b758f6c701..240a539f2e 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -163,7 +163,7 @@ LLViewerJoystick::LLViewerJoystick() memset(mBtn, 0, sizeof(mBtn)); // factor in bandwidth? bandwidth = gViewerStats->mKBitStat - mPerfScale = 4000.f / gSysCPU.getMhz(); + mPerfScale = 4000.f / gSysCPU.getMHz(); // hmm. why? } // ----------------------------------------------------------------------------- diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index e829d7a5b4..bc6716697e 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -46,6 +46,12 @@ #include "llurl.h" + +#if defined(LL_DARWIN) || (LL_WINDOWS && !LL_RELEASE_FOR_DOWNLOAD ) +#define PER_MEDIA_VOLUME +#endif + + class LLViewerMediaImpl; class LLUUID; class LLViewerMediaTexture; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 832a6283ab..1fcbbd7fd4 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1636,6 +1636,18 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const return false; } +class LLPostponedOfferNotification: public LLPostponedNotification +{ +protected: + /* virtual */ + void modifyNotificationParams() + { + LLSD substitutions = mParams.substitutions; + substitutions["NAME"] = mName; + mParams.substitutions = substitutions; + } +}; + void inventory_offer_handler(LLOfferInfo* info) { //Until throttling is implmented, busy mode should reject inventory instead of silently @@ -1785,7 +1797,10 @@ void inventory_offer_handler(LLOfferInfo* info) // Inform user that there is a script floater via toast system { payload["give_inventory_notification"] = TRUE; - LLNotificationPtr notification = LLNotifications::instance().add(p.payload(payload)); + LLNotification::Params params(p.name); + params.substitutions = p.substitutions; + params.payload = p.payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, info->mFromID, false); } } } @@ -2557,7 +2572,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) payload["from_id"] = from_id; payload["lure_id"] = session_id; payload["godlike"] = FALSE; - LLNotificationsUtil::add("TeleportOffered", args, payload); + + LLNotification::Params params("TeleportOffered"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); } } break; @@ -2626,7 +2645,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) else { args["[MESSAGE]"] = message; - LLNotificationsUtil::add("OfferFriendship", args, payload); + LLNotification::Params params("OfferFriendship"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); } } } @@ -4408,6 +4430,9 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data) } gAgentCamera.setForceMouselook(force_mouselook); + // Forcing turning off flying here to prevent flying after pressing "Stand" + // to stand up from an object. See EXT-1655. + gAgent.setFlying(FALSE); LLViewerObject* object = gObjectList.findObject(sitObjectID); if (object) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index e30a211185..09b9da444f 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -67,6 +67,7 @@ #include "llmeshrepository.h" #include "llmutelist.h" #include "llmoveview.h" +#include "llnotificationsutil.h" #include "llquantize.h" #include "llregionhandle.h" #include "llresmgr.h" @@ -103,6 +104,8 @@ #include <boost/lexical_cast.hpp> +#define DISPLAY_AVATAR_LOAD_TIMES + using namespace LLVOAvatarDefines; //----------------------------------------------------------------------------- @@ -5576,8 +5579,6 @@ void LLVOAvatar::sitDown(BOOL bSitting) //----------------------------------------------------------------------------- void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) { - sitDown(TRUE); - if (isSelf()) { // Might be first sit @@ -5610,6 +5611,9 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot); gPipeline.markMoved(mDrawable, TRUE); + // Notice that removing sitDown() from here causes avatars sitting on + // objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655. + sitDown(TRUE); mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject mRoot.setPosition(getPosition()); mRoot.updateWorldMatrixChildren(); @@ -5818,6 +5822,7 @@ void LLVOAvatar::updateRuthTimer(bool loading) if (mPreviousFullyLoaded) { mRuthTimer.reset(); + mRuthDebugTimer.reset(); } const F32 LOADING_TIMEOUT = 120.f; @@ -5846,7 +5851,17 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading) mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE); - +#ifdef DISPLAY_AVATAR_LOAD_TIMES + if (!mPreviousFullyLoaded && !loading && mFullyLoaded) + { + llinfos << "Avatar '" << getFullname() << "' resolved in " << mRuthDebugTimer.getElapsedTimeF32() << " seconds." << llendl; + LLSD args; + args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); + args["NAME"] = getFullname(); + LLNotificationsUtil::add("AvatarRezNotification",args); + } +#endif + // did our loading state "change" from last call? const S32 UPDATE_RATE = 30; BOOL changed = diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 19e2c23ddd..411ebe4121 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -259,6 +259,7 @@ private: S32 mFullyLoadedFrameCounter; LLFrameTimer mFullyLoadedTimer; LLFrameTimer mRuthTimer; + LLFrameTimer mRuthDebugTimer; // For tracking how long it takes for av to rez /** State ** ** diff --git a/indra/newview/skins/default/xui/da/panel_status_bar.xml b/indra/newview/skins/default/xui/da/panel_status_bar.xml index 4618fe536d..08ffafd5a6 100644 --- a/indra/newview/skins/default/xui/da/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/da/panel_status_bar.xml @@ -22,7 +22,7 @@ L$ [AMT] </panel.string> <button label="" label_selected="" name="buycurrency" tool_tip="Min balance"/> - <button label="Køb" name="buyL" tool_tip="Klik for at købe flere L$"/> + <button label="Køb L$" name="buyL" tool_tip="Klik for at købe flere L$"/> <text name="TimeText" tool_tip="Nuværende tid (Pacific)"> 24:00 PST </text> diff --git a/indra/newview/skins/default/xui/de/panel_status_bar.xml b/indra/newview/skins/default/xui/de/panel_status_bar.xml index 0e182fa417..3dc6997320 100644 --- a/indra/newview/skins/default/xui/de/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml @@ -22,7 +22,7 @@ [AMT] L$ </panel.string> <button label="" label_selected="" name="buycurrency" tool_tip="Mein Kontostand"/> - <button label="Kaufen" name="buyL" tool_tip="Hier klicken, um mehr L$ zu kaufen"/> + <button label="L$ kaufen" name="buyL" tool_tip="Hier klicken, um mehr L$ zu kaufen"/> <text name="TimeText" tool_tip="Aktuelle Zeit (Pazifik)"> 24:00 H PST </text> diff --git a/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml index bd9925be1d..e94af2c8d5 100644 --- a/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml +++ b/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml @@ -15,7 +15,7 @@ follows="left|top|right|bottom" height="176" layout="topleft" - max_length="10000" + max_length="2147483647" name="Chat History Editor" parse_highlights="true" width="420" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 25e10114b0..4b8f897bf6 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5973,6 +5973,13 @@ The button will be shown when there is enough space for it. </notification> <notification + icon="notifytip.tga" + name="ShareNotification" + type="notifytip"> +Drag items from inventory onto a person in the resident picker + </notification> + + <notification name="MeshUploadError" icon="alert.tga" type="alert"> @@ -5981,11 +5988,10 @@ The button will be shown when there is enough space for it. <notification icon="notifytip.tga" - name="ShareNotification" + name="AvatarRezNotification" type="notifytip"> -Drag items from inventory onto a person in the resident picker +Avatar '[NAME]' rezzed in [TIME] seconds. </notification> - <global name="UnsupportedCPU"> - Your CPU speed does not meet the minimum requirements. </global> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index 9ece4aead8..bc37af0319 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -25,6 +25,10 @@ (unknown) </panel.string> + <!-- Wearables filtering strings --> + <string name="Filter.All" value="All"/> + <string name="Filter.Clothes/Body" value="Clothes/Body"/> + <string name="Filter.Objects" value="Objects"/> <button follows="top|left" @@ -154,6 +158,16 @@ sort_column="look_item_sort" name="look_item_sort" /> </scroll_list> + <!-- TODO remove this button. Added it temporary for QA to be able to test new edit wearable panel (see EXT-6564)--> + <button + follows="left|top|right" + height="20" + label="edit" + left="0" + top="0" + layout="topleft" + name="edit_wearable_btn" + width="40" /> <panel background_visible="true" @@ -222,29 +236,18 @@ <layout_panel auto_resize="true" default_tab_group="3" - height="250" - min_height="120" + height="210" + min_height="210" name="add_wearables_panel" width="300" tab_group="2" user_resize="true" visible="false"> - <text - follows="top|left|right" - font="SansSerifBold" - height="13" - layout="topleft" - left="5" - name="status" - text_color="LtGray" - top="5" - value="Add Wearables" - use_ellipses="true" - width="275" /> - + <!-- *NOTE is not used, invisible and disabled --> <filter_editor background_image="TextField_Search_Off" + enabled="false" follows="left|top|right" font="SansSerif" label="Filter" @@ -254,13 +257,79 @@ height="20" name="look_item_filter" text_color="black" - text_pad_left="25" /> + text_pad_left="25" + visible="false"/> + + <layout_stack + animate="true" + follows="all" + height="25" + width="300" + layout="topleft" + orientation="horizontal" + name="filter_panels" + top="0" + left="0"> + <layout_panel + layout="topleft" + follows="left|top|right" + height="25" + label="IM Control Panel" + name="filter_button_panel" + width="150" + auto_resize="true" + user_resize="false"> + <text + follows="top|left|right" + font="SansSerifBold" + height="13" + layout="topleft" + left="5" + name="add_to_outfit_label" + text_color="LtGray" + top="3" + value="Add to Outfit:" + use_ellipses="true" + width="270" /> + <button + follows="top|right" + height="20" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + is_toggle="true" + label="O" + layout="topleft" + right="-1" + name="filter_button" + top="3" + width="20" /> + </layout_panel> + <layout_panel + auto_resize="true" + height="25" + min_width="130" + name="filter_combobox_panel" + width="150" + user_resize="false" + visible="false"> + <combo_box + follows="top|left|right" + height="20" + layout="topleft" + right="-5" + name="filter_wearables_combobox" + top="0" + width="130"/> + </layout_panel> + </layout_stack> <inventory_panel allow_multi_select="false" border="false" follows="left|top|right|bottom" - height="176" + height="155" layout="topleft" left="0" mouse_opaque="false" diff --git a/indra/newview/skins/default/xui/en/panel_scrolling_param.xml b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml index 8042563900..19eb4bb0d6 100644 --- a/indra/newview/skins/default/xui/en/panel_scrolling_param.xml +++ b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml @@ -110,7 +110,6 @@ increment="1" initial_value="0" label="[DESC]" - label_width="100" layout="bottom|left" left="6" max_val="100" diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index c2624ce0d0..690d2971ee 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -99,7 +99,7 @@ image_pressed="Pause_Press" image_pressed_selected="Play_Press" is_toggle="true" - left_pad="20" + left_pad="15" top="1" name="media_toggle_btn" tool_tip="Start/Stop All Media (Music, Video, Web pages)" @@ -112,12 +112,12 @@ image_pressed="Audio_Press" image_unselected="Audio_Off" is_toggle="true" - left_pad="10" + left_pad="5" top="2" name="volume_btn" tool_tip="Global Volume Control" width="16" /> - <!-- <text + <text follows="right|top" halign="center" height="12" @@ -125,5 +125,5 @@ left_delta="0" name="stat_btn" top_delta="0" - width="20"/>--> + width="20"/> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_status_bar.xml b/indra/newview/skins/default/xui/es/panel_status_bar.xml index 1afa68106e..d4404fd9b5 100644 --- a/indra/newview/skins/default/xui/es/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/es/panel_status_bar.xml @@ -22,7 +22,7 @@ [AMT] L$ </panel.string> <button label="" label_selected="" name="buycurrency" tool_tip="Mi saldo"/> - <button label="Comprar" name="buyL" tool_tip="Pulsa para comprar más L$"/> + <button label="Comprar L$" name="buyL" tool_tip="Pulsa para comprar más L$"/> <text name="TimeText" tool_tip="Hora actual (Pacífico)"> 24:00 AM PST </text> diff --git a/indra/newview/skins/default/xui/fr/panel_status_bar.xml b/indra/newview/skins/default/xui/fr/panel_status_bar.xml index 657bf792cf..dffb1d4238 100644 --- a/indra/newview/skins/default/xui/fr/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/fr/panel_status_bar.xml @@ -22,7 +22,7 @@ [AMT] L$ </panel.string> <button label="" label_selected="" name="buycurrency" tool_tip="Mon solde"/> - <button label="Acheter" name="buyL" tool_tip="Cliquez pour acheter plus de L$"/> + <button label="Acheter L$" name="buyL" tool_tip="Cliquez pour acheter plus de L$"/> <text name="TimeText" tool_tip="Heure actuelle (Pacifique)"> 00h00 PST </text> diff --git a/indra/newview/skins/default/xui/it/panel_status_bar.xml b/indra/newview/skins/default/xui/it/panel_status_bar.xml index 584ac5e4b4..4c860ff479 100644 --- a/indra/newview/skins/default/xui/it/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/it/panel_status_bar.xml @@ -22,7 +22,7 @@ L$ [AMT] </panel.string> <button label="" label_selected="" name="buycurrency" tool_tip="Il mio saldo"/> - <button label="Acquista" name="buyL" tool_tip="Clicca per comprare più L$"/> + <button label="Acquista L$" name="buyL" tool_tip="Clicca per comprare più L$"/> <text name="TimeText" tool_tip="Orario attuale (Pacifico)"> 24:00, ora del Pacifico </text> diff --git a/indra/newview/skins/default/xui/ja/panel_status_bar.xml b/indra/newview/skins/default/xui/ja/panel_status_bar.xml index 923455abba..8a848f496d 100644 --- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml @@ -22,7 +22,7 @@ L$ [AMT] </panel.string> <button label="" label_selected="" name="buycurrency" tool_tip="所持金"/> - <button label="購入" name="buyL" tool_tip="クリックして L$ を購入します"/> + <button label="L$ の購入" name="buyL" tool_tip="クリックして L$ を購入します"/> <text name="TimeText" tool_tip="現在時刻(太平洋)"> 24:00 AM PST </text> diff --git a/indra/newview/skins/default/xui/pl/panel_status_bar.xml b/indra/newview/skins/default/xui/pl/panel_status_bar.xml index cd2ae14f6c..313c2732ff 100644 --- a/indra/newview/skins/default/xui/pl/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/pl/panel_status_bar.xml @@ -22,7 +22,7 @@ L$ [AMT] </panel.string> <button label="" label_selected="" name="buycurrency" tool_tip="Bilans"/> - <button label="Kup" name="buyL" tool_tip="Kliknij aby kupić L$"/> + <button label="Kup L$" name="buyL" tool_tip="Kliknij aby kupić L$"/> <text name="TimeText" tool_tip="Obecny Czas (Pacyficzny)"> 24:00 AM PST </text> diff --git a/indra/newview/skins/default/xui/pt/panel_status_bar.xml b/indra/newview/skins/default/xui/pt/panel_status_bar.xml index ae2879f4a9..a320d9d56d 100644 --- a/indra/newview/skins/default/xui/pt/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/pt/panel_status_bar.xml @@ -22,7 +22,7 @@ L$ [AMT] </panel.string> <button label="" label_selected="" name="buycurrency" tool_tip="Meu saldo"/> - <button label="Comprar" name="buyL" tool_tip="Comprar mais L$"/> + <button label="Comprar L$" name="buyL" tool_tip="Comprar mais L$"/> <text name="TimeText" tool_tip="Hora atual (Pacífico)"> 24:00 AM PST </text> diff --git a/indra/win_updater/CMakeLists.txt b/indra/win_updater/CMakeLists.txt index 82347adf20..210486c668 100644 --- a/indra/win_updater/CMakeLists.txt +++ b/indra/win_updater/CMakeLists.txt @@ -6,6 +6,13 @@ include(00-Common) include(LLCommon) include(Linking) +# *HACK - override msvcrt implementation (intialized on 00-Common) to be +# statically linked for the installer this relies on vc taking the last flag on +# the command line +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + include_directories( ${LLCOMMON_INCLUDE_DIRS} ) @@ -30,9 +37,9 @@ target_link_libraries(windows-updater set_target_properties(windows-updater PROPERTIES - LINK_FLAGS "/NODEFAULTLIB:LIBCMT" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\"" + LINK_FLAGS "/NODEFAULTLIB:MSVCRT" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;MSVCRT\"" ) # The windows-updater doesn't link against anything non-system, apparently -#ll_deploy_sharedlibs_command(windows-updater)
\ No newline at end of file +#ll_deploy_sharedlibs_command(windows-updater) |