[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