[SCM] A client for connecting to 3D metaverses such as Linden Labs Secondlife(tm) and OpenSim grids branch, master, updated. upstream/1.20.15-68-g3c8b31e

Robin Cornelius robin.cornelius at gmail.com
Tue Sep 2 19:43:07 UTC 2008


The following commit has been merged in the master branch:
commit 01eecc0e1de6e0079f57057e2bea3be9a03e4411
Author: Robin Cornelius <robin.cornelius at gmail.com>
Date:   Tue Sep 2 20:40:56 2008 +0100

    Import all new quilt patches rebased for 1.21.0

diff --git a/debian/patches/0000_keep_statbars_from_overshooting.patch.diff b/debian/patches/0000_keep_statbars_from_overshooting.patch.diff
new file mode 100644
index 0000000..13a17d5
--- /dev/null
+++ b/debian/patches/0000_keep_statbars_from_overshooting.patch.diff
@@ -0,0 +1,49 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## Keep stat bars from overshooting.dpatch by  <root at debian.example.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+Index: ./indra/newview/llstatbar.cpp
+===================================================================
+--- ./indra/newview/llstatbar.cpp	(revision 49)
++++ ./indra/newview/llstatbar.cpp	(working copy)
+@@ -223,6 +223,7 @@
+ 		}
+ 
+ 		right = (S32) ((max - mMinBar) * value_scale);
++		right = llclamp(0, right, width);
+ 		gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 0.25f));
+ 
+ 		S32 num_values = mStatp->getNumValues() - 1;
+@@ -238,22 +239,22 @@
+ 				if (mPerSec)
+ 				{
+ 					left = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale);
+-					right = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale) + 1;
+-					gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+ 				}
+ 				else
+ 				{
+ 					left = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale);
+-					right = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale) + 1;
+-					gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+-				}
++				}	
++				left = llclamp(0, left, width-1);
++				right = left+1;
++				gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+ 			}
+ 		}
+ 		else
+ 		{
+ 			// draw current
+ 			left = (S32) ((current - mMinBar) * value_scale) - 1;
+-			right = (S32) ((current - mMinBar) * value_scale) + 1;
++			left = llclamp(0, left, width-1);
++			right = left + 2;
+ 			gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 1.f));
+ 		}
+ 
diff --git a/debian/patches/0001_possible_crash_and_leak_llassetstorage.patch.diff b/debian/patches/0001_possible_crash_and_leak_llassetstorage.patch.diff
new file mode 100644
index 0000000..16fbfa0
--- /dev/null
+++ b/debian/patches/0001_possible_crash_and_leak_llassetstorage.patch.diff
@@ -0,0 +1,141 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 0001_possible_crash_and_leak_llassetstorage.patch.dpatch by  <robin at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: 0001_possible_crash_and_leak_llassetstorage.patch
+
+ at DPATCH@
+
+--- linden/indra/llmessage/llassetstorage.cpp	2007-09-20 12:36:46.000000000 +0200
++++ linden/indra/llmessage/llassetstorage.cpp	2007-10-08 00:10:17.828125000 +0200
+@@ -512,16 +512,19 @@
+ 	S32 result,
+ 	const LLUUID& file_id,
+ 	LLAssetType::EType file_type,
+-	void* user_data, LLExtStat ext_status)
++	void* callback_parm_req, LLExtStat ext_status)
+ {
+ 	lldebugs << "LLAssetStorage::downloadCompleteCallback() for " << file_id
+ 		 << "," << LLAssetType::lookup(file_type) << llendl;
+-	LLAssetRequest* req = (LLAssetRequest*)user_data;
++
++	// be careful! req may be a ptr to memory already freed (a timeout does this)
++	LLAssetRequest* req = (LLAssetRequest*)callback_parm_req;	
+ 	if(!req)
+ 	{
+ 		llwarns << "LLAssetStorage::downloadCompleteCallback called without"
+ 			"a valid request." << llendl;
+-		return;
++		// we can live with a null pointer, we're not allowed to deref the ptr anyway (see above)
++		// return;  
+ 	}
+ 	if (!gAssetStorage)
+ 	{
+@@ -529,12 +532,10 @@
+ 		return;
+ 	}
+ 
+-	req->setUUID(file_id);
+-	req->setType(file_type);
+ 	if (LL_ERR_NOERR == result)
+ 	{
+ 		// we might have gotten a zero-size file
+-		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType());
++		LLVFile vfile(gAssetStorage->mVFS, file_id, file_type);
+ 		if (vfile.getSize() <= 0)
+ 		{
+ 			llwarns << "downloadCompleteCallback has non-existent or zero-size asset " << req->getUUID() << llendl;
+@@ -553,7 +554,7 @@
+ 	{
+ 		request_list_t::iterator curiter = iter++;
+ 		LLAssetRequest* tmp = *curiter;
+-		if ((tmp->getUUID() == req->getUUID()) && (tmp->getType()== req->getType()))
++		if ((tmp->getUUID() == file_id) && (tmp->getType() == file_type))
+ 		{
+ 			requests.push_front(tmp);
+ 			iter = gAssetStorage->mPendingDownloads.erase(curiter);
+@@ -566,7 +567,7 @@
+ 		LLAssetRequest* tmp = *curiter;
+ 		if (tmp->mDownCallback)
+ 		{
+-			tmp->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), tmp->mUserData, result, ext_status);
++			tmp->mDownCallback(gAssetStorage->mVFS, tmp->getUUID(), tmp->getType(), tmp->mUserData, result, ext_status);
+ 		}
+ 		delete tmp;
+ 	}
+@@ -662,10 +663,10 @@
+ 	S32 result,
+ 	const LLUUID& file_id,
+ 	LLAssetType::EType file_type,
+-	void* user_data,
++	void* callback_parm_req,
+ 	LLExtStat ext_status)
+ {
+-	LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data;
++	LLEstateAssetRequest *req = (LLEstateAssetRequest*)callback_parm_req;
+ 	if(!req)
+ 	{
+ 		llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+@@ -679,12 +680,10 @@
+ 		return;
+ 	}
+ 
+-	req->setUUID(file_id);
+-	req->setType(file_type);
+ 	if (LL_ERR_NOERR == result)
+ 	{
+ 		// we might have gotten a zero-size file
+-		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getAType());
++		LLVFile vfile(gAssetStorage->mVFS, file_id, file_type);
+ 		if (vfile.getSize() <= 0)
+ 		{
+ 			llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl;
+@@ -694,7 +693,9 @@
+ 		}
+ 	}
+ 
+-	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status);
++	req->mDownCallback(gAssetStorage->mVFS, file_id, file_type, req->mUserData, result, ext_status);
++
++	delete req;
+ }
+ 
+ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,
+@@ -799,10 +800,10 @@
+ 	S32 result,
+ 	const LLUUID& file_id,
+ 	LLAssetType::EType file_type,
+-	void* user_data,
++	void* callback_parm_req,
+ 	LLExtStat ext_status)
+ {
+-	LLInvItemRequest *req = (LLInvItemRequest*)user_data;
++	LLInvItemRequest *req = (LLInvItemRequest*)callback_parm_req;
+ 	if(!req)
+ 	{
+ 		llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+@@ -815,12 +816,10 @@
+ 		return;
+ 	}
+ 
+-	req->setUUID(file_id);
+-	req->setType(file_type);
+ 	if (LL_ERR_NOERR == result)
+ 	{
+ 		// we might have gotten a zero-size file
+-		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType());
++		LLVFile vfile(gAssetStorage->mVFS, file_id, file_type);
+ 		if (vfile.getSize() <= 0)
+ 		{
+ 			llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl;
+@@ -830,7 +829,9 @@
+ 		}
+ 	}
+ 
+-	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);
++	req->mDownCallback(gAssetStorage->mVFS, file_id, file_type, req->mUserData, result, ext_status);
++
++	delete req;
+ }
+ 
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/debian/patches/0001_possible_crash_in_llviewerpartssim.diff b/debian/patches/0001_possible_crash_in_llviewerpartssim.diff
new file mode 100644
index 0000000..0da8d6a
--- /dev/null
+++ b/debian/patches/0001_possible_crash_in_llviewerpartssim.diff
@@ -0,0 +1,34 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## possible crash in llviewerpartssim.dpatch by  <root at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+Index: ./indra/newview/llviewerpartsim.cpp
+===================================================================
+--- ./indra/newview/llviewerpartsim.cpp	(revision 368)
++++ ./indra/newview/llviewerpartsim.cpp	(working copy)
+@@ -639,11 +639,18 @@
+ 		S32 visirate = 1;
+ 		if (vobj)
+ 		{
+-			LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup();
+-			if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY))
++			if(vobj->mDrawable)
+ 			{
+-				visirate = 8;
++				LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup();
++				if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY))
++				{
++					visirate = 8;
++				}
+ 			}
++			else
++			{
++				llwarns << "Crash avoided, vobj->mDrawable is NULL" << llendl;
++			}
+ 		}
+ 
+ 		if ((LLDrawable::getCurrentFrame()+mViewerPartGroups[i]->mID)%visirate == 0)
diff --git a/debian/patches/1294_llworkerthread_when_terminating_program.patch.diff b/debian/patches/1294_llworkerthread_when_terminating_program.patch.diff
new file mode 100644
index 0000000..727ed53
--- /dev/null
+++ b/debian/patches/1294_llworkerthread_when_terminating_program.patch.diff
@@ -0,0 +1,19 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 1294_llworkerthread_when_terminating_program.patch.dpatch by  <robin at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: 1294_llworkerthread_when_terminating_program.patch
+
+ at DPATCH@
+
+--- linden/indra/llcommon/llworkerthread.cpp	2007-08-02 14:16:42.000000000 +0200
++++ linden/indra/llcommon/llworkerthread.cpp	2007-08-08 00:56:01.750000000 +0200
+@@ -105,7 +105,7 @@
+ 		delete *iter;
+ 	}
+     // delete and aborted entries mean there's still work to do
+-	res += delete_list.size() + abort_list.size();
++	res +=  !mDeleteList.empty() + !delete_list.empty();  // deleted entries mean there's still work to do
+ 	return res;
+ }
+ 
diff --git a/debian/patches/1857_apr_thread_mutex_nested.patch.diff b/debian/patches/1857_apr_thread_mutex_nested.patch.diff
new file mode 100644
index 0000000..22f5517
--- /dev/null
+++ b/debian/patches/1857_apr_thread_mutex_nested.patch.diff
@@ -0,0 +1,43 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 1857_apr_thread_mutex_nested.patch.dpatch by  <robin at debian.example.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: 1857_apr_thread_mutex_nested.patch
+
+ at DPATCH@
+
+--- linden-orig/indra/llcommon/llapr.cpp	2007-09-13 15:35:18.000000000 +0200
++++ linden/indra/llcommon/llapr.cpp	2007-09-16 17:59:54.640625000 +0200
+@@ -44,7 +44,7 @@
+ 		apr_pool_create(&gAPRPoolp, NULL);
+ 
+ 		// Initialize the logging mutex
+-		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
++		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_NESTED, gAPRPoolp);
+ 	}
+ }
+ 
+--- linden-orig/indra/llcommon/llthread.cpp	2007-09-13 15:35:18.000000000 +0200
++++ linden/indra/llcommon/llthread.cpp	2007-09-16 17:59:53.203125000 +0200
+@@ -266,7 +266,7 @@
+ 		mIsLocalPool = TRUE;
+ 		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
+ 	}
+-	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
++	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_NESTED, mAPRPoolp);
+ }
+ 
+ 
+--- linden-orig/indra/llmessage/llpumpio.cpp	2007-09-13 15:35:18.000000000 +0200
++++ linden/indra/llmessage/llpumpio.cpp	2007-09-16 17:59:51.656250000 +0200
+@@ -684,8 +684,8 @@
+ 	if(!pool) return;
+ #if LL_THREADS_APR
+ 	// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
+-	apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool);
+-	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool);
++	apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_NESTED, pool);
++	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_NESTED, pool);
+ #endif
+ 	mPool = pool;
+ }
diff --git a/debian/patches/2003_possible_crash_draganddrop.patch.diff b/debian/patches/2003_possible_crash_draganddrop.patch.diff
new file mode 100644
index 0000000..3d60804
--- /dev/null
+++ b/debian/patches/2003_possible_crash_draganddrop.patch.diff
@@ -0,0 +1,23 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 2003_possible_crash_draganddrop.patch.dpatch by  <robin at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: 2003_possible_crash_draganddrop.patch
+
+ at DPATCH@
+
+--- linden/indra/newview/lltooldraganddrop.cpp	2007-07-11 15:19:48.000000000 +0200
++++ linden/indra/newview/lltooldraganddrop.cpp	2007-08-03 21:09:45.109375000 +0200
+@@ -962,6 +962,12 @@
+ 		{
+ 			LLInventoryObject* cargo = locateInventory(item, cat);
+ 
++			if (!cargo) 
++			{
++				handled = FALSE;
++				break;
++			}
++
+ 			EAcceptance item_acceptance = ACCEPT_NO;
+ 			handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+ 												mCargoTypes[mCurItemIndex],
diff --git a/debian/patches/24_always_test_vectorize.diff b/debian/patches/24_always_test_vectorize.diff
new file mode 100644
index 0000000..684951b
--- /dev/null
+++ b/debian/patches/24_always_test_vectorize.diff
@@ -0,0 +1,34 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## update vectorize patch.dpatch by  <root at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+Index: ./indra/newview/llappviewer.cpp
+===================================================================
+--- ./indra/newview/llappviewer.cpp	(revision 319)
++++ ./indra/newview/llappviewer.cpp	(working copy)
+@@ -415,7 +415,6 @@
+ 	LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //sqaure lod factor to get exponential range of [1,4]
+ 	gGL.setClever(gSavedSettings.getBOOL("RenderUseCleverUI"));
+ 	
+-#if LL_VECTORIZE
+ 	if (gSysCPU.hasAltivec())
+ 	{
+ 		gSavedSettings.setBOOL("VectorizeEnable", TRUE );
+@@ -441,13 +440,6 @@
+ 		gSavedSettings.setU32("VectorizeProcessor", 0 );
+ 		gSavedSettings.setBOOL("VectorizeSkin", FALSE);
+ 	}
+-#else
+-	// This build target doesn't support SSE, don't test/run.
+-	gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
+-	gSavedSettings.setBOOL("VectorizeEnable", FALSE );
+-	gSavedSettings.setU32("VectorizeProcessor", 0 );
+-	gSavedSettings.setBOOL("VectorizeSkin", FALSE);
+-#endif
+ 
+ 	// propagate push to talk preference to current status
+ 	gSavedSettings.setBOOL("PTTCurrentlyEnabled", TRUE); //gSavedSettings.getBOOL("EnablePushToTalk"));
diff --git a/debian/patches/2543_possible_crash_in_group_voting_propsals.patch.diff b/debian/patches/2543_possible_crash_in_group_voting_propsals.patch.diff
new file mode 100644
index 0000000..c587e47
--- /dev/null
+++ b/debian/patches/2543_possible_crash_in_group_voting_propsals.patch.diff
@@ -0,0 +1,116 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 2543_possible_crash_in_group_voting_propsals.patch.dpatch by  <root at debian.example.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: 2543_possible_crash_in_group_voting_propsals.patch
+
+ at DPATCH@
+
+--- linden-orig/indra/llui/llscrolllistctrl.cpp	2007-09-20 12:36:46.000000000 +0200
++++ linden/indra/llui/llscrolllistctrl.cpp	2007-09-26 02:26:16.406250000 +0200
+@@ -543,6 +543,11 @@
+ 
+ LLScrollListItem* LLScrollListCtrl::getFirstSelected() const
+ {
++	if (!getCanSelect())
++	{
++		return NULL;
++	}
++
+ 	item_list::const_iterator iter;
+ 	for(iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ 	{
+@@ -558,6 +563,13 @@
+ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
+ {
+ 	std::vector<LLScrollListItem*> ret;
++
++	if (!getCanSelect())
++	{
++		return ret;
++	}
++
++
+ 	item_list::const_iterator iter;
+ 	for(iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ 	{
+@@ -572,6 +584,12 @@
+ 
+ S32 LLScrollListCtrl::getFirstSelectedIndex() const
+ {
++	if (!getCanSelect())
++	{
++		return -1;
++	}
++
++
+ 	S32 CurSelectedIndex = 0;
+ 	item_list::const_iterator iter;
+ 	for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+--- linden-orig/indra/newview/llpanelgroupvoting.cpp	2007-09-20 12:36:50.000000000 +0200
++++ linden/indra/newview/llpanelgroupvoting.cpp	2007-09-26 02:14:20.218750000 +0200
+@@ -524,6 +524,7 @@
+ 	//we're pining the server in high latency situations
+ 	addPendingActiveScrollListItem(0, 0, ADD_BOTTOM);
+ 	mProposals->setCanSelect(FALSE);
++	mBtnViewProposalItem->setEnabled(FALSE);
+ 
+ 	LLMessageSystem *msg = gMessageSystem;
+ 	msg->newMessageFast(_PREHASH_GroupActiveProposalsRequest);
+@@ -620,6 +621,7 @@
+ 	//add some text so the user knows we're doing something
+ 	addPendingHistoryScrollListItem(0, 0, ADD_BOTTOM);
+ 	mVotesHistory->setCanSelect(FALSE);
++	mBtnViewHistoryItem->setEnabled(FALSE);
+ 
+ 	LLMessageSystem *msg = gMessageSystem;
+ 	msg->newMessageFast(_PREHASH_GroupVoteHistoryRequest);
+@@ -835,6 +837,7 @@
+ 		//no active proposals and make the scroll list unselectable
+ 		self->addNoActiveScrollListItem(ADD_BOTTOM);
+ 		self->mProposals->setCanSelect(FALSE);
++		self->mBtnViewProposalItem->setEnabled(FALSE);
+ 	}
+ 	else if ( (U32)received != num_expected )
+ 	{
+@@ -842,6 +845,7 @@
+ 											 num_expected,
+ 											 ADD_BOTTOM);
+ 		self->mProposals->setCanSelect(FALSE);
++		self->mBtnViewProposalItem->setEnabled(FALSE);
+ 	}
+ 	else
+ 	{
+@@ -855,6 +859,7 @@
+ 		}
+ 
+ 		self->mProposals->setCanSelect(TRUE);
++		self->mBtnViewProposalItem->setEnabled(TRUE);
+ 	}
+ }
+ 
+@@ -904,7 +909,7 @@
+ 		//no active proposals and make the scroll list unselectable
+ 		self->addNoHistoryScrollListItem(ADD_BOTTOM);
+ 		self->mVotesHistory->setCanSelect(FALSE);
+-
++		self->mBtnViewHistoryItem->setEnabled(FALSE);
+ 		return;
+ 	}
+ 
+@@ -1024,6 +1029,7 @@
+ 											  num_expected,
+ 											  ADD_BOTTOM);
+ 		self->mVotesHistory->setCanSelect(FALSE);
++		self->mBtnViewHistoryItem->setEnabled(FALSE);
+ 	}
+ 	else
+ 	{
+@@ -1037,6 +1043,7 @@
+ 		}
+ 
+ 		self->mVotesHistory->setCanSelect(TRUE);
++		self->mBtnViewHistoryItem->setEnabled(TRUE);
+ 	}
+ }
+ 
diff --git a/debian/patches/2683_possible_crash_update_speaker_list.patch.diff b/debian/patches/2683_possible_crash_update_speaker_list.patch.diff
new file mode 100644
index 0000000..368754f
--- /dev/null
+++ b/debian/patches/2683_possible_crash_update_speaker_list.patch.diff
@@ -0,0 +1,41 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 2683_possible_crash_update_speaker_list.patch.dpatch by  <root at debian.example.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: 2683_possible_crash_update_speaker_list.patch
+
+ at DPATCH@
+
+--- linden/indra/newview/llfloateractivespeakers.cpp	2007-09-20 12:36:50.000000000 +0200
++++ linden/indra/newview/llfloateractivespeakers.cpp	2007-10-01 16:39:42.562500000 +0200
+@@ -806,7 +903,7 @@
+ 	for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it)
+ 	{
+ 		LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it;
+-		if (dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS)
++		if (!avatarp->isDead() &&  dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS)
+ 		{
+ 			setSpeaker(avatarp->getID());
+ 		}
+@@ -820,7 +917,7 @@
+ 		if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
+ 		{
+ 			LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id);
+-			if (!avatarp || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
++			if (!avatarp || avatarp->isDead() || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
+ 			{
+ 				speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
+ 				speakerp->mDotColor = INACTIVE_COLOR;
+--- linden/indra/newview/llviewerobjectlist.cpp	2007-09-20 12:36:50.000000000 +0200
++++ linden/indra/newview/llviewerobjectlist.cpp	2007-10-01 16:45:38.562500000 +0200
+@@ -868,6 +868,10 @@
+ 		if (objectp->mRegionp == regionp)
+ 		{
+ 			killObject(objectp);
++
++			// invalidate region pointer. region will become invalid, but 
++			// refcounted objects may survive the cleanDeadObjects() call below
++			objectp->mRegionp = NULL;	 
+ 		}
+ 	}
+ 
diff --git a/debian/patches/50_get_cpu_clock_count_for_more_than_just_i386.diff b/debian/patches/50_get_cpu_clock_count_for_more_than_just_i386.diff
new file mode 100644
index 0000000..952e621
--- /dev/null
+++ b/debian/patches/50_get_cpu_clock_count_for_more_than_just_i386.diff
@@ -0,0 +1,34 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 50_get_cpu_clock_count_for_more_than_just_i386.dpatch by Paul "TBBle" Hampson <Paul.Hampson at Pobox.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Drop RDTSC reads on Linux and Solaris, and fallback to
+## DP: gettimeofday()-based implementation
+
+ at DPATCH@
+diff -urNad linden~/indra/llcommon/llfasttimer.cpp linden/indra/llcommon/llfasttimer.cpp
+--- linden~/indra/llcommon/llfasttimer.cpp	2007-05-12 13:44:24.000000000 +1000
++++ linden/indra/llcommon/llfasttimer.cpp	2007-05-13 11:22:49.000000000 +1000
+@@ -91,20 +91,8 @@
+ #endif // LL_WINDOWS
+ 
+ 
+-#if (LL_LINUX || LL_SOLARIS) && (defined(__i386__) || defined(__amd64__))
+-U64 get_cpu_clock_count()
+-{
+-	U64 x;
+-	__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+-	return x;
+-}
+-#endif
+-
+-#if LL_DARWIN || (LL_SOLARIS && defined(__sparc__))
+-//
+-// Mac implementation of CPU clock
+-//
+-// Just use gettimeofday implementation for now
++#if LL_LINUX || LL_DARWIN || LL_SOLARIS
++// Both Linux and Mac use gettimeofday for accurate time
+ 
+ U64 get_cpu_clock_count()
+ {
diff --git a/debian/patches/55_fix_the_locales.diff b/debian/patches/55_fix_the_locales.diff
new file mode 100644
index 0000000..1489a3e
--- /dev/null
+++ b/debian/patches/55_fix_the_locales.diff
@@ -0,0 +1,55 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## Why am i the only one with this locale bug.dpatch by  <robin at debian.example.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+
+Index: ./indra/llxml/llxmlnode.cpp
+===================================================================
+--- ./indra/llxml/llxmlnode.cpp	(revision 374)
++++ ./indra/llxml/llxmlnode.cpp	(working copy)
+@@ -571,6 +571,9 @@
+ 	LLXMLNodePtr& node,
+ 	LLXMLNode* defaults_tree)
+ {
++
++	std::string saved_locale = setlocale(LC_ALL,"C");
++
+ 	// Read file
+ 	LLFILE* fp = LLFile::fopen(filename.c_str(), "rb");		/* Flawfinder: ignore */
+ 	if (fp == NULL)
+@@ -589,6 +592,9 @@
+ 
+ 	bool rv = parseBuffer(buffer, nread, node, defaults_tree);
+ 	delete [] buffer;
++
++	setlocale(LC_ALL, saved_locale.c_str() );
++
+ 	return rv;
+ }
+ 
+Index: ./indra/llxml/llxmlparser.cpp
+===================================================================
+--- ./indra/llxml/llxmlparser.cpp	(revision 374)
++++ ./indra/llxml/llxmlparser.cpp	(working copy)
+@@ -76,6 +76,7 @@
+ 	llassert( !mDepth );
+ 	
+ 	BOOL success = TRUE;
++	std::string saved_locale = setlocale(LC_ALL,"C");
+ 
+ 	LLFILE* file = LLFile::fopen(path.c_str(), "rb");		/* Flawfinder: ignore */
+ 	if( !file )
+@@ -129,6 +130,9 @@
+ 		llwarns << mAuxErrorString << llendl;
+ 	}
+ 
++	setlocale(LC_ALL, saved_locale.c_str() );
++
++
+ 	return success;
+ }
+ 
diff --git a/debian/patches/59_need_llpreprocessor_to_access_endian_macros.diff b/debian/patches/59_need_llpreprocessor_to_access_endian_macros.diff
new file mode 100644
index 0000000..cf875ad
--- /dev/null
+++ b/debian/patches/59_need_llpreprocessor_to_access_endian_macros.diff
@@ -0,0 +1,21 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 59_need_llpreprocessor_to_access_endian_macros.dpatch by Paul "TBBle" Hampson <Paul.Hampson at Pobox.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Message.h implements htonmemcpy, which uses the LL_BIG_ENDIAN macro
+## DP: to check if swizzle of the largely little-endian data is needed
+## DP: However, the LL_BIG_ENDIAN macro is not current dragged in by any headers
+## DP: already included
+
+ at DPATCH@
+diff -urNad linden~/indra/llmessage/message.h linden/indra/llmessage/message.h
+--- linden~/indra/llmessage/message.h	2007-05-20 22:07:39.000000000 +1000
++++ linden/indra/llmessage/message.h	2007-05-20 22:17:14.000000000 +1000
+@@ -47,6 +47,7 @@
+ #include "winsock2.h" // htons etc.
+ #endif
+ 
++#include "llpreprocessor.h"
+ #include "llerror.h"
+ #include "net.h"
+ #include "string_table.h"
diff --git a/debian/patches/71_use_debian_alternatives_for_www_browser.diff b/debian/patches/71_use_debian_alternatives_for_www_browser.diff
new file mode 100644
index 0000000..67e3229
--- /dev/null
+++ b/debian/patches/71_use_debian_alternatives_for_www_browser.diff
@@ -0,0 +1,35 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## Use Debian alternitives for web browser AND use system() and let system() do the forking.dpatch by  <robin at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+
+Index: ./indra/newview/linux_tools/launch_url.sh
+===================================================================
+--- ./indra/newview/linux_tools/launch_url.sh	(revision 135)
++++ ./indra/newview/linux_tools/launch_url.sh	(working copy)
+@@ -8,6 +8,7 @@
+ # On Unixoids we try, in order of decreasing priority:
+ # - $BROWSER if set (preferred)
+ # - kfmclient openURL
++# - gnome-open
+ # - x-www-browser
+ # - opera
+ # - firefox
+@@ -48,6 +49,13 @@
+     exit
+ fi
+ 
++# else gnome-open
++# (embodies gnome concept of 'preferred browser')
++if which gnome-open  >/dev/null; then
++    gnome-open "$URL" &
++    exit
++fi
++
+ # else x-www-browser
+ # (Debianesque idea of a working X browser)
+ if which x-www-browser >/dev/null; then
diff --git a/debian/patches/75_use_debian-included_fonts.diff b/debian/patches/75_use_debian-included_fonts.diff
new file mode 100644
index 0000000..2b65ba1
--- /dev/null
+++ b/debian/patches/75_use_debian-included_fonts.diff
@@ -0,0 +1,40 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## fix fonts.dpatch by  <root at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+
+Index: ./indra/newview/app_settings/settings.xml
+===================================================================
+--- ./indra/newview/app_settings/settings.xml	(revision 374)
++++ ./indra/newview/app_settings/settings.xml	(working copy)
+@@ -3464,7 +3464,7 @@
+       <key>Type</key>
+       <string>String</string>
+       <key>Value</key>
+-      <string>profontwindows.ttf</string>
++      <string>/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf</string>
+     </map>
+     <key>FontSansSerif</key>
+     <map>
+@@ -3475,7 +3475,7 @@
+       <key>Type</key>
+       <string>String</string>
+       <key>Value</key>
+-      <string>MtBkLfRg.ttf</string>
++      <string>/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf</string>
+     </map>
+     <key>FontSansSerifBold</key>
+     <map>
+@@ -3486,7 +3486,7 @@
+       <key>Type</key>
+       <string>String</string>
+       <key>Value</key>
+-      <string>MtBdLfRg.ttf</string>
++      <string>/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf</string>
+     </map>
+     <key>FontSansSerifFallback</key>
+     <map>
diff --git a/debian/patches/79_use_debian_channel.diff b/debian/patches/79_use_debian_channel.diff
new file mode 100644
index 0000000..8edfbae
--- /dev/null
+++ b/debian/patches/79_use_debian_channel.diff
@@ -0,0 +1,18 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## change channel version.dpatch by  <robin at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+ 
+ #endif
+Index: ./indra/llcommon/llversionviewer.h
+===================================================================
+--- ./indra/llcommon/llversionviewer.h	(revision 217)
++++ ./indra/llcommon/llversionviewer.h	(working copy)
+@@ -39,3 +39,3 @@
+ 
+-const char * const LL_CHANNEL = "Second Life Release";
++const char * const LL_CHANNEL = "Open Metaverse Viewer";
+ 
diff --git a/debian/patches/VWR-1815_top_corner_fix.diff b/debian/patches/VWR-1815_top_corner_fix.diff
new file mode 100644
index 0000000..94f4ccf
--- /dev/null
+++ b/debian/patches/VWR-1815_top_corner_fix.diff
@@ -0,0 +1,57 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## top corner workaround.dpatch by  <robin at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+
+Index: ./indra/newview/lltexturefetch.cpp
+===================================================================
+--- ./indra/newview/lltexturefetch.cpp	(revision 374)
++++ ./indra/newview/lltexturefetch.cpp	(working copy)
+@@ -54,6 +54,9 @@
+ {
+ friend class LLTextureFetch;
+ 
++public:
++	BOOL mAccelerateDownloadStuckTexture;
++
+ private:
+ #if 0
+ 	class URLResponder : public LLHTTPClient::Responder
+@@ -1059,6 +1062,14 @@
+ 		}
+ 		bool have_all_data = mLastPacket >= mTotalPackets-1;
+ 		llassert_always(mRequestedSize > 0);
++		
++		if((buffer_size >= mRequestedSize) && mRequestedDiscard <=0)
++ 		{
++			if(!mAccelerateDownloadStuckTexture);
++				llwarns << "Accelerating download of a stuck texture :"<<mID << llendl
++			mAccelerateDownloadStuckTexture=TRUE;
++		}
++
+ 		if (buffer_size >= mRequestedSize || have_all_data)
+ 		{
+ 			/// We have enough (or all) data
+@@ -1552,6 +1563,7 @@
+ 	const F32 LAZY_FLUSH_TIMEOUT = 15.f; // 10.0f // temp
+ 	const F32 MIN_REQUEST_TIME = 1.0f;
+ 	const F32 MIN_DELTA_PRIORITY = 1000.f;
++	const F32 MIN_ACCEL_KICK = 0.5f;
+ 
+ 	LLMutexLock lock(&mQueueMutex);
+ 	
+@@ -1582,7 +1594,9 @@
+ 		F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
+ 		if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
+ 			(delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
+-			(elapsed >= LAZY_FLUSH_TIMEOUT))
++			(elapsed >= LAZY_FLUSH_TIMEOUT) ||
++			(req->mAccelerateDownloadStuckTexture && (elapsed >=MIN_ACCEL_KICK))
++			)
+ 		{
+ 			requests[req->mHost].insert(req);
+ 		}
diff --git a/debian/patches/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff b/debian/patches/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff
new file mode 100644
index 0000000..7cdecaf
--- /dev/null
+++ b/debian/patches/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff
@@ -0,0 +1,21 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## llGetInventoryNumber tooltip missing INVENTORY_ANIMATION.dpatch by  <root at debian.example.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Patch by McCabe Maxsted
+
+ at DPATCH@
+
+Index: ./indra/lscript/lscript_library/lscript_library.cpp
+===================================================================
+--- ./indra/lscript/lscript_library/lscript_library.cpp	(revision 327)
++++ ./indra/lscript/lscript_library/lscript_library.cpp	(working copy)
+@@ -221,7 +221,7 @@
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llBreakAllLinks", NULL, NULL, "llBreakAllLinks()\nDelinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)"));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkKey", "k", "i", "key llGetLinkKey(integer linknum)\nGet the key of linknumber in link set"));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkName", "s", "i", "string llGetLinkName(integer linknum)\nGet the name of linknumber in link set"));
+-	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryNumber", "i", "i", "integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ALL"));
++	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryNumber", "i", "i", "integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ANIMATION, INVENTORY_GESTURE, INVENTORY_ALL"));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryName", "s", "ii", "string llGetInventoryName(integer type, integer number)\nGet the name of the inventory item number of type"));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetScriptState", NULL, "si", "llSetScriptState(string name, integer run)\nControl the state of a script name."));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetEnergy", "f", NULL, "float llGetEnergy()\nReturns how much energy is in the object as a percentage of maximum"));
diff --git a/debian/patches/VWR-5082_set_bulk_inv_permissions.diff b/debian/patches/VWR-5082_set_bulk_inv_permissions.diff
new file mode 100644
index 0000000..fe69361
--- /dev/null
+++ b/debian/patches/VWR-5082_set_bulk_inv_permissions.diff
@@ -0,0 +1,946 @@
+Index: omvviewer-1.21.0/indra/newview/CMakeLists.txt
+===================================================================
+--- omvviewer-1.21.0.orig/indra/newview/CMakeLists.txt	2008-09-01 21:00:07.000000000 +0100
++++ omvviewer-1.21.0/indra/newview/CMakeLists.txt	2008-09-01 21:00:09.000000000 +0100
+@@ -126,6 +126,7 @@
+     llfloateravatarpicker.cpp
+     llfloateravatartextures.cpp
+     llfloaterbuildoptions.cpp
++    llfloaterbulkpermission.cpp
+     llfloaterbump.cpp
+     llfloaterbuycontents.cpp
+     llfloaterbuy.cpp
+Index: omvviewer-1.21.0/indra/newview/llviewermenu.cpp
+===================================================================
+--- omvviewer-1.21.0.orig/indra/newview/llviewermenu.cpp	2008-09-01 21:00:07.000000000 +0100
++++ omvviewer-1.21.0/indra/newview/llviewermenu.cpp	2008-09-01 21:00:09.000000000 +0100
+@@ -86,6 +86,7 @@
+ #include "llfloateravatarinfo.h"
+ #include "llfloateravatartextures.h"
+ #include "llfloaterbuildoptions.h"
++#include "llfloaterbulkpermission.h"
+ #include "llfloaterbump.h"
+ #include "llfloaterbuy.h"
+ #include "llfloaterbuycontents.h"
+@@ -6225,6 +6226,17 @@
+ 	}
+ }
+ 
++class LLToolsSetBulkPerms : public view_listener_t
++{
++	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
++	{
++		LLFloaterBulkPermission* queue = NULL;
++		queue = LLFloaterBulkPermission::create();
++		return true;
++	}
++};
++
++
+ class LLToolsSelectedScriptAction : public view_listener_t
+ {
+ 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+@@ -7850,6 +7862,7 @@
+ 	addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory");
+ 	addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory");
+ 	addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction");
++	addMenu(new LLToolsSetBulkPerms(), "Tools.SetBulkPerms");
+ 
+ 	addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie");
+ 	addMenu(new LLToolsEnableLink(), "Tools.EnableLink");
+Index: omvviewer-1.21.0/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ omvviewer-1.21.0/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml	2008-09-01 21:49:41.000000000 +0100
+@@ -0,0 +1,127 @@
++<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
++<floater bottom="-554" can_close="true" can_drag_on_left="false" can_minimize="true"
++     can_resize="false" can_tear_off="false" enabled="true" height="420"
++     left="367" min_height="1000" min_width="460" mouse_opaque="true"
++     name="floaterrecursiveperms" title="Bulk permission settings"
++     width="460">
++
++<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++			     bottom="-40" drop_shadow_visible="true" enabled="true" follows="left|top"
++			     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
++			     mouse_opaque="true" name="applyto" v_pad="0" width="206">Apply to</text>
++
++<check_box bottom="-70" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Scripts" left="10" mouse_opaque="true"
++			     name="scripts" radio_style="false"
++			     tool_tip="Apply bulk permissions to scripts"
++			     width="219"/>
++
++<check_box bottom="-90" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Textures" left="10" mouse_opaque="true"
++			     name="textures" radio_style="false"
++			     tool_tip="Apply bulk permissions to textures"
++			     width="219"/>
++
++<check_box bottom="-110" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Animations" left="10" mouse_opaque="true"
++			     name="animations" radio_style="false"
++			     tool_tip="Apply bulk permissions to animations"
++			     width="219"/>
++
++<check_box bottom="-130" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Sounds" left="10" mouse_opaque="true"
++			     name="sounds" radio_style="false"
++			     tool_tip="Apply bulk permissions to sounds"
++			     width="219"/>
++
++<check_box bottom="-150" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Contained objects" left="10" mouse_opaque="true"
++			     name="objects" radio_style="false"
++			     tool_tip="Apply bulk permissions to objects inside inventory"
++			     width="219"/>
++
++<check_box bottom="-170" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Landmarks" left="10" mouse_opaque="true"
++			     name="landmarks" radio_style="false"
++			     tool_tip="Apply bulk permissions to landmarks"
++			     width="219"/>
++
++<check_box bottom="-190" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Notecards" left="10" mouse_opaque="true"
++			     name="notecards" radio_style="false"
++			     tool_tip="Apply bulk permissions to notecards"
++			     width="219"/>
++
++<check_box bottom="-210" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Gesture" left="10" mouse_opaque="true"
++			     name="gestures" radio_style="false"
++			     tool_tip="Apply bulk permissions to gestures"
++			     width="219"/>
++
++<check_box bottom="-230" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Clothing" left="10" mouse_opaque="true"
++			     name="clothing" radio_style="false"
++			     tool_tip="Apply bulk permissions to clothing"
++			     width="219"/>
++
++<check_box bottom="-250" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Bodypart" left="10" mouse_opaque="true"
++			     name="bodyparts" radio_style="false"
++			     tool_tip="Apply bulk permissions to bodyparts"
++			     width="219"/>
++
++<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++			     bottom="-40" drop_shadow_visible="true" enabled="true" follows="left|top"
++			     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="200"
++			     mouse_opaque="true" name="applyto" v_pad="0" width="206">Permissions</text>
++
++
++<check_box bottom="-110" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Copy" left="200" mouse_opaque="true"
++			     name="Copy" radio_style="false"
++			     tool_tip="Next owner can copy"
++			     width="219"/>
++
++<check_box bottom="-130" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Modify" left="200" mouse_opaque="true"
++			     name="Modify" radio_style="false"
++			     tool_tip="Next owner can modify"
++			     width="219"/>
++
++<check_box bottom="-150" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Trans" left="200" mouse_opaque="true"
++			     name="Trans" radio_style="false"
++			     tool_tip="Next owner can transfer"
++			     width="219"/>
++
++<check_box bottom="-230" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Modify Parent Prims" left="200" mouse_opaque="true"
++			     name="Parent" radio_style="false"
++			     tool_tip="Modify parent prims not just inventory"
++			     width="219" default="true"/>
++
++<scroll_list background_visible="true" bottom="-410" column_padding="5" draw_border="true"
++	     draw_heading="false" draw_stripes="true" enabled="true"
++	     follows="left|top|right|bottom" height="140" left="10" mouse_opaque="true"
++	     multi_select="false" name="queue output" width="440" />
++
++<button bottom="-70" enabled="true" follows="left|top" font="SansSerif"
++			     halign="center" height="20" label="Apply..."
++			     label_selected="Apply..." left="295" mouse_opaque="true"
++			     name="Apply..." scale_image="true" width="145" />
++
++</floater>
+Index: omvviewer-1.21.0/indra/newview/skins/default/xui/en-us/menu_viewer.xml
+===================================================================
+--- omvviewer-1.21.0.orig/indra/newview/skins/default/xui/en-us/menu_viewer.xml	2008-09-01 21:00:07.000000000 +0100
++++ omvviewer-1.21.0/indra/newview/skins/default/xui/en-us/menu_viewer.xml	2008-09-01 21:00:09.000000000 +0100
+@@ -771,6 +771,11 @@
+ 			<on_click function="Tools.SelectedScriptAction" userdata="stop" />
+ 			<on_enable function="EditableSelected" />
+ 		</menu_item_call>
++		<menu_item_call bottom="-468" enabled="false" height="19" label="Set permissions on selected task inventory"
++		     left="0" mouse_opaque="true" name="Set permissions on selected task inventory" width="250">
++			<on_click function="Tools.SetBulkPerms" userdata="" />
++			<on_enable function="EditableSelected" />
++		</menu_item_call>
+ 	</menu>
+ 	<menu bottom="219" create_jump_keys="true" drop_shadow="true" enabled="true"
+ 	     height="317" label="Help" left="227" mouse_opaque="false" name="Help"
+Index: omvviewer-1.21.0/indra/newview/llfloaterbulkpermission.cpp
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ omvviewer-1.21.0/indra/newview/llfloaterbulkpermission.cpp	2008-09-01 22:07:08.000000000 +0100
+@@ -0,0 +1,595 @@
++/** 
++ * @file llfloaterbulkpermissions.cpp
++ * @brief A floater which allows task inventory item's properties to be changed on mass.
++ *
++ * $LicenseInfo:firstyear=2008&license=viewergpl$
++ * 
++ * Copyright (c) 2008, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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$
++ */
++
++/* Allow multiple task inventory properties to be set in one go, by Michelle2 Zenovka */
++
++/* TODO
++	
++	* Add in the option to select objects or task inventory
++s
++
++It would be nice to set the permissions on groups of prims as well as task inventory
++
++*/
++
++
++#include "llviewerprecompiledheaders.h"
++#include "llfloaterbulkpermission.h"
++#include "llagent.h"
++#include "llchat.h"
++#include "llviewerwindow.h"
++#include "llviewerobject.h"
++#include "llviewerobjectlist.h"
++#include "llviewerregion.h"
++#include "lscript_rt_interface.h"
++#include "llviewercontrol.h"
++#include "llviewerobject.h"
++#include "llviewerregion.h"
++#include "llresmgr.h"
++#include "llbutton.h"
++#include "lldir.h"
++#include "llfloaterchat.h"
++#include "llviewerstats.h"
++#include "lluictrlfactory.h"
++#include "llselectmgr.h"
++#include "llinventory.h"
++
++
++#include <algorithm>
++#include <functional>
++#include "llcachename.h"
++#include "lldbstrings.h"
++#include "llinventory.h"
++
++#include "llagent.h"
++#include "llbutton.h"
++#include "llcheckboxctrl.h"
++#include "llfloateravatarinfo.h"
++#include "llfloatergroupinfo.h"
++#include "llinventorymodel.h"
++#include "lllineeditor.h"
++#include "llradiogroup.h"
++#include "llresmgr.h"
++#include "roles_constants.h"
++#include "llselectmgr.h"
++#include "lltextbox.h"
++#include "lluiconstants.h"
++#include "llviewerinventory.h"
++#include "llviewerobjectlist.h"
++#include "llviewerregion.h"
++#include "llviewercontrol.h"
++
++#include "lluictrlfactory.h"
++
++
++const char* BULKPERM_QUEUE_TITLE = "Update Progress";
++const char* BULKPERM_START_STRING = "update";
++
++namespace
++{
++	struct BulkQueueObjects : public LLSelectedObjectFunctor
++	{
++		BOOL scripted;
++		BOOL modifiable;
++		LLFloaterBulkPermission* mQueue;
++		BulkQueueObjects(LLFloaterBulkPermission* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {}
++		virtual bool apply(LLViewerObject* obj)
++		{
++			scripted = obj->flagScripted();
++			modifiable = obj->permModify();
++
++			mQueue->addObject(obj->getID());
++			return false;
++			
++		}
++	};
++}
++
++///----------------------------------------------------------------------------
++/// Class LLFloaterBulkPermission
++///----------------------------------------------------------------------------
++
++// static
++LLMap<LLUUID, LLFloaterBulkPermission*> LLFloaterBulkPermission::sInstances;
++
++
++// Default constructor
++LLFloaterBulkPermission::LLFloaterBulkPermission(const std::string& name,
++											 const LLRect& rect,
++											 const char* title,
++											 const char* start_string) :
++	LLFloater(name, rect, title,
++			  RESIZE_YES, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT,
++			  DRAG_ON_TOP, MINIMIZE_YES, CLOSE_YES)
++{
++
++	req_perm_mask=0; // This should match the default state the checkboxes are set to
++	recurse=false;
++
++	LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml");
++
++	childSetAction("Apply...",onApplyBtn,this);
++	childSetEnabled("Apply...",TRUE);
++
++	childSetCommitCallback("Modify",&onCommitPermissions, this);
++	childSetCommitCallback("Trans",&onCommitPermissions, this);
++	childSetCommitCallback("Copy",&onCommitPermissions, this);
++
++	//childSetCommitCallback("Recurse",&onRecurse, this);
++
++	childSetCommitCallback("Parent",&onParent, this);
++
++	childSetCommitCallback("objects",&InvSelection, this);
++	childSetCommitCallback("scripts",&InvSelection, this);
++	childSetCommitCallback("textures",&InvSelection, this);
++	childSetCommitCallback("sounds",&InvSelection, this);
++	childSetCommitCallback("animations",&InvSelection, this);
++	childSetCommitCallback("notecards",&InvSelection, this);
++	childSetCommitCallback("landmarks",&InvSelection, this);
++	childSetCommitCallback("bodyparts",&InvSelection, this);
++	childSetCommitCallback("clothing",&InvSelection, this);
++	childSetCommitCallback("gestures",&InvSelection, this);
++
++	//Set variable state to XUI default state consistancy
++	processObject=getChild<LLCheckBoxCtrl>("objects")->get();
++	processScript=getChild<LLCheckBoxCtrl>("scripts")->get();
++	processTexture=getChild<LLCheckBoxCtrl>("textures")->get();
++	processSound=getChild<LLCheckBoxCtrl>("sounds")->get();
++	processAnimation=getChild<LLCheckBoxCtrl>("animations")->get();
++	processNotecard=getChild<LLCheckBoxCtrl>("notecards")->get();
++	processGesture=getChild<LLCheckBoxCtrl>("gestures")->get();
++	processClothing=getChild<LLCheckBoxCtrl>("clothing")->get();
++	processBodypart=getChild<LLCheckBoxCtrl>("bodyparts")->get();
++	processLandmark=getChild<LLCheckBoxCtrl>("landmarks")->get();
++	parent=getChild<LLCheckBoxCtrl>("Parent")->get();
++
++
++	setTitle(title);
++	
++	if (!getHost())
++	{
++		LLRect curRect = getRect();
++		translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
++	}
++	
++	mStartString = start_string;
++	mDone = FALSE;
++	sInstances.addData(mID, this);
++
++}
++
++void LLFloaterBulkPermission::doApply()
++{
++	// Its alive now do the nasty work that the ScriptQueue and friends try to do in the menu code
++	// but first grab the user options
++
++	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
++	list->deleteAllItems();
++
++	//Apply to selected objects if requested first
++
++	if(parent)
++	{
++		llinfos<< "Setting permission on parent items" << llendl;
++		LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_NEXT_OWNER,true, req_perm_mask);
++		LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_NEXT_OWNER,false, ~req_perm_mask); //How annoying need to set and unset
++	}
++
++
++	LLFloaterBulkPermission* q;
++	q=(LLFloaterBulkPermission*)this;
++
++	BulkQueueObjects func(q);
++	const bool firstonly = false;
++	bool fail = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func, firstonly);
++	if(fail)
++	{
++		if ( !func.modifiable )
++		{
++			gViewerWindow->alertXml("NO MODIFY");
++		}
++		else
++		{
++			llwarns << "Bad logic. Are there actualy any items in that prim?" << llendl;
++		}
++	}
++	else
++	{
++		if (!q->start())
++		{
++			llwarns << "Unexpected failure attepmting to set permissions." << llendl;
++		}
++	}
++}
++
++// Destroys the object
++LLFloaterBulkPermission::~LLFloaterBulkPermission()
++{
++	sInstances.removeData(mID);
++}
++
++// find an instance by ID. Return NULL if it does not exist.
++// static
++LLFloaterBulkPermission* LLFloaterBulkPermission::findInstance(const LLUUID& id)
++{
++	if(sInstances.checkData(id))
++	{
++		return sInstances.getData(id);
++	}
++	return NULL;
++}
++
++
++// This is the callback method for the viewer object currently being
++// worked on.
++// NOT static, virtual!
++void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object,
++											 InventoryObjectList* inv,
++											 S32,
++											 void* q_id)
++{
++	llinfos << "LLFloaterBulkPermission::inventoryChanged() for  object "
++			<< viewer_object->getID() << llendl;
++
++	//Remove this listener from the object since its
++	//listener callback is now being executed.
++	
++	//We remove the listener here because the function
++	//removeVOInventoryListener removes the listener from a ViewerObject
++	//which it internally stores.
++	
++	//If we call this further down in the function, calls to handleInventory
++	//and nextObject may update the interally stored viewer object causing
++	//the removal of the incorrect listener from an incorrect object.
++	
++	//Fixes SL-6119:Recompile scripts fails to complete
++	removeVOInventoryListener();
++
++	if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) )
++	{
++		handleInventory(viewer_object, inv);
++	}
++	else
++	{
++		// something went wrong...
++		// note that we're not working on this one, and move onto the
++		// next object in the list.
++		llwarns << "No inventory for " << mCurrentObjectID
++				<< llendl;
++		nextObject();
++	}
++}
++
++void LLFloaterBulkPermission::onApplyBtn(void* user_data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)user_data;
++	self->doApply();
++}
++
++
++// static
++void LLFloaterBulkPermission::InvSelection(LLUICtrl* ctrl, void* data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
++
++	self->processObject=self->getChild<LLCheckBoxCtrl>("objects")->get();
++	self->processScript=self->getChild<LLCheckBoxCtrl>("scripts")->get();
++	self->processTexture=self->getChild<LLCheckBoxCtrl>("textures")->get();
++	self->processSound=self->getChild<LLCheckBoxCtrl>("sounds")->get();
++	self->processAnimation=self->getChild<LLCheckBoxCtrl>("animations")->get();
++	self->processNotecard=self->getChild<LLCheckBoxCtrl>("notecards")->get();
++	self->processGesture=self->getChild<LLCheckBoxCtrl>("gestures")->get();
++	self->processClothing=self->getChild<LLCheckBoxCtrl>("clothing")->get();
++	self->processBodypart=self->getChild<LLCheckBoxCtrl>("bodyparts")->get();
++	self->processLandmark=self->getChild<LLCheckBoxCtrl>("landmarks")->get();
++
++
++}
++
++// static
++void LLFloaterBulkPermission::onParent(LLUICtrl* ctrl, void* data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
++	self->parent=self->getChild<LLCheckBoxCtrl>("Parent")->get();
++}
++
++// static
++void LLFloaterBulkPermission::onRecurse(LLUICtrl* ctrl, void* data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
++	self->recurse=self->getChild<LLCheckBoxCtrl>("Recurse")->get();
++}
++
++// static
++void LLFloaterBulkPermission::onCommitPermissions(LLUICtrl* ctrl, void* data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
++	LLCheckBoxCtrl* CheckModify = self->getChild<LLCheckBoxCtrl>("Modify");
++	LLCheckBoxCtrl* CheckCopy = self->getChild<LLCheckBoxCtrl>("Copy");
++	LLCheckBoxCtrl* CheckTrans = self->getChild<LLCheckBoxCtrl>("Trans");
++
++	self->req_perm_mask=0;
++
++	if(CheckModify->get())
++	{
++		self->req_perm_mask|=PERM_MODIFY;
++	}
++	else
++	{
++		self->req_perm_mask&=~PERM_MODIFY;
++	}
++
++	if(CheckCopy->get())
++	{
++		self->req_perm_mask|=PERM_COPY;
++	}
++	else
++	{
++		self->req_perm_mask&=~PERM_COPY;
++	}
++
++	if(CheckTrans->get())
++	{
++		self->req_perm_mask|=PERM_TRANSFER;
++	}
++	else
++	{
++		self->req_perm_mask&=~PERM_TRANSFER;
++	}
++
++
++}
++
++void LLFloaterBulkPermission::addObject(const LLUUID& id)
++{
++	mObjectIDs.put(id);
++}
++
++BOOL LLFloaterBulkPermission::start()
++{
++	llinfos << "LLFloaterBulkPermission::start()" << llendl;
++	char buffer[MAX_STRING]; 				/*Flawfinder: ignore*/
++	snprintf(buffer, sizeof(buffer), "Starting %s of %d items.", mStartString, mObjectIDs.count()); 		/* Flawfinder: ignore */
++
++	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
++	list->addCommentText(buffer);
++
++	return nextObject();
++}
++
++BOOL LLFloaterBulkPermission::isDone() const
++{
++	return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0));
++}
++
++// go to the next object. If no objects left, it falls out silently
++// and waits to be killed by the window being closed.
++BOOL LLFloaterBulkPermission::nextObject()
++{
++	S32 count;
++	BOOL successful_start = FALSE;
++	do
++	{
++		count = mObjectIDs.count();
++		llinfos << "LLFloaterBulkPermission::nextObject() - " << count
++				<< " objects left to process." << llendl;
++		mCurrentObjectID.setNull();
++		if(count > 0)
++		{
++			successful_start = popNext();
++		}
++		llinfos << "LLFloaterBulkPermission::nextObject() "
++				<< (successful_start ? "successful" : "unsuccessful")
++				<< llendl; 
++	} while((mObjectIDs.count() > 0) && !successful_start);
++
++	if(isDone() && !mDone)
++	{
++		
++		LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
++		mDone = TRUE;
++		char buffer[MAX_STRING];		/*Flawfinder: ignore*/
++		snprintf(buffer, sizeof(buffer), "Done.");				/* Flawfinder: ignore */
++		list->addCommentText(buffer);
++
++	}
++	return successful_start;
++}
++
++// returns true if the queue has started, otherwise false.  This
++// method pops the top object off of the queue.
++BOOL LLFloaterBulkPermission::popNext()
++{
++	// get the first element off of the container, and attempt to get
++	// the inventory.
++	BOOL rv = FALSE;
++	S32 count = mObjectIDs.count();
++	if(mCurrentObjectID.isNull() && (count > 0))
++	{
++		mCurrentObjectID = mObjectIDs.get(0);
++		llinfos << "LLFloaterBulkPermission::popNext() - mCurrentID: "
++				<< mCurrentObjectID << llendl;
++		mObjectIDs.remove(0);
++		LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID);
++		if(obj)
++		{
++			llinfos << "LLFloaterBulkPermission::popNext() requesting inv for "
++					<< mCurrentObjectID << llendl;
++			LLUUID* id = new LLUUID(mID);
++
++			registerVOInventoryListener(obj,id);
++			requestVOInventory();
++			rv = TRUE;
++		}
++		else
++		{
++			llinfos<<"LLFloaterBulkPermission::popNext() returned a NULL LLViewerObject" <<llendl;
++			//Arrrg what do we do here?
++		}
++	}
++
++	return rv;
++}
++
++
++// static
++LLFloaterBulkPermission* LLFloaterBulkPermission::create()
++{
++	S32 left, top;
++	gFloaterView->getNewFloaterPosition(&left, &top);
++	LLRect rect = gSavedSettings.getRect("CompileOutputRect");
++	rect.translate(left - rect.mLeft, top - rect.mTop);
++	LLFloaterBulkPermission* new_queue = new LLFloaterBulkPermission("queue",rect,"Setting Bulk permissions","Results");
++	new_queue->open();	 /*Flawfinder: ignore*/
++	return new_queue;
++}
++
++
++void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, InventoryObjectList* inv)
++{
++	// find all of the lsl, leaving off duplicates. We'll remove
++	// all matching asset uuids on compilation success.
++
++	llinfos<<"handleInventory"<<llendl;
++
++	char buffer[MAX_STRING];		 /*Flawfinder: ignore*/
++	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
++
++	InventoryObjectList::const_iterator it = inv->begin();
++	InventoryObjectList::const_iterator end = inv->end();
++	for ( ; it != end; ++it)
++	{
++		llinfos<<"Doing iterator of inventory"<<llendl;
++
++		if(  ( (*it)->getType() == LLAssetType::AT_LSL_TEXT && processScript) ||
++  		     ( (*it)->getType() == LLAssetType::AT_TEXTURE && processTexture) ||
++	             ( (*it)->getType() == LLAssetType::AT_SOUND && processSound) ||
++	             ( (*it)->getType() == LLAssetType::AT_LANDMARK && processLandmark) ||
++    		     ( (*it)->getType() == LLAssetType::AT_CLOTHING && processClothing) ||
++    		     ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject) ||
++   		     ( (*it)->getType() == LLAssetType::AT_NOTECARD && processNotecard) ||
++   		     ( (*it)->getType() == LLAssetType::AT_BODYPART && processBodypart) ||
++   		     ( (*it)->getType() == LLAssetType::AT_ANIMATION && processAnimation) ||
++   		     ( (*it)->getType() == LLAssetType::AT_GESTURE && processGesture))
++		{
++
++			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
++
++			if (object)
++			{
++				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
++				LLViewerInventoryItem* new_item = (LLViewerInventoryItem*)item;
++				LLPermissions perm(new_item->getPermissions());
++
++				// chomp the inventory name so it fits in the scroll window nicely
++				// and the user can see the [OK]
++				std::string invname;
++				invname=item->getName().substr(0,item->getName().size() < 30 ? item->getName().size() : 30 );
++				
++				// My attempt at checking valid permissions, CHECK ME
++				// note its not actually bad to try to set permissions that are not allowed as the
++				// server will protect against this, but it will piss the user off if its wrong
++				if(
++				(perm.getCreator()==gAgentID) ||
++				(perm.getMaskOwner() & PERM_TRANSFER) && (perm.getMaskOwner() & PERM_MODIFY) || 
++				(gAgent.getGroupID()==perm.getGroup() && (perm.getMaskGroup() & PERM_TRANSFER) && (perm.getMaskGroup() & PERM_MODIFY))
++				){	
++					llinfos<<"Setting perms"<<llendl;
++					perm.setMaskNext(req_perm_mask);
++					new_item->setPermissions(perm);
++					updateInventory(object,new_item,TASK_INVENTORY_ITEM_KEY,FALSE);				
++					snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [OK]", invname.c_str());		 	/* Flawfinder: ignore */
++				}
++				else
++				{
++					llinfos<<"NOT setting perms"<<llendl;
++					snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [FAILED]", invname.c_str());		 	/* Flawfinder: ignore */
++
++				}
++				
++				list->addCommentText(buffer);
++
++				if(recurse &&  ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject))
++				{
++					//Add this object back to the queue to be processed as it has inventory
++					snprintf(buffer, sizeof(buffer), "Queueing object '%s' for open", invname.c_str());
++					llwarns << "Queueing object "<<	invname.c_str() << " ID "<< (*it)->getUUID()<<llendl;
++					mObjectIDs.put((*it)->getUUID());
++					// This will not YET work. as this is not a viewer object the unpack will fail			
++				}
++
++			}
++		}
++	}
++
++	nextObject();	
++}
++
++
++// Avoid inventory callbacks etc by just fire and forgetting the message with the permissions update
++// we could do this via LLViewerObject::updateInventory but that uses inventory call backs and buggers
++// us up and we would have a dodgy item iterator
++
++void LLFloaterBulkPermission::updateInventory(
++	LLViewerObject* object,
++	LLViewerInventoryItem* item,
++	U8 key,
++	bool is_new)
++{
++	LLMemType mt(LLMemType::MTYPE_OBJECT);
++	
++
++	// This slices the object into what we're concerned about on the
++	// viewer. The simulator will take the permissions and transfer
++	// ownership.
++	LLPointer<LLViewerInventoryItem> task_item =
++		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
++								  item->getAssetUUID(), item->getType(),
++								  item->getInventoryType(),
++								  item->getName(), item->getDescription(),
++								  item->getSaleInfo(),
++								  item->getFlags(),
++								  item->getCreationDate());
++	task_item->setTransactionID(item->getTransactionID());
++	LLMessageSystem* msg = gMessageSystem;
++	msg->newMessageFast(_PREHASH_UpdateTaskInventory);
++	msg->nextBlockFast(_PREHASH_AgentData);
++	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
++	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
++	msg->nextBlockFast(_PREHASH_UpdateData);
++	msg->addU32Fast(_PREHASH_LocalID, object->mLocalID);
++	msg->addU8Fast(_PREHASH_Key, key);
++	msg->nextBlockFast(_PREHASH_InventoryData);
++	task_item->packMessage(msg);
++	msg->sendReliable(object->getRegion()->getHost());
++
++}
++
+Index: omvviewer-1.21.0/indra/newview/llfloaterbulkpermission.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ omvviewer-1.21.0/indra/newview/llfloaterbulkpermission.h	2008-09-01 21:00:09.000000000 +0100
+@@ -0,0 +1,143 @@
++/** 
++ * @file llfloaterbulkpermissions.h
++ * @brief A floater which allows task inventory item's properties to be changed on mass.
++ *
++ * $LicenseInfo:firstyear=2008&license=viewergpl$
++ * 
++ * Copyright (c) 2008, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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$
++ */
++
++/* Allow multiple task inventory properties to be set in one go, by Michelle2 Zenovka */
++
++#ifndef LL_LLBULKPERMISSION_H
++#define LL_LLBULKPERMISSION_H
++
++#include "lldarray.h"
++#include "llinventory.h"
++#include "llviewerobject.h"
++#include "llvoinventorylistener.h"
++#include "llmap.h"
++#include "lluuid.h"
++
++#include "llfloater.h"
++#include "llscrolllistctrl.h"
++
++#include "llviewerinventory.h"
++
++class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener
++{
++public:
++	// addObject() accepts an object id.
++	void addObject(const LLUUID& id);
++
++	// start() returns TRUE if the queue has started, otherwise FALSE.
++	BOOL start();
++
++	// Use this method to create a reset queue. Once created, it
++	// will be responsible for it's own destruction.
++	static LLFloaterBulkPermission * create();
++
++protected:
++	LLFloaterBulkPermission(const std::string& name, const LLRect& rect,
++						 const char* title, const char* start_string);
++	virtual ~LLFloaterBulkPermission();
++
++	// This is the callback method for the viewer object currently
++	// being worked on.
++	/*virtual*/ void inventoryChanged(LLViewerObject* obj,
++								 InventoryObjectList* inv,
++								 S32 serial_num,
++								 void* queue);
++	
++	// This is called by inventoryChanged
++	void handleInventory(LLViewerObject* viewer_obj,
++								InventoryObjectList* inv);
++
++
++	void updateInventory(LLViewerObject* object,
++								LLViewerInventoryItem* item,
++								U8 key,
++								bool is_new);
++
++
++	static void onCloseBtn(void* user_data);
++	static void onApplyBtn(void* user_data);
++	static void onCommitPermissions(LLUICtrl* ctrl, void* data);
++	static void InvSelection(LLUICtrl* ctrl, void* data);
++	static void onRecurse(LLUICtrl* ctrl, void* data);	
++	static void onParent(LLUICtrl* ctrl, void* data);
++
++	// returns true if this is done
++	BOOL isDone() const;
++
++	//Read the settings and Apply the permissions
++	void doApply();
++
++	// go to the next object. If no objects left, it falls out
++	// silently and waits to be killed by the deleteIfDone() callback.
++	BOOL nextObject();
++	BOOL popNext();
++
++	// Get this instances ID.
++	const LLUUID& getID() const { return mID; } 
++
++	// find an instance by ID. Return NULL if it does not exist.
++	static LLFloaterBulkPermission* findInstance(const LLUUID& id);
++
++	U32 req_perm_mask;
++
++	BOOL processObject;
++	BOOL processScript;
++	BOOL processTexture;
++	BOOL processSound;
++	BOOL processAnimation;
++	BOOL processCallingcard;
++	BOOL processNotecard;
++	BOOL processGesture;
++	BOOL processClothing;
++	BOOL processBodypart;
++	BOOL processLandmark;
++
++	BOOL recurse;
++	BOOL parent;
++
++protected:
++	// UI
++	LLScrollListCtrl* mMessages;
++	LLButton* mCloseBtn;
++
++	// Object Queue
++	LLDynamicArray<LLUUID> mObjectIDs;
++	LLUUID mCurrentObjectID;
++	BOOL mDone;
++
++	LLUUID mID;
++	static LLMap<LLUUID, LLFloaterBulkPermission*> sInstances;
++
++	const char* mStartString;
++
++};
++
++#endif
diff --git a/debian/patches/VWR-5697_fix_startup_paths.diff b/debian/patches/VWR-5697_fix_startup_paths.diff
new file mode 100644
index 0000000..7772c94
--- /dev/null
+++ b/debian/patches/VWR-5697_fix_startup_paths.diff
@@ -0,0 +1,70 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## fix startup paths.dpatch by  <root at debian.example.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+Index: ./indra/llvfs/lldir_solaris.cpp
+===================================================================
+--- ./indra/llvfs/lldir_solaris.cpp	(revision 367)
++++ ./indra/llvfs/lldir_solaris.cpp	(working copy)
+@@ -91,7 +91,9 @@
+ 	mAppRODataDir = strdup(tmp_str);
+ 	mOSUserDir = getCurrentUserHome(tmp_str);
+ 	mOSUserAppDir = "";
+-	mLindenUserDir = tmp_str;
++	// Init this to a sensible location it will be updated once we try to login but it could
++	// be used as a write location before then.
++	mLindenUserDir = mOSUserDir;
+ 
+ 	char path [LL_MAX_PATH];	/* Flawfinder: ignore */ 
+ 
+Index: ./indra/llvfs/lldir_linux.cpp
+===================================================================
+--- ./indra/llvfs/lldir_linux.cpp	(revision 367)
++++ ./indra/llvfs/lldir_linux.cpp	(working copy)
+@@ -96,8 +96,11 @@
+ 	mAppRODataDir = tmp_str;
+ 	mOSUserDir = getCurrentUserHome(tmp_str);
+ 	mOSUserAppDir = "";
+-	mLindenUserDir = tmp_str;
+ 
++	// Init this to a sensible location it will be updated once we try to login but it could
++	// be used as a write location before then.
++	mLindenUserDir = mOSUserDir;
++
+ 	char path [32];	/* Flawfinder: ignore */ 
+ 
+ 	// *NOTE: /proc/%d/exe doesn't work on FreeBSD. But that's ok,
+Index: ./indra/llvfs/lldir_mac.cpp
+===================================================================
+--- ./indra/llvfs/lldir_mac.cpp	(revision 367)
++++ ./indra/llvfs/lldir_mac.cpp	(working copy)
+@@ -168,6 +168,10 @@
+ 		
+ 		// mOSUserAppDir
+ 		mOSUserAppDir = mOSUserDir;
++
++		// Init this to a sensible location it will be updated once we try to login but it could
++		// be used as a write location before then.
++		mLindenUserDir = mOSUserDir;
+ 		
+ 		// mTempDir
+ 		error = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, true, &fileRef);
+Index: ./indra/llvfs/lldir_win32.cpp
+===================================================================
+--- ./indra/llvfs/lldir_win32.cpp	(revision 367)
++++ ./indra/llvfs/lldir_win32.cpp	(working copy)
+@@ -58,6 +58,10 @@
+ 
+ 	mOSUserDir = utf16str_to_utf8str(llutf16string(w_str));
+ 
++	// Init this to a sensible location it will be updated once we try to login but it could
++	// be used as a write location before then.
++	mLindenUserDir = mOSUserDir;
++
+ 	// Local Settings\Application Data is where cache files should
+ 	// go, they don't get copied to the server if the user moves his
+ 	// profile around on the network. JC
diff --git a/debian/patches/VWR-8194_clamp_outline_for_broken_nvidia.diff b/debian/patches/VWR-8194_clamp_outline_for_broken_nvidia.diff
new file mode 100644
index 0000000..cc9d0c5
--- /dev/null
+++ b/debian/patches/VWR-8194_clamp_outline_for_broken_nvidia.diff
@@ -0,0 +1,33 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## VWR-8194 fix.dpatch by  <robin.cornelius at gmail.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Clamp selection outline to 660 nodes
+
+ at DPATCH@
+
+diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
+index e9c1227..5c1c73e 100644
+--- a/indra/llrender/llrender.cpp
++++ b/indra/llrender/llrender.cpp
+@@ -657,6 +657,9 @@ void LLRender::vertex3fv(const GLfloat* v)
+ 
+ void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
+ { 
++	if (mCount >= 4096)
++		return;
++
+ 	mTexcoordsp[mCount] = LLVector2(x,y);
+ }
+ 
+@@ -672,6 +675,10 @@ void LLRender::texCoord2fv(const GLfloat* tc)
+ 
+ void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
+ {
++
++	if (mCount >= 4096)
++		return;
++
+ 	mColorsp[mCount] = LLColor4U(r,g,b,a);
+ }
+ void LLRender::color4ubv(const GLubyte* c)
diff --git a/debian/patches/VWR4070-openjpeg_check_number_of_components.diff b/debian/patches/VWR4070-openjpeg_check_number_of_components.diff
new file mode 100644
index 0000000..af10856
--- /dev/null
+++ b/debian/patches/VWR4070-openjpeg_check_number_of_components.diff
@@ -0,0 +1,125 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## VWR4070.dpatch by  <root at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+
+Index: ./indra/llimagej2coj/llimagej2coj.cpp
+===================================================================
+--- ./indra/llimagej2coj/llimagej2coj.cpp	(revision 367)
++++ ./indra/llimagej2coj/llimagej2coj.cpp	(working copy)
+@@ -134,9 +134,15 @@
+ 	/* open a byte stream */
+ 	cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
+ 
+-	/* decode the stream and fill the image structure */
+-	image = opj_decode(dinfo, cio);
+ 
++	/* decode the stream and fill the image structure, also fill in an additional
++	   structure to get the decoding result. This structure is a bit unusual in that
++	   it is not received through opj, but still has some dynamically allocated fields
++	   that need to be cleared up at the end by calling a destroy function. */
++	opj_codestream_info_t cinfo;
++	memset(&cinfo, 0, sizeof(opj_codestream_info_t));
++	image = opj_decode_with_info(dinfo, cio, &cinfo);
++	
+ 	/* close the byte stream */
+ 	opj_cio_close(cio);
+ 
+@@ -146,30 +152,58 @@
+ 		opj_destroy_decompress(dinfo);
+ 	}
+ 
+-	// The image decode failed if the return was NULL or the component
+-	// count was zero.  The latter is just a sanity check before we
+-	// dereference the array.
++	/* The image decode failed if the return was NULL or the component
++	   count was zero.  The latter is just a sanity check before we
++	   dereference the array. */
+ 	if(!image || !image->numcomps)
+ 	{
+ 		fprintf(stderr, "ERROR -> decodeImpl: failed to decode image!\n");
+ 		if (image)
++		{
++			opj_destroy_cstr_info(&cinfo);
+ 			opj_image_destroy(image);
++		}
+ 
+ 		return TRUE; // done
+ 	}
+ 
+ 	// sometimes we get bad data out of the cache - check to see if the decode succeeded
+-	for (S32 i = 0; i < image->numcomps; i++)
+-	{
+-		if (image->comps[i].factor != base.getRawDiscardLevel())
++	int decompdifference = 0;
++	if (cinfo.numdecompos) // sanity
++	{	
++		for (int comp = 0; comp < image->numcomps; comp++)
++		{	/* get maximum decomposition level difference, first field is from the COD header and the second
++			   is what is actually met in the codestream, NB: if everything was ok, this calculation will
++			   return what was set in the cp_reduce value! */
++			decompdifference = std::max(decompdifference, cinfo.numdecompos[comp] - image->comps[comp].resno_decoded);
++		}
++		if (decompdifference < 0) // sanity
+ 		{
+-			// if we didn't get the discard level we're expecting, fail
+-			opj_image_destroy(image);
+-			base.mDecoding = FALSE;
+-			return TRUE;
++			decompdifference = 0;
+ 		}
+ 	}
++
++	/* if OpenJPEG failed to decode all requested decomposition levels 
++	   the difference will be greater than this level */
++	if (decompdifference > base.getRawDiscardLevel())
++	{
++		llwarns << "not enough data for requested discard level, setting mDecoding to FALSE, difference: " << (decompdifference - base.getRawDiscardLevel()) << llendl;
++		opj_destroy_cstr_info(&cinfo);
++		opj_image_destroy(image);
++			
++		base.mDecoding = FALSE;
++		return TRUE;
++	}
+ 	
++	if(image->numcomps <= first_channel)
++	{
++		// sanity
++		llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl;
++		opj_destroy_cstr_info(&cinfo);
++		opj_image_destroy(image);			
++		return TRUE;
++	}
++
+ 	// Copy image data into our raw image format (instead of the separate channel format
+ 
+ 	S32 img_components = image->numcomps;
+@@ -191,6 +225,7 @@
+ 	raw_image.resize(width, height, channels);
+ 	U8 *rawp = raw_image.getData();
+ 
++
+ 	// first_channel is what channel to start copying from
+ 	// dest is what channel to copy to.  first_channel comes from the
+ 	// argument, dest always starts writing at channel zero.
+@@ -212,13 +247,15 @@
+ 		else // Some rare OpenJPEG versions have this bug.
+ 		{
+ 			fprintf(stderr, "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)\n");
++			opj_destroy_cstr_info(&cinfo);
+ 			opj_image_destroy(image);
+ 
+ 			return TRUE; // done
+ 		}
+ 	}
+ 
+-	/* free image data structure */
++	/* free opj data structures */
++	opj_destroy_cstr_info(&cinfo);
+ 	opj_image_destroy(image);
+ 
+ 	return TRUE; // done
diff --git a/debian/patches/VWR5715_text_not_replaced_by_input_with_japanses_im.diff b/debian/patches/VWR5715_text_not_replaced_by_input_with_japanses_im.diff
new file mode 100644
index 0000000..0cb83f9
--- /dev/null
+++ b/debian/patches/VWR5715_text_not_replaced_by_input_with_japanses_im.diff
@@ -0,0 +1,64 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## Selected Text is not replaced by Input text when Japanese IM is on.dpatch by  <root at debian.example.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Patch by Alissa Sabre
+
+ at DPATCH@
+
+Index: linden/indra/llui/lllineeditor.cpp
+===================================================================
+--- linden/indra/llui/lllineeditor.cpp	(revision 535)
++++ linden/indra/llui/lllineeditor.cpp	(revision 536)
+@@ -2315,14 +2315,20 @@
+ 
+ void LLLineEditor::resetPreedit()
+ {
+-	if (hasPreeditString())
++	if (hasSelection())
+ 	{
+-		if (hasSelection())
++		if (hasPreeditString())
+ 		{
+ 			llwarns << "Preedit and selection!" << llendl;
+ 			deselect();
+ 		}
+-
++		else
++		{
++			deleteSelection();
++		}
++	}
++	if (hasPreeditString())
++	{
+ 		const S32 preedit_pos = mPreeditPositions.front();
+ 		mText.erase(preedit_pos, mPreeditPositions.back() - preedit_pos);
+ 		mText.insert(preedit_pos, mPreeditOverwrittenWString);
+Index: linden/indra/llui/lltexteditor.cpp
+===================================================================
+--- linden/indra/llui/lltexteditor.cpp	(revision 535)
++++ linden/indra/llui/lltexteditor.cpp	(revision 536)
+@@ -4333,14 +4333,20 @@
+ 
+ void LLTextEditor::resetPreedit()
+ {
+-	if (hasPreeditString())
++	if (hasSelection())
+ 	{
+-		if (hasSelection())
++		if (hasPreeditString())
+ 		{
+ 			llwarns << "Preedit and selection!" << llendl;
+ 			deselect();
+ 		}
+-
++		else
++		{
++			deleteSelection(FALSE);
++		}
++	}
++	if (hasPreeditString())
++	{
+ 		mCursorPos = mPreeditPositions.front();
+ 		removeStringNoUndo(mCursorPos, mPreeditPositions.back() - mCursorPos);
+ 		insertStringNoUndo(mCursorPos, mPreeditOverwrittenWString);
diff --git a/debian/patches/VWR6800_motioncontroller_leak.diff b/debian/patches/VWR6800_motioncontroller_leak.diff
new file mode 100644
index 0000000..3e22d7a
--- /dev/null
+++ b/debian/patches/VWR6800_motioncontroller_leak.diff
@@ -0,0 +1,34 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## apply VWR6800.dpatch by  <root at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+Index: Branch_1-20-Viewer/indra/llcharacter/llmotioncontroller.cpp
+===================================================================
+--- Branch_1-20-Viewer.orig/indra/llcharacter/llmotioncontroller.cpp	2008-04-24 00:13:22.000000000 +0200
++++ Branch_1-20-Viewer/indra/llcharacter/llmotioncontroller.cpp	2008-04-24 00:19:42.000000000 +0200
+@@ -190,6 +190,11 @@
+ 
+ 	for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer());
+ 	mAllMotions.clear();
++
++	// LLMotion instances on this list were removed from the AllMotions map
++	for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer());
++	mDeprecatedMotions.clear();
++	
+ }
+ 
+ //-----------------------------------------------------------------------------
+@@ -379,7 +384,8 @@
+ 	if (motion
+ 		&& motion->canDeprecate()
+ 		&& motion->getFadeWeight() > 0.01f // not LOD-ed out
+-		&& (motion->isBlending() || motion->getStopTime() != 0.f))
++		&& (motion->isBlending() || motion->getStopTime() != 0.f)
++		&& motion->isActive())
+ 	{
+ 		deprecateMotionInstance(motion);
+ 		// force creation of new instance
diff --git a/debian/patches/dam_flex_2.5.34.diff b/debian/patches/dam_flex_2.5.34.diff
new file mode 100644
index 0000000..4882c61
--- /dev/null
+++ b/debian/patches/dam_flex_2.5.34.diff
@@ -0,0 +1,22 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## dam flex 2.5.34.dpatch by  <robin at debian>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+
+Index: ./indra/lscript/lscript_compile/indra.l
+===================================================================
+--- ./indra/lscript/lscript_compile/indra.l	(revision 178)
++++ ./indra/lscript/lscript_compile/indra.l	(working copy)
+@@ -4,9 +4,6 @@
+ H			[a-fA-F0-9]
+ E			[Ee][+-]?{N}+
+ FS			(f|F)
+-%e 10000
+-%n 4000
+-%p 5000
+ 
+ %{
+ #include "linden_common.h"
diff --git a/debian/patches/openal_1.21.0.diff b/debian/patches/openal_1.21.0.diff
new file mode 100644
index 0000000..f43c7ff
--- /dev/null
+++ b/debian/patches/openal_1.21.0.diff
@@ -0,0 +1,1104 @@
+Index: omvviewer-1.21.0/indra/llaudio/audioengine.cpp
+===================================================================
+--- omvviewer-1.21.0.orig/indra/llaudio/audioengine.cpp	2008-08-31 09:42:53.000000000 +0100
++++ omvviewer-1.21.0/indra/llaudio/audioengine.cpp	2008-08-31 14:26:27.000000000 +0100
+@@ -111,6 +111,8 @@
+ 	// Initialize the decode manager
+ 	gAudioDecodeMgrp = new LLAudioDecodeMgr;
+ 
++	llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl;
++
+ 	return TRUE;
+ }
+ 
+@@ -1336,7 +1338,11 @@
+ BOOL LLAudioSource::isDone()
+ {
+ 	const F32 MAX_AGE = 60.f;
++#if LL_OPENAL
++	const F32 MAX_UNPLAYED_AGE = 30.f;
++#else
+ 	const F32 MAX_UNPLAYED_AGE = 15.f;
++#endif
+ 	if (isLoop())
+ 	{
+ 		// Looped sources never die on their own.
+Index: omvviewer-1.21.0/indra/llaudio/audioengine.h
+===================================================================
+--- omvviewer-1.21.0.orig/indra/llaudio/audioengine.h	2008-08-31 09:42:53.000000000 +0100
++++ omvviewer-1.21.0/indra/llaudio/audioengine.h	2008-08-31 11:54:11.000000000 +0100
+@@ -159,6 +159,10 @@
+ 	static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
+ 
+ 
++	#if LL_OPENAL
++		virtual void InitStreamer() = 0;
++	#endif
++
+ 	friend class LLPipeline; // For debugging
+ public:
+ 	F32 mMaxWindGain; // Hack.  Public to set before fade in?
+Index: omvviewer-1.21.0/indra/llaudio/audioengine_openal.cpp
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ omvviewer-1.21.0/indra/llaudio/audioengine_openal.cpp	2008-08-31 14:34:11.000000000 +0100
+@@ -0,0 +1,618 @@
++/**
++ * @file audioengine_openal.cpp
++ * @brief implementation of audio engine using OpenAL
++ * support as a OpenAL 3D implementation
++ *
++ * Copyright (c) 2002-2008, 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.
++ */
++
++#include "linden_common.h"
++
++#include "audioengine_openal.h"
++#include "listener_openal.h"
++
++
++#if LL_OPENAL_WIND
++// Variables and definitions for Wind
++#define NO_WIND_BUFFERS 20
++static ALuint wind_buffers[NO_WIND_BUFFERS];
++static ALuint wind_sources[1];
++static S16 *winddata=NULL;
++
++static BOOL first_wind=TRUE;
++
++ALfloat source0Vel[]={ 0.0, 0.0, 0.0};
++
++// These globals for the wind filter.  Blech!
++F64 gbuf0 = 0.0;
++F64 gbuf1 = 0.0;
++F64 gbuf2 = 0.0;
++F64 gbuf3 = 0.0;
++F64 gbuf4 = 0.0;
++F64 gbuf5 = 0.0;
++F64 gY0 = 0.0;
++F64 gY1 = 0.0;
++
++F32 gTargetGain = 0.f;
++F32 gCurrentGain = 0.f;
++F32 gTargetFreq = 100.f;
++F32 gCurrentFreq = 100.f;
++F32 gTargetPanGainR = 0.5f;
++F32 gCurrentPanGainR = 0.5f;
++#endif // LL_OPENAL_WIND
++
++LLAudioEngine_OpenAL::LLAudioEngine_OpenAL(){
++
++#if LL_GSTREAMER_ENABLED
++	mMedia_data = new LLMediaManagerData;
++	LLMediaImplGStreamer::startup( mMedia_data );	// initialize GStreamer
++
++	m_streamer=new LLMediaImplGStreamer ();
++
++	if(!m_streamer)
++	{
++		llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl;
++	}
++#endif
++}
++
++LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL(){
++}
++
++BOOL LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata){
++
++	LLAudioEngine::init(num_channels, userdata);
++
++	if(!alutInit(NULL, NULL)){
++		llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << llendl;
++		return FALSE;
++	}
++
++	initInternetStream();
++
++	llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl;
++
++	llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl;
++
++	return TRUE;
++}
++
++void LLAudioEngine_OpenAL::idle(F32 max_decode_time){
++	LLAudioEngine::idle(max_decode_time);
++#if LL_GSTREAMER_ENABLED
++       if(m_streamer != NULL)
++		m_streamer->updateMedia();
++#endif
++}
++
++void LLAudioEngine_OpenAL::allocateListener(){
++	mListenerp = (LLListener *) new LLListener_OpenAL();
++	if(!mListenerp){
++		llwarns << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << llendl;
++	}
++}
++
++void LLAudioEngine_OpenAL::shutdown(){
++	LLAudioEngine::shutdown();
++
++	if(!alutExit()){
++		llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl;
++	}
++
++	llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl;
++
++	delete mListenerp;
++	mListenerp = NULL;
++
++#if LL_GSTREAMER_ENABLED
++	if(m_streamer){
++		delete m_streamer;
++		m_streamer = NULL;
++	}
++#endif
++}
++
++LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer(){
++   return new LLAudioBufferOpenAL();
++}
++
++LLAudioChannel *LLAudioEngine_OpenAL::createChannel(){
++   return new LLAudioChannelOpenAL();
++}
++
++void LLAudioEngine_OpenAL::setInternalGain(F32 gain){
++	//llinfos << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << llendl;
++	alListenerf(AL_GAIN, gain);
++}
++
++LLAudioChannelOpenAL::LLAudioChannelOpenAL(){
++	alGenSources(1, &ALSource);
++}
++
++LLAudioChannelOpenAL::~LLAudioChannelOpenAL(){
++	cleanup();
++	alDeleteSources(1, &ALSource);
++}
++
++void LLAudioChannelOpenAL::cleanup(){
++	alSourceStop(ALSource);
++	mCurrentBufferp = NULL;
++}
++
++void LLAudioChannelOpenAL::play(){
++	if(!isPlaying()){
++		alSourcePlay(ALSource);
++		getSource()->setPlayedOnce(TRUE);
++	}
++}
++
++void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp){
++	play();
++}
++
++BOOL LLAudioChannelOpenAL::isPlaying(){
++	ALint state;
++	alGetSourcei(ALSource, AL_SOURCE_STATE, &state);
++	if(state == AL_PLAYING){
++		return TRUE;
++	}
++	return FALSE;
++}
++
++BOOL LLAudioChannelOpenAL::updateBuffer(){
++	if (LLAudioChannel::updateBuffer()){
++		// Base class update returned TRUE, which means that we need to actually
++		// set up the source for a different buffer.
++		LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer();
++		alSourcei(ALSource, AL_BUFFER, bufferp->getBuffer());
++		alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain());
++		alSourcei(ALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE);
++	}
++
++	return TRUE;
++}
++
++void LLAudioChannelOpenAL::update3DPosition(){
++	if(!mCurrentSourcep){
++		return;
++	}
++	if (mCurrentSourcep->isAmbient()){
++		alSource3f(ALSource, AL_POSITION, 0.0, 0.0, 0.0);
++		alSource3f(ALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
++		//alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
++		alSourcef (ALSource, AL_ROLLOFF_FACTOR, 0.0);
++		alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_TRUE);
++	}else{
++		LLVector3 float_pos;
++		float_pos.setVec(mCurrentSourcep->getPositionGlobal());
++		alSourcefv(ALSource, AL_POSITION, float_pos.mV);
++		//llinfos << "LLAudioChannelOpenAL::update3DPosition() Velocity: " << mCurrentSourcep->getVelocity() << llendl;
++		alSourcefv(ALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV);
++		//alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
++		alSourcef (ALSource, AL_ROLLOFF_FACTOR, 1.0);
++		alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_FALSE);
++	}
++	//llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl;
++	alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain());
++}
++
++LLAudioBufferOpenAL::LLAudioBufferOpenAL(){
++	ALBuffer = AL_NONE;
++}
++
++LLAudioBufferOpenAL::~LLAudioBufferOpenAL(){
++	cleanup();
++}
++
++void LLAudioBufferOpenAL::cleanup(){
++	if(ALBuffer != AL_NONE){
++		alDeleteBuffers(1, &ALBuffer);
++	}
++}
++
++BOOL LLAudioBufferOpenAL::loadWAV(const std::string& filename){
++	cleanup();
++	ALBuffer = alutCreateBufferFromFile(filename.c_str());
++	if(ALBuffer == AL_NONE){
++		//ALenum error = alutGetError();
++		//llwarns << "LLAudioBufferOpenAL::loadWAV() Error loading " << filename
++		//	<< " " << alutGetErrorString(error) << llendl;
++		return FALSE;
++	}
++
++	return TRUE;
++}
++
++U32 LLAudioBufferOpenAL::getLength(){
++	if(ALBuffer == AL_NONE){
++		return 0;
++	}
++	ALint length;
++	alGetBufferi(ALBuffer, AL_SIZE, &length);
++	return length >> 2;
++}
++
++// ------------
++
++void LLAudioEngine_OpenAL::initWind(){
++#if LL_OPENAL_WIND
++	ALenum error;
++       llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl;
++
++       alGetError(); /* clear error */
++       alGenBuffers(NO_WIND_BUFFERS,wind_buffers);
++       if((error=alGetError()) != AL_NO_ERROR)
++       {
++               llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffers: "<<error<<llendl;
++       }
++
++       alGenSources(1,wind_sources);
++
++       if((error=alGetError()) != AL_NO_ERROR)
++       {
++               llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<llendl;
++       }
++
++       winddata=(S16*)malloc(sizeof(S16)*44100*0.2*2*2); //200ms @44100Hz Stereo
++
++       if(winddata==NULL)
++       {
++               llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl;
++               mEnableWind=FALSE;
++       }
++
++       llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl;
++#endif
++}
++
++void LLAudioEngine_OpenAL::cleanupWind(){
++#if LL_OPENAL_WIND
++       llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl;
++
++       alDeleteBuffers(NO_WIND_BUFFERS,wind_buffers);
++
++       alDeleteSources(1, wind_sources);
++
++       if(winddata)
++               free(winddata);
++#endif
++}
++
++void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude){
++#if LL_OPENAL_WIND
++       LLVector3 wind_pos;
++       F64 pitch;
++       F64 center_freq;
++       ALenum error;
++
++       mMaxWindGain=1.0;
++
++       if (!mEnableWind)
++               return;
++
++       if(!winddata)
++               return;
++
++       if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
++       {
++
++               // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
++               // need to convert this to the conventional orientation DS3D and OpenAL use
++               // where +X = right, +Y = up, +Z = backwards
++
++               wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
++
++               // cerr << "Wind update" << endl;
++
++               pitch = 1.0 + mapWindVecToPitch(wind_vec);
++               center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
++
++               gTargetFreq = (F32)center_freq;
++               gTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
++               gTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
++
++               ALfloat source0Pos[]={mListenerp->getPosition().mV[0],mListenerp->getPosition().mV[1],mListenerp->getPosition().mV[2]};
++
++               alSourcef(wind_sources[0], AL_GAIN, gTargetGain);
++               alSourcef(wind_sources[0], AL_PITCH, pitch);
++               alSourcefv(wind_sources[0], AL_POSITION, source0Pos);
++               alSourcefv(wind_sources[0], AL_VELOCITY, source0Vel);
++               alSourcei(wind_sources[0], AL_LOOPING, AL_FALSE);
++
++       }
++
++       // ok lets make a wind buffer now
++
++       if(first_wind==TRUE)
++       {
++               llinfos << "LLAudioEngine_OpenAL::updateWind() making first buffer" << llendl;
++               alGetError(); /* clear error */
++
++               for(int counter=0;counter<NO_WIND_BUFFERS;counter++)
++               {
++                       alBufferData(wind_buffers[counter],AL_FORMAT_STEREO16,windDSP((void*)winddata,2*44100*0.02),2*44100*0.02*sizeof(U16),44100);
++                       if((error=alGetError()) != AL_NO_ERROR)
++                       {
++                               llwarns << "LLAudioEngine_OpenAL::initWind() Error creating INITAL WIND BUFFER 1: "<<error<<llendl;
++                       }
++               }
++
++               alSourceQueueBuffers(wind_sources[0], NO_WIND_BUFFERS, wind_buffers);
++
++               alSourcePlay(wind_sources[0]);
++               if((error=alGetError()) != AL_NO_ERROR)
++               {
++                       llwarns << "LLAudioEngine_OpenAL::initWind() Error inital wind play: "<<error<<llendl;
++               }
++
++               first_wind=FALSE;
++               llinfos << "LLAudioEngine_OpenAL::updateWind() making first buffer DONE!" << llendl;
++
++       }
++       else
++       {
++               int processed;
++               alGetSourcei(wind_sources[0], AL_BUFFERS_PROCESSED, &processed);
++
++               while(processed--)
++               {
++                       ALuint buffer;
++                       int error;
++                       alSourceUnqueueBuffers(wind_sources[0], 1, &buffer);
++                       error = alGetError();
++                       if(error != AL_NO_ERROR)
++                               llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping buffers" << llendl;
++
++                       alBufferData(buffer,AL_FORMAT_STEREO16,windDSP((void*)winddata,44100*0.2),2*44100*0.2*sizeof(U16),44100);
++                       error = alGetError();
++                       if(error != AL_NO_ERROR)
++                               llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping buffers" << llendl;
++
++
++                       alSourceQueueBuffers(wind_sources[0], 1, &buffer);
++                       error = alGetError();
++                       if(error != AL_NO_ERROR)
++                               llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping buffers" << llendl;
++
++
++               }
++
++               int playing;
++               alGetSourcei(wind_sources[0], AL_SOURCE_STATE, &playing);
++
++               if(playing==AL_STOPPED)
++                       alSourcePlay(wind_sources[0]);
++
++       }
++#endif //LL_OPENAL_WIND
++}
++
++inline S16 clipSample(S16 sample, S16 min, S16 max)
++{
++#if LL_OPENAL_WIND
++       if (sample > max)
++               sample = max;
++       else if (sample < min)
++               sample = min;
++
++#endif
++       return sample;
++}
++
++void * LLAudioEngine_OpenAL::windDSP(void *newbuffer, int length)
++{
++#if LL_OPENAL_WIND
++       // newbuffer = the buffer passed from the previous DSP unit.
++       // length = length in samples at this mix time.
++
++       U8 *cursamplep = (U8*)newbuffer;
++       U8   wordsize = 2;
++
++       double bandwidth = 50;
++       double inputSamplingRate = 44100;
++       double a0,b1,b2;
++
++       // calculate resonant filter coeffs
++       b2 = exp(-(F_TWO_PI) * (bandwidth / inputSamplingRate));
++
++       while (length--)
++       {
++               gCurrentFreq = (float)((0.999 * gCurrentFreq) + (0.001 * gTargetFreq));
++               gCurrentGain = (float)((0.999 * gCurrentGain) + (0.001 * gTargetGain));
++               gCurrentPanGainR = (float)((0.999 * gCurrentPanGainR) + (0.001 * gTargetPanGainR));
++               b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (gCurrentFreq / inputSamplingRate));
++               a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2));
++               double nextSample;
++
++           // start with white noise
++               nextSample = ll_frand(2.0f) - 1.0f;
++
++#if 1 // LLAE_WIND_PINK apply pinking filter
++               gbuf0 = 0.997f * gbuf0 + 0.0126502f * nextSample;
++               gbuf1 = 0.985f * gbuf1 + 0.0139083f * nextSample;
++               gbuf2 = 0.950f * gbuf2 + 0.0205439f * nextSample;
++               gbuf3 = 0.850f * gbuf3 + 0.0387225f * nextSample;
++               gbuf4 = 0.620f * gbuf4 + 0.0465932f * nextSample;
++               gbuf5 = 0.250f * gbuf5 + 0.1093477f * nextSample;
++
++                       nextSample = gbuf0 + gbuf1 + gbuf2 + gbuf3 + gbuf4 + gbuf5;
++#endif
++
++#if 1 //LLAE_WIND_RESONANT // do a resonant filter on the noise
++               nextSample = (double)( a0 * nextSample - b1 * gY0 - b2 * gY1 );
++
++               gY1 = gY0;
++               gY0 = nextSample;
++#endif
++               nextSample *= gCurrentGain;
++
++               S16     sample;
++
++               sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f);
++               *(S16*)cursamplep = clipSample(sample, -32768, 32767);
++
++               cursamplep += wordsize;
++
++               sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
++
++               sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
++               *(S16*)cursamplep = clipSample(sample, -32768, 32767);
++               cursamplep += wordsize;
++       }
++
++#endif //LL_OPENAL_WIND
++       return newbuffer;
++}
++
++// ------------
++
++void LLAudioEngine_OpenAL::InitStreamer()
++{
++#if LL_GSTREAMER_ENABLED
++       m_streamer=new LLMediaImplGStreamer ();
++
++       if(!m_streamer)
++       {
++               llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl;
++       }
++
++       if(m_streamer)
++       {
++               m_streamer->init ();
++       }
++#endif
++}
++
++// ------------
++
++void LLAudioEngine_OpenAL::initInternetStream(){
++	if(!mInternetStreamURL.empty())
++		mInternetStreamURL.erase();
++}
++
++void LLAudioEngine_OpenAL::startInternetStream(const std::string& url){
++
++#if LL_GSTREAMER_ENABLED
++	if(!m_streamer)
++		return;
++// DCF_DEBUG
++llinfos << "entered LLAudioEngine_OpenAL::startInternetStream()" << llendl;
++	
++
++	if (!url.empty()) {
++		llinfos << "LLAudioEngine_OpenAL::startInternetStream() Starting internet stream: " << url << llendl;
++		mInternetStreamURL=url;
++		m_streamer->navigateTo ( url );
++		llinfos << "Playing....." << llendl;		
++		m_streamer->addCommand(LLMediaBase::COMMAND_START);
++		m_streamer->updateMedia();
++
++	}else{
++		llinfos << "LLAudioEngine_OpenAL setting stream to NULL"<< llendl;
++		mInternetStreamURL.erase();
++		m_streamer->addCommand(LLMediaBase::COMMAND_STOP);
++		m_streamer->updateMedia();
++	}
++#endif
++}
++
++void LLAudioEngine_OpenAL::updateInternetStream(){
++// DCF_DEBUG
++llinfos << "entered LLAudioEngine_OpenAL::updateInternetStream()" << llendl;
++	
++}
++
++void LLAudioEngine_OpenAL::stopInternetStream(){
++// DCF_DEBUG
++llinfos << "entered LLAudioEngine_OpenAL::stopInternetStream()" << llendl;
++	
++#if LL_GSTREAMER_ENABLED
++	if( ! m_streamer->addCommand(LLMediaBase::COMMAND_STOP)){
++		llinfos << "attempting to stop stream failed!" << llendl;
++	}
++	m_streamer->updateMedia();
++#endif
++	mInternetStreamURL.erase();
++}
++
++void LLAudioEngine_OpenAL::pauseInternetStream(int pause){
++#if LL_GSTREAMER_ENABLED
++	if(!m_streamer)
++		return;
++// DCF_DEBUG
++llinfos << "entered LLAudioEngine_OpenAL::pauseInternetStream()" << llendl;
++	
++	if(pause){
++		if(!m_streamer->addCommand(LLMediaBase::COMMAND_PAUSE)){
++			llinfos << "attempting to pause stream failed!" << llendl;
++		}
++		m_streamer->updateMedia();
++	}else{
++		if( ! m_streamer->addCommand(LLMediaBase::COMMAND_START)){
++			llinfos << "attempting to pause stream failed!" << llendl;
++		}
++		m_streamer->updateMedia();
++	}
++#endif
++}
++
++int LLAudioEngine_OpenAL::isInternetStreamPlaying(){
++
++#if LL_GSTREAMER_ENABLED
++	if(!m_streamer)
++		return 0;
++	
++	if(m_streamer->getStatus() == LLMediaBase::STATUS_STARTED)
++	{
++		return 1; // Active and playing
++	}	
++
++	if(m_streamer->getStatus() == LLMediaBase::STATUS_PAUSED)
++	{
++		return 2; // paused
++	}
++#endif
++	return 0; // Stopped
++}
++
++void LLAudioEngine_OpenAL::getInternetStreamInfo(char* artist_out, char* title_out){
++}
++
++void LLAudioEngine_OpenAL::setInternetStreamGain(F32 vol){
++#if LL_GSTREAMER_ENABLED
++	// Set the gstreamer volume here
++	if(!m_streamer)
++		return;
++
++	vol = llclamp(vol, 0.f, 1.f);
++	m_streamer->setVolume(vol);
++	m_streamer->updateMedia();
++
++#endif
++}
++
++const std::string& LLAudioEngine_OpenAL::getInternetStreamURL(){
++	return mInternetStreamURL;
++}
++
+Index: omvviewer-1.21.0/indra/llaudio/audioengine_openal.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ omvviewer-1.21.0/indra/llaudio/audioengine_openal.h	2008-08-31 14:48:25.000000000 +0100
+@@ -0,0 +1,122 @@
++/**
++ * @file audioengine_openal.cpp
++ * @brief implementation of audio engine using OpenAL
++ * support as a OpenAL 3D implementation
++ *
++ * Copyright (c) 2002-2008, 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.
++ */
++
++
++#ifndef LL_AUDIOENGINE_OpenAL_H
++#define LL_AUDIOENGINE_OpenAL_H
++
++
++#include <string>
++
++#include "audioengine.h"
++#include "listener_openal.h"
++
++
++#if LL_GSTREAMER_ENABLED
++#include "llmediamanager.h"
++#include "llmediaimplgstreamer.h"
++#endif
++
++#include "llrand.h"
++
++class LLAudioEngine_OpenAL : public LLAudioEngine{
++	public:
++		LLAudioEngine_OpenAL();
++		virtual ~LLAudioEngine_OpenAL();
++
++		virtual BOOL init(const S32 num_channels, void *user_data);
++		virtual void allocateListener();
++
++		virtual void shutdown();
++
++		virtual void idle(F32 max_decode_time = 0.f);
++
++		void setInternalGain(F32 gain);
++
++		LLAudioBuffer* createBuffer();
++		LLAudioChannel* createChannel();
++
++		// Internet stream methods
++		virtual void initInternetStream();
++		virtual void startInternetStream(const std::string& url);
++		virtual void stopInternetStream();
++		virtual void updateInternetStream();
++		virtual void pauseInternetStream(int pause);
++		virtual int isInternetStreamPlaying();
++		virtual void getInternetStreamInfo(char* artist, char* title);
++		virtual void setInternetStreamGain(F32 vol);
++		virtual const std::string& getInternetStreamURL();
++		virtual void InitStreamer();
++
++		void initWind();
++		void cleanupWind();
++		void updateWind(LLVector3 direction, F32 camera_altitude);
++
++	protected:
++		std::string mInternetStreamURL;
++		void * windDSP(void *newbuffer, int length);
++#if LL_GSTREAMER_ENABLED
++		LLMediaManagerData * mMedia_data;
++		LLMediaImplGStreamer * m_streamer;
++#endif
++};
++
++class LLAudioChannelOpenAL : public LLAudioChannel{
++	public:
++		LLAudioChannelOpenAL();
++		virtual ~LLAudioChannelOpenAL();
++	protected:
++		void play();
++		void playSynced(LLAudioChannel *channelp);
++		void cleanup();
++		BOOL isPlaying();
++
++		BOOL updateBuffer();
++		void update3DPosition();
++		void updateLoop(){};
++
++		ALuint ALSource;
++};
++
++class LLAudioBufferOpenAL : public LLAudioBuffer{
++	public:
++		LLAudioBufferOpenAL();
++		virtual ~LLAudioBufferOpenAL();
++
++		BOOL loadWAV(const std::string& filename);
++		U32 getLength();
++
++		friend class LLAudioChannelOpenAL;
++	protected:
++		void cleanup();
++		ALuint getBuffer(){return ALBuffer;}
++		ALuint ALBuffer;
++};
++
++#endif
+Index: omvviewer-1.21.0/indra/llaudio/listener_openal.cpp
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ omvviewer-1.21.0/indra/llaudio/listener_openal.cpp	2008-08-31 13:53:08.000000000 +0100
+@@ -0,0 +1,95 @@
++/**
++ * @file audioengine_openal.cpp
++ * @brief implementation of audio engine using OpenAL
++ * support as a OpenAL 3D implementation
++ *
++ * Copyright (c) 2002-2007, 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.
++ */
++
++#include "linden_common.h"
++#include "audioengine.h"
++
++#include "listener_openal.h"
++
++LLListener_OpenAL::LLListener_OpenAL(){
++	init();
++}
++
++LLListener_OpenAL::~LLListener_OpenAL(){
++}
++
++void LLListener_OpenAL::translate(LLVector3 offset){
++	LLListener::translate(offset);
++	llinfos << "LLListener_OpenAL::translate() : " << offset << llendl;
++}
++
++void LLListener_OpenAL::setPosition(LLVector3 pos){
++	LLListener::setPosition(pos);
++	//llinfos << "LLListener_OpenAL::setPosition() : " << pos << llendl;
++}
++
++void LLListener_OpenAL::setVelocity(LLVector3 vel){
++	LLListener::setVelocity(vel);
++}
++
++void LLListener_OpenAL::orient(LLVector3 up, LLVector3 at){
++	LLListener::orient(up, at);
++	//llinfos << "LLListener_OpenAL::orient() up: " << up << " at: " << at << llendl;
++}
++
++void LLListener_OpenAL::commitDeferredChanges(){
++	ALfloat orientation[6];
++	orientation[0] = mListenAt.mV[0];
++	orientation[1] = mListenAt.mV[1];
++	orientation[2] = mListenAt.mV[2];
++	orientation[3] = mListenUp.mV[0];
++	orientation[4] = mListenUp.mV[1];
++	orientation[5] = mListenUp.mV[2];
++
++	// Why is this backwards?
++	ALfloat velocity[3];
++	velocity[0] = -mVelocity.mV[0];
++	velocity[1] = -mVelocity.mV[1];
++	velocity[2] = -mVelocity.mV[2];
++
++	alListenerfv(AL_ORIENTATION, orientation);
++	alListenerfv(AL_POSITION, mPosition.mV);
++	alListenerfv(AL_VELOCITY, velocity);
++}
++
++void LLListener_OpenAL::setDopplerFactor(F32 factor){
++	// Effect is way too strong by default, scale it down here.
++	// Scaling the speed of sound up causes crashes.
++	factor *= 0.01f;
++	//llinfos << "LLListener_OpenAL::setDopplerFactor() : " << factor << llendl;
++	alDopplerFactor(factor);
++}
++
++F32 LLListener_OpenAL::getDopplerFactor(){
++	ALfloat factor;
++	alDopplerFactor(factor);
++	llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl;
++	return factor;
++}
++
+Index: omvviewer-1.21.0/indra/llaudio/listener_openal.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ omvviewer-1.21.0/indra/llaudio/listener_openal.h	2008-08-31 14:34:35.000000000 +0100
+@@ -0,0 +1,62 @@
++/** 
++ * @file listener_openal.h
++ * @brief Description of LISTENER class abstracting the audio support
++ * as an OpenAL implementation
++ *
++ * $LicenseInfo:firstyear=2000&license=viewergpl$
++ * 
++ * Copyright (c) 2000-2008, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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$
++ */
++
++#ifndef LL_LISTENER_OPENAL_H
++#define LL_LISTENER_OPENAL_H
++
++#include "listener.h"
++#include "AL/al.h"
++#include "AL/alut.h"
++
++class LLListener_OpenAL  : public LLListener
++{
++ private:
++ protected:
++ public:
++
++ private:
++ protected:
++ public:  
++	LLListener_OpenAL();
++	virtual ~LLListener_OpenAL();
++
++	virtual void translate(LLVector3 offset);
++	virtual void setPosition(LLVector3 pos);
++	virtual void setVelocity(LLVector3 vel);
++	virtual void orient(LLVector3 up, LLVector3 at);
++	virtual void commitDeferredChanges();
++
++	virtual void setDopplerFactor(F32 factor);
++	virtual F32 getDopplerFactor();
++};
++
++#endif
+Index: omvviewer-1.21.0/indra/llaudio/CMakeLists.txt
+===================================================================
+--- omvviewer-1.21.0.orig/indra/llaudio/CMakeLists.txt	2008-08-31 09:42:53.000000000 +0100
++++ omvviewer-1.21.0/indra/llaudio/CMakeLists.txt	2008-08-31 14:55:11.000000000 +0100
+@@ -9,6 +9,7 @@
+ include(LLMath)
+ include(LLMessage)
+ include(LLVFS)
++include(LLMedia)
+ 
+ include_directories(
+     ${FMOD_INCLUDE_DIR}
+@@ -20,6 +21,10 @@
+     ${VORBISENC_INCLUDE_DIRS}
+     ${VORBISFILE_INCLUDE_DIRS}
+     ${VORBIS_INCLUDE_DIRS}
++    ${OPENAL_LIB_INCLUDE_DIRS}
++    ${FREEAULT_LIB_INCLUDE_DIRS}
++    ${LLMEDIA_INCLUDE_DIRS}
++    ${GSTREAMER_INCLUDE_DIRS}
+     )
+ 
+ set(llaudio_SOURCE_FILES
+@@ -59,6 +64,19 @@
+     endif (LINUX)
+ endif (FMOD)
+ 
++if (OPENAL)
++	list(APPEND llaudio_SOURCE_FILES
++	audioengine_openal.cpp
++	listener_openal.cpp
++	)
++
++	list(APPEND llaudio_HEADER_FILES
++	audioengine_openal.h
++	listener_openal.h
++	)
++  	
++endif (OPENAL)
++
+ set_source_files_properties(${llaudio_HEADER_FILES}
+                             PROPERTIES HEADER_FILE_ONLY TRUE)
+ 
+Index: omvviewer-1.21.0/indra/newview/CMakeLists.txt
+===================================================================
+--- omvviewer-1.21.0.orig/indra/newview/CMakeLists.txt	2008-08-31 09:42:53.000000000 +0100
++++ omvviewer-1.21.0/indra/newview/CMakeLists.txt	2008-09-01 19:34:47.000000000 +0100
+@@ -8,6 +8,7 @@
+ include(DirectX)
+ include(ELFIO)
+ include(FMOD)
++include(OPENAL)
+ include(FindOpenGL)
+ include(LLAudio)
+ include(LLCharacter)
+@@ -56,6 +57,7 @@
+     ${LLXML_INCLUDE_DIRS}
+     ${LSCRIPT_INCLUDE_DIRS}
+     ${LSCRIPT_INCLUDE_DIRS}/lscript_compile
++    ${GSTREAMER_INCLUDE_DIRS}
+     )
+ 
+ set(viewer_SOURCE_FILES
+@@ -1240,6 +1242,11 @@
+ 
+ #list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
+ 
++
++if (OPENAL)
++  set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS -DLL_OPENAL)
++endif (OPENAL)
++
+ if (FMOD)
+   set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS -DLL_FMOD)
+ 
+Index: omvviewer-1.21.0/indra/cmake/OPENAL.cmake
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ omvviewer-1.21.0/indra/cmake/OPENAL.cmake	2008-08-31 13:09:59.000000000 +0100
+@@ -0,0 +1,14 @@
++
++set(OPENAL OFF CACHE BOOL "Enable OpenAL")
++
++
++if (OPENAL)
++	include(FindPkgConfig)
++	pkg_check_modules(OPENAL_LIB REQUIRED openal)
++	pkg_check_modules(FREEAULT_LIB REQUIRED freealut)
++	set(OPENAL_LIBRARIES 
++		openal
++		alut
++	)
++		
++endif (OPENAL)
+Index: omvviewer-1.21.0/indra/newview/llstartup.cpp
+===================================================================
+--- omvviewer-1.21.0.orig/indra/newview/llstartup.cpp	2008-08-31 09:42:53.000000000 +0100
++++ omvviewer-1.21.0/indra/newview/llstartup.cpp	2008-08-31 13:51:14.000000000 +0100
+@@ -17,7 +17,7 @@
+  * 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://secondlifegrid.net/programs/open_source/licensing/flossexception
++ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexceptionOP
+  * 
+  * By copying, modifying or distributing this software, you acknowledge
+  * that you have read and understood your obligations described above,
+@@ -45,6 +45,10 @@
+ # include "audioengine_fmod.h"
+ #endif
+ 
++#ifdef LL_OPENAL
++#include "audioengine_openal.h"
++#endif
++
+ #include "llares.h"
+ #include "llcachename.h"
+ #include "llviewercontrol.h"
+@@ -574,10 +578,14 @@
+ 
+ 		if (FALSE == gSavedSettings.getBOOL("NoAudio"))
+ 		{
++			gAudiop = NULL;
++
+ #ifdef LL_FMOD
+ 			gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
+-#else
+-			gAudiop = NULL;
++#endif
++
++#ifdef LL_OPENAL
++			gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
+ #endif
+ 
+ 			if (gAudiop)
+Index: omvviewer-1.21.0/indra/cmake/LLAudio.cmake
+===================================================================
+--- omvviewer-1.21.0.orig/indra/cmake/LLAudio.cmake	2008-08-31 13:06:37.000000000 +0100
++++ omvviewer-1.21.0/indra/cmake/LLAudio.cmake	2008-08-31 13:07:05.000000000 +0100
+@@ -8,6 +8,7 @@
+ 
+ set(LLAUDIO_LIBRARIES
+     llaudio
++    ${OPENAL_LIBRARIES}
+     ${VORBISENC_LIBRARIES}
+     ${VORBISFILE_LIBRARIES}
+     ${VORBIS_LIBRARIES}
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..8d013a2
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,28 @@
+24_always_test_vectorize.diff
+50_get_cpu_clock_count_for_more_than_just_i386.diff
+55_fix_the_locales.diff
+59_need_llpreprocessor_to_access_endian_macros.diff
+71_use_debian_alternatives_for_www_browser.diff
+75_use_debian-included_fonts.diff
+79_use_debian_channel.diff
+0001_possible_crash_and_leak_llassetstorage.patch.diff
+2543_possible_crash_in_group_voting_propsals.patch.diff
+2683_possible_crash_update_speaker_list.patch.diff
+1857_apr_thread_mutex_nested.patch.diff
+2003_possible_crash_draganddrop.patch.diff
+1294_llworkerthread_when_terminating_program.patch.diff
+0000_keep_statbars_from_overshooting.patch.diff
+dam_flex_2.5.34.diff
+VWR4070-openjpeg_check_number_of_components.diff
+VWR6800_motioncontroller_leak.diff
+VWR5715_text_not_replaced_by_input_with_japanses_im.diff
+VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff
+VWR-1815_top_corner_fix.diff
+0001_possible_crash_in_llviewerpartssim.diff
+VWR-5697_fix_startup_paths.diff
+VWR-8194_clamp_outline_for_broken_nvidia.diff
+openal_1.21.0.diff
+
+VWR-5082_set_bulk_inv_permissions.diff
+use_c_locale_and_dont_spam_me_because_i_am_not_american.patch
+VWR-4981_save_windlight_settings_in_user_rw_area.patch
diff --git a/debian/patches/use_c_locale_and_dont_spam_me_because_i_am_not_american.patch b/debian/patches/use_c_locale_and_dont_spam_me_because_i_am_not_american.patch
new file mode 100644
index 0000000..9466381
--- /dev/null
+++ b/debian/patches/use_c_locale_and_dont_spam_me_because_i_am_not_american.patch
@@ -0,0 +1,16 @@
+Index: omvviewer-1.21.0/indra/llui/llresmgr.cpp
+===================================================================
+--- omvviewer-1.21.0.orig/indra/llui/llresmgr.cpp	2008-09-01 21:49:27.000000000 +0100
++++ omvviewer-1.21.0/indra/llui/llresmgr.cpp	2008-09-01 21:50:52.000000000 +0100
+@@ -446,7 +446,10 @@
+ const std::string LLLocale::USER_LOCALE("en_US.ISO8859-1");
+ const std::string LLLocale::SYSTEM_LOCALE("C");
+ #else // LL_LINUX likes this
+-const std::string LLLocale::USER_LOCALE("en_US.utf8");
++//const std::string LLLocale::USER_LOCALE("en_US.utf8");
++// this is a good chance that I AM NOT AN AMERICAN don't assume that i am and
++// assume i have an american locale installed, C should do for the viewer
++const std::string LLLocale::USER_LOCALE("C");
+ const std::string LLLocale::SYSTEM_LOCALE("C");
+ #endif
+ 

-- 
A client for connecting to 3D metaverses such as Linden Labs Secondlife(tm) and OpenSim grids



More information about the Pkg-games-commits mailing list