diff options
31 files changed, 539 insertions, 58 deletions
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..f434782977 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1295,11 +1295,6 @@ void LLAgent::stopAutoPilot(BOOL user_cancel)  		{  			resetAxes(mAutoPilotTargetFacing);  		} -		// If the user cancelled, don't change the fly state -		if (!user_cancel) -		{ -			setFlying(mAutoPilotFlyOnStop); -		}  		//NB: auto pilot can terminate for a reason other than reaching the destination  		if (mAutoPilotFinishedCallback)  		{ @@ -1307,6 +1302,11 @@ void LLAgent::stopAutoPilot(BOOL user_cancel)  		}  		mLeaderID = LLUUID::null; +		// If the user cancelled, don't change the fly state +		if (!user_cancel) +		{ +			setFlying(mAutoPilotFlyOnStop); +		}  		setControlFlags(AGENT_CONTROL_STOP);  		if (user_cancel && !mAutoPilotBehaviorName.empty()) 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/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/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/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/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..e0c327068c 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);  				}  			}  		} diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 43a9bd2b2f..6bd8f2790c 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;  //----------------------------------------------------------------------------- @@ -5730,8 +5733,6 @@ void LLVOAvatar::sitDown(BOOL bSitting)  //-----------------------------------------------------------------------------  void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)  { -	sitDown(TRUE); -  	if (isSelf())  	{  		// Might be first sit @@ -5764,6 +5765,7 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)  	mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot);  	gPipeline.markMoved(mDrawable, TRUE); +	sitDown(TRUE);  	mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject  	mRoot.setPosition(getPosition());  	mRoot.updateWorldMatrixChildren(); @@ -5972,6 +5974,7 @@ void LLVOAvatar::updateRuthTimer(bool loading)  	if (mPreviousFullyLoaded)  	{  		mRuthTimer.reset(); +		mRuthDebugTimer.reset();  	}  	const F32 LOADING_TIMEOUT = 120.f; @@ -6000,7 +6003,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 d0ad2b727b..3bafa8bcda 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_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)  | 
