aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:04 -0500
committerJacek Antonelli2008-08-15 23:45:04 -0500
commit117e22047c5752352342d64e3fb7ce00a4eb8113 (patch)
treee32de2cfba0dda8705ae528fcd1fbe23ba075685
parentSecond Life viewer sources 1.18.0.6 (diff)
downloadmeta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.zip
meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.tar.gz
meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.tar.bz2
meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.tar.xz
Second Life viewer sources 1.18.1.2
-rw-r--r--linden/doc/contributions.txt23
-rw-r--r--linden/etc/message.xml85
-rw-r--r--linden/indra/SConstruct129
-rw-r--r--linden/indra/indra_complete/indra_complete.sln4
-rw-r--r--linden/indra/indra_complete/indra_complete_vc8.sln2
-rw-r--r--linden/indra/lib/python/indra/__init__.py12
-rw-r--r--linden/indra/lib/python/indra/ipc/__init__.py27
-rw-r--r--linden/indra/lib/python/indra/ipc/compatibility.py (renamed from linden/indra/lib/python/indra/compatibility.py)12
-rw-r--r--linden/indra/lib/python/indra/ipc/llmessage.py (renamed from linden/indra/lib/python/indra/llmessage.py)16
-rw-r--r--linden/indra/lib/python/indra/ipc/tokenstream.py (renamed from linden/indra/lib/python/indra/tokenstream.py)12
-rw-r--r--linden/indra/lib/python/indra/util/__init__.py27
-rw-r--r--linden/indra/lib/python/indra/util/llmanifest.py (renamed from linden/indra/lib/python/indra/llmanifest.py)14
-rw-r--r--linden/indra/linux_crash_logger/linux_crash_logger.cpp10
-rw-r--r--linden/indra/llaudio/audioengine.cpp2
-rw-r--r--linden/indra/llcharacter/lljoint.cpp33
-rw-r--r--linden/indra/llcharacter/lljoint.h5
-rw-r--r--linden/indra/llcharacter/llmotion.cpp11
-rw-r--r--linden/indra/llcharacter/llmotion.h8
-rw-r--r--linden/indra/llcharacter/llmotioncontroller.cpp157
-rw-r--r--linden/indra/llcharacter/llmotioncontroller.h15
-rw-r--r--linden/indra/llcharacter/llpose.cpp20
-rw-r--r--linden/indra/llcharacter/llpose.h2
-rw-r--r--linden/indra/llcommon/indra_constants.h10
-rw-r--r--linden/indra/llcommon/llapr.h2
-rw-r--r--linden/indra/llcommon/llcommon.vcproj3
-rw-r--r--linden/indra/llcommon/lldate.cpp48
-rw-r--r--linden/indra/llcommon/lldate.h6
-rw-r--r--linden/indra/llcommon/llfasttimer.cpp8
-rw-r--r--linden/indra/llcommon/llfixedbuffer.cpp2
-rw-r--r--linden/indra/llcommon/llhash.h4
-rw-r--r--linden/indra/llcommon/llmemory.cpp5
-rw-r--r--linden/indra/llcommon/llmemtype.h2
-rw-r--r--linden/indra/llcommon/llpagemem.h393
-rw-r--r--linden/indra/llcommon/llpreprocessor.h27
-rw-r--r--linden/indra/llcommon/llprocessor.cpp184
-rw-r--r--linden/indra/llcommon/llprocessor.h15
-rw-r--r--linden/indra/llcommon/llsdserialize_xml.cpp6
-rw-r--r--linden/indra/llcommon/llsdutil.cpp2
-rw-r--r--linden/indra/llcommon/llskiplist.h12
-rw-r--r--linden/indra/llcommon/llstring.h10
-rw-r--r--linden/indra/llcommon/llsys.cpp204
-rw-r--r--linden/indra/llcommon/llsys.h13
-rw-r--r--linden/indra/llcommon/llthread.cpp4
-rw-r--r--linden/indra/llcommon/lltimer.cpp14
-rw-r--r--linden/indra/llcommon/lltimer.h2
-rw-r--r--linden/indra/llcommon/lluri.cpp35
-rw-r--r--linden/indra/llcommon/lluri.h97
-rw-r--r--linden/indra/llcommon/llversion.h4
-rw-r--r--linden/indra/llcommon/llworkerthread.cpp2
-rw-r--r--linden/indra/llcommon/stdtypes.h22
-rw-r--r--linden/indra/llcommon/timing.h2
-rw-r--r--linden/indra/llimage/llimagejpeg.h9
-rw-r--r--linden/indra/llinventory/llinventory.cpp12
-rw-r--r--linden/indra/llinventory/llpermissions.cpp6
-rw-r--r--linden/indra/llinventory/llsaleinfo.cpp6
-rw-r--r--linden/indra/llmath/llcrc.cpp19
-rw-r--r--linden/indra/llmath/llcrc.h2
-rw-r--r--linden/indra/llmath/llmath.h3
-rw-r--r--linden/indra/llmath/llmath.vcproj12
-rw-r--r--linden/indra/llmath/llmath_vc8.vcproj16
-rw-r--r--linden/indra/llmath/llmd5.cpp111
-rw-r--r--linden/indra/llmath/llmd5.h17
-rw-r--r--linden/indra/llmath/lloctree.h68
-rw-r--r--linden/indra/llmath/llrect.h47
-rw-r--r--linden/indra/llmath/lltreenode.h22
-rw-r--r--linden/indra/llmath/lluuid.cpp4
-rw-r--r--linden/indra/llmath/llv4math.h143
-rw-r--r--linden/indra/llmath/llv4matrix3.h222
-rw-r--r--linden/indra/llmath/llv4matrix4.h251
-rw-r--r--linden/indra/llmath/llv4vector3.h82
-rw-r--r--linden/indra/llmath/llvolume.cpp18
-rw-r--r--linden/indra/llmath/llvolume.h2
-rw-r--r--linden/indra/llmedia/files.lst3
-rw-r--r--linden/indra/llmedia/llmedia_vc8.vcproj594
-rw-r--r--linden/indra/llmedia/llmediabase.cpp8
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer.cpp715
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer.h126
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms.cpp189
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms.h75
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc42
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc5
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc5
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamervidplug.cpp461
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamervidplug.h101
-rw-r--r--linden/indra/llmedia/llmediamoviebase.cpp8
-rw-r--r--linden/indra/llmessage/llcurl.cpp2
-rw-r--r--linden/indra/llmessage/lldatapacker.cpp5
-rw-r--r--linden/indra/llmessage/llhttpassetstorage.cpp6
-rw-r--r--linden/indra/llmessage/llhttpclient.cpp40
-rw-r--r--linden/indra/llmessage/llhttpclient.h2
-rw-r--r--linden/indra/llmessage/lliohttpserver.cpp37
-rw-r--r--linden/indra/llmessage/llmessageconfig.cpp16
-rw-r--r--linden/indra/llmessage/llmessageconfig.h2
-rw-r--r--linden/indra/llmessage/llmessagereader.cpp3
-rw-r--r--linden/indra/llmessage/llmessagetemplateparser.cpp1
-rw-r--r--linden/indra/llmessage/llnamevalue.cpp3
-rw-r--r--linden/indra/llmessage/llnamevalue.h1
-rw-r--r--linden/indra/llmessage/llservicebuilder.cpp19
-rw-r--r--linden/indra/llmessage/lltemplatemessagereader.cpp11
-rw-r--r--linden/indra/llmessage/lluseroperation.cpp21
-rw-r--r--linden/indra/llmessage/lluseroperation.h4
-rw-r--r--linden/indra/llmessage/llxfer_file.cpp6
-rw-r--r--linden/indra/llmessage/message.cpp1
-rw-r--r--linden/indra/llmessage/message.h103
-rw-r--r--linden/indra/llrender/llfont.cpp37
-rw-r--r--linden/indra/llrender/llimagegl.cpp3
-rw-r--r--linden/indra/llrender/llimagegl.h1
-rw-r--r--linden/indra/llui/files.lst1
-rw-r--r--linden/indra/llui/llbutton.cpp28
-rw-r--r--linden/indra/llui/llbutton.h7
-rw-r--r--linden/indra/llui/llcheckboxctrl.cpp12
-rw-r--r--linden/indra/llui/llcheckboxctrl.h2
-rw-r--r--linden/indra/llui/llctrlselectioninterface.h3
-rw-r--r--linden/indra/llui/llfloater.cpp286
-rw-r--r--linden/indra/llui/llfloater.h14
-rw-r--r--linden/indra/llui/llfocusmgr.cpp9
-rw-r--r--linden/indra/llui/llfocusmgr.h1
-rw-r--r--linden/indra/llui/lllineeditor.h1
-rw-r--r--linden/indra/llui/llmenugl.cpp52
-rw-r--r--linden/indra/llui/llpanel.cpp659
-rw-r--r--linden/indra/llui/llpanel.h58
-rw-r--r--linden/indra/llui/llradiogroup.cpp66
-rw-r--r--linden/indra/llui/llradiogroup.h21
-rw-r--r--linden/indra/llui/llresizebar.cpp86
-rw-r--r--linden/indra/llui/llresizebar.h11
-rw-r--r--linden/indra/llui/llresmgr.cpp3
-rw-r--r--linden/indra/llui/llscrollcontainer.cpp3
-rw-r--r--linden/indra/llui/llscrolllistctrl.cpp55
-rw-r--r--linden/indra/llui/llscrolllistctrl.h1
-rw-r--r--linden/indra/llui/llslider.cpp158
-rw-r--r--linden/indra/llui/llslider.h6
-rw-r--r--linden/indra/llui/llsliderctrl.cpp10
-rw-r--r--linden/indra/llui/llsliderctrl.h4
-rw-r--r--linden/indra/llui/lltabcontainer.cpp114
-rw-r--r--linden/indra/llui/lltabcontainer.h11
-rw-r--r--linden/indra/llui/lltabcontainervertical.cpp74
-rw-r--r--linden/indra/llui/lltexteditor.cpp51
-rw-r--r--linden/indra/llui/lltexteditor.h4
-rw-r--r--linden/indra/llui/llui.cpp60
-rw-r--r--linden/indra/llui/llui.h57
-rw-r--r--linden/indra/llui/lluictrl.cpp2
-rw-r--r--linden/indra/llui/lluictrl.h3
-rw-r--r--linden/indra/llui/lluictrlfactory.cpp36
-rw-r--r--linden/indra/llui/lluictrlfactory.h8
-rw-r--r--linden/indra/llui/lluistring.cpp3
-rw-r--r--linden/indra/llui/lluistring.h2
-rw-r--r--linden/indra/llui/lluixmltags.h1
-rw-r--r--linden/indra/llui/llview.cpp125
-rw-r--r--linden/indra/llui/llview.h2
-rw-r--r--linden/indra/llvfs/files.sunos5.lst1
-rw-r--r--linden/indra/llvfs/lldir.cpp3
-rw-r--r--linden/indra/llvfs/lldir_linux.cpp17
-rw-r--r--linden/indra/llvfs/lldir_solaris.cpp374
-rw-r--r--linden/indra/llvfs/lldir_solaris.h61
-rw-r--r--linden/indra/llvfs/llvfs.cpp90
-rw-r--r--linden/indra/llwindow/files.sunos5.lst4
-rw-r--r--linden/indra/llwindow/files.win32.lst2
-rw-r--r--linden/indra/llwindow/llglstubs.h2
-rw-r--r--linden/indra/llwindow/llwindowsdl.cpp46
-rw-r--r--linden/indra/llwindow/llwindowsolaris.cpp58
-rw-r--r--linden/indra/llwindow/llwindowsolaris.h116
-rw-r--r--linden/indra/llwindow/llwindowwin32.cpp12
-rw-r--r--linden/indra/llxml/llxmlnode.cpp11
-rw-r--r--linden/indra/llxml/llxmlnode.h4
-rw-r--r--linden/indra/llxml/llxmlparser.h4
-rw-r--r--linden/indra/lscript/lscript_compile/indra.l9
-rw-r--r--linden/indra/lscript/lscript_compile/indra.y4
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_bytecode.cpp5
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_execute.cpp14
-rw-r--r--linden/indra/lscript/lscript_execute/lscript_readlso.cpp14
-rw-r--r--linden/indra/mac_updater/mac_updater.cpp9
-rw-r--r--linden/indra/newview/English.lproj/InfoPlist.strings4
-rw-r--r--linden/indra/newview/Info-SecondLife.plist2
-rw-r--r--linden/indra/newview/fakevoicesoundsignal.cpp49
-rw-r--r--linden/indra/newview/fakevoicesoundsignal.h25
-rw-r--r--linden/indra/newview/featuretable_solaris.txt173
-rw-r--r--linden/indra/newview/files.lst13
-rw-r--r--linden/indra/newview/licenses-solaris.txt516
-rw-r--r--linden/indra/newview/linux_tools/client-readme.txt29
l---------linden/indra/newview/linux_tools/unicode.ttf2
-rwxr-xr-xlinden/indra/newview/linux_tools/wrapper.sh17
-rw-r--r--linden/indra/newview/llagent.cpp62
-rw-r--r--linden/indra/newview/llagent.h2
-rw-r--r--linden/indra/newview/llaudiosourcevo.cpp2
-rw-r--r--linden/indra/newview/llaudiostatus.cpp412
-rw-r--r--linden/indra/newview/llcallingcard.cpp1
-rw-r--r--linden/indra/newview/llchatbar.cpp155
-rw-r--r--linden/indra/newview/llchatbar.h21
-rw-r--r--linden/indra/newview/llcolorswatch.cpp15
-rw-r--r--linden/indra/newview/llcolorswatch.h2
-rw-r--r--linden/indra/newview/llcontroldef.cpp604
-rw-r--r--linden/indra/newview/lldebugmessagebox.cpp10
-rw-r--r--linden/indra/newview/lldebugview.cpp14
-rw-r--r--linden/indra/newview/lldrawable.h1
-rw-r--r--linden/indra/newview/lldrawpoolsky.h2
-rw-r--r--linden/indra/newview/lldrawpoolwater.cpp2
-rw-r--r--linden/indra/newview/llemote.h2
-rw-r--r--linden/indra/newview/llface.h1
-rw-r--r--linden/indra/newview/llfasttimerview.cpp3
-rw-r--r--linden/indra/newview/llfeaturemanager.cpp7
-rw-r--r--linden/indra/newview/llfirstuse.cpp13
-rw-r--r--linden/indra/newview/llfirstuse.h1
-rw-r--r--linden/indra/newview/llfloateractivespeakers.cpp831
-rw-r--r--linden/indra/newview/llfloateractivespeakers.h211
-rw-r--r--linden/indra/newview/llfloateranimpreview.cpp2
-rw-r--r--linden/indra/newview/llfloateravatarpicker.cpp7
-rw-r--r--linden/indra/newview/llfloaterchat.cpp213
-rw-r--r--linden/indra/newview/llfloaterchat.h25
-rw-r--r--linden/indra/newview/llfloaterchatterbox.cpp342
-rw-r--r--linden/indra/newview/llfloaterchatterbox.h87
-rw-r--r--linden/indra/newview/llfloatercustomize.cpp28
-rw-r--r--linden/indra/newview/llfloaterdirectory.cpp14
-rw-r--r--linden/indra/newview/llfloaterfriends.cpp395
-rw-r--r--linden/indra/newview/llfloaterfriends.h26
-rw-r--r--linden/indra/newview/llfloatergroups.cpp477
-rw-r--r--linden/indra/newview/llfloatergroups.h79
-rw-r--r--linden/indra/newview/llfloaterhtmlhelp.cpp2
-rw-r--r--linden/indra/newview/llfloaterimport.cpp5
-rw-r--r--linden/indra/newview/llfloaterinspect.cpp19
-rw-r--r--linden/indra/newview/llfloaterland.cpp73
-rw-r--r--linden/indra/newview/llfloaterland.h2
-rw-r--r--linden/indra/newview/llfloatermute.cpp1
-rw-r--r--linden/indra/newview/llfloaternamedesc.cpp4
-rw-r--r--linden/indra/newview/llfloaternewim.cpp8
-rw-r--r--linden/indra/newview/llfloaterpostcard.cpp2
-rw-r--r--linden/indra/newview/llfloaterpreference.cpp10
-rw-r--r--linden/indra/newview/llfloaterpreference.h2
-rw-r--r--linden/indra/newview/llfloaterregioninfo.cpp26
-rw-r--r--linden/indra/newview/llfloaterscriptdebug.cpp11
-rw-r--r--linden/indra/newview/llfloatersnapshot.cpp22
-rw-r--r--linden/indra/newview/llfloatertest.cpp7
-rw-r--r--linden/indra/newview/llfloatertest.h8
-rw-r--r--linden/indra/newview/llfloatertools.cpp11
-rw-r--r--linden/indra/newview/llfloatertools.h2
-rw-r--r--linden/indra/newview/llfloatervoicewizard.cpp444
-rw-r--r--linden/indra/newview/llfloatervoicewizard.h100
-rw-r--r--linden/indra/newview/llfloaterworldmap.cpp75
-rw-r--r--linden/indra/newview/llfloaterworldmap.h1
-rw-r--r--linden/indra/newview/llfolderview.cpp79
-rw-r--r--linden/indra/newview/llframestatview.cpp6
-rw-r--r--linden/indra/newview/llgesturemgr.cpp68
-rw-r--r--linden/indra/newview/llgesturemgr.h2
-rw-r--r--linden/indra/newview/llglslshader.cpp21
-rw-r--r--linden/indra/newview/llhoverview.cpp7
-rw-r--r--linden/indra/newview/llhudeffectlookat.cpp63
-rw-r--r--linden/indra/newview/llhudmanager.cpp101
-rw-r--r--linden/indra/newview/llhudmanager.h10
-rw-r--r--linden/indra/newview/llhudobject.cpp4
-rw-r--r--linden/indra/newview/llhudobject.h3
-rw-r--r--linden/indra/newview/llhudtext.cpp3
-rw-r--r--linden/indra/newview/llimpanel.cpp1020
-rw-r--r--linden/indra/newview/llimpanel.h155
-rw-r--r--linden/indra/newview/llimview.cpp823
-rw-r--r--linden/indra/newview/llimview.h57
-rw-r--r--linden/indra/newview/llinventoryactions.cpp4
-rw-r--r--linden/indra/newview/llinventorybridge.cpp9
-rw-r--r--linden/indra/newview/llinventorymodel.cpp9
-rw-r--r--linden/indra/newview/llinventoryview.cpp12
-rw-r--r--linden/indra/newview/llmediaremotectrl.cpp167
-rw-r--r--linden/indra/newview/llmediaremotectrl.h92
-rw-r--r--linden/indra/newview/llmemoryview.cpp53
-rw-r--r--linden/indra/newview/llmemoryview.h7
-rw-r--r--linden/indra/newview/llmutelist.cpp124
-rw-r--r--linden/indra/newview/llmutelist.h32
-rw-r--r--linden/indra/newview/llnetmap.cpp2
-rw-r--r--linden/indra/newview/llnotify.cpp215
-rw-r--r--linden/indra/newview/llnotify.h60
-rw-r--r--linden/indra/newview/lloverlaybar.cpp453
-rw-r--r--linden/indra/newview/lloverlaybar.h45
-rw-r--r--linden/indra/newview/llpanelaudioprefs.cpp142
-rw-r--r--linden/indra/newview/llpanelaudioprefs.h15
-rw-r--r--linden/indra/newview/llpanelaudiovolume.cpp109
-rw-r--r--linden/indra/newview/llpanelaudiovolume.h (renamed from linden/indra/newview/llaudiostatus.h)37
-rw-r--r--linden/indra/newview/llpanelavatar.cpp36
-rw-r--r--linden/indra/newview/llpanelavatar.h18
-rw-r--r--linden/indra/newview/llpanelclassified.cpp21
-rw-r--r--linden/indra/newview/llpanelclassified.h25
-rw-r--r--linden/indra/newview/llpaneldebug.cpp2
-rw-r--r--linden/indra/newview/llpaneldirbrowser.cpp5
-rw-r--r--linden/indra/newview/llpaneldisplay.cpp1
-rw-r--r--linden/indra/newview/llpanelgeneral.cpp2
-rw-r--r--linden/indra/newview/llpanelgroup.cpp11
-rw-r--r--linden/indra/newview/llpanelinventory.cpp2
-rw-r--r--linden/indra/newview/llpanellogin.cpp32
-rw-r--r--linden/indra/newview/llpanellogin.h1
-rw-r--r--linden/indra/newview/llpanelpermissions.cpp16
-rw-r--r--linden/indra/newview/llpolymesh.cpp5
-rw-r--r--linden/indra/newview/llprefschat.cpp13
-rw-r--r--linden/indra/newview/llprefsvoice.cpp277
-rw-r--r--linden/indra/newview/llprefsvoice.h87
-rw-r--r--linden/indra/newview/llpreview.cpp3
-rw-r--r--linden/indra/newview/llpreviewscript.cpp32
-rw-r--r--linden/indra/newview/llpreviewsound.cpp15
-rw-r--r--linden/indra/newview/llpreviewtexture.cpp2
-rw-r--r--linden/indra/newview/llselectmgr.cpp40
-rw-r--r--linden/indra/newview/llselectmgr.h5
-rw-r--r--linden/indra/newview/llstartup.cpp128
-rw-r--r--linden/indra/newview/llstatusbar.cpp110
-rw-r--r--linden/indra/newview/llstatusbar.h25
-rw-r--r--linden/indra/newview/lltoolbar.cpp35
-rw-r--r--linden/indra/newview/lltoolbar.h3
-rw-r--r--linden/indra/newview/lltooldraganddrop.cpp2
-rw-r--r--linden/indra/newview/lltoolselect.cpp2
-rw-r--r--linden/indra/newview/lluserauth.cpp2
-rw-r--r--linden/indra/newview/llviewercontrol.h2
-rw-r--r--linden/indra/newview/llviewerimage.h22
-rw-r--r--linden/indra/newview/llviewerimagelist.cpp17
-rw-r--r--linden/indra/newview/llviewerinventory.cpp6
-rw-r--r--linden/indra/newview/llviewerjointattachment.cpp17
-rw-r--r--linden/indra/newview/llviewerjointmesh.cpp215
-rw-r--r--linden/indra/newview/llviewerjointmesh.h16
-rw-r--r--linden/indra/newview/llviewerjointmesh_sse.cpp114
-rw-r--r--linden/indra/newview/llviewerjointmesh_sse2.cpp121
-rw-r--r--linden/indra/newview/llviewerjointmesh_vec.cpp95
-rw-r--r--linden/indra/newview/llviewermenu.cpp168
-rw-r--r--linden/indra/newview/llviewermenufile.cpp16
-rw-r--r--linden/indra/newview/llviewermessage.cpp98
-rw-r--r--linden/indra/newview/llviewerobject.cpp23
-rw-r--r--linden/indra/newview/llviewerobject.h5
-rw-r--r--linden/indra/newview/llviewerobjectlist.cpp6
-rw-r--r--linden/indra/newview/llviewerparcelmgr.cpp19
-rw-r--r--linden/indra/newview/llviewerpartsim.cpp2
-rw-r--r--linden/indra/newview/llviewerpartsource.cpp6
-rw-r--r--linden/indra/newview/llviewerprecompiledheaders.h2
-rw-r--r--linden/indra/newview/llviewerregion.cpp148
-rw-r--r--linden/indra/newview/llviewerregion.h16
-rw-r--r--linden/indra/newview/llviewertexteditor.cpp17
-rw-r--r--linden/indra/newview/llvieweruictrlfactory.cpp7
-rw-r--r--linden/indra/newview/llvieweruictrlfactory.h2
-rw-r--r--linden/indra/newview/llviewerwindow.cpp338
-rw-r--r--linden/indra/newview/llviewerwindow.h5
-rw-r--r--linden/indra/newview/llvoavatar.cpp318
-rw-r--r--linden/indra/newview/llvoavatar.h16
-rw-r--r--linden/indra/newview/llvocache.cpp45
-rw-r--r--linden/indra/newview/llvograss.cpp8
-rw-r--r--linden/indra/newview/llvoiceclient.cpp4076
-rw-r--r--linden/indra/newview/llvoiceclient.h523
-rw-r--r--linden/indra/newview/llvoiceremotectrl.cpp180
-rw-r--r--linden/indra/newview/llvoiceremotectrl.h (renamed from linden/indra/newview/llvolumesliderctrl.h)42
-rw-r--r--linden/indra/newview/llvoicevisualizer.cpp431
-rw-r--r--linden/indra/newview/llvoicevisualizer.h111
-rw-r--r--linden/indra/newview/llvolumesliderctrl.cpp193
-rw-r--r--linden/indra/newview/llvopartgroup.cpp2
-rw-r--r--linden/indra/newview/llvosky.cpp8
-rw-r--r--linden/indra/newview/llvotree.cpp4
-rw-r--r--linden/indra/newview/llvovolume.cpp4
-rw-r--r--linden/indra/newview/llweb.cpp2
-rw-r--r--linden/indra/newview/llwebbrowserctrl.cpp4
-rw-r--r--linden/indra/newview/llworldmap.cpp11
-rw-r--r--linden/indra/newview/llworldmap.h4
-rw-r--r--linden/indra/newview/llworldmapview.cpp3
-rw-r--r--linden/indra/newview/llxmlrpctransaction.cpp2
-rw-r--r--linden/indra/newview/macview.xcodeproj/project.pbxproj238
-rw-r--r--linden/indra/newview/moviemaker.cpp10
-rw-r--r--linden/indra/newview/newview.vcproj210
-rw-r--r--linden/indra/newview/newview_vc8.vcproj208
-rw-r--r--linden/indra/newview/pipeline.cpp265
-rw-r--r--linden/indra/newview/pipeline.h27
-rw-r--r--linden/indra/newview/postbuild.bat52
-rw-r--r--linden/indra/newview/releasenotes.txt80
-rw-r--r--linden/indra/newview/res/newViewRes.rc8
-rw-r--r--linden/indra/newview/secondlife setup build voicebeta.bat4
-rw-r--r--linden/indra/newview/secondlife setup build voicefirstlook.bat (renamed from linden/indra/newview/secondlife setup build firstlook.bat)2
-rw-r--r--linden/indra/newview/skins/textures/textures.xml22
-rw-r--r--linden/indra/newview/skins/xui/de/role_actions.xml82
-rw-r--r--linden/indra/newview/skins/xui/en-us/alerts.xml59
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_about.xml5
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_about_land.xml78
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_active_speakers.xml72
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_audio_volume.xml11
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_buy_contents.xml2
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_chat_history.xml134
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_chatterbox.xml6
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_device_settings.xml4
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_friends.xml225
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_groups.xml80
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_im.xml39
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_instant_message.xml57
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_instant_message_ad_hoc.xml119
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_instant_message_group.xml160
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_inventory_item_properties.xml4
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_my_friends.xml9
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_report_bug.xml4
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_select_key.xml15
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_settings_debug.xml7
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_test.xml5
-rw-r--r--linden/indra/newview/skins/xui/en-us/floater_voice_wizard.xml17
-rw-r--r--linden/indra/newview/skins/xui/en-us/menu_inventory.xml16
-rw-r--r--linden/indra/newview/skins/xui/en-us/menu_viewer.xml70
-rw-r--r--linden/indra/newview/skins/xui/en-us/notify.xml93
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_audio.xml39
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_audio_device.xml77
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_friends.xml62
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_group_roles.xml2
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_groups.xml43
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_master_volume.xml13
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_media_remote.xml27
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_music_remote.xml27
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_overlaybar.xml17
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_preferences_audio.xml155
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_preferences_chat.xml2
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_preferences_graphics3.xml2
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_preferences_voice.xml89
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_region_estate.xml7
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_status_bar.xml8
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_toolbar.xml7
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_voice_enable.xml98
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_voice_options.xml46
-rw-r--r--linden/indra/newview/skins/xui/en-us/panel_voice_remote.xml12
-rw-r--r--linden/indra/newview/skins/xui/es/role_actions.xml372
-rw-r--r--linden/indra/newview/skins/xui/fr/role_actions.xml378
-rw-r--r--linden/indra/newview/skins/xui/ja/role_actions.xml84
-rw-r--r--linden/indra/newview/skins/xui/ko/role_actions.xml84
-rw-r--r--linden/indra/newview/skins/xui/pt/role_actions.xml372
-rw-r--r--linden/indra/newview/skins/xui/zh/role_actions.xml366
-rw-r--r--linden/indra/newview/viewer.cpp944
-rw-r--r--linden/indra/newview/viewer.h7
-rwxr-xr-xlinden/indra/newview/viewer_manifest.py197
-rw-r--r--linden/indra/test/files.lst1
-rw-r--r--linden/indra/test/llbuffer_tut.cpp2
-rw-r--r--linden/indra/test/llhttpdate_tut.cpp92
-rw-r--r--linden/indra/test/llmessagetemplateparser_tut.cpp1
-rw-r--r--linden/indra/test/llpermissions_tut.cpp1
-rwxr-xr-xlinden/indra/test/llsdmessagereader_tut.cpp1
-rw-r--r--linden/indra/test/llservicebuilder_tut.cpp17
-rw-r--r--linden/indra/test/lltemplatemessagebuilder_tut.cpp1
-rw-r--r--linden/indra/test/lluri_tut.cpp12
-rw-r--r--linden/indra/test/message_tut.cpp1
-rw-r--r--linden/indra/test/test_llmanifest.py2
-rw-r--r--linden/indra/win_crash_logger/resource.h28
-rw-r--r--linden/indra/win_crash_logger/win_crash_logger.rc10
-rwxr-xr-xlinden/scripts/template_verifier.py159
432 files changed, 25174 insertions, 7843 deletions
diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt
index 4546053..26f37a4 100644
--- a/linden/doc/contributions.txt
+++ b/linden/doc/contributions.txt
@@ -4,22 +4,27 @@ along with the issue identifier corresponding to the patches we've
4received from them. To see more about these contributions, visit 4received from them. To see more about these contributions, visit
5http://jira.secondlife.com/ and enter the issue identifier. 5http://jira.secondlife.com/ and enter the issue identifier.
6 6
7Able Whitman - VWR-650 7Able Whitman - VWR-650, VWR-1460
8Alissa Sabre - VWR-81, VWR-83, VWR-171, VWR-251, VWR-414, VWR-415, VWR-459, VWR-606, VWR-652, VWR-1351, VWR-1410 8Alissa Sabre - VWR-81, VWR-83, VWR-171, VWR-251, VWR-414, VWR-415, VWR-459, VWR-606, VWR-652, VWR-1351, VWR-1410
9Argent Stonecutter - VWR-68 9Argent Stonecutter - VWR-68
10Benja Kepler - VWR-746 10Benja Kepler - VWR-746
11Blakar Ogre - VWR-881 11Blakar Ogre - VWR-881
12blino Nakamura - VWR-17 12blino Nakamura - VWR-17
13bushing Spatula - VWR-424, VWR-119 13bushing Spatula - VWR-424, VWR-119
14Catherine Pfeffer - VWR-1282
14Dale Glass - VWR-120, VWR-560 15Dale Glass - VWR-120, VWR-560
15Drewan Keats - VWR-28, VWR-248, VWR-412 16Drewan Keats - VWR-28, VWR-248, VWR-412
16Duckless Vandyke - VWR-383 17Duckless Vandyke - VWR-383
17Dylan Haskell - VWR-72 18Dylan Haskell - VWR-72
18Dzonatas Sol - VWR-198, VWR-878 19Dzonatas Sol - VWR-198, VWR-878, VWR-1704, VWR-1705, VWR-1729, VWR-975
19Eddy Stryker - VWR-15, VWR-23 20Eddy Stryker - VWR-15, VWR-23, VWR-1468
21EponymousDylan Ra - VWR-1465
22Fee Larsson - VWR-1314
20Fremont Cunningham - VWR-1147 23Fremont Cunningham - VWR-1147
21Gigs Taggart - VWR-71, VWR-326, VWR-1217 24Gigs Taggart - VWR-71, VWR-326, VWR-1217, VWR-1434
22Ginko Bayliss - VWR-4 25Ginko Bayliss - VWR-4
26Grazer Kline - VWR-1092
27Gudmund Shepherd - VWR-1594
23Hikkoshi Sakai - VWR-429 28Hikkoshi Sakai - VWR-429
24Hiro Sommambulist - VWR-66, VWR-97, VWR-100, VWR-105, VWR-108, VWR-118, VWR-132, VWR-136, VWR-143 29Hiro Sommambulist - VWR-66, VWR-97, VWR-100, VWR-105, VWR-108, VWR-118, VWR-132, VWR-136, VWR-143
25Iskar Ariantho - VWR-1223 30Iskar Ariantho - VWR-1223
@@ -27,20 +32,22 @@ Jacek Antonelli - VWR-165, VWR-188, VWR-427, VWR-597
27Joghert LeSabre - VWR-64 32Joghert LeSabre - VWR-64
28Kage Pixel - VWR-11 33Kage Pixel - VWR-11
29Kunnis Basiat - VWR-82 34Kunnis Basiat - VWR-82
30Nicholaz Beresford - VWR-132, VWR-176, VWR-793, VWR-794, VWR-802, VWR-803, VWR-804, VWR-805, VWR-808, VWR-809, VWR-810, VWR-823, VWR-869, VWR-870, VWR-871, VWR-873, VWR-908, VWR-966, VWR-1410, VWR-1418 35McCabe Maxsted - VWR-1318
36Nicholaz Beresford - VWR-132, VWR-176, VWR-364, VWR-691, VWR-793, VWR-794, VWR-802, VWR-803, VWR-804, VWR-805, VWR-808, VWR-809, VWR-810, VWR-823, VWR-856, VWR-869, VWR-870, VWR-871, VWR-873, VWR-908, VWR-966, VWR-1221, VWR-1270, VWR-1296, VWR-1410, VWR-1418, VWR-1453, VWR-1455, VWR-1470, VWR-1578, VWR-1626, VWR-1655, VWR-1698, VWR-1706, VWR-1723, VWR-1732, VWR-1861
31Paul Churchill - VWR-20 37Paul Churchill - VWR-20
32Paula Innis - VWR-30, VWR-1049 38Paula Innis - VWR-30, VWR-1049
33Peekay Semyorka - VWR-7, VWR-19, VWR-49, VWR-79 39Peekay Semyorka - VWR-7, VWR-19, VWR-49, VWR-79
34Ryozu Kojima - VWR-287 40Ryozu Kojima - VWR-287
35SignpostMarv Martin - VWR-154, VWR-155 41SignpostMarv Martin - VWR-154, VWR-155
36Simon Nolan - VWR-409 42Simon Nolan - VWR-409
37SpacedOut Frye - VWR-57, VWR-94, VWR-121, VWR-123 43SpacedOut Frye - VWR-57, VWR-94, VWR-121, VWR-123, VWR-1823
38Stevex Janus - VWR-1182 44Stevex Janus - VWR-1182
39Still Defiant - VWR-207, VWR-446 45Still Defiant - VWR-207, VWR-446
40Strife Onizuka - SVC-9, VWR-74, VWR-85, VWR-148 46Strife Onizuka - SVC-9, VWR-74, VWR-85, VWR-148
41tenebrous pau - VWR-247 47tenebrous pau - VWR-247
42TBBle Kurosawa - VWR-938, VWR-941, VWR-944 48TBBle Kurosawa - VWR-938, VWR-941, VWR-944, VWR-945
43Tharax Ferraris - VWR-605 49Tharax Ferraris - VWR-605
50Thraxis Epsilon - VWR-383, SVC-371
51Whoops Babii - VWR-1640
44Zi Ree - VWR-671, VWR-682, VWR-1140 52Zi Ree - VWR-671, VWR-682, VWR-1140
45Zipherius Turas - VWR-76, VWR-77 53Zipherius Turas - VWR-76, VWR-77
46
diff --git a/linden/etc/message.xml b/linden/etc/message.xml
index ad2364a..304ba32 100644
--- a/linden/etc/message.xml
+++ b/linden/etc/message.xml
@@ -243,7 +243,6 @@
243 <key>trusted-sender</key> 243 <key>trusted-sender</key>
244 <boolean>false</boolean> 244 <boolean>false</boolean>
245 </map> 245 </map>
246
247 <!-- Simulator to simulator unreliable messages --> 246 <!-- Simulator to simulator unreliable messages -->
248 <key>EdgeDataPacket</key> 247 <key>EdgeDataPacket</key>
249 <map> 248 <map>
@@ -301,7 +300,7 @@
301 <boolean>true</boolean> 300 <boolean>true</boolean>
302 </map> 301 </map>
303 302
304 <key>ChatterBoxSessionLeaveReply</key> 303 <key>ChatterBoxSessionAgentListUpdates</key>
305 <map> 304 <map>
306 <key>flavor</key> 305 <key>flavor</key>
307 <string>llsd</string> 306 <string>llsd</string>
@@ -309,7 +308,7 @@
309 <boolean>true</boolean> 308 <boolean>true</boolean>
310 </map> 309 </map>
311 310
312 <key>ChatterBoxSessionAgentListUpdates</key> 311 <key>ChatterBoxInvitation</key>
313 <map> 312 <map>
314 <key>flavor</key> 313 <key>flavor</key>
315 <string>llsd</string> 314 <string>llsd</string>
@@ -317,13 +316,82 @@
317 <boolean>true</boolean> 316 <boolean>true</boolean>
318 </map> 317 </map>
319 318
320 <key>ChatterBoxInvitation</key> 319 <!-- Client to server -->
320 <key>ParcelVoiceInfoRequest</key>
321 <map>
322 <key>flavor</key>
323 <string>llsd</string>
324 <key>trusted-sender</key>
325 <boolean>false</boolean>
326 </map>
327
328 <!-- Server to client -->
329 <key>ParcelVoiceInfo</key>
321 <map> 330 <map>
322 <key>flavor</key> 331 <key>flavor</key>
323 <string>llsd</string> 332 <string>llsd</string>
324 <key>trusted-sender</key> 333 <key>trusted-sender</key>
325 <boolean>true</boolean> 334 <boolean>true</boolean>
326 </map> 335 </map>
336
337 <key>avatarnotesrequest</key>
338 <map>
339 <key>service_name</key>
340 <string>avatar-notes</string>
341 <key>builder</key>
342 <string>template</string>
343 <key>trusted-sender</key>
344 <boolean>false</boolean>
345 </map>
346
347 <key>avatarclassifiedsrequest</key>
348 <map>
349 <key>service_name</key>
350 <string>avatar-classifieds</string>
351 <key>builder</key>
352 <string>template</string>
353 <key>trusted-sender</key>
354 <boolean>false</boolean>
355 </map>
356
357 <key>avatarpickrequest</key>
358 <map>
359 <key>service_name</key>
360 <string>avatar-pick</string>
361 <key>builder</key>
362 <string>template</string>
363 <key>trusted-sender</key>
364 <boolean>false</boolean>
365 </map>
366
367 <key>pickinforequest</key>
368 <map>
369 <key>service_name</key>
370 <string>pick-info</string>
371 <key>builder</key>
372 <string>template</string>
373 <key>trusted-sender</key>
374 <boolean>false</boolean>
375 </map>
376
377 <key>ProvisionVoiceAccountRequest</key>
378 <map>
379 <key>flavor</key>
380 <string>llsd</string>
381 <key>trusted-sender</key>
382 <boolean>false</boolean>
383 </map>
384
385 <!-- Server to client -->
386 <key>RequiredVoiceVersion</key>
387 <map>
388 <key>flavor</key>
389 <string>llsd</string>
390 <key>trusted-sender</key>
391 <boolean>true</boolean>
392 </map>
393
394
327 </map> 395 </map>
328 <key>capBans</key> 396 <key>capBans</key>
329 <map> 397 <map>
@@ -383,6 +451,15 @@
383 451
384 <key>SendPostcard3</key> 452 <key>SendPostcard3</key>
385 <boolean>true</boolean> 453 <boolean>true</boolean>
454
455 <key>ParcelVoiceInfoRequest</key>
456 <boolean>false</boolean>
457
458 <key>ChatSessionRequest</key>
459 <boolean>false</boolean>
460
461 <key>ProvisionVoiceAccountRequest</key>
462 <boolean>false</boolean>
386 </map> 463 </map>
387 464
388 <key>messageBans</key> 465 <key>messageBans</key>
diff --git a/linden/indra/SConstruct b/linden/indra/SConstruct
index f988b1b..e90a7e6 100644
--- a/linden/indra/SConstruct
+++ b/linden/indra/SConstruct
@@ -10,7 +10,7 @@
10# installed, with headers. We pick up the correct flags to use for 10# installed, with headers. We pick up the correct flags to use for
11# these libraries using the "pkg-config" command. 11# these libraries using the "pkg-config" command.
12# 12#
13# cairo glib-2.0 gtk+-2.0 sdl vorbis vorbisenc vorbisfile 13# cairo glib-2.0 atk gmobile-2.0 gdk-2.0 gdk-pixbuf-2.0 pango pangoft2 pangox pangoxft gtk+-2.0 sdl vorbis vorbisenc vorbisfile
14# 14#
15# Then build as follows: 15# Then build as follows:
16# 16#
@@ -99,6 +99,7 @@ opts.AddOptions(
99 BoolOption('DISTCC', 'Enabled distcc', True), 99 BoolOption('DISTCC', 'Enabled distcc', True),
100 BoolOption('MOZLIB', 'Enabled llmozlib/mozilla support', True), 100 BoolOption('MOZLIB', 'Enabled llmozlib/mozilla support', True),
101 BoolOption('FMOD', 'Enabled FMOD audio support', True), 101 BoolOption('FMOD', 'Enabled FMOD audio support', True),
102 BoolOption('GSTREAMER', 'Enabled GStreamer support', True),
102 BoolOption('COLORGCC', 'Enabled colorgcc', True), 103 BoolOption('COLORGCC', 'Enabled colorgcc', True),
103 EnumOption('GRID', 'Client package\'s default grid', 'default', 104 EnumOption('GRID', 'Client package\'s default grid', 'default',
104 allowed_values=('default', 'aditi', 'agni', 'dmz', 'durga', 'firstlook', 'ganga', 'shakti', 'siva', 'soma', 'uma', 'vaak')), 105 allowed_values=('default', 'aditi', 'agni', 'dmz', 'durga', 'firstlook', 'ganga', 'shakti', 'siva', 'soma', 'uma', 'vaak')),
@@ -114,6 +115,7 @@ arch = optenv['ARCH']
114target_param = optenv['BTARGET'] 115target_param = optenv['BTARGET']
115enable_distcc = optenv['DISTCC'] 116enable_distcc = optenv['DISTCC']
116enable_mozlib = optenv['MOZLIB'] 117enable_mozlib = optenv['MOZLIB']
118enable_gstreamer = optenv['GSTREAMER']
117enable_colorgcc = optenv['COLORGCC'] 119enable_colorgcc = optenv['COLORGCC']
118grid = optenv['GRID'] 120grid = optenv['GRID']
119standalone = optenv['STANDALONE'] 121standalone = optenv['STANDALONE']
@@ -133,14 +135,35 @@ duplicate = True
133if standalone and platform != 'linux': 135if standalone and platform != 'linux':
134 print >> sys.stderr, 'Warning: standalone builds have only been tested on Linux' 136 print >> sys.stderr, 'Warning: standalone builds have only been tested on Linux'
135 137
136standalone_pkgs = 'cairo glib-2.0 gtk+-2.0 sdl vorbis vorbisenc vorbisfile' 138standalone_pkgs = [
139 'apr-1',
140 'apr-util-1',
141 'atk',
142 'cairo',
143 'freetype2',
144 'gdk-2.0',
145 'gdk-pixbuf-2.0',
146 'glib-2.0',
147 'gmodule-2.0',
148 'gtk+-2.0',
149 'libcurl',
150 'libpng',
151 'pango',
152 'pangoft2',
153 'pangox',
154 'pangoxft',
155 'sdl',
156 'vorbis',
157 'vorbisenc',
158 'vorbisfile',
159 ]
137 160
138def pkgconfig(opt, pkgs=None): 161def pkgconfig(opt, pkgs=None):
139 return os.popen('pkg-config %s %s' % 162 return os.popen('pkg-config %s %s' %
140 (opt, pkgs or standalone_pkgs)).read().strip() 163 (opt, pkgs or ' '.join(standalone_pkgs))).read().strip()
141 164
142if standalone: 165if standalone:
143 missing = [pkg for pkg in standalone_pkgs.split() 166 missing = [pkg for pkg in standalone_pkgs
144 if os.system('pkg-config --exists ' + pkg)] 167 if os.system('pkg-config --exists ' + pkg)]
145 if missing: 168 if missing:
146 print >> sys.stderr, ('Error: pkg-config cannot find these ' 169 print >> sys.stderr, ('Error: pkg-config cannot find these '
@@ -194,7 +217,10 @@ for build_target in targets:
194 if arch == 'x86_64' and os.path.exists('/usr/lib64'): 217 if arch == 'x86_64' and os.path.exists('/usr/lib64'):
195 client_external_libs = [File('/usr/lib64/libresolv.a')] 218 client_external_libs = [File('/usr/lib64/libresolv.a')]
196 else: 219 else:
197 client_external_libs = ['llresolv6'] 220 # Custom libresolv build which avoids a billion flavors of
221 # brokenness prevalent in common libresolvs out there.
222 client_external_libs = ['resolv']
223 include_dirs += ['../libraries/' + system_str + '/include/llresolv8']
198 else: 224 else:
199 client_external_libs = ['resolv'] 225 client_external_libs = ['resolv']
200 226
@@ -230,7 +256,9 @@ for build_target in targets:
230 # Generic GCC flags 256 # Generic GCC flags
231 cflags = '-g -pipe -Wall -Wno-trigraphs -Wno-sign-compare -Werror ' 257 cflags = '-g -pipe -Wall -Wno-trigraphs -Wno-sign-compare -Werror '
232 cxxflags = '' 258 cxxflags = ''
233 cppflags = '' 259 cppflags = '-D_FORTIFY_SOURCE=2 '
260 if standalone:
261 cppflags += '-DLL_STANDALONE '
234 262
235 if build_target == 'server': 263 if build_target == 'server':
236 # Server flags 264 # Server flags
@@ -255,6 +283,7 @@ for build_target in targets:
255 client_cppflags = '' 283 client_cppflags = ''
256 cppflags += client_cppflags + ' ' 284 cppflags += client_cppflags + ' '
257 285
286
258 if platform == 'linux': 287 if platform == 'linux':
259 # Linux-only flags 288 # Linux-only flags
260 cppflags += '-DLL_LINUX=1 ' 289 cppflags += '-DLL_LINUX=1 '
@@ -267,14 +296,14 @@ for build_target in targets:
267 include_dirs += [d[2:] for d in 296 include_dirs += [d[2:] for d in
268 pkgconfig('--cflags-only-I').split()] 297 pkgconfig('--cflags-only-I').split()]
269 else: 298 else:
270 client_external_libs += [ 'gtk-x11-2.0' ] 299 client_external_libs += [ 'gtk-x11-2.0', 'atk-1.0', 'gmodule-2.0', 'gdk-x11-2.0', 'gdk_pixbuf-2.0', 'pango-1.0', 'pangoft2-1.0', 'pangox-1.0', 'pangoxft-1.0', 'Xinerama' ]
271 incdirs = [ 'ELFIO', 'atk-1.0', 'glib-2.0', 'gtk-2.0', 300 incdirs = [ 'ELFIO', 'atk-1.0', 'glib-2.0', 'gtk-2.0',
272 'llfreetype2', 'pango-1.0' ] 301 'llfreetype2', 'pango-1.0' ]
273 include_dirs += ['../libraries/' + system_str + '/include/' + d 302 include_dirs += ['../libraries/' + system_str + '/include/' + d
274 for d in incdirs] 303 for d in incdirs]
275 304
276 if elfio: 305 if elfio:
277 client_external_libs += [ 'elfio' ] 306 client_external_libs += [ 'ELFIO' ]
278 else: 307 else:
279 cppflags += '-DLL_ELFBIN=0 ' 308 cppflags += '-DLL_ELFBIN=0 '
280 309
@@ -285,6 +314,17 @@ for build_target in targets:
285 client_external_libs += [ 'mozjs', 'nspr4', 'plc4', 'plds4', 'profdirserviceprovider_s', 'xpcom', 'xul' ] 314 client_external_libs += [ 'mozjs', 'nspr4', 'plc4', 'plds4', 'profdirserviceprovider_s', 'xpcom', 'xul' ]
286 else: 315 else:
287 cppflags += '-DLL_LIBXUL_ENABLED=0 ' 316 cppflags += '-DLL_LIBXUL_ENABLED=0 '
317
318 # GStreamer stuff
319 if enable_gstreamer:
320 cppflags += '-DLL_GSTREAMER_ENABLED=1 '
321 client_external_libs += [ 'glib-2.0', 'gobject-2.0' ]
322 #client_external_libs += [ 'gstreamer-0.10', 'gstvideo-0.10', 'gstaudio-0.10' ]
323 include_dirs += [ '../libraries/' + system_str + '/include/gstreamer-0.10' ]
324 include_dirs += [ '../libraries/' + system_str + '/include/glib-2.0', '../libraries/' + system_str + '/include/glib-2.0/include' ]
325 include_dirs += [ '../libraries/' + system_str + '/include/libxml2']
326 else:
327 cppflags += '-DLL_GSTREAMER_ENABLED=0 '
288 else: 328 else:
289 # Mac-only flags 329 # Mac-only flags
290 cflags += '-x c++ -arch ppc -pipe -Wno-trigraphs -fpascal-strings -faltivec -fasm-blocks -g -fmessage-length=0 -mtune=G4 -Wno-deprecated-declarations -Wno-invalid-offsetof -mmacosx-version-min=10.3 -Wmost -Wno-sign-compare -Wno-switch -fconstant-cfstrings -ffor-scope -Wno-reorder ' 330 cflags += '-x c++ -arch ppc -pipe -Wno-trigraphs -fpascal-strings -faltivec -fasm-blocks -g -fmessage-length=0 -mtune=G4 -Wno-deprecated-declarations -Wno-invalid-offsetof -mmacosx-version-min=10.3 -Wmost -Wno-sign-compare -Wno-switch -fconstant-cfstrings -ffor-scope -Wno-reorder '
@@ -392,6 +432,18 @@ for build_target in targets:
392 432
393 env_no_distcc = env.Copy(CXX = compiler_no_distcc) 433 env_no_distcc = env.Copy(CXX = compiler_no_distcc)
394 434
435 vec_match = re.compile("_vec\.")
436 env_vec = env.Copy() # _vec is for default vector optimizations or none
437
438 sse_match = re.compile("_sse\.")
439 env_sse = env.Copy()
440 env_sse.Append(CPPFLAGS = ' -msse -mfpmath=sse')
441
442 sse2_match = re.compile("_sse2\.")
443 env_sse2 = env.Copy()
444 env_sse2.Append(CPPFLAGS = ' -msse2 -mfpmath=sse')
445
446
395 ### Distributed build hosts ### 447 ### Distributed build hosts ###
396 448
397 if enable_distcc: 449 if enable_distcc:
@@ -419,6 +471,21 @@ for build_target in targets:
419 # HELPER FUNCTIONS # 471 # HELPER FUNCTIONS #
420 ##################### 472 #####################
421 473
474 ## handle special compiler modes
475
476 def file_obj(file):
477 if file == 'newsim/lltask.cpp':
478 print 'Found lltask!'
479 return env_no_distcc.Object(file)
480 elif vec_match.search(file) != None:
481 return env_vec.Object(file)
482 elif sse_match.search(file) != None:
483 return env_sse.Object(file)
484 elif sse2_match.search(file) != None:
485 return env_sse2.Object(file)
486 else:
487 return file
488
422 ### Load a files.lst and files.PLATFORM.lst for each module ### 489 ### Load a files.lst and files.PLATFORM.lst for each module ###
423 490
424 def load_files(module, source_fname): 491 def load_files(module, source_fname):
@@ -429,12 +496,7 @@ for build_target in targets:
429 for x in list: 496 for x in list:
430 if not x.startswith('#'): 497 if not x.startswith('#'):
431 file = os.path.join(build_dir, x) 498 file = os.path.join(build_dir, x)
432 if x == 'newsim/lltask.cpp': 499 new_list.append(file_obj(file))
433 print 'Found lltask!'
434 obj = env_no_distcc.Object(file)
435 new_list.append(obj)
436 else:
437 new_list.append(file)
438 list_file.close() 500 list_file.close()
439 except IOError, val: 501 except IOError, val:
440 print 'Error: unable to open file list',source_fname, 502 print 'Error: unable to open file list',source_fname,
@@ -446,7 +508,7 @@ for build_target in targets:
446 list = Split(platform_list_file.read()) 508 list = Split(platform_list_file.read())
447 for x in list: 509 for x in list:
448 file = os.path.join(build_dir, x) 510 file = os.path.join(build_dir, x)
449 new_list.append(file) 511 new_list.append(file_obj(file))
450 platform_list_file.close() 512 platform_list_file.close()
451 except IOError: 513 except IOError:
452 return new_list 514 return new_list
@@ -460,18 +522,22 @@ for build_target in targets:
460 mod_name, 522 mod_name,
461 local_flags="", 523 local_flags="",
462 source_files = 'files.lst', 524 source_files = 'files.lst',
463 extra_depends=None): 525 extra_depends=None,
526 source_env=env):
464 files_list = load_files(input_dir, source_files) 527 files_list = load_files(input_dir, source_files)
465 BuildDir(build_dir + '/' + input_dir, input_dir, duplicate=duplicate) 528 BuildDir(build_dir + '/' + input_dir, input_dir, duplicate=duplicate)
466 local_env = env.Copy(CPPFLAGS = env['CPPFLAGS'] + ' ' + local_flags) 529 local_env = source_env.Copy(CPPFLAGS=env['CPPFLAGS'] + ' ' + local_flags)
467 if extra_depends: 530 if extra_depends:
468 for x in files_list: 531 for x in files_list:
469 Depends(local_env.Object(x), extra_depends) 532 Depends(local_env.Object(x), extra_depends)
470 tgt = local_env.StaticLibrary(lib_dir + '/' + mod_name, files_list) 533 tgt = local_env.StaticLibrary(lib_dir + '/' + mod_name, files_list)
471 Default(tgt) 534 Default(tgt)
472 535
473 def create_static_module(module, local_flags="", source_files = 'files.lst', extra_depends=None): 536 def create_static_module(module, local_flags="", source_env=env,
474 create_static_module_from_dir(module, module, local_flags, source_files, extra_depends) 537 source_files='files.lst', extra_depends=None):
538 create_static_module_from_dir(module, module, local_flags,
539 source_files, extra_depends,
540 source_env=source_env)
475 541
476 def create_dynamic_module( 542 def create_dynamic_module(
477 module, 543 module,
@@ -484,11 +550,16 @@ for build_target in targets:
484 tgt = local_env.SharedLibrary(lib_dir + '/' + module, files_list, LIBS = module_libs) 550 tgt = local_env.SharedLibrary(lib_dir + '/' + module, files_list, LIBS = module_libs)
485 Default(tgt) 551 Default(tgt)
486 552
553 # Some libraries need to be built using PIC so that they can be
554 # linked into libllkdu.so. If we're not building libllkdu.so, we
555 # don't need to add the PIC flag.
487 def create_cond_module(module, module_libs=[]): 556 def create_cond_module(module, module_libs=[]):
488 if build_target != 'client' or not opensource: 557 if build_target == 'client' and not opensource:
489 create_static_module(module=module) 558 shared_env = env.Copy(CFLAGS=env['CFLAGS'] + '-fpic ',
559 CXXFLAGS=env['CXXFLAGS'] + '-fpic ')
560 create_static_module(module=module, source_env=shared_env)
490 else: 561 else:
491 create_dynamic_module(module=module, module_libs=module_libs) 562 create_static_module(module=module, source_env=env)
492 563
493 ### Create an executable from the module ### 564 ### Create an executable from the module ###
494 565
@@ -503,7 +574,7 @@ for build_target in targets:
503 ### Check the message template for compatibility with the base ### 574 ### Check the message template for compatibility with the base ###
504 tgt = env.Command("template_verifier_output", 575 tgt = env.Command("template_verifier_output",
505 '../scripts/template_verifier.py', 576 '../scripts/template_verifier.py',
506 'python $SOURCE --mode="development" 2>&1') 577 'python $SOURCE --mode="development" --cache_master 2>&1')
507 Default(tgt) 578 Default(tgt)
508 AlwaysBuild(tgt) 579 AlwaysBuild(tgt)
509 580
@@ -539,7 +610,7 @@ for build_target in targets:
539 ############################# 610 #############################
540 output_crashlogger_bin = 'linux_crash_logger/linux-crash-logger-' + arch + '-bin' 611 output_crashlogger_bin = 'linux_crash_logger/linux-crash-logger-' + arch + '-bin'
541 if standalone: 612 if standalone:
542 external_libs = net_external_libs + [ 'db' ] 613 external_libs = net_external_libs
543 external_libs += [d[2:] for d in 614 external_libs += [d[2:] for d in
544 pkgconfig('--libs-only-l', 'gtk+-2.0').split()] 615 pkgconfig('--libs-only-l', 'gtk+-2.0').split()]
545 else: 616 else:
@@ -566,7 +637,6 @@ for build_target in targets:
566 external_libs = client_external_libs + common_external_libs 637 external_libs = client_external_libs + common_external_libs
567 638
568 if standalone: 639 if standalone:
569 external_libs += [ 'db' ]
570 external_libs += [ d[2:] for d in 640 external_libs += [ d[2:] for d in
571 pkgconfig('--libs-only-l').split() ] 641 pkgconfig('--libs-only-l').split() ]
572 else: 642 else:
@@ -654,15 +724,13 @@ for build_target in targets:
654 internal_libs + external_libs) 724 internal_libs + external_libs)
655 725
656 # Dataserver 726 # Dataserver
657 Depends('dataserver/dataserver', 'launcher/launcher' + file_suffix) 727 external_libs = common_external_libs + ['boost_regex-gcc-mt', 'mysqlclient']
658 external_libs = common_external_libs + ['boost_regex-gcc-mt', 'mysqlclient', 'tcmalloc', 'stacktrace']
659 internal_libs = [ 'llcharacter', 'lldatabase', 'llimage', 'llimagej2coj', 'llinventory', 728 internal_libs = [ 'llcharacter', 'lldatabase', 'llimage', 'llimagej2coj', 'llinventory',
660 'llscene', 'llmessage', 'llvfs', 'llxml', 'llcommon', 'llmath' ] 729 'llscene', 'llmessage', 'llvfs', 'llxml', 'llcommon', 'llmath' ]
661 create_executable('dataserver/dataserver' + file_suffix, 'dataserver', 730 create_executable('dataserver/dataserver' + file_suffix, 'dataserver',
662 internal_libs + external_libs) 731 internal_libs + external_libs)
663 732
664 # Spaceserver 733 # Spaceserver
665 Depends('newspace/spaceserver', 'dataserver/dataserver' + file_suffix)
666 external_libs = common_external_libs + ['mysqlclient'] 734 external_libs = common_external_libs + ['mysqlclient']
667 internal_libs = ['llscene', 'lldatabase', 'llmessage', 'llvfs', 735 internal_libs = ['llscene', 'lldatabase', 'llmessage', 'llvfs',
668 'llmath', 'llcommon'] 736 'llmath', 'llcommon']
@@ -670,7 +738,6 @@ for build_target in targets:
670 internal_libs + external_libs) 738 internal_libs + external_libs)
671 739
672 # Rpcserver 740 # Rpcserver
673 Depends('rpcserver/rpcserver', 'newspace/spaceserver' + file_suffix)
674 external_libs = common_external_libs + ['xmlrpc', 'mysqlclient'] 741 external_libs = common_external_libs + ['xmlrpc', 'mysqlclient']
675 internal_libs = ['llscene', 'llmessage', 'lldatabase', 'llvfs', 742 internal_libs = ['llscene', 'llmessage', 'lldatabase', 'llvfs',
676 'llmath', 'llcommon'] 743 'llmath', 'llcommon']
@@ -678,7 +745,6 @@ for build_target in targets:
678 internal_libs + external_libs) 745 internal_libs + external_libs)
679 746
680 # Mapserver 747 # Mapserver
681 Depends('mapserver/mapserver', 'rpcserver/rpcserver' + file_suffix)
682 external_libs = common_external_libs + ['OSMesa16', 'kdu', 748 external_libs = common_external_libs + ['OSMesa16', 'kdu',
683 'boost_regex-gcc-mt', 'iconv', 'jpeg', 'openjpeg', 'GL', 749 'boost_regex-gcc-mt', 'iconv', 'jpeg', 'openjpeg', 'GL',
684 'mysqlclient', 'pthread', 'dl'] 750 'mysqlclient', 'pthread', 'dl']
@@ -688,8 +754,7 @@ for build_target in targets:
688 internal_libs + external_libs) 754 internal_libs + external_libs)
689 755
690 # Simulator 756 # Simulator
691 Depends('newsim/simulator' + file_suffix, 'mapserver/mapserver' + file_suffix) 757 external_libs = common_external_libs + ['hkdynamics', 'hkgeometry', 'hkmath', 'hkbase', 'hkcollide', 'hkactions', 'boost_regex-gcc-mt', 'openjpeg', 'dl', 'kdu', 'mysqlclient', 'iconv']
692 external_libs = common_external_libs + ['hkdynamics', 'hkgeometry', 'hkmath', 'hkbase', 'hkcollide', 'hkactions', 'boost_regex-gcc-mt', 'openjpeg', 'dl', 'kdu', 'mysqlclient', 'iconv', 'tcmalloc', 'stacktrace']
693 internal_libs = [ 'lscript', 'llprimitive', 758 internal_libs = [ 'lscript', 'llprimitive',
694 'llscene', 'llhavok', 'llinventory', 'llimage', 'llimagej2coj', 759 'llscene', 'llhavok', 'llinventory', 'llimage', 'llimagej2coj',
695 'llcharacter', 'llxml', 'lldatabase', 'llkdustatic', 760 'llcharacter', 'llxml', 'lldatabase', 'llkdustatic',
diff --git a/linden/indra/indra_complete/indra_complete.sln b/linden/indra/indra_complete/indra_complete.sln
index 24495ff..76346f9 100644
--- a/linden/indra/indra_complete/indra_complete.sln
+++ b/linden/indra/indra_complete/indra_complete.sln
@@ -141,12 +141,14 @@ EndProject
141 ProjectSection(ProjectDependencies) = postProject 141 ProjectSection(ProjectDependencies) = postProject
142 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F} = {7BCB4B2C-8378-4186-88EA-5742B5ABE17F} 142 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F} = {7BCB4B2C-8378-4186-88EA-5742B5ABE17F}
143 {44CE6D82-7320-4609-8FC3-5965C19F4808} = {44CE6D82-7320-4609-8FC3-5965C19F4808} 143 {44CE6D82-7320-4609-8FC3-5965C19F4808} = {44CE6D82-7320-4609-8FC3-5965C19F4808}
144 {BFA102B0-C891-4E13-B1CF-C2F28073DA8E} = {BFA102B0-C891-4E13-B1CF-C2F28073DA8E}
144 {E87FD9BE-BE42-4EA3-BF4D-D992223046D9} = {E87FD9BE-BE42-4EA3-BF4D-D992223046D9} 145 {E87FD9BE-BE42-4EA3-BF4D-D992223046D9} = {E87FD9BE-BE42-4EA3-BF4D-D992223046D9}
145 EndProjectSection 146 EndProjectSection
146EndProject 147EndProject
147 ProjectSection(ProjectDependencies) = postProject 148 ProjectSection(ProjectDependencies) = postProject
148 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F} = {7BCB4B2C-8378-4186-88EA-5742B5ABE17F} 149 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F} = {7BCB4B2C-8378-4186-88EA-5742B5ABE17F}
149 {F882263E-4F2A-43D9-A45A-FA4C8EC66552} = {F882263E-4F2A-43D9-A45A-FA4C8EC66552} 150 {F882263E-4F2A-43D9-A45A-FA4C8EC66552} = {F882263E-4F2A-43D9-A45A-FA4C8EC66552}
151 {BFA102B0-C891-4E13-B1CF-C2F28073DA8E} = {BFA102B0-C891-4E13-B1CF-C2F28073DA8E}
150 {E87FD9BE-BE42-4EA3-BF4D-D992223046D9} = {E87FD9BE-BE42-4EA3-BF4D-D992223046D9} 152 {E87FD9BE-BE42-4EA3-BF4D-D992223046D9} = {E87FD9BE-BE42-4EA3-BF4D-D992223046D9}
151 EndProjectSection 153 EndProjectSection
152EndProject 154EndProject
@@ -254,6 +256,8 @@ Global
254 Debug = Debug 256 Debug = Debug
255 Release = Release 257 Release = Release
256 EndGlobalSection 258 EndGlobalSection
259 GlobalSection(ProjectDependencies) = postSolution
260 EndGlobalSection
257 GlobalSection(ProjectConfiguration) = postSolution 261 GlobalSection(ProjectConfiguration) = postSolution
258 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F}.Debug.ActiveCfg = Debug|Win32 262 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F}.Debug.ActiveCfg = Debug|Win32
259 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F}.Debug.Build.0 = Debug|Win32 263 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F}.Debug.Build.0 = Debug|Win32
diff --git a/linden/indra/indra_complete/indra_complete_vc8.sln b/linden/indra/indra_complete/indra_complete_vc8.sln
index 9a35696..f6b4304 100644
--- a/linden/indra/indra_complete/indra_complete_vc8.sln
+++ b/linden/indra/indra_complete/indra_complete_vc8.sln
@@ -26,12 +26,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llinventory", "..\llinvento
26EndProject 26EndProject
27Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "newview", "..\newview\newview_vc8.vcproj", "{E6F4CF1B-6109-4CA8-B58D-87FA936CDE08}" 27Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "newview", "..\newview\newview_vc8.vcproj", "{E6F4CF1B-6109-4CA8-B58D-87FA936CDE08}"
28 ProjectSection(ProjectDependencies) = postProject 28 ProjectSection(ProjectDependencies) = postProject
29 {E928F33B-E090-4FA8-818B-6B5D8B0F1F4B} = {E928F33B-E090-4FA8-818B-6B5D8B0F1F4B}
29 {9D0C7E02-6506-4EE7-BC5C-75671D28D594} = {9D0C7E02-6506-4EE7-BC5C-75671D28D594} 30 {9D0C7E02-6506-4EE7-BC5C-75671D28D594} = {9D0C7E02-6506-4EE7-BC5C-75671D28D594}
30 {2ADE3C14-94C4-40BF-B033-70F3C954EE90} = {2ADE3C14-94C4-40BF-B033-70F3C954EE90} 31 {2ADE3C14-94C4-40BF-B033-70F3C954EE90} = {2ADE3C14-94C4-40BF-B033-70F3C954EE90}
31 {B5B53617-416F-404A-BF10-22EBCCA0E4FB} = {B5B53617-416F-404A-BF10-22EBCCA0E4FB} 32 {B5B53617-416F-404A-BF10-22EBCCA0E4FB} = {B5B53617-416F-404A-BF10-22EBCCA0E4FB}
32 {93B2BA29-FBE9-4376-92C1-6108DCFE09D3} = {93B2BA29-FBE9-4376-92C1-6108DCFE09D3} 33 {93B2BA29-FBE9-4376-92C1-6108DCFE09D3} = {93B2BA29-FBE9-4376-92C1-6108DCFE09D3}
33 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F} = {7BCB4B2C-8378-4186-88EA-5742B5ABE17F} 34 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F} = {7BCB4B2C-8378-4186-88EA-5742B5ABE17F}
34 {E928F33B-E090-4FA8-818B-6B5D8B0F1F4B} = {E928F33B-E090-4FA8-818B-6B5D8B0F1F4B}
35 {FCC4483C-5B84-4944-B91F-4589A219BC0B} = {FCC4483C-5B84-4944-B91F-4589A219BC0B} 35 {FCC4483C-5B84-4944-B91F-4589A219BC0B} = {FCC4483C-5B84-4944-B91F-4589A219BC0B}
36 {F882263E-4F2A-43D9-A45A-FA4C8EC66552} = {F882263E-4F2A-43D9-A45A-FA4C8EC66552} 36 {F882263E-4F2A-43D9-A45A-FA4C8EC66552} = {F882263E-4F2A-43D9-A45A-FA4C8EC66552}
37 {076DD042-2E58-42EA-9401-53210B65C1FC} = {076DD042-2E58-42EA-9401-53210B65C1FC} 37 {076DD042-2E58-42EA-9401-53210B65C1FC} = {076DD042-2E58-42EA-9401-53210B65C1FC}
diff --git a/linden/indra/lib/python/indra/__init__.py b/linden/indra/lib/python/indra/__init__.py
index 7548558..220768f 100644
--- a/linden/indra/lib/python/indra/__init__.py
+++ b/linden/indra/lib/python/indra/__init__.py
@@ -1,8 +1,9 @@
1# @file __init__.py 1"""\
2# @brief Initialization file for the indra module. 2@file __init__.py
3# 3@brief Initialization file for the indra module.
4# Copyright (c) 2006-2007, Linden Research, Inc. 4
5# 5Copyright (c) 2006-2007, Linden Research, Inc.
6
6# Second Life Viewer Source Code 7# Second Life Viewer Source Code
7# The source code in this file ("Source Code") is provided by Linden Lab 8# The source code in this file ("Source Code") is provided by Linden Lab
8# to you under the terms of the GNU General Public License, version 2.0 9# to you under the terms of the GNU General Public License, version 2.0
@@ -23,3 +24,4 @@
23# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 24# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 25# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25# COMPLETENESS OR PERFORMANCE. 26# COMPLETENESS OR PERFORMANCE.
27"""
diff --git a/linden/indra/lib/python/indra/ipc/__init__.py b/linden/indra/lib/python/indra/ipc/__init__.py
new file mode 100644
index 0000000..92c9416
--- /dev/null
+++ b/linden/indra/lib/python/indra/ipc/__init__.py
@@ -0,0 +1,27 @@
1"""\
2@file __init__.py
3@brief Initialization file for the indra ipc module.
4
5Copyright (c) 2006-2007, Linden Research, Inc.
6
7# Second Life Viewer Source Code
8# The source code in this file ("Source Code") is provided by Linden Lab
9# to you under the terms of the GNU General Public License, version 2.0
10# ("GPL"), unless you have obtained a separate licensing agreement
11# ("Other License"), formally executed by you and Linden Lab. Terms of
12# the GPL can be found in doc/GPL-license.txt in this distribution, or
13# online at http://secondlife.com/developers/opensource/gplv2
14#
15# There are special exceptions to the terms and conditions of the GPL as
16# it is applied to this Source Code. View the full text of the exception
17# in the file doc/FLOSS-exception.txt in this software distribution, or
18# online at http://secondlife.com/developers/opensource/flossexception
19#
20# By copying, modifying or distributing this software, you acknowledge
21# that you have read and understood your obligations described above,
22# and agree to abide by those obligations.
23#
24# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26# COMPLETENESS OR PERFORMANCE.
27"""
diff --git a/linden/indra/lib/python/indra/compatibility.py b/linden/indra/lib/python/indra/ipc/compatibility.py
index abc1c6a..358820c 100644
--- a/linden/indra/lib/python/indra/compatibility.py
+++ b/linden/indra/lib/python/indra/ipc/compatibility.py
@@ -1,8 +1,9 @@
1# @file compatibility.py 1"""\
2# @brief Classes that manage compatibility states. 2@file compatibility.py
3# 3@brief Classes that manage compatibility states.
4# Copyright (c) 2007-2007, Linden Research, Inc. 4
5# 5Copyright (c) 2007, Linden Research, Inc.
6
6# Second Life Viewer Source Code 7# Second Life Viewer Source Code
7# The source code in this file ("Source Code") is provided by Linden Lab 8# The source code in this file ("Source Code") is provided by Linden Lab
8# to you under the terms of the GNU General Public License, version 2.0 9# to you under the terms of the GNU General Public License, version 2.0
@@ -23,6 +24,7 @@
23# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 24# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 25# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25# COMPLETENESS OR PERFORMANCE. 26# COMPLETENESS OR PERFORMANCE.
27"""
26 28
27 29
28"""Compatibility combination table: 30"""Compatibility combination table:
diff --git a/linden/indra/lib/python/indra/llmessage.py b/linden/indra/lib/python/indra/ipc/llmessage.py
index 1d4995d..de6fd3b 100644
--- a/linden/indra/lib/python/indra/llmessage.py
+++ b/linden/indra/lib/python/indra/ipc/llmessage.py
@@ -1,8 +1,9 @@
1# @file llmessage.py 1"""\
2# @brief Message template parsing and compatiblity 2@file llmessage.py
3# 3@brief Message template parsing and compatiblity
4# Copyright (c) 2007-2007, Linden Research, Inc. 4
5# 5Copyright (c) 2007, Linden Research, Inc.
6
6# Second Life Viewer Source Code 7# Second Life Viewer Source Code
7# The source code in this file ("Source Code") is provided by Linden Lab 8# The source code in this file ("Source Code") is provided by Linden Lab
8# to you under the terms of the GNU General Public License, version 2.0 9# to you under the terms of the GNU General Public License, version 2.0
@@ -23,6 +24,7 @@
23# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 24# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 25# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25# COMPLETENESS OR PERFORMANCE. 26# COMPLETENESS OR PERFORMANCE.
27"""
26 28
27from sets import Set, ImmutableSet 29from sets import Set, ImmutableSet
28 30
@@ -369,7 +371,3 @@ def parseTemplateString(s):
369 371
370def parseTemplateFile(f): 372def parseTemplateFile(f):
371 return TemplateParser(TokenStream().fromFile(f)).parseTemplate() 373 return TemplateParser(TokenStream().fromFile(f)).parseTemplate()
372
373
374
375
diff --git a/linden/indra/lib/python/indra/tokenstream.py b/linden/indra/lib/python/indra/ipc/tokenstream.py
index 7dab11f..83b087a 100644
--- a/linden/indra/lib/python/indra/tokenstream.py
+++ b/linden/indra/lib/python/indra/ipc/tokenstream.py
@@ -1,8 +1,9 @@
1# @file tokenstream.py 1"""\
2# @brief Message template parsing utility class 2@file tokenstream.py
3# 3@brief Message template parsing utility class
4# Copyright (c) 2007-2007, Linden Research, Inc. 4
5# 5Copyright (c) 2007, Linden Research, Inc.
6
6# Second Life Viewer Source Code 7# Second Life Viewer Source Code
7# The source code in this file ("Source Code") is provided by Linden Lab 8# The source code in this file ("Source Code") is provided by Linden Lab
8# to you under the terms of the GNU General Public License, version 2.0 9# to you under the terms of the GNU General Public License, version 2.0
@@ -23,6 +24,7 @@
23# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 24# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 25# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25# COMPLETENESS OR PERFORMANCE. 26# COMPLETENESS OR PERFORMANCE.
27"""
26 28
27import re 29import re
28 30
diff --git a/linden/indra/lib/python/indra/util/__init__.py b/linden/indra/lib/python/indra/util/__init__.py
new file mode 100644
index 0000000..3f79d0a
--- /dev/null
+++ b/linden/indra/lib/python/indra/util/__init__.py
@@ -0,0 +1,27 @@
1"""\
2@file __init__.py
3@brief Initialization file for the indra util module.
4
5Copyright (c) 2006-2007, Linden Research, Inc.
6
7# Second Life Viewer Source Code
8# The source code in this file ("Source Code") is provided by Linden Lab
9# to you under the terms of the GNU General Public License, version 2.0
10# ("GPL"), unless you have obtained a separate licensing agreement
11# ("Other License"), formally executed by you and Linden Lab. Terms of
12# the GPL can be found in doc/GPL-license.txt in this distribution, or
13# online at http://secondlife.com/developers/opensource/gplv2
14#
15# There are special exceptions to the terms and conditions of the GPL as
16# it is applied to this Source Code. View the full text of the exception
17# in the file doc/FLOSS-exception.txt in this software distribution, or
18# online at http://secondlife.com/developers/opensource/flossexception
19#
20# By copying, modifying or distributing this software, you acknowledge
21# that you have read and understood your obligations described above,
22# and agree to abide by those obligations.
23#
24# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26# COMPLETENESS OR PERFORMANCE.
27"""
diff --git a/linden/indra/lib/python/indra/llmanifest.py b/linden/indra/lib/python/indra/util/llmanifest.py
index 22483b4..0e46589 100644
--- a/linden/indra/lib/python/indra/llmanifest.py
+++ b/linden/indra/lib/python/indra/util/llmanifest.py
@@ -1,10 +1,11 @@
1#!/usr/bin/python 1#!/usr/bin/python
2# @file llmanifest.py 2"""\
3# @author Ryan Williams 3@file llmanifest.py
4# @brief Library for specifying operations on a set of files. 4@author Ryan Williams
5# 5@brief Library for specifying operations on a set of files.
6# Copyright (c) 2007-2007, Linden Research, Inc. 6
7# 7Copyright (c) 2007, Linden Research, Inc.
8
8# Second Life Viewer Source Code 9# Second Life Viewer Source Code
9# The source code in this file ("Source Code") is provided by Linden Lab 10# The source code in this file ("Source Code") is provided by Linden Lab
10# to you under the terms of the GNU General Public License, version 2.0 11# to you under the terms of the GNU General Public License, version 2.0
@@ -25,6 +26,7 @@
25# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 26# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
26# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 27# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27# COMPLETENESS OR PERFORMANCE. 28# COMPLETENESS OR PERFORMANCE.
29"""
28 30
29import commands 31import commands
30import filecmp 32import filecmp
diff --git a/linden/indra/linux_crash_logger/linux_crash_logger.cpp b/linden/indra/linux_crash_logger/linux_crash_logger.cpp
index b950753..f9c03b0 100644
--- a/linden/indra/linux_crash_logger/linux_crash_logger.cpp
+++ b/linden/indra/linux_crash_logger/linux_crash_logger.cpp
@@ -54,10 +54,8 @@ static const char dialog_text[] =
54"Second Life appears to have crashed.\n" 54"Second Life appears to have crashed.\n"
55"This crash reporter collects information about your computer's hardware, operating system, and some Second Life logs, which are used for debugging purposes only.\n" 55"This crash reporter collects information about your computer's hardware, operating system, and some Second Life logs, which are used for debugging purposes only.\n"
56"Sending crash reports is the best way to help us improve the quality of Second Life.\n" 56"Sending crash reports is the best way to help us improve the quality of Second Life.\n"
57"If you continue to experience this problem, please try one of the following:\n" 57"If you continue to experience this problem, please try:\n"
58"- Contact support by email at support@EXAMPLE.com\n" 58"- Contacting support by visiting http://www.secondlife.com/support\n"
59"- If you can log-in, please contact Live Help by using menu Help > Live Help.\n"
60"- Search the Second Life Knowledge Base at http://secondlife.com/knowledgebase/\n"
61"\n" 59"\n"
62"Send crash report?"; 60"Send crash report?";
63 61
@@ -474,9 +472,9 @@ LLFileEncoder::LLFileEncoder(const char *form_name, const char *filename, bool i
474 S32 buf_size = stat_data.st_size; 472 S32 buf_size = stat_data.st_size;
475 FILE *fp = fopen(mFilename.c_str(), "rb"); 473 FILE *fp = fopen(mFilename.c_str(), "rb");
476 U8 *buf = new U8[buf_size + 1]; 474 U8 *buf = new U8[buf_size + 1];
477 fread(buf, 1, buf_size, fp); 475 size_t nread = fread(buf, 1, buf_size, fp);
478 fclose(fp); 476 fclose(fp);
479 buf[buf_size] = 0; 477 buf[nread] = 0;
480 478
481 mBuf = (char *)buf; 479 mBuf = (char *)buf;
482 480
diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp
index d5c2a40..4428cea 100644
--- a/linden/indra/llaudio/audioengine.cpp
+++ b/linden/indra/llaudio/audioengine.cpp
@@ -34,7 +34,7 @@
34#include <string.h> 34#include <string.h>
35#include <math.h> 35#include <math.h>
36 36
37#if LL_LINUX 37#if LL_LINUX || LL_SOLARIS
38#include <time.h> 38#include <time.h>
39#endif 39#endif
40 40
diff --git a/linden/indra/llcharacter/lljoint.cpp b/linden/indra/llcharacter/lljoint.cpp
index 6141cc0..07c34a8 100644
--- a/linden/indra/llcharacter/lljoint.cpp
+++ b/linden/indra/llcharacter/lljoint.cpp
@@ -485,39 +485,6 @@ void LLJoint::setSkinOffset( const LLVector3& offset )
485 mSkinOffset = offset; 485 mSkinOffset = offset;
486} 486}
487 487
488//-----------------------------------------------------------------------------
489// setConstraintSilhouette()
490//-----------------------------------------------------------------------------
491void LLJoint::setConstraintSilhouette(LLDynamicArray<LLVector3>& silhouette)
492{
493 S32 i;
494
495 mConstraintSilhouette.reset();
496 for (i = 0; i < silhouette.count(); i++)
497 {
498 if (i % 2 == 1)
499 {
500 // skip normals
501 continue;
502 }
503 mConstraintSilhouette[i / 2] = silhouette[i];
504 }
505 LLQuaternion inv_parent_rotation = LLQuaternion::DEFAULT;
506
507 if (getParent())
508 {
509 inv_parent_rotation = ~getParent()->getWorldRotation();
510 }
511
512 for (i = 0; i < mConstraintSilhouette.count(); i++)
513 {
514 LLVector3 vert = mConstraintSilhouette[i];
515
516 vert -= getWorldPosition();
517 vert.normVec();
518 vert = vert * inv_parent_rotation;
519 }
520}
521 488
522//----------------------------------------------------------------------------- 489//-----------------------------------------------------------------------------
523// clampRotation() 490// clampRotation()
diff --git a/linden/indra/llcharacter/lljoint.h b/linden/indra/llcharacter/lljoint.h
index f188968..d1e0107 100644
--- a/linden/indra/llcharacter/lljoint.h
+++ b/linden/indra/llcharacter/lljoint.h
@@ -85,7 +85,6 @@ protected:
85 85
86public: 86public:
87 U32 mDirtyFlags; 87 U32 mDirtyFlags;
88 BOOL mWorldRotationDirty;
89 BOOL mUpdateXform; 88 BOOL mUpdateXform;
90 89
91 // describes the skin binding pose 90 // describes the skin binding pose
@@ -93,8 +92,6 @@ public:
93 92
94 S32 mJointNum; 93 S32 mJointNum;
95 94
96 LLDynamicArray<LLVector3> mConstraintSilhouette;
97
98 // child joints 95 // child joints
99 typedef std::list<LLJoint*> child_list_t; 96 typedef std::list<LLJoint*> child_list_t;
100 child_list_t mChildren; 97 child_list_t mChildren;
@@ -171,8 +168,6 @@ public:
171 168
172 LLXformMatrix *getXform() { return &mXform; } 169 LLXformMatrix *getXform() { return &mXform; }
173 170
174 void setConstraintSilhouette(LLDynamicArray<LLVector3>& silhouette);
175
176 void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot); 171 void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot);
177 172
178 virtual BOOL isAnimatable() { return TRUE; } 173 virtual BOOL isAnimatable() { return TRUE; }
diff --git a/linden/indra/llcharacter/llmotion.cpp b/linden/indra/llcharacter/llmotion.cpp
index b13ea60..40a30a4 100644
--- a/linden/indra/llcharacter/llmotion.cpp
+++ b/linden/indra/llcharacter/llmotion.cpp
@@ -126,6 +126,11 @@ void LLMotion::setDeactivateCallback( void (*cb)(void *), void* userdata )
126 mDeactivateCallbackUserData = userdata; 126 mDeactivateCallbackUserData = userdata;
127} 127}
128 128
129BOOL LLMotion::isBlending()
130{
131 return mPose.getWeight() < 1.f;
132}
133
129//----------------------------------------------------------------------------- 134//-----------------------------------------------------------------------------
130// activate() 135// activate()
131//----------------------------------------------------------------------------- 136//-----------------------------------------------------------------------------
@@ -142,10 +147,16 @@ void LLMotion::activate()
142void LLMotion::deactivate() 147void LLMotion::deactivate()
143{ 148{
144 mActive = FALSE; 149 mActive = FALSE;
150 mPose.setWeight(0.f);
145 151
146 if (mDeactivateCallback) (*mDeactivateCallback)(mDeactivateCallbackUserData); 152 if (mDeactivateCallback) (*mDeactivateCallback)(mDeactivateCallbackUserData);
147 153
148 onDeactivate(); 154 onDeactivate();
149} 155}
150 156
157BOOL LLMotion::canDeprecate()
158{
159 return TRUE;
160}
161
151// End 162// End
diff --git a/linden/indra/llcharacter/llmotion.h b/linden/indra/llcharacter/llmotion.h
index 48d402a..e60b0c0 100644
--- a/linden/indra/llcharacter/llmotion.h
+++ b/linden/indra/llcharacter/llmotion.h
@@ -99,13 +99,14 @@ public:
99 99
100 void setStopped(BOOL stopped) { mStopped = stopped; } 100 void setStopped(BOOL stopped) { mStopped = stopped; }
101 101
102 BOOL isBlending();
103
102 void activate(); 104 void activate();
103 105
104 void deactivate(); 106 void deactivate();
105 107
106 BOOL isActive() { return mActive; } 108 BOOL isActive() { return mActive; }
107 109
108
109public: 110public:
110 //------------------------------------------------------------------------- 111 //-------------------------------------------------------------------------
111 // animation callbacks to be implemented by subclasses 112 // animation callbacks to be implemented by subclasses
@@ -145,6 +146,11 @@ public:
145 // called when a motion is deactivated 146 // called when a motion is deactivated
146 virtual void onDeactivate() = 0; 147 virtual void onDeactivate() = 0;
147 148
149 // can we crossfade this motion with a new instance when restarted?
150 // should ultimately always be TRUE, but lack of emote blending, etc
151 // requires this
152 virtual BOOL canDeprecate();
153
148 // optional callback routine called when animation deactivated. 154 // optional callback routine called when animation deactivated.
149 void setDeactivateCallback( void (*cb)(void *), void* userdata ); 155 void setDeactivateCallback( void (*cb)(void *), void* userdata );
150 156
diff --git a/linden/indra/llcharacter/llmotioncontroller.cpp b/linden/indra/llcharacter/llmotioncontroller.cpp
index 2427fd8..aebfaf6 100644
--- a/linden/indra/llcharacter/llmotioncontroller.cpp
+++ b/linden/indra/llcharacter/llmotioncontroller.cpp
@@ -194,34 +194,44 @@ void LLMotionController::deleteAllMotions()
194//----------------------------------------------------------------------------- 194//-----------------------------------------------------------------------------
195void LLMotionController::addLoadedMotion(LLMotion* motionp) 195void LLMotionController::addLoadedMotion(LLMotion* motionp)
196{ 196{
197 std::set<LLUUID> motions_to_kill;
198
199 // gather all inactive, loaded motions
197 if (mLoadedMotions.size() > MAX_MOTION_INSTANCES) 200 if (mLoadedMotions.size() > MAX_MOTION_INSTANCES)
198 { 201 {
199 // too many motions active this frame, kill all blenders 202 // too many motions active this frame, kill all blenders
200 mPoseBlender.clearBlenders(); 203 mPoseBlender.clearBlenders();
201 204
202 for (U32 i = 0; i < mLoadedMotions.size(); i++) 205 for (motion_list_t::iterator loaded_motion_it = mLoadedMotions.begin();
206 loaded_motion_it != mLoadedMotions.end();
207 ++loaded_motion_it)
203 { 208 {
204 LLMotion* cur_motionp = mLoadedMotions.front(); 209 LLMotion* cur_motionp = *loaded_motion_it;
205 mLoadedMotions.pop_front();
206 210
207 // motion isn't playing, delete it 211 // motion isn't playing, delete it
208 if (!isMotionActive(cur_motionp)) 212 if (!isMotionActive(cur_motionp))
209 { 213 {
210 mCharacter->requestStopMotion(cur_motionp); 214 motions_to_kill.insert(cur_motionp->getID());
211 mAllMotions.erase(cur_motionp->getID());
212 delete cur_motionp;
213 if (mLoadedMotions.size() <= MAX_MOTION_INSTANCES)
214 {
215 break;
216 }
217 }
218 else
219 {
220 // put active motion on back
221 mLoadedMotions.push_back(cur_motionp);
222 } 215 }
223 } 216 }
224 } 217 }
218
219 // clean up all inactive, loaded motions
220 for (std::set<LLUUID>::iterator motion_it = motions_to_kill.begin();
221 motion_it != motions_to_kill.end();
222 ++motion_it)
223 {
224 // look up the motion again by ID to get canonical instance
225 // and kill it only if that one is inactive
226 LLUUID motion_id = *motion_it;
227 LLMotion* motionp = findMotion(motion_id);
228 if (motionp && !isMotionActive(motionp))
229 {
230 removeMotion(motion_id);
231 }
232 }
233
234 // add new motion to loaded list
225 mLoadedMotions.push_back(motionp); 235 mLoadedMotions.push_back(motionp);
226} 236}
227 237
@@ -280,14 +290,24 @@ BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constr
280void LLMotionController::removeMotion( const LLUUID& id) 290void LLMotionController::removeMotion( const LLUUID& id)
281{ 291{
282 LLMotion* motionp = findMotion(id); 292 LLMotion* motionp = findMotion(id);
293
294 removeMotionInstance(motionp);
295
296 mAllMotions.erase(id);
297}
298
299// removes instance of a motion from all runtime structures, but does
300// not erase entry by ID, as this could be a duplicate instance
301// use removeMotion(id) to remove all references to a given motion by id.
302void LLMotionController::removeMotionInstance(LLMotion* motionp)
303{
283 if (motionp) 304 if (motionp)
284 { 305 {
285 stopMotionLocally(id, TRUE); 306 stopMotionInstance(motionp, TRUE);
286 307
287 mLoadingMotions.erase(motionp); 308 mLoadingMotions.erase(motionp);
288 mLoadedMotions.remove(motionp); 309 mLoadedMotions.remove(motionp);
289 mActiveMotions.remove(motionp); 310 mActiveMotions.remove(motionp);
290 mAllMotions.erase(id);
291 delete motionp; 311 delete motionp;
292 } 312 }
293} 313}
@@ -348,28 +368,39 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id )
348//----------------------------------------------------------------------------- 368//-----------------------------------------------------------------------------
349BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset) 369BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset)
350{ 370{
351 // look for motion in our list of created motions 371 // do we have an instance of this motion for this character?
352 LLMotion *motion = createMotion(id); 372 LLMotion *motion = findMotion(id);
373
374 // motion that is stopping will be allowed to stop but
375 // replaced by a new instance of that motion
376 if (motion
377 && motion->canDeprecate()
378 && motion->getFadeWeight() > 0.01f // not LOD-ed out
379 && (motion->isBlending() || motion->getStopTime() != 0.f))
380 {
381 deprecateMotionInstance(motion);
382 // force creation of new instance
383 motion = NULL;
384 }
385
386 // create new motion instance
387 if (!motion)
388 {
389 motion = createMotion(id);
390 }
353 391
354 if (!motion) 392 if (!motion)
355 { 393 {
356 return FALSE; 394 return FALSE;
357 } 395 }
358 //if the motion is already active, then we're done 396 //if the motion is already active and allows deprecation, then let it keep playing
359 else if (isMotionActive(motion)) // motion is playing and... 397 else if (motion->canDeprecate() && isMotionActive(motion))
360 { 398 {
361 if (motion->isStopped()) // motion has been stopped 399 return TRUE;
362 {
363 deactivateMotion(motion, false);
364 }
365 else if (mTime < motion->mSendStopTimestamp) // motion is still active
366 {
367 return TRUE;
368 }
369 } 400 }
370 401
371// llinfos << "Starting motion " << name << llendl; 402// llinfos << "Starting motion " << name << llendl;
372 return activateMotion(motion, mTime - start_offset); 403 return activateMotionInstance(motion, mTime - start_offset);
373} 404}
374 405
375 406
@@ -380,6 +411,12 @@ BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate
380{ 411{
381 // if already inactive, return false 412 // if already inactive, return false
382 LLMotion *motion = findMotion(id); 413 LLMotion *motion = findMotion(id);
414
415 return stopMotionInstance(motion, stop_immediate);
416}
417
418BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediate)
419{
383 if (!motion) 420 if (!motion)
384 { 421 {
385 return FALSE; 422 return FALSE;
@@ -396,7 +433,7 @@ BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate
396 433
397 if (stop_immediate) 434 if (stop_immediate)
398 { 435 {
399 deactivateMotion(motion, false); 436 deactivateMotionInstance(motion);
400 } 437 }
401 return TRUE; 438 return TRUE;
402 } 439 }
@@ -492,7 +529,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
492 { 529 {
493 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) 530 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
494 { 531 {
495 deactivateMotion(motionp, false); 532 deactivateMotionInstance(motionp);
496 } 533 }
497 else if (motionp->isStopped() && mTime > motionp->getStopTime()) 534 else if (motionp->isStopped() && mTime > motionp->getStopTime())
498 { 535 {
@@ -510,7 +547,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
510 if (mLastTime <= motionp->mSendStopTimestamp) 547 if (mLastTime <= motionp->mSendStopTimestamp)
511 { 548 {
512 mCharacter->requestStopMotion( motionp ); 549 mCharacter->requestStopMotion( motionp );
513 stopMotionLocally(motionp->getID(), FALSE); 550 stopMotionInstance(motionp, FALSE);
514 } 551 }
515 } 552 }
516 else if (mTime >= motionp->mActivationTimestamp) 553 else if (mTime >= motionp->mActivationTimestamp)
@@ -538,7 +575,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
538 if (mLastTime <= motionp->mSendStopTimestamp) 575 if (mLastTime <= motionp->mSendStopTimestamp)
539 { 576 {
540 mCharacter->requestStopMotion( motionp ); 577 mCharacter->requestStopMotion( motionp );
541 stopMotionLocally(motionp->getID(), FALSE); 578 stopMotionInstance(motionp, FALSE);
542 } 579 }
543 } 580 }
544 581
@@ -546,7 +583,8 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
546 { 583 {
547 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration()) 584 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
548 { 585 {
549 deactivateMotion(motionp, true); 586 posep->setWeight(0.f);
587 deactivateMotionInstance(motionp);
550 } 588 }
551 continue; 589 continue;
552 } 590 }
@@ -572,7 +610,8 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
572 } 610 }
573 else 611 else
574 { 612 {
575 deactivateMotion(motionp, true); 613 posep->setWeight(0.f);
614 deactivateMotionInstance(motionp);
576 continue; 615 continue;
577 } 616 }
578 } 617 }
@@ -617,7 +656,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
617 if (mLastTime <= motionp->mSendStopTimestamp) 656 if (mLastTime <= motionp->mSendStopTimestamp)
618 { 657 {
619 mCharacter->requestStopMotion( motionp ); 658 mCharacter->requestStopMotion( motionp );
620 stopMotionLocally(motionp->getID(), FALSE); 659 stopMotionInstance(motionp, FALSE);
621 } 660 }
622 } 661 }
623 662
@@ -661,7 +700,7 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
661 // propagate this to the network 700 // propagate this to the network
662 // as not all viewers are guaranteed to have access to the same logic 701 // as not all viewers are guaranteed to have access to the same logic
663 mCharacter->requestStopMotion( motionp ); 702 mCharacter->requestStopMotion( motionp );
664 stopMotionLocally(motionp->getID(), FALSE); 703 stopMotionInstance(motionp, FALSE);
665 } 704 }
666 705
667 } 706 }
@@ -733,7 +772,7 @@ void LLMotionController::updateMotion()
733 // this motion should be playing 772 // this motion should be playing
734 if (!motionp->isStopped()) 773 if (!motionp->isStopped())
735 { 774 {
736 activateMotion(motionp, mTime); 775 activateMotionInstance(motionp, mTime);
737 } 776 }
738 } 777 }
739 else if (status == LLMotion::STATUS_FAILURE) 778 else if (status == LLMotion::STATUS_FAILURE)
@@ -741,6 +780,7 @@ void LLMotionController::updateMotion()
741 llinfos << "Motion " << motionp->getID() << " init failed." << llendl; 780 llinfos << "Motion " << motionp->getID() << " init failed." << llendl;
742 sRegistry.markBad(motionp->getID()); 781 sRegistry.markBad(motionp->getID());
743 mLoadingMotions.erase(curiter); 782 mLoadingMotions.erase(curiter);
783
744 mAllMotions.erase(motionp->getID()); 784 mAllMotions.erase(motionp->getID());
745 delete motionp; 785 delete motionp;
746 } 786 }
@@ -773,9 +813,9 @@ void LLMotionController::updateMotion()
773 813
774 814
775//----------------------------------------------------------------------------- 815//-----------------------------------------------------------------------------
776// activateMotion() 816// activateMotionInstance()
777//----------------------------------------------------------------------------- 817//-----------------------------------------------------------------------------
778BOOL LLMotionController::activateMotion(LLMotion *motion, F32 time) 818BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time)
779{ 819{
780 if (mLoadingMotions.find(motion) != mLoadingMotions.end()) 820 if (mLoadingMotions.find(motion) != mLoadingMotions.end())
781 { 821 {
@@ -818,23 +858,38 @@ BOOL LLMotionController::activateMotion(LLMotion *motion, F32 time)
818} 858}
819 859
820//----------------------------------------------------------------------------- 860//-----------------------------------------------------------------------------
821// deactivateMotion() 861// deactivateMotionInstance()
822//----------------------------------------------------------------------------- 862//-----------------------------------------------------------------------------
823BOOL LLMotionController::deactivateMotion(LLMotion *motion, bool remove_weight) 863BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion)
824{ 864{
825 if( remove_weight ) 865 motion->deactivate();
866
867 motion_set_t::iterator found_it = mDeprecatedMotions.find(motion);
868 if (found_it != mDeprecatedMotions.end())
826 { 869 {
827 // immediately remove pose weighting instead of letting it time out 870 // deprecated motions need to be completely excised
828 LLPose *posep = motion->getPose(); 871 removeMotionInstance(motion);
829 posep->setWeight(0.f); 872 mDeprecatedMotions.erase(found_it);
873 }
874 else
875 {
876 // for motions that we are keeping, simply remove from active queue
877 mActiveMotions.remove(motion);
830 } 878 }
831
832 motion->deactivate();
833 mActiveMotions.remove(motion);
834 879
835 return TRUE; 880 return TRUE;
836} 881}
837 882
883void LLMotionController::deprecateMotionInstance(LLMotion* motion)
884{
885 mDeprecatedMotions.insert(motion);
886
887 //fade out deprecated motion
888 stopMotionInstance(motion, FALSE);
889 //no longer canonical
890 mAllMotions.erase(motion->getID());
891}
892
838//----------------------------------------------------------------------------- 893//-----------------------------------------------------------------------------
839// isMotionActive() 894// isMotionActive()
840//----------------------------------------------------------------------------- 895//-----------------------------------------------------------------------------
@@ -857,7 +912,7 @@ bool LLMotionController::isMotionLoading(LLMotion* motion)
857//----------------------------------------------------------------------------- 912//-----------------------------------------------------------------------------
858LLMotion *LLMotionController::findMotion(const LLUUID& id) 913LLMotion *LLMotionController::findMotion(const LLUUID& id)
859{ 914{
860 return mAllMotions[id]; 915 return get_if_there<LLUUID, LLMotion*>(mAllMotions, id, NULL);
861} 916}
862 917
863//----------------------------------------------------------------------------- 918//-----------------------------------------------------------------------------
diff --git a/linden/indra/llcharacter/llmotioncontroller.h b/linden/indra/llcharacter/llmotioncontroller.h
index 959a16a..efc12d5 100644
--- a/linden/indra/llcharacter/llmotioncontroller.h
+++ b/linden/indra/llcharacter/llmotioncontroller.h
@@ -179,16 +179,21 @@ public:
179 LLMotion *findMotion( const LLUUID& id ); 179 LLMotion *findMotion( const LLUUID& id );
180 180
181protected: 181protected:
182 // internal operations act on motion instances directly
183 // as there can be duplicate motions per id during blending overlap
182 void deleteAllMotions(); 184 void deleteAllMotions();
183 void addLoadedMotion(LLMotion *motion); 185 void addLoadedMotion(LLMotion *motion);
184 BOOL activateMotion(LLMotion *motion, F32 time); 186 BOOL activateMotionInstance(LLMotion *motion, F32 time);
185 BOOL deactivateMotion(LLMotion *motion, bool remove_weight); 187 BOOL deactivateMotionInstance(LLMotion *motion);
188 void deprecateMotionInstance(LLMotion* motion);
189 BOOL stopMotionInstance(LLMotion *motion, BOOL stop_imemdiate);
190 void removeMotionInstance(LLMotion* motion);
186 void updateRegularMotions(); 191 void updateRegularMotions();
187 void updateAdditiveMotions(); 192 void updateAdditiveMotions();
188 void resetJointSignatures(); 193 void resetJointSignatures();
189 void updateMotionsByType(LLMotion::LLMotionBlendType motion_type); 194 void updateMotionsByType(LLMotion::LLMotionBlendType motion_type);
190protected:
191 195
196protected:
192 F32 mTimeFactor; 197 F32 mTimeFactor;
193 static LLMotionRegistry sRegistry; 198 static LLMotionRegistry sRegistry;
194 LLPoseBlender mPoseBlender; 199 LLPoseBlender mPoseBlender;
@@ -203,11 +208,13 @@ protected:
203// Once an animations is loaded, it will be initialized and put on the mLoadedMotions deque. 208// Once an animations is loaded, it will be initialized and put on the mLoadedMotions deque.
204// Any animation that is currently playing also sits in the mActiveMotions list. 209// Any animation that is currently playing also sits in the mActiveMotions list.
205 210
206 std::map<LLUUID, LLMotion*> mAllMotions; 211 typedef std::map<LLUUID, LLMotion*> motion_map_t;
212 motion_map_t mAllMotions;
207 213
208 motion_set_t mLoadingMotions; 214 motion_set_t mLoadingMotions;
209 motion_list_t mLoadedMotions; 215 motion_list_t mLoadedMotions;
210 motion_list_t mActiveMotions; 216 motion_list_t mActiveMotions;
217 motion_set_t mDeprecatedMotions;
211 218
212 LLFrameTimer mTimer; 219 LLFrameTimer mTimer;
213 F32 mTime; 220 F32 mTime;
diff --git a/linden/indra/llcharacter/llpose.cpp b/linden/indra/llcharacter/llpose.cpp
index ccedc1e..a07cd58 100644
--- a/linden/indra/llcharacter/llpose.cpp
+++ b/linden/indra/llcharacter/llpose.cpp
@@ -275,9 +275,9 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now)
275 joint_state_index < JSB_NUM_JOINT_STATES && mJointStates[joint_state_index] != NULL; 275 joint_state_index < JSB_NUM_JOINT_STATES && mJointStates[joint_state_index] != NULL;
276 joint_state_index++) 276 joint_state_index++)
277 { 277 {
278 U32 current_usage = mJointStates[joint_state_index]->getUsage();
279 F32 current_weight = mJointStates[joint_state_index]->getWeight();
280 LLJointState* jsp = mJointStates[joint_state_index]; 278 LLJointState* jsp = mJointStates[joint_state_index];
279 U32 current_usage = jsp->getUsage();
280 F32 current_weight = jsp->getWeight();
281 281
282 if (current_weight == 0.f) 282 if (current_weight == 0.f)
283 { 283 {
@@ -292,17 +292,14 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now)
292 292
293 // add in pos for this jointstate modulated by weight 293 // add in pos for this jointstate modulated by weight
294 added_pos += jsp->getPosition() * (new_weight_sum - sum_weights[POS_WEIGHT]); 294 added_pos += jsp->getPosition() * (new_weight_sum - sum_weights[POS_WEIGHT]);
295 //sum_weights[POS_WEIGHT] = new_weight_sum;
296 } 295 }
297 296
298 // now do scale
299 if(current_usage & LLJointState::SCALE) 297 if(current_usage & LLJointState::SCALE)
300 { 298 {
301 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]); 299 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]);
302 300
303 // add in scale for this jointstate modulated by weight 301 // add in scale for this jointstate modulated by weight
304 added_scale += jsp->getScale() * (new_weight_sum - sum_weights[SCALE_WEIGHT]); 302 added_scale += jsp->getScale() * (new_weight_sum - sum_weights[SCALE_WEIGHT]);
305 //sum_weights[SCALE_WEIGHT] = new_weight_sum;
306 } 303 }
307 304
308 if (current_usage & LLJointState::ROT) 305 if (current_usage & LLJointState::ROT)
@@ -311,7 +308,6 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now)
311 308
312 // add in rotation for this jointstate modulated by weight 309 // add in rotation for this jointstate modulated by weight
313 added_rot = nlerp((new_weight_sum - sum_weights[ROT_WEIGHT]), added_rot, jsp->getRotation()) * added_rot; 310 added_rot = nlerp((new_weight_sum - sum_weights[ROT_WEIGHT]), added_rot, jsp->getRotation()) * added_rot;
314 //sum_weights[ROT_WEIGHT] = new_weight_sum;
315 } 311 }
316 } 312 }
317 else 313 else
@@ -326,13 +322,13 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now)
326 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]); 322 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]);
327 323
328 // blend positions from both 324 // blend positions from both
329 blended_pos = lerp(mJointStates[joint_state_index]->getPosition(), blended_pos, sum_weights[POS_WEIGHT] / new_weight_sum); 325 blended_pos = lerp(jsp->getPosition(), blended_pos, sum_weights[POS_WEIGHT] / new_weight_sum);
330 sum_weights[POS_WEIGHT] = new_weight_sum; 326 sum_weights[POS_WEIGHT] = new_weight_sum;
331 } 327 }
332 else 328 else
333 { 329 {
334 // copy position from current 330 // copy position from current
335 blended_pos = mJointStates[joint_state_index]->getPosition(); 331 blended_pos = jsp->getPosition();
336 sum_weights[POS_WEIGHT] = current_weight; 332 sum_weights[POS_WEIGHT] = current_weight;
337 } 333 }
338 } 334 }
@@ -345,13 +341,13 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now)
345 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]); 341 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]);
346 342
347 // blend scales from both 343 // blend scales from both
348 blended_scale = lerp(mJointStates[joint_state_index]->getScale(), blended_scale, sum_weights[SCALE_WEIGHT] / new_weight_sum); 344 blended_scale = lerp(jsp->getScale(), blended_scale, sum_weights[SCALE_WEIGHT] / new_weight_sum);
349 sum_weights[SCALE_WEIGHT] = new_weight_sum; 345 sum_weights[SCALE_WEIGHT] = new_weight_sum;
350 } 346 }
351 else 347 else
352 { 348 {
353 // copy scale from current 349 // copy scale from current
354 blended_scale = mJointStates[joint_state_index]->getScale(); 350 blended_scale = jsp->getScale();
355 sum_weights[SCALE_WEIGHT] = current_weight; 351 sum_weights[SCALE_WEIGHT] = current_weight;
356 } 352 }
357 } 353 }
@@ -364,13 +360,13 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now)
364 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]); 360 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]);
365 361
366 // blend rotations from both 362 // blend rotations from both
367 blended_rot = nlerp(sum_weights[ROT_WEIGHT] / new_weight_sum, mJointStates[joint_state_index]->getRotation(), blended_rot); 363 blended_rot = nlerp(sum_weights[ROT_WEIGHT] / new_weight_sum, jsp->getRotation(), blended_rot);
368 sum_weights[ROT_WEIGHT] = new_weight_sum; 364 sum_weights[ROT_WEIGHT] = new_weight_sum;
369 } 365 }
370 else 366 else
371 { 367 {
372 // copy rotation from current 368 // copy rotation from current
373 blended_rot = mJointStates[joint_state_index]->getRotation(); 369 blended_rot = jsp->getRotation();
374 sum_weights[ROT_WEIGHT] = current_weight; 370 sum_weights[ROT_WEIGHT] = current_weight;
375 } 371 }
376 } 372 }
diff --git a/linden/indra/llcharacter/llpose.h b/linden/indra/llcharacter/llpose.h
index f57f7de..4e1bb64 100644
--- a/linden/indra/llcharacter/llpose.h
+++ b/linden/indra/llcharacter/llpose.h
@@ -81,7 +81,7 @@ public:
81 S32 getNumJointStates() const; 81 S32 getNumJointStates() const;
82}; 82};
83 83
84const S32 JSB_NUM_JOINT_STATES = 4; 84const S32 JSB_NUM_JOINT_STATES = 6;
85 85
86class LLJointStateBlender 86class LLJointStateBlender
87{ 87{
diff --git a/linden/indra/llcommon/indra_constants.h b/linden/indra/llcommon/indra_constants.h
index 9024b12..21635b5 100644
--- a/linden/indra/llcommon/indra_constants.h
+++ b/linden/indra/llcommon/indra_constants.h
@@ -130,10 +130,12 @@ const char CLOUD_LAYER_CODE = '8';
130 130
131// keys 131// keys
132// Bit masks for various keyboard modifier keys. 132// Bit masks for various keyboard modifier keys.
133const MASK MASK_NONE = 0x0000; 133const MASK MASK_NONE = 0x0000;
134const MASK MASK_CONTROL = 0x0001; 134const MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs
135const MASK MASK_ALT = 0x0002; 135const MASK MASK_ALT = 0x0002;
136const MASK MASK_SHIFT = 0x0004; 136const MASK MASK_SHIFT = 0x0004;
137const MASK MASK_NORMALKEYS = 0x0007; // A real mask - only get the bits for normal modifier keys
138const MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows
137 139
138// Special keys go into >128 140// Special keys go into >128
139const KEY KEY_SPECIAL = 0x80; // special keys start here 141const KEY KEY_SPECIAL = 0x80; // special keys start here
diff --git a/linden/indra/llcommon/llapr.h b/linden/indra/llcommon/llapr.h
index e7b12d5..6edfc18 100644
--- a/linden/indra/llcommon/llapr.h
+++ b/linden/indra/llcommon/llapr.h
@@ -31,7 +31,7 @@
31#ifndef LL_LLAPR_H 31#ifndef LL_LLAPR_H
32#define LL_LLAPR_H 32#define LL_LLAPR_H
33 33
34#if LL_LINUX 34#if LL_LINUX || LL_SOLARIS
35#include <sys/param.h> // Need PATH_MAX in APR headers... 35#include <sys/param.h> // Need PATH_MAX in APR headers...
36#endif 36#endif
37 37
diff --git a/linden/indra/llcommon/llcommon.vcproj b/linden/indra/llcommon/llcommon.vcproj
index 399dae3..5557f94 100644
--- a/linden/indra/llcommon/llcommon.vcproj
+++ b/linden/indra/llcommon/llcommon.vcproj
@@ -445,9 +445,6 @@
445 RelativePath=".\llnametable.h"> 445 RelativePath=".\llnametable.h">
446 </File> 446 </File>
447 <File 447 <File
448 RelativePath=".\llpagemem.h">
449 </File>
450 <File
451 RelativePath=".\llpreprocessor.h"> 448 RelativePath=".\llpreprocessor.h">
452 </File> 449 </File>
453 <File 450 <File
diff --git a/linden/indra/llcommon/lldate.cpp b/linden/indra/llcommon/lldate.cpp
index ccc314d..47e5370 100644
--- a/linden/indra/llcommon/lldate.cpp
+++ b/linden/indra/llcommon/lldate.cpp
@@ -72,6 +72,54 @@ std::string LLDate::asString() const
72 return stream.str(); 72 return stream.str();
73} 73}
74 74
75//@ brief Converts time in seconds since EPOCH
76// to RFC 1123 compliant date format
77// E.g. 1184797044.037586 == Wednesday, 18 Jul 2007 22:17:24 GMT
78// in RFC 1123. HTTP dates are always in GMT and RFC 1123
79// is one of the standards used and the prefered format
80std::string LLDate::asRFC1123() const
81{
82 std::ostringstream stream;
83 toHTTPDateStream(stream);
84 return stream.str();
85}
86
87void LLDate::toHTTPDateStream(std::ostream& s) const
88{
89 // http://apr.apache.org/docs/apr/0.9/group__apr__time.html
90 apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC);
91
92 apr_time_exp_t exp_time ; //Apache time module
93
94 if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS)
95 {
96 // Return Epoch UTC date
97 s << "Thursday, 01 Jan 1970 00:00:00 GMT" ;
98 return;
99 }
100
101 s << std::dec << std::setfill('0');
102#if( LL_WINDOWS || __GNUC__ > 2)
103 s << std::right ;
104#else
105 s.setf(ios::right);
106#endif
107 std::string day = weekdays[exp_time.tm_wday];
108 std::string month = months[exp_time.tm_mon];
109
110 s << std::setw(day.length()) << (day)
111 << ", " << std::setw(2) << (exp_time.tm_mday)
112 << ' ' << std::setw(month.length()) << (month)
113 << ' ' << std::setw(4) << (exp_time.tm_year + 1900)
114 << ' ' << std::setw(2) << (exp_time.tm_hour)
115 << ':' << std::setw(2) << (exp_time.tm_min)
116 << ':' << std::setw(2) << (exp_time.tm_sec)
117 << " GMT";
118
119 // RFC 1123 date does not use microseconds
120 llinfos << "Date in RFC 1123 format is " << s << llendl;
121}
122
75void LLDate::toStream(std::ostream& s) const 123void LLDate::toStream(std::ostream& s) const
76{ 124{
77 apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC); 125 apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC);
diff --git a/linden/indra/llcommon/lldate.h b/linden/indra/llcommon/lldate.h
index f8bd625..5d90a54 100644
--- a/linden/indra/llcommon/lldate.h
+++ b/linden/indra/llcommon/lldate.h
@@ -77,7 +77,9 @@ public:
77 * @return A string representation of the date. 77 * @return A string representation of the date.
78 */ 78 */
79 std::string asString() const; 79 std::string asString() const;
80 std::string asRFC1123() const;
80 void toStream(std::ostream&) const; 81 void toStream(std::ostream&) const;
82 void toHTTPDateStream(std::ostream&) const;
81 /** 83 /**
82 * @brief Set the date from an ISO-8601 string. 84 * @brief Set the date from an ISO-8601 string.
83 * 85 *
@@ -119,4 +121,8 @@ std::ostream& operator<<(std::ostream& s, const LLDate& date);
119std::istream& operator>>(std::istream& s, LLDate& date); 121std::istream& operator>>(std::istream& s, LLDate& date);
120 122
121 123
124const static std::string weekdays[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
125
126const static std::string months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
127
122#endif // LL_LLDATE_H 128#endif // LL_LLDATE_H
diff --git a/linden/indra/llcommon/llfasttimer.cpp b/linden/indra/llcommon/llfasttimer.cpp
index 2b1d58f..6c0f9ac 100644
--- a/linden/indra/llcommon/llfasttimer.cpp
+++ b/linden/indra/llcommon/llfasttimer.cpp
@@ -33,7 +33,7 @@
33#if LL_WINDOWS 33#if LL_WINDOWS
34#include <time.h> 34#include <time.h>
35 35
36#elif LL_LINUX 36#elif LL_LINUX || LL_SOLARIS
37#include <time.h> 37#include <time.h>
38#include <sys/time.h> 38#include <sys/time.h>
39#include <sched.h> 39#include <sched.h>
@@ -91,7 +91,7 @@ U64 get_cpu_clock_count()
91#endif // LL_WINDOWS 91#endif // LL_WINDOWS
92 92
93 93
94#if LL_LINUX 94#if (LL_LINUX || LL_SOLARIS) && (defined(__i386__) || defined(__amd64__))
95U64 get_cpu_clock_count() 95U64 get_cpu_clock_count()
96{ 96{
97 U64 x; 97 U64 x;
@@ -100,7 +100,7 @@ U64 get_cpu_clock_count()
100} 100}
101#endif 101#endif
102 102
103#if LL_DARWIN 103#if LL_DARWIN || (LL_SOLARIS && defined(__sparc__))
104// 104//
105// Mac implementation of CPU clock 105// Mac implementation of CPU clock
106// 106//
@@ -115,7 +115,7 @@ U64 get_cpu_clock_count()
115////////////////////////////////////////////////////////////////////////////// 115//////////////////////////////////////////////////////////////////////////////
116 116
117//static 117//static
118#if LL_LINUX || LL_DARWIN 118#if LL_LINUX || LL_DARWIN || LL_SOLARIS
119// Both Linux and Mac use gettimeofday for accurate time 119// Both Linux and Mac use gettimeofday for accurate time
120U64 LLFastTimer::countsPerSecond() 120U64 LLFastTimer::countsPerSecond()
121{ 121{
diff --git a/linden/indra/llcommon/llfixedbuffer.cpp b/linden/indra/llcommon/llfixedbuffer.cpp
index 397fcfd..6defd92 100644
--- a/linden/indra/llcommon/llfixedbuffer.cpp
+++ b/linden/indra/llcommon/llfixedbuffer.cpp
@@ -82,7 +82,7 @@ void LLFixedBuffer::setMaxLines(S32 max_lines)
82 82
83void LLFixedBuffer::removeExtraLines() 83void LLFixedBuffer::removeExtraLines()
84{ 84{
85 while ((S32)mLines.size() > llmax(0, (S32)(mMaxLines - 1))) 85 while ((S32)mLines.size() > llmax((S32)0, (S32)(mMaxLines - 1)))
86 { 86 {
87 mLines.pop_front(); 87 mLines.pop_front();
88 mAddTimes.pop_front(); 88 mAddTimes.pop_front();
diff --git a/linden/indra/llcommon/llhash.h b/linden/indra/llcommon/llhash.h
index c3c4ec9..793783f 100644
--- a/linden/indra/llcommon/llhash.h
+++ b/linden/indra/llcommon/llhash.h
@@ -42,6 +42,8 @@
42# else 42# else
43# include <hashtable.h> 43# include <hashtable.h>
44# endif 44# endif
45#elif LL_SOLARIS
46#include <ext/hashtable.h>
45#else 47#else
46#error Please define your platform. 48#error Please define your platform.
47#endif 49#endif
@@ -53,7 +55,7 @@ template<class T> inline size_t llhash(T value)
53#elif ( (defined _STLPORT_VERSION) || ((LL_LINUX) && (__GNUC__ <= 2)) ) 55#elif ( (defined _STLPORT_VERSION) || ((LL_LINUX) && (__GNUC__ <= 2)) )
54 std::hash<T> H; 56 std::hash<T> H;
55 return H(value); 57 return H(value);
56#elif LL_DARWIN || LL_LINUX 58#elif LL_DARWIN || LL_LINUX || LL_SOLARIS
57 __gnu_cxx::hash<T> H; 59 __gnu_cxx::hash<T> H;
58 return H(value); 60 return H(value);
59#else 61#else
diff --git a/linden/indra/llcommon/llmemory.cpp b/linden/indra/llcommon/llmemory.cpp
index 284c8e7..65f3409 100644
--- a/linden/indra/llcommon/llmemory.cpp
+++ b/linden/indra/llcommon/llmemory.cpp
@@ -69,6 +69,7 @@ S32 LLMemType::sCurType = LLMemType::MTYPE_INIT;
69S32 LLMemType::sType[LLMemType::MTYPE_MAX_DEPTH]; 69S32 LLMemType::sType[LLMemType::MTYPE_MAX_DEPTH];
70S32 LLMemType::sMemCount[LLMemType::MTYPE_NUM_TYPES] = { 0 }; 70S32 LLMemType::sMemCount[LLMemType::MTYPE_NUM_TYPES] = { 0 };
71S32 LLMemType::sMaxMemCount[LLMemType::MTYPE_NUM_TYPES] = { 0 }; 71S32 LLMemType::sMaxMemCount[LLMemType::MTYPE_NUM_TYPES] = { 0 };
72S32 LLMemType::sNewCount[LLMemType::MTYPE_NUM_TYPES] = { 0 };
72S32 LLMemType::sOverheadMem = 0; 73S32 LLMemType::sOverheadMem = 0;
73 74
74const char* LLMemType::sTypeDesc[LLMemType::MTYPE_NUM_TYPES] = 75const char* LLMemType::sTypeDesc[LLMemType::MTYPE_NUM_TYPES] =
@@ -133,7 +134,7 @@ void LLMemType::printMem()
133 { 134 {
134 if (sMemCount[i]) 135 if (sMemCount[i])
135 { 136 {
136 llinfos << llformat("MEM: % 20s %03d MB (%03d MB)",sTypeDesc[i],sMemCount[i]>>20,sMaxMemCount[i]>>20) << llendl; 137 llinfos << llformat("MEM: % 20s %03d MB (%03d MB) in %06d News",sTypeDesc[i],sMemCount[i]>>20,sMaxMemCount[i]>>20, sNewCount[i]) << llendl;
137 } 138 }
138 misc_mem -= sMemCount[i]; 139 misc_mem -= sMemCount[i];
139 } 140 }
@@ -180,6 +181,7 @@ void* ll_allocate (size_t size)
180 { 181 {
181 LLMemType::sMaxMemCount[LLMemType::sCurType] = LLMemType::sMemCount[LLMemType::sCurType]; 182 LLMemType::sMaxMemCount[LLMemType::sCurType] = LLMemType::sMemCount[LLMemType::sCurType];
182 } 183 }
184 LLMemType::sNewCount[LLMemType::sCurType]++;
183#endif 185#endif
184 return (void*)p; 186 return (void*)p;
185} 187}
@@ -205,6 +207,7 @@ void ll_release (void *pin)
205#if MEM_TRACK_TYPE 207#if MEM_TRACK_TYPE
206 LLMemType::sMemCount[type] -= size; 208 LLMemType::sMemCount[type] -= size;
207 LLMemType::sOverheadMem -= 4; 209 LLMemType::sOverheadMem -= 4;
210 LLMemType::sNewCount[type]--;
208#endif 211#endif
209 LLMemType::sTotalMem -= size; 212 LLMemType::sTotalMem -= size;
210 free(p); 213 free(p);
diff --git a/linden/indra/llcommon/llmemtype.h b/linden/indra/llcommon/llmemtype.h
index 501b5f5..9bab72e 100644
--- a/linden/indra/llcommon/llmemtype.h
+++ b/linden/indra/llcommon/llmemtype.h
@@ -41,6 +41,7 @@ extern void ll_release (void *p);
41#define MEM_TRACK_TYPE (1 && MEM_TRACK_MEM) 41#define MEM_TRACK_TYPE (1 && MEM_TRACK_MEM)
42 42
43#if MEM_TRACK_TYPE 43#if MEM_TRACK_TYPE
44#define MEM_DUMP_DATA 1
44#define MEM_TYPE_NEW(T) \ 45#define MEM_TYPE_NEW(T) \
45static void* operator new(size_t s) { LLMemType mt(T); return ll_allocate(s); } \ 46static void* operator new(size_t s) { LLMemType mt(T); return ll_allocate(s); } \
46static void operator delete(void* p) { ll_release(p); } 47static void operator delete(void* p) { ll_release(p); }
@@ -143,6 +144,7 @@ public:
143 static S32 sType[MTYPE_MAX_DEPTH]; 144 static S32 sType[MTYPE_MAX_DEPTH];
144 static S32 sMemCount[MTYPE_NUM_TYPES]; 145 static S32 sMemCount[MTYPE_NUM_TYPES];
145 static S32 sMaxMemCount[MTYPE_NUM_TYPES]; 146 static S32 sMaxMemCount[MTYPE_NUM_TYPES];
147 static S32 sNewCount[MTYPE_NUM_TYPES];
146 static S32 sOverheadMem; 148 static S32 sOverheadMem;
147 static const char* sTypeDesc[MTYPE_NUM_TYPES]; 149 static const char* sTypeDesc[MTYPE_NUM_TYPES];
148#endif 150#endif
diff --git a/linden/indra/llcommon/llpagemem.h b/linden/indra/llcommon/llpagemem.h
deleted file mode 100644
index f3d6061..0000000
--- a/linden/indra/llcommon/llpagemem.h
+++ /dev/null
@@ -1,393 +0,0 @@
1/**
2 * @file llpagemem.h
3 *
4 * Copyright (c) 2002-2007, Linden Research, Inc.
5 *
6 * Second Life Viewer Source Code
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27#ifndef LL_LLPAGEMEM_H
28#define LL_LLPAGEMEM_H
29
30#if !LL_DARWIN
31#include "malloc.h"
32#endif
33
34#include "llrand.h"
35
36
37#ifndef __GNUC__
38template <class Object, U32 mPageSize=1024>
39class LLPageMemory
40{
41private:
42
43 union XObject
44 {
45 XObject *mNextFreeObject;
46 U8 mObject[sizeof(Object)];
47 };
48
49 template <U32 mPageSize> struct Page
50 {
51 XObject *mFirstFreeObject;
52 U32 mObjectCount;
53 U8 mObjects[mPageSize-8];
54
55 void init(U32 mObjPerPage)
56 {
57 XObject *o = (XObject*)&mObjects;
58 mObjectCount = 0;
59 mFirstFreeObject = o;
60
61 for (U32 i = 0; i < mObjPerPage-1; i++)
62 {
63 o->mNextFreeObject = o+1;
64 o++;
65 }
66 o->mNextFreeObject = NULL;
67 };
68
69 Object* alloc()
70 {
71 if (mFirstFreeObject)
72 {
73 XObject *ret = mFirstFreeObject;
74 mFirstFreeObject = mFirstFreeObject->mNextFreeObject;
75 ret->mNextFreeObject = NULL;
76 mObjectCount++;
77 return (Object*)&ret->mObject;
78 };
79 return NULL;
80 }
81 };
82
83 U32 mObjPerPage;
84 U32 mMaxPages;
85 U32 mObjectCount;
86
87 Page<mPageSize>* mPageMemory;
88 Page<mPageSize>* mFirstPage;
89
90public:
91 U32 precise, anywhere, fail;
92
93 void init()
94 {
95 Page<mPageSize> *p = mFirstPage;
96 for (U32 i = 0; i < mMaxPages; i++)
97 {
98 p[i].init(mObjPerPage);
99 }
100
101 precise = 0;
102 anywhere = 0;
103 fail = 0;
104 };
105
106public:
107
108 Page<mPageSize>* pageof(Object *object)
109 {
110 return (Page<mPageSize>*) ((((U32)object - 8) / mPageSize) * mPageSize );
111 }
112
113 LLPageMemory(U32 maxObjects)
114 {
115 mObjPerPage = (mPageSize-8) / sizeof(Object);
116 mMaxPages = (maxObjects / mObjPerPage) + 1;
117 mObjectCount= 0;
118
119 //printf("%d objects per page, %d pages total, %d/%d objects\n",
120 // mObjPerPage, mMaxPages, mMaxPages * mObjPerPage,maxObjects);
121
122 mPageMemory = (Page<mPageSize>*)calloc(mPageSize,mMaxPages+1);
123 mFirstPage = mPageMemory;
124 U32 fix = ((U32)mPageMemory % mPageSize);
125 if (fix) mFirstPage = (Page<mPageSize>*)((U32)mPageMemory+mPageSize-fix);
126
127 //printf("fix = %d\n",fix);
128
129 init();
130 };
131
132 LLPageMemory(void *pageMem, U32 bytes)
133 {
134 }
135
136 ~LLPageMemory()
137 {
138 if (mPageMemory)
139 {
140 free(mPageMemory);
141 }
142 }
143
144 Object* alloc(Object *after=NULL)
145 {
146 Page<mPageSize> * p = mFirstPage;
147 Object * o = NULL;
148 U32 i = mMaxPages;
149
150 if (after)
151 {
152 o = pageof(after)->alloc();
153 if (o)
154 {
155 precise++;
156 return o;
157 }
158 return NULL;
159 }
160
161 F32 frac = 1.0f / (F32)mMaxPages;
162 F32 thresh = 0.0f;
163 for (i = 0; i < mMaxPages; i++)
164 {
165 if (thresh > ((F32)p[i].mObjectCount / (F32)mObjPerPage))
166 {
167 o = p[i].alloc();
168 if (o)
169 {
170 //printf("allocating page %x obj %x\n",p, o);
171 anywhere++;
172 return o;
173 }
174 }
175 thresh += frac;
176 }
177
178 fail++;
179 return NULL;
180 };
181
182 void free(Object *o)
183 {
184 if (!o) return;
185
186 Page<mPageSize> *page = pageof(o);
187 XObject *obj = (XObject*)o;
188
189 //printf("freeing %x\n",obj);
190
191 obj->mNextFreeObject = page->mFirstFreeObject;
192 page->mFirstFreeObject = obj;
193 page->mObjectCount--;
194
195 //printf("freeing page %x %d\n",page, page->mObjectCount);
196 };
197
198 U32 indexof(Object *object)
199 {
200 if (!object) return -1;
201
202 return ((((U32)object-8) % mPageSize) / sizeof(Object)) +
203 ((pageof(object) - mFirstPage) * mObjPerPage);
204 }
205
206
207 void dump()
208 {
209
210 for (U32 i=0;i < mMaxPages;i++)
211 {
212 //printf("page %d %d/%d objects\n",i,mFirstPage[i].mObjectCount,mObjPerPage);
213 }
214 //printf("precise = %d anywhere %d ratio = %f\n",precise,anywhere,(F32)precise/(F32)(anywhere+precise));
215 //printf("fail = %d\n",fail);
216
217 }
218
219 static void test()
220 {
221 struct Foo
222 {
223 U32 ord;
224 U32 foo[8];
225 };
226
227 const U32 count = 100;
228 U32 i,c;
229 U32 mix = 50;
230
231 LLPageMemory<Foo> mem(count);
232 LLRand rand(LLUUID::getRandomSeed());
233
234 Foo *obj[count];
235
236 for (i=0;i<count;i++) obj[i] = 0;
237
238 U32 x= 0;
239 for (U32 run=0; run < 10000 ;run++)
240 {
241 U32 m =rand.llrand(count);
242 for (c=0;c < m;c++)
243 {
244 U32 j = rand.llrand(count);
245 if (obj[j])
246 {
247 mem.free(obj[j]);
248 obj[j] = 0;
249 }
250 }
251
252 m =rand.llrand(count);
253 for (c=0;c<m;c++)
254 {
255 U32 i = rand.llrand(count);
256 while (obj[i] && i < count) i++;
257
258 if (!obj[i])
259 {
260 if (i > 0) obj[i] = mem.alloc(obj[i-1]);
261 else obj[i] = mem.alloc();
262 if (obj[i]) obj[i]->ord = x++;
263 }
264 }
265 }
266
267 for (i = 0; i< count; i++)
268 {
269 //printf("obj[%2d] = %08x %02d %4d\n",i,obj[i],mem.indexof(obj[i]),(obj[i] ? obj[i]->ord : -1));
270 }
271
272 mem.dump();
273 }
274};
275
276
277template <class Object>
278class LLObjectPool
279{
280private:
281
282 class XObject
283 {
284 public:
285 Object mObject;
286 U32 mNextFreeObject;
287
288 XObject() { mObject = NULL; mNextFreeObject = 0; }
289 };
290
291 U32 mNumObjects;
292 U32 mMaxObjects;
293 XObject* mObjects;
294 U32 mFirstFreeObject;
295
296 U32 indexof(XObject *xobj) { return (xobj - mObjects); }
297
298public:
299 LLObjectPool(U32 maxObjects)
300 {
301 mMaxObjects = maxObjects;
302 mFirstFreeObject = 0;
303
304 mObjects = new XObject[mMaxObjects];
305
306 //printf("objectpool allocated %d bytes\n",sizeof(XObject) * mMaxObjects);
307
308 for (U32 i=0;i<mMaxObjects;i++) mObjects[i].mNextFreeObject = i+1;
309 };
310
311 ~LLObjectPool()
312 {
313 delete [] mObjects;
314 mObjects = NULL;
315 }
316
317 Object* alloc(Object *after=NULL)
318 {
319 XObject *obj = &mObjects[mFirstFreeObject];
320 mFirstFreeObject = obj->mNextFreeObject;
321 if (mFirstFreeObject >= mMaxObjects)
322 {
323 llerrs << "Attempted to allocate too many objects out of pool\n" << llendl;
324 llassert(0);
325 }
326 return &obj->mObject;
327 };
328
329 void free(Object *obj)
330 {
331 if (!obj) return;
332 XObject *xobj = (XObject*)obj;
333 xobj->mNextFreeObject = mFirstFreeObject;
334 mFirstFreeObject = indexof(xobj);
335 };
336
337 static void test()
338 {
339 struct Foo
340 {
341 U32 ord;
342 U32 foo[8];
343 };
344
345 const U32 count = 100;
346 U32 i,c;
347 U32 mix = 50;
348
349 LLPageMemory<Foo> mem(count);
350 LLRand rand(LLUUID::getRandomSeed());
351
352 Foo *obj[count];
353
354 for (i=0;i<count;i++) obj[i] = 0;
355
356 U32 x= 0;
357 for (U32 run=0; run < 10000 ;run++)
358 {
359 U32 m =rand.llrand(count);
360 for (c=0;c < m;c++)
361 {
362 U32 j = rand.llrand(count);
363 if (obj[j])
364 {
365 mem.free(obj[j]);
366 obj[j] = 0;
367 }
368 }
369
370 m =rand.llrand(count);
371 for (c=0;c<m;c++)
372 {
373 U32 i = rand.llrand(count);
374 while (obj[i] && i < count) i++;
375
376 if (!obj[i])
377 {
378 if (i > 0) obj[i] = mem.alloc(obj[i-1]);
379 else obj[i] = mem.alloc();
380 if (obj[i]) obj[i]->ord = x++;
381 }
382 }
383 }
384
385 for (i = 0; i< count; i++)
386 {
387 //printf("obj[%2d] = %08x %02d %4d\n",i,obj[i],mem.indexof(obj[i]),(obj[i] ? obj[i]->ord : -1));
388 }
389 }
390};
391#endif // !defined __GNUC__
392
393#endif
diff --git a/linden/indra/llcommon/llpreprocessor.h b/linden/indra/llcommon/llpreprocessor.h
index 495b9e8..f19d5a0 100644
--- a/linden/indra/llcommon/llpreprocessor.h
+++ b/linden/indra/llcommon/llpreprocessor.h
@@ -62,6 +62,11 @@
62 #ifndef LL_LIBXUL_ENABLED 62 #ifndef LL_LIBXUL_ENABLED
63 #define LL_LIBXUL_ENABLED 1 63 #define LL_LIBXUL_ENABLED 1
64 #endif // def LL_LIBXUL_ENABLED 64 #endif // def LL_LIBXUL_ENABLED
65#elif LL_SOLARIS
66 #define LL_QUICKTIME_ENABLED 0
67 #ifndef LL_LIBXUL_ENABLED
68 #define LL_LIBXUL_ENABLED 0
69 #endif // def LL_LIBXUL_ENABLED
65#endif 70#endif
66 71
67#if LL_LIBXUL_ENABLED && !defined(MOZILLA_INTERNAL_API) 72#if LL_LIBXUL_ENABLED && !defined(MOZILLA_INTERNAL_API)
@@ -71,12 +76,22 @@
71 #define MOZILLA_INTERNAL_API 1 76 #define MOZILLA_INTERNAL_API 1
72#endif 77#endif
73 78
74// Deal with minor differences on Unixy OSes. 79// Figure out differences between compilers
75#if LL_DARWIN || LL_LINUX 80#if defined(__GNUC__)
76 #define GCC_VERSION (__GNUC__ * 10000 \ 81 #define GCC_VERSION (__GNUC__ * 10000 \
77 + __GNUC_MINOR__ * 100 \ 82 + __GNUC_MINOR__ * 100 \
78 + __GNUC_PATCHLEVEL__) 83 + __GNUC_PATCHLEVEL__)
84 #ifndef LL_GNUC
85 #define LL_GNUC 1
86 #endif
87#elif defined(__MSVC_VER__) || defined(_MSC_VER)
88 #ifndef LL_MSVC
89 #define LL_MSVC 1
90 #endif
91#endif
79 92
93// Deal with minor differences on Unixy OSes.
94#if LL_DARWIN || LL_LINUX
80 // Different name, same functionality. 95 // Different name, same functionality.
81 #define stricmp strcasecmp 96 #define stricmp strcasecmp
82 #define strnicmp strncasecmp 97 #define strnicmp strncasecmp
@@ -89,9 +104,9 @@
89#endif 104#endif
90 105
91// Deal with the differeneces on Windows 106// Deal with the differeneces on Windows
92#if LL_WINDOWS 107#if LL_MSVC
93#define snprintf safe_snprintf /* Flawfinder: ignore */ 108#define snprintf safe_snprintf /* Flawfinder: ignore */
94#endif // LL_WINDOWS 109#endif // LL_MSVC
95 110
96// Static linking with apr on windows needs to be declared. 111// Static linking with apr on windows needs to be declared.
97#ifdef LL_WINDOWS 112#ifdef LL_WINDOWS
@@ -110,7 +125,7 @@
110 125
111 126
112// Deal with VC6 problems 127// Deal with VC6 problems
113#if defined(LL_WINDOWS) 128#if LL_MSVC
114#pragma warning( 3 : 4701 ) // "local variable used without being initialized" Treat this as level 3, not level 4. 129#pragma warning( 3 : 4701 ) // "local variable used without being initialized" Treat this as level 3, not level 4.
115#pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4. 130#pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4.
116#pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4. 131#pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4.
@@ -121,6 +136,6 @@
121#pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation. 136#pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation.
122#pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) 137#pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
123#pragma warning( disable : 4996 ) // warning: deprecated 138#pragma warning( disable : 4996 ) // warning: deprecated
124#endif // LL_WINDOWS 139#endif // LL_MSVC
125 140
126#endif // not LL_LINDEN_PREPROCESSOR_H 141#endif // not LL_LINDEN_PREPROCESSOR_H
diff --git a/linden/indra/llcommon/llprocessor.cpp b/linden/indra/llcommon/llprocessor.cpp
index bd21351..4d00ab5 100644
--- a/linden/indra/llcommon/llprocessor.cpp
+++ b/linden/indra/llcommon/llprocessor.cpp
@@ -58,7 +58,7 @@
58# include <windows.h> 58# include <windows.h>
59#endif 59#endif
60 60
61#if !LL_DARWIN 61#if !LL_DARWIN && !LL_SOLARIS
62 62
63#ifdef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE 63#ifdef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE
64// We need the QueryPerformanceCounter and Sleep functions 64// We need the QueryPerformanceCounter and Sleep functions
@@ -255,24 +255,24 @@ bool CProcessor::AnalyzeIntelProcessor()
255 /* 0x03 */ "0.13 micron Intel Celeron", 255 /* 0x03 */ "0.13 micron Intel Celeron",
256 /* 0x04 */ "0.13 micron Intel Pentium III", 256 /* 0x04 */ "0.13 micron Intel Pentium III",
257 /* 0x05 */ "", 257 /* 0x05 */ "",
258 /* 0x06 */ "0.13 micron Intel Pentium III mobile", 258 /* 0x06 */ "0.13 micron Intel Pentium III Mobile",
259 /* 0x07 */ "0.13 micron Intel Celeron mobile", 259 /* 0x07 */ "0.13 micron Intel Celeron Mobile",
260 /* 0x08 */ "0.18 micron Intel Pentium 4", 260 /* 0x08 */ "0.18 micron Intel Pentium 4",
261 /* 0x09 */ "0.13 micron Intel Pentium 4", 261 /* 0x09 */ "0.13 micron Intel Pentium 4",
262 /* 0x0A */ "0.13 micron Intel Pentium 4", 262 /* 0x0A */ "0.13 micron Intel Celeron",
263 /* 0x0B */ "0.13 micron Intel Pentium 4 Xeon", 263 /* 0x0B */ "0.13 micron Intel Pentium 4 Xeon",
264 /* 0x0C */ "", 264 /* 0x0C */ "Intel Xeon MP",
265 /* 0x0D */ "", 265 /* 0x0D */ "",
266 /* 0x0E */ "0.18 micron Intel Pentium 4 Xeon", 266 /* 0x0E */ "0.18 micron Intel Pentium 4 Xeon",
267 /* 0x0F */ "", 267 /* 0x0F */ "Mobile Intel Celeron",
268 /* 0x10 */ "", 268 /* 0x10 */ "",
269 /* 0x11 */ "", 269 /* 0x11 */ "Mobile Genuine Intel",
270 /* 0x12 */ "Intel Celeron M", 270 /* 0x12 */ "Intel Celeron M",
271 /* 0x13 */ "mobile Intel Celeron", 271 /* 0x13 */ "Mobile Intel Celeron",
272 /* 0x14 */ "Intel Celeron", 272 /* 0x14 */ "Intel Celeron",
273 /* 0x15 */ "mobile Intel", 273 /* 0x15 */ "Mobile Genuine Intel",
274 /* 0x16 */ "Intel Pentium M", 274 /* 0x16 */ "Intel Pentium M",
275 /* 0x17 */ "mobile Intel Celeron", 275 /* 0x17 */ "Mobile Intel Celeron",
276 }; 276 };
277 277
278 // Only override the brand if we have it in the lookup table. We should 278 // Only override the brand if we have it in the lookup table. We should
@@ -300,7 +300,7 @@ bool CProcessor::AnalyzeIntelProcessor()
300 strcpy(CPUInfo.strFamily, "Intel Pentium"); /* Flawfinder: ignore */ 300 strcpy(CPUInfo.strFamily, "Intel Pentium"); /* Flawfinder: ignore */
301 break; 301 break;
302 case 6: // Family = 6: Pentium Pro (80686) processor family 302 case 6: // Family = 6: Pentium Pro (80686) processor family
303 strcpy(CPUInfo.strFamily, "Intel Pentium Pro"); /* Flawfinder: ignore */ 303 strcpy(CPUInfo.strFamily, "Intel Pentium Pro/2/3, Core"); /* Flawfinder: ignore */
304 break; 304 break;
305 case 15: // Family = 15: Extended family specific 305 case 15: // Family = 15: Extended family specific
306 // Masking the extended family 306 // Masking the extended family
@@ -447,17 +447,21 @@ bool CProcessor::AnalyzeIntelProcessor()
447 case 1: // Model = 8, Brand id = 1: Celeron (on-die L2 cache) processor model 447 case 1: // Model = 8, Brand id = 1: Celeron (on-die L2 cache) processor model
448 strncat(strCPUName, "Intel Celeron (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 448 strncat(strCPUName, "Intel Celeron (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
449 break; 449 break;
450 case 2: // Model = 8, Brand id = 2: Pentium III (on-die L2 cache) processor model (my current cpu :-)) 450 case 2: // Model = 8, Brand id = 2: Pentium III (on-die L2 cache) processor model (my current cpu :-))
451 strncat(strCPUName, "Intel Pentium III (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 451 strncat(strCPUName, "Intel Pentium III (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
452 break; 452 break;
453 case 3: // Model = 8, Brand id = 3: Pentium III Xeon (on-die L2 cache) processor model 453 case 3: // Model = 8, Brand id = 3: Pentium III Xeon (on-die L2 cache) processor model
454 strncat(strCPUName, "Intel Pentium III Xeon (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 454 strncat(strCPUName, "Intel Pentium III Xeon (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
455 break; 455 break;
456 default: // ... 456 default: // ...
457 strncat(strCPUName, "Intel Pentium III core (unknown model, 0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 457 strncat(strCPUName, "Intel Pentium III core (unknown model, 0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
458 break; 458 break;
459 } 459 }
460 break; 460 break;
461 case 9: // Model = 9: Intel Pentium M processor, Intel Celeron M processor, model 9
462 strcpy(CPUInfo.strModel, "Intel Pentium M Series Processor"); /*Flawfinder: ignore*/
463 strncat(strCPUName, "Intel Pentium M Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
464 break;
461 case 0xA: // Model = 0xA: Pentium III/Xeon/Celeron (1 or 2 MB on-die L2 cache) processor model 465 case 0xA: // Model = 0xA: Pentium III/Xeon/Celeron (1 or 2 MB on-die L2 cache) processor model
462 strcpy(CPUInfo.strModel, "Intel Pentium III/Celeron/Pentium III Xeon - internal L2 cache, 0.18 micron"); /*Flawfinder: ignore*/ 466 strcpy(CPUInfo.strModel, "Intel Pentium III/Celeron/Pentium III Xeon - internal L2 cache, 0.18 micron"); /*Flawfinder: ignore*/
463 // Exact detection: 467 // Exact detection:
@@ -466,11 +470,11 @@ bool CProcessor::AnalyzeIntelProcessor()
466 case 1: // Model = 0xA, Brand id = 1: Celeron (1 or 2 MB on-die L2 cache (does it exist??)) processor model 470 case 1: // Model = 0xA, Brand id = 1: Celeron (1 or 2 MB on-die L2 cache (does it exist??)) processor model
467 strncat(strCPUName, "Intel Celeron (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 471 strncat(strCPUName, "Intel Celeron (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
468 break; 472 break;
469 case 2: // Model = 0xA, Brand id = 2: Pentium III (1 or 2 MB on-die L2 cache (never seen...)) processor model 473 case 2: // Model = 0xA, Brand id = 2: Pentium III (1 or 2 MB on-die L2 cache (never seen...)) processor model
470 strncat(strCPUName, "Intel Pentium III (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 474 strncat(strCPUName, "Intel Pentium III (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
471 break; 475 break;
472 case 3: // Model = 0xA, Brand id = 3: Pentium III Xeon (1 or 2 MB on-die L2 cache) processor model 476 case 3: // Model = 0xA, Brand id = 3: Pentium III Xeon (1 or 2 MB on-die L2 cache) processor model
473 strncat(strCPUName, "Intel Pentium III Xeon (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 477 strncat(strCPUName, "Intel Pentium III Xeon (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
474 break; 478 break;
475 default: // Getting bored of this............ 479 default: // Getting bored of this............
476 strncat(strCPUName, "Intel Pentium III core (unknown model, 0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 480 strncat(strCPUName, "Intel Pentium III core (unknown model, 0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
@@ -485,20 +489,32 @@ bool CProcessor::AnalyzeIntelProcessor()
485 case 3: // Model = 0xB, Brand id = 3: Celeron (Tualatin core) processor model 489 case 3: // Model = 0xB, Brand id = 3: Celeron (Tualatin core) processor model
486 strncat(strCPUName, "Intel Celeron (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 490 strncat(strCPUName, "Intel Celeron (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
487 break; 491 break;
488 case 4: // Model = 0xB, Brand id = 4: Pentium III (Tualatin core) processor model 492 case 4: // Model = 0xB, Brand id = 4: Pentium III (Tualatin core) processor model
489 strncat(strCPUName, "Intel Pentium III (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 493 strncat(strCPUName, "Intel Pentium III (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
490 break; 494 break;
491 case 7: // Model = 0xB, Brand id = 7: Celeron mobile (Tualatin core) processor model 495 case 7: // Model = 0xB, Brand id = 7: Celeron mobile (Tualatin core) processor model
492 strncat(strCPUName, "Intel Celeron mobile (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 496 strncat(strCPUName, "Intel Celeron mobile (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
493 break; 497 break;
494 default: // *bored* 498 default: // *bored*
495 strncat(strCPUName, "Intel Pentium III Tualatin core (unknown model, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 499 strncat(strCPUName, "Intel Pentium III Tualatin core (unknown model, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
496 break; 500 break;
497 } 501 }
498 break; 502 break;
503 case 0xD: // Model = 0xD: Intel Pentium M processor, Intel Celeron M processor, model D
504 strcpy(CPUInfo.strModel, "Intel Pentium M Series Processor"); /*Flawfinder: ignore*/
505 strncat(strCPUName, "Intel Pentium M Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
506 break;
507 case 0xE: // Model = 0xE: Intel Core Duo processor, Intel Core Solo processor, model E
508 strcpy(CPUInfo.strModel, "Intel Core Series Processor"); /*Flawfinder: ignore*/
509 strncat(strCPUName, "Intel Core Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
510 break;
511 case 0xF: // Model = 0xF: Intel Core 2 Duo processor, model F
512 strcpy(CPUInfo.strModel, "Intel Core 2 Series Processor"); /*Flawfinder: ignore*/
513 strncat(strCPUName, "Intel Core 2 Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
514 break;
499 default: // *more bored* 515 default: // *more bored*
500 strcpy(CPUInfo.strModel, "Unknown Intel Pentium Pro"); /*Flawfinder: ignore*/ 516 strcpy(CPUInfo.strModel, "Unknown Intel Pentium Pro/2/3, Core"); /*Flawfinder: ignore*/
501 strncat(strCPUName, "Intel Pentium Pro (Unknown model)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ 517 strncat(strCPUName, "Intel Pentium Pro/2/3, Core (Unknown model)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/
502 break; 518 break;
503 } 519 }
504 break; 520 break;
@@ -1538,6 +1554,7 @@ void CProcessor::GetStandardProcessorExtensions()
1538 CPUInfo._Ext.FXSR_FastStreamingSIMD_ExtensionsSaveRestore = CheckBit(edxreg, 24); 1554 CPUInfo._Ext.FXSR_FastStreamingSIMD_ExtensionsSaveRestore = CheckBit(edxreg, 24);
1539 CPUInfo._Ext.SSE_StreamingSIMD_Extensions = CheckBit(edxreg, 25); 1555 CPUInfo._Ext.SSE_StreamingSIMD_Extensions = CheckBit(edxreg, 25);
1540 CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = CheckBit(edxreg, 26); 1556 CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = CheckBit(edxreg, 26);
1557 CPUInfo._Ext.Altivec_Extensions = false;
1541 CPUInfo._Ext.SS_SelfSnoop = CheckBit(edxreg, 27); 1558 CPUInfo._Ext.SS_SelfSnoop = CheckBit(edxreg, 27);
1542 CPUInfo._Ext.HT_HyperThreading = CheckBit(edxreg, 28); 1559 CPUInfo._Ext.HT_HyperThreading = CheckBit(edxreg, 28);
1543 CPUInfo._Ext.HT_HyterThreadingSiblings = (ebxreg >> 16) & 0xFF; 1560 CPUInfo._Ext.HT_HyterThreadingSiblings = (ebxreg >> 16) & 0xFF;
@@ -1643,6 +1660,125 @@ const ProcessorInfo *CProcessor::GetCPUInfo()
1643 return (&CPUInfo); 1660 return (&CPUInfo);
1644} 1661}
1645 1662
1663#elif LL_SOLARIS
1664#include <kstat.h>
1665
1666// ======================
1667// Class constructor:
1668/////////////////////////
1669CProcessor::CProcessor()
1670{
1671 uqwFrequency = 0;
1672 strCPUName[0] = 0;
1673 memset(&CPUInfo, 0, sizeof(CPUInfo));
1674}
1675
1676// unsigned __int64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs)
1677// =========================================================================
1678// Function to query the current CPU frequency
1679////////////////////////////////////////////////////////////////////////////
1680F64 CProcessor::GetCPUFrequency(unsigned int /*uiMeasureMSecs*/)
1681{
1682 if(uqwFrequency == 0){
1683 GetCPUInfo();
1684 }
1685
1686 return uqwFrequency;
1687}
1688
1689// const ProcessorInfo *CProcessor::GetCPUInfo()
1690// =============================================
1691// Calls all the other detection function to create an detailed
1692// processor information
1693///////////////////////////////////////////////////////////////
1694const ProcessorInfo *CProcessor::GetCPUInfo()
1695{
1696 // In Solaris the CPU info is in the kstats
1697 // try "psrinfo" or "kstat cpu_info" to see all
1698 // that's available
1699 int ncpus=0, i;
1700 kstat_ctl_t *kc;
1701 kstat_t *ks;
1702 kstat_named_t *ksinfo, *ksi;
1703 kstat_t *CPU_stats_list;
1704
1705 kc = kstat_open();
1706
1707 if((int)kc == -1){
1708 llwarns << "kstat_open(0 failed!" << llendl;
1709 return (&CPUInfo);
1710 }
1711
1712 for (ks = kc->kc_chain; ks != NULL; ks = ks->ks_next) {
1713 if (strncmp(ks->ks_module, "cpu_info", 8) == 0 &&
1714 strncmp(ks->ks_name, "cpu_info", 8) == 0)
1715 ncpus++;
1716 }
1717
1718 if(ncpus < 1){
1719 llwarns << "No cpus found in kstats!" << llendl;
1720 return (&CPUInfo);
1721 }
1722
1723 for (ks = kc->kc_chain; ks; ks = ks->ks_next) {
1724 if (strncmp(ks->ks_module, "cpu_info", 8) == 0
1725 && strncmp(ks->ks_name, "cpu_info", 8) == 0
1726 && kstat_read(kc, ks, NULL) != -1){
1727 CPU_stats_list = ks; // only looking at the first CPU
1728
1729 break;
1730 }
1731 }
1732
1733 if(ncpus > 1)
1734 snprintf(strCPUName, sizeof(strCPUName), "%d x ", ncpus);
1735
1736 kstat_read(kc, CPU_stats_list, NULL);
1737 ksinfo = (kstat_named_t *)CPU_stats_list->ks_data;
1738 for(i=0; i < (int)(CPU_stats_list->ks_ndata); ++i){ // Walk the kstats for this cpu gathering what we need
1739 ksi = ksinfo++;
1740 if(!strcmp(ksi->name, "brand")){
1741 strncat(strCPUName, (char *)KSTAT_NAMED_STR_PTR(ksi),
1742 sizeof(strCPUName)-strlen(strCPUName)-1);
1743 strncat(CPUInfo.strFamily, (char *)KSTAT_NAMED_STR_PTR(ksi),
1744 sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);
1745 strncpy(CPUInfo.strBrandID, strCPUName,sizeof(CPUInfo.strBrandID)-1);
1746 CPUInfo.strBrandID[sizeof(CPUInfo.strBrandID)-1]='\0';
1747 // DEBUG llinfos << "CPU brand: " << strCPUName << llendl;
1748 continue;
1749 }
1750
1751 if(!strcmp(ksi->name, "clock_MHz")){
1752#if defined(__sparc)
1753 llinfos << "Raw kstat clock rate is: " << ksi->value.l << llendl;
1754 uqwFrequency = (F64)(ksi->value.l * 1000000);
1755#else
1756 uqwFrequency = (F64)(ksi->value.i64 * 1000000);
1757#endif
1758 //DEBUG llinfos << "CPU frequency: " << uqwFrequency << llendl;
1759 continue;
1760 }
1761
1762#if defined(__i386)
1763 if(!strcmp(ksi->name, "vendor_id")){
1764 strncpy(CPUInfo.strVendor, (char *)KSTAT_NAMED_STR_PTR(ksi), sizeof(CPUInfo.strVendor)-1);
1765 // DEBUG llinfos << "CPU vendor: " << CPUInfo.strVendor << llendl;
1766 continue;
1767 }
1768#endif
1769 }
1770
1771 kstat_close(kc);
1772
1773#if defined(__sparc) // SPARC does not define a vendor string in kstat
1774 strncpy(CPUInfo.strVendor, "Sun Microsystems, Inc.", sizeof(CPUInfo.strVendor)-1);
1775#endif
1776
1777 // DEBUG llinfo << "The system has " << ncpus << " CPUs with a clock rate of " << uqwFrequency << "MHz." << llendl;
1778
1779 return (&CPUInfo);
1780}
1781
1646#else 1782#else
1647// LL_DARWIN 1783// LL_DARWIN
1648 1784
@@ -1891,11 +2027,12 @@ const ProcessorInfo *CProcessor::GetCPUInfo()
1891 break; 2027 break;
1892 } 2028 }
1893 2029
1894 // It's kinda like MMX or SSE...
1895 CPUInfo._Ext.EMMX_MultimediaExtensions = 2030 CPUInfo._Ext.EMMX_MultimediaExtensions =
1896 CPUInfo._Ext.MMX_MultimediaExtensions = 2031 CPUInfo._Ext.MMX_MultimediaExtensions =
1897 CPUInfo._Ext.SSE_StreamingSIMD_Extensions = 2032 CPUInfo._Ext.SSE_StreamingSIMD_Extensions =
1898 CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = hasFeature("hw.optional.altivec"); 2033 CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = false;
2034
2035 CPUInfo._Ext.Altivec_Extensions = hasFeature("hw.optional.altivec");
1899 2036
1900#endif 2037#endif
1901 2038
@@ -1912,6 +2049,7 @@ const ProcessorInfo *CProcessor::GetCPUInfo()
1912 CPUInfo._Ext.MMX_MultimediaExtensions = hasFeature("hw.optional.mmx"); 2049 CPUInfo._Ext.MMX_MultimediaExtensions = hasFeature("hw.optional.mmx");
1913 CPUInfo._Ext.SSE_StreamingSIMD_Extensions = hasFeature("hw.optional.sse"); 2050 CPUInfo._Ext.SSE_StreamingSIMD_Extensions = hasFeature("hw.optional.sse");
1914 CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = hasFeature("hw.optional.sse2"); 2051 CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = hasFeature("hw.optional.sse2");
2052 CPUInfo._Ext.Altivec_Extensions = false;
1915 CPUInfo._Ext.AA64_AMD64BitArchitecture = hasFeature("hw.optional.x86_64"); 2053 CPUInfo._Ext.AA64_AMD64BitArchitecture = hasFeature("hw.optional.x86_64");
1916 2054
1917#endif 2055#endif
@@ -2015,6 +2153,7 @@ bool CProcessor::CPUInfoToText(char *strBuffer, unsigned int uiMaxLen)
2015 { 2153 {
2016 COPYADD("Processor Serial: Disabled\n"); 2154 COPYADD("Processor Serial: Disabled\n");
2017 } 2155 }
2156#if !LL_SOLARIS // NOTE: Why bother printing all this when it's irrelavent
2018 2157
2019 COPYADD("\n\n// CPU Configuration\n////////////////////\n"); 2158 COPYADD("\n\n// CPU Configuration\n////////////////////\n");
2020 FORMATADD("L1 instruction cache: %s\n", CPUInfo._L1.Instruction.strCache); 2159 FORMATADD("L1 instruction cache: %s\n", CPUInfo._L1.Instruction.strCache);
@@ -2065,12 +2204,13 @@ bool CProcessor::CPUInfoToText(char *strBuffer, unsigned int uiMaxLen)
2065 BOOLADD("SS Self Snoop: ", CPUInfo._Ext.SS_SelfSnoop); 2204 BOOLADD("SS Self Snoop: ", CPUInfo._Ext.SS_SelfSnoop);
2066 BOOLADD("SSE Streaming SIMD Extensions: ", CPUInfo._Ext.SSE_StreamingSIMD_Extensions); 2205 BOOLADD("SSE Streaming SIMD Extensions: ", CPUInfo._Ext.SSE_StreamingSIMD_Extensions);
2067 BOOLADD("SSE2 Streaming SIMD 2 Extensions: ", CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions); 2206 BOOLADD("SSE2 Streaming SIMD 2 Extensions: ", CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions);
2207 BOOLADD("ALTVEC Altivec Extensions: ", CPUInfo._Ext.Altivec_Extensions);
2068 BOOLADD("TM Thermal Monitor: ", CPUInfo._Ext.TM_ThermalMonitor); 2208 BOOLADD("TM Thermal Monitor: ", CPUInfo._Ext.TM_ThermalMonitor);
2069 BOOLADD("TSC Time Stamp Counter: ", CPUInfo._Ext.TSC_TimeStampCounter); 2209 BOOLADD("TSC Time Stamp Counter: ", CPUInfo._Ext.TSC_TimeStampCounter);
2070 BOOLADD("VME Virtual 8086 Mode Enhancements: ", CPUInfo._Ext.VME_Virtual8086ModeEnhancements); 2210 BOOLADD("VME Virtual 8086 Mode Enhancements: ", CPUInfo._Ext.VME_Virtual8086ModeEnhancements);
2071 BOOLADD("3DNow! Instructions: ", CPUInfo._Ext._3DNOW_InstructionExtensions); 2211 BOOLADD("3DNow! Instructions: ", CPUInfo._Ext._3DNOW_InstructionExtensions);
2072 BOOLADD("Enhanced 3DNow! Instructions: ", CPUInfo._Ext._E3DNOW_InstructionExtensions); 2212 BOOLADD("Enhanced 3DNow! Instructions: ", CPUInfo._Ext._E3DNOW_InstructionExtensions);
2073 2213#endif
2074 // Yippie!!! 2214 // Yippie!!!
2075 return true; 2215 return true;
2076} 2216}
diff --git a/linden/indra/llcommon/llprocessor.h b/linden/indra/llcommon/llprocessor.h
index fd9a5da..79dd1e8 100644
--- a/linden/indra/llcommon/llprocessor.h
+++ b/linden/indra/llcommon/llprocessor.h
@@ -40,6 +40,20 @@
40#define PROCESSOR_FREQUENCY_MEASURE_AVAILABLE 40#define PROCESSOR_FREQUENCY_MEASURE_AVAILABLE
41#endif 41#endif
42 42
43#if LL_MSVC && _M_X64
44# define LL_X86_64 1
45# define LL_X86 1
46#elif LL_MSVC && _M_IX86
47# define LL_X86 1
48#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) )
49# define LL_X86_64 1
50# define LL_X86 1
51#elif LL_GNUC && ( defined(__i386__) )
52# define LL_X86 1
53#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) )
54# define LL_PPC 1
55#endif
56
43 57
44typedef struct ProcessorExtensions 58typedef struct ProcessorExtensions
45{ 59{
@@ -71,6 +85,7 @@ typedef struct ProcessorExtensions
71 bool FXSR_FastStreamingSIMD_ExtensionsSaveRestore; 85 bool FXSR_FastStreamingSIMD_ExtensionsSaveRestore;
72 bool SSE_StreamingSIMD_Extensions; 86 bool SSE_StreamingSIMD_Extensions;
73 bool SSE2_StreamingSIMD2_Extensions; 87 bool SSE2_StreamingSIMD2_Extensions;
88 bool Altivec_Extensions;
74 bool SS_SelfSnoop; 89 bool SS_SelfSnoop;
75 bool HT_HyperThreading; 90 bool HT_HyperThreading;
76 unsigned int HT_HyterThreadingSiblings; 91 unsigned int HT_HyterThreadingSiblings;
diff --git a/linden/indra/llcommon/llsdserialize_xml.cpp b/linden/indra/llcommon/llsdserialize_xml.cpp
index 85d3883..6d2f583 100644
--- a/linden/indra/llcommon/llsdserialize_xml.cpp
+++ b/linden/indra/llcommon/llsdserialize_xml.cpp
@@ -36,7 +36,11 @@
36 36
37extern "C" 37extern "C"
38{ 38{
39#include "expat/expat.h" 39#ifdef LL_STANDALONE
40# include <expat.h>
41#else
42# include "expat/expat.h"
43#endif
40} 44}
41 45
42/** 46/**
diff --git a/linden/indra/llcommon/llsdutil.cpp b/linden/indra/llcommon/llsdutil.cpp
index e8b3ac5..0e23054 100644
--- a/linden/indra/llcommon/llsdutil.cpp
+++ b/linden/indra/llcommon/llsdutil.cpp
@@ -35,7 +35,7 @@
35#if LL_WINDOWS 35#if LL_WINDOWS
36# define WIN32_LEAN_AND_MEAN 36# define WIN32_LEAN_AND_MEAN
37# include <winsock2.h> // for htonl 37# include <winsock2.h> // for htonl
38#elif LL_LINUX 38#elif LL_LINUX || LL_SOLARIS
39# include <netinet/in.h> 39# include <netinet/in.h>
40#elif LL_DARWIN 40#elif LL_DARWIN
41# include <arpa/inet.h> 41# include <arpa/inet.h>
diff --git a/linden/indra/llcommon/llskiplist.h b/linden/indra/llcommon/llskiplist.h
index be3385d..40d0c8a 100644
--- a/linden/indra/llcommon/llskiplist.h
+++ b/linden/indra/llcommon/llskiplist.h
@@ -28,11 +28,10 @@
28#ifndef LL_LLSKIPLIST_H 28#ifndef LL_LLSKIPLIST_H
29#define LL_LLSKIPLIST_H 29#define LL_LLSKIPLIST_H
30 30
31#include "llerror.h" 31#include "llrand.h"
32//#include "vmath.h"
33 32
34// NOTA BENE: Insert first needs to be < NOT <= 33// NOTA BENE: Insert first needs to be < NOT <=
35 34// Binary depth must be >= 2
36template <class DATA_TYPE, S32 BINARY_DEPTH = 10> 35template <class DATA_TYPE, S32 BINARY_DEPTH = 10>
37class LLSkipList 36class LLSkipList
38{ 37{
@@ -144,14 +143,11 @@ private:
144// Implementation 143// Implementation
145// 144//
146 145
146
147// Binary depth must be >= 2
147template <class DATA_TYPE, S32 BINARY_DEPTH> 148template <class DATA_TYPE, S32 BINARY_DEPTH>
148inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::init() 149inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::init()
149{ 150{
150 if (BINARY_DEPTH < 2)
151 {
152 llerrs << "Trying to create skip list with too little depth, "
153 "must be 2 or greater" << llendl;
154 }
155 S32 i; 151 S32 i;
156 for (i = 0; i < BINARY_DEPTH; i++) 152 for (i = 0; i < BINARY_DEPTH; i++)
157 { 153 {
diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h
index adfdfb8..5f48580 100644
--- a/linden/indra/llcommon/llstring.h
+++ b/linden/indra/llcommon/llstring.h
@@ -40,7 +40,7 @@
40#include <errno.h> 40#include <errno.h>
41#include <math.h> 41#include <math.h>
42#include <stdarg.h> /* for vsnprintf */ 42#include <stdarg.h> /* for vsnprintf */
43#if LL_LINUX 43#if LL_LINUX || LL_SOLARIS
44#include <wctype.h> 44#include <wctype.h>
45#include <wchar.h> 45#include <wchar.h>
46#endif 46#endif
@@ -54,7 +54,7 @@ class LLUUID;
54class LLColor4; 54class LLColor4;
55class LLColor4U; 55class LLColor4U;
56 56
57#if (LL_DARWIN || (LL_LINUX && __GNUC__ > 2)) 57#if (LL_DARWIN || LL_SOLARIS || (LL_LINUX && __GNUC__ > 2))
58// Template specialization of char_traits for U16s. Only necessary on Mac for now (exists on Windows, unused/broken on Linux/gcc2.95) 58// Template specialization of char_traits for U16s. Only necessary on Mac for now (exists on Windows, unused/broken on Linux/gcc2.95)
59namespace std 59namespace std
60{ 60{
@@ -205,7 +205,7 @@ public:
205 LLStringBase(const T* s, size_type n); 205 LLStringBase(const T* s, size_type n);
206 LLStringBase(const T* s, size_type pos, size_type n ); 206 LLStringBase(const T* s, size_type pos, size_type n );
207 207
208#if LL_LINUX 208#if LL_LINUX || LL_SOLARIS
209 void clear() { assign(null); } 209 void clear() { assign(null); }
210 210
211 LLStringBase<T>& assign(const T* s); 211 LLStringBase<T>& assign(const T* s);
@@ -700,7 +700,7 @@ LLStringBase<T>::LLStringBase(const T* s, size_type pos, size_type n ) : std::ba
700 } 700 }
701} 701}
702 702
703#if LL_LINUX 703#if LL_LINUX || LL_SOLARIS
704template<class T> 704template<class T>
705LLStringBase<T>& LLStringBase<T>::assign(const T* s) 705LLStringBase<T>& LLStringBase<T>::assign(const T* s)
706{ 706{
@@ -1095,7 +1095,7 @@ BOOL LLStringBase<T>::read(std::basic_string<T>& string, const char* filename)
1095template<class T> 1095template<class T>
1096BOOL LLStringBase<T>::write(std::basic_string<T>& string, const char* filename) 1096BOOL LLStringBase<T>::write(std::basic_string<T>& string, const char* filename)
1097{ 1097{
1098#ifdef LL_LINUX 1098#if LL_LINUX || LL_SOLARIS
1099 printf("STUBBED: LLStringBase<T>::write at %s:%d\n", __FILE__, __LINE__); 1099 printf("STUBBED: LLStringBase<T>::write at %s:%d\n", __FILE__, __LINE__);
1100#else 1100#else
1101 llofstream ofs(filename, llofstream::binary); 1101 llofstream ofs(filename, llofstream::binary);
diff --git a/linden/indra/llcommon/llsys.cpp b/linden/indra/llcommon/llsys.cpp
index 48f2474..25749e1 100644
--- a/linden/indra/llcommon/llsys.cpp
+++ b/linden/indra/llcommon/llsys.cpp
@@ -31,9 +31,13 @@
31#include "llsys.h" 31#include "llsys.h"
32 32
33#include <iostream> 33#include <iostream>
34#include <zlib/zlib.h> 34#ifdef LL_STANDALONE
35# include <zlib.h>
36#else
37# include "zlib/zlib.h"
38#endif
35 39
36#include "processor.h" 40#include "llprocessor.h"
37 41
38#if LL_WINDOWS 42#if LL_WINDOWS
39# define WIN32_LEAN_AND_MEAN 43# define WIN32_LEAN_AND_MEAN
@@ -44,6 +48,8 @@
44# include <sys/utsname.h> 48# include <sys/utsname.h>
45#elif LL_LINUX 49#elif LL_LINUX
46# include <sys/utsname.h> 50# include <sys/utsname.h>
51# include <unistd.h>
52# include <sys/sysinfo.h>
47const char MEMINFO_FILE[] = "/proc/meminfo"; 53const char MEMINFO_FILE[] = "/proc/meminfo";
48const char CPUINFO_FILE[] = "/proc/cpuinfo"; 54const char CPUINFO_FILE[] = "/proc/cpuinfo";
49#endif 55#endif
@@ -182,7 +188,7 @@ LLOSInfo::LLOSInfo() :
182 } 188 }
183#else 189#else
184 struct utsname un; 190 struct utsname un;
185 if(0==uname(&un)) 191 if(uname(&un) != -1)
186 { 192 {
187 mOSString.append(un.sysname); 193 mOSString.append(un.sysname);
188 mOSString.append(" "); 194 mOSString.append(" ");
@@ -252,13 +258,12 @@ U32 LLOSInfo::getProcessVirtualSizeKB()
252#if LL_WINDOWS 258#if LL_WINDOWS
253#endif 259#endif
254#if LL_LINUX 260#if LL_LINUX
255 FILE* status_filep = LLFile::fopen("/proc/self/status", "r"); /* Flawfinder: ignore */ 261 FILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
256 S32 numRead = 0; 262 S32 numRead = 0;
257 char buff[STATUS_SIZE]; /* Flawfinder: ignore */ 263 char buff[STATUS_SIZE]; /* Flawfinder: ignore */
258 bzero(buff, STATUS_SIZE);
259 264
260 rewind(status_filep); 265 size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep);
261 fread(buff, 1, STATUS_SIZE-2, status_filep); 266 buff[nbytes] = '\0';
262 267
263 // All these guys return numbers in KB 268 // All these guys return numbers in KB
264 char *memp = strstr(buff, "VmSize:"); 269 char *memp = strstr(buff, "VmSize:");
@@ -267,6 +272,24 @@ U32 LLOSInfo::getProcessVirtualSizeKB()
267 numRead += sscanf(memp, "%*s %u", &virtual_size); 272 numRead += sscanf(memp, "%*s %u", &virtual_size);
268 } 273 }
269 fclose(status_filep); 274 fclose(status_filep);
275#elif LL_SOLARIS
276 char proc_ps[LL_MAX_PATH];
277 sprintf(proc_ps, "/proc/%d/psinfo", (int)getpid());
278 int proc_fd = -1;
279 if((proc_fd = open(proc_ps, O_RDONLY)) == -1){
280 llwarns << "unable to open " << proc_ps << llendl;
281 return 0;
282 }
283 psinfo_t proc_psinfo;
284 if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
285 llwarns << "Unable to read " << proc_ps << llendl;
286 close(proc_fd);
287 return 0;
288 }
289
290 close(proc_fd);
291
292 virtual_size = proc_psinfo.pr_size;
270#endif 293#endif
271 return virtual_size; 294 return virtual_size;
272} 295}
@@ -278,15 +301,14 @@ U32 LLOSInfo::getProcessResidentSizeKB()
278#if LL_WINDOWS 301#if LL_WINDOWS
279#endif 302#endif
280#if LL_LINUX 303#if LL_LINUX
281 FILE* status_filep = LLFile::fopen("/proc/self/status", "r"); /* Flawfinder: ignore */ 304 FILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
282 if (status_filep != NULL) 305 if (status_filep != NULL)
283 { 306 {
284 S32 numRead = 0; 307 S32 numRead = 0;
285 char buff[STATUS_SIZE]; /* Flawfinder: ignore */ 308 char buff[STATUS_SIZE]; /* Flawfinder: ignore */
286 bzero(buff, STATUS_SIZE);
287 309
288 rewind(status_filep); 310 size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep);
289 fread(buff, 1, STATUS_SIZE-2, status_filep); 311 buff[nbytes] = '\0';
290 312
291 // All these guys return numbers in KB 313 // All these guys return numbers in KB
292 char *memp = strstr(buff, "VmRSS:"); 314 char *memp = strstr(buff, "VmRSS:");
@@ -296,47 +318,126 @@ U32 LLOSInfo::getProcessResidentSizeKB()
296 } 318 }
297 fclose(status_filep); 319 fclose(status_filep);
298 } 320 }
321#elif LL_SOLARIS
322 char proc_ps[LL_MAX_PATH];
323 sprintf(proc_ps, "/proc/%d/psinfo", (int)getpid());
324 int proc_fd = -1;
325 if((proc_fd = open(proc_ps, O_RDONLY)) == -1){
326 llwarns << "unable to open " << proc_ps << llendl;
327 return 0;
328 }
329 psinfo_t proc_psinfo;
330 if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
331 llwarns << "Unable to read " << proc_ps << llendl;
332 close(proc_fd);
333 return 0;
334 }
335
336 close(proc_fd);
337
338 resident_size = proc_psinfo.pr_rssize;
299#endif 339#endif
300 return resident_size; 340 return resident_size;
301} 341}
302 342
303LLCPUInfo::LLCPUInfo() 343LLCPUInfo::LLCPUInfo()
304{ 344{
345 std::ostringstream out;
305 CProcessor proc; 346 CProcessor proc;
306 const ProcessorInfo* info = proc.GetCPUInfo(); 347 const ProcessorInfo* info = proc.GetCPUInfo();
307 mHasSSE = (info->_Ext.SSE_StreamingSIMD_Extensions != 0); 348 // proc.WriteInfoTextFile("procInfo.txt");
308 mHasSSE2 = (info->_Ext.SSE2_StreamingSIMD2_Extensions != 0); 349 mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions;
350 mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions;
351 mHasAltivec = info->_Ext.Altivec_Extensions;
309 mCPUMhz = (S32)(proc.GetCPUFrequency(50)/1000000.0); 352 mCPUMhz = (S32)(proc.GetCPUFrequency(50)/1000000.0);
310 mFamily.assign( info->strFamily ); 353 mFamily.assign( info->strFamily );
354 mCPUString = "Unknown";
355
356#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS
357 out << proc.strCPUName;
358 if (200 < mCPUMhz && mCPUMhz < 10000) // *NOTE: cpu speed is often way wrong, do a sanity check
359 {
360 out << " (" << mCPUMhz << " MHz)";
361 }
362 mCPUString = out.str();
363
364#elif LL_LINUX
365 std::map< LLString, LLString > cpuinfo;
366 FILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb");
367 if(cpuinfo_fp)
368 {
369 char line[MAX_STRING];
370 memset(line, 0, MAX_STRING);
371 while(fgets(line, MAX_STRING, cpuinfo_fp))
372 {
373 // /proc/cpuinfo on Linux looks like:
374 // name\t*: value\n
375 char* tabspot = strchr( line, '\t' );
376 if (tabspot == NULL)
377 continue;
378 char* colspot = strchr( tabspot, ':' );
379 if (colspot == NULL)
380 continue;
381 char* spacespot = strchr( colspot, ' ' );
382 if (spacespot == NULL)
383 continue;
384 char* nlspot = strchr( line, '\n' );
385 if (nlspot == NULL)
386 nlspot = line + strlen( line ); // Fallback to terminating NUL
387 std::string linename( line, tabspot );
388 LLString llinename(linename);
389 LLString::toLower(llinename);
390 std::string lineval( spacespot + 1, nlspot );
391 cpuinfo[ llinename ] = lineval;
392 }
393 fclose(cpuinfo_fp);
394 }
395# if LL_X86
396 LLString flags = " " + cpuinfo["flags"] + " ";
397 LLString::toLower(flags);
398 mHasSSE = ( flags.find( " sse " ) != std::string::npos );
399 mHasSSE2 = ( flags.find( " sse2 " ) != std::string::npos );
400
401 F64 mhz;
402 if (LLString::convertToF64(cpuinfo["cpu mhz"], mhz)
403 && 200.0 < mhz && mhz < 10000.0)
404 {
405 mCPUMhz = (S32)llrint(mhz);
406 }
407 if (!cpuinfo["model name"].empty())
408 mCPUString = cpuinfo["model name"];
409# endif // LL_X86
410#endif // LL_LINUX
311} 411}
312 412
413bool LLCPUInfo::hasAltivec() const
414{
415 return mHasAltivec;
416}
313 417
314std::string LLCPUInfo::getCPUString() const 418bool LLCPUInfo::hasSSE() const
315{ 419{
316#if LL_WINDOWS || LL_DARWIN 420 return mHasSSE;
317 std::ostringstream out; 421}
318 422
319 CProcessor proc; 423bool LLCPUInfo::hasSSE2() const
320 (void) proc.GetCPUInfo(); 424{
321 out << proc.strCPUName << " "; 425 return mHasSSE2;
322 426}
323 F32 freq = (F32)(proc.GetCPUFrequency(50) / 1000000.0);
324 427
325 // cpu speed is often way wrong, do a sanity check 428S32 LLCPUInfo::getMhz() const
326 if (200.f < freq && freq < 10000.f) 429{
327 { 430 return mCPUMhz;
328 out << "(" << (S32)(freq) << " MHz)"; 431}
329 }
330 432
331 return out.str(); 433std::string LLCPUInfo::getCPUString() const
332#else 434{
333 return "Can't get terse CPU information"; 435 return mCPUString;
334#endif
335} 436}
336 437
337void LLCPUInfo::stream(std::ostream& s) const 438void LLCPUInfo::stream(std::ostream& s) const
338{ 439{
339#if LL_WINDOWS || LL_DARWIN 440#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS
340 // gather machine information. 441 // gather machine information.
341 char proc_buf[CPUINFO_BUFFER_SIZE]; /* Flawfinder: ignore */ 442 char proc_buf[CPUINFO_BUFFER_SIZE]; /* Flawfinder: ignore */
342 CProcessor proc; 443 CProcessor proc;
@@ -346,38 +447,41 @@ void LLCPUInfo::stream(std::ostream& s) const
346 } 447 }
347 else 448 else
348 { 449 {
349 s << "Unable to collect processor info"; 450 s << "Unable to collect processor information" << std::endl;
350 } 451 }
351#else 452#else
352 // *NOTE: This works on linux. What will it do on other systems? 453 // *NOTE: This works on linux. What will it do on other systems?
353 FILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "r"); /* Flawfinder: ignore */ 454 FILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "rb");
354 if(cpuinfo) 455 if(cpuinfo)
355 { 456 {
356 char line[MAX_STRING]; /* Flawfinder: ignore */ 457 char line[MAX_STRING];
357 memset(line, 0, MAX_STRING); 458 memset(line, 0, MAX_STRING);
358 while(fgets(line, MAX_STRING, cpuinfo)) 459 while(fgets(line, MAX_STRING, cpuinfo))
359 { 460 {
360 line[strlen(line)-1] = ' '; /*Flawfinder: ignore*/ 461 line[strlen(line)-1] = ' ';
361 s << line; 462 s << line;
362 } 463 }
363 fclose(cpuinfo); 464 fclose(cpuinfo);
465 s << std::endl;
364 } 466 }
365 else 467 else
366 { 468 {
367 s << "Unable to collect memory information"; 469 s << "Unable to collect processor information" << std::endl;
368 } 470 }
369#endif 471#endif
472 // These are interesting as they reflect our internal view of the
473 // CPU's attributes regardless of platform
474 s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
475 s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl;
476 s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
477 s << "->mCPUMhz: " << mCPUMhz << std::endl;
478 s << "->mCPUString: " << mCPUString << std::endl;
370} 479}
371 480
372LLMemoryInfo::LLMemoryInfo() 481LLMemoryInfo::LLMemoryInfo()
373{ 482{
374} 483}
375 484
376#if LL_LINUX
377#include <unistd.h>
378#include <sys/sysinfo.h>
379#endif
380
381U32 LLMemoryInfo::getPhysicalMemory() const 485U32 LLMemoryInfo::getPhysicalMemory() const
382{ 486{
383#if LL_WINDOWS 487#if LL_WINDOWS
@@ -399,7 +503,8 @@ U32 LLMemoryInfo::getPhysicalMemory() const
399#elif LL_LINUX 503#elif LL_LINUX
400 504
401 return getpagesize() * get_phys_pages(); 505 return getpagesize() * get_phys_pages();
402 506#elif LL_SOLARIS
507 return getpagesize() * sysconf(_SC_PHYS_PAGES);
403#else 508#else
404 return 0; 509 return 0;
405 510
@@ -433,10 +538,15 @@ void LLMemoryInfo::stream(std::ostream& s) const
433 { 538 {
434 s << "Unable to collect memory information"; 539 s << "Unable to collect memory information";
435 } 540 }
436 541#elif LL_SOLARIS
542 U64 phys = 0;
543
544 phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
545
546 s << "Total Physical Kb: " << phys << std::endl;
437#else 547#else
438 // *NOTE: This works on linux. What will it do on other systems? 548 // *NOTE: This works on linux. What will it do on other systems?
439 FILE* meminfo = LLFile::fopen(MEMINFO_FILE,"r"); /* Flawfinder: ignore */ 549 FILE* meminfo = LLFile::fopen(MEMINFO_FILE,"rb");
440 if(meminfo) 550 if(meminfo)
441 { 551 {
442 char line[MAX_STRING]; /* Flawfinder: ignore */ 552 char line[MAX_STRING]; /* Flawfinder: ignore */
@@ -491,7 +601,11 @@ BOOL gunzip_file(const char *srcfile, const char *dstfile)
491 do 601 do
492 { 602 {
493 bytes = gzread(src, buffer, UNCOMPRESS_BUFFER_SIZE); 603 bytes = gzread(src, buffer, UNCOMPRESS_BUFFER_SIZE);
494 fwrite(buffer, sizeof(U8), bytes, dst); 604 size_t nwrit = fwrite(buffer, sizeof(U8), bytes, dst);
605 if (nwrit < (size_t) bytes)
606 {
607 llerrs << "Short write on " << tmpfile << llendl;
608 }
495 } while(gzeof(src) == 0); 609 } while(gzeof(src) == 0);
496 fclose(dst); 610 fclose(dst);
497 dst = NULL; 611 dst = NULL;
diff --git a/linden/indra/llcommon/llsys.h b/linden/indra/llcommon/llsys.h
index 2047d9a..416bd54 100644
--- a/linden/indra/llcommon/llsys.h
+++ b/linden/indra/llcommon/llsys.h
@@ -72,18 +72,21 @@ public:
72 72
73 std::string getCPUString() const; 73 std::string getCPUString() const;
74 74
75 BOOL hasSSE() const { return mHasSSE; } 75 bool hasAltivec() const;
76 BOOL hasSSE2() const { return mHasSSE2; } 76 bool hasSSE() const;
77 S32 getMhz() const { return mCPUMhz; } 77 bool hasSSE2() const;
78 S32 getMhz() const;
78 79
79 // Family is "AMD Duron" or "Intel Pentium Pro" 80 // Family is "AMD Duron" or "Intel Pentium Pro"
80 const std::string& getFamily() const { return mFamily; } 81 const std::string& getFamily() const { return mFamily; }
81 82
82private: 83private:
83 BOOL mHasSSE; 84 bool mHasSSE;
84 BOOL mHasSSE2; 85 bool mHasSSE2;
86 bool mHasAltivec;
85 S32 mCPUMhz; 87 S32 mCPUMhz;
86 std::string mFamily; 88 std::string mFamily;
89 std::string mCPUString;
87}; 90};
88 91
89class LLMemoryInfo 92class LLMemoryInfo
diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp
index 0f833ab..d261c8b 100644
--- a/linden/indra/llcommon/llthread.cpp
+++ b/linden/indra/llcommon/llthread.cpp
@@ -32,7 +32,7 @@
32 32
33#include "lltimer.h" 33#include "lltimer.h"
34 34
35#if LL_LINUX 35#if LL_LINUX || LL_SOLARIS
36#include <sched.h> 36#include <sched.h>
37#endif 37#endif
38 38
@@ -226,7 +226,7 @@ void LLThread::setQuitting()
226// static 226// static
227void LLThread::yield() 227void LLThread::yield()
228{ 228{
229#if LL_LINUX 229#if LL_LINUX || LL_SOLARIS
230 sched_yield(); // annoyingly, apr_thread_yield is a noop on linux... 230 sched_yield(); // annoyingly, apr_thread_yield is a noop on linux...
231#else 231#else
232 apr_thread_yield(); 232 apr_thread_yield();
diff --git a/linden/indra/llcommon/lltimer.cpp b/linden/indra/llcommon/lltimer.cpp
index 21fbf0e..6077063 100644
--- a/linden/indra/llcommon/lltimer.cpp
+++ b/linden/indra/llcommon/lltimer.cpp
@@ -37,7 +37,7 @@
37# include <winsock2.h> 37# include <winsock2.h>
38# include <windows.h> 38# include <windows.h>
39# include <time.h> 39# include <time.h>
40#elif LL_LINUX 40#elif LL_LINUX || LL_SOLARIS
41# include <time.h> 41# include <time.h>
42# include <sys/time.h> 42# include <sys/time.h>
43# include <sched.h> 43# include <sched.h>
@@ -90,7 +90,7 @@ void llyield()
90{ 90{
91 SleepEx(0, TRUE); // Relinquishes time slice to any thread of equal priority, can be woken up by extended IO functions 91 SleepEx(0, TRUE); // Relinquishes time slice to any thread of equal priority, can be woken up by extended IO functions
92} 92}
93#elif LL_LINUX 93#elif LL_LINUX || LL_SOLARIS
94void ms_sleep(long ms) 94void ms_sleep(long ms)
95{ 95{
96 struct timespec t; 96 struct timespec t;
@@ -150,7 +150,7 @@ F64 calc_clock_frequency(U32 uiMeasureMSecs)
150#endif // LL_WINDOWS 150#endif // LL_WINDOWS
151 151
152 152
153#if LL_LINUX || LL_DARWIN 153#if LL_LINUX || LL_DARWIN || LL_SOLARIS
154// Both Linux and Mac use gettimeofday for accurate time 154// Both Linux and Mac use gettimeofday for accurate time
155F64 calc_clock_frequency(unsigned int uiMeasureMSecs) 155F64 calc_clock_frequency(unsigned int uiMeasureMSecs)
156{ 156{
@@ -169,7 +169,7 @@ U64 get_clock_count()
169 169
170void update_clock_frequencies() 170void update_clock_frequencies()
171{ 171{
172 gClockFrequency = calc_clock_frequency(50); 172 gClockFrequency = calc_clock_frequency(50U);
173 gClockFrequencyInv = 1.0/gClockFrequency; 173 gClockFrequencyInv = 1.0/gClockFrequency;
174 gClocksToMicroseconds = gClockFrequencyInv * SEC_TO_MICROSEC; 174 gClocksToMicroseconds = gClockFrequencyInv * SEC_TO_MICROSEC;
175} 175}
@@ -512,7 +512,7 @@ void secondsToTimecodeString(F32 current_time, char *tcstring)
512std::list<LLEventTimer*> LLEventTimer::sActiveList; 512std::list<LLEventTimer*> LLEventTimer::sActiveList;
513 513
514LLEventTimer::LLEventTimer(F32 period) 514LLEventTimer::LLEventTimer(F32 period)
515: mTimer() 515: mEventTimer()
516{ 516{
517 mPeriod = period; 517 mPeriod = period;
518 sActiveList.push_back(this); 518 sActiveList.push_back(this);
@@ -528,9 +528,9 @@ void LLEventTimer::updateClass()
528 for (std::list<LLEventTimer*>::iterator iter = sActiveList.begin(); iter != sActiveList.end(); ) 528 for (std::list<LLEventTimer*>::iterator iter = sActiveList.begin(); iter != sActiveList.end(); )
529 { 529 {
530 LLEventTimer* timer = *iter++; 530 LLEventTimer* timer = *iter++;
531 F32 et = timer->mTimer.getElapsedTimeF32(); 531 F32 et = timer->mEventTimer.getElapsedTimeF32();
532 if (et > timer->mPeriod) { 532 if (et > timer->mPeriod) {
533 timer->mTimer.reset(); 533 timer->mEventTimer.reset();
534 timer->tick(); 534 timer->tick();
535 } 535 }
536 } 536 }
diff --git a/linden/indra/llcommon/lltimer.h b/linden/indra/llcommon/lltimer.h
index 94dcbb9..37917d0 100644
--- a/linden/indra/llcommon/lltimer.h
+++ b/linden/indra/llcommon/lltimer.h
@@ -151,7 +151,7 @@ public:
151 static void updateClass(); 151 static void updateClass();
152 152
153protected: 153protected:
154 LLTimer mTimer; 154 LLTimer mEventTimer;
155 F32 mPeriod; 155 F32 mPeriod;
156 156
157private: 157private:
diff --git a/linden/indra/llcommon/lluri.cpp b/linden/indra/llcommon/lluri.cpp
index 83de022..43d2147 100644
--- a/linden/indra/llcommon/lluri.cpp
+++ b/linden/indra/llcommon/lluri.cpp
@@ -295,9 +295,10 @@ LLURI LLURI::buildHTTP(const std::string& prefix,
295 const LLSD& query) 295 const LLSD& query)
296{ 296{
297 LLURI uri = buildHTTP(prefix, path); 297 LLURI uri = buildHTTP(prefix, path);
298 uri.mEscapedQuery = mapToQueryString(query);
299 // break out and escape each query component 298 // break out and escape each query component
300 uri.mEscapedOpaque += "?" + uri.mEscapedQuery ; 299 uri.mEscapedQuery = mapToQueryString(query);
300 uri.mEscapedOpaque += uri.mEscapedQuery ;
301 uri.mEscapedQuery.erase(0,1); // trim the leading '?'
301 return uri; 302 return uri;
302} 303}
303 304
@@ -601,20 +602,30 @@ LLSD LLURI::queryMap(std::string escaped_query_string)
601std::string LLURI::mapToQueryString(const LLSD& queryMap) 602std::string LLURI::mapToQueryString(const LLSD& queryMap)
602{ 603{
603 std::string query_string; 604 std::string query_string;
604
605 if (queryMap.isMap()) 605 if (queryMap.isMap())
606 { 606 {
607 for (LLSD::map_const_iterator iter = queryMap.beginMap(); 607 bool first_element = true;
608 iter != queryMap.endMap(); 608 LLSD::map_const_iterator iter = queryMap.beginMap();
609 iter++) 609 LLSD::map_const_iterator end = queryMap.endMap();
610 std::ostringstream ostr;
611 for (; iter != end; ++iter)
610 { 612 {
611 query_string += escapeQueryVariable(iter->first) + 613 if(first_element)
612 (iter->second.isUndefined() ? "" : "=" + escapeQueryValue(iter->second.asString())) + "&" ; 614 {
615 ostr << "?";
616 first_element = false;
617 }
618 else
619 {
620 ostr << "&";
621 }
622 ostr << escapeQueryVariable(iter->first);
623 if(iter->second.isDefined())
624 {
625 ostr << "=" << escapeQueryValue(iter->second.asString());
626 }
613 } 627 }
614 //if (queryMap.size() > 0) 628 query_string = ostr.str();
615 //{
616 // query_string += "?" + query_string ;
617 //}
618 } 629 }
619 return query_string; 630 return query_string;
620} 631}
diff --git a/linden/indra/llcommon/lluri.h b/linden/indra/llcommon/lluri.h
index 3f24799..1044c48 100644
--- a/linden/indra/llcommon/lluri.h
+++ b/linden/indra/llcommon/lluri.h
@@ -58,34 +58,42 @@ public:
58 58
59 // construct from escaped string, as would be transmitted on the net 59 // construct from escaped string, as would be transmitted on the net
60 60
61 ~LLURI(); 61 ~LLURI();
62 62
63 static LLURI buildHTTP(const std::string& prefix, 63 static LLURI buildHTTP(
64 const LLSD& path); 64 const std::string& prefix,
65 static LLURI buildHTTP(const std::string& prefix, 65 const LLSD& path);
66 const LLSD& path,
67 const LLSD& query);
68 // prefix is either a full URL prefix of the form "http://example.com:8080",
69 // or it can be simply a host and optional port like "example.com" or
70 // "example.com:8080", in these cases, the "http://" will be added
71 66
72 static LLURI buildHTTP(const std::string& host, 67 static LLURI buildHTTP(
73 const U32& port, 68 const std::string& prefix,
74 const LLSD& path); 69 const LLSD& path,
75 static LLURI buildHTTP(const std::string& host, 70 const LLSD& query);
76 const U32& port, 71 ///< prefix is either a full URL prefix of the form
77 const LLSD& path, 72 /// "http://example.com:8080", or it can be simply a host and
78 const LLSD& query); 73 /// optional port like "example.com" or "example.com:8080", in
79 std::string asString() const; 74 /// these cases, the "http://" will be added
80 // the whole URI, escaped as needed 75
76 static LLURI buildHTTP(
77 const std::string& host,
78 const U32& port,
79 const LLSD& path);
80 static LLURI buildHTTP(
81 const std::string& host,
82 const U32& port,
83 const LLSD& path,
84 const LLSD& query);
85
86 std::string asString() const;
87 ///< the whole URI, escaped as needed
81 88
82 // Parts of a URI 89 /** @name Parts of a URI */
83 // These functions return parts of the decoded URI. The returned 90 //@{
84 // strings are un-escaped as needed 91 // These functions return parts of the decoded URI. The returned
92 // strings are un-escaped as needed
85 93
86 // for all schemes 94 // for all schemes
87 std::string scheme() const; // ex.: "http", note lack of colon 95 std::string scheme() const; ///< ex.: "http", note lack of colon
88 std::string opaque() const; // everything after the colon 96 std::string opaque() const; ///< everything after the colon
89 97
90 // for schemes that follow path like syntax (http, https, ftp) 98 // for schemes that follow path like syntax (http, https, ftp)
91 std::string authority() const; // ex.: "host.com:80" 99 std::string authority() const; // ex.: "host.com:80"
@@ -101,27 +109,34 @@ public:
101 const std::string& escapedQuery() const { return mEscapedQuery; } 109 const std::string& escapedQuery() const { return mEscapedQuery; }
102 LLSD queryMap() const; // above decoded into a map 110 LLSD queryMap() const; // above decoded into a map
103 static LLSD queryMap(std::string escaped_query_string); 111 static LLSD queryMap(std::string escaped_query_string);
104 static std::string mapToQueryString(const LLSD& queryMap);
105 112
106 // Escaping Utilities 113 /**
107 // Escape a string by urlencoding all the characters that aren't in the allowed string. 114 * @brief given a name value map, return a serialized query string.
108 static std::string escape(const std::string& str); 115 *
109 static std::string escape(const std::string& str, const std::string & allowed); 116
110 static std::string unescape(const std::string& str); 117 * @param query_map a map of name value. every value must be
118 * representable as a string.
119 * @return Returns an url query string of '?n1=v1&n2=v2&...'
120 */
121 static std::string mapToQueryString(const LLSD& query_map);
111 122
112 // Functions for building specific URIs for web services 123 /** @name Escaping Utilities */
113 // *NOTE: DEPRECATED. use the service builder instead. 124 //@{
114 //static LLURI buildBulkAgentNamesURI(LLApp* app); 125 // Escape a string by urlencoding all the characters that aren't
115 //static LLURI buildAgentSessionURI(const LLUUID& agent_id, LLApp* app); 126 // in the allowed string.
116 //static LLURI buildAgentLoginInfoURI(const LLUUID& agent_id, const std::string& dataserver); 127 static std::string escape(const std::string& str);
117 //static LLURI buildAgentNameURI(const LLUUID& agent_id, LLApp* app); 128 static std::string escape(
129 const std::string& str,
130 const std::string & allowed);
131 static std::string unescape(const std::string& str);
132 //@}
118 133
119private: 134private:
120 std::string mScheme; 135 std::string mScheme;
121 std::string mEscapedOpaque; 136 std::string mEscapedOpaque;
122 std::string mEscapedAuthority; 137 std::string mEscapedAuthority;
123 std::string mEscapedPath; 138 std::string mEscapedPath;
124 std::string mEscapedQuery; 139 std::string mEscapedQuery;
125}; 140};
126 141
127#endif // LL_LLURI_H 142#endif // LL_LLURI_H
diff --git a/linden/indra/llcommon/llversion.h b/linden/indra/llcommon/llversion.h
index 9739d04..555698d 100644
--- a/linden/indra/llcommon/llversion.h
+++ b/linden/indra/llcommon/llversion.h
@@ -31,7 +31,7 @@
31 31
32const S32 LL_VERSION_MAJOR = 1; 32const S32 LL_VERSION_MAJOR = 1;
33const S32 LL_VERSION_MINOR = 18; 33const S32 LL_VERSION_MINOR = 18;
34const S32 LL_VERSION_PATCH = 0; 34const S32 LL_VERSION_PATCH = 1;
35const S32 LL_VERSION_BUILD = 6; 35const S32 LL_VERSION_BUILD = 2;
36 36
37#endif 37#endif
diff --git a/linden/indra/llcommon/llworkerthread.cpp b/linden/indra/llcommon/llworkerthread.cpp
index aa0bedf..b4d9485 100644
--- a/linden/indra/llcommon/llworkerthread.cpp
+++ b/linden/indra/llcommon/llworkerthread.cpp
@@ -104,6 +104,8 @@ S32 LLWorkerThread::update(U32 max_time_ms)
104 } 104 }
105 delete *iter; 105 delete *iter;
106 } 106 }
107 // delete and aborted entries mean there's still work to do
108 res += delete_list.size() + abort_list.size();
107 return res; 109 return res;
108} 110}
109 111
diff --git a/linden/indra/llcommon/stdtypes.h b/linden/indra/llcommon/stdtypes.h
index 16b57fa..118278f 100644
--- a/linden/indra/llcommon/stdtypes.h
+++ b/linden/indra/llcommon/stdtypes.h
@@ -31,18 +31,18 @@
31#include <limits.h> 31#include <limits.h>
32#include <float.h> 32#include <float.h>
33 33
34typedef signed char S8; 34typedef signed char S8;
35typedef unsigned char U8; 35typedef unsigned char U8;
36typedef signed short S16; 36typedef signed short S16;
37typedef unsigned short U16; 37typedef unsigned short U16;
38typedef signed int S32; 38typedef signed int S32;
39typedef unsigned int U32; 39typedef unsigned int U32;
40 40
41#if LL_WINDOWS 41#if LL_WINDOWS
42// Windows wchar_t is 16-bit 42// Windows wchar_t is 16-bit
43typedef U32 llwchar; 43typedef U32 llwchar;
44#else 44#else
45typedef wchar_t llwchar; 45typedef wchar_t llwchar;
46#endif 46#endif
47 47
48#if LL_WINDOWS 48#if LL_WINDOWS
@@ -53,20 +53,20 @@ typedef unsigned __int64 U64;
53#define U64L(a) (a) 53#define U64L(a) (a)
54#else 54#else
55typedef long long int S64; 55typedef long long int S64;
56typedef long long unsigned int U64; 56typedef long long unsigned int U64;
57#if LL_DARWIN || LL_LINUX 57#if LL_DARWIN || LL_LINUX || LL_SOLARIS
58#define S64L(a) (a##LL) 58#define S64L(a) (a##LL)
59#define U64L(a) (a##ULL) 59#define U64L(a) (a##ULL)
60#endif 60#endif
61#endif 61#endif
62 62
63typedef float F32; 63typedef float F32;
64typedef double F64; 64typedef double F64;
65 65
66typedef S32 BOOL; 66typedef S32 BOOL;
67typedef U8 KEY; 67typedef U8 KEY;
68typedef U32 MASK; 68typedef U32 MASK;
69typedef U32 TPACKETID; 69typedef U32 TPACKETID;
70 70
71// Use #define instead of consts to avoid conversion headaches 71// Use #define instead of consts to avoid conversion headaches
72#define S8_MAX (SCHAR_MAX) 72#define S8_MAX (SCHAR_MAX)
diff --git a/linden/indra/llcommon/timing.h b/linden/indra/llcommon/timing.h
index 662d22b..b799001 100644
--- a/linden/indra/llcommon/timing.h
+++ b/linden/indra/llcommon/timing.h
@@ -31,7 +31,7 @@
31 31
32#include <time.h> 32#include <time.h>
33 33
34#if LL_LINUX || LL_DARWIN 34#if LL_LINUX || LL_DARWIN || LL_SOLARIS
35# include <sys/time.h> 35# include <sys/time.h>
36#endif 36#endif
37 37
diff --git a/linden/indra/llimage/llimagejpeg.h b/linden/indra/llimage/llimagejpeg.h
index aca780d..34b3f76 100644
--- a/linden/indra/llimage/llimagejpeg.h
+++ b/linden/indra/llimage/llimagejpeg.h
@@ -34,8 +34,13 @@
34#include "llimage.h" 34#include "llimage.h"
35 35
36extern "C" { 36extern "C" {
37#include "jpeglib/jpeglib.h" 37#ifdef LL_STANDALONE
38#include "jpeglib/jerror.h" 38# include <jpeglib.h>
39# include <jerror.h>
40#else
41# include "jpeglib/jpeglib.h"
42# include "jpeglib/jerror.h"
43#endif
39} 44}
40 45
41class LLImageJPEG : public LLImageFormatted 46class LLImageJPEG : public LLImageFormatted
diff --git a/linden/indra/llinventory/llinventory.cpp b/linden/indra/llinventory/llinventory.cpp
index 93c480e..3800de2 100644
--- a/linden/indra/llinventory/llinventory.cpp
+++ b/linden/indra/llinventory/llinventory.cpp
@@ -535,7 +535,11 @@ BOOL LLInventoryItem::importFile(FILE* fp)
535 mAssetUUID.setNull(); 535 mAssetUUID.setNull();
536 while(success && (!feof(fp))) 536 while(success && (!feof(fp)))
537 { 537 {
538 fgets(buffer, MAX_STRING, fp); 538 if (fgets(buffer, MAX_STRING, fp) == NULL)
539 {
540 buffer[0] = '\0';
541 }
542
539 sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */ 543 sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */
540 if(0 == strcmp("{",keyword)) 544 if(0 == strcmp("{",keyword))
541 { 545 {
@@ -1391,7 +1395,11 @@ BOOL LLInventoryCategory::importFile(FILE* fp)
1391 valuestr[0] = '\0'; 1395 valuestr[0] = '\0';
1392 while(!feof(fp)) 1396 while(!feof(fp))
1393 { 1397 {
1394 fgets(buffer, MAX_STRING, fp); 1398 if (fgets(buffer, MAX_STRING, fp) == NULL)
1399 {
1400 buffer[0] = '\0';
1401 }
1402
1395 sscanf( /* Flawfinder: ignore */ 1403 sscanf( /* Flawfinder: ignore */
1396 buffer, 1404 buffer,
1397 " %254s %254s", 1405 " %254s %254s",
diff --git a/linden/indra/llinventory/llpermissions.cpp b/linden/indra/llinventory/llpermissions.cpp
index ae4360a..925b68f 100644
--- a/linden/indra/llinventory/llpermissions.cpp
+++ b/linden/indra/llinventory/llpermissions.cpp
@@ -526,7 +526,11 @@ BOOL LLPermissions::importFile(FILE* fp)
526 526
527 while (!feof(fp)) 527 while (!feof(fp))
528 { 528 {
529 fgets(buffer, BUFSIZE, fp); 529 if (fgets(buffer, BUFSIZE, fp) == NULL)
530 {
531 buffer[0] = '\0';
532 }
533
530 sscanf( /* Flawfinder: ignore */ 534 sscanf( /* Flawfinder: ignore */
531 buffer, 535 buffer,
532 " %255s %255s", 536 " %255s %255s",
diff --git a/linden/indra/llinventory/llsaleinfo.cpp b/linden/indra/llinventory/llsaleinfo.cpp
index debb092..0258259 100644
--- a/linden/indra/llinventory/llsaleinfo.cpp
+++ b/linden/indra/llinventory/llsaleinfo.cpp
@@ -170,7 +170,11 @@ BOOL LLSaleInfo::importFile(FILE* fp, BOOL& has_perm_mask, U32& perm_mask)
170 valuestr[0] = '\0'; 170 valuestr[0] = '\0';
171 while(success && (!feof(fp))) 171 while(success && (!feof(fp)))
172 { 172 {
173 fgets(buffer, MAX_STRING, fp); 173 if (fgets(buffer, MAX_STRING, fp) == NULL)
174 {
175 buffer[0] = '\0';
176 }
177
174 sscanf( /* Flawfinder: ignore */ 178 sscanf( /* Flawfinder: ignore */
175 buffer, 179 buffer,
176 " %254s %254s", 180 " %254s %254s",
diff --git a/linden/indra/llmath/llcrc.cpp b/linden/indra/llmath/llcrc.cpp
index cc0f955..5b3ab4b 100644
--- a/linden/indra/llmath/llcrc.cpp
+++ b/linden/indra/llmath/llcrc.cpp
@@ -154,11 +154,11 @@ void LLCRC::update(U8 next_byte)
154 mCurrent = UPDC32(next_byte, mCurrent); 154 mCurrent = UPDC32(next_byte, mCurrent);
155} 155}
156 156
157void LLCRC::update(const U8* buffer, U32 buffer_size) 157void LLCRC::update(const U8* buffer, size_t buffer_size)
158{ 158{
159 for ( ; buffer_size; --buffer_size, ++buffer) 159 for (size_t i = 0; i < buffer_size; i++)
160 { 160 {
161 mCurrent = UPDC32(*buffer, mCurrent); 161 mCurrent = UPDC32(buffer[i], mCurrent);
162 } 162 }
163} 163}
164 164
@@ -175,17 +175,24 @@ void LLCRC::update(const char* filename)
175 if (fp) 175 if (fp)
176 { 176 {
177 fseek(fp, 0, SEEK_END); 177 fseek(fp, 0, SEEK_END);
178 U32 size = ftell(fp); 178 long size = ftell(fp);
179 179
180 fseek(fp, 0, SEEK_SET); 180 fseek(fp, 0, SEEK_SET);
181 181
182 if (size > 0) 182 if (size > 0)
183 { 183 {
184 U8* data = new U8[size]; 184 U8* data = new U8[size];
185 fread(data, size, 1, fp); 185 size_t nread;
186
187 nread = fread(data, 1, size, fp);
186 fclose(fp); 188 fclose(fp);
189
190 if (nread < (size_t) size)
191 {
192 llwarns << "Short read on " << filename << llendl;
193 }
187 194
188 update(data, size); 195 update(data, nread);
189 delete[] data; 196 delete[] data;
190 } 197 }
191 } 198 }
diff --git a/linden/indra/llmath/llcrc.h b/linden/indra/llmath/llcrc.h
index 06ddac2..9f71fcc 100644
--- a/linden/indra/llmath/llcrc.h
+++ b/linden/indra/llmath/llcrc.h
@@ -56,7 +56,7 @@ public:
56 56
57 U32 getCRC() const; 57 U32 getCRC() const;
58 void update(U8 next_byte); 58 void update(U8 next_byte);
59 void update(const U8* buffer, U32 buffer_size); 59 void update(const U8* buffer, size_t buffer_size);
60 void update(const char *filename); 60 void update(const char *filename);
61 61
62#ifdef _DEBUG 62#ifdef _DEBUG
diff --git a/linden/indra/llmath/llmath.h b/linden/indra/llmath/llmath.h
index dd44e0c..9be2524 100644
--- a/linden/indra/llmath/llmath.h
+++ b/linden/indra/llmath/llmath.h
@@ -42,6 +42,9 @@
42#elif (LL_LINUX && __GNUC__ <= 2) 42#elif (LL_LINUX && __GNUC__ <= 2)
43#define llisnan(val) isnan(val) 43#define llisnan(val) isnan(val)
44#define llfinite(val) isfinite(val) 44#define llfinite(val) isfinite(val)
45#elif LL_SOLARIS
46#define llisnan(val) isnan(val)
47#define llfinite(val) (val <= std::numeric_limits<double>::max())
45#else 48#else
46#define llisnan(val) std::isnan(val) 49#define llisnan(val) std::isnan(val)
47#define llfinite(val) std::isfinite(val) 50#define llfinite(val) std::isfinite(val)
diff --git a/linden/indra/llmath/llmath.vcproj b/linden/indra/llmath/llmath.vcproj
index 4876065..bdc8ded 100644
--- a/linden/indra/llmath/llmath.vcproj
+++ b/linden/indra/llmath/llmath.vcproj
@@ -272,6 +272,18 @@
272 RelativePath=".\lluuid.h"> 272 RelativePath=".\lluuid.h">
273 </File> 273 </File>
274 <File 274 <File
275 RelativePath=".\llv4math.h">
276 </File>
277 <File
278 RelativePath=".\llv4matrix3.h">
279 </File>
280 <File
281 RelativePath=".\llv4matrix4.h">
282 </File>
283 <File
284 RelativePath=".\llv4vector3.h">
285 </File>
286 <File
275 RelativePath=".\llvolume.h"> 287 RelativePath=".\llvolume.h">
276 </File> 288 </File>
277 <File 289 <File
diff --git a/linden/indra/llmath/llmath_vc8.vcproj b/linden/indra/llmath/llmath_vc8.vcproj
index ea23702..03d75c3 100644
--- a/linden/indra/llmath/llmath_vc8.vcproj
+++ b/linden/indra/llmath/llmath_vc8.vcproj
@@ -389,6 +389,22 @@
389 > 389 >
390 </File> 390 </File>
391 <File 391 <File
392 RelativePath=".\llv4math.h"
393 >
394 </File>
395 <File
396 RelativePath=".\llv4matrix3.h"
397 >
398 </File>
399 <File
400 RelativePath=".\llv4matrix4.h"
401 >
402 </File>
403 <File
404 RelativePath=".\llv4vector3.h"
405 >
406 </File>
407 <File
392 RelativePath=".\llvolume.h" 408 RelativePath=".\llvolume.h"
393 > 409 >
394 </File> 410 </File>
diff --git a/linden/indra/llmath/llmd5.cpp b/linden/indra/llmath/llmd5.cpp
index aad4617..1a8630c 100644
--- a/linden/indra/llmath/llmd5.cpp
+++ b/linden/indra/llmath/llmd5.cpp
@@ -83,6 +83,9 @@ documentation and/or software.
83#include <fstream> 83#include <fstream>
84#include <iostream> 84#include <iostream>
85 85
86// how many bytes to grab at a time when checking files
87const int LLMD5::BLOCK_LEN = 4096;
88
86 89
87// LLMD5 simple initialization method 90// LLMD5 simple initialization method
88 91
@@ -156,10 +159,10 @@ void LLMD5::update (const uint1 *input, const uint4 input_length) {
156 159
157void LLMD5::update(FILE* file){ 160void LLMD5::update(FILE* file){
158 161
159 unsigned char buffer[1024]; /* Flawfinder: ignore */ 162 unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
160 int len; 163 int len;
161 164
162 while ( (len=(int)fread(buffer, 1, 1024, file)) ) 165 while ( (len=(int)fread(buffer, 1, BLOCK_LEN, file)) )
163 update(buffer, len); 166 update(buffer, len);
164 167
165 fclose (file); 168 fclose (file);
@@ -176,11 +179,11 @@ void LLMD5::update(FILE* file){
176 179
177void LLMD5::update(std::istream& stream){ 180void LLMD5::update(std::istream& stream){
178 181
179 unsigned char buffer[1024]; /* Flawfinder: ignore */ 182 unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
180 int len; 183 int len;
181 184
182 while (stream.good()){ 185 while (stream.good()){
183 stream.read( (char*)buffer, 1024); /* Flawfinder: ignore */ // note that return value of read is unusable. 186 stream.read( (char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable.
184 len=stream.gcount(); 187 len=stream.gcount();
185 update(buffer, len); 188 update(buffer, len);
186 } 189 }
@@ -366,11 +369,48 @@ void LLMD5::init(){
366#define S43 15 369#define S43 15
367#define S44 21 370#define S44 21
368 371
372// #defines are faster then inline, etc because the compiler is not required to inline.
373// Timing tests prove that this works ~40% faster on win with msvc++2k3 over using static inline.
374
375/* F, G, H and I are basic MD5 functions.
376 */
377#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
378#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
379#define H(x, y, z) ((x) ^ (y) ^ (z))
380#define I(x, y, z) ((y) ^ ((x) | (~z)))
381
382/* ROTATE_LEFT rotates x left n bits.
383 */
384#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
385
386/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
387Rotation is separate from addition to prevent recomputation.
388 */
389#define FF(a, b, c, d, x, s, ac) { \
390 (a) += F ((b), (c), (d)) + (x) + (U32)(ac); \
391 (a) = ROTATE_LEFT ((a), (s)); \
392 (a) += (b); \
393 }
394#define GG(a, b, c, d, x, s, ac) { \
395 (a) += G ((b), (c), (d)) + (x) + (U32)(ac); \
396 (a) = ROTATE_LEFT ((a), (s)); \
397 (a) += (b); \
398 }
399#define HH(a, b, c, d, x, s, ac) { \
400 (a) += H ((b), (c), (d)) + (x) + (U32)(ac); \
401 (a) = ROTATE_LEFT ((a), (s)); \
402 (a) += (b); \
403 }
404#define II(a, b, c, d, x, s, ac) { \
405 (a) += I ((b), (c), (d)) + (x) + (U32)(ac); \
406 (a) = ROTATE_LEFT ((a), (s)); \
407 (a) += (b); \
408 }
369 409
370 410
371 411
372// LLMD5 basic transformation. Transforms state based on block. 412// LLMD5 basic transformation. Transforms state based on block.
373void LLMD5::transform (const uint1 block[64]){ 413void LLMD5::transform (const U8 block[64]){
374 414
375 uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 415 uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
376 416
@@ -489,64 +529,3 @@ void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){
489 output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | 529 output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
490 (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); 530 (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
491} 531}
492
493
494
495
496
497// ROTATE_LEFT rotates x left n bits.
498
499inline unsigned int LLMD5::rotate_left (uint4 x, uint4 n){
500 return (x << n) | (x >> (32-n)) ;
501}
502
503
504
505
506// F, G, H and I are basic MD5 functions.
507
508inline unsigned int LLMD5::F (uint4 x, uint4 y, uint4 z){
509 return (x & y) | (~x & z);
510}
511
512inline unsigned int LLMD5::G (uint4 x, uint4 y, uint4 z){
513 return (x & z) | (y & ~z);
514}
515
516inline unsigned int LLMD5::H (uint4 x, uint4 y, uint4 z){
517 return x ^ y ^ z;
518}
519
520inline unsigned int LLMD5::I (uint4 x, uint4 y, uint4 z){
521 return y ^ (x | ~z);
522}
523
524
525
526// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
527// Rotation is separate from addition to prevent recomputation.
528
529
530inline void LLMD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
531 uint4 s, uint4 ac){
532 a += F(b, c, d) + x + ac;
533 a = rotate_left (a, s) +b;
534}
535
536inline void LLMD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
537 uint4 s, uint4 ac){
538 a += G(b, c, d) + x + ac;
539 a = rotate_left (a, s) +b;
540}
541
542inline void LLMD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
543 uint4 s, uint4 ac){
544 a += H(b, c, d) + x + ac;
545 a = rotate_left (a, s) +b;
546}
547
548inline void LLMD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
549 uint4 s, uint4 ac){
550 a += I(b, c, d) + x + ac;
551 a = rotate_left (a, s) +b;
552}
diff --git a/linden/indra/llmath/llmd5.h b/linden/indra/llmath/llmd5.h
index 20c32ed..5df98bf 100644
--- a/linden/indra/llmath/llmd5.h
+++ b/linden/indra/llmath/llmd5.h
@@ -85,6 +85,9 @@ class LLMD5 {
85 typedef unsigned short int uint2; // assumes short integer is 2 words long 85 typedef unsigned short int uint2; // assumes short integer is 2 words long
86 typedef unsigned char uint1; // assumes char is 1 word long 86 typedef unsigned char uint1; // assumes char is 1 word long
87 87
88// how many bytes to grab at a time when checking files
89 static const int BLOCK_LEN;
90
88public: 91public:
89// methods for controlled operation: 92// methods for controlled operation:
90 LLMD5 (); // simple initializer 93 LLMD5 (); // simple initializer
@@ -125,20 +128,6 @@ private:
125 static void encode (uint1 *dest, const uint4 *src, const uint4 length); 128 static void encode (uint1 *dest, const uint4 *src, const uint4 length);
126 static void decode (uint4 *dest, const uint1 *src, const uint4 length); 129 static void decode (uint4 *dest, const uint1 *src, const uint4 length);
127 130
128 static inline uint4 rotate_left (uint4 x, uint4 n);
129 static inline uint4 F (uint4 x, uint4 y, uint4 z);
130 static inline uint4 G (uint4 x, uint4 y, uint4 z);
131 static inline uint4 H (uint4 x, uint4 y, uint4 z);
132 static inline uint4 I (uint4 x, uint4 y, uint4 z);
133 static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
134 uint4 s, uint4 ac);
135 static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
136 uint4 s, uint4 ac);
137 static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
138 uint4 s, uint4 ac);
139 static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
140 uint4 s, uint4 ac);
141
142}; 131};
143 132
144#endif // LL_LLMD5_H 133#endif // LL_LLMD5_H
diff --git a/linden/indra/llmath/lloctree.h b/linden/indra/llmath/lloctree.h
index 004b0a2..2395f0f 100644
--- a/linden/indra/llmath/lloctree.h
+++ b/linden/indra/llmath/lloctree.h
@@ -95,34 +95,34 @@ public:
95 } 95 }
96 } 96 }
97 97
98 virtual ~LLOctreeNode() { BaseType::destroyListeners(); delete this->mState; } 98 ~LLOctreeNode() { BaseType::destroyListeners(); delete this->mState; }
99 99
100 virtual const BaseType* getParent() const { return mParent; } 100 inline const BaseType* getParent() const { return mParent; }
101 virtual void setParent(BaseType* parent) { mParent = (oct_node*) parent; } 101 inline void setParent(BaseType* parent) { mParent = (oct_node*) parent; }
102 virtual const LLVector3d& getCenter() const { return mCenter; } 102 inline const LLVector3d& getCenter() const { return mCenter; }
103 virtual const LLVector3d& getSize() const { return mSize; } 103 inline const LLVector3d& getSize() const { return mSize; }
104 virtual void setCenter(LLVector3d center) { mCenter = center; } 104 inline void setCenter(LLVector3d center) { mCenter = center; }
105 virtual void setSize(LLVector3d size) { mSize = size; } 105 inline void setSize(LLVector3d size) { mSize = size; }
106 virtual bool balance() { return getOctState()->balance(); } 106 inline bool balance() { return getOctState()->balance(); }
107 virtual void validate() { getOctState()->validate(); } 107 inline void validate() { getOctState()->validate(); }
108 virtual U32 getChildCount() const { return getOctState()->getChildCount(); } 108 inline U32 getChildCount() const { return getOctState()->getChildCount(); }
109 virtual oct_node* getChild(U32 index) { return getOctState()->getChild(index); } 109 inline oct_node* getChild(U32 index) { return getOctState()->getChild(index); }
110 virtual const oct_node* getChild(U32 index) const { return getOctState()->getChild(index); } 110 inline const oct_node* getChild(U32 index) const { return getOctState()->getChild(index); }
111 virtual U32 getElementCount() const { return getOctState()->getElementCount(); } 111 inline U32 getElementCount() const { return getOctState()->getElementCount(); }
112 virtual void removeByAddress(T* data) { getOctState()->removeByAddress(data); } 112 inline void removeByAddress(T* data) { getOctState()->removeByAddress(data); }
113 virtual bool hasLeafState() const { return getOctState()->isLeaf(); } 113 inline bool hasLeafState() const { return getOctState()->isLeaf(); }
114 virtual void destroy() { getOctState()->destroy(); } 114 inline void destroy() { getOctState()->destroy(); }
115 virtual oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } 115 inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); }
116 virtual oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) { return getOctState()->getNodeAt(pos, rad); } 116 inline oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) { return getOctState()->getNodeAt(pos, rad); }
117 virtual U8 getOctant() const { return mOctant; } 117 inline U8 getOctant() const { return mOctant; }
118 virtual void setOctant(U8 octant) { mOctant = octant; } 118 inline void setOctant(U8 octant) { mOctant = octant; }
119 virtual const oct_state* getOctState() const { return (const oct_state*) BaseType::mState; } 119 inline const oct_state* getOctState() const { return (const oct_state*) BaseType::mState; }
120 virtual oct_state* getOctState() { return (oct_state*) BaseType::mState; } 120 inline oct_state* getOctState() { return (oct_state*) BaseType::mState; }
121 virtual const oct_node* getOctParent() const { return (const oct_node*) getParent(); } 121 inline const oct_node* getOctParent() const { return (const oct_node*) getParent(); }
122 virtual oct_node* getOctParent() { return (oct_node*) getParent(); } 122 inline oct_node* getOctParent() { return (oct_node*) getParent(); }
123 virtual void deleteChild(oct_node* child) { getOctState()->deleteChild(child); } 123 inline void deleteChild(oct_node* child) { getOctState()->deleteChild(child); }
124 124
125 virtual U8 getOctant(const F64 pos[]) const //get the octant pos is in 125 U8 getOctant(const F64 pos[]) const //get the octant pos is in
126 { 126 {
127 U8 ret = 0; 127 U8 ret = 0;
128 128
@@ -142,17 +142,17 @@ public:
142 return ret; 142 return ret;
143 } 143 }
144 144
145 virtual bool isInside(const LLVector3d& pos, const F64& rad) const 145 inline bool isInside(const LLVector3d& pos, const F64& rad) const
146 { 146 {
147 return rad <= mSize.mdV[0]*2.0 && isInside(pos); 147 return rad <= mSize.mdV[0]*2.0 && isInside(pos);
148 } 148 }
149 149
150 virtual bool isInside(T* data) const 150 inline bool isInside(T* data) const
151 { 151 {
152 return isInside(data->getPositionGroup(), data->getBinRadius()); 152 return isInside(data->getPositionGroup(), data->getBinRadius());
153 } 153 }
154 154
155 virtual bool isInside(const LLVector3d& pos) const 155 bool isInside(const LLVector3d& pos) const
156 { 156 {
157 const F64& x = pos.mdV[0]; 157 const F64& x = pos.mdV[0];
158 const F64& y = pos.mdV[1]; 158 const F64& y = pos.mdV[1];
@@ -168,7 +168,7 @@ public:
168 return true; 168 return true;
169 } 169 }
170 170
171 virtual void updateMinMax() 171 void updateMinMax()
172 { 172 {
173 for (U32 i = 0; i < 3; i++) 173 for (U32 i = 0; i < 3; i++)
174 { 174 {
@@ -178,12 +178,12 @@ public:
178 } 178 }
179 } 179 }
180 180
181 virtual oct_listener* getOctListener(U32 index) 181 inline oct_listener* getOctListener(U32 index)
182 { 182 {
183 return (oct_listener*) BaseType::getListener(index); 183 return (oct_listener*) BaseType::getListener(index);
184 } 184 }
185 185
186 bool contains(T* xform) 186 inline bool contains(T* xform)
187 { 187 {
188 return contains(xform->getBinRadius()); 188 return contains(xform->getBinRadius());
189 } 189 }
diff --git a/linden/indra/llmath/llrect.h b/linden/indra/llmath/llrect.h
index a17ab39..38a4983 100644
--- a/linden/indra/llmath/llrect.h
+++ b/linden/indra/llmath/llrect.h
@@ -213,47 +213,28 @@ public:
213 mBottom = llmin(mBottom, mTop); 213 mBottom = llmin(mBottom, mTop);
214 } 214 }
215 215
216 friend const LLRectBase& operator|=(LLRectBase &a, const LLRectBase &b) // Return rect including a & b 216 void unionWith(const LLRectBase &other)
217 { 217 {
218 a.mLeft = llmin(a.mLeft, b.mLeft); 218 mLeft = llmin(mLeft, other.mLeft);
219 a.mRight = llmax(a.mRight, b.mRight); 219 mRight = llmax(mRight, other.mRight);
220 a.mBottom = llmin(a.mBottom, b.mBottom); 220 mBottom = llmin(mBottom, other.mBottom);
221 a.mTop = llmax(a.mTop, b.mTop); 221 mTop = llmax(mTop, other.mTop);
222 return a;
223 } 222 }
224 223
225 friend LLRectBase operator|(const LLRectBase &a, const LLRectBase &b) // Return rect including a & b 224 void intersectWith(const LLRectBase &other)
226 { 225 {
227 LLRectBase<Type> result; 226 mLeft = llmax(mLeft, other.mLeft);
228 result.mLeft = llmin(a.mLeft, b.mLeft); 227 mRight = llmin(mRight, other.mRight);
229 result.mRight = llmax(a.mRight, b.mRight); 228 mBottom = llmax(mBottom, other.mBottom);
230 result.mBottom = llmin(a.mBottom, b.mBottom); 229 mTop = llmin(mTop, other.mTop);
231 result.mTop = llmax(a.mTop, b.mTop); 230 if (mLeft > mRight)
232 return result;
233 }
234
235 friend const LLRectBase& operator&=(LLRectBase &a, const LLRectBase &b) // set a to rect where a intersects b
236 {
237 a.mLeft = llmax(a.mLeft, b.mLeft);
238 a.mRight = llmin(a.mRight, b.mRight);
239 a.mBottom = llmax(a.mBottom, b.mBottom);
240 a.mTop = llmin(a.mTop, b.mTop);
241 if (a.mLeft > a.mRight)
242 { 231 {
243 a.mLeft = a.mRight; 232 mLeft = mRight;
244 } 233 }
245 if (a.mBottom > a.mTop) 234 if (mBottom > mTop)
246 { 235 {
247 a.mBottom = a.mTop; 236 mBottom = mTop;
248 } 237 }
249 return a;
250 }
251
252 friend LLRectBase operator&(const LLRectBase &a, const LLRectBase &b) // Return rect where a intersects b
253 {
254 LLRectBase result = a;
255 result &= b;
256 return result;
257 } 238 }
258 239
259 friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect) 240 friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect)
diff --git a/linden/indra/llmath/lltreenode.h b/linden/indra/llmath/lltreenode.h
index a47795d..8a8710f 100644
--- a/linden/indra/llmath/lltreenode.h
+++ b/linden/indra/llmath/lltreenode.h
@@ -69,17 +69,17 @@ class LLTreeNode
69public: 69public:
70 LLTreeNode(LLTreeState<T>* state) { setState(state); } 70 LLTreeNode(LLTreeState<T>* state) { setState(state); }
71 virtual ~LLTreeNode(); 71 virtual ~LLTreeNode();
72 virtual LLTreeState<T>* getState() { return mState; } 72 LLTreeState<T>* getState() { return mState; }
73 virtual const LLTreeState<T>* getState() const { return mState; } 73 const LLTreeState<T>* getState() const { return mState; }
74 74
75 virtual void setState(LLTreeState<T>* state); 75 void setState(LLTreeState<T>* state);
76 virtual void insert(T* data); 76 void insert(T* data);
77 virtual bool remove(T* data); 77 bool remove(T* data);
78 virtual void notifyRemoval(T* data); 78 void notifyRemoval(T* data);
79 virtual U32 getListenerCount() { return mListeners.size(); } 79 inline U32 getListenerCount() { return mListeners.size(); }
80 virtual LLTreeListener<T>* getListener(U32 index) const { return mListeners[index]; } 80 inline LLTreeListener<T>* getListener(U32 index) const { return mListeners[index]; }
81 virtual void addListener(LLTreeListener<T>* listener) { mListeners.push_back(listener); } 81 inline void addListener(LLTreeListener<T>* listener) { mListeners.push_back(listener); }
82 virtual void removeListener(U32 index) { mListeners.erase(mListeners.begin()+index); } 82 inline void removeListener(U32 index) { mListeners.erase(mListeners.begin()+index); }
83 83
84protected: 84protected:
85 void destroyListeners() 85 void destroyListeners()
diff --git a/linden/indra/llmath/lluuid.cpp b/linden/indra/llmath/lluuid.cpp
index 0fed6b3..97d8c1c 100644
--- a/linden/indra/llmath/lluuid.cpp
+++ b/linden/indra/llmath/lluuid.cpp
@@ -613,7 +613,9 @@ S32 LLUUID::getNodeID(unsigned char *node_id)
613#define HAVE_NETINET_IN_H 613#define HAVE_NETINET_IN_H
614#ifdef HAVE_NETINET_IN_H 614#ifdef HAVE_NETINET_IN_H
615#include <netinet/in.h> 615#include <netinet/in.h>
616#if !LL_DARWIN 616#if LL_SOLARIS
617#include <sys/sockio.h>
618#elif !LL_DARWIN
617#include <linux/sockios.h> 619#include <linux/sockios.h>
618#endif 620#endif
619#endif 621#endif
diff --git a/linden/indra/llmath/llv4math.h b/linden/indra/llmath/llv4math.h
new file mode 100644
index 0000000..2853ab6
--- /dev/null
+++ b/linden/indra/llmath/llv4math.h
@@ -0,0 +1,143 @@
1/**
2 * @file llv4math.h
3 * @brief LLV4* class header file - vector processor enabled math
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LL_LLV4MATH_H
30#define LL_LLV4MATH_H
31
32// *NOTE: We do not support SSE acceleration on Windows builds.
33// Our minimum specification for the viewer includes 1 GHz Athlon processors,
34// which covers the Athlon Thunderbird series that does not support SSE.
35//
36// Our header files include statements like this
37// const F32 HAVOK_TIMESTEP = 1.f / 45.f;
38// This creates "globals" that are included in each .obj file. If a single
39// .cpp file has SSE code generation turned on (eg, llviewerjointmesh_sse.cpp)
40// these globals will be initialized using SSE instructions. This causes SL
41// to crash before main() on processors without SSE. Untangling all these
42// headers/variables is too much work for the small performance gains of
43// vectorization.
44//
45// Therefore we only support vectorization on builds where the everything is
46// built with SSE or Altivec. See https://jira.secondlife.com/browse/VWR-1610
47// and https://jira.lindenlab.com/browse/SL-47720 for details.
48//
49// Sorry the code is such a mess. JC
50
51//-----------------------------------------------------------------------------
52//-----------------------------------------------------------------------------
53// LLV4MATH - GNUC
54//-----------------------------------------------------------------------------
55//-----------------------------------------------------------------------------
56
57#if LL_GNUC && __GNUC__ >= 4 && __SSE__
58
59#define LL_VECTORIZE 1
60
61#if LL_DARWIN
62
63#include <Accelerate/Accelerate.h>
64#include <xmmintrin.h>
65typedef vFloat V4F32;
66
67#else
68
69#include <xmmintrin.h>
70typedef float V4F32 __attribute__((vector_size(16)));
71
72#endif
73
74#endif
75#if LL_GNUC
76
77#define LL_LLV4MATH_ALIGN_PREFIX
78#define LL_LLV4MATH_ALIGN_POSTFIX __attribute__((aligned(16)))
79
80#endif
81
82//-----------------------------------------------------------------------------
83//-----------------------------------------------------------------------------
84// LLV4MATH - MSVC
85//-----------------------------------------------------------------------------
86//-----------------------------------------------------------------------------
87
88// Only vectorize if the entire Windows build uses SSE.
89// _M_IX86_FP is set when SSE code generation is turned on, and I have
90// confirmed this in VS2003, VS2003 SP1, and VS2005. JC
91#if LL_MSVC && _M_IX86_FP
92
93#define LL_VECTORIZE 1
94
95#include <xmmintrin.h>
96
97typedef __m128 V4F32;
98
99#endif
100#if LL_MSVC
101
102#define LL_LLV4MATH_ALIGN_PREFIX __declspec(align(16))
103#define LL_LLV4MATH_ALIGN_POSTFIX
104
105#endif
106
107//-----------------------------------------------------------------------------
108//-----------------------------------------------------------------------------
109// LLV4MATH - default - no vectorization
110//-----------------------------------------------------------------------------
111//-----------------------------------------------------------------------------
112
113#if !LL_VECTORIZE
114
115#define LL_VECTORIZE 0
116
117struct V4F32 { F32 __pad__[4]; };
118
119inline F32 llv4lerp(F32 a, F32 b, F32 w) { return ( b - a ) * w + a; }
120
121#endif
122
123#ifndef LL_LLV4MATH_ALIGN_PREFIX
124# define LL_LLV4MATH_ALIGN_PREFIX
125#endif
126#ifndef LL_LLV4MATH_ALIGN_POSTFIX
127# define LL_LLV4MATH_ALIGN_POSTFIX
128#endif
129
130//-----------------------------------------------------------------------------
131//-----------------------------------------------------------------------------
132// LLV4MATH
133//-----------------------------------------------------------------------------
134//-----------------------------------------------------------------------------
135
136
137#define LLV4_NUM_AXIS 4
138
139class LLV4Vector3;
140class LLV4Matrix3;
141class LLV4Matrix4;
142
143#endif
diff --git a/linden/indra/llmath/llv4matrix3.h b/linden/indra/llmath/llv4matrix3.h
new file mode 100644
index 0000000..0811338
--- /dev/null
+++ b/linden/indra/llmath/llv4matrix3.h
@@ -0,0 +1,222 @@
1/**
2 * @file llviewerjointmesh.cpp
3 * @brief LLV4* class header file - vector processor enabled math
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LL_LLV4MATRIX3_H
30#define LL_LLV4MATRIX3_H
31
32#include "llv4math.h"
33#include "llv4vector3.h"
34#include "m3math.h" // for operator LLMatrix3()
35
36//-----------------------------------------------------------------------------
37//-----------------------------------------------------------------------------
38// LLV4Matrix3
39//-----------------------------------------------------------------------------
40//-----------------------------------------------------------------------------
41
42LL_LLV4MATH_ALIGN_PREFIX
43
44class LLV4Matrix3
45{
46public:
47 union {
48 F32 mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS];
49 V4F32 mV[LLV4_NUM_AXIS];
50 };
51
52 void lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w);
53 void multiply(const LLVector3 &a, LLVector3& out) const;
54 void multiply(const LLVector4 &a, LLV4Vector3& out) const;
55 void multiply(const LLVector3 &a, LLV4Vector3& out) const;
56
57 const LLV4Matrix3& transpose();
58 const LLV4Matrix3& operator=(const LLMatrix3& a);
59
60 operator LLMatrix3() const { return (reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0])))->getMat3(); }
61
62 friend LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b);
63}
64
65LL_LLV4MATH_ALIGN_POSTFIX;
66
67
68
69//-----------------------------------------------------------------------------
70//-----------------------------------------------------------------------------
71// LLV4Matrix3 - SSE
72//-----------------------------------------------------------------------------
73//-----------------------------------------------------------------------------
74
75#if LL_VECTORIZE
76
77inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
78{
79 __m128 vw = _mm_set1_ps(w);
80 mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a
81 mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
82 mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
83}
84
85inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
86{
87 LLV4Vector3 j;
88 j.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
89 j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
90 j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
91 o.setVec(j.mV);
92}
93
94inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
95{
96 o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
97 o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
98 o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
99}
100
101inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
102{
103 o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
104 o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
105 o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
106}
107
108//-----------------------------------------------------------------------------
109//-----------------------------------------------------------------------------
110// LLV4Matrix3
111//-----------------------------------------------------------------------------
112//-----------------------------------------------------------------------------
113
114#else
115
116inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
117{
118 mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
119 mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
120 mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
121
122 mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
123 mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
124 mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
125
126 mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
127 mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
128 mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
129}
130
131inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
132{
133 o.setVec( a.mV[VX] * mMatrix[VX][VX] +
134 a.mV[VY] * mMatrix[VY][VX] +
135 a.mV[VZ] * mMatrix[VZ][VX],
136
137 a.mV[VX] * mMatrix[VX][VY] +
138 a.mV[VY] * mMatrix[VY][VY] +
139 a.mV[VZ] * mMatrix[VZ][VY],
140
141 a.mV[VX] * mMatrix[VX][VZ] +
142 a.mV[VY] * mMatrix[VY][VZ] +
143 a.mV[VZ] * mMatrix[VZ][VZ]);
144}
145
146inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
147{
148 o.setVec( a.mV[VX] * mMatrix[VX][VX] +
149 a.mV[VY] * mMatrix[VY][VX] +
150 a.mV[VZ] * mMatrix[VZ][VX],
151
152 a.mV[VX] * mMatrix[VX][VY] +
153 a.mV[VY] * mMatrix[VY][VY] +
154 a.mV[VZ] * mMatrix[VZ][VY],
155
156 a.mV[VX] * mMatrix[VX][VZ] +
157 a.mV[VY] * mMatrix[VY][VZ] +
158 a.mV[VZ] * mMatrix[VZ][VZ]);
159}
160
161inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
162{
163 o.setVec( a.mV[VX] * mMatrix[VX][VX] +
164 a.mV[VY] * mMatrix[VY][VX] +
165 a.mV[VZ] * mMatrix[VZ][VX],
166
167 a.mV[VX] * mMatrix[VX][VY] +
168 a.mV[VY] * mMatrix[VY][VY] +
169 a.mV[VZ] * mMatrix[VZ][VY],
170
171 a.mV[VX] * mMatrix[VX][VZ] +
172 a.mV[VY] * mMatrix[VY][VZ] +
173 a.mV[VZ] * mMatrix[VZ][VZ]);
174}
175
176//-----------------------------------------------------------------------------
177//-----------------------------------------------------------------------------
178// LLV4Matrix3
179//-----------------------------------------------------------------------------
180//-----------------------------------------------------------------------------
181
182#endif
183
184inline const LLV4Matrix3& LLV4Matrix3::transpose()
185{
186#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
187 _MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
188 return *this;
189#else
190 F32 temp;
191 temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
192 temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
193 temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
194#endif
195 return *this;
196}
197
198inline const LLV4Matrix3& LLV4Matrix3::operator=(const LLMatrix3& a)
199{
200 memcpy(mMatrix[VX], a.mMatrix[VX], sizeof(F32) * 3 );
201 memcpy(mMatrix[VY], a.mMatrix[VY], sizeof(F32) * 3 );
202 memcpy(mMatrix[VZ], a.mMatrix[VZ], sizeof(F32) * 3 );
203 return *this;
204}
205
206inline LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b)
207{
208 return LLVector3(
209 a.mV[VX] * b.mMatrix[VX][VX] +
210 a.mV[VY] * b.mMatrix[VY][VX] +
211 a.mV[VZ] * b.mMatrix[VZ][VX],
212
213 a.mV[VX] * b.mMatrix[VX][VY] +
214 a.mV[VY] * b.mMatrix[VY][VY] +
215 a.mV[VZ] * b.mMatrix[VZ][VY],
216
217 a.mV[VX] * b.mMatrix[VX][VZ] +
218 a.mV[VY] * b.mMatrix[VY][VZ] +
219 a.mV[VZ] * b.mMatrix[VZ][VZ] );
220}
221
222#endif
diff --git a/linden/indra/llmath/llv4matrix4.h b/linden/indra/llmath/llv4matrix4.h
new file mode 100644
index 0000000..38280a2
--- /dev/null
+++ b/linden/indra/llmath/llv4matrix4.h
@@ -0,0 +1,251 @@
1/**
2 * @file llviewerjointmesh.cpp
3 * @brief LLV4* class header file - vector processor enabled math
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LL_LLV4MATRIX4_H
30#define LL_LLV4MATRIX4_H
31
32#include "llv4math.h"
33#include "llv4matrix3.h" // just for operator LLV4Matrix3()
34#include "llv4vector3.h"
35
36//-----------------------------------------------------------------------------
37//-----------------------------------------------------------------------------
38// LLV4Matrix4
39//-----------------------------------------------------------------------------
40//-----------------------------------------------------------------------------
41
42LL_LLV4MATH_ALIGN_PREFIX
43
44class LLV4Matrix4
45{
46public:
47 union {
48 F32 mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS];
49 V4F32 mV[LLV4_NUM_AXIS];
50 };
51
52 void lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w);
53 void multiply(const LLVector3 &a, LLVector3& o) const;
54 void multiply(const LLVector3 &a, LLV4Vector3& o) const;
55
56 const LLV4Matrix4& transpose();
57 const LLV4Matrix4& translate(const LLVector3 &vec);
58 const LLV4Matrix4& translate(const LLV4Vector3 &vec);
59 const LLV4Matrix4& operator=(const LLMatrix4& a);
60
61 operator LLMatrix4() const { return *(reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0]))); }
62 operator LLV4Matrix3() const { return *(reinterpret_cast<const LLV4Matrix3*>(const_cast<const F32*>(&mMatrix[0][0]))); }
63
64 friend LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b);
65}
66
67LL_LLV4MATH_ALIGN_POSTFIX;
68
69//-----------------------------------------------------------------------------
70//-----------------------------------------------------------------------------
71// LLV4Matrix4 - SSE
72//-----------------------------------------------------------------------------
73//-----------------------------------------------------------------------------
74
75#if LL_VECTORIZE
76
77inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
78{
79 __m128 vw = _mm_set1_ps(w);
80 mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a
81 mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
82 mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
83 mV[VW] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VW], a.mV[VW]), vw), a.mV[VW]);
84}
85
86inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
87{
88 LLV4Vector3 j;
89 j.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
90 j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
91 j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
92 o.setVec(j.mV);
93}
94
95inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
96{
97 o.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
98 o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
99 o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
100}
101
102inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
103{
104 mV[VW] = _mm_add_ps(mV[VW], vec.v);
105 return (*this);
106}
107
108//-----------------------------------------------------------------------------
109//-----------------------------------------------------------------------------
110// LLV4Matrix4
111//-----------------------------------------------------------------------------
112//-----------------------------------------------------------------------------
113
114#else
115
116inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
117{
118 mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
119 mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
120 mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
121
122 mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
123 mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
124 mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
125
126 mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
127 mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
128 mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
129
130 mMatrix[VW][VX] = llv4lerp(a.mMatrix[VW][VX], b.mMatrix[VW][VX], w);
131 mMatrix[VW][VY] = llv4lerp(a.mMatrix[VW][VY], b.mMatrix[VW][VY], w);
132 mMatrix[VW][VZ] = llv4lerp(a.mMatrix[VW][VZ], b.mMatrix[VW][VZ], w);
133}
134
135inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
136{
137 o.setVec( a.mV[VX] * mMatrix[VX][VX] +
138 a.mV[VY] * mMatrix[VY][VX] +
139 a.mV[VZ] * mMatrix[VZ][VX] +
140 mMatrix[VW][VX],
141
142 a.mV[VX] * mMatrix[VX][VY] +
143 a.mV[VY] * mMatrix[VY][VY] +
144 a.mV[VZ] * mMatrix[VZ][VY] +
145 mMatrix[VW][VY],
146
147 a.mV[VX] * mMatrix[VX][VZ] +
148 a.mV[VY] * mMatrix[VY][VZ] +
149 a.mV[VZ] * mMatrix[VZ][VZ] +
150 mMatrix[VW][VZ]);
151}
152
153inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
154{
155 o.setVec( a.mV[VX] * mMatrix[VX][VX] +
156 a.mV[VY] * mMatrix[VY][VX] +
157 a.mV[VZ] * mMatrix[VZ][VX] +
158 mMatrix[VW][VX],
159
160 a.mV[VX] * mMatrix[VX][VY] +
161 a.mV[VY] * mMatrix[VY][VY] +
162 a.mV[VZ] * mMatrix[VZ][VY] +
163 mMatrix[VW][VY],
164
165 a.mV[VX] * mMatrix[VX][VZ] +
166 a.mV[VY] * mMatrix[VY][VZ] +
167 a.mV[VZ] * mMatrix[VZ][VZ] +
168 mMatrix[VW][VZ]);
169}
170
171inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
172{
173 mMatrix[3][0] += vec.mV[0];
174 mMatrix[3][1] += vec.mV[1];
175 mMatrix[3][2] += vec.mV[2];
176 return (*this);
177}
178
179//-----------------------------------------------------------------------------
180//-----------------------------------------------------------------------------
181// LLV4Matrix4
182//-----------------------------------------------------------------------------
183//-----------------------------------------------------------------------------
184
185#endif
186
187inline const LLV4Matrix4& LLV4Matrix4::operator=(const LLMatrix4& a)
188{
189 memcpy(mMatrix, a.mMatrix, sizeof(F32) * 16 );
190 return *this;
191}
192
193inline const LLV4Matrix4& LLV4Matrix4::transpose()
194{
195#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
196 _MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
197#else
198 LLV4Matrix4 mat;
199 mat.mMatrix[0][0] = mMatrix[0][0];
200 mat.mMatrix[1][0] = mMatrix[0][1];
201 mat.mMatrix[2][0] = mMatrix[0][2];
202 mat.mMatrix[3][0] = mMatrix[0][3];
203
204 mat.mMatrix[0][1] = mMatrix[1][0];
205 mat.mMatrix[1][1] = mMatrix[1][1];
206 mat.mMatrix[2][1] = mMatrix[1][2];
207 mat.mMatrix[3][1] = mMatrix[1][3];
208
209 mat.mMatrix[0][2] = mMatrix[2][0];
210 mat.mMatrix[1][2] = mMatrix[2][1];
211 mat.mMatrix[2][2] = mMatrix[2][2];
212 mat.mMatrix[3][2] = mMatrix[2][3];
213
214 mat.mMatrix[0][3] = mMatrix[3][0];
215 mat.mMatrix[1][3] = mMatrix[3][1];
216 mat.mMatrix[2][3] = mMatrix[3][2];
217 mat.mMatrix[3][3] = mMatrix[3][3];
218
219 *this = mat;
220#endif
221 return *this;
222}
223
224inline const LLV4Matrix4& LLV4Matrix4::translate(const LLVector3 &vec)
225{
226 mMatrix[3][0] += vec.mV[0];
227 mMatrix[3][1] += vec.mV[1];
228 mMatrix[3][2] += vec.mV[2];
229 return (*this);
230}
231
232inline LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b)
233{
234 return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] +
235 a.mV[VY] * b.mMatrix[VY][VX] +
236 a.mV[VZ] * b.mMatrix[VZ][VX] +
237 b.mMatrix[VW][VX],
238
239 a.mV[VX] * b.mMatrix[VX][VY] +
240 a.mV[VY] * b.mMatrix[VY][VY] +
241 a.mV[VZ] * b.mMatrix[VZ][VY] +
242 b.mMatrix[VW][VY],
243
244 a.mV[VX] * b.mMatrix[VX][VZ] +
245 a.mV[VY] * b.mMatrix[VY][VZ] +
246 a.mV[VZ] * b.mMatrix[VZ][VZ] +
247 b.mMatrix[VW][VZ]);
248}
249
250
251#endif
diff --git a/linden/indra/llmath/llv4vector3.h b/linden/indra/llmath/llv4vector3.h
new file mode 100644
index 0000000..994e7f5
--- /dev/null
+++ b/linden/indra/llmath/llv4vector3.h
@@ -0,0 +1,82 @@
1/**
2 * @file llviewerjointmesh.cpp
3 * @brief LLV4* class header file - vector processor enabled math
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LL_LLV4VECTOR3_H
30#define LL_LLV4VECTOR3_H
31
32#include "llv4math.h"
33
34//-----------------------------------------------------------------------------
35//-----------------------------------------------------------------------------
36// LLV4Vector3
37//-----------------------------------------------------------------------------
38//-----------------------------------------------------------------------------
39
40LL_LLV4MATH_ALIGN_PREFIX
41
42class LLV4Vector3
43{
44public:
45 union {
46 F32 mV[LLV4_NUM_AXIS];
47 V4F32 v;
48 };
49
50 enum {
51 ALIGNMENT = 16
52 };
53
54 void setVec(F32 x, F32 y, F32 z);
55 void setVec(F32 a);
56}
57
58LL_LLV4MATH_ALIGN_POSTFIX;
59
60//-----------------------------------------------------------------------------
61//-----------------------------------------------------------------------------
62// LLV4Vector3
63//-----------------------------------------------------------------------------
64//-----------------------------------------------------------------------------
65
66inline void LLV4Vector3::setVec(F32 x, F32 y, F32 z)
67{
68 mV[VX] = x;
69 mV[VY] = y;
70 mV[VZ] = z;
71}
72
73inline void LLV4Vector3::setVec(F32 a)
74{
75#if LL_VECTORIZE
76 v = _mm_set1_ps(a);
77#else
78 setVec(a, a, a);
79#endif
80}
81
82#endif
diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp
index 5764c38..c0a33c7 100644
--- a/linden/indra/llmath/llvolume.cpp
+++ b/linden/indra/llmath/llvolume.cpp
@@ -750,7 +750,11 @@ BOOL LLProfileParams::importFile(FILE *fp)
750 750
751 while (!feof(fp)) 751 while (!feof(fp))
752 { 752 {
753 fgets(buffer, BUFSIZE, fp); 753 if (fgets(buffer, BUFSIZE, fp) == NULL)
754 {
755 buffer[0] = '\0';
756 }
757
754 sscanf( /* Flawfinder: ignore */ 758 sscanf( /* Flawfinder: ignore */
755 buffer, 759 buffer,
756 " %255s %255s", 760 " %255s %255s",
@@ -1251,7 +1255,11 @@ BOOL LLPathParams::importFile(FILE *fp)
1251 1255
1252 while (!feof(fp)) 1256 while (!feof(fp))
1253 { 1257 {
1254 fgets(buffer, BUFSIZE, fp); 1258 if (fgets(buffer, BUFSIZE, fp) == NULL)
1259 {
1260 buffer[0] = '\0';
1261 }
1262
1255 sscanf( /* Flawfinder: ignore */ 1263 sscanf( /* Flawfinder: ignore */
1256 buffer, 1264 buffer,
1257 " %255s %255s", 1265 " %255s %255s",
@@ -3582,7 +3590,11 @@ BOOL LLVolumeParams::importFile(FILE *fp)
3582 3590
3583 while (!feof(fp)) 3591 while (!feof(fp))
3584 { 3592 {
3585 fgets(buffer, BUFSIZE, fp); 3593 if (fgets(buffer, BUFSIZE, fp) == NULL)
3594 {
3595 buffer[0] = '\0';
3596 }
3597
3586 sscanf(buffer, " %255s", keyword); /* Flawfinder: ignore */ 3598 sscanf(buffer, " %255s", keyword); /* Flawfinder: ignore */
3587 if (!strcmp("{", keyword)) 3599 if (!strcmp("{", keyword))
3588 { 3600 {
diff --git a/linden/indra/llmath/llvolume.h b/linden/indra/llmath/llvolume.h
index 8292d0c..ee28057 100644
--- a/linden/indra/llmath/llvolume.h
+++ b/linden/indra/llmath/llvolume.h
@@ -783,7 +783,7 @@ public:
783 FLAT_MASK = 0x0100, 783 FLAT_MASK = 0x0100,
784 TOP_MASK = 0x0200, 784 TOP_MASK = 0x0200,
785 BOTTOM_MASK = 0x0400 785 BOTTOM_MASK = 0x0400
786 } TypeMask; 786 };
787 787
788public: 788public:
789 S32 mID; 789 S32 mID;
diff --git a/linden/indra/llmedia/files.lst b/linden/indra/llmedia/files.lst
index 35ae5ab..bda6459 100644
--- a/linden/indra/llmedia/files.lst
+++ b/linden/indra/llmedia/files.lst
@@ -1,4 +1,7 @@
1llmedia/llmediabase.cpp 1llmedia/llmediabase.cpp
2llmedia/llmediaengine.cpp 2llmedia/llmediaengine.cpp
3llmedia/llmediaimplgstreamer.cpp
4llmedia/llmediaimplgstreamer_syms.cpp
5llmedia/llmediaimplgstreamervidplug.cpp
3llmedia/llmediaimplquicktime.cpp 6llmedia/llmediaimplquicktime.cpp
4llmedia/llmediamoviebase.cpp 7llmedia/llmediamoviebase.cpp
diff --git a/linden/indra/llmedia/llmedia_vc8.vcproj b/linden/indra/llmedia/llmedia_vc8.vcproj
index 12fa817..2bc8014 100644
--- a/linden/indra/llmedia/llmedia_vc8.vcproj
+++ b/linden/indra/llmedia/llmedia_vc8.vcproj
@@ -1,297 +1,297 @@
1<?xml version="1.0" encoding="Windows-1252"?> 1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject 2<VisualStudioProject
3 ProjectType="Visual C++" 3 ProjectType="Visual C++"
4 Version="8.00" 4 Version="8.00"
5 Name="llmedia" 5 Name="llmedia"
6 ProjectGUID="{9D0C7E02-6506-4EE7-BC5C-75671D28D594}" 6 ProjectGUID="{9D0C7E02-6506-4EE7-BC5C-75671D28D594}"
7 RootNamespace="llmedia" 7 RootNamespace="llmedia"
8 Keyword="Win32Proj" 8 Keyword="Win32Proj"
9 > 9 >
10 <Platforms> 10 <Platforms>
11 <Platform 11 <Platform
12 Name="Win32" 12 Name="Win32"
13 /> 13 />
14 </Platforms> 14 </Platforms>
15 <ToolFiles> 15 <ToolFiles>
16 </ToolFiles> 16 </ToolFiles>
17 <Configurations> 17 <Configurations>
18 <Configuration 18 <Configuration
19 Name="Debug|Win32" 19 Name="Debug|Win32"
20 OutputDirectory="../lib_$(ConfigurationName)/i686-win32" 20 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
21 IntermediateDirectory="Debug" 21 IntermediateDirectory="Debug"
22 ConfigurationType="4" 22 ConfigurationType="4"
23 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" 23 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
24 CharacterSet="1" 24 CharacterSet="1"
25 > 25 >
26 <Tool 26 <Tool
27 Name="VCPreBuildEventTool" 27 Name="VCPreBuildEventTool"
28 /> 28 />
29 <Tool 29 <Tool
30 Name="VCCustomBuildTool" 30 Name="VCCustomBuildTool"
31 /> 31 />
32 <Tool 32 <Tool
33 Name="VCXMLDataGeneratorTool" 33 Name="VCXMLDataGeneratorTool"
34 /> 34 />
35 <Tool 35 <Tool
36 Name="VCWebServiceProxyGeneratorTool" 36 Name="VCWebServiceProxyGeneratorTool"
37 /> 37 />
38 <Tool 38 <Tool
39 Name="VCMIDLTool" 39 Name="VCMIDLTool"
40 /> 40 />
41 <Tool 41 <Tool
42 Name="VCCLCompilerTool" 42 Name="VCCLCompilerTool"
43 Optimization="0" 43 Optimization="0"
44 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;" 44 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;"
45 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_DEBUG;XP_WIN;XP_WIN32" 45 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_DEBUG;XP_WIN;XP_WIN32"
46 MinimalRebuild="true" 46 MinimalRebuild="true"
47 BasicRuntimeChecks="3" 47 BasicRuntimeChecks="3"
48 RuntimeLibrary="1" 48 RuntimeLibrary="1"
49 StructMemberAlignment="4" 49 StructMemberAlignment="4"
50 TreatWChar_tAsBuiltInType="false" 50 TreatWChar_tAsBuiltInType="false"
51 ForceConformanceInForLoopScope="true" 51 ForceConformanceInForLoopScope="true"
52 UsePrecompiledHeader="0" 52 UsePrecompiledHeader="0"
53 WarningLevel="3" 53 WarningLevel="3"
54 WarnAsError="true" 54 WarnAsError="true"
55 Detect64BitPortabilityProblems="false" 55 Detect64BitPortabilityProblems="false"
56 DebugInformationFormat="4" 56 DebugInformationFormat="4"
57 DisableSpecificWarnings="4702" 57 DisableSpecificWarnings="4702"
58 /> 58 />
59 <Tool 59 <Tool
60 Name="VCManagedResourceCompilerTool" 60 Name="VCManagedResourceCompilerTool"
61 /> 61 />
62 <Tool 62 <Tool
63 Name="VCResourceCompilerTool" 63 Name="VCResourceCompilerTool"
64 /> 64 />
65 <Tool 65 <Tool
66 Name="VCPreLinkEventTool" 66 Name="VCPreLinkEventTool"
67 /> 67 />
68 <Tool 68 <Tool
69 Name="VCLibrarianTool" 69 Name="VCLibrarianTool"
70 OutputFile="$(OutDir)/llmedia.lib" 70 OutputFile="$(OutDir)/llmedia.lib"
71 AdditionalLibraryDirectories="" 71 AdditionalLibraryDirectories=""
72 /> 72 />
73 <Tool 73 <Tool
74 Name="VCALinkTool" 74 Name="VCALinkTool"
75 /> 75 />
76 <Tool 76 <Tool
77 Name="VCXDCMakeTool" 77 Name="VCXDCMakeTool"
78 /> 78 />
79 <Tool 79 <Tool
80 Name="VCBscMakeTool" 80 Name="VCBscMakeTool"
81 /> 81 />
82 <Tool 82 <Tool
83 Name="VCFxCopTool" 83 Name="VCFxCopTool"
84 /> 84 />
85 <Tool 85 <Tool
86 Name="VCPostBuildEventTool" 86 Name="VCPostBuildEventTool"
87 /> 87 />
88 </Configuration> 88 </Configuration>
89 <Configuration 89 <Configuration
90 Name="Release|Win32" 90 Name="Release|Win32"
91 OutputDirectory="../lib_$(ConfigurationName)/i686-win32" 91 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
92 IntermediateDirectory="Release" 92 IntermediateDirectory="Release"
93 ConfigurationType="4" 93 ConfigurationType="4"
94 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" 94 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
95 CharacterSet="1" 95 CharacterSet="1"
96 > 96 >
97 <Tool 97 <Tool
98 Name="VCPreBuildEventTool" 98 Name="VCPreBuildEventTool"
99 /> 99 />
100 <Tool 100 <Tool
101 Name="VCCustomBuildTool" 101 Name="VCCustomBuildTool"
102 /> 102 />
103 <Tool 103 <Tool
104 Name="VCXMLDataGeneratorTool" 104 Name="VCXMLDataGeneratorTool"
105 /> 105 />
106 <Tool 106 <Tool
107 Name="VCWebServiceProxyGeneratorTool" 107 Name="VCWebServiceProxyGeneratorTool"
108 /> 108 />
109 <Tool 109 <Tool
110 Name="VCMIDLTool" 110 Name="VCMIDLTool"
111 /> 111 />
112 <Tool 112 <Tool
113 Name="VCCLCompilerTool" 113 Name="VCCLCompilerTool"
114 InlineFunctionExpansion="0" 114 InlineFunctionExpansion="0"
115 EnableIntrinsicFunctions="false" 115 EnableIntrinsicFunctions="false"
116 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;" 116 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;"
117 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE;XP_WIN;XP_WIN32" 117 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE;XP_WIN;XP_WIN32"
118 RuntimeLibrary="0" 118 RuntimeLibrary="0"
119 StructMemberAlignment="0" 119 StructMemberAlignment="0"
120 TreatWChar_tAsBuiltInType="false" 120 TreatWChar_tAsBuiltInType="false"
121 ForceConformanceInForLoopScope="true" 121 ForceConformanceInForLoopScope="true"
122 UsePrecompiledHeader="0" 122 UsePrecompiledHeader="0"
123 WarningLevel="3" 123 WarningLevel="3"
124 WarnAsError="false" 124 WarnAsError="false"
125 Detect64BitPortabilityProblems="false" 125 Detect64BitPortabilityProblems="false"
126 DebugInformationFormat="3" 126 DebugInformationFormat="3"
127 DisableSpecificWarnings="4702" 127 DisableSpecificWarnings="4702"
128 /> 128 />
129 <Tool 129 <Tool
130 Name="VCManagedResourceCompilerTool" 130 Name="VCManagedResourceCompilerTool"
131 /> 131 />
132 <Tool 132 <Tool
133 Name="VCResourceCompilerTool" 133 Name="VCResourceCompilerTool"
134 /> 134 />
135 <Tool 135 <Tool
136 Name="VCPreLinkEventTool" 136 Name="VCPreLinkEventTool"
137 /> 137 />
138 <Tool 138 <Tool
139 Name="VCLibrarianTool" 139 Name="VCLibrarianTool"
140 OutputFile="$(OutDir)/llmedia.lib" 140 OutputFile="$(OutDir)/llmedia.lib"
141 AdditionalLibraryDirectories="" 141 AdditionalLibraryDirectories=""
142 IgnoreAllDefaultLibraries="false" 142 IgnoreAllDefaultLibraries="false"
143 IgnoreDefaultLibraryNames="" 143 IgnoreDefaultLibraryNames=""
144 /> 144 />
145 <Tool 145 <Tool
146 Name="VCALinkTool" 146 Name="VCALinkTool"
147 /> 147 />
148 <Tool 148 <Tool
149 Name="VCXDCMakeTool" 149 Name="VCXDCMakeTool"
150 /> 150 />
151 <Tool 151 <Tool
152 Name="VCBscMakeTool" 152 Name="VCBscMakeTool"
153 /> 153 />
154 <Tool 154 <Tool
155 Name="VCFxCopTool" 155 Name="VCFxCopTool"
156 /> 156 />
157 <Tool 157 <Tool
158 Name="VCPostBuildEventTool" 158 Name="VCPostBuildEventTool"
159 /> 159 />
160 </Configuration> 160 </Configuration>
161 <Configuration 161 <Configuration
162 Name="ReleaseNoOpt|Win32" 162 Name="ReleaseNoOpt|Win32"
163 OutputDirectory="../lib_$(ConfigurationName)/i686-win32" 163 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
164 IntermediateDirectory="$(ConfigurationName)" 164 IntermediateDirectory="$(ConfigurationName)"
165 ConfigurationType="4" 165 ConfigurationType="4"
166 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" 166 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
167 CharacterSet="1" 167 CharacterSet="1"
168 > 168 >
169 <Tool 169 <Tool
170 Name="VCPreBuildEventTool" 170 Name="VCPreBuildEventTool"
171 /> 171 />
172 <Tool 172 <Tool
173 Name="VCCustomBuildTool" 173 Name="VCCustomBuildTool"
174 /> 174 />
175 <Tool 175 <Tool
176 Name="VCXMLDataGeneratorTool" 176 Name="VCXMLDataGeneratorTool"
177 /> 177 />
178 <Tool 178 <Tool
179 Name="VCWebServiceProxyGeneratorTool" 179 Name="VCWebServiceProxyGeneratorTool"
180 /> 180 />
181 <Tool 181 <Tool
182 Name="VCMIDLTool" 182 Name="VCMIDLTool"
183 /> 183 />
184 <Tool 184 <Tool
185 Name="VCCLCompilerTool" 185 Name="VCCLCompilerTool"
186 Optimization="0" 186 Optimization="0"
187 InlineFunctionExpansion="0" 187 InlineFunctionExpansion="0"
188 EnableIntrinsicFunctions="false" 188 EnableIntrinsicFunctions="false"
189 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;" 189 AdditionalIncludeDirectories="..\llcommon;..\llrender;..\llwindow;..\llimage;..\llmath;..\llvfs;..\llmessage;..\llui;&quot;..\..\libraries\i686-win32\include&quot;;..\..\libraries\include\;&quot;..\..\libraries\i686-win32\include\quicktime&quot;"
190 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE;XP_WIN;XP_WIN32" 190 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE;XP_WIN;XP_WIN32"
191 RuntimeLibrary="0" 191 RuntimeLibrary="0"
192 StructMemberAlignment="0" 192 StructMemberAlignment="0"
193 TreatWChar_tAsBuiltInType="false" 193 TreatWChar_tAsBuiltInType="false"
194 ForceConformanceInForLoopScope="true" 194 ForceConformanceInForLoopScope="true"
195 UsePrecompiledHeader="0" 195 UsePrecompiledHeader="0"
196 WarningLevel="3" 196 WarningLevel="3"
197 WarnAsError="true" 197 WarnAsError="true"
198 Detect64BitPortabilityProblems="false" 198 Detect64BitPortabilityProblems="false"
199 DebugInformationFormat="3" 199 DebugInformationFormat="3"
200 DisableSpecificWarnings="4702" 200 DisableSpecificWarnings="4702"
201 /> 201 />
202 <Tool 202 <Tool
203 Name="VCManagedResourceCompilerTool" 203 Name="VCManagedResourceCompilerTool"
204 /> 204 />
205 <Tool 205 <Tool
206 Name="VCResourceCompilerTool" 206 Name="VCResourceCompilerTool"
207 /> 207 />
208 <Tool 208 <Tool
209 Name="VCPreLinkEventTool" 209 Name="VCPreLinkEventTool"
210 /> 210 />
211 <Tool 211 <Tool
212 Name="VCLibrarianTool" 212 Name="VCLibrarianTool"
213 OutputFile="$(OutDir)/llmedia.lib" 213 OutputFile="$(OutDir)/llmedia.lib"
214 AdditionalLibraryDirectories="" 214 AdditionalLibraryDirectories=""
215 IgnoreAllDefaultLibraries="false" 215 IgnoreAllDefaultLibraries="false"
216 IgnoreDefaultLibraryNames="" 216 IgnoreDefaultLibraryNames=""
217 /> 217 />
218 <Tool 218 <Tool
219 Name="VCALinkTool" 219 Name="VCALinkTool"
220 /> 220 />
221 <Tool 221 <Tool
222 Name="VCXDCMakeTool" 222 Name="VCXDCMakeTool"
223 /> 223 />
224 <Tool 224 <Tool
225 Name="VCBscMakeTool" 225 Name="VCBscMakeTool"
226 /> 226 />
227 <Tool 227 <Tool
228 Name="VCFxCopTool" 228 Name="VCFxCopTool"
229 /> 229 />
230 <Tool 230 <Tool
231 Name="VCPostBuildEventTool" 231 Name="VCPostBuildEventTool"
232 /> 232 />
233 </Configuration> 233 </Configuration>
234 </Configurations> 234 </Configurations>
235 <References> 235 <References>
236 </References> 236 </References>
237 <Files> 237 <Files>
238 <Filter 238 <Filter
239 Name="Source Files" 239 Name="Source Files"
240 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" 240 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
241 UniqueIdentifier="{44DBC47A-0AF0-4726-A094-2D6FBB65FFFA}" 241 UniqueIdentifier="{44DBC47A-0AF0-4726-A094-2D6FBB65FFFA}"
242 > 242 >
243 <File 243 <File
244 RelativePath=".\llmediabase.cpp" 244 RelativePath=".\llmediabase.cpp"
245 > 245 >
246 </File> 246 </File>
247 <File 247 <File
248 RelativePath=".\llmediaengine.cpp" 248 RelativePath=".\llmediaengine.cpp"
249 > 249 >
250 </File> 250 </File>
251 <File 251 <File
252 RelativePath=".\llmediaimplquicktime.cpp" 252 RelativePath=".\llmediaimplquicktime.cpp"
253 > 253 >
254 </File> 254 </File>
255 <File 255 <File
256 RelativePath=".\llmediamoviebase.cpp" 256 RelativePath=".\llmediamoviebase.cpp"
257 > 257 >
258 </File> 258 </File>
259 <File 259 <File
260 RelativePath=".\llmediamoviebase.h" 260 RelativePath=".\llmediamoviebase.h"
261 > 261 >
262 </File> 262 </File>
263 </Filter> 263 </Filter>
264 <Filter 264 <Filter
265 Name="Header Files" 265 Name="Header Files"
266 Filter="h;hpp;hxx;hm;inl;inc;xsd" 266 Filter="h;hpp;hxx;hm;inl;inc;xsd"
267 UniqueIdentifier="{D188664C-B9B7-4982-8C4B-8D9A44B4D9EF}" 267 UniqueIdentifier="{D188664C-B9B7-4982-8C4B-8D9A44B4D9EF}"
268 > 268 >
269 <File 269 <File
270 RelativePath=".\llmediabase.h" 270 RelativePath=".\llmediabase.h"
271 > 271 >
272 </File> 272 </File>
273 <File 273 <File
274 RelativePath=".\llmediaemitter.h" 274 RelativePath=".\llmediaemitter.h"
275 > 275 >
276 </File> 276 </File>
277 <File 277 <File
278 RelativePath=".\llmediaemitterevents.h" 278 RelativePath=".\llmediaemitterevents.h"
279 > 279 >
280 </File> 280 </File>
281 <File 281 <File
282 RelativePath=".\llmediaengine.h" 282 RelativePath=".\llmediaengine.h"
283 > 283 >
284 </File> 284 </File>
285 <File 285 <File
286 RelativePath=".\llmediaimplquicktime.h" 286 RelativePath=".\llmediaimplquicktime.h"
287 > 287 >
288 </File> 288 </File>
289 <File 289 <File
290 RelativePath=".\llmediaobservers.h" 290 RelativePath=".\llmediaobservers.h"
291 > 291 >
292 </File> 292 </File>
293 </Filter> 293 </Filter>
294 </Files> 294 </Files>
295 <Globals> 295 <Globals>
296 </Globals> 296 </Globals>
297</VisualStudioProject> 297</VisualStudioProject>
diff --git a/linden/indra/llmedia/llmediabase.cpp b/linden/indra/llmedia/llmediabase.cpp
index 7abf960..17bb563 100644
--- a/linden/indra/llmedia/llmediabase.cpp
+++ b/linden/indra/llmedia/llmediabase.cpp
@@ -30,6 +30,7 @@
30 30
31#include "llmediabase.h" 31#include "llmediabase.h"
32#include "llmediaimplquicktime.h" 32#include "llmediaimplquicktime.h"
33#include "llmediaimplgstreamer.h"
33 34
34LLMediaBase::LLMediaBase() : 35LLMediaBase::LLMediaBase() :
35 mBufferChangeCount ( 1 ), 36 mBufferChangeCount ( 1 ),
@@ -60,6 +61,13 @@ LLMediaBase* LLMediaBase::make( const MediaType mediaTypeIn, S32 width_pixels, S
60 } 61 }
61 else 62 else
62#endif 63#endif
64#if LL_GSTREAMER_ENABLED
65 if ( mediaTypeIn == QuickTime )
66 {
67 return new LLMediaImplGStreamer ();
68 }
69 else
70#endif
63 71
64 return 0; 72 return 0;
65} 73}
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.cpp b/linden/indra/llmedia/llmediaimplgstreamer.cpp
new file mode 100644
index 0000000..f8b4c74
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer.cpp
@@ -0,0 +1,715 @@
1/**
2 * @file llmediaimplgstreamer.cpp
3 * @brief implementation that supports various media through GStreamer.
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "linden_common.h"
30
31#if LL_GSTREAMER_ENABLED
32
33extern "C" {
34#include <gst/gst.h>
35}
36
37#include "llmediaimplgstreamer.h"
38
39#include "llmediaimplgstreamervidplug.h"
40
41#ifdef LL_GST_SOUNDSINK
42#include "llmediaimplgstreamersndplug.h"
43#endif // LL_GST_SOUNDSINK
44
45#include "llmediaimplgstreamer_syms.h"
46
47#include "llgl.h"
48#include "llglheaders.h" // For gl texture modes
49
50///////////////////////////////////////////////////////////////////////////////
51//
52LLMediaImplGStreamer::
53LLMediaImplGStreamer () :
54 mediaData ( NULL ),
55 ownBuffer ( TRUE ),
56 mVolume ( 1.0f ),
57 currentMode ( ModeIdle ),
58 mPump ( NULL ),
59 mPlaybin ( NULL ),
60 mVideoSink ( NULL )
61#ifdef LL_GST_SOUNDSINK
62 ,mAudioSink ( NULL )
63#endif // LL_GST_SOUNDSINK
64{
65 mMediaDepthBytes = 4;
66 mTextureDepth = 4;
67 mTextureFormatInternal = GL_RGB8;
68 mTextureFormatPrimary = GL_BGRA;
69 mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV;
70}
71
72///////////////////////////////////////////////////////////////////////////////
73//
74LLMediaImplGStreamer::
75~LLMediaImplGStreamer ()
76{
77 unload();
78}
79
80void UnloadGStreamer()
81{
82 ungrab_gst_syms();
83}
84
85
86///////////////////////////////////////////////////////////////////////////////
87//
88BOOL
89LLMediaImplGStreamer::
90setBuffer ( U8* bufferIn )
91{
92 // Since we've pointed GStreamer at the old media data buffer
93 // directly, we need to be somewhat careful deleting it...
94 U8* oldMediaData = mediaData;
95 BOOL ownedMediaData = ownBuffer;
96
97 if(bufferIn == NULL)
98 {
99 // Passing NULL to this function requests that the object
100 // allocate its own buffer.
101 mediaData = new unsigned char[ mMediaHeight * mMediaRowbytes ];
102 ownBuffer = TRUE;
103 }
104 else
105 {
106 // Use the supplied buffer.
107 mediaData = bufferIn;
108 ownBuffer = FALSE;
109 }
110
111 if(mediaData == NULL)
112 {
113 // This is bad - probably out of memory.
114 llerrs << "LLMediaImplGStreamer::setBuffer: mediaData is NULL" << llendl;
115 // NOTE: This case doesn't clean up properly. This assert is fatal, so this isn't a huge problem,
116 // but if this assert is ever removed the code should be fixed to clean up correctly.
117 return FALSE;
118 }
119
120 // [..]
121
122 // Delete the old media data buffer iff we owned it.
123 if ( ownedMediaData )
124 {
125 if ( oldMediaData )
126 {
127 delete [] oldMediaData;
128 }
129 }
130
131 return TRUE;
132}
133
134///////////////////////////////////////////////////////////////////////////////
135//
136BOOL
137LLMediaImplGStreamer::
138init ()
139{
140 static bool done_init = false;
141 if (!done_init)
142 {
143 // Get symbols!
144 if (! grab_gst_syms("libgstreamer-0.10.so.0",
145 "libgstvideo-0.10.so.0",
146 "libgstaudio-0.10.so.0") )
147 {
148 llwarns << "Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled." << llendl;
149 return FALSE;
150 }
151
152 if (llgst_segtrap_set_enabled)
153 llgst_segtrap_set_enabled(FALSE);
154 else
155 llwarns << "gst_segtrap_set_enabled() is not available; Second Life automated crash-reporter may cease to function until next restart." << llendl;
156
157 if (0 == llgst_init_check(NULL, NULL, NULL))
158 {
159 return FALSE;
160 }
161
162 // Init our custom plugins - only really need do this once.
163 gst_slvideo_init_class();
164#if 0
165 gst_slsound_init_class();
166#endif
167
168 done_init = true;
169 }
170
171 // Create a pumpable main-loop for this media
172 mPump = g_main_loop_new (NULL, FALSE);
173 if (!mPump)
174 {
175 return FALSE;
176 }
177
178 // instantiate a playbin element to do the hard work
179 mPlaybin = llgst_element_factory_make ("playbin", "play");
180 if (!mPlaybin)
181 {
182 // todo: cleanup pump
183 return FALSE;
184 }
185
186 if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) {
187 // instantiate and connect a custom video sink
188 mVideoSink =
189 GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo"));
190 if (!mVideoSink)
191 {
192 llwarns << "Could not instantiate private-slvideo element."
193 << llendl;
194 // todo: cleanup.
195 return FALSE;
196 }
197
198 g_object_set(mPlaybin, "video-sink", mVideoSink, NULL);
199
200#ifdef LL_GST_SOUNDSINK
201 // instantiate and connect a custom audio sink
202 mAudioSink =
203 GST_SLSOUND(llgst_element_factory_make ("private-slsound", "slsound"));
204 if (!mAudioSink)
205 {
206 llwarns << "Could not instantiate private-slsound element."
207 << llendl;
208 // todo: cleanup.
209 return FALSE;
210 }
211
212 g_object_set(mPlaybin, "audio-sink", mAudioSink, NULL);
213#endif
214 }
215
216 return LLMediaMovieBase::init();
217}
218
219
220///////////////////////////////////////////////////////////////////////////////
221//
222//#define LL_GST_REPORT_STATE_CHANGES
223#ifdef LL_GST_REPORT_STATE_CHANGES
224static char* get_gst_state_name(GstState state)
225{
226 switch (state) {
227 case GST_STATE_VOID_PENDING: return "VOID_PENDING";
228 case GST_STATE_NULL: return "NULL";
229 case GST_STATE_READY: return "READY";
230 case GST_STATE_PAUSED: return "PAUSED";
231 case GST_STATE_PLAYING: return "PLAYING";
232 }
233 return "(unknown)";
234}
235#endif // LL_GST_REPORT_STATE_CHANGES
236
237static gboolean
238my_bus_callback (GstBus *bus,
239 GstMessage *message,
240 gpointer data)
241{
242 if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
243 GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
244 {
245 llinfos << "Got GST message type: "
246 << LLGST_MESSAGE_TYPE_NAME (message)
247 << llendl;
248 }
249 else
250 {
251 lldebugs << "Got GST message type: "
252 << LLGST_MESSAGE_TYPE_NAME (message)
253 << llendl;
254 }
255
256 LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data;
257
258 switch (GST_MESSAGE_TYPE (message)) {
259 case GST_MESSAGE_BUFFERING: {
260 // NEEDS GST 0.10.11+
261 if (llgst_message_parse_buffering)
262 {
263 gint percent = 0;
264 llgst_message_parse_buffering(message, &percent);
265 llinfos << "GST buffering: " << percent
266 << "%" << llendl;
267 // ModeBuffering seems to do nothing except make
268 // the UI worse
269 /*if (percent < 100) impl->setCurrentMode(LLMediaImplGStreamer::ModeBuffering);*/
270 }
271 break;
272 }
273 case GST_MESSAGE_STATE_CHANGED: {
274 GstState old_state;
275 GstState new_state;
276 GstState pending_state;
277 llgst_message_parse_state_changed(message,
278 &old_state,
279 &new_state,
280 &pending_state);
281#ifdef LL_GST_REPORT_STATE_CHANGES
282 // not generally very useful, and rather spammy.
283 llinfos << "state change (old,<new>,pending): "
284 << get_gst_state_name(old_state) << ", <"
285 << get_gst_state_name(new_state) << ">, "
286 << get_gst_state_name(pending_state) <<
287 llendl;
288#endif // LL_GST_REPORT_STATE_CHANGES
289
290 switch (new_state) {
291 case GST_STATE_VOID_PENDING:
292 impl->setCurrentMode(LLMediaImplGStreamer::ModeNone);
293 break;
294 case GST_STATE_NULL:
295 impl->setCurrentMode(LLMediaImplGStreamer::ModeNone);
296 break;
297 case GST_STATE_READY:
298 impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);
299 break;
300 case GST_STATE_PAUSED:
301 impl->setCurrentMode(LLMediaImplGStreamer::ModePaused);
302 break;
303 case GST_STATE_PLAYING:
304 impl->setCurrentMode(LLMediaImplGStreamer::ModePlaying);
305 break;
306 }
307 break;
308 }
309 case GST_MESSAGE_ERROR: {
310 GError *err;
311 gchar *debug;
312
313 llgst_message_parse_error (message, &err, &debug);
314 llinfos << "GST error: " << err->message << llendl;
315 g_error_free (err);
316 g_free (debug);
317
318 impl->setCurrentMode(LLMediaImplGStreamer::ModeError);
319
320 impl->stop();
321
322 break;
323 }
324 case GST_MESSAGE_INFO: {
325 if (llgst_message_parse_info)
326 {
327 GError *err;
328 gchar *debug;
329
330 llgst_message_parse_info (message, &err, &debug);
331 llinfos << "GST info: " << err->message << llendl;
332 g_error_free (err);
333 g_free (debug);
334 }
335 break;
336 }
337 case GST_MESSAGE_WARNING: {
338 GError *err;
339 gchar *debug;
340
341 llgst_message_parse_warning (message, &err, &debug);
342 llinfos << "GST warning: " << err->message << llendl;
343 g_error_free (err);
344 g_free (debug);
345
346 break;
347 }
348 case GST_MESSAGE_EOS:
349 /* end-of-stream */
350 llinfos << "GST EOS." << llendl;
351 impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);//?
352 impl->stop();
353 break;
354 default:
355 /* unhandled message */
356 break;
357 }
358
359 /* we want to be notified again the next time there is a message
360 * on the bus, so returning TRUE (FALSE means we want to stop watching
361 * for messages on the bus and our callback should not be called again)
362 */
363 return TRUE;
364}
365
366BOOL
367LLMediaImplGStreamer::
368load ( const LLString& urlIn )
369{
370 llinfos << "Setting media URI: " << urlIn << llendl;
371
372 // set URI
373 g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL);
374 //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL);
375
376 // get playbin's bus - perhaps this can/should be done at init()
377 GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin));
378 if (!bus)
379 {
380 return FALSE;
381 }
382 llgst_bus_add_watch (bus, my_bus_callback, this);
383 llgst_object_unref (bus);
384
385 if (true) // dummy values
386 {
387 const int fixedsize = 2;
388 mMediaRowbytes = mMediaDepthBytes * fixedsize;
389 mMediaWidth = fixedsize;
390 mMediaHeight = fixedsize;
391 mTextureWidth = fixedsize;
392 mTextureHeight = fixedsize;
393 }
394
395 BOOL rtn = LLMediaMovieBase::load(urlIn);
396 llinfos << "load returns " << int(rtn) << llendl;
397 return rtn;
398}
399
400///////////////////////////////////////////////////////////////////////////////
401//
402BOOL
403LLMediaImplGStreamer::
404unload ()
405{
406 if (mPlaybin)
407 {
408 llgst_element_set_state (mPlaybin, GST_STATE_NULL);
409 llgst_object_unref (GST_OBJECT (mPlaybin));
410 mPlaybin = NULL;
411 }
412
413 if (mPump)
414 {
415 g_main_loop_quit(mPump);
416 mPump = NULL;
417 }
418
419 if (mediaData)
420 {
421 if (ownBuffer)
422 {
423 delete mediaData;
424 mediaData = NULL;
425 }
426 }
427
428 mVideoSink = NULL;
429
430 return TRUE;
431}
432
433///////////////////////////////////////////////////////////////////////////////
434//
435S32
436LLMediaImplGStreamer::
437updateMedia ()
438{
439 //llinfos << "updating media..." << llendl;
440 if (g_main_context_pending(g_main_loop_get_context(mPump)))
441 {
442 g_main_context_iteration(g_main_loop_get_context(mPump), FALSE);
443 }
444
445 if (mVideoSink)
446 {
447 GST_OBJECT_LOCK(mVideoSink);
448 if (mVideoSink->retained_frame_ready)
449 {
450 //llinfos << "NEW FRAME " << llendl;
451 if (mVideoSink->retained_frame_width != mMediaWidth ||
452 mVideoSink->retained_frame_height != mMediaHeight)
453 // *TODO: also check for change in format
454 {
455 // just resize container
456 mMediaWidth = mVideoSink->retained_frame_width;
457 mMediaHeight = mVideoSink->retained_frame_height;
458 mTextureWidth = mMediaWidth;
459 mTextureHeight = mMediaHeight;
460 mMediaDepthBytes = mTextureDepth =
461 SLVPixelFormatBytes[mVideoSink->retained_frame_format];
462 if (SLV_PF_RGBX == mVideoSink->retained_frame_format)
463 {
464 mTextureFormatPrimary = GL_RGBA;
465 mTextureFormatType=GL_UNSIGNED_INT_8_8_8_8_REV;
466 }
467 else
468 {
469 mTextureFormatPrimary = GL_BGRA;
470 mTextureFormatType=GL_UNSIGNED_INT_8_8_8_8_REV;
471 }
472 mMediaRowbytes = mMediaWidth * mMediaDepthBytes;
473 llinfos << "video container resized to " <<
474 mMediaWidth << "x" << mMediaHeight << llendl;
475
476 if (ownBuffer)
477 {
478 // we manage the buffer, so we need to realloc
479 delete[] mediaData;
480 mediaData = new U8[mMediaRowbytes *
481 mMediaHeight];
482 }
483
484 GST_OBJECT_UNLOCK(mVideoSink);
485 return updateMediaNeedsSizeChange;
486 }
487
488 // we're gonna totally consume this frame - reset 'ready' flag
489 mVideoSink->retained_frame_ready = FALSE;
490 memcpy(mediaData, mVideoSink->retained_frame_data,
491 mMediaRowbytes * mMediaHeight);
492
493 GST_OBJECT_UNLOCK(mVideoSink);
494 return updateMediaNeedsUpdate;
495 }
496 else
497 {
498 // nothing to do yet.
499 GST_OBJECT_UNLOCK(mVideoSink);
500 return updateMediaNoChanges;
501 }
502 }
503
504 return updateMediaNoChanges;
505}
506
507///////////////////////////////////////////////////////////////////////////////
508//
509void
510LLMediaImplGStreamer::
511setAutoScaled ( BOOL autoScaledIn )
512{
513 autoScaled = autoScaledIn;
514}
515
516///////////////////////////////////////////////////////////////////////////////
517//
518BOOL
519LLMediaImplGStreamer::
520stop ()
521{
522 llinfos << "stopping media..." << llendl;
523 // todo: error-check this?
524 llgst_element_set_state(mPlaybin, GST_STATE_READY);
525
526 BOOL rtn = LLMediaMovieBase::stop();
527 setCurrentMode(LLMediaImplGStreamer::ModeStopped);//?
528 return rtn;
529}
530
531///////////////////////////////////////////////////////////////////////////////
532//
533BOOL
534LLMediaImplGStreamer::
535play ()
536{
537 llinfos << "playing media..." << llendl;
538 // todo: error-check this?
539 llgst_element_set_state(mPlaybin, GST_STATE_PLAYING);
540
541 return LLMediaMovieBase::play();
542}
543
544///////////////////////////////////////////////////////////////////////////////
545//
546BOOL
547LLMediaImplGStreamer::
548loop ( S32 howMany )
549{
550 llinfos << "looping media... " << howMany << llendl;
551 // todo: implement this
552 if (!play())
553 return FALSE;
554
555 return LLMediaMovieBase::loop(howMany);
556};
557
558///////////////////////////////////////////////////////////////////////////////
559//
560BOOL
561LLMediaImplGStreamer::
562pause ()
563{
564 llinfos << "pausing media..." << llendl;
565 // todo: error-check this?
566 llgst_element_set_state(mPlaybin, GST_STATE_PAUSED);
567
568 return LLMediaMovieBase::pause();
569};
570
571///////////////////////////////////////////////////////////////////////////////
572//
573BOOL
574LLMediaImplGStreamer::
575setVolume ( F32 volumeIn )
576{
577 mVolume = volumeIn;
578 g_object_set(mPlaybin, "volume", mVolume, NULL);
579 return TRUE;
580}
581
582///////////////////////////////////////////////////////////////////////////////
583//
584F32
585LLMediaImplGStreamer::
586getVolume ()
587{
588 return mVolume;
589}
590
591///////////////////////////////////////////////////////////////////////////////
592//
593BOOL
594LLMediaImplGStreamer::
595isIdle () const
596{
597 // todo: probably semantically decouple from currentMode
598 return currentMode == ModeIdle;
599}
600
601///////////////////////////////////////////////////////////////////////////////
602//
603BOOL
604LLMediaImplGStreamer::
605isError () const
606{
607 // todo: probably semantically decouple from currentMode
608 return currentMode == ModeError;
609}
610
611///////////////////////////////////////////////////////////////////////////////
612//
613BOOL
614LLMediaImplGStreamer::
615isBuffering () const
616{
617 // todo: probably semantically decouple from currentMode
618 return currentMode == ModeBuffering;
619}
620
621///////////////////////////////////////////////////////////////////////////////
622//
623BOOL
624LLMediaImplGStreamer::
625isLoaded () const
626{
627 // todo: probably semantically decouple from currentMode
628 //return currentMode == ModeLoaded;
629 return (mPump != NULL);
630}
631
632///////////////////////////////////////////////////////////////////////////////
633//
634BOOL
635LLMediaImplGStreamer::
636isPlaying () const
637{
638 // todo: probably semantically decouple from currentMode
639 return currentMode == ModePlaying;
640}
641
642///////////////////////////////////////////////////////////////////////////////
643//
644BOOL
645LLMediaImplGStreamer::
646isLooping () const
647{
648 // todo: probably semantically decouple from currentMode
649 return currentMode == ModeLooping;
650}
651
652///////////////////////////////////////////////////////////////////////////////
653//
654BOOL
655LLMediaImplGStreamer::
656isPaused () const
657{
658 // todo: probably semantically decouple from currentMode
659 return currentMode == ModePaused;
660}
661
662///////////////////////////////////////////////////////////////////////////////
663//
664BOOL
665LLMediaImplGStreamer::
666isStopped () const
667{
668 // todo: probably semantically decouple from currentMode
669 return currentMode == ModeStopped;
670}
671
672///////////////////////////////////////////////////////////////////////////////
673//
674U8*
675LLMediaImplGStreamer::
676getMediaData ()
677{
678 return mediaData;
679}
680
681///////////////////////////////////////////////////////////////////////////////
682//
683BOOL
684LLMediaImplGStreamer::
685seek ( F64 time )
686{
687 // todo: implement this
688 llinfos << "Tried to seek to time " << time
689 << " - faking it" << llendl;
690 return TRUE;
691}
692
693///////////////////////////////////////////////////////////////////////////////
694//
695F64
696LLMediaImplGStreamer::
697getTime () const
698{
699 // todo: implement this
700 F64 result = 0;
701 return result;
702}
703
704///////////////////////////////////////////////////////////////////////////////
705//
706F64
707LLMediaImplGStreamer::
708getMediaDuration () const
709{
710 // todo: implement this
711 F64 result = 0;
712 return result;
713}
714
715#endif // LL_GSTREAMER_ENABLED
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.h b/linden/indra/llmedia/llmediaimplgstreamer.h
new file mode 100644
index 0000000..52a5c84
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer.h
@@ -0,0 +1,126 @@
1/**
2 * @file llmediaimplgstreamer.h
3 * @brief implementation that supports media playback via GStreamer.
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29// header guard
30#ifndef llmediaimplgstreamer_h
31#define llmediaimplgstreamer_h
32
33#if LL_GSTREAMER_ENABLED
34
35extern "C" {
36#include <gst/gst.h>
37
38#include <apr-1/apr_pools.h>
39#include <apr-1/apr_dso.h>
40}
41
42#include "stdtypes.h"
43
44#include "llmediamoviebase.h"
45
46#include "llmediaimplgstreamervidplug.h"
47#ifdef LL_GST_SOUNDSINK
48#include "llmediaimplgstreamersndplug.h"
49#endif // LL_GST_SOUNDSINK
50
51///////////////////////////////////////////////////////////////////////////
52class LLMediaImplGStreamer:
53 public LLMediaMovieBase
54{
55 public:
56 LLMediaImplGStreamer ();
57 virtual ~LLMediaImplGStreamer ();
58
59 ////////////////////////////////////////////////////////
60 // implementation of the media public interface
61
62 // housekeeping
63 virtual BOOL setBuffer ( U8* bufferIn );
64 virtual BOOL init ();
65 virtual BOOL load ( const LLString& urlIn );
66 virtual BOOL unload ();
67
68 // transport controls
69 virtual BOOL stop ();
70 virtual BOOL play ();
71 virtual BOOL loop ( S32 howMany );
72 virtual BOOL pause ();
73 virtual BOOL seek ( F64 time );
74
75 // audio levels
76 virtual BOOL setVolume ( F32 volumeIn );
77 virtual F32 getVolume ();
78
79 // status
80 virtual BOOL isIdle () const;
81 virtual BOOL isBuffering () const;
82 virtual BOOL isError () const;
83 virtual BOOL isLoaded () const;
84 virtual BOOL isStopped () const;
85 virtual BOOL isPaused () const;
86 virtual BOOL isPlaying () const;
87 virtual BOOL isLooping () const;
88 virtual F64 getTime () const;
89
90 // media data
91 virtual S32 updateMedia ();
92 virtual void setAutoScaled ( BOOL autoScaledIn );
93 virtual U8* getMediaData ();
94 virtual F64 getMediaDuration () const;
95
96 // class-specific
97 GMainLoop *getPump() {return mPump;};
98 typedef enum { ModeNone, ModeIdle, ModeError, ModeBuffering, ModeStopped, ModePaused, ModePlaying, ModeLooping } llGstMode;
99 llGstMode getCurrentMode() {return currentMode;};
100 void setCurrentMode(llGstMode mode) {currentMode = mode;};
101
102 private:
103 // misc
104 U8* mediaData;
105 BOOL ownBuffer;
106 BOOL autoScaled;
107 F32 mVolume;
108
109 llGstMode currentMode;
110
111 // GStreamer-specific
112 GMainLoop *mPump; // event pump for this media
113 GstElement *mPlaybin;
114 GstSLVideo *mVideoSink;
115#ifdef LL_GST_SOUNDSINK
116 GstSLSound *mAudioSink;
117#endif // LL_GST_SOUNDSINK
118};
119
120// called during shutdown when no instances may exist
121void UnloadGStreamer();
122
123
124#endif // LL_GSTREAMER_ENABLED
125
126#endif // llmediaimplgstreamer_h
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp b/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp
new file mode 100644
index 0000000..76f62e1
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp
@@ -0,0 +1,189 @@
1/**
2 * @file llmediaimplgstreamer_syms.cpp
3 * @brief dynamic GStreamer symbol-grabbing code
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "linden_common.h"
30
31#if LL_GSTREAMER_ENABLED
32
33extern "C" {
34#include <gst/gst.h>
35
36#include <apr-1/apr_pools.h>
37#include <apr-1/apr_dso.h>
38}
39
40#include "llmediaimplgstreamer.h"
41
42#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL
43#include "llmediaimplgstreamer_syms_raw.inc"
44#include "llmediaimplgstreamer_syms_rawa.inc"
45#include "llmediaimplgstreamer_syms_rawv.inc"
46#undef LL_GST_SYM
47
48
49static bool sSymsGrabbed = false;
50static apr_pool_t *sSymGSTDSOMemoryPool = NULL;
51static apr_dso_handle_t *sSymGSTDSOHandleG = NULL;
52static apr_dso_handle_t *sSymGSTDSOHandleV = NULL;
53static apr_dso_handle_t *sSymGSTDSOHandleA = NULL;
54
55
56bool grab_gst_syms(std::string gst_dso_name,
57 std::string gst_dso_name_vid,
58 std::string gst_dso_name_aud)
59{
60 if (sSymsGrabbed)
61 {
62 // already have grabbed good syms
63 return TRUE;
64 }
65
66 bool sym_error = false;
67 bool rtn = false;
68 apr_status_t rv;
69 apr_dso_handle_t *sSymGSTDSOHandle = NULL;
70
71#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {llwarns << "Failed to grab symbol: " << #GSTSYM << llendl; if (REQ) sym_error = true;} else llinfos << "grabbed symbol: " << #GSTSYM << " from " << (void*)ll##GSTSYM << llendl;}while(0)
72
73 //attempt to load the shared libraries
74 apr_pool_create(&sSymGSTDSOMemoryPool, NULL);
75
76 if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle,
77 gst_dso_name.c_str(),
78 sSymGSTDSOMemoryPool) ))
79 {
80 llinfos << "Found DSO: " << gst_dso_name << llendl;
81#include "llmediaimplgstreamer_syms_raw.inc"
82
83 if ( sSymGSTDSOHandle )
84 {
85 sSymGSTDSOHandleG = sSymGSTDSOHandle;
86 sSymGSTDSOHandle = NULL;
87 }
88
89 if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle,
90 gst_dso_name_aud.c_str(),
91 sSymGSTDSOMemoryPool) ))
92 {
93 llinfos << "Found DSO: " << gst_dso_name_aud << llendl;
94#include "llmediaimplgstreamer_syms_rawa.inc"
95
96 if ( sSymGSTDSOHandle )
97 {
98 sSymGSTDSOHandleA = sSymGSTDSOHandle;
99 sSymGSTDSOHandle = NULL;
100 }
101
102 if ( APR_SUCCESS ==
103 (rv = apr_dso_load(&sSymGSTDSOHandle,
104 gst_dso_name_vid.c_str(),
105 sSymGSTDSOMemoryPool) ))
106 {
107 llinfos << "Found DSO: " << gst_dso_name_vid << llendl;
108#include "llmediaimplgstreamer_syms_rawv.inc"
109 }
110 else
111 {
112 llwarns << "Couldn't load DSO: "
113 << gst_dso_name_vid << llendl;
114 rtn = false; // failure
115 }
116 }
117 else
118 {
119 llwarns << "Couldn't load DSO: "
120 << gst_dso_name_aud << llendl;
121 rtn = false; // failure
122 }
123
124 rtn = !sym_error;
125 }
126 else
127 {
128 llwarns << "Couldn't load DSO: " << gst_dso_name << llendl;
129 rtn = false; // failure
130 }
131
132 if (sym_error)
133 {
134 llwarns << "Failed to find necessary symbols in GStreamer libraries." << llendl;
135 }
136
137 if ( sSymGSTDSOHandle )
138 {
139 sSymGSTDSOHandleV = sSymGSTDSOHandle;
140 sSymGSTDSOHandle = NULL;
141 }
142#undef LL_GST_SYM
143
144 sSymsGrabbed = !!rtn;
145 return rtn;
146}
147
148
149void ungrab_gst_syms()
150{
151 // should be safe to call regardless of whether we've
152 // actually grabbed syms.
153
154 if ( sSymGSTDSOHandleG )
155 {
156 apr_dso_unload(sSymGSTDSOHandleG);
157 sSymGSTDSOHandleG = NULL;
158 }
159
160 if ( sSymGSTDSOHandleA )
161 {
162 apr_dso_unload(sSymGSTDSOHandleA);
163 sSymGSTDSOHandleA = NULL;
164 }
165
166 if ( sSymGSTDSOHandleV )
167 {
168 apr_dso_unload(sSymGSTDSOHandleV);
169 sSymGSTDSOHandleV = NULL;
170 }
171
172 if ( sSymGSTDSOMemoryPool )
173 {
174 apr_pool_destroy(sSymGSTDSOMemoryPool);
175 sSymGSTDSOMemoryPool = NULL;
176 }
177
178 // NULL-out all of the symbols we'd grabbed
179#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0)
180#include "llmediaimplgstreamer_syms_raw.inc"
181#include "llmediaimplgstreamer_syms_rawa.inc"
182#include "llmediaimplgstreamer_syms_rawv.inc"
183#undef LL_GST_SYM
184
185 sSymsGrabbed = false;
186}
187
188
189#endif // LL_GSTREAMER_ENABLED
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms.h b/linden/indra/llmedia/llmediaimplgstreamer_syms.h
new file mode 100644
index 0000000..6dec2a2
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms.h
@@ -0,0 +1,75 @@
1/**
2 * @file llmediaimplgstreamer_syms.h
3 * @brief dynamic GStreamer symbol-grabbing code
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "linden_common.h"
30
31#if LL_GSTREAMER_ENABLED
32
33extern "C" {
34#include <gst/gst.h>
35}
36
37bool grab_gst_syms(std::string gst_dso_name,
38 std::string gst_dso_name_vid,
39 std::string gst_dso_name_aud);
40void ungrab_gst_syms();
41
42#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__)
43#include "llmediaimplgstreamer_syms_raw.inc"
44#include "llmediaimplgstreamer_syms_rawa.inc"
45#include "llmediaimplgstreamer_syms_rawv.inc"
46#undef LL_GST_SYM
47
48// regrettable hacks to give us better runtime compatibility with older systems
49#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0)
50#define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0)
51
52// regrettable hacks because GStreamer was not designed for runtime loading
53#undef GST_TYPE_MESSAGE
54#define GST_TYPE_MESSAGE (llgst_message_get_type())
55#undef GST_TYPE_OBJECT
56#define GST_TYPE_OBJECT (llgst_object_get_type())
57#undef GST_TYPE_PIPELINE
58#define GST_TYPE_PIPELINE (llgst_pipeline_get_type())
59#undef GST_TYPE_ELEMENT
60#define GST_TYPE_ELEMENT (llgst_element_get_type())
61#undef GST_TYPE_AUDIO_SINK
62#define GST_TYPE_AUDIO_SINK (llgst_audio_sink_get_type())
63#undef GST_TYPE_VIDEO_SINK
64#define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type())
65#undef _gst_debug_register_funcptr
66#define _gst_debug_register_funcptr ll_gst_debug_register_funcptr
67#undef _gst_debug_category_new
68#define _gst_debug_category_new ll_gst_debug_category_new
69#undef __gst_debug_enabled
70#define __gst_debug_enabled (0)
71
72// more hacks
73#define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M)))
74
75#endif // LL_GSTREAMER_ENABLED
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc b/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc
new file mode 100644
index 0000000..c00947f
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc
@@ -0,0 +1,42 @@
1
2// required symbols to grab
3LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err);
4LL_GST_SYM(true, gst_message_get_type, GType, void);
5LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type);
6LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug);
7LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug);
8LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending);
9LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state);
10LL_GST_SYM(true, gst_object_unref, void, gpointer object);
11LL_GST_SYM(true, gst_object_get_type, GType, void);
12LL_GST_SYM(true, gst_pipeline_get_type, GType, void);
13LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline);
14LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data);
15LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name);
16LL_GST_SYM(true, gst_element_get_type, GType, void);
17LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template);
18LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp);
19LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details);
20LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps);
21LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps);
22LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname);
23LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description);
24LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps);
25LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string);
26LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps);
27LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index);
28LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps);
29LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2);
30LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type);
31LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc);
32LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value);
33LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname);
34LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value);
35LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value);
36LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure);
37
38// optional symbols to grab
39LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled);
40LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent);
41LL_GST_SYM(false, expected_to_be_missing, void, gboolean enabled);
42LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug);
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc
new file mode 100644
index 0000000..0be99b5
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc
@@ -0,0 +1,5 @@
1
2// required symbols to grab
3LL_GST_SYM(true, gst_audio_sink_get_type, GType, void);
4
5// optional symbols to grab
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc
new file mode 100644
index 0000000..14fbcb4
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc
@@ -0,0 +1,5 @@
1
2// required symbols to grab
3LL_GST_SYM(true, gst_video_sink_get_type, GType, void);
4
5// optional symbols to grab
diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp b/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp
new file mode 100644
index 0000000..dade946
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp
@@ -0,0 +1,461 @@
1/**
2 * @file llmediaimplgstreamervidplug.h
3 * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#if LL_GSTREAMER_ENABLED
30
31#include <string.h>
32
33#include <gst/gst.h>
34#include <gst/video/video.h>
35#include <gst/video/gstvideosink.h>
36
37#include "llmediaimplgstreamer_syms.h"
38
39#include "llthread.h"
40
41#include "llmediaimplgstreamervidplug.h"
42
43GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug);
44#define GST_CAT_DEFAULT gst_slvideo_debug
45
46/* Filter signals and args */
47enum
48{
49 /* FILL ME */
50 LAST_SIGNAL
51};
52
53enum
54{
55 ARG_0
56};
57
58#define SLV_SIZECAPS ", width=(int){1,2,4,8,16,32,64,128,256,512,1024}, height=(int){1,2,4,8,16,32,64,128,256,512,1024} "
59#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS ";" GST_VIDEO_CAPS_BGRx SLV_SIZECAPS
60
61static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE (
62 "sink",
63 GST_PAD_SINK,
64 GST_PAD_ALWAYS,
65 GST_STATIC_CAPS (SLV_ALLCAPS)
66 );
67
68GST_BOILERPLATE (GstSLVideo, gst_slvideo, GstVideoSink,
69 GST_TYPE_VIDEO_SINK);
70
71static void gst_slvideo_set_property (GObject * object, guint prop_id,
72 const GValue * value,
73 GParamSpec * pspec);
74static void gst_slvideo_get_property (GObject * object, guint prop_id,
75 GValue * value, GParamSpec * pspec);
76
77static void
78gst_slvideo_base_init (gpointer gclass)
79{
80 static GstElementDetails element_details = {
81 "PluginTemplate",
82 "Generic/PluginTemplate",
83 "Generic Template Element",
84 "Linden Lab"
85 };
86 GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
87
88 llgst_element_class_add_pad_template (element_class,
89 llgst_static_pad_template_get (&sink_factory));
90 llgst_element_class_set_details (element_class, &element_details);
91}
92
93
94static void
95gst_slvideo_finalize (GObject * object)
96{
97 GstSLVideo *slvideo;
98 slvideo = GST_SLVIDEO (object);
99 if (slvideo->caps)
100 {
101 llgst_caps_unref(slvideo->caps);
102 }
103
104 G_OBJECT_CLASS(parent_class)->finalize (object);
105}
106
107
108static GstFlowReturn
109gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf)
110{
111 GstSLVideo *slvideo;
112 llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
113
114 slvideo = GST_SLVIDEO(bsink);
115
116#if 0
117 fprintf(stderr, "\n\ntransferring a frame of %dx%d <- %p (%d)\n\n",
118 slvideo->width, slvideo->height, GST_BUFFER_DATA(buf),
119 slvideo->format);
120#endif
121 if (GST_BUFFER_DATA(buf))
122 {
123 // copy frame and frame info into neutral territory
124 GST_OBJECT_LOCK(slvideo);
125 slvideo->retained_frame_ready = TRUE;
126 slvideo->retained_frame_width = slvideo->width;
127 slvideo->retained_frame_height = slvideo->height;
128 slvideo->retained_frame_format = slvideo->format;
129 int rowbytes =
130 SLVPixelFormatBytes[slvideo->retained_frame_format] *
131 slvideo->retained_frame_width;
132 int needbytes = rowbytes * slvideo->retained_frame_width;
133 // resize retained frame hunk only if necessary
134 if (needbytes != slvideo->retained_frame_allocbytes)
135 {
136 delete[] slvideo->retained_frame_data;
137 slvideo->retained_frame_data = new U8[needbytes];
138 slvideo->retained_frame_allocbytes = needbytes;
139
140 }
141 // copy the actual frame data to neutral territory -
142 // flipped, for GL reasons
143 for (int ypos=0; ypos<slvideo->height; ++ypos)
144 {
145 memcpy(&slvideo->retained_frame_data[(slvideo->height-1-ypos)*rowbytes],
146 &(((U8*)GST_BUFFER_DATA(buf))[ypos*rowbytes]),
147 rowbytes);
148 }
149 // done with the shared data
150 GST_OBJECT_UNLOCK(slvideo);
151 }
152
153 return GST_FLOW_OK;
154}
155
156
157static GstStateChangeReturn
158gst_slvideo_change_state(GstElement * element, GstStateChange transition)
159{
160 GstSLVideo *slvideo;
161 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
162
163 slvideo = GST_SLVIDEO (element);
164
165 switch (transition) {
166 case GST_STATE_CHANGE_NULL_TO_READY:
167 break;
168 case GST_STATE_CHANGE_READY_TO_PAUSED:
169 break;
170 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
171 break;
172 default:
173 break;
174 }
175
176 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
177 if (ret == GST_STATE_CHANGE_FAILURE)
178 return ret;
179
180 switch (transition) {
181 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
182 break;
183 case GST_STATE_CHANGE_PAUSED_TO_READY:
184 slvideo->fps_n = 0;
185 slvideo->fps_d = 1;
186 GST_VIDEO_SINK_WIDTH(slvideo) = 0;
187 GST_VIDEO_SINK_HEIGHT(slvideo) = 0;
188 break;
189 case GST_STATE_CHANGE_READY_TO_NULL:
190 break;
191 default:
192 break;
193 }
194
195 return ret;
196}
197
198
199static GstCaps *
200gst_slvideo_get_caps (GstBaseSink * bsink)
201{
202 GstSLVideo *slvideo;
203 slvideo = GST_SLVIDEO(bsink);
204
205 return llgst_caps_ref (slvideo->caps);
206}
207
208
209/* this function handles the link with other elements */
210static gboolean
211gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps)
212{
213 GstSLVideo *filter;
214 GstStructure *structure;
215 GstCaps *intersection;
216
217 GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
218
219 filter = GST_SLVIDEO(bsink);
220
221 intersection = llgst_caps_intersect (filter->caps, caps);
222 if (llgst_caps_is_empty (intersection))
223 {
224 // no overlap between our caps and requested caps
225 return FALSE;
226 }
227 llgst_caps_unref(intersection);
228
229 int width, height;
230 gboolean ret;
231 const GValue *fps;
232 const GValue *par;
233 structure = llgst_caps_get_structure (caps, 0);
234 ret = llgst_structure_get_int (structure, "width", &width);
235 ret = ret && llgst_structure_get_int (structure, "height", &height);
236 fps = llgst_structure_get_value (structure, "framerate");
237 ret = ret && (fps != NULL);
238 par = llgst_structure_get_value (structure, "pixel-aspect-ratio");
239 if (!ret)
240 return FALSE;
241
242 filter->width = width;
243 filter->height = height;
244 filter->fps_n = llgst_value_get_fraction_numerator(fps);
245 filter->fps_d = llgst_value_get_fraction_denominator(fps);
246 if (par)
247 {
248 filter->par_n = llgst_value_get_fraction_numerator(par);
249 filter->par_d = llgst_value_get_fraction_denominator(par);
250 }
251 else
252 {
253 filter->par_n = 1;
254 filter->par_d = 1;
255 }
256 GST_VIDEO_SINK_WIDTH(filter) = width;
257 GST_VIDEO_SINK_HEIGHT(filter) = height;
258
259 filter->format = SLV_PF_UNKNOWN;
260 if (0 == strcmp(llgst_structure_get_name(structure),
261 "video/x-raw-rgb"))
262 {
263 int red_mask;
264 int green_mask;
265 int blue_mask;
266 llgst_structure_get_int(structure, "red_mask", &red_mask);
267 llgst_structure_get_int(structure, "green_mask", &green_mask);
268 llgst_structure_get_int(structure, "blue_mask", &blue_mask);
269 if ((unsigned int)red_mask == 0xFF000000 &&
270 (unsigned int)green_mask == 0x00FF0000 &&
271 (unsigned int)blue_mask == 0x0000FF00)
272 {
273 filter->format = SLV_PF_RGBX;
274 //fprintf(stderr, "\n\nPIXEL FORMAT RGB\n\n");
275 } else if ((unsigned int)red_mask == 0x0000FF00 &&
276 (unsigned int)green_mask == 0x00FF0000 &&
277 (unsigned int)blue_mask == 0xFF000000)
278 {
279 filter->format = SLV_PF_BGRX;
280 //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n");
281 }
282 }
283
284 return TRUE;
285}
286
287
288static gboolean
289gst_slvideo_start (GstBaseSink * bsink)
290{
291 GstSLVideo *slvideo;
292 gboolean ret = TRUE;
293
294 slvideo = GST_SLVIDEO(bsink);
295
296 return ret;
297}
298
299static gboolean
300gst_slvideo_stop (GstBaseSink * bsink)
301{
302 GstSLVideo *slvideo;
303 slvideo = GST_SLVIDEO(bsink);
304
305 // free-up retained frame buffer
306 GST_OBJECT_LOCK(slvideo);
307 slvideo->retained_frame_ready = FALSE;
308 delete[] slvideo->retained_frame_data;
309 slvideo->retained_frame_data = NULL;
310 slvideo->retained_frame_allocbytes = 0;
311 GST_OBJECT_UNLOCK(slvideo);
312
313 return TRUE;
314}
315
316
317static gboolean
318gst_slvideo_unlock (GstBaseSink * bsink)
319{
320 // nothing really to do here.
321 return TRUE;
322}
323
324
325/* initialize the plugin's class */
326static void
327gst_slvideo_class_init (GstSLVideoClass * klass)
328{
329 GObjectClass *gobject_class;
330 GstElementClass *gstelement_class;
331 GstBaseSinkClass *gstbasesink_class;
332
333 gobject_class = (GObjectClass *) klass;
334 gstelement_class = (GstElementClass *) klass;
335 gstbasesink_class = (GstBaseSinkClass *) klass;
336
337 gobject_class->finalize = gst_slvideo_finalize;
338 gobject_class->set_property = gst_slvideo_set_property;
339 gobject_class->get_property = gst_slvideo_get_property;
340
341 gstelement_class->change_state = gst_slvideo_change_state;
342
343 gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_slvideo_get_caps);
344 gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR( gst_slvideo_set_caps);
345 //gstbasesink_class->buffer_alloc=GST_DEBUG_FUNCPTR(gst_slvideo_buffer_alloc);
346 //gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_slvideo_get_times);
347 gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_slvideo_show_frame);
348 gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_slvideo_show_frame);
349
350 gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_slvideo_start);
351 gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_slvideo_stop);
352
353 gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_slvideo_unlock);
354}
355
356
357static void
358gst_slvideo_update_caps (GstSLVideo * slvideo)
359{
360 GstCaps *caps;
361
362 // GStreamer will automatically convert colourspace if necessary.
363 // GStreamer will automatically resize media to one of these enumerated
364 // powers-of-two that we ask for (yay GStreamer!)
365 caps = llgst_caps_from_string (SLV_ALLCAPS);
366
367 llgst_caps_replace (&slvideo->caps, caps);
368}
369
370
371/* initialize the new element
372 * instantiate pads and add them to element
373 * set functions
374 * initialize structure
375 */
376static void
377gst_slvideo_init (GstSLVideo * filter,
378 GstSLVideoClass * gclass)
379{
380 filter->width = -1;
381 filter->height = -1;
382
383 // this is the info we share with the client app
384 GST_OBJECT_LOCK(filter);
385 filter->retained_frame_ready = FALSE;
386 filter->retained_frame_data = NULL;
387 filter->retained_frame_allocbytes = 0;
388 filter->retained_frame_width = filter->width;
389 filter->retained_frame_height = filter->height;
390 filter->retained_frame_format = SLV_PF_UNKNOWN;
391 GST_OBJECT_UNLOCK(filter);
392
393 gst_slvideo_update_caps(filter);
394}
395
396static void
397gst_slvideo_set_property (GObject * object, guint prop_id,
398 const GValue * value, GParamSpec * pspec)
399{
400 llg_return_if_fail (GST_IS_SLVIDEO (object));
401
402 switch (prop_id) {
403 default:
404 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
405 break;
406 }
407}
408
409static void
410gst_slvideo_get_property (GObject * object, guint prop_id,
411 GValue * value, GParamSpec * pspec)
412{
413 llg_return_if_fail (GST_IS_SLVIDEO (object));
414
415 switch (prop_id) {
416 default:
417 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
418 break;
419 }
420}
421
422
423/* entry point to initialize the plug-in
424 * initialize the plug-in itself
425 * register the element factories and pad templates
426 * register the features
427 */
428static gboolean
429plugin_init (GstPlugin * plugin)
430{
431 //fprintf(stderr, "\n\n\nPLUGIN INIT\n\n\n");
432
433 GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, "private-slvideo-plugin",
434 0, "Second Life Video Sink");
435
436 return llgst_element_register (plugin, "private-slvideo",
437 GST_RANK_NONE, GST_TYPE_SLVIDEO);
438}
439
440/* this is the structure that gstreamer looks for to register plugins
441 */
442/* NOTE: Can't rely upon GST_PLUGIN_DEFINE_STATIC to self-register, since
443 some g++ versions buggily avoid __attribute__((constructor)) functions -
444 so we provide an explicit plugin init function.
445 */
446void gst_slvideo_init_class (void)
447{
448#define PACKAGE "packagehack"
449 static GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
450 GST_VERSION_MINOR,
451 "private-slvideoplugin",
452 "SL Video sink plugin",
453 plugin_init, "0.1", GST_LICENSE_UNKNOWN,
454 "Second Life",
455 "http://www.secondlife.com/");
456#undef PACKAGE
457 ll_gst_plugin_register_static (&gst_plugin_desc);
458 //fprintf(stderr, "\n\n\nCLASS INIT\n\n\n");
459}
460
461#endif // LL_GSTREAMER_ENABLED
diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.h b/linden/indra/llmedia/llmediaimplgstreamervidplug.h
new file mode 100644
index 0000000..2bfb853
--- /dev/null
+++ b/linden/indra/llmedia/llmediaimplgstreamervidplug.h
@@ -0,0 +1,101 @@
1/**
2 * @file llmediaimplgstreamervidplug.h
3 * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef __GST_SLVIDEO_H__
30#define __GST_SLVIDEO_H__
31
32#if LL_GSTREAMER_ENABLED
33
34extern "C" {
35#include <gst/gst.h>
36#include <gst/video/video.h>
37#include <gst/video/gstvideosink.h>
38}
39
40G_BEGIN_DECLS
41
42/* #defines don't like whitespacey bits */
43#define GST_TYPE_SLVIDEO \
44 (gst_slvideo_get_type())
45#define GST_SLVIDEO(obj) \
46 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SLVIDEO,GstSLVideo))
47#define GST_SLVIDEO_CLASS(klass) \
48 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SLVIDEO,GstSLVideoClass))
49#define GST_IS_SLVIDEO(obj) \
50 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SLVIDEO))
51#define GST_IS_SLVIDEO_CLASS(klass) \
52 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SLVIDEO))
53
54typedef struct _GstSLVideo GstSLVideo;
55typedef struct _GstSLVideoClass GstSLVideoClass;
56
57typedef enum {
58 SLV_PF_UNKNOWN = 0,
59 SLV_PF_RGBX = 1,
60 SLV_PF_BGRX = 2,
61 SLV__END = 3
62} SLVPixelFormat;
63const int SLVPixelFormatBytes[SLV__END] = {1, 4, 4};
64
65struct _GstSLVideo
66{
67 GstVideoSink video_sink;
68
69 GstCaps *caps;
70
71 int fps_n, fps_d;
72 int par_n, par_d;
73 int height, width;
74 SLVPixelFormat format;
75
76 // SHARED WITH APPLICATION:
77 // Access to the following should be protected by GST_OBJECT_LOCK() on
78 // the GstSLVideo object, and should be totally consistent upon UNLOCK
79 // (i.e. all written at once to reflect the current retained frame info
80 // when the retained frame is updated.)
81 bool retained_frame_ready; // new frame ready since flag last reset. (*TODO: could get the writer to wait on a semaphore instead of having the reader poll, potentially making dropped frames somewhat cheaper.)
82 U8* retained_frame_data;
83 int retained_frame_allocbytes;
84 int retained_frame_width, retained_frame_height;
85 SLVPixelFormat retained_frame_format;
86};
87
88struct _GstSLVideoClass
89{
90 GstVideoSink parent_class;
91};
92
93GType gst_slvideo_get_type (void);
94
95void gst_slvideo_init_class (void);
96
97G_END_DECLS
98
99#endif // LL_GSTREAMER_ENABLED
100
101#endif /* __GST_SLVIDEO_H__ */
diff --git a/linden/indra/llmedia/llmediamoviebase.cpp b/linden/indra/llmedia/llmediamoviebase.cpp
index 46b76b0..de9933b 100644
--- a/linden/indra/llmedia/llmediamoviebase.cpp
+++ b/linden/indra/llmedia/llmediamoviebase.cpp
@@ -30,6 +30,7 @@
30 30
31#include "llmediamoviebase.h" 31#include "llmediamoviebase.h"
32#include "llmediaimplquicktime.h" 32#include "llmediaimplquicktime.h"
33#include "llmediaimplgstreamer.h"
33 34
34LLMediaMovieBase::LLMediaMovieBase() 35LLMediaMovieBase::LLMediaMovieBase()
35{ 36{
@@ -47,6 +48,13 @@ LLMediaMovieBase* LLMediaMovieBase::make( const MediaType mediaTypeIn, S32 width
47 } 48 }
48 else 49 else
49#endif 50#endif
51#if LL_GSTREAMER_ENABLED
52 if ( mediaTypeIn == QuickTime )
53 {
54 return new LLMediaImplGStreamer ();
55 }
56 else
57#endif
50 58
51 return 0; 59 return 0;
52} 60}
diff --git a/linden/indra/llmessage/llcurl.cpp b/linden/indra/llmessage/llcurl.cpp
index 362204a..b94a41e 100644
--- a/linden/indra/llmessage/llcurl.cpp
+++ b/linden/indra/llmessage/llcurl.cpp
@@ -96,7 +96,7 @@ namespace boost
96 96
97 void intrusive_ptr_release(LLCurl::Responder* p) 97 void intrusive_ptr_release(LLCurl::Responder* p)
98 { 98 {
99 if(0 == --p->mReferenceCount) 99 if(p && 0 == --p->mReferenceCount)
100 { 100 {
101 delete p; 101 delete p;
102 } 102 }
diff --git a/linden/indra/llmessage/lldatapacker.cpp b/linden/indra/llmessage/lldatapacker.cpp
index 3cdaa25..8725870 100644
--- a/linden/indra/llmessage/lldatapacker.cpp
+++ b/linden/indra/llmessage/lldatapacker.cpp
@@ -1895,7 +1895,10 @@ BOOL LLDataPackerAsciiFile::getValueStr(const char *name, char *out_value, S32 v
1895 { 1895 {
1896 fpos_t last_pos; 1896 fpos_t last_pos;
1897 fgetpos(mFP, &last_pos); 1897 fgetpos(mFP, &last_pos);
1898 fgets(buffer, DP_BUFSIZE, mFP); 1898 if (fgets(buffer, DP_BUFSIZE, mFP) == NULL)
1899 {
1900 buffer[0] = '\0';
1901 }
1899 1902
1900 sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */ 1903 sscanf(buffer, "%511s %511[^\n]", keyword, value); /* Flawfinder: ignore */
1901 1904
diff --git a/linden/indra/llmessage/llhttpassetstorage.cpp b/linden/indra/llmessage/llhttpassetstorage.cpp
index d83349b..b6c20b9 100644
--- a/linden/indra/llmessage/llhttpassetstorage.cpp
+++ b/linden/indra/llmessage/llhttpassetstorage.cpp
@@ -38,7 +38,11 @@
38#include "llvfile.h" 38#include "llvfile.h"
39#include "llvfs.h" 39#include "llvfs.h"
40 40
41#include "zlib/zlib.h" 41#ifdef LL_STANDALONE
42# include <zlib.h>
43#else
44# include "zlib/zlib.h"
45#endif
42 46
43const U32 MAX_RUNNING_REQUESTS = 1; 47const U32 MAX_RUNNING_REQUESTS = 1;
44const F32 MAX_PROCESSING_TIME = 0.005f; 48const F32 MAX_PROCESSING_TIME = 0.005f;
diff --git a/linden/indra/llmessage/llhttpclient.cpp b/linden/indra/llmessage/llhttpclient.cpp
index 392dfd0..e36503a 100644
--- a/linden/indra/llmessage/llhttpclient.cpp
+++ b/linden/indra/llmessage/llhttpclient.cpp
@@ -252,6 +252,7 @@ static void request(
252 LLURLRequest::ERequestAction method, 252 LLURLRequest::ERequestAction method,
253 Injector* body_injector, 253 Injector* body_injector,
254 LLHTTPClient::ResponderPtr responder, 254 LLHTTPClient::ResponderPtr responder,
255 const LLSD& headers,
255 const F32 timeout=HTTP_REQUEST_EXPIRY_SECS) 256 const F32 timeout=HTTP_REQUEST_EXPIRY_SECS)
256{ 257{
257 if (!LLHTTPClient::hasPump()) 258 if (!LLHTTPClient::hasPump())
@@ -263,6 +264,19 @@ static void request(
263 264
264 LLURLRequest *req = new LLURLRequest(method, url); 265 LLURLRequest *req = new LLURLRequest(method, url);
265 req->requestEncoding(""); 266 req->requestEncoding("");
267
268 if (headers.isMap())
269 {
270 LLSD::map_const_iterator iter = headers.beginMap();
271 LLSD::map_const_iterator end = headers.endMap();
272
273 for (; iter != end; ++iter)
274 {
275 std::ostringstream header;
276 header << iter->first << ": " << iter->second.asString() ;
277 req->addHeader(header.str().c_str());
278 }
279 }
266 if (!gCABundle.empty()) 280 if (!gCABundle.empty())
267 { 281 {
268 req->checkRootCertificate(true, gCABundle.c_str()); 282 req->checkRootCertificate(true, gCABundle.c_str());
@@ -287,17 +301,37 @@ static void request(
287 theClientPump->addChain(chain, timeout); 301 theClientPump->addChain(chain, timeout);
288} 302}
289 303
304static void request(
305 const std::string& url,
306 LLURLRequest::ERequestAction method,
307 Injector* body_injector,
308 LLHTTPClient::ResponderPtr responder,
309 const F32 timeout=HTTP_REQUEST_EXPIRY_SECS)
310{
311 request(url, method, body_injector, responder, LLSD(), timeout);
312}
313
314void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout)
315{
316 request(url, LLURLRequest::HTTP_GET, NULL, responder, headers, timeout);
317}
318
290void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const F32 timeout) 319void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const F32 timeout)
291{ 320{
292 request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout); 321 get(url, responder, LLSD(), timeout);
293} 322}
294 323
295void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const F32 timeout) 324void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, const F32 timeout)
296{ 325{
297 LLURI uri; 326 LLURI uri;
298 327
299 uri = LLURI::buildHTTP(url, LLSD::emptyArray(), query); 328 uri = LLURI::buildHTTP(url, LLSD::emptyArray(), query);
300 get(uri.asString(), responder, timeout); 329 get(uri.asString(), responder, headers, timeout);
330}
331
332void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const F32 timeout)
333{
334 get(url, query, responder, LLSD(), timeout);
301} 335}
302 336
303// A simple class for managing data returned from a curl http request. 337// A simple class for managing data returned from a curl http request.
diff --git a/linden/indra/llmessage/llhttpclient.h b/linden/indra/llmessage/llhttpclient.h
index 88f8cbb..578b176 100644
--- a/linden/indra/llmessage/llhttpclient.h
+++ b/linden/indra/llmessage/llhttpclient.h
@@ -79,7 +79,9 @@ public:
79 typedef boost::intrusive_ptr<Responder> ResponderPtr; 79 typedef boost::intrusive_ptr<Responder> ResponderPtr;
80 80
81 static void get(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); 81 static void get(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
82 static void get(const std::string& url, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
82 static void get(const std::string& url, const LLSD& query, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); 83 static void get(const std::string& url, const LLSD& query, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
84 static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
83 static void put(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); 85 static void put(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
84 ///< non-blocking 86 ///< non-blocking
85 static void post(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); 87 static void post(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
diff --git a/linden/indra/llmessage/lliohttpserver.cpp b/linden/indra/llmessage/lliohttpserver.cpp
index 5c96102..3c8010b 100644
--- a/linden/indra/llmessage/lliohttpserver.cpp
+++ b/linden/indra/llmessage/lliohttpserver.cpp
@@ -53,6 +53,7 @@
53 53
54static const char HTTP_VERSION_STR[] = "HTTP/1.0"; 54static const char HTTP_VERSION_STR[] = "HTTP/1.0";
55static const std::string CONTEXT_REQUEST("request"); 55static const std::string CONTEXT_REQUEST("request");
56static const std::string CONTEXT_RESPONSE("response");
56static const std::string HTTP_VERB_GET("GET"); 57static const std::string HTTP_VERB_GET("GET");
57static const std::string HTTP_VERB_PUT("PUT"); 58static const std::string HTTP_VERB_PUT("PUT");
58static const std::string HTTP_VERB_POST("POST"); 59static const std::string HTTP_VERB_POST("POST");
@@ -156,10 +157,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
156 LLBufferStream istr(channels, buffer.get()); 157 LLBufferStream istr(channels, buffer.get());
157 158
158 static LLTimer timer; 159 static LLTimer timer;
159 if (sTimingCallback) 160 timer.reset();
160 {
161 timer.reset();
162 }
163 161
164 std::string verb = context[CONTEXT_REQUEST]["verb"]; 162 std::string verb = context[CONTEXT_REQUEST]["verb"];
165 if(verb == HTTP_VERB_GET) 163 if(verb == HTTP_VERB_GET)
@@ -189,6 +187,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
189 mResponse->methodNotAllowed(); 187 mResponse->methodNotAllowed();
190 } 188 }
191 189
190 F32 delta = timer.getElapsedTimeF32();
192 if (sTimingCallback) 191 if (sTimingCallback)
193 { 192 {
194 LLHTTPNode::Description desc; 193 LLHTTPNode::Description desc;
@@ -197,16 +196,20 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
197 std::string timing_name = info["description"]; 196 std::string timing_name = info["description"];
198 timing_name += " "; 197 timing_name += " ";
199 timing_name += verb; 198 timing_name += verb;
200 F32 delta = timer.getElapsedTimeF32();
201 sTimingCallback(timing_name.c_str(), delta, sTimingCallbackData); 199 sTimingCallback(timing_name.c_str(), delta, sTimingCallbackData);
202 } 200 }
203 201
202 // Log all HTTP transactions.
203 llinfos << verb << " " << context[CONTEXT_REQUEST]["path"].asString()
204 << " " << mStatusCode << " " << mStatusMessage << " " << delta
205 << "s" << llendl;
206
204 // Log Internal Server Errors 207 // Log Internal Server Errors
205 if(mStatusCode == 500) 208 //if(mStatusCode == 500)
206 { 209 //{
207 llwarns << "LLHTTPPipe::process_impl:500:Internal Server Error" 210 // llwarns << "LLHTTPPipe::process_impl:500:Internal Server Error"
208 << llendl; 211 // << llendl;
209 } 212 //}
210 } 213 }
211 214
212 PUMP_DEBUG; 215 PUMP_DEBUG;
@@ -223,7 +226,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
223 226
224 case STATE_GOOD_RESULT: 227 case STATE_GOOD_RESULT:
225 { 228 {
226 context["response"]["contentType"] = "application/xml"; 229 context[CONTEXT_RESPONSE]["contentType"] = "application/xml";
227 LLBufferStream ostr(channels, buffer.get()); 230 LLBufferStream ostr(channels, buffer.get());
228 LLSDSerialize::toXML(mGoodResult, ostr); 231 LLSDSerialize::toXML(mGoodResult, ostr);
229 232
@@ -232,9 +235,9 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
232 235
233 case STATE_STATUS_RESULT: 236 case STATE_STATUS_RESULT:
234 { 237 {
235 context["response"]["contentType"] = "text/plain"; 238 context[CONTEXT_RESPONSE]["contentType"] = "text/plain";
236 context["response"]["statusCode"] = mStatusCode; 239 context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode;
237 context["response"]["statusMessage"] = mStatusMessage; 240 context[CONTEXT_RESPONSE]["statusMessage"] = mStatusMessage;
238 LLBufferStream ostr(channels, buffer.get()); 241 LLBufferStream ostr(channels, buffer.get());
239 ostr << mStatusMessage << std::ends; 242 ostr << mStatusMessage << std::ends;
240 243
@@ -371,9 +374,9 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
371 PUMP_DEBUG; 374 PUMP_DEBUG;
372 //mGotEOS = true; 375 //mGotEOS = true;
373 std::ostringstream ostr; 376 std::ostringstream ostr;
374 std::string message = context["response"]["statusMessage"]; 377 std::string message = context[CONTEXT_RESPONSE]["statusMessage"];
375 378
376 int code = context["response"]["statusCode"]; 379 int code = context[CONTEXT_RESPONSE]["statusCode"];
377 if (code < 200) 380 if (code < 200)
378 { 381 {
379 code = 200; 382 code = 200;
@@ -382,7 +385,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
382 385
383 ostr << HTTP_VERSION_STR << " " << code << " " << message << "\r\n"; 386 ostr << HTTP_VERSION_STR << " " << code << " " << message << "\r\n";
384 387
385 std::string type = context["response"]["contentType"].asString(); 388 std::string type = context[CONTEXT_RESPONSE]["contentType"].asString();
386 if (!type.empty()) 389 if (!type.empty())
387 { 390 {
388 ostr << "Content-Type: " << type << "\r\n"; 391 ostr << "Content-Type: " << type << "\r\n";
diff --git a/linden/indra/llmessage/llmessageconfig.cpp b/linden/indra/llmessage/llmessageconfig.cpp
index 8d114a9..6ecb1ad 100644
--- a/linden/indra/llmessage/llmessageconfig.cpp
+++ b/linden/indra/llmessage/llmessageconfig.cpp
@@ -252,3 +252,19 @@ bool LLMessageConfig::isCapBanned(const std::string& cap_name)
252{ 252{
253 return LLMessageConfigFile::instance().isCapBanned(cap_name); 253 return LLMessageConfigFile::instance().isCapBanned(cap_name);
254} 254}
255
256// return the web-service path to use for a given
257// message. This entry *should* match the entry
258// in simulator.xml!
259LLSD LLMessageConfig::getConfigForMessage(const std::string& msg_name)
260{
261 if (sServerName.empty())
262 {
263 llerrs << "LLMessageConfig::isMessageTrusted(name) before"
264 << " LLMessageConfig::initClass()" << llendl;
265 }
266 LLMessageConfigFile& file = LLMessageConfigFile::instance();
267 // LLSD for the CamelCase message name
268 LLSD config = file.mMessages[msg_name];
269 return config;
270}
diff --git a/linden/indra/llmessage/llmessageconfig.h b/linden/indra/llmessage/llmessageconfig.h
index ca09c27..86e7fb0 100644
--- a/linden/indra/llmessage/llmessageconfig.h
+++ b/linden/indra/llmessage/llmessageconfig.h
@@ -30,6 +30,7 @@
30#define LL_MESSAGECONFIG_H 30#define LL_MESSAGECONFIG_H
31 31
32#include <string> 32#include <string>
33#include "llsd.h"
33 34
34class LLSD; 35class LLSD;
35 36
@@ -50,5 +51,6 @@ public:
50 static SenderTrust getSenderTrustedness(const std::string& msg_name); 51 static SenderTrust getSenderTrustedness(const std::string& msg_name);
51 static bool isValidMessage(const std::string& msg_name); 52 static bool isValidMessage(const std::string& msg_name);
52 static bool isCapBanned(const std::string& cap_name); 53 static bool isCapBanned(const std::string& cap_name);
54 static LLSD getConfigForMessage(const std::string& msg_name);
53}; 55};
54#endif // LL_MESSAGECONFIG_H 56#endif // LL_MESSAGECONFIG_H
diff --git a/linden/indra/llmessage/llmessagereader.cpp b/linden/indra/llmessage/llmessagereader.cpp
index db4cbdf..2679019 100644
--- a/linden/indra/llmessage/llmessagereader.cpp
+++ b/linden/indra/llmessage/llmessagereader.cpp
@@ -1,5 +1,5 @@
1/** 1/**
2 * @file llsdmessagereader.cpp 2 * @file llmessagereader.cpp
3 * @brief LLMessageReader class implementation 3 * @brief LLMessageReader class implementation
4 * 4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc. 5 * Copyright (c) 2007-2007, Linden Research, Inc.
@@ -26,6 +26,7 @@
26 * COMPLETENESS OR PERFORMANCE. 26 * COMPLETENESS OR PERFORMANCE.
27 */ 27 */
28 28
29#include "linden_common.h"
29#include "llmessagereader.h" 30#include "llmessagereader.h"
30 31
31static BOOL sTimeDecodes = FALSE; 32static BOOL sTimeDecodes = FALSE;
diff --git a/linden/indra/llmessage/llmessagetemplateparser.cpp b/linden/indra/llmessage/llmessagetemplateparser.cpp
index eb5e87e..4c14ede 100644
--- a/linden/indra/llmessage/llmessagetemplateparser.cpp
+++ b/linden/indra/llmessage/llmessagetemplateparser.cpp
@@ -26,6 +26,7 @@
26 * COMPLETENESS OR PERFORMANCE. 26 * COMPLETENESS OR PERFORMANCE.
27 */ 27 */
28 28
29#include "linden_common.h"
29#include "llmessagetemplateparser.h" 30#include "llmessagetemplateparser.h"
30#include <boost/tokenizer.hpp> 31#include <boost/tokenizer.hpp>
31 32
diff --git a/linden/indra/llmessage/llnamevalue.cpp b/linden/indra/llmessage/llnamevalue.cpp
index 6e449ed..a11bf97 100644
--- a/linden/indra/llmessage/llnamevalue.cpp
+++ b/linden/indra/llmessage/llnamevalue.cpp
@@ -122,6 +122,9 @@ void LLNameValue::baseInit()
122 122
123 mSendto = NVS_NULL; 123 mSendto = NVS_NULL;
124 mStringSendto = NameValueSendtoStrings[NVS_NULL]; 124 mStringSendto = NameValueSendtoStrings[NVS_NULL];
125
126 mNameValueCB = NULL;
127 mUserData = NULL;
125} 128}
126 129
127void LLNameValue::init(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto, TNameValueCallback nvcb, void **user_data) 130void LLNameValue::init(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto, TNameValueCallback nvcb, void **user_data)
diff --git a/linden/indra/llmessage/llnamevalue.h b/linden/indra/llmessage/llnamevalue.h
index fe733fa..580c99d 100644
--- a/linden/indra/llmessage/llnamevalue.h
+++ b/linden/indra/llmessage/llnamevalue.h
@@ -194,7 +194,6 @@ public:
194 ENameValueSendto mSendto; 194 ENameValueSendto mSendto;
195 195
196 UNameValueReference mNameValueReference; 196 UNameValueReference mNameValueReference;
197 S32 mNumberEntries;
198 LLStringTable *mNVNameTable; 197 LLStringTable *mNVNameTable;
199 TNameValueCallback mNameValueCB; 198 TNameValueCallback mNameValueCB;
200 void **mUserData; 199 void **mUserData;
diff --git a/linden/indra/llmessage/llservicebuilder.cpp b/linden/indra/llmessage/llservicebuilder.cpp
index 91040c0..0b35a69 100644
--- a/linden/indra/llmessage/llservicebuilder.cpp
+++ b/linden/indra/llmessage/llservicebuilder.cpp
@@ -109,7 +109,7 @@ std::string LLServiceBuilder::buildServiceURI(
109 const LLSD& option_map) 109 const LLSD& option_map)
110{ 110{
111 std::string service_url = buildServiceURI(service_name); 111 std::string service_url = buildServiceURI(service_name);
112 112
113 // Find the Service Name 113 // Find the Service Name
114 if(!service_url.empty() && option_map.isMap()) 114 if(!service_url.empty() && option_map.isMap())
115 { 115 {
@@ -128,6 +128,23 @@ std::string LLServiceBuilder::buildServiceURI(
128 find_pos, 128 find_pos,
129 variable_name.length(), 129 variable_name.length(),
130 (*option_itr).second.asString()); 130 (*option_itr).second.asString());
131 continue;
132 }
133 variable_name.assign("{%");
134 variable_name.append((*option_itr).first);
135 variable_name.append("}");
136 find_pos = service_url.find(variable_name);
137 if(find_pos != std::string::npos)
138 {
139 std::string query_str = LLURI::mapToQueryString(
140 (*option_itr).second);
141 if(!query_str.empty())
142 {
143 service_url.replace(
144 find_pos,
145 variable_name.length(),
146 query_str);
147 }
131 } 148 }
132 } 149 }
133 } 150 }
diff --git a/linden/indra/llmessage/lltemplatemessagereader.cpp b/linden/indra/llmessage/lltemplatemessagereader.cpp
index a1f5213..329d2a8 100644
--- a/linden/indra/llmessage/lltemplatemessagereader.cpp
+++ b/linden/indra/llmessage/lltemplatemessagereader.cpp
@@ -26,6 +26,7 @@
26 * COMPLETENESS OR PERFORMANCE. 26 * COMPLETENESS OR PERFORMANCE.
27 */ 27 */
28 28
29#include "linden_common.h"
29#include "lltemplatemessagereader.h" 30#include "lltemplatemessagereader.h"
30 31
31#include "llfasttimer.h" 32#include "llfasttimer.h"
@@ -351,7 +352,7 @@ void LLTemplateMessageReader::getF64(const char *block, const char *var,
351void LLTemplateMessageReader::getVector3(const char *block, const char *var, 352void LLTemplateMessageReader::getVector3(const char *block, const char *var,
352 LLVector3 &v, S32 blocknum ) 353 LLVector3 &v, S32 blocknum )
353{ 354{
354 getData(block, var, v.mV, sizeof(v.mV), blocknum); 355 getData(block, var, &v.mV[0], sizeof(v.mV), blocknum);
355 356
356 if( !v.isFinite() ) 357 if( !v.isFinite() )
357 { 358 {
@@ -364,7 +365,7 @@ void LLTemplateMessageReader::getVector3(const char *block, const char *var,
364void LLTemplateMessageReader::getVector4(const char *block, const char *var, 365void LLTemplateMessageReader::getVector4(const char *block, const char *var,
365 LLVector4 &v, S32 blocknum) 366 LLVector4 &v, S32 blocknum)
366{ 367{
367 getData(block, var, v.mV, sizeof(v.mV), blocknum); 368 getData(block, var, &v.mV[0], sizeof(v.mV), blocknum);
368 369
369 if( !v.isFinite() ) 370 if( !v.isFinite() )
370 { 371 {
@@ -377,7 +378,7 @@ void LLTemplateMessageReader::getVector4(const char *block, const char *var,
377void LLTemplateMessageReader::getVector3d(const char *block, const char *var, 378void LLTemplateMessageReader::getVector3d(const char *block, const char *var,
378 LLVector3d &v, S32 blocknum ) 379 LLVector3d &v, S32 blocknum )
379{ 380{
380 getData(block, var, v.mdV, sizeof(v.mdV), blocknum); 381 getData(block, var, &v.mdV[0], sizeof(v.mdV), blocknum);
381 382
382 if( !v.isFinite() ) 383 if( !v.isFinite() )
383 { 384 {
@@ -392,7 +393,7 @@ void LLTemplateMessageReader::getQuat(const char *block, const char *var,
392 LLQuaternion &q, S32 blocknum) 393 LLQuaternion &q, S32 blocknum)
393{ 394{
394 LLVector3 vec; 395 LLVector3 vec;
395 getData(block, var, vec.mV, sizeof(vec.mV), blocknum); 396 getData(block, var, &vec.mV[0], sizeof(vec.mV), blocknum);
396 if( vec.isFinite() ) 397 if( vec.isFinite() )
397 { 398 {
398 q.unpackFromVector3( vec ); 399 q.unpackFromVector3( vec );
@@ -408,7 +409,7 @@ void LLTemplateMessageReader::getQuat(const char *block, const char *var,
408void LLTemplateMessageReader::getUUID(const char *block, const char *var, 409void LLTemplateMessageReader::getUUID(const char *block, const char *var,
409 LLUUID &u, S32 blocknum) 410 LLUUID &u, S32 blocknum)
410{ 411{
411 getData(block, var, u.mData, sizeof(u.mData), blocknum); 412 getData(block, var, &u.mData[0], sizeof(u.mData), blocknum);
412} 413}
413 414
414inline void LLTemplateMessageReader::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum) 415inline void LLTemplateMessageReader::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum)
diff --git a/linden/indra/llmessage/lluseroperation.cpp b/linden/indra/llmessage/lluseroperation.cpp
index 29146ea..f43e02a 100644
--- a/linden/indra/llmessage/lluseroperation.cpp
+++ b/linden/indra/llmessage/lluseroperation.cpp
@@ -42,7 +42,8 @@ LLUserOperationMgr* gUserOperationMgr = NULL;
42 42
43LLUserOperation::LLUserOperation(const LLUUID& agent_id) 43LLUserOperation::LLUserOperation(const LLUUID& agent_id)
44: mAgentID(agent_id), 44: mAgentID(agent_id),
45 mTimer() 45 mTimer(),
46 mNoExpire(FALSE)
46{ 47{
47 mTransactionID.generate(); 48 mTransactionID.generate();
48} 49}
@@ -51,14 +52,16 @@ LLUserOperation::LLUserOperation(const LLUUID& agent_id,
51 const LLUUID& transaction_id) : 52 const LLUUID& transaction_id) :
52 mAgentID(agent_id), 53 mAgentID(agent_id),
53 mTransactionID(transaction_id), 54 mTransactionID(transaction_id),
54 mTimer() 55 mTimer(),
56 mNoExpire(FALSE)
55{ 57{
56} 58}
57 59
58// protected constructor which is used by base classes that determine 60// protected constructor which is used by base classes that determine
59// transaction, agent, et. after construction. 61// transaction, agent, et. after construction.
60LLUserOperation::LLUserOperation() : 62LLUserOperation::LLUserOperation() :
61 mTimer() 63 mTimer(),
64 mNoExpire(FALSE)
62{ 65{
63} 66}
64 67
@@ -66,11 +69,19 @@ LLUserOperation::~LLUserOperation()
66{ 69{
67} 70}
68 71
72void LLUserOperation::SetNoExpireFlag(const BOOL flag)
73{
74 mNoExpire = flag;
75}
69 76
70BOOL LLUserOperation::isExpired() 77BOOL LLUserOperation::isExpired()
71{ 78{
72 const F32 EXPIRE_TIME_SECS = 10.f; 79 if (!mNoExpire)
73 return mTimer.getElapsedTimeF32() > EXPIRE_TIME_SECS; 80 {
81 const F32 EXPIRE_TIME_SECS = 10.f;
82 return mTimer.getElapsedTimeF32() > EXPIRE_TIME_SECS;
83 }
84 return FALSE;
74} 85}
75 86
76void LLUserOperation::expire() 87void LLUserOperation::expire()
diff --git a/linden/indra/llmessage/lluseroperation.h b/linden/indra/llmessage/lluseroperation.h
index 2b351f9..6ac2862 100644
--- a/linden/indra/llmessage/lluseroperation.h
+++ b/linden/indra/llmessage/lluseroperation.h
@@ -48,6 +48,9 @@ public:
48 // Operation never got necessary data, so expired 48 // Operation never got necessary data, so expired
49 virtual BOOL isExpired(); 49 virtual BOOL isExpired();
50 50
51 // ability to mark this operation as never expiring.
52 void SetNoExpireFlag(const BOOL flag);
53
51 // Send request to the dataserver 54 // Send request to the dataserver
52 virtual void sendRequest() = 0; 55 virtual void sendRequest() = 0;
53 56
@@ -67,6 +70,7 @@ protected:
67 LLUUID mAgentID; 70 LLUUID mAgentID;
68 LLUUID mTransactionID; 71 LLUUID mTransactionID;
69 LLFrameTimer mTimer; 72 LLFrameTimer mTimer;
73 BOOL mNoExpire; // this is used for operations that expect an answer and will wait till it gets one.
70}; 74};
71 75
72 76
diff --git a/linden/indra/llmessage/llxfer_file.cpp b/linden/indra/llmessage/llxfer_file.cpp
index 33db248..b36dd5a 100644
--- a/linden/indra/llmessage/llxfer_file.cpp
+++ b/linden/indra/llmessage/llxfer_file.cpp
@@ -289,7 +289,11 @@ S32 LLXfer_File::flush()
289 289
290 if (mFp) 290 if (mFp)
291 { 291 {
292 fwrite(mBuffer,1,mBufferLength,mFp); 292 if (fwrite(mBuffer,1,mBufferLength,mFp) != mBufferLength)
293 {
294 llwarns << "Short write" << llendl;
295 }
296
293// llinfos << "******* wrote " << mBufferLength << " bytes of file xfer" << llendl; 297// llinfos << "******* wrote " << mBufferLength << " bytes of file xfer" << llendl;
294 fclose(mFp); 298 fclose(mFp);
295 mFp = NULL; 299 mFp = NULL;
diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp
index 01dce40..a9d5dd3 100644
--- a/linden/indra/llmessage/message.cpp
+++ b/linden/indra/llmessage/message.cpp
@@ -405,6 +405,7 @@ LLMessageSystem::~LLMessageSystem()
405 { 405 {
406 end_net(mSocket); 406 end_net(mSocket);
407 } 407 }
408 mSocket = 0;
408 409
409 delete mTemplateMessageReader; 410 delete mTemplateMessageReader;
410 mTemplateMessageReader = NULL; 411 mTemplateMessageReader = NULL;
diff --git a/linden/indra/llmessage/message.h b/linden/indra/llmessage/message.h
index 6c834f7..d18bd09 100644
--- a/linden/indra/llmessage/message.h
+++ b/linden/indra/llmessage/message.h
@@ -39,6 +39,10 @@
39#include <netinet/in.h> 39#include <netinet/in.h>
40#endif 40#endif
41 41
42#if LL_SOLARIS
43#include <netinet/in.h>
44#endif
45
42#if LL_WINDOWS 46#if LL_WINDOWS
43#include "winsock2.h" // htons etc. 47#include "winsock2.h" // htons etc.
44#endif 48#endif
@@ -204,14 +208,14 @@ public:
204class LLMessageSystem 208class LLMessageSystem
205{ 209{
206 private: 210 private:
207 U8 mSendBuffer[MAX_BUFFER_SIZE]; 211 U8 mSendBuffer[MAX_BUFFER_SIZE];
208 S32 mSendSize; 212 S32 mSendSize;
209 213
210 public: 214 public:
211 LLPacketRing mPacketRing; 215 LLPacketRing mPacketRing;
212 LLReliablePacketParams mReliablePacketParams; 216 LLReliablePacketParams mReliablePacketParams;
213 217
214 //LLLinkedList<LLPacketAck> mAckList; 218 //LLLinkedList<LLPacketAck> mAckList;
215 219
216 // Set this flag to TRUE when you want *very* verbose logs. 220 // Set this flag to TRUE when you want *very* verbose logs.
217 BOOL mVerboseLog; 221 BOOL mVerboseLog;
@@ -222,36 +226,35 @@ class LLMessageSystem
222 typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; 226 typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;
223 227
224private: 228private:
225 message_template_name_map_t mMessageTemplates; 229 message_template_name_map_t mMessageTemplates;
226 message_template_number_map_t mMessageNumbers; 230 message_template_number_map_t mMessageNumbers;
227 231
228public: 232public:
229 S32 mSystemVersionMajor; 233 S32 mSystemVersionMajor;
230 S32 mSystemVersionMinor; 234 S32 mSystemVersionMinor;
231 S32 mSystemVersionPatch; 235 S32 mSystemVersionPatch;
232 S32 mSystemVersionServer; 236 S32 mSystemVersionServer;
233 U32 mVersionFlags; 237 U32 mVersionFlags;
234 238
239 BOOL mbProtected;
235 240
236 BOOL mbProtected; 241 U32 mNumberHighFreqMessages;
242 U32 mNumberMediumFreqMessages;
243 U32 mNumberLowFreqMessages;
244 S32 mPort;
245 S32 mSocket;
237 246
238 U32 mNumberHighFreqMessages; 247 U32 mPacketsIn; // total packets in, including compressed and uncompressed
239 U32 mNumberMediumFreqMessages; 248 U32 mPacketsOut; // total packets out, including compressed and uncompressed
240 U32 mNumberLowFreqMessages;
241 S32 mPort;
242 S32 mSocket;
243 249
244 U32 mPacketsIn; // total packets in, including compressed and uncompressed 250 U64 mBytesIn; // total bytes in, including compressed and uncompressed
245 U32 mPacketsOut; // total packets out, including compressed and uncompressed 251 U64 mBytesOut; // total bytes out, including compressed and uncompressed
246
247 U64 mBytesIn; // total bytes in, including compressed and uncompressed
248 U64 mBytesOut; // total bytes out, including compressed and uncompressed
249 252
250 U32 mCompressedPacketsIn; // total compressed packets in 253 U32 mCompressedPacketsIn; // total compressed packets in
251 U32 mCompressedPacketsOut; // total compressed packets out 254 U32 mCompressedPacketsOut; // total compressed packets out
252 255
253 U32 mReliablePacketsIn; // total reliable packets in 256 U32 mReliablePacketsIn; // total reliable packets in
254 U32 mReliablePacketsOut; // total reliable packets out 257 U32 mReliablePacketsOut; // total reliable packets out
255 258
256 U32 mDroppedPackets; // total dropped packets in 259 U32 mDroppedPackets; // total dropped packets in
257 U32 mResentPackets; // total resent packets out 260 U32 mResentPackets; // total resent packets out
@@ -259,26 +262,26 @@ public:
259 U32 mOffCircuitPackets; // total # of off-circuit packets rejected 262 U32 mOffCircuitPackets; // total # of off-circuit packets rejected
260 U32 mInvalidOnCircuitPackets; // total # of on-circuit but invalid packets rejected 263 U32 mInvalidOnCircuitPackets; // total # of on-circuit but invalid packets rejected
261 264
262 S64 mUncompressedBytesIn; // total uncompressed size of compressed packets in 265 S64 mUncompressedBytesIn; // total uncompressed size of compressed packets in
263 S64 mUncompressedBytesOut; // total uncompressed size of compressed packets out 266 S64 mUncompressedBytesOut; // total uncompressed size of compressed packets out
264 S64 mCompressedBytesIn; // total compressed size of compressed packets in 267 S64 mCompressedBytesIn; // total compressed size of compressed packets in
265 S64 mCompressedBytesOut; // total compressed size of compressed packets out 268 S64 mCompressedBytesOut; // total compressed size of compressed packets out
266 S64 mTotalBytesIn; // total size of all uncompressed packets in 269 S64 mTotalBytesIn; // total size of all uncompressed packets in
267 S64 mTotalBytesOut; // total size of all uncompressed packets out 270 S64 mTotalBytesOut; // total size of all uncompressed packets out
268 271
269 BOOL mSendReliable; // does the outgoing message require a pos ack? 272 BOOL mSendReliable; // does the outgoing message require a pos ack?
270 273
271 LLCircuit mCircuitInfo; 274 LLCircuit mCircuitInfo;
272 F64 mCircuitPrintTime; // used to print circuit debug info every couple minutes 275 F64 mCircuitPrintTime; // used to print circuit debug info every couple minutes
273 F32 mCircuitPrintFreq; // seconds 276 F32 mCircuitPrintFreq; // seconds
274 277
275 std::map<U64, U32> mIPPortToCircuitCode; 278 std::map<U64, U32> mIPPortToCircuitCode;
276 std::map<U32, U64> mCircuitCodeToIPPort; 279 std::map<U32, U64> mCircuitCodeToIPPort;
277 U32 mOurCircuitCode; 280 U32 mOurCircuitCode;
278 S32 mSendPacketFailureCount; 281 S32 mSendPacketFailureCount;
279 S32 mUnackedListDepth; 282 S32 mUnackedListDepth;
280 S32 mUnackedListSize; 283 S32 mUnackedListSize;
281 S32 mDSMaxListDepth; 284 S32 mDSMaxListDepth;
282 285
283public: 286public:
284 // Read file and build message templates 287 // Read file and build message templates
@@ -693,14 +696,14 @@ private:
693 696
694 LLMessagePollInfo *mPollInfop; 697 LLMessagePollInfo *mPollInfop;
695 698
696 U8 mEncodedRecvBuffer[MAX_BUFFER_SIZE]; 699 U8 mEncodedRecvBuffer[MAX_BUFFER_SIZE];
697 U8 mTrueReceiveBuffer[MAX_BUFFER_SIZE]; 700 U8 mTrueReceiveBuffer[MAX_BUFFER_SIZE];
698 S32 mTrueReceiveSize; 701 S32 mTrueReceiveSize;
699 702
700 // Must be valid during decode 703 // Must be valid during decode
701 704
702 BOOL mbError; 705 BOOL mbError;
703 S32 mErrorCode; 706 S32 mErrorCode;
704 707
705 F64 mResendDumpTime; // The last time we dumped resends 708 F64 mResendDumpTime; // The last time we dumped resends
706 709
@@ -775,6 +778,10 @@ void null_message_callback(LLMessageSystem *msg, void **data);
775// Inlines 778// Inlines
776// 779//
777 780
781#if !defined( LL_BIG_ENDIAN ) && !defined( LL_LITTLE_ENDIAN )
782#error Unknown endianness for htonmemcpy. Did you miss a common include?
783#endif
784
778static inline void *htonmemcpy(void *vs, const void *vct, EMsgVariableType type, size_t n) 785static inline void *htonmemcpy(void *vs, const void *vct, EMsgVariableType type, size_t n)
779{ 786{
780 char *s = (char *)vs; 787 char *s = (char *)vs;
diff --git a/linden/indra/llrender/llfont.cpp b/linden/indra/llrender/llfont.cpp
index ed787e0..b07d0d6 100644
--- a/linden/indra/llrender/llfont.cpp
+++ b/linden/indra/llrender/llfont.cpp
@@ -31,10 +31,11 @@
31#include "llfont.h" 31#include "llfont.h"
32 32
33// Freetype stuff 33// Freetype stuff
34#if LL_LINUX // I had to do some work to avoid the system-installed FreeType headers... --ryan. 34#if !defined(LL_LINUX) || defined(LL_STANDALONE)
35#include "llfreetype2/freetype/ft2build.h" 35# include <ft2build.h>
36#else 36#else
37#include <ft2build.h> 37// I had to do some work to avoid the system-installed FreeType headers... --ryan.
38# include "llfreetype2/freetype/ft2build.h"
38#endif 39#endif
39 40
40// For some reason, this won't work if it's not wrapped in the ifdef 41// For some reason, this won't work if it's not wrapped in the ifdef
@@ -178,11 +179,20 @@ F32 LLFont::getDescenderHeight() const
178 179
179BOOL LLFont::loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback) 180BOOL LLFont::loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback)
180{ 181{
182 // Don't leak face objects. This is also needed to deal with
183 // changed font file names.
184 if (mFTFace)
185 {
186 FT_Done_Face(mFTFace);
187 mFTFace = NULL;
188 }
189
181 int error; 190 int error;
191
182 error = FT_New_Face( gFTLibrary, 192 error = FT_New_Face( gFTLibrary,
183 filename.c_str(), 193 filename.c_str(),
184 0, 194 0,
185 &mFTFace ); 195 &mFTFace );
186 196
187 if (error) 197 if (error)
188 { 198 {
@@ -326,6 +336,9 @@ BOOL LLFont::hasGlyph(const llwchar wch) const
326 336
327BOOL LLFont::addChar(const llwchar wch) 337BOOL LLFont::addChar(const llwchar wch)
328{ 338{
339 if (mFTFace == NULL)
340 return FALSE;
341
329 llassert(!mIsFallback); 342 llassert(!mIsFallback);
330 //lldebugs << "Adding new glyph for " << wch << " to font" << llendl; 343 //lldebugs << "Adding new glyph for " << wch << " to font" << llendl;
331 344
@@ -378,6 +391,9 @@ void LLFont::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
378 391
379BOOL LLFont::addGlyphFromFont(LLFont *fontp, const llwchar wch, const U32 glyph_index) 392BOOL LLFont::addGlyphFromFont(LLFont *fontp, const llwchar wch, const U32 glyph_index)
380{ 393{
394 if (mFTFace == NULL)
395 return FALSE;
396
381 llassert(!mIsFallback); 397 llassert(!mIsFallback);
382 fontp->renderGlyph(glyph_index); 398 fontp->renderGlyph(glyph_index);
383 S32 width = fontp->mFTFace->glyph->bitmap.width; 399 S32 width = fontp->mFTFace->glyph->bitmap.width;
@@ -501,6 +517,9 @@ BOOL LLFont::addGlyph(const llwchar wch, const U32 glyph_index)
501 517
502F32 LLFont::getXAdvance(const llwchar wch) const 518F32 LLFont::getXAdvance(const llwchar wch) const
503{ 519{
520 if (mFTFace == NULL)
521 return 0.0;
522
504 llassert(!mIsFallback); 523 llassert(!mIsFallback);
505 U32 glyph_index; 524 U32 glyph_index;
506 525
@@ -569,6 +588,9 @@ F32 LLFont::getXAdvance(const llwchar wch) const
569 588
570void LLFont::renderGlyph(const U32 glyph_index) 589void LLFont::renderGlyph(const U32 glyph_index)
571{ 590{
591 if (mFTFace == NULL)
592 return;
593
572 int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT ); 594 int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT );
573 llassert(!error); 595 llassert(!error);
574 596
@@ -579,6 +601,9 @@ void LLFont::renderGlyph(const U32 glyph_index)
579 601
580F32 LLFont::getXKerning(const llwchar char_left, const llwchar char_right) const 602F32 LLFont::getXKerning(const llwchar char_left, const llwchar char_right) const
581{ 603{
604 if (mFTFace == NULL)
605 return 0.0;
606
582 llassert(!mIsFallback); 607 llassert(!mIsFallback);
583 LLFontGlyphInfo* left_glyph_info = get_if_there(mCharGlyphInfoMap, char_left, (LLFontGlyphInfo*)NULL); 608 LLFontGlyphInfo* left_glyph_info = get_if_there(mCharGlyphInfoMap, char_left, (LLFontGlyphInfo*)NULL);
584 U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0; 609 U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp
index e2c4a59..a2e5abc 100644
--- a/linden/indra/llrender/llimagegl.cpp
+++ b/linden/indra/llrender/llimagegl.cpp
@@ -963,7 +963,8 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level)
963 } 963 }
964 else 964 else
965 { 965 {
966#ifndef LL_LINUX // *FIX: This should not be skipped for the linux client. 966#if !LL_LINUX && !LL_SOLARIS
967 // *FIX: This should not be skipped for the linux client.
967 llerrs << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl; 968 llerrs << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl;
968#endif 969#endif
969 return FALSE; 970 return FALSE;
diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h
index 16315ee..3bdd1c9 100644
--- a/linden/indra/llrender/llimagegl.h
+++ b/linden/indra/llrender/llimagegl.h
@@ -136,7 +136,6 @@ public:
136 // Various GL/Rendering options 136 // Various GL/Rendering options
137 S32 mTextureMemory; 137 S32 mTextureMemory;
138 mutable F32 mLastBindTime; // last time this was bound, by discard level 138 mutable F32 mLastBindTime; // last time this was bound, by discard level
139 mutable F32 mLastBindAttempt; // last time bindTexture was called on this texture
140 139
141private: 140private:
142 LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL 141 LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
diff --git a/linden/indra/llui/files.lst b/linden/indra/llui/files.lst
index 5a62573..96bb170 100644
--- a/linden/indra/llui/files.lst
+++ b/linden/indra/llui/files.lst
@@ -8,7 +8,6 @@ llui/lldraghandle.cpp
8llui/lleditmenuhandler.cpp 8llui/lleditmenuhandler.cpp
9llui/llfloater.cpp 9llui/llfloater.cpp
10llui/llfocusmgr.cpp 10llui/llfocusmgr.cpp
11llui/llhtmlhelp.h
12llui/lliconctrl.cpp 11llui/lliconctrl.cpp
13llui/llkeywords.cpp 12llui/llkeywords.cpp
14llui/lllineeditor.cpp 13llui/lllineeditor.cpp
diff --git a/linden/indra/llui/llbutton.cpp b/linden/indra/llui/llbutton.cpp
index de8b82e..aa50a6e 100644
--- a/linden/indra/llui/llbutton.cpp
+++ b/linden/indra/llui/llbutton.cpp
@@ -89,7 +89,8 @@ LLButton::LLButton( const LLString& name, const LLRect& rect, const LLString& co
89 mCurGlowStrength(0.f), 89 mCurGlowStrength(0.f),
90 mNeedsHighlight(FALSE), 90 mNeedsHighlight(FALSE),
91 mCommitOnReturn(TRUE), 91 mCommitOnReturn(TRUE),
92 mImagep( NULL ) 92 mImagep( NULL ),
93 mIsDirty( FALSE )
93{ 94{
94 mUnselectedLabel = name; 95 mUnselectedLabel = name;
95 mSelectedLabel = name; 96 mSelectedLabel = name;
@@ -216,6 +217,9 @@ void LLButton::init(void (*click_callback)(void*), void *callback_data, const LL
216 mHighlightColor = ( LLUI::sColorsGroup->getColor( "ButtonUnselectedFgColor" ) ); 217 mHighlightColor = ( LLUI::sColorsGroup->getColor( "ButtonUnselectedFgColor" ) );
217 mUnselectedBgColor = ( LLUI::sColorsGroup->getColor( "ButtonUnselectedBgColor" ) ); 218 mUnselectedBgColor = ( LLUI::sColorsGroup->getColor( "ButtonUnselectedBgColor" ) );
218 mSelectedBgColor = ( LLUI::sColorsGroup->getColor( "ButtonSelectedBgColor" ) ); 219 mSelectedBgColor = ( LLUI::sColorsGroup->getColor( "ButtonSelectedBgColor" ) );
220
221 mImageOverlayAlignment = LLFontGL::HCENTER;
222 mImageOverlayColor = LLColor4::white;
219} 223}
220 224
221LLButton::~LLButton() 225LLButton::~LLButton()
@@ -271,8 +275,12 @@ void LLButton::onCommit()
271 { 275 {
272 (*mClickedCallback)( mCallbackUserData ); 276 (*mClickedCallback)( mCallbackUserData );
273 } 277 }
278
279 mIsDirty = TRUE;
274} 280}
275 281
282
283
276BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) 284BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent)
277{ 285{
278 BOOL handled = FALSE; 286 BOOL handled = FALSE;
@@ -282,7 +290,8 @@ BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent)
282 { 290 {
283 (*mClickedCallback)( mCallbackUserData ); 291 (*mClickedCallback)( mCallbackUserData );
284 } 292 }
285 handled = TRUE; 293 handled = TRUE;
294 mIsDirty = TRUE;
286 } 295 }
287 return handled; 296 return handled;
288} 297}
@@ -299,6 +308,7 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent )
299 (*mClickedCallback)( mCallbackUserData ); 308 (*mClickedCallback)( mCallbackUserData );
300 } 309 }
301 handled = TRUE; 310 handled = TRUE;
311 mIsDirty = TRUE;
302 } 312 }
303 } 313 }
304 return handled; 314 return handled;
@@ -359,6 +369,8 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
359 { 369 {
360 (*mClickedCallback)( mCallbackUserData ); 370 (*mClickedCallback)( mCallbackUserData );
361 } 371 }
372
373 mIsDirty = TRUE;
362 } 374 }
363 375
364 mMouseDownTimer.stop(); 376 mMouseDownTimer.stop();
@@ -618,7 +630,7 @@ void LLButton::draw()
618 // draw overlay image 630 // draw overlay image
619 if (mImageOverlay.notNull()) 631 if (mImageOverlay.notNull())
620 { 632 {
621 const S32 IMG_PAD = 4; 633 const S32 IMG_PAD = 5;
622 // get max width and height (discard level 0) 634 // get max width and height (discard level 0)
623 S32 overlay_width = mImageOverlay->getWidth(0); 635 S32 overlay_width = mImageOverlay->getWidth(0);
624 S32 overlay_height = mImageOverlay->getHeight(0); 636 S32 overlay_height = mImageOverlay->getHeight(0);
@@ -639,7 +651,7 @@ void LLButton::draw()
639 overlay_width, 651 overlay_width,
640 overlay_height, 652 overlay_height,
641 mImageOverlay, 653 mImageOverlay,
642 LLColor4::white); 654 mImageOverlayColor);
643 break; 655 break;
644 case LLFontGL::HCENTER: 656 case LLFontGL::HCENTER:
645 gl_draw_scaled_image( 657 gl_draw_scaled_image(
@@ -648,7 +660,7 @@ void LLButton::draw()
648 overlay_width, 660 overlay_width,
649 overlay_height, 661 overlay_height,
650 mImageOverlay, 662 mImageOverlay,
651 LLColor4::white); 663 mImageOverlayColor);
652 break; 664 break;
653 case LLFontGL::RIGHT: 665 case LLFontGL::RIGHT:
654 gl_draw_scaled_image( 666 gl_draw_scaled_image(
@@ -657,7 +669,7 @@ void LLButton::draw()
657 overlay_width, 669 overlay_width,
658 overlay_height, 670 overlay_height,
659 mImageOverlay, 671 mImageOverlay,
660 LLColor4::white); 672 mImageOverlayColor);
661 break; 673 break;
662 default: 674 default:
663 // draw nothing 675 // draw nothing
@@ -761,6 +773,7 @@ void LLButton::setToggleState(BOOL b)
761void LLButton::setValue(const LLSD& value ) 773void LLButton::setValue(const LLSD& value )
762{ 774{
763 mToggleState = value.asBoolean(); 775 mToggleState = value.asBoolean();
776 mIsDirty = FALSE;
764} 777}
765 778
766LLSD LLButton::getValue() const 779LLSD LLButton::getValue() const
@@ -876,7 +889,7 @@ void LLButton::setHoverImages( const LLString& image_name, const LLString& selec
876 setImageHoverSelected(selected_name); 889 setImageHoverSelected(selected_name);
877} 890}
878 891
879void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment) 892void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment, const LLColor4& color)
880{ 893{
881 if (image_name.empty()) 894 if (image_name.empty())
882 { 895 {
@@ -887,6 +900,7 @@ void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alig
887 LLUUID overlay_image_id = LLUI::findAssetUUIDByName(image_name); 900 LLUUID overlay_image_id = LLUI::findAssetUUIDByName(image_name);
888 mImageOverlay = LLUI::sImageProvider->getUIImageByID(overlay_image_id); 901 mImageOverlay = LLUI::sImageProvider->getUIImageByID(overlay_image_id);
889 mImageOverlayAlignment = alignment; 902 mImageOverlayAlignment = alignment;
903 mImageOverlayColor = color;
890 } 904 }
891} 905}
892 906
diff --git a/linden/indra/llui/llbutton.h b/linden/indra/llui/llbutton.h
index 6e11779..aedc411 100644
--- a/linden/indra/llui/llbutton.h
+++ b/linden/indra/llui/llbutton.h
@@ -100,6 +100,8 @@ public:
100 // HACK: "committing" a button is the same as clicking on it. 100 // HACK: "committing" a button is the same as clicking on it.
101 virtual void onCommit(); 101 virtual void onCommit();
102 102
103 virtual BOOL isDirty() { return mIsDirty; }; // Returns TRUE if the user has clicked on the button at all
104
103 void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; } 105 void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; }
104 void setSelectedLabelColor( const LLColor4& c ) { mSelectedLabelColor = c; } 106 void setSelectedLabelColor( const LLColor4& c ) { mSelectedLabelColor = c; }
105 107
@@ -142,7 +144,7 @@ public:
142 144
143 void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; } 145 void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; }
144 146
145 void setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER); 147 void setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
146 LLPointer<LLImageGL> getImageOverlay() { return mImageOverlay; } 148 LLPointer<LLImageGL> getImageOverlay() { return mImageOverlay; }
147 149
148 150
@@ -208,6 +210,7 @@ protected:
208 210
209 LLPointer<LLImageGL> mImageOverlay; 211 LLPointer<LLImageGL> mImageOverlay;
210 LLFontGL::HAlign mImageOverlayAlignment; 212 LLFontGL::HAlign mImageOverlayAlignment;
213 LLColor4 mImageOverlayColor;
211 214
212 LLPointer<LLImageGL> mImageUnselected; 215 LLPointer<LLImageGL> mImageUnselected;
213 LLUIString mUnselectedLabel; 216 LLUIString mUnselectedLabel;
@@ -276,6 +279,8 @@ protected:
276 279
277 LLPointer<LLImageGL> mImagep; 280 LLPointer<LLImageGL> mImagep;
278 281
282 BOOL mIsDirty;
283
279 static LLFrameTimer sFlashingTimer; 284 static LLFrameTimer sFlashingTimer;
280}; 285};
281 286
diff --git a/linden/indra/llui/llcheckboxctrl.cpp b/linden/indra/llui/llcheckboxctrl.cpp
index 5f3350e..24cf680 100644
--- a/linden/indra/llui/llcheckboxctrl.cpp
+++ b/linden/indra/llui/llcheckboxctrl.cpp
@@ -267,6 +267,18 @@ void LLCheckBoxCtrl::setControlName(const LLString& control_name, LLView* contex
267 mButton->setControlName(control_name, context); 267 mButton->setControlName(control_name, context);
268} 268}
269 269
270
271// virtual Returns TRUE if the user has modified this control.
272BOOL LLCheckBoxCtrl::isDirty()
273{
274 if ( mButton )
275 {
276 return mButton->isDirty();
277 }
278 return FALSE; // Shouldn't get here
279}
280
281
270// virtual 282// virtual
271LLXMLNodePtr LLCheckBoxCtrl::getXML(bool save_children) const 283LLXMLNodePtr LLCheckBoxCtrl::getXML(bool save_children) const
272{ 284{
diff --git a/linden/indra/llui/llcheckboxctrl.h b/linden/indra/llui/llcheckboxctrl.h
index 1b895cb..37b1330 100644
--- a/linden/indra/llui/llcheckboxctrl.h
+++ b/linden/indra/llui/llcheckboxctrl.h
@@ -110,6 +110,8 @@ public:
110 110
111 static void onButtonPress(void *userdata); 111 static void onButtonPress(void *userdata);
112 112
113 virtual BOOL isDirty(); // Returns TRUE if the user has modified this control.
114
113protected: 115protected:
114 // note: value is stored in toggle state of button 116 // note: value is stored in toggle state of button
115 LLButton* mButton; 117 LLButton* mButton;
diff --git a/linden/indra/llui/llctrlselectioninterface.h b/linden/indra/llui/llctrlselectioninterface.h
index 878648d..e21f039 100644
--- a/linden/indra/llui/llctrlselectioninterface.h
+++ b/linden/indra/llui/llctrlselectioninterface.h
@@ -51,6 +51,8 @@ public:
51 51
52 virtual BOOL getCanSelect() const = 0; 52 virtual BOOL getCanSelect() const = 0;
53 53
54 virtual S32 getItemCount() const = 0;
55
54 virtual BOOL selectFirstItem() = 0; 56 virtual BOOL selectFirstItem() = 0;
55 virtual BOOL selectNthItem( S32 index ) = 0; 57 virtual BOOL selectNthItem( S32 index ) = 0;
56 58
@@ -76,7 +78,6 @@ class LLCtrlListInterface : public LLCtrlSelectionInterface
76public: 78public:
77 virtual ~LLCtrlListInterface(); 79 virtual ~LLCtrlListInterface();
78 80
79 virtual S32 getItemCount() const = 0;
80 virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM) = 0; 81 virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM) = 0;
81 virtual void clearColumns() = 0; 82 virtual void clearColumns() = 0;
82 virtual void setColumnLabel(const LLString& column, const LLString& label) = 0; 83 virtual void setColumnLabel(const LLString& column, const LLString& label) = 0;
diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp
index 6ab182f..b45661f 100644
--- a/linden/indra/llui/llfloater.cpp
+++ b/linden/indra/llui/llfloater.cpp
@@ -312,28 +312,32 @@ void LLFloater::init(const LLString& title,
312 { 312 {
313 // Resize bars (sides) 313 // Resize bars (sides)
314 const S32 RESIZE_BAR_THICKNESS = 3; 314 const S32 RESIZE_BAR_THICKNESS = 3;
315 mResizeBar[0] = new LLResizeBar( 315 mResizeBar[LLResizeBar::LEFT] = new LLResizeBar(
316 "resizebar_left", 316 "resizebar_left",
317 this,
317 LLRect( 0, mRect.getHeight(), RESIZE_BAR_THICKNESS, 0), 318 LLRect( 0, mRect.getHeight(), RESIZE_BAR_THICKNESS, 0),
318 min_width, min_height, LLResizeBar::LEFT ); 319 min_width, S32_MAX, LLResizeBar::LEFT );
319 addChild( mResizeBar[0] ); 320 addChild( mResizeBar[0] );
320 321
321 mResizeBar[1] = new LLResizeBar( 322 mResizeBar[LLResizeBar::TOP] = new LLResizeBar(
322 "resizebar_top", 323 "resizebar_top",
324 this,
323 LLRect( 0, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_BAR_THICKNESS), 325 LLRect( 0, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_BAR_THICKNESS),
324 min_width, min_height, LLResizeBar::TOP ); 326 min_height, S32_MAX, LLResizeBar::TOP );
325 addChild( mResizeBar[1] ); 327 addChild( mResizeBar[1] );
326 328
327 mResizeBar[2] = new LLResizeBar( 329 mResizeBar[LLResizeBar::RIGHT] = new LLResizeBar(
328 "resizebar_right", 330 "resizebar_right",
331 this,
329 LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0), 332 LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0),
330 min_width, min_height, LLResizeBar::RIGHT ); 333 min_width, S32_MAX, LLResizeBar::RIGHT );
331 addChild( mResizeBar[2] ); 334 addChild( mResizeBar[2] );
332 335
333 mResizeBar[3] = new LLResizeBar( 336 mResizeBar[LLResizeBar::BOTTOM] = new LLResizeBar(
334 "resizebar_bottom", 337 "resizebar_bottom",
338 this,
335 LLRect( 0, RESIZE_BAR_THICKNESS, mRect.getWidth(), 0), 339 LLRect( 0, RESIZE_BAR_THICKNESS, mRect.getWidth(), 0),
336 min_width, min_height, LLResizeBar::BOTTOM ); 340 min_height, S32_MAX, LLResizeBar::BOTTOM );
337 addChild( mResizeBar[3] ); 341 addChild( mResizeBar[3] );
338 342
339 343
@@ -367,18 +371,6 @@ void LLFloater::init(const LLString& title,
367 LLResizeHandle::LEFT_TOP ); 371 LLResizeHandle::LEFT_TOP );
368 addChild(mResizeHandle[3]); 372 addChild(mResizeHandle[3]);
369 } 373 }
370 else
371 {
372 mResizeBar[0] = NULL;
373 mResizeBar[1] = NULL;
374 mResizeBar[2] = NULL;
375 mResizeBar[3] = NULL;
376
377 mResizeHandle[0] = NULL;
378 mResizeHandle[1] = NULL;
379 mResizeHandle[2] = NULL;
380 mResizeHandle[3] = NULL;
381 }
382 374
383 // Close button. 375 // Close button.
384 if (close_btn) 376 if (close_btn)
@@ -392,6 +384,13 @@ void LLFloater::init(const LLString& title,
392 mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; 384 mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;
393 } 385 }
394 386
387 // Keep track of whether this window has ever been dragged while it
388 // was minimized. If it has, we'll remember its position for the
389 // next time it's minimized.
390 mHasBeenDraggedWhileMinimized = FALSE;
391 mPreviousMinimizedLeft = 0;
392 mPreviousMinimizedBottom = 0;
393
395 buildButtons(); 394 buildButtons();
396 395
397 // JC - Don't do this here, because many floaters first construct themselves, 396 // JC - Don't do this here, because many floaters first construct themselves,
@@ -626,7 +625,14 @@ void LLFloater::setResizeLimits( S32 min_width, S32 min_height )
626 { 625 {
627 if( mResizeBar[i] ) 626 if( mResizeBar[i] )
628 { 627 {
629 mResizeBar[i]->setResizeLimits( min_width, min_height ); 628 if (i == LLResizeBar::LEFT || i == LLResizeBar::RIGHT)
629 {
630 mResizeBar[i]->setResizeLimits( min_width, S32_MAX );
631 }
632 else
633 {
634 mResizeBar[i]->setResizeLimits( min_height, S32_MAX );
635 }
630 } 636 }
631 if( mResizeHandle[i] ) 637 if( mResizeHandle[i] )
632 { 638 {
@@ -678,6 +684,25 @@ const LLString& LLFloater::getTitle() const
678 return mDragHandle ? mDragHandle->getTitle() : LLString::null; 684 return mDragHandle ? mDragHandle->getTitle() : LLString::null;
679} 685}
680 686
687void LLFloater::setShortTitle( const LLString& short_title )
688{
689 mShortTitle = short_title;
690}
691
692LLString LLFloater::getShortTitle()
693{
694 if (mShortTitle.empty())
695 {
696 return mDragHandle ? mDragHandle->getTitle() : LLString::null;
697 }
698 else
699 {
700 return mShortTitle;
701 }
702}
703
704
705
681BOOL LLFloater::canSnapTo(LLView* other_view) 706BOOL LLFloater::canSnapTo(LLView* other_view)
682{ 707{
683 if (NULL == other_view) 708 if (NULL == other_view)
@@ -757,6 +782,16 @@ void LLFloater::userSetShape(const LLRect& new_rect)
757 } 782 }
758 } 783 }
759 } 784 }
785 else
786 {
787 // If minimized, and origin has changed, set
788 // mHasBeenDraggedWhileMinimized to TRUE
789 if ((new_rect.mLeft != old_rect.mLeft) ||
790 (new_rect.mBottom != old_rect.mBottom))
791 {
792 mHasBeenDraggedWhileMinimized = TRUE;
793 }
794 }
760} 795}
761 796
762void LLFloater::setMinimized(BOOL minimize) 797void LLFloater::setMinimized(BOOL minimize)
@@ -769,9 +804,19 @@ void LLFloater::setMinimized(BOOL minimize)
769 804
770 reshape( MINIMIZED_WIDTH, LLFLOATER_HEADER_SIZE, TRUE); 805 reshape( MINIMIZED_WIDTH, LLFLOATER_HEADER_SIZE, TRUE);
771 806
772 S32 left, bottom; 807 // If the floater has been dragged while minimized in the
773 gFloaterView->getMinimizePosition(&left, &bottom); 808 // past, then locate it at its previous minimized location.
774 setOrigin( left, bottom ); 809 // Otherwise, ask the view for a minimize position.
810 if (mHasBeenDraggedWhileMinimized)
811 {
812 setOrigin(mPreviousMinimizedLeft, mPreviousMinimizedBottom);
813 }
814 else
815 {
816 S32 left, bottom;
817 gFloaterView->getMinimizePosition(&left, &bottom);
818 setOrigin( left, bottom );
819 }
775 820
776 if (mButtonsEnabled[BUTTON_MINIMIZE]) 821 if (mButtonsEnabled[BUTTON_MINIMIZE])
777 { 822 {
@@ -824,6 +869,15 @@ void LLFloater::setMinimized(BOOL minimize)
824 } 869 }
825 else 870 else
826 { 871 {
872 // If this window has been dragged while minimized (at any time),
873 // remember its position for the next time it's minimized.
874 if (mHasBeenDraggedWhileMinimized)
875 {
876 const LLRect& currentRect = getRect();
877 mPreviousMinimizedLeft = currentRect.mLeft;
878 mPreviousMinimizedBottom = currentRect.mBottom;
879 }
880
827 reshape( mPreviousRect.getWidth(), mPreviousRect.getHeight(), TRUE ); 881 reshape( mPreviousRect.getWidth(), mPreviousRect.getHeight(), TRUE );
828 setOrigin( mPreviousRect.mLeft, mPreviousRect.mBottom ); 882 setOrigin( mPreviousRect.mLeft, mPreviousRect.mBottom );
829 883
@@ -987,12 +1041,22 @@ void LLFloater::setHost(LLMultiFloater* host)
987 } 1041 }
988} 1042}
989 1043
990void LLFloater::moveResizeHandleToFront() 1044void LLFloater::moveResizeHandlesToFront()
991{ 1045{
992 // 0 is the bottom right 1046 for( S32 i = 0; i < 4; i++ )
993 if( mResizeHandle[0] )
994 { 1047 {
995 sendChildToFront(mResizeHandle[0]); 1048 if( mResizeBar[i] )
1049 {
1050 sendChildToFront(mResizeBar[i]);
1051 }
1052 }
1053
1054 for( S32 i = 0; i < 4; i++ )
1055 {
1056 if( mResizeHandle[i] )
1057 {
1058 sendChildToFront(mResizeHandle[i]);
1059 }
996 } 1060 }
997} 1061}
998 1062
@@ -1040,7 +1104,6 @@ BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
1040 if( mMinimized ) 1104 if( mMinimized )
1041 { 1105 {
1042 // Offer the click to the close button. 1106 // Offer the click to the close button.
1043 // Any other click = restore
1044 if( mButtonsEnabled[BUTTON_CLOSE] ) 1107 if( mButtonsEnabled[BUTTON_CLOSE] )
1045 { 1108 {
1046 S32 local_x = x - mButtons[BUTTON_CLOSE]->getRect().mLeft; 1109 S32 local_x = x - mButtons[BUTTON_CLOSE]->getRect().mLeft;
@@ -1054,9 +1117,22 @@ BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
1054 } 1117 }
1055 } 1118 }
1056 1119
1057 // restore 1120 // Offer the click to the restore button.
1058 bringToFront( x, y ); 1121 if( mButtonsEnabled[BUTTON_RESTORE] )
1059 return TRUE; 1122 {
1123 S32 local_x = x - mButtons[BUTTON_RESTORE]->getRect().mLeft;
1124 S32 local_y = y - mButtons[BUTTON_RESTORE]->getRect().mBottom;
1125
1126 if (mButtons[BUTTON_RESTORE]->pointInView(local_x, local_y)
1127 && mButtons[BUTTON_RESTORE]->handleMouseDown(local_x, local_y, mask))
1128 {
1129 // restore button handled it, return
1130 return TRUE;
1131 }
1132 }
1133
1134 // Otherwise pass to drag handle for movement
1135 return mDragHandle->handleMouseDown(x, y, mask);
1060 } 1136 }
1061 else 1137 else
1062 { 1138 {
@@ -1177,6 +1253,10 @@ BOOL LLFloater::getEditModeEnabled()
1177void LLFloater::show(LLFloater* floaterp) 1253void LLFloater::show(LLFloater* floaterp)
1178{ 1254{
1179 if (floaterp) floaterp->open(); 1255 if (floaterp) floaterp->open();
1256 if (floaterp->getHost())
1257 {
1258 floaterp->getHost()->open();
1259 }
1180} 1260}
1181 1261
1182//static 1262//static
@@ -1190,7 +1270,7 @@ BOOL LLFloater::visible(LLFloater* floaterp)
1190{ 1270{
1191 if (floaterp) 1271 if (floaterp)
1192 { 1272 {
1193 return floaterp->isInVisibleChain(); 1273 return !floaterp->isMinimized() && floaterp->isInVisibleChain();
1194 } 1274 }
1195 return FALSE; 1275 return FALSE;
1196} 1276}
@@ -1217,12 +1297,15 @@ void LLFloater::onClickTearOff(void *userdata)
1217 // reparent to floater view 1297 // reparent to floater view
1218 gFloaterView->addChild(self); 1298 gFloaterView->addChild(self);
1219 1299
1220 new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - LLFLOATER_HEADER_SIZE - 5, self->mRect.getWidth(), self->mRect.getHeight());
1221
1222 self->open(); /* Flawfinder: ignore */ 1300 self->open(); /* Flawfinder: ignore */
1223 self->setRect(new_rect); 1301
1302 // only force position for floaters that don't have that data saved
1303 if (self->mRectControl.empty())
1304 {
1305 new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - LLFLOATER_HEADER_SIZE - 5, self->mRect.getWidth(), self->mRect.getHeight());
1306 self->setRect(new_rect);
1307 }
1224 gFloaterView->adjustToFitScreen(self, FALSE); 1308 gFloaterView->adjustToFitScreen(self, FALSE);
1225 self->setCanDrag(TRUE);
1226 // give focus to new window to keep continuity for the user 1309 // give focus to new window to keep continuity for the user
1227 self->setFocus(TRUE); 1310 self->setFocus(TRUE);
1228 } 1311 }
@@ -1232,6 +1315,8 @@ void LLFloater::onClickTearOff(void *userdata)
1232 if (new_host) 1315 if (new_host)
1233 { 1316 {
1234 new_host->showFloater(self); 1317 new_host->showFloater(self);
1318 // make sure host is visible
1319 new_host->open();
1235 } 1320 }
1236 } 1321 }
1237} 1322}
@@ -1468,30 +1553,14 @@ void LLFloater::setCanResize(BOOL can_resize)
1468{ 1553{
1469 if (mResizable && !can_resize) 1554 if (mResizable && !can_resize)
1470 { 1555 {
1471 removeChild(mResizeBar[0]); 1556 for (S32 i = 0; i < 4; i++)
1472 removeChild(mResizeBar[1]); 1557 {
1473 removeChild(mResizeBar[2]); 1558 removeChild(mResizeBar[i], TRUE);
1474 removeChild(mResizeBar[3]); 1559 mResizeBar[i] = NULL;
1475 removeChild(mResizeHandle[0]); 1560
1476 removeChild(mResizeHandle[1]); 1561 removeChild(mResizeHandle[i], TRUE);
1477 removeChild(mResizeHandle[2]); 1562 mResizeHandle[i] = NULL;
1478 removeChild(mResizeHandle[3]); 1563 }
1479 delete mResizeBar[0];
1480 delete mResizeBar[1];
1481 delete mResizeBar[2];
1482 delete mResizeBar[3];
1483 delete mResizeHandle[0];
1484 delete mResizeHandle[1];
1485 delete mResizeHandle[2];
1486 mResizeHandle[3] = NULL;
1487 mResizeBar[0] = NULL;
1488 mResizeBar[1] = NULL;
1489 mResizeBar[2] = NULL;
1490 mResizeBar[3] = NULL;
1491 mResizeHandle[0] = NULL;
1492 mResizeHandle[1] = NULL;
1493 mResizeHandle[2] = NULL;
1494 mResizeHandle[3] = NULL;
1495 } 1564 }
1496 else if (!mResizable && can_resize) 1565 else if (!mResizable && can_resize)
1497 { 1566 {
@@ -1499,26 +1568,30 @@ void LLFloater::setCanResize(BOOL can_resize)
1499 const S32 RESIZE_BAR_THICKNESS = 3; 1568 const S32 RESIZE_BAR_THICKNESS = 3;
1500 mResizeBar[0] = new LLResizeBar( 1569 mResizeBar[0] = new LLResizeBar(
1501 "resizebar_left", 1570 "resizebar_left",
1571 this,
1502 LLRect( 0, mRect.getHeight(), RESIZE_BAR_THICKNESS, 0), 1572 LLRect( 0, mRect.getHeight(), RESIZE_BAR_THICKNESS, 0),
1503 mMinWidth, mMinHeight, LLResizeBar::LEFT ); 1573 mMinWidth, S32_MAX, LLResizeBar::LEFT );
1504 addChild( mResizeBar[0] ); 1574 addChild( mResizeBar[0] );
1505 1575
1506 mResizeBar[1] = new LLResizeBar( 1576 mResizeBar[1] = new LLResizeBar(
1507 "resizebar_top", 1577 "resizebar_top",
1578 this,
1508 LLRect( 0, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_BAR_THICKNESS), 1579 LLRect( 0, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_BAR_THICKNESS),
1509 mMinWidth, mMinHeight, LLResizeBar::TOP ); 1580 mMinHeight, S32_MAX, LLResizeBar::TOP );
1510 addChild( mResizeBar[1] ); 1581 addChild( mResizeBar[1] );
1511 1582
1512 mResizeBar[2] = new LLResizeBar( 1583 mResizeBar[2] = new LLResizeBar(
1513 "resizebar_right", 1584 "resizebar_right",
1585 this,
1514 LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0), 1586 LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0),
1515 mMinWidth, mMinHeight, LLResizeBar::RIGHT ); 1587 mMinWidth, S32_MAX, LLResizeBar::RIGHT );
1516 addChild( mResizeBar[2] ); 1588 addChild( mResizeBar[2] );
1517 1589
1518 mResizeBar[3] = new LLResizeBar( 1590 mResizeBar[3] = new LLResizeBar(
1519 "resizebar_bottom", 1591 "resizebar_bottom",
1592 this,
1520 LLRect( 0, RESIZE_BAR_THICKNESS, mRect.getWidth(), 0), 1593 LLRect( 0, RESIZE_BAR_THICKNESS, mRect.getWidth(), 0),
1521 mMinWidth, mMinHeight, LLResizeBar::BOTTOM ); 1594 mMinHeight, S32_MAX, LLResizeBar::BOTTOM );
1522 addChild( mResizeBar[3] ); 1595 addChild( mResizeBar[3] );
1523 1596
1524 1597
@@ -1855,7 +1928,7 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF
1855 sibling->getVisible() && 1928 sibling->getVisible() &&
1856 expanded_base_rect.rectInRect(&sibling->getRect())) 1929 expanded_base_rect.rectInRect(&sibling->getRect()))
1857 { 1930 {
1858 base_rect |= sibling->getRect(); 1931 base_rect.unionWith(sibling->getRect());
1859 } 1932 }
1860 } 1933 }
1861 1934
@@ -2550,18 +2623,22 @@ BOOL LLMultiFloater::closeAllFloaters()
2550 return TRUE; //else all tabs were successfully closed... 2623 return TRUE; //else all tabs were successfully closed...
2551} 2624}
2552 2625
2553void LLMultiFloater::growToFit(LLFloater* floaterp, S32 width, S32 height) 2626void LLMultiFloater::growToFit(S32 content_width, S32 content_height)
2554{ 2627{
2555 floater_data_map_t::iterator found_data_it; 2628 S32 new_width = llmax(mRect.getWidth(), content_width + LLPANEL_BORDER_WIDTH * 2);
2556 found_data_it = mFloaterDataMap.find(floaterp->getHandle()); 2629 S32 new_height = llmax(mRect.getHeight(), content_height + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT);
2557 if (found_data_it != mFloaterDataMap.end()) 2630
2631 if (isMinimized())
2558 { 2632 {
2559 // store new width and height with this floater so that it will keep its size when detached 2633 mPreviousRect.setLeftTopAndSize(mPreviousRect.mLeft, mPreviousRect.mTop, new_width, new_height);
2560 found_data_it->second.mWidth = width; 2634 }
2561 found_data_it->second.mHeight = height; 2635 else
2636 {
2637 S32 old_height = mRect.getHeight();
2638 reshape(new_width, new_height);
2639 // keep top left corner in same position
2640 translate(0, old_height - new_height);
2562 } 2641 }
2563
2564 resizeToContents();
2565} 2642}
2566 2643
2567/** 2644/**
@@ -2618,12 +2695,18 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
2618 floaterp->setCanMinimize(FALSE); 2695 floaterp->setCanMinimize(FALSE);
2619 floaterp->setCanResize(FALSE); 2696 floaterp->setCanResize(FALSE);
2620 floaterp->setCanDrag(FALSE); 2697 floaterp->setCanDrag(FALSE);
2698 floaterp->storeRectControl();
2699
2700 if (mAutoResize)
2701 {
2702 growToFit(floater_data.mWidth, floater_data.mHeight);
2703 }
2621 2704
2622 //add the panel, add it to proper maps 2705 //add the panel, add it to proper maps
2623 mTabContainer->addTabPanel(floaterp, floaterp->getTitle(), FALSE, onTabSelected, this, 0, FALSE, insertion_point); 2706 mTabContainer->addTabPanel(floaterp, floaterp->getShortTitle(), FALSE, onTabSelected, this, 0, FALSE, insertion_point);
2624 mFloaterDataMap[floaterp->getHandle()] = floater_data; 2707 mFloaterDataMap[floaterp->getHandle()] = floater_data;
2625 2708
2626 resizeToContents(); 2709 updateResizeLimits();
2627 2710
2628 if ( select_added_floater ) 2711 if ( select_added_floater )
2629 { 2712 {
@@ -2673,7 +2756,6 @@ void LLMultiFloater::showFloater(LLFloater* floaterp)
2673 { 2756 {
2674 addFloater(floaterp, TRUE); 2757 addFloater(floaterp, TRUE);
2675 } 2758 }
2676 setVisibleAndFrontmost();
2677} 2759}
2678 2760
2679void LLMultiFloater::removeFloater(LLFloater* floaterp) 2761void LLMultiFloater::removeFloater(LLFloater* floaterp)
@@ -2696,9 +2778,11 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp)
2696 } 2778 }
2697 mTabContainer->removeTabPanel(floaterp); 2779 mTabContainer->removeTabPanel(floaterp);
2698 floaterp->setBackgroundVisible(TRUE); 2780 floaterp->setBackgroundVisible(TRUE);
2781 floaterp->setCanDrag(TRUE);
2699 floaterp->setHost(NULL); 2782 floaterp->setHost(NULL);
2783 floaterp->applyRectControl();
2700 2784
2701 resizeToContents(); 2785 updateResizeLimits();
2702 2786
2703 tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false); 2787 tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false);
2704} 2788}
@@ -2840,18 +2924,8 @@ BOOL LLMultiFloater::postBuild()
2840 return FALSE; 2924 return FALSE;
2841} 2925}
2842 2926
2843void LLMultiFloater::resizeToContents() 2927void LLMultiFloater::updateResizeLimits()
2844{ 2928{
2845 // we're already in the middle of a reshape, don't interrupt it
2846 floater_data_map_t::iterator floater_it;
2847 S32 new_width = 0;
2848 S32 new_height = 0;
2849 for (floater_it = mFloaterDataMap.begin(); floater_it != mFloaterDataMap.end(); ++floater_it)
2850 {
2851 new_width = llmax(new_width, floater_it->second.mWidth + LLPANEL_BORDER_WIDTH * 2);
2852 new_height = llmax(new_height, floater_it->second.mHeight + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT);
2853 }
2854
2855 S32 new_min_width = 0; 2929 S32 new_min_width = 0;
2856 S32 new_min_height = 0; 2930 S32 new_min_height = 0;
2857 S32 tab_idx; 2931 S32 tab_idx;
@@ -2867,21 +2941,23 @@ void LLMultiFloater::resizeToContents()
2867 setResizeLimits(new_min_width, new_min_height); 2941 setResizeLimits(new_min_width, new_min_height);
2868 2942
2869 S32 cur_height = mRect.getHeight(); 2943 S32 cur_height = mRect.getHeight();
2944 S32 new_width = llmax(mRect.getWidth(), new_min_width);
2945 S32 new_height = llmax(mRect.getHeight(), new_min_height);
2870 2946
2871 if (mAutoResize) 2947 if (isMinimized())
2872 { 2948 {
2873 reshape(new_width, new_height); 2949 mPreviousRect.setLeftTopAndSize(mPreviousRect.mLeft, mPreviousRect.mTop, llmax(mPreviousRect.getWidth(), new_width), llmax(mPreviousRect.getHeight(), new_height));
2874 } 2950 }
2875 else 2951 else
2876 { 2952 {
2877 reshape(llmax(new_min_width, mRect.getWidth()), llmax(new_min_height, mRect.getHeight())); 2953 reshape(new_width, new_height);
2878 }
2879 2954
2880 // make sure upper left corner doesn't move 2955 // make sure upper left corner doesn't move
2881 translate(0, cur_height - mRect.getHeight()); 2956 translate(0, cur_height - mRect.getHeight());
2882 2957
2883 // Try to keep whole view onscreen, don't allow partial offscreen. 2958 // Try to keep whole view onscreen, don't allow partial offscreen.
2884 gFloaterView->adjustToFitScreen(this, FALSE); 2959 gFloaterView->adjustToFitScreen(this, FALSE);
2960 }
2885} 2961}
2886 2962
2887// virtual 2963// virtual
@@ -2937,6 +3013,7 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
2937{ 3013{
2938 LLString name(getName()); 3014 LLString name(getName());
2939 LLString title(getTitle()); 3015 LLString title(getTitle());
3016 LLString short_title(getShortTitle());
2940 LLString rect_control(""); 3017 LLString rect_control("");
2941 BOOL resizable = isResizable(); 3018 BOOL resizable = isResizable();
2942 S32 min_width = getMinWidth(); 3019 S32 min_width = getMinWidth();
@@ -2948,6 +3025,7 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
2948 3025
2949 node->getAttributeString("name", name); 3026 node->getAttributeString("name", name);
2950 node->getAttributeString("title", title); 3027 node->getAttributeString("title", title);
3028 node->getAttributeString("short_title", short_title);
2951 node->getAttributeString("rect_control", rect_control); 3029 node->getAttributeString("rect_control", rect_control);
2952 node->getAttributeBOOL("can_resize", resizable); 3030 node->getAttributeBOOL("can_resize", resizable);
2953 node->getAttributeBOOL("can_minimize", minimizable); 3031 node->getAttributeBOOL("can_minimize", minimizable);
@@ -2974,6 +3052,8 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
2974 minimizable, 3052 minimizable,
2975 close_btn); 3053 close_btn);
2976 3054
3055 setShortTitle(short_title);
3056
2977 BOOL can_tear_off; 3057 BOOL can_tear_off;
2978 if (node->getAttributeBOOL("can_tear_off", can_tear_off)) 3058 if (node->getAttributeBOOL("can_tear_off", can_tear_off))
2979 { 3059 {
@@ -2988,17 +3068,13 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
2988 LLFloater::setFloaterHost((LLMultiFloater*) this); 3068 LLFloater::setFloaterHost((LLMultiFloater*) this);
2989 } 3069 }
2990 3070
2991 LLXMLNodePtr child; 3071 initChildrenXML(node, factory);
2992 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) 3072
2993 {
2994 factory->createWidget(this, child);
2995 }
2996 if (node->hasName("multi_floater")) 3073 if (node->hasName("multi_floater"))
2997 { 3074 {
2998 LLFloater::setFloaterHost(last_host); 3075 LLFloater::setFloaterHost(last_host);
2999 } 3076 }
3000 3077
3001
3002 BOOL result = postBuild(); 3078 BOOL result = postBuild();
3003 3079
3004 if (!result) 3080 if (!result)
@@ -3011,4 +3087,6 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
3011 { 3087 {
3012 this->open(); /* Flawfinder: ignore */ 3088 this->open(); /* Flawfinder: ignore */
3013 } 3089 }
3090
3091 moveResizeHandlesToFront();
3014} 3092}
diff --git a/linden/indra/llui/llfloater.h b/linden/indra/llui/llfloater.h
index 8b610e3..baa192a 100644
--- a/linden/indra/llui/llfloater.h
+++ b/linden/indra/llui/llfloater.h
@@ -143,8 +143,10 @@ public:
143 143
144 void setTitle( const LLString& title ); 144 void setTitle( const LLString& title );
145 const LLString& getTitle() const; 145 const LLString& getTitle() const;
146 void setShortTitle( const LLString& short_title );
147 LLString getShortTitle();
146 virtual void setMinimized(BOOL b); 148 virtual void setMinimized(BOOL b);
147 void moveResizeHandleToFront(); 149 void moveResizeHandlesToFront();
148 void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE); 150 void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE);
149 void addDependentFloater(LLViewHandle dependent_handle, BOOL reposition = TRUE); 151 void addDependentFloater(LLViewHandle dependent_handle, BOOL reposition = TRUE);
150 LLFloater* getDependee() { return (LLFloater*)LLFloater::getFloaterByHandle(mDependeeHandle); } 152 LLFloater* getDependee() { return (LLFloater*)LLFloater::getFloaterByHandle(mDependeeHandle); }
@@ -242,6 +244,7 @@ protected:
242 LLRect mPreviousRect; 244 LLRect mPreviousRect;
243 BOOL mForeground; 245 BOOL mForeground;
244 LLViewHandle mDependeeHandle; 246 LLViewHandle mDependeeHandle;
247 LLString mShortTitle;
245 248
246 BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible. 249 BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible.
247 250
@@ -281,6 +284,10 @@ protected:
281 static handle_map_t sFloaterMap; 284 static handle_map_t sFloaterMap;
282 285
283 std::vector<LLView*> mMinimizedHiddenChildren; 286 std::vector<LLView*> mMinimizedHiddenChildren;
287
288 BOOL mHasBeenDraggedWhileMinimized;
289 S32 mPreviousMinimizedBottom;
290 S32 mPreviousMinimizedLeft;
284}; 291};
285 292
286///////////////////////////////////////////////////////////// 293/////////////////////////////////////////////////////////////
@@ -367,12 +374,11 @@ public:
367 /*virtual*/ void draw(); 374 /*virtual*/ void draw();
368 /*virtual*/ void setVisible(BOOL visible); 375 /*virtual*/ void setVisible(BOOL visible);
369 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); 376 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent);
370
371 /*virtual*/ EWidgetType getWidgetType() const; 377 /*virtual*/ EWidgetType getWidgetType() const;
372 /*virtual*/ LLString getWidgetTag() const; 378 /*virtual*/ LLString getWidgetTag() const;
373 379
374 virtual void setCanResize(BOOL can_resize); 380 virtual void setCanResize(BOOL can_resize);
375 virtual void growToFit(LLFloater* floaterp, S32 width, S32 height); 381 virtual void growToFit(S32 content_width, S32 content_height);
376 virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainerCommon::eInsertionPoint insertion_point = LLTabContainerCommon::END); 382 virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainerCommon::eInsertionPoint insertion_point = LLTabContainerCommon::END);
377 383
378 virtual void showFloater(LLFloater* floaterp); 384 virtual void showFloater(LLFloater* floaterp);
@@ -394,7 +400,7 @@ public:
394 void setTabContainer(LLTabContainerCommon* tab_container) { if (!mTabContainer) mTabContainer = tab_container; } 400 void setTabContainer(LLTabContainerCommon* tab_container) { if (!mTabContainer) mTabContainer = tab_container; }
395 static void onTabSelected(void* userdata, bool); 401 static void onTabSelected(void* userdata, bool);
396 402
397 virtual void resizeToContents(); 403 virtual void updateResizeLimits();
398 404
399protected: 405protected:
400 struct LLFloaterData 406 struct LLFloaterData
diff --git a/linden/indra/llui/llfocusmgr.cpp b/linden/indra/llui/llfocusmgr.cpp
index f79164e..f9f3350 100644
--- a/linden/indra/llui/llfocusmgr.cpp
+++ b/linden/indra/llui/llfocusmgr.cpp
@@ -152,8 +152,7 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, FocusLostCallback on_focu
152 152
153 if (lock) 153 if (lock)
154 { 154 {
155 mLockedView = mKeyboardFocus; 155 lockFocus();
156 mKeyboardLockedFocusLostCallback = on_focus_lost;
157 } 156 }
158} 157}
159 158
@@ -312,6 +311,12 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( LLUICtrl* top_view )
312 } 311 }
313} 312}
314 313
314void LLFocusMgr::lockFocus()
315{
316 mLockedView = mKeyboardFocus;
317 mKeyboardLockedFocusLostCallback = mKeyboardFocusLostCallback;
318}
319
315void LLFocusMgr::unlockFocus() 320void LLFocusMgr::unlockFocus()
316{ 321{
317 mLockedView = NULL; 322 mLockedView = NULL;
diff --git a/linden/indra/llui/llfocusmgr.h b/linden/indra/llui/llfocusmgr.h
index e189945..9b7a84e 100644
--- a/linden/indra/llui/llfocusmgr.h
+++ b/linden/indra/llui/llfocusmgr.h
@@ -81,6 +81,7 @@ public:
81 81
82 // All Three 82 // All Three
83 void releaseFocusIfNeeded( LLView* top_view ); 83 void releaseFocusIfNeeded( LLView* top_view );
84 void lockFocus();
84 void unlockFocus(); 85 void unlockFocus();
85 BOOL focusLocked() { return mLockedView != NULL; } 86 BOOL focusLocked() { return mLockedView != NULL; }
86 87
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h
index e715737..5ff2de7 100644
--- a/linden/indra/llui/lllineeditor.h
+++ b/linden/indra/llui/lllineeditor.h
@@ -127,6 +127,7 @@ public:
127 virtual void setRect(const LLRect& rect); 127 virtual void setRect(const LLRect& rect);
128 virtual BOOL acceptsTextInput() const; 128 virtual BOOL acceptsTextInput() const;
129 virtual void onCommit(); 129 virtual void onCommit();
130 virtual BOOL isDirty() { return ( mText.getString() != mPrevText ); }; // Returns TRUE if the user has changed value at all
130 131
131 // assumes UTF8 text 132 // assumes UTF8 text
132 virtual void setValue(const LLSD& value ); 133 virtual void setValue(const LLSD& value );
diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp
index 9530f26..b0d2d9f 100644
--- a/linden/indra/llui/llmenugl.cpp
+++ b/linden/indra/llui/llmenugl.cpp
@@ -172,6 +172,14 @@ LLXMLNodePtr LLMenuItemGL::getXML(bool save_children) const
172 out << LLKeyboard::stringFromKey(mAcceleratorKey); 172 out << LLKeyboard::stringFromKey(mAcceleratorKey);
173 173
174 node->createChild("shortcut", TRUE)->setStringValue(out.str()); 174 node->createChild("shortcut", TRUE)->setStringValue(out.str());
175
176#ifdef LL_DARWIN
177 // Write in special tag if this key is really a ctrl combination on the Mac
178 if (mAcceleratorMask & MASK_MAC_CONTROL)
179 {
180 node->createChild("useMacCtrl", TRUE)->setBoolValue( TRUE );
181 }
182#endif // LL_DARWIN
175 } 183 }
176 184
177 return node; 185 return node;
@@ -204,7 +212,7 @@ BOOL LLMenuItemGL::handleKey(KEY key, MASK mask, BOOL called_from_parent)
204 212
205BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) 213BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
206{ 214{
207 if( mEnabled && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == mAcceleratorMask) ) 215 if( mEnabled && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) )
208 { 216 {
209 doIt(); 217 doIt();
210 return TRUE; 218 return TRUE;
@@ -236,7 +244,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
236 for (list_it = listp->begin(); list_it != listp->end(); ++list_it) 244 for (list_it = listp->begin(); list_it != listp->end(); ++list_it)
237 { 245 {
238 accelerator = *list_it; 246 accelerator = *list_it;
239 if ((accelerator->mKey == mAcceleratorKey) && (accelerator->mMask == mAcceleratorMask)) 247 if ((accelerator->mKey == mAcceleratorKey) && (accelerator->mMask == (mAcceleratorMask & MASK_NORMALKEYS)))
240 { 248 {
241 249
242 // *NOTE: get calling code to throw up warning or route 250 // *NOTE: get calling code to throw up warning or route
@@ -260,7 +268,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
260 if (accelerator) 268 if (accelerator)
261 { 269 {
262 accelerator->mKey = mAcceleratorKey; 270 accelerator->mKey = mAcceleratorKey;
263 accelerator->mMask = mAcceleratorMask; 271 accelerator->mMask = (mAcceleratorMask & MASK_NORMALKEYS);
264// accelerator->mName = mLabel; 272// accelerator->mName = mLabel;
265 } 273 }
266 listp->push_back(accelerator);//addData(accelerator); 274 listp->push_back(accelerator);//addData(accelerator);
@@ -284,7 +292,16 @@ void LLMenuItemGL::appendAcceleratorString( LLString& st )
284 // Standard Mac names for modifier keys in menu equivalents 292 // Standard Mac names for modifier keys in menu equivalents
285 // We could use the symbol characters, but they only exist in certain fonts. 293 // We could use the symbol characters, but they only exist in certain fonts.
286 if( mAcceleratorMask & MASK_CONTROL ) 294 if( mAcceleratorMask & MASK_CONTROL )
287 st.append( "Cmd-" ); // Symbol would be "\xE2\x8C\x98" 295 {
296 if ( mAcceleratorMask & MASK_MAC_CONTROL )
297 {
298 st.append( "Ctrl-" );
299 }
300 else
301 {
302 st.append( "Cmd-" ); // Symbol would be "\xE2\x8C\x98"
303 }
304 }
288 if( mAcceleratorMask & MASK_ALT ) 305 if( mAcceleratorMask & MASK_ALT )
289 st.append( "Opt-" ); // Symbol would be "\xE2\x8C\xA5" 306 st.append( "Opt-" ); // Symbol would be "\xE2\x8C\xA5"
290 if( mAcceleratorMask & MASK_SHIFT ) 307 if( mAcceleratorMask & MASK_SHIFT )
@@ -299,7 +316,7 @@ void LLMenuItemGL::appendAcceleratorString( LLString& st )
299#endif 316#endif
300 317
301 LLString keystr = LLKeyboard::stringFromKey( mAcceleratorKey ); 318 LLString keystr = LLKeyboard::stringFromKey( mAcceleratorKey );
302 if ((mAcceleratorMask & (MASK_CONTROL|MASK_ALT|MASK_SHIFT)) && 319 if ((mAcceleratorMask & MASK_NORMALKEYS) &&
303 (keystr[0] == '-' || keystr[0] == '=')) 320 (keystr[0] == '-' || keystr[0] == '='))
304 { 321 {
305 st.append( " " ); 322 st.append( " " );
@@ -998,7 +1015,7 @@ void LLMenuItemCallGL::buildDrawLabel( void )
998 1015
999BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask ) 1016BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask )
1000{ 1017{
1001 if( (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == mAcceleratorMask) ) 1018 if( (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) )
1002 { 1019 {
1003 LLPointer<LLEvent> fired_event = new LLEvent(this); 1020 LLPointer<LLEvent> fired_event = new LLEvent(this);
1004 fireEvent(fired_event, "on_build"); 1021 fireEvent(fired_event, "on_build");
@@ -1394,9 +1411,9 @@ void LLMenuItemBranchGL::updateBranchParent(LLView* parentp)
1394 } 1411 }
1395} 1412}
1396 1413
1397void LLMenuItemBranchGL::onVisibilityChange( BOOL curVisibilityIn ) 1414void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility )
1398{ 1415{
1399 if (curVisibilityIn == FALSE && mBranch->getVisible() && !mBranch->getTornOff()) 1416 if (new_visibility == FALSE && !mBranch->getTornOff())
1400 { 1417 {
1401 mBranch->setVisible(FALSE); 1418 mBranch->setVisible(FALSE);
1402 } 1419 }
@@ -1965,10 +1982,23 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory
1965 child->hasName(LL_MENU_ITEM_CHECK_GL_TAG)) 1982 child->hasName(LL_MENU_ITEM_CHECK_GL_TAG))
1966 { 1983 {
1967 MASK mask = 0; 1984 MASK mask = 0;
1985
1986#ifdef LL_DARWIN
1987 // See if this Mac accelerator should really use the ctrl key and not get mapped to cmd
1988 BOOL useMacCtrl = FALSE;
1989 child->getAttributeBOOL("useMacCtrl", useMacCtrl);
1990#endif // LL_DARWIN
1991
1968 LLString shortcut; 1992 LLString shortcut;
1969 child->getAttributeString("shortcut", shortcut); 1993 child->getAttributeString("shortcut", shortcut);
1970 if (shortcut.find("control") != shortcut.npos) 1994 if (shortcut.find("control") != shortcut.npos)
1971 { 1995 {
1996#ifdef LL_DARWIN
1997 if ( useMacCtrl )
1998 {
1999 mask |= MASK_MAC_CONTROL;
2000 }
2001#endif // LL_DARWIN
1972 mask |= MASK_CONTROL; 2002 mask |= MASK_CONTROL;
1973 } 2003 }
1974 if (shortcut.find("alt") != shortcut.npos) 2004 if (shortcut.find("alt") != shortcut.npos)
@@ -2935,6 +2965,12 @@ BOOL LLMenuGL::handleKey( KEY key, MASK mask, BOOL called_from_parent )
2935 2965
2936BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask) 2966BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask)
2937{ 2967{
2968 // don't handle if not enabled
2969 if(!mEnabled)
2970 {
2971 return FALSE;
2972 }
2973
2938 // Pass down even if not visible 2974 // Pass down even if not visible
2939 item_list_t::iterator item_iter; 2975 item_list_t::iterator item_iter;
2940 for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) 2976 for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp
index dfa3f8a..91a327b 100644
--- a/linden/indra/llui/llpanel.cpp
+++ b/linden/indra/llui/llpanel.cpp
@@ -51,9 +51,18 @@
51#include "llviewborder.h" 51#include "llviewborder.h"
52#include "llbutton.h" 52#include "llbutton.h"
53 53
54// LLLayoutStack
55#include "llgl.h"
56#include "llglheaders.h"
57#include "llresizebar.h"
58#include "llcriticaldamp.h"
59
54LLPanel::panel_map_t LLPanel::sPanelMap; 60LLPanel::panel_map_t LLPanel::sPanelMap;
55LLPanel::alert_queue_t LLPanel::sAlertQueue; 61LLPanel::alert_queue_t LLPanel::sAlertQueue;
56 62
63const S32 RESIZE_BAR_OVERLAP = 1;
64const S32 PANEL_STACK_GAP = RESIZE_BAR_HEIGHT;
65
57void LLPanel::init() 66void LLPanel::init()
58{ 67{
59 // mRectControl 68 // mRectControl
@@ -119,13 +128,16 @@ void LLPanel::addBorder(LLViewBorder::EBevel border_bevel,
119 addChild( mBorder ); 128 addChild( mBorder );
120} 129}
121 130
131void LLPanel::removeBorder()
132{
133 delete mBorder;
134 mBorder = NULL;
135}
136
122 137
123LLPanel::~LLPanel() 138LLPanel::~LLPanel()
124{ 139{
125 if( !mRectControl.empty() ) 140 storeRectControl();
126 {
127 LLUI::sConfigGroup->setRect( mRectControl, mRect );
128 }
129 sPanelMap.erase(mViewHandle); 141 sPanelMap.erase(mViewHandle);
130} 142}
131 143
@@ -179,44 +191,41 @@ void LLPanel::setCtrlsEnabled( BOOL b )
179 191
180void LLPanel::draw() 192void LLPanel::draw()
181{ 193{
182 if( getVisible() ) 194 // draw background
195 if( mBgVisible )
183 { 196 {
184 // draw background 197 //RN: I don't see the point of this
185 if( mBgVisible ) 198 S32 left = 0;//LLPANEL_BORDER_WIDTH;
186 { 199 S32 top = mRect.getHeight();// - LLPANEL_BORDER_WIDTH;
187 //RN: I don't see the point of this 200 S32 right = mRect.getWidth();// - LLPANEL_BORDER_WIDTH;
188 S32 left = 0;//LLPANEL_BORDER_WIDTH; 201 S32 bottom = 0;//LLPANEL_BORDER_WIDTH;
189 S32 top = mRect.getHeight();// - LLPANEL_BORDER_WIDTH;
190 S32 right = mRect.getWidth();// - LLPANEL_BORDER_WIDTH;
191 S32 bottom = 0;//LLPANEL_BORDER_WIDTH;
192 202
193 if (mBgOpaque ) 203 if (mBgOpaque )
194 { 204 {
195 gl_rect_2d( left, top, right, bottom, mBgColorOpaque ); 205 gl_rect_2d( left, top, right, bottom, mBgColorOpaque );
196 }
197 else
198 {
199 gl_rect_2d( left, top, right, bottom, mBgColorAlpha );
200 }
201 } 206 }
202 207 else
203 if( mDefaultBtn)
204 { 208 {
205 if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) 209 gl_rect_2d( left, top, right, bottom, mBgColorAlpha );
206 {
207 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
208 BOOL focus_is_child_button = focus_ctrl->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(focus_ctrl)->getCommitOnReturn();
209 // only enable default button when current focus is not a return-capturing button
210 mDefaultBtn->setBorderEnabled(!focus_is_child_button);
211 }
212 else
213 {
214 mDefaultBtn->setBorderEnabled(FALSE);
215 }
216 } 210 }
211 }
217 212
218 LLView::draw(); 213 if( mDefaultBtn)
214 {
215 if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled())
216 {
217 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
218 BOOL focus_is_child_button = focus_ctrl->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast<LLButton *>(focus_ctrl)->getCommitOnReturn();
219 // only enable default button when current focus is not a return-capturing button
220 mDefaultBtn->setBorderEnabled(!focus_is_child_button);
221 }
222 else
223 {
224 mDefaultBtn->setBorderEnabled(FALSE);
225 }
219 } 226 }
227
228 LLView::draw();
220} 229}
221 230
222void LLPanel::refresh() 231void LLPanel::refresh()
@@ -572,7 +581,7 @@ LLXMLNodePtr LLPanel::getXML(bool save_children) const
572 return node; 581 return node;
573} 582}
574 583
575LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parentp, LLUICtrlFactory *factory) 584LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory *factory)
576{ 585{
577 LLString name("panel"); 586 LLString name("panel");
578 node->getAttributeString("name", name); 587 node->getAttributeString("name", name);
@@ -581,11 +590,21 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parentp, LLUICtrlFactory *fa
581 // Fall back on a default panel, if there was no special factory. 590 // Fall back on a default panel, if there was no special factory.
582 if (!panelp) 591 if (!panelp)
583 { 592 {
584 panelp = new LLPanel("tab panel"); 593 LLRect rect;
594 createRect(node, rect, parent, LLRect());
595 panelp = new LLPanel(name, rect);
596 panelp->initPanelXML(node, parent, factory);
597 // preserve panel's width and height, but override the location
598 const LLRect& panelrect = panelp->getRect();
599 S32 w = panelrect.getWidth();
600 S32 h = panelrect.getHeight();
601 rect.setLeftTopAndSize(rect.mLeft, rect.mTop, w, h);
602 panelp->setRect(rect);
603 }
604 else
605 {
606 panelp->initPanelXML(node, parent, factory);
585 } 607 }
586
587 panelp->initPanelXML(node, parentp, factory);
588
589 return panelp; 608 return panelp;
590} 609}
591 610
@@ -597,11 +616,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f
597 616
598 setPanelParameters(node, parent); 617 setPanelParameters(node, parent);
599 618
600 LLXMLNodePtr child; 619 initChildrenXML(node, factory);
601 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
602 {
603 factory->createWidget(this, child);
604 }
605 620
606 LLString xml_filename; 621 LLString xml_filename;
607 node->getAttributeString("filename", xml_filename); 622 node->getAttributeString("filename", xml_filename);
@@ -610,8 +625,16 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f
610 625
611 if (!xml_filename.empty()) 626 if (!xml_filename.empty())
612 { 627 {
628 // Preserve postion of embedded panel but allow panel to dictate width/height
629 LLRect rect(getRect());
613 didPost = factory->buildPanel(this, xml_filename, NULL); 630 didPost = factory->buildPanel(this, xml_filename, NULL);
614 } else { 631 S32 w = getRect().getWidth();
632 S32 h = getRect().getHeight();
633 rect.setLeftTopAndSize(rect.mLeft, rect.mTop, w, h);
634 setRect(rect);
635 }
636 else
637 {
615 didPost = FALSE; 638 didPost = FALSE;
616 } 639 }
617 640
@@ -624,10 +647,32 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f
624 return didPost; 647 return didPost;
625} 648}
626 649
627void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parentp) 650void LLPanel::initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory)
651{
652 LLXMLNodePtr child;
653 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
654 {
655 // look for string declarations for programmatic text
656 if (child->hasName("string"))
657 {
658 LLString string_name;
659 child->getAttributeString("name", string_name);
660 if (!string_name.empty())
661 {
662 mUIStrings[string_name] = LLUIString(child->getTextContents());
663 }
664 }
665 else
666 {
667 factory->createWidget(this, child);
668 }
669 }
670}
671
672void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parent)
628{ 673{
629 /////// Rect, follows, tool_tip, enabled, visible attributes /////// 674 /////// Rect, follows, tool_tip, enabled, visible attributes ///////
630 initFromXML(node, parentp); 675 initFromXML(node, parent);
631 676
632 /////// Border attributes /////// 677 /////// Border attributes ///////
633 BOOL border = FALSE; 678 BOOL border = FALSE;
@@ -652,6 +697,10 @@ void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parentp)
652 697
653 addBorder(bevel_style, border_style, border_thickness); 698 addBorder(bevel_style, border_style, border_thickness);
654 } 699 }
700 else
701 {
702 removeBorder();
703 }
655 704
656 /////// Background attributes /////// 705 /////// Background attributes ///////
657 BOOL background_visible = FALSE; 706 BOOL background_visible = FALSE;
@@ -676,6 +725,30 @@ void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parentp)
676 setLabel(label); 725 setLabel(label);
677} 726}
678 727
728LLString LLPanel::getFormattedUIString(const LLString& name, const LLString::format_map_t& args) const
729{
730 ui_string_map_t::const_iterator found_it = mUIStrings.find(name);
731 if (found_it != mUIStrings.end())
732 {
733 // make a copy as format works in place
734 LLUIString formatted_string = found_it->second;
735 formatted_string.setArgList(args);
736 return formatted_string.getString();
737 }
738 return LLString::null;
739}
740
741LLUIString LLPanel::getUIString(const LLString& name) const
742{
743 ui_string_map_t::const_iterator found_it = mUIStrings.find(name);
744 if (found_it != mUIStrings.end())
745 {
746 return found_it->second;
747 }
748 return LLUIString(LLString::null);
749}
750
751
679void LLPanel::childSetVisible(const LLString& id, bool visible) 752void LLPanel::childSetVisible(const LLString& id, bool visible)
680{ 753{
681 LLView* child = getChildByName(id, true); 754 LLView* child = getChildByName(id, true);
@@ -1065,3 +1138,493 @@ void LLPanel::childDisplayNotFound()
1065 LLAlertDialog::showXml("FloaterNotFound", args); 1138 LLAlertDialog::showXml("FloaterNotFound", args);
1066} 1139}
1067 1140
1141void LLPanel::storeRectControl()
1142{
1143 if( !mRectControl.empty() )
1144 {
1145 LLUI::sConfigGroup->setRect( mRectControl, mRect );
1146 }
1147}
1148
1149
1150//
1151// LLLayoutStack
1152//
1153struct LLLayoutStack::LLEmbeddedPanel
1154{
1155 LLEmbeddedPanel(LLPanel* panelp, eLayoutOrientation orientation, S32 min_width, S32 min_height, BOOL auto_resize) :
1156 mPanel(panelp),
1157 mMinWidth(min_width),
1158 mMinHeight(min_height),
1159 mAutoResize(auto_resize),
1160 mOrientation(orientation),
1161 mVisibleAmt(1.f) // default to fully visible
1162 {
1163 LLResizeBar::Side side = (orientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
1164 LLRect resize_bar_rect = panelp->getRect();
1165
1166 S32 min_dim;
1167 if (orientation == HORIZONTAL)
1168 {
1169 min_dim = mMinHeight;
1170 }
1171 else
1172 {
1173 min_dim = mMinWidth;
1174 }
1175 mResizeBar = new LLResizeBar("resizer", mPanel, LLRect(), min_dim, S32_MAX, side);
1176 mResizeBar->setEnableSnapping(FALSE);
1177 // panels initialized as hidden should not start out partially visible
1178 if (!mPanel->getVisible())
1179 {
1180 mVisibleAmt = 0.f;
1181 }
1182 }
1183
1184 LLPanel* mPanel;
1185 S32 mMinWidth;
1186 S32 mMinHeight;
1187 BOOL mAutoResize;
1188 LLResizeBar* mResizeBar;
1189 eLayoutOrientation mOrientation;
1190 F32 mVisibleAmt;
1191};
1192
1193LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) :
1194 mOrientation(orientation),
1195 mMinWidth(0),
1196 mMinHeight(0)
1197{
1198}
1199
1200LLLayoutStack::~LLLayoutStack()
1201{
1202}
1203
1204void LLLayoutStack::draw()
1205{
1206 updateLayout();
1207 {
1208 // clip if outside nominal bounds
1209 LLLocalClipRect clip(getLocalRect(), mRect.getWidth() > mMinWidth || mRect.getHeight() > mMinHeight);
1210 e_panel_list_t::iterator panel_it;
1211 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
1212 {
1213 LLRect clip_rect = (*panel_it)->mPanel->getRect();
1214 // scale clipping rectangle by visible amount
1215 if (mOrientation == HORIZONTAL)
1216 {
1217 clip_rect.mRight = clip_rect.mLeft + llround(clip_rect.getWidth() * (*panel_it)->mVisibleAmt);
1218 }
1219 else
1220 {
1221 clip_rect.mBottom = clip_rect.mTop - llround(clip_rect.getHeight() * (*panel_it)->mVisibleAmt);
1222 }
1223 LLLocalClipRect clip(clip_rect, (*panel_it)->mVisibleAmt < 1.f);
1224 // only force drawing invisible children if visible amount is non-zero
1225 drawChild((*panel_it)->mPanel, 0, 0, (*panel_it)->mVisibleAmt > 0.f);
1226 }
1227 }
1228}
1229
1230void LLLayoutStack::removeCtrl(LLUICtrl* ctrl)
1231{
1232 LLEmbeddedPanel* embedded_panelp = findEmbeddedPanel((LLPanel*)ctrl);
1233
1234 if (embedded_panelp)
1235 {
1236 mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
1237 delete embedded_panelp;
1238 }
1239
1240 calcMinExtents();
1241
1242 LLView::removeCtrl(ctrl);
1243}
1244
1245void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent)
1246{
1247 LLView::reshape(width, height, called_from_parent);
1248 //updateLayout();
1249}
1250
1251LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const
1252{
1253 LLXMLNodePtr node = LLView::getXML();
1254 return node;
1255}
1256
1257//static
1258LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
1259{
1260 LLString orientation_string("vertical");
1261 node->getAttributeString("orientation", orientation_string);
1262
1263 eLayoutOrientation orientation = VERTICAL;
1264
1265 if (orientation_string == "horizontal")
1266 {
1267 orientation = HORIZONTAL;
1268 }
1269 else if (orientation_string == "vertical")
1270 {
1271 orientation = VERTICAL;
1272 }
1273 else
1274 {
1275 llwarns << "Unknown orientation " << orientation_string << ", using vertical" << llendl;
1276 }
1277
1278 LLLayoutStack* layout_stackp = new LLLayoutStack(orientation);
1279
1280 layout_stackp->initFromXML(node, parent);
1281
1282 LLXMLNodePtr child;
1283 for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
1284 {
1285 if (child->hasName("layout_panel"))
1286 {
1287 S32 min_width = 0;
1288 S32 min_height = 0;
1289 BOOL auto_resize = TRUE;
1290
1291 child->getAttributeS32("min_width", min_width);
1292 child->getAttributeS32("min_height", min_height);
1293 child->getAttributeBOOL("auto_resize", auto_resize);
1294
1295 LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory);
1296 panelp->setFollowsNone();
1297 if (panelp)
1298 {
1299 layout_stackp->addPanel(panelp, min_width, min_height, auto_resize);
1300 }
1301 }
1302 }
1303
1304 return layout_stackp;
1305}
1306
1307S32 LLLayoutStack::getMinWidth()
1308{
1309 return mMinWidth;
1310}
1311
1312S32 LLLayoutStack::getMinHeight()
1313{
1314 return mMinHeight;
1315}
1316
1317void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, S32 index)
1318{
1319 LLEmbeddedPanel* embedded_panel = new LLEmbeddedPanel(panel, mOrientation, min_width, min_height, auto_resize);
1320
1321 mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel);
1322 addChild(panel);
1323 addChild(embedded_panel->mResizeBar);
1324
1325 // bring all resize bars to the front so that they are clickable even over the panels
1326 // with a bit of overlap
1327 for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
1328 {
1329 e_panel_list_t::iterator next_it = panel_it;
1330 ++next_it;
1331
1332 LLResizeBar* resize_barp = (*panel_it)->mResizeBar;
1333 sendChildToFront(resize_barp);
1334 // last resize bar is disabled, since its not between any two panels
1335 if ( next_it == mPanels.end() )
1336 {
1337 resize_barp->setEnabled(FALSE);
1338 }
1339 else
1340 {
1341 resize_barp->setEnabled(TRUE);
1342 }
1343 }
1344
1345 //updateLayout();
1346}
1347
1348void LLLayoutStack::removePanel(LLPanel* panel)
1349{
1350 removeChild(panel);
1351 //updateLayout();
1352}
1353
1354void LLLayoutStack::updateLayout(BOOL force_resize)
1355{
1356 calcMinExtents();
1357
1358 // calculate current extents
1359 S32 cur_width = 0;
1360 S32 cur_height = 0;
1361
1362 const F32 ANIM_OPEN_TIME = 0.02f;
1363 const F32 ANIM_CLOSE_TIME = 0.02f;
1364
1365 e_panel_list_t::iterator panel_it;
1366 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
1367 {
1368 LLPanel* panelp = (*panel_it)->mPanel;
1369 if (panelp->getVisible())
1370 {
1371 (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_OPEN_TIME));
1372 if ((*panel_it)->mVisibleAmt > 0.99f)
1373 {
1374 (*panel_it)->mVisibleAmt = 1.f;
1375 }
1376 }
1377 else // not visible
1378 {
1379 (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
1380 if ((*panel_it)->mVisibleAmt < 0.001f)
1381 {
1382 (*panel_it)->mVisibleAmt = 0.f;
1383 }
1384 }
1385 if (mOrientation == HORIZONTAL)
1386 {
1387 // all panels get expanded to max of all the minimum dimensions
1388 cur_height = llmax(mMinHeight, panelp->getRect().getHeight());
1389 cur_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt);
1390 if (panel_it != mPanels.end())
1391 {
1392 cur_width += PANEL_STACK_GAP;
1393 }
1394 }
1395 else //VERTICAL
1396 {
1397 cur_width = llmax(mMinWidth, panelp->getRect().getWidth());
1398 cur_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt);
1399 if (panel_it != mPanels.end())
1400 {
1401 cur_height += PANEL_STACK_GAP;
1402 }
1403 }
1404 }
1405
1406 S32 num_resizable_panels = 0;
1407 S32 shrink_headroom_available = 0;
1408 S32 shrink_headroom_total = 0;
1409 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
1410 {
1411 // panels that are not fully visible do not count towards shrink headroom
1412 if ((*panel_it)->mVisibleAmt < 1.f)
1413 continue;
1414 // if currently resizing a panel or the panel is flagged as not automatically resizing
1415 // only track total available headroom, but don't use it for automatic resize logic
1416 if ((*panel_it)->mResizeBar->hasMouseCapture() || (!(*panel_it)->mAutoResize && !force_resize))
1417 {
1418 if (mOrientation == HORIZONTAL)
1419 {
1420 shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
1421 }
1422 else //VERTICAL
1423 {
1424 shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
1425 }
1426 }
1427 else
1428 {
1429 num_resizable_panels++;
1430 if (mOrientation == HORIZONTAL)
1431 {
1432 shrink_headroom_available += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
1433 shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
1434 }
1435 else //VERTICAL
1436 {
1437 shrink_headroom_available += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
1438 shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
1439 }
1440 }
1441 }
1442
1443 // positive means panels need to grow, negative means shrink
1444 S32 pixels_to_distribute;
1445 if (mOrientation == HORIZONTAL)
1446 {
1447 pixels_to_distribute = mRect.getWidth() - cur_width;
1448 }
1449 else //VERTICAL
1450 {
1451 pixels_to_distribute = mRect.getHeight() - cur_height;
1452 }
1453
1454 S32 cur_x = 0;
1455 S32 cur_y = mRect.getHeight();
1456
1457 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
1458 {
1459 LLPanel* panelp = (*panel_it)->mPanel;
1460
1461 S32 cur_width = panelp->getRect().getWidth();
1462 S32 cur_height = panelp->getRect().getHeight();
1463 S32 new_width = llmax((*panel_it)->mMinWidth, cur_width);
1464 S32 new_height = llmax((*panel_it)->mMinHeight, cur_height);
1465
1466 S32 delta_size = 0;
1467
1468 // if panel can automatically resize (not animating, and resize flag set)...
1469 if ((*panel_it)->mVisibleAmt == 1.f && (force_resize || (*panel_it)->mAutoResize) && !(*panel_it)->mResizeBar->hasMouseCapture())
1470 {
1471 if (mOrientation == HORIZONTAL)
1472 {
1473 // if we're shrinking
1474 if (pixels_to_distribute < 0)
1475 {
1476 // shrink proportionally to amount over minimum
1477 delta_size = llround((F32)pixels_to_distribute * (F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available);
1478 }
1479 else
1480 {
1481 // grow all elements equally
1482 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
1483 }
1484 new_width = llmax((*panel_it)->mMinWidth, panelp->getRect().getWidth() + delta_size);
1485 }
1486 else
1487 {
1488 new_width = llmax(mMinWidth, mRect.getWidth());
1489 }
1490
1491 if (mOrientation == VERTICAL)
1492 {
1493 if (pixels_to_distribute < 0)
1494 {
1495 // shrink proportionally to amount over minimum
1496 delta_size = llround((F32)pixels_to_distribute * (F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available);
1497 }
1498 else
1499 {
1500 delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
1501 }
1502 new_height = llmax((*panel_it)->mMinHeight, panelp->getRect().getHeight() + delta_size);
1503 }
1504 else
1505 {
1506 new_height = llmax(mMinHeight, mRect.getHeight());
1507 }
1508 }
1509 else // don't resize
1510 {
1511 if (mOrientation == HORIZONTAL)
1512 {
1513 new_height = llmax(mMinHeight, mRect.getHeight());
1514 }
1515 else // VERTICAL
1516 {
1517 new_width = llmax(mMinWidth, mRect.getWidth());
1518 }
1519 }
1520
1521 // adjust running headroom count based on new sizes
1522 shrink_headroom_total += delta_size;
1523
1524 panelp->reshape(new_width, new_height);
1525 panelp->setOrigin(cur_x, cur_y - new_height);
1526
1527 LLRect panel_rect = panelp->getRect();
1528 LLRect resize_bar_rect = panel_rect;
1529 if (mOrientation == HORIZONTAL)
1530 {
1531 resize_bar_rect.mLeft = panel_rect.mRight - RESIZE_BAR_OVERLAP;
1532 resize_bar_rect.mRight = panel_rect.mRight + PANEL_STACK_GAP + RESIZE_BAR_OVERLAP;
1533 }
1534 else
1535 {
1536 resize_bar_rect.mTop = panel_rect.mBottom + RESIZE_BAR_OVERLAP;
1537 resize_bar_rect.mBottom = panel_rect.mBottom - PANEL_STACK_GAP - RESIZE_BAR_OVERLAP;
1538 }
1539 (*panel_it)->mResizeBar->setRect(resize_bar_rect);
1540
1541 if (mOrientation == HORIZONTAL)
1542 {
1543 cur_x += llround(new_width * (*panel_it)->mVisibleAmt) + PANEL_STACK_GAP;
1544 }
1545 else //VERTICAL
1546 {
1547 cur_y -= llround(new_height * (*panel_it)->mVisibleAmt) + PANEL_STACK_GAP;
1548 }
1549 }
1550
1551 // update resize bars with new limits
1552 LLResizeBar* last_resize_bar = NULL;
1553 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
1554 {
1555 LLPanel* panelp = (*panel_it)->mPanel;
1556
1557 if (mOrientation == HORIZONTAL)
1558 {
1559 (*panel_it)->mResizeBar->setResizeLimits((*panel_it)->mMinWidth, (*panel_it)->mMinWidth + shrink_headroom_total);
1560 }
1561 else //VERTICAL
1562 {
1563 (*panel_it)->mResizeBar->setResizeLimits((*panel_it)->mMinHeight, (*panel_it)->mMinHeight + shrink_headroom_total);
1564 }
1565 // hide resize bars for invisible panels
1566 (*panel_it)->mResizeBar->setVisible(panelp->getVisible());
1567 if (panelp->getVisible())
1568 {
1569 last_resize_bar = (*panel_it)->mResizeBar;
1570 }
1571 }
1572
1573 // hide last resize bar as there is nothing past it
1574 if (last_resize_bar)
1575 {
1576 last_resize_bar->setVisible(FALSE);
1577 }
1578
1579 // not enough room to fit existing contents
1580 if (!force_resize &&
1581 ((cur_y != -PANEL_STACK_GAP) || (cur_x != mRect.getWidth() + PANEL_STACK_GAP)))
1582 {
1583 // do another layout pass with all stacked elements contributing
1584 // even those that don't usually resize
1585 llassert_always(force_resize == FALSE);
1586 updateLayout(TRUE);
1587 }
1588}
1589
1590LLLayoutStack::LLEmbeddedPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp)
1591{
1592 e_panel_list_t::iterator panel_it;
1593 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
1594 {
1595 if ((*panel_it)->mPanel == panelp)
1596 {
1597 return *panel_it;
1598 }
1599 }
1600 return NULL;
1601}
1602
1603void LLLayoutStack::calcMinExtents()
1604{
1605 mMinWidth = 0;
1606 mMinHeight = 0;
1607
1608 e_panel_list_t::iterator panel_it;
1609 for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
1610 {
1611 if (mOrientation == HORIZONTAL)
1612 {
1613 mMinHeight = llmax(mMinHeight, (*panel_it)->mMinHeight);
1614 mMinWidth += (*panel_it)->mMinWidth;
1615 if (panel_it != mPanels.begin())
1616 {
1617 mMinWidth += PANEL_STACK_GAP;
1618 }
1619 }
1620 else //VERTICAL
1621 {
1622 mMinWidth = llmax(mMinWidth, (*panel_it)->mMinWidth);
1623 mMinHeight += (*panel_it)->mMinHeight;
1624 if (panel_it != mPanels.begin())
1625 {
1626 mMinHeight += PANEL_STACK_GAP;
1627 }
1628 }
1629 }
1630}
diff --git a/linden/indra/llui/llpanel.h b/linden/indra/llui/llpanel.h
index fea3eee..28c56fa 100644
--- a/linden/indra/llui/llpanel.h
+++ b/linden/indra/llui/llpanel.h
@@ -35,6 +35,7 @@
35#include "llcallbackmap.h" 35#include "llcallbackmap.h"
36#include "lluictrl.h" 36#include "lluictrl.h"
37#include "llviewborder.h" 37#include "llviewborder.h"
38#include "lluistring.h"
38#include "v4color.h" 39#include "v4color.h"
39#include <list> 40#include <list>
40#include <queue> 41#include <queue>
@@ -91,6 +92,8 @@ public:
91 LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE, 92 LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE,
92 S32 border_thickness = LLPANEL_BORDER_WIDTH ); 93 S32 border_thickness = LLPANEL_BORDER_WIDTH );
93 94
95 void removeBorder();
96
94 virtual ~LLPanel(); 97 virtual ~LLPanel();
95 virtual void draw(); 98 virtual void draw();
96 virtual void refresh(); // called in setFocus() 99 virtual void refresh(); // called in setFocus()
@@ -117,6 +120,7 @@ public:
117 LLString getLabel() const { return mLabel; } 120 LLString getLabel() const { return mLabel; }
118 121
119 void setRectControl(const LLString& rect_control) { mRectControl.assign(rect_control); } 122 void setRectControl(const LLString& rect_control) { mRectControl.assign(rect_control); }
123 void storeRectControl();
120 124
121 void setBorderVisible( BOOL b ); 125 void setBorderVisible( BOOL b );
122 126
@@ -136,8 +140,12 @@ public:
136 virtual LLXMLNodePtr getXML(bool save_children = true) const; 140 virtual LLXMLNodePtr getXML(bool save_children = true) const;
137 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 141 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
138 BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 142 BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
143 void initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory);
139 void setPanelParameters(LLXMLNodePtr node, LLView *parentp); 144 void setPanelParameters(LLXMLNodePtr node, LLView *parentp);
140 145
146 LLString getFormattedUIString(const LLString& name, const LLString::format_map_t& args = LLUIString::sNullArgs) const;
147 LLUIString getUIString(const LLString& name) const;
148
141 // ** Wrappers for setting child properties by name ** -TomY 149 // ** Wrappers for setting child properties by name ** -TomY
142 150
143 // Override to set not found list 151 // Override to set not found list
@@ -216,6 +224,8 @@ public:
216 typedef std::queue<LLAlertInfo> alert_queue_t; 224 typedef std::queue<LLAlertInfo> alert_queue_t;
217 static alert_queue_t sAlertQueue; 225 static alert_queue_t sAlertQueue;
218 226
227 typedef std::map<LLString, LLUIString> ui_string_map_t;
228
219private: 229private:
220 // common constructor 230 // common constructor
221 void init(); 231 void init();
@@ -241,6 +251,8 @@ protected:
241 LLString mLabel; 251 LLString mLabel;
242 S32 mLastTabGroup; 252 S32 mLastTabGroup;
243 253
254 ui_string_map_t mUIStrings;
255
244 typedef std::map<LLString, EWidgetType> requirements_map_t; 256 typedef std::map<LLString, EWidgetType> requirements_map_t;
245 requirements_map_t mRequirements; 257 requirements_map_t mRequirements;
246 258
@@ -248,4 +260,50 @@ protected:
248 static panel_map_t sPanelMap; 260 static panel_map_t sPanelMap;
249}; 261};
250 262
263class LLLayoutStack : public LLView
264{
265public:
266 typedef enum e_layout_orientation
267 {
268 HORIZONTAL,
269 VERTICAL
270 } eLayoutOrientation;
271
272 LLLayoutStack(eLayoutOrientation orientation);
273 virtual ~LLLayoutStack();
274
275 /*virtual*/ void draw();
276 /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
277 /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
278 /*virtual*/ void removeCtrl(LLUICtrl* ctrl);
279 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LAYOUT_STACK; }
280 virtual LLString getWidgetTag() const { return LL_LAYOUT_STACK_TAG; }
281
282 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
283
284 S32 getMinWidth();
285 S32 getMinHeight();
286
287 void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, S32 index = S32_MAX);
288 void removePanel(LLPanel* panel);
289 void updateLayout(BOOL force_resize = FALSE);
290
291protected:
292 struct LLEmbeddedPanel;
293
294 LLEmbeddedPanel* findEmbeddedPanel(LLPanel* panelp);
295 void calcMinExtents();
296 S32 getMinStackSize();
297 S32 getCurStackSize();
298
299protected:
300 eLayoutOrientation mOrientation;
301
302 typedef std::vector<LLEmbeddedPanel*> e_panel_list_t;
303 e_panel_list_t mPanels;
304
305 S32 mMinWidth;
306 S32 mMinHeight;
307};
308
251#endif 309#endif
diff --git a/linden/indra/llui/llradiogroup.cpp b/linden/indra/llui/llradiogroup.cpp
index eda54b1..0104998 100644
--- a/linden/indra/llui/llradiogroup.cpp
+++ b/linden/indra/llui/llradiogroup.cpp
@@ -169,7 +169,7 @@ BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
169{ 169{
170 BOOL handled = FALSE; 170 BOOL handled = FALSE;
171 // do any of the tab buttons have keyboard focus? 171 // do any of the tab buttons have keyboard focus?
172 if (getEnabled() && !called_from_parent) 172 if (getEnabled() && !called_from_parent && mask == MASK_NONE)
173 { 173 {
174 switch(key) 174 switch(key)
175 { 175 {
@@ -441,6 +441,69 @@ LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
441 return radio_group; 441 return radio_group;
442} 442}
443 443
444// LLCtrlSelectionInterface functions
445BOOL LLRadioGroup::setCurrentByID( const LLUUID& id )
446{
447 return FALSE;
448}
449
450LLUUID LLRadioGroup::getCurrentID()
451{
452 return LLUUID::null;
453}
454
455BOOL LLRadioGroup::setSelectedByValue(LLSD value, BOOL selected)
456{
457 S32 idx = 0;
458 std::string value_string = value.asString();
459 for (button_list_t::const_iterator iter = mRadioButtons.begin();
460 iter != mRadioButtons.end(); ++iter)
461 {
462 if((*iter)->getName() == value_string)
463 {
464 setSelectedIndex(idx);
465 return TRUE;
466 }
467 idx++;
468 }
469
470 return FALSE;
471}
472
473LLSD LLRadioGroup::getSimpleSelectedValue()
474{
475 return getValue();
476}
477
478BOOL LLRadioGroup::isSelected(LLSD value)
479{
480 S32 idx = 0;
481 std::string value_string = value.asString();
482 for (button_list_t::const_iterator iter = mRadioButtons.begin();
483 iter != mRadioButtons.end(); ++iter)
484 {
485 if((*iter)->getName() == value_string)
486 {
487 if (idx == mSelectedIndex)
488 {
489 return TRUE;
490 }
491 }
492 idx++;
493 }
494 return FALSE;
495}
496
497BOOL LLRadioGroup::operateOnSelection(EOperation op)
498{
499 return FALSE;
500}
501
502BOOL LLRadioGroup::operateOnAll(EOperation op)
503{
504 return FALSE;
505}
506
444 507
445LLRadioCtrl::LLRadioCtrl(const LLString& name, const LLRect& rect, const LLString& label, 508LLRadioCtrl::LLRadioCtrl(const LLString& name, const LLRect& rect, const LLString& label,
446 const LLFontGL* font, void (*commit_callback)(LLUICtrl*, void*), void* callback_userdata) : 509 const LLFontGL* font, void (*commit_callback)(LLUICtrl*, void*), void* callback_userdata) :
@@ -458,3 +521,4 @@ void LLRadioCtrl::setValue(const LLSD& value)
458 LLCheckBoxCtrl::setValue(value); 521 LLCheckBoxCtrl::setValue(value);
459 mButton->setTabStop(value.asBoolean()); 522 mButton->setTabStop(value.asBoolean());
460} 523}
524
diff --git a/linden/indra/llui/llradiogroup.h b/linden/indra/llui/llradiogroup.h
index 0cd5901..3dec41d 100644
--- a/linden/indra/llui/llradiogroup.h
+++ b/linden/indra/llui/llradiogroup.h
@@ -35,6 +35,7 @@
35 35
36#include "lluictrl.h" 36#include "lluictrl.h"
37#include "llcheckboxctrl.h" 37#include "llcheckboxctrl.h"
38#include "llctrlselectioninterface.h"
38 39
39class LLFontGL; 40class LLFontGL;
40 41
@@ -52,7 +53,7 @@ public:
52}; 53};
53 54
54class LLRadioGroup 55class LLRadioGroup
55: public LLUICtrl 56: public LLUICtrl, public LLCtrlSelectionInterface
56{ 57{
57public: 58public:
58 // Build a radio group. The number (0...n-1) of the currently selected 59 // Build a radio group. The number (0...n-1) of the currently selected
@@ -83,7 +84,6 @@ public:
83 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 84 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
84 void setIndexEnabled(S32 index, BOOL enabled); 85 void setIndexEnabled(S32 index, BOOL enabled);
85 86
86 S32 getItemCount() { return mRadioButtons.size(); }
87 // return the index value of the selected item 87 // return the index value of the selected item
88 S32 getSelectedIndex() const; 88 S32 getSelectedIndex() const;
89 89
@@ -107,6 +107,23 @@ public:
107 // button. 107 // button.
108 static void onClickButton(LLUICtrl* radio, void* userdata); 108 static void onClickButton(LLUICtrl* radio, void* userdata);
109 109
110 //========================================================================
111 LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; };
112
113 // LLCtrlSelectionInterface functions
114 /*virtual*/ S32 getItemCount() const { return mRadioButtons.size(); }
115 /*virtual*/ BOOL getCanSelect() const { return TRUE; }
116 /*virtual*/ BOOL selectFirstItem() { return setSelectedIndex(0); }
117 /*virtual*/ BOOL selectNthItem( S32 index ) { return setSelectedIndex(index); }
118 /*virtual*/ S32 getFirstSelectedIndex() { return getSelectedIndex(); }
119 /*virtual*/ BOOL setCurrentByID( const LLUUID& id );
120 /*virtual*/ LLUUID getCurrentID(); // LLUUID::null if no items in menu
121 /*virtual*/ BOOL setSelectedByValue(LLSD value, BOOL selected);
122 /*virtual*/ LLSD getSimpleSelectedValue();
123 /*virtual*/ BOOL isSelected(LLSD value);
124 /*virtual*/ BOOL operateOnSelection(EOperation op);
125 /*virtual*/ BOOL operateOnAll(EOperation op);
126
110protected: 127protected:
111 // protected function shared by the two constructors. 128 // protected function shared by the two constructors.
112 void init(BOOL border); 129 void init(BOOL border);
diff --git a/linden/indra/llui/llresizebar.cpp b/linden/indra/llui/llresizebar.cpp
index 79127a8..f716e8e 100644
--- a/linden/indra/llui/llresizebar.cpp
+++ b/linden/indra/llui/llresizebar.cpp
@@ -38,16 +38,18 @@
38#include "llfocusmgr.h" 38#include "llfocusmgr.h"
39#include "llwindow.h" 39#include "llwindow.h"
40 40
41LLResizeBar::LLResizeBar( const LLString& name, const LLRect& rect, S32 min_width, S32 min_height, Side side ) 41LLResizeBar::LLResizeBar( const LLString& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side )
42 : 42 :
43 LLView( name, rect, TRUE ), 43 LLView( name, rect, TRUE ),
44 mDragLastScreenX( 0 ), 44 mDragLastScreenX( 0 ),
45 mDragLastScreenY( 0 ), 45 mDragLastScreenY( 0 ),
46 mLastMouseScreenX( 0 ), 46 mLastMouseScreenX( 0 ),
47 mLastMouseScreenY( 0 ), 47 mLastMouseScreenY( 0 ),
48 mMinWidth( min_width ), 48 mMinSize( min_size ),
49 mMinHeight( min_height ), 49 mMaxSize( max_size ),
50 mSide( side ) 50 mSide( side ),
51 mSnappingEnabled(TRUE),
52 mResizingView(resizing_view)
51{ 53{
52 // set up some generically good follow code. 54 // set up some generically good follow code.
53 switch( side ) 55 switch( side )
@@ -149,12 +151,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
149 // Make sure the mouse in still over the application. We don't want to make the parent 151 // Make sure the mouse in still over the application. We don't want to make the parent
150 // so big that we can't see the resize handle any more. 152 // so big that we can't see the resize handle any more.
151 LLRect valid_rect = getRootView()->getRect(); 153 LLRect valid_rect = getRootView()->getRect();
152 LLView* resizing_view = getParent();
153 154
154 if( valid_rect.localPointInRect( screen_x, screen_y ) && resizing_view ) 155 if( valid_rect.localPointInRect( screen_x, screen_y ) && mResizingView )
155 { 156 {
156 // Resize the parent 157 // Resize the parent
157 LLRect orig_rect = resizing_view->getRect(); 158 LLRect orig_rect = mResizingView->getRect();
158 LLRect scaled_rect = orig_rect; 159 LLRect scaled_rect = orig_rect;
159 160
160 S32 new_width = orig_rect.getWidth(); 161 S32 new_width = orig_rect.getWidth();
@@ -163,76 +164,63 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
163 switch( mSide ) 164 switch( mSide )
164 { 165 {
165 case LEFT: 166 case LEFT:
166 new_width = orig_rect.getWidth() - delta_x; 167 new_width = llclamp(orig_rect.getWidth() - delta_x, mMinSize, mMaxSize);
167 if( new_width < mMinWidth ) 168 delta_x = orig_rect.getWidth() - new_width;
168 {
169 new_width = mMinWidth;
170 delta_x = orig_rect.getWidth() - mMinWidth;
171 }
172 scaled_rect.translate(delta_x, 0); 169 scaled_rect.translate(delta_x, 0);
173 break; 170 break;
174 171
175 case TOP: 172 case TOP:
176 new_height = orig_rect.getHeight() + delta_y; 173 new_height = llclamp(orig_rect.getHeight() + delta_y, mMinSize, mMaxSize);
177 if( new_height < mMinHeight ) 174 delta_y = new_height - orig_rect.getHeight();
178 {
179 new_height = mMinHeight;
180 delta_y = mMinHeight - orig_rect.getHeight();
181 }
182 break; 175 break;
183 176
184 case RIGHT: 177 case RIGHT:
185 new_width = orig_rect.getWidth() + delta_x; 178 new_width = llclamp(orig_rect.getWidth() + delta_x, mMinSize, mMaxSize);
186 if( new_width < mMinWidth ) 179 delta_x = new_width - orig_rect.getWidth();
187 {
188 new_width = mMinWidth;
189 delta_x = mMinWidth - orig_rect.getWidth();
190 }
191 break; 180 break;
192 181
193 case BOTTOM: 182 case BOTTOM:
194 new_height = orig_rect.getHeight() - delta_y; 183 new_height = llclamp(orig_rect.getHeight() - delta_y, mMinSize, mMaxSize);
195 if( new_height < mMinHeight ) 184 delta_y = orig_rect.getHeight() - new_height;
196 {
197 new_height = mMinHeight;
198 delta_y = orig_rect.getHeight() - mMinHeight;
199 }
200 scaled_rect.translate(0, delta_y); 185 scaled_rect.translate(0, delta_y);
201 break; 186 break;
202 } 187 }
203 188
204 scaled_rect.mTop = scaled_rect.mBottom + new_height; 189 scaled_rect.mTop = scaled_rect.mBottom + new_height;
205 scaled_rect.mRight = scaled_rect.mLeft + new_width; 190 scaled_rect.mRight = scaled_rect.mLeft + new_width;
206 resizing_view->setRect(scaled_rect); 191 mResizingView->setRect(scaled_rect);
207 192
208 LLView* snap_view = NULL; 193 LLView* snap_view = NULL;
209 194
210 switch( mSide ) 195 if (mSnappingEnabled)
211 { 196 {
212 case LEFT: 197 switch( mSide )
213 snap_view = resizing_view->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); 198 {
214 break; 199 case LEFT:
215 case TOP: 200 snap_view = mResizingView->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
216 snap_view = resizing_view->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); 201 break;
217 break; 202 case TOP:
218 case RIGHT: 203 snap_view = mResizingView->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
219 snap_view = resizing_view->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); 204 break;
220 break; 205 case RIGHT:
221 case BOTTOM: 206 snap_view = mResizingView->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
222 snap_view = resizing_view->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); 207 break;
223 break; 208 case BOTTOM:
209 snap_view = mResizingView->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
210 break;
211 }
224 } 212 }
225 213
226 // register "snap" behavior with snapped view 214 // register "snap" behavior with snapped view
227 resizing_view->snappedTo(snap_view); 215 mResizingView->snappedTo(snap_view);
228 216
229 // restore original rectangle so the appropriate changes are detected 217 // restore original rectangle so the appropriate changes are detected
230 resizing_view->setRect(orig_rect); 218 mResizingView->setRect(orig_rect);
231 // change view shape as user operation 219 // change view shape as user operation
232 resizing_view->userSetShape(scaled_rect); 220 mResizingView->userSetShape(scaled_rect);
233 221
234 // update last valid mouse cursor position based on resized view's actual size 222 // update last valid mouse cursor position based on resized view's actual size
235 LLRect new_rect = resizing_view->getRect(); 223 LLRect new_rect = mResizingView->getRect();
236 switch(mSide) 224 switch(mSide)
237 { 225 {
238 case LEFT: 226 case LEFT:
diff --git a/linden/indra/llui/llresizebar.h b/linden/indra/llui/llresizebar.h
index e1fc0f9..d3596ec 100644
--- a/linden/indra/llui/llresizebar.h
+++ b/linden/indra/llui/llresizebar.h
@@ -37,7 +37,7 @@ class LLResizeBar : public LLView
37public: 37public:
38 enum Side { LEFT, TOP, RIGHT, BOTTOM }; 38 enum Side { LEFT, TOP, RIGHT, BOTTOM };
39 39
40 LLResizeBar(const LLString& name, const LLRect& rect, S32 min_width, S32 min_height, Side side ); 40 LLResizeBar(const LLString& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side );
41 41
42 virtual EWidgetType getWidgetType() const; 42 virtual EWidgetType getWidgetType() const;
43 virtual LLString getWidgetTag() const; 43 virtual LLString getWidgetTag() const;
@@ -47,7 +47,8 @@ public:
47 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); 47 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
48 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); 48 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
49 49
50 void setResizeLimits( S32 min_width, S32 min_height ) { mMinWidth = min_width; mMinHeight = min_height; } 50 void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; }
51 void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; }
51 52
52protected: 53protected:
53 S32 mDragLastScreenX; 54 S32 mDragLastScreenX;
@@ -55,9 +56,11 @@ protected:
55 S32 mLastMouseScreenX; 56 S32 mLastMouseScreenX;
56 S32 mLastMouseScreenY; 57 S32 mLastMouseScreenY;
57 LLCoordGL mLastMouseDir; 58 LLCoordGL mLastMouseDir;
58 S32 mMinWidth; 59 S32 mMinSize;
59 S32 mMinHeight; 60 S32 mMaxSize;
60 Side mSide; 61 Side mSide;
62 BOOL mSnappingEnabled;
63 LLView* mResizingView;
61}; 64};
62 65
63const S32 RESIZE_BAR_HEIGHT = 3; 66const S32 RESIZE_BAR_HEIGHT = 3;
diff --git a/linden/indra/llui/llresmgr.cpp b/linden/indra/llui/llresmgr.cpp
index 2350093..5ed2cb3 100644
--- a/linden/indra/llui/llresmgr.cpp
+++ b/linden/indra/llui/llresmgr.cpp
@@ -440,6 +440,9 @@ const LLString LLLocale::SYSTEM_LOCALE("English_United States.1252");
440#elif LL_DARWIN 440#elif LL_DARWIN
441const LLString LLLocale::USER_LOCALE("en_US.iso8859-1");// = LLString::null; 441const LLString LLLocale::USER_LOCALE("en_US.iso8859-1");// = LLString::null;
442const LLString LLLocale::SYSTEM_LOCALE("en_US.iso8859-1"); 442const LLString LLLocale::SYSTEM_LOCALE("en_US.iso8859-1");
443#elif LL_SOLARIS
444const LLString LLLocale::USER_LOCALE("en_US.ISO8859-1");
445const LLString LLLocale::SYSTEM_LOCALE("C");
443#else // LL_LINUX likes this 446#else // LL_LINUX likes this
444const LLString LLLocale::USER_LOCALE("en_US.utf8"); 447const LLString LLLocale::USER_LOCALE("en_US.utf8");
445const LLString LLLocale::SYSTEM_LOCALE("C"); 448const LLString LLLocale::SYSTEM_LOCALE("C");
diff --git a/linden/indra/llui/llscrollcontainer.cpp b/linden/indra/llui/llscrollcontainer.cpp
index be41aa8..b910964 100644
--- a/linden/indra/llui/llscrollcontainer.cpp
+++ b/linden/indra/llui/llscrollcontainer.cpp
@@ -505,8 +505,7 @@ void LLScrollableContainerView::draw()
505 BOOL show_h_scrollbar = FALSE; 505 BOOL show_h_scrollbar = FALSE;
506 calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); 506 calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
507 507
508 LLGLEnable scissor_test(GL_SCISSOR_TEST); 508 LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
509 LLUI::setScissorRegionLocal(LLRect(mInnerRect.mLeft,
510 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height, 509 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height,
511 visible_width, 510 visible_width,
512 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) 511 mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0)
diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp
index 5571d39..56a6a22 100644
--- a/linden/indra/llui/llscrolllistctrl.cpp
+++ b/linden/indra/llui/llscrolllistctrl.cpp
@@ -51,7 +51,7 @@
51#include "llkeyboard.h" 51#include "llkeyboard.h"
52#include "llresizebar.h" 52#include "llresizebar.h"
53 53
54const S32 LIST_BORDER_PAD = 2; // white space inside the border and to the left of the scrollbar 54const S32 LIST_BORDER_PAD = 0; // white space inside the border and to the left of the scrollbar
55const S32 MIN_COLUMN_WIDTH = 20; 55const S32 MIN_COLUMN_WIDTH = 20;
56const S32 LIST_SNAP_PADDING = 5; 56const S32 LIST_SNAP_PADDING = 5;
57 57
@@ -417,6 +417,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect,
417 mCommitOnKeyboardMovement(TRUE), 417 mCommitOnKeyboardMovement(TRUE),
418 mCommitOnSelectionChange(FALSE), 418 mCommitOnSelectionChange(FALSE),
419 mSelectionChanged(FALSE), 419 mSelectionChanged(FALSE),
420 mNeedsScroll(FALSE),
420 mCanSelect(TRUE), 421 mCanSelect(TRUE),
421 mDisplayColumnHeaders(FALSE), 422 mDisplayColumnHeaders(FALSE),
422 mCollapseEmptyColumns(FALSE), 423 mCollapseEmptyColumns(FALSE),
@@ -1439,14 +1440,16 @@ void LLScrollListCtrl::drawItems()
1439 S32 x = mItemListRect.mLeft; 1440 S32 x = mItemListRect.mLeft;
1440 S32 y = mItemListRect.mTop - mLineHeight; 1441 S32 y = mItemListRect.mTop - mLineHeight;
1441 1442
1442 S32 num_page_lines = mPageLines; 1443 // allow for partial line at bottom
1444 S32 num_page_lines = mPageLines + 1;
1443 1445
1444 LLRect item_rect; 1446 LLRect item_rect;
1445 1447
1446 LLGLSUIDefault gls_ui; 1448 LLGLSUIDefault gls_ui;
1447 1449
1448 { 1450 {
1449 1451 LLLocalClipRect clip(mItemListRect);
1452
1450 S32 cur_x = x; 1453 S32 cur_x = x;
1451 S32 cur_y = y; 1454 S32 cur_y = y;
1452 1455
@@ -1558,6 +1561,11 @@ void LLScrollListCtrl::draw()
1558{ 1561{
1559 if( getVisible() ) 1562 if( getVisible() )
1560 { 1563 {
1564 if (mNeedsScroll)
1565 {
1566 scrollToShowSelected();
1567 mNeedsScroll = FALSE;
1568 }
1561 LLRect background(0, mRect.getHeight(), mRect.getWidth(), 0); 1569 LLRect background(0, mRect.getHeight(), mRect.getWidth(), 0);
1562 // Draw background 1570 // Draw background
1563 if (mBackgroundVisible) 1571 if (mBackgroundVisible)
@@ -1710,6 +1718,7 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
1710 1718
1711 gFocusMgr.setMouseCapture(this); 1719 gFocusMgr.setMouseCapture(this);
1712 selectItemAt(x, y, mask); 1720 selectItemAt(x, y, mask);
1721 mNeedsScroll = TRUE;
1713 } 1722 }
1714 1723
1715 return TRUE; 1724 return TRUE;
@@ -1719,17 +1728,16 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
1719{ 1728{
1720 if (hasMouseCapture()) 1729 if (hasMouseCapture())
1721 { 1730 {
1731 // release mouse capture immediately so
1732 // scroll to show selected logic will work
1733 gFocusMgr.setMouseCapture(NULL);
1722 if(mask == MASK_NONE) 1734 if(mask == MASK_NONE)
1723 { 1735 {
1724 selectItemAt(x, y, mask); 1736 selectItemAt(x, y, mask);
1737 mNeedsScroll = TRUE;
1725 } 1738 }
1726 } 1739 }
1727 1740
1728 if (hasMouseCapture())
1729 {
1730 gFocusMgr.setMouseCapture(NULL);
1731 }
1732
1733 // always commit when mouse operation is completed inside list 1741 // always commit when mouse operation is completed inside list
1734 if (mItemListRect.pointInRect(x,y)) 1742 if (mItemListRect.pointInRect(x,y))
1735 { 1743 {
@@ -1770,7 +1778,8 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y )
1770 mItemListRect.getWidth(), 1778 mItemListRect.getWidth(),
1771 mLineHeight ); 1779 mLineHeight );
1772 1780
1773 int num_page_lines = mPageLines; 1781 // allow for partial line at bottom
1782 S32 num_page_lines = mPageLines + 1;
1774 1783
1775 S32 line = 0; 1784 S32 line = 0;
1776 item_list::iterator iter; 1785 item_list::iterator iter;
@@ -1803,6 +1812,7 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
1803 if(mask == MASK_NONE) 1812 if(mask == MASK_NONE)
1804 { 1813 {
1805 selectItemAt(x, y, mask); 1814 selectItemAt(x, y, mask);
1815 mNeedsScroll = TRUE;
1806 } 1816 }
1807 } 1817 }
1808 else if (mCanSelect) 1818 else if (mCanSelect)
@@ -1850,7 +1860,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent
1850 { 1860 {
1851 // commit implicit in call 1861 // commit implicit in call
1852 selectPrevItem(FALSE); 1862 selectPrevItem(FALSE);
1853 scrollToShowSelected(); 1863 mNeedsScroll = TRUE;
1854 handled = TRUE; 1864 handled = TRUE;
1855 } 1865 }
1856 break; 1866 break;
@@ -1859,7 +1869,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent
1859 { 1869 {
1860 // commit implicit in call 1870 // commit implicit in call
1861 selectNextItem(FALSE); 1871 selectNextItem(FALSE);
1862 scrollToShowSelected(); 1872 mNeedsScroll = TRUE;
1863 handled = TRUE; 1873 handled = TRUE;
1864 } 1874 }
1865 break; 1875 break;
@@ -1867,7 +1877,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent
1867 if (mAllowKeyboardMovement || hasFocus()) 1877 if (mAllowKeyboardMovement || hasFocus())
1868 { 1878 {
1869 selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1)); 1879 selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1));
1870 scrollToShowSelected(); 1880 mNeedsScroll = TRUE;
1871 if (mCommitOnKeyboardMovement 1881 if (mCommitOnKeyboardMovement
1872 && !mCommitOnSelectionChange) 1882 && !mCommitOnSelectionChange)
1873 { 1883 {
@@ -1880,7 +1890,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent
1880 if (mAllowKeyboardMovement || hasFocus()) 1890 if (mAllowKeyboardMovement || hasFocus())
1881 { 1891 {
1882 selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1)); 1892 selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1));
1883 scrollToShowSelected(); 1893 mNeedsScroll = TRUE;
1884 if (mCommitOnKeyboardMovement 1894 if (mCommitOnKeyboardMovement
1885 && !mCommitOnSelectionChange) 1895 && !mCommitOnSelectionChange)
1886 { 1896 {
@@ -1893,7 +1903,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent
1893 if (mAllowKeyboardMovement || hasFocus()) 1903 if (mAllowKeyboardMovement || hasFocus())
1894 { 1904 {
1895 selectFirstItem(); 1905 selectFirstItem();
1896 scrollToShowSelected(); 1906 mNeedsScroll = TRUE;
1897 if (mCommitOnKeyboardMovement 1907 if (mCommitOnKeyboardMovement
1898 && !mCommitOnSelectionChange) 1908 && !mCommitOnSelectionChange)
1899 { 1909 {
@@ -1906,7 +1916,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent
1906 if (mAllowKeyboardMovement || hasFocus()) 1916 if (mAllowKeyboardMovement || hasFocus())
1907 { 1917 {
1908 selectNthItem(getItemCount() - 1); 1918 selectNthItem(getItemCount() - 1);
1909 scrollToShowSelected(); 1919 mNeedsScroll = TRUE;
1910 if (mCommitOnKeyboardMovement 1920 if (mCommitOnKeyboardMovement
1911 && !mCommitOnSelectionChange) 1921 && !mCommitOnSelectionChange)
1912 { 1922 {
@@ -1945,6 +1955,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask, BOOL called_from_parent
1945 } 1955 }
1946 else if (selectSimpleItemByPrefix(wstring_to_utf8str(mSearchString), FALSE)) 1956 else if (selectSimpleItemByPrefix(wstring_to_utf8str(mSearchString), FALSE))
1947 { 1957 {
1958 mNeedsScroll = TRUE;
1948 // update search string only on successful match 1959 // update search string only on successful match
1949 mSearchTimer.reset(); 1960 mSearchTimer.reset();
1950 1961
@@ -1984,6 +1995,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_
1984 if (selectSimpleItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE)) 1995 if (selectSimpleItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE))
1985 { 1996 {
1986 // update search string only on successful match 1997 // update search string only on successful match
1998 mNeedsScroll = TRUE;
1987 mSearchString += uni_char; 1999 mSearchString += uni_char;
1988 mSearchTimer.reset(); 2000 mSearchTimer.reset();
1989 2001
@@ -2029,6 +2041,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_
2029 if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) 2041 if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char)
2030 { 2042 {
2031 selectItem(item); 2043 selectItem(item);
2044 mNeedsScroll = TRUE;
2032 cellp->highlightText(0, 1); 2045 cellp->highlightText(0, 1);
2033 mSearchTimer.reset(); 2046 mSearchTimer.reset();
2034 2047
@@ -2050,8 +2063,6 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_
2050 } 2063 }
2051 } 2064 }
2052 2065
2053 // make sure selected item is on screen
2054 scrollToShowSelected();
2055 return TRUE; 2066 return TRUE;
2056} 2067}
2057 2068
@@ -2203,6 +2214,13 @@ void LLScrollListCtrl::setScrollPos( S32 pos )
2203 2214
2204void LLScrollListCtrl::scrollToShowSelected() 2215void LLScrollListCtrl::scrollToShowSelected()
2205{ 2216{
2217 // don't scroll automatically when capturing mouse input
2218 // as that will change what is currently under the mouse cursor
2219 if (hasMouseCapture())
2220 {
2221 return;
2222 }
2223
2206 S32 index = getFirstSelectedIndex(); 2224 S32 index = getFirstSelectedIndex();
2207 if (index < 0) 2225 if (index < 0)
2208 { 2226 {
@@ -3033,8 +3051,9 @@ LLColumnHeader::LLColumnHeader(const LLString& label, const LLRect &rect, LLScro
3033 const S32 RESIZE_BAR_THICKNESS = 3; 3051 const S32 RESIZE_BAR_THICKNESS = 3;
3034 mResizeBar = new LLResizeBar( 3052 mResizeBar = new LLResizeBar(
3035 "resizebar", 3053 "resizebar",
3054 this,
3036 LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0), 3055 LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0),
3037 MIN_COLUMN_WIDTH, mRect.getHeight(), LLResizeBar::RIGHT ); 3056 MIN_COLUMN_WIDTH, S32_MAX, LLResizeBar::RIGHT );
3038 addChild(mResizeBar); 3057 addChild(mResizeBar);
3039 3058
3040 mResizeBar->setEnabled(FALSE); 3059 mResizeBar->setEnabled(FALSE);
diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h
index f1bd9bb..809c528 100644
--- a/linden/indra/llui/llscrolllistctrl.h
+++ b/linden/indra/llui/llscrolllistctrl.h
@@ -605,6 +605,7 @@ protected:
605 BOOL mCommitOnKeyboardMovement; 605 BOOL mCommitOnKeyboardMovement;
606 BOOL mCommitOnSelectionChange; 606 BOOL mCommitOnSelectionChange;
607 BOOL mSelectionChanged; 607 BOOL mSelectionChanged;
608 BOOL mNeedsScroll;
608 BOOL mCanSelect; 609 BOOL mCanSelect;
609 BOOL mDisplayColumnHeaders; 610 BOOL mDisplayColumnHeaders;
610 BOOL mCollapseEmptyColumns; 611 BOOL mCollapseEmptyColumns;
diff --git a/linden/indra/llui/llslider.cpp b/linden/indra/llui/llslider.cpp
index 8c0d2a1..e3a3153 100644
--- a/linden/indra/llui/llslider.cpp
+++ b/linden/indra/llui/llslider.cpp
@@ -50,6 +50,7 @@ LLSlider::LLSlider(
50 F32 min_value, 50 F32 min_value,
51 F32 max_value, 51 F32 max_value,
52 F32 increment, 52 F32 increment,
53 BOOL volume,
53 const LLString& control_name) 54 const LLString& control_name)
54 : 55 :
55 LLUICtrl( name, rect, TRUE, on_commit_callback, callback_userdata, 56 LLUICtrl( name, rect, TRUE, on_commit_callback, callback_userdata,
@@ -59,6 +60,7 @@ LLSlider::LLSlider(
59 mMinValue( min_value ), 60 mMinValue( min_value ),
60 mMaxValue( max_value ), 61 mMaxValue( max_value ),
61 mIncrement( increment ), 62 mIncrement( increment ),
63 mVolumeSlider( volume ),
62 mMouseOffset( 0 ), 64 mMouseOffset( 0 ),
63 mDragStartThumbRect( 0, mRect.getHeight(), THUMB_WIDTH, 0 ), 65 mDragStartThumbRect( 0, mRect.getHeight(), THUMB_WIDTH, 0 ),
64 mThumbRect( 0, mRect.getHeight(), THUMB_WIDTH, 0 ), 66 mThumbRect( 0, mRect.getHeight(), THUMB_WIDTH, 0 ),
@@ -69,7 +71,7 @@ LLSlider::LLSlider(
69 mMouseDownCallback( NULL ), 71 mMouseDownCallback( NULL ),
70 mMouseUpCallback( NULL ) 72 mMouseUpCallback( NULL )
71{ 73{
72 // prperly handle setting the starting thumb rect 74 // properly handle setting the starting thumb rect
73 // do it this way to handle both the operating-on-settings 75 // do it this way to handle both the operating-on-settings
74 // and standalone ways of using this 76 // and standalone ways of using this
75 setControlName(control_name, NULL); 77 setControlName(control_name, NULL);
@@ -94,13 +96,15 @@ void LLSlider::setValue(F32 value, BOOL from_event)
94 value -= mMinValue; 96 value -= mMinValue;
95 value += mIncrement/2.0001f; 97 value += mIncrement/2.0001f;
96 value -= fmod(value, mIncrement); 98 value -= fmod(value, mIncrement);
97 mValue = mMinValue + value; 99 value += mMinValue;
98 100
99 if (!from_event) 101 if (!from_event && mValue != value)
100 { 102 {
101 setControlValue(mValue); 103 setControlValue(value);
102 } 104 }
103 105
106 mValue = value;
107
104 F32 t = (mValue - mMinValue) / (mMaxValue - mMinValue); 108 F32 t = (mValue - mMinValue) / (mMaxValue - mMinValue);
105 109
106 S32 left_edge = THUMB_WIDTH/2; 110 S32 left_edge = THUMB_WIDTH/2;
@@ -111,6 +115,18 @@ void LLSlider::setValue(F32 value, BOOL from_event)
111 mThumbRect.mRight = x + (THUMB_WIDTH/2); 115 mThumbRect.mRight = x + (THUMB_WIDTH/2);
112} 116}
113 117
118void LLSlider::setValueAndCommit(F32 value)
119{
120 F32 old_value = mValue;
121 setValue(value);
122
123 if (mValue != old_value)
124 {
125 onCommit();
126 }
127}
128
129
114F32 LLSlider::getValueF32() const 130F32 LLSlider::getValueF32() const
115{ 131{
116 return mValue; 132 return mValue;
@@ -127,8 +143,7 @@ BOOL LLSlider::handleHover(S32 x, S32 y, MASK mask)
127 x = llclamp( x, left_edge, right_edge ); 143 x = llclamp( x, left_edge, right_edge );
128 144
129 F32 t = F32(x - left_edge) / (right_edge - left_edge); 145 F32 t = F32(x - left_edge) / (right_edge - left_edge);
130 setValue(t * (mMaxValue - mMinValue) + mMinValue ); 146 setValueAndCommit(t * (mMaxValue - mMinValue) + mMinValue );
131 onCommit();
132 147
133 getWindow()->setCursor(UI_CURSOR_ARROW); 148 getWindow()->setCursor(UI_CURSOR_ARROW);
134 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl; 149 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
@@ -178,8 +193,7 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask)
178 193
179 if (MASK_CONTROL & mask) // if CTRL is modifying 194 if (MASK_CONTROL & mask) // if CTRL is modifying
180 { 195 {
181 setValue(mInitialValue); 196 setValueAndCommit(mInitialValue);
182 onCommit();
183 } 197 }
184 else 198 else
185 { 199 {
@@ -216,13 +230,11 @@ BOOL LLSlider::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
216 handled = TRUE; 230 handled = TRUE;
217 break; 231 break;
218 case KEY_LEFT: 232 case KEY_LEFT:
219 setValue(getValueF32() - getIncrement()); 233 setValueAndCommit(getValueF32() - getIncrement());
220 onCommit();
221 handled = TRUE; 234 handled = TRUE;
222 break; 235 break;
223 case KEY_RIGHT: 236 case KEY_RIGHT:
224 setValue(getValueF32() + getIncrement()); 237 setValueAndCommit(getValueF32() + getIncrement());
225 onCommit();
226 handled = TRUE; 238 handled = TRUE;
227 break; 239 break;
228 default: 240 default:
@@ -244,33 +256,93 @@ void LLSlider::draw()
244 LLRect rect(mDragStartThumbRect); 256 LLRect rect(mDragStartThumbRect);
245 257
246 F32 opacity = mEnabled ? 1.f : 0.3f; 258 F32 opacity = mEnabled ? 1.f : 0.3f;
259 LLColor4 center_color = (mThumbCenterColor % opacity);
260 LLColor4 outline_color = (mThumbOutlineColor % opacity);
261 LLColor4 track_color = (mTrackColor % opacity);
247 262
263 LLImageGL* thumb_imagep = NULL;
264
248 // Track 265 // Track
266 if (mVolumeSlider)
267 {
268 LLRect track(0, mRect.getHeight(), mRect.getWidth(), 0);
269
270 track.mBottom += 3;
271 track.mTop -= 1;
272 track.mRight -= 1;
273
274 gl_triangle_2d(track.mLeft, track.mBottom,
275 track.mRight, track.mBottom,
276 track.mRight, track.mTop,
277 center_color,
278 TRUE);
279 gl_triangle_2d(track.mLeft, track.mBottom,
280 track.mRight, track.mBottom,
281 track.mRight, track.mTop,
282 outline_color,
283 FALSE);
284 }
285 else
286 {
287 LLUUID thumb_image_id;
288 thumb_image_id.set(LLUI::sAssetsGroup->getString("rounded_square.tga"));
289 thumb_imagep = LLUI::sImageProvider->getUIImageByID(thumb_image_id);
249 290
250 LLUUID thumb_image_id; 291 S32 height_offset = (mRect.getHeight() - TRACK_HEIGHT) / 2;
251 thumb_image_id.set(LLUI::sAssetsGroup->getString("rounded_square.tga")); 292 LLRect track_rect(0, mRect.getHeight() - height_offset, mRect.getWidth(), height_offset );
252 LLImageGL* thumb_imagep = LLUI::sImageProvider->getUIImageByID(thumb_image_id);
253
254 S32 height_offset = (mRect.getHeight() - TRACK_HEIGHT) / 2;
255 LLRect track_rect(0, mRect.getHeight() - height_offset, mRect.getWidth(), height_offset );
256 293
257 track_rect.stretch(-1); 294 track_rect.stretch(-1);
258 gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 16, 16, track_rect.getWidth(), track_rect.getHeight(), 295 gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 16, 16, track_rect.getWidth(), track_rect.getHeight(),
259 thumb_imagep, mTrackColor % opacity); 296 thumb_imagep, track_color);
260 //gl_rect_2d( track_rect, mThumbOutlineColor % opacity ); 297 }
261 298
299 // Thumb
262 if (!thumb_imagep) 300 if (!thumb_imagep)
263 { 301 {
264 gl_rect_2d(mThumbRect, mThumbCenterColor, TRUE); 302 if (mVolumeSlider)
265 if (hasMouseCapture()) 303 {
304 if (hasMouseCapture())
305 {
306 LLRect rect(mDragStartThumbRect);
307 gl_rect_2d( rect, outline_color );
308 rect.stretch(-1);
309 gl_rect_2d( rect, mThumbCenterColor % 0.3f );
310
311 if (hasFocus())
312 {
313 LLRect thumb_rect = mThumbRect;
314 thumb_rect.stretch(llround(lerp(1.f, 3.f, gFocusMgr.getFocusFlashAmt())));
315 gl_rect_2d(thumb_rect, gFocusMgr.getFocusColor());
316 }
317 gl_rect_2d( mThumbRect, mThumbOutlineColor );
318 }
319 else
320 {
321 if (hasFocus())
322 {
323 LLRect thumb_rect = mThumbRect;
324 thumb_rect.stretch(llround(lerp(1.f, 3.f, gFocusMgr.getFocusFlashAmt())));
325 gl_rect_2d(thumb_rect, gFocusMgr.getFocusColor());
326 }
327 LLRect rect(mThumbRect);
328 gl_rect_2d(rect, outline_color);
329 rect.stretch(-1);
330 gl_rect_2d( rect, center_color);
331 }
332 }
333 else
266 { 334 {
267 gl_rect_2d(mDragStartThumbRect, mThumbCenterColor % opacity, FALSE); 335 gl_rect_2d(mThumbRect, mThumbCenterColor, TRUE);
336 if (hasMouseCapture())
337 {
338 gl_rect_2d(mDragStartThumbRect, center_color, FALSE);
339 }
268 } 340 }
269 } 341 }
270 else if( hasMouseCapture() ) 342 else if( hasMouseCapture() )
271 { 343 {
272 gl_draw_scaled_image_with_border(mDragStartThumbRect.mLeft, mDragStartThumbRect.mBottom, 16, 16, mDragStartThumbRect.getWidth(), mDragStartThumbRect.getHeight(), 344 gl_draw_scaled_image_with_border(mDragStartThumbRect.mLeft, mDragStartThumbRect.mBottom, 16, 16, mDragStartThumbRect.getWidth(), mDragStartThumbRect.getHeight(),
273 thumb_imagep, mThumbCenterColor % 0.3f, TRUE); 345 thumb_imagep, mThumbCenterColor % 0.3f, TRUE);
274 346
275 if (hasFocus()) 347 if (hasFocus())
276 { 348 {
@@ -278,20 +350,12 @@ void LLSlider::draw()
278 LLRect highlight_rect = mThumbRect; 350 LLRect highlight_rect = mThumbRect;
279 highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); 351 highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt)));
280 gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(), 352 gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(),
281 thumb_imagep, gFocusMgr.getFocusColor()); 353 thumb_imagep, gFocusMgr.getFocusColor());
282 } 354 }
283 355
284
285 gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(), 356 gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(),
286 thumb_imagep, mThumbOutlineColor, TRUE); 357 thumb_imagep, mThumbOutlineColor, TRUE);
287
288 //// Start Thumb
289 //gl_rect_2d( mDragStartThumbRect, mThumbOutlineColor % 0.3f );
290 //rect.stretch(-1);
291 //gl_rect_2d( rect, mThumbCenterColor % 0.3f );
292 358
293 //// Thumb
294 //gl_rect_2d( mThumbRect, mThumbOutlineColor );
295 } 359 }
296 else 360 else
297 { 361 {
@@ -301,22 +365,12 @@ void LLSlider::draw()
301 LLRect highlight_rect = mThumbRect; 365 LLRect highlight_rect = mThumbRect;
302 highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); 366 highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt)));
303 gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(), 367 gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(),
304 thumb_imagep, gFocusMgr.getFocusColor()); 368 thumb_imagep, gFocusMgr.getFocusColor());
305 } 369 }
306 370
307 gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(), 371 gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(),
308 thumb_imagep, mThumbCenterColor % opacity, TRUE); 372 thumb_imagep, center_color, TRUE);
309 //rect = mThumbRect;
310
311 //gl_rect_2d( mThumbRect, mThumbOutlineColor % opacity );
312 //
313 //rect.stretch(-1);
314
315 //// Thumb
316 //gl_rect_2d( rect, mThumbCenterColor % opacity );
317
318 } 373 }
319
320 LLUICtrl::draw(); 374 LLUICtrl::draw();
321 } 375 }
322} 376}
@@ -330,6 +384,7 @@ LLXMLNodePtr LLSlider::getXML(bool save_children) const
330 node->createChild("min_val", TRUE)->setFloatValue(getMinValue()); 384 node->createChild("min_val", TRUE)->setFloatValue(getMinValue());
331 node->createChild("max_val", TRUE)->setFloatValue(getMaxValue()); 385 node->createChild("max_val", TRUE)->setFloatValue(getMaxValue());
332 node->createChild("increment", TRUE)->setFloatValue(getIncrement()); 386 node->createChild("increment", TRUE)->setFloatValue(getIncrement());
387 node->createChild("volume", TRUE)->setBoolValue(getVolumeSlider());
333 388
334 return node; 389 return node;
335} 390}
@@ -356,6 +411,8 @@ LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa
356 F32 increment = 0.1f; 411 F32 increment = 0.1f;
357 node->getAttributeF32("increment", increment); 412 node->getAttributeF32("increment", increment);
358 413
414 BOOL volume = node->hasName("volume_slider") ? TRUE : FALSE;
415 node->getAttributeBOOL("volume", volume);
359 416
360 LLSlider* slider = new LLSlider(name, 417 LLSlider* slider = new LLSlider(name,
361 rect, 418 rect,
@@ -364,7 +421,8 @@ LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa
364 initial_value, 421 initial_value,
365 min_value, 422 min_value,
366 max_value, 423 max_value,
367 increment); 424 increment,
425 volume);
368 426
369 slider->initFromXML(node, parent); 427 slider->initFromXML(node, parent);
370 428
diff --git a/linden/indra/llui/llslider.h b/linden/indra/llui/llslider.h
index 4f42a56..8fcd672 100644
--- a/linden/indra/llui/llslider.h
+++ b/linden/indra/llui/llslider.h
@@ -46,6 +46,7 @@ public:
46 F32 min_value, 46 F32 min_value,
47 F32 max_value, 47 F32 max_value,
48 F32 increment, 48 F32 increment,
49 BOOL volume,
49 const LLString& control_name = LLString::null ); 50 const LLString& control_name = LLString::null );
50 51
51 virtual EWidgetType getWidgetType() const; 52 virtual EWidgetType getWidgetType() const;
@@ -66,6 +67,7 @@ public:
66 F32 getMinValue() const { return mMinValue; } 67 F32 getMinValue() const { return mMinValue; }
67 F32 getMaxValue() const { return mMaxValue; } 68 F32 getMaxValue() const { return mMaxValue; }
68 F32 getIncrement() const { return mIncrement; } 69 F32 getIncrement() const { return mIncrement; }
70 BOOL getVolumeSlider() const { return mVolumeSlider; }
69 void setMinValue(F32 min_value) {mMinValue = min_value;} 71 void setMinValue(F32 min_value) {mMinValue = min_value;}
70 void setMaxValue(F32 max_value) {mMaxValue = max_value;} 72 void setMaxValue(F32 max_value) {mMaxValue = max_value;}
71 void setIncrement(F32 increment) {mIncrement = increment;} 73 void setIncrement(F32 increment) {mIncrement = increment;}
@@ -79,12 +81,16 @@ public:
79 virtual void draw(); 81 virtual void draw();
80 82
81protected: 83protected:
84 void setValueAndCommit(F32 value);
85
86protected:
82 F32 mValue; 87 F32 mValue;
83 F32 mInitialValue; 88 F32 mInitialValue;
84 F32 mMinValue; 89 F32 mMinValue;
85 F32 mMaxValue; 90 F32 mMaxValue;
86 F32 mIncrement; 91 F32 mIncrement;
87 92
93 BOOL mVolumeSlider;
88 S32 mMouseOffset; 94 S32 mMouseOffset;
89 LLRect mDragStartThumbRect; 95 LLRect mDragStartThumbRect;
90 96
diff --git a/linden/indra/llui/llsliderctrl.cpp b/linden/indra/llui/llsliderctrl.cpp
index 9a67bca..dff27cc 100644
--- a/linden/indra/llui/llsliderctrl.cpp
+++ b/linden/indra/llui/llsliderctrl.cpp
@@ -57,6 +57,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect,
57 S32 text_left, 57 S32 text_left,
58 BOOL show_text, 58 BOOL show_text,
59 BOOL can_edit_text, 59 BOOL can_edit_text,
60 BOOL volume,
60 void (*commit_callback)(LLUICtrl*, void*), 61 void (*commit_callback)(LLUICtrl*, void*),
61 void* callback_user_data, 62 void* callback_user_data,
62 F32 initial_value, F32 min_value, F32 max_value, F32 increment, 63 F32 initial_value, F32 min_value, F32 max_value, F32 increment,
@@ -65,6 +66,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect,
65 mFont(font), 66 mFont(font),
66 mShowText( show_text ), 67 mShowText( show_text ),
67 mCanEditText( can_edit_text ), 68 mCanEditText( can_edit_text ),
69 mVolumeSlider( volume ),
68 mPrecision( 3 ), 70 mPrecision( 3 ),
69 mLabelBox( NULL ), 71 mLabelBox( NULL ),
70 mLabelWidth( label_width ), 72 mLabelWidth( label_width ),
@@ -104,7 +106,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect,
104 "slider", 106 "slider",
105 slider_rect, 107 slider_rect,
106 LLSliderCtrl::onSliderCommit, this, 108 LLSliderCtrl::onSliderCommit, this,
107 initial_value, min_value, max_value, increment, 109 initial_value, min_value, max_value, increment, volume,
108 control_which ); 110 control_which );
109 addChild( mSlider ); 111 addChild( mSlider );
110 112
@@ -443,6 +445,8 @@ LLXMLNodePtr LLSliderCtrl::getXML(bool save_children) const
443 445
444 node->createChild("can_edit_text", TRUE)->setBoolValue(mCanEditText); 446 node->createChild("can_edit_text", TRUE)->setBoolValue(mCanEditText);
445 447
448 node->createChild("volume", TRUE)->setBoolValue(mVolumeSlider);
449
446 node->createChild("decimal_digits", TRUE)->setIntValue(mPrecision); 450 node->createChild("decimal_digits", TRUE)->setIntValue(mPrecision);
447 451
448 if (mLabelBox) 452 if (mLabelBox)
@@ -494,6 +498,9 @@ LLView* LLSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
494 BOOL can_edit_text = FALSE; 498 BOOL can_edit_text = FALSE;
495 node->getAttributeBOOL("can_edit_text", can_edit_text); 499 node->getAttributeBOOL("can_edit_text", can_edit_text);
496 500
501 BOOL volume = FALSE;
502 node->getAttributeBOOL("volume", volume);
503
497 F32 initial_value = 0.f; 504 F32 initial_value = 0.f;
498 node->getAttributeF32("initial_val", initial_value); 505 node->getAttributeF32("initial_val", initial_value);
499 506
@@ -541,6 +548,7 @@ LLView* LLSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
541 rect.getWidth() - text_left, 548 rect.getWidth() - text_left,
542 show_text, 549 show_text,
543 can_edit_text, 550 can_edit_text,
551 volume,
544 callback, 552 callback,
545 NULL, 553 NULL,
546 initial_value, 554 initial_value,
diff --git a/linden/indra/llui/llsliderctrl.h b/linden/indra/llui/llsliderctrl.h
index 26c9dee..6896360 100644
--- a/linden/indra/llui/llsliderctrl.h
+++ b/linden/indra/llui/llsliderctrl.h
@@ -60,6 +60,7 @@ public:
60 S32 text_left, 60 S32 text_left,
61 BOOL show_text, 61 BOOL show_text,
62 BOOL can_edit_text, 62 BOOL can_edit_text,
63 BOOL volume,
63 void (*commit_callback)(LLUICtrl*, void*), 64 void (*commit_callback)(LLUICtrl*, void*),
64 void* callback_userdata, 65 void* callback_userdata,
65 F32 initial_value, F32 min_value, F32 max_value, F32 increment, 66 F32 initial_value, F32 min_value, F32 max_value, F32 increment,
@@ -124,7 +125,8 @@ private:
124 const LLFontGL* mFont; 125 const LLFontGL* mFont;
125 BOOL mShowText; 126 BOOL mShowText;
126 BOOL mCanEditText; 127 BOOL mCanEditText;
127 128 BOOL mVolumeSlider;
129
128 S32 mPrecision; 130 S32 mPrecision;
129 LLTextBox* mLabelBox; 131 LLTextBox* mLabelBox;
130 S32 mLabelWidth; 132 S32 mLabelWidth;
diff --git a/linden/indra/llui/lltabcontainer.cpp b/linden/indra/llui/lltabcontainer.cpp
index 01c06c3..135931d 100644
--- a/linden/indra/llui/lltabcontainer.cpp
+++ b/linden/indra/llui/lltabcontainer.cpp
@@ -70,6 +70,7 @@ LLTabContainerCommon::LLTabContainerCommon(
70 : 70 :
71 LLPanel(name, rect, bordered), 71 LLPanel(name, rect, bordered),
72 mCurrentTabIdx(-1), 72 mCurrentTabIdx(-1),
73 mTabsHidden(FALSE),
73 mScrolled(FALSE), 74 mScrolled(FALSE),
74 mScrollPos(0), 75 mScrollPos(0),
75 mScrollPosPixels(0), 76 mScrollPosPixels(0),
@@ -95,6 +96,7 @@ LLTabContainerCommon::LLTabContainerCommon(
95 : 96 :
96 LLPanel(name, rect_control, bordered), 97 LLPanel(name, rect_control, bordered),
97 mCurrentTabIdx(-1), 98 mCurrentTabIdx(-1),
99 mTabsHidden(FALSE),
98 mScrolled(FALSE), 100 mScrolled(FALSE),
99 mScrollPos(0), 101 mScrollPos(0),
100 mScrollPosPixels(0), 102 mScrollPosPixels(0),
@@ -147,11 +149,11 @@ void LLTabContainerCommon::addPlaceholder(LLPanel* child, const LLString& label)
147 addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE); 149 addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE);
148} 150}
149 151
150void LLTabContainerCommon::lockTabs() 152void LLTabContainerCommon::lockTabs(S32 num_tabs)
151{ 153{
152 // count current tabs and ensure no new tabs get 154 // count current tabs or use supplied value and ensure no new tabs get
153 // inserted between them 155 // inserted between them
154 mLockedTabCount = getTabCount(); 156 mLockedTabCount = num_tabs > 0 ? num_tabs : getTabCount();
155} 157}
156 158
157void LLTabContainerCommon::removeTabPanel(LLPanel* child) 159void LLTabContainerCommon::removeTabPanel(LLPanel* child)
@@ -542,12 +544,12 @@ void LLTabContainerCommon::setTabPanelFlashing(LLPanel* child, BOOL state )
542 } 544 }
543} 545}
544 546
545void LLTabContainerCommon::setTabImage(LLPanel* child, std::string img_name) 547void LLTabContainerCommon::setTabImage(LLPanel* child, std::string img_name, const LLColor4& color)
546{ 548{
547 LLTabTuple* tuple = getTabByPanel(child); 549 LLTabTuple* tuple = getTabByPanel(child);
548 if( tuple ) 550 if( tuple )
549 { 551 {
550 tuple->mButton->setImageOverlay(img_name, LLFontGL::RIGHT); 552 tuple->mButton->setImageOverlay(img_name, LLFontGL::RIGHT, color);
551 } 553 }
552} 554}
553 555
@@ -667,6 +669,8 @@ LLView* LLTabContainerCommon::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtr
667 } 669 }
668 } 670 }
669 671
672 node->getAttributeBOOL("hide_tabs", tab_container->mTabsHidden);
673
670 tab_container->setPanelParameters(node, parent); 674 tab_container->setPanelParameters(node, parent);
671 675
672 if (LLFloater::getFloaterHost()) 676 if (LLFloater::getFloaterHost())
@@ -1036,10 +1040,11 @@ void LLTabContainer::setPanelTitle(S32 index, const LLString& title)
1036{ 1040{
1037 if (index >= 0 && index < (S32)mTabList.size()) 1041 if (index >= 0 && index < (S32)mTabList.size())
1038 { 1042 {
1039 LLButton* tab_button = mTabList[index]->mButton; 1043 LLTabTuple* tuple = mTabList[index];
1044 LLButton* tab_button = tuple->mButton;
1040 const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); 1045 const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL );
1041 mTotalTabWidth -= tab_button->getRect().getWidth(); 1046 mTotalTabWidth -= tab_button->getRect().getWidth();
1042 tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight()); 1047 tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight());
1043 mTotalTabWidth += tab_button->getRect().getWidth(); 1048 mTotalTabWidth += tab_button->getRect().getWidth();
1044 tab_button->setLabelSelected(title); 1049 tab_button->setLabelSelected(title);
1045 tab_button->setLabelUnselected(title); 1050 tab_button->setLabelUnselected(title);
@@ -1245,63 +1250,60 @@ void LLTabContainer::draw()
1245 1250
1246 LLPanel::draw(); 1251 LLPanel::draw();
1247 1252
1248 // Show all the buttons 1253 // if tabs are hidden, don't draw them and leave them in the invisible state
1249 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) 1254 if (!mTabsHidden)
1250 { 1255 {
1251 LLTabTuple* tuple = *iter; 1256 // Show all the buttons
1252 tuple->mButton->setVisible( TRUE ); 1257 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
1253 } 1258 {
1254 1259 LLTabTuple* tuple = *iter;
1255 // Draw some of the buttons... 1260 tuple->mButton->setVisible( TRUE );
1261 }
1256 1262
1257 LLGLEnable scissor_test(has_scroll_arrows ? GL_SCISSOR_TEST : GL_FALSE); 1263 // Draw some of the buttons...
1258 if( has_scroll_arrows ) 1264 LLRect clip_rect = getLocalRect();
1259 { 1265 if (has_scroll_arrows)
1260 // ...but clip them.
1261 S32 x1 = mLeftArrowBtn->getRect().mRight;
1262 S32 y1 = 0;
1263 S32 x2 = mRightArrowBtn->getRect().mLeft;
1264 S32 y2 = 1;
1265 if (mTabList.size() > 0)
1266 { 1266 {
1267 y2 = mTabList[0]->mButton->getRect().mTop; 1267 // ...but clip them.
1268 clip_rect.mLeft = mLeftArrowBtn->getRect().mRight;
1269 clip_rect.mRight = mRightArrowBtn->getRect().mLeft;
1268 } 1270 }
1269 LLUI::setScissorRegionLocal(LLRect(x1, y2, x2, y1)); 1271 LLLocalClipRect clip(clip_rect);
1270 }
1271 1272
1272 S32 max_scroll_visible = mTabList.size() - mMaxScrollPos + mScrollPos; 1273 S32 max_scroll_visible = mTabList.size() - mMaxScrollPos + mScrollPos;
1273 S32 idx = 0; 1274 S32 idx = 0;
1274 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) 1275 for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
1275 { 1276 {
1276 LLTabTuple* tuple = *iter; 1277 LLTabTuple* tuple = *iter;
1277 1278
1278 tuple->mButton->translate( left - tuple->mButton->getRect().mLeft, 0 ); 1279 tuple->mButton->translate( left - tuple->mButton->getRect().mLeft, 0 );
1279 left += tuple->mButton->getRect().getWidth(); 1280 left += tuple->mButton->getRect().getWidth();
1280 1281
1281 if( idx < mScrollPos ) 1282 if( idx < mScrollPos )
1282 {
1283 if( tuple->mButton->getFlashing() )
1284 { 1283 {
1285 mLeftArrowBtn->setFlashing( TRUE ); 1284 if( tuple->mButton->getFlashing() )
1285 {
1286 mLeftArrowBtn->setFlashing( TRUE );
1287 }
1286 } 1288 }
1287 } 1289 else
1288 else 1290 if( max_scroll_visible < idx )
1289 if( max_scroll_visible < idx )
1290 {
1291 if( tuple->mButton->getFlashing() )
1292 { 1291 {
1293 mRightArrowBtn->setFlashing( TRUE ); 1292 if( tuple->mButton->getFlashing() )
1293 {
1294 mRightArrowBtn->setFlashing( TRUE );
1295 }
1294 } 1296 }
1295 }
1296 1297
1297 LLUI::pushMatrix(); 1298 LLUI::pushMatrix();
1298 { 1299 {
1299 LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f); 1300 LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f);
1300 tuple->mButton->draw(); 1301 tuple->mButton->draw();
1302 }
1303 LLUI::popMatrix();
1304
1305 idx++;
1301 } 1306 }
1302 LLUI::popMatrix();
1303
1304 idx++;
1305 } 1307 }
1306 1308
1307 mLeftArrowBtn->setFlashing(FALSE); 1309 mLeftArrowBtn->setFlashing(FALSE);
@@ -1628,12 +1630,12 @@ BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDrag
1628 return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip); 1630 return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip);
1629} 1631}
1630 1632
1631void LLTabContainer::setTabImage(LLPanel* child, std::string image_name) 1633void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color)
1632{ 1634{
1633 LLTabTuple* tuple = getTabByPanel(child); 1635 LLTabTuple* tuple = getTabByPanel(child);
1634 if( tuple ) 1636 if( tuple )
1635 { 1637 {
1636 tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT); 1638 tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT, color);
1637 1639
1638 const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); 1640 const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL );
1639 // remove current width from total tab strip width 1641 // remove current width from total tab strip width
@@ -1642,7 +1644,11 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name)
1642 S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? 1644 S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ?
1643 tuple->mButton->getImageOverlay()->getWidth(0) : 1645 tuple->mButton->getImageOverlay()->getWidth(0) :
1644 0; 1646 0;
1645 tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + image_overlay_width, mMinTabWidth, mMaxTabWidth), 1647
1648 tuple->mPadding = image_overlay_width;
1649
1650 tuple->mButton->setRightHPad(tuple->mPadding + LLBUTTON_H_PAD);
1651 tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth),
1646 tuple->mButton->getRect().getHeight()); 1652 tuple->mButton->getRect().getHeight());
1647 // add back in button width to total tab strip width 1653 // add back in button width to total tab strip width
1648 mTotalTabWidth += tuple->mButton->getRect().getWidth(); 1654 mTotalTabWidth += tuple->mButton->getRect().getWidth();
diff --git a/linden/indra/llui/lltabcontainer.h b/linden/indra/llui/lltabcontainer.h
index f3365c3..3056c0a 100644
--- a/linden/indra/llui/lltabcontainer.h
+++ b/linden/indra/llui/lltabcontainer.h
@@ -87,7 +87,7 @@ public:
87 BOOL placeholder = FALSE, 87 BOOL placeholder = FALSE,
88 eInsertionPoint insertion_point = END) = 0; 88 eInsertionPoint insertion_point = END) = 0;
89 virtual void addPlaceholder(LLPanel* child, const LLString& label); 89 virtual void addPlaceholder(LLPanel* child, const LLString& label);
90 virtual void lockTabs(); 90 virtual void lockTabs(S32 num_tabs = 0);
91 91
92 virtual void enableTabButton(S32 which, BOOL enable); 92 virtual void enableTabButton(S32 which, BOOL enable);
93 93
@@ -114,7 +114,7 @@ public:
114 114
115 BOOL getTabPanelFlashing(LLPanel* child); 115 BOOL getTabPanelFlashing(LLPanel* child);
116 void setTabPanelFlashing(LLPanel* child, BOOL state); 116 void setTabPanelFlashing(LLPanel* child, BOOL state);
117 virtual void setTabImage(LLPanel* child, std::string img_name); 117 virtual void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white);
118 void setTitle( const LLString& title ); 118 void setTitle( const LLString& title );
119 const LLString getPanelTitle(S32 index); 119 const LLString getPanelTitle(S32 index);
120 120
@@ -155,7 +155,8 @@ protected:
155 mOnChangeCallback( cb ), 155 mOnChangeCallback( cb ),
156 mUserData( userdata ), 156 mUserData( userdata ),
157 mOldState(FALSE), 157 mOldState(FALSE),
158 mPlaceholderText(placeholder) 158 mPlaceholderText(placeholder),
159 mPadding(0)
159 {} 160 {}
160 161
161 LLTabContainerCommon* mTabContainer; 162 LLTabContainerCommon* mTabContainer;
@@ -165,11 +166,13 @@ protected:
165 void* mUserData; 166 void* mUserData;
166 BOOL mOldState; 167 BOOL mOldState;
167 LLTextBox* mPlaceholderText; 168 LLTextBox* mPlaceholderText;
169 S32 mPadding;
168 }; 170 };
169 171
170 typedef std::vector<LLTabTuple*> tuple_list_t; 172 typedef std::vector<LLTabTuple*> tuple_list_t;
171 tuple_list_t mTabList; 173 tuple_list_t mTabList;
172 S32 mCurrentTabIdx; 174 S32 mCurrentTabIdx;
175 BOOL mTabsHidden;
173 176
174 BOOL mScrolled; 177 BOOL mScrolled;
175 LLFrameTimer mScrollTimer; 178 LLFrameTimer mScrollTimer;
@@ -228,7 +231,7 @@ public:
228 /*virtual*/ void removeTabPanel( LLPanel* child ); 231 /*virtual*/ void removeTabPanel( LLPanel* child );
229 232
230 /*virtual*/ void setPanelTitle(S32 index, const LLString& title); 233 /*virtual*/ void setPanelTitle(S32 index, const LLString& title);
231 /*virtual*/ void setTabImage(LLPanel* child, std::string img_name); 234 /*virtual*/ void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white);
232 /*virtual*/ void setRightTabBtnOffset( S32 offset ); 235 /*virtual*/ void setRightTabBtnOffset( S32 offset );
233 236
234 /*virtual*/ void setMinTabWidth(S32 width); 237 /*virtual*/ void setMinTabWidth(S32 width);
diff --git a/linden/indra/llui/lltabcontainervertical.cpp b/linden/indra/llui/lltabcontainervertical.cpp
index 317b7ca..e2d84a5 100644
--- a/linden/indra/llui/lltabcontainervertical.cpp
+++ b/linden/indra/llui/lltabcontainervertical.cpp
@@ -392,49 +392,47 @@ void LLTabContainerVertical::draw()
392 } 392 }
393 393
394 // Draw some of the buttons... 394 // Draw some of the buttons...
395
396 LLGLEnable scissor_test(has_scroll_arrows ? GL_SCISSOR_TEST : GL_FALSE);
397
398 if( has_scroll_arrows )
399 {
400 // ...but clip them.
401 S32 x1 = mRect.mLeft;
402 S32 y1 = mDownArrowBtn->getRect().mTop + 3*TABCNTRV_PAD;
403 S32 x2 = mRect.mRight;
404 S32 y2 = mUpArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD;
405 LLUI::setScissorRegionLocal(LLRect(x1, y2, x2, y1));
406 }
407
408 //S32 max_scroll_visible = mTabList.size() - mMaxScrollPos + mScrollPos;
409 S32 idx = 0;
410 for(std::vector<LLTabTuple*>::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
411 { 395 {
412 LLTabTuple* tuple = *iter; 396 LLRect clip_rect = getLocalRect();
413 tuple->mButton->translate( 0 , top - tuple->mButton->getRect().mTop); 397 if (has_scroll_arrows)
414 top -= BTN_HEIGHT + TABCNTRV_PAD;
415
416 LLUI::pushMatrix();
417 { 398 {
418 LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f); 399 // ...but clip them.
419 tuple->mButton->draw(); 400 clip_rect.mBottom = mDownArrowBtn->getRect().mTop + 3*TABCNTRV_PAD;
401 clip_rect.mTop = mUpArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD;
420 } 402 }
421 LLUI::popMatrix(); 403 LLLocalClipRect clip(clip_rect);
422 404
423 idx++; 405 //S32 max_scroll_visible = mTabList.size() - mMaxScrollPos + mScrollPos;
424 } 406 S32 idx = 0;
407 for(std::vector<LLTabTuple*>::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
408 {
409 LLTabTuple* tuple = *iter;
410 tuple->mButton->translate( 0 , top - tuple->mButton->getRect().mTop);
411 top -= BTN_HEIGHT + TABCNTRV_PAD;
425 412
426 if( has_scroll_arrows ) 413 LLUI::pushMatrix();
427 { 414 {
428 // Redraw the arrows so that they appears on top. 415 LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f);
429 glPushMatrix(); 416 tuple->mButton->draw();
430 glTranslatef((F32)mUpArrowBtn->getRect().mLeft, (F32)mUpArrowBtn->getRect().mBottom, 0.f); 417 }
431 mUpArrowBtn->draw(); 418 LLUI::popMatrix();
432 glPopMatrix(); 419
433 420 idx++;
434 glPushMatrix(); 421 }
435 glTranslatef((F32)mDownArrowBtn->getRect().mLeft, (F32)mDownArrowBtn->getRect().mBottom, 0.f); 422
436 mDownArrowBtn->draw(); 423 if( has_scroll_arrows )
437 glPopMatrix(); 424 {
425 // Redraw the arrows so that they appears on top.
426 glPushMatrix();
427 glTranslatef((F32)mUpArrowBtn->getRect().mLeft, (F32)mUpArrowBtn->getRect().mBottom, 0.f);
428 mUpArrowBtn->draw();
429 glPopMatrix();
430
431 glPushMatrix();
432 glTranslatef((F32)mDownArrowBtn->getRect().mLeft, (F32)mDownArrowBtn->getRect().mBottom, 0.f);
433 mDownArrowBtn->draw();
434 glPopMatrix();
435 }
438 } 436 }
439 } 437 }
440} 438}
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp
index 513670b..f49b2db 100644
--- a/linden/indra/llui/lltexteditor.cpp
+++ b/linden/indra/llui/lltexteditor.cpp
@@ -103,9 +103,9 @@ BOOL LLTextCmd::hasExtCharValue( llwchar value )
103} 103}
104 104
105// Utility funcs 105// Utility funcs
106S32 LLTextCmd::insert(LLTextEditor* editor, S32 pos, const LLWString &utf8str) 106S32 LLTextCmd::insert(LLTextEditor* editor, S32 pos, const LLWString &wstr)
107{ 107{
108 return editor->insertStringNoUndo( pos, utf8str ); 108 return editor->insertStringNoUndo( pos, wstr );
109} 109}
110S32 LLTextCmd::remove(LLTextEditor* editor, S32 pos, S32 length) 110S32 LLTextCmd::remove(LLTextEditor* editor, S32 pos, S32 length)
111{ 111{
@@ -122,29 +122,29 @@ class LLTextCmdInsert : public LLTextCmd
122{ 122{
123public: 123public:
124 LLTextCmdInsert(S32 pos, BOOL group_with_next, const LLWString &ws) 124 LLTextCmdInsert(S32 pos, BOOL group_with_next, const LLWString &ws)
125 : LLTextCmd(pos, group_with_next), mString(ws) 125 : LLTextCmd(pos, group_with_next), mWString(ws)
126 { 126 {
127 } 127 }
128 virtual BOOL execute( LLTextEditor* editor, S32* delta ) 128 virtual BOOL execute( LLTextEditor* editor, S32* delta )
129 { 129 {
130 *delta = insert(editor, mPos, mString ); 130 *delta = insert(editor, mPos, mWString );
131 LLWString::truncate(mString, *delta); 131 LLWString::truncate(mWString, *delta);
132 //mString = wstring_truncate(mString, *delta); 132 //mWString = wstring_truncate(mWString, *delta);
133 return (*delta != 0); 133 return (*delta != 0);
134 } 134 }
135 virtual S32 undo( LLTextEditor* editor ) 135 virtual S32 undo( LLTextEditor* editor )
136 { 136 {
137 remove(editor, mPos, mString.length() ); 137 remove(editor, mPos, mWString.length() );
138 return mPos; 138 return mPos;
139 } 139 }
140 virtual S32 redo( LLTextEditor* editor ) 140 virtual S32 redo( LLTextEditor* editor )
141 { 141 {
142 insert(editor, mPos, mString ); 142 insert(editor, mPos, mWString );
143 return mPos + mString.length(); 143 return mPos + mWString.length();
144 } 144 }
145 145
146private: 146private:
147 LLWString mString; 147 LLWString mWString;
148}; 148};
149 149
150/////////////////////////////////////////////////////////////////// 150///////////////////////////////////////////////////////////////////
@@ -153,7 +153,7 @@ class LLTextCmdAddChar : public LLTextCmd
153{ 153{
154public: 154public:
155 LLTextCmdAddChar( S32 pos, BOOL group_with_next, llwchar wc) 155 LLTextCmdAddChar( S32 pos, BOOL group_with_next, llwchar wc)
156 : LLTextCmd(pos, group_with_next), mString(1, wc), mBlockExtensions(FALSE) 156 : LLTextCmd(pos, group_with_next), mWString(1, wc), mBlockExtensions(FALSE)
157 { 157 {
158 } 158 }
159 virtual void blockExtensions() 159 virtual void blockExtensions()
@@ -162,13 +162,13 @@ public:
162 } 162 }
163 virtual BOOL canExtend(S32 pos) 163 virtual BOOL canExtend(S32 pos)
164 { 164 {
165 return !mBlockExtensions && (pos == mPos + (S32)mString.length()); 165 return !mBlockExtensions && (pos == mPos + (S32)mWString.length());
166 } 166 }
167 virtual BOOL execute( LLTextEditor* editor, S32* delta ) 167 virtual BOOL execute( LLTextEditor* editor, S32* delta )
168 { 168 {
169 *delta = insert(editor, mPos, mString); 169 *delta = insert(editor, mPos, mWString);
170 LLWString::truncate(mString, *delta); 170 LLWString::truncate(mWString, *delta);
171 //mString = wstring_truncate(mString, *delta); 171 //mWString = wstring_truncate(mWString, *delta);
172 return (*delta != 0); 172 return (*delta != 0);
173 } 173 }
174 virtual BOOL extendAndExecute( LLTextEditor* editor, S32 pos, llwchar wc, S32* delta ) 174 virtual BOOL extendAndExecute( LLTextEditor* editor, S32 pos, llwchar wc, S32* delta )
@@ -179,23 +179,23 @@ public:
179 *delta = insert(editor, pos, ws); 179 *delta = insert(editor, pos, ws);
180 if( *delta > 0 ) 180 if( *delta > 0 )
181 { 181 {
182 mString += wc; 182 mWString += wc;
183 } 183 }
184 return (*delta != 0); 184 return (*delta != 0);
185 } 185 }
186 virtual S32 undo( LLTextEditor* editor ) 186 virtual S32 undo( LLTextEditor* editor )
187 { 187 {
188 remove(editor, mPos, mString.length() ); 188 remove(editor, mPos, mWString.length() );
189 return mPos; 189 return mPos;
190 } 190 }
191 virtual S32 redo( LLTextEditor* editor ) 191 virtual S32 redo( LLTextEditor* editor )
192 { 192 {
193 insert(editor, mPos, mString ); 193 insert(editor, mPos, mWString );
194 return mPos + mString.length(); 194 return mPos + mWString.length();
195 } 195 }
196 196
197private: 197private:
198 LLWString mString; 198 LLWString mWString;
199 BOOL mBlockExtensions; 199 BOOL mBlockExtensions;
200 200
201}; 201};
@@ -242,14 +242,14 @@ public:
242 } 242 }
243 virtual BOOL execute( LLTextEditor* editor, S32* delta ) 243 virtual BOOL execute( LLTextEditor* editor, S32* delta )
244 { 244 {
245 mString = editor->getWSubString(mPos, mLen); 245 mWString = editor->getWSubString(mPos, mLen);
246 *delta = remove(editor, mPos, mLen ); 246 *delta = remove(editor, mPos, mLen );
247 return (*delta != 0); 247 return (*delta != 0);
248 } 248 }
249 virtual S32 undo( LLTextEditor* editor ) 249 virtual S32 undo( LLTextEditor* editor )
250 { 250 {
251 insert(editor, mPos, mString ); 251 insert(editor, mPos, mWString );
252 return mPos + mString.length(); 252 return mPos + mWString.length();
253 } 253 }
254 virtual S32 redo( LLTextEditor* editor ) 254 virtual S32 redo( LLTextEditor* editor )
255 { 255 {
@@ -257,7 +257,7 @@ public:
257 return mPos; 257 return mPos;
258 } 258 }
259private: 259private:
260 LLWString mString; 260 LLWString mWString;
261 S32 mLen; 261 S32 mLen;
262}; 262};
263 263
@@ -3013,8 +3013,7 @@ void LLTextEditor::draw()
3013 if( getVisible() ) 3013 if( getVisible() )
3014 { 3014 {
3015 { 3015 {
3016 LLGLEnable scissor_test(GL_SCISSOR_TEST); 3016 LLLocalClipRect clip(LLRect(0, mRect.getHeight(), mRect.getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0));
3017 LLUI::setScissorRegionLocal(LLRect(0, mRect.getHeight(), mRect.getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0));
3018 3017
3019 bindEmbeddedChars( mGLFont ); 3018 bindEmbeddedChars( mGLFont );
3020 3019
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h
index ebe8ac3..68c1d4a 100644
--- a/linden/indra/llui/lltexteditor.h
+++ b/linden/indra/llui/lltexteditor.h
@@ -329,7 +329,7 @@ protected:
329 S32 append(const LLWString &wstr, const BOOL group_with_next_op); 329 S32 append(const LLWString &wstr, const BOOL group_with_next_op);
330 330
331 // direct operations 331 // direct operations
332 S32 insertStringNoUndo(S32 pos, const LLWString &utf8str); // returns num of chars actually inserted 332 S32 insertStringNoUndo(S32 pos, const LLWString &wstr); // returns num of chars actually inserted
333 S32 removeStringNoUndo(S32 pos, S32 length); 333 S32 removeStringNoUndo(S32 pos, S32 length);
334 S32 overwriteCharNoUndo(S32 pos, llwchar wc); 334 S32 overwriteCharNoUndo(S32 pos, llwchar wc);
335 335
@@ -495,7 +495,7 @@ public:
495 virtual BOOL hasExtCharValue( llwchar value ); 495 virtual BOOL hasExtCharValue( llwchar value );
496 496
497 // Define these here so they can access LLTextEditor through the friend relationship 497 // Define these here so they can access LLTextEditor through the friend relationship
498 S32 insert(LLTextEditor* editor, S32 pos, const LLWString &utf8str); 498 S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr);
499 S32 remove(LLTextEditor* editor, S32 pos, S32 length); 499 S32 remove(LLTextEditor* editor, S32 pos, S32 length);
500 S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc); 500 S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc);
501 501
diff --git a/linden/indra/llui/llui.cpp b/linden/indra/llui/llui.cpp
index a725281..d0815a7 100644
--- a/linden/indra/llui/llui.cpp
+++ b/linden/indra/llui/llui.cpp
@@ -77,6 +77,8 @@ LLVector2 LLUI::sGLScaleFactor(1.f, 1.f);
77LLWindow* LLUI::sWindow = NULL; 77LLWindow* LLUI::sWindow = NULL;
78LLHtmlHelp* LLUI::sHtmlHelp = NULL; 78LLHtmlHelp* LLUI::sHtmlHelp = NULL;
79BOOL LLUI::sShowXUINames = FALSE; 79BOOL LLUI::sShowXUINames = FALSE;
80std::stack<LLRect> LLUI::sClipRectStack;
81
80// 82//
81// Functions 83// Functions
82// 84//
@@ -110,7 +112,7 @@ void make_ui_sound(const LLString& name)
110 { 112 {
111 llinfos << "ui sound name: " << name << llendl; 113 llinfos << "ui sound name: " << name << llendl;
112 } 114 }
113 LLUI::sAudioCallback(uuid, LLUI::sConfigGroup->getF32("AudioLevelUI")); 115 LLUI::sAudioCallback(uuid);
114 } 116 }
115 } 117 }
116} 118}
@@ -1811,3 +1813,59 @@ void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
1811{ 1813{
1812 LLUI::sHtmlHelp = html_help; 1814 LLUI::sHtmlHelp = html_help;
1813} 1815}
1816
1817//static
1818void LLUI::pushClipRect(const LLRect& rect)
1819{
1820 LLRect combined_clip_rect = rect;
1821 if (!sClipRectStack.empty())
1822 {
1823 combined_clip_rect.intersectWith(sClipRectStack.top());
1824 }
1825 sClipRectStack.push(combined_clip_rect);
1826 setScissorRegionScreen(combined_clip_rect);
1827}
1828
1829//static
1830void LLUI::popClipRect()
1831{
1832 sClipRectStack.pop();
1833 if (!sClipRectStack.empty())
1834 {
1835 setScissorRegionScreen(sClipRectStack.top());
1836 }
1837}
1838
1839LLClipRect::LLClipRect(const LLRect& rect, BOOL enabled) : mScissorState(GL_SCISSOR_TEST, enabled), mEnabled(enabled)
1840{
1841 if (mEnabled)
1842 {
1843 LLUI::pushClipRect(rect);
1844 }
1845}
1846
1847LLClipRect::~LLClipRect()
1848{
1849 if (mEnabled)
1850 {
1851 LLUI::popClipRect();
1852 }
1853}
1854
1855LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled) : mScissorState(GL_SCISSOR_TEST, enabled), mEnabled(enabled)
1856{
1857 if (mEnabled)
1858 {
1859 LLRect scissor_rect = rect;
1860 scissor_rect.translate(LLFontGL::sCurOrigin.mX, LLFontGL::sCurOrigin.mY);
1861 LLUI::pushClipRect(scissor_rect);
1862 }
1863}
1864
1865LLLocalClipRect::~LLLocalClipRect()
1866{
1867 if (mEnabled)
1868 {
1869 LLUI::popClipRect();
1870 }
1871}
diff --git a/linden/indra/llui/llui.h b/linden/indra/llui/llui.h
index 3085bd9..201d88f 100644
--- a/linden/indra/llui/llui.h
+++ b/linden/indra/llui/llui.h
@@ -36,6 +36,8 @@
36#include "llrect.h" 36#include "llrect.h"
37#include "llcoord.h" 37#include "llcoord.h"
38#include "llhtmlhelp.h" 38#include "llhtmlhelp.h"
39#include "llgl.h"
40#include <stack>
39 41
40class LLColor4; 42class LLColor4;
41class LLVector3; 43class LLVector3;
@@ -143,7 +145,7 @@ extern BOOL gShowTextEditCursor;
143extern LLString gLanguage; 145extern LLString gLanguage;
144 146
145class LLImageProviderInterface; 147class LLImageProviderInterface;
146typedef void (*LLUIAudioCallback)(const LLUUID& uuid, F32 volume); 148typedef void (*LLUIAudioCallback)(const LLUUID& uuid);
147 149
148class LLUI 150class LLUI
149{ 151{
@@ -164,8 +166,8 @@ public:
164 166
165 //helper functions (should probably move free standing rendering helper functions here) 167 //helper functions (should probably move free standing rendering helper functions here)
166 static LLString locateSkin(const LLString& filename); 168 static LLString locateSkin(const LLString& filename);
167 static void setScissorRegionScreen(const LLRect& rect); 169 static void pushClipRect(const LLRect& rect);
168 static void setScissorRegionLocal(const LLRect& rect); // works assuming LLUI::translate has been called 170 static void popClipRect();
169 static void setCursorPositionScreen(S32 x, S32 y); 171 static void setCursorPositionScreen(S32 x, S32 y);
170 static void setCursorPositionLocal(LLView* viewp, S32 x, S32 y); 172 static void setCursorPositionLocal(LLView* viewp, S32 x, S32 y);
171 static void setScaleFactor(const LLVector2& scale_factor); 173 static void setScaleFactor(const LLVector2& scale_factor);
@@ -173,6 +175,11 @@ public:
173 static LLUUID findAssetUUIDByName(const LLString& name); 175 static LLUUID findAssetUUIDByName(const LLString& name);
174 static LLVector2 getWindowSize(); 176 static LLVector2 getWindowSize();
175 static void setHtmlHelp(LLHtmlHelp* html_help); 177 static void setHtmlHelp(LLHtmlHelp* html_help);
178
179private:
180 static void setScissorRegionScreen(const LLRect& rect);
181 static void setScissorRegionLocal(const LLRect& rect); // works assuming LLUI::translate has been called
182
176public: 183public:
177 static LLControlGroup* sConfigGroup; 184 static LLControlGroup* sConfigGroup;
178 static LLControlGroup* sColorsGroup; 185 static LLControlGroup* sColorsGroup;
@@ -183,6 +190,8 @@ public:
183 static LLWindow* sWindow; 190 static LLWindow* sWindow;
184 static BOOL sShowXUINames; 191 static BOOL sShowXUINames;
185 static LLHtmlHelp* sHtmlHelp; 192 static LLHtmlHelp* sHtmlHelp;
193 static std::stack<LLRect> sClipRectStack;
194
186}; 195};
187 196
188// UI widgets 197// UI widgets
@@ -271,6 +280,7 @@ typedef enum e_widget_type
271 WIDGET_TYPE_TEXTURE_VIEW, 280 WIDGET_TYPE_TEXTURE_VIEW,
272 WIDGET_TYPE_MEMORY_VIEW, 281 WIDGET_TYPE_MEMORY_VIEW,
273 WIDGET_TYPE_FRAME_STAT_VIEW, 282 WIDGET_TYPE_FRAME_STAT_VIEW,
283 WIDGET_TYPE_LAYOUT_STACK,
274 WIDGET_TYPE_DONTCARE, 284 WIDGET_TYPE_DONTCARE,
275 WIDGET_TYPE_COUNT 285 WIDGET_TYPE_COUNT
276} EWidgetType; 286} EWidgetType;
@@ -292,38 +302,38 @@ public:
292 } 302 }
293 303
294 // default show and hide methods 304 // default show and hide methods
295 static T* showInstance(const LLSD& seed) 305 static T* showInstance(const LLSD& seed = LLSD())
296 { 306 {
297 T* instance = INSTANCE_ADAPTOR::getInstance(seed); 307 T* instance = INSTANCE_ADAPTOR::getInstance(seed);
298 INSTANCE_ADAPTOR::show(instance); 308 INSTANCE_ADAPTOR::show(instance);
299 return instance; 309 return instance;
300 } 310 }
301 311
302 static void hideInstance(const LLSD& seed) 312 static void hideInstance(const LLSD& seed = LLSD())
303 { 313 {
304 T* instance = INSTANCE_ADAPTOR::getInstance(seed); 314 T* instance = INSTANCE_ADAPTOR::getInstance(seed);
305 INSTANCE_ADAPTOR::hide(instance); 315 INSTANCE_ADAPTOR::hide(instance);
306 } 316 }
307 317
308 static void toggleInstance(const LLSD& seed) 318 static void toggleInstance(const LLSD& seed = LLSD())
309 { 319 {
310 if (!INSTANCE_ADAPTOR::instanceVisible(seed)) 320 if (INSTANCE_ADAPTOR::instanceVisible(seed))
311 { 321 {
312 INSTANCE_ADAPTOR::showInstance(seed); 322 INSTANCE_ADAPTOR::hideInstance(seed);
313 } 323 }
314 else 324 else
315 { 325 {
316 INSTANCE_ADAPTOR::hideInstance(seed); 326 INSTANCE_ADAPTOR::showInstance(seed);
317 } 327 }
318 } 328 }
319 329
320 static BOOL instanceVisible(const LLSD& seed) 330 static BOOL instanceVisible(const LLSD& seed = LLSD())
321 { 331 {
322 T* instance = INSTANCE_ADAPTOR::findInstance(seed); 332 T* instance = INSTANCE_ADAPTOR::findInstance(seed);
323 return instance != NULL && INSTANCE_ADAPTOR::visible(instance); 333 return instance != NULL && INSTANCE_ADAPTOR::visible(instance);
324 } 334 }
325 335
326 static T* getInstance(const LLSD& seed) 336 static T* getInstance(const LLSD& seed = LLSD())
327 { 337 {
328 T* instance = INSTANCE_ADAPTOR::findInstance(seed); 338 T* instance = INSTANCE_ADAPTOR::findInstance(seed);
329 if (instance == NULL) 339 if (instance == NULL)
@@ -332,6 +342,7 @@ public:
332 } 342 }
333 return instance; 343 return instance;
334 } 344 }
345
335}; 346};
336 347
337// Creates a UI singleton by ignoring the identifying parameter 348// Creates a UI singleton by ignoring the identifying parameter
@@ -346,12 +357,12 @@ public:
346 LLUISingleton() : LLUIInstanceMgr<T, INSTANCE_ADAPTOR>() { sInstance = (T*)this; } 357 LLUISingleton() : LLUIInstanceMgr<T, INSTANCE_ADAPTOR>() { sInstance = (T*)this; }
347 ~LLUISingleton() { sInstance = NULL; } 358 ~LLUISingleton() { sInstance = NULL; }
348 359
349 static T* findInstance(const LLSD& seed) 360 static T* findInstance(const LLSD& seed = LLSD())
350 { 361 {
351 return sInstance; 362 return sInstance;
352 } 363 }
353 364
354 static T* createInstance(const LLSD& seed) 365 static T* createInstance(const LLSD& seed = LLSD())
355 { 366 {
356 if (sInstance == NULL) 367 if (sInstance == NULL)
357 { 368 {
@@ -366,4 +377,24 @@ protected:
366 377
367template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL; 378template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL;
368 379
380class LLClipRect
381{
382public:
383 LLClipRect(const LLRect& rect, BOOL enabled = TRUE);
384 virtual ~LLClipRect();
385protected:
386 LLGLState mScissorState;
387 BOOL mEnabled;
388};
389
390class LLLocalClipRect
391{
392public:
393 LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE);
394 virtual ~LLLocalClipRect();
395protected:
396 LLGLState mScissorState;
397 BOOL mEnabled;
398};
399
369#endif 400#endif
diff --git a/linden/indra/llui/lluictrl.cpp b/linden/indra/llui/lluictrl.cpp
index 1762d7c..0ac3916 100644
--- a/linden/indra/llui/lluictrl.cpp
+++ b/linden/indra/llui/lluictrl.cpp
@@ -256,7 +256,7 @@ public:
256 /*virtual*/ void operator() (LLView * parent, viewList_t &children) const 256 /*virtual*/ void operator() (LLView * parent, viewList_t &children) const
257 { 257 {
258 children.sort(CompareByDefaultTabGroup(parent->getCtrlOrder(), parent->getDefaultTabGroup())); 258 children.sort(CompareByDefaultTabGroup(parent->getCtrlOrder(), parent->getDefaultTabGroup()));
259 } 259 }
260}; 260};
261 261
262BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields) 262BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields)
diff --git a/linden/indra/llui/lluictrl.h b/linden/indra/llui/lluictrl.h
index 5056319..2060a0d 100644
--- a/linden/indra/llui/lluictrl.h
+++ b/linden/indra/llui/lluictrl.h
@@ -148,6 +148,9 @@ public:
148 } 148 }
149 }; 149 };
150 150
151 // Returns TRUE if the user has modified this control. Editable controls should override this.
152 virtual BOOL isDirty() { return FALSE; };
153
151protected: 154protected:
152 virtual void onFocusReceived(); 155 virtual void onFocusReceived();
153 virtual void onFocusLost(); 156 virtual void onFocusLost();
diff --git a/linden/indra/llui/lluictrlfactory.cpp b/linden/indra/llui/lluictrlfactory.cpp
index 79f7313..70f1e3e 100644
--- a/linden/indra/llui/lluictrlfactory.cpp
+++ b/linden/indra/llui/lluictrlfactory.cpp
@@ -89,7 +89,7 @@ const LLString LLUICtrlFactory::sUICtrlNames[WIDGET_TYPE_COUNT] =
89 LLString("web_browser"), //WIDGET_TYPE_WEBBROWSER 89 LLString("web_browser"), //WIDGET_TYPE_WEBBROWSER
90 LLString("slider"), //WIDGET_TYPE_SLIDER, actually LLSliderCtrl 90 LLString("slider"), //WIDGET_TYPE_SLIDER, actually LLSliderCtrl
91 LLString("slider_bar"), //WIDGET_TYPE_SLIDER_BAR, actually LLSlider 91 LLString("slider_bar"), //WIDGET_TYPE_SLIDER_BAR, actually LLSlider
92 LLString("volume_slider"), //WIDGET_TYPE_VOLUME_SLIDER, actually LLVolumeSliderCtrl 92 LLString("volume_slider"), //WIDGET_TYPE_VOLUME_SLIDER, actually LLSlider + "volume" param
93 LLString("spinner"), //WIDGET_TYPE_SPINNER, actually LLSpinCtrl 93 LLString("spinner"), //WIDGET_TYPE_SPINNER, actually LLSpinCtrl
94 LLString("text_editor"), //WIDGET_TYPE_TEXT_EDITOR 94 LLString("text_editor"), //WIDGET_TYPE_TEXT_EDITOR
95 LLString("texture_picker"),//WIDGET_TYPE_TEXTURE_PICKER 95 LLString("texture_picker"),//WIDGET_TYPE_TEXTURE_PICKER
@@ -155,6 +155,7 @@ const LLString LLUICtrlFactory::sUICtrlNames[WIDGET_TYPE_COUNT] =
155 LLString("texture_view"), //WIDGET_TYPE_TEXTURE_VIEW 155 LLString("texture_view"), //WIDGET_TYPE_TEXTURE_VIEW
156 LLString("memory_view"), //WIDGET_TYPE_MEMORY_VIEW 156 LLString("memory_view"), //WIDGET_TYPE_MEMORY_VIEW
157 LLString("frame_stat_view"), //WIDGET_TYPE_FRAME_STAT_VIEW 157 LLString("frame_stat_view"), //WIDGET_TYPE_FRAME_STAT_VIEW
158 LLString("layout_stack"), //WIDGET_TYPE_LAYOUT_STACK
158 LLString("DONT_CARE"), //WIDGET_TYPE_DONTCARE 159 LLString("DONT_CARE"), //WIDGET_TYPE_DONTCARE
159}; 160};
160 161
@@ -197,6 +198,7 @@ LLUICtrlFactory::LLUICtrlFactory()
197 LLUICtrlCreator<LLScrollListCtrl>::registerCreator(LL_SCROLL_LIST_CTRL_TAG, this); 198 LLUICtrlCreator<LLScrollListCtrl>::registerCreator(LL_SCROLL_LIST_CTRL_TAG, this);
198 LLUICtrlCreator<LLSliderCtrl>::registerCreator(LL_SLIDER_CTRL_TAG, this); 199 LLUICtrlCreator<LLSliderCtrl>::registerCreator(LL_SLIDER_CTRL_TAG, this);
199 LLUICtrlCreator<LLSlider>::registerCreator(LL_SLIDER_TAG, this); 200 LLUICtrlCreator<LLSlider>::registerCreator(LL_SLIDER_TAG, this);
201 LLUICtrlCreator<LLSlider>::registerCreator(LL_VOLUME_SLIDER_CTRL_TAG, this);
200 LLUICtrlCreator<LLSpinCtrl>::registerCreator(LL_SPIN_CTRL_TAG, this); 202 LLUICtrlCreator<LLSpinCtrl>::registerCreator(LL_SPIN_CTRL_TAG, this);
201 LLUICtrlCreator<LLTextBox>::registerCreator(LL_TEXT_BOX_TAG, this); 203 LLUICtrlCreator<LLTextBox>::registerCreator(LL_TEXT_BOX_TAG, this);
202 LLUICtrlCreator<LLRadioGroup>::registerCreator(LL_RADIO_GROUP_TAG, this); 204 LLUICtrlCreator<LLRadioGroup>::registerCreator(LL_RADIO_GROUP_TAG, this);
@@ -210,6 +212,7 @@ LLUICtrlFactory::LLUICtrlFactory()
210 LLUICtrlCreator<LLMenuGL>::registerCreator(LL_MENU_GL_TAG, this); 212 LLUICtrlCreator<LLMenuGL>::registerCreator(LL_MENU_GL_TAG, this);
211 LLUICtrlCreator<LLMenuBarGL>::registerCreator(LL_MENU_BAR_GL_TAG, this); 213 LLUICtrlCreator<LLMenuBarGL>::registerCreator(LL_MENU_BAR_GL_TAG, this);
212 LLUICtrlCreator<LLScrollingPanelList>::registerCreator(LL_SCROLLING_PANEL_LIST_TAG, this); 214 LLUICtrlCreator<LLScrollingPanelList>::registerCreator(LL_SCROLLING_PANEL_LIST_TAG, this);
215 LLUICtrlCreator<LLLayoutStack>::registerCreator(LL_LAYOUT_STACK_TAG, this);
213 216
214 setupPaths(); 217 setupPaths();
215 218
@@ -765,6 +768,37 @@ LLScrollingPanelList* LLUICtrlFactory::getScrollingPanelList(LLPanel* panelp, co
765 return (LLScrollingPanelList*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SCROLLING_PANEL_LIST); 768 return (LLScrollingPanelList*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SCROLLING_PANEL_LIST);
766} 769}
767 770
771
772LLCtrlListInterface* LLUICtrlFactory::getListInterfaceByName(LLPanel* panelp, const LLString& name)
773{
774 LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE);
775 if (viewp && viewp->isCtrl())
776 {
777 return ((LLUICtrl*)viewp)->getListInterface();
778 }
779 return NULL;
780}
781
782LLCtrlSelectionInterface* LLUICtrlFactory::getSelectionInterfaceByName(LLPanel* panelp, const LLString& name)
783{
784 LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE);
785 if (viewp && viewp->isCtrl())
786 {
787 return ((LLUICtrl*)viewp)->getSelectionInterface();
788 }
789 return NULL;
790}
791
792LLCtrlScrollInterface* LLUICtrlFactory::getScrollInterfaceByName(LLPanel* panelp, const LLString& name)
793{
794 LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE);
795 if (viewp && viewp->isCtrl())
796 {
797 return ((LLUICtrl*)viewp)->getScrollInterface();
798 }
799 return NULL;
800}
801
768void LLUICtrlFactory::registerCreator(LLString ctrlname, creator_function_t function) 802void LLUICtrlFactory::registerCreator(LLString ctrlname, creator_function_t function)
769{ 803{
770 LLString::toLower(ctrlname); 804 LLString::toLower(ctrlname);
diff --git a/linden/indra/llui/lluictrlfactory.h b/linden/indra/llui/lluictrlfactory.h
index eaae754..e12017d 100644
--- a/linden/indra/llui/lluictrlfactory.h
+++ b/linden/indra/llui/lluictrlfactory.h
@@ -65,6 +65,9 @@ class LLWebBrowserCtrl;
65class LLViewBorder; 65class LLViewBorder;
66class LLColorSwatchCtrl; 66class LLColorSwatchCtrl;
67class LLScrollingPanelList; 67class LLScrollingPanelList;
68class LLCtrlListInterface;
69class LLCtrlSelectionInterface;
70class LLCtrlScrollInterface;
68 71
69// Widget 72// Widget
70 73
@@ -123,6 +126,11 @@ public:
123 static LLMenuItemCallGL* getMenuItemCallByName(LLPanel* panelp, const LLString& name); 126 static LLMenuItemCallGL* getMenuItemCallByName(LLPanel* panelp, const LLString& name);
124 static LLScrollingPanelList* getScrollingPanelList(LLPanel* panelp, const LLString& name); 127 static LLScrollingPanelList* getScrollingPanelList(LLPanel* panelp, const LLString& name);
125 128
129 // interface getters
130 static LLCtrlListInterface* getListInterfaceByName(LLPanel* panelp, const LLString& name);
131 static LLCtrlSelectionInterface* getSelectionInterfaceByName(LLPanel* panelp, const LLString& name);
132 static LLCtrlScrollInterface* getScrollInterfaceByName(LLPanel* panelp, const LLString& name);
133
126 LLPanel* createFactoryPanel(LLString name); 134 LLPanel* createFactoryPanel(LLString name);
127 135
128 virtual LLView* createCtrlWidget(LLPanel *parent, LLXMLNodePtr node); 136 virtual LLView* createCtrlWidget(LLPanel *parent, LLXMLNodePtr node);
diff --git a/linden/indra/llui/lluistring.cpp b/linden/indra/llui/lluistring.cpp
index 49b6fca..cf1b0e0 100644
--- a/linden/indra/llui/lluistring.cpp
+++ b/linden/indra/llui/lluistring.cpp
@@ -30,6 +30,9 @@
30 30
31#include "lluistring.h" 31#include "lluistring.h"
32 32
33const LLString::format_map_t LLUIString::sNullArgs;
34
35
33// public 36// public
34 37
35LLUIString::LLUIString(const LLString& instring, const LLString::format_map_t& args) 38LLUIString::LLUIString(const LLString& instring, const LLString::format_map_t& args)
diff --git a/linden/indra/llui/lluistring.h b/linden/indra/llui/lluistring.h
index 37792aa..c5d9152 100644
--- a/linden/indra/llui/lluistring.h
+++ b/linden/indra/llui/lluistring.h
@@ -95,6 +95,8 @@ public:
95 void insert(S32 charidx, const LLWString& wchars); 95 void insert(S32 charidx, const LLWString& wchars);
96 void replace(S32 charidx, llwchar wc); 96 void replace(S32 charidx, llwchar wc);
97 97
98 static const LLString::format_map_t sNullArgs;
99
98private: 100private:
99 void format(); 101 void format();
100 102
diff --git a/linden/indra/llui/lluixmltags.h b/linden/indra/llui/lluixmltags.h
index 08c5f67..7728d73 100644
--- a/linden/indra/llui/lluixmltags.h
+++ b/linden/indra/llui/lluixmltags.h
@@ -116,4 +116,5 @@
116#define LL_JOYSTICK_SLIDE "joystick_slide" 116#define LL_JOYSTICK_SLIDE "joystick_slide"
117#define LL_JOYSTICK_TURN "joystick_turn" 117#define LL_JOYSTICK_TURN "joystick_turn"
118#define LL_GROUP_DROP_TARGET_TAG "group_drop_target" 118#define LL_GROUP_DROP_TARGET_TAG "group_drop_target"
119#define LL_LAYOUT_STACK_TAG "layout_stack"
119#endif 120#endif
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp
index 0b04213..2a62602 100644
--- a/linden/indra/llui/llview.cpp
+++ b/linden/indra/llui/llview.cpp
@@ -325,6 +325,10 @@ void LLView::moveChildToFrontOfTabGroup(LLUICtrl* child)
325 325
326void LLView::addChild(LLView* child, S32 tab_group) 326void LLView::addChild(LLView* child, S32 tab_group)
327{ 327{
328 if (mParentView == child)
329 {
330 llerrs << "Adding view " << child->getName() << " as child of itself" << llendl;
331 }
328 // remove from current parent 332 // remove from current parent
329 if (child->mParentView) 333 if (child->mParentView)
330 { 334 {
@@ -348,6 +352,10 @@ void LLView::addChild(LLView* child, S32 tab_group)
348 352
349void LLView::addChildAtEnd(LLView* child, S32 tab_group) 353void LLView::addChildAtEnd(LLView* child, S32 tab_group)
350{ 354{
355 if (mParentView == child)
356 {
357 llerrs << "Adding view " << child->getName() << " as child of itself" << llendl;
358 }
351 // remove from current parent 359 // remove from current parent
352 if (child->mParentView) 360 if (child->mParentView)
353 { 361 {
@@ -752,18 +760,22 @@ void LLView::setEnabled(BOOL enabled)
752// virtual 760// virtual
753void LLView::setVisible(BOOL visible) 761void LLView::setVisible(BOOL visible)
754{ 762{
755 if( !visible && (gFocusMgr.getTopCtrl() == this) )
756 {
757 gFocusMgr.setTopCtrl( NULL );
758 }
759
760 if ( mVisible != visible ) 763 if ( mVisible != visible )
761 { 764 {
762 // tell all children of this view that the visibility may have changed 765 if( !visible && (gFocusMgr.getTopCtrl() == this) )
763 onVisibilityChange ( visible ); 766 {
764 } 767 gFocusMgr.setTopCtrl( NULL );
768 }
765 769
766 mVisible = visible; 770 mVisible = visible;
771
772 // notify children of visibility change if root, or part of visible hierarchy
773 if (!getParent() || getParent()->isInVisibleChain())
774 {
775 // tell all children of this view that the visibility may have changed
776 onVisibilityChange( visible );
777 }
778 }
767} 779}
768 780
769// virtual 781// virtual
@@ -778,7 +790,7 @@ BOOL LLView::setLabelArg(const LLString& key, const LLString& text)
778 return FALSE; 790 return FALSE;
779} 791}
780 792
781void LLView::onVisibilityChange ( BOOL curVisibilityIn ) 793void LLView::onVisibilityChange ( BOOL new_visibility )
782{ 794{
783 for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) 795 for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
784 { 796 {
@@ -786,7 +798,7 @@ void LLView::onVisibilityChange ( BOOL curVisibilityIn )
786 // only views that are themselves visible will have their overall visibility affected by their ancestors 798 // only views that are themselves visible will have their overall visibility affected by their ancestors
787 if (viewp->getVisible()) 799 if (viewp->getVisible())
788 { 800 {
789 viewp->onVisibilityChange ( curVisibilityIn ); 801 viewp->onVisibilityChange ( new_visibility );
790 } 802 }
791 } 803 }
792} 804}
@@ -1390,64 +1402,61 @@ LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask)
1390 1402
1391void LLView::draw() 1403void LLView::draw()
1392{ 1404{
1393 if (getVisible()) 1405 if (sDebugRects)
1394 { 1406 {
1395 if (sDebugRects) 1407 drawDebugRect();
1396 {
1397 drawDebugRect();
1398 1408
1399 // Check for bogus rectangle 1409 // Check for bogus rectangle
1400 if (mRect.mRight <= mRect.mLeft 1410 if (mRect.mRight <= mRect.mLeft
1401 || mRect.mTop <= mRect.mBottom) 1411 || mRect.mTop <= mRect.mBottom)
1402 { 1412 {
1403 llwarns << "Bogus rectangle for " << getName() << " with " << mRect << llendl; 1413 llwarns << "Bogus rectangle for " << getName() << " with " << mRect << llendl;
1404 }
1405 } 1414 }
1415 }
1406 1416
1407 LLRect rootRect = getRootView()->getRect(); 1417 LLRect rootRect = getRootView()->getRect();
1408 LLRect screenRect; 1418 LLRect screenRect;
1409 1419
1410 // draw focused control on top of everything else 1420 // draw focused control on top of everything else
1411 LLView* focus_view = gFocusMgr.getKeyboardFocus(); 1421 LLView* focus_view = gFocusMgr.getKeyboardFocus();
1412 if (focus_view && focus_view->getParent() != this) 1422 if (focus_view && focus_view->getParent() != this)
1413 { 1423 {
1414 focus_view = NULL; 1424 focus_view = NULL;
1415 } 1425 }
1416 1426
1417 for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter) 1427 for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter)
1418 { 1428 {
1419 LLView *viewp = *child_iter; 1429 LLView *viewp = *child_iter;
1420 ++sDepth; 1430 ++sDepth;
1421 1431
1422 if (viewp->getVisible() && viewp != focus_view) 1432 if (viewp->getVisible() && viewp != focus_view)
1433 {
1434 // Only draw views that are within the root view
1435 localRectToScreen(viewp->getRect(),&screenRect);
1436 if ( rootRect.rectInRect(&screenRect) )
1423 { 1437 {
1424 // Only draw views that are within the root view 1438 glMatrixMode(GL_MODELVIEW);
1425 localRectToScreen(viewp->getRect(),&screenRect); 1439 LLUI::pushMatrix();
1426 if ( rootRect.rectInRect(&screenRect) )
1427 { 1440 {
1428 glMatrixMode(GL_MODELVIEW); 1441 LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom, 0.f);
1429 LLUI::pushMatrix(); 1442 viewp->draw();
1430 {
1431 LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom, 0.f);
1432 viewp->draw();
1433 }
1434 LLUI::popMatrix();
1435 } 1443 }
1444 LLUI::popMatrix();
1436 } 1445 }
1437
1438 --sDepth;
1439 } 1446 }
1440 1447
1441 if (focus_view && focus_view->getVisible()) 1448 --sDepth;
1442 { 1449 }
1443 drawChild(focus_view);
1444 }
1445 1450
1446 // HACK 1451 if (focus_view && focus_view->getVisible())
1447 if (sEditingUI && this == sEditingUIView) 1452 {
1448 { 1453 drawChild(focus_view);
1449 drawDebugRect(); 1454 }
1450 } 1455
1456 // HACK
1457 if (sEditingUI && this == sEditingUIView)
1458 {
1459 drawDebugRect();
1451 } 1460 }
1452} 1461}
1453 1462
@@ -1500,13 +1509,13 @@ void LLView::drawDebugRect()
1500 } 1509 }
1501} 1510}
1502 1511
1503void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset) 1512void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_draw)
1504{ 1513{
1505 if (childp && childp->getParent() == this) 1514 if (childp && childp->getParent() == this)
1506 { 1515 {
1507 ++sDepth; 1516 ++sDepth;
1508 1517
1509 if (childp->getVisible()) 1518 if (childp->getVisible() || force_draw)
1510 { 1519 {
1511 glMatrixMode(GL_MODELVIEW); 1520 glMatrixMode(GL_MODELVIEW);
1512 LLUI::pushMatrix(); 1521 LLUI::pushMatrix();
@@ -1636,7 +1645,7 @@ void LLView::updateRect()
1636 LLView* viewp = *child_it; 1645 LLView* viewp = *child_it;
1637 if (viewp->getVisible()) 1646 if (viewp->getVisible())
1638 { 1647 {
1639 child_spanning_rect |= viewp->mRect; 1648 child_spanning_rect.unionWith(viewp->mRect);
1640 } 1649 }
1641 } 1650 }
1642 1651
diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h
index c7664eb..053ef82 100644
--- a/linden/indra/llui/llview.h
+++ b/linden/indra/llui/llview.h
@@ -379,7 +379,7 @@ public:
379 virtual void draw(); 379 virtual void draw();
380 380
381 void drawDebugRect(); 381 void drawDebugRect();
382 void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0); 382 void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE);
383 383
384 virtual const LLString& getName() const; 384 virtual const LLString& getName() const;
385 385
diff --git a/linden/indra/llvfs/files.sunos5.lst b/linden/indra/llvfs/files.sunos5.lst
new file mode 100644
index 0000000..f1b74d8
--- /dev/null
+++ b/linden/indra/llvfs/files.sunos5.lst
@@ -0,0 +1 @@
llvfs/lldir_solaris.cpp
diff --git a/linden/indra/llvfs/lldir.cpp b/linden/indra/llvfs/lldir.cpp
index d71224a..5f0efbe 100644
--- a/linden/indra/llvfs/lldir.cpp
+++ b/linden/indra/llvfs/lldir.cpp
@@ -45,6 +45,9 @@ LLDir_Win32 gDirUtil;
45#elif LL_DARWIN 45#elif LL_DARWIN
46#include "lldir_mac.h" 46#include "lldir_mac.h"
47LLDir_Mac gDirUtil; 47LLDir_Mac gDirUtil;
48#elif LL_SOLARIS
49#include "lldir_solaris.h"
50LLDir_Solaris gDirUtil;
48#else 51#else
49#include "lldir_linux.h" 52#include "lldir_linux.h"
50LLDir_Linux gDirUtil; 53LLDir_Linux gDirUtil;
diff --git a/linden/indra/llvfs/lldir_linux.cpp b/linden/indra/llvfs/lldir_linux.cpp
index e3aada6..7cf1c2a 100644
--- a/linden/indra/llvfs/lldir_linux.cpp
+++ b/linden/indra/llvfs/lldir_linux.cpp
@@ -75,7 +75,16 @@ LLDir_Linux::LLDir_Linux()
75 mDirp = NULL; 75 mDirp = NULL;
76 76
77 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */ 77 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
78 getcwd(tmp_str, LL_MAX_PATH); 78 if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
79 {
80 strcpy(tmp_str, "/tmp");
81 llwarns << "Could not get current directory; changing to "
82 << tmp_str << llendl;
83 if (chdir(tmp_str) == -1)
84 {
85 llerrs << "Could not change directory to " << tmp_str << llendl;
86 }
87 }
79 88
80 mExecutableFilename = ""; 89 mExecutableFilename = "";
81 mExecutablePathAndName = ""; 90 mExecutablePathAndName = "";
@@ -328,7 +337,11 @@ void LLDir_Linux::getRandomFileInDir(const std::string &dirname, const std::stri
328std::string LLDir_Linux::getCurPath() 337std::string LLDir_Linux::getCurPath()
329{ 338{
330 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */ 339 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
331 getcwd(tmp_str, LL_MAX_PATH); 340 if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
341 {
342 llwarns << "Could not get current directory" << llendl;
343 tmp_str[0] = '\0';
344 }
332 return tmp_str; 345 return tmp_str;
333} 346}
334 347
diff --git a/linden/indra/llvfs/lldir_solaris.cpp b/linden/indra/llvfs/lldir_solaris.cpp
new file mode 100644
index 0000000..41262aa
--- /dev/null
+++ b/linden/indra/llvfs/lldir_solaris.cpp
@@ -0,0 +1,374 @@
1/**
2 * @file fmodwrapper.cpp
3 * @brief dummy source file for building a shared library to wrap libfmod.a
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "linden_common.h"
30
31#include "lldir_solaris.h"
32#include "llerror.h"
33#include "llrand.h"
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <sys/param.h>
38#include <unistd.h>
39#include <glob.h>
40#include <pwd.h>
41#include <sys/utsname.h>
42#define _STRUCTURED_PROC 1
43#include <sys/procfs.h>
44
45static std::string getCurrentUserHome(char* fallback)
46{
47 const uid_t uid = getuid();
48 struct passwd *pw;
49 char *result_cstr = fallback;
50
51 pw = getpwuid(uid);
52 if ((pw != NULL) && (pw->pw_dir != NULL))
53 {
54 result_cstr = (char*) pw->pw_dir;
55 }
56 else
57 {
58 llinfos << "Couldn't detect home directory from passwd - trying $HOME" << llendl;
59 const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */
60 if (home_env)
61 {
62 result_cstr = (char*) home_env;
63 }
64 else
65 {
66 llwarns << "Couldn't detect home directory! Falling back to " << fallback << llendl;
67 }
68 }
69
70 return std::string(result_cstr);
71}
72
73
74LLDir_Solaris::LLDir_Solaris()
75{
76 mDirDelimiter = "/";
77 mCurrentDirIndex = -1;
78 mCurrentDirCount = -1;
79 mDirp = NULL;
80
81 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
82 getcwd(tmp_str, LL_MAX_PATH);
83
84 mExecutableFilename = "";
85 mExecutablePathAndName = "";
86 mExecutableDir = strdup(tmp_str);
87 mWorkingDir = strdup(tmp_str);
88 mAppRODataDir = strdup(tmp_str);
89 mOSUserDir = getCurrentUserHome(tmp_str);
90 mOSUserAppDir = "";
91 mLindenUserDir = tmp_str;
92
93 char path [LL_MAX_PATH]; /* Flawfinder: ignore */
94
95 sprintf(path, "/proc/%d/psinfo", (int)getpid());
96 int proc_fd = -1;
97 if((proc_fd = open(path, O_RDONLY)) == -1){
98 llwarns << "unable to open " << path << llendl;
99 return;
100 }
101 psinfo_t proc_psinfo;
102 if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
103 llwarns << "Unable to read " << path << llendl;
104 close(proc_fd);
105 return;
106 }
107
108 close(proc_fd);
109
110 mExecutableFilename = strdup(proc_psinfo.pr_fname);
111 llinfos << "mExecutableFilename = [" << mExecutableFilename << "]" << llendl;
112
113 sprintf(path, "/proc/%d/path/a.out", (int)getpid());
114
115 char execpath[LL_MAX_PATH];
116 if(readlink(path, execpath, LL_MAX_PATH) == -1){
117 llwarns << "Unable to read link from " << path << llendl;
118 return;
119 }
120
121 mExecutablePathAndName = strdup(execpath);
122 llinfos << "mExecutablePathAndName = [" << mExecutablePathAndName << "]" << llendl;
123
124 // plunk a null at last '/' to get exec dir
125 char *s = execpath + strlen(execpath) -1;
126 while(*s != '/' && s != execpath){
127 --s;
128 }
129
130 if(s != execpath){
131 *s = (char)NULL;
132
133 mExecutableDir = strdup(execpath);
134 llinfos << "mExecutableDir = [" << mExecutableDir << "]" << llendl;
135 }
136
137 // *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
138 mTempDir = "/tmp";
139}
140
141LLDir_Solaris::~LLDir_Solaris()
142{
143}
144
145// Implementation
146
147
148void LLDir_Solaris::initAppDirs(const std::string &app_name)
149{
150 mAppName = app_name;
151
152 LLString upper_app_name(app_name);
153 LLString::toUpper(upper_app_name);
154
155 char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */
156 if (app_home_env)
157 {
158 // user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
159 mOSUserAppDir = app_home_env;
160 }
161 else
162 {
163 // traditionally on unixoids, MyApp gets ~/.myapp dir for data
164 mOSUserAppDir = mOSUserDir;
165 mOSUserAppDir += "/";
166 mOSUserAppDir += ".";
167 LLString lower_app_name(app_name);
168 LLString::toLower(lower_app_name);
169 mOSUserAppDir += lower_app_name;
170 }
171
172 // create any directories we expect to write to.
173
174 int res = LLFile::mkdir(mOSUserAppDir.c_str());
175 if (res == -1)
176 {
177 if (errno != EEXIST)
178 {
179 llwarns << "Couldn't create app user dir " << mOSUserAppDir << llendl;
180 llwarns << "Default to base dir" << mOSUserDir << llendl;
181 mOSUserAppDir = mOSUserDir;
182 }
183 }
184
185 res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,"").c_str());
186 if (res == -1)
187 {
188 if (errno != EEXIST)
189 {
190 llwarns << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << llendl;
191 }
192 }
193
194 res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,"").c_str());
195 if (res == -1)
196 {
197 if (errno != EEXIST)
198 {
199 llwarns << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << llendl;
200 }
201 }
202
203 res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,"").c_str());
204 if (res == -1)
205 {
206 if (errno != EEXIST)
207 {
208 llwarns << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << llendl;
209 }
210 }
211
212 res = LLFile::mkdir(getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"").c_str());
213 if (res == -1)
214 {
215 if (errno != EEXIST)
216 {
217 llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl;
218 }
219 }
220
221 mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
222}
223
224U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string &mask)
225{
226 U32 file_count = 0;
227 glob_t g;
228
229 std::string tmp_str;
230 tmp_str = dirname;
231 tmp_str += mask;
232
233 if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
234 {
235 file_count = g.gl_pathc;
236
237 globfree(&g);
238 }
239
240 return (file_count);
241}
242
243// get the next file in the directory
244// automatically wrap if we've hit the end
245BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
246{
247 glob_t g;
248 BOOL result = FALSE;
249 fname = "";
250
251 if(!(dirname == mCurrentDir))
252 {
253 // different dir specified, close old search
254 mCurrentDirIndex = -1;
255 mCurrentDirCount = -1;
256 mCurrentDir = dirname;
257 }
258
259 std::string tmp_str;
260 tmp_str = dirname;
261 tmp_str += mask;
262
263 if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
264 {
265 if(g.gl_pathc > 0)
266 {
267 if((int)g.gl_pathc != mCurrentDirCount)
268 {
269 // Number of matches has changed since the last search, meaning a file has been added or deleted.
270 // Reset the index.
271 mCurrentDirIndex = -1;
272 mCurrentDirCount = g.gl_pathc;
273 }
274
275 mCurrentDirIndex++;
276
277 if((mCurrentDirIndex >= (int)g.gl_pathc) && wrap)
278 {
279 mCurrentDirIndex = 0;
280 }
281
282 if(mCurrentDirIndex < (int)g.gl_pathc)
283 {
284// llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
285
286 // The API wants just the filename, not the full path.
287 //fname = g.gl_pathv[mCurrentDirIndex];
288
289 char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
290
291 if(s == NULL)
292 s = g.gl_pathv[mCurrentDirIndex];
293 else if(s[0] == '/')
294 s++;
295
296 fname = s;
297
298 result = TRUE;
299 }
300 }
301
302 globfree(&g);
303 }
304
305 return(result);
306}
307
308
309// get a random file in the directory
310// automatically wrap if we've hit the end
311void LLDir_Solaris::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
312{
313 S32 num_files;
314 S32 which_file;
315 DIR *dirp;
316 dirent *entryp = NULL;
317
318 fname = "";
319
320 num_files = countFilesInDir(dirname,mask);
321 if (!num_files)
322 {
323 return;
324 }
325
326 which_file = ll_rand(num_files);
327
328// llinfos << "Random select file #" << which_file << llendl;
329
330 // which_file now indicates the (zero-based) index to which file to play
331
332 if (!((dirp = opendir(dirname.c_str()))))
333 {
334 while (which_file--)
335 {
336 if (!((entryp = readdir(dirp))))
337 {
338 return;
339 }
340 }
341
342 if ((!which_file) && entryp)
343 {
344 fname = entryp->d_name;
345 }
346
347 closedir(dirp);
348 }
349}
350
351std::string LLDir_Solaris::getCurPath()
352{
353 char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
354 getcwd(tmp_str, LL_MAX_PATH);
355 return tmp_str;
356}
357
358
359BOOL LLDir_Solaris::fileExists(const std::string &filename)
360{
361 struct stat stat_data;
362 // Check the age of the file
363 // Now, we see if the files we've gathered are recent...
364 int res = stat(filename.c_str(), &stat_data);
365 if (!res)
366 {
367 return TRUE;
368 }
369 else
370 {
371 return FALSE;
372 }
373}
374
diff --git a/linden/indra/llvfs/lldir_solaris.h b/linden/indra/llvfs/lldir_solaris.h
new file mode 100644
index 0000000..4a8feed
--- /dev/null
+++ b/linden/indra/llvfs/lldir_solaris.h
@@ -0,0 +1,61 @@
1/**
2 * @file fmodwrapper.cpp
3 * @brief dummy source file for building a shared library to wrap libfmod.a
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LL_LLDIR_SOLARIS_H
30#define LL_LLDIR_SOLARIS_H
31
32#include "lldir.h"
33
34#include <stdio.h>
35#include <dirent.h>
36#include <errno.h>
37
38class LLDir_Solaris : public LLDir
39{
40public:
41 LLDir_Solaris();
42 virtual ~LLDir_Solaris();
43
44 virtual void initAppDirs(const std::string &app_name);
45public:
46 virtual std::string getCurPath();
47 virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
48 virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap);
49 virtual void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
50 /*virtual*/ BOOL fileExists(const std::string &filename);
51
52private:
53 DIR *mDirp;
54 int mCurrentDirIndex;
55 int mCurrentDirCount;
56 std::string mCurrentDir;
57};
58
59#endif // LL_LLDIR_SOLARIS_H
60
61
diff --git a/linden/indra/llvfs/llvfs.cpp b/linden/indra/llvfs/llvfs.cpp
index dd5854c..a05d1b9 100644
--- a/linden/indra/llvfs/llvfs.cpp
+++ b/linden/indra/llvfs/llvfs.cpp
@@ -35,6 +35,10 @@
35#include <map> 35#include <map>
36#if LL_WINDOWS 36#if LL_WINDOWS
37#include <share.h> 37#include <share.h>
38#elif LL_SOLARIS
39#include <sys/types.h>
40#include <unistd.h>
41#include <fcntl.h>
38#else 42#else
39#include <sys/file.h> 43#include <sys/file.h>
40#endif 44#endif
@@ -379,13 +383,13 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r
379 ) 383 )
380 { 384 {
381 U8 *buffer = new U8[fbuf.st_size]; 385 U8 *buffer = new U8[fbuf.st_size];
382 fread(buffer, fbuf.st_size, 1, mIndexFP); 386 size_t nread = fread(buffer, 1, fbuf.st_size, mIndexFP);
383 387
384 U8 *tmp_ptr = buffer; 388 U8 *tmp_ptr = buffer;
385 389
386 std::vector<LLVFSFileBlock*> files_by_loc; 390 std::vector<LLVFSFileBlock*> files_by_loc;
387 391
388 while (tmp_ptr < buffer + fbuf.st_size) 392 while (tmp_ptr < buffer + nread)
389 { 393 {
390 LLVFSFileBlock *block = new LLVFSFileBlock(); 394 LLVFSFileBlock *block = new LLVFSFileBlock();
391 395
@@ -881,12 +885,18 @@ BOOL LLVFS::setMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type
881 // move the file into the new block 885 // move the file into the new block
882 U8 *buffer = new U8[block->mSize]; 886 U8 *buffer = new U8[block->mSize];
883 fseek(mDataFP, block->mLocation, SEEK_SET); 887 fseek(mDataFP, block->mLocation, SEEK_SET);
884 fread(buffer, block->mSize, 1, mDataFP); 888 if (fread(buffer, block->mSize, 1, mDataFP) == 1)
885 fseek(mDataFP, free_block->mLocation, SEEK_SET); 889 {
886 fwrite(buffer, block->mSize, 1, mDataFP); 890 fseek(mDataFP, free_block->mLocation, SEEK_SET);
887 // fflush(mDataFP); 891 if (fwrite(buffer, block->mSize, 1, mDataFP) != 1)
888 892 {
889 delete[] buffer; 893 llwarns << "Short write" << llendl;
894 }
895
896 delete[] buffer;
897 } else {
898 llwarns << "Short read" << llendl;
899 }
890 } 900 }
891 } 901 }
892 902
@@ -1486,7 +1496,7 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove)
1486 } 1496 }
1487 1497
1488 BOOL set_index_to_end = FALSE; 1498 BOOL set_index_to_end = FALSE;
1489 S32 seek_pos = block->mIndexLocation; 1499 long seek_pos = block->mIndexLocation;
1490 1500
1491 if (-1 == seek_pos) 1501 if (-1 == seek_pos)
1492 { 1502 {
@@ -1534,7 +1544,11 @@ void LLVFS::sync(LLVFSFileBlock *block, BOOL remove)
1534 fseek(mIndexFP, seek_pos, SEEK_SET); 1544 fseek(mIndexFP, seek_pos, SEEK_SET);
1535 } 1545 }
1536 1546
1537 fwrite(buffer, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP); 1547 if (fwrite(buffer, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP) != 1)
1548 {
1549 llwarns << "Short write" << llendl;
1550 }
1551
1538 // fflush(mIndexFP); 1552 // fflush(mIndexFP);
1539 1553
1540 lockData(); 1554 lockData();
@@ -1663,18 +1677,24 @@ void LLVFS::pokeFiles()
1663 // only write data if we actually read 4 bytes 1677 // only write data if we actually read 4 bytes
1664 // otherwise we're writing garbage and screwing up the file 1678 // otherwise we're writing garbage and screwing up the file
1665 fseek(mDataFP, 0, SEEK_SET); 1679 fseek(mDataFP, 0, SEEK_SET);
1666 if (fread(&word, 1, 4, mDataFP) == 4) 1680 if (fread(&word, sizeof(word), 1, mDataFP) == 1)
1667 { 1681 {
1668 fseek(mDataFP, 0, SEEK_SET); 1682 fseek(mDataFP, 0, SEEK_SET);
1669 fwrite(&word, 1, 4, mDataFP); 1683 if (fwrite(&word, sizeof(word), 1, mDataFP) != 1)
1684 {
1685 llwarns << "Could not write to data file" << llendl;
1686 }
1670 fflush(mDataFP); 1687 fflush(mDataFP);
1671 } 1688 }
1672 1689
1673 fseek(mIndexFP, 0, SEEK_SET); 1690 fseek(mIndexFP, 0, SEEK_SET);
1674 if (fread(&word, 1, 4, mIndexFP) == 4) 1691 if (fread(&word, sizeof(word), 1, mIndexFP) == 1)
1675 { 1692 {
1676 fseek(mIndexFP, 0, SEEK_SET); 1693 fseek(mIndexFP, 0, SEEK_SET);
1677 fwrite(&word, 1, 4, mIndexFP); 1694 if (fwrite(&word, sizeof(word), 1, mIndexFP) != 1)
1695 {
1696 llwarns << "Could not write to index file" << llendl;
1697 }
1678 fflush(mIndexFP); 1698 fflush(mIndexFP);
1679 } 1699 }
1680} 1700}
@@ -1709,21 +1729,26 @@ void LLVFS::audit()
1709 fflush(mIndexFP); 1729 fflush(mIndexFP);
1710 1730
1711 fseek(mIndexFP, 0, SEEK_END); 1731 fseek(mIndexFP, 0, SEEK_END);
1712 S32 index_size = ftell(mIndexFP); 1732 long index_size = ftell(mIndexFP);
1713 fseek(mIndexFP, 0, SEEK_SET); 1733 fseek(mIndexFP, 0, SEEK_SET);
1714 1734
1735 BOOL vfs_corrupt = FALSE;
1736
1715 U8 *buffer = new U8[index_size]; 1737 U8 *buffer = new U8[index_size];
1716 fread(buffer, index_size, 1, mIndexFP); 1738
1739 if (fread(buffer, 1, index_size, mIndexFP) != index_size)
1740 {
1741 llwarns << "Index truncated" << llendl;
1742 vfs_corrupt = TRUE;
1743 }
1717 1744
1718 U8 *tmp_ptr = buffer; 1745 U8 *tmp_ptr = buffer;
1719 1746
1720 std::map<LLVFSFileSpecifier, LLVFSFileBlock*> found_files; 1747 std::map<LLVFSFileSpecifier, LLVFSFileBlock*> found_files;
1721 U32 cur_time = (U32)time(NULL); 1748 U32 cur_time = (U32)time(NULL);
1722 1749
1723 BOOL vfs_corrupt = FALSE;
1724
1725 std::vector<LLVFSFileBlock*> audit_blocks; 1750 std::vector<LLVFSFileBlock*> audit_blocks;
1726 while (tmp_ptr < buffer + index_size) 1751 while (!vfs_corrupt && tmp_ptr < buffer + index_size)
1727 { 1752 {
1728 LLVFSFileBlock *block = new LLVFSFileBlock(); 1753 LLVFSFileBlock *block = new LLVFSFileBlock();
1729 audit_blocks.push_back(block); 1754 audit_blocks.push_back(block);
@@ -1803,7 +1828,11 @@ void LLVFS::audit()
1803 llwarns << "VFile " << block->mFileID << ":" << block->mFileType << " in memory, not on disk, loc " << block->mIndexLocation<< llendl; 1828 llwarns << "VFile " << block->mFileID << ":" << block->mFileType << " in memory, not on disk, loc " << block->mIndexLocation<< llendl;
1804 fseek(mIndexFP, block->mIndexLocation, SEEK_SET); 1829 fseek(mIndexFP, block->mIndexLocation, SEEK_SET);
1805 U8 buf[LLVFSFileBlock::SERIAL_SIZE]; 1830 U8 buf[LLVFSFileBlock::SERIAL_SIZE];
1806 fread(buf, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP); 1831 if (fread(buf, LLVFSFileBlock::SERIAL_SIZE, 1, mIndexFP) != 1)
1832 {
1833 llwarns << "VFile " << block->mFileID
1834 << " gave short read" << llendl;
1835 }
1807 1836
1808 LLVFSFileBlock disk_block; 1837 LLVFSFileBlock disk_block;
1809 disk_block.deserialize(buf, block->mIndexLocation); 1838 disk_block.deserialize(buf, block->mIndexLocation);
@@ -2116,6 +2145,12 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
2116 int fd; 2145 int fd;
2117 2146
2118 // first test the lock in a non-destructive way 2147 // first test the lock in a non-destructive way
2148#if LL_SOLARIS
2149 struct flock fl;
2150 fl.l_whence = SEEK_SET;
2151 fl.l_start = 0;
2152 fl.l_len = 1;
2153#else // !LL_SOLARIS
2119 if (strstr(mode, "w")) 2154 if (strstr(mode, "w"))
2120 { 2155 {
2121 fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ 2156 fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
@@ -2131,13 +2166,19 @@ FILE *LLVFS::openAndLock(const char *filename, const char *mode, BOOL read_lock)
2131 fclose(fp); 2166 fclose(fp);
2132 } 2167 }
2133 } 2168 }
2169#endif // !LL_SOLARIS
2134 2170
2135 // now actually open the file for use 2171 // now actually open the file for use
2136 fp = LLFile::fopen(filename, mode); /* Flawfinder: ignore */ 2172 fp = LLFile::fopen(filename, mode); /* Flawfinder: ignore */
2137 if (fp) 2173 if (fp)
2138 { 2174 {
2139 fd = fileno(fp); 2175 fd = fileno(fp);
2176#if LL_SOLARIS
2177 fl.l_type = read_lock ? F_RDLCK : F_WRLCK;
2178 if (fcntl(fd, F_SETLK, &fl) == -1)
2179#else
2140 if (flock(fd, (read_lock ? LOCK_SH : LOCK_EX) | LOCK_NB) == -1) 2180 if (flock(fd, (read_lock ? LOCK_SH : LOCK_EX) | LOCK_NB) == -1)
2181#endif
2141 { 2182 {
2142 fclose(fp); 2183 fclose(fp);
2143 fp = NULL; 2184 fp = NULL;
@@ -2165,7 +2206,14 @@ void LLVFS::unlockAndClose(FILE *fp)
2165 flock(fd, LOCK_UN); 2206 flock(fd, LOCK_UN);
2166 #endif 2207 #endif
2167 */ 2208 */
2168 2209#if LL_SOLARIS
2210 struct flock fl;
2211 fl.l_whence = SEEK_SET;
2212 fl.l_start = 0;
2213 fl.l_len = 1;
2214 fl.l_type = F_UNLCK;
2215 fcntl(fileno(fp), F_SETLK, &fl);
2216#endif
2169 fclose(fp); 2217 fclose(fp);
2170 } 2218 }
2171} 2219}
diff --git a/linden/indra/llwindow/files.sunos5.lst b/linden/indra/llwindow/files.sunos5.lst
new file mode 100644
index 0000000..ee20b05
--- /dev/null
+++ b/linden/indra/llwindow/files.sunos5.lst
@@ -0,0 +1,4 @@
1llwindow/llkeyboardsdl.cpp
2llwindow/llwindowsdl.cpp
3llwindow/llwindowsolaris.cpp
4llwindow/llwindowmesaheadless.cpp
diff --git a/linden/indra/llwindow/files.win32.lst b/linden/indra/llwindow/files.win32.lst
new file mode 100644
index 0000000..1abcb6e
--- /dev/null
+++ b/linden/indra/llwindow/files.win32.lst
@@ -0,0 +1,2 @@
1llwindow/llkeyboardwin32.cpp
2llwindow/llwindowwin32.cpp
diff --git a/linden/indra/llwindow/llglstubs.h b/linden/indra/llwindow/llglstubs.h
index 1d70400..fbbcd1f 100644
--- a/linden/indra/llwindow/llglstubs.h
+++ b/linden/indra/llwindow/llglstubs.h
@@ -222,7 +222,7 @@ GL_FUNC(void,glArrayObjectATI,(GLenum a, GLint b, GLenum c, GLsizei d, GLuint e,
222GL_FUNC(void,glVertexAttribArrayObjectATI,(GLuint a, GLint b, GLenum c, GLboolean d, GLsizei e, GLuint f, GLuint g),(a,b,c,d,e,f,g),) 222GL_FUNC(void,glVertexAttribArrayObjectATI,(GLuint a, GLint b, GLenum c, GLboolean d, GLsizei e, GLuint f, GLuint g),(a,b,c,d,e,f,g),)
223 223
224// CgGL needs these on Linux... 224// CgGL needs these on Linux...
225#if LL_LINUX 225#if LL_LINUX || LL_SOLARIS
226GL_FUNC(void*,glXGetCurrentDisplay,(void),(),return) 226GL_FUNC(void*,glXGetCurrentDisplay,(void),(),return)
227GL_FUNC(const char *,glXQueryExtensionsString,(void *dpy, int screen),(dpy,screen),return) 227GL_FUNC(const char *,glXQueryExtensionsString,(void *dpy, int screen),(dpy,screen),return)
228GL_FUNC(void*,glXGetProcAddressARB,(const GLubyte *fn),(fn),return) 228GL_FUNC(void*,glXGetProcAddressARB,(const GLubyte *fn),(fn),return)
diff --git a/linden/indra/llwindow/llwindowsdl.cpp b/linden/indra/llwindow/llwindowsdl.cpp
index 94111e7..b38d4d1 100644
--- a/linden/indra/llwindow/llwindowsdl.cpp
+++ b/linden/indra/llwindow/llwindowsdl.cpp
@@ -47,13 +47,13 @@ extern "C" {
47} 47}
48#endif // LL_GTK 48#endif // LL_GTK
49 49
50#if LL_LINUX 50#if LL_LINUX || LL_SOLARIS
51// not necessarily available on random SDL platforms, so #if LL_LINUX 51// not necessarily available on random SDL platforms, so #if LL_LINUX
52// for execv(), waitpid(), fork() 52// for execv(), waitpid(), fork()
53# include <unistd.h> 53# include <unistd.h>
54# include <sys/types.h> 54# include <sys/types.h>
55# include <sys/wait.h> 55# include <sys/wait.h>
56#endif // LL_LINUX 56#endif // LL_LINUX || LL_SOLARIS
57 57
58extern BOOL gDebugWindowProc; 58extern BOOL gDebugWindowProc;
59 59
@@ -349,6 +349,13 @@ static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str)
349 349
350static int x11_detect_VRAM_kb() 350static int x11_detect_VRAM_kb()
351{ 351{
352#if LL_SOLARIS
353#error Can this be done without an explicit architecture test, ie a test FOR xorg? Was followed by: && defined(__sparc)
354 // NOTE: there's no Xorg server on SPARC so just return 0
355 // and allow SDL to attempt to get the amount of VRAM
356 return(0);
357#else
358
352 std::string x_log_location("/var/log/"); 359 std::string x_log_location("/var/log/");
353 std::string fname; 360 std::string fname;
354 int rtn = 0; // 'could not detect' 361 int rtn = 0; // 'could not detect'
@@ -420,6 +427,7 @@ static int x11_detect_VRAM_kb()
420 } 427 }
421 } 428 }
422 return rtn; 429 return rtn;
430#endif // LL_SOLARIS
423} 431}
424#endif // LL_X11 432#endif // LL_X11
425 433
@@ -489,7 +497,24 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B
489 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 497 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
490 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); 498 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
491 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 499 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
500#if !LL_SOLARIS
492 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24); 501 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24);
502#else
503 // NOTE- use smaller Z-buffer to enable more graphics cards
504 // - This should not affect better GPUs and has been proven
505 // to provide 24-bit z-buffers when available.
506 //
507 // As the API states:
508 //
509 // GLX_DEPTH_SIZE Must be followed by a nonnegative
510 // minimum size specification. If this
511 // value is zero, visuals with no depth
512 // buffer are preferred. Otherwise, the
513 // largest available depth buffer of at
514 // least the minimum size is preferred.
515
516 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
517#endif
493 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, (bits <= 16) ? 1 : 8); 518 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, (bits <= 16) ? 1 : 8);
494 519
495 // *FIX: try to toggle vsync here? 520 // *FIX: try to toggle vsync here?
@@ -655,13 +680,26 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B
655 // fixme: actually, it's REALLY important for picking that we get at 680 // fixme: actually, it's REALLY important for picking that we get at
656 // least 8 bits each of red,green,blue. Alpha we can be a bit more 681 // least 8 bits each of red,green,blue. Alpha we can be a bit more
657 // relaxed about if we have to. 682 // relaxed about if we have to.
683#if LL_SOLARIS
684#error && defined(__sparc)
685 if(colorBits < 24) //HACK: on SPARC allow 24-bit color
686#else
658 if (colorBits < 32) 687 if (colorBits < 32)
688#endif
659 { 689 {
660 close(); 690 close();
661 setupFailure( 691 setupFailure(
692#if LL_SOLARIS
693#error && defined(__sparc)
694 "Second Life requires at least 24-bit color on SPARC to run in a window.\n"
695 "Please use fbconfig to set your default color depth to 24 bits.\n"
696 "You may also need to adjust the X11 setting in SMF. To do so use\n"
697 " 'svccfg -s svc:/application/x11/x11-server setprop options/default_depth=24'\n"
698#else
662 "Second Life requires True Color (32-bit) to run in a window.\n" 699 "Second Life requires True Color (32-bit) to run in a window.\n"
663 "Please go to Control Panels -> Display -> Settings and\n" 700 "Please go to Control Panels -> Display -> Settings and\n"
664 "set the screen to 32-bit color.\n" 701 "set the screen to 32-bit color.\n"
702#endif
665 "Alternately, if you choose to run fullscreen, Second Life\n" 703 "Alternately, if you choose to run fullscreen, Second Life\n"
666 "will automatically adjust the screen each time it runs.", 704 "will automatically adjust the screen each time it runs.",
667 "Error", 705 "Error",
@@ -2657,7 +2695,7 @@ void spawn_web_browser(const char* escaped_url)
2657{ 2695{
2658 llinfos << "spawn_web_browser: " << escaped_url << llendl; 2696 llinfos << "spawn_web_browser: " << escaped_url << llendl;
2659 2697
2660#if LL_LINUX 2698#if LL_LINUX || LL_SOLARIS
2661# if LL_X11 2699# if LL_X11
2662 if (gWindowImplementation && gWindowImplementation->mSDL_Display) 2700 if (gWindowImplementation && gWindowImplementation->mSDL_Display)
2663 { 2701 {
@@ -2697,7 +2735,7 @@ void spawn_web_browser(const char* escaped_url)
2697 llwarns << "fork failure." << llendl; 2735 llwarns << "fork failure." << llendl;
2698 } 2736 }
2699 } 2737 }
2700#endif // LL_LINUX 2738#endif // LL_LINUX || LL_SOLARIS
2701 2739
2702 llinfos << "spawn_web_browser returning." << llendl; 2740 llinfos << "spawn_web_browser returning." << llendl;
2703} 2741}
diff --git a/linden/indra/llwindow/llwindowsolaris.cpp b/linden/indra/llwindow/llwindowsolaris.cpp
new file mode 100644
index 0000000..7e3c3e6
--- /dev/null
+++ b/linden/indra/llwindow/llwindowsolaris.cpp
@@ -0,0 +1,58 @@
1/**
2 * @file fmodwrapper.cpp
3 * @brief dummy source file for building a shared library to wrap libfmod.a
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#if LL_SOLARIS
30
31#include "linden_common.h"
32#include "indra_constants.h"
33
34#include "llwindowsolaris.h"
35#include "llgl.h"
36#include "llglheaders.h"
37
38//
39// LLWindowSolaris
40//
41LLWindowSolaris::LLWindowSolaris(char *title, char *name, S32 x, S32 y, S32 width, S32 height,
42 U32 flags, BOOL fullscreen, BOOL clearBg,
43 BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth)
44 : LLWindow(fullscreen, flags)
45{
46 llerrs << "Solaris window not yet supported" << llendl;
47}
48
49
50LLWindowSolaris::~LLWindowSolaris()
51{
52}
53
54void LLWindowSolaris::swapBuffers()
55{
56}
57
58#endif // LL_SOLARIS
diff --git a/linden/indra/llwindow/llwindowsolaris.h b/linden/indra/llwindow/llwindowsolaris.h
new file mode 100644
index 0000000..57aa9b9
--- /dev/null
+++ b/linden/indra/llwindow/llwindowsolaris.h
@@ -0,0 +1,116 @@
1/**
2 * @file fmodwrapper.cpp
3 * @brief dummy source file for building a shared library to wrap libfmod.a
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LL_LLWINDOWSOLARIS_H
30#define LL_LLWINDOWSOLARIS_H
31
32#include "llwindow.h"
33
34class LLWindowSolaris : public LLWindow
35{
36public:
37 /*virtual*/ void show() {};
38 /*virtual*/ void hide() {};
39 /*virtual*/ void close() {};
40 /*virtual*/ BOOL getVisible() {return FALSE;};
41 /*virtual*/ BOOL getMinimized() {return FALSE;};
42 /*virtual*/ BOOL getMaximized() {return FALSE;};
43 /*virtual*/ BOOL maximize() {return FALSE;};
44 /*virtual*/ BOOL getFullscreen() {return FALSE;};
45 /*virtual*/ BOOL getPosition(LLCoordScreen *position) {return FALSE;};
46 /*virtual*/ BOOL getSize(LLCoordScreen *size) {return FALSE;};
47 /*virtual*/ BOOL getSize(LLCoordWindow *size) {return FALSE;};
48 /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;};
49 /*virtual*/ BOOL setSize(LLCoordScreen size) {return FALSE;};
50 /*virtual*/ BOOL switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync) {return FALSE;};
51 /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;};
52 /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;};
53 /*virtual*/ void showCursor() {};
54 /*virtual*/ void hideCursor() {};
55 /*virtual*/ void showCursorFromMouseMove() {};
56 /*virtual*/ void hideCursorUntilMouseMove() {};
57 /*virtual*/ BOOL isCursorHidden() {return FALSE;};
58 /*virtual*/ void setCursor(ECursorType cursor) {};
59 //virtual ECursorType getCursor() { return mCurrentCursor; };
60 /*virtual*/ void captureMouse() {};
61 /*virtual*/ void releaseMouse() {};
62 /*virtual*/ void setMouseClipping( BOOL b ) {};
63 /*virtual*/ BOOL isClipboardTextAvailable() {return FALSE; };
64 /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) {return FALSE; };
65 /*virtual*/ BOOL copyTextToClipboard(const LLWString &src) {return FALSE; };
66 /*virtual*/ void flashIcon(F32 seconds) {};
67 /*virtual*/ F32 getGamma() {return 1.0f; };
68 /*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma
69 /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma)
70 //virtual ESwapMethod getSwapMethod() { return mSwapMethod; }
71 /*virtual*/ void gatherInput() {};
72 /*virtual*/ void delayInputProcessing() {};
73 /*virtual*/ void swapBuffers();
74
75 /*virtual*/ LLString getTempFileName() {return LLString(""); };
76 /*virtual*/ void deleteFile( const char* file_name ) {};
77 /*virtual*/ S32 stat( const char* file_name, struct stat* stat_info ) {return 0; };
78 /*virtual*/ BOOL sendEmail(const char* address,const char* subject,const char* body_text,const char* attachment=NULL, const char* attachment_displayed_name=NULL) { return FALSE; };
79
80
81 // handy coordinate space conversion routines
82 /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) { return FALSE; };
83 /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) { return FALSE; };
84 /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) { return FALSE; };
85 /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) { return FALSE; };
86 /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) { return FALSE; };
87 /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) { return FALSE; };
88
89 /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) { return NULL; };
90 /*virtual*/ F32 getNativeAspectRatio() { return 1.0f; };
91 /*virtual*/ F32 getPixelAspectRatio() { return 1.0f; };
92 /*virtual*/ void setNativeAspectRatio(F32 ratio) {}
93
94 //virtual BOOL dialog_color_picker (F32 *r, F32 *g, F32 *b );
95
96 /*virtual*/ void *getPlatformWindow() { return NULL; }
97
98 LLWindowSolaris(char *title, char *name, S32 x, S32 y, S32 width, S32 height,
99 U32 flags, BOOL fullscreen, BOOL clearBg,
100 BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth);
101 ~LLWindowSolaris();
102};
103
104class LLSplashScreenLinux : public LLSplashScreen
105{
106public:
107 LLSplashScreenLinux() {};
108 virtual ~LLSplashScreenLinux() {};
109
110 /*virtual*/ void showImpl() {};
111 /*virtual*/ void updateImpl(const char* mesg) {};
112 /*virtual*/ void hideImpl() {};
113
114};
115
116#endif //LL_LLWINDOWSOLARIS_H
diff --git a/linden/indra/llwindow/llwindowwin32.cpp b/linden/indra/llwindow/llwindowwin32.cpp
index 0b3cdd4..3a41d01 100644
--- a/linden/indra/llwindow/llwindowwin32.cpp
+++ b/linden/indra/llwindow/llwindowwin32.cpp
@@ -1585,6 +1585,11 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre
1585 } 1585 }
1586 } 1586 }
1587 1587
1588 // if the window was already maximized, MoveWindow seems to still set the maximized flag even if
1589 // the window is smaller than maximized.
1590 // So we're going to do a restore first (which is a ShowWindow call) (SL-44655).
1591 ShowWindow(mWindowHandle, SW_RESTORE);
1592 // NOW we can call MoveWindow
1588 MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE); 1593 MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE);
1589} 1594}
1590 1595
@@ -2289,6 +2294,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
2289 << llendl; 2294 << llendl;
2290 } 2295 }
2291 2296
2297 // There's an odd behavior with WM_SIZE that I would call a bug. If
2298 // the window is maximized, and you call MoveWindow() with a size smaller
2299 // than a maximized window, it ends up sending WM_SIZE with w_param set
2300 // to SIZE_MAXIMIZED -- which isn't true. So the logic below doesn't work.
2301 // (SL-44655). Fixed it by calling ShowWindow(SW_RESTORE) first (see
2302 // LLWindowWin32::moveWindow in this file).
2303
2292 // If we are now restored, but we weren't before, this 2304 // If we are now restored, but we weren't before, this
2293 // means that the window was un-minimized. 2305 // means that the window was un-minimized.
2294 if (w_param == SIZE_RESTORED && window_imp->mLastSizeWParam != SIZE_RESTORED) 2306 if (w_param == SIZE_RESTORED && window_imp->mLastSizeWParam != SIZE_RESTORED)
diff --git a/linden/indra/llxml/llxmlnode.cpp b/linden/indra/llxml/llxmlnode.cpp
index bdbb606..8a267a5 100644
--- a/linden/indra/llxml/llxmlnode.cpp
+++ b/linden/indra/llxml/llxmlnode.cpp
@@ -580,11 +580,11 @@ bool LLXMLNode::parseFile(
580 fseek(fp, 0, SEEK_SET); 580 fseek(fp, 0, SEEK_SET);
581 581
582 U8* buffer = new U8[length+1]; 582 U8* buffer = new U8[length+1];
583 fread(buffer, 1, length, fp); 583 size_t nread = fread(buffer, 1, length, fp);
584 buffer[length] = 0; 584 buffer[nread] = 0;
585 fclose(fp); 585 fclose(fp);
586 586
587 bool rv = parseBuffer(buffer, length, node, defaults_tree); 587 bool rv = parseBuffer(buffer, nread, node, defaults_tree);
588 delete [] buffer; 588 delete [] buffer;
589 return rv; 589 return rv;
590} 590}
@@ -754,7 +754,10 @@ void LLXMLNode::writeToFile(FILE *fOut, LLString indent)
754 std::ostringstream ostream; 754 std::ostringstream ostream;
755 writeToOstream(ostream, indent); 755 writeToOstream(ostream, indent);
756 LLString outstring = ostream.str(); 756 LLString outstring = ostream.str();
757 fwrite(outstring.c_str(), 1, outstring.length(), fOut); 757 if (fwrite(outstring.c_str(), 1, outstring.length(), fOut) != outstring.length())
758 {
759 llwarns << "Short write" << llendl;
760 }
758} 761}
759 762
760void LLXMLNode::writeToOstream(std::ostream& output_stream, const LLString& indent) 763void LLXMLNode::writeToOstream(std::ostream& output_stream, const LLString& indent)
diff --git a/linden/indra/llxml/llxmlnode.h b/linden/indra/llxml/llxmlnode.h
index 3c338e2..e0e8f2f 100644
--- a/linden/indra/llxml/llxmlnode.h
+++ b/linden/indra/llxml/llxmlnode.h
@@ -30,7 +30,11 @@
30#define LL_LLXMLNODE_H 30#define LL_LLXMLNODE_H
31 31
32#define XML_STATIC 32#define XML_STATIC
33#ifdef LL_STANDALONE
34#include <expat.h>
35#else
33#include "expat/expat.h" 36#include "expat/expat.h"
37#endif
34#include <map> 38#include <map>
35 39
36#include "indra_constants.h" 40#include "indra_constants.h"
diff --git a/linden/indra/llxml/llxmlparser.h b/linden/indra/llxml/llxmlparser.h
index 307a34f..7904175 100644
--- a/linden/indra/llxml/llxmlparser.h
+++ b/linden/indra/llxml/llxmlparser.h
@@ -30,7 +30,11 @@
30#define LL_LLXMLPARSER_H 30#define LL_LLXMLPARSER_H
31 31
32#define XML_STATIC 32#define XML_STATIC
33#ifdef LL_STANDALONE
34#include <expat.h>
35#else
33#include "expat/expat.h" 36#include "expat/expat.h"
37#endif
34 38
35class LLXmlParser 39class LLXmlParser
36{ 40{
diff --git a/linden/indra/lscript/lscript_compile/indra.l b/linden/indra/lscript/lscript_compile/indra.l
index c219cec..0beffe5 100644
--- a/linden/indra/lscript/lscript_compile/indra.l
+++ b/linden/indra/lscript/lscript_compile/indra.l
@@ -1,3 +1,4 @@
1
1N [0-9] 2N [0-9]
2L [a-zA-Z_] 3L [a-zA-Z_]
3H [a-fA-F0-9] 4H [a-fA-F0-9]
@@ -41,6 +42,12 @@ void parse_string();
41#define YYLMAX 16384 42#define YYLMAX 16384
42#define YY_NEVER_INTERACTIVE 1 /* stops flex from calling isatty() */ 43#define YY_NEVER_INTERACTIVE 1 /* stops flex from calling isatty() */
43 44
45#ifdef ECHO
46#undef ECHO
47#endif
48
49#define ECHO do { } while (0)
50
44#if defined(__cplusplus) 51#if defined(__cplusplus)
45extern "C" { int yylex( void ); } 52extern "C" { int yylex( void ); }
46extern "C" { int yyparse( void ); } 53extern "C" { int yyparse( void ); }
@@ -750,7 +757,7 @@ BOOL lscript_compile(char *filename, BOOL is_god_like = FALSE)
750 757
751S32 yywrap() 758S32 yywrap()
752{ 759{
753#ifdef FLEX_SCANNER 760#if defined(FLEX_SCANNER) && !defined(LL_WINDOWS)
754 // get gcc to stop complaining about lack of use of yyunput 761 // get gcc to stop complaining about lack of use of yyunput
755 (void) yyunput; 762 (void) yyunput;
756#endif 763#endif
diff --git a/linden/indra/lscript/lscript_compile/indra.y b/linden/indra/lscript/lscript_compile/indra.y
index c7a4fd6..49d0c38 100644
--- a/linden/indra/lscript/lscript_compile/indra.y
+++ b/linden/indra/lscript/lscript_compile/indra.y
@@ -15,6 +15,10 @@
15 #define getenv getenv_workaround 15 #define getenv getenv_workaround
16 #endif 16 #endif
17 17
18 #ifdef LL_WINDOWS
19 #pragma warning( disable : 4065 ) // warning: switch statement contains 'default' but no 'case' labels
20 #endif
21
18 #ifdef __cplusplus 22 #ifdef __cplusplus
19 } 23 }
20 #endif 24 #endif
diff --git a/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp b/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp
index a1ea22b..0d75eee 100644
--- a/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp
+++ b/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp
@@ -308,7 +308,10 @@ void LLScriptScriptCodeChunk::build(FILE *efp, FILE *bcfp)
308 set_register(mCompleteCode, LREG_TM, mTotalSize); 308 set_register(mCompleteCode, LREG_TM, mTotalSize);
309 309
310 310
311 fwrite(mCompleteCode, 1, mTotalSize, bcfp); 311 if (fwrite(mCompleteCode, 1, mTotalSize, bcfp) != mTotalSize)
312 {
313 llwarns << "Short write" << llendl;
314 }
312 } 315 }
313 else 316 else
314 { 317 {
diff --git a/linden/indra/lscript/lscript_execute/lscript_execute.cpp b/linden/indra/lscript/lscript_execute/lscript_execute.cpp
index 2f81416..9e8be15 100644
--- a/linden/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/linden/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -63,11 +63,19 @@ LLScriptExecute::LLScriptExecute(FILE *fp)
63 U8 sizearray[4]; 63 U8 sizearray[4];
64 S32 filesize; 64 S32 filesize;
65 S32 pos = 0; 65 S32 pos = 0;
66 fread(&sizearray, 1, 4, fp); 66 if (fread(&sizearray, 1, 4, fp) != 4)
67 filesize = bytestream2integer(sizearray, pos); 67 {
68 llwarns << "Short read" << llendl;
69 filesize = 0;
70 } else {
71 filesize = bytestream2integer(sizearray, pos);
72 }
68 mBuffer = new U8[filesize]; 73 mBuffer = new U8[filesize];
69 fseek(fp, 0, SEEK_SET); 74 fseek(fp, 0, SEEK_SET);
70 fread(mBuffer, 1, filesize, fp); 75 if (fread(mBuffer, 1, filesize, fp) != filesize)
76 {
77 llwarns << "Short read" << llendl;
78 }
71 fclose(fp); 79 fclose(fp);
72 80
73 init(); 81 init();
diff --git a/linden/indra/lscript/lscript_execute/lscript_readlso.cpp b/linden/indra/lscript/lscript_execute/lscript_readlso.cpp
index 077e47c..f84abc5 100644
--- a/linden/indra/lscript/lscript_execute/lscript_readlso.cpp
+++ b/linden/indra/lscript/lscript_execute/lscript_readlso.cpp
@@ -37,11 +37,19 @@ LLScriptLSOParse::LLScriptLSOParse(FILE *fp)
37 U8 sizearray[4]; 37 U8 sizearray[4];
38 S32 filesize; 38 S32 filesize;
39 S32 pos = 0; 39 S32 pos = 0;
40 fread(&sizearray, 1, 4, fp); 40 if (fread(&sizearray, 1, 4, fp) != 4)
41 filesize = bytestream2integer(sizearray, pos); 41 {
42 llwarns << "Short read" << llendl;
43 filesize = 0;
44 } else {
45 filesize = bytestream2integer(sizearray, pos);
46 }
42 mRawData = new U8[filesize]; 47 mRawData = new U8[filesize];
43 fseek(fp, 0, SEEK_SET); 48 fseek(fp, 0, SEEK_SET);
44 fread(mRawData, 1, filesize, fp); 49 if (fread(mRawData, 1, filesize, fp) != filesize)
50 {
51 llwarns << "Short read" << llendl;
52 }
45 53
46 initOpCodePrinting(); 54 initOpCodePrinting();
47} 55}
diff --git a/linden/indra/mac_updater/mac_updater.cpp b/linden/indra/mac_updater/mac_updater.cpp
index a30f024..659fbf4a 100644
--- a/linden/indra/mac_updater/mac_updater.cpp
+++ b/linden/indra/mac_updater/mac_updater.cpp
@@ -991,10 +991,12 @@ void *updatethreadproc(void*)
991 if(len < sizeof(temp)-1) 991 if(len < sizeof(temp)-1)
992 { 992 {
993 // End of file or error. 993 // End of file or error.
994 if(pclose(mounter) != 0) 994 int result = pclose(mounter);
995 if(result != 0)
995 { 996 {
996 llinfos << "Failed to mount disk image, exiting."<< llendl; 997 // NOTE: We used to abort here, but pclose() started returning
997 throw 0; 998 // -1, possibly when the size of the DMG passed a certain point
999 llinfos << "Unexpected result closing pipe: " << result << llendl;
998 } 1000 }
999 mounter = NULL; 1001 mounter = NULL;
1000 } 1002 }
@@ -1020,6 +1022,7 @@ void *updatethreadproc(void*)
1020 else 1022 else
1021 { 1023 {
1022 llinfos << "Disk image device node not found!" << llendl; 1024 llinfos << "Disk image device node not found!" << llendl;
1025 throw 0;
1023 } 1026 }
1024 1027
1025 // Get an FSRef to the new application on the disk image 1028 // Get an FSRef to the new application on the disk image
diff --git a/linden/indra/newview/English.lproj/InfoPlist.strings b/linden/indra/newview/English.lproj/InfoPlist.strings
index bc1c7dd..aa9b6c0 100644
--- a/linden/indra/newview/English.lproj/InfoPlist.strings
+++ b/linden/indra/newview/English.lproj/InfoPlist.strings
@@ -1,5 +1,5 @@
1/* Localized versions of Info.plist keys */ 1/* Localized versions of Info.plist keys */
2 2
3CFBundleName = "Second Life"; 3CFBundleName = "Second Life";
4CFBundleShortVersionString = "Second Life version 1.18.0.6"; 4CFBundleShortVersionString = "Second Life version 1.18.1.2";
5CFBundleGetInfoString = "Second Life version 1.18.0.6, Copyright 2004-2007 Linden Research, Inc."; 5CFBundleGetInfoString = "Second Life version 1.18.1.2, Copyright 2004-2007 Linden Research, Inc.";
diff --git a/linden/indra/newview/Info-SecondLife.plist b/linden/indra/newview/Info-SecondLife.plist
index f4dd8e0..91d1849 100644
--- a/linden/indra/newview/Info-SecondLife.plist
+++ b/linden/indra/newview/Info-SecondLife.plist
@@ -32,7 +32,7 @@
32 </dict> 32 </dict>
33 </array> 33 </array>
34 <key>CFBundleVersion</key> 34 <key>CFBundleVersion</key>
35 <string>1.18.0.6</string> 35 <string>1.18.1.2</string>
36 <key>CSResourcesFileMapped</key> 36 <key>CSResourcesFileMapped</key>
37 <true/> 37 <true/>
38</dict> 38</dict>
diff --git a/linden/indra/newview/fakevoicesoundsignal.cpp b/linden/indra/newview/fakevoicesoundsignal.cpp
new file mode 100644
index 0000000..2a271ad
--- /dev/null
+++ b/linden/indra/newview/fakevoicesoundsignal.cpp
@@ -0,0 +1,49 @@
1//----------------------------------------------------------------------
2// Fake Voice Sound Signal
3// author: JJ Ventrella
4// THIS IS A TEMPORARY FILE FOR DEVELOPMENT PURPOSES ONLY
5//----------------------------------------------------------------------
6
7#include "llviewerprecompiledheaders.h"
8#include "fakevoicesoundsignal.h"
9
10//-----------------------------------------------
11// constructor
12//-----------------------------------------------
13FakeVoiceSoundSignal::FakeVoiceSoundSignal()
14{
15}//---------------------------------------------------
16
17
18//-----------------------------------------------
19// destructor
20//-----------------------------------------------
21FakeVoiceSoundSignal::~FakeVoiceSoundSignal()
22{
23}//---------------------------------------------------
24
25//---------------------------------------------------
26F32 FakeVoiceSoundSignal::getAmplitude()
27{
28 return 0.0;
29
30}//---------------------------------------------------
31
32
33//---------------------------------------------------
34bool FakeVoiceSoundSignal::getActive()
35{
36 return false;
37
38}//---------------------------------------------------
39
40
41//---------------------------------------------------
42void FakeVoiceSoundSignal::update()
43{
44
45}//---------------------------------------------------
46
47
48
49
diff --git a/linden/indra/newview/fakevoicesoundsignal.h b/linden/indra/newview/fakevoicesoundsignal.h
new file mode 100644
index 0000000..9e0132c
--- /dev/null
+++ b/linden/indra/newview/fakevoicesoundsignal.h
@@ -0,0 +1,25 @@
1//--------------------------------------------------------------------
2// Fake Voice Sound Signal
3// author: JJ Ventrella
4// THIS IS A TEMPORARY FILE FOR DEVELOPMENT PURPOSES ONLY
5//-----------------------------------------------------------------------------
6#ifndef FAKE_VOICE_SOUND_SIGNAL_H
7#define FAKE_VOICE_SOUND_SIGNAL_H
8
9//----------------------------------------------------------------------------
10// FakeVoiceSoundSignal
11//----------------------------------------------------------------------------
12class FakeVoiceSoundSignal
13{
14 public:
15 FakeVoiceSoundSignal();
16 ~FakeVoiceSoundSignal();
17 void update();
18 F32 getAmplitude();
19 bool getActive();
20
21};//-----------------------------------------------------------------
22 // end of class
23//------------------------------------------------------------------
24
25#endif //FAKE_VOICE_SOUND_SIGNAL_H
diff --git a/linden/indra/newview/featuretable_solaris.txt b/linden/indra/newview/featuretable_solaris.txt
new file mode 100644
index 0000000..6c7acfa
--- /dev/null
+++ b/linden/indra/newview/featuretable_solaris.txt
@@ -0,0 +1,173 @@
1version 10
2
3// NOTE: This is mostly identical to featuretable.txt with a few differences
4// Should be combined into one table
5
6//
7// Generates lists of feature mask that can be applied on top of each other.
8//
9// // Begin comments
10// list <name>
11// Starts a feature list named <name>
12// <name> <available> <recommended>
13// <name> is the name of a feature
14// <available> is 0 or 1, whether the feature is available
15// <recommended> is an S32 which is the recommended value
16//
17// For now, the first list read sets up all of the default values
18//
19
20
21//
22// All contains everything at their default settings for high end machines
23// NOTE: All settings are set to the MIN of applied values, including 'all'!
24//
25list all
26RenderVBO 1 1
27RenderAniso 1 0
28RenderAvatarMode 1 2
29RenderAvatarVP 1 1
30RenderDistance 1 128
31RenderLighting 1 1
32RenderObjectBump 1 1
33RenderParticleCount 1 4096
34RenderRippleWater 1 1
35RenderTerrainDetail 1 2
36VertexShaderEnable 1 1
37
38//
39// Class 0 Hardware (Unknown or just old)
40//
41list Class0
42VertexShaderEnable 1 0
43RenderVBO 1 0
44RenderDistance 1 64
45RenderAvatarVP 1 0
46RenderAvatarMode 1 0
47RenderLighting 1 0
48RenderObjectBump 1 0
49RenderRippleWater 1 0
50
51//
52// Class 1 Hardware
53//
54list Class1
55VertexShaderEnable 1 0
56RenderVBO 1 1
57RenderDistance 1 96
58RenderAvatarVP 1 1
59RenderAvatarMode 1 0
60RenderLighting 1 0
61RenderObjectBump 1 0
62RenderRippleWater 1 0
63
64//
65// Class 2 Hardware (make it purty)
66//
67list Class2
68VertexShaderEnable 1 1
69RenderAvatarVP 1 1
70RenderAvatarMode 1 1
71RenderLighting 1 1
72RenderObjectBump 1 1
73RenderRippleWater 1 1
74
75//
76// Class 3 Hardware (make it purty)
77//
78list Class3
79VertexShaderEnable 1 1
80RenderAvatarVP 1 1
81RenderAvatarMode 1 1
82RenderLighting 1 1
83RenderObjectBump 1 1
84RenderRippleWater 1 1
85
86//
87// No Pixel Shaders available
88//
89list NoPixelShaders
90VertexShaderEnable 0 0
91RenderAvatarVP 0 0
92
93//
94// No Vertex Shaders available
95//
96list NoVertexShaders
97VertexShaderEnable 0 0
98RenderAvatarVP 0 0
99
100//
101// "Default" setups for safe, low, medium, high
102//
103list safe
104RenderVBO 1 0
105RenderAniso 1 0
106RenderAvatarVP 0 0
107RenderLighting 1 0
108RenderParticleCount 1 1024
109RenderTerrainDetail 1 0
110
111
112list low
113RenderVBO 1 0
114RenderAniso 1 0
115RenderLighting 1 0
116
117list medium
118RenderLighting 1 0
119
120
121//
122// CPU based feature masks
123//
124
125// 1Ghz or less (equiv)
126list CPUSlow
127RenderParticleCount 1 1024
128
129
130//
131// RAM based feature masks
132//
133list RAM256MB
134RenderObjectBump 0 0
135
136
137//
138// Graphics card based feature masks
139//
140list OpenGLPre15
141RenderVBO 1 0
142
143list Intel
144RenderVBO 1 0
145RenderAniso 1 0
146RenderLighting 1 0
147RenderTerrainDetail 1 0
148
149list GeForce2
150RenderVBO 1 1
151RenderAniso 1 0
152RenderLighting 1 0
153RenderParticleCount 1 2048
154RenderTerrainDetail 1 0
155
156list GeForce3
157
158list ATI
159
160list Radeon8500
161RenderLighting 1 0
162RenderParticleCount 1 4096
163
164// Hacked to be paranoid "safe"
165list Radeon9700
166RenderParticleCount 1 4096
167
168// Hacked to be paranoid "safe"
169list MobilityRadeon9000
170RenderLighting 1 0
171RenderParticleCount 1 4096
172
173list GeForceFX
diff --git a/linden/indra/newview/files.lst b/linden/indra/newview/files.lst
index 6c51893..a5c348c 100644
--- a/linden/indra/newview/files.lst
+++ b/linden/indra/newview/files.lst
@@ -6,7 +6,6 @@ newview/llanimalcontrols.cpp
6newview/llassetuploadresponders.cpp 6newview/llassetuploadresponders.cpp
7newview/llasynchostbyname.cpp 7newview/llasynchostbyname.cpp
8newview/llaudiosourcevo.cpp 8newview/llaudiosourcevo.cpp
9newview/llaudiostatus.cpp
10newview/llbbox.cpp 9newview/llbbox.cpp
11newview/llbox.cpp 10newview/llbox.cpp
12newview/llcallbacklist.cpp 11newview/llcallbacklist.cpp
@@ -56,6 +55,7 @@ newview/llfilepicker.cpp
56newview/llfirstuse.cpp 55newview/llfirstuse.cpp
57newview/llflexibleobject.cpp 56newview/llflexibleobject.cpp
58newview/llfloaterabout.cpp 57newview/llfloaterabout.cpp
58newview/llfloateractivespeakers.cpp
59newview/llfloateranimpreview.cpp 59newview/llfloateranimpreview.cpp
60newview/llfloaterauction.cpp 60newview/llfloaterauction.cpp
61newview/llfloateravatarinfo.cpp 61newview/llfloateravatarinfo.cpp
@@ -68,6 +68,7 @@ newview/llfloaterbuy.cpp
68newview/llfloaterbuycurrency.cpp 68newview/llfloaterbuycurrency.cpp
69newview/llfloaterbuyland.cpp 69newview/llfloaterbuyland.cpp
70newview/llfloaterchat.cpp 70newview/llfloaterchat.cpp
71newview/llfloaterchatterbox.cpp
71newview/llfloaterclothing.cpp 72newview/llfloaterclothing.cpp
72newview/llfloatercolorpicker.cpp 73newview/llfloatercolorpicker.cpp
73newview/llfloatercustomize.cpp 74newview/llfloatercustomize.cpp
@@ -107,6 +108,7 @@ newview/llfloatertest.cpp
107newview/llfloatertools.cpp 108newview/llfloatertools.cpp
108newview/llfloatertopobjects.cpp 109newview/llfloatertopobjects.cpp
109newview/llfloatertos.cpp 110newview/llfloatertos.cpp
111newview/llfloatervoicewizard.cpp
110newview/llfloaterworldmap.cpp 112newview/llfloaterworldmap.cpp
111newview/llfolderview.cpp 113newview/llfolderview.cpp
112newview/llfollowcam.cpp 114newview/llfollowcam.cpp
@@ -162,6 +164,7 @@ newview/llnetmap.cpp
162newview/llnotify.cpp 164newview/llnotify.cpp
163newview/lloverlaybar.cpp 165newview/lloverlaybar.cpp
164newview/llpanelaudioprefs.cpp 166newview/llpanelaudioprefs.cpp
167newview/llpanelaudiovolume.cpp
165newview/llpanelavatar.cpp 168newview/llpanelavatar.cpp
166newview/llpanelclassified.cpp 169newview/llpanelclassified.cpp
167newview/llpanelcontents.cpp 170newview/llpanelcontents.cpp
@@ -206,6 +209,7 @@ newview/llpolymesh.cpp
206newview/llpolymorph.cpp 209newview/llpolymorph.cpp
207newview/llprefschat.cpp 210newview/llprefschat.cpp
208newview/llprefsim.cpp 211newview/llprefsim.cpp
212newview/llprefsvoice.cpp
209newview/llpreviewanim.cpp 213newview/llpreviewanim.cpp
210newview/llpreview.cpp 214newview/llpreview.cpp
211newview/llpreviewgesture.cpp 215newview/llpreviewgesture.cpp
@@ -275,6 +279,9 @@ newview/llviewerinventory.cpp
275newview/llviewerjointattachment.cpp 279newview/llviewerjointattachment.cpp
276newview/llviewerjoint.cpp 280newview/llviewerjoint.cpp
277newview/llviewerjointmesh.cpp 281newview/llviewerjointmesh.cpp
282newview/llviewerjointmesh_sse.cpp
283newview/llviewerjointmesh_sse2.cpp
284newview/llviewerjointmesh_vec.cpp
278newview/llviewerjointshape.cpp 285newview/llviewerjointshape.cpp
279newview/llviewerjoystick.cpp 286newview/llviewerjoystick.cpp
280newview/llviewerkeyboard.cpp 287newview/llviewerkeyboard.cpp
@@ -305,8 +312,10 @@ newview/llvocache.cpp
305newview/llvoclouds.cpp 312newview/llvoclouds.cpp
306newview/llvograss.cpp 313newview/llvograss.cpp
307newview/llvoground.cpp 314newview/llvoground.cpp
315newview/llvoiceclient.cpp
316newview/llvoiceremotectrl.cpp
317newview/llvoicevisualizer.cpp
308newview/llvoinventorylistener.cpp 318newview/llvoinventorylistener.cpp
309newview/llvolumesliderctrl.cpp
310newview/llvopartgroup.cpp 319newview/llvopartgroup.cpp
311newview/llvosky.cpp 320newview/llvosky.cpp
312newview/llvostars.cpp 321newview/llvostars.cpp
diff --git a/linden/indra/newview/licenses-solaris.txt b/linden/indra/newview/licenses-solaris.txt
new file mode 100644
index 0000000..a0dc048
--- /dev/null
+++ b/linden/indra/newview/licenses-solaris.txt
@@ -0,0 +1,516 @@
1===========
2APR License
3===========
4
5Copyright 2000-2004 The Apache Software Foundation
6
7Licensed under the Apache License, Version 2.0 (the "License");
8you may not use this file except in compliance with the License.
9You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13Unless required by applicable law or agreed to in writing, software
14distributed under the License is distributed on an "AS IS" BASIS,
15WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16See the License for the specific language governing permissions and
17limitations under the License.
18
19==============
20Base32 License
21==============
22
23 * Copyright (c) 2006 Christian Biere <christianbiere@gmx.de>
24 * All rights reserved.
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
28 * are met:
29 *
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. Neither the name of the authors nor the names of its contributors
36 * may be used to endorse or promote products derived from this software
37 * without specific prior written permission.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
40 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
43 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
44 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
45 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
47 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
48 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 * SUCH DAMAGE.
50
51==========
52Cg License
53==========
54
55Copyright (c) 2002, NVIDIA Corporation.
56
57
58
59NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
60of your agreement to the following terms, and your use, installation,
61modification or redistribution of this NVIDIA software constitutes
62acceptance of these terms. If you do not agree with these terms, please do
63not use, install, modify or redistribute this NVIDIA software.
64
65
66
67In consideration of your agreement to abide by the following terms, and
68subject to these terms, NVIDIA grants you a personal, non-exclusive license,
69under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
70Software"), to use, reproduce, modify and redistribute the NVIDIA
71Software, with or without modifications, in source and/or binary forms;
72provided that if you redistribute the NVIDIA Software, you must retain the
73copyright notice of NVIDIA, this notice and the following text and
74disclaimers in all such redistributions of the NVIDIA Software. Neither the
75name, trademarks, service marks nor logos of NVIDIA Corporation may be used
76to endorse or promote products derived from the NVIDIA Software without
77specific prior written permission from NVIDIA. Except as expressly stated
78in this notice, no other rights or licenses express or implied, are granted
79by NVIDIA herein, including but not limited to any patent rights that may be
80infringed by your derivative works or by other works in which the NVIDIA
81Software may be incorporated. No hardware is licensed hereunder.
82
83
84
85THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
86WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
87WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
88MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
89EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
90
91
92
93IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
94EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
95PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
96PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
97REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
98HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
99NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
100OF THE POSSIBILITY OF SUCH DAMAGE.
101
102
103============
104cURL License
105============
106
107COPYRIGHT AND PERMISSION NOTICE
108
109Copyright (c) 1996 - 2002, Daniel Stenberg, <daniel@haxx.se>.
110
111All rights reserved.
112
113Permission to use, copy, modify, and distribute this software for any purpose
114with or without fee is hereby granted, provided that the above copyright
115notice and this permission notice appear in all copies.
116
117THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
118IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
119FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
120NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
121DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
122OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
123OR OTHER DEALINGS IN THE SOFTWARE.
124
125Except as contained in this notice, the name of a copyright holder shall not
126be used in advertising or otherwise to promote the sale, use or other dealings
127in this Software without prior written authorization of the copyright holder.
128
129
130=============
131expat License
132=============
133
134Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
135
136Permission is hereby granted, free of charge, to any person obtaining
137a copy of this software and associated documentation files (the
138"Software"), to deal in the Software without restriction, including
139without limitation the rights to use, copy, modify, merge, publish,
140distribute, sublicense, and/or sell copies of the Software, and to
141permit persons to whom the Software is furnished to do so, subject to
142the following conditions:
143
144The above copyright notice and this permission notice shall be included
145in all copies or substantial portions of the Software.
146
147THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
148EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
149MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
150IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
151CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
152TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
153SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
154
155================
156FreeType License
157================
158
159Portions of this software are copyright (c) 2003 The FreeType
160Project (www.freetype.org). All rights reserved.
161
162==========================
163FSI FontShop International
164==========================
165
166Certain of the fonts in the Meta family of copyrighted typefaces are
167used in Second Life under license from FSI FontShop
168International. Copies of such Meta fonts that are included in the
169Viewer are not themselves open source and are not available under the
170GPL license, and they may not be copied. Developers may use those
171fonts solely to the extent necessary to use or customize the Linden
172Software in Second Life and to develop and distribute content solely
173for use in the Second Life environment, and for no other purposes.
174Second Life developers who wish to make other uses of Meta fonts must
175obtain a license from FSI FontShop International at www.fontfont.com.
176
177==========
178GL License
179==========
180
181Mesa 3-D graphics library
182Version: 6.2
183
184Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
185
186Permission is hereby granted, free of charge, to any person obtaining a
187copy of this software and associated documentation files (the "Software"),
188to deal in the Software without restriction, including without limitation
189the rights to use, copy, modify, merge, publish, distribute, sublicense,
190and/or sell copies of the Software, and to permit persons to whom the
191Software is furnished to do so, subject to the following conditions:
192
193The above copyright notice and this permission notice shall be included
194in all copies or substantial portions of the Software.
195
196THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
197OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
199BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
200AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
201CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
202
203=======================
204JPEG Library 6b License
205=======================
206
207This software is based in part on the work of the Independent JPEG Group
208
209================
210JPEG2000 License
211================
212
213Copyright 2001, David Taubman, The University of New South Wales (UNSW)
214The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW)
215Neither this copyright statement, nor the licensing details below
216may be removed from this file or dissociated from its contents.
217
218Licensee: Linden Research, Inc.
219License number: 00024
220The licensee has been granted a COMMERCIAL license to the contents of
221this source file. A brief summary of this license appears below. This
222summary is not to be relied upon in preference to the full text of the
223license agreement, accepted at purchase of the license.
2241. The Licensee has the right to Commercial Use of the Kakadu software,
225 including distribution of one or more Applications built using the
226 software.
2272. The Licensee has the right to Internal Use of the Kakadu software,
228 including use by employees of the Licensee or an Affiliate for the
229 purpose of performing services on behalf of the Licensee or Affiliate,
230 or in the performance of services for Third Parties who engage Licensee
231 or an Affiliate for such services.
2323. The Licensee has the right to distribute Reusable Code (including
233 source code and dynamically or statically linked libraries) to a Third
234 Party, provided the Third Party possesses a license to use the Kakadu
235 software.
236
237==================
238ogg/vorbis License
239==================
240
241Copyright (c) 2001, Xiphophorus
242
243Redistribution and use in source and binary forms, with or without
244modification, are permitted provided that the following conditions
245are met:
246
247- Redistributions of source code must retain the above copyright
248notice, this list of conditions and the following disclaimer.
249
250- Redistributions in binary form must reproduce the above copyright
251notice, this list of conditions and the following disclaimer in the
252documentation and/or other materials provided with the distribution.
253
254- Neither the name of the Xiphophorus nor the names of its contributors
255may be used to endorse or promote products derived from this software
256without specific prior written permission.
257
258THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
259``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
260LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
261A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
262CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
263EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
264PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
265PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
266LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
267NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
268SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
269
270
271===========
272SDL License
273===========
274
275SDL - Simple DirectMedia Layer
276Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
277
278This library is free software; you can redistribute it and/or
279modify it under the terms of the GNU Library General Public
280License as published by the Free Software Foundation; either
281version 2 of the License, or (at your option) any later version.
282
283This library is distributed in the hope that it will be useful,
284but WITHOUT ANY WARRANTY; without even the implied warranty of
285MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
286Library General Public License for more details.
287
288You should have received a copy of the GNU Library General Public
289License along with this library; if not, write to the Free
290Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
291
292Sam Lantinga
293slouken@libsdl.org
294
295The GNU Library GPL is available at http://www.gnu.org/copyleft/lesser.html
296
297=============
298ELFIO License
299=============
300
301ELFIO.h - ELF reader and producer.
302Copyright (C) 2001 Serge Lamikhov-Center <to_serge@users.sourceforge.net>
303
304This library is free software; you can redistribute it and/or
305modify it under the terms of the GNU Lesser General Public
306License as published by the Free Software Foundation; either
307version 2.1 of the License, or (at your option) any later version.
308
309This library is distributed in the hope that it will be useful,
310but WITHOUT ANY WARRANTY; without even the implied warranty of
311MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
312Lesser General Public License for more details.
313
314You should have received a copy of the GNU Lesser General Public
315License along with this library; if not, write to the Free Software
316Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
317
318The GNU Library GPL is available at http://www.gnu.org/copyleft/lesser.html
319
320===============
321OpenSSL License
322===============
323
324Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
325
326Redistribution and use in source and binary forms, with or without
327modification, are permitted provided that the following conditions
328are met:
329
3301. Redistributions of source code must retain the above copyright
331 notice, this list of conditions and the following disclaimer.
332
3332. Redistributions in binary form must reproduce the above copyright
334 notice, this list of conditions and the following disclaimer in
335 the documentation and/or other materials provided with the
336 distribution.
337
3383. All advertising materials mentioning features or use of this
339 software must display the following acknowledgment:
340 "This product includes software developed by the OpenSSL Project
341 for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
342
3434. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
344 endorse or promote products derived from this software without
345 prior written permission. For written permission, please contact
346 openssl-core@openssl.org.
347
3485. Products derived from this software may not be called "OpenSSL"
349 nor may "OpenSSL" appear in their names without prior written
350 permission of the OpenSSL Project.
351
3526. Redistributions of any form whatsoever must retain the following
353 acknowledgment:
354 "This product includes software developed by the OpenSSL Project
355 for use in the OpenSSL Toolkit (http://www.openssl.org/)"
356
357THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
358EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
359IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
360PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
361ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
362SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
363NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
364LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
365HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
366STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
367ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
368OF THE POSSIBILITY OF SUCH DAMAGE.
369====================================================================
370
371This product includes cryptographic software written by Eric Young
372(eay@cryptsoft.com). This product includes software written by Tim
373Hudson (tjh@cryptsoft.com).
374
375
376
377=======================
378Original SSLeay License
379=======================
380
381Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
382All rights reserved.
383
384This package is an SSL implementation written
385by Eric Young (eay@cryptsoft.com).
386The implementation was written so as to conform with Netscapes SSL.
387
388This library is free for commercial and non-commercial use as long as
389the following conditions are aheared to. The following conditions
390apply to all code found in this distribution, be it the RC4, RSA,
391lhash, DES, etc., code; not just the SSL code. The SSL documentation
392included with this distribution is covered by the same copyright terms
393except that the holder is Tim Hudson (tjh@cryptsoft.com).
394
395Copyright remains Eric Young's, and as such any Copyright notices in
396the code are not to be removed.
397If this package is used in a product, Eric Young should be given attribution
398as the author of the parts of the library used.
399This can be in the form of a textual message at program startup or
400in documentation (online or textual) provided with the package.
401
402Redistribution and use in source and binary forms, with or without
403modification, are permitted provided that the following conditions
404are met:
4051. Redistributions of source code must retain the copyright
406 notice, this list of conditions and the following disclaimer.
4072. Redistributions in binary form must reproduce the above copyright
408 notice, this list of conditions and the following disclaimer in the
409 documentation and/or other materials provided with the distribution.
4103. All advertising materials mentioning features or use of this software
411 must display the following acknowledgement:
412 "This product includes cryptographic software written by
413 Eric Young (eay@cryptsoft.com)"
414 The word 'cryptographic' can be left out if the rouines from the library
415 being used are not cryptographic related :-).
4164. If you include any Windows specific code (or a derivative thereof) from
417 the apps directory (application code) you must include an acknowledgement:
418 "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
419
420THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
421ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
422IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
423ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
424FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
425DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
426OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
427HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
428LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
429OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
430SUCH DAMAGE.
431
432The licence and distribution terms for any publically available version or
433derivative of this code cannot be changed. i.e. this code cannot simply be
434copied and put under another distribution licence
435[including the GNU Public Licence.]
436
437
438==================
439xmlrpc-epi License
440==================
441
442Copyright 2000 Epinions, Inc.
443
444Subject to the following 3 conditions, Epinions, Inc. permits you, free of charge, to (a) use, copy, distribute, modify, perform and display this software and associated documentation files (the "Software"), and (b) permit others to whom the Software is furnished to do so as well.
445
4461) The above copyright notice and this permission notice shall be included without modification in all copies or substantial portions of the Software.
447
4482) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
449
4503) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
451
452
453===============
454libuuid License
455===============
456
457Copyright (C) 1999, 2000, 2003, 2004 by Theodore Ts'o
458
459Redistribution and use in source and binary forms, with or without
460modification, are permitted provided that the following conditions
461are met:
4621. Redistributions of source code must retain the above copyright
463 notice, and the entire permission notice in its entirety,
464 including the disclaimer of warranties.
4652. Redistributions in binary form must reproduce the above copyright
466 notice, this list of conditions and the following disclaimer in the
467 documentation and/or other materials provided with the distribution.
4683. The name of the author may not be used to endorse or promote
469 products derived from this software without specific prior
470 written permission.
471
472THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
473WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
474OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
475WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
476LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
477CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
478OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
479BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
480LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
481(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
482USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
483DAMAGE.
484
485
486============
487zlib License
488============
489
490'zlib' general purpose compression library version 1.1.4, March 11th, 2002
491
492Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
493
494This software is provided 'as-is', without any express or implied warranty.
495In no event will the authors be held liable for any damages arising from the
496use of this software.
497
498Permission is granted to anyone to use this software for any purpose,
499including commercial applications, and to alter it and redistribute it
500freely, subject to the following restrictions:
501
502The origin of this software must not be misrepresented; you must not claim
503that you wrote the original software. If you use this software in a product,
504an acknowledgment in the product documentation would be appreciated but is
505not required.
506
507Altered source versions must be plainly marked as such, and must not be
508misrepresented as being the original software.
509
510This notice may not be removed or altered from any source distribution.
511
512Jean-loup Gailly
513jloup@gzip.org
514
515Mark Adler
516madler@alumni.caltech.edu
diff --git a/linden/indra/newview/linux_tools/client-readme.txt b/linden/indra/newview/linux_tools/client-readme.txt
index 63086c8..e07384c 100644
--- a/linden/indra/newview/linux_tools/client-readme.txt
+++ b/linden/indra/newview/linux_tools/client-readme.txt
@@ -15,6 +15,7 @@ Life itself - please see <http://www.secondlife.com/whatis/>.
15 5.3. 'Shiny' and client performance 15 5.3. 'Shiny' and client performance
16 5.4. Audio 16 5.4. Audio
17 5.5. 'Alt' key for camera controls doesn't work 17 5.5. 'Alt' key for camera controls doesn't work
18 5.6. In-world movie playback
186. Advanced Troubleshooting 196. Advanced Troubleshooting
19 6.1. Audio 20 6.1. Audio
20 6.2. OpenGL 21 6.2. OpenGL
@@ -57,6 +58,7 @@ Minimum requirements:
57 * Video/Graphics Card: 58 * Video/Graphics Card:
58 o nVidia GeForce 2, GeForce 4mx, or better 59 o nVidia GeForce 2, GeForce 4mx, or better
59 o OR ATI Radeon 8500, 9250, or better 60 o OR ATI Radeon 8500, 9250, or better
61 (nVidia cards are strongly recommended for the Linux client)
60 62
61 **NOTE**: Second Life absolutely requires you to have recent, correctly- 63 **NOTE**: Second Life absolutely requires you to have recent, correctly-
62 configured OpenGL 3D drivers for your hardware - the graphics drivers 64 configured OpenGL 3D drivers for your hardware - the graphics drivers
@@ -76,6 +78,14 @@ unpacked it into - no installation step is required.
76 78
77Run ./secondlife from the installation directory to start Second Life. 79Run ./secondlife from the installation directory to start Second Life.
78 80
81For in-world MOVIE PLAYBACK, you will need GStreamer 0.10 installed on your
82system. This is optional - it is not required for general client
83functionality. If you have GStreamer 0.10 installed, the selection of
84in-world movies you can successfully play will depend on the GStreamer
85plugins you have; if you cannot play a certain in-world movie then you are
86probably missing the appropriate GStreamer plugin on your system - you may
87be able to install it (see TROUBLESHOOTING).
88
79User data is stored in the hidden directory ~/.secondlife by default; you may 89User data is stored in the hidden directory ~/.secondlife by default; you may
80override this location with the SECONDLIFE_USER_DIR environment variable if 90override this location with the SECONDLIFE_USER_DIR environment variable if
81you wish. 91you wish.
@@ -93,10 +103,9 @@ the Alpha release of the Linux client.
93 stability. See PROBLEM 3 in the TROUBLESHOOTING section if you wish to 103 stability. See PROBLEM 3 in the TROUBLESHOOTING section if you wish to
94 turn these on to possibly enhance your experience. 104 turn these on to possibly enhance your experience.
95 105
96* MISC - The following user-visible features are not currently fully 106* MISC - The following features are not currently fully implemented on the
97 implemented on the Linux client and are therefore known not to work properly 107 Linux client and are therefore known not to work properly:
98 at this time: 108 * Movie recording
99 * QuickTime movie playback and movie recording
100 * Full Unicode font rendering 109 * Full Unicode font rendering
101 * Auto-updater 110 * Auto-updater
102 111
@@ -176,6 +185,13 @@ SOLUTION:- Some window managers eat the Alt key for their own purposes; you
176 example, the 'Windows' key!) which will allow the Alt key to function 185 example, the 'Windows' key!) which will allow the Alt key to function
177 properly with mouse actions in Second Life and other applications. 186 properly with mouse actions in Second Life and other applications.
178 187
188PROBLEM 6:- In-world movie playback doesn't work for me.
189SOLUTION:- You need to have a working installation of GStreamer 0.10; this
190 is usually an optional package for most versions of Linux. If you have
191 installed GStreamer 0.10 and you can play some movies but not others then
192 you need to install a wider selection of GStreamer plugins, either
193 from your vendor or an appropriate third party.
194
179 195
1806. ADVANCED TROUBLESHOOTING 1966. ADVANCED TROUBLESHOOTING
181-=-=-=-=-=-=-=-=-=-=-=-=-=- 197-=-=-=-=-=-=-=-=-=-=-=-=-=-
@@ -219,9 +235,8 @@ For problems and discussion concerning unofficial (not secondlife.com)
219releases, please contact your packager or the SLDev mailing list: 235releases, please contact your packager or the SLDev mailing list:
220<https://lists.secondlife.com/cgi-bin/mailman/listinfo/sldev> 236<https://lists.secondlife.com/cgi-bin/mailman/listinfo/sldev>
221 237
222In-world help: Please use the 'Help' menu in the client for general 238In-world help: Please use the 'Help' menu in the client for various
223non-Linux-specific Second Life help including live support from the fabulous 239non-Linux-specific Second Life help options.
224'Help Request' team.
225 240
226In-world discussion: There is a 'Linux Client Users' group 241In-world discussion: There is a 'Linux Client Users' group
227inside Second Life which is free to join. You can find it by pressing 242inside Second Life which is free to join. You can find it by pressing
diff --git a/linden/indra/newview/linux_tools/unicode.ttf b/linden/indra/newview/linux_tools/unicode.ttf
index c9c230d..91e6150 120000
--- a/linden/indra/newview/linux_tools/unicode.ttf
+++ b/linden/indra/newview/linux_tools/unicode.ttf
@@ -1 +1 @@
/usr/share/fonts/truetype/kochi/kochi-mincho.ttf \ No newline at end of file /usr/share/fonts/truetype/kochi/kochi-gothic.ttf \ No newline at end of file
diff --git a/linden/indra/newview/linux_tools/wrapper.sh b/linden/indra/newview/linux_tools/wrapper.sh
index d77da88..d39fc3a 100755
--- a/linden/indra/newview/linux_tools/wrapper.sh
+++ b/linden/indra/newview/linux_tools/wrapper.sh
@@ -48,6 +48,23 @@ export SDL_VIDEO_X11_DGAMOUSE=0
48 48
49RUN_PATH=`dirname "$0" || echo .` 49RUN_PATH=`dirname "$0" || echo .`
50cd "${RUN_PATH}" 50cd "${RUN_PATH}"
51if [ -n "$LL_TCMALLOC" ]; then
52 tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0'
53 all=1
54 for f in $tcmalloc_libs; do
55 if [ ! -f $f ]; then
56 all=0
57 fi
58 done
59 if [ $all != 1 ]; then
60 echo 'Cannot use tcmalloc libraries: components missing' 1>&2
61 else
62 export LD_PRELOAD=$(echo $tcmalloc_libs | tr ' ' :)
63 if [ -z "$HEAPCHECK" -a -z "$HEAPPROFILE" ]; then
64 export HEAPCHECK=${HEAPCHECK:-normal}
65 fi
66 fi
67fi
51LD_LIBRARY_PATH="`pwd`"/lib:"`pwd`"/app_settings/mozilla-runtime-linux-i686:"${LD_LIBRARY_PATH}" $LL_WRAPPER bin/do-not-directly-run-secondlife-bin `cat gridargs.dat` $@ | cat 68LD_LIBRARY_PATH="`pwd`"/lib:"`pwd`"/app_settings/mozilla-runtime-linux-i686:"${LD_LIBRARY_PATH}" $LL_WRAPPER bin/do-not-directly-run-secondlife-bin `cat gridargs.dat` $@ | cat
52 69
53echo 70echo
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp
index 307ab6f..3f6ab4f 100644
--- a/linden/indra/newview/llagent.cpp
+++ b/linden/indra/newview/llagent.cpp
@@ -61,6 +61,7 @@
61#include "llface.h" 61#include "llface.h"
62#include "llfirstuse.h" 62#include "llfirstuse.h"
63#include "llfloater.h" 63#include "llfloater.h"
64#include "llfloateractivespeakers.h"
64#include "llfloateravatarinfo.h" 65#include "llfloateravatarinfo.h"
65#include "llfloaterbuildoptions.h" 66#include "llfloaterbuildoptions.h"
66#include "llfloaterchat.h" 67#include "llfloaterchat.h"
@@ -117,6 +118,7 @@
117#include "pipeline.h" 118#include "pipeline.h"
118#include "roles_constants.h" 119#include "roles_constants.h"
119#include "viewer.h" 120#include "viewer.h"
121#include "llvoiceclient.h"
120 122
121// Ventrella 123// Ventrella
122#include "llfollowcam.h" 124#include "llfollowcam.h"
@@ -346,7 +348,7 @@ LLAgent::LLAgent()
346 mEffectColor(0.f, 1.f, 1.f, 1.f), 348 mEffectColor(0.f, 1.f, 1.f, 1.f),
347 mHaveHomePosition(FALSE), 349 mHaveHomePosition(FALSE),
348 mHomeRegionHandle( 0 ), 350 mHomeRegionHandle( 0 ),
349 mNearChatRadius(10.f), 351 mNearChatRadius(CHAT_NORMAL_RADIUS / 2.f),
350 mGodLevel( GOD_NOT ), 352 mGodLevel( GOD_NOT ),
351 353
352 354
@@ -2844,7 +2846,7 @@ void LLAgent::endAnimationUpdateUI()
2844 gMorphView->setVisible(FALSE); 2846 gMorphView->setVisible(FALSE);
2845 } 2847 }
2846 2848
2847 gIMView->setFloaterOpen( FALSE ); 2849 gIMMgr->setFloaterOpen( FALSE );
2848 gConsole->setVisible( TRUE ); 2850 gConsole->setVisible( TRUE );
2849 2851
2850 if (mAvatarObject) 2852 if (mAvatarObject)
@@ -3259,6 +3261,19 @@ void LLAgent::updateCamera()
3259 setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent); 3261 setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent);
3260 } 3262 }
3261 3263
3264 // Send the camera position to the spatialized voice system.
3265 if(gVoiceClient && getRegion())
3266 {
3267 LLMatrix3 rot;
3268 rot.setRows(gCamera->getAtAxis(), gCamera->getLeftAxis (), gCamera->getUpAxis());
3269
3270 // MBW -- XXX -- Setting velocity to 0 for now. May figure it out later...
3271 gVoiceClient->setCameraPosition(
3272 getRegion()->getPosGlobalFromRegion(gCamera->getOrigin()),// position
3273 LLVector3::zero, // velocity
3274 rot); // rotation matrix
3275 }
3276
3262 // update the travel distance stat 3277 // update the travel distance stat
3263 // this isn't directly related to the camera 3278 // this isn't directly related to the camera
3264 // but this seemed like the best place to do this 3279 // but this seemed like the best place to do this
@@ -3269,7 +3284,7 @@ void LLAgent::updateCamera()
3269 mDistanceTraveled += delta.magVec(); 3284 mDistanceTraveled += delta.magVec();
3270 } 3285 }
3271 mLastPositionGlobal = global_pos; 3286 mLastPositionGlobal = global_pos;
3272 3287
3273 if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->mIsSitting && cameraMouselook()) 3288 if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->mIsSitting && cameraMouselook())
3274 { 3289 {
3275 LLVector3 head_pos = mAvatarObject->mHeadp->getWorldPosition() + 3290 LLVector3 head_pos = mAvatarObject->mHeadp->getWorldPosition() +
@@ -4465,18 +4480,23 @@ void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
4465//----------------------------------------------------------------------------- 4480//-----------------------------------------------------------------------------
4466// heardChat() 4481// heardChat()
4467//----------------------------------------------------------------------------- 4482//-----------------------------------------------------------------------------
4468void LLAgent::heardChat(const LLChat& chat) 4483void LLAgent::heardChat(const LLUUID& id)
4469{ 4484{
4470 if (chat.mChatType == CHAT_TYPE_START 4485 // log text and voice chat to speaker mgr
4471 || chat.mChatType == CHAT_TYPE_STOP) 4486 // for keeping track of active speakers, etc.
4487 gLocalSpeakerMgr->speakerChatted(id);
4488
4489 // don't respond to your own voice
4490 if (id == getID()) return;
4491
4492 if (ll_rand(2) == 0)
4472 { 4493 {
4473 return; 4494 LLViewerObject *chatter = gObjectList.findObject(mLastChatterID);
4474 } 4495 setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero);
4496 }
4475 4497
4476 mLastChatterID = chat.mFromID; 4498 mLastChatterID = id;
4477 mChatTimer.reset(); 4499 mChatTimer.reset();
4478
4479 mNearChatRadius = CHAT_NORMAL_RADIUS / 2.f;
4480} 4500}
4481 4501
4482//----------------------------------------------------------------------------- 4502//-----------------------------------------------------------------------------
@@ -5068,14 +5088,6 @@ void LLAgent::initOriginGlobal(const LLVector3d &origin_global)
5068 5088
5069void update_group_floaters(const LLUUID& group_id) 5089void update_group_floaters(const LLUUID& group_id)
5070{ 5090{
5071 // *HACK: added to do a live update of the groups floater if it is
5072 // open.
5073 LLFloaterGroups* fg = LLFloaterGroups::getInstance(gAgent.getID());
5074 if(fg)
5075 {
5076 fg->reset();
5077 }
5078
5079 LLFloaterGroupInfo::refreshGroup(group_id); 5091 LLFloaterGroupInfo::refreshGroup(group_id);
5080 5092
5081 // update avatar info 5093 // update avatar info
@@ -5085,10 +5097,10 @@ void update_group_floaters(const LLUUID& group_id)
5085 fa->resetGroupList(); 5097 fa->resetGroupList();
5086 } 5098 }
5087 5099
5088 if (gIMView) 5100 if (gIMMgr)
5089 { 5101 {
5090 // update the talk view 5102 // update the talk view
5091 gIMView->refresh(); 5103 gIMMgr->refresh();
5092 } 5104 }
5093} 5105}
5094 5106
@@ -5179,6 +5191,7 @@ void LLAgent::processAgentGroupDataUpdate(LLMessageSystem *msg, void **)
5179 if (need_floater_update) 5191 if (need_floater_update)
5180 { 5192 {
5181 update_group_floaters(group.mID); 5193 update_group_floaters(group.mID);
5194 gAgent.fireEvent(new LLEvent(&gAgent, "new group"), "");
5182 } 5195 }
5183 } 5196 }
5184 5197
@@ -5508,6 +5521,11 @@ bool LLAgent::teleportCore(bool is_local)
5508 gAgent.setTeleportState( LLAgent::TELEPORT_START ); 5521 gAgent.setTeleportState( LLAgent::TELEPORT_START );
5509 } 5522 }
5510 make_ui_sound("UISndTeleportOut"); 5523 make_ui_sound("UISndTeleportOut");
5524
5525 // MBW -- Let the voice client know a teleport has begun so it can leave the existing channel.
5526 // This was breaking the case of teleporting within a single sim. Backing it out for now.
5527// gVoiceClient->leaveChannel();
5528
5511 return true; 5529 return true;
5512} 5530}
5513 5531
@@ -6770,7 +6788,7 @@ void LLAgent::removeWearable( EWearableType type )
6770 if( old_wearable->isDirty() ) 6788 if( old_wearable->isDirty() )
6771 { 6789 {
6772 // Bring up view-modal dialog: Save changes? Yes, No, Cancel 6790 // Bring up view-modal dialog: Save changes? Yes, No, Cancel
6773 gViewerWindow->alertXml("WearableSave", LLAgent::onRemoveWearableDialog, (void*)(S32)type ); 6791 gViewerWindow->alertXml("WearableSave", LLAgent::onRemoveWearableDialog, (void*)type );
6774 return; 6792 return;
6775 } 6793 }
6776 else 6794 else
diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h
index e4d207c..7fb4571 100644
--- a/linden/indra/newview/llagent.h
+++ b/linden/indra/newview/llagent.h
@@ -190,7 +190,7 @@ public:
190 void setObjectTracking(BOOL track) { mTrackFocusObject = track; } 190 void setObjectTracking(BOOL track) { mTrackFocusObject = track; }
191// void setLookingAtAvatar(BOOL looking); 191// void setLookingAtAvatar(BOOL looking);
192 192
193 void heardChat(const LLChat& chat); 193 void heardChat(const LLUUID& id);
194 void lookAtLastChat(); 194 void lookAtLastChat();
195 LLUUID getLastChatter() { return mLastChatterID; } 195 LLUUID getLastChatter() { return mLastChatterID; }
196 F32 getTypingTime() { return mTypingTimer.getElapsedTimeF32(); } 196 F32 getTypingTime() { return mTypingTimer.getElapsedTimeF32(); }
diff --git a/linden/indra/newview/llaudiosourcevo.cpp b/linden/indra/newview/llaudiosourcevo.cpp
index 084d532..b0e0758 100644
--- a/linden/indra/newview/llaudiosourcevo.cpp
+++ b/linden/indra/newview/llaudiosourcevo.cpp
@@ -83,7 +83,7 @@ void LLAudioSourceVO::updateGain()
83 { 83 {
84 mute = TRUE; 84 mute = TRUE;
85 } 85 }
86 else if (gMuteListp->isMuted(mOwnerID)) 86 else if (gMuteListp->isMuted(mOwnerID, LLMute::flagObjectSounds))
87 { 87 {
88 mute = TRUE; 88 mute = TRUE;
89 } 89 }
diff --git a/linden/indra/newview/llaudiostatus.cpp b/linden/indra/newview/llaudiostatus.cpp
deleted file mode 100644
index f24d939..0000000
--- a/linden/indra/newview/llaudiostatus.cpp
+++ /dev/null
@@ -1,412 +0,0 @@
1/**
2 * @file llaudiostatus.cpp
3 * @brief Audio channel allocation information
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "llviewerprecompiledheaders.h"
30
31#include "llaudiostatus.h"
32
33#include "linked_lists.h"
34#include "llmath.h" // clampf()
35#include "llgl.h"
36#include "llview.h"
37#include "llfontgl.h"
38#include "llcircuit.h"
39#include "message.h"
40#include "sound_ids.h"
41#include "audioengine.h"
42
43#include "llui.h"
44#include "llagent.h"
45#include "llviewercontrol.h"
46#include "viewer.h"
47
48#include "llglheaders.h"
49
50//
51// Imported globals
52//
53extern LLMessageSystem* gMessageSystem;
54extern LLAudioEngine* gAudiop;
55
56//
57// Constants
58//
59
60
61LLAudiostatus::LLAudiostatus(const std::string& name, const LLRect& rect)
62 : LLView(name, rect, FALSE)
63{
64 mPage = 0;
65}
66
67//
68// Functions
69//
70
71EWidgetType LLAudiostatus::getWidgetType() const
72{
73 return WIDGET_TYPE_AUDIO_STATUS;
74}
75
76LLString LLAudiostatus::getWidgetTag() const
77{
78 return LL_AUDIOSTATUS_TAG;
79}
80
81const F32 AUDIOSTATUS_SIZE = 64;
82
83void LLAudiostatus::draw()
84{
85 /*
86 mPage = gSavedSettings.getS32("AudioInfoPage");
87
88 if (!getVisible() || !mPage)
89 {
90 return;
91 }
92
93 glMatrixMode(GL_MODELVIEW);
94 glPushMatrix();
95
96 // We're going to be drawing flat shaded rectangles
97 {
98 LLGLSNoTexture gls_ui_no_texture;
99
100 // Draw background black rectangle
101 glColor4f(0.f, 0.f, 0.f, 0.3f);
102 gl_rect_2d(0, 0, 325, -340); // -y is down (don't know why)
103 }
104
105 glPopMatrix();
106 glPushMatrix();
107
108 S32 channel;
109 char out_str[64];
110 LLColor4 color;
111
112 if (gAudiop)
113 {
114 for (channel = 0; channel < MAX_BUFFERS; channel++)
115 {
116 if (gAudiop->getFlags(channel) & LL_SOUND_FLAG_LOOP)
117 {
118 color.setVec(0.5f,0.5f,1.f,1.f);
119 }
120 else
121 {
122 color.setVec(1.f,1.f,1.f,1.f);
123 }
124
125 sprintf(out_str,"%d:",channel);
126
127 U8 render_style = LLFontGL::NORMAL;
128
129 if (gAudiop->getFlags(channel) & LL_SOUND_FLAG_SYNC_MASTER)
130 {
131 render_style |= LLFontGL::BOLD;
132 }
133
134 if (gAudiop->getFlags(channel) & LL_SOUND_FLAG_SYNC_SLAVE)
135 {
136 render_style |= LLFontGL::ITALIC;
137 }
138
139 if (gAudiop->getFlags(channel) & LL_SOUND_FLAG_SYNC_PENDING)
140 {
141 render_style |= LLFontGL::UNDERLINE;
142 }
143
144 LLFontGL::sMonospace->render(out_str, 0, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP, render_style, S32_MAX, S32_MAX, NULL);
145
146// render_style = LLFontGL::NORMAL;
147// if (gAudiop->mCurrentSyncMaster == channel)
148// {
149// render_style |= LLFontGL::BOLD;
150// }
151
152 if (!gAudiop->mBufferInUse[channel])
153 {
154 color.setVec(0.5f,0.5f,0.5f,1.f);
155 }
156 else if (gAudiop->isPlaying(channel))
157 {
158 color.setVec(0.f,1.f,0.f,1.f);
159 }
160 else
161 {
162 color.setVec(1.f,0.f,0.f,1.f);
163 }
164
165 if (gAudiop->mWindBufferID ==channel)
166 {
167 strcpy(out_str,"wind DMO");
168 }
169 else if (gAudiop->mWaterBufferID ==channel)
170 {
171 strcpy(out_str,"water DMO");
172 }
173 else if (gAudiop->mGUID[channel] == SND_CHIRP)
174 {
175 strcpy(out_str,"chirp");
176 }
177 else if (gAudiop->mGUID[channel] == SND_SHOT)
178 {
179 strcpy(out_str,"shot");
180 }
181 else if (gAudiop->mGUID[channel] == SND_MORTAR)
182 {
183 strcpy(out_str,"mortar");
184 }
185 else if (gAudiop->mGUID[channel] == SND_HIT)
186 {
187 strcpy(out_str,"hit");
188 }
189 else if (gAudiop->mGUID[channel] == SND_EXPLOSION)
190 {
191 strcpy(out_str,"explosion");
192 }
193 else if (gAudiop->mGUID[channel] == SND_BOING)
194 {
195 strcpy(out_str,"boing");
196 }
197 else if (gAudiop->mGUID[channel] == SND_MUNCH)
198 {
199 strcpy(out_str,"munch");
200 }
201 else if (gAudiop->mGUID[channel] == SND_PUNCH)
202 {
203 strcpy(out_str,"punch");
204 }
205 else if (gAudiop->mGUID[channel] == SND_SPLASH)
206 {
207 strcpy(out_str,"splash");
208 }
209 else if (gAudiop->mGUID[channel] == SND_CLICK)
210 {
211 strcpy(out_str,"click");
212 }
213 else if (gAudiop->mGUID[channel] == SND_ARROW_SHOT)
214 {
215 strcpy(out_str,"arrow");
216 }
217 else if (gAudiop->mGUID[channel] == SND_ARROW_THUD)
218 {
219 strcpy(out_str,"arrow thud");
220 }
221 else if (gAudiop->mGUID[channel] == SND_SILENCE)
222 {
223 strcpy(out_str,"silence");
224 }
225 else if (gAudiop->mGUID[channel] == SND_WELCOME)
226 {
227 strcpy(out_str,"welcome");
228 }
229 else if (gAudiop->mGUID[channel] == SND_WELCOME)
230 {
231 strcpy(out_str,"welcome");
232 }
233 else if (gAudiop->mGUID[channel] == SND_READY_FOR_BATTLE)
234 {
235 strcpy(out_str,"ready for battle");
236 }
237 else if (gAudiop->mGUID[channel] == SND_SQUISH)
238 {
239 strcpy(out_str,"squish");
240 }
241 else if (gAudiop->mGUID[channel] == SND_FOOTSTEPS)
242 {
243 strcpy(out_str,"footsteps");
244 }
245 else if (gAudiop->mGUID[channel] == SND_BALL_COLLISION)
246 {
247 strcpy(out_str,"ball collision");
248 }
249 else
250 {
251 gAudiop->mGUID[channel].toString(out_str);
252 }
253
254 out_str[8] = 0;
255 LLFontGL::sMonospace->render(out_str, 23, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP, render_style, S32_MAX, S32_MAX, NULL);
256
257 if (mPage == 1)
258 {
259 LLVector3 pos = gAudiop->getSourcePos(channel);
260 sprintf(out_str,"%6.2f %6.2f %6.2f",pos.mV[VX],pos.mV[VY],pos.mV[VZ]);
261 LLFontGL::sMonospace->render(out_str, 103, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP);
262
263 F32 gain = gAudiop->getSourceGain_dB(channel);
264 sprintf(out_str,"%7.2f",gain);
265 LLFontGL::sMonospace->render(out_str, 260, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP);
266
267 sprintf(out_str,"%X", gAudiop->mPriority[channel] >> 28);
268 LLFontGL::sMonospace->render(out_str, 315, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP);
269 }
270 else if (mPage == 4)
271 {
272 F32 indicator_width = 240;
273
274 glPushMatrix();
275 // We're going to be drawing flat shaded rectangles
276 LLGLSNoTexture gls_no_texture;
277 // Draw background black rectangle
278 glColor4f(0.f, 0.f, 0.f, 1.0f);
279
280 F32 length = gAudiop->getSourceLength(channel);
281 length = length/(44100.0*2.0); // length in seconds
282 length = length/10.f; // rescale per maximum length
283
284 gl_rect_2d(80, (-channel*10)-1, 80 + llfloor((F32)(indicator_width * length)), (-channel*10)-9); // -y is down (don't know why)
285
286 F32 current_pointer = gAudiop->getSourceCurrentSample(channel);
287 current_pointer = current_pointer/(44100.0*2.0); // length in seconds
288 current_pointer = current_pointer/10.f; // rescale per maximum length
289
290 if (!gAudiop->mBufferInUse[channel])
291 {
292 glColor4f(0.5f,0.5f,0.5f,1.f);
293 }
294 else if (gAudiop->isPlaying(channel))
295 {
296 glColor4f(0.f,1.f,0.f,1.f);
297 }
298 else
299 {
300 glColor4f(1.f,0.f,0.f,1.f);
301 }
302
303 gl_rect_2d(80, (-channel*10)-1, 80 + llfloor((F32)(indicator_width * current_pointer)), (-channel*10)-9); // -y is down (don't know why)
304
305 glPopMatrix();
306 {
307 LLGLSUIDefault gls_ui;
308
309 color.setVec(1.f,1.f,1.f,1.f);
310
311 sprintf(out_str,"%6.3f",length*10.f);
312 LLFontGL::sMonospace->render(out_str, 200, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP, render_style, S32_MAX, S32_MAX, NULL);
313
314 if (!(gAudiop->mVO_ID[channel].isNull()))
315 {
316 gAudiop->mVO_ID[channel].toString(out_str);
317 out_str[8] = 0;
318 LLFontGL::sMonospace->render(out_str, 260, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP, render_style, S32_MAX, S32_MAX, NULL);
319 }
320 if (gAudiop->mQueuedTrigger[channel])
321 {
322 gAudiop->mQueuedTrigger[channel]->mID.toString(out_str);
323 out_str[8] = 0;
324 LLFontGL::sMonospace->render(out_str, 320, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP, render_style, S32_MAX, S32_MAX, NULL);
325 }
326 }
327 }
328 else
329 {
330 S32 volume;
331 S32 freq;
332 S32 inside;
333 S32 outside;
334 LLVector3 orient;
335 S32 out_volume;
336 F32 min_dist;
337 F32 max_dist;
338
339 gAudiop->get3DParams(channel, &volume, &freq, &inside, &outside, &orient, &out_volume, &min_dist, &max_dist);
340
341 if (mPage == 2)
342 {
343 sprintf(out_str,"%4.2f %4.2f %4.2f",orient.mV[VX],orient.mV[VY],orient.mV[VZ]);
344 LLFontGL::sMonospace->render(out_str, 103, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP);
345
346 sprintf(out_str,"%4d %4d",inside, outside);
347 LLFontGL::sMonospace->render(out_str, 210, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP);
348
349 sprintf(out_str,"%6d", out_volume);
350 LLFontGL::sMonospace->render(out_str, 280, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP);
351 }
352 else // mPage == 3
353 {
354 F32 distance = 0.f;
355 if (gAudiop->isSourceAmbient(channel))
356 {
357 distance = dist_vec(gAudiop->getSourcePos(channel),LLVector3::zero);
358 }
359 else
360 {
361 distance = dist_vec(gAudiop->getSourcePos(channel),gAudiop->getListenerPos());
362 }
363
364 sprintf(out_str,"%6.2f %6.2f %6.2f",distance, min_dist, max_dist);
365 LLFontGL::sMonospace->render(out_str, 103, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP);
366
367 F32 gain = gAudiop->getSourceGain_dB(channel);
368 sprintf(out_str,"%7.2f",gain);
369 LLFontGL::sMonospace->render(out_str, 280, -channel*10, color, LLFontGL::LEFT, LLFontGL::TOP);
370 }
371 }
372 }
373 LLFontGL::sMonospace->render("Listener", 23, -(channel*10+5), color, LLFontGL::LEFT, LLFontGL::TOP);
374
375
376 if (mPage == 1)
377 {
378 LLVector3 lpos = gAudiop->getListenerPos();
379 sprintf(out_str,"%6.2f %6.2f %6.2f",lpos.mV[VX],lpos.mV[VY],lpos.mV[VZ]);
380 LLFontGL::sMonospace->render(out_str, 103, -(channel*10+5), color, LLFontGL::LEFT, LLFontGL::TOP);
381
382 F32 gain = gAudiop->getMasterGain_dB();
383 sprintf(out_str,"%7.2f",gain);
384 LLFontGL::sMonospace->render(out_str, 280, -(channel*10+5), color, LLFontGL::LEFT, LLFontGL::TOP);
385 }
386 else if (mPage == 2)
387 {
388 sprintf(out_str,"cone orient inner outer gain");
389 LLFontGL::sMonospace->render(out_str, 103, -(channel*10+5), color, LLFontGL::LEFT, LLFontGL::TOP);
390 }
391 else if (mPage == 3)
392 {
393 sprintf(out_str,"distance min max gain");
394 LLFontGL::sMonospace->render(out_str, 103, -(channel*10+5), color, LLFontGL::LEFT, LLFontGL::TOP);
395 }
396 }
397 else
398 {
399 LLFontGL::sMonospace->render("No Audio Engine available", 50 , -175,
400 LLColor4(1.f,0.1f,0.1f,1.f),
401 LLFontGL::LEFT, LLFontGL::TOP);
402 }
403
404 glPopMatrix();
405 */
406}
407
408
409
410
411
412
diff --git a/linden/indra/newview/llcallingcard.cpp b/linden/indra/newview/llcallingcard.cpp
index 22a7f20..dfc99bf 100644
--- a/linden/indra/newview/llcallingcard.cpp
+++ b/linden/indra/newview/llcallingcard.cpp
@@ -294,6 +294,7 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
294 << "]" << llendl; 294 << "]" << llendl;
295 } 295 }
296 } 296 }
297 notifyObservers();
297 298
298 return new_buddy_count; 299 return new_buddy_count;
299} 300}
diff --git a/linden/indra/newview/llchatbar.cpp b/linden/indra/newview/llchatbar.cpp
index 66ffdc4..9798796 100644
--- a/linden/indra/newview/llchatbar.cpp
+++ b/linden/indra/newview/llchatbar.cpp
@@ -47,6 +47,7 @@
47#include "llgesturemgr.h" 47#include "llgesturemgr.h"
48#include "llkeyboard.h" 48#include "llkeyboard.h"
49#include "lllineeditor.h" 49#include "lllineeditor.h"
50#include "llstatusbar.h"
50#include "lltextbox.h" 51#include "lltextbox.h"
51#include "lluiconstants.h" 52#include "lluiconstants.h"
52#include "llviewergesture.h" // for triggering gestures 53#include "llviewergesture.h" // for triggering gestures
@@ -70,15 +71,18 @@ const F32 AGENT_TYPING_TIMEOUT = 5.f; // seconds
70 71
71LLChatBar *gChatBar = NULL; 72LLChatBar *gChatBar = NULL;
72 73
73LLChatBarGestureObserver* LLChatBar::sObserver = NULL; 74// legacy calllback glue
75void toggleChatHistory(void* user_data);
74 76
75 77
76class LLChatBarGestureObserver : public LLGestureManagerObserver 78class LLChatBarGestureObserver : public LLGestureManagerObserver
77{ 79{
78public: 80public:
79 LLChatBarGestureObserver() {} 81 LLChatBarGestureObserver(LLChatBar* chat_barp) : mChatBar(chat_barp){}
80 virtual ~LLChatBarGestureObserver() {} 82 virtual ~LLChatBarGestureObserver() {}
81 virtual void changed() { gChatBar->refreshGestures(); } 83 virtual void changed() { mChatBar->refreshGestures(); }
84private:
85 LLChatBar* mChatBar;
82}; 86};
83 87
84 88
@@ -86,12 +90,29 @@ public:
86// Functions 90// Functions
87// 91//
88 92
89LLChatBar::LLChatBar(const std::string& name, const LLRect& rect) 93//inline constructor
94// for chat bars embedded in floaters, etc
95LLChatBar::LLChatBar(const std::string& name)
96: LLPanel(name, LLRect(), BORDER_NO),
97 mInputEditor(NULL),
98 mGestureLabelTimer(),
99 mLastSpecialChatChannel(0),
100 mIsBuilt(FALSE),
101 mDynamicLayout(FALSE),
102 mGestureCombo(NULL),
103 mObserver(NULL)
104{
105}
106
107LLChatBar::LLChatBar(const std::string& name, const LLRect& rect)
90: LLPanel(name, rect, BORDER_NO), 108: LLPanel(name, rect, BORDER_NO),
91 mInputEditor(NULL), 109 mInputEditor(NULL),
92 mGestureLabelTimer(), 110 mGestureLabelTimer(),
93 mLastSpecialChatChannel(0), 111 mLastSpecialChatChannel(0),
94 mIsBuilt(FALSE) 112 mIsBuilt(FALSE),
113 mDynamicLayout(TRUE),
114 mGestureCombo(NULL),
115 mObserver(NULL)
95{ 116{
96 setIsChrome(TRUE); 117 setIsChrome(TRUE);
97 118
@@ -107,29 +128,6 @@ LLChatBar::LLChatBar(const std::string& name, const LLRect& rect)
107 // Start visible if we left the app while chatting. 128 // Start visible if we left the app while chatting.
108 setVisible( gSavedSettings.getBOOL("ChatVisible") ); 129 setVisible( gSavedSettings.getBOOL("ChatVisible") );
109 130
110 mInputEditor = LLUICtrlFactory::getLineEditorByName(this, "Chat Editor");
111 if (mInputEditor)
112 {
113 mInputEditor->setCallbackUserData(this);
114 mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke);
115 mInputEditor->setFocusLostCallback(&onInputEditorFocusLost);
116 mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus );
117 mInputEditor->setCommitOnFocusLost( FALSE );
118 mInputEditor->setRevertOnEsc( FALSE );
119 mInputEditor->setIgnoreTab(TRUE);
120 mInputEditor->setPassDelete(TRUE);
121 mInputEditor->setMaxTextLength(1023);
122 mInputEditor->setEnableLineHistory(TRUE);
123 }
124
125 // Build the list of gestures
126 refreshGestures();
127
128 sObserver = new LLChatBarGestureObserver;
129 gGestureManager.addObserver(sObserver);
130
131 mIsBuilt = TRUE;
132
133 // Apply custom layout. 131 // Apply custom layout.
134 layout(); 132 layout();
135 133
@@ -142,23 +140,43 @@ LLChatBar::LLChatBar(const std::string& name, const LLRect& rect)
142 140
143LLChatBar::~LLChatBar() 141LLChatBar::~LLChatBar()
144{ 142{
145 delete sObserver; 143 delete mObserver;
146 sObserver = NULL; 144 mObserver = NULL;
147 // LLView destructor cleans up children 145 // LLView destructor cleans up children
148} 146}
149 147
150BOOL LLChatBar::postBuild() 148BOOL LLChatBar::postBuild()
151{ 149{
152 childSetAction("History", LLFloaterChat::toggle, this); 150 childSetAction("History", toggleChatHistory, this);
153 childSetAction("Say", onClickSay, this); 151 childSetAction("Say", onClickSay, this);
154 childSetAction("Shout", onClickShout, this); 152 childSetAction("Shout", onClickShout, this);
155 childSetCommitCallback("Gesture", onCommitGesture, this); 153
156 LLButton * sayp = static_cast<LLButton*>(getChildByName("Say")); 154 // attempt to bind to an existing combo box named gesture
155 setGestureCombo(LLUICtrlFactory::getComboBoxByName(this, "Gesture"));
156
157 LLButton * sayp = static_cast<LLButton*>(getChildByName("Say", TRUE));
157 if(sayp) 158 if(sayp)
158 { 159 {
159 setDefaultBtn(sayp); 160 setDefaultBtn(sayp);
160 } 161 }
161 162
163 mInputEditor = LLUICtrlFactory::getLineEditorByName(this, "Chat Editor");
164 if (mInputEditor)
165 {
166 mInputEditor->setCallbackUserData(this);
167 mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke);
168 mInputEditor->setFocusLostCallback(&onInputEditorFocusLost);
169 mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus );
170 mInputEditor->setCommitOnFocusLost( FALSE );
171 mInputEditor->setRevertOnEsc( FALSE );
172 mInputEditor->setIgnoreTab(TRUE);
173 mInputEditor->setPassDelete(TRUE);
174
175 mInputEditor->setMaxTextLength(1023);
176 }
177
178 mIsBuilt = TRUE;
179
162 return TRUE; 180 return TRUE;
163} 181}
164 182
@@ -206,7 +224,8 @@ BOOL LLChatBar::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent )
206 handled = TRUE; 224 handled = TRUE;
207 } 225 }
208 } 226 }
209 else if ( KEY_ESCAPE == key ) 227 // only do this in main chatbar
228 else if ( KEY_ESCAPE == key && gChatBar == this)
210 { 229 {
211 stopChat(); 230 stopChat();
212 231
@@ -219,6 +238,8 @@ BOOL LLChatBar::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent )
219 238
220void LLChatBar::layout() 239void LLChatBar::layout()
221{ 240{
241 if (!mDynamicLayout) return;
242
222 S32 rect_width = mRect.getWidth(); 243 S32 rect_width = mRect.getWidth();
223 S32 count = 9; // number of elements in LLToolBar 244 S32 count = 9; // number of elements in LLToolBar
224 S32 pad = 4; 245 S32 pad = 4;
@@ -281,13 +302,16 @@ void LLChatBar::refresh()
281 // hide in mouselook, but keep previous visibility state 302 // hide in mouselook, but keep previous visibility state
282 //BOOL mouselook = gAgent.cameraMouselook(); 303 //BOOL mouselook = gAgent.cameraMouselook();
283 // call superclass setVisible so that we don't overwrite the saved setting 304 // call superclass setVisible so that we don't overwrite the saved setting
284 LLPanel::setVisible(gSavedSettings.getBOOL("ChatVisible")); 305 if (mDynamicLayout)
306 {
307 LLPanel::setVisible(gSavedSettings.getBOOL("ChatVisible"));
308 }
285 309
286 // HACK: Leave the name of the gesture in place for a few seconds. 310 // HACK: Leave the name of the gesture in place for a few seconds.
287 const F32 SHOW_GESTURE_NAME_TIME = 2.f; 311 const F32 SHOW_GESTURE_NAME_TIME = 2.f;
288 if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME) 312 if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME)
289 { 313 {
290 LLCtrlListInterface* gestures = childGetListInterface("Gesture"); 314 LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
291 if (gestures) gestures->selectFirstItem(); 315 if (gestures) gestures->selectFirstItem();
292 mGestureLabelTimer.stop(); 316 mGestureLabelTimer.stop();
293 } 317 }
@@ -297,6 +321,8 @@ void LLChatBar::refresh()
297 gAgent.stopTyping(); 321 gAgent.stopTyping();
298 } 322 }
299 323
324 childSetValue("History", LLFloaterChat::instanceVisible(LLSD()));
325
300 childSetEnabled("Say", mInputEditor->getText().size() > 0); 326 childSetEnabled("Say", mInputEditor->getText().size() > 0);
301 childSetEnabled("Shout", mInputEditor->getText().size() > 0); 327 childSetEnabled("Shout", mInputEditor->getText().size() > 0);
302 328
@@ -304,16 +330,18 @@ void LLChatBar::refresh()
304 330
305void LLChatBar::refreshGestures() 331void LLChatBar::refreshGestures()
306{ 332{
307 LLCtrlListInterface* gestures = childGetListInterface("Gesture"); 333 LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
308 if (gestures) 334 if (mGestureCombo && gestures)
309 { 335 {
310 //store current selection so we can maintain it 336 //store current selection so we can maintain it
311 LLString cur_gesture = childGetValue("Gesture").asString(); 337 LLString cur_gesture = mGestureCombo->getValue().asString();
312 gestures->selectFirstItem(); 338 gestures->selectFirstItem();
313 LLString label = childGetValue("Gesture").asString(); 339 LLString label = mGestureCombo->getValue().asString();;
314 // clear 340 // clear
315 gestures->clearRows(); 341 gestures->clearRows();
316 // add gestures 342
343 // collect list of unique gestures
344 std::map <std::string, BOOL> unique;
317 LLGestureManager::item_map_t::iterator it; 345 LLGestureManager::item_map_t::iterator it;
318 for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it) 346 for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it)
319 { 347 {
@@ -322,10 +350,18 @@ void LLChatBar::refreshGestures()
322 { 350 {
323 if (!gesture->mTrigger.empty()) 351 if (!gesture->mTrigger.empty())
324 { 352 {
325 gestures->addSimpleElement(gesture->mTrigger); 353 unique[gesture->mTrigger] = TRUE;
326 } 354 }
327 } 355 }
328 } 356 }
357
358 // ad unique gestures
359 std::map <std::string, BOOL>::iterator it2;
360 for (it2 = unique.begin(); it2 != unique.end(); ++it2)
361 {
362 gestures->addSimpleElement((*it2).first);
363 }
364
329 gestures->sortByColumn(0, TRUE); 365 gestures->sortByColumn(0, TRUE);
330 // Insert label after sorting 366 // Insert label after sorting
331 gestures->addSimpleElement(label, ADD_TOP); 367 gestures->addSimpleElement(label, ADD_TOP);
@@ -382,6 +418,23 @@ LLString LLChatBar::getCurrentChat()
382 return mInputEditor ? mInputEditor->getText() : LLString::null; 418 return mInputEditor ? mInputEditor->getText() : LLString::null;
383} 419}
384 420
421void LLChatBar::setGestureCombo(LLComboBox* combo)
422{
423 mGestureCombo = combo;
424 if (mGestureCombo)
425 {
426 mGestureCombo->setCommitCallback(onCommitGesture);
427 mGestureCombo->setCallbackUserData(this);
428
429 // now register observer since we have a place to put the results
430 mObserver = new LLChatBarGestureObserver(this);
431 gGestureManager.addObserver(mObserver);
432
433 // refresh list from current active gestures
434 refreshGestures();
435 }
436}
437
385//----------------------------------------------------------------------- 438//-----------------------------------------------------------------------
386// Internal functions 439// Internal functions
387//----------------------------------------------------------------------- 440//-----------------------------------------------------------------------
@@ -473,13 +526,13 @@ void LLChatBar::sendChat( EChatType type )
473 sendChatFromViewer(utf8_revised_text, type, TRUE); 526 sendChatFromViewer(utf8_revised_text, type, TRUE);
474 } 527 }
475 } 528 }
476 childSetValue("Chat Editor", LLSD(LLString::null)); 529 childSetValue("Chat Editor", LLString::null);
477 530
478 gAgent.stopTyping(); 531 gAgent.stopTyping();
479 532
480 // If the user wants to stop chatting on hitting return, lose focus 533 // If the user wants to stop chatting on hitting return, lose focus
481 // and go out of chat mode. 534 // and go out of chat mode.
482 if (gSavedSettings.getBOOL("CloseChatOnReturn")) 535 if (gChatBar == this && gSavedSettings.getBOOL("CloseChatOnReturn"))
483 { 536 {
484 stopChat(); 537 stopChat();
485 } 538 }
@@ -704,7 +757,7 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
704void LLChatBar::onCommitGesture(LLUICtrl* ctrl, void* data) 757void LLChatBar::onCommitGesture(LLUICtrl* ctrl, void* data)
705{ 758{
706 LLChatBar* self = (LLChatBar*)data; 759 LLChatBar* self = (LLChatBar*)data;
707 LLCtrlListInterface* gestures = self->childGetListInterface("Gesture"); 760 LLCtrlListInterface* gestures = self->mGestureCombo ? self->mGestureCombo->getListInterface() : NULL;
708 if (gestures) 761 if (gestures)
709 { 762 {
710 S32 index = gestures->getFirstSelectedIndex(); 763 S32 index = gestures->getFirstSelectedIndex();
@@ -728,6 +781,14 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl, void* data)
728 } 781 }
729 } 782 }
730 self->mGestureLabelTimer.start(); 783 self->mGestureLabelTimer.start();
731 // free focus back to chat bar 784 if (self->mGestureCombo != NULL)
732 self->childSetFocus("Gesture", FALSE); 785 {
786 // free focus back to chat bar
787 self->mGestureCombo->setFocus(FALSE);
788 }
789}
790
791void toggleChatHistory(void* user_data)
792{
793 LLFloaterChat::toggleInstance(LLSD());
733} 794}
diff --git a/linden/indra/newview/llchatbar.h b/linden/indra/newview/llchatbar.h
index 32b0018..8a5acc6 100644
--- a/linden/indra/newview/llchatbar.h
+++ b/linden/indra/newview/llchatbar.h
@@ -33,23 +33,21 @@
33#include "llframetimer.h" 33#include "llframetimer.h"
34#include "llchat.h" 34#include "llchat.h"
35 35
36class LLButton;
37class LLComboBox;
38class LLLineEditor; 36class LLLineEditor;
39class LLMessageSystem; 37class LLMessageSystem;
40class LLTextBox;
41class LLTextEditor;
42class LLUICtrl; 38class LLUICtrl;
43class LLUUID; 39class LLUUID;
44class LLFrameTimer; 40class LLFrameTimer;
45class LLStatGraph;
46class LLChatBarGestureObserver; 41class LLChatBarGestureObserver;
42class LLComboBox;
47 43
48class LLChatBar 44class LLChatBar
49: public LLPanel 45: public LLPanel
50{ 46{
51public: 47public:
52 LLChatBar(const std::string& name, const LLRect& rect ); 48 // constructor for inline chat-bars (e.g. hosted in chat history window)
49 LLChatBar(const std::string& name);
50 LLChatBar(const std::string& name, const LLRect& rect);
53 ~LLChatBar(); 51 ~LLChatBar();
54 virtual BOOL postBuild(); 52 virtual BOOL postBuild();
55 53
@@ -71,6 +69,10 @@ public:
71 BOOL inputEditorHasFocus(); 69 BOOL inputEditorHasFocus();
72 LLString getCurrentChat(); 70 LLString getCurrentChat();
73 71
72 // since chat bar logic is reused for chat history
73 // gesture combo box might not be a direct child
74 void setGestureCombo(LLComboBox* combo);
75
74 // Send a chat (after stripping /20foo channel chats). 76 // Send a chat (after stripping /20foo channel chats).
75 // "Animate" means the nodding animation for regular text. 77 // "Animate" means the nodding animation for regular text.
76 void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); 78 void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
@@ -81,7 +83,6 @@ public:
81 LLWString stripChannelNumber(const LLWString &mesg, S32* channel); 83 LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
82 84
83 // callbacks 85 // callbacks
84 static void onClickHistory( void* userdata );
85 static void onClickSay( void* userdata ); 86 static void onClickSay( void* userdata );
86 static void onClickShout( void* userdata ); 87 static void onClickShout( void* userdata );
87 88
@@ -109,8 +110,10 @@ protected:
109 S32 mLastSpecialChatChannel; 110 S32 mLastSpecialChatChannel;
110 111
111 BOOL mIsBuilt; 112 BOOL mIsBuilt;
112 113 BOOL mDynamicLayout;
113 static LLChatBarGestureObserver* sObserver; 114 LLComboBox* mGestureCombo;
115
116 LLChatBarGestureObserver* mObserver;
114}; 117};
115 118
116extern LLChatBar *gChatBar; 119extern LLChatBar *gChatBar;
diff --git a/linden/indra/newview/llcolorswatch.cpp b/linden/indra/newview/llcolorswatch.cpp
index 19490a2..2503649 100644
--- a/linden/indra/newview/llcolorswatch.cpp
+++ b/linden/indra/newview/llcolorswatch.cpp
@@ -260,21 +260,6 @@ void LLColorSwatchCtrl::setEnabled( BOOL enabled )
260} 260}
261 261
262 262
263//////////////////////////////////////////////////////////////////////////////
264// called when parent filters down a visibility changed message
265void LLColorSwatchCtrl::onVisibilityChange ( BOOL curVisibilityIn )
266{
267 // visibility changed - moved away to different tab for instance - cancel selection
268 //if ( ! curVisibilityIn)
269 //{
270 // LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle);
271 // if (pickerp)
272 // {
273 // pickerp->cancelSelection();
274 // }
275 //}
276}
277
278void LLColorSwatchCtrl::setValue(const LLSD& value) 263void LLColorSwatchCtrl::setValue(const LLSD& value)
279{ 264{
280 set(LLColor4(value), TRUE, TRUE); 265 set(LLColor4(value), TRUE, TRUE);
diff --git a/linden/indra/newview/llcolorswatch.h b/linden/indra/newview/llcolorswatch.h
index b80a0e6..710d332 100644
--- a/linden/indra/newview/llcolorswatch.h
+++ b/linden/indra/newview/llcolorswatch.h
@@ -88,8 +88,6 @@ public:
88 virtual LLXMLNodePtr getXML(bool save_children = true) const; 88 virtual LLXMLNodePtr getXML(bool save_children = true) const;
89 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); 89 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
90 90
91 virtual void onVisibilityChange ( BOOL curVisibilityIn );
92
93 static void onColorChanged ( void* data, EColorPickOp pick_op = COLOR_CHANGE ); 91 static void onColorChanged ( void* data, EColorPickOp pick_op = COLOR_CHANGE );
94 92
95protected: 93protected:
diff --git a/linden/indra/newview/llcontroldef.cpp b/linden/indra/newview/llcontroldef.cpp
index 7481d99..dffaa36 100644
--- a/linden/indra/newview/llcontroldef.cpp
+++ b/linden/indra/newview/llcontroldef.cpp
@@ -43,6 +43,33 @@
43#include "v3color.h" 43#include "v3color.h"
44#include "llfirstuse.h" 44#include "llfirstuse.h"
45 45
46// For Listeners
47#include "audioengine.h"
48#include "llagent.h"
49#include "llconsole.h"
50#include "lldrawpoolterrain.h"
51#include "llflexibleobject.h"
52#include "llglslshader.h"
53#include "llmediaengine.h"
54#include "llpanelgeneral.h"
55#include "llpanelinput.h"
56#include "llsky.h"
57#include "llviewerimagelist.h"
58#include "llviewerthrottle.h"
59#include "llviewerwindow.h"
60#include "llvoavatar.h"
61#include "llvosky.h"
62#include "llvotree.h"
63#include "llvovolume.h"
64#include "llworld.h"
65#include "pipeline.h"
66#include "viewer.h"
67#include "llviewerjoystick.h"
68#include "llviewerparcelmgr.h"
69#include "llparcel.h"
70#include "llnotify.h"
71#include "llkeyboard.h"
72
46void declare_settings() 73void declare_settings()
47{ 74{
48 // Somewhat under 1024 by 768 75 // Somewhat under 1024 by 768
@@ -61,7 +88,7 @@ void declare_settings()
61 gSavedSettings.declareColor4("SystemChatColor", LLColor4(0.8f, 1.f, 1.f, 1.f), "Color of chat messages from SL System"); 88 gSavedSettings.declareColor4("SystemChatColor", LLColor4(0.8f, 1.f, 1.f, 1.f), "Color of chat messages from SL System");
62 gSavedSettings.declareColor4("AgentChatColor", LLColor4(1.0f, 1.0f, 1.0f, 1.0f), "Color of chat messages from other residents"); 89 gSavedSettings.declareColor4("AgentChatColor", LLColor4(1.0f, 1.0f, 1.0f, 1.0f), "Color of chat messages from other residents");
63 gSavedSettings.declareColor4("ObjectChatColor", LLColor4(0.7f, 0.9f, 0.7f, 1.0f), "Color of chat messages from objects"); 90 gSavedSettings.declareColor4("ObjectChatColor", LLColor4(0.7f, 0.9f, 0.7f, 1.0f), "Color of chat messages from objects");
64 gSavedSettings.declareColor4("llOwnerSayChatColor", LLColor4(0.7f, 0.0f, 0.7f, 1.0f), "Color of chat messages from objects only visible to the owner"); 91 gSavedSettings.declareColor4("llOwnerSayChatColor", LLColor4(0.99f, 0.99f, 0.69f, 1.0f), "Color of chat messages from objects only visible to the owner");
65 gSavedSettings.declareColor4("BackgroundChatColor", LLColor4(0.f, 0.f, 0.f, 1.0f), "Color of chat bubble background"); 92 gSavedSettings.declareColor4("BackgroundChatColor", LLColor4(0.f, 0.f, 0.f, 1.0f), "Color of chat bubble background");
66 gSavedSettings.declareColor4("ScriptErrorColor", LLColor4(0.82f, 0.82f, 0.99f, 1.0f), "Color of script error messages"); 93 gSavedSettings.declareColor4("ScriptErrorColor", LLColor4(0.82f, 0.82f, 0.99f, 1.0f), "Color of script error messages");
67 gSavedSettings.declareColor4("HTMLLinkColor", LLColor4(0.6f, 0.6f, 1.0f, 1.0f), "Color of hyperlinks"); 94 gSavedSettings.declareColor4("HTMLLinkColor", LLColor4(0.6f, 0.6f, 1.0f, 1.0f), "Color of hyperlinks");
@@ -237,6 +264,75 @@ void declare_settings()
237 264
238 gSavedSettings.declareBOOL("ChatShowTimestamps", TRUE, "Show timestamps in chat"); 265 gSavedSettings.declareBOOL("ChatShowTimestamps", TRUE, "Show timestamps in chat");
239 266
267 gSavedSettings.declareBOOL("EnableVoiceChat", FALSE, "Enable talking to other residents with a microphone");
268 gSavedSettings.declareBOOL("VoiceCallsFriendsOnly", FALSE, "Only accept voice calls from residents on your friends list");
269 gSavedSettings.declareBOOL("PTTCurrentlyEnabled", TRUE, "", NO_PERSIST);
270 gSavedSettings.declareBOOL("EnablePushToTalk", TRUE, "Must hold down a key or moouse button when talking into your microphone");
271 gSavedSettings.declareString("PushToTalkButton", "MiddleMouse", "Which button or keyboard key is used for push-to-talk");
272 gSavedSettings.declareBOOL("PushToTalkToggle", FALSE, "Should the push-to-talk button behave as a toggle");
273 gSavedSettings.declareS32("VoiceEarLocation", 0, "Location of the virtual ear for voice");
274 gSavedSettings.declareString("VivoxDebugServerName", "bhd.vivox.com", "Hostname of the vivox account server to use for voice when not connected to Agni.");
275 gSavedSettings.declareColor4("SpeakingColor", LLColor4(0.f, 1.f, 0.f, 1.f), "Color of various indicators when resident is speaking on a voice channel.");
276 gSavedSettings.declareColor4("OverdrivenColor", LLColor4(1.f, 0.f, 0.f, 1.f), "Color of various indicators when resident is speaking too loud.");
277 gSavedSettings.declareString("VoiceInputAudioDevice", "Default", "Audio input device to use for voice");
278 gSavedSettings.declareString("VoiceOutputAudioDevice", "Default", "Audio output device to use for voice");
279 gSavedSettings.declareString("VivoxDebugLevel", "-1", "Logging level to use when launching the vivox daemon");
280
281 //voice amplitude images;
282
283 /*
284 gSavedSettings.declareString("VoiceImageLevel0", "5b41b4c3-eb70-0f0f-17d9-1765cbd07d39", "Texture UUID for voice image level 0");
285 gSavedSettings.declareString("VoiceImageLevel1", "b06ffd0a-7bfe-0449-0bbc-df291f1857c4", "Texture UUID for voice image level 1");
286 gSavedSettings.declareString("VoiceImageLevel2", "bfa16494-b731-5b59-3260-9e4fd29d63f7", "Texture UUID for voice image level 2");
287 gSavedSettings.declareString("VoiceImageLevel3", "6951074f-de1d-3c55-cb2f-e972877f7f81", "Texture UUID for voice image level 3");
288 gSavedSettings.declareString("VoiceImageLevel4", "ce3df80a-f0c5-a7cb-f5bc-d3bb38949d0d", "Texture UUID for voice image level 4");
289 gSavedSettings.declareString("VoiceImageLevel5", "8d0e359c-5cea-bdf5-b6b0-32d2fea6355c", "Texture UUID for voice image level 5");
290 gSavedSettings.declareString("VoiceImageLevel6", "ad9e64e0-a763-5d8c-f2e8-7b5dfdb7f20f", "Texture UUID for voice image level 6");
291 */
292
293 /*
294 // Jeffrey's first version
295 gSavedSettings.declareString("VoiceImageLevel0", "5b41b4c3-eb70-0f0f-17d9-1765cbd07d39", "Texture UUID for voice image level 0");
296 gSavedSettings.declareString("VoiceImageLevel1", "cde76ae8-0044-d575-8e2c-65fb0a14cbde", "Texture UUID for voice image level 1");
297 gSavedSettings.declareString("VoiceImageLevel2", "cde76ae8-0044-d575-8e2c-65fb0a14cbde", "Texture UUID for voice image level 2");
298 gSavedSettings.declareString("VoiceImageLevel3", "cde76ae8-0044-d575-8e2c-65fb0a14cbde", "Texture UUID for voice image level 3");
299 gSavedSettings.declareString("VoiceImageLevel4", "cde76ae8-0044-d575-8e2c-65fb0a14cbde", "Texture UUID for voice image level 4");
300 gSavedSettings.declareString("VoiceImageLevel5", "cde76ae8-0044-d575-8e2c-65fb0a14cbde", "Texture UUID for voice image level 5");
301 gSavedSettings.declareString("VoiceImageLevel6", "cde76ae8-0044-d575-8e2c-65fb0a14cbde", "Texture UUID for voice image level 6");
302 */
303
304 // Brent's first version
305 /*
306 gSavedSettings.declareString("VoiceImageLevel0", "5b41b4c3-eb70-0f0f-17d9-1765cbd07d39", "Texture UUID for voice image level 0");
307 gSavedSettings.declareString("VoiceImageLevel1", "72365124-c7a7-a1f9-3d7a-d8e521eb5011", "Texture UUID for voice image level 1");
308 gSavedSettings.declareString("VoiceImageLevel2", "72365124-c7a7-a1f9-3d7a-d8e521eb5011", "Texture UUID for voice image level 2");
309 gSavedSettings.declareString("VoiceImageLevel3", "72365124-c7a7-a1f9-3d7a-d8e521eb5011", "Texture UUID for voice image level 3");
310 gSavedSettings.declareString("VoiceImageLevel4", "72365124-c7a7-a1f9-3d7a-d8e521eb5011", "Texture UUID for voice image level 4");
311 gSavedSettings.declareString("VoiceImageLevel5", "72365124-c7a7-a1f9-3d7a-d8e521eb5011", "Texture UUID for voice image level 5");
312 gSavedSettings.declareString("VoiceImageLevel6", "72365124-c7a7-a1f9-3d7a-d8e521eb5011", "Texture UUID for voice image level 6");
313 */
314
315 /*
316 // Brent's second version
317 gSavedSettings.declareString("VoiceImageLevel0", "5b41b4c3-eb70-0f0f-17d9-1765cbd07d39", "Texture UUID for voice image level 0");
318 gSavedSettings.declareString("VoiceImageLevel1", "4ee6a7ac-472e-b5ff-7125-f6213798cbee", "Texture UUID for voice image level 1");
319 gSavedSettings.declareString("VoiceImageLevel2", "4ee6a7ac-472e-b5ff-7125-f6213798cbee", "Texture UUID for voice image level 2");
320 gSavedSettings.declareString("VoiceImageLevel3", "4ee6a7ac-472e-b5ff-7125-f6213798cbee", "Texture UUID for voice image level 3");
321 gSavedSettings.declareString("VoiceImageLevel4", "4ee6a7ac-472e-b5ff-7125-f6213798cbee", "Texture UUID for voice image level 4");
322 gSavedSettings.declareString("VoiceImageLevel5", "4ee6a7ac-472e-b5ff-7125-f6213798cbee", "Texture UUID for voice image level 5");
323 gSavedSettings.declareString("VoiceImageLevel6", "4ee6a7ac-472e-b5ff-7125-f6213798cbee", "Texture UUID for voice image level 6");
324 */
325
326 // Jeffrey's tweak on 4/9/07
327 gSavedSettings.declareString("VoiceImageLevel0", "041ee5a0-cb6a-9ac5-6e49-41e9320507d5", "Texture UUID for voice image level 0");
328 gSavedSettings.declareString("VoiceImageLevel1", "29de489d-0491-fb00-7dab-f9e686d31e83", "Texture UUID for voice image level 1");
329 gSavedSettings.declareString("VoiceImageLevel2", "29de489d-0491-fb00-7dab-f9e686d31e83", "Texture UUID for voice image level 2");
330 gSavedSettings.declareString("VoiceImageLevel3", "29de489d-0491-fb00-7dab-f9e686d31e83", "Texture UUID for voice image level 3");
331 gSavedSettings.declareString("VoiceImageLevel4", "29de489d-0491-fb00-7dab-f9e686d31e83", "Texture UUID for voice image level 4");
332 gSavedSettings.declareString("VoiceImageLevel5", "29de489d-0491-fb00-7dab-f9e686d31e83", "Texture UUID for voice image level 5");
333 gSavedSettings.declareString("VoiceImageLevel6", "29de489d-0491-fb00-7dab-f9e686d31e83", "Texture UUID for voice image level 6");
334
335
240 //------------------------------------------------------------------------ 336 //------------------------------------------------------------------------
241 // Caution Script Permission Prompts 337 // Caution Script Permission Prompts
242 //------------------------------------------------------------------------ 338 //------------------------------------------------------------------------
@@ -419,6 +515,7 @@ void declare_settings()
419 gSavedSettings.declareBOOL("CloseChatOnReturn", FALSE, "Close chat after hitting return"); 515 gSavedSettings.declareBOOL("CloseChatOnReturn", FALSE, "Close chat after hitting return");
420 516
421 // Copy IM messages into chat history 517 // Copy IM messages into chat history
518 gSavedSettings.declareBOOL("ChatHistoryTornOff", FALSE, "Show chat history window separately from Communicate window.");
422 gSavedSettings.declareBOOL("IMInChatHistory", FALSE, "Copy IM into chat history"); 519 gSavedSettings.declareBOOL("IMInChatHistory", FALSE, "Copy IM into chat history");
423 gSavedSettings.declareBOOL("IMShowTimestamps", TRUE, "Show timestamps in IM"); 520 gSavedSettings.declareBOOL("IMShowTimestamps", TRUE, "Show timestamps in IM");
424 521
@@ -591,11 +688,10 @@ void declare_settings()
591 688
592 gSavedSettings.declareBOOL("ShowLeaders", FALSE, "", NO_PERSIST); 689 gSavedSettings.declareBOOL("ShowLeaders", FALSE, "", NO_PERSIST);
593 gSavedSettings.declareBOOL("ShowDirectory", FALSE, "", NO_PERSIST); 690 gSavedSettings.declareBOOL("ShowDirectory", FALSE, "", NO_PERSIST);
594 gSavedSettings.declareBOOL("ShowFriends", FALSE, "", NO_PERSIST);
595 691
596 gSavedSettings.declareBOOL("AutoLoadWebProfiles", FALSE, "Automatically load ALL profile webpages without asking first."); 692 gSavedSettings.declareBOOL("AutoLoadWebProfiles", FALSE, "Automatically load ALL profile webpages without asking first.");
597 693
598 gSavedSettings.declareBOOL("ShowIM", FALSE, "", NO_PERSIST); 694 gSavedSettings.declareBOOL("ShowCommunicate", FALSE, "", NO_PERSIST);
599 gSavedSettings.declareBOOL("ShowChatHistory", FALSE, "", NO_PERSIST); 695 gSavedSettings.declareBOOL("ShowChatHistory", FALSE, "", NO_PERSIST);
600 696
601#ifdef LL_RELEASE_FOR_DOWNLOAD 697#ifdef LL_RELEASE_FOR_DOWNLOAD
@@ -636,6 +732,7 @@ void declare_settings()
636 LLFirstUse::addConfigVariable("FirstStreamingMusic"); 732 LLFirstUse::addConfigVariable("FirstStreamingMusic");
637 LLFirstUse::addConfigVariable("FirstStreamingVideo"); 733 LLFirstUse::addConfigVariable("FirstStreamingVideo");
638 LLFirstUse::addConfigVariable("FirstSculptedPrim"); 734 LLFirstUse::addConfigVariable("FirstSculptedPrim");
735 LLFirstUse::addConfigVariable("FirstVoice");
639 736
640 gSavedSettings.declareBOOL("ShowDebugConsole", FALSE, "Show log in SL window"); 737 gSavedSettings.declareBOOL("ShowDebugConsole", FALSE, "Show log in SL window");
641 gSavedSettings.declareBOOL("ShowDebugStats", FALSE, "Show performance stats display"); 738 gSavedSettings.declareBOOL("ShowDebugStats", FALSE, "Show performance stats display");
@@ -797,6 +894,9 @@ void declare_settings()
797 894
798 //gSavedSettings.declareS32("BWRadio", 0, "[NOT USED]"); 895 //gSavedSettings.declareS32("BWRadio", 0, "[NOT USED]");
799 896
897 gSavedSettings.declareRect("ChatterboxRect", LLRect(0, 400, 350, 0), "Rectangle for chatterbox window");
898 gSavedSettings.declareRect("FloaterActiveSpeakersRect", LLRect(0, 300, 250, 0), "Rectangle for active speakers window");
899
800 // Avatar customizing floaters 900 // Avatar customizing floaters
801 gSavedSettings.declareRect("FloaterCustomizeAppearanceRect", LLRect(0, 540, 494, 0), "Rectangle for avatar customization window"); 901 gSavedSettings.declareRect("FloaterCustomizeAppearanceRect", LLRect(0, 540, 494, 0), "Rectangle for avatar customization window");
802 902
@@ -923,6 +1023,9 @@ void declare_settings()
923 // Script Panel 1023 // Script Panel
924 //gSavedSettings.declareRect("ScriptPanelRect", LLRect(250, 175 + 400, 250 + 400, 175), "[NOT USED]"); 1024 //gSavedSettings.declareRect("ScriptPanelRect", LLRect(250, 175 + 400, 250 + 400, 175), "[NOT USED]");
925 1025
1026 // volume floater
1027 gSavedSettings.declareRect("FloaterAudioVolumeRect", LLRect(0, 440, 470, 0), "Rectangle for Audio Volume window");
1028
926 // Radio button sets 1029 // Radio button sets
927 gSavedSettings.declareU32("AvatarSex", 0, "", NO_PERSIST); 1030 gSavedSettings.declareU32("AvatarSex", 0, "", NO_PERSIST);
928 1031
@@ -1012,16 +1115,20 @@ void declare_settings()
1012 gSavedSettings.declareRect("HtmlFindRect", LLRect(16,650,600,128), "Rectangle for HTML find window"); 1115 gSavedSettings.declareRect("HtmlFindRect", LLRect(16,650,600,128), "Rectangle for HTML find window");
1013 1116
1014 // Audio 1117 // Audio
1015 gSavedSettings.declareF32("AudioLevelDistance", 1.0f, "Scale factor for audio engine (multiple of world scale, 2.0 = audio falls off twice as fast)");
1016 gSavedSettings.declareF32("AudioLevelDoppler", 1.0f, "Scale of doppler effect on moving audio sources (1.0 = normal, <1.0 = diminished doppler effect, >1.0 = enhanced doppler effect)");
1017 gSavedSettings.declareF32("AudioLevelFootsteps", 0.15f, "Relative audio level of footstep sound effects");
1018 gSavedSettings.declareF32("AudioLevelMaster", 1.0f, "Master audio level, or overall volume"); 1118 gSavedSettings.declareF32("AudioLevelMaster", 1.0f, "Master audio level, or overall volume");
1119 gSavedSettings.declareF32("AudioLevelSFX", 1.0f, "Audio level of in-world sound effects");
1120 gSavedSettings.declareF32("AudioLevelAmbient",0.5f, "Audio level of environment sounds");
1121 gSavedSettings.declareF32("AudioLevelUI", 0.5f, "Audio level of UI sound effects");
1019 gSavedSettings.declareF32("AudioLevelMusic", 1.0f, "Audio level of streaming music"); 1122 gSavedSettings.declareF32("AudioLevelMusic", 1.0f, "Audio level of streaming music");
1020 gSavedSettings.declareF32("MediaAudioVolume", 1.0f, "Audio level of Quicktime movies"); 1123 gSavedSettings.declareF32("AudioLevelVoice", 1.0f, "Audio level of voice chat");
1124 gSavedSettings.declareF32("AudioLevelMedia", 1.0f, "Audio level of Quicktime movies");
1125 gSavedSettings.declareF32("AudioLevelMic", 1.0f, "Audio level of microphone input");
1126
1127// gSavedSettings.declareF32("MediaAudioVolume", 1.0f, "Audio level of Quicktime movies"); // removed
1128
1129 gSavedSettings.declareF32("AudioLevelDistance", 1.0f, "Scale factor for audio engine (multiple of world scale, 2.0 = audio falls off twice as fast)");
1130 gSavedSettings.declareF32("AudioLevelDoppler", 1.0f, "Scale of doppler effect on moving audio sources (1.0 = normal, <1.0 = diminished doppler effect, >1.0 = enhanced doppler effect)");
1021 gSavedSettings.declareF32("AudioLevelRolloff", 1.0f, "Controls the distance-based dropoff of audio volume (fraction or multiple of default audio rolloff)"); 1131 gSavedSettings.declareF32("AudioLevelRolloff", 1.0f, "Controls the distance-based dropoff of audio volume (fraction or multiple of default audio rolloff)");
1022 gSavedSettings.declareF32("AudioLevelUI", 0.5f, "Audio level of UI sound effects");
1023 //gSavedSettings.declareF32("AudioLevelWater", 0.0f, "[NOT USED]");
1024 gSavedSettings.declareF32("AudioLevelWind", 0.5f, "Audio level of wind sound effect");
1025 1132
1026 gSavedSettings.declareS32("AudioDefaultBitrate", 64, "Data streaming rate of uploaded audio samples (thousands of bits per second)"); 1133 gSavedSettings.declareS32("AudioDefaultBitrate", 64, "Data streaming rate of uploaded audio samples (thousands of bits per second)");
1027 gSavedSettings.declareBOOL("AudioStreamingMusic", FALSE, "Enable streaming audio"); 1134 gSavedSettings.declareBOOL("AudioStreamingMusic", FALSE, "Enable streaming audio");
@@ -1107,11 +1214,7 @@ void declare_settings()
1107 gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "Turns on \"Debug\" menu"); 1214 gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "Turns on \"Debug\" menu");
1108 gSavedSettings.declareS32("ServerChoice", 0, "[DO NOT MODIFY] Controls which grid you connect to"); 1215 gSavedSettings.declareS32("ServerChoice", 0, "[DO NOT MODIFY] Controls which grid you connect to");
1109 gSavedSettings.declareString("CustomServer", "", "Specifies IP address or hostname of userserver to which you connect"); 1216 gSavedSettings.declareString("CustomServer", "", "Specifies IP address or hostname of userserver to which you connect");
1110#ifdef LL_RELEASE_FOR_DOWNLOAD
1111 gSavedSettings.declareBOOL("UseDebugLogin", FALSE, "Provides extra control over which grid to connect to"); 1217 gSavedSettings.declareBOOL("UseDebugLogin", FALSE, "Provides extra control over which grid to connect to");
1112#else
1113 gSavedSettings.declareBOOL("UseDebugLogin", TRUE, "Provides extra control over which grid to connect to" );
1114#endif
1115 1218
1116 // First run is true on the first startup of a given installation. 1219 // First run is true on the first startup of a given installation.
1117 // It is not related to whether your ACCOUNT has been logged in before. 1220 // It is not related to whether your ACCOUNT has been logged in before.
@@ -1146,7 +1249,15 @@ void declare_settings()
1146 gSavedSettings.declareBOOL("EditCameraMovement", FALSE, "When entering build mode, camera moves up above avatar"); 1249 gSavedSettings.declareBOOL("EditCameraMovement", FALSE, "When entering build mode, camera moves up above avatar");
1147 gSavedSettings.declareBOOL("AppearanceCameraMovement", TRUE, "When entering appearance editing mode, camera zooms in on currently selected portion of avatar"); 1250 gSavedSettings.declareBOOL("AppearanceCameraMovement", TRUE, "When entering appearance editing mode, camera zooms in on currently selected portion of avatar");
1148 1251
1149 gSavedSettings.declareBOOL("AltShowsPhysical", FALSE, "When ALT key is held down, physical objects are rendered in red."); 1252 //gSavedSettings.declareBOOL("AltShowsPhysical", FALSE, "When ALT key is held down, physical objects are rendered in red.");
1253 gSavedSettings.declareBOOL("BeaconAlwaysOn", FALSE, "Beacons / highlighting always on");
1254 gSavedSettings.declareBOOL("scriptsbeacon", FALSE, "Beacon / Highlight scripted objects");
1255 gSavedSettings.declareBOOL("physicalbeacon", TRUE, "Beacon / Highlight physical objects");
1256 gSavedSettings.declareBOOL("soundsbeacon", FALSE, "Beacon / Highlight sound generators");
1257 gSavedSettings.declareBOOL("particlesbeacon", FALSE, "Beacon / Highlight particle generators");
1258 gSavedSettings.declareBOOL("scripttouchbeacon", TRUE, "Beacon / Highlight scripted objects with touch function");
1259 gSavedSettings.declareBOOL("renderbeacons", FALSE, "Beacon / Highlight particle generators");
1260 gSavedSettings.declareBOOL("renderhighlights", TRUE, "Beacon / Highlight scripted objects with touch function");
1150 1261
1151 gSavedSettings.declareBOOL("MuteAudio", FALSE, "All audio plays at 0 volume (streaming audio still takes up bandwidth, for example)"); 1262 gSavedSettings.declareBOOL("MuteAudio", FALSE, "All audio plays at 0 volume (streaming audio still takes up bandwidth, for example)");
1152 gSavedSettings.declareBOOL("MuteWhenMinimized", TRUE, "Mute audio when SL window is minimized"); 1263 gSavedSettings.declareBOOL("MuteWhenMinimized", TRUE, "Mute audio when SL window is minimized");
@@ -1317,6 +1428,12 @@ void declare_settings()
1317 gSavedSettings.declareBOOL("FlycamAbsolute", FALSE, "Treat Flycam values as absolute positions (not deltas)."); 1428 gSavedSettings.declareBOOL("FlycamAbsolute", FALSE, "Treat Flycam values as absolute positions (not deltas).");
1318 gSavedSettings.declareBOOL("FlycamZoomDirect", FALSE, "Map flycam zoom axis directly to camera zoom."); 1429 gSavedSettings.declareBOOL("FlycamZoomDirect", FALSE, "Map flycam zoom axis directly to camera zoom.");
1319 1430
1431 // Vector Processor & Math
1432 gSavedSettings.declareBOOL("VectorizePerfTest", TRUE, "Test SSE/vectorization performance and choose fastest version.");
1433 gSavedSettings.declareBOOL("VectorizeEnable", FALSE, "Enable general vector operations and data alignment.");
1434 gSavedSettings.declareBOOL("VectorizeSkin", TRUE, "Enable vector operations for avatar skinning.");
1435 gSavedSettings.declareU32( "VectorizeProcessor", 0, "0=Compiler Default, 1=SSE, 2=SSE2, autodetected", NO_PERSIST);
1436
1320 // 1437 //
1321 // crash_settings.xml 1438 // crash_settings.xml
1322 // 1439 //
@@ -1333,3 +1450,460 @@ void fixup_settings()
1333 gSavedSettings.setBOOL("AnimateTextures", TRUE); // Force AnimateTextures to always be on 1450 gSavedSettings.setBOOL("AnimateTextures", TRUE); // Force AnimateTextures to always be on
1334#endif 1451#endif
1335} 1452}
1453
1454////////////////////////////////////////////////////////////////////////////
1455// Listeners
1456
1457class LLAFKTimeoutListener: public LLSimpleListener
1458{
1459 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1460 {
1461 gAFKTimeout = (F32) event->getValue().asReal();
1462 return true;
1463 }
1464};
1465static LLAFKTimeoutListener afk_timeout_listener;
1466
1467class LLMouseSensitivityListener: public LLSimpleListener
1468{
1469 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1470 {
1471 gMouseSensitivity = (F32) event->getValue().asReal();
1472 return true;
1473 }
1474};
1475static LLMouseSensitivityListener mouse_sensitivity_listener;
1476
1477
1478class LLInvertMouseListener: public LLSimpleListener
1479{
1480 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1481 {
1482 gInvertMouse = event->getValue().asBoolean();
1483 return true;
1484 }
1485};
1486static LLInvertMouseListener invert_mouse_listener;
1487
1488class LLRenderAvatarMouselookListener: public LLSimpleListener
1489{
1490 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1491 {
1492 LLVOAvatar::sVisibleInFirstPerson = event->getValue().asBoolean();
1493 return true;
1494 }
1495};
1496static LLRenderAvatarMouselookListener render_avatar_mouselook_listener;
1497
1498class LLRenderFarClipListener: public LLSimpleListener
1499{
1500 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1501 {
1502 F32 draw_distance = (F32) event->getValue().asReal();
1503 gAgent.mDrawDistance = draw_distance;
1504 if (gWorldPointer)
1505 {
1506 gWorldPointer->setLandFarClip(draw_distance);
1507 }
1508 return true;
1509 }
1510};
1511static LLRenderFarClipListener render_far_clip_listener;
1512
1513class LLTerrainDetailListener: public LLSimpleListener
1514{
1515 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1516 {
1517 LLDrawPoolTerrain::sDetailMode = event->getValue().asInteger();
1518 return true;
1519 }
1520};
1521static LLTerrainDetailListener terrain_detail_listener;
1522
1523
1524class LLSetShaderListener: public LLSimpleListener
1525{
1526 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1527 {
1528 LLShaderMgr::setShaders();
1529 return true;
1530 }
1531};
1532static LLSetShaderListener set_shader_listener;
1533
1534class LLReleaseGLBufferListener: public LLSimpleListener
1535{
1536 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1537 {
1538 gPipeline.releaseGLBuffers();
1539 LLShaderMgr::setShaders();
1540 return true;
1541 }
1542};
1543static LLReleaseGLBufferListener release_gl_buffer_listener;
1544
1545class LLVolumeLODListener: public LLSimpleListener
1546{
1547 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1548 {
1549 LLVOVolume::sLODFactor = (F32) event->getValue().asReal();
1550 LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
1551 return true;
1552 }
1553};
1554static LLVolumeLODListener volume_lod_listener;
1555
1556class LLAvatarLODListener: public LLSimpleListener
1557{
1558 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1559 {
1560 LLVOAvatar::sLODFactor = (F32) event->getValue().asReal();
1561 return true;
1562 }
1563};
1564static LLAvatarLODListener avatar_lod_listener;
1565
1566class LLTreeLODListener: public LLSimpleListener
1567{
1568 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1569 {
1570 LLVOTree::sTreeFactor = (F32) event->getValue().asReal();
1571 return true;
1572 }
1573};
1574static LLTreeLODListener tree_lod_listener;
1575
1576class LLFlexLODListener: public LLSimpleListener
1577{
1578 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1579 {
1580 LLVolumeImplFlexible::sUpdateFactor = (F32) event->getValue().asReal();
1581 return true;
1582 }
1583};
1584static LLFlexLODListener flex_lod_listener;
1585
1586class LLGammaListener: public LLSimpleListener
1587{
1588 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1589 {
1590 F32 gamma = (F32) event->getValue().asReal();
1591 if (gamma == 0.0f)
1592 {
1593 gamma = 1.0f; // restore normal gamma
1594 }
1595 if (gamma != gViewerWindow->getWindow()->getGamma())
1596 {
1597 // Only save it if it's changed
1598 if (!gViewerWindow->getWindow()->setGamma(gamma))
1599 {
1600 llwarns << "setGamma failed!" << llendl;
1601 }
1602 }
1603
1604 return true;
1605 }
1606};
1607static LLGammaListener gamma_listener;
1608
1609class LLNightBrightnessListener: public LLSimpleListener
1610{
1611 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1612 {
1613 LLVOSky::sNighttimeBrightness = (F32) event->getValue().asReal();
1614 return true;
1615 }
1616};
1617static LLNightBrightnessListener night_brightness_listener;
1618
1619const F32 MAX_USER_FOG_RATIO = 4.f;
1620const F32 MIN_USER_FOG_RATIO = 0.5f;
1621
1622class LLFogRatioListener: public LLSimpleListener
1623{
1624 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1625 {
1626 F32 fog_ratio = llmax(MIN_USER_FOG_RATIO,
1627 llmin((F32) event->getValue().asReal(),
1628 MAX_USER_FOG_RATIO));
1629 gSky.setFogRatio(fog_ratio);
1630 return true;
1631 }
1632};
1633static LLFogRatioListener fog_ratio_listener;
1634
1635class LLMaxPartCountListener: public LLSimpleListener
1636{
1637 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1638 {
1639 LLViewerPartSim::setMaxPartCount(event->getValue().asInteger());
1640 return true;
1641 }
1642};
1643static LLMaxPartCountListener max_partCount_listener;
1644
1645const S32 MAX_USER_COMPOSITE_LIMIT = 100;
1646const S32 MIN_USER_COMPOSITE_LIMIT = 0;
1647
1648class LLCompositeLimitListener: public LLSimpleListener
1649{
1650 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1651 {
1652 S32 composite_limit = llmax(MIN_USER_COMPOSITE_LIMIT,
1653 llmin((S32)event->getValue().asInteger(),
1654 MAX_USER_COMPOSITE_LIMIT));
1655 LLVOAvatar::sMaxOtherAvatarsToComposite = composite_limit;
1656 return true;
1657 }
1658};
1659static LLCompositeLimitListener composite_limit_listener;
1660
1661class LLVideoMemoryListener: public LLSimpleListener
1662{
1663 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1664 {
1665 gImageList.updateMaxResidentTexMem(event->getValue().asInteger());
1666 return true;
1667 }
1668};
1669static LLVideoMemoryListener video_memory_listener;
1670
1671class LLBandwidthListener: public LLSimpleListener
1672{
1673 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1674 {
1675 gViewerThrottle.setMaxBandwidth((F32) event->getValue().asReal());
1676 return true;
1677 }
1678};
1679static LLBandwidthListener bandwidth_listener;
1680
1681class LLChatFontSizeListener: public LLSimpleListener
1682{
1683 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1684 {
1685 gConsole->setFontSize(event->getValue().asInteger());
1686 return true;
1687 }
1688};
1689static LLChatFontSizeListener chat_font_size_listener;
1690
1691class LLChatPersistTimeListener: public LLSimpleListener
1692{
1693 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1694 {
1695 gConsole->setLinePersistTime((F32) event->getValue().asReal());
1696 return true;
1697 }
1698};
1699static LLChatPersistTimeListener chat_persist_time_listener;
1700
1701class LLConsoleMaxLinesListener: public LLSimpleListener
1702{
1703 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1704 {
1705 gConsole->setMaxLines(event->getValue().asInteger());
1706 return true;
1707 }
1708};
1709static LLConsoleMaxLinesListener console_max_lines_listener;
1710
1711// Listener for all volume settings
1712class LLAudioListener: public LLSimpleListener
1713{
1714 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1715 {
1716 audio_update_volume(true);
1717 return true;
1718 }
1719};
1720static LLAudioListener audio_listener;
1721
1722class LLJoystickListener : public LLSimpleListener
1723{
1724 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1725 {
1726 LLViewerJoystick::updateCamera(TRUE);
1727 return true;
1728 }
1729};
1730static LLJoystickListener joystick_listener;
1731
1732void stop_video();
1733void prepare_video(const LLParcel *parcel);
1734
1735class LLAudioStreamMusicListener: public LLSimpleListener
1736{
1737 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1738 {
1739 if (gAudiop)
1740 {
1741 if ( event->getValue().asBoolean() )
1742 {
1743 if (gParcelMgr
1744 && gParcelMgr->getAgentParcel()
1745 && gParcelMgr->getAgentParcel()->getMusicURL())
1746 {
1747 // if stream is already playing, don't call this
1748 // otherwise music will briefly stop
1749 if ( ! gAudiop->isInternetStreamPlaying() )
1750 {
1751 gAudiop->startInternetStream(gParcelMgr->getAgentParcel()->getMusicURL());
1752 }
1753 }
1754 }
1755 else
1756 {
1757 gAudiop->stopInternetStream();
1758 }
1759 }
1760 return true;
1761 }
1762};
1763
1764static LLAudioStreamMusicListener audio_stream_music_listener;
1765
1766
1767
1768class LLAudioStreamMediaListener: public LLSimpleListener
1769{
1770 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1771 {
1772 if (LLMediaEngine::getInstance() && LLMediaEngine::getInstance()->isAvailable())
1773 {
1774 if (event->getValue().asBoolean())
1775 {
1776 gMessageSystem->setHandlerFunc ( "ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media );
1777 gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update );
1778 if ( ( gParcelMgr ) &&
1779 ( gParcelMgr->getAgentParcel () ) &&
1780 ( gParcelMgr->getAgentParcel()->getMediaURL () ) )
1781 {
1782 prepare_video ( gParcelMgr->getAgentParcel () );
1783 }
1784 }
1785 else
1786 {
1787 gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback);
1788 gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback );
1789 stop_video();
1790 }
1791 }
1792 else
1793 {
1794 if (gSavedSettings.getWarning("QuickTimeInstalled"))
1795 {
1796 gSavedSettings.setWarning("QuickTimeInstalled", FALSE);
1797
1798 LLNotifyBox::showXml("NoQuickTime" );
1799 }
1800 }
1801
1802 return true;
1803 }
1804};
1805
1806static LLAudioStreamMediaListener audio_stream_media_listener;
1807
1808
1809class LLUseOcclusionListener: public LLSimpleListener
1810{
1811 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1812 {
1813 LLPipeline::sUseOcclusion = (event->getValue().asBoolean() && gGLManager.mHasOcclusionQuery &&
1814 !gUseWireframe);
1815 return true;
1816 }
1817};
1818static LLUseOcclusionListener use_occlusion_listener;
1819
1820class LLNumpadControlListener: public LLSimpleListener
1821{
1822 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1823 {
1824 if (gKeyboard)
1825 {
1826 gKeyboard->setNumpadDistinct(static_cast<LLKeyboard::e_numpad_distinct>(event->getValue().asInteger()));
1827 }
1828 return true;
1829 }
1830};
1831
1832static LLNumpadControlListener numpad_control_listener;
1833
1834class LLRenderUseVBOListener: public LLSimpleListener
1835{
1836 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1837 {
1838 gPipeline.setUseVBO(event->getValue().asBoolean());
1839 return true;
1840 }
1841};
1842static LLRenderUseVBOListener render_use_vbo_listener;
1843
1844class LLRenderLightingDetailListener: public LLSimpleListener
1845{
1846 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1847 {
1848 gPipeline.setLightingDetail(event->getValue().asInteger());
1849 return true;
1850 }
1851};
1852static LLRenderLightingDetailListener render_lighting_detail_listener;
1853
1854////////////////////////////////////////////////////////////////////////////
1855
1856void settings_setup_listeners()
1857{
1858 gSavedSettings.getControl("FirstPersonAvatarVisible")->addListener(&render_avatar_mouselook_listener);
1859 gSavedSettings.getControl("MouseSensitivity")->addListener(&mouse_sensitivity_listener);
1860 gSavedSettings.getControl("InvertMouse")->addListener(&invert_mouse_listener);
1861 gSavedSettings.getControl("AFKTimeout")->addListener(&afk_timeout_listener);
1862 gSavedSettings.getControl("RenderFarClip")->addListener(&render_far_clip_listener);
1863 gSavedSettings.getControl("RenderTerrainDetail")->addListener(&terrain_detail_listener);
1864 gSavedSettings.getControl("RenderRippleWater")->addListener(&set_shader_listener);
1865 gSavedSettings.getControl("RenderAvatarVP")->addListener(&set_shader_listener);
1866 gSavedSettings.getControl("VertexShaderEnable")->addListener(&set_shader_listener);
1867 gSavedSettings.getControl("RenderDynamicReflections")->addListener(&set_shader_listener);
1868 gSavedSettings.getControl("RenderGlow")->addListener(&release_gl_buffer_listener);
1869 gSavedSettings.getControl("RenderGlowResolution")->addListener(&release_gl_buffer_listener);
1870 gSavedSettings.getControl("RenderAvatarMode")->addListener(&set_shader_listener);
1871 gSavedSettings.getControl("RenderVolumeLODFactor")->addListener(&volume_lod_listener);
1872 gSavedSettings.getControl("RenderAvatarLODFactor")->addListener(&avatar_lod_listener);
1873 gSavedSettings.getControl("RenderTreeLODFactor")->addListener(&tree_lod_listener);
1874 gSavedSettings.getControl("RenderFlexTimeFactor")->addListener(&flex_lod_listener);
1875 gSavedSettings.getControl("ThrottleBandwidthKBPS")->addListener(&bandwidth_listener);
1876 gSavedSettings.getControl("RenderGamma")->addListener(&gamma_listener);
1877 gSavedSettings.getControl("RenderNightBrightness")->addListener(&night_brightness_listener);
1878 gSavedSettings.getControl("RenderFogRatio")->addListener(&fog_ratio_listener);
1879 gSavedSettings.getControl("RenderMaxPartCount")->addListener(&max_partCount_listener);
1880 gSavedSettings.getControl("AvatarCompositeLimit")->addListener(&composite_limit_listener);
1881 gSavedSettings.getControl("GraphicsCardMemorySetting")->addListener(&video_memory_listener);
1882 gSavedSettings.getControl("ChatFontSize")->addListener(&chat_font_size_listener);
1883 gSavedSettings.getControl("ChatPersistTime")->addListener(&chat_persist_time_listener);
1884 gSavedSettings.getControl("ConsoleMaxLines")->addListener(&console_max_lines_listener);
1885 gSavedSettings.getControl("UseOcclusion")->addListener(&use_occlusion_listener);
1886 gSavedSettings.getControl("AudioLevelMaster")->addListener(&audio_listener);
1887// gSavedSettings.getControl("AudioLevelSFX")->addListener(&audio_volume_listener); // no need for listener
1888// gSavedSettings.getControl("AudioLevelUI")->addListener(&audio_volume_listener); // no need for listener
1889 gSavedSettings.getControl("AudioLevelAmbient")->addListener(&audio_listener);
1890 gSavedSettings.getControl("AudioLevelMusic")->addListener(&audio_listener);
1891 gSavedSettings.getControl("AudioLevelMedia")->addListener(&audio_listener);
1892 gSavedSettings.getControl("AudioLevelVoice")->addListener(&audio_listener);
1893 gSavedSettings.getControl("AudioLevelDistance")->addListener(&audio_listener);
1894 gSavedSettings.getControl("AudioLevelDoppler")->addListener(&audio_listener);
1895 gSavedSettings.getControl("AudioLevelRolloff")->addListener(&audio_listener);
1896 gSavedSettings.getControl("AudioStreamingMusic")->addListener(&audio_stream_music_listener);
1897 gSavedSettings.getControl("AudioStreamingVideo")->addListener(&audio_stream_media_listener);
1898 gSavedSettings.getControl("MuteAudio")->addListener(&audio_listener);
1899 gSavedSettings.getControl("RenderVBOEnable")->addListener(&render_use_vbo_listener);
1900 gSavedSettings.getControl("RenderLightingDetail")->addListener(&render_lighting_detail_listener);
1901 gSavedSettings.getControl("NumpadControl")->addListener(&numpad_control_listener);
1902 gSavedSettings.getControl("FlycamAxis0")->addListener(&joystick_listener);
1903 gSavedSettings.getControl("FlycamAxis1")->addListener(&joystick_listener);
1904 gSavedSettings.getControl("FlycamAxis2")->addListener(&joystick_listener);
1905 gSavedSettings.getControl("FlycamAxis3")->addListener(&joystick_listener);
1906 gSavedSettings.getControl("FlycamAxis4")->addListener(&joystick_listener);
1907 gSavedSettings.getControl("FlycamAxis5")->addListener(&joystick_listener);
1908 gSavedSettings.getControl("FlycamAxis6")->addListener(&joystick_listener);
1909}
diff --git a/linden/indra/newview/lldebugmessagebox.cpp b/linden/indra/newview/lldebugmessagebox.cpp
index 948b96a..b1f44e9 100644
--- a/linden/indra/newview/lldebugmessagebox.cpp
+++ b/linden/indra/newview/lldebugmessagebox.cpp
@@ -53,25 +53,25 @@ LLDebugVarMessageBox::LLDebugVarMessageBox(const std::string& title, EDebugVarTy
53 switch(var_type) 53 switch(var_type)
54 { 54 {
55 case VAR_TYPE_F32: 55 case VAR_TYPE_F32:
56 mSlider1 = new LLSliderCtrl("slider 1", LLRect(20,130,190,110), title, NULL, 70, 130, TRUE, TRUE, NULL, NULL, *((F32*)var), -100.f, 100.f, 0.1f, NULL); 56 mSlider1 = new LLSliderCtrl("slider 1", LLRect(20,130,190,110), title, NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, *((F32*)var), -100.f, 100.f, 0.1f, NULL);
57 mSlider1->setPrecision(3); 57 mSlider1->setPrecision(3);
58 addChild(mSlider1); 58 addChild(mSlider1);
59 mSlider2 = NULL; 59 mSlider2 = NULL;
60 mSlider3 = NULL; 60 mSlider3 = NULL;
61 break; 61 break;
62 case VAR_TYPE_S32: 62 case VAR_TYPE_S32:
63 mSlider1 = new LLSliderCtrl("slider 1", LLRect(20,100,190,80), title, NULL, 70, 130, TRUE, TRUE, NULL, NULL, (F32)*((S32*)var), -255.f, 255.f, 1.f, NULL); 63 mSlider1 = new LLSliderCtrl("slider 1", LLRect(20,100,190,80), title, NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, (F32)*((S32*)var), -255.f, 255.f, 1.f, NULL);
64 mSlider1->setPrecision(0); 64 mSlider1->setPrecision(0);
65 addChild(mSlider1); 65 addChild(mSlider1);
66 mSlider2 = NULL; 66 mSlider2 = NULL;
67 mSlider3 = NULL; 67 mSlider3 = NULL;
68 break; 68 break;
69 case VAR_TYPE_VEC3: 69 case VAR_TYPE_VEC3:
70 mSlider1 = new LLSliderCtrl("slider 1", LLRect(20,130,190,110), "x: ", NULL, 70, 130, TRUE, TRUE, NULL, NULL, ((LLVector3*)var)->mV[VX], -100.f, 100.f, 0.1f, NULL); 70 mSlider1 = new LLSliderCtrl("slider 1", LLRect(20,130,190,110), "x: ", NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, ((LLVector3*)var)->mV[VX], -100.f, 100.f, 0.1f, NULL);
71 mSlider1->setPrecision(3); 71 mSlider1->setPrecision(3);
72 mSlider2 = new LLSliderCtrl("slider 2", LLRect(20,100,190,80), "y: ", NULL, 70, 130, TRUE, TRUE, NULL, NULL, ((LLVector3*)var)->mV[VY], -100.f, 100.f, 0.1f, NULL); 72 mSlider2 = new LLSliderCtrl("slider 2", LLRect(20,100,190,80), "y: ", NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, ((LLVector3*)var)->mV[VY], -100.f, 100.f, 0.1f, NULL);
73 mSlider2->setPrecision(3); 73 mSlider2->setPrecision(3);
74 mSlider3 = new LLSliderCtrl("slider 3", LLRect(20,70,190,50), "z: ", NULL, 70, 130, TRUE, TRUE, NULL, NULL, ((LLVector3*)var)->mV[VZ], -100.f, 100.f, 0.1f, NULL); 74 mSlider3 = new LLSliderCtrl("slider 3", LLRect(20,70,190,50), "z: ", NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, ((LLVector3*)var)->mV[VZ], -100.f, 100.f, 0.1f, NULL);
75 mSlider3->setPrecision(3); 75 mSlider3->setPrecision(3);
76 addChild(mSlider1); 76 addChild(mSlider1);
77 addChild(mSlider2); 77 addChild(mSlider2);
diff --git a/linden/indra/newview/lldebugview.cpp b/linden/indra/newview/lldebugview.cpp
index dc179cc..861a5bb 100644
--- a/linden/indra/newview/lldebugview.cpp
+++ b/linden/indra/newview/lldebugview.cpp
@@ -37,7 +37,6 @@
37#include "llconsole.h" 37#include "llconsole.h"
38#include "lltextureview.h" 38#include "lltextureview.h"
39#include "llresmgr.h" 39#include "llresmgr.h"
40#include "llaudiostatus.h"
41#include "imageids.h" 40#include "imageids.h"
42#include "llvelocitybar.h" 41#include "llvelocitybar.h"
43#include "llviewerwindow.h" 42#include "llviewerwindow.h"
@@ -109,19 +108,6 @@ LLDebugView::LLDebugView(const std::string& name, const LLRect &rect)
109 mStatViewp->setVisible(FALSE); 108 mStatViewp->setVisible(FALSE);
110 addChild(mStatViewp); 109 addChild(mStatViewp);
111 110
112 //
113 // Audio debugging stuff
114 //
115 const S32 AUDIO_STATUS_LEFT = rect.getWidth()/2-100;
116 const S32 AUDIO_STATUS_WIDTH = 320;
117 const S32 AUDIO_STATUS_TOP = (rect.getHeight()/2)+400;
118 const S32 AUDIO_STATUS_HEIGHT = 320;
119 r.setLeftTopAndSize( AUDIO_STATUS_LEFT, AUDIO_STATUS_TOP, AUDIO_STATUS_WIDTH, AUDIO_STATUS_HEIGHT );
120 LLAudiostatus* gAudioStatus = new LLAudiostatus("AudioStatus", r);
121 gAudioStatus->setFollowsTop();
122 gAudioStatus->setFollowsRight();
123 addChild(gAudioStatus);
124
125 const S32 VELOCITY_LEFT = 10; // 370; 111 const S32 VELOCITY_LEFT = 10; // 370;
126 const S32 VELOCITY_WIDTH = 500; 112 const S32 VELOCITY_WIDTH = 500;
127 const S32 VELOCITY_TOP = 140; 113 const S32 VELOCITY_TOP = 140;
diff --git a/linden/indra/newview/lldrawable.h b/linden/indra/newview/lldrawable.h
index c2cafe3..e550142 100644
--- a/linden/indra/newview/lldrawable.h
+++ b/linden/indra/newview/lldrawable.h
@@ -46,6 +46,7 @@
46#include "llviewerobject.h" 46#include "llviewerobject.h"
47#include "llrect.h" 47#include "llrect.h"
48 48
49class LLCamera;
49class LLDrawPool; 50class LLDrawPool;
50class LLDrawable; 51class LLDrawable;
51class LLFace; 52class LLFace;
diff --git a/linden/indra/newview/lldrawpoolsky.h b/linden/indra/newview/lldrawpoolsky.h
index 2f11c67..645e669 100644
--- a/linden/indra/newview/lldrawpoolsky.h
+++ b/linden/indra/newview/lldrawpoolsky.h
@@ -57,7 +57,7 @@ public:
57 /*virtual*/ void render(S32 pass = 0); 57 /*virtual*/ void render(S32 pass = 0);
58 /*virtual*/ void renderForSelect(); 58 /*virtual*/ void renderForSelect();
59 void setSkyTex(LLSkyTex* const st) { mSkyTex = st; } 59 void setSkyTex(LLSkyTex* const st) { mSkyTex = st; }
60 void setSun(LLHeavenBody* sun) { mHB[0] = sun; } 60 void setSun(LLHeavenBody* sun_flag) { mHB[0] = sun_flag; }
61 void setMoon(LLHeavenBody* moon) { mHB[1] = moon; } 61 void setMoon(LLHeavenBody* moon) { mHB[1] = moon; }
62 62
63 void renderSkyCubeFace(U8 side); 63 void renderSkyCubeFace(U8 side);
diff --git a/linden/indra/newview/lldrawpoolwater.cpp b/linden/indra/newview/lldrawpoolwater.cpp
index 343f14c..100eb43 100644
--- a/linden/indra/newview/lldrawpoolwater.cpp
+++ b/linden/indra/newview/lldrawpoolwater.cpp
@@ -595,7 +595,7 @@ void LLDrawPoolWater::shade()
595 glUniform1fARB(gWaterProgram.mUniform[LLShaderMgr::WATER_TIME], sTime); 595 glUniform1fARB(gWaterProgram.mUniform[LLShaderMgr::WATER_TIME], sTime);
596 glUniform3fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_SPECULAR], 1, light_diffuse.mV); 596 glUniform3fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_SPECULAR], 1, light_diffuse.mV);
597 glUniform1fARB(gWaterProgram.mUniform[LLShaderMgr::WATER_SPECULAR_EXP], light_exp); 597 glUniform1fARB(gWaterProgram.mUniform[LLShaderMgr::WATER_SPECULAR_EXP], light_exp);
598 glUniform3fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_EYEVEC], 1, gCamera->getOrigin().mV); 598 glUniform3fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_EYEVEC], 1, (GLfloat *)(gCamera->getOrigin().mV));
599 glUniform2fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_WAVE_DIR1], 1, d1.mV); 599 glUniform2fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_WAVE_DIR1], 1, d1.mV);
600 glUniform2fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_WAVE_DIR2], 1, d2.mV); 600 glUniform2fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_WAVE_DIR2], 1, d2.mV);
601 glUniform3fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_LIGHT_DIR], 1, light_dir.mV); 601 glUniform3fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_LIGHT_DIR], 1, light_dir.mV);
diff --git a/linden/indra/newview/llemote.h b/linden/indra/newview/llemote.h
index a0aa353..9e2e09c 100644
--- a/linden/indra/newview/llemote.h
+++ b/linden/indra/newview/llemote.h
@@ -108,6 +108,8 @@ public:
108 // called when a motion is deactivated 108 // called when a motion is deactivated
109 virtual void onDeactivate(); 109 virtual void onDeactivate();
110 110
111 virtual BOOL canDeprecate() { return FALSE; }
112
111 static BOOL getIndexFromName( const char* name, U32* index ); 113 static BOOL getIndexFromName( const char* name, U32* index );
112 114
113protected: 115protected:
diff --git a/linden/indra/newview/llface.h b/linden/indra/newview/llface.h
index 711cd8e..24ef213 100644
--- a/linden/indra/newview/llface.h
+++ b/linden/indra/newview/llface.h
@@ -41,7 +41,6 @@
41#include "lldarrayptr.h" 41#include "lldarrayptr.h"
42#include "llvertexbuffer.h" 42#include "llvertexbuffer.h"
43#include "llviewerimage.h" 43#include "llviewerimage.h"
44#include "llpagemem.h"
45#include "llstat.h" 44#include "llstat.h"
46#include "lldrawable.h" 45#include "lldrawable.h"
47 46
diff --git a/linden/indra/newview/llfasttimerview.cpp b/linden/indra/newview/llfasttimerview.cpp
index c7be3aa..ba1296a 100644
--- a/linden/indra/newview/llfasttimerview.cpp
+++ b/linden/indra/newview/llfasttimerview.cpp
@@ -931,8 +931,7 @@ void LLFastTimerView::draw()
931 //draw line graph history 931 //draw line graph history
932 { 932 {
933 LLGLSNoTexture no_texture; 933 LLGLSNoTexture no_texture;
934 LLGLEnable scissor(GL_SCISSOR_TEST); 934 LLLocalClipRect clip(graph_rect);
935 LLUI::setScissorRegionLocal(graph_rect);
936 935
937 //normalize based on last frame's maximum 936 //normalize based on last frame's maximum
938 static U64 last_max = 0; 937 static U64 last_max = 0;
diff --git a/linden/indra/newview/llfeaturemanager.cpp b/linden/indra/newview/llfeaturemanager.cpp
index 2a30680..8bcbc1e 100644
--- a/linden/indra/newview/llfeaturemanager.cpp
+++ b/linden/indra/newview/llfeaturemanager.cpp
@@ -62,6 +62,8 @@ extern void write_debug(const std::string& str);
62const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt"; 62const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
63#elif LL_LINUX 63#elif LL_LINUX
64const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt"; 64const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt";
65#elif LL_SOLARIS
66const char FEATURE_TABLE_FILENAME[] = "featuretable_solaris.txt";
65#else 67#else
66const char FEATURE_TABLE_FILENAME[] = "featuretable.txt"; 68const char FEATURE_TABLE_FILENAME[] = "featuretable.txt";
67#endif 69#endif
@@ -405,7 +407,12 @@ void LLFeatureManager::initCPUFeatureMasks()
405 maskFeatures("RAM256MB"); 407 maskFeatures("RAM256MB");
406 } 408 }
407 409
410#if LL_SOLARIS && defined(__sparc) // even low MHz SPARCs are fast
411#error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here?
412 if (gSysCPU.getMhz() < 800)
413#else
408 if (gSysCPU.getMhz() < 1100) 414 if (gSysCPU.getMhz() < 1100)
415#endif
409 { 416 {
410 maskFeatures("CPUSlow"); 417 maskFeatures("CPUSlow");
411 } 418 }
diff --git a/linden/indra/newview/llfirstuse.cpp b/linden/indra/newview/llfirstuse.cpp
index 1ddac8e..b6bd444 100644
--- a/linden/indra/newview/llfirstuse.cpp
+++ b/linden/indra/newview/llfirstuse.cpp
@@ -35,6 +35,7 @@
35 35
36// viewer includes 36// viewer includes
37#include "llnotify.h" 37#include "llnotify.h"
38#include "llfloatervoicewizard.h"
38#include "llviewercontrol.h" 39#include "llviewercontrol.h"
39#include "llui.h" 40#include "llui.h"
40#include "viewer.h" 41#include "viewer.h"
@@ -248,3 +249,15 @@ void LLFirstUse::useSculptedPrim()
248 249
249 } 250 }
250} 251}
252
253// static
254void LLFirstUse::useVoice()
255{
256 if (gDisableVoice) return;
257 if (gSavedSettings.getWarning("FirstVoice"))
258 {
259 gSavedSettings.setWarning("FirstVoice", FALSE);
260
261 LLFloaterVoiceWizard::showInstance();
262 }
263}
diff --git a/linden/indra/newview/llfirstuse.h b/linden/indra/newview/llfirstuse.h
index d48ae96..1edbf70 100644
--- a/linden/indra/newview/llfirstuse.h
+++ b/linden/indra/newview/llfirstuse.h
@@ -101,6 +101,7 @@ public:
101 static void useFlexible(); 101 static void useFlexible();
102 static void useDebugMenus(); 102 static void useDebugMenus();
103 static void useSculptedPrim(); 103 static void useSculptedPrim();
104 static void useVoice();
104 105
105protected: 106protected:
106 static std::set<LLString> sConfigVariables; 107 static std::set<LLString> sConfigVariables;
diff --git a/linden/indra/newview/llfloateractivespeakers.cpp b/linden/indra/newview/llfloateractivespeakers.cpp
new file mode 100644
index 0000000..1c3990e
--- /dev/null
+++ b/linden/indra/newview/llfloateractivespeakers.cpp
@@ -0,0 +1,831 @@
1/**
2 * @file llfloateractivespeakers.cpp
3 * @brief Management interface for muting and controlling volume of residents currently speaking
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "llviewerprecompiledheaders.h"
30
31#include "llfloateractivespeakers.h"
32
33#include "llagent.h"
34#include "llvoavatar.h"
35#include "llfloateravatarinfo.h"
36#include "llvieweruictrlfactory.h"
37#include "llviewercontrol.h"
38#include "llscrolllistctrl.h"
39#include "llbutton.h"
40#include "lltextbox.h"
41#include "llmutelist.h"
42#include "llviewerobjectlist.h"
43#include "llimpanel.h" // LLVoiceChannel
44#include "llsdutil.h"
45
46const F32 SPEAKER_TIMEOUT = 10.f; // seconds of not being on voice channel before removed from list of active speakers
47const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
48const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
49const F32 TYPING_ANIMATION_FPS = 2.5f;
50
51LLLocalSpeakerMgr* gLocalSpeakerMgr = NULL;
52LLActiveSpeakerMgr* gActiveChannelSpeakerMgr = NULL;
53
54LLSpeaker::speaker_map_t LLSpeaker::sSpeakers;
55
56LLSpeaker::LLSpeaker(const LLUUID& id, const LLString& name, const ESpeakerType type) :
57 mStatus(LLSpeaker::STATUS_TEXT_ONLY),
58 mLastSpokeTime(0.f),
59 mSpeechVolume(0.f),
60 mHasSpoken(FALSE),
61 mDotColor(LLColor4::white),
62 mID(id),
63 mTyping(FALSE),
64 mSortIndex(0),
65 mType(type)
66{
67 mHandle.init();
68 sSpeakers.insert(std::make_pair(mHandle, this));
69 if (name.empty() && type == SPEAKER_AGENT)
70 {
71 lookupName();
72 }
73 else
74 {
75 mDisplayName = name;
76 }
77 mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
78}
79
80LLSpeaker::~LLSpeaker()
81{
82 sSpeakers.erase(mHandle);
83}
84
85void LLSpeaker::lookupName()
86{
87 gCacheName->getName(mID, onAvatarNameLookup, new LLViewHandle(mHandle));
88}
89
90//static
91void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data)
92{
93 LLViewHandle speaker_handle = *(LLViewHandle*)user_data;
94 delete (LLViewHandle*)user_data;
95
96 speaker_map_t::iterator found_it = sSpeakers.find(speaker_handle);
97 if (found_it != sSpeakers.end())
98 {
99 LLSpeaker* speakerp = found_it->second;
100 if (speakerp)
101 {
102 speakerp->mDisplayName = llformat("%s %s", first, last);
103 }
104 }
105}
106
107
108// helper sort class
109struct LLSortRecentSpeakers
110{
111 bool operator()(const LLPointer<LLSpeaker> lhs, const LLPointer<LLSpeaker> rhs) const;
112};
113
114bool LLSortRecentSpeakers::operator()(const LLPointer<LLSpeaker> lhs, const LLPointer<LLSpeaker> rhs) const
115{
116 // Sort first on status
117 if (lhs->mStatus != rhs->mStatus)
118 {
119 return (lhs->mStatus < rhs->mStatus);
120 }
121
122 // and then on last speaking time
123 if(lhs->mLastSpokeTime != rhs->mLastSpokeTime)
124 {
125 return (lhs->mLastSpokeTime > rhs->mLastSpokeTime);
126 }
127
128 // and finally (only if those are both equal), on name.
129 return( lhs->mDisplayName.compare(rhs->mDisplayName) < 0 );
130}
131
132LLFloaterActiveSpeakers::LLFloaterActiveSpeakers(const LLSD& seed) : mPanel(NULL)
133{
134 mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL);
135 // do not automatically open singleton floaters (as result of getInstance())
136 BOOL no_open = FALSE;
137 gUICtrlFactory->buildFloater(this, "floater_active_speakers.xml", &getFactoryMap(), no_open);
138 //RN: for now, we poll voice client every frame to get voice amplitude feedback
139 //gVoiceClient->addObserver(this);
140 mPanel->refreshSpeakers();
141}
142
143LLFloaterActiveSpeakers::~LLFloaterActiveSpeakers()
144{
145}
146
147void LLFloaterActiveSpeakers::onClose(bool app_quitting)
148{
149 setVisible(FALSE);
150}
151
152void LLFloaterActiveSpeakers::draw()
153{
154 // update state every frame to get live amplitude feedback
155 mPanel->refreshSpeakers();
156 LLFloater::draw();
157}
158
159BOOL LLFloaterActiveSpeakers::postBuild()
160{
161 mPanel = (LLPanelActiveSpeakers*)LLUICtrlFactory::getPanelByName(this, "active_speakers_panel");
162 return TRUE;
163}
164
165void LLFloaterActiveSpeakers::onChange()
166{
167 //refresh();
168}
169
170//static
171void* LLFloaterActiveSpeakers::createSpeakersPanel(void* data)
172{
173 // don't show text only speakers
174 return new LLPanelActiveSpeakers(gActiveChannelSpeakerMgr, FALSE);
175}
176
177
178//
179// LLPanelActiveSpeakers
180//
181LLPanelActiveSpeakers::LLPanelActiveSpeakers(LLSpeakerMgr* data_source, BOOL show_text_chatters) :
182 mSpeakerList(NULL),
183 mMuteVoiceCtrl(NULL),
184 mMuteTextCtrl(NULL),
185 mNameText(NULL),
186 mProfileBtn(NULL),
187 mShowTextChatters(show_text_chatters),
188 mSpeakerMgr(data_source)
189{
190 setMouseOpaque(FALSE);
191}
192
193LLPanelActiveSpeakers::~LLPanelActiveSpeakers()
194{
195
196}
197
198BOOL LLPanelActiveSpeakers::postBuild()
199{
200 mSpeakerList = LLUICtrlFactory::getScrollListByName(this, "speakers_list");
201
202 mMuteTextCtrl = (LLUICtrl*)getCtrlByNameAndType("mute_text_btn", WIDGET_TYPE_DONTCARE);
203 childSetCommitCallback("mute_text_btn", onClickMuteTextCommit, this);
204
205 mMuteVoiceCtrl = (LLUICtrl*)getCtrlByNameAndType("mute_btn", WIDGET_TYPE_DONTCARE);
206 childSetCommitCallback("mute_btn", onClickMuteVoiceCommit, this);
207 childSetAction("mute_btn", onClickMuteVoice, this);
208
209 childSetCommitCallback("speaker_volume", onVolumeChange, this);
210
211 mNameText = LLUICtrlFactory::getTextBoxByName(this, "resident_name");
212
213 mProfileBtn = LLUICtrlFactory::getButtonByName(this, "profile_btn");
214 childSetAction("profile_btn", onClickProfile, this);
215 return TRUE;
216}
217
218void LLPanelActiveSpeakers::refreshSpeakers()
219{
220 // store off current selection and scroll state to preserve across list rebuilds
221 LLUUID selected_id = mSpeakerList->getSimpleSelectedValue().asUUID();
222 S32 scroll_pos = mSpeakerList->getScrollInterface()->getScrollPos();
223
224 BOOL sort_ascending = mSpeakerList->getSortAscending();
225 LLString sort_column = mSpeakerList->getSortColumnName();
226 // TODO: put this in xml
227 // enforces default sort column of speaker status
228 if (sort_column.empty())
229 {
230 sort_column = "speaking_status";
231 }
232
233 mSpeakerMgr->update();
234
235 // clear scrolling list widget of names
236 mSpeakerList->clearRows();
237
238 LLSpeakerMgr::speaker_list_t speaker_list;
239 mSpeakerMgr->getSpeakerList(&speaker_list, mShowTextChatters);
240 for (LLSpeakerMgr::speaker_list_t::const_iterator speaker_it = speaker_list.begin(); speaker_it != speaker_list.end(); ++speaker_it)
241 {
242 LLUUID speaker_id = (*speaker_it)->mID;
243 LLPointer<LLSpeaker> speakerp = (*speaker_it);
244
245 // since we are forced to sort by text, encode sort order as string
246 LLString speaking_order_sort_string = llformat("%010d", speakerp->mSortIndex);
247
248 LLSD row;
249 row["id"] = speaker_id;
250
251 row["columns"][0]["column"] = "icon_speaking_status";
252 row["columns"][0]["type"] = "icon";
253 row["columns"][0]["color"] = speakerp->mDotColor.getValue();
254 LLString icon_image_id;
255
256 S32 icon_image_idx = llmin(2, llfloor((speakerp->mSpeechVolume / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
257 switch(icon_image_idx)
258 {
259 case 0:
260 icon_image_id = gViewerArt.getString("icn_active-speakers-dot-lvl0.tga");
261 break;
262 case 1:
263 icon_image_id = gViewerArt.getString("icn_active-speakers-dot-lvl1.tga");
264 break;
265 case 2:
266 icon_image_id = gViewerArt.getString("icn_active-speakers-dot-lvl2.tga");
267 break;
268 }
269 //if (speakerp->mTyping)
270 //{
271 // S32 typing_anim_idx = llround(mIconAnimationTimer.getElapsedTimeF32() * TYPING_ANIMATION_FPS) % 3;
272 // switch(typing_anim_idx)
273 // {
274 // case 0:
275 // row["columns"][0]["overlay"] = LLUUID(gViewerArt.getString("icn_active-speakers-typing1.tga"));
276 // break;
277 // case 1:
278 // row["columns"][0]["overlay"] = LLUUID(gViewerArt.getString("icn_active-speakers-typing2.tga"));
279 // break;
280 // case 2:
281 // row["columns"][0]["overlay"] = LLUUID(gViewerArt.getString("icn_active-speakers-typing3.tga"));
282 // break;
283 // default:
284 // break;
285 // }
286 //}
287
288 row["columns"][0]["value"] = speakerp->mStatus == LLSpeaker::STATUS_MUTED ?
289 gViewerArt.getString("mute_icon.tga") : icon_image_id;
290 if (speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE) // if voice is disabled for this speaker
291 {
292 // non voice speakers have hidden icons, render as transparent
293 row["columns"][0]["color"] = LLColor4(0.f, 0.f, 0.f, 0.f).getValue();
294 }
295 row["columns"][1]["column"] = "speaker_name";
296 row["columns"][1]["type"] = "text";
297 if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL)
298 {
299 // draw inactive speakers in gray
300 row["columns"][1]["color"] = LLColor4::grey4.getValue();
301 }
302
303 if (speakerp->mDisplayName.empty())
304 {
305 row["columns"][1]["value"] = LLCacheName::getDefaultName();
306 }
307 else
308 {
309 row["columns"][1]["value"] = speakerp->mDisplayName;
310 }
311
312 row["columns"][2]["column"] = "speaking_status";
313 row["columns"][2]["type"] = "text";
314
315 // print speaking ordinal in a text-sorting friendly manner
316 row["columns"][2]["value"] = speaking_order_sort_string;
317
318 mSpeakerList->addElement(row);
319 }
320
321 //restore sort order, selection, etc
322 mSpeakerList->sortByColumn(sort_column, sort_ascending);
323 // make sure something is selected
324 if (selected_id.isNull())
325 {
326 mSpeakerList->selectFirstItem();
327 }
328 else
329 {
330 mSpeakerList->selectByValue(selected_id);
331 }
332
333 LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(selected_id);
334
335 if (gMuteListp)
336 {
337 // update UI for selected participant
338 if (mMuteVoiceCtrl)
339 {
340 mMuteVoiceCtrl->setValue(gMuteListp->isMuted(selected_id, LLMute::flagVoiceChat));
341 mMuteVoiceCtrl->setEnabled(selected_id.notNull()
342 && selected_id != gAgent.getID()
343 && mSpeakerMgr->isVoiceActive()
344 && (speakerp.notNull() && speakerp->mType == LLSpeaker::SPEAKER_AGENT));
345 }
346 if (mMuteTextCtrl)
347 {
348 mMuteTextCtrl->setValue(gMuteListp->isMuted(selected_id, LLMute::flagTextChat));
349 mMuteTextCtrl->setEnabled(selected_id.notNull() && selected_id != gAgent.getID() && speakerp.notNull() && !gMuteListp->isLinden(speakerp->mDisplayName));
350 }
351 childSetValue("speaker_volume", gVoiceClient->getUserVolume(selected_id));
352 childSetEnabled("speaker_volume", selected_id.notNull()
353 && selected_id != gAgent.getID()
354 && mSpeakerMgr->isVoiceActive()
355 && (speakerp.notNull() && speakerp->mType == LLSpeaker::SPEAKER_AGENT));
356 if (mProfileBtn)
357 {
358 mProfileBtn->setEnabled(selected_id.notNull());
359 }
360 }
361
362 // show selected user name in large font
363 if (mNameText)
364 {
365 if (speakerp)
366 {
367 mNameText->setValue(speakerp->mDisplayName);
368 }
369 else
370 {
371 mNameText->setValue("");
372 }
373 }
374
375 // keep scroll value stable
376 mSpeakerList->getScrollInterface()->setScrollPos(scroll_pos);
377}
378
379void LLPanelActiveSpeakers::setSpeaker(const LLUUID& id, const LLString& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
380{
381 mSpeakerMgr->setSpeaker(id, name, status, type);
382}
383
384
385//static
386void LLPanelActiveSpeakers::onClickMuteTextCommit(LLUICtrl* ctrl, void* user_data)
387{
388 LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
389 LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
390 BOOL is_muted = gMuteListp->isMuted(speaker_id, LLMute::flagTextChat);
391 std::string name;
392
393 //fill in name using voice client's copy of name cache
394 LLPointer<LLSpeaker> speakerp = panelp->mSpeakerMgr->findSpeaker(speaker_id);
395 if (speakerp.isNull())
396 {
397 return;
398 }
399
400 name = speakerp->mDisplayName;
401
402 LLMute mute(speaker_id, name, speakerp->mType == LLSpeaker::SPEAKER_AGENT ? LLMute::AGENT : LLMute::OBJECT);
403
404 if (!is_muted)
405 {
406 gMuteListp->add(mute, LLMute::flagTextChat);
407 }
408 else
409 {
410 gMuteListp->remove(mute, LLMute::flagTextChat);
411 }
412}
413
414//static
415void LLPanelActiveSpeakers::onClickMuteVoice(void* user_data)
416{
417 onClickMuteVoiceCommit(NULL, user_data);
418}
419
420//static
421void LLPanelActiveSpeakers::onClickMuteVoiceCommit(LLUICtrl* ctrl, void* user_data)
422{
423 LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
424 LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
425 BOOL is_muted = gMuteListp->isMuted(speaker_id, LLMute::flagVoiceChat);
426 std::string name;
427
428 LLPointer<LLSpeaker> speakerp = panelp->mSpeakerMgr->findSpeaker(speaker_id);
429 if (speakerp.isNull())
430 {
431 return;
432 }
433
434 name = speakerp->mDisplayName;
435
436 // muting voice means we're dealing with an agent
437 LLMute mute(speaker_id, name, LLMute::AGENT);
438
439 if (!is_muted)
440 {
441 gMuteListp->add(mute, LLMute::flagVoiceChat);
442 }
443 else
444 {
445 gMuteListp->remove(mute, LLMute::flagVoiceChat);
446 }
447}
448
449
450//static
451void LLPanelActiveSpeakers::onVolumeChange(LLUICtrl* source, void* user_data)
452{
453 LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
454 LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
455
456 gVoiceClient->setUserVolume(speaker_id, (F32)panelp->childGetValue("speaker_volume").asReal());
457}
458
459//static
460void LLPanelActiveSpeakers::onClickProfile(void* user_data)
461{
462 LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
463 LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
464
465 LLFloaterAvatarInfo::showFromDirectory(speaker_id);
466}
467
468//
469// LLSpeakerMgr
470//
471
472LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) :
473 mVoiceChannel(channelp)
474{
475}
476
477LLSpeakerMgr::~LLSpeakerMgr()
478{
479}
480
481LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const LLString& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
482{
483 if (id.isNull()) return NULL;
484
485 LLPointer<LLSpeaker> speakerp;
486 if (mSpeakers.find(id) == mSpeakers.end())
487 {
488 speakerp = new LLSpeaker(id, name, type);
489 speakerp->mStatus = status;
490 mSpeakers.insert(std::make_pair(speakerp->mID, speakerp));
491 mSpeakersSorted.push_back(speakerp);
492 }
493 else
494 {
495 speakerp = findSpeaker(id);
496 if (speakerp.notNull())
497 {
498 // keep highest priority status (lowest value) instead of overriding current value
499 speakerp->mStatus = llmin(speakerp->mStatus, status);
500 speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
501 // RN: due to a weird behavior where IMs from attached objects come from the wearer's agent_id
502 // we need to override speakers that we think are objects when we find out they are really
503 // residents
504 if (type == LLSpeaker::SPEAKER_AGENT)
505 {
506 speakerp->mType = LLSpeaker::SPEAKER_AGENT;
507 speakerp->lookupName();
508 }
509 }
510 }
511
512 return speakerp;
513}
514
515void LLSpeakerMgr::update()
516{
517 if (!gVoiceClient)
518 {
519 return;
520 }
521
522 LLColor4 speaking_color = gSavedSettings.getColor4("SpeakingColor");
523 LLColor4 overdriven_color = gSavedSettings.getColor4("OverdrivenColor");
524
525 updateSpeakerList();
526
527 // update status of all current speakers
528 BOOL voice_channel_active = (!mVoiceChannel && gVoiceClient->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
529 for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end();)
530 {
531 LLUUID speaker_id = speaker_it->first;
532 LLSpeaker* speakerp = speaker_it->second;
533
534 speaker_map_t::iterator cur_speaker_it = speaker_it++;
535
536 if (voice_channel_active && gVoiceClient->getVoiceEnabled(speaker_id))
537 {
538 speakerp->mSpeechVolume = gVoiceClient->getCurrentPower(speaker_id);
539
540 if (gVoiceClient->getOnMuteList(speaker_id))
541 {
542 speakerp->mStatus = LLSpeaker::STATUS_MUTED;
543 speakerp->mDotColor = LLColor4::white;
544 }
545 else if (gVoiceClient->getIsSpeaking(speaker_id))
546 {
547 // reset inactivity expiration
548 if (speakerp->mStatus != LLSpeaker::STATUS_SPEAKING)
549 {
550 speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
551 speakerp->mHasSpoken = TRUE;
552 }
553 speakerp->mStatus = LLSpeaker::STATUS_SPEAKING;
554 // interpolate between active color and full speaking color based on power of speech output
555 speakerp->mDotColor = speaking_color;
556 if (speakerp->mSpeechVolume > LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
557 {
558 speakerp->mDotColor = overdriven_color;
559 }
560 }
561 else
562 {
563 speakerp->mSpeechVolume = 0.f;
564 speakerp->mDotColor = ACTIVE_COLOR;
565
566 if (speakerp->mHasSpoken)
567 {
568 // have spoken once, not currently speaking
569 speakerp->mStatus = LLSpeaker::STATUS_HAS_SPOKEN;
570 }
571 else
572 {
573 // default state for being in voice channel
574 speakerp->mStatus = LLSpeaker::STATUS_VOICE_ACTIVE;
575 }
576 }
577 }
578 // speaker no longer registered in voice channel, demote to text only
579 else if (speakerp->mStatus != LLSpeaker::STATUS_NOT_IN_CHANNEL)
580 {
581 speakerp->mStatus = LLSpeaker::STATUS_TEXT_ONLY;
582 speakerp->mSpeechVolume = 0.f;
583 speakerp->mDotColor = ACTIVE_COLOR;
584 }
585 }
586
587 // sort by status then time last spoken
588 std::sort(mSpeakersSorted.begin(), mSpeakersSorted.end(), LLSortRecentSpeakers());
589
590 // for recent speakers who are not currently speaking, show "recent" color dot for most recent
591 // fading to "active" color
592
593 S32 recent_speaker_count = 0;
594 S32 sort_index = 0;
595 speaker_list_t::iterator sorted_speaker_it;
596 for(sorted_speaker_it = mSpeakersSorted.begin();
597 sorted_speaker_it != mSpeakersSorted.end(); )
598 {
599 LLPointer<LLSpeaker> speakerp = *sorted_speaker_it;
600
601 // color code recent speakers who are not currently speaking
602 if (speakerp->mStatus == LLSpeaker::STATUS_HAS_SPOKEN)
603 {
604 speakerp->mDotColor = lerp(speaking_color, ACTIVE_COLOR, clamp_rescale((F32)recent_speaker_count, -2.f, 3.f, 0.f, 1.f));
605 recent_speaker_count++;
606 }
607
608 // stuff sort ordinal into speaker so the ui can sort by this value
609 speakerp->mSortIndex = sort_index++;
610
611 // remove speakers that have been gone too long
612 if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL && speakerp->mActivityTimer.hasExpired())
613 {
614 mSpeakers.erase(speakerp->mID);
615 sorted_speaker_it = mSpeakersSorted.erase(sorted_speaker_it);
616 }
617 else
618 {
619 ++sorted_speaker_it;
620 }
621 }
622}
623
624void LLSpeakerMgr::updateSpeakerList()
625{
626 // are we bound to the currently active voice channel?
627 if ((!mVoiceChannel && gVoiceClient->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
628 {
629 LLVoiceClient::participantMap* participants = gVoiceClient->getParticipantList();
630 LLVoiceClient::participantMap::iterator participant_it;
631
632 // add new participants to our list of known speakers
633 for (participant_it = participants->begin(); participant_it != participants->end(); ++participant_it)
634 {
635 LLVoiceClient::participantState* participantp = participant_it->second;
636 setSpeaker(participantp->mAvatarID, "", LLSpeaker::STATUS_VOICE_ACTIVE);
637 }
638 }
639}
640
641const LLPointer<LLSpeaker> LLSpeakerMgr::findSpeaker(const LLUUID& speaker_id)
642{
643 speaker_map_t::iterator found_it = mSpeakers.find(speaker_id);
644 if (found_it == mSpeakers.end())
645 {
646 return NULL;
647 }
648 return found_it->second;
649}
650
651void LLSpeakerMgr::getSpeakerList(speaker_list_t* speaker_list, BOOL include_text)
652{
653 speaker_list->clear();
654 for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
655 {
656 LLPointer<LLSpeaker> speakerp = speaker_it->second;
657 // what about text only muted or inactive?
658 if (include_text || speakerp->mStatus != LLSpeaker::STATUS_TEXT_ONLY)
659 {
660 speaker_list->push_back(speakerp);
661 }
662 }
663}
664
665void LLSpeakerMgr::setSpeakerTyping(const LLUUID& speaker_id, BOOL typing)
666{
667 LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
668 if (speakerp.notNull())
669 {
670 speakerp->mTyping = typing;
671 }
672}
673
674// speaker has chatted via either text or voice
675void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id)
676{
677 LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
678 if (speakerp.notNull())
679 {
680 speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
681 speakerp->mHasSpoken = TRUE;
682 }
683}
684
685BOOL LLSpeakerMgr::isVoiceActive()
686{
687 // mVoiceChannel = NULL means current voice channel, whatever it is
688 return LLVoiceClient::voiceEnabled() && mVoiceChannel && mVoiceChannel->isActive();
689}
690
691
692//
693// LLIMSpeakerMgr
694//
695LLIMSpeakerMgr::LLIMSpeakerMgr(LLVoiceChannel* channel) : LLSpeakerMgr(channel)
696{
697}
698
699void LLIMSpeakerMgr::updateSpeakerList()
700{
701 // don't do normal updates which are pulled from voice channel
702 // rely on user list reported by sim
703 return;
704}
705
706void LLIMSpeakerMgr::processSpeakerList(LLSD list)
707{
708 for(LLSD::array_iterator list_it = list.beginArray();
709 list_it != list.endArray();
710 ++list_it)
711 {
712 LLUUID agent_id(list_it->asUUID());
713
714 setSpeaker(agent_id, "", LLSpeaker::STATUS_TEXT_ONLY);
715 }
716}
717
718void LLIMSpeakerMgr::processSpeakerMap(LLSD map)
719{
720 for(LLSD::map_iterator map_it = map.beginMap();
721 map_it != map.endMap();
722 ++map_it)
723 {
724 // add as new speaker
725 setSpeaker(LLUUID(map_it->first));
726 }
727}
728
729
730
731void LLIMSpeakerMgr::processSpeakerListUpdate(LLSD update)
732{
733 for(LLSD::map_iterator update_it = update.beginMap();
734 update_it != update.endMap();
735 ++update_it)
736 {
737 LLUUID agent_id(update_it->first);
738
739 if (update_it->second.asString() == "LEAVE")
740 {
741 LLPointer<LLSpeaker> speakerp = findSpeaker(agent_id);
742 if (speakerp)
743 {
744 speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
745 speakerp->mDotColor = INACTIVE_COLOR;
746 speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
747 }
748 }
749 else if (update_it->second.asString() == "ENTER")
750 {
751 // add or update speaker
752 setSpeaker(agent_id);
753 }
754 else
755 {
756 llwarns << "LLIMSpeakerMgr::processSpeakerListUpdate() : bad membership list update " << ll_print_sd(update_it->second) << llendl;
757 }
758 }
759}
760
761
762//
763// LLActiveSpeakerMgr
764//
765
766LLActiveSpeakerMgr::LLActiveSpeakerMgr() : LLSpeakerMgr(NULL)
767{
768}
769
770void LLActiveSpeakerMgr::updateSpeakerList()
771{
772 // point to whatever the current voice channel is
773 mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel();
774
775 // always populate from active voice channel
776 if (LLVoiceChannel::getCurrentVoiceChannel() != mVoiceChannel)
777 {
778 mSpeakers.clear();
779 mSpeakersSorted.clear();
780 mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel();
781 }
782 LLSpeakerMgr::updateSpeakerList();
783}
784
785
786
787//
788// LLLocalSpeakerMgr
789//
790
791LLLocalSpeakerMgr::LLLocalSpeakerMgr() : LLSpeakerMgr(LLVoiceChannelProximal::getInstance())
792{
793}
794
795LLLocalSpeakerMgr::~LLLocalSpeakerMgr ()
796{
797}
798
799void LLLocalSpeakerMgr::updateSpeakerList()
800{
801 // pull speakers from voice channel
802 LLSpeakerMgr::updateSpeakerList();
803
804 // add non-voice speakers in chat range
805 std::vector< LLCharacter* >::iterator avatar_it;
806 for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it)
807 {
808 LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it;
809 if (dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS)
810 {
811 setSpeaker(avatarp->getID());
812 }
813 }
814
815 // check if text only speakers have moved out of chat range
816 for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
817 {
818 LLUUID speaker_id = speaker_it->first;
819 LLSpeaker* speakerp = speaker_it->second;
820 if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
821 {
822 LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id);
823 if (!avatarp || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
824 {
825 speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
826 speakerp->mDotColor = INACTIVE_COLOR;
827 speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
828 }
829 }
830 }
831}
diff --git a/linden/indra/newview/llfloateractivespeakers.h b/linden/indra/newview/llfloateractivespeakers.h
new file mode 100644
index 0000000..f24eca4
--- /dev/null
+++ b/linden/indra/newview/llfloateractivespeakers.h
@@ -0,0 +1,211 @@
1/**
2 * @file llfloateractivespeakers.h
3 * @brief Management interface for muting and controlling volume of residents currently speaking
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LL_LLFLOATERACTIVESPEAKERS_H
30#define LL_LLFLOATERACTIVESPEAKERS_H
31
32#include "llfloater.h"
33#include "llmemory.h"
34#include "llvoiceclient.h"
35#include "llframetimer.h"
36
37class LLScrollListCtrl;
38class LLButton;
39class LLPanelActiveSpeakers;
40class LLSpeakerMgr;
41class LLVoiceChannel;
42
43
44// data for a given participant in a voice channel
45class LLSpeaker : public LLRefCount
46{
47public:
48 typedef enum e_speaker_type
49 {
50 SPEAKER_AGENT,
51 SPEAKER_OBJECT
52 } ESpeakerType;
53
54 typedef enum e_speaker_status
55 {
56 STATUS_SPEAKING,
57 STATUS_HAS_SPOKEN,
58 STATUS_VOICE_ACTIVE,
59 STATUS_TEXT_ONLY,
60 STATUS_NOT_IN_CHANNEL,
61 STATUS_MUTED
62 } ESpeakerStatus;
63
64
65 LLSpeaker(const LLUUID& id, const LLString& name = LLString::null, const ESpeakerType type = SPEAKER_AGENT);
66 ~LLSpeaker();
67
68 void lookupName();
69
70 static void onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data);
71
72public:
73
74 ESpeakerStatus mStatus; // current activity status in speech group
75 F32 mLastSpokeTime; // timestamp when this speaker last spoke
76 F32 mSpeechVolume; // current speech amplitude (timea average rms amplitude?)
77 LLString mDisplayName; // cache user name for this speaker
78 LLFrameTimer mActivityTimer; // time out speakers when they are not part of current voice channel
79 BOOL mHasSpoken; // has this speaker said anything this session?
80 LLColor4 mDotColor;
81 LLUUID mID;
82 BOOL mTyping;
83 S32 mSortIndex;
84 LLViewHandle mHandle;
85 ESpeakerType mType;
86
87 typedef std::map<LLViewHandle, LLSpeaker*> speaker_map_t;
88 static speaker_map_t sSpeakers;
89};
90
91class LLSpeakerMgr
92{
93public:
94 LLSpeakerMgr(LLVoiceChannel* channelp);
95 virtual ~LLSpeakerMgr();
96
97 const LLPointer<LLSpeaker> findSpeaker(const LLUUID& avatar_id);
98 void update();
99 void setSpeakerTyping(const LLUUID& speaker_id, BOOL typing);
100 void speakerChatted(const LLUUID& speaker_id);
101 LLPointer<LLSpeaker> setSpeaker(const LLUUID& id,
102 const LLString& name = LLString::null,
103 LLSpeaker::ESpeakerStatus status = LLSpeaker::STATUS_TEXT_ONLY,
104 LLSpeaker::ESpeakerType = LLSpeaker::SPEAKER_AGENT);
105
106 BOOL isVoiceActive();
107
108 typedef std::vector<LLPointer<LLSpeaker> > speaker_list_t;
109 void getSpeakerList(speaker_list_t* speaker_list, BOOL include_text);
110
111protected:
112 virtual void updateSpeakerList();
113
114 typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
115 speaker_map_t mSpeakers;
116
117 speaker_list_t mSpeakersSorted;
118 LLFrameTimer mSpeechTimer;
119 LLVoiceChannel* mVoiceChannel;
120};
121
122class LLIMSpeakerMgr : public LLSpeakerMgr
123{
124public:
125 LLIMSpeakerMgr(LLVoiceChannel* channel);
126
127 void processSpeakerListUpdate(LLSD update);
128 void processSpeakerList(LLSD list);
129 void processSpeakerMap(LLSD list);
130protected:
131 virtual void updateSpeakerList();
132};
133
134class LLActiveSpeakerMgr : public LLSpeakerMgr
135{
136public:
137 LLActiveSpeakerMgr();
138protected:
139 virtual void updateSpeakerList();
140};
141
142class LLLocalSpeakerMgr : public LLSpeakerMgr
143{
144public:
145 LLLocalSpeakerMgr();
146 ~LLLocalSpeakerMgr ();
147protected:
148 virtual void updateSpeakerList();
149};
150
151
152class LLFloaterActiveSpeakers :
153 public LLUISingleton<LLFloaterActiveSpeakers>,
154 public LLFloater,
155 public LLVoiceClientParticipantObserver
156{
157 // friend of singleton class to allow construction inside getInstance() since constructor is protected
158 // to enforce singleton constraint
159 friend class LLUISingleton<LLFloaterActiveSpeakers>;
160public:
161 virtual ~LLFloaterActiveSpeakers();
162
163 /*virtual*/ BOOL postBuild();
164 /*virtual*/ void onClose(bool app_quitting);
165 /*virtual*/ void draw();
166
167 /*virtual*/ void onChange();
168
169 static void* createSpeakersPanel(void* data);
170
171protected:
172 LLFloaterActiveSpeakers(const LLSD& seed);
173
174 LLPanelActiveSpeakers* mPanel;
175};
176
177class LLPanelActiveSpeakers : public LLPanel
178{
179public:
180 LLPanelActiveSpeakers(LLSpeakerMgr* data_source, BOOL show_text_chatters);
181 virtual ~LLPanelActiveSpeakers();
182
183 /*virtual*/ BOOL postBuild();
184
185 void refreshSpeakers();
186
187 void setSpeaker(const LLUUID& id,
188 const LLString& name = LLString::null,
189 LLSpeaker::ESpeakerStatus status = LLSpeaker::STATUS_TEXT_ONLY,
190 LLSpeaker::ESpeakerType = LLSpeaker::SPEAKER_AGENT);
191
192 static void onClickMuteVoice(void* user_data);
193 static void onClickMuteVoiceCommit(LLUICtrl* ctrl, void* user_data);
194 static void onClickMuteTextCommit(LLUICtrl* ctrl, void* user_data);
195 static void onVolumeChange(LLUICtrl* source, void* user_data);
196 static void onClickProfile(void* user_data);
197protected:
198 LLScrollListCtrl* mSpeakerList;
199 LLUICtrl* mMuteVoiceCtrl;
200 LLUICtrl* mMuteTextCtrl;
201 LLTextBox* mNameText;
202 LLButton* mProfileBtn;
203 BOOL mShowTextChatters;
204 LLSpeakerMgr* mSpeakerMgr;
205 LLFrameTimer mIconAnimationTimer;
206};
207
208extern LLLocalSpeakerMgr* gLocalSpeakerMgr;
209extern LLActiveSpeakerMgr* gActiveChannelSpeakerMgr;
210
211#endif // LL_LLFLOATERACTIVESPEAKERS_H
diff --git a/linden/indra/newview/llfloateranimpreview.cpp b/linden/indra/newview/llfloateranimpreview.cpp
index b1f8a53..09fc508 100644
--- a/linden/indra/newview/llfloateranimpreview.cpp
+++ b/linden/indra/newview/llfloateranimpreview.cpp
@@ -993,7 +993,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata)
993 LLKeyframeDataCache::removeKeyframeData(floaterp->mMotionID); 993 LLKeyframeDataCache::removeKeyframeData(floaterp->mMotionID);
994 } 994 }
995 995
996 floaterp->onClose(false); 996 floaterp->close(false);
997} 997}
998 998
999//----------------------------------------------------------------------------- 999//-----------------------------------------------------------------------------
diff --git a/linden/indra/newview/llfloateravatarpicker.cpp b/linden/indra/newview/llfloateravatarpicker.cpp
index 6989084..3bb2462 100644
--- a/linden/indra/newview/llfloateravatarpicker.cpp
+++ b/linden/indra/newview/llfloateravatarpicker.cpp
@@ -208,7 +208,12 @@ void LLFloaterAvatarPicker::onSelectionChange(const std::deque<LLFolderViewItem*
208 self->mAvatarIDs.clear(); 208 self->mAvatarIDs.clear();
209 self->mAvatarNames.clear(); 209 self->mAvatarNames.clear();
210 210
211 self->childSetEnabled("Select", FALSE); 211 // if we have calling cards, disable select button until
212 // the inventory picks a valid calling card
213 if (!items.empty())
214 {
215 self->childSetEnabled("Select", FALSE);
216 }
212 217
213 if (!self->mListNames) 218 if (!self->mListNames)
214 { 219 {
diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp
index dd79afd..2621161 100644
--- a/linden/indra/newview/llfloaterchat.cpp
+++ b/linden/indra/newview/llfloaterchat.cpp
@@ -34,6 +34,7 @@
34#include "llviewerprecompiledheaders.h" 34#include "llviewerprecompiledheaders.h"
35 35
36#include "llfloaterchat.h" 36#include "llfloaterchat.h"
37#include "llfloateractivespeakers.h"
37#include "llfloaterscriptdebug.h" 38#include "llfloaterscriptdebug.h"
38 39
39#include "llchat.h" 40#include "llchat.h"
@@ -49,11 +50,13 @@
49#include "llcheckboxctrl.h" 50#include "llcheckboxctrl.h"
50#include "llcombobox.h" 51#include "llcombobox.h"
51#include "llconsole.h" 52#include "llconsole.h"
53#include "llfloaterchatterbox.h"
52#include "llfloatermute.h" 54#include "llfloatermute.h"
53#include "llkeyboard.h" 55#include "llkeyboard.h"
54//#include "lllineeditor.h" 56//#include "lllineeditor.h"
55#include "llmutelist.h" 57#include "llmutelist.h"
56//#include "llresizehandle.h" 58//#include "llresizehandle.h"
59#include "llchatbar.h"
57#include "llstatusbar.h" 60#include "llstatusbar.h"
58#include "llviewertexteditor.h" 61#include "llviewertexteditor.h"
59#include "llviewergesture.h" // for triggering gestures 62#include "llviewergesture.h" // for triggering gestures
@@ -70,7 +73,6 @@
70// 73//
71// Constants 74// Constants
72// 75//
73const char FLOATER_TITLE[] = "Chat History";
74const F32 INSTANT_MSG_SIZE = 8.0f; 76const F32 INSTANT_MSG_SIZE = 8.0f;
75const F32 CHAT_MSG_SIZE = 8.0f; 77const F32 CHAT_MSG_SIZE = 8.0f;
76const LLColor4 INSTANT_MSG_COLOR(1, 1, 1, 1); 78const LLColor4 INSTANT_MSG_COLOR(1, 1, 1, 1);
@@ -80,25 +82,25 @@ const S32 MAX_CHATTER_COUNT = 16;
80// 82//
81// Global statics 83// Global statics
82// 84//
83LLFloaterChat* gFloaterChat = NULL;
84
85LLColor4 get_text_color(const LLChat& chat); 85LLColor4 get_text_color(const LLChat& chat);
86 86
87// 87//
88// Member Functions 88// Member Functions
89// 89//
90LLFloaterChat::LLFloaterChat() 90LLFloaterChat::LLFloaterChat(const LLSD& seed)
91: LLFloater("chat floater", "FloaterChatRect", FLOATER_TITLE, 91: LLFloater("chat floater", "FloaterChatRect", "",
92 RESIZE_YES, 440, 100, DRAG_ON_TOP, MINIMIZE_NO, CLOSE_YES) 92 RESIZE_YES, 440, 100, DRAG_ON_TOP, MINIMIZE_NO, CLOSE_YES),
93 mPanel(NULL)
93{ 94{
94 95 mFactoryMap["chat_panel"] = LLCallbackMap(createChatPanel, NULL);
95 gUICtrlFactory->buildFloater(this,"floater_chat_history.xml"); 96 mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL);
97 // do not automatically open singleton floaters (as result of getInstance())
98 BOOL no_open = FALSE;
99 gUICtrlFactory->buildFloater(this,"floater_chat_history.xml",&getFactoryMap(),no_open);
96 100
97 childSetAction("Mute resident",onClickMute,this);
98 childSetAction("Chat", onClickChat, this);
99 childSetCommitCallback("chatter combobox",onCommitUserSelect,this);
100 childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes 101 childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes
101 childSetVisible("Chat History Editor with mute",FALSE); 102 childSetVisible("Chat History Editor with mute",FALSE);
103 childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
102 setDefaultBtn("Chat"); 104 setDefaultBtn("Chat");
103} 105}
104 106
@@ -112,33 +114,53 @@ void LLFloaterChat::setVisible(BOOL visible)
112 LLFloater::setVisible( visible ); 114 LLFloater::setVisible( visible );
113 115
114 gSavedSettings.setBOOL("ShowChatHistory", visible); 116 gSavedSettings.setBOOL("ShowChatHistory", visible);
117}
115 118
116 // Hide the chat overlay when our history is visible. 119void LLFloaterChat::draw()
117 gConsole->setVisible( !visible ); 120{
121 // enable say and shout only when text available
122
123 childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel"));
124
125 LLChatBar* chat_barp = (LLChatBar*)getChildByName("chat_panel", TRUE);
126 if (chat_barp)
127 {
128 chat_barp->refresh();
129 }
130
131 mPanel->refreshSpeakers();
132 LLFloater::draw();
118} 133}
119 134
135BOOL LLFloaterChat::postBuild()
136{
137 mPanel = (LLPanelActiveSpeakers*)LLUICtrlFactory::getPanelByName(this, "active_speakers_panel");
138
139 LLChatBar* chat_barp = (LLChatBar*)getChildByName("chat_panel", TRUE);
140 if (chat_barp)
141 {
142 chat_barp->setGestureCombo(LLUICtrlFactory::getComboBoxByName(this, "Gesture"));
143 }
144 return TRUE;
145}
120 146
121// public virtual 147// public virtual
122void LLFloaterChat::onClose(bool app_quitting) 148void LLFloaterChat::onClose(bool app_quitting)
123{ 149{
124 LLFloater::setVisible( FALSE );
125
126 if (!app_quitting) 150 if (!app_quitting)
127 { 151 {
128 gSavedSettings.setBOOL("ShowChatHistory", FALSE); 152 gSavedSettings.setBOOL("ShowChatHistory", FALSE);
129 } 153 }
130 154 setVisible(FALSE);
131 // Hide the chat overlay when our history is visible.
132 gConsole->setVisible( TRUE );
133} 155}
134 156
135 157void LLFloaterChat::onVisibilityChange(BOOL new_visibility)
136// public
137void LLFloaterChat::show()
138{ 158{
139 open(); /*Flawfinder: ignore*/ 159 // Hide the chat overlay when our history is visible.
160 gConsole->setVisible( !new_visibility );
140} 161}
141 162
163
142void add_timestamped_line(LLViewerTextEditor* edit, const LLString& line, const LLColor4& color) 164void add_timestamped_line(LLViewerTextEditor* edit, const LLString& line, const LLColor4& color)
143{ 165{
144 bool prepend_newline = true; 166 bool prepend_newline = true;
@@ -162,7 +184,7 @@ void log_chat_text(const LLChat& chat)
162} 184}
163// static 185// static
164void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) 186void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
165{ 187{
166 if ( gSavedPerAccountSettings.getBOOL("LogChat") && log_to_file) 188 if ( gSavedPerAccountSettings.getBOOL("LogChat") && log_to_file)
167 { 189 {
168 log_chat_text(chat); 190 log_chat_text(chat);
@@ -185,10 +207,9 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
185 } 207 }
186 208
187 // could flash the chat button in the status bar here. JC 209 // could flash the chat button in the status bar here. JC
188 if (!gFloaterChat) return; 210 LLFloaterChat* chat_floater = LLFloaterChat::getInstance(LLSD());
189 211 LLViewerTextEditor* history_editor = (LLViewerTextEditor*)chat_floater->getChildByName("Chat History Editor", TRUE);
190 LLViewerTextEditor* history_editor = (LLViewerTextEditor*)gFloaterChat->getChildByName("Chat History Editor"); 212 LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)chat_floater->getChildByName("Chat History Editor with mute", TRUE);
191 LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)gFloaterChat->getChildByName("Chat History Editor with mute");
192 213
193 history_editor->setParseHTML(TRUE); 214 history_editor->setParseHTML(TRUE);
194 history_editor_with_mute->setParseHTML(TRUE); 215 history_editor_with_mute->setParseHTML(TRUE);
@@ -204,77 +225,24 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
204 LLColor4 muted_color = lerp(color, LLColor4::grey, 0.5f); 225 LLColor4 muted_color = lerp(color, LLColor4::grey, 0.5f);
205 add_timestamped_line(history_editor_with_mute, chat.mText, color); 226 add_timestamped_line(history_editor_with_mute, chat.mText, color);
206 } 227 }
207 228
208 if (!chat.mMuted 229 // add objects as transient speakers that can be muted
209 && chat.mSourceType != CHAT_SOURCE_SYSTEM 230 if (chat.mSourceType == CHAT_SOURCE_OBJECT)
210 && chat.mFromID.notNull()
211 && chat.mFromID != gAgent.getID())
212 { 231 {
213 232 chat_floater->mPanel->setSpeaker(chat.mFromID, chat.mFromName, LLSpeaker::STATUS_NOT_IN_CHANNEL, LLSpeaker::SPEAKER_OBJECT);
214 LLComboBox* chatter_combo = LLUICtrlFactory::getComboBoxByName(gFloaterChat,"chatter combobox");
215
216 if(!chatter_combo)
217 {
218 return;
219 }
220
221 if (!chatter_combo->setCurrentByID(chat.mFromID))
222 {
223 // if we have too many items...
224 if (chatter_combo->getItemCount() >= MAX_CHATTER_COUNT)
225 {
226 chatter_combo->remove(0);
227 }
228
229 LLMute mute(chat.mFromID, chat.mFromName);
230 if (chat.mSourceType == CHAT_SOURCE_OBJECT)
231 {
232 mute.mType = LLMute::OBJECT;
233 }
234 else if (chat.mSourceType == CHAT_SOURCE_AGENT)
235 {
236 mute.mType = LLMute::AGENT;
237 }
238 LLString item = mute.getDisplayName();
239 chatter_combo->add(item, chat.mFromID);
240 chatter_combo->setCurrentByIndex(chatter_combo->getItemCount() - 1);
241 gFloaterChat->childSetEnabled("Mute resident",TRUE);
242 }
243 } 233 }
244} 234}
245 235
246// static 236// static
247void LLFloaterChat::setHistoryCursorAndScrollToEnd() 237void LLFloaterChat::setHistoryCursorAndScrollToEnd()
248{ 238{
249 if (gFloaterChat) 239 LLViewerTextEditor* history_editor = (LLViewerTextEditor*)LLFloaterChat::getInstance(LLSD())->getChildByName("Chat History Editor", TRUE);
250 { 240 LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)LLFloaterChat::getInstance(LLSD())->getChildByName("Chat History Editor with mute", TRUE);
251 LLViewerTextEditor* history_editor = (LLViewerTextEditor*)gFloaterChat->getChildByName("Chat History Editor"); 241
252 LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)gFloaterChat->getChildByName("Chat History Editor with mute"); 242 history_editor->setCursorAndScrollToEnd();
253 243 history_editor_with_mute->setCursorAndScrollToEnd();
254 history_editor->setCursorAndScrollToEnd();
255 history_editor_with_mute->setCursorAndScrollToEnd();
256 }
257}
258
259
260// static
261void LLFloaterChat::toggle(void*)
262{
263 if (gFloaterChat->getVisible())
264 {
265 gFloaterChat->close();
266 }
267 else
268 {
269 gFloaterChat->show();
270 }
271} 244}
272 245
273// static
274BOOL LLFloaterChat::visible(void*)
275{
276 return (gFloaterChat && gFloaterChat->getVisible());
277}
278 246
279//static 247//static
280void LLFloaterChat::onClickMute(void *data) 248void LLFloaterChat::onClickMute(void *data)
@@ -299,30 +267,6 @@ void LLFloaterChat::onClickMute(void *data)
299} 267}
300 268
301//static 269//static
302void LLFloaterChat::onClickChat(void*)
303{
304 // we need this function as a level of indirection because otherwise startChat would
305 // cast the data pointer to a character string, and dump garbage in the chat
306 LLChatBar::startChat(NULL);
307}
308
309//static
310void LLFloaterChat::onCommitUserSelect(LLUICtrl* caller, void* data)
311{
312 LLFloaterChat* floater = (LLFloaterChat*)data;
313 LLComboBox* combo = (LLComboBox*)caller;
314
315 if (combo->getCurrentIndex() == -1)
316 {
317 floater->childSetEnabled("Mute resident",FALSE);
318 }
319 else
320 {
321 floater->childSetEnabled("Mute resident",TRUE);
322 }
323}
324
325//static
326void LLFloaterChat::onClickToggleShowMute(LLUICtrl* caller, void *data) 270void LLFloaterChat::onClickToggleShowMute(LLUICtrl* caller, void *data)
327{ 271{
328 LLFloaterChat* floater = (LLFloaterChat*)data; 272 LLFloaterChat* floater = (LLFloaterChat*)data;
@@ -330,8 +274,8 @@ void LLFloaterChat::onClickToggleShowMute(LLUICtrl* caller, void *data)
330 274
331 //LLCheckBoxCtrl* 275 //LLCheckBoxCtrl*
332 BOOL show_mute = LLUICtrlFactory::getCheckBoxByName(floater,"show mutes")->get(); 276 BOOL show_mute = LLUICtrlFactory::getCheckBoxByName(floater,"show mutes")->get();
333 LLViewerTextEditor* history_editor = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor"); 277 LLViewerTextEditor* history_editor = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor", TRUE);
334 LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor with mute"); 278 LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor with mute", TRUE);
335 279
336 if (!history_editor || !history_editor_with_mute) 280 if (!history_editor || !history_editor_with_mute)
337 return; 281 return;
@@ -447,7 +391,7 @@ LLColor4 get_text_color(const LLChat& chat)
447//static 391//static
448void LLFloaterChat::loadHistory() 392void LLFloaterChat::loadHistory()
449{ 393{
450 LLLogChat::loadHistory("chat", &chatFromLogFile, (void *)gFloaterChat); 394 LLLogChat::loadHistory("chat", &chatFromLogFile, (void *)LLFloaterChat::getInstance(LLSD()));
451} 395}
452 396
453//static 397//static
@@ -458,3 +402,40 @@ void LLFloaterChat::chatFromLogFile(LLString line, void* userdata)
458 chat.mText = line; 402 chat.mText = line;
459 addChatHistory(chat, FALSE); 403 addChatHistory(chat, FALSE);
460} 404}
405
406//static
407void* LLFloaterChat::createSpeakersPanel(void* data)
408{
409 return new LLPanelActiveSpeakers(gLocalSpeakerMgr, TRUE);
410}
411
412//static
413void* LLFloaterChat::createChatPanel(void* data)
414{
415 LLChatBar* chatp = new LLChatBar("floating_chat_bar");
416 return chatp;
417}
418
419//static
420void LLFloaterChat::hideInstance(const LLSD& id)
421{
422 LLFloaterChat* floaterp = LLFloaterChat::getInstance(LLSD());
423 // don't do anything when hosted in the chatterbox
424 if(floaterp->getHost())
425 {
426 LLFloaterChatterBox::hideInstance(LLSD());
427 }
428 else
429 {
430 LLUISingleton<LLFloaterChat>::hideInstance(id);
431 }
432}
433
434// static
435void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata)
436{
437 LLFloaterChat* self = (LLFloaterChat*)userdata;
438
439 self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel"));
440}
441
diff --git a/linden/indra/newview/llfloaterchat.h b/linden/indra/newview/llfloaterchat.h
index 54df738..9558a65 100644
--- a/linden/indra/newview/llfloaterchat.h
+++ b/linden/indra/newview/llfloaterchat.h
@@ -44,17 +44,20 @@ class LLViewerTextEditor;
44class LLMessageSystem; 44class LLMessageSystem;
45class LLUUID; 45class LLUUID;
46class LLCheckBoxCtrl; 46class LLCheckBoxCtrl;
47class LLPanelActiveSpeakers;
47 48
48class LLFloaterChat 49class LLFloaterChat
49: public LLFloater 50: public LLFloater, public LLUISingleton<LLFloaterChat>
50{ 51{
51public: 52public:
52 LLFloaterChat(); 53 LLFloaterChat(const LLSD& seed);
53 ~LLFloaterChat(); 54 ~LLFloaterChat();
54 55
55 void show();
56 virtual void onClose(bool app_quitting);
57 virtual void setVisible( BOOL b ); 56 virtual void setVisible( BOOL b );
57 virtual void draw();
58 virtual BOOL postBuild();
59 virtual void onClose(bool app_quitting);
60 virtual void onVisibilityChange(BOOL cur_visibility);
58 61
59 static void setHistoryCursorAndScrollToEnd(); 62 static void setHistoryCursorAndScrollToEnd();
60 63
@@ -65,17 +68,17 @@ public:
65 // Add chat to history alone. 68 // Add chat to history alone.
66 static void addChatHistory(const LLChat& chat, bool log_to_file = true); 69 static void addChatHistory(const LLChat& chat, bool log_to_file = true);
67 70
68 static void toggle(void*);
69 static BOOL visible(void*);
70
71 static void onClickMute(void *data); 71 static void onClickMute(void *data);
72 static void onClickChat(void *);
73 static void onCommitUserSelect(LLUICtrl* caller, void* data);
74 static void onClickToggleShowMute(LLUICtrl* caller, void *data); 72 static void onClickToggleShowMute(LLUICtrl* caller, void *data);
73 static void onClickToggleActiveSpeakers(void* userdata);
75 static void chatFromLogFile(LLString line, void* userdata); 74 static void chatFromLogFile(LLString line, void* userdata);
76 static void loadHistory(); 75 static void loadHistory();
77}; 76 static void* createSpeakersPanel(void* data);
77 static void* createChatPanel(void* data);
78 static void hideInstance(const LLSD& id);
78 79
79extern LLFloaterChat* gFloaterChat; 80protected:
81 LLPanelActiveSpeakers* mPanel;
82};
80 83
81#endif 84#endif
diff --git a/linden/indra/newview/llfloaterchatterbox.cpp b/linden/indra/newview/llfloaterchatterbox.cpp
new file mode 100644
index 0000000..11d2ee6
--- /dev/null
+++ b/linden/indra/newview/llfloaterchatterbox.cpp
@@ -0,0 +1,342 @@
1/**
2 * @file llfloaterchatterbox.cpp
3 * @author Richard
4 * @date 2007-05-08
5 * @brief Implementation of the chatterbox integrated conversation ui
6 *
7 * Copyright (c) 2007-2007, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlife.com/developers/opensource/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlife.com/developers/opensource/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 */
30
31
32#include "llviewerprecompiledheaders.h"
33
34#include "llfloaterchatterbox.h"
35#include "llvieweruictrlfactory.h"
36#include "llfloaterchat.h"
37#include "llfloaterfriends.h"
38#include "llfloatergroups.h"
39#include "llviewercontrol.h"
40#include "llimview.h"
41#include "llimpanel.h"
42
43//
44// LLFloaterMyFriends
45//
46
47LLFloaterMyFriends::LLFloaterMyFriends(const LLSD& seed)
48{
49 mFactoryMap["friends_panel"] = LLCallbackMap(LLFloaterMyFriends::createFriendsPanel, NULL);
50 mFactoryMap["groups_panel"] = LLCallbackMap(LLFloaterMyFriends::createGroupsPanel, NULL);
51 // do not automatically open singleton floaters (as result of getInstance())
52 BOOL no_open = FALSE;
53 gUICtrlFactory->buildFloater(this, "floater_my_friends.xml", &getFactoryMap(), no_open);
54}
55
56LLFloaterMyFriends::~LLFloaterMyFriends()
57{
58}
59
60BOOL LLFloaterMyFriends::postBuild()
61{
62 mTabs = LLUICtrlFactory::getTabContainerByName(this, "friends_and_groups");
63
64 return TRUE;
65}
66
67
68void LLFloaterMyFriends::onClose(bool app_quitting)
69{
70 setVisible(FALSE);
71}
72
73//static
74LLFloaterMyFriends* LLFloaterMyFriends::showInstance(const LLSD& id)
75{
76 LLFloaterMyFriends* floaterp = LLUIInstanceMgr<LLFloaterMyFriends>::showInstance(id);
77 // garbage values in id will be interpreted as 0, or the friends tab
78 floaterp->mTabs->selectTab(id);
79
80 return floaterp;
81}
82
83//static
84void LLFloaterMyFriends::hideInstance(const LLSD& id)
85{
86 if(instanceVisible(id))
87 {
88 LLFloaterChatterBox::hideInstance(LLSD());
89 }
90}
91
92// is the specified panel currently visible
93//static
94BOOL LLFloaterMyFriends::instanceVisible(const LLSD& id)
95{
96 // if singleton not created yet, trivially return false
97 if (!findInstance(id)) return FALSE;
98
99 LLFloaterMyFriends* floaterp = getInstance(id);
100 return floaterp->isInVisibleChain() && floaterp->mTabs->getCurrentPanelIndex() == id.asInteger();
101}
102
103//static
104void* LLFloaterMyFriends::createFriendsPanel(void* data)
105{
106 return new LLPanelFriends();
107}
108
109//static
110void* LLFloaterMyFriends::createGroupsPanel(void* data)
111{
112 return new LLPanelGroups();
113}
114
115//
116// LLFloaterChatterBox
117//
118LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) :
119 mActiveVoiceFloater(NULL)
120{
121 mAutoResize = FALSE;
122
123 gUICtrlFactory->buildFloater(this, "floater_chatterbox.xml", NULL, FALSE);
124 addFloater(LLFloaterMyFriends::getInstance(0), TRUE);
125 if (gSavedSettings.getBOOL("ChatHistoryTornOff"))
126 {
127 LLFloaterChat* floater_chat = LLFloaterChat::getInstance(LLSD());
128 // add then remove to set up relationship for re-attach
129 addFloater(floater_chat, FALSE);
130 removeFloater(floater_chat);
131 // reparent to floater view
132 gFloaterView->addChild(floater_chat);
133 }
134 else
135 {
136 addFloater(LLFloaterChat::getInstance(LLSD()), FALSE);
137 }
138 mTabContainer->lockTabs();
139}
140
141LLFloaterChatterBox::~LLFloaterChatterBox()
142{
143}
144
145BOOL LLFloaterChatterBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
146{
147 if (getEnabled()
148 && mask == MASK_CONTROL)
149 {
150 if (key == 'W')
151 {
152 LLFloater* floater = getActiveFloater();
153 // is user closeable and is system closeable
154 if (floater && floater->canClose())
155 {
156 if (floater->isCloseable())
157 {
158 floater->close();
159 }
160 else
161 {
162 // close chatterbox window if frontmost tab is reserved, non-closeable tab
163 // such as contacts or near me
164 close();
165 }
166 }
167 return TRUE;
168 }
169 }
170
171 return LLMultiFloater::handleKeyHere(key, mask, called_from_parent);
172}
173
174void LLFloaterChatterBox::draw()
175{
176 // clear new im notifications when chatterbox is visible
177 if (!isMinimized())
178 {
179 gIMMgr->clearNewIMNotification();
180 }
181 LLFloater* current_active_floater = getCurrentVoiceFloater();
182 // set icon on tab for floater currently associated with active voice channel
183 if(mActiveVoiceFloater != current_active_floater)
184 {
185 // remove image from old floater's tab
186 if (mActiveVoiceFloater)
187 {
188 mTabContainer->setTabImage(mActiveVoiceFloater, "");
189 }
190 }
191
192 // update image on current active tab
193 if (current_active_floater)
194 {
195 LLColor4 icon_color = LLColor4::white;
196 LLVoiceChannel* channelp = LLVoiceChannel::getCurrentVoiceChannel();
197 if (channelp)
198 {
199 if (channelp->isActive())
200 {
201 icon_color = LLColor4::green;
202 }
203 else if (channelp->getState() == LLVoiceChannel::STATE_ERROR)
204 {
205 icon_color = LLColor4::red;
206 }
207 else // active, but not connected
208 {
209 icon_color = LLColor4::yellow;
210 }
211 }
212 mTabContainer->setTabImage(current_active_floater, "active_voice_tab.tga", icon_color);
213 }
214
215 mActiveVoiceFloater = current_active_floater;
216
217 LLFloater::draw();
218}
219
220void LLFloaterChatterBox::onOpen()
221{
222 gSavedSettings.setBOOL("ShowCommunicate", TRUE);
223}
224
225void LLFloaterChatterBox::onClose(bool app_quitting)
226{
227 setVisible(FALSE);
228 gSavedSettings.setBOOL("ShowCommunicate", FALSE);
229}
230
231void LLFloaterChatterBox::removeFloater(LLFloater* floaterp)
232{
233 if (floaterp->getName() == "chat floater")
234 {
235 // only my friends floater now locked
236 mTabContainer->lockTabs(1);
237 gSavedSettings.setBOOL("ChatHistoryTornOff", TRUE);
238 floaterp->setCanClose(TRUE);
239 }
240 LLMultiFloater::removeFloater(floaterp);
241}
242
243void LLFloaterChatterBox::addFloater(LLFloater* floaterp,
244 BOOL select_added_floater,
245 LLTabContainerCommon::eInsertionPoint insertion_point)
246{
247 // make sure my friends and chat history both locked when re-attaching chat history
248 if (floaterp->getName() == "chat floater")
249 {
250 // select my friends tab
251 mTabContainer->selectFirstTab();
252 // add chat history to the right of the my friends tab
253 //*TODO: respect select_added_floater so that we don't leave first tab selected
254 LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::RIGHT_OF_CURRENT);
255 // make sure first two tabs are now locked
256 mTabContainer->lockTabs(2);
257 gSavedSettings.setBOOL("ChatHistoryTornOff", FALSE);
258 floaterp->setCanClose(FALSE);
259 }
260 else
261 {
262 LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
263 }
264
265 // make sure active voice icon shows up for new tab
266 if (floaterp == mActiveVoiceFloater)
267 {
268 mTabContainer->setTabImage(floaterp, "active_voice_tab.tga");
269 }
270}
271
272
273//static
274LLFloaterChatterBox* LLFloaterChatterBox::showInstance(const LLSD& seed)
275{
276 LLFloaterChatterBox* floater = LLUISingleton<LLFloaterChatterBox>::showInstance(seed);
277
278 // if TRUE, show tab for active voice channel, otherwise, just show last tab
279 if (seed.asBoolean())
280 {
281 LLFloater* floater_to_show = getCurrentVoiceFloater();
282 if (floater_to_show)
283 {
284 floater_to_show->open();
285 }
286 else
287 {
288 // just open chatterbox if there is no active voice window
289 LLUISingleton<LLFloaterChatterBox>::getInstance(seed)->open();
290 }
291 }
292
293 return floater;
294}
295
296//static
297BOOL LLFloaterChatterBox::instanceVisible(const LLSD &seed)
298{
299 if (seed.asBoolean())
300 {
301 LLFloater* floater_to_show = getCurrentVoiceFloater();
302 if (floater_to_show)
303 {
304 return floater_to_show->isInVisibleChain();
305 }
306 }
307
308 return LLUISingleton<LLFloaterChatterBox>::instanceVisible(seed);
309}
310
311//static
312LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
313{
314 if (!LLVoiceClient::voiceEnabled())
315 {
316 return NULL;
317 }
318 if (LLVoiceChannelProximal::getInstance() == LLVoiceChannel::getCurrentVoiceChannel())
319 {
320 // show near me tab if in proximal channel
321 return LLFloaterChat::getInstance(LLSD());
322 }
323 else
324 {
325 LLFloaterChatterBox* floater = LLFloaterChatterBox::getInstance(LLSD());
326 // iterator over all IM tabs (skip friends and near me)
327 for (S32 i = 0; i < floater->getFloaterCount(); i++)
328 {
329 LLPanel* panelp = floater->mTabContainer->getPanelByIndex(i);
330 if (panelp->getName() == "im_floater")
331 {
332 // only LLFloaterIMPanels are called "im_floater"
333 LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp;
334 if (im_floaterp->getVoiceChannel() == LLVoiceChannel::getCurrentVoiceChannel())
335 {
336 return im_floaterp;
337 }
338 }
339 }
340 }
341 return NULL;
342}
diff --git a/linden/indra/newview/llfloaterchatterbox.h b/linden/indra/newview/llfloaterchatterbox.h
new file mode 100644
index 0000000..737f43e
--- /dev/null
+++ b/linden/indra/newview/llfloaterchatterbox.h
@@ -0,0 +1,87 @@
1/**
2 * @file llfloaterchatterbox.h
3 * @author Richard
4 * @date 2007-05-04
5 * @brief Integrated friends and group management/communication tool
6 *
7 * Copyright (c) 2007-2007, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlife.com/developers/opensource/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlife.com/developers/opensource/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 */
30
31#ifndef LL_LLFLOATERCHATTERBOX_H
32#define LL_LLFLOATERCHATTERBOX_H
33
34#include "llfloater.h"
35#include "llstring.h"
36
37class LLTabContainerCommon;
38
39class LLFloaterMyFriends : public LLFloater, public LLUISingleton<LLFloaterMyFriends>
40{
41public:
42 LLFloaterMyFriends(const LLSD& seed);
43 virtual ~LLFloaterMyFriends();
44
45 virtual BOOL postBuild();
46
47 void onClose(bool app_quitting);
48
49 // override LLUISingleton behavior
50 static LLFloaterMyFriends* showInstance(const LLSD& id);
51 static void hideInstance(const LLSD& id);
52 static BOOL instanceVisible(const LLSD& id);
53
54 static void* createFriendsPanel(void* data);
55 static void* createGroupsPanel(void* data);
56
57protected:
58 LLTabContainerCommon* mTabs;
59};
60
61class LLFloaterChatterBox : public LLMultiFloater, public LLUISingleton<LLFloaterChatterBox>
62{
63public:
64 LLFloaterChatterBox(const LLSD& seed);
65 virtual ~LLFloaterChatterBox();
66
67 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent);
68 /*virtual*/ void draw();
69 /*virtual*/ void onOpen();
70 /*virtual*/ void onClose(bool app_quitting);
71
72 /*virtual*/ void removeFloater(LLFloater* floaterp);
73 /*virtual*/ void addFloater(LLFloater* floaterp,
74 BOOL select_added_floater,
75 LLTabContainerCommon::eInsertionPoint insertion_point = LLTabContainerCommon::END);
76
77 static LLFloaterChatterBox* showInstance(const LLSD& seed);
78 static BOOL instanceVisible(const LLSD& seed);
79
80 static LLFloater* getCurrentVoiceFloater();
81
82protected:
83 LLFloater* mActiveVoiceFloater;
84};
85
86
87#endif // LL_LLFLOATERCHATTERBOX_H
diff --git a/linden/indra/newview/llfloatercustomize.cpp b/linden/indra/newview/llfloatercustomize.cpp
index 62ead8f..41bd8d7 100644
--- a/linden/indra/newview/llfloatercustomize.cpp
+++ b/linden/indra/newview/llfloatercustomize.cpp
@@ -489,7 +489,7 @@ void LLPanelEditWearable::addSubpart( const LLString& name, ESubpart id, LLSubpa
489{ 489{
490 if (!name.empty()) 490 if (!name.empty())
491 { 491 {
492 childSetAction(name, &LLPanelEditWearable::onBtnSubpart, (void*)(S32)id); 492 childSetAction(name, &LLPanelEditWearable::onBtnSubpart, (void*)id);
493 part->mButtonName = name; 493 part->mButtonName = name;
494 } 494 }
495 mSubpartList[id] = part; 495 mSubpartList[id] = part;
@@ -1585,19 +1585,19 @@ BOOL LLFloaterCustomize::postBuild()
1585 initWearablePanels(); 1585 initWearablePanels();
1586 1586
1587 // Tab container 1587 // Tab container
1588 childSetTabChangeCallback("customize tab container", "Shape", onTabChanged, (void*)(S32)WT_SHAPE ); 1588 childSetTabChangeCallback("customize tab container", "Shape", onTabChanged, (void*)WT_SHAPE );
1589 childSetTabChangeCallback("customize tab container", "Skin", onTabChanged, (void*)(S32)WT_SKIN ); 1589 childSetTabChangeCallback("customize tab container", "Skin", onTabChanged, (void*)WT_SKIN );
1590 childSetTabChangeCallback("customize tab container", "Hair", onTabChanged, (void*)(S32)WT_HAIR ); 1590 childSetTabChangeCallback("customize tab container", "Hair", onTabChanged, (void*)WT_HAIR );
1591 childSetTabChangeCallback("customize tab container", "Eyes", onTabChanged, (void*)(S32)WT_EYES ); 1591 childSetTabChangeCallback("customize tab container", "Eyes", onTabChanged, (void*)WT_EYES );
1592 childSetTabChangeCallback("customize tab container", "Shirt", onTabChanged, (void*)(S32)WT_SHIRT ); 1592 childSetTabChangeCallback("customize tab container", "Shirt", onTabChanged, (void*)WT_SHIRT );
1593 childSetTabChangeCallback("customize tab container", "Pants", onTabChanged, (void*)(S32)WT_PANTS ); 1593 childSetTabChangeCallback("customize tab container", "Pants", onTabChanged, (void*)WT_PANTS );
1594 childSetTabChangeCallback("customize tab container", "Shoes", onTabChanged, (void*)(S32)WT_SHOES ); 1594 childSetTabChangeCallback("customize tab container", "Shoes", onTabChanged, (void*)WT_SHOES );
1595 childSetTabChangeCallback("customize tab container", "Socks", onTabChanged, (void*)(S32)WT_SOCKS ); 1595 childSetTabChangeCallback("customize tab container", "Socks", onTabChanged, (void*)WT_SOCKS );
1596 childSetTabChangeCallback("customize tab container", "Jacket", onTabChanged, (void*)(S32)WT_JACKET ); 1596 childSetTabChangeCallback("customize tab container", "Jacket", onTabChanged, (void*)WT_JACKET );
1597 childSetTabChangeCallback("customize tab container", "Gloves", onTabChanged, (void*)(S32)WT_GLOVES ); 1597 childSetTabChangeCallback("customize tab container", "Gloves", onTabChanged, (void*)WT_GLOVES );
1598 childSetTabChangeCallback("customize tab container", "Undershirt", onTabChanged, (void*)(S32)WT_UNDERSHIRT ); 1598 childSetTabChangeCallback("customize tab container", "Undershirt", onTabChanged, (void*)WT_UNDERSHIRT );
1599 childSetTabChangeCallback("customize tab container", "Underpants", onTabChanged, (void*)(S32)WT_UNDERPANTS ); 1599 childSetTabChangeCallback("customize tab container", "Underpants", onTabChanged, (void*)WT_UNDERPANTS );
1600 childSetTabChangeCallback("customize tab container", "Skirt", onTabChanged, (void*)(S32)WT_SKIRT ); 1600 childSetTabChangeCallback("customize tab container", "Skirt", onTabChanged, (void*)WT_SKIRT );
1601 1601
1602 // Remove underware panels for teens 1602 // Remove underware panels for teens
1603 if (gAgent.mAccess < SIM_ACCESS_MATURE) 1603 if (gAgent.mAccess < SIM_ACCESS_MATURE)
diff --git a/linden/indra/newview/llfloaterdirectory.cpp b/linden/indra/newview/llfloaterdirectory.cpp
index aea55f7..3a05715 100644
--- a/linden/indra/newview/llfloaterdirectory.cpp
+++ b/linden/indra/newview/llfloaterdirectory.cpp
@@ -347,13 +347,13 @@ void LLFloaterDirectory::refreshGroup(const LLUUID& group_id)
347LLFloaterDirectory::~LLFloaterDirectory() 347LLFloaterDirectory::~LLFloaterDirectory()
348{ 348{
349 sInstance = NULL; 349 sInstance = NULL;
350 delete mPanelAvatarp; 350 delete mPanelAvatarp; mPanelAvatarp = NULL;
351 delete mPanelEventp; 351 delete mPanelEventp; mPanelEventp = NULL;
352 delete mPanelGroupp; 352 delete mPanelGroupp; mPanelGroupp = NULL;
353 delete mPanelGroupHolderp; 353 delete mPanelGroupHolderp; mPanelGroupHolderp = NULL;
354 delete mPanelPlacep; 354 delete mPanelPlacep; mPanelPlacep = NULL;
355 delete mPanelPlaceSmallp; 355 delete mPanelPlaceSmallp; mPanelPlaceSmallp = NULL;
356 delete mPanelClassifiedp; 356 delete mPanelClassifiedp; mPanelClassifiedp = NULL;
357 gSavedSettings.setBOOL("ShowDirectory", FALSE); 357 gSavedSettings.setBOOL("ShowDirectory", FALSE);
358} 358}
359 359
diff --git a/linden/indra/newview/llfloaterfriends.cpp b/linden/indra/newview/llfloaterfriends.cpp
index d01a24b..78447e9 100644
--- a/linden/indra/newview/llfloaterfriends.cpp
+++ b/linden/indra/newview/llfloaterfriends.cpp
@@ -63,20 +63,18 @@
63class LLLocalFriendsObserver : public LLFriendObserver 63class LLLocalFriendsObserver : public LLFriendObserver
64{ 64{
65public: 65public:
66 LLLocalFriendsObserver(LLFloaterFriends* floater) : mFloater(floater) {} 66 LLLocalFriendsObserver(LLPanelFriends* floater) : mFloater(floater) {}
67 virtual ~LLLocalFriendsObserver() { mFloater = NULL; } 67 virtual ~LLLocalFriendsObserver() { mFloater = NULL; }
68 virtual void changed(U32 mask) 68 virtual void changed(U32 mask)
69 { 69 {
70 mFloater->updateFriends(mask); 70 mFloater->updateFriends(mask);
71 } 71 }
72protected: 72protected:
73 LLFloaterFriends* mFloater; 73 LLPanelFriends* mFloater;
74}; 74};
75 75
76LLFloaterFriends* LLFloaterFriends::sInstance = NULL; 76LLPanelFriends::LLPanelFriends() :
77 77 LLPanel(),
78LLFloaterFriends::LLFloaterFriends() :
79 LLFloater("Friends"),
80 LLEventTimer(1000000), 78 LLEventTimer(1000000),
81 mObserver(NULL), 79 mObserver(NULL),
82 mMenuState(0), 80 mMenuState(0),
@@ -84,80 +82,38 @@ LLFloaterFriends::LLFloaterFriends() :
84 mAllowRightsChange(TRUE), 82 mAllowRightsChange(TRUE),
85 mNumRightsChanged(0) 83 mNumRightsChanged(0)
86{ 84{
87 mTimer.stop(); 85 mEventTimer.stop();
88 sInstance = this;
89 mObserver = new LLLocalFriendsObserver(this); 86 mObserver = new LLLocalFriendsObserver(this);
90 LLAvatarTracker::instance().addObserver(mObserver); 87 LLAvatarTracker::instance().addObserver(mObserver);
91 gSavedSettings.setBOOL("ShowFriends", TRUE);
92 // Builds and adds to gFloaterView
93 gUICtrlFactory->buildFloater(this, "floater_friends.xml");
94} 88}
95 89
96LLFloaterFriends::~LLFloaterFriends() 90LLPanelFriends::~LLPanelFriends()
97{ 91{
98 LLAvatarTracker::instance().removeObserver(mObserver); 92 LLAvatarTracker::instance().removeObserver(mObserver);
99 delete mObserver; 93 delete mObserver;
100 sInstance = NULL;
101 gSavedSettings.setBOOL("ShowFriends", FALSE);
102} 94}
103 95
104void LLFloaterFriends::tick() 96void LLPanelFriends::tick()
105{ 97{
106 mTimer.stop(); 98 mEventTimer.stop();
107 mPeriod = 1000000; 99 mPeriod = 1000000;
108 mAllowRightsChange = TRUE; 100 mAllowRightsChange = TRUE;
109 updateFriends(LLFriendObserver::ADD); 101 updateFriends(LLFriendObserver::ADD);
110} 102}
111 103
112// static 104void LLPanelFriends::updateFriends(U32 changed_mask)
113void LLFloaterFriends::show(void*)
114{
115 if(sInstance)
116 {
117 sInstance->open(); /*Flawfinder: ignore*/
118 }
119 else
120 {
121 LLFloaterFriends* self = new LLFloaterFriends;
122 self->open(); /*Flawfinder: ignore*/
123 }
124}
125
126
127// static
128BOOL LLFloaterFriends::visible(void*)
129{
130 return sInstance && sInstance->getVisible();
131}
132
133
134// static
135void LLFloaterFriends::toggle(void*)
136{
137 if (sInstance)
138 {
139 sInstance->close();
140 }
141 else
142 {
143 show();
144 }
145}
146
147
148void LLFloaterFriends::updateFriends(U32 changed_mask)
149{ 105{
150 LLUUID selected_id; 106 LLUUID selected_id;
151 LLCtrlListInterface *friends_list = sInstance->childGetListInterface("friend_list"); 107 LLCtrlListInterface *friends_list = childGetListInterface("friend_list");
152 if (!friends_list) return; 108 if (!friends_list) return;
153 LLCtrlScrollInterface *friends_scroll = sInstance->childGetScrollInterface("friend_list"); 109 LLCtrlScrollInterface *friends_scroll = childGetScrollInterface("friend_list");
154 if (!friends_scroll) return; 110 if (!friends_scroll) return;
155 111
156 // We kill the selection warning, otherwise we'll spam with warning popups 112 // We kill the selection warning, otherwise we'll spam with warning popups
157 // if the maximum amount of friends are selected 113 // if the maximum amount of friends are selected
158 mShowMaxSelectWarning = false; 114 mShowMaxSelectWarning = false;
159 115
160 LLDynamicArray<LLUUID> selected_friends = sInstance->getSelectedIDs(); 116 LLDynamicArray<LLUUID> selected_friends = getSelectedIDs();
161 if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE)) 117 if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
162 { 118 {
163 refreshNames(); 119 refreshNames();
@@ -168,8 +124,8 @@ void LLFloaterFriends::updateFriends(U32 changed_mask)
168 if(mNumRightsChanged > 0) 124 if(mNumRightsChanged > 0)
169 { 125 {
170 mPeriod = RIGHTS_CHANGE_TIMEOUT; 126 mPeriod = RIGHTS_CHANGE_TIMEOUT;
171 mTimer.start(); 127 mEventTimer.start();
172 mTimer.reset(); 128 mEventTimer.reset();
173 mAllowRightsChange = FALSE; 129 mAllowRightsChange = FALSE;
174 } 130 }
175 else 131 else
@@ -194,12 +150,12 @@ void LLFloaterFriends::updateFriends(U32 changed_mask)
194} 150}
195 151
196// virtual 152// virtual
197BOOL LLFloaterFriends::postBuild() 153BOOL LLPanelFriends::postBuild()
198{ 154{
199
200 mFriendsList = LLUICtrlFactory::getScrollListByName(this, "friend_list"); 155 mFriendsList = LLUICtrlFactory::getScrollListByName(this, "friend_list");
201 mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT); 156 mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT);
202 mFriendsList->setMaxiumumSelectCallback(onMaximumSelect); 157 mFriendsList->setMaxiumumSelectCallback(onMaximumSelect);
158 mFriendsList->setCommitOnSelectionChange(TRUE);
203 childSetCommitCallback("friend_list", onSelectName, this); 159 childSetCommitCallback("friend_list", onSelectName, this);
204 childSetDoubleClickCallback("friend_list", onClickIM); 160 childSetDoubleClickCallback("friend_list", onClickIM);
205 161
@@ -214,14 +170,17 @@ BOOL LLFloaterFriends::postBuild()
214 childSetAction("pay_btn", onClickPay, this); 170 childSetAction("pay_btn", onClickPay, this);
215 childSetAction("add_btn", onClickAddFriend, this); 171 childSetAction("add_btn", onClickAddFriend, this);
216 childSetAction("remove_btn", onClickRemove, this); 172 childSetAction("remove_btn", onClickRemove, this);
217 childSetAction("close_btn", onClickClose, this);
218 173
174 setDefaultBtn("im_btn");
175
176 updateFriends(LLFriendObserver::ADD);
219 refreshUI(); 177 refreshUI();
178
220 return TRUE; 179 return TRUE;
221} 180}
222 181
223 182
224void LLFloaterFriends::addFriend(const std::string& name, const LLUUID& agent_id) 183void LLPanelFriends::addFriend(const std::string& name, const LLUUID& agent_id)
225{ 184{
226 LLAvatarTracker& at = LLAvatarTracker::instance(); 185 LLAvatarTracker& at = LLAvatarTracker::instance();
227 const LLRelationship* relationInfo = at.getBuddyInfo(agent_id); 186 const LLRelationship* relationInfo = at.getBuddyInfo(agent_id);
@@ -275,17 +234,26 @@ void LLFloaterFriends::addFriend(const std::string& name, const LLUUID& agent_id
275 mFriendsList->addElement(element, ADD_BOTTOM); 234 mFriendsList->addElement(element, ADD_BOTTOM);
276} 235}
277 236
278void LLFloaterFriends::refreshRightsChangeList(U8 state) 237void LLPanelFriends::refreshRightsChangeList()
279{ 238{
280 LLDynamicArray<LLUUID> friends = getSelectedIDs(); 239 LLDynamicArray<LLUUID> friends = getSelectedIDs();
281 const LLRelationship* friend_status = NULL; 240 S32 num_selected = friends.size();
282 if(friends.size() > 0) friend_status = LLAvatarTracker::instance().getBuddyInfo(friends[0]);
283 241
284 LLSD row; 242 LLSD row;
285 bool can_change_visibility = false; 243 bool can_offer_teleport = num_selected >= 1;
286 bool can_change_modify = false; 244
287 bool can_change_online_multiple = true; 245 // aggregate permissions over all selected friends
288 bool can_change_map_multiple = true; 246 bool friends_see_online = true;
247 bool friends_see_on_map = true;
248 bool friends_modify_objects = true;
249
250 // do at least some of the friends selected have these rights?
251 bool some_friends_see_online = false;
252 bool some_friends_see_on_map = false;
253 bool some_friends_modify_objects = false;
254
255 bool selected_friends_online = true;
256
289 LLTextBox* processing_label = LLUICtrlFactory::getTextBoxByName(this, "process_rights_label"); 257 LLTextBox* processing_label = LLUICtrlFactory::getTextBoxByName(this, "process_rights_label");
290 258
291 if(!mAllowRightsChange) 259 if(!mAllowRightsChange)
@@ -293,7 +261,9 @@ void LLFloaterFriends::refreshRightsChangeList(U8 state)
293 if(processing_label) 261 if(processing_label)
294 { 262 {
295 processing_label->setVisible(true); 263 processing_label->setVisible(true);
296 state = 0; 264 // ignore selection for now
265 friends.clear();
266 num_selected = 0;
297 } 267 }
298 } 268 }
299 else 269 else
@@ -304,82 +274,111 @@ void LLFloaterFriends::refreshRightsChangeList(U8 state)
304 } 274 }
305 } 275 }
306 276
307 if(state == 1) 277 const LLRelationship* friend_status = NULL;
308 { 278 for(LLDynamicArray<LLUUID>::iterator itr = friends.begin(); itr != friends.end(); ++itr)
309 if(friend_status && !friend_status->isOnline())
310 {
311 childSetEnabled("offer_teleport_btn", false);
312 }
313 can_change_visibility = true;
314 can_change_modify = true;
315 }
316 else if (state == 2)
317 { 279 {
318 can_change_visibility = true; 280 friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr);
319 can_change_modify = false; 281 if (friend_status)
320 for(LLDynamicArray<LLUUID>::iterator itr = friends.begin(); itr != friends.end(); ++itr)
321 { 282 {
322 friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr); 283 bool can_see_online = friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS);
284 bool can_see_on_map = friend_status->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION);
285 bool can_modify_objects = friend_status->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS);
286
287 // aggregate rights of this friend into total selection
288 friends_see_online &= can_see_online;
289 friends_see_on_map &= can_see_on_map;
290 friends_modify_objects &= can_modify_objects;
291
292 // can at least one of your selected friends do any of these?
293 some_friends_see_online |= can_see_online;
294 some_friends_see_on_map |= can_see_on_map;
295 some_friends_modify_objects |= can_modify_objects;
296
323 if(!friend_status->isOnline()) 297 if(!friend_status->isOnline())
324 { 298 {
325 childSetEnabled("offer_teleport_btn", false); 299 can_offer_teleport = false;
326 } 300 selected_friends_online = false;
327 if(!friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS))
328 {
329 can_change_online_multiple = false;
330 can_change_map_multiple = false;
331 }
332 else if(!friend_status->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))
333 {
334 can_change_map_multiple = false;
335 } 301 }
336 } 302 }
337 303 else // missing buddy info, don't allow any operations
304 {
305 can_offer_teleport = false;
306
307 friends_see_online = false;
308 friends_see_on_map = false;
309 friends_modify_objects = false;
310
311 some_friends_see_online = false;
312 some_friends_see_on_map = false;
313 some_friends_modify_objects = false;
314 }
338 } 315 }
339 316
340 317
341 LLCheckboxCtrl* check; 318 // seeing a friend on the map requires seeing online status as a prerequisite
319 friends_see_on_map &= friends_see_online;
320
342 mMenuState = 0; 321 mMenuState = 0;
343 322
344 check = LLUICtrlFactory::getCheckBoxByName(this, "online_status_cb"); 323 // make checkboxes visible after we have finished processing rights
345 check->setEnabled(can_change_visibility); 324 childSetVisible("online_status_cb", mAllowRightsChange);
346 check->set(FALSE); 325 childSetVisible("map_status_cb", mAllowRightsChange);
347 if(!mAllowRightsChange) check->setVisible(FALSE); 326 childSetVisible("modify_status_cb", mAllowRightsChange);
348 else check->setVisible(TRUE); 327
349 if(friend_status) 328 if (num_selected == 0) // nothing selected
350 { 329 {
351 check->set(friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS) && can_change_online_multiple); 330 childSetEnabled("im_btn", FALSE);
352 if(friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)) mMenuState |= LLRelationship::GRANT_ONLINE_STATUS; 331 childSetEnabled("offer_teleport_btn", FALSE);
332
333 childSetEnabled("online_status_cb", FALSE);
334 childSetValue("online_status_cb", FALSE);
335 childSetTentative("online_status_cb", FALSE);
336
337 childSetEnabled("map_status_cb", FALSE);
338 childSetValue("map_status_cb", FALSE);
339 childSetTentative("map_status_cb", FALSE);
340
341 childSetEnabled("modify_status_cb", FALSE);
342 childSetValue("modify_status_cb", FALSE);
343 childSetTentative("modify_status_cb", FALSE);
353 } 344 }
354 345 else // we have at least one friend selected...
355 check = LLUICtrlFactory::getCheckBoxByName(this, "map_status_cb");
356 check->setEnabled(false);
357 check->set(FALSE);
358 if(!mAllowRightsChange) check->setVisible(FALSE);
359 else check->setVisible(TRUE);
360 if(friend_status)
361 { 346 {
362 check->setEnabled(friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS) && can_change_visibility && can_change_online_multiple); 347 // only allow IMs to groups when everyone in the group is online
363 check->set(friend_status->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION) && can_change_map_multiple); 348 // to be consistent with context menus in inventory and because otherwise
364 if(friend_status->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION)) mMenuState |= LLRelationship::GRANT_MAP_LOCATION; 349 // offline friends would be silently dropped from the session
365 } 350 childSetEnabled("im_btn", selected_friends_online || num_selected == 1);
366 351
367 check = LLUICtrlFactory::getCheckBoxByName(this, "modify_status_cb"); 352 childSetEnabled("offer_teleport_btn", can_offer_teleport);
368 check->setEnabled(can_change_modify); 353
369 check->set(FALSE); 354 childSetEnabled("online_status_cb", TRUE);
370 if(!mAllowRightsChange) check->setVisible(FALSE); 355 childSetValue("online_status_cb", some_friends_see_online);
371 else check->setVisible(TRUE); 356 childSetTentative("online_status_cb", some_friends_see_online != friends_see_online);
372 if(can_change_modify) 357 if (friends_see_online)
373 { 358 {
374 if(friend_status) 359 mMenuState |= LLRelationship::GRANT_ONLINE_STATUS;
360 }
361
362 childSetEnabled("map_status_cb", TRUE);
363 childSetValue("map_status_cb", some_friends_see_on_map);
364 childSetTentative("map_status_cb", some_friends_see_on_map != friends_see_on_map);
365 if(friends_see_on_map)
375 { 366 {
376 check->set(friend_status->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS)); 367 mMenuState |= LLRelationship::GRANT_MAP_LOCATION;
377 if(friend_status->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS)) mMenuState |= LLRelationship::GRANT_MODIFY_OBJECTS; 368 }
369
370 // for now, don't allow modify rights change for multiple select
371 childSetEnabled("modify_status_cb", num_selected == 1);
372 childSetValue("modify_status_cb", some_friends_modify_objects);
373 childSetTentative("modify_status_cb", some_friends_modify_objects != friends_modify_objects);
374 if(friends_modify_objects)
375 {
376 mMenuState |= LLRelationship::GRANT_MODIFY_OBJECTS;
378 } 377 }
379 } 378 }
380} 379}
381 380
382void LLFloaterFriends::refreshNames() 381void LLPanelFriends::refreshNames()
383{ 382{
384 LLDynamicArray<LLUUID> selected_ids = getSelectedIDs(); 383 LLDynamicArray<LLUUID> selected_ids = getSelectedIDs();
385 S32 pos = mFriendsList->getScrollPos(); 384 S32 pos = mFriendsList->getScrollPos();
@@ -409,7 +408,7 @@ void LLFloaterFriends::refreshNames()
409} 408}
410 409
411 410
412void LLFloaterFriends::refreshUI() 411void LLPanelFriends::refreshUI()
413{ 412{
414 BOOL single_selected = FALSE; 413 BOOL single_selected = FALSE;
415 BOOL multiple_selected = FALSE; 414 BOOL multiple_selected = FALSE;
@@ -443,40 +442,34 @@ void LLFloaterFriends::refreshUI()
443 childSetEnabled("im_btn", single_selected); 442 childSetEnabled("im_btn", single_selected);
444 childSetEnabled("friend_rights", single_selected); 443 childSetEnabled("friend_rights", single_selected);
445 444
446 //Note: We reset this in refreshRightsChangeList since we already have to iterate 445 refreshRightsChangeList();
447 //through all selected friends there
448 childSetEnabled("offer_teleport_btn", single_selected);
449
450 refreshRightsChangeList((single_selected + multiple_selected));
451} 446}
452 447
453// static 448LLDynamicArray<LLUUID> LLPanelFriends::getSelectedIDs()
454LLDynamicArray<LLUUID> LLFloaterFriends::getSelectedIDs()
455{ 449{
456 LLUUID selected_id; 450 LLUUID selected_id;
457 LLDynamicArray<LLUUID> friend_ids; 451 LLDynamicArray<LLUUID> friend_ids;
458 if(sInstance) 452 std::vector<LLScrollListItem*> selected = mFriendsList->getAllSelected();
453 for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
459 { 454 {
460 std::vector<LLScrollListItem*> selected = sInstance->mFriendsList->getAllSelected(); 455 friend_ids.push_back((*itr)->getUUID());
461 for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
462 {
463 friend_ids.push_back((*itr)->getUUID());
464 }
465 } 456 }
466 return friend_ids; 457 return friend_ids;
467} 458}
468 459
469// static 460// static
470void LLFloaterFriends::onSelectName(LLUICtrl* ctrl, void* user_data) 461void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data)
471{ 462{
472 if(sInstance) 463 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
464
465 if(panelp)
473 { 466 {
474 sInstance->refreshUI(); 467 panelp->refreshUI();
475 } 468 }
476} 469}
477 470
478//static 471//static
479void LLFloaterFriends::onMaximumSelect(void* user_data) 472void LLPanelFriends::onMaximumSelect(void* user_data)
480{ 473{
481 LLString::format_map_t args; 474 LLString::format_map_t args;
482 args["[MAX_SELECT]"] = llformat("%d", MAX_FRIEND_SELECT); 475 args["[MAX_SELECT]"] = llformat("%d", MAX_FRIEND_SELECT);
@@ -484,10 +477,12 @@ void LLFloaterFriends::onMaximumSelect(void* user_data)
484}; 477};
485 478
486// static 479// static
487void LLFloaterFriends::onClickProfile(void* user_data) 480void LLPanelFriends::onClickProfile(void* user_data)
488{ 481{
489 //llinfos << "LLFloaterFriends::onClickProfile()" << llendl; 482 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
490 LLDynamicArray<LLUUID> ids = getSelectedIDs(); 483
484 //llinfos << "LLPanelFriends::onClickProfile()" << llendl;
485 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
491 if(ids.size() > 0) 486 if(ids.size() > 0)
492 { 487 {
493 LLUUID agent_id = ids[0]; 488 LLUUID agent_id = ids[0];
@@ -498,10 +493,12 @@ void LLFloaterFriends::onClickProfile(void* user_data)
498} 493}
499 494
500// static 495// static
501void LLFloaterFriends::onClickIM(void* user_data) 496void LLPanelFriends::onClickIM(void* user_data)
502{ 497{
503 //llinfos << "LLFloaterFriends::onClickIM()" << llendl; 498 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
504 LLDynamicArray<LLUUID> ids = getSelectedIDs(); 499
500 //llinfos << "LLPanelFriends::onClickIM()" << llendl;
501 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
505 if(ids.size() > 0) 502 if(ids.size() > 0)
506 { 503 {
507 if(ids.size() == 1) 504 if(ids.size() == 1)
@@ -514,8 +511,8 @@ void LLFloaterFriends::onClickIM(void* user_data)
514 { 511 {
515 char buffer[MAX_STRING]; /* Flawfinder: ignore */ 512 char buffer[MAX_STRING]; /* Flawfinder: ignore */
516 snprintf(buffer, MAX_STRING, "%s %s", first, last); /* Flawfinder: ignore */ 513 snprintf(buffer, MAX_STRING, "%s %s", first, last); /* Flawfinder: ignore */
517 gIMView->setFloaterOpen(TRUE); 514 gIMMgr->setFloaterOpen(TRUE);
518 gIMView->addSession( 515 gIMMgr->addSession(
519 buffer, 516 buffer,
520 IM_NOTHING_SPECIAL, 517 IM_NOTHING_SPECIAL,
521 agent_id); 518 agent_id);
@@ -523,17 +520,18 @@ void LLFloaterFriends::onClickIM(void* user_data)
523 } 520 }
524 else 521 else
525 { 522 {
526 gIMView->setFloaterOpen(TRUE); 523 gIMMgr->setFloaterOpen(TRUE);
527 gIMView->addSession("Friends Conference", 524 gIMMgr->addSession("Friends Conference",
528 IM_SESSION_CONFERENCE_START, 525 IM_SESSION_CONFERENCE_START,
529 ids[0], 526 ids[0],
530 ids); 527 ids);
531 } 528 }
529 make_ui_sound("UISndStartIM");
532 } 530 }
533} 531}
534 532
535// static 533// static
536void LLFloaterFriends::requestFriendship(const LLUUID& target_id, const LLString& target_name) 534void LLPanelFriends::requestFriendship(const LLUUID& target_id, const LLString& target_name)
537{ 535{
538 // HACK: folder id stored as "message" 536 // HACK: folder id stored as "message"
539 LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD); 537 LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
@@ -552,7 +550,7 @@ struct LLAddFriendData
552}; 550};
553 551
554// static 552// static
555void LLFloaterFriends::callbackAddFriend(S32 option, void* data) 553void LLPanelFriends::callbackAddFriend(S32 option, void* data)
556{ 554{
557 LLAddFriendData* add = (LLAddFriendData*)data; 555 LLAddFriendData* add = (LLAddFriendData*)data;
558 if (option == 0) 556 if (option == 0)
@@ -563,7 +561,7 @@ void LLFloaterFriends::callbackAddFriend(S32 option, void* data)
563} 561}
564 562
565// static 563// static
566void LLFloaterFriends::onPickAvatar(const std::vector<std::string>& names, 564void LLPanelFriends::onPickAvatar(const std::vector<std::string>& names,
567 const std::vector<LLUUID>& ids, 565 const std::vector<LLUUID>& ids,
568 void* ) 566 void* )
569{ 567{
@@ -573,7 +571,7 @@ void LLFloaterFriends::onPickAvatar(const std::vector<std::string>& names,
573} 571}
574 572
575// static 573// static
576void LLFloaterFriends::requestFriendshipDialog(const LLUUID& id, 574void LLPanelFriends::requestFriendshipDialog(const LLUUID& id,
577 const std::string& name) 575 const std::string& name)
578{ 576{
579 if(id == gAgentID) 577 if(id == gAgentID)
@@ -593,16 +591,24 @@ void LLFloaterFriends::requestFriendshipDialog(const LLUUID& id,
593} 591}
594 592
595// static 593// static
596void LLFloaterFriends::onClickAddFriend(void* user_data) 594void LLPanelFriends::onClickAddFriend(void* user_data)
597{ 595{
598 LLFloaterAvatarPicker::show(onPickAvatar, user_data, FALSE, TRUE); 596 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
597 LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
598 LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(onPickAvatar, user_data, FALSE, TRUE);
599 if (root_floater)
600 {
601 root_floater->addDependentFloater(picker);
602 }
599} 603}
600 604
601// static 605// static
602void LLFloaterFriends::onClickRemove(void* user_data) 606void LLPanelFriends::onClickRemove(void* user_data)
603{ 607{
604 //llinfos << "LLFloaterFriends::onClickRemove()" << llendl; 608 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
605 LLDynamicArray<LLUUID> ids = getSelectedIDs(); 609
610 //llinfos << "LLPanelFriends::onClickRemove()" << llendl;
611 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
606 LLStringBase<char>::format_map_t args; 612 LLStringBase<char>::format_map_t args;
607 if(ids.size() > 0) 613 if(ids.size() > 0)
608 { 614 {
@@ -630,9 +636,11 @@ void LLFloaterFriends::onClickRemove(void* user_data)
630} 636}
631 637
632// static 638// static
633void LLFloaterFriends::onClickOfferTeleport(void*) 639void LLPanelFriends::onClickOfferTeleport(void* user_data)
634{ 640{
635 LLDynamicArray<LLUUID> ids = getSelectedIDs(); 641 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
642
643 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
636 if(ids.size() > 0) 644 if(ids.size() > 0)
637 { 645 {
638 handle_lure(ids); 646 handle_lure(ids);
@@ -640,43 +648,40 @@ void LLFloaterFriends::onClickOfferTeleport(void*)
640} 648}
641 649
642// static 650// static
643void LLFloaterFriends::onClickPay(void*) 651void LLPanelFriends::onClickPay(void* user_data)
644{ 652{
645 LLDynamicArray<LLUUID> ids = getSelectedIDs(); 653 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
654
655 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
646 if(ids.size() == 1) 656 if(ids.size() == 1)
647 { 657 {
648 handle_pay_by_id(ids[0]); 658 handle_pay_by_id(ids[0]);
649 } 659 }
650} 660}
651 661
652// static 662void LLPanelFriends::onClickOnlineStatus(LLUICtrl* ctrl, void* user_data)
653void LLFloaterFriends::onClickClose(void* user_data)
654{ 663{
655 //llinfos << "LLFloaterFriends::onClickClose()" << llendl; 664 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
656 if(sInstance)
657 {
658 sInstance->onClose(false);
659 }
660}
661 665
662void LLFloaterFriends::onClickOnlineStatus(LLUICtrl* ctrl, void* user_data)
663{
664 bool checked = ctrl->getValue(); 666 bool checked = ctrl->getValue();
665 sInstance->updateMenuState(LLRelationship::GRANT_ONLINE_STATUS, checked); 667 panelp->updateMenuState(LLRelationship::GRANT_ONLINE_STATUS, checked);
666 sInstance->applyRightsToFriends(LLRelationship::GRANT_ONLINE_STATUS, checked); 668 panelp->applyRightsToFriends(LLRelationship::GRANT_ONLINE_STATUS, checked);
667} 669}
668 670
669void LLFloaterFriends::onClickMapStatus(LLUICtrl* ctrl, void* user_data) 671void LLPanelFriends::onClickMapStatus(LLUICtrl* ctrl, void* user_data)
670{ 672{
673 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
671 bool checked = ctrl->getValue(); 674 bool checked = ctrl->getValue();
672 sInstance->updateMenuState(LLRelationship::GRANT_MAP_LOCATION, checked); 675 panelp->updateMenuState(LLRelationship::GRANT_MAP_LOCATION, checked);
673 sInstance->applyRightsToFriends(LLRelationship::GRANT_MAP_LOCATION, checked); 676 panelp->applyRightsToFriends(LLRelationship::GRANT_MAP_LOCATION, checked);
674} 677}
675 678
676void LLFloaterFriends::onClickModifyStatus(LLUICtrl* ctrl, void* user_data) 679void LLPanelFriends::onClickModifyStatus(LLUICtrl* ctrl, void* user_data)
677{ 680{
681 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
682
678 bool checked = ctrl->getValue(); 683 bool checked = ctrl->getValue();
679 LLDynamicArray<LLUUID> ids = getSelectedIDs(); 684 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
680 LLStringBase<char>::format_map_t args; 685 LLStringBase<char>::format_map_t args;
681 if(ids.size() > 0) 686 if(ids.size() > 0)
682 { 687 {
@@ -690,33 +695,35 @@ void LLFloaterFriends::onClickModifyStatus(LLUICtrl* ctrl, void* user_data)
690 args["[FIRST_NAME]"] = first; 695 args["[FIRST_NAME]"] = first;
691 args["[LAST_NAME]"] = last; 696 args["[LAST_NAME]"] = last;
692 } 697 }
693 if(checked) gViewerWindow->alertXml("GrantModifyRights", args, handleModifyRights, NULL); 698 if(checked) gViewerWindow->alertXml("GrantModifyRights", args, handleModifyRights, user_data);
694 else gViewerWindow->alertXml("RevokeModifyRights", args, handleModifyRights, NULL); 699 else gViewerWindow->alertXml("RevokeModifyRights", args, handleModifyRights, user_data);
695 } 700 }
696 else return; 701 else return;
697 } 702 }
698} 703}
699 704
700void LLFloaterFriends::handleModifyRights(S32 option, void* user_data) 705void LLPanelFriends::handleModifyRights(S32 option, void* user_data)
701{ 706{
702 if(sInstance) 707 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
708
709 if(panelp)
703 { 710 {
704 if(!option) 711 if(!option)
705 { 712 {
706 sInstance->updateMenuState(LLRelationship::GRANT_MODIFY_OBJECTS, !((sInstance->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0)); 713 panelp->updateMenuState(LLRelationship::GRANT_MODIFY_OBJECTS, !((panelp->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0));
707 sInstance->applyRightsToFriends(LLRelationship::GRANT_MODIFY_OBJECTS, ((sInstance->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0)); 714 panelp->applyRightsToFriends(LLRelationship::GRANT_MODIFY_OBJECTS, ((panelp->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0));
708 } 715 }
709 sInstance->refreshUI(); 716 panelp->refreshUI();
710 } 717 }
711} 718}
712 719
713void LLFloaterFriends::updateMenuState(S32 flag, BOOL value) 720void LLPanelFriends::updateMenuState(S32 flag, BOOL value)
714{ 721{
715 if(value) mMenuState |= flag; 722 if(value) mMenuState |= flag;
716 else mMenuState &= ~flag; 723 else mMenuState &= ~flag;
717} 724}
718 725
719void LLFloaterFriends::applyRightsToFriends(S32 flag, BOOL value) 726void LLPanelFriends::applyRightsToFriends(S32 flag, BOOL value)
720{ 727{
721 LLMessageSystem* msg = gMessageSystem; 728 LLMessageSystem* msg = gMessageSystem;
722 msg->newMessageFast(_PREHASH_GrantUserRights); 729 msg->newMessageFast(_PREHASH_GrantUserRights);
@@ -745,7 +752,7 @@ void LLFloaterFriends::applyRightsToFriends(S32 flag, BOOL value)
745 752
746 753
747// static 754// static
748void LLFloaterFriends::handleRemove(S32 option, void* user_data) 755void LLPanelFriends::handleRemove(S32 option, void* user_data)
749{ 756{
750 LLDynamicArray<LLUUID>* ids = static_cast<LLDynamicArray<LLUUID>*>(user_data); 757 LLDynamicArray<LLUUID>* ids = static_cast<LLDynamicArray<LLUUID>*>(user_data);
751 for(LLDynamicArray<LLUUID>::iterator itr = ids->begin(); itr != ids->end(); ++itr) 758 for(LLDynamicArray<LLUUID>::iterator itr = ids->begin(); itr != ids->end(); ++itr)
diff --git a/linden/indra/newview/llfloaterfriends.h b/linden/indra/newview/llfloaterfriends.h
index 327a8cf..0b6646d 100644
--- a/linden/indra/newview/llfloaterfriends.h
+++ b/linden/indra/newview/llfloaterfriends.h
@@ -31,7 +31,7 @@
31#ifndef LL_LLFLOATERFRIENDS_H 31#ifndef LL_LLFLOATERFRIENDS_H
32#define LL_LLFLOATERFRIENDS_H 32#define LL_LLFLOATERFRIENDS_H
33 33
34#include "llfloater.h" 34#include "llpanel.h"
35#include "llstring.h" 35#include "llstring.h"
36#include "lluuid.h" 36#include "lluuid.h"
37#include "lltimer.h" 37#include "lltimer.h"
@@ -40,24 +40,23 @@ class LLFriendObserver;
40 40
41 41
42/** 42/**
43 * @class LLFloaterFriends 43 * @class LLPanelFriends
44 * @brief An instance of this class is used for displaying your friends 44 * @brief An instance of this class is used for displaying your friends
45 * and gives you quick access to all agents which a user relationship. 45 * and gives you quick access to all agents which a user relationship.
46 * 46 *
47 * @sa LLFloater 47 * @sa LLFloater
48 */ 48 */
49class LLFloaterFriends : public LLFloater, public LLEventTimer 49class LLPanelFriends : public LLPanel, public LLEventTimer
50{ 50{
51public: 51public:
52 virtual ~LLFloaterFriends(); 52 LLPanelFriends();
53 virtual ~LLPanelFriends();
53 54
54 /** 55 /**
55 * @brief This method either creates or brings to the front the 56 * @brief This method either creates or brings to the front the
56 * current instantiation of this floater. There is only once since 57 * current instantiation of this floater. There is only once since
57 * you can currently only look at your local friends. 58 * you can currently only look at your local friends.
58 */ 59 */
59 static void show(void* ignored = NULL);
60
61 virtual void tick(); 60 virtual void tick();
62 61
63 /** 62 /**
@@ -68,11 +67,6 @@ public:
68 67
69 virtual BOOL postBuild(); 68 virtual BOOL postBuild();
70 69
71 static BOOL visible(void* unused = NULL);
72
73 // Toggles visibility of floater
74 static void toggle(void* unused = NULL);
75
76 // Show a dialog explaining what friendship entails, then request 70 // Show a dialog explaining what friendship entails, then request
77 // friendship. JC 71 // friendship. JC
78 static void requestFriendshipDialog(const LLUUID& target_id, 72 static void requestFriendshipDialog(const LLUUID& target_id,
@@ -95,19 +89,18 @@ private:
95 }; 89 };
96 90
97 // protected members 91 // protected members
98 LLFloaterFriends();
99 92
100 void reloadNames(); 93 void reloadNames();
101 void refreshNames(); 94 void refreshNames();
102 void refreshUI(); 95 void refreshUI();
103 void refreshRightsChangeList(U8 state); 96 void refreshRightsChangeList();
104 void applyRightsToFriends(S32 flag, BOOL value); 97 void applyRightsToFriends(S32 flag, BOOL value);
105 void updateMenuState(S32 flag, BOOL value); 98 void updateMenuState(S32 flag, BOOL value);
106 S32 getMenuState() { return mMenuState; } 99 S32 getMenuState() { return mMenuState; }
107 void addFriend(const std::string& name, const LLUUID& agent_id); 100 void addFriend(const std::string& name, const LLUUID& agent_id);
108 101
109 // return LLUUID::null if nothing is selected 102 // return LLUUID::null if nothing is selected
110 static LLDynamicArray<LLUUID> getSelectedIDs(); 103 LLDynamicArray<LLUUID> getSelectedIDs();
111 104
112 // callback methods 105 // callback methods
113 static void onSelectName(LLUICtrl* ctrl, void* user_data); 106 static void onSelectName(LLUICtrl* ctrl, void* user_data);
@@ -123,8 +116,6 @@ private:
123 static void onClickOfferTeleport(void* user_data); 116 static void onClickOfferTeleport(void* user_data);
124 static void onClickPay(void* user_data); 117 static void onClickPay(void* user_data);
125 118
126 static void onClickClose(void* user_data);
127
128 static void onClickOnlineStatus(LLUICtrl* ctrl, void* user_data); 119 static void onClickOnlineStatus(LLUICtrl* ctrl, void* user_data);
129 static void onClickMapStatus(LLUICtrl* ctrl, void* user_data); 120 static void onClickMapStatus(LLUICtrl* ctrl, void* user_data);
130 static void onClickModifyStatus(LLUICtrl* ctrl, void* user_data); 121 static void onClickModifyStatus(LLUICtrl* ctrl, void* user_data);
@@ -133,9 +124,6 @@ private:
133 static void handleModifyRights(S32 option, void* user_data); 124 static void handleModifyRights(S32 option, void* user_data);
134 125
135private: 126private:
136 // static data
137 static LLFloaterFriends* sInstance;
138
139 // member data 127 // member data
140 LLFriendObserver* mObserver; 128 LLFriendObserver* mObserver;
141 LLUUID mAddFriendID; 129 LLUUID mAddFriendID;
diff --git a/linden/indra/newview/llfloatergroups.cpp b/linden/indra/newview/llfloatergroups.cpp
index 53d5147..74526e1 100644
--- a/linden/indra/newview/llfloatergroups.cpp
+++ b/linden/indra/newview/llfloatergroups.cpp
@@ -1,6 +1,6 @@
1/** 1/**
2 * @file llfloatergroups.cpp 2 * @file llfloatergroups.cpp
3 * @brief LLFloaterGroups class implementation 3 * @brief LLPanelGroups class implementation
4 * 4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc. 5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 * 6 *
@@ -50,115 +50,135 @@
50#include "lltextbox.h" 50#include "lltextbox.h"
51#include "llvieweruictrlfactory.h" 51#include "llvieweruictrlfactory.h"
52#include "llviewerwindow.h" 52#include "llviewerwindow.h"
53 53#include "llimview.h"
54const LLRect FLOATER_RECT(0, 258, 280, 0);
55const char FLOATER_TITLE[] = "Groups";
56 54
57// static 55// static
58LLMap<const LLUUID, LLFloaterGroups*> LLFloaterGroups::sInstances; 56std::map<const LLUUID, LLFloaterGroupPicker*> LLFloaterGroupPicker::sInstances;
59 57
58// helper functions
59void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id);
60 60
61///---------------------------------------------------------------------------- 61///----------------------------------------------------------------------------
62/// Class LLFloaterGroups 62/// Class LLFloaterGroupPicker
63///---------------------------------------------------------------------------- 63///----------------------------------------------------------------------------
64 64
65//LLEventListener 65// static
66//virtual 66LLFloaterGroupPicker* LLFloaterGroupPicker::findInstance(const LLSD& seed)
67bool LLFloaterGroups::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
68{ 67{
69 if (event->desc() == "new group") 68 instance_map_t::iterator found_it = sInstances.find(seed.asUUID());
69 if (found_it != sInstances.end())
70 { 70 {
71 reset(); 71 return found_it->second;
72 return true;
73 } 72 }
74 73 return NULL;
75 return LLView::handleEvent(event, userdata);
76} 74}
77 75
78// Call this with an agent id and AGENT_GROUPS for an agent's
79// groups, otherwise, call with an object id and SET_OBJECT_GROUP
80// when modifying an object.
81// static 76// static
82LLFloaterGroups* LLFloaterGroups::show(const LLUUID& id, EGroupDialog type) 77LLFloaterGroupPicker* LLFloaterGroupPicker::createInstance(const LLSD &seed)
78{
79 LLFloaterGroupPicker* pickerp = new LLFloaterGroupPicker(seed);
80 gUICtrlFactory->buildFloater(pickerp, "floater_choose_group.xml");
81 return pickerp;
82}
83
84LLFloaterGroupPicker::LLFloaterGroupPicker(const LLSD& seed) :
85 mSelectCallback(NULL),
86 mCallbackUserdata(NULL)
87{
88 mID = seed.asUUID();
89 sInstances.insert(std::make_pair(mID, this));
90}
91
92LLFloaterGroupPicker::~LLFloaterGroupPicker()
93{
94 sInstances.erase(mID);
95}
96
97void LLFloaterGroupPicker::setSelectCallback(void (*callback)(LLUUID, void*),
98 void* userdata)
83{ 99{
84 LLFloaterGroups* instance = NULL; 100 mSelectCallback = callback;
85 if(sInstances.checkData(id)) 101 mCallbackUserdata = userdata;
102}
103
104BOOL LLFloaterGroupPicker::postBuild()
105{
106 init_group_list(LLUICtrlFactory::getScrollListByName(this, "group list"), gAgent.getGroupID());
107
108 childSetAction("OK", onBtnOK, this);
109
110 childSetAction("Cancel", onBtnCancel, this);
111
112 setDefaultBtn("OK");
113
114 childSetDoubleClickCallback("group list", onBtnOK);
115 childSetUserData("group list", this);
116
117 childEnable("OK");
118
119 return TRUE;
120}
121
122void LLFloaterGroupPicker::onBtnOK(void* userdata)
123{
124 LLFloaterGroupPicker* self = (LLFloaterGroupPicker*)userdata;
125 if(self) self->ok();
126}
127
128void LLFloaterGroupPicker::onBtnCancel(void* userdata)
129{
130 LLFloaterGroupPicker* self = (LLFloaterGroupPicker*)userdata;
131 if(self) self->close();
132}
133
134
135void LLFloaterGroupPicker::ok()
136{
137 LLCtrlListInterface *group_list = childGetListInterface("group list");
138 LLUUID group_id;
139 if (group_list)
86 { 140 {
87 instance = sInstances.getData(id); 141 group_id = group_list->getCurrentID();
88 if (instance->getType() != type)
89 {
90 // not the type we want ==> destroy it and rebuild below
91 instance->destroy();
92 instance = NULL;
93 }
94 else
95 {
96 // Move the existing view to the front
97 instance->open(); /* Flawfinder: ignore */
98 }
99 } 142 }
100 143 if(mSelectCallback)
101 if (!instance)
102 { 144 {
103 S32 left = 0; 145 mSelectCallback(group_id, mCallbackUserdata);
104 S32 top = 0;
105 LLRect rect = FLOATER_RECT;
106 rect.translate( left - rect.mLeft, top - rect.mTop );
107 instance = new LLFloaterGroups("groups", rect, FLOATER_TITLE, id);
108 if(instance)
109 {
110 sInstances.addData(id, instance);
111 //instance->init(type);
112 instance->mType = type;
113 switch (type)
114 {
115 case AGENT_GROUPS:
116 gUICtrlFactory->buildFloater(instance, "floater_groups.xml");
117 break;
118 case CHOOSE_ONE:
119 gUICtrlFactory->buildFloater(instance, "floater_choose_group.xml");
120 break;
121 }
122 instance->center();
123 instance->open(); /*Flawfinder: ignore*/
124 }
125 } 146 }
126 return instance; 147
148 close();
127} 149}
128 150
129// static 151///----------------------------------------------------------------------------
130LLFloaterGroups* LLFloaterGroups::getInstance(const LLUUID& id) 152/// Class LLPanelGroups
153///----------------------------------------------------------------------------
154
155//LLEventListener
156//virtual
157bool LLPanelGroups::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
131{ 158{
132 if(sInstances.checkData(id)) 159 if (event->desc() == "new group")
133 { 160 {
134 return sInstances.getData(id); 161 reset();
162 return true;
135 } 163 }
136 return NULL; 164
165 return LLView::handleEvent(event, userdata);
137} 166}
138 167
139// Default constructor 168// Default constructor
140LLFloaterGroups::LLFloaterGroups(const std::string& name, 169LLPanelGroups::LLPanelGroups() :
141 const LLRect& rect, 170 LLPanel()
142 const std::string& title,
143 const LLUUID& id) :
144 LLFloater(name, rect, title),
145 mID(id),
146 mType(AGENT_GROUPS),
147 mOKCallback(NULL),
148 mCallbackUserdata(NULL)
149{ 171{
172 gAgent.addListener(this, "new group");
150} 173}
151 174
152// Destroys the object 175LLPanelGroups::~LLPanelGroups()
153LLFloaterGroups::~LLFloaterGroups()
154{ 176{
155 gFocusMgr.releaseFocusIfNeeded( this ); 177 gAgent.removeListener(this);
156
157 sInstances.removeData(mID);
158} 178}
159 179
160// clear the group list, and get a fresh set of info. 180// clear the group list, and get a fresh set of info.
161void LLFloaterGroups::reset() 181void LLPanelGroups::reset()
162{ 182{
163 LLCtrlListInterface *group_list = childGetListInterface("group list"); 183 LLCtrlListInterface *group_list = childGetListInterface("group list");
164 if (group_list) 184 if (group_list)
@@ -168,215 +188,126 @@ void LLFloaterGroups::reset()
168 childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count())); 188 childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
169 childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS)); 189 childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
170 190
171 initAgentGroups(gAgent.getGroupID()); 191 init_group_list(LLUICtrlFactory::getScrollListByName(this, "group list"), gAgent.getGroupID());
172 enableButtons(); 192 enableButtons();
173} 193}
174 194
175void LLFloaterGroups::setOkCallback(void (*callback)(LLUUID, void*), 195BOOL LLPanelGroups::postBuild()
176 void* userdata)
177{
178 mOKCallback = callback;
179 mCallbackUserdata = userdata;
180}
181
182BOOL LLFloaterGroups::postBuild()
183{ 196{
184 childSetCommitCallback("group list", onGroupList, this); 197 childSetCommitCallback("group list", onGroupList, this);
185 198
186 if(mType == AGENT_GROUPS) 199 childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
187 { 200 childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
188 childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
189 childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
190
191 initAgentGroups(gAgent.getGroupID());
192
193 childSetAction("Activate", onBtnActivate, this);
194 201
195 childSetAction("Info", onBtnInfo, this); 202 init_group_list(LLUICtrlFactory::getScrollListByName(this, "group list"), gAgent.getGroupID());
196 203
197 childSetAction("Leave", onBtnLeave, this); 204 childSetAction("Activate", onBtnActivate, this);
198 205
199 childSetAction("Create", onBtnCreate, this); 206 childSetAction("Info", onBtnInfo, this);
200 207
201 childSetAction("Search...", onBtnSearch, this); 208 childSetAction("IM", onBtnIM, this);
202 209
203 childSetAction("Close", onBtnCancel, this); 210 childSetAction("Leave", onBtnLeave, this);
204 211
205 setDefaultBtn("Info"); 212 childSetAction("Create", onBtnCreate, this);
206 213
207 childSetDoubleClickCallback("group list", onBtnInfo); 214 childSetAction("Search...", onBtnSearch, this);
208 childSetUserData("group list", this);
209 }
210 else
211 {
212 initAgentGroups(gAgent.getGroupID());
213
214 childSetAction("OK", onBtnOK, this);
215 215
216 childSetAction("Cancel", onBtnCancel, this); 216 setDefaultBtn("IM");
217 217
218 setDefaultBtn("OK"); 218 childSetDoubleClickCallback("group list", onBtnIM);
219 childSetUserData("group list", this);
219 220
220 childSetDoubleClickCallback("group list", onBtnOK); 221 reset();
221 childSetUserData("group list", this);
222 }
223
224 enableButtons();
225 222
226 return TRUE; 223 return TRUE;
227} 224}
228 225
229void LLFloaterGroups::initAgentGroups(const LLUUID& highlight_id) 226void LLPanelGroups::enableButtons()
230{ 227{
231 S32 count = gAgent.mGroups.count();
232 LLUUID id;
233 LLCtrlListInterface *group_list = childGetListInterface("group list"); 228 LLCtrlListInterface *group_list = childGetListInterface("group list");
234 if (!group_list) return; 229 LLUUID group_id;
235 230 if (group_list)
236 group_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
237
238 for(S32 i = 0; i < count; ++i)
239 { 231 {
240 id = gAgent.mGroups.get(i).mID; 232 group_id = group_list->getCurrentID();
241 LLGroupData* group_datap = &gAgent.mGroups.get(i);
242 LLString style = "NORMAL";
243 if(highlight_id == id)
244 {
245 style = "BOLD";
246 }
247
248 LLSD element;
249 element["id"] = id;
250 element["columns"][0]["column"] = "name";
251 element["columns"][0]["value"] = group_datap->mName;
252 element["columns"][0]["font"] = "SANSSERIF";
253 element["columns"][0]["font-style"] = style;
254
255 group_list->addElement(element, ADD_SORTED);
256 } 233 }
257 234
235 if(group_id != gAgent.getGroupID())
258 { 236 {
259 LLString style = "NORMAL"; 237 childEnable("Activate");
260 if (highlight_id.isNull())
261 {
262 style = "BOLD";
263 }
264 LLSD element;
265 element["id"] = LLUUID::null;
266 element["columns"][0]["column"] = "name";
267 element["columns"][0]["value"] = "none";
268 element["columns"][0]["font"] = "SANSSERIF";
269 element["columns"][0]["font-style"] = style;
270
271 group_list->addElement(element, ADD_TOP);
272 } 238 }
273 239 else
274 group_list->selectByValue(highlight_id);
275
276 childSetFocus("group list");
277}
278
279void LLFloaterGroups::enableButtons()
280{
281 LLCtrlListInterface *group_list = childGetListInterface("group list");
282 LLUUID group_id;
283 if (group_list)
284 { 240 {
285 group_id = group_list->getCurrentID(); 241 childDisable("Activate");
286 } 242 }
287 if(mType == AGENT_GROUPS) 243 if (group_id.notNull())
288 { 244 {
289 if(group_id != gAgent.getGroupID()) 245 childEnable("Info");
290 { 246 childEnable("IM");
291 childEnable("Activate"); 247 childEnable("Leave");
292 }
293 else
294 {
295 childDisable("Activate");
296 }
297 if (group_id.notNull())
298 {
299 childEnable("Info");
300 childEnable("Leave");
301 }
302 else
303 {
304 childDisable("Info");
305 childDisable("Leave");
306 }
307 if(gAgent.mGroups.count() < MAX_AGENT_GROUPS)
308 {
309 childEnable("Create");
310 }
311 else
312 {
313 childDisable("Create");
314 }
315 } 248 }
316 else 249 else
317 { 250 {
318 childEnable("OK"); 251 childDisable("Info");
252 childDisable("IM");
253 childDisable("Leave");
254 }
255 if(gAgent.mGroups.count() < MAX_AGENT_GROUPS)
256 {
257 childEnable("Create");
258 }
259 else
260 {
261 childDisable("Create");
319 } 262 }
320} 263}
321 264
322 265
323void LLFloaterGroups::onBtnCreate(void* userdata) 266void LLPanelGroups::onBtnCreate(void* userdata)
324{ 267{
325 LLFloaterGroups* self = (LLFloaterGroups*)userdata; 268 LLPanelGroups* self = (LLPanelGroups*)userdata;
326 if(self) self->create(); 269 if(self) self->create();
327} 270}
328 271
329void LLFloaterGroups::onBtnActivate(void* userdata) 272void LLPanelGroups::onBtnActivate(void* userdata)
330{ 273{
331 LLFloaterGroups* self = (LLFloaterGroups*)userdata; 274 LLPanelGroups* self = (LLPanelGroups*)userdata;
332 if(self) self->activate(); 275 if(self) self->activate();
333} 276}
334 277
335void LLFloaterGroups::onBtnInfo(void* userdata) 278void LLPanelGroups::onBtnInfo(void* userdata)
336{ 279{
337 LLFloaterGroups* self = (LLFloaterGroups*)userdata; 280 LLPanelGroups* self = (LLPanelGroups*)userdata;
338 if(self) self->info(); 281 if(self) self->info();
339} 282}
340 283
341void LLFloaterGroups::onBtnLeave(void* userdata) 284void LLPanelGroups::onBtnIM(void* userdata)
342{ 285{
343 LLFloaterGroups* self = (LLFloaterGroups*)userdata; 286 LLPanelGroups* self = (LLPanelGroups*)userdata;
344 if(self) self->leave(); 287 if(self) self->startIM();
345} 288}
346 289
347void LLFloaterGroups::onBtnSearch(void* userdata) 290void LLPanelGroups::onBtnLeave(void* userdata)
348{ 291{
349 LLFloaterGroups* self = (LLFloaterGroups*)userdata; 292 LLPanelGroups* self = (LLPanelGroups*)userdata;
350 if(self) self->search(); 293 if(self) self->leave();
351}
352
353void LLFloaterGroups::onBtnOK(void* userdata)
354{
355 LLFloaterGroups* self = (LLFloaterGroups*)userdata;
356 if(self) self->ok();
357}
358
359void LLFloaterGroups::onBtnCancel(void* userdata)
360{
361 LLFloaterGroups* self = (LLFloaterGroups*)userdata;
362 if(self) self->close();
363} 294}
364 295
365void LLFloaterGroups::onGroupList(LLUICtrl* ctrl, void* userdata) 296void LLPanelGroups::onBtnSearch(void* userdata)
366{ 297{
367 LLFloaterGroups* self = (LLFloaterGroups*)userdata; 298 LLPanelGroups* self = (LLPanelGroups*)userdata;
368 if(self) self->highlightGroupList(ctrl); 299 if(self) self->search();
369} 300}
370 301
371void LLFloaterGroups::create() 302void LLPanelGroups::create()
372{ 303{
373 llinfos << "LLFloaterGroups::create" << llendl; 304 llinfos << "LLPanelGroups::create" << llendl;
374 LLFloaterGroupInfo::showCreateGroup(NULL); 305 LLFloaterGroupInfo::showCreateGroup(NULL);
375} 306}
376 307
377void LLFloaterGroups::activate() 308void LLPanelGroups::activate()
378{ 309{
379 llinfos << "LLFloaterGroups::activate" << llendl; 310 llinfos << "LLPanelGroups::activate" << llendl;
380 LLCtrlListInterface *group_list = childGetListInterface("group list"); 311 LLCtrlListInterface *group_list = childGetListInterface("group list");
381 LLUUID group_id; 312 LLUUID group_id;
382 if (group_list) 313 if (group_list)
@@ -392,9 +323,9 @@ void LLFloaterGroups::activate()
392 gAgent.sendReliableMessage(); 323 gAgent.sendReliableMessage();
393} 324}
394 325
395void LLFloaterGroups::info() 326void LLPanelGroups::info()
396{ 327{
397 llinfos << "LLFloaterGroups::info" << llendl; 328 llinfos << "LLPanelGroups::info" << llendl;
398 LLCtrlListInterface *group_list = childGetListInterface("group list"); 329 LLCtrlListInterface *group_list = childGetListInterface("group list");
399 LLUUID group_id; 330 LLUUID group_id;
400 if (group_list && (group_id = group_list->getCurrentID()).notNull()) 331 if (group_list && (group_id = group_list->getCurrentID()).notNull())
@@ -403,9 +334,36 @@ void LLFloaterGroups::info()
403 } 334 }
404} 335}
405 336
406void LLFloaterGroups::leave() 337void LLPanelGroups::startIM()
338{
339 //llinfos << "LLPanelFriends::onClickIM()" << llendl;
340 LLCtrlListInterface *group_list = childGetListInterface("group list");
341 LLUUID group_id;
342
343 if (group_list && (group_id = group_list->getCurrentID()).notNull())
344 {
345 LLGroupData group_data;
346 if (gAgent.getGroupData(group_id, group_data))
347 {
348 gIMMgr->setFloaterOpen(TRUE);
349 gIMMgr->addSession(
350 group_data.mName,
351 IM_SESSION_GROUP_START,
352 group_id);
353 make_ui_sound("UISndStartIM");
354 }
355 else
356 {
357 // this should never happen, as starting a group IM session
358 // relies on you belonging to the group and hence having the group data
359 make_ui_sound("UISndInvalidOp");
360 }
361 }
362}
363
364void LLPanelGroups::leave()
407{ 365{
408 llinfos << "LLFloaterGroups::leave" << llendl; 366 llinfos << "LLPanelGroups::leave" << llendl;
409 LLCtrlListInterface *group_list = childGetListInterface("group list"); 367 LLCtrlListInterface *group_list = childGetListInterface("group list");
410 LLUUID group_id; 368 LLUUID group_id;
411 if (group_list && (group_id = group_list->getCurrentID()).notNull()) 369 if (group_list && (group_id = group_list->getCurrentID()).notNull())
@@ -427,13 +385,13 @@ void LLFloaterGroups::leave()
427 } 385 }
428} 386}
429 387
430void LLFloaterGroups::search() 388void LLPanelGroups::search()
431{ 389{
432 LLFloaterDirectory::showGroups(); 390 LLFloaterDirectory::showGroups();
433} 391}
434 392
435// static 393// static
436void LLFloaterGroups::callbackLeaveGroup(S32 option, void* userdata) 394void LLPanelGroups::callbackLeaveGroup(S32 option, void* userdata)
437{ 395{
438 LLUUID* group_id = (LLUUID*)userdata; 396 LLUUID* group_id = (LLUUID*)userdata;
439 if(option == 0 && group_id) 397 if(option == 0 && group_id)
@@ -450,25 +408,58 @@ void LLFloaterGroups::callbackLeaveGroup(S32 option, void* userdata)
450 delete group_id; 408 delete group_id;
451} 409}
452 410
453void LLFloaterGroups::ok() 411void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata)
454{ 412{
455 llinfos << "LLFloaterGroups::ok" << llendl; 413 LLPanelGroups* self = (LLPanelGroups*)userdata;
456 LLCtrlListInterface *group_list = childGetListInterface("group list"); 414 if(self) self->enableButtons();
457 LLUUID group_id; 415}
458 if (group_list) 416
417void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id)
418{
419 S32 count = gAgent.mGroups.count();
420 LLUUID id;
421 LLCtrlListInterface *group_list = ctrl->getListInterface();
422 if (!group_list) return;
423
424 group_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
425
426 for(S32 i = 0; i < count; ++i)
459 { 427 {
460 group_id = group_list->getCurrentID(); 428 id = gAgent.mGroups.get(i).mID;
429 LLGroupData* group_datap = &gAgent.mGroups.get(i);
430 LLString style = "NORMAL";
431 if(highlight_id == id)
432 {
433 style = "BOLD";
434 }
435
436 LLSD element;
437 element["id"] = id;
438 element["columns"][0]["column"] = "name";
439 element["columns"][0]["value"] = group_datap->mName;
440 element["columns"][0]["font"] = "SANSSERIF";
441 element["columns"][0]["font-style"] = style;
442
443 group_list->addElement(element, ADD_SORTED);
461 } 444 }
462 if(mOKCallback) 445
446 // add "none" to list at top
463 { 447 {
464 mOKCallback(group_id, mCallbackUserdata); 448 LLString style = "NORMAL";
449 if (highlight_id.isNull())
450 {
451 style = "BOLD";
452 }
453 LLSD element;
454 element["id"] = LLUUID::null;
455 element["columns"][0]["column"] = "name";
456 element["columns"][0]["value"] = "none";
457 element["columns"][0]["font"] = "SANSSERIF";
458 element["columns"][0]["font-style"] = style;
459
460 group_list->addElement(element, ADD_TOP);
465 } 461 }
466 462
467 close(); 463 group_list->selectByValue(highlight_id);
468} 464}
469 465
470void LLFloaterGroups::highlightGroupList(LLUICtrl*)
471{
472 llinfos << "LLFloaterGroups::highlightGroupList" << llendl;
473 enableButtons();
474}
diff --git a/linden/indra/newview/llfloatergroups.h b/linden/indra/newview/llfloatergroups.h
index 9c51d2f..ed5b8b2 100644
--- a/linden/indra/newview/llfloatergroups.h
+++ b/linden/indra/newview/llfloatergroups.h
@@ -41,89 +41,80 @@
41//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 41//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42 42
43#include "lluuid.h" 43#include "lluuid.h"
44#include "llmap.h"
45#include "llevent.h"
46#include "llfloater.h" 44#include "llfloater.h"
45#include <map>
47 46
48class LLUICtrl; 47class LLUICtrl;
49class LLTextBox; 48class LLTextBox;
50class LLScrollListCtrl; 49class LLScrollListCtrl;
51class LLButton; 50class LLButton;
51class LLFloaterGroupPicker;
52 52
53class LLFloaterGroups : public LLFloater 53class LLFloaterGroupPicker : public LLFloater, public LLUIInstanceMgr<LLFloaterGroupPicker>
54{ 54{
55 friend class LLUIInstanceMgr<LLFloaterGroupPicker>;
55public: 56public:
57 ~LLFloaterGroupPicker();
58 void setSelectCallback( void (*callback)(LLUUID, void*),
59 void* userdata);
60 BOOL postBuild();
61
62protected:
63 LLFloaterGroupPicker(const LLSD& seed);
64 void ok();
65 static LLFloaterGroupPicker* findInstance(const LLSD& seed);
66 static LLFloaterGroupPicker* createInstance(const LLSD& seed);
67 static void onBtnOK(void* userdata);
68 static void onBtnCancel(void* userdata);
69
70protected:
71 LLUUID mID;
72 void (*mSelectCallback)(LLUUID id, void* userdata);
73 void* mCallbackUserdata;
74
75 typedef std::map<const LLUUID, LLFloaterGroupPicker*> instance_map_t;
76 static instance_map_t sInstances;
77};
78
79class LLPanelGroups : public LLPanel
80{
81public:
82 LLPanelGroups();
83 virtual ~LLPanelGroups();
84
56 //LLEventListener 85 //LLEventListener
57 /*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); 86 /*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
58 87
59 enum EGroupDialog
60 {
61 AGENT_GROUPS,
62 CHOOSE_ONE
63 };
64 // Call this with an agent id and AGENT_GROUPS for an agent's
65 // groups, otherwise, call with an object id and SET_OBJECT_GROUP
66 // when modifying an object.
67 static LLFloaterGroups* show(const LLUUID& id, EGroupDialog type);
68
69 // Return the instance requested if it already exists. Otherwise,
70 // return NULL.
71 static LLFloaterGroups* getInstance(const LLUUID& id);
72
73 // clear the group list, and get a fresh set of info. 88 // clear the group list, and get a fresh set of info.
74 void reset(); 89 void reset();
75 90
76 void setOkCallback( void (*callback)(LLUUID, void*),
77 void* userdata);
78
79 EGroupDialog getType() const { return mType; }
80
81protected: 91protected:
82 // initialize based on the type 92 // initialize based on the type
83 BOOL postBuild(); 93 BOOL postBuild();
84 94
85 // highlight_id is a group id to highlight 95 // highlight_id is a group id to highlight
86 void initAgentGroups(const LLUUID& highlight_id);
87 void enableButtons(); 96 void enableButtons();
88 97
98 static void onGroupList(LLUICtrl* ctrl, void* userdata);
89 static void onBtnCreate(void* userdata); 99 static void onBtnCreate(void* userdata);
90 static void onBtnActivate(void* userdata); 100 static void onBtnActivate(void* userdata);
91 static void onBtnInfo(void* userdata); 101 static void onBtnInfo(void* userdata);
102 static void onBtnIM(void* userdata);
92 static void onBtnLeave(void* userdata); 103 static void onBtnLeave(void* userdata);
93 static void onBtnSearch(void* userdata); 104 static void onBtnSearch(void* userdata);
94 static void onBtnVote(void* userdata); 105 static void onBtnVote(void* userdata);
95 static void onBtnOK(void* userdata);
96 static void onBtnCancel(void* userdata);
97 static void onGroupList(LLUICtrl* ctrl, void* userdata);
98 static void onDoubleClickGroup(void* userdata); 106 static void onDoubleClickGroup(void* userdata);
99 107
100 void create(); 108 void create();
101 void activate(); 109 void activate();
102 void info(); 110 void info();
111 void startIM();
103 void leave(); 112 void leave();
104 void search(); 113 void search();
105 void callVote(); 114 void callVote();
106 void ok();
107 void highlightGroupList(LLUICtrl*);
108 115
109 static void callbackLeaveGroup(S32 option, void* userdata); 116 static void callbackLeaveGroup(S32 option, void* userdata);
110 117
111protected:
112 LLUUID mID;
113
114 EGroupDialog mType;
115
116 void (*mOKCallback)(LLUUID id, void* userdata);
117 void* mCallbackUserdata;
118
119protected:
120 static LLMap<const LLUUID, LLFloaterGroups*> sInstances;
121
122public:
123 // do not call these directly
124 LLFloaterGroups(const std::string& name, const LLRect& rect, const std::string& title,
125 const LLUUID& id);
126 virtual ~LLFloaterGroups();
127}; 118};
128 119
129 120
diff --git a/linden/indra/newview/llfloaterhtmlhelp.cpp b/linden/indra/newview/llfloaterhtmlhelp.cpp
index 9cae4cc..1d6f19e 100644
--- a/linden/indra/newview/llfloaterhtmlhelp.cpp
+++ b/linden/indra/newview/llfloaterhtmlhelp.cpp
@@ -204,7 +204,7 @@ void LLFloaterHtmlHelp::onClickF1HelpLoadURL(S32 option, void* userdata)
204 204
205 // this sucks but there isn't a way to grab an arbitrary string from an XML file 205 // this sucks but there isn't a way to grab an arbitrary string from an XML file
206 // (using llcontroldef strings causes problems if string don't exist) 206 // (using llcontroldef strings causes problems if string don't exist)
207 LLString help_url( "https://support.secondlife.com/" ); 207 LLString help_url( "http://secondlife.com/support" );
208 if ( lang == "ja" ) 208 if ( lang == "ja" )
209 help_url = "http://help.secondlife.com/jp"; 209 help_url = "http://help.secondlife.com/jp";
210 else 210 else
diff --git a/linden/indra/newview/llfloaterimport.cpp b/linden/indra/newview/llfloaterimport.cpp
index c60c571..f30f69d 100644
--- a/linden/indra/newview/llfloaterimport.cpp
+++ b/linden/indra/newview/llfloaterimport.cpp
@@ -56,6 +56,7 @@
56#include "pipeline.h" 56#include "pipeline.h"
57#include "viewer.h" 57#include "viewer.h"
58#include "llvieweruictrlfactory.h" 58#include "llvieweruictrlfactory.h"
59#include "llmd5.h"
59 60
60extern LLInventoryModel gInventory; 61extern LLInventoryModel gInventory;
61 62
@@ -588,7 +589,7 @@ void LLFloaterImport::onBtnOK(void*userdata)
588 finishImport(asset_info); 589 finishImport(asset_info);
589 } 590 }
590 591
591 fp->onClose(false); 592 fp->close(false);
592} 593}
593 594
594//----------------------------------------------------------------------------- 595//-----------------------------------------------------------------------------
@@ -597,7 +598,7 @@ void LLFloaterImport::onBtnOK(void*userdata)
597void LLFloaterImport::onBtnCancel(void*userdata) 598void LLFloaterImport::onBtnCancel(void*userdata)
598{ 599{
599 LLFloaterImport *fp =(LLFloaterImport*)userdata; 600 LLFloaterImport *fp =(LLFloaterImport*)userdata;
600 fp->onClose(false); 601 fp->close(false);
601} 602}
602 603
603 604
diff --git a/linden/indra/newview/llfloaterinspect.cpp b/linden/indra/newview/llfloaterinspect.cpp
index 85cfc4e..c926afa 100644
--- a/linden/indra/newview/llfloaterinspect.cpp
+++ b/linden/indra/newview/llfloaterinspect.cpp
@@ -74,18 +74,21 @@ BOOL LLFloaterInspect::isVisible()
74 74
75void LLFloaterInspect::show(void* ignored) 75void LLFloaterInspect::show(void* ignored)
76{ 76{
77 if(sInstance) 77 // setForceSelection ensures that the pie menu does not deselect things when it
78 { 78 // looses the focus (this can happen with "select own objects only" enabled
79 sInstance->open(); 79 // VWR-1471
80 } 80 BOOL forcesel = gSelectMgr->setForceSelection(TRUE);
81 else 81
82 if (!sInstance) // first use
82 { 83 {
83 LLFloaterInspect* self = new LLFloaterInspect; 84 sInstance = new LLFloaterInspect;
84 self->open();
85 } 85 }
86 86
87 sInstance->mObjectSelection = gSelectMgr->getSelection(); 87 sInstance->open();
88 select_tool(gToolInspect); 88 select_tool(gToolInspect);
89 gSelectMgr->setForceSelection(forcesel); // restore previouis value
90
91 sInstance->mObjectSelection = gSelectMgr->getSelection();
89 sInstance->refresh(); 92 sInstance->refresh();
90} 93}
91 94
diff --git a/linden/indra/newview/llfloaterland.cpp b/linden/indra/newview/llfloaterland.cpp
index 78e5e70..a98c835 100644
--- a/linden/indra/newview/llfloaterland.cpp
+++ b/linden/indra/newview/llfloaterland.cpp
@@ -42,6 +42,7 @@
42#include "llfloateravatarpicker.h" 42#include "llfloateravatarpicker.h"
43#include "llbutton.h" 43#include "llbutton.h"
44#include "llcheckboxctrl.h" 44#include "llcheckboxctrl.h"
45#include "llradiogroup.h"
45#include "llcombobox.h" 46#include "llcombobox.h"
46#include "llfloaterauction.h" 47#include "llfloaterauction.h"
47#include "llfloateravatarinfo.h" 48#include "llfloateravatarinfo.h"
@@ -110,6 +111,14 @@ static const char RAW_HTML[] = "Raw HTML";
110static const BOOL BUY_GROUP_LAND = TRUE; 111static const BOOL BUY_GROUP_LAND = TRUE;
111static const BOOL BUY_PERSONAL_LAND = FALSE; 112static const BOOL BUY_PERSONAL_LAND = FALSE;
112 113
114// Values for the parcel voice settings radio group
115enum
116{
117 kRadioVoiceChatEstate = 0,
118 kRadioVoiceChatPrivate = 1,
119 kRadioVoiceChatDisable = 2
120};
121
113// Statics 122// Statics
114LLFloaterLand* LLFloaterLand::sInstance = NULL; 123LLFloaterLand* LLFloaterLand::sInstance = NULL;
115LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL; 124LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL;
@@ -828,9 +837,20 @@ void LLPanelLandGeneral::draw()
828// static 837// static
829void LLPanelLandGeneral::onClickSetGroup(void* userdata) 838void LLPanelLandGeneral::onClickSetGroup(void* userdata)
830{ 839{
831 LLFloaterGroups* fg; 840 LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)userdata;
832 fg = LLFloaterGroups::show(gAgent.getID(), LLFloaterGroups::CHOOSE_ONE); 841 LLFloaterGroupPicker* fg;
833 fg->setOkCallback( cbGroupID, userdata ); 842
843 LLFloater* parent_floater = gFloaterView->getParentFloater(panelp);
844
845 fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
846 fg->setSelectCallback( cbGroupID, userdata );
847
848 if (parent_floater)
849 {
850 LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
851 fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
852 parent_floater->addDependentFloater(fg);
853 }
834} 854}
835 855
836// static 856// static
@@ -2339,6 +2359,9 @@ BOOL LLPanelLandMedia::postBuild()
2339 mCheckSoundLocal = LLUICtrlFactory::getCheckBoxByName(this, "check sound local"); 2359 mCheckSoundLocal = LLUICtrlFactory::getCheckBoxByName(this, "check sound local");
2340 childSetCommitCallback("check sound local", onCommitAny, this); 2360 childSetCommitCallback("check sound local", onCommitAny, this);
2341 2361
2362 mRadioVoiceChat = LLUICtrlFactory::getRadioGroupByName(this, "parcel_voice_channel");
2363 childSetCommitCallback("parcel_voice_channel", onCommitAny, this);
2364
2342 mMusicURLEdit = LLUICtrlFactory::getLineEditorByName(this, "music_url"); 2365 mMusicURLEdit = LLUICtrlFactory::getLineEditorByName(this, "music_url");
2343 childSetCommitCallback("music_url", onCommitAny, this); 2366 childSetCommitCallback("music_url", onCommitAny, this);
2344 2367
@@ -2382,6 +2405,9 @@ void LLPanelLandMedia::refresh()
2382 mCheckSoundLocal->set(FALSE); 2405 mCheckSoundLocal->set(FALSE);
2383 mCheckSoundLocal->setEnabled(FALSE); 2406 mCheckSoundLocal->setEnabled(FALSE);
2384 2407
2408 mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate);
2409 mRadioVoiceChat->setEnabled(FALSE);
2410
2385 mMusicURLEdit->setText(""); 2411 mMusicURLEdit->setText("");
2386 mMusicURLEdit->setEnabled(FALSE); 2412 mMusicURLEdit->setEnabled(FALSE);
2387 2413
@@ -2409,6 +2435,20 @@ void LLPanelLandMedia::refresh()
2409 mCheckSoundLocal->set( parcel->getSoundLocal() ); 2435 mCheckSoundLocal->set( parcel->getSoundLocal() );
2410 mCheckSoundLocal->setEnabled( can_change_media ); 2436 mCheckSoundLocal->setEnabled( can_change_media );
2411 2437
2438 if(parcel->getVoiceEnabled())
2439 {
2440 if(parcel->getVoiceUseEstateChannel())
2441 mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate);
2442 else
2443 mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate);
2444 }
2445 else
2446 {
2447 mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable);
2448 }
2449
2450 mRadioVoiceChat->setEnabled( can_change_media );
2451
2412 // don't display urls if you're not able to change it 2452 // don't display urls if you're not able to change it
2413 // much requested change in forums so people can't 'steal' urls 2453 // much requested change in forums so people can't 'steal' urls
2414 // NOTE: bug#2009 means this is still vunerable - however, bug 2454 // NOTE: bug#2009 means this is still vunerable - however, bug
@@ -2468,12 +2508,39 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl *ctrl, void *userdata)
2468 2508
2469 // Extract data from UI 2509 // Extract data from UI
2470 BOOL sound_local = self->mCheckSoundLocal->get(); 2510 BOOL sound_local = self->mCheckSoundLocal->get();
2511 int voice_setting = self->mRadioVoiceChat->getSelectedIndex();
2471 std::string music_url = self->mMusicURLEdit->getText(); 2512 std::string music_url = self->mMusicURLEdit->getText();
2472 std::string media_url = self->mMediaURLEdit->getText(); 2513 std::string media_url = self->mMediaURLEdit->getText();
2473 U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); 2514 U8 media_auto_scale = self->mMediaAutoScaleCheck->get();
2474 LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); 2515 LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID();
2475 2516
2517 BOOL voice_enabled;
2518 BOOL voice_estate_chan;
2519
2520 switch(voice_setting)
2521 {
2522 default:
2523 case kRadioVoiceChatEstate:
2524 voice_enabled = TRUE;
2525 voice_estate_chan = TRUE;
2526 break;
2527 case kRadioVoiceChatPrivate:
2528 voice_enabled = TRUE;
2529 voice_estate_chan = FALSE;
2530 break;
2531 case kRadioVoiceChatDisable:
2532 voice_enabled = FALSE;
2533 voice_estate_chan = FALSE;
2534 break;
2535 }
2536
2537 // Remove leading/trailing whitespace (common when copying/pasting)
2538 LLString::trim(music_url);
2539 LLString::trim(media_url);
2540
2476 // Push data into current parcel 2541 // Push data into current parcel
2542 parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled);
2543 parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan);
2477 parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); 2544 parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local);
2478 parcel->setMusicURL(music_url.c_str()); 2545 parcel->setMusicURL(music_url.c_str());
2479 parcel->setMediaURL(media_url.c_str()); 2546 parcel->setMediaURL(media_url.c_str());
diff --git a/linden/indra/newview/llfloaterland.h b/linden/indra/newview/llfloaterland.h
index 3cc0b27..6e54d12 100644
--- a/linden/indra/newview/llfloaterland.h
+++ b/linden/indra/newview/llfloaterland.h
@@ -41,6 +41,7 @@ const F32 CACHE_REFRESH_TIME = 2.5f;
41 41
42class LLTextBox; 42class LLTextBox;
43class LLCheckBoxCtrl; 43class LLCheckBoxCtrl;
44class LLRadioGroup;
44class LLComboBox; 45class LLComboBox;
45class LLButton; 46class LLButton;
46class LLNameListCtrl; 47class LLNameListCtrl;
@@ -368,6 +369,7 @@ public:
368 369
369protected: 370protected:
370 LLCheckBoxCtrl* mCheckSoundLocal; 371 LLCheckBoxCtrl* mCheckSoundLocal;
372 LLRadioGroup* mRadioVoiceChat;
371 LLLineEditor* mMusicURLEdit; 373 LLLineEditor* mMusicURLEdit;
372 LLLineEditor* mMediaURLEdit; 374 LLLineEditor* mMediaURLEdit;
373 LLTextureCtrl* mMediaTextureCtrl; 375 LLTextureCtrl* mMediaTextureCtrl;
diff --git a/linden/indra/newview/llfloatermute.cpp b/linden/indra/newview/llfloatermute.cpp
index 696f9fe..0f11042 100644
--- a/linden/indra/newview/llfloatermute.cpp
+++ b/linden/indra/newview/llfloatermute.cpp
@@ -89,6 +89,7 @@ LLFloaterMute::LLFloaterMute()
89 childSetAction("Unmute", onClickRemove, this); 89 childSetAction("Unmute", onClickRemove, this);
90 90
91 mMuteList = LLUICtrlFactory::getScrollListByName(this, "mutes"); 91 mMuteList = LLUICtrlFactory::getScrollListByName(this, "mutes");
92 mMuteList->setCommitOnSelectionChange(TRUE);
92 93
93 refreshMuteList(); 94 refreshMuteList();
94} 95}
diff --git a/linden/indra/newview/llfloaternamedesc.cpp b/linden/indra/newview/llfloaternamedesc.cpp
index 5f41b13..3f90752 100644
--- a/linden/indra/newview/llfloaternamedesc.cpp
+++ b/linden/indra/newview/llfloaternamedesc.cpp
@@ -213,7 +213,7 @@ void LLFloaterNameDesc::onBtnOK( void* userdata )
213 fp->childGetValue("name_form").asString(), 213 fp->childGetValue("name_form").asString(),
214 fp->childGetValue("description_form").asString(), 214 fp->childGetValue("description_form").asString(),
215 bitrate, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); 215 bitrate, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
216 fp->onClose(false); 216 fp->close(false);
217} 217}
218 218
219// static 219// static
@@ -223,5 +223,5 @@ void LLFloaterNameDesc::onBtnOK( void* userdata )
223void LLFloaterNameDesc::onBtnCancel( void* userdata ) 223void LLFloaterNameDesc::onBtnCancel( void* userdata )
224{ 224{
225 LLFloaterNameDesc *fp =(LLFloaterNameDesc *)userdata; 225 LLFloaterNameDesc *fp =(LLFloaterNameDesc *)userdata;
226 fp->onClose(false); 226 fp->close(false);
227} 227}
diff --git a/linden/indra/newview/llfloaternewim.cpp b/linden/indra/newview/llfloaternewim.cpp
index 1adb37c..844259f 100644
--- a/linden/indra/newview/llfloaternewim.cpp
+++ b/linden/indra/newview/llfloaternewim.cpp
@@ -208,8 +208,8 @@ void LLFloaterNewIM::onStart(void* userdata)
208 EInstantMessage type; 208 EInstantMessage type;
209 EInstantMessage* t = (EInstantMessage*)item->getUserdata(); 209 EInstantMessage* t = (EInstantMessage*)item->getUserdata();
210 if(t) type = (*t); 210 if(t) type = (*t);
211 else type = LLIMView::defaultIMTypeForAgent(item->getUUID()); 211 else type = LLIMMgr::defaultIMTypeForAgent(item->getUUID());
212 gIMView->addSession(name, type, item->getUUID()); 212 gIMMgr->addSession(name, type, item->getUUID());
213 213
214 make_ui_sound("UISndStartIM"); 214 make_ui_sound("UISndStartIM");
215 } 215 }
@@ -223,7 +223,7 @@ void LLFloaterNewIM::onStart(void* userdata)
223// static 223// static
224void LLFloaterNewIM::onClickClose(void *userdata) 224void LLFloaterNewIM::onClickClose(void *userdata)
225{ 225{
226 gIMView->setFloaterOpen(FALSE); 226 gIMMgr->setFloaterOpen(FALSE);
227} 227}
228 228
229 229
@@ -236,7 +236,7 @@ BOOL LLFloaterNewIM::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
236 { 236 {
237 handled = TRUE; 237 handled = TRUE;
238 // Close talk panel on escape 238 // Close talk panel on escape
239 gIMView->toggle(NULL); 239 gIMMgr->toggle(NULL);
240 } 240 }
241 } 241 }
242 242
diff --git a/linden/indra/newview/llfloaterpostcard.cpp b/linden/indra/newview/llfloaterpostcard.cpp
index 82bab03..24344bf 100644
--- a/linden/indra/newview/llfloaterpostcard.cpp
+++ b/linden/indra/newview/llfloaterpostcard.cpp
@@ -223,7 +223,7 @@ void LLFloaterPostcard::onClickCancel(void* data)
223 { 223 {
224 LLFloaterPostcard *self = (LLFloaterPostcard *)data; 224 LLFloaterPostcard *self = (LLFloaterPostcard *)data;
225 225
226 self->onClose(false); 226 self->close(false);
227 } 227 }
228} 228}
229 229
diff --git a/linden/indra/newview/llfloaterpreference.cpp b/linden/indra/newview/llfloaterpreference.cpp
index f7392c4..0b3e856 100644
--- a/linden/indra/newview/llfloaterpreference.cpp
+++ b/linden/indra/newview/llfloaterpreference.cpp
@@ -54,6 +54,7 @@
54#include "llpanelmsgs.h" 54#include "llpanelmsgs.h"
55#include "llpanelweb.h" 55#include "llpanelweb.h"
56#include "llprefschat.h" 56#include "llprefschat.h"
57#include "llprefsvoice.h"
57#include "llprefsim.h" 58#include "llprefsim.h"
58#include "llresizehandle.h" 59#include "llresizehandle.h"
59#include "llresmgr.h" 60#include "llresmgr.h"
@@ -144,6 +145,10 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton
144 mTabContainer->addTabPanel(mPrefsChat->getPanel(), mPrefsChat->getPanel()->getLabel(), FALSE, onTabChanged, mTabContainer); 145 mTabContainer->addTabPanel(mPrefsChat->getPanel(), mPrefsChat->getPanel()->getLabel(), FALSE, onTabChanged, mTabContainer);
145 mPrefsChat->getPanel()->setDefaultBtn(default_btn); 146 mPrefsChat->getPanel()->setDefaultBtn(default_btn);
146 147
148 mPrefsVoice = new LLPrefsVoice();
149 mTabContainer->addTabPanel(mPrefsVoice, mPrefsVoice->getLabel(), FALSE, onTabChanged, mTabContainer);
150 mPrefsVoice->setDefaultBtn(default_btn);
151
147 mPrefsIM = new LLPrefsIM(); 152 mPrefsIM = new LLPrefsIM();
148 mTabContainer->addTabPanel(mPrefsIM->getPanel(), mPrefsIM->getPanel()->getLabel(), FALSE, onTabChanged, mTabContainer); 153 mTabContainer->addTabPanel(mPrefsIM->getPanel(), mPrefsIM->getPanel()->getLabel(), FALSE, onTabChanged, mTabContainer);
149 mPrefsIM->getPanel()->setDefaultBtn(default_btn); 154 mPrefsIM->getPanel()->setDefaultBtn(default_btn);
@@ -225,8 +230,8 @@ void LLPreferenceCore::apply()
225 mDisplayPanel->apply(); 230 mDisplayPanel->apply();
226 mDisplayPanel2->apply(); 231 mDisplayPanel2->apply();
227 mDisplayPanel3->apply(); 232 mDisplayPanel3->apply();
228 mAudioPanel->apply();
229 mPrefsChat->apply(); 233 mPrefsChat->apply();
234 mPrefsVoice->apply();
230 mPrefsIM->apply(); 235 mPrefsIM->apply();
231 mMsgPanel->apply(); 236 mMsgPanel->apply();
232 #if LL_LIBXUL_ENABLED 237 #if LL_LIBXUL_ENABLED
@@ -245,6 +250,7 @@ void LLPreferenceCore::cancel()
245 mDisplayPanel3->cancel(); 250 mDisplayPanel3->cancel();
246 mAudioPanel->cancel(); 251 mAudioPanel->cancel();
247 mPrefsChat->cancel(); 252 mPrefsChat->cancel();
253 mPrefsVoice->cancel();
248 mPrefsIM->cancel(); 254 mPrefsIM->cancel();
249 mMsgPanel->cancel(); 255 mMsgPanel->cancel();
250 #if LL_LIBXUL_ENABLED 256 #if LL_LIBXUL_ENABLED
@@ -388,7 +394,7 @@ void LLFloaterPreference::onBtnOK( void* userdata )
388 if (fp->canClose()) 394 if (fp->canClose())
389 { 395 {
390 fp->apply(); 396 fp->apply();
391 fp->onClose(false); 397 fp->close(false);
392 398
393 gSavedSettings.saveToFile( gSettingsFileName, TRUE ); 399 gSavedSettings.saveToFile( gSettingsFileName, TRUE );
394 400
diff --git a/linden/indra/newview/llfloaterpreference.h b/linden/indra/newview/llfloaterpreference.h
index 1823069..df22c1e 100644
--- a/linden/indra/newview/llfloaterpreference.h
+++ b/linden/indra/newview/llfloaterpreference.h
@@ -49,6 +49,7 @@ class LLPanelNetwork;
49class LLPanelWeb; 49class LLPanelWeb;
50class LLMessageSystem; 50class LLMessageSystem;
51class LLPrefsChat; 51class LLPrefsChat;
52class LLPrefsVoice;
52class LLPrefsIM; 53class LLPrefsIM;
53class LLPanelMsgs; 54class LLPanelMsgs;
54class LLScrollListCtrl; 55class LLScrollListCtrl;
@@ -83,6 +84,7 @@ private:
83 LLPanelAudioPrefs *mAudioPanel; 84 LLPanelAudioPrefs *mAudioPanel;
84// LLPanelDebug *mDebugPanel; 85// LLPanelDebug *mDebugPanel;
85 LLPrefsChat *mPrefsChat; 86 LLPrefsChat *mPrefsChat;
87 LLPrefsVoice *mPrefsVoice;
86 LLPrefsIM *mPrefsIM; 88 LLPrefsIM *mPrefsIM;
87 LLPanelMsgs *mMsgPanel; 89 LLPanelMsgs *mMsgPanel;
88 LLPanelWeb *mWebPanel; 90 LLPanelWeb *mWebPanel;
diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp
index 70e975e..571bcac 100644
--- a/linden/indra/newview/llfloaterregioninfo.cpp
+++ b/linden/indra/newview/llfloaterregioninfo.cpp
@@ -1430,11 +1430,21 @@ void LLPanelEstateInfo::addAllowedGroup(S32 option, void* user_data)
1430{ 1430{
1431 if (option != 0) return; 1431 if (option != 0) return;
1432 1432
1433 LLFloaterGroups* widget; 1433 LLPanelEstateInfo* panelp = (LLPanelEstateInfo*)user_data;
1434 widget = LLFloaterGroups::show(gAgent.getID(), LLFloaterGroups::CHOOSE_ONE); 1434
1435 LLFloater* parent_floater = gFloaterView->getParentFloater(panelp);
1436
1437 LLFloaterGroupPicker* widget;
1438 widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
1435 if (widget) 1439 if (widget)
1436 { 1440 {
1437 widget->setOkCallback(addAllowedGroup2, user_data); 1441 widget->setSelectCallback(addAllowedGroup2, user_data);
1442 if (parent_floater)
1443 {
1444 LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget);
1445 widget->setOrigin(new_rect.mLeft, new_rect.mBottom);
1446 parent_floater->addDependentFloater(widget);
1447 }
1438 } 1448 }
1439} 1449}
1440 1450
@@ -1930,6 +1940,7 @@ BOOL LLPanelEstateInfo::postBuild()
1930 initCtrl("deny_anonymous"); 1940 initCtrl("deny_anonymous");
1931 initCtrl("deny_identified"); 1941 initCtrl("deny_identified");
1932 initCtrl("deny_transacted"); 1942 initCtrl("deny_transacted");
1943 initCtrl("voice_chat_check");
1933 1944
1934 initHelpBtn("estate_manager_help", "HelpEstateEstateManager"); 1945 initHelpBtn("estate_manager_help", "HelpEstateEstateManager");
1935 initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime"); 1946 initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime");
@@ -1939,6 +1950,7 @@ BOOL LLPanelEstateInfo::postBuild()
1939 initHelpBtn("allow_resident_help", "HelpEstateAllowResident"); 1950 initHelpBtn("allow_resident_help", "HelpEstateAllowResident");
1940 initHelpBtn("allow_group_help", "HelpEstateAllowGroup"); 1951 initHelpBtn("allow_group_help", "HelpEstateAllowGroup");
1941 initHelpBtn("ban_resident_help", "HelpEstateBanResident"); 1952 initHelpBtn("ban_resident_help", "HelpEstateBanResident");
1953 initHelpBtn("voice_chat_help", "HelpEstateVoiceChat");
1942 1954
1943 // set up the use global time checkbox 1955 // set up the use global time checkbox
1944 childSetCommitCallback("use_global_time_check", onChangeUseGlobalTime, this); 1956 childSetCommitCallback("use_global_time_check", onChangeUseGlobalTime, this);
@@ -2104,6 +2116,9 @@ void LLPanelEstateInfo::setEstateFlags(U32 flags)
2104{ 2116{
2105 childSetValue("externally_visible_check", LLSD(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE) ); 2117 childSetValue("externally_visible_check", LLSD(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE) );
2106 childSetValue("fixed_sun_check", LLSD(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE) ); 2118 childSetValue("fixed_sun_check", LLSD(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE) );
2119 childSetValue(
2120 "voice_chat_check",
2121 LLSD(flags & REGION_FLAGS_ALLOW_VOICE ? TRUE : FALSE));
2107 childSetValue("allow_direct_teleport", LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) ); 2122 childSetValue("allow_direct_teleport", LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) );
2108 childSetValue("deny_anonymous", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) ); 2123 childSetValue("deny_anonymous", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) );
2109 childSetValue("deny_identified", LLSD(flags & REGION_FLAGS_DENY_IDENTIFIED ? TRUE : FALSE) ); 2124 childSetValue("deny_identified", LLSD(flags & REGION_FLAGS_DENY_IDENTIFIED ? TRUE : FALSE) );
@@ -2119,6 +2134,11 @@ U32 LLPanelEstateInfo::computeEstateFlags()
2119 { 2134 {
2120 flags |= REGION_FLAGS_EXTERNALLY_VISIBLE; 2135 flags |= REGION_FLAGS_EXTERNALLY_VISIBLE;
2121 } 2136 }
2137
2138 if ( childGetValue("voice_chat_check").asBoolean() )
2139 {
2140 flags |= REGION_FLAGS_ALLOW_VOICE;
2141 }
2122 2142
2123 if (childGetValue("allow_direct_teleport").asBoolean()) 2143 if (childGetValue("allow_direct_teleport").asBoolean())
2124 { 2144 {
diff --git a/linden/indra/newview/llfloaterscriptdebug.cpp b/linden/indra/newview/llfloaterscriptdebug.cpp
index 5ad2dc9..82f5ce8 100644
--- a/linden/indra/newview/llfloaterscriptdebug.cpp
+++ b/linden/indra/newview/llfloaterscriptdebug.cpp
@@ -51,10 +51,12 @@ LLFloaterScriptDebug* LLFloaterScriptDebug::sInstance = NULL;
51// 51//
52// Member Functions 52// Member Functions
53// 53//
54LLFloaterScriptDebug::LLFloaterScriptDebug() 54LLFloaterScriptDebug::LLFloaterScriptDebug() :
55: LLMultiFloater() 55 LLMultiFloater()
56{ 56{
57 57 // avoid resizing of the window to match
58 // the initial size of the tabbed-childs, whenever a tab is opened or closed
59 mAutoResize = FALSE;
58} 60}
59 61
60LLFloaterScriptDebug::~LLFloaterScriptDebug() 62LLFloaterScriptDebug::~LLFloaterScriptDebug()
@@ -110,6 +112,9 @@ LLFloater* LLFloaterScriptDebug::addOutputWindow(const LLUUID &object_id)
110 } 112 }
111 LLFloater::setFloaterHost(NULL); 113 LLFloater::setFloaterHost(NULL);
112 114
115 // Tabs sometimes overlap resize handle
116 sInstance->moveResizeHandlesToFront();
117
113 return floaterp; 118 return floaterp;
114} 119}
115 120
diff --git a/linden/indra/newview/llfloatersnapshot.cpp b/linden/indra/newview/llfloatersnapshot.cpp
index 5008509..8b104a3 100644
--- a/linden/indra/newview/llfloatersnapshot.cpp
+++ b/linden/indra/newview/llfloatersnapshot.cpp
@@ -125,7 +125,7 @@ public:
125 void updateSnapshot(BOOL new_snapshot); 125 void updateSnapshot(BOOL new_snapshot);
126 LLFloaterPostcard* savePostcard(); 126 LLFloaterPostcard* savePostcard();
127 void saveTexture(); 127 void saveTexture();
128 void saveLocal(); 128 BOOL saveLocal();
129 129
130 static void onIdle( void* snapshot_preview ); 130 static void onIdle( void* snapshot_preview );
131 131
@@ -381,8 +381,7 @@ void LLSnapshotLivePreview::draw()
381 F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME); 381 F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
382 382
383 // draw "shine" effect 383 // draw "shine" effect
384 LLGLEnable scissor_test(GL_SCISSOR_TEST); 384 LLLocalClipRect clip(getLocalRect());
385 LLUI::setScissorRegionLocal(LLRect(0, mRect.getHeight(), mRect.getWidth(), 0));
386 { 385 {
387 // draw diagonal stripe with gradient that passes over screen 386 // draw diagonal stripe with gradient that passes over screen
388 S32 x1 = gViewerWindow->getWindowWidth() * llround((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f))); 387 S32 x1 = gViewerWindow->getWindowWidth() * llround((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f)));
@@ -698,9 +697,9 @@ void LLSnapshotLivePreview::saveTexture()
698 gViewerStats->incStat(LLViewerStats::ST_SNAPSHOT_COUNT ); 697 gViewerStats->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
699} 698}
700 699
701void LLSnapshotLivePreview::saveLocal() 700BOOL LLSnapshotLivePreview::saveLocal()
702{ 701{
703 gViewerWindow->saveImageNumbered(mRawImage); 702 return gViewerWindow->saveImageNumbered(mRawImage);
704} 703}
705 704
706///---------------------------------------------------------------------------- 705///----------------------------------------------------------------------------
@@ -959,6 +958,8 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data)
959 958
960 if (previewp) 959 if (previewp)
961 { 960 {
961 BOOL succeeded = TRUE; // Only used for saveLocal for now
962
962 if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD) 963 if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD)
963 { 964 {
964 LLFloaterPostcard* floater = previewp->savePostcard(); 965 LLFloaterPostcard* floater = previewp->savePostcard();
@@ -977,21 +978,24 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data)
977 } 978 }
978 else 979 else
979 { 980 {
980 previewp->saveLocal(); 981 succeeded = previewp->saveLocal();
981 } 982 }
982 983
983 if (gSavedSettings.getBOOL("CloseSnapshotOnKeep")) 984 if (gSavedSettings.getBOOL("CloseSnapshotOnKeep"))
984 { 985 {
985 view->close(); 986 view->close();
986 // only plays sound and anim when keeping a snapshot, and closing the snapshot UI 987 // only plays sound and anim when keeping a snapshot, and closing the snapshot UI,
987 gViewerWindow->playSnapshotAnimAndSound(); 988 // and only if the save succeeded (i.e. was not canceled)
989 if (succeeded)
990 {
991 gViewerWindow->playSnapshotAnimAndSound();
992 }
988 } 993 }
989 else 994 else
990 { 995 {
991 checkAutoSnapshot(previewp); 996 checkAutoSnapshot(previewp);
992 } 997 }
993 } 998 }
994
995} 999}
996 1000
997// static 1001// static
diff --git a/linden/indra/newview/llfloatertest.cpp b/linden/indra/newview/llfloatertest.cpp
index c5e353a..6719a38 100644
--- a/linden/indra/newview/llfloatertest.cpp
+++ b/linden/indra/newview/llfloatertest.cpp
@@ -387,3 +387,10 @@ LLFloaterTest::~LLFloaterTest()
387{ 387{
388 delete &impl; 388 delete &impl;
389} 389}
390
391//---------------------------------------------------------------------------
392
393LLFloaterSimple::LLFloaterSimple(const std::string& xml_filename)
394{
395 gUICtrlFactory->buildFloater(this, xml_filename);
396}
diff --git a/linden/indra/newview/llfloatertest.h b/linden/indra/newview/llfloatertest.h
index 93869ef..afb0683 100644
--- a/linden/indra/newview/llfloatertest.h
+++ b/linden/indra/newview/llfloatertest.h
@@ -30,6 +30,8 @@
30#ifndef LL_LLFLOATERTEST_H 30#ifndef LL_LLFLOATERTEST_H
31#define LL_LLFLOATERTEST_H 31#define LL_LLFLOATERTEST_H
32 32
33#include "llfloater.h"
34
33class LLFloaterTestImpl; 35class LLFloaterTestImpl;
34 36
35class LLFloaterTest 37class LLFloaterTest
@@ -44,4 +46,10 @@ private:
44 LLFloaterTestImpl& impl; 46 LLFloaterTestImpl& impl;
45}; 47};
46 48
49class LLFloaterSimple : public LLFloater
50{
51public:
52 LLFloaterSimple(const std::string& filename);
53};
54
47#endif 55#endif
diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp
index 3748131..df5d488 100644
--- a/linden/indra/newview/llfloatertools.cpp
+++ b/linden/indra/newview/llfloatertools.cpp
@@ -73,7 +73,6 @@
73#include "llviewerparcelmgr.h" 73#include "llviewerparcelmgr.h"
74#include "llviewerwindow.h" 74#include "llviewerwindow.h"
75#include "llviewercontrol.h" 75#include "llviewercontrol.h"
76#include "llvolumesliderctrl.h"
77#include "viewer.h" 76#include "viewer.h"
78 77
79#include "llvieweruictrlfactory.h" 78#include "llvieweruictrlfactory.h"
@@ -195,7 +194,6 @@ BOOL LLFloaterTools::postBuild()
195 childSetAction("button land",LLFloaterTools::setEditTool, (void*)gToolParcel); 194 childSetAction("button land",LLFloaterTools::setEditTool, (void*)gToolParcel);
196 mTextStatus = LLUICtrlFactory::getTextBoxByName(this,"text status"); 195 mTextStatus = LLUICtrlFactory::getTextBoxByName(this,"text status");
197 mRadioZoom = LLUICtrlFactory::getCheckBoxByName(this,"radio zoom"); 196 mRadioZoom = LLUICtrlFactory::getCheckBoxByName(this,"radio zoom");
198 mSliderZoom = LLViewerUICtrlFactory::getVolumeSliderByName(this,"slider zoom");
199 childSetCommitCallback("slider zoom",commit_slider_zoom,this); 197 childSetCommitCallback("slider zoom",commit_slider_zoom,this);
200 mRadioOrbit = LLUICtrlFactory::getCheckBoxByName(this,"radio orbit"); 198 mRadioOrbit = LLUICtrlFactory::getCheckBoxByName(this,"radio orbit");
201 childSetCommitCallback("radio orbit",commit_radio_orbit,this); 199 childSetCommitCallback("radio orbit",commit_radio_orbit,this);
@@ -496,8 +494,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
496 mRadioZoom ->setVisible( focus_visible ); 494 mRadioZoom ->setVisible( focus_visible );
497 mRadioOrbit ->setVisible( focus_visible ); 495 mRadioOrbit ->setVisible( focus_visible );
498 mRadioPan ->setVisible( focus_visible ); 496 mRadioPan ->setVisible( focus_visible );
499 mSliderZoom ->setVisible( focus_visible ); 497 childSetVisible("slider zoom", focus_visible);
500 498
501 mRadioZoom ->set( !gCameraBtnOrbit && 499 mRadioZoom ->set( !gCameraBtnOrbit &&
502 !gCameraBtnPan && 500 !gCameraBtnPan &&
503 !(mask == MASK_ORBIT) && 501 !(mask == MASK_ORBIT) &&
@@ -514,7 +512,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
514 (mask == (MASK_PAN | MASK_ALT)) ); 512 (mask == (MASK_PAN | MASK_ALT)) );
515 513
516 // multiply by correction factor because volume sliders go [0, 0.5] 514 // multiply by correction factor because volume sliders go [0, 0.5]
517 mSliderZoom ->setValue( gAgent.getCameraZoomFraction() * 0.5f); 515 childSetValue( "slider zoom", gAgent.getCameraZoomFraction() * 0.5f);
518 516
519 // Move buttons 517 // Move buttons
520 BOOL move_visible = (tool == gToolGrab); 518 BOOL move_visible = (tool == gToolGrab);
@@ -853,9 +851,8 @@ void commit_radio_pan(LLUICtrl *, void*)
853 851
854void commit_slider_zoom(LLUICtrl *ctrl, void*) 852void commit_slider_zoom(LLUICtrl *ctrl, void*)
855{ 853{
856 LLVolumeSliderCtrl* slider = (LLVolumeSliderCtrl*)ctrl;
857 // renormalize value, since max "volume" level is 0.5 for some reason 854 // renormalize value, since max "volume" level is 0.5 for some reason
858 F32 zoom_level = (F32)slider->getValue().asReal() * 2.f; // / 0.5f; 855 F32 zoom_level = (F32)ctrl->getValue().asReal() * 2.f; // / 0.5f;
859 gAgent.setCameraZoomFraction(zoom_level); 856 gAgent.setCameraZoomFraction(zoom_level);
860} 857}
861 858
diff --git a/linden/indra/newview/llfloatertools.h b/linden/indra/newview/llfloatertools.h
index 27d7f56..ae70a04 100644
--- a/linden/indra/newview/llfloatertools.h
+++ b/linden/indra/newview/llfloatertools.h
@@ -44,7 +44,6 @@ class LLPanelContents;
44class LLPanelFace; 44class LLPanelFace;
45class LLPanelLandInfo; 45class LLPanelLandInfo;
46class LLComboBox; 46class LLComboBox;
47class LLVolumeSliderCtrl;
48class LLParcelSelection; 47class LLParcelSelection;
49class LLObjectSelection; 48class LLObjectSelection;
50 49
@@ -120,7 +119,6 @@ public:
120 LLCheckBoxCtrl *mRadioOrbit; 119 LLCheckBoxCtrl *mRadioOrbit;
121 LLCheckBoxCtrl *mRadioZoom; 120 LLCheckBoxCtrl *mRadioZoom;
122 LLCheckBoxCtrl *mRadioPan; 121 LLCheckBoxCtrl *mRadioPan;
123 LLVolumeSliderCtrl *mSliderZoom;
124 122
125 // Move buttons 123 // Move buttons
126 LLCheckBoxCtrl *mRadioMove; 124 LLCheckBoxCtrl *mRadioMove;
diff --git a/linden/indra/newview/llfloatervoicewizard.cpp b/linden/indra/newview/llfloatervoicewizard.cpp
new file mode 100644
index 0000000..879cb6d
--- /dev/null
+++ b/linden/indra/newview/llfloatervoicewizard.cpp
@@ -0,0 +1,444 @@
1/**
2 * @file llfloatervoicewizard.cpp
3 * @author Richard Nelson
4 * @brief Voice communication set-up wizard
5 *
6 * Copyright (c) 2007-2007, Linden Research, Inc.
7 *
8 * Second Life Viewer Source Code
9 * The source code in this file ("Source Code") is provided by Linden Lab
10 * to you under the terms of the GNU General Public License, version 2.0
11 * ("GPL"), unless you have obtained a separate licensing agreement
12 * ("Other License"), formally executed by you and Linden Lab. Terms of
13 * the GPL can be found in doc/GPL-license.txt in this distribution, or
14 * online at http://secondlife.com/developers/opensource/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at http://secondlife.com/developers/opensource/flossexception
20 *
21 * By copying, modifying or distributing this software, you acknowledge
22 * that you have read and understood your obligations described above,
23 * and agree to abide by those obligations.
24 *
25 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
26 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27 * COMPLETENESS OR PERFORMANCE.
28 */
29
30#include "llviewerprecompiledheaders.h"
31
32#include "llfloatervoicewizard.h"
33
34#include "llagent.h"
35#include "llbutton.h"
36#include "llcombobox.h"
37#include "llfocusmgr.h"
38#include "lliconctrl.h"
39#include "llprefsvoice.h"
40#include "llsliderctrl.h"
41#include "llviewercontrol.h"
42#include "llvieweruictrlfactory.h"
43#include "llvoiceclient.h"
44#include "llimpanel.h"
45
46LLFloaterVoiceWizard::LLFloaterVoiceWizard(const LLSD& seed) : LLFloater("floater_voice_wizard"), mDevicePanel(NULL)
47{
48 mFactoryMap["device_settings"] = LLCallbackMap(createPanelDeviceSettings, this);
49 // do not automatically open singleton floaters (as result of getInstance())
50 BOOL no_open = FALSE;
51 gUICtrlFactory->buildFloater(this, "floater_voice_wizard.xml", &mFactoryMap, no_open);
52
53 mLogic = new LLPrefsVoiceLogic(this);
54 center();
55}
56
57LLFloaterVoiceWizard::~LLFloaterVoiceWizard()
58{
59 delete mLogic;
60 mLogic = NULL;
61}
62
63BOOL LLFloaterVoiceWizard::postBuild()
64{
65 childSetAction("next_btn", onClickNext, this);
66 childSetAction("back_btn", onClickBack, this);
67 childSetAction("ok_btn", onClickOK, this);
68 childSetAction("cancel_btn", onClickCancel, this);
69
70 childSetCommitCallback("voice_enable", onCommitVoiceEnable, this);
71
72 return TRUE;
73}
74
75void LLFloaterVoiceWizard::draw()
76{
77 mLogic->refresh();
78 if (mDevicePanel)
79 {
80 mDevicePanel->refresh();
81 }
82
83 LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(this, "wizard_tabs");
84
85 if (tabs)
86 {
87 // if on first tab, disable back button, etc
88 if (tabs->getCurrentPanelIndex() == 0)
89 {
90 if (gSavedSettings.getBOOL("EnableVoiceChat"))
91 {
92 childSetEnabled("next_btn", TRUE);
93 setDefaultBtn(gUICtrlFactory->getButtonByName(this, "next_btn"));
94 }
95 else
96 {
97 childSetEnabled("next_btn", FALSE);
98 setDefaultBtn(gUICtrlFactory->getButtonByName(this, "ok_btn"));
99 }
100 childSetEnabled("back_btn", FALSE);
101 }
102 else
103 {
104 // if on any tab but the last, enable the next button
105 if (tabs->getCurrentPanelIndex() < tabs->getTabCount() - 1)
106 {
107 childSetEnabled("next_btn", TRUE);
108 setDefaultBtn(gUICtrlFactory->getButtonByName(this, "next_btn"));
109 }
110 else
111 {
112 childSetEnabled("next_btn", FALSE);
113 setDefaultBtn(gUICtrlFactory->getButtonByName(this, "ok_btn"));
114 }
115 childSetEnabled("back_btn", TRUE);
116 }
117 }
118
119 // because we can simultaneously change voice settings from the preferences UI
120 // we need to stay in sync
121 childSetValue("voice_enable", gSavedSettings.getBOOL("EnableVoiceChat") ? "1" : "0");
122
123 // show appropriate text on first tab
124 childSetVisible("voice_intro_text3", !gSavedSettings.getBOOL("EnableVoiceChat"));
125 childSetVisible("voice_intro_text4", gSavedSettings.getBOOL("EnableVoiceChat"));
126
127 LLFloater::draw();
128}
129
130void LLFloaterVoiceWizard::onOpen()
131{
132 // put voice client in "tuning" mode
133 gVoiceClient->tuningStart();
134 //LLVoiceChannel::suspend();
135 LLFloater::onOpen();
136}
137
138void LLFloaterVoiceWizard::onClose(bool app_quitting)
139{
140 gVoiceClient->tuningStop();
141 //LLVoiceChannel::resume();
142 LLFloater::onClose(app_quitting);
143}
144
145
146// static
147void LLFloaterVoiceWizard::onClickNext(void *user_data)
148{
149 LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName((LLFloater*)user_data, "wizard_tabs");
150 if (tabs)
151 {
152 tabs->selectNextTab();
153 }
154}
155
156// static
157void LLFloaterVoiceWizard::onClickBack(void *user_data)
158{
159 LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName((LLFloater*)user_data, "wizard_tabs");
160 if (tabs)
161 {
162 tabs->selectPrevTab();
163 }
164}
165
166// static
167void LLFloaterVoiceWizard::onClickOK(void *user_data)
168{
169 LLFloaterVoiceWizard* self = (LLFloaterVoiceWizard*)user_data;
170
171 // propagate tuning mic volume to actual mic volume
172 self->mLogic->apply();
173 if (self->mDevicePanel)
174 {
175 self->mDevicePanel->apply();
176 }
177 self->close();
178}
179
180// static
181void LLFloaterVoiceWizard::onClickCancel(void *user_data)
182{
183 LLFloaterVoiceWizard* self = (LLFloaterVoiceWizard*)user_data;
184
185 self->mLogic->cancel();
186 if (self->mDevicePanel)
187 {
188 self->mDevicePanel->cancel();
189 }
190 self->close();
191}
192
193// static
194void LLFloaterVoiceWizard::onCommitVoiceEnable(LLUICtrl* ctrl, void* user_data)
195{
196 gSavedSettings.setBOOL("EnableVoiceChat", ctrl->getValue().asInteger());
197}
198
199// static
200void* LLFloaterVoiceWizard::createPanelDeviceSettings(void* user_data)
201{
202 LLFloaterVoiceWizard* floaterp = (LLFloaterVoiceWizard*)user_data;
203 floaterp->mDevicePanel = new LLPanelDeviceSettings();
204 return floaterp->mDevicePanel;
205}
206
207
208//
209// LLPanelDeviceSettings
210//
211
212LLPanelDeviceSettings::LLPanelDeviceSettings()
213{
214 mCtrlInputDevices = NULL;
215 mCtrlOutputDevices = NULL;
216 mInputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
217 mOutputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
218 mDevicesUpdated = FALSE;
219
220 // grab "live" mic volume level
221 mMicVolume = gSavedSettings.getF32("AudioLevelMic");
222
223 // ask for new device enumeration
224 gVoiceClient->refreshDeviceLists();
225}
226
227LLPanelDeviceSettings::~LLPanelDeviceSettings()
228{
229}
230
231BOOL LLPanelDeviceSettings::postBuild()
232{
233 LLSlider* volume_slider = gUICtrlFactory->getSliderBarByName(this, "mic_volume_slider");
234 if (volume_slider)
235 {
236 // set mic volume tuning slider based on last mic volume setting
237 volume_slider->setValue(mMicVolume);
238 }
239
240 return TRUE;
241}
242
243void LLPanelDeviceSettings::draw()
244{
245 // let user know that volume indicator is not yet available
246 childSetVisible("wait_text", !gVoiceClient->inTuningMode());
247
248 LLPanel::draw();
249
250 F32 voice_power = gVoiceClient->tuningGetEnergy();
251 S32 discrete_power = 0;
252
253 if (!gVoiceClient->inTuningMode())
254 {
255 discrete_power = 0;
256 }
257 else
258 {
259 discrete_power = llmin(4, llfloor((voice_power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 4.f));
260 }
261
262 if (gVoiceClient->inTuningMode())
263 {
264 const S32 GAP = 5;
265 S32 cur_x = 100;
266 S32 cur_y = 15;
267
268 for(S32 power_bar_idx = 0; power_bar_idx < 5; power_bar_idx++)
269 {
270 if (power_bar_idx < discrete_power)
271 {
272 LLColor4 color = (power_bar_idx >= 3) ? gSavedSettings.getColor4("OverdrivenColor") : gSavedSettings.getColor4("SpeakingColor");
273 gl_rect_2d(cur_x, cur_y + 20, cur_x + 20, cur_y, color, TRUE);
274 }
275 gl_rect_2d(cur_x, cur_y + 20, cur_x + 20, cur_y, LLColor4::grey, FALSE);
276 cur_x += 20 + GAP;
277 }
278 }
279}
280
281void LLPanelDeviceSettings::apply()
282{
283 std::string s;
284 if(mCtrlInputDevices)
285 {
286 s = mCtrlInputDevices->getSimple();
287 gSavedSettings.setString("VoiceInputAudioDevice", s);
288 }
289
290 if(mCtrlOutputDevices)
291 {
292 s = mCtrlOutputDevices->getSimple();
293 gSavedSettings.setString("VoiceOutputAudioDevice", s);
294 }
295
296 // assume we are being destroyed by closing our embedding window
297 gSavedSettings.setF32("AudioLevelMic", mMicVolume);
298}
299
300void LLPanelDeviceSettings::cancel()
301{
302 gSavedSettings.setString("VoiceInputAudioDevice", mInputDevice);
303 gSavedSettings.setString("VoiceOutputAudioDevice", mOutputDevice);
304
305 if(mCtrlInputDevices)
306 mCtrlInputDevices->setSimple(mInputDevice);
307
308 if(mCtrlOutputDevices)
309 mCtrlOutputDevices->setSimple(mOutputDevice);
310}
311
312void LLPanelDeviceSettings::refresh()
313{
314 //grab current volume
315 LLSlider* volume_slider = gUICtrlFactory->getSliderBarByName(this, "mic_volume_slider");
316 if (volume_slider)
317 {
318 // set mic volume tuning slider based on last mic volume setting
319 mMicVolume = (F32)volume_slider->getValue().asReal();
320 gVoiceClient->tuningSetMicVolume(mMicVolume);
321 }
322
323 // Fill in popup menus
324 mCtrlInputDevices = LLUICtrlFactory::getComboBoxByName(this, "voice_input_device");
325 mCtrlOutputDevices = LLUICtrlFactory::getComboBoxByName(this, "voice_output_device");
326
327 if(!gVoiceClient->deviceSettingsAvailable())
328 {
329 // The combo boxes are disabled, since we can't get the device settings from the daemon just now.
330 // Put the currently set default (ONLY) in the box, and select it.
331 if(mCtrlInputDevices)
332 {
333 mCtrlInputDevices->removeall();
334 mCtrlInputDevices->add( mInputDevice, ADD_BOTTOM );
335 mCtrlInputDevices->setSimple(mInputDevice);
336 }
337 if(mCtrlOutputDevices)
338 {
339 mCtrlOutputDevices->removeall();
340 mCtrlOutputDevices->add( mOutputDevice, ADD_BOTTOM );
341 mCtrlOutputDevices->setSimple(mOutputDevice);
342 }
343 }
344 else if (!mDevicesUpdated)
345 {
346 LLVoiceClient::deviceList *devices;
347
348 LLVoiceClient::deviceList::iterator iter;
349
350 if(mCtrlInputDevices)
351 {
352 mCtrlInputDevices->removeall();
353 mCtrlInputDevices->add( "Default", ADD_BOTTOM );
354
355 devices = gVoiceClient->getCaptureDevices();
356 for(iter=devices->begin(); iter != devices->end(); iter++)
357 {
358 mCtrlInputDevices->add( *iter, ADD_BOTTOM );
359 }
360
361 if(!mCtrlInputDevices->setSimple(mInputDevice))
362 {
363 mCtrlInputDevices->setSimple("Default");
364 }
365 }
366
367 if(mCtrlOutputDevices)
368 {
369 mCtrlOutputDevices->removeall();
370 mCtrlOutputDevices->add( "Default", ADD_BOTTOM );
371
372 devices = gVoiceClient->getRenderDevices();
373 for(iter=devices->begin(); iter != devices->end(); iter++)
374 {
375 mCtrlOutputDevices->add( *iter, ADD_BOTTOM );
376 }
377
378 if(!mCtrlOutputDevices->setSimple(mOutputDevice))
379 {
380 mCtrlOutputDevices->setSimple("Default");
381 }
382 }
383 mDevicesUpdated = TRUE;
384 }
385}
386
387//
388// LLFloaterDeviceSettings
389//
390
391LLFloaterDeviceSettings::LLFloaterDeviceSettings(const LLSD& seed) : LLFloater("floater_device_settings"), mDevicePanel(NULL)
392{
393 mFactoryMap["device_settings"] = LLCallbackMap(createPanelDeviceSettings, this);
394 gUICtrlFactory->buildFloater(this, "floater_device_settings.xml", &mFactoryMap);
395 center();
396}
397
398void LLFloaterDeviceSettings::onOpen()
399{
400 // put voice client in "tuning" mode
401 gVoiceClient->tuningStart();
402 //LLVoiceChannel::suspend();
403 LLFloater::onOpen();
404}
405
406void LLFloaterDeviceSettings::onClose(bool app_quitting)
407{
408 gVoiceClient->tuningStop();
409 //LLVoiceChannel::resume();
410 setVisible(FALSE);
411}
412
413void LLFloaterDeviceSettings::apply()
414{
415 if (mDevicePanel)
416 {
417 mDevicePanel->apply();
418 }
419}
420
421void LLFloaterDeviceSettings::cancel()
422{
423 if (mDevicePanel)
424 {
425 mDevicePanel->cancel();
426 }
427}
428
429void LLFloaterDeviceSettings::draw()
430{
431 if (mDevicePanel)
432 {
433 mDevicePanel->refresh();
434 }
435 LLFloater::draw();
436}
437
438// static
439void* LLFloaterDeviceSettings::createPanelDeviceSettings(void* user_data)
440{
441 LLFloaterDeviceSettings* floaterp = (LLFloaterDeviceSettings*)user_data;
442 floaterp->mDevicePanel = new LLPanelDeviceSettings();
443 return floaterp->mDevicePanel;
444}
diff --git a/linden/indra/newview/llfloatervoicewizard.h b/linden/indra/newview/llfloatervoicewizard.h
new file mode 100644
index 0000000..bd9ce80
--- /dev/null
+++ b/linden/indra/newview/llfloatervoicewizard.h
@@ -0,0 +1,100 @@
1/**
2 * @file llfloatervoicewizard.h
3 * @author Richard Nelson
4 * @brief Voice communication set-up wizard
5 *
6 * Copyright (c) 2001-2007, Linden Research, Inc.
7 *
8 * Second Life Viewer Source Code
9 * The source code in this file ("Source Code") is provided by Linden Lab
10 * to you under the terms of the GNU General Public License, version 2.0
11 * ("GPL"), unless you have obtained a separate licensing agreement
12 * ("Other License"), formally executed by you and Linden Lab. Terms of
13 * the GPL can be found in doc/GPL-license.txt in this distribution, or
14 * online at http://secondlife.com/developers/opensource/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at http://secondlife.com/developers/opensource/flossexception
20 *
21 * By copying, modifying or distributing this software, you acknowledge
22 * that you have read and understood your obligations described above,
23 * and agree to abide by those obligations.
24 *
25 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
26 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27 * COMPLETENESS OR PERFORMANCE.
28 */
29
30#ifndef LL_LLFLOATERVOICEWIZARD_H
31#define LL_LLFLOATERVOICEWIZARD_H
32
33#include "llfloater.h"
34
35class LLPrefsVoiceLogic;
36class LLPanelDeviceSettings;
37
38class LLFloaterVoiceWizard
39: public LLFloater, public LLUISingleton<LLFloaterVoiceWizard>
40{
41public:
42 LLFloaterVoiceWizard(const LLSD& seed);
43 virtual ~LLFloaterVoiceWizard();
44
45 /*virtual*/ BOOL postBuild();
46 /*virtual*/ void draw();
47 /*virtual*/ void onOpen();
48 /*virtual*/ void onClose(bool app_quitting);
49
50protected:
51 static void onClickNext(void *user_data);
52 static void onClickBack(void *user_data);
53 static void onClickOK(void *user_data);
54 static void onClickCancel(void *user_data);
55 static void onCommitVoiceEnable(LLUICtrl* ctrl, void* user_data);
56 static void* createPanelDeviceSettings(void* user_data);
57
58protected:
59 LLPrefsVoiceLogic* mLogic;
60 LLPanelDeviceSettings* mDevicePanel;
61};
62
63class LLPanelDeviceSettings : public LLPanel
64{
65public:
66 LLPanelDeviceSettings();
67 ~LLPanelDeviceSettings();
68
69 /*virtual*/ void draw();
70 /*virtual*/ BOOL postBuild();
71 void apply();
72 void cancel();
73 void refresh();
74
75protected:
76 F32 mMicVolume;
77 std::string mInputDevice;
78 std::string mOutputDevice;
79 LLComboBox *mCtrlInputDevices;
80 LLComboBox *mCtrlOutputDevices;
81 BOOL mDevicesUpdated;
82};
83
84class LLFloaterDeviceSettings : public LLFloater, public LLUISingleton<LLFloaterDeviceSettings>
85{
86public:
87 LLFloaterDeviceSettings(const LLSD& seed);
88 /*virtual*/ void onOpen();
89 /*virtual*/ void onClose(bool app_quitting);
90 /*virtual*/ void draw();
91 void apply();
92 void cancel();
93
94protected:
95 static void* createPanelDeviceSettings(void* user_data);
96
97 LLPanelDeviceSettings* mDevicePanel;
98};
99
100#endif // LL_LLFLOATERVOICEWIZARD_H
diff --git a/linden/indra/newview/llfloaterworldmap.cpp b/linden/indra/newview/llfloaterworldmap.cpp
index dc42a40..ccd252b 100644
--- a/linden/indra/newview/llfloaterworldmap.cpp
+++ b/linden/indra/newview/llfloaterworldmap.cpp
@@ -179,6 +179,8 @@ LLFloaterWorldMap::LLFloaterWorldMap()
179 mCompletingRegionName(""), 179 mCompletingRegionName(""),
180 mWaitingForTracker(FALSE), 180 mWaitingForTracker(FALSE),
181 mExactMatch(FALSE), 181 mExactMatch(FALSE),
182 mIsClosing(FALSE),
183 mSetToUserPosition(TRUE),
182 mTrackedLocation(0,0,0), 184 mTrackedLocation(0,0,0),
183 mTrackedStatus(LLTracker::TRACKING_NOTHING) 185 mTrackedStatus(LLTracker::TRACKING_NOTHING)
184{ 186{
@@ -355,6 +357,9 @@ void LLFloaterWorldMap::show(void*, BOOL center_on_target)
355 357
356 gFloaterWorldMap->buildAvatarIDList(); 358 gFloaterWorldMap->buildAvatarIDList();
357 gFloaterWorldMap->buildLandmarkIDLists(); 359 gFloaterWorldMap->buildLandmarkIDLists();
360
361 // If nothing is being tracked, set flag so the user position will be found
362 gFloaterWorldMap->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
358 } 363 }
359 364
360 if (center_on_target) 365 if (center_on_target)
@@ -517,7 +522,7 @@ void LLFloaterWorldMap::draw()
517 childSetEnabled("Teleport", (BOOL)tracking_status); 522 childSetEnabled("Teleport", (BOOL)tracking_status);
518// childSetEnabled("Clear", (BOOL)tracking_status); 523// childSetEnabled("Clear", (BOOL)tracking_status);
519 childSetEnabled("Show Destination", (BOOL)tracking_status || gWorldMap->mIsTrackingUnknownLocation); 524 childSetEnabled("Show Destination", (BOOL)tracking_status || gWorldMap->mIsTrackingUnknownLocation);
520 childSetEnabled("copy_slurl", (BOOL)tracking_status); 525 childSetEnabled("copy_slurl", (mSLURL.size() > 0) );
521 526
522 setMouseOpaque(TRUE); 527 setMouseOpaque(TRUE);
523 mDragHandle->setMouseOpaque(TRUE); 528 mDragHandle->setMouseOpaque(TRUE);
@@ -661,7 +666,8 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
661 return; 666 return;
662 } 667 }
663 668
664 LLString sim_name = gWorldMap->simNameFromPosGlobal( pos_global ); 669 LLString sim_name;
670 gWorldMap->simNameFromPosGlobal( pos_global, sim_name );
665 F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); 671 F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
666 F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); 672 F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
667 LLString full_name = llformat("%s (%d, %d, %d)", 673 LLString full_name = llformat("%s (%d, %d, %d)",
@@ -682,15 +688,51 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
682 688
683void LLFloaterWorldMap::updateLocation() 689void LLFloaterWorldMap::updateLocation()
684{ 690{
691 bool gotSimName;
692
693 LLTracker::ETrackingStatus status = LLTracker::getTrackingStatus();
694
685 // These values may get updated by a message, so need to check them every frame 695 // These values may get updated by a message, so need to check them every frame
686 // The fields may be changed by the user, so only update them if the data changes 696 // The fields may be changed by the user, so only update them if the data changes
687 LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); 697 LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
688 if (pos_global.isExactlyZero()) 698 if (pos_global.isExactlyZero())
689 { 699 {
700 LLVector3d agentPos = gAgent.getPositionGlobal();
701
702 // Set to avatar's current postion if nothing is selected
703 if ( status == LLTracker::TRACKING_NOTHING && mSetToUserPosition )
704 {
705 // Make sure we know where we are before setting the current user position
706 LLString agent_sim_name;
707 gotSimName = gWorldMap->simNameFromPosGlobal( agentPos, agent_sim_name );
708 if ( gotSimName )
709 {
710 mSetToUserPosition = FALSE;
711
712 // Fill out the location field
713 childSetValue("location", agent_sim_name);
714
715 // Figure out where user is
716 LLVector3d agentPos = gAgent.getPositionGlobal();
717
718 S32 agent_x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) );
719 S32 agent_y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) );
720 S32 agent_z = llround( (F32)agentPos.mdV[VZ] );
721
722 childSetValue("spin x", LLSD(agent_x) );
723 childSetValue("spin y", LLSD(agent_y) );
724 childSetValue("spin z", LLSD(agent_z) );
725
726 // Set the current SLURL
727 mSLURL = LLWeb::escapeURL( llformat("http://slurl.com/secondlife/%s/%d/%d/%d",
728 agent_sim_name.c_str(), agent_x, agent_y, agent_z) );
729 }
730 }
731
690 return; // invalid location 732 return; // invalid location
691 } 733 }
692 LLTracker::ETrackingStatus status = LLTracker::getTrackingStatus(); 734 LLString sim_name;
693 LLString sim_name = gWorldMap->simNameFromPosGlobal( pos_global ); 735 gotSimName = gWorldMap->simNameFromPosGlobal( pos_global, sim_name );
694 if ((status != LLTracker::TRACKING_NOTHING) && 736 if ((status != LLTracker::TRACKING_NOTHING) &&
695 (status != mTrackedStatus || pos_global != mTrackedLocation || sim_name != mTrackedSimName)) 737 (status != mTrackedStatus || pos_global != mTrackedLocation || sim_name != mTrackedSimName))
696 { 738 {
@@ -717,8 +759,16 @@ void LLFloaterWorldMap::updateLocation()
717 childSetValue("spin y", LLSD(region_y) ); 759 childSetValue("spin y", LLSD(region_y) );
718 childSetValue("spin z", LLSD((F32)pos_global.mdV[VZ]) ); 760 childSetValue("spin z", LLSD((F32)pos_global.mdV[VZ]) );
719 761
720 mSLURL = LLWeb::escapeURL(llformat("http://slurl.com/secondlife/%s/%d/%d/%d", 762 // simNameFromPosGlobal can fail, so don't give the user an invalid SLURL
721 sim_name.c_str(), llround(region_x), llround(region_y), llround((F32)pos_global.mdV[VZ]))); 763 if ( gotSimName )
764 {
765 mSLURL = LLWeb::escapeURL(llformat("http://slurl.com/secondlife/%s/%d/%d/%d",
766 sim_name.c_str(), llround(region_x), llround(region_y), llround((F32)pos_global.mdV[VZ])));
767 }
768 else
769 { // Empty SLURL will disable the "Copy SLURL to clipboard" button
770 mSLURL = "";
771 }
722 } 772 }
723} 773}
724 774
@@ -1102,6 +1152,9 @@ void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata )
1102 1152
1103 self->trackLandmark( item_id); 1153 self->trackLandmark( item_id);
1104 onShowTargetBtn(self); 1154 onShowTargetBtn(self);
1155
1156 // Reset to user postion if nothing is tracked
1157 self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
1105} 1158}
1106 1159
1107// static 1160// static
@@ -1153,6 +1206,10 @@ void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata )
1153 self->trackAvatar(new_avatar_id, name); 1206 self->trackAvatar(new_avatar_id, name);
1154 onShowTargetBtn(self); 1207 onShowTargetBtn(self);
1155 } 1208 }
1209 else
1210 { // Reset to user postion if nothing is tracked
1211 self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
1212 }
1156} 1213}
1157 1214
1158// static 1215// static
@@ -1208,6 +1265,8 @@ void LLFloaterWorldMap::onClearBtn(void* data)
1208 self->mTrackedStatus = LLTracker::TRACKING_NOTHING; 1265 self->mTrackedStatus = LLTracker::TRACKING_NOTHING;
1209 LLTracker::stopTracking((void *)(intptr_t)TRUE); 1266 LLTracker::stopTracking((void *)(intptr_t)TRUE);
1210 gWorldMap->mIsTrackingUnknownLocation = FALSE; 1267 gWorldMap->mIsTrackingUnknownLocation = FALSE;
1268 self->mSLURL = ""; // Clear the SLURL since it's invalid
1269 self->mSetToUserPosition = TRUE; // Revert back to the current user position
1211} 1270}
1212 1271
1213// static 1272// static
@@ -1226,6 +1285,10 @@ void LLFloaterWorldMap::onShowTargetBtn(void* data)
1226void LLFloaterWorldMap::onShowAgentBtn(void* data) 1285void LLFloaterWorldMap::onShowAgentBtn(void* data)
1227{ 1286{
1228 LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate 1287 LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate
1288
1289 // Set flag so user's location will be displayed if not tracking anything else
1290 LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
1291 self->mSetToUserPosition = TRUE;
1229} 1292}
1230 1293
1231// static 1294// static
diff --git a/linden/indra/newview/llfloaterworldmap.h b/linden/indra/newview/llfloaterworldmap.h
index f383754..d2a4e6f 100644
--- a/linden/indra/newview/llfloaterworldmap.h
+++ b/linden/indra/newview/llfloaterworldmap.h
@@ -176,6 +176,7 @@ protected:
176 BOOL mExactMatch; 176 BOOL mExactMatch;
177 177
178 BOOL mIsClosing; 178 BOOL mIsClosing;
179 BOOL mSetToUserPosition;
179 180
180 LLVector3d mTrackedLocation; 181 LLVector3d mTrackedLocation;
181 LLTracker::ETrackingStatus mTrackedStatus; 182 LLTracker::ETrackingStatus mTrackedStatus;
diff --git a/linden/indra/newview/llfolderview.cpp b/linden/indra/newview/llfolderview.cpp
index 36d0b40..f3c6ace 100644
--- a/linden/indra/newview/llfolderview.cpp
+++ b/linden/indra/newview/llfolderview.cpp
@@ -568,16 +568,15 @@ void LLFolderViewItem::rename(const LLString& new_name)
568 if( !new_name.empty() ) 568 if( !new_name.empty() )
569 { 569 {
570 mLabel = new_name.c_str(); 570 mLabel = new_name.c_str();
571 BOOL is_renamed = TRUE;
572 if( mListener ) 571 if( mListener )
573 { 572 {
574 is_renamed = mListener->renameItem(new_name); 573 mListener->renameItem(new_name);
575 } 574
576 if(mParentFolder && is_renamed) 575 if(mParentFolder)
577 { 576 {
578 mParentFolder->resort(this); 577 mParentFolder->resort(this);
578 }
579 } 579 }
580 //refresh();
581 } 580 }
582} 581}
583 582
@@ -2990,7 +2989,10 @@ void LLFolderView::sanitizeSelection()
2990 // store off current item in case it is automatically deselected 2989 // store off current item in case it is automatically deselected
2991 // and we want to preserve context 2990 // and we want to preserve context
2992 LLFolderViewItem* original_selected_item = getCurSelectedItem(); 2991 LLFolderViewItem* original_selected_item = getCurSelectedItem();
2993 2992
2993 // Cache "Show all folders" filter setting
2994 BOOL show_all_folders = (getRoot()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS);
2995
2994 std::vector<LLFolderViewItem*> items_to_remove; 2996 std::vector<LLFolderViewItem*> items_to_remove;
2995 selected_items_t::iterator item_iter; 2997 selected_items_t::iterator item_iter;
2996 for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter) 2998 for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
@@ -3001,10 +3003,20 @@ void LLFolderView::sanitizeSelection()
3001 BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item 3003 BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item
3002 // modify with parent open and filters states 3004 // modify with parent open and filters states
3003 LLFolderViewFolder* parent_folder = item->getParentFolder(); 3005 LLFolderViewFolder* parent_folder = item->getParentFolder();
3004 while(parent_folder) 3006 if ( parent_folder )
3005 { 3007 {
3006 visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible(); 3008 if ( show_all_folders )
3007 parent_folder = parent_folder->getParentFolder(); 3009 { // "Show all folders" is on, so this folder is visible
3010 visible = TRUE;
3011 }
3012 else
3013 { // Move up through parent folders and see what's visible
3014 while(parent_folder)
3015 {
3016 visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible();
3017 parent_folder = parent_folder->getParentFolder();
3018 }
3019 }
3008 } 3020 }
3009 3021
3010 // deselect item if any ancestor is closed or didn't pass filter requirements. 3022 // deselect item if any ancestor is closed or didn't pass filter requirements.
@@ -3020,7 +3032,7 @@ void LLFolderView::sanitizeSelection()
3020 for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter) 3032 for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter)
3021 { 3033 {
3022 LLFolderViewItem* other_item = *other_item_iter; 3034 LLFolderViewItem* other_item = *other_item_iter;
3023 for(LLFolderViewFolder* parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder()) 3035 for( parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder())
3024 { 3036 {
3025 if (parent_folder == item) 3037 if (parent_folder == item)
3026 { 3038 {
@@ -3359,19 +3371,30 @@ void LLFolderView::openSelectedItems( void )
3359 { 3371 {
3360 S32 left, top; 3372 S32 left, top;
3361 gFloaterView->getNewFloaterPosition(&left, &top); 3373 gFloaterView->getNewFloaterPosition(&left, &top);
3362
3363 LLMultiPreview* multi_previewp = new LLMultiPreview(LLRect(left, top, left + 300, top - 100)); 3374 LLMultiPreview* multi_previewp = new LLMultiPreview(LLRect(left, top, left + 300, top - 100));
3364 3375 gFloaterView->getNewFloaterPosition(&left, &top);
3365 LLFloater::setFloaterHost(multi_previewp); 3376 LLMultiProperties* multi_propertiesp = new LLMultiProperties(LLRect(left, top, left + 300, top - 100));
3366 3377
3367 selected_items_t::iterator item_it; 3378 selected_items_t::iterator item_it;
3368 for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) 3379 for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
3369 { 3380 {
3370 (*item_it)->open(); /* Flawfinder: ignore */ 3381 // IT_{OBJECT,ATTACHMENT} creates LLProperties
3382 // floaters; others create LLPreviews. Put
3383 // each one in the right type of container.
3384 LLFolderViewEventListener* listener = (*item_it)->getListener();
3385 bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
3386 if (is_prop)
3387 LLFloater::setFloaterHost(multi_propertiesp);
3388 else
3389 LLFloater::setFloaterHost(multi_previewp);
3390 (*item_it)->open();
3371 } 3391 }
3372 3392
3373 LLFloater::setFloaterHost(NULL); 3393 LLFloater::setFloaterHost(NULL);
3374 multi_previewp->open(); /* Flawfinder: ignore */ 3394 // *NOTE: LLMulti* will safely auto-delete when open'd
3395 // without any children.
3396 multi_previewp->open();
3397 multi_propertiesp->open();
3375 } 3398 }
3376 } 3399 }
3377} 3400}
@@ -4665,7 +4688,7 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
4665 4688
4666BOOL LLInventoryFilter::isSinceLogoff() 4689BOOL LLInventoryFilter::isSinceLogoff()
4667{ 4690{
4668 return mFilterOps.mMinDate == mLastLogoff && mFilterOps.mMaxDate == U32_MAX; 4691 return (mFilterOps.mMinDate == mLastLogoff) && (mFilterOps.mMaxDate == U32_MAX);
4669} 4692}
4670 4693
4671void LLInventoryFilter::setHoursAgo(U32 hours) 4694void LLInventoryFilter::setHoursAgo(U32 hours)
@@ -4966,28 +4989,48 @@ void LLInventoryFilter::toLLSD(LLSD& data)
4966 data["permissions"] = (LLSD::Integer)getFilterPermissions(); 4989 data["permissions"] = (LLSD::Integer)getFilterPermissions();
4967 data["substring"] = (LLSD::String)getFilterSubString(); 4990 data["substring"] = (LLSD::String)getFilterSubString();
4968 data["sort_order"] = (LLSD::Integer)getSortOrder(); 4991 data["sort_order"] = (LLSD::Integer)getSortOrder();
4992 data["since_logoff"] = (LLSD::Boolean)isSinceLogoff();
4969} 4993}
4970 4994
4971void LLInventoryFilter::fromLLSD(LLSD& data) 4995void LLInventoryFilter::fromLLSD(LLSD& data)
4972{ 4996{
4973 if(data.has("filter_types")) 4997 if(data.has("filter_types"))
4998 {
4974 setFilterTypes((U32)data["filter_types"].asInteger()); 4999 setFilterTypes((U32)data["filter_types"].asInteger());
5000 }
4975 5001
4976 if(data.has("min_date") && data.has("max_date")) 5002 if(data.has("min_date") && data.has("max_date"))
5003 {
4977 setDateRange((U32)data["min_date"].asInteger(), (U32)data["max_date"].asInteger()); 5004 setDateRange((U32)data["min_date"].asInteger(), (U32)data["max_date"].asInteger());
5005 }
4978 5006
4979 if(data.has("hours_ago")) 5007 if(data.has("hours_ago"))
5008 {
4980 setHoursAgo((U32)data["hours_ago"].asInteger()); 5009 setHoursAgo((U32)data["hours_ago"].asInteger());
5010 }
4981 5011
4982 if(data.has("show_folder_state")) 5012 if(data.has("show_folder_state"))
5013 {
4983 setShowFolderState((EFolderShow)data["show_folder_state"].asInteger()); 5014 setShowFolderState((EFolderShow)data["show_folder_state"].asInteger());
5015 }
4984 5016
4985 if(data.has("permissions")) 5017 if(data.has("permissions"))
5018 {
4986 setFilterPermissions((PermissionMask)data["permissions"].asInteger()); 5019 setFilterPermissions((PermissionMask)data["permissions"].asInteger());
5020 }
4987 5021
4988 if(data.has("substring")) 5022 if(data.has("substring"))
5023 {
4989 setFilterSubString(LLString(data["substring"].asString())); 5024 setFilterSubString(LLString(data["substring"].asString()));
5025 }
4990 5026
4991 if(data.has("sort_order")) 5027 if(data.has("sort_order"))
5028 {
4992 setSortOrder((U32)data["sort_order"].asInteger()); 5029 setSortOrder((U32)data["sort_order"].asInteger());
5030 }
5031
5032 if(data.has("since_logoff"))
5033 {
5034 setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean());
5035 }
4993} 5036}
diff --git a/linden/indra/newview/llframestatview.cpp b/linden/indra/newview/llframestatview.cpp
index af9162d..c489caa 100644
--- a/linden/indra/newview/llframestatview.cpp
+++ b/linden/indra/newview/llframestatview.cpp
@@ -378,6 +378,12 @@ void LLFrameStatView::draw()
378 378
379void LLFrameStatView::addStat(LLStat *statp, const char *label, const LLColor4 &color) 379void LLFrameStatView::addStat(LLStat *statp, const char *label, const LLColor4 &color)
380{ 380{
381 if( mNumStats >= MAX_STATS )
382 {
383 llwarns << "LLFrameStatView::addStat - too many stats!" << llendl;
384 return;
385 }
386
381 mStats[mNumStats] = statp; 387 mStats[mNumStats] = statp;
382 mColors[mNumStats] = color; 388 mColors[mNumStats] = color;
383 mLabels[mNumStats] = label; 389 mLabels[mNumStats] = label;
diff --git a/linden/indra/newview/llgesturemgr.cpp b/linden/indra/newview/llgesturemgr.cpp
index c94e9e2..bf3c057 100644
--- a/linden/indra/newview/llgesturemgr.cpp
+++ b/linden/indra/newview/llgesturemgr.cpp
@@ -103,7 +103,7 @@ void LLGestureManager::activateGesture(const LLUUID& item_id)
103 mDeactivateSimilarNames.clear(); 103 mDeactivateSimilarNames.clear();
104 104
105 const BOOL inform_server = TRUE; 105 const BOOL inform_server = TRUE;
106 const BOOL deactivate_similar = TRUE; 106 const BOOL deactivate_similar = FALSE;
107 activateGestureWithAsset(item_id, asset_id, inform_server, deactivate_similar); 107 activateGestureWithAsset(item_id, asset_id, inform_server, deactivate_similar);
108} 108}
109 109
@@ -206,6 +206,11 @@ void LLGestureManager::activateGestureWithAsset(const LLUUID& item_id,
206 BOOL inform_server, 206 BOOL inform_server,
207 BOOL deactivate_similar) 207 BOOL deactivate_similar)
208{ 208{
209 if( !gAssetStorage )
210 {
211 llwarns << "LLGestureManager::activateGestureWithAsset without valid gAssetStorage" << llendl;
212 return;
213 }
209 // If gesture is already active, nothing to do. 214 // If gesture is already active, nothing to do.
210 if (isGestureActive(item_id)) 215 if (isGestureActive(item_id))
211 { 216 {
@@ -418,7 +423,7 @@ void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new
418 LLLoadInfo* info = new LLLoadInfo; 423 LLLoadInfo* info = new LLLoadInfo;
419 info->mItemID = item_id; 424 info->mItemID = item_id;
420 info->mInformServer = TRUE; 425 info->mInformServer = TRUE;
421 info->mDeactivateSimilar = TRUE; 426 info->mDeactivateSimilar = FALSE;
422 427
423 const BOOL high_priority = TRUE; 428 const BOOL high_priority = TRUE;
424 gAssetStorage->getAssetData(asset_id, 429 gAssetStorage->getAssetData(asset_id,
@@ -489,6 +494,8 @@ BOOL LLGestureManager::triggerAndReviseString(const std::string &utf8str, std::s
489 LLString cur_token_lower = cur_token; 494 LLString cur_token_lower = cur_token;
490 LLString::toLower(cur_token_lower); 495 LLString::toLower(cur_token_lower);
491 496
497 // collect gestures that match
498 std::vector <LLMultiGesture *> matching;
492 item_map_t::iterator it; 499 item_map_t::iterator it;
493 for (it = mActive.begin(); it != mActive.end(); ++it) 500 for (it = mActive.begin(); it != mActive.end(); ++it)
494 { 501 {
@@ -496,16 +503,32 @@ BOOL LLGestureManager::triggerAndReviseString(const std::string &utf8str, std::s
496 503
497 // Gesture asset data might not have arrived yet 504 // Gesture asset data might not have arrived yet
498 if (!gesture) continue; 505 if (!gesture) continue;
499 506
500 if (!stricmp(gesture->mTrigger.c_str(), cur_token_lower.c_str())) 507 if (!stricmp(gesture->mTrigger.c_str(), cur_token_lower.c_str()))
501 { 508 {
509 matching.push_back(gesture);
510 }
511
512 gesture = NULL;
513 }
514
515
516 if (matching.size() > 0)
517 {
518 // choose one at random
519 {
520 S32 random = ll_rand(matching.size());
521
522 gesture = matching[random];
523
502 playGesture(gesture); 524 playGesture(gesture);
503 525
504 if (!gesture->mReplaceText.empty()) 526 if (!gesture->mReplaceText.empty())
505 { 527 {
506 if( !first_token ) 528 if( !first_token )
507 { 529 {
508 revised_string->append( " " ); 530 if (revised_string)
531 revised_string->append( " " );
509 } 532 }
510 533
511 // Don't muck with the user's capitalization if we don't have to. 534 // Don't muck with the user's capitalization if we don't have to.
@@ -514,30 +537,34 @@ BOOL LLGestureManager::triggerAndReviseString(const std::string &utf8str, std::s
514 LLString::toLower(output_lower); 537 LLString::toLower(output_lower);
515 if( cur_token_lower == output_lower ) 538 if( cur_token_lower == output_lower )
516 { 539 {
517 revised_string->append( cur_token ); 540 if (revised_string)
541 revised_string->append( cur_token );
518 } 542 }
519 else 543 else
520 { 544 {
521 revised_string->append( output ); 545 if (revised_string)
546 revised_string->append( output );
522 } 547 }
523 } 548 }
524 found_gestures = TRUE; 549 found_gestures = TRUE;
525 break;
526 } 550 }
527 gesture = NULL;
528 } 551 }
529 } 552 }
530 553
531 if( !gesture ) 554 if(!gesture)
532 { 555 {
556 // This token doesn't match a gesture. Pass it through to the output.
533 if( !first_token ) 557 if( !first_token )
534 { 558 {
535 revised_string->append( " " ); 559 if (revised_string)
560 revised_string->append( " " );
536 } 561 }
537 revised_string->append( cur_token ); 562 if (revised_string)
563 revised_string->append( cur_token );
538 } 564 }
539 565
540 first_token = FALSE; 566 first_token = FALSE;
567 gesture = NULL;
541 } 568 }
542 return found_gestures; 569 return found_gestures;
543} 570}
@@ -545,7 +572,10 @@ BOOL LLGestureManager::triggerAndReviseString(const std::string &utf8str, std::s
545 572
546BOOL LLGestureManager::triggerGesture(KEY key, MASK mask) 573BOOL LLGestureManager::triggerGesture(KEY key, MASK mask)
547{ 574{
575 std::vector <LLMultiGesture *> matching;
548 item_map_t::iterator it; 576 item_map_t::iterator it;
577
578 // collect matching gestures
549 for (it = mActive.begin(); it != mActive.end(); ++it) 579 for (it = mActive.begin(); it != mActive.end(); ++it)
550 { 580 {
551 LLMultiGesture* gesture = (*it).second; 581 LLMultiGesture* gesture = (*it).second;
@@ -556,10 +586,20 @@ BOOL LLGestureManager::triggerGesture(KEY key, MASK mask)
556 if (gesture->mKey == key 586 if (gesture->mKey == key
557 && gesture->mMask == mask) 587 && gesture->mMask == mask)
558 { 588 {
559 playGesture(gesture); 589 matching.push_back(gesture);
560 return TRUE;
561 } 590 }
562 } 591 }
592
593 // choose one and play it
594 if (matching.size() > 0)
595 {
596 U32 random = ll_rand(matching.size());
597
598 LLMultiGesture* gesture = matching[random];
599
600 playGesture(gesture);
601 return TRUE;
602 }
563 return FALSE; 603 return FALSE;
564} 604}
565 605
diff --git a/linden/indra/newview/llgesturemgr.h b/linden/indra/newview/llgesturemgr.h
index 8544599..29aecf3 100644
--- a/linden/indra/newview/llgesturemgr.h
+++ b/linden/indra/newview/llgesturemgr.h
@@ -105,7 +105,7 @@ public:
105 BOOL triggerGesture(KEY key, MASK mask); 105 BOOL triggerGesture(KEY key, MASK mask);
106 106
107 // Trigger all gestures referenced as substrings in this string 107 // Trigger all gestures referenced as substrings in this string
108 BOOL triggerAndReviseString(const std::string &str, std::string *revised_string); 108 BOOL triggerAndReviseString(const std::string &str, std::string *revised_string = NULL);
109 109
110 // Does some gesture have this key bound? 110 // Does some gesture have this key bound?
111 BOOL isKeyBound(KEY key, MASK mask); 111 BOOL isKeyBound(KEY key, MASK mask);
diff --git a/linden/indra/newview/llglslshader.cpp b/linden/indra/newview/llglslshader.cpp
index 9c3d707..cc440c4 100644
--- a/linden/indra/newview/llglslshader.cpp
+++ b/linden/indra/newview/llglslshader.cpp
@@ -180,7 +180,7 @@ static LLString get_object_log(GLhandleARB ret)
180 //the log could be any size, so allocate appropriately 180 //the log could be any size, so allocate appropriately
181 GLcharARB* log = new GLcharARB[length]; 181 GLcharARB* log = new GLcharARB[length];
182 glGetInfoLogARB(ret, length, &length, log); 182 glGetInfoLogARB(ret, length, &length, log);
183 res = LLString(log); 183 res = LLString((char *)log);
184 delete[] log; 184 delete[] log;
185 } 185 }
186 return res; 186 return res;
@@ -249,11 +249,12 @@ GLhandleARB LLShaderMgr::loadShader(const LLString& filename, S32 cls, GLenum ty
249 GLcharARB* text[1024]; 249 GLcharARB* text[1024];
250 GLuint count = 0; 250 GLuint count = 0;
251 251
252
252 //copy file into memory 253 //copy file into memory
253 while(fgets(buff, 1024, file) != NULL) 254 while(fgets((char *)buff, 1024, file) != NULL && count < (sizeof(buff)/sizeof(buff[0])))
254 { 255 {
255 text[count++] = strdup(buff); 256 text[count++] = (GLcharARB *)strdup((char *)buff);
256 } 257 }
257 fclose(file); 258 fclose(file);
258 259
259 //create shader object 260 //create shader object
@@ -1036,7 +1037,7 @@ BOOL LLGLSLShader::mapAttributes(const char** attrib_names, S32 count)
1036 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedAttribCount; i++) 1037 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedAttribCount; i++)
1037 { 1038 {
1038 const char* name = LLShaderMgr::sReservedAttribs[i]; 1039 const char* name = LLShaderMgr::sReservedAttribs[i];
1039 S32 index = glGetAttribLocationARB(mProgramObject, name); 1040 S32 index = glGetAttribLocationARB(mProgramObject, (GLcharARB *)name);
1040 if (index != -1) 1041 if (index != -1)
1041 { 1042 {
1042 mAttribute[i] = index; 1043 mAttribute[i] = index;
@@ -1047,7 +1048,7 @@ BOOL LLGLSLShader::mapAttributes(const char** attrib_names, S32 count)
1047 for (S32 i = 0; i < count; i++) 1048 for (S32 i = 0; i < count; i++)
1048 { 1049 {
1049 const char* name = attrib_names[i]; 1050 const char* name = attrib_names[i];
1050 S32 index = glGetAttribLocationARB(mProgramObject, name); 1051 S32 index = glGetAttribLocationARB(mProgramObject, (GLcharARB *)name);
1051 if (index != -1) 1052 if (index != -1)
1052 { 1053 {
1053 mAttribute[LLShaderMgr::sReservedAttribCount + i] = index; 1054 mAttribute[LLShaderMgr::sReservedAttribCount + i] = index;
@@ -1074,7 +1075,7 @@ void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count
1074 char name[1024]; /* Flawfinder: ignore */ 1075 char name[1024]; /* Flawfinder: ignore */
1075 name[0] = 0; 1076 name[0] = 0;
1076 1077
1077 glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, name); 1078 glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
1078 1079
1079 //find the index of this uniform 1080 //find the index of this uniform
1080 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedUniformCount; i++) 1081 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedUniformCount; i++)
@@ -1082,7 +1083,7 @@ void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count
1082 if (mUniform[i] == -1 && !strncmp(LLShaderMgr::sReservedUniforms[i],name, strlen(LLShaderMgr::sReservedUniforms[i]))) /* Flawfinder: ignore */ 1083 if (mUniform[i] == -1 && !strncmp(LLShaderMgr::sReservedUniforms[i],name, strlen(LLShaderMgr::sReservedUniforms[i]))) /* Flawfinder: ignore */
1083 { 1084 {
1084 //found it 1085 //found it
1085 S32 location = glGetUniformLocationARB(mProgramObject, name); 1086 S32 location = glGetUniformLocationARB(mProgramObject, (GLcharARB *)name);
1086 mUniform[i] = location; 1087 mUniform[i] = location;
1087 llinfos << "Uniform " << name << " is at location " << location << llendl; 1088 llinfos << "Uniform " << name << " is at location " << location << llendl;
1088 mTexture[i] = mapUniformTextureChannel(location, type); 1089 mTexture[i] = mapUniformTextureChannel(location, type);
@@ -1096,7 +1097,7 @@ void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count
1096 !strncmp(uniform_names[i],name, strlen(uniform_names[i]))) /* Flawfinder: ignore */ 1097 !strncmp(uniform_names[i],name, strlen(uniform_names[i]))) /* Flawfinder: ignore */
1097 { 1098 {
1098 //found it 1099 //found it
1099 S32 location = glGetUniformLocationARB(mProgramObject, name); 1100 S32 location = glGetUniformLocationARB(mProgramObject, (GLcharARB *)name);
1100 mUniform[i+LLShaderMgr::sReservedUniformCount] = location; 1101 mUniform[i+LLShaderMgr::sReservedUniformCount] = location;
1101 llinfos << "Uniform " << name << " is at location " << location << " stored in index " << 1102 llinfos << "Uniform " << name << " is at location " << location << " stored in index " <<
1102 (i+LLShaderMgr::sReservedUniformCount) << llendl; 1103 (i+LLShaderMgr::sReservedUniformCount) << llendl;
@@ -1215,7 +1216,7 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
1215void LLScatterShader::init(GLhandleARB shader, int map_stage) 1216void LLScatterShader::init(GLhandleARB shader, int map_stage)
1216{ 1217{
1217 glUseProgramObjectARB(shader); 1218 glUseProgramObjectARB(shader);
1218 glUniform1iARB(glGetUniformLocationARB(shader, "scatterMap"), map_stage); 1219 glUniform1iARB(glGetUniformLocationARB(shader, (GLcharARB *)"scatterMap"), map_stage);
1219 glUseProgramObjectARB(0); 1220 glUseProgramObjectARB(0);
1220} 1221}
1221 1222
diff --git a/linden/indra/newview/llhoverview.cpp b/linden/indra/newview/llhoverview.cpp
index d00b062..f9c3443 100644
--- a/linden/indra/newview/llhoverview.cpp
+++ b/linden/indra/newview/llhoverview.cpp
@@ -224,6 +224,13 @@ void LLHoverView::updateText()
224 mText.deleteAllData(); 224 mText.deleteAllData();
225 if ( hit_object ) 225 if ( hit_object )
226 { 226 {
227 if ( hit_object->isHUDAttachment() )
228 {
229 // no hover tips for HUD elements, since they can obscure
230 // what the HUD is displaying
231 return;
232 }
233
227 if ( hit_object->isAttachment() ) 234 if ( hit_object->isAttachment() )
228 { 235 {
229 // get root of attachment then parent, which is avatar 236 // get root of attachment then parent, which is avatar
diff --git a/linden/indra/newview/llhudeffectlookat.cpp b/linden/indra/newview/llhudeffectlookat.cpp
index 813f924..da0ec60 100644
--- a/linden/indra/newview/llhudeffectlookat.cpp
+++ b/linden/indra/newview/llhudeffectlookat.cpp
@@ -442,12 +442,25 @@ void LLHUDEffectLookAt::update()
442 } 442 }
443} 443}
444 444
445/**
446 * Initializes the mTargetPos member from the current mSourceObjec and mTargetObject
447 * (and possibly mTargetOffsetGlobal).
448 * When mTargetObject is another avatar, it sets mTargetPos to be their eyes.
449 *
450 * Has the side-effect of also calling setAnimationData("LookAtPoint") with the new
451 * mTargetPos on the source object which is assumed to be an avatar.
452 */
445void LLHUDEffectLookAt::calcTargetPosition() 453void LLHUDEffectLookAt::calcTargetPosition()
446{ 454{
447 LLViewerObject *targetObject = (LLViewerObject *)mTargetObject; 455 if (gNoRender)
456 {
457 return;
458 }
459
460 LLViewerObject *target_obj = (LLViewerObject *)mTargetObject;
448 LLVector3 local_offset; 461 LLVector3 local_offset;
449 462
450 if (targetObject) 463 if (target_obj)
451 { 464 {
452 local_offset.setVec(mTargetOffsetGlobal); 465 local_offset.setVec(mTargetOffsetGlobal);
453 } 466 }
@@ -456,20 +469,16 @@ void LLHUDEffectLookAt::calcTargetPosition()
456 local_offset = gAgent.getPosAgentFromGlobal(mTargetOffsetGlobal); 469 local_offset = gAgent.getPosAgentFromGlobal(mTargetOffsetGlobal);
457 } 470 }
458 471
459 if (gNoRender) 472 LLVOAvatar* source_avatar = (LLVOAvatar*)(LLViewerObject*)mSourceObject;
460 {
461 return;
462 }
463 LLVector3 head_position = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
464 473
465 if (targetObject && targetObject->mDrawable.notNull()) 474 if (target_obj && target_obj->mDrawable.notNull())
466 { 475 {
467 LLQuaternion objRot; 476 LLQuaternion target_rot;
468 if (targetObject->isAvatar()) 477 if (target_obj->isAvatar())
469 { 478 {
470 LLVOAvatar *avatarp = (LLVOAvatar *)targetObject; 479 LLVOAvatar *target_av = (LLVOAvatar *)target_obj;
471 480
472 BOOL looking_at_self = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->isSelf() && avatarp->isSelf(); 481 BOOL looking_at_self = source_avatar->isSelf() && target_av->isSelf();
473 482
474 // if selecting self, stare forward 483 // if selecting self, stare forward
475 if (looking_at_self && mTargetOffsetGlobal.magVecSquared() < MIN_TARGET_OFFSET_SQUARED) 484 if (looking_at_self && mTargetOffsetGlobal.magVecSquared() < MIN_TARGET_OFFSET_SQUARED)
@@ -479,46 +488,46 @@ void LLHUDEffectLookAt::calcTargetPosition()
479 local_offset.setVec(mTargetOffsetGlobal); 488 local_offset.setVec(mTargetOffsetGlobal);
480 } 489 }
481 490
482 mTargetPos = avatarp->mHeadp->getWorldPosition(); 491 // look the other avatar in the eye. note: what happens if target is self? -MG
492 mTargetPos = target_av->mHeadp->getWorldPosition();
483 if (mTargetType == LOOKAT_TARGET_MOUSELOOK || mTargetType == LOOKAT_TARGET_FREELOOK) 493 if (mTargetType == LOOKAT_TARGET_MOUSELOOK || mTargetType == LOOKAT_TARGET_FREELOOK)
484 { 494 {
485 // mouselook and freelook target offsets are absolute 495 // mouselook and freelook target offsets are absolute
486 objRot = LLQuaternion::DEFAULT; 496 target_rot = LLQuaternion::DEFAULT;
487 } 497 }
488 else if (looking_at_self && gAgent.cameraCustomizeAvatar()) 498 else if (looking_at_self && gAgent.cameraCustomizeAvatar())
489 { 499 {
490 // *NOTE: We have to do this because animation 500 // *NOTE: We have to do this because animation
491 // overrides do not set lookat behavior. 501 // overrides do not set lookat behavior.
492 // *TODO: animation overrides for lookat behavior. 502 // *TODO: animation overrides for lookat behavior.
493 objRot = avatarp->mPelvisp->getWorldRotation(); 503 target_rot = target_av->mPelvisp->getWorldRotation();
494 } 504 }
495 else 505 else
496 { 506 {
497 objRot = avatarp->mRoot.getWorldRotation(); 507 target_rot = target_av->mRoot.getWorldRotation();
498 } 508 }
499 } 509 }
500 else 510 else // target obj is not an avatar
501 { 511 {
502 if (targetObject->mDrawable->getGeneration() == -1) 512 if (target_obj->mDrawable->getGeneration() == -1)
503 { 513 {
504 mTargetPos = targetObject->getPositionAgent(); 514 mTargetPos = target_obj->getPositionAgent();
505 objRot = targetObject->getWorldRotation(); 515 target_rot = target_obj->getWorldRotation();
506 } 516 }
507 else 517 else
508 { 518 {
509 mTargetPos = targetObject->getRenderPosition(); 519 mTargetPos = target_obj->getRenderPosition();
510 objRot = targetObject->getRenderRotation(); 520 target_rot = target_obj->getRenderRotation();
511 } 521 }
512 } 522 }
513 523
514 mTargetPos += (local_offset * objRot); 524 mTargetPos += (local_offset * target_rot);
515 } 525 }
516 else 526 else // no target obj or it's not drawable
517 { 527 {
518 mTargetPos = local_offset; 528 mTargetPos = local_offset;
519 } 529 }
520 530
521 mTargetPos -= head_position; 531 mTargetPos -= source_avatar->mHeadp->getWorldPosition();
522 532 source_avatar->setAnimationData("LookAtPoint", (void *)&mTargetPos);
523 ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->setAnimationData("LookAtPoint", (void *)&mTargetPos);
524} 533}
diff --git a/linden/indra/newview/llhudmanager.cpp b/linden/indra/newview/llhudmanager.cpp
index f4eeb5b..0da2f8e 100644
--- a/linden/indra/newview/llhudmanager.cpp
+++ b/linden/indra/newview/llhudmanager.cpp
@@ -50,7 +50,6 @@ LLColor4 LLHUDManager::sChildColor;
50 50
51LLHUDManager::LLHUDManager() 51LLHUDManager::LLHUDManager()
52{ 52{
53 mShowPhysical = FALSE;
54 53
55 LLHUDManager::sParentColor = gColors.getColor("FocusColor"); 54 LLHUDManager::sParentColor = gColors.getColor("FocusColor");
56 // rdw commented out since it's not used. Also removed from colors_base.xml 55 // rdw commented out since it's not used. Also removed from colors_base.xml
@@ -59,110 +58,10 @@ LLHUDManager::LLHUDManager()
59 58
60LLHUDManager::~LLHUDManager() 59LLHUDManager::~LLHUDManager()
61{ 60{
62 mHUDJoints.reset();
63 mHUDSelectedJoints.reset();
64 mHUDEffects.reset(); 61 mHUDEffects.reset();
65} 62}
66 63
67 64
68void LLHUDManager::toggleShowPhysical(const BOOL show_physical)
69{
70 if (show_physical == mShowPhysical)
71 {
72 return;
73 }
74
75 mShowPhysical = show_physical;
76 if (show_physical)
77 {
78 S32 i;
79 for (i = 0; i < gObjectList.getNumObjects(); i++)
80 {
81 LLViewerObject *vobjp = gObjectList.getObject(i);
82
83 if (vobjp && vobjp->isJointChild() && vobjp->getParent())
84 {
85 LLHUDConnector *connectorp = (LLHUDConnector *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_CONNECTOR);
86 connectorp->setTargets(vobjp, (LLViewerObject *)vobjp->getParent());
87 connectorp->setColors(LLColor4(1.f, 1.f, 1.f, 1.f), sChildColor, sParentColor);
88 EHavokJointType joint_type = vobjp->getJointType();
89 if (HJT_HINGE == joint_type)
90 {
91 connectorp->setLabel("Hinge");
92 }
93 else if (HJT_POINT == joint_type)
94 {
95 connectorp->setLabel("P2P");
96 }
97#if 0
98 else if (HJT_LPOINT == joint_type)
99 {
100 connectorp->setLabel("LP2P");
101 }
102#endif
103#if 0
104 else if (HJT_WHEEL == joint_type)
105 {
106 connectorp->setLabel("Wheel");
107 }
108#endif
109 mHUDJoints.put(connectorp);
110 }
111 }
112 }
113 else
114 {
115 mHUDJoints.reset();
116 }
117}
118
119void LLHUDManager::showJoints(LLDynamicArray < LLViewerObject* > *object_list)
120{
121 for (S32 i=0; i<object_list->count(); i++)
122 {
123 LLViewerObject *vobjp = object_list->get(i);
124 if (vobjp && vobjp->isJointChild() && vobjp->getParent())
125 {
126 LLHUDConnector *connectorp = (LLHUDConnector *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_CONNECTOR);
127 connectorp->setTargets(vobjp, (LLViewerObject *)vobjp->getParent());
128 connectorp->setColors(LLColor4(1.f, 1.f, 1.f, 1.f), sChildColor, sParentColor);
129
130 EHavokJointType joint_type = vobjp->getJointType();
131 if (HJT_HINGE == joint_type)
132 {
133 connectorp->setLabel("Hinge");
134 }
135 else if (HJT_POINT == joint_type)
136 {
137 connectorp->setLabel("P2P");
138 }
139#if 0
140 else if (HJT_LPOINT == joint_type)
141 {
142 connectorp->setLabel("LP2P");
143 }
144#endif
145#if 0
146 else if (HJT_WHEEL == joint_type)
147 {
148 connectorp->setLabel("Wheel");
149 }
150#endif
151 mHUDSelectedJoints.put(connectorp);
152 }
153 }
154}
155
156void LLHUDManager::clearJoints()
157{
158 mHUDSelectedJoints.reset();
159}
160
161BOOL LLHUDManager::getShowPhysical() const
162{
163 return mShowPhysical;
164}
165
166void LLHUDManager::updateEffects() 65void LLHUDManager::updateEffects()
167{ 66{
168 LLFastTimer ftm(LLFastTimer::FTM_HUD_EFFECTS); 67 LLFastTimer ftm(LLFastTimer::FTM_HUD_EFFECTS);
diff --git a/linden/indra/newview/llhudmanager.h b/linden/indra/newview/llhudmanager.h
index 41cf018..44c8ed5 100644
--- a/linden/indra/newview/llhudmanager.h
+++ b/linden/indra/newview/llhudmanager.h
@@ -50,11 +50,6 @@ public:
50 LLHUDManager(); 50 LLHUDManager();
51 ~LLHUDManager(); 51 ~LLHUDManager();
52 52
53 void toggleShowPhysical(const BOOL show_physical);
54 void showJoints(LLDynamicArray < LLViewerObject* > *object_list);
55 void clearJoints();
56 BOOL getShowPhysical() const;
57
58 LLHUDEffect *createViewerEffect(const U8 type, BOOL send_to_sim = TRUE, BOOL originated_here = TRUE); 53 LLHUDEffect *createViewerEffect(const U8 type, BOOL send_to_sim = TRUE, BOOL originated_here = TRUE);
59 54
60 void updateEffects(); 55 void updateEffects();
@@ -67,12 +62,7 @@ public:
67 static LLColor4 sChildColor; 62 static LLColor4 sChildColor;
68 63
69protected: 64protected:
70 LLDynamicArrayPtr<LLPointer<LLHUDObject> > mHUDJoints;
71 LLDynamicArrayPtr<LLPointer<LLHUDObject> > mHUDSelectedJoints;
72 LLDynamicArrayPtr<LLPointer<LLHUDEffect> > mHUDEffects; 65 LLDynamicArrayPtr<LLPointer<LLHUDEffect> > mHUDEffects;
73
74 // ALT held down this frame?
75 BOOL mShowPhysical;
76}; 66};
77 67
78extern LLHUDManager *gHUDManager; 68extern LLHUDManager *gHUDManager;
diff --git a/linden/indra/newview/llhudobject.cpp b/linden/indra/newview/llhudobject.cpp
index 6032354..3788c29 100644
--- a/linden/indra/newview/llhudobject.cpp
+++ b/linden/indra/newview/llhudobject.cpp
@@ -42,6 +42,7 @@
42#include "llhudeffectlookat.h" 42#include "llhudeffectlookat.h"
43 43
44//Ventrella 44//Ventrella
45#include "llvoicevisualizer.h"
45#include "llanimalcontrols.h" 46#include "llanimalcontrols.h"
46#include "lllocalanimationobject.h" 47#include "lllocalanimationobject.h"
47#include "llcape.h" 48#include "llcape.h"
@@ -225,6 +226,9 @@ LLHUDObject *LLHUDObject::addHUDObject(const U8 type)
225 case LL_HUD_EFFECT_LOOKAT: 226 case LL_HUD_EFFECT_LOOKAT:
226 hud_objectp = new LLHUDEffectLookAt(type); 227 hud_objectp = new LLHUDEffectLookAt(type);
227 break; 228 break;
229 case LL_HUD_EFFECT_VOICE_VISUALIZER:
230 hud_objectp = new LLVoiceVisualizer(type);
231 break;
228 case LL_HUD_EFFECT_POINTAT: 232 case LL_HUD_EFFECT_POINTAT:
229 hud_objectp = new LLHUDEffectPointAt(type); 233 hud_objectp = new LLHUDEffectPointAt(type);
230 break; 234 break;
diff --git a/linden/indra/newview/llhudobject.h b/linden/indra/newview/llhudobject.h
index b3af006..a64fe9b 100644
--- a/linden/indra/newview/llhudobject.h
+++ b/linden/indra/newview/llhudobject.h
@@ -88,7 +88,8 @@ public:
88 LL_HUD_EFFECT_SPIRAL, 88 LL_HUD_EFFECT_SPIRAL,
89 LL_HUD_EFFECT_EDIT, 89 LL_HUD_EFFECT_EDIT,
90 LL_HUD_EFFECT_LOOKAT, 90 LL_HUD_EFFECT_LOOKAT,
91 LL_HUD_EFFECT_POINTAT 91 LL_HUD_EFFECT_POINTAT,
92 LL_HUD_EFFECT_VOICE_VISUALIZER // Ventrella
92 }; 93 };
93protected: 94protected:
94 static void sortObjects(); 95 static void sortObjects();
diff --git a/linden/indra/newview/llhudtext.cpp b/linden/indra/newview/llhudtext.cpp
index fce52f1..20bf486 100644
--- a/linden/indra/newview/llhudtext.cpp
+++ b/linden/indra/newview/llhudtext.cpp
@@ -859,7 +859,8 @@ void LLHUDText::updateAll()
859 } 859 }
860 if (src_textp->mSoftScreenRect.rectInRect(&dst_textp->mSoftScreenRect)) 860 if (src_textp->mSoftScreenRect.rectInRect(&dst_textp->mSoftScreenRect))
861 { 861 {
862 LLRectf intersect_rect = src_textp->mSoftScreenRect & dst_textp->mSoftScreenRect; 862 LLRectf intersect_rect = src_textp->mSoftScreenRect;
863 intersect_rect.intersectWith(dst_textp->mSoftScreenRect);
863 intersect_rect.stretch(-BUFFER_SIZE * 0.5f); 864 intersect_rect.stretch(-BUFFER_SIZE * 0.5f);
864 865
865 F32 src_center_x = src_textp->mSoftScreenRect.getCenterX(); 866 F32 src_center_x = src_textp->mSoftScreenRect.getCenterX();
diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp
index b74fff0..2529d04 100644
--- a/linden/indra/newview/llimpanel.cpp
+++ b/linden/indra/newview/llimpanel.cpp
@@ -33,7 +33,6 @@
33#include "indra_constants.h" 33#include "indra_constants.h"
34#include "llfocusmgr.h" 34#include "llfocusmgr.h"
35#include "llfontgl.h" 35#include "llfontgl.h"
36#include "llhttpclient.h"
37#include "llrect.h" 36#include "llrect.h"
38#include "llerror.h" 37#include "llerror.h"
39#include "llstring.h" 38#include "llstring.h"
@@ -43,12 +42,14 @@
43#include "llagent.h" 42#include "llagent.h"
44#include "llbutton.h" 43#include "llbutton.h"
45#include "llcallingcard.h" 44#include "llcallingcard.h"
45#include "llchat.h"
46#include "llconsole.h" 46#include "llconsole.h"
47#include "llfloater.h" 47#include "llfloater.h"
48#include "llinventory.h" 48#include "llinventory.h"
49#include "llinventorymodel.h" 49#include "llinventorymodel.h"
50#include "llinventoryview.h" 50#include "llinventoryview.h"
51#include "llfloateravatarinfo.h" 51#include "llfloateravatarinfo.h"
52#include "llfloaterchat.h"
52#include "llkeyboard.h" 53#include "llkeyboard.h"
53#include "lllineeditor.h" 54#include "lllineeditor.h"
54#include "llresmgr.h" 55#include "llresmgr.h"
@@ -61,8 +62,13 @@
61#include "llvieweruictrlfactory.h" 62#include "llvieweruictrlfactory.h"
62#include "lllogchat.h" 63#include "lllogchat.h"
63#include "llfloaterhtml.h" 64#include "llfloaterhtml.h"
64#include "llviewerregion.h"
65#include "llweb.h" 65#include "llweb.h"
66#include "llhttpclient.h"
67#include "llfloateractivespeakers.h" // LLSpeakerMgr
68#include "llfloatergroupinfo.h"
69#include "llsdutil.h"
70#include "llnotify.h"
71#include "llmutelist.h"
66 72
67// 73//
68// Constants 74// Constants
@@ -79,6 +85,10 @@ static LLString sTitleString = "Instant Message with [NAME]";
79static LLString sTypingStartString = "[NAME]: ..."; 85static LLString sTypingStartString = "[NAME]: ...";
80static LLString sSessionStartString = "Starting session with [NAME] please wait."; 86static LLString sSessionStartString = "Starting session with [NAME] please wait.";
81 87
88LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap;
89LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap;
90LLVoiceChannel* LLVoiceChannel::sCurrentVoiceChannel = NULL;
91
82void session_starter_helper(const LLUUID& temp_session_id, 92void session_starter_helper(const LLUUID& temp_session_id,
83 const LLUUID& other_participant_id, 93 const LLUUID& other_participant_id,
84 EInstantMessage im_type) 94 EInstantMessage im_type)
@@ -161,45 +171,669 @@ bool send_start_session_messages(const LLUUID& temp_session_id,
161 return false; 171 return false;
162} 172}
163 173
164// Member Functions 174class LLVoiceCallCapResponder : public LLHTTPClient::Responder
175{
176public:
177 LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {};
178
179 virtual void error(U32 status, const std::string& reason); // called with bad status codes
180 virtual void result(const LLSD& content);
181
182private:
183 LLUUID mSessionID;
184};
185
186
187void LLVoiceCallCapResponder::error(U32 status, const std::string& reason)
188{
189 llwarns << "LLVoiceCallCapResponder::error("
190 << status << ": " << reason << ")"
191 << llendl;
192 LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
193 if (channelp)
194 {
195 channelp->deactivate();
196 }
197}
198
199void LLVoiceCallCapResponder::result(const LLSD& content)
200{
201 LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
202 if (channelp)
203 {
204 //*TODO: DEBUG SPAM
205 LLSD::map_const_iterator iter;
206 for(iter = content.beginMap(); iter != content.endMap(); ++iter)
207 {
208 llinfos << "LLVoiceCallCapResponder::result got "
209 << iter->first << llendl;
210 }
211
212 channelp->setChannelInfo(
213 content["voice_credentials"]["channel_uri"].asString(),
214 content["voice_credentials"]["channel_credentials"].asString());
215 }
216}
217
218//
219// LLVoiceChannel
220//
221LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const LLString& session_name) :
222 mSessionID(session_id),
223 mState(STATE_NO_CHANNEL_INFO),
224 mSessionName(session_name),
225 mIgnoreNextSessionLeave(FALSE)
226{
227 mNotifyArgs["[VOICE_CHANNEL_NAME]"] = mSessionName;
228
229 if (!sVoiceChannelMap.insert(std::make_pair(session_id, this)).second)
230 {
231 // a voice channel already exists for this session id, so this instance will be orphaned
232 // the end result should simply be the failure to make voice calls
233 llwarns << "Duplicate voice channels registered for session_id " << session_id << llendl;
234 }
235
236 LLVoiceClient::getInstance()->addStatusObserver(this);
237}
238
239LLVoiceChannel::~LLVoiceChannel()
240{
241 // CANNOT do this here, since it will crash on quit in the LLVoiceChannelProximal singleton destructor.
242 // Do it in all other subclass destructors instead.
243 // deactivate();
244
245 // Don't use LLVoiceClient::getInstance() here -- this can get called during atexit() time and that singleton MAY have already been destroyed.
246 if(gVoiceClient)
247 {
248 gVoiceClient->removeStatusObserver(this);
249 }
250
251 sVoiceChannelMap.erase(mSessionID);
252 sVoiceChannelURIMap.erase(mURI);
253}
254
255void LLVoiceChannel::setChannelInfo(
256 const LLString& uri,
257 const LLString& credentials)
258{
259 setURI(uri);
260
261 mCredentials = credentials;
262
263 if (mState == STATE_NO_CHANNEL_INFO)
264 {
265 if(!mURI.empty() && !mCredentials.empty())
266 {
267 setState(STATE_READY);
268
269 // if we are supposed to be active, reconnect
270 // this will happen on initial connect, as we request credentials on first use
271 if (sCurrentVoiceChannel == this)
272 {
273 // just in case we got new channel info while active
274 // should move over to new channel
275 activate();
276 }
277 }
278 else
279 {
280 //*TODO: notify user
281 llwarns << "Received invalid credentials for channel " << mSessionName << llendl;
282 deactivate();
283 }
284 }
285}
286
287void LLVoiceChannel::onChange(EStatusType type, const std::string &channelURI, bool proximal)
288{
289 if (channelURI != mURI)
290 {
291 return;
292 }
293
294 if (type < BEGIN_ERROR_STATUS)
295 {
296 handleStatusChange(type);
297 }
298 else
299 {
300 handleError(type);
301 }
302}
303
304void LLVoiceChannel::handleStatusChange(EStatusType type)
305{
306 // status updates
307 switch(type)
308 {
309 case STATUS_LOGIN_RETRY:
310 mLoginNotificationHandle = LLNotifyBox::showXml("VoiceLoginRetry")->getHandle();
311 break;
312 case STATUS_LOGGED_IN:
313 if (!mLoginNotificationHandle.isDead())
314 {
315 LLNotifyBox* notifyp = (LLNotifyBox*)LLPanel::getPanelByHandle(mLoginNotificationHandle);
316 if (notifyp)
317 {
318 notifyp->close();
319 }
320 mLoginNotificationHandle.markDead();
321 }
322 break;
323 case STATUS_LEFT_CHANNEL:
324 if (callStarted() && !mIgnoreNextSessionLeave)
325 {
326 // if forceably removed from channel
327 // update the UI and revert to default channel
328 LLNotifyBox::showXml("VoiceChannelDisconnected", mNotifyArgs);
329 deactivate();
330 }
331 mIgnoreNextSessionLeave = FALSE;
332 break;
333 case STATUS_JOINING:
334 if (callStarted())
335 {
336 setState(STATE_RINGING);
337 }
338 break;
339 case STATUS_JOINED:
340 if (callStarted())
341 {
342 setState(STATE_CONNECTED);
343 }
344 default:
345 break;
346 }
347}
348
349// default behavior is to just deactivate channel
350// derived classes provide specific error messages
351void LLVoiceChannel::handleError(EStatusType type)
352{
353 deactivate();
354 setState(STATE_ERROR);
355}
356
357BOOL LLVoiceChannel::isActive()
358{
359 // only considered active when currently bound channel matches what our channel
360 return callStarted() && LLVoiceClient::getInstance()->getCurrentChannel() == mURI;
361}
362
363BOOL LLVoiceChannel::callStarted()
364{
365 return mState >= STATE_CALL_STARTED;
366}
367
368void LLVoiceChannel::deactivate()
369{
370 if (mState >= STATE_RINGING)
371 {
372 // ignore session leave event
373 mIgnoreNextSessionLeave = TRUE;
374 }
375
376 if (callStarted())
377 {
378 setState(STATE_HUNG_UP);
379 }
380 if (sCurrentVoiceChannel == this)
381 {
382 // default channel is proximal channel
383 sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance();
384 sCurrentVoiceChannel->activate();
385 }
386}
387
388void LLVoiceChannel::activate()
389{
390 if (callStarted())
391 {
392 return;
393 }
394
395 // deactivate old channel and mark ourselves as the active one
396 if (sCurrentVoiceChannel != this)
397 {
398 if (sCurrentVoiceChannel)
399 {
400 sCurrentVoiceChannel->deactivate();
401 }
402 sCurrentVoiceChannel = this;
403 }
404
405 if (mState == STATE_NO_CHANNEL_INFO)
406 {
407 // responsible for setting status to active
408 getChannelInfo();
409 }
410 else
411 {
412 setState(STATE_CALL_STARTED);
413 }
414}
415
416void LLVoiceChannel::getChannelInfo()
417{
418 // pretend we have everything we need
419 if (sCurrentVoiceChannel == this)
420 {
421 setState(STATE_CALL_STARTED);
422 }
423}
424
425//static
426LLVoiceChannel* LLVoiceChannel::getChannelByID(const LLUUID& session_id)
427{
428 voice_channel_map_t::iterator found_it = sVoiceChannelMap.find(session_id);
429 if (found_it == sVoiceChannelMap.end())
430 {
431 return NULL;
432 }
433 else
434 {
435 return found_it->second;
436 }
437}
438
439//static
440LLVoiceChannel* LLVoiceChannel::getChannelByURI(LLString uri)
441{
442 voice_channel_map_uri_t::iterator found_it = sVoiceChannelURIMap.find(uri);
443 if (found_it == sVoiceChannelURIMap.end())
444 {
445 return NULL;
446 }
447 else
448 {
449 return found_it->second;
450 }
451}
452
453
454void LLVoiceChannel::updateSessionID(const LLUUID& new_session_id)
455{
456 sVoiceChannelMap.erase(sVoiceChannelMap.find(mSessionID));
457 mSessionID = new_session_id;
458 sVoiceChannelMap.insert(std::make_pair(mSessionID, this));
459}
460
461void LLVoiceChannel::setURI(LLString uri)
462{
463 sVoiceChannelURIMap.erase(mURI);
464 mURI = uri;
465 sVoiceChannelURIMap.insert(std::make_pair(mURI, this));
466}
467
468void LLVoiceChannel::setState(EState state)
469{
470 switch(state)
471 {
472 case STATE_RINGING:
473 gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs);
474 break;
475 case STATE_CONNECTED:
476 gIMMgr->addSystemMessage(mSessionID, "connected", mNotifyArgs);
477 break;
478 case STATE_HUNG_UP:
479 gIMMgr->addSystemMessage(mSessionID, "hang_up", mNotifyArgs);
480 break;
481 default:
482 break;
483 }
484
485 mState = state;
486}
487
488
489//static
490void LLVoiceChannel::initClass()
491{
492 sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance();
493}
494
495//
496// LLVoiceChannelGroup
497//
498
499LLVoiceChannelGroup::LLVoiceChannelGroup(const LLUUID& session_id, const LLString& session_name) :
500 LLVoiceChannel(session_id, session_name)
501{
502}
503
504LLVoiceChannelGroup::~LLVoiceChannelGroup()
505{
506 deactivate();
507}
508
509void LLVoiceChannelGroup::deactivate()
510{
511 if (callStarted())
512 {
513 LLVoiceClient::getInstance()->leaveNonSpatialChannel();
514 }
515 LLVoiceChannel::deactivate();
516}
517
518void LLVoiceChannelGroup::activate()
519{
520 if (callStarted()) return;
521
522 LLVoiceChannel::activate();
523
524 if (callStarted())
525 {
526 // we have the channel info, just need to use it now
527 LLVoiceClient::getInstance()->setNonSpatialChannel(
528 mURI,
529 mCredentials);
530 }
531}
532
533void LLVoiceChannelGroup::getChannelInfo()
534{
535 LLViewerRegion* region = gAgent.getRegion();
536 if (region)
537 {
538 std::string url = region->getCapability("ChatSessionRequest");
539 LLSD data;
540 data["method"] = "call";
541 data["session-id"] = mSessionID;
542 LLHTTPClient::post(url,
543 data,
544 new LLVoiceCallCapResponder(mSessionID));
545 }
546}
547
548void LLVoiceChannelGroup::handleError(EStatusType status)
549{
550 std::string notify;
551 switch(status)
552 {
553 case ERROR_CHANNEL_LOCKED:
554 case ERROR_CHANNEL_FULL:
555 notify = "VoiceChannelFull";
556 break;
557 case ERROR_UNKNOWN:
558 break;
559 default:
560 break;
561 }
562
563 // notification
564 if (!notify.empty())
565 {
566 LLNotifyBox::showXml(notify, mNotifyArgs);
567 // echo to im window
568 gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, LLNotifyBox::getTemplateMessage(notify, mNotifyArgs).c_str());
569 }
570
571 LLVoiceChannel::handleError(status);
572}
573
574//
575// LLVoiceChannelProximal
576//
577LLVoiceChannelProximal::LLVoiceChannelProximal() :
578 LLVoiceChannel(LLUUID::null, LLString::null)
579{
580 activate();
581}
582
583LLVoiceChannelProximal::~LLVoiceChannelProximal()
584{
585 // DO NOT call deactivate() here, since this will only happen at atexit() time.
586}
587
588BOOL LLVoiceChannelProximal::isActive()
589{
590 return callStarted() && LLVoiceClient::getInstance()->inProximalChannel();
591}
592
593void LLVoiceChannelProximal::activate()
594{
595 if (callStarted()) return;
596
597 LLVoiceChannel::activate();
598
599 if (callStarted())
600 {
601 // this implicitly puts you back in the spatial channel
602 LLVoiceClient::getInstance()->leaveNonSpatialChannel();
603 }
604}
605
606void LLVoiceChannelProximal::onChange(EStatusType type, const std::string &channelURI, bool proximal)
607{
608 if (!proximal)
609 {
610 return;
611 }
612
613 if (type < BEGIN_ERROR_STATUS)
614 {
615 handleStatusChange(type);
616 }
617 else
618 {
619 handleError(type);
620 }
621}
622
623void LLVoiceChannelProximal::handleStatusChange(EStatusType status)
624{
625 // status updates
626 switch(status)
627 {
628 case STATUS_LEFT_CHANNEL:
629 // do not notify user when leaving proximal channel
630 return;
631 default:
632 break;
633 }
634 LLVoiceChannel::handleStatusChange(status);
635}
636
637
638void LLVoiceChannelProximal::handleError(EStatusType status)
639{
640 std::string notify;
641 switch(status)
642 {
643 case ERROR_CHANNEL_LOCKED:
644 case ERROR_CHANNEL_FULL:
645 notify = "ProximalVoiceChannelFull";
646 break;
647 default:
648 break;
649 }
650
651 // notification
652 if (!notify.empty())
653 {
654 LLNotifyBox::showXml(notify, mNotifyArgs);
655 }
656
657 LLVoiceChannel::handleError(status);
658}
659
660void LLVoiceChannelProximal::deactivate()
661{
662 if (callStarted())
663 {
664 setState(STATE_HUNG_UP);
665 }
666}
667
165// 668//
669// LLVoiceChannelP2P
670//
671LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const LLString& session_name, const LLUUID& other_user_id) :
672 LLVoiceChannelGroup(session_id, session_name),
673 mOtherUserID(other_user_id)
674{
675 // make sure URI reflects encoded version of other user's agent id
676 setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id));
677}
678
679LLVoiceChannelP2P::~LLVoiceChannelP2P()
680{
681 deactivate();
682}
683
684void LLVoiceChannelP2P::handleStatusChange(EStatusType type)
685{
686 // status updates
687 switch(type)
688 {
689 case STATUS_LEFT_CHANNEL:
690 if (callStarted() && !mIgnoreNextSessionLeave)
691 {
692 if (mState == STATE_RINGING)
693 {
694 // other user declined call
695 LLNotifyBox::showXml("P2PCallDeclined", mNotifyArgs);
696 }
697 else
698 {
699 // other user hung up
700 LLNotifyBox::showXml("VoiceChannelDisconnectedP2P", mNotifyArgs);
701 }
702 deactivate();
703 }
704 mIgnoreNextSessionLeave = FALSE;
705 return;
706 default:
707 break;
708 }
709
710 LLVoiceChannelGroup::handleStatusChange(type);
711}
712
713void LLVoiceChannelP2P::handleError(EStatusType type)
714{
715 switch(type)
716 {
717 case ERROR_NOT_AVAILABLE:
718 LLNotifyBox::showXml("P2PCallNoAnswer", mNotifyArgs);
719 break;
720 default:
721 break;
722 }
723
724 LLVoiceChannelGroup::handleError(type);
725}
726
727void LLVoiceChannelP2P::activate()
728{
729 if (callStarted()) return;
166 730
167LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name, 731 LLVoiceChannel::activate();
168 const LLRect& rect, 732
169 const std::string& session_label, 733 if (callStarted())
170 const LLUUID& session_id, 734 {
171 const LLUUID& other_participant_id, 735 // no session handle yet, we're starting the call
172 EInstantMessage dialog) : 736 if (mSessionHandle.empty())
737 {
738 LLVoiceClient::getInstance()->callUser(mOtherUserID);
739 }
740 // otherwise answering the call
741 else
742 {
743 LLVoiceClient::getInstance()->answerInvite(mSessionHandle, mOtherUserID);
744 // using the session handle invalidates it. Clear it out here so we can't reuse it by accident.
745 mSessionHandle.clear();
746 }
747 }
748}
749
750void LLVoiceChannelP2P::getChannelInfo()
751{
752 // pretend we have everything we need, since P2P doesn't use channel info
753 if (sCurrentVoiceChannel == this)
754 {
755 setState(STATE_CALL_STARTED);
756 }
757}
758
759// receiving session from other user who initiated call
760void LLVoiceChannelP2P::setSessionHandle(const LLString& handle)
761{
762 BOOL needs_activate = FALSE;
763 if (callStarted())
764 {
765 // defer to lower agent id when already active
766 if (mOtherUserID < gAgent.getID())
767 {
768 // pretend we haven't started the call yet, so we can connect to this session instead
769 deactivate();
770 needs_activate = TRUE;
771 }
772 else
773 {
774 // we are active and have priority, invite the other user again
775 // under the assumption they will join this new session
776 mSessionHandle.clear();
777 LLVoiceClient::getInstance()->callUser(mOtherUserID);
778 return;
779 }
780 }
781
782 mSessionHandle = handle;
783 // The URI of a p2p session should always be the other end's SIP URI.
784 setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID));
785
786 if (needs_activate)
787 {
788 activate();
789 }
790}
791
792//
793// LLFloaterIMPanel
794//
795LLFloaterIMPanel::LLFloaterIMPanel(
796 const std::string& name,
797 const LLRect& rect,
798 const std::string& session_label,
799 const LLUUID& session_id,
800 const LLUUID& other_participant_id,
801 EInstantMessage dialog) :
173 LLFloater(name, rect, session_label), 802 LLFloater(name, rect, session_label),
174 mInputEditor(NULL), 803 mInputEditor(NULL),
175 mHistoryEditor(NULL), 804 mHistoryEditor(NULL),
176 mSessionUUID(session_id), 805 mSessionUUID(session_id),
177 mSessionInitRequested(FALSE), 806 mVoiceChannel(NULL),
178 mSessionInitialized(FALSE), 807 mSessionInitialized(FALSE),
808
179 mOtherParticipantUUID(other_participant_id), 809 mOtherParticipantUUID(other_participant_id),
180 mDialog(dialog), 810 mDialog(dialog),
181 mTyping(FALSE), 811 mTyping(FALSE),
182 mOtherTyping(FALSE), 812 mOtherTyping(FALSE),
183 mTypingLineStartIndex(0), 813 mTypingLineStartIndex(0),
184 mSentTypingState(TRUE), 814 mSentTypingState(TRUE),
815 mShowSpeakersOnConnect(TRUE),
816 mAutoConnect(FALSE),
817 mSpeakerPanel(NULL),
185 mFirstKeystrokeTimer(), 818 mFirstKeystrokeTimer(),
186 mLastKeystrokeTimer() 819 mLastKeystrokeTimer()
187{ 820{
188 init(session_label); 821 init(session_label);
189} 822}
190 823
191LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name, 824LLFloaterIMPanel::LLFloaterIMPanel(
192 const LLRect& rect, 825 const std::string& name,
193 const std::string& session_label, 826 const LLRect& rect,
194 const LLUUID& session_id, 827 const std::string& session_label,
195 const LLUUID& other_participant_id, 828 const LLUUID& session_id,
196 const LLDynamicArray<LLUUID>& ids, 829 const LLUUID& other_participant_id,
197 EInstantMessage dialog) : 830 const LLDynamicArray<LLUUID>& ids,
831 EInstantMessage dialog) :
198 LLFloater(name, rect, session_label), 832 LLFloater(name, rect, session_label),
199 mInputEditor(NULL), 833 mInputEditor(NULL),
200 mHistoryEditor(NULL), 834 mHistoryEditor(NULL),
201 mSessionUUID(session_id), 835 mSessionUUID(session_id),
202 mSessionInitRequested(FALSE), 836 mVoiceChannel(NULL),
203 mSessionInitialized(FALSE), 837 mSessionInitialized(FALSE),
204 mOtherParticipantUUID(other_participant_id), 838 mOtherParticipantUUID(other_participant_id),
205 mDialog(dialog), 839 mDialog(dialog),
@@ -207,6 +841,10 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name,
207 mOtherTyping(FALSE), 841 mOtherTyping(FALSE),
208 mTypingLineStartIndex(0), 842 mTypingLineStartIndex(0),
209 mSentTypingState(TRUE), 843 mSentTypingState(TRUE),
844 mShowSpeakersOnConnect(TRUE),
845 mAutoConnect(FALSE),
846 mSpeakers(NULL),
847 mSpeakerPanel(NULL),
210 mFirstKeystrokeTimer(), 848 mFirstKeystrokeTimer(),
211 mLastKeystrokeTimer() 849 mLastKeystrokeTimer()
212{ 850{
@@ -217,11 +855,53 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name,
217 855
218void LLFloaterIMPanel::init(const LLString& session_label) 856void LLFloaterIMPanel::init(const LLString& session_label)
219{ 857{
858 LLString xml_filename;
859 switch(mDialog)
860 {
861 case IM_SESSION_GROUP_START:
862 mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
863 xml_filename = "floater_instant_message_group.xml";
864 mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, session_label);
865 break;
866 case IM_SESSION_INVITE:
867 mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
868 if (gAgent.isInGroup(mSessionUUID))
869 {
870 xml_filename = "floater_instant_message_group.xml";
871 }
872 else // must be invite to ad hoc IM
873 {
874 xml_filename = "floater_instant_message_ad_hoc.xml";
875 }
876 mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, session_label);
877 break;
878 case IM_SESSION_P2P_INVITE:
879 xml_filename = "floater_instant_message.xml";
880 mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, session_label, mOtherParticipantUUID);
881 break;
882 case IM_SESSION_CONFERENCE_START:
883 mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
884 xml_filename = "floater_instant_message_ad_hoc.xml";
885 mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, session_label);
886 break;
887 // just received text from another user
888 case IM_NOTHING_SPECIAL:
889 xml_filename = "floater_instant_message.xml";
890 mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, session_label, mOtherParticipantUUID);
891 break;
892 default:
893 llwarns << "Unknown session type" << llendl;
894 xml_filename = "floater_instant_message.xml";
895 break;
896 }
897
898 mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
899
220 gUICtrlFactory->buildFloater(this, 900 gUICtrlFactory->buildFloater(this,
221 "floater_instant_message.xml", 901 xml_filename,
222 NULL, 902 &getFactoryMap(),
223 FALSE); 903 FALSE);
224 904
225 setLabel(session_label); 905 setLabel(session_label);
226 setTitle(session_label); 906 setTitle(session_label);
227 mInputEditor->setMaxTextLength(1023); 907 mInputEditor->setMaxTextLength(1023);
@@ -256,21 +936,32 @@ void LLFloaterIMPanel::init(const LLString& session_label)
256 mSessionStartMsgPos = 936 mSessionStartMsgPos =
257 mHistoryEditor->getText().length(); 937 mHistoryEditor->getText().length();
258 938
259 bool log_to_file = false;
260 addHistoryLine( 939 addHistoryLine(
261 session_start, 940 session_start,
262 LLColor4::grey, 941 gSavedSettings.getColor4("SystemChatColor"),
263 log_to_file); 942 false);
264 } 943 }
265 } 944 }
266} 945}
267 946
268 947
948LLFloaterIMPanel::~LLFloaterIMPanel()
949{
950 delete mSpeakers;
951 mSpeakers = NULL;
952
953 //kicks you out of the voice channel if it is currently active
954
955 // HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
956 mVoiceChannel->deactivate();
957
958 delete mVoiceChannel;
959 mVoiceChannel = NULL;
960}
961
269BOOL LLFloaterIMPanel::postBuild() 962BOOL LLFloaterIMPanel::postBuild()
270{ 963{
271 requires("chat_editor", WIDGET_TYPE_LINE_EDITOR); 964 requires("chat_editor", WIDGET_TYPE_LINE_EDITOR);
272 requires("profile_btn", WIDGET_TYPE_BUTTON);
273 requires("close_btn", WIDGET_TYPE_BUTTON);
274 requires("im_history", WIDGET_TYPE_TEXT_EDITOR); 965 requires("im_history", WIDGET_TYPE_TEXT_EDITOR);
275 requires("live_help_dialog", WIDGET_TYPE_TEXT_BOX); 966 requires("live_help_dialog", WIDGET_TYPE_TEXT_BOX);
276 requires("title_string", WIDGET_TYPE_TEXT_BOX); 967 requires("title_string", WIDGET_TYPE_TEXT_BOX);
@@ -283,22 +974,28 @@ BOOL LLFloaterIMPanel::postBuild()
283 mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived ); 974 mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived );
284 mInputEditor->setFocusLostCallback( onInputEditorFocusLost ); 975 mInputEditor->setFocusLostCallback( onInputEditorFocusLost );
285 mInputEditor->setKeystrokeCallback( onInputEditorKeystroke ); 976 mInputEditor->setKeystrokeCallback( onInputEditorKeystroke );
977 mInputEditor->setCommitCallback( onCommitChat );
286 mInputEditor->setCallbackUserData(this); 978 mInputEditor->setCallbackUserData(this);
287 mInputEditor->setCommitOnFocusLost( FALSE ); 979 mInputEditor->setCommitOnFocusLost( FALSE );
288 mInputEditor->setRevertOnEsc( FALSE ); 980 mInputEditor->setRevertOnEsc( FALSE );
289 981
290 LLButton* profile_btn = LLUICtrlFactory::getButtonByName(this, "profile_btn"); 982 childSetAction("profile_callee_btn", onClickProfile, this);
291 profile_btn->setClickedCallback(&LLFloaterIMPanel::onClickProfile, this); 983 childSetAction("group_info_btn", onClickGroupInfo, this);
984
985 childSetAction("start_call_btn", onClickStartCall, this);
986 childSetAction("end_call_btn", onClickEndCall, this);
987 childSetAction("send_btn", onClickSend, this);
988 childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
292 989
293 LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn"); 990 //LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn");
294 close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); 991 //close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this);
295 992
296 mHistoryEditor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "im_history"); 993 mHistoryEditor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "im_history");
297 mHistoryEditor->setParseHTML(TRUE); 994 mHistoryEditor->setParseHTML(TRUE);
298 995
299 if (IM_SESSION_GROUP_START == mDialog) 996 if ( IM_SESSION_GROUP_START == mDialog )
300 { 997 {
301 profile_btn->setEnabled(FALSE); 998 childSetEnabled("profile_btn", FALSE);
302 } 999 }
303 LLTextBox* title = LLUICtrlFactory::getTextBoxByName(this, "title_string"); 1000 LLTextBox* title = LLUICtrlFactory::getTextBoxByName(this, "title_string");
304 sTitleString = title->getText(); 1001 sTitleString = title->getText();
@@ -311,16 +1008,91 @@ BOOL LLFloaterIMPanel::postBuild()
311 this, 1008 this,
312 "session_start_string"); 1009 "session_start_string");
313 sSessionStartString = session_start->getText(); 1010 sSessionStartString = session_start->getText();
1011 if (mSpeakerPanel)
1012 {
1013 mSpeakerPanel->refreshSpeakers();
1014 }
314 1015
1016 if (mDialog == IM_NOTHING_SPECIAL)
1017 {
1018 childSetCommitCallback("mute_btn", onClickMuteVoice, this);
1019 childSetCommitCallback("speaker_volume", onVolumeChange, this);
1020 }
1021
1022 setDefaultBtn("send_btn");
315 return TRUE; 1023 return TRUE;
316 } 1024 }
317 1025
318 return FALSE; 1026 return FALSE;
319} 1027}
320 1028
1029void* LLFloaterIMPanel::createSpeakersPanel(void* data)
1030{
1031 LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)data;
1032 floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(floaterp->mSpeakers, TRUE);
1033 return floaterp->mSpeakerPanel;
1034}
1035
1036//static
1037void LLFloaterIMPanel::onClickMuteVoice(LLUICtrl* source, void* user_data)
1038{
1039 LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data;
1040 if (floaterp)
1041 {
1042 BOOL is_muted = gMuteListp->isMuted(floaterp->mOtherParticipantUUID, LLMute::flagVoiceChat);
1043
1044 LLMute mute(floaterp->mOtherParticipantUUID, floaterp->getTitle(), LLMute::AGENT);
1045 if (!is_muted)
1046 {
1047 gMuteListp->add(mute, LLMute::flagVoiceChat);
1048 }
1049 else
1050 {
1051 gMuteListp->remove(mute, LLMute::flagVoiceChat);
1052 }
1053 }
1054}
1055
1056//static
1057void LLFloaterIMPanel::onVolumeChange(LLUICtrl* source, void* user_data)
1058{
1059 LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data;
1060 if (floaterp)
1061 {
1062 gVoiceClient->setUserVolume(floaterp->mOtherParticipantUUID, (F32)source->getValue().asReal());
1063 }
1064}
1065
1066
321// virtual 1067// virtual
322void LLFloaterIMPanel::draw() 1068void LLFloaterIMPanel::draw()
323{ 1069{
1070 LLViewerRegion* region = gAgent.getRegion();
1071
1072 BOOL enable_connect = (region && region->getCapability("ChatSessionRequest") != "")
1073 && mSessionInitialized
1074 && LLVoiceClient::voiceEnabled();
1075
1076 // hide/show start call and end call buttons
1077 childSetVisible("end_call_btn", mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
1078 childSetVisible("start_call_btn", mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
1079 childSetEnabled("start_call_btn", enable_connect);
1080 childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
1081
1082 if (mAutoConnect && enable_connect)
1083 {
1084 onClickStartCall(this);
1085 mAutoConnect = FALSE;
1086 }
1087
1088 // show speakers window when voice first connects
1089 if (mShowSpeakersOnConnect && mVoiceChannel->isActive())
1090 {
1091 childSetVisible("active_speakers_panel", TRUE);
1092 mShowSpeakersOnConnect = FALSE;
1093 }
1094 childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel"));
1095
324 if (mTyping) 1096 if (mTyping)
325 { 1097 {
326 // Time out if user hasn't typed for a while. 1098 // Time out if user hasn't typed for a while.
@@ -339,6 +1111,19 @@ void LLFloaterIMPanel::draw()
339 } 1111 }
340 } 1112 }
341 1113
1114 if (mSpeakerPanel)
1115 {
1116 mSpeakerPanel->refreshSpeakers();
1117 }
1118 else
1119 {
1120 // refresh volume and mute checkbox
1121 childSetEnabled("speaker_volume", mVoiceChannel->isActive());
1122 childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID));
1123
1124 childSetValue("mute_btn", gMuteListp->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
1125 childSetEnabled("mute_btn", mVoiceChannel->isActive());
1126 }
342 LLFloater::draw(); 1127 LLFloater::draw();
343} 1128}
344 1129
@@ -363,16 +1148,22 @@ private:
363 1148
364BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids) 1149BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
365{ 1150{
1151 LLViewerRegion* region = gAgent.getRegion();
1152 if (!region)
1153 {
1154 return FALSE;
1155 }
1156
366 S32 count = ids.count(); 1157 S32 count = ids.count();
367 1158
368 if( isAddAllowed() && (count > 0) ) 1159 if( isInviteAllowed() && (count > 0) )
369 { 1160 {
370 llinfos << "LLFloaterIMPanel::inviteToSession() - adding participants" << llendl; 1161 llinfos << "LLFloaterIMPanel::inviteToSession() - inviting participants" << llendl;
371 1162
372 std::string url = 1163 std::string url = region->getCapability("ChatSessionRequest");
373 gAgent.getRegion()->getCapability("ChatSessionRequest");
374 1164
375 LLSD data; 1165 LLSD data;
1166
376 data["params"] = LLSD::emptyArray(); 1167 data["params"] = LLSD::emptyArray();
377 for (int i = 0; i < count; i++) 1168 for (int i = 0; i < count; i++)
378 { 1169 {
@@ -399,6 +1190,13 @@ BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
399 return TRUE; 1190 return TRUE;
400} 1191}
401 1192
1193void LLFloaterIMPanel::addHistoryLine(const LLUUID& source, const std::string &utf8msg, const LLColor4& color, bool log_to_file)
1194{
1195 addHistoryLine(utf8msg, color, log_to_file);
1196 mSpeakers->speakerChatted(source);
1197 mSpeakers->setSpeakerTyping(source, FALSE);
1198}
1199
402void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file) 1200void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file)
403{ 1201{
404 LLMultiFloater* hostp = getHost(); 1202 LLMultiFloater* hostp = getHost();
@@ -412,7 +1210,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
412 // Now we're adding the actual line of text, so erase the 1210 // Now we're adding the actual line of text, so erase the
413 // "Foo is typing..." text segment, and the optional timestamp 1211 // "Foo is typing..." text segment, and the optional timestamp
414 // if it was present. JC 1212 // if it was present. JC
415 removeTypingIndicator(); 1213 removeTypingIndicator(NULL);
416 1214
417 // Actually add the line 1215 // Actually add the line
418 LLString timestring; 1216 LLString timestring;
@@ -491,7 +1289,7 @@ BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_paren
491 // but not shift-return or control-return 1289 // but not shift-return or control-return
492 if ( !gSavedSettings.getBOOL("PinTalkViewOpen") && !(mask & MASK_CONTROL) && !(mask & MASK_SHIFT) ) 1290 if ( !gSavedSettings.getBOOL("PinTalkViewOpen") && !(mask & MASK_CONTROL) && !(mask & MASK_SHIFT) )
493 { 1291 {
494 gIMView->toggle(NULL); 1292 gIMMgr->toggle(NULL);
495 } 1293 }
496 } 1294 }
497 else if ( KEY_ESCAPE == key ) 1295 else if ( KEY_ESCAPE == key )
@@ -502,7 +1300,7 @@ BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_paren
502 // Close talk panel with escape 1300 // Close talk panel with escape
503 if( !gSavedSettings.getBOOL("PinTalkViewOpen") ) 1301 if( !gSavedSettings.getBOOL("PinTalkViewOpen") )
504 { 1302 {
505 gIMView->toggle(NULL); 1303 gIMMgr->toggle(NULL);
506 } 1304 }
507 } 1305 }
508 } 1306 }
@@ -543,7 +1341,7 @@ BOOL LLFloaterIMPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
543 1341
544BOOL LLFloaterIMPanel::dropCallingCard(LLInventoryItem* item, BOOL drop) 1342BOOL LLFloaterIMPanel::dropCallingCard(LLInventoryItem* item, BOOL drop)
545{ 1343{
546 BOOL rv = isAddAllowed(); 1344 BOOL rv = isInviteAllowed();
547 if(rv && item && item->getCreatorUUID().notNull()) 1345 if(rv && item && item->getCreatorUUID().notNull())
548 { 1346 {
549 if(drop) 1347 if(drop)
@@ -563,7 +1361,7 @@ BOOL LLFloaterIMPanel::dropCallingCard(LLInventoryItem* item, BOOL drop)
563 1361
564BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop) 1362BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop)
565{ 1363{
566 BOOL rv = isAddAllowed(); 1364 BOOL rv = isInviteAllowed();
567 if(rv && category) 1365 if(rv && category)
568 { 1366 {
569 LLInventoryModel::cat_array_t cats; 1367 LLInventoryModel::cat_array_t cats;
@@ -592,11 +1390,11 @@ BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop)
592 return rv; 1390 return rv;
593} 1391}
594 1392
595BOOL LLFloaterIMPanel::isAddAllowed() const 1393BOOL LLFloaterIMPanel::isInviteAllowed() const
596{ 1394{
597 1395
598 return ((IM_SESSION_CONFERENCE_START == mDialog) 1396 return ( (IM_SESSION_CONFERENCE_START == mDialog)
599 || (IM_SESSION_INVITE) ); 1397 || (IM_SESSION_INVITE == mDialog) );
600} 1398}
601 1399
602 1400
@@ -621,6 +1419,15 @@ void LLFloaterIMPanel::onClickProfile( void* userdata )
621} 1419}
622 1420
623// static 1421// static
1422void LLFloaterIMPanel::onClickGroupInfo( void* userdata )
1423{
1424 // Bring up the Profile window
1425 LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
1426
1427 LLFloaterGroupInfo::showFromUUID(self->mSessionUUID);
1428}
1429
1430// static
624void LLFloaterIMPanel::onClickClose( void* userdata ) 1431void LLFloaterIMPanel::onClickClose( void* userdata )
625{ 1432{
626 LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; 1433 LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
@@ -631,6 +1438,44 @@ void LLFloaterIMPanel::onClickClose( void* userdata )
631} 1438}
632 1439
633// static 1440// static
1441void LLFloaterIMPanel::onClickStartCall(void* userdata)
1442{
1443 LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
1444
1445 self->mVoiceChannel->activate();
1446}
1447
1448// static
1449void LLFloaterIMPanel::onClickEndCall(void* userdata)
1450{
1451 LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
1452
1453 self->getVoiceChannel()->deactivate();
1454}
1455
1456// static
1457void LLFloaterIMPanel::onClickSend(void* userdata)
1458{
1459 LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata;
1460 self->sendMsg();
1461}
1462
1463// static
1464void LLFloaterIMPanel::onClickToggleActiveSpeakers(void* userdata)
1465{
1466 LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata;
1467
1468 self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel"));
1469}
1470
1471// static
1472void LLFloaterIMPanel::onCommitChat(LLUICtrl* caller, void* userdata)
1473{
1474 LLFloaterIMPanel* self= (LLFloaterIMPanel*) userdata;
1475 self->sendMsg();
1476}
1477
1478// static
634void LLFloaterIMPanel::onInputEditorFocusReceived( LLUICtrl* caller, void* userdata ) 1479void LLFloaterIMPanel::onInputEditorFocusReceived( LLUICtrl* caller, void* userdata )
635{ 1480{
636 LLFloaterIMPanel* self= (LLFloaterIMPanel*) userdata; 1481 LLFloaterIMPanel* self= (LLFloaterIMPanel*) userdata;
@@ -681,7 +1526,7 @@ void LLFloaterIMPanel::onClose(bool app_quitting)
681 mSessionUUID); 1526 mSessionUUID);
682 gAgent.sendReliableMessage(); 1527 gAgent.sendReliableMessage();
683 } 1528 }
684 gIMView->removeSession(mSessionUUID); 1529 gIMMgr->removeSession(mSessionUUID);
685 1530
686 destroy(); 1531 destroy();
687} 1532}
@@ -768,11 +1613,22 @@ void LLFloaterIMPanel::sendMsg()
768 history_echo += ": "; 1613 history_echo += ": ";
769 } 1614 }
770 history_echo += utf8_text; 1615 history_echo += utf8_text;
771 addHistoryLine(history_echo); 1616
1617 BOOL other_was_typing = mOtherTyping;
1618
1619 addHistoryLine(gAgent.getID(), history_echo);
1620
1621 if (other_was_typing)
1622 {
1623 addTypingIndicator(mOtherTypingName);
1624 }
1625
772 } 1626 }
773 } 1627 }
774 else 1628 else
775 { 1629 {
1630 //queue up the message to send once the session is
1631 //initialized
776 mQueuedMsgsForInit.append(utf8_text); 1632 mQueuedMsgsForInit.append(utf8_text);
777 } 1633 }
778 1634
@@ -786,15 +1642,31 @@ void LLFloaterIMPanel::sendMsg()
786 mSentTypingState = TRUE; 1642 mSentTypingState = TRUE;
787} 1643}
788 1644
1645void LLFloaterIMPanel::updateSpeakersList(LLSD speaker_updates)
1646{
1647 mSpeakers->processSpeakerListUpdate(speaker_updates);
1648}
1649
1650void LLFloaterIMPanel::setSpeakersListFromMap(LLSD speaker_map)
1651{
1652 mSpeakers->processSpeakerMap(speaker_map);
1653}
1654
1655void LLFloaterIMPanel::setSpeakersList(LLSD speaker_list)
1656{
1657 mSpeakers->processSpeakerList(speaker_list);
1658}
1659
789void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) 1660void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
790{ 1661{
791 mSessionUUID = session_id; 1662 mSessionUUID = session_id;
1663 mVoiceChannel->updateSessionID(session_id);
792 mSessionInitialized = TRUE; 1664 mSessionInitialized = TRUE;
793 1665
794 //we assume the history editor hasn't moved at all since 1666 //we assume the history editor hasn't moved at all since
795 //we added the starting session message 1667 //we added the starting session message
796 //so, we count how many characters to remove 1668 //so, we count how many characters to remove
797 S32 chars_to_remove = mHistoryEditor->getText().length() - 1669 S32 chars_to_remove = mHistoryEditor->getText().length() -
798 mSessionStartMsgPos; 1670 mSessionStartMsgPos;
799 mHistoryEditor->removeTextFromEnd(chars_to_remove); 1671 mHistoryEditor->removeTextFromEnd(chars_to_remove);
800 1672
@@ -804,13 +1676,18 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
804 iter != mQueuedMsgsForInit.endArray(); 1676 iter != mQueuedMsgsForInit.endArray();
805 ++iter) 1677 ++iter)
806 { 1678 {
807 deliver_message(iter->asString(), 1679 deliver_message(
808 mSessionUUID, 1680 iter->asString(),
809 mOtherParticipantUUID, 1681 mSessionUUID,
810 mDialog); 1682 mOtherParticipantUUID,
1683 mDialog);
811 } 1684 }
812} 1685}
813 1686
1687void LLFloaterIMPanel::requestAutoConnect()
1688{
1689 mAutoConnect = TRUE;
1690}
814 1691
815void LLFloaterIMPanel::setTyping(BOOL typing) 1692void LLFloaterIMPanel::setTyping(BOOL typing)
816{ 1693{
@@ -827,6 +1704,8 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
827 // Will send typing state after a short delay. 1704 // Will send typing state after a short delay.
828 mSentTypingState = FALSE; 1705 mSentTypingState = FALSE;
829 } 1706 }
1707
1708 mSpeakers->setSpeakerTyping(gAgent.getID(), TRUE);
830 } 1709 }
831 else 1710 else
832 { 1711 {
@@ -836,6 +1715,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
836 sendTypingState(FALSE); 1715 sendTypingState(FALSE);
837 mSentTypingState = TRUE; 1716 mSentTypingState = TRUE;
838 } 1717 }
1718 mSpeakers->setSpeakerTyping(gAgent.getID(), FALSE);
839 } 1719 }
840 1720
841 mTyping = typing; 1721 mTyping = typing;
@@ -864,35 +1744,40 @@ void LLFloaterIMPanel::sendTypingState(BOOL typing)
864 gAgent.sendReliableMessage(); 1744 gAgent.sendReliableMessage();
865} 1745}
866 1746
867
868void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, BOOL typing) 1747void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, BOOL typing)
869{ 1748{
870 if (typing) 1749 if (typing)
871 { 1750 {
872 // other user started typing 1751 // other user started typing
873 addTypingIndicator(im_info); 1752 addTypingIndicator(im_info->mName);
874 } 1753 }
875 else 1754 else
876 { 1755 {
877 // other user stopped typing 1756 // other user stopped typing
878 removeTypingIndicator(); 1757 removeTypingIndicator(im_info);
879 } 1758 }
880} 1759}
881 1760
882 1761
883void LLFloaterIMPanel::addTypingIndicator(const LLIMInfo* im_info) 1762void LLFloaterIMPanel::addTypingIndicator(const std::string &name)
884{ 1763{
885 mTypingLineStartIndex = mHistoryEditor->getText().length(); 1764 // we may have lost a "stop-typing" packet, don't add it twice
886 1765 if (!mOtherTyping)
887 LLUIString typing_start = sTypingStartString; 1766 {
888 typing_start.setArg("[NAME]", im_info->mName); 1767 mTypingLineStartIndex = mHistoryEditor->getText().length();
889 bool log_to_file = false; 1768 LLUIString typing_start = sTypingStartString;
890 addHistoryLine(typing_start, LLColor4::grey, log_to_file); 1769 typing_start.setArg("[NAME]", name);
891 mOtherTyping = TRUE; 1770 addHistoryLine(typing_start, gSavedSettings.getColor4("SystemChatColor"), false);
1771 mOtherTypingName = name;
1772 mOtherTyping = TRUE;
1773 }
1774 // MBW -- XXX -- merge from release broke this (argument to this function changed from an LLIMInfo to a name)
1775 // Richard will fix.
1776// mSpeakers->setSpeakerTyping(im_info->mFromID, TRUE);
892} 1777}
893 1778
894 1779
895void LLFloaterIMPanel::removeTypingIndicator() 1780void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
896{ 1781{
897 if (mOtherTyping) 1782 if (mOtherTyping)
898 { 1783 {
@@ -901,6 +1786,10 @@ void LLFloaterIMPanel::removeTypingIndicator()
901 1786
902 S32 chars_to_remove = mHistoryEditor->getText().length() - mTypingLineStartIndex; 1787 S32 chars_to_remove = mHistoryEditor->getText().length() - mTypingLineStartIndex;
903 mHistoryEditor->removeTextFromEnd(chars_to_remove); 1788 mHistoryEditor->removeTextFromEnd(chars_to_remove);
1789 if (im_info)
1790 {
1791 mSpeakers->setSpeakerTyping(im_info->mFromID, FALSE);
1792 }
904 } 1793 }
905} 1794}
906 1795
@@ -913,4 +1802,3 @@ void LLFloaterIMPanel::chatFromLogFile(LLString line, void* userdata)
913 self->mHistoryEditor->appendColoredText(line, false, true, LLColor4::grey); 1802 self->mHistoryEditor->appendColoredText(line, false, true, LLColor4::grey);
914 1803
915} 1804}
916
diff --git a/linden/indra/newview/llimpanel.h b/linden/indra/newview/llimpanel.h
index 10d387e..525f868 100644
--- a/linden/indra/newview/llimpanel.h
+++ b/linden/indra/newview/llimpanel.h
@@ -33,15 +33,122 @@
33#include "lluuid.h" 33#include "lluuid.h"
34#include "lldarray.h" 34#include "lldarray.h"
35#include "llinstantmessage.h" 35#include "llinstantmessage.h"
36#include "llvoiceclient.h"
36 37
37class LLLineEditor; 38class LLLineEditor;
38class LLViewerTextEditor; 39class LLViewerTextEditor;
39class LLInventoryItem; 40class LLInventoryItem;
40class LLInventoryCategory; 41class LLInventoryCategory;
42class LLIMSpeakerMgr;
43class LLPanelActiveSpeakers;
44
45class LLVoiceChannel : public LLVoiceClientStatusObserver
46{
47public:
48 typedef enum e_voice_channel_state
49 {
50 STATE_NO_CHANNEL_INFO,
51 STATE_ERROR,
52 STATE_HUNG_UP,
53 STATE_READY,
54 STATE_CALL_STARTED,
55 STATE_RINGING,
56 STATE_CONNECTED
57 } EState;
58
59 LLVoiceChannel(const LLUUID& session_id, const LLString& session_name);
60 virtual ~LLVoiceChannel();
61
62 void setChannelInfo(const LLString& uri, const LLString& credentials);
63 /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
64
65 virtual void handleStatusChange(EStatusType status);
66 virtual void handleError(EStatusType status);
67 virtual void deactivate();
68 virtual void activate();
69 virtual void getChannelInfo();
70 virtual BOOL isActive();
71 virtual BOOL callStarted();
72 EState getState() { return mState; }
73
74 void updateSessionID(const LLUUID& new_session_id);
75
76 static LLVoiceChannel* getChannelByID(const LLUUID& session_id);
77 static LLVoiceChannel* getChannelByURI(LLString uri);
78 static LLVoiceChannel* getCurrentVoiceChannel() { return sCurrentVoiceChannel; }
79 static void initClass();
80
81protected:
82 void setState(EState state);
83 void setURI(LLString uri);
84
85 LLString mURI;
86 LLString mCredentials;
87 LLUUID mSessionID;
88 EState mState;
89 LLString mSessionName;
90 LLString::format_map_t mNotifyArgs;
91 BOOL mIgnoreNextSessionLeave;
92 LLViewHandle mLoginNotificationHandle;
93
94 typedef std::map<LLUUID, LLVoiceChannel*> voice_channel_map_t;
95 static voice_channel_map_t sVoiceChannelMap;
96
97 typedef std::map<LLString, LLVoiceChannel*> voice_channel_map_uri_t;
98 static voice_channel_map_uri_t sVoiceChannelURIMap;
99
100 static LLVoiceChannel* sCurrentVoiceChannel;
101};
102
103class LLVoiceChannelGroup : public LLVoiceChannel
104{
105public:
106 LLVoiceChannelGroup(const LLUUID& session_id, const LLString& session_name);
107 virtual ~LLVoiceChannelGroup();
108
109 /*virtual*/ void handleError(EStatusType status);
110 /*virtual*/ void activate();
111 /*virtual*/ void deactivate();
112 /*virtual*/ void getChannelInfo();
113};
114
115class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton<LLVoiceChannelProximal>
116{
117public:
118 LLVoiceChannelProximal();
119 virtual ~LLVoiceChannelProximal();
120
121 /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
122 /*virtual*/ void handleStatusChange(EStatusType status);
123 /*virtual*/ void handleError(EStatusType status);
124 /*virtual*/ BOOL isActive();
125 /*virtual*/ void activate();
126 /*virtual*/ void deactivate();
127
128};
129
130class LLVoiceChannelP2P : public LLVoiceChannelGroup
131{
132public:
133 LLVoiceChannelP2P(const LLUUID& session_id, const LLString& session_name, const LLUUID& other_user_id);
134 virtual ~LLVoiceChannelP2P();
135
136 /*virtual*/ void handleStatusChange(EStatusType status);
137 /*virtual*/ void handleError(EStatusType status);
138 /*virtual*/ void activate();
139 /*virtual*/ void getChannelInfo();
140
141 void setSessionHandle(const LLString& handle);
142
143private:
144 LLString mSessionHandle;
145 LLUUID mOtherUserID;
146};
41 147
42class LLFloaterIMPanel : public LLFloater 148class LLFloaterIMPanel : public LLFloater
43{ 149{
44public: 150public:
151
45 // The session id is the id of the session this is for. The target 152 // The session id is the id of the session this is for. The target
46 // refers to the user (or group) that where this session serves as 153 // refers to the user (or group) that where this session serves as
47 // the default. For example, if you open a session though a 154 // the default. For example, if you open a session though a
@@ -60,7 +167,7 @@ public:
60 const LLUUID& target_id, 167 const LLUUID& target_id,
61 const LLDynamicArray<LLUUID>& ids, 168 const LLDynamicArray<LLUUID>& ids,
62 EInstantMessage dialog); 169 EInstantMessage dialog);
63 170 virtual ~LLFloaterIMPanel();
64 171
65 /*virtual*/ BOOL postBuild(); 172 /*virtual*/ BOOL postBuild();
66 173
@@ -73,6 +180,10 @@ public:
73 // Return TRUE if successful, otherwise FALSE. 180 // Return TRUE if successful, otherwise FALSE.
74 BOOL inviteToSession(const LLDynamicArray<LLUUID>& agent_ids); 181 BOOL inviteToSession(const LLDynamicArray<LLUUID>& agent_ids);
75 182
183 void addHistoryLine(const LLUUID& source,
184 const std::string &utf8msg,
185 const LLColor4& color = LLColor4::white,
186 bool log_to_file = true);
76 void addHistoryLine(const std::string &utf8msg, 187 void addHistoryLine(const std::string &utf8msg,
77 const LLColor4& color = LLColor4::white, 188 const LLColor4& color = LLColor4::white,
78 bool log_to_file = true); 189 bool log_to_file = true);
@@ -91,15 +202,32 @@ public:
91 static void onInputEditorFocusReceived( LLUICtrl* caller, void* userdata ); 202 static void onInputEditorFocusReceived( LLUICtrl* caller, void* userdata );
92 static void onInputEditorFocusLost(LLUICtrl* caller, void* userdata); 203 static void onInputEditorFocusLost(LLUICtrl* caller, void* userdata);
93 static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); 204 static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
205 static void onCommitChat(LLUICtrl* caller, void* userdata);
94 static void onTabClick( void* userdata ); 206 static void onTabClick( void* userdata );
95 207
96 static void onClickProfile( void* userdata ); // Profile button pressed 208 static void onClickProfile( void* userdata );
209 static void onClickGroupInfo( void* userdata );
97 static void onClickClose( void* userdata ); 210 static void onClickClose( void* userdata );
211 static void onClickStartCall( void* userdata );
212 static void onClickEndCall( void* userdata );
213 static void onClickSend( void* userdata );
214 static void onClickToggleActiveSpeakers( void* userdata );
215 static void* createSpeakersPanel(void* data);
216
217 //callbacks for P2P muting and volume control
218 static void onClickMuteVoice(LLUICtrl* source, void* user_data);
219 static void onVolumeChange(LLUICtrl* source, void* user_data);
98 220
99 const LLUUID& getSessionID() const { return mSessionUUID; } 221 const LLUUID& getSessionID() const { return mSessionUUID; }
100 const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; } 222 const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
223 void updateSpeakersList(LLSD speaker_updates);
224 void setSpeakersListFromMap(LLSD speaker_list);
225 void setSpeakersList(LLSD speaker_list);
226 LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
101 EInstantMessage getDialogType() const { return mDialog; } 227 EInstantMessage getDialogType() const { return mDialog; }
102 228
229 void requestAutoConnect();
230
103 void sessionInitReplyReceived(const LLUUID& im_session_id); 231 void sessionInitReplyReceived(const LLUUID& im_session_id);
104 232
105 // Handle other participant in the session typing. 233 // Handle other participant in the session typing.
@@ -118,17 +246,17 @@ private:
118 BOOL dropCategory(LLInventoryCategory* category, BOOL drop); 246 BOOL dropCategory(LLInventoryCategory* category, BOOL drop);
119 247
120 // test if local agent can add agents. 248 // test if local agent can add agents.
121 BOOL isAddAllowed() const; 249 BOOL isInviteAllowed() const;
122 250
123 // Called whenever the user starts or stops typing. 251 // Called whenever the user starts or stops typing.
124 // Sends the typing state to the other user if necessary. 252 // Sends the typing state to the other user if necessary.
125 void setTyping(BOOL typing); 253 void setTyping(BOOL typing);
126 254
127 // Add the "User is typing..." indicator. 255 // Add the "User is typing..." indicator.
128 void addTypingIndicator(const LLIMInfo* im_info); 256 void addTypingIndicator(const std::string &name);
129 257
130 // Remove the "User is typing..." indicator. 258 // Remove the "User is typing..." indicator.
131 void removeTypingIndicator(); 259 void removeTypingIndicator(const LLIMInfo* im_info);
132 260
133 void sendTypingState(BOOL typing); 261 void sendTypingState(BOOL typing);
134 262
@@ -145,7 +273,8 @@ private:
145 // 911 ==> Gaurdian_Angel_Group_ID ^ gAgent.getID() 273 // 911 ==> Gaurdian_Angel_Group_ID ^ gAgent.getID()
146 LLUUID mSessionUUID; 274 LLUUID mSessionUUID;
147 275
148 BOOL mSessionInitRequested; 276 LLVoiceChannel* mVoiceChannel;
277
149 BOOL mSessionInitialized; 278 BOOL mSessionInitialized;
150 LLSD mQueuedMsgsForInit; 279 LLSD mQueuedMsgsForInit;
151 280
@@ -165,12 +294,22 @@ private:
165 // Is other user currently typing? 294 // Is other user currently typing?
166 BOOL mOtherTyping; 295 BOOL mOtherTyping;
167 296
297 // name of other user who is currently typing
298 std::string mOtherTypingName;
299
168 // Where does the "User is typing..." line start? 300 // Where does the "User is typing..." line start?
169 S32 mTypingLineStartIndex; 301 S32 mTypingLineStartIndex;
170 //Where does the "Starting session..." line start? 302 // Where does the "Starting session..." line start?
171 S32 mSessionStartMsgPos; 303 S32 mSessionStartMsgPos;
172 304
173 BOOL mSentTypingState; 305 BOOL mSentTypingState;
306
307 BOOL mShowSpeakersOnConnect;
308
309 BOOL mAutoConnect;
310
311 LLIMSpeakerMgr* mSpeakers;
312 LLPanelActiveSpeakers* mSpeakerPanel;
174 313
175 // Optimization: Don't send "User is typing..." until the 314 // Optimization: Don't send "User is typing..." until the
176 // user has actually been typing for a little while. Prevents 315 // user has actually been typing for a little while. Prevents
diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp
index 111852d..9df51b9 100644
--- a/linden/indra/newview/llimview.cpp
+++ b/linden/indra/newview/llimview.cpp
@@ -1,5 +1,5 @@
1/** 1/**
2 * @file llimview.cpp 2 * @file LLIMMgr.cpp
3 * @brief Container for Instant Messaging 3 * @brief Container for Instant Messaging
4 * 4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 5 * Copyright (c) 2001-2007, Linden Research, Inc.
@@ -32,9 +32,9 @@
32 32
33#include "llfontgl.h" 33#include "llfontgl.h"
34#include "llrect.h" 34#include "llrect.h"
35#include "lldbstrings.h"
36#include "llerror.h" 35#include "llerror.h"
37#include "llbutton.h" 36#include "llbutton.h"
37#include "llhttpclient.h"
38#include "llsdutil.h" 38#include "llsdutil.h"
39#include "llstring.h" 39#include "llstring.h"
40#include "linked_lists.h" 40#include "linked_lists.h"
@@ -46,8 +46,8 @@
46#include "llviewerwindow.h" 46#include "llviewerwindow.h"
47#include "llresmgr.h" 47#include "llresmgr.h"
48#include "llfloaterchat.h" 48#include "llfloaterchat.h"
49#include "llfloaterchatterbox.h"
49#include "llfloaternewim.h" 50#include "llfloaternewim.h"
50#include "llhttpclient.h"
51#include "llhttpnode.h" 51#include "llhttpnode.h"
52#include "llimpanel.h" 52#include "llimpanel.h"
53#include "llresizebar.h" 53#include "llresizebar.h"
@@ -62,40 +62,48 @@
62#include "llcallingcard.h" 62#include "llcallingcard.h"
63#include "lltoolbar.h" 63#include "lltoolbar.h"
64#include "llviewermessage.h" 64#include "llviewermessage.h"
65#include "llnotify.h"
65#include "llviewerregion.h" 66#include "llviewerregion.h"
66 67
68#include "llfirstuse.h"
69
67const EInstantMessage GROUP_DIALOG = IM_SESSION_GROUP_START; 70const EInstantMessage GROUP_DIALOG = IM_SESSION_GROUP_START;
68const EInstantMessage DEFAULT_DIALOG = IM_NOTHING_SPECIAL; 71const EInstantMessage DEFAULT_DIALOG = IM_NOTHING_SPECIAL;
69 72
70// 73//
71// Globals 74// Globals
72// 75//
73LLIMView* gIMView = NULL; 76LLIMMgr* gIMMgr = NULL;
74 77
75// 78//
76// Statics 79// Statics
77// 80//
81//*FIXME: make these all either UIStrings or Strings
78static LLString sOnlyUserMessage; 82static LLString sOnlyUserMessage;
79static LLString sOfflineMessage; 83static LLUIString sOfflineMessage;
80 84
81static std::map<std::string,LLString> sEventStringsMap; 85static std::map<std::string,LLString> sEventStringsMap;
82static std::map<std::string,LLString> sErrorStringsMap; 86static std::map<std::string,LLString> sErrorStringsMap;
83static std::map<std::string,LLString> sForceCloseSessionMap; 87static std::map<std::string,LLString> sForceCloseSessionMap;
88static LLUIString sInviteMessage;
84// 89//
85// Helper Functions 90// Helper Functions
86// 91//
87 92
88// returns true if a should appear before b 93// returns true if a should appear before b
89static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b ) 94//static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b )
90{ 95//{
91 return (LLString::compareDict( a->mName, b->mName ) < 0); 96// return (LLString::compareDict( a->mName, b->mName ) < 0);
92} 97//}
93 98
94 99
95// the other_participant_id is either an agent_id, a group_id, or an inventory 100// the other_participant_id is either an agent_id, a group_id, or an inventory
96// folder item_id (collection of calling cards) 101// folder item_id (collection of calling cards)
97static LLUUID compute_session_id(EInstantMessage dialog, 102
98 const LLUUID& other_participant_id) 103// static
104LLUUID LLIMMgr::computeSessionID(
105 EInstantMessage dialog,
106 const LLUUID& other_participant_id)
99{ 107{
100 LLUUID session_id; 108 LLUUID session_id;
101 if (IM_SESSION_GROUP_START == dialog) 109 if (IM_SESSION_GROUP_START == dialog)
@@ -107,6 +115,11 @@ static LLUUID compute_session_id(EInstantMessage dialog,
107 { 115 {
108 session_id.generate(); 116 session_id.generate();
109 } 117 }
118 else if (IM_SESSION_INVITE == dialog)
119 {
120 // use provided session id for invites
121 session_id = other_participant_id;
122 }
110 else 123 else
111 { 124 {
112 LLUUID agent_id = gAgent.getID(); 125 LLUUID agent_id = gAgent.getID();
@@ -131,88 +144,35 @@ static LLUUID compute_session_id(EInstantMessage dialog,
131 144
132LLFloaterIM::LLFloaterIM() 145LLFloaterIM::LLFloaterIM()
133{ 146{
147 // autoresize=false is necessary to avoid resizing of the IM window whenever
148 // a session is opened or closed (it would otherwise resize the window to match
149 // the size of the im-sesssion when they were created. This happens in
150 // LLMultiFloater::resizeToContents() when called through LLMultiFloater::addFloater())
151 this->mAutoResize = FALSE;
134 gUICtrlFactory->buildFloater(this, "floater_im.xml"); 152 gUICtrlFactory->buildFloater(this, "floater_im.xml");
135} 153}
136 154
137BOOL LLFloaterIM::postBuild() 155BOOL LLFloaterIM::postBuild()
138{ 156{
139 requires("only_user_message", WIDGET_TYPE_TEXT_BOX); 157 sOnlyUserMessage = getFormattedUIString("only_user_message");
140 requires("offline_message", WIDGET_TYPE_TEXT_BOX); 158 sOfflineMessage = getUIString("offline_message");
141 requires("generic_request_error", WIDGET_TYPE_TEXT_BOX);
142 requires("insufficient_perms_error", WIDGET_TYPE_TEXT_BOX);
143 requires("generic_request_error", WIDGET_TYPE_TEXT_BOX);
144 requires("add_session_event", WIDGET_TYPE_TEXT_BOX);
145 requires("message_session_event", WIDGET_TYPE_TEXT_BOX);
146 requires("removed_from_group", WIDGET_TYPE_TEXT_BOX);
147
148 if (checkRequirements())
149 {
150 sOnlyUserMessage = childGetText("only_user_message");
151 sOfflineMessage = childGetText("offline_message");
152
153 sErrorStringsMap["generic"] =
154 childGetText("generic_request_error");
155 sErrorStringsMap["unverified"] =
156 childGetText("insufficient_perms_error");
157 sErrorStringsMap["no_user_911"] =
158 childGetText("user_no_help");
159 159
160 sEventStringsMap["add"] = childGetText("add_session_event"); 160 sErrorStringsMap["generic"] =
161 sEventStringsMap["message"] = 161 getFormattedUIString("generic_request_error");
162 childGetText("message_session_event"); 162 sErrorStringsMap["unverified"] =
163 getFormattedUIString("insufficient_perms_error");
164 sErrorStringsMap["no_user_911"] =
165 getFormattedUIString("user_no_help");
163 166
164 sForceCloseSessionMap["removed"] = 167 sEventStringsMap["add"] = childGetText("add_session_event");
165 childGetText("removed_from_group"); 168 sEventStringsMap["message"] =
169 getFormattedUIString("message_session_event");
166 170
167 return TRUE; 171 sForceCloseSessionMap["removed"] =
168 } 172 getFormattedUIString("removed_from_group");
169 return FALSE;
170}
171
172//// virtual
173//BOOL LLFloaterIM::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
174//{
175// BOOL handled = FALSE;
176// if (getEnabled()
177// && mask == (MASK_CONTROL|MASK_SHIFT))
178// {
179// if (key == 'W')
180// {
181// LLFloater* floater = getActiveFloater();
182// if (floater)
183// {
184// if (mTabContainer->getTabCount() == 1)
185// {
186// // trying to close last tab, close
187// // entire window.
188// close();
189// handled = TRUE;
190// }
191// }
192// }
193// }
194// return handled || LLMultiFloater::handleKeyHere(key, mask, called_from_parent);
195//}
196 173
197void LLFloaterIM::onClose(bool app_quitting) 174 sInviteMessage = getUIString("invite_message");
198{ 175 return TRUE;
199 if (!app_quitting)
200 {
201 gSavedSettings.setBOOL("ShowIM", FALSE);
202 }
203 setVisible(FALSE);
204}
205
206//virtual
207void LLFloaterIM::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point)
208{
209 // this code is needed to fix the bug where new IMs received will resize the IM floater.
210 // SL-29075, SL-24556, and others
211 LLRect parent_rect = getRect();
212 S32 dheight = LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT;
213 LLRect rect(0, parent_rect.getHeight()-dheight, parent_rect.getWidth(), 0);
214 floaterp->reshape(rect.getWidth(), rect.getHeight(), TRUE);
215 LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
216} 176}
217 177
218//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 178//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -224,7 +184,7 @@ void LLFloaterIM::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLT
224class LLIMViewFriendObserver : public LLFriendObserver 184class LLIMViewFriendObserver : public LLFriendObserver
225{ 185{
226public: 186public:
227 LLIMViewFriendObserver(LLIMView* tv) : mTV(tv) {} 187 LLIMViewFriendObserver(LLIMMgr* tv) : mTV(tv) {}
228 virtual ~LLIMViewFriendObserver() {} 188 virtual ~LLIMViewFriendObserver() {}
229 virtual void changed(U32 mask) 189 virtual void changed(U32 mask)
230 { 190 {
@@ -234,7 +194,30 @@ public:
234 } 194 }
235 } 195 }
236protected: 196protected:
237 LLIMView* mTV; 197 LLIMMgr* mTV;
198};
199
200
201class LLIMMgr::LLIMSessionInvite
202{
203public:
204 LLIMSessionInvite(const LLUUID& session_id, const LLString& session_name, const LLUUID& caller_id,const LLString& caller_name, EInstantMessage type, const LLString& session_handle, const LLString& notify_box) :
205 mSessionID(session_id),
206 mSessionName(session_name),
207 mCallerID(caller_id),
208 mCallerName(caller_name),
209 mType(type),
210 mSessionHandle(session_handle),
211 mNotifyBox(notify_box)
212 {};
213
214 LLUUID mSessionID;
215 LLString mSessionName;
216 LLUUID mCallerID;
217 LLString mCallerName;
218 EInstantMessage mType;
219 LLString mSessionHandle;
220 LLString mNotifyBox;
238}; 221};
239 222
240 223
@@ -245,7 +228,7 @@ protected:
245// This is a helper function to determine what kind of im session 228// This is a helper function to determine what kind of im session
246// should be used for the given agent. 229// should be used for the given agent.
247// static 230// static
248EInstantMessage LLIMView::defaultIMTypeForAgent(const LLUUID& agent_id) 231EInstantMessage LLIMMgr::defaultIMTypeForAgent(const LLUUID& agent_id)
249{ 232{
250 EInstantMessage type = IM_NOTHING_SPECIAL; 233 EInstantMessage type = IM_NOTHING_SPECIAL;
251 if(is_agent_friend(agent_id)) 234 if(is_agent_friend(agent_id))
@@ -259,20 +242,20 @@ EInstantMessage LLIMView::defaultIMTypeForAgent(const LLUUID& agent_id)
259} 242}
260 243
261// static 244// static
262//void LLIMView::onPinButton(void*) 245//void LLIMMgr::onPinButton(void*)
263//{ 246//{
264// BOOL state = gSavedSettings.getBOOL( "PinTalkViewOpen" ); 247// BOOL state = gSavedSettings.getBOOL( "PinTalkViewOpen" );
265// gSavedSettings.setBOOL( "PinTalkViewOpen", !state ); 248// gSavedSettings.setBOOL( "PinTalkViewOpen", !state );
266//} 249//}
267 250
268// static 251// static
269void LLIMView::toggle(void*) 252void LLIMMgr::toggle(void*)
270{ 253{
271 static BOOL return_to_mouselook = FALSE; 254 static BOOL return_to_mouselook = FALSE;
272 255
273 // Hide the button and show the floater or vice versa. 256 // Hide the button and show the floater or vice versa.
274 llassert( gIMView ); 257 llassert( gIMMgr );
275 BOOL old_state = gIMView->getFloaterOpen(); 258 BOOL old_state = gIMMgr->getFloaterOpen();
276 259
277 // If we're in mouselook and we triggered the Talk View, we want to talk. 260 // If we're in mouselook and we triggered the Talk View, we want to talk.
278 if( gAgent.cameraMouselook() && old_state ) 261 if( gAgent.cameraMouselook() && old_state )
@@ -303,53 +286,39 @@ void LLIMView::toggle(void*)
303 return_to_mouselook = FALSE; 286 return_to_mouselook = FALSE;
304 } 287 }
305 288
306 gIMView->setFloaterOpen( new_state ); 289 gIMMgr->setFloaterOpen( new_state );
307} 290}
308 291
309// 292//
310// Member Functions 293// Member Functions
311// 294//
312 295
313LLIMView::LLIMView(const std::string& name, const LLRect& rect) : 296LLIMMgr::LLIMMgr() :
314 LLView(name, rect, FALSE),
315 mFriendObserver(NULL), 297 mFriendObserver(NULL),
316 mIMReceived(FALSE) 298 mIMReceived(FALSE)
317{ 299{
318 gIMView = this;
319 mFriendObserver = new LLIMViewFriendObserver(this); 300 mFriendObserver = new LLIMViewFriendObserver(this);
320 LLAvatarTracker::instance().addObserver(mFriendObserver); 301 LLAvatarTracker::instance().addObserver(mFriendObserver);
321 302
322 mTalkFloater = new LLFloaterIM(); 303 //*HACK: use floater to initialize string constants from xml file
304 // then delete it right away
305 LLFloaterIM* dummy_floater = new LLFloaterIM();
306 delete dummy_floater;
323 307
324 // New IM Panel 308 mPendingVoiceInvitations = LLSD::emptyMap();
325 mNewIMFloater = new LLFloaterNewIM();
326 mTalkFloater->addFloater(mNewIMFloater, TRUE);
327
328 // Tabs sometimes overlap resize handle
329 mTalkFloater->moveResizeHandleToFront();
330} 309}
331 310
332LLIMView::~LLIMView() 311LLIMMgr::~LLIMMgr()
333{ 312{
334 LLAvatarTracker::instance().removeObserver(mFriendObserver); 313 LLAvatarTracker::instance().removeObserver(mFriendObserver);
335 delete mFriendObserver; 314 delete mFriendObserver;
336 // Children all cleaned up by default view destructor. 315 // Children all cleaned up by default view destructor.
337} 316}
338 317
339EWidgetType LLIMView::getWidgetType() const
340{
341 return WIDGET_TYPE_TALK_VIEW;
342}
343
344LLString LLIMView::getWidgetTag() const
345{
346 return LL_TALK_VIEW_TAG;
347}
348
349// Add a message to a session. 318// Add a message to a session.
350void LLIMView::addMessage( 319void LLIMMgr::addMessage(
351 const LLUUID& session_id, 320 const LLUUID& session_id,
352 const LLUUID& other_participant_id, 321 const LLUUID& target_id,
353 const char* from, 322 const char* from,
354 const char* msg, 323 const char* msg,
355 const char* session_name, 324 const char* session_name,
@@ -358,11 +327,30 @@ void LLIMView::addMessage(
358 const LLUUID& region_id, 327 const LLUUID& region_id,
359 const LLVector3& position) 328 const LLVector3& position)
360{ 329{
330 LLUUID other_participant_id = target_id;
331 bool is_from_system = target_id.isNull();
332
333 // don't process muted IMs
334 if (gMuteListp->isMuted(
335 other_participant_id,
336 LLMute::flagTextChat) && !gMuteListp->isLinden(from))
337 {
338 return;
339 }
340
341 //not sure why...but if it is from ourselves we set the target_id
342 //to be NULL
343 if( other_participant_id == gAgent.getID() )
344 {
345 other_participant_id = LLUUID::null;
346 }
347
361 LLFloaterIMPanel* floater; 348 LLFloaterIMPanel* floater;
362 LLUUID new_session_id = session_id; 349 LLUUID new_session_id = session_id;
363 if (new_session_id.isNull()) 350 if (new_session_id.isNull())
364 { 351 {
365 new_session_id = compute_session_id(dialog, other_participant_id); 352 //no session ID...compute new one
353 new_session_id = computeSessionID(dialog, other_participant_id);
366 } 354 }
367 floater = findFloaterBySession(new_session_id); 355 floater = findFloaterBySession(new_session_id);
368 if (!floater) 356 if (!floater)
@@ -374,20 +362,10 @@ void LLIMView::addMessage(
374 << " by participant " << other_participant_id << llendl; 362 << " by participant " << other_participant_id << llendl;
375 } 363 }
376 } 364 }
377 if(floater)
378 {
379 floater->addHistoryLine(msg);
380 }
381 else
382 {
383 //if we have recently requsted to be dropped from a session
384 //but are still receiving messages from the session, don't make
385 //a new floater
386 if ( mSessionsDropRequested.has(session_id.asString()) )
387 {
388 return ;
389 }
390 365
366 // create IM window as necessary
367 if(!floater)
368 {
391 const char* name = from; 369 const char* name = from;
392 if(session_name && (strlen(session_name)>1)) 370 if(session_name && (strlen(session_name)>1))
393 { 371 {
@@ -395,7 +373,12 @@ void LLIMView::addMessage(
395 } 373 }
396 374
397 375
398 floater = createFloater(new_session_id, other_participant_id, name, dialog, FALSE); 376 floater = createFloater(
377 new_session_id,
378 other_participant_id,
379 name,
380 dialog,
381 FALSE);
399 382
400 // When we get a new IM, and if you are a god, display a bit 383 // When we get a new IM, and if you are a god, display a bit
401 // of information about the source. This is to help liaisons 384 // of information about the source. This is to help liaisons
@@ -415,27 +398,41 @@ void LLIMView::addMessage(
415 //<< "*** region_id: " << region_id << std::endl 398 //<< "*** region_id: " << region_id << std::endl
416 //<< "*** position: " << position << std::endl; 399 //<< "*** position: " << position << std::endl;
417 400
418 floater->addHistoryLine(bonus_info.str()); 401 floater->addHistoryLine(bonus_info.str(), gSavedSettings.getColor4("SystemChatColor"));
419 } 402 }
420 403
421 floater->addHistoryLine(msg);
422 make_ui_sound("UISndNewIncomingIMSession"); 404 make_ui_sound("UISndNewIncomingIMSession");
423 } 405 }
424 406
425 if( !mTalkFloater->getVisible() && !floater->getVisible()) 407 // now add message to floater
408 if ( is_from_system ) // chat came from system
409 {
410 floater->addHistoryLine(
411 other_participant_id,
412 msg,
413 gSavedSettings.getColor4("SystemChatColor"));
414 }
415 else
416 {
417 floater->addHistoryLine(other_participant_id, msg);
418 }
419
420 LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance(LLSD());
421
422 if( !chat_floater->getVisible() && !floater->getVisible())
426 { 423 {
427 //if the IM window is not open and the floater is not visible (i.e. not torn off) 424 //if the IM window is not open and the floater is not visible (i.e. not torn off)
428 LLFloater* previouslyActiveFloater = mTalkFloater->getActiveFloater(); 425 LLFloater* previouslyActiveFloater = chat_floater->getActiveFloater();
429 426
430 // select the newly added floater (or the floater with the new line added to it). 427 // select the newly added floater (or the floater with the new line added to it).
431 // it should be there. 428 // it should be there.
432 mTalkFloater->selectFloater(floater); 429 chat_floater->selectFloater(floater);
433 430
434 //there was a previously unseen IM, make that old tab flashing 431 //there was a previously unseen IM, make that old tab flashing
435 //it is assumed that the most recently unseen IM tab is the one current selected/active 432 //it is assumed that the most recently unseen IM tab is the one current selected/active
436 if ( previouslyActiveFloater && getIMReceived() ) 433 if ( previouslyActiveFloater && getIMReceived() )
437 { 434 {
438 mTalkFloater->setFloaterFlashing(previouslyActiveFloater, TRUE); 435 chat_floater->setFloaterFlashing(previouslyActiveFloater, TRUE);
439 } 436 }
440 437
441 //notify of a new IM 438 //notify of a new IM
@@ -443,37 +440,87 @@ void LLIMView::addMessage(
443 } 440 }
444} 441}
445 442
446void LLIMView::notifyNewIM() 443void LLIMMgr::addSystemMessage(const LLUUID& session_id, const LLString& message_name, const LLString::format_map_t& args)
444{
445 LLUIString message;
446
447 // null session id means near me (chat history)
448 if (session_id.isNull())
449 {
450 LLFloaterChat* floaterp = LLFloaterChat::getInstance();
451
452 message = floaterp->getUIString(message_name);
453 message.setArgList(args);
454
455 LLChat chat(message);
456 chat.mSourceType = CHAT_SOURCE_SYSTEM;
457 LLFloaterChat::getInstance()->addChatHistory(chat);
458 }
459 else // going to IM session
460 {
461 LLFloaterIMPanel* floaterp = findFloaterBySession(session_id);
462 if (floaterp)
463 {
464 message = floaterp->getUIString(message_name);
465 message.setArgList(args);
466
467 gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString().c_str());
468 }
469 }
470}
471
472void LLIMMgr::notifyNewIM()
447{ 473{
448 if(!gIMView->getFloaterOpen()) 474 if(!gIMMgr->getFloaterOpen())
449 { 475 {
450 mIMReceived = TRUE; 476 mIMReceived = TRUE;
451 } 477 }
452} 478}
453 479
454BOOL LLIMView::getIMReceived() const 480void LLIMMgr::clearNewIMNotification()
481{
482 mIMReceived = FALSE;
483}
484
485BOOL LLIMMgr::getIMReceived() const
455{ 486{
456 return mIMReceived; 487 return mIMReceived;
457} 488}
458 489
459// This method returns TRUE if the local viewer has a session 490// This method returns TRUE if the local viewer has a session
460// currently open keyed to the uuid. 491// currently open keyed to the uuid.
461BOOL LLIMView::isIMSessionOpen(const LLUUID& uuid) 492BOOL LLIMMgr::isIMSessionOpen(const LLUUID& uuid)
462{ 493{
463 LLFloaterIMPanel* floater = findFloaterBySession(uuid); 494 LLFloaterIMPanel* floater = findFloaterBySession(uuid);
464 if(floater) return TRUE; 495 if(floater) return TRUE;
465 return FALSE; 496 return FALSE;
466} 497}
467 498
499LLUUID LLIMMgr::addP2PSession(const std::string& name,
500 const LLUUID& other_participant_id,
501 const LLString& voice_session_handle)
502{
503 LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id);
504
505 LLFloaterIMPanel* floater = findFloaterBySession(session_id);
506 if(floater)
507 {
508 LLVoiceChannelP2P* voice_channelp = (LLVoiceChannelP2P*)floater->getVoiceChannel();
509 voice_channelp->setSessionHandle(voice_session_handle);
510 }
511
512 return session_id;
513}
514
468// This adds a session to the talk view. The name is the local name of 515// This adds a session to the talk view. The name is the local name of
469// the session, dialog specifies the type of session. If the session 516// the session, dialog specifies the type of session. If the session
470// exists, it is brought forward. Specifying id = NULL results in an 517// exists, it is brought forward. Specifying id = NULL results in an
471// im session to everyone. Returns the uuid of the session. 518// im session to everyone. Returns the uuid of the session.
472LLUUID LLIMView::addSession(const std::string& name, 519LLUUID LLIMMgr::addSession(const std::string& name,
473 EInstantMessage dialog, 520 EInstantMessage dialog,
474 const LLUUID& other_participant_id) 521 const LLUUID& other_participant_id)
475{ 522{
476 LLUUID session_id = compute_session_id(dialog, other_participant_id); 523 LLUUID session_id = computeSessionID(dialog, other_participant_id);
477 524
478 LLFloaterIMPanel* floater = findFloaterBySession(session_id); 525 LLFloaterIMPanel* floater = findFloaterBySession(session_id);
479 if(!floater) 526 if(!floater)
@@ -489,7 +536,7 @@ LLUUID LLIMView::addSession(const std::string& name,
489 TRUE); 536 TRUE);
490 537
491 noteOfflineUsers(floater, ids); 538 noteOfflineUsers(floater, ids);
492 mTalkFloater->showFloater(floater); 539 LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater);
493 } 540 }
494 else 541 else
495 { 542 {
@@ -502,7 +549,7 @@ LLUUID LLIMView::addSession(const std::string& name,
502 549
503// Adds a session using the given session_id. If the session already exists 550// Adds a session using the given session_id. If the session already exists
504// the dialog type is assumed correct. Returns the uuid of the session. 551// the dialog type is assumed correct. Returns the uuid of the session.
505LLUUID LLIMView::addSession(const std::string& name, 552LLUUID LLIMMgr::addSession(const std::string& name,
506 EInstantMessage dialog, 553 EInstantMessage dialog,
507 const LLUUID& other_participant_id, 554 const LLUUID& other_participant_id,
508 const LLDynamicArray<LLUUID>& ids) 555 const LLDynamicArray<LLUUID>& ids)
@@ -512,7 +559,7 @@ LLUUID LLIMView::addSession(const std::string& name,
512 return LLUUID::null; 559 return LLUUID::null;
513 } 560 }
514 561
515 LLUUID session_id = compute_session_id(dialog, 562 LLUUID session_id = computeSessionID(dialog,
516 other_participant_id); 563 other_participant_id);
517 564
518 LLFloaterIMPanel* floater = findFloaterBySession(session_id); 565 LLFloaterIMPanel* floater = findFloaterBySession(session_id);
@@ -531,7 +578,7 @@ LLUUID LLIMView::addSession(const std::string& name,
531 578
532 noteOfflineUsers(floater, ids); 579 noteOfflineUsers(floater, ids);
533 } 580 }
534 mTalkFloater->showFloater(floater); 581 LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater);
535 //mTabContainer->selectTabPanel(panel); 582 //mTabContainer->selectTabPanel(panel);
536 floater->setInputFocus(TRUE); 583 floater->setInputFocus(TRUE);
537 return floater->getSessionID(); 584 return floater->getSessionID();
@@ -539,134 +586,272 @@ LLUUID LLIMView::addSession(const std::string& name,
539 586
540// This removes the panel referenced by the uuid, and then restores 587// This removes the panel referenced by the uuid, and then restores
541// internal consistency. The internal pointer is not deleted. 588// internal consistency. The internal pointer is not deleted.
542void LLIMView::removeSession(const LLUUID& session_id) 589void LLIMMgr::removeSession(const LLUUID& session_id)
543{ 590{
544 LLFloaterIMPanel* floater = findFloaterBySession(session_id); 591 LLFloaterIMPanel* floater = findFloaterBySession(session_id);
545 if(floater) 592 if(floater)
546 { 593 {
547 mFloaters.erase(floater->getHandle()); 594 mFloaters.erase(floater->getHandle());
548 mTalkFloater->removeFloater(floater); 595 LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater);
549 //mTabContainer->removeTabPanel(floater); 596 //mTabContainer->removeTabPanel(floater);
550 } 597 }
551
552 if ( session_id.notNull() && floater->getDialogType() != IM_NOTHING_SPECIAL )
553 {
554 mSessionsDropRequested[session_id.asString()] = LLSD();
555 }
556} 598}
557 599
558void LLIMView::refresh() 600void LLIMMgr::inviteToSession(
601 const LLUUID& session_id,
602 const LLString& session_name,
603 const LLUUID& caller_id,
604 const LLString& caller_name,
605 EInstantMessage type,
606 const LLString& session_handle)
559{ 607{
560 S32 old_scroll_pos = mNewIMFloater->getScrollPos(); 608 //ignore voice invites from voice-muted residents
561 mNewIMFloater->clearAllTargets(); 609 if (gMuteListp->isMuted(caller_id))
610 {
611 return;
612 }
562 613
563 // build a list of groups. 614 LLString notify_box_type;
564 LLLinkedList<LLGroupData> group_list( group_dictionary_sort );
565 615
566 LLGroupData* group; 616 BOOL ad_hoc_invite = FALSE;
567 S32 count = gAgent.mGroups.count(); 617 if(type == IM_SESSION_P2P_INVITE)
568 S32 i;
569 // read/sort groups on the first pass.
570 for(i = 0; i < count; ++i)
571 { 618 {
572 group = &(gAgent.mGroups.get(i)); 619 notify_box_type = "VoiceInviteP2P";
573 group_list.addDataSorted( group );
574 } 620 }
575 621 else if (gAgent.isInGroup(session_id))
576 // add groups to the floater on the second pass. 622 {
577 for(group = group_list.getFirstData(); 623 notify_box_type = "VoiceInviteGroup";
578 group; 624 }
579 group = group_list.getNextData()) 625 else
580 { 626 {
581 mNewIMFloater->addGroup(group->mID, (void*)(&GROUP_DIALOG), TRUE, FALSE); 627 notify_box_type = "VoiceInviteAdHoc";
628 ad_hoc_invite = TRUE;
582 } 629 }
583 630
584 // build a set of buddies in the current buddy list. 631 LLIMSessionInvite* invite = new LLIMSessionInvite(
585 LLCollectAllBuddies collector; 632 session_id,
586 LLAvatarTracker::instance().applyFunctor(collector); 633 session_name,
587 LLCollectAllBuddies::buddy_map_t::iterator it; 634 caller_id,
588 LLCollectAllBuddies::buddy_map_t::iterator end; 635 caller_name,
589 it = collector.mOnline.begin(); 636 type,
590 end = collector.mOnline.end(); 637 session_handle,
591 for( ; it != end; ++it) 638 notify_box_type);
639
640 LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id);
641 if (channelp && channelp->callStarted())
592 { 642 {
593 mNewIMFloater->addAgent((*it).second, (void*)(&DEFAULT_DIALOG), TRUE); 643 // you have already started a call to the other user, so just accept the invite
644 inviteUserResponse(0, invite);
645 return;
594 } 646 }
595 it = collector.mOffline.begin(); 647
596 end = collector.mOffline.end(); 648 if (type == IM_SESSION_P2P_INVITE || ad_hoc_invite)
597 for( ; it != end; ++it)
598 { 649 {
599 mNewIMFloater->addAgent((*it).second, (void*)(&DEFAULT_DIALOG), FALSE); 650 // is the inviter a friend?
651 if (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)
652 {
653 // if not, and we are ignoring voice invites from non-friends
654 // then silently decline
655 if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
656 {
657 // invite not from a friend, so decline
658 inviteUserResponse(1, invite);
659 return;
660 }
661 }
600 } 662 }
601 663
602 mNewIMFloater->setScrollPos( old_scroll_pos ); 664 if ( !mPendingVoiceInvitations.has(session_id.asString()) )
665 {
666 if (caller_name.empty())
667 {
668 gCacheName->getName(caller_id, onInviteNameLookup, invite);
669 }
670 else
671 {
672 LLString::format_map_t args;
673 args["[NAME]"] = caller_name;
674 args["[GROUP]"] = session_name;
675
676 LLNotifyBox::showXml(notify_box_type,
677 args,
678 inviteUserResponse,
679 (void*)invite);
680
681 }
682 mPendingVoiceInvitations[session_id.asString()] = LLSD();
683 }
603} 684}
604 685
605// JC - This used to set console visibility. It doesn't any more. 686//static
606void LLIMView::setFloaterOpen(BOOL set_open) 687void LLIMMgr::onInviteNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* userdata)
607{ 688{
608 gSavedSettings.setBOOL("ShowIM", set_open); 689 LLIMSessionInvite* invite = (LLIMSessionInvite*)userdata;
609 690
610 //RN "visible" and "open" are considered synonomous for now 691 invite->mCallerName = llformat("%s %s", first, last);
611 if (set_open) 692 invite->mSessionName = invite->mCallerName;
693
694 LLString::format_map_t args;
695 args["[NAME]"] = invite->mCallerName;
696
697 LLNotifyBox::showXml(invite->mNotifyBox,
698 args,
699 inviteUserResponse,
700 (void*)invite);
701}
702
703class LLViewerChatterBoxInvitationAcceptResponder :
704 public LLHTTPClient::Responder
705{
706public:
707 LLViewerChatterBoxInvitationAcceptResponder(
708 const LLUUID& session_id,
709 bool is_voice_invitation)
612 { 710 {
613 mTalkFloater->open(); /*Flawfinder: ignore*/ 711 mSessionID = session_id;
712 mIsVoiceInvitiation = is_voice_invitation;
614 } 713 }
615 else 714
715 void result(const LLSD& content)
616 { 716 {
617 mTalkFloater->close(); 717 if ( gIMMgr)
718 {
719 LLFloaterIMPanel* floaterp =
720 gIMMgr->findFloaterBySession(mSessionID);
721
722 if (floaterp)
723 {
724 floaterp->setSpeakersList(content["agents"]);
725
726 if ( mIsVoiceInvitiation )
727 {
728 floaterp->requestAutoConnect();
729 LLFloaterIMPanel::onClickStartCall(floaterp);
730 }
731 }
732
733 if ( mIsVoiceInvitiation )
734 {
735 gIMMgr->clearPendingVoiceInviation(mSessionID);
736 }
737 }
618 } 738 }
619 739
620 if( set_open ) 740 void error(U32 statusNum, const std::string& reason)
621 { 741 {
622 // notifyNewIM(); 742 //throw something back to the viewer here?
623 743 if ( gIMMgr && mIsVoiceInvitiation )
624 // We're showing the IM, so mark view as non-pending 744 {
625 mIMReceived = FALSE; 745 gIMMgr->clearPendingVoiceInviation(mSessionID);
746 }
626 } 747 }
627}
628 748
749private:
750 LLUUID mSessionID;
751 bool mIsVoiceInvitiation;
752};
629 753
630BOOL LLIMView::getFloaterOpen() 754//static
631{ 755void LLIMMgr::inviteUserResponse(S32 option, void* user_data)
632 return mTalkFloater->getVisible();
633}
634
635void LLIMView::pruneSessions()
636{ 756{
637 if(mNewIMFloater) 757 LLIMSessionInvite* invitep = (LLIMSessionInvite*)user_data;
758
759 switch(option)
638 { 760 {
639 BOOL removed = TRUE; 761 case 0: // accept
640 LLFloaterIMPanel* floater = NULL; 762 {
641 while(removed) 763 if (invitep->mType == IM_SESSION_P2P_INVITE)
764 {
765 // create a normal IM session
766 invitep->mSessionID = gIMMgr->addP2PSession(
767 invitep->mSessionName,
768 invitep->mCallerID,
769 invitep->mSessionHandle);
770
771 LLFloaterIMPanel* im_floater =
772 gIMMgr->findFloaterBySession(
773 invitep->mSessionID);
774 if (im_floater)
775 {
776 im_floater->requestAutoConnect();
777 LLFloaterIMPanel::onClickStartCall(im_floater);
778 }
779
780 gIMMgr->clearPendingVoiceInviation(invitep->mSessionID);
781 }
782 else
783 {
784 gIMMgr->addSession(
785 invitep->mSessionName,
786 invitep->mType,
787 invitep->mSessionID);
788
789 std::string url = gAgent.getRegion()->getCapability(
790 "ChatSessionRequest");
791
792 LLSD data;
793 data["method"] = "accept invitation";
794 data["session-id"] = invitep->mSessionID;
795 LLHTTPClient::post(
796 url,
797 data,
798 new LLViewerChatterBoxInvitationAcceptResponder(
799 invitep->mSessionID,
800 true));
801 }
802 }
803 break;
804 case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
805 {
806 // mute the sender of this invite
807 if (!gMuteListp->isMuted(invitep->mCallerID))
808 {
809 LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT);
810 gMuteListp->add(mute);
811 }
812 }
813 /* FALLTHROUGH */
814
815 case 1: // ignore
642 { 816 {
643 removed = FALSE; 817 if (invitep->mType == IM_SESSION_P2P_INVITE)
644 std::set<LLViewHandle>::iterator handle_it;
645 for(handle_it = mFloaters.begin();
646 handle_it != mFloaters.end();
647 ++handle_it)
648 { 818 {
649 floater = (LLFloaterIMPanel*)LLFloater::getFloaterByHandle(*handle_it); 819 if(gVoiceClient)
650 if(floater && !mNewIMFloater->isUUIDAvailable(floater->getOtherParticipantID()))
651 { 820 {
652 // remove this floater 821 gVoiceClient->declineInvite(invitep->mSessionHandle);
653 removed = TRUE;
654 mFloaters.erase(handle_it++);
655 floater->close();
656 break;
657 } 822 }
658 } 823 }
659 } 824 }
825 break;
660 } 826 }
827
828 delete invitep;
661} 829}
662 830
831void LLIMMgr::refresh()
832{
833}
663 834
664void LLIMView::disconnectAllSessions() 835void LLIMMgr::setFloaterOpen(BOOL set_open)
665{ 836{
666 if(mNewIMFloater) 837 if (set_open)
667 { 838 {
668 mNewIMFloater->setEnabled(FALSE); 839 LLFloaterChatterBox::showInstance(LLSD());
669 } 840 }
841 else
842 {
843 LLFloaterChatterBox::hideInstance(LLSD());
844 }
845}
846
847
848BOOL LLIMMgr::getFloaterOpen()
849{
850 return LLFloaterChatterBox::instanceVisible(LLSD());
851}
852
853void LLIMMgr::disconnectAllSessions()
854{
670 LLFloaterIMPanel* floater = NULL; 855 LLFloaterIMPanel* floater = NULL;
671 std::set<LLViewHandle>::iterator handle_it; 856 std::set<LLViewHandle>::iterator handle_it;
672 for(handle_it = mFloaters.begin(); 857 for(handle_it = mFloaters.begin();
@@ -681,7 +866,7 @@ void LLIMView::disconnectAllSessions()
681 if (floater) 866 if (floater)
682 { 867 {
683 floater->setEnabled(FALSE); 868 floater->setEnabled(FALSE);
684 floater->onClose(TRUE); 869 floater->close(TRUE);
685 } 870 }
686 } 871 }
687} 872}
@@ -690,7 +875,7 @@ void LLIMView::disconnectAllSessions()
690// This method returns the im panel corresponding to the uuid 875// This method returns the im panel corresponding to the uuid
691// provided. The uuid can either be a session id or an agent 876// provided. The uuid can either be a session id or an agent
692// id. Returns NULL if there is no matching panel. 877// id. Returns NULL if there is no matching panel.
693LLFloaterIMPanel* LLIMView::findFloaterBySession(const LLUUID& session_id) 878LLFloaterIMPanel* LLIMMgr::findFloaterBySession(const LLUUID& session_id)
694{ 879{
695 LLFloaterIMPanel* rv = NULL; 880 LLFloaterIMPanel* rv = NULL;
696 std::set<LLViewHandle>::iterator handle_it; 881 std::set<LLViewHandle>::iterator handle_it;
@@ -709,17 +894,25 @@ LLFloaterIMPanel* LLIMView::findFloaterBySession(const LLUUID& session_id)
709} 894}
710 895
711 896
712BOOL LLIMView::hasSession(const LLUUID& session_id) 897BOOL LLIMMgr::hasSession(const LLUUID& session_id)
713{ 898{
714 return (findFloaterBySession(session_id) != NULL); 899 return (findFloaterBySession(session_id) != NULL);
715} 900}
716 901
902void LLIMMgr::clearPendingVoiceInviation(const LLUUID& session_id)
903{
904 if ( mPendingVoiceInvitations.has(session_id.asString()) )
905 {
906 mPendingVoiceInvitations.erase(session_id.asString());
907 }
908}
909
717 910
718// create a floater and update internal representation for 911// create a floater and update internal representation for
719// consistency. Returns the pointer, caller (the class instance since 912// consistency. Returns the pointer, caller (the class instance since
720// it is a private method) is not responsible for deleting the 913// it is a private method) is not responsible for deleting the
721// pointer. Add the floater to this but do not select it. 914// pointer. Add the floater to this but do not select it.
722LLFloaterIMPanel* LLIMView::createFloater( 915LLFloaterIMPanel* LLIMMgr::createFloater(
723 const LLUUID& session_id, 916 const LLUUID& session_id,
724 const LLUUID& other_participant_id, 917 const LLUUID& other_participant_id,
725 const std::string& session_label, 918 const std::string& session_label,
@@ -731,7 +924,7 @@ LLFloaterIMPanel* LLIMView::createFloater(
731 llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl; 924 llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
732 } 925 }
733 926
734 llinfos << "LLIMView::createFloater: from " << other_participant_id 927 llinfos << "LLIMMgr::createFloater: from " << other_participant_id
735 << " in session " << session_id << llendl; 928 << " in session " << session_id << llendl;
736 LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label, 929 LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
737 LLRect(), 930 LLRect(),
@@ -740,12 +933,12 @@ LLFloaterIMPanel* LLIMView::createFloater(
740 other_participant_id, 933 other_participant_id,
741 dialog); 934 dialog);
742 LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END; 935 LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END;
743 mTalkFloater->addFloater(floater, FALSE, i_pt); 936 LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt);
744 mFloaters.insert(floater->getHandle()); 937 mFloaters.insert(floater->getHandle());
745 return floater; 938 return floater;
746} 939}
747 940
748LLFloaterIMPanel* LLIMView::createFloater( 941LLFloaterIMPanel* LLIMMgr::createFloater(
749 const LLUUID& session_id, 942 const LLUUID& session_id,
750 const LLUUID& other_participant_id, 943 const LLUUID& other_participant_id,
751 const std::string& session_label, 944 const std::string& session_label,
@@ -758,7 +951,7 @@ LLFloaterIMPanel* LLIMView::createFloater(
758 llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl; 951 llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
759 } 952 }
760 953
761 llinfos << "LLIMView::createFloater: from " << other_participant_id 954 llinfos << "LLIMMgr::createFloater: from " << other_participant_id
762 << " in session " << session_id << llendl; 955 << " in session " << session_id << llendl;
763 LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label, 956 LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
764 LLRect(), 957 LLRect(),
@@ -768,18 +961,18 @@ LLFloaterIMPanel* LLIMView::createFloater(
768 ids, 961 ids,
769 dialog); 962 dialog);
770 LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END; 963 LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END;
771 mTalkFloater->addFloater(floater, FALSE, i_pt); 964 LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt);
772 mFloaters.insert(floater->getHandle()); 965 mFloaters.insert(floater->getHandle());
773 return floater; 966 return floater;
774} 967}
775 968
776void LLIMView::noteOfflineUsers(LLFloaterIMPanel* floater, 969void LLIMMgr::noteOfflineUsers(LLFloaterIMPanel* floater,
777 const LLDynamicArray<LLUUID>& ids) 970 const LLDynamicArray<LLUUID>& ids)
778{ 971{
779 S32 count = ids.count(); 972 S32 count = ids.count();
780 if(count == 0) 973 if(count == 0)
781 { 974 {
782 floater->addHistoryLine(sOnlyUserMessage); 975 floater->addHistoryLine(sOnlyUserMessage, gSavedSettings.getColor4("SystemChatColor"));
783 } 976 }
784 else 977 else
785 { 978 {
@@ -796,25 +989,25 @@ void LLIMView::noteOfflineUsers(LLFloaterIMPanel* floater,
796 LLUIString offline = sOfflineMessage; 989 LLUIString offline = sOfflineMessage;
797 offline.setArg("[FIRST]", first); 990 offline.setArg("[FIRST]", first);
798 offline.setArg("[LAST]", last); 991 offline.setArg("[LAST]", last);
799 floater->addHistoryLine(offline); 992 floater->addHistoryLine(offline, gSavedSettings.getColor4("SystemChatColor"));
800 } 993 }
801 } 994 }
802 } 995 }
803} 996}
804 997
805void LLIMView::processIMTypingStart(const LLIMInfo* im_info) 998void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info)
806{ 999{
807 processIMTypingCore(im_info, TRUE); 1000 processIMTypingCore(im_info, TRUE);
808} 1001}
809 1002
810void LLIMView::processIMTypingStop(const LLIMInfo* im_info) 1003void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
811{ 1004{
812 processIMTypingCore(im_info, FALSE); 1005 processIMTypingCore(im_info, FALSE);
813} 1006}
814 1007
815void LLIMView::processIMTypingCore(const LLIMInfo* im_info, BOOL typing) 1008void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
816{ 1009{
817 LLUUID session_id = compute_session_id(im_info->mIMType, im_info->mFromID); 1010 LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
818 LLFloaterIMPanel* floater = findFloaterBySession(session_id); 1011 LLFloaterIMPanel* floater = findFloaterBySession(session_id);
819 if (floater) 1012 if (floater)
820 { 1013 {
@@ -822,8 +1015,9 @@ void LLIMView::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
822 } 1015 }
823} 1016}
824 1017
825void LLIMView::updateFloaterSessionID(const LLUUID& old_session_id, 1018void LLIMMgr::updateFloaterSessionID(
826 const LLUUID& new_session_id) 1019 const LLUUID& old_session_id,
1020 const LLUUID& new_session_id)
827{ 1021{
828 LLFloaterIMPanel* floater = findFloaterBySession(old_session_id); 1022 LLFloaterIMPanel* floater = findFloaterBySession(old_session_id);
829 if (floater) 1023 if (floater)
@@ -832,9 +1026,9 @@ void LLIMView::updateFloaterSessionID(const LLUUID& old_session_id,
832 } 1026 }
833} 1027}
834 1028
835void LLIMView::onDropRequestReplyReceived(const LLUUID& session_id) 1029LLFloaterChatterBox* LLIMMgr::getFloater()
836{ 1030{
837 mSessionsDropRequested.erase(session_id.asString()); 1031 return LLFloaterChatterBox::getInstance(LLSD());
838} 1032}
839 1033
840void onConfirmForceCloseError(S32 option, void* data) 1034void onConfirmForceCloseError(S32 option, void* data)
@@ -842,25 +1036,24 @@ void onConfirmForceCloseError(S32 option, void* data)
842 //only 1 option really 1036 //only 1 option really
843 LLFloaterIMPanel* floater = ((LLFloaterIMPanel*) data); 1037 LLFloaterIMPanel* floater = ((LLFloaterIMPanel*) data);
844 1038
845 if ( floater ) floater->onClose(FALSE); 1039 if ( floater ) floater->close(FALSE);
846} 1040}
847 1041
848class LLViewerIMSessionStartReply : public LLHTTPNode 1042class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
849{ 1043{
850public: 1044public:
851 virtual void describe(Description& desc) const 1045 virtual void describe(Description& desc) const
852 { 1046 {
853 desc.shortInfo("Used for receiving a reply to a request to initialize an IM session"); 1047 desc.shortInfo("Used for receiving a reply to a request to initialize an ChatterBox session");
854 desc.postAPI(); 1048 desc.postAPI();
855 desc.input( 1049 desc.input(
856 "{\"client_session_id\": UUID, \"session_id\": UUID, \"success\" boolean, \"reason\": string"); 1050 "{\"client_session_id\": UUID, \"session_id\": UUID, \"success\" boolean, \"reason\": string");
857 desc.source(__FILE__, __LINE__); 1051 desc.source(__FILE__, __LINE__);
858 } 1052 }
859 1053
860 virtual void post( 1054 virtual void post(ResponsePtr response,
861 ResponsePtr response, 1055 const LLSD& context,
862 const LLSD& context, 1056 const LLSD& input) const
863 const LLSD& input) const
864 { 1057 {
865 LLSD body; 1058 LLSD body;
866 LLUUID temp_session_id; 1059 LLUUID temp_session_id;
@@ -874,16 +1067,21 @@ public:
874 if ( success ) 1067 if ( success )
875 { 1068 {
876 session_id = body["session_id"].asUUID(); 1069 session_id = body["session_id"].asUUID();
877 gIMView->updateFloaterSessionID( 1070 gIMMgr->updateFloaterSessionID(
878 temp_session_id, 1071 temp_session_id,
879 session_id); 1072 session_id);
1073 LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
1074 if (floaterp)
1075 {
1076 floaterp->setSpeakersList(body["agents"]);
1077 }
880 } 1078 }
881 else 1079 else
882 { 1080 {
883 //throw an error dialog and close the temp session's 1081 //throw an error dialog and close the temp session's
884 //floater 1082 //floater
885 LLFloaterIMPanel* floater = 1083 LLFloaterIMPanel* floater =
886 gIMView->findFloaterBySession(temp_session_id); 1084 gIMMgr->findFloaterBySession(temp_session_id);
887 if (floater) 1085 if (floater)
888 { 1086 {
889 LLString::format_map_t args; 1087 LLString::format_map_t args;
@@ -891,22 +1089,22 @@ public:
891 sErrorStringsMap[body["error"].asString()]; 1089 sErrorStringsMap[body["error"].asString()];
892 args["[RECIPIENT]"] = floater->getTitle(); 1090 args["[RECIPIENT]"] = floater->getTitle();
893 1091
894 gViewerWindow->alertXml( 1092 gViewerWindow->alertXml("ChatterBoxSessionStartError",
895 "IMSessionStartError", 1093 args,
896 args, 1094 onConfirmForceCloseError,
897 onConfirmForceCloseError, 1095 floater);
898 floater); 1096
899 } 1097 }
900 } 1098 }
901 } 1099 }
902}; 1100};
903 1101
904class LLViewerIMSessionEventReply : public LLHTTPNode 1102class LLViewerChatterBoxSessionEventReply : public LLHTTPNode
905{ 1103{
906public: 1104public:
907 virtual void describe(Description& desc) const 1105 virtual void describe(Description& desc) const
908 { 1106 {
909 desc.shortInfo("Used for receiving a reply to a IM session event"); 1107 desc.shortInfo("Used for receiving a reply to a ChatterBox session event");
910 desc.postAPI(); 1108 desc.postAPI();
911 desc.input( 1109 desc.input(
912 "{\"event\": string, \"reason\": string, \"success\": boolean, \"session_id\": UUID"); 1110 "{\"event\": string, \"reason\": string, \"success\": boolean, \"session_id\": UUID");
@@ -928,7 +1126,7 @@ public:
928 { 1126 {
929 //throw an error dialog 1127 //throw an error dialog
930 LLFloaterIMPanel* floater = 1128 LLFloaterIMPanel* floater =
931 gIMView->findFloaterBySession(session_id); 1129 gIMMgr->findFloaterBySession(session_id);
932 if (floater) 1130 if (floater)
933 { 1131 {
934 LLString::format_map_t args; 1132 LLString::format_map_t args;
@@ -938,14 +1136,14 @@ public:
938 sEventStringsMap[body["event"].asString()]; 1136 sEventStringsMap[body["event"].asString()];
939 args["[RECIPIENT]"] = floater->getTitle(); 1137 args["[RECIPIENT]"] = floater->getTitle();
940 1138
941 gViewerWindow->alertXml("IMSessionEventError", 1139 gViewerWindow->alertXml("ChatterBoxSessionEventError",
942 args); 1140 args);
943 } 1141 }
944 } 1142 }
945 } 1143 }
946}; 1144};
947 1145
948class LLViewerForceCloseIMSession: public LLHTTPNode 1146class LLViewerForceCloseChatterBoxSession: public LLHTTPNode
949{ 1147{
950public: 1148public:
951 virtual void post(ResponsePtr response, 1149 virtual void post(ResponsePtr response,
@@ -959,7 +1157,7 @@ public:
959 reason = input["body"]["reason"].asString(); 1157 reason = input["body"]["reason"].asString();
960 1158
961 LLFloaterIMPanel* floater = 1159 LLFloaterIMPanel* floater =
962 gIMView ->findFloaterBySession(session_id); 1160 gIMMgr ->findFloaterBySession(session_id);
963 1161
964 if ( floater ) 1162 if ( floater )
965 { 1163 {
@@ -968,7 +1166,7 @@ public:
968 args["[NAME]"] = floater->getTitle(); 1166 args["[NAME]"] = floater->getTitle();
969 args["[REASON]"] = sForceCloseSessionMap[reason]; 1167 args["[REASON]"] = sForceCloseSessionMap[reason];
970 1168
971 gViewerWindow->alertXml("ForceCloseIMSession", 1169 gViewerWindow->alertXml("ForceCloseChatterBoxSession",
972 args, 1170 args,
973 onConfirmForceCloseError, 1171 onConfirmForceCloseError,
974 floater); 1172 floater);
@@ -976,28 +1174,6 @@ public:
976 } 1174 }
977}; 1175};
978 1176
979class LLViewerIMSessionDropReply : public LLHTTPNode
980{
981public:
982 virtual void post(ResponsePtr response,
983 const LLSD& context,
984 const LLSD& input) const
985 {
986 LLUUID session_id;
987 bool success;
988
989 success = input["body"]["success"].asBoolean();
990 session_id = input["body"]["session_id"].asUUID();
991
992 if ( !success )
993 {
994 //throw an error alert?
995 }
996
997 gIMView->onDropRequestReplyReceived(session_id);
998 }
999};
1000
1001class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode 1177class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode
1002{ 1178{
1003public: 1179public:
@@ -1006,29 +1182,38 @@ public:
1006 const LLSD& context, 1182 const LLSD& context,
1007 const LLSD& input) const 1183 const LLSD& input) const
1008 { 1184 {
1185 LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
1186 if (floaterp)
1187 {
1188 floaterp->updateSpeakersList(input["body"]["updates"]);
1189 }
1009 } 1190 }
1010}; 1191};
1011 1192
1012class LLViewerChatterBoxInvitation : public LLHTTPNode 1193class LLViewerChatterBoxInvitation : public LLHTTPNode
1013{ 1194{
1014public: 1195public:
1196
1015 virtual void post( 1197 virtual void post(
1016 ResponsePtr responder, 1198 ResponsePtr response,
1017 const LLSD& context, 1199 const LLSD& context,
1018 const LLSD& input) const 1200 const LLSD& input) const
1019 { 1201 {
1020 if ( input["body"].has("instantmessage") ) 1202 if ( input["body"].has("instantmessage") )
1021 { 1203 {
1204 LLString capability = input["body"]["capabilities"]["call"].asString();
1205
1022 LLSD message_params = 1206 LLSD message_params =
1023 input["body"]["instantmessage"]["message_params"]; 1207 input["body"]["instantmessage"]["message_params"];
1024 1208
1209 //do something here to have the IM invite behave
1210 //just like a normal IM
1025 //this is just replicated code from process_improved_im 1211 //this is just replicated code from process_improved_im
1026 //and should really go in it's own function -jwolk 1212 //and should really go in it's own function -jwolk
1027 if (gNoRender) 1213 if (gNoRender)
1028 { 1214 {
1029 return; 1215 return;
1030 } 1216 }
1031
1032 char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ 1217 char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */
1033 LLChat chat; 1218 LLChat chat;
1034 1219
@@ -1043,7 +1228,11 @@ public:
1043 (time_t) message_params["timestamp"].asInteger(); 1228 (time_t) message_params["timestamp"].asInteger();
1044 1229
1045 BOOL is_busy = gAgent.getBusy(); 1230 BOOL is_busy = gAgent.getBusy();
1046 BOOL is_muted = gMuteListp->isMuted(from_id, name); 1231 BOOL is_muted = gMuteListp->isMuted(
1232 from_id,
1233 name.c_str(),
1234 LLMute::flagTextChat);
1235
1047 BOOL is_linden = gMuteListp->isLinden( 1236 BOOL is_linden = gMuteListp->isLinden(
1048 name.c_str()); 1237 name.c_str());
1049 char separator_string[3]=": "; /* Flawfinder: ignore */ 1238 char separator_string[3]=": "; /* Flawfinder: ignore */
@@ -1060,7 +1249,8 @@ public:
1060 chat.mMuted = is_muted && !is_linden; 1249 chat.mMuted = is_muted && !is_linden;
1061 chat.mFromID = from_id; 1250 chat.mFromID = from_id;
1062 chat.mFromName = name; 1251 chat.mFromName = name;
1063 if (!is_linden && is_busy) 1252
1253 if (!is_linden && (is_busy || is_muted))
1064 { 1254 {
1065 return; 1255 return;
1066 } 1256 }
@@ -1088,10 +1278,9 @@ public:
1088 BOOL is_this_agent = FALSE; 1278 BOOL is_this_agent = FALSE;
1089 if(from_id == gAgentID) 1279 if(from_id == gAgentID)
1090 { 1280 {
1091 from_id = LLUUID::null;
1092 is_this_agent = TRUE; 1281 is_this_agent = TRUE;
1093 } 1282 }
1094 gIMView->addMessage( 1283 gIMMgr->addMessage(
1095 session_id, 1284 session_id,
1096 from_id, 1285 from_id,
1097 name.c_str(), 1286 name.c_str(),
@@ -1113,11 +1302,7 @@ public:
1113 chat.mText = buffer; 1302 chat.mText = buffer;
1114 LLFloaterChat::addChat(chat, TRUE, is_this_agent); 1303 LLFloaterChat::addChat(chat, TRUE, is_this_agent);
1115 1304
1116 //if we succesfully accepted the invitation 1305 //K now we want to accept the invitation
1117 //send a message back down
1118
1119 //TODO - When availble, have this response just be part
1120 //of an automatic response system
1121 std::string url = gAgent.getRegion()->getCapability( 1306 std::string url = gAgent.getRegion()->getCapability(
1122 "ChatSessionRequest"); 1307 "ChatSessionRequest");
1123 1308
@@ -1129,28 +1314,46 @@ public:
1129 LLHTTPClient::post( 1314 LLHTTPClient::post(
1130 url, 1315 url,
1131 data, 1316 data,
1132 NULL); 1317 new LLViewerChatterBoxInvitationAcceptResponder(
1318 input["body"]["session_id"],
1319 false));
1133 } 1320 }
1134 } //end if invitation has instant message 1321 } //end if invitation has instant message
1322 else if ( input["body"].has("voice") )
1323 {
1324 if (gNoRender)
1325 {
1326 return;
1327 }
1328
1329 if(!LLVoiceClient::voiceEnabled())
1330 {
1331 // Don't display voice invites unless the user has voice enabled.
1332 return;
1333 }
1334
1335 gIMMgr->inviteToSession(
1336 input["body"]["session_id"].asUUID(),
1337 input["body"]["session_name"].asString(),
1338 input["body"]["from_id"].asUUID(),
1339 input["body"]["from_name"].asString(),
1340 IM_SESSION_INVITE);
1341 }
1135 } 1342 }
1136}; 1343};
1137 1344
1138LLHTTPRegistration<LLViewerIMSessionStartReply> 1345LLHTTPRegistration<LLViewerChatterBoxSessionStartReply>
1139 gHTTPRegistrationMessageImsessionstartreply( 1346 gHTTPRegistrationMessageChatterboxsessionstartreply(
1140 "/message/ChatterBoxSessionStartReply"); 1347 "/message/ChatterBoxSessionStartReply");
1141 1348
1142LLHTTPRegistration<LLViewerIMSessionEventReply> 1349LLHTTPRegistration<LLViewerChatterBoxSessionEventReply>
1143 gHTTPRegistrationMessageImsessioneventreply( 1350 gHTTPRegistrationMessageChatterboxsessioneventreply(
1144 "/message/ChatterBoxSessionEventReply"); 1351 "/message/ChatterBoxSessionEventReply");
1145 1352
1146LLHTTPRegistration<LLViewerForceCloseIMSession> 1353LLHTTPRegistration<LLViewerForceCloseChatterBoxSession>
1147 gHTTPRegistrationMessageForceCloseImSession( 1354 gHTTPRegistrationMessageForceclosechatterboxsession(
1148 "/message/ForceCloseChatterBoxSession"); 1355 "/message/ForceCloseChatterBoxSession");
1149 1356
1150LLHTTPRegistration<LLViewerIMSessionDropReply>
1151 gHTTPRegistrationMessageImSessionDropReply(
1152 "/message/ChatterBoxSessionLeaveReply");
1153
1154LLHTTPRegistration<LLViewerChatterBoxSessionAgentListUpdates> 1357LLHTTPRegistration<LLViewerChatterBoxSessionAgentListUpdates>
1155 gHTTPRegistrationMessageChatterboxsessionagentlistupdates( 1358 gHTTPRegistrationMessageChatterboxsessionagentlistupdates(
1156 "/message/ChatterBoxSessionAgentListUpdates"); 1359 "/message/ChatterBoxSessionAgentListUpdates");
diff --git a/linden/indra/newview/llimview.h b/linden/indra/newview/llimview.h
index c0b0f79..ca3ef5f 100644
--- a/linden/indra/newview/llimview.h
+++ b/linden/indra/newview/llimview.h
@@ -1,5 +1,5 @@
1/** 1/**
2 * @file llimview.h 2 * @file LLIMMgr.h
3 * @brief Container for Instant Messaging 3 * @brief Container for Instant Messaging
4 * 4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 5 * Copyright (c) 2001-2007, Linden Research, Inc.
@@ -33,31 +33,32 @@
33#include "llinstantmessage.h" 33#include "llinstantmessage.h"
34#include "lluuid.h" 34#include "lluuid.h"
35 35
36class LLFloaterNewIM; 36class LLFloaterChatterBox;
37class LLUUID; 37class LLUUID;
38class LLFloaterIMPanel; 38class LLFloaterIMPanel;
39class LLFriendObserver; 39class LLFriendObserver;
40class LLFloaterIM; 40class LLFloaterIM;
41 41
42class LLIMView : public LLView 42class LLIMMgr : public LLSingleton<LLIMMgr>
43{ 43{
44public: 44public:
45 LLIMView(const std::string& name, const LLRect& rect); 45 LLIMMgr();
46 ~LLIMView(); 46 virtual ~LLIMMgr();
47
48 virtual EWidgetType getWidgetType() const;
49 virtual LLString getWidgetTag() const;
50 47
51 // Add a message to a session. The session can keyed to sesion id 48 // Add a message to a session. The session can keyed to sesion id
52 // or agent id. 49 // or agent id.
53 void addMessage(const LLUUID& session_id, const LLUUID& target_id, 50 void addMessage(const LLUUID& session_id,
54 const char* from, const char* msg, 51 const LLUUID& target_id,
52 const char* from,
53 const char* msg,
55 const char* session_name = NULL, 54 const char* session_name = NULL,
56 EInstantMessage dialog = IM_NOTHING_SPECIAL, 55 EInstantMessage dialog = IM_NOTHING_SPECIAL,
57 U32 parent_estate_id = 0, 56 U32 parent_estate_id = 0,
58 const LLUUID& region_id = LLUUID::null, 57 const LLUUID& region_id = LLUUID::null,
59 const LLVector3& position = LLVector3::zero); 58 const LLVector3& position = LLVector3::zero);
60 59
60 void addSystemMessage(const LLUUID& session_id, const LLString& message_name, const LLString::format_map_t& args);
61
61 // This method returns TRUE if the local viewer has a session 62 // This method returns TRUE if the local viewer has a session
62 // currently open keyed to the uuid. The uuid can be keyed by 63 // currently open keyed to the uuid. The uuid can be keyed by
63 // either session id or agent id. 64 // either session id or agent id.
@@ -82,11 +83,23 @@ public:
82 const LLUUID& other_participant_id, 83 const LLUUID& other_participant_id,
83 const LLDynamicArray<LLUUID>& ids); 84 const LLDynamicArray<LLUUID>& ids);
84 85
86 // Creates a P2P session with the requisite handle for responding to voice calls
87 LLUUID addP2PSession(const std::string& name,
88 const LLUUID& other_participant_id,
89 const LLString& voice_session_handle);
90
85 // This removes the panel referenced by the uuid, and then 91 // This removes the panel referenced by the uuid, and then
86 // restores internal consistency. The internal pointer is not 92 // restores internal consistency. The internal pointer is not
87 // deleted. 93 // deleted.
88 void removeSession(const LLUUID& session_id); 94 void removeSession(const LLUUID& session_id);
89 95
96 void inviteToSession(const LLUUID& session_id,
97 const LLString& session_name,
98 const LLUUID& caller,
99 const LLString& caller_name,
100 EInstantMessage type,
101 const LLString& session_handle = LLString::null);
102
90 //Updates a given session's session IDs. Does not open, 103 //Updates a given session's session IDs. Does not open,
91 //create or do anything new. If the old session doesn't 104 //create or do anything new. If the old session doesn't
92 //exist, then nothing happens. 105 //exist, then nothing happens.
@@ -100,6 +113,7 @@ public:
100 void refresh(); 113 void refresh();
101 114
102 void notifyNewIM(); 115 void notifyNewIM();
116 void clearNewIMNotification();
103 117
104 // IM received that you haven't seen yet 118 // IM received that you haven't seen yet
105 BOOL getIMReceived() const; 119 BOOL getIMReceived() const;
@@ -107,10 +121,7 @@ public:
107 void setFloaterOpen(BOOL open); /*Flawfinder: ignore*/ 121 void setFloaterOpen(BOOL open); /*Flawfinder: ignore*/
108 BOOL getFloaterOpen(); 122 BOOL getFloaterOpen();
109 123
110 LLFloaterIM * getFloater() { return mTalkFloater; } 124 LLFloaterChatterBox* getFloater();
111
112 // close any sessions which are not available in the newimpanel.
113 void pruneSessions();
114 125
115 // This method is used to go through all active sessions and 126 // This method is used to go through all active sessions and
116 // disable all of them. This method is usally called when you are 127 // disable all of them. This method is usally called when you are
@@ -131,9 +142,13 @@ public:
131 // is no matching panel. 142 // is no matching panel.
132 LLFloaterIMPanel* findFloaterBySession(const LLUUID& session_id); 143 LLFloaterIMPanel* findFloaterBySession(const LLUUID& session_id);
133 144
134 void onDropRequestReplyReceived(const LLUUID& session_id); 145 static LLUUID computeSessionID(EInstantMessage dialog, const LLUUID& other_participant_id);
135 146
147 void clearPendingVoiceInviation(const LLUUID& session_id);
148
136private: 149private:
150 class LLIMSessionInvite;
151
137 // create a panel and update internal representation for 152 // create a panel and update internal representation for
138 // consistency. Returns the pointer, caller (the class instance 153 // consistency. Returns the pointer, caller (the class instance
139 // since it is a private method) is not responsible for deleting 154 // since it is a private method) is not responsible for deleting
@@ -159,9 +174,8 @@ private:
159 174
160 void processIMTypingCore(const LLIMInfo* im_info, BOOL typing); 175 void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
161 176
162public: 177 static void inviteUserResponse(S32 option, void* user_data);
163 LLFloaterIM* mTalkFloater; 178 static void onInviteNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* userdata);
164 LLFloaterNewIM* mNewIMFloater;
165 179
166private: 180private:
167 std::set<LLViewHandle> mFloaters; 181 std::set<LLViewHandle> mFloaters;
@@ -170,7 +184,7 @@ private:
170 // An IM has been received that you haven't seen yet. 184 // An IM has been received that you haven't seen yet.
171 BOOL mIMReceived; 185 BOOL mIMReceived;
172 186
173 LLSD mSessionsDropRequested; 187 LLSD mPendingVoiceInvitations;
174}; 188};
175 189
176 190
@@ -178,13 +192,10 @@ class LLFloaterIM : public LLMultiFloater
178{ 192{
179public: 193public:
180 LLFloaterIM(); 194 LLFloaterIM();
181 ///*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent);
182 /*virtual*/ BOOL postBuild(); 195 /*virtual*/ BOOL postBuild();
183 /*virtual*/ void onClose(bool app_quitting);
184 /*virtual*/ void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainerCommon::END);
185}; 196};
186 197
187// Globals 198// Globals
188extern LLIMView *gIMView; 199extern LLIMMgr *gIMMgr;
189 200
190#endif // LL_LLIMView_H 201#endif // LL_LLIMView_H
diff --git a/linden/indra/newview/llinventoryactions.cpp b/linden/indra/newview/llinventoryactions.cpp
index af4e16b..c1b85e1 100644
--- a/linden/indra/newview/llinventoryactions.cpp
+++ b/linden/indra/newview/llinventoryactions.cpp
@@ -563,7 +563,7 @@ class LLBeginIMSession : public inventory_panel_listener_t
563 if(count > 0) 563 if(count > 0)
564 { 564 {
565 // create the session 565 // create the session
566 gIMView->setFloaterOpen(TRUE); 566 gIMMgr->setFloaterOpen(TRUE);
567 S32 i; 567 S32 i;
568 568
569 LLAvatarTracker& at = LLAvatarTracker::instance(); 569 LLAvatarTracker& at = LLAvatarTracker::instance();
@@ -614,7 +614,7 @@ class LLBeginIMSession : public inventory_panel_listener_t
614 } 614 }
615 615
616 616
617 gIMView->addSession(name, 617 gIMMgr->addSession(name,
618 type, 618 type,
619 members[0], 619 members[0],
620 members); 620 members);
diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp
index 27be9f6..fd7d98e 100644
--- a/linden/indra/newview/llinventorybridge.cpp
+++ b/linden/indra/newview/llinventorybridge.cpp
@@ -2593,8 +2593,8 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel*
2593 if (item && (item->getCreatorUUID() != gAgent.getID()) && 2593 if (item && (item->getCreatorUUID() != gAgent.getID()) &&
2594 (!item->getCreatorUUID().isNull())) 2594 (!item->getCreatorUUID().isNull()))
2595 { 2595 {
2596 gIMView->setFloaterOpen(TRUE); 2596 gIMMgr->setFloaterOpen(TRUE);
2597 gIMView->addSession(item->getName(), IM_NOTHING_SPECIAL, item->getCreatorUUID()); 2597 gIMMgr->addSession(item->getName(), IM_NOTHING_SPECIAL, item->getCreatorUUID());
2598 } 2598 }
2599 } 2599 }
2600 else if ("lure" == action) 2600 else if ("lure" == action)
@@ -2671,7 +2671,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
2671 BOOL good_card = (item 2671 BOOL good_card = (item
2672 && (LLUUID::null != item->getCreatorUUID()) 2672 && (LLUUID::null != item->getCreatorUUID())
2673 && (item->getCreatorUUID() != gAgent.getID())); 2673 && (item->getCreatorUUID() != gAgent.getID()));
2674 2674 BOOL user_online = (LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()));
2675 items.push_back("Send Instant Message"); 2675 items.push_back("Send Instant Message");
2676 items.push_back("Offer Teleport..."); 2676 items.push_back("Offer Teleport...");
2677 items.push_back("Conference Chat"); 2677 items.push_back("Conference Chat");
@@ -2679,6 +2679,9 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
2679 if (!good_card) 2679 if (!good_card)
2680 { 2680 {
2681 disabled_items.push_back("Send Instant Message"); 2681 disabled_items.push_back("Send Instant Message");
2682 }
2683 if (!good_card || !user_online)
2684 {
2682 disabled_items.push_back("Offer Teleport..."); 2685 disabled_items.push_back("Offer Teleport...");
2683 disabled_items.push_back("Conference Chat"); 2686 disabled_items.push_back("Conference Chat");
2684 } 2687 }
diff --git a/linden/indra/newview/llinventorymodel.cpp b/linden/indra/newview/llinventorymodel.cpp
index 743b06d..9df8fa4 100644
--- a/linden/indra/newview/llinventorymodel.cpp
+++ b/linden/indra/newview/llinventorymodel.cpp
@@ -1486,11 +1486,18 @@ bool LLInventoryModel::loadSkeleton(
1486 { 1486 {
1487 LLViewerInventoryCategory* cat = categories[i]; 1487 LLViewerInventoryCategory* cat = categories[i];
1488 cat_set_t::iterator cit = temp_cats.find(cat); 1488 cat_set_t::iterator cit = temp_cats.find(cat);
1489 if (cit == temp_cats.end())
1490 {
1491 continue; // cache corruption?? not sure why this happens -SJB
1492 }
1489 LLViewerInventoryCategory* tcat = *cit; 1493 LLViewerInventoryCategory* tcat = *cit;
1490 1494
1491 // we can safely ignore anything loaded from file, but 1495 // we can safely ignore anything loaded from file, but
1492 // not sent down in the skeleton. 1496 // not sent down in the skeleton.
1493 if(cit == not_cached) continue; 1497 if(cit == not_cached)
1498 {
1499 continue;
1500 }
1494 if(cat->getVersion() != tcat->getVersion()) 1501 if(cat->getVersion() != tcat->getVersion())
1495 { 1502 {
1496 // if the cached version does not match the server version, 1503 // if the cached version does not match the server version,
diff --git a/linden/indra/newview/llinventoryview.cpp b/linden/indra/newview/llinventoryview.cpp
index 8ac5f21..112c071 100644
--- a/linden/indra/newview/llinventoryview.cpp
+++ b/linden/indra/newview/llinventoryview.cpp
@@ -502,11 +502,16 @@ void LLInventoryView::init(LLInventoryModel* inventory)
502 502
503 // Load the persistent "Recent Items" settings. 503 // Load the persistent "Recent Items" settings.
504 // Note that the "All Items" settings do not persist. 504 // Note that the "All Items" settings do not persist.
505 if(savedFilterState.has(recent_items_panel->getFilter()->getName())) 505 if(recent_items_panel)
506 { 506 {
507 LLSD recent_items = savedFilterState.get(recent_items_panel->getFilter()->getName()); 507 if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
508 recent_items_panel->getFilter()->fromLLSD(recent_items); 508 {
509 LLSD recent_items = savedFilterState.get(
510 recent_items_panel->getFilter()->getName());
511 recent_items_panel->getFilter()->fromLLSD(recent_items);
512 }
509 } 513 }
514
510 } 515 }
511 516
512 517
@@ -516,7 +521,6 @@ void LLInventoryView::init(LLInventoryModel* inventory)
516 mSearchEditor->setSearchCallback(onSearchEdit, this); 521 mSearchEditor->setSearchCallback(onSearchEdit, this);
517 } 522 }
518 523
519 moveResizeHandleToFront();
520 sActiveViews.put(this); 524 sActiveViews.put(this);
521 525
522 gInventory.addObserver(this); 526 gInventory.addObserver(this);
diff --git a/linden/indra/newview/llmediaremotectrl.cpp b/linden/indra/newview/llmediaremotectrl.cpp
index 4549c3b..0d524b0 100644
--- a/linden/indra/newview/llmediaremotectrl.cpp
+++ b/linden/indra/newview/llmediaremotectrl.cpp
@@ -30,179 +30,66 @@
30 30
31#include "llmediaremotectrl.h" 31#include "llmediaremotectrl.h"
32 32
33#include "llui.h" 33#include "lloverlaybar.h"
34#include "lltextbox.h"
35#include "llbutton.h"
36#include "llfocusmgr.h"
37#include "llmediaengine.h"
38#include "llviewercontrol.h"
39#include "llvieweruictrlfactory.h" 34#include "llvieweruictrlfactory.h"
35#include "llpanelaudiovolume.h"
40 36
41//////////////////////////////////////////////////////////////////////////////// 37////////////////////////////////////////////////////////////////////////////////
42// 38//
43// 39//
44LLMediaRemoteCtrl:: 40LLMediaRemoteCtrl::LLMediaRemoteCtrl ( const LLString& name,
45LLMediaRemoteCtrl ( const std::string& name, 41 const LLString& label,
46 const std::string& label, 42 const LLRect& rect,
47 const LLRect& rect, 43 const LLString& xml_file ) :
48 const std::string& xml_file ) :
49 LLPanel ( name, rect, FALSE ) 44 LLPanel ( name, rect, FALSE )
50{ 45{
51 setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
52 setBackgroundVisible(TRUE);
53 setIsChrome(TRUE); 46 setIsChrome(TRUE);
54 47
55 gUICtrlFactory->buildPanel(this, xml_file); 48 gUICtrlFactory->buildPanel(this, xml_file);
56 49
57 playButton = LLUICtrlFactory::getButtonByName(this, "play_btn");
58 stopButton = LLUICtrlFactory::getButtonByName(this, "stop_btn");
59 pauseButton = LLUICtrlFactory::getButtonByName(this, "pause_btn");
60
61 childSetAction("play_btn",onPlayButton,this);
62 childSetAction("stop_btn",onStopButton,this);
63 childSetAction("pause_btn",onPauseButton,this);
64
65 mVolumeSlider = LLViewerUICtrlFactory::getVolumeSliderByName(this, "volume_slider");
66
67 childSetCommitCallback("volume_slider", onCommitVolume, this);
68
69 mIsFocusRoot = TRUE; 50 mIsFocusRoot = TRUE;
70} 51}
71 52
72//////////////////////////////////////////////////////////////////////////////// 53BOOL LLMediaRemoteCtrl::postBuild()
73//
74//
75LLMediaRemoteCtrl::
76~LLMediaRemoteCtrl ()
77{ 54{
78} 55 childSetAction("media_play",LLOverlayBar::mediaPlay,this);
56 childSetAction("media_stop",LLOverlayBar::mediaStop,this);
57 childSetAction("media_pause",LLOverlayBar::mediaPause,this);
79 58
80EWidgetType LLMediaRemoteCtrl::getWidgetType() const 59 childSetAction("music_play",LLOverlayBar::musicPlay,this);
81{ 60 childSetAction("music_stop",LLOverlayBar::musicStop,this);
82 return WIDGET_TYPE_MEDIA_REMOTE; 61 childSetAction("music_pause",LLOverlayBar::musicPause,this);
83}
84 62
85LLString LLMediaRemoteCtrl::getWidgetTag() const 63 childSetAction("volume",LLOverlayBar::toggleAudioVolumeFloater,this);
86{ 64
87 return LL_MEDIA_REMOTE_CTRL_TAG; 65 return TRUE;
88}
89
90////////////////////////////////////////////////////////////////////////////////
91//
92//
93void
94LLMediaRemoteCtrl::
95setTransportState ( TransportState transportStateIn, BOOL pauseEnabled )
96{
97 transportState = transportStateIn;
98
99 if ( transportState == Play )
100 {
101 playButton->setVisible ( TRUE );
102 playButton->setEnabled ( pauseEnabled );
103
104 pauseButton->setVisible ( FALSE );
105 pauseButton->setEnabled ( FALSE );
106
107 stopButton->setVisible ( TRUE );
108 stopButton->setEnabled ( TRUE );
109 }
110 else
111 if ( transportState == Pause )
112 {
113 playButton->setVisible ( FALSE );
114 playButton->setEnabled ( FALSE );
115
116 pauseButton->setVisible ( TRUE );
117 pauseButton->setEnabled ( TRUE );
118
119 stopButton->setVisible ( TRUE );
120 stopButton->setEnabled ( TRUE );
121 }
122 else
123 if ( transportState == Stop )
124 {
125 playButton->setVisible ( TRUE );
126 playButton->setEnabled ( TRUE );
127
128 pauseButton->setVisible ( FALSE );
129 pauseButton->setEnabled ( FALSE );
130
131 stopButton->setVisible ( TRUE );
132 stopButton->setEnabled ( FALSE );
133 };
134}
135
136////////////////////////////////////////////////////////////////////////////////
137//
138//
139LLMediaRemoteCtrl::TransportState
140LLMediaRemoteCtrl::
141getTransportState ()
142{
143 return transportState;
144}
145
146
147////////////////////////////////////////////////////////////////////////////////
148//
149//
150void
151LLMediaRemoteCtrl::
152setVolume ( F32 volumeIn )
153{
154 mVolumeSlider->setValue ( volumeIn );
155} 66}
156 67
157//////////////////////////////////////////////////////////////////////////////// 68LLMediaRemoteCtrl::~LLMediaRemoteCtrl ()
158//
159//
160void
161LLMediaRemoteCtrl::
162onCommitVolume ( LLUICtrl* ctrl, void* data )
163{ 69{
164 LLMediaRemoteCtrl* self = ( LLMediaRemoteCtrl* ) data;
165
166 LLMediaRemoteCtrlEvent event ( self, (F32)self->mVolumeSlider->getValue().asReal() );
167 self->mediaRemoteCtrlEventEmitter.update ( &LLMediaRemoteCtrlObserver::onVolumeChange, event );
168} 70}
169 71
170//////////////////////////////////////////////////////////////////////////////// 72////////////////////////////////////////////////////////////////////////////////
171// 73//
172// 74//
173void 75EWidgetType LLMediaRemoteCtrl::getWidgetType() const
174LLMediaRemoteCtrl::
175onPlayButton ( void* data )
176{ 76{
177 LLMediaRemoteCtrl* self = ( LLMediaRemoteCtrl* ) data; 77 return WIDGET_TYPE_MEDIA_REMOTE;
178
179 LLMediaRemoteCtrlEvent event ( self, 0.0f );
180 self->mediaRemoteCtrlEventEmitter.update ( &LLMediaRemoteCtrlObserver::onPlayButtonPressed, event );
181} 78}
182 79
183//////////////////////////////////////////////////////////////////////////////// 80LLString LLMediaRemoteCtrl::getWidgetTag() const
184//
185//
186void
187LLMediaRemoteCtrl::
188onPauseButton ( void* data )
189{ 81{
190 LLMediaRemoteCtrl* self = ( LLMediaRemoteCtrl* ) data; 82 return LL_MEDIA_REMOTE_CTRL_TAG;
191
192 LLMediaRemoteCtrlEvent event ( self, 0.0f );
193 self->mediaRemoteCtrlEventEmitter.update ( &LLMediaRemoteCtrlObserver::onPauseButtonPressed, event );
194} 83}
195 84
196//////////////////////////////////////////////////////////////////////////////// 85////////////////////////////////////////////////////////////////////////////////
197// 86//
198// 87//
199void 88void LLMediaRemoteCtrl::draw()
200LLMediaRemoteCtrl::
201onStopButton ( void* data )
202{ 89{
203 LLMediaRemoteCtrl* self = ( LLMediaRemoteCtrl* ) data; 90 LLOverlayBar::enableMusicButtons(this);
204 91 LLOverlayBar::enableMediaButtons(this);
205 LLMediaRemoteCtrlEvent event ( self, 0.0f ); 92 LLPanel::draw();
206 self->mediaRemoteCtrlEventEmitter.update ( &LLMediaRemoteCtrlObserver::onStopButtonPressed, event ); 93 // make volume button reflect of volume floater
94 childSetValue("volume", LLFloaterAudioVolume::instanceVisible(LLSD()));
207} 95}
208
diff --git a/linden/indra/newview/llmediaremotectrl.h b/linden/indra/newview/llmediaremotectrl.h
index 605be04..4f4ba77 100644
--- a/linden/indra/newview/llmediaremotectrl.h
+++ b/linden/indra/newview/llmediaremotectrl.h
@@ -30,94 +30,24 @@
30#define LL_LLMEDIAREMOTECTRL_H 30#define LL_LLMEDIAREMOTECTRL_H
31 31
32#include "llpanel.h" 32#include "llpanel.h"
33#include "llvolumesliderctrl.h"
34#include "lleventemitter.h"
35 33
36//////////////////////////////////////////////////////////////////////////////// 34////////////////////////////////////////////////////////////////////////////////
37// 35//
38class LLMediaRemoteCtrlEvent 36class LLMediaRemoteCtrl : public LLPanel
39{
40 public:
41 LLMediaRemoteCtrlEvent ( LLUICtrl* controlIn, F32 valueIn ):
42 control ( controlIn ),
43 value ( valueIn )
44 {
45 };
46
47 virtual ~LLMediaRemoteCtrlEvent () { }
48
49 LLUICtrl* getControl () const { return control; };
50 F32 getValue () const { return value; };
51
52 private:
53 LLUICtrl* control;
54 F32 value;
55};
56
57////////////////////////////////////////////////////////////////////////////////
58//
59class LLMediaRemoteCtrlObserver
60{ 37{
61public: 38public:
62 typedef LLMediaRemoteCtrlEvent EventType; 39 LLMediaRemoteCtrl ( const LLString& name,
63 virtual ~LLMediaRemoteCtrlObserver() {} 40 const LLString& label,
64 virtual void onVolumeChange ( const EventType& eventIn ) { }; 41 const LLRect& rect,
65 virtual void onStopButtonPressed ( const EventType& eventIn ) { }; 42 const LLString& xml_file );
66 virtual void onPlayButtonPressed ( const EventType& eventIn ) { };
67 virtual void onPauseButtonPressed ( const EventType& eventIn ) { };
68};
69
70////////////////////////////////////////////////////////////////////////////////
71//
72class LLMediaRemoteCtrl :
73 public LLPanel
74{
75 public:
76 LLMediaRemoteCtrl ( const std::string& name,
77 const std::string& label,
78 const LLRect& rect,
79 const std::string& xml_file );
80 43
81 virtual ~LLMediaRemoteCtrl (); 44 virtual ~LLMediaRemoteCtrl ();
82 45 virtual BOOL postBuild();
83 virtual EWidgetType getWidgetType() const;
84 virtual LLString getWidgetTag() const;
85
86 // set current transport state of remote control
87 enum TransportState { Stop, Play, Pause };
88 void setTransportState ( TransportState transportStateIn, BOOL pauseEnabled );
89 TransportState getTransportState ();
90 void setVolume ( F32 volumeIn );
91
92 // allow consumers to observe remote control events
93 virtual BOOL addObserver ( LLMediaRemoteCtrlObserver* observerIn )
94 {
95 return mediaRemoteCtrlEventEmitter.addObserver ( observerIn );
96 };
97 virtual BOOL remObserver ( LLMediaRemoteCtrlObserver* observerIn )
98 {
99 return mediaRemoteCtrlEventEmitter.remObserver ( observerIn );
100 };
101 46
102 private: 47 virtual void draw();
103 LLVolumeSliderCtrl* mVolumeSlider; 48
104 LLRect volumeSliderRect; 49 virtual EWidgetType getWidgetType() const;
105 50 virtual LLString getWidgetTag() const;
106 TransportState transportState;
107
108 LLTextBox* titleLabel;
109 LLButton* playButton;
110 LLButton* pauseButton;
111 LLButton* stopButton;
112
113 // event emitter
114 eventEmitter < LLMediaRemoteCtrlObserver > mediaRemoteCtrlEventEmitter;
115
116 // callbacks
117 static void onCommitVolume ( LLUICtrl* ctrl, void* data );
118 static void onPlayButton ( void* data );
119 static void onPauseButton ( void* data );
120 static void onStopButton ( void* data );
121}; 51};
122 52
123#endif 53#endif
diff --git a/linden/indra/newview/llmemoryview.cpp b/linden/indra/newview/llmemoryview.cpp
index 1d92bff..c29b33f 100644
--- a/linden/indra/newview/llmemoryview.cpp
+++ b/linden/indra/newview/llmemoryview.cpp
@@ -45,10 +45,20 @@
45 45
46#include "llfasttimer.h" 46#include "llfasttimer.h"
47 47
48
49
48LLMemoryView::LLMemoryView(const std::string& name, const LLRect& rect) 50LLMemoryView::LLMemoryView(const std::string& name, const LLRect& rect)
49: LLView(name, rect, TRUE) 51: LLView(name, rect, TRUE),
52mDelay(120)
50{ 53{
51 setVisible(FALSE); 54 setVisible(FALSE);
55 mDumpTimer.reset();
56
57#ifdef MEM_DUMP_DATA
58 // clear out file.
59 FILE *dump = fopen("memusagedump.txt", "w");
60 fclose(dump);
61#endif
52} 62}
53 63
54LLMemoryView::~LLMemoryView() 64LLMemoryView::~LLMemoryView()
@@ -196,7 +206,7 @@ void LLMemoryView::draw()
196 peak += maxbytes; 206 peak += maxbytes;
197 S32 mbytes = bytes >> 20; 207 S32 mbytes = bytes >> 20;
198 208
199 tdesc = llformat("%s [%4d MB]",mtv_display_table[i].desc,mbytes); 209 tdesc = llformat("%s [%4d MB] in %06d NEWS",mtv_display_table[i].desc,mbytes, LLMemType::sNewCount[tidx]);
200 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); 210 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
201 211
202 y -= (texth + 2); 212 y -= (texth + 2);
@@ -239,7 +249,46 @@ void LLMemoryView::draw()
239 y -= (texth + 2); 249 y -= (texth + 2);
240 } 250 }
241 251
252 dumpData();
253
242#endif 254#endif
243 255
244 LLView::draw(); 256 LLView::draw();
245} 257}
258
259void LLMemoryView::setDataDumpInterval(float delay)
260{
261 mDelay = delay;
262}
263
264void LLMemoryView::dumpData()
265{
266#if MEM_TRACK_TYPE && MEM_DUMP_DATA
267 if (mDelay && (mDumpTimer.getElapsedTimeF32() > mDelay ))
268 {
269 // reset timer
270 mDumpTimer.reset();
271 // append dump info to text file
272 FILE *dump = fopen("memusagedump.txt", "a");
273
274 if (dump)
275 {
276 // write out total memory usage
277 fprintf (dump, "Total memory in use = %09d (%03d MB)\n", LLMemType::sTotalMem, LLMemType::sTotalMem>>20);
278 fprintf (dump, "High Water Mark = %09d (%03d MB)\n\n", LLMemType::sMaxTotalMem, LLMemType::sMaxTotalMem>>20);
279 // dump out usage of 'new' for each memory type
280 for (S32 i=0; i<LLMemType::MTYPE_NUM_TYPES; i++)
281 {
282 if (LLMemType::sMemCount[i])
283 {
284 std::string outData = llformat("MEM: % 20s %09d %03d MB (%09d %03d MB) in %06d News", LLMemType::sTypeDesc[i], LLMemType::sMemCount[i], LLMemType::sMemCount[i]>>20, LLMemType::sMaxMemCount[i], LLMemType::sMaxMemCount[i]>>20, LLMemType::sNewCount[i]);
285 fprintf (dump, "%s\n", outData.c_str());
286 }
287 }
288 fprintf (dump, "\n\n");
289
290 fclose(dump);
291 }
292 }
293#endif
294}
diff --git a/linden/indra/newview/llmemoryview.h b/linden/indra/newview/llmemoryview.h
index 6d5b96b..809e40f 100644
--- a/linden/indra/newview/llmemoryview.h
+++ b/linden/indra/newview/llmemoryview.h
@@ -46,6 +46,13 @@ public:
46 virtual void draw(); 46 virtual void draw();
47 47
48private: 48private:
49 void setDataDumpInterval(float delay);
50 void dumpData();
51
52 float mDelay;
53 LLFrameTimer mDumpTimer;
54
55private:
49}; 56};
50 57
51#endif 58#endif
diff --git a/linden/indra/newview/llmutelist.cpp b/linden/indra/newview/llmutelist.cpp
index bca9080..b5764c5 100644
--- a/linden/indra/newview/llmutelist.cpp
+++ b/linden/indra/newview/llmutelist.cpp
@@ -189,11 +189,11 @@ BOOL LLMuteList::isLinden(const LLString& name) const
189} 189}
190 190
191 191
192BOOL LLMuteList::add(const LLMute& mute) 192BOOL LLMuteList::add(const LLMute& mute, U32 flags)
193{ 193{
194 // Can't mute Lindens 194 // Can't mute text from Lindens
195 if ((mute.mType == LLMute::AGENT || mute.mType == LLMute::BY_NAME) 195 if ((mute.mType == LLMute::AGENT || mute.mType == LLMute::BY_NAME)
196 && isLinden(mute.mName)) 196 && isLinden(mute.mName) && (flags & LLMute::flagTextChat || flags == 0))
197 { 197 {
198 gViewerWindow->alertXml("MuteLinden"); 198 gViewerWindow->alertXml("MuteLinden");
199 return FALSE; 199 return FALSE;
@@ -238,25 +238,59 @@ BOOL LLMuteList::add(const LLMute& mute)
238 } 238 }
239 else 239 else
240 { 240 {
241 std::pair<mute_set_t::iterator, bool> result = mMutes.insert(mute); 241 // Need a local (non-const) copy to set up flags properly.
242 if (result.second) 242 LLMute localmute = mute;
243
244 // If an entry for the same entity is already in the list, remove it, saving flags as necessary.
245 mute_set_t::iterator it = mMutes.find(localmute);
246 if (it != mMutes.end())
243 { 247 {
244 llinfos << "Muting " << mute.mName << " id " << mute.mID << llendl; 248 // This mute is already in the list. Save the existing entry's flags if that's warranted.
245 updateAdd(mute); 249 localmute.mFlags = it->mFlags;
246 notifyObservers(); 250
247 //Kill all particle systems owned by muted task 251 mMutes.erase(it);
248 if(mute.mType == LLMute::AGENT || mute.mType == LLMute::OBJECT) 252 // Don't need to call notifyObservers() here, since it will happen after the entry has been re-added below.
249 { 253 }
250 gWorldPointer->mPartSim.cleanMutedParticles(mute.mID); 254 else
251 } 255 {
256 // There was no entry in the list previously. Fake things up by making it look like the previous entry had all properties unmuted.
257 localmute.mFlags = LLMute::flagAll;
258 }
252 259
253 return TRUE; 260 if(flags)
261 {
262 // The user passed some combination of flags. Make sure those flag bits are turned off (i.e. those properties will be muted).
263 localmute.mFlags &= (~flags);
254 } 264 }
255 else 265 else
256 { 266 {
257 return FALSE; 267 // The user passed 0. Make sure all flag bits are turned off (i.e. all properties will be muted).
268 localmute.mFlags = 0;
269 }
270
271 // (re)add the mute entry.
272 {
273 std::pair<mute_set_t::iterator, bool> result = mMutes.insert(localmute);
274 if (result.second)
275 {
276 llinfos << "Muting " << localmute.mName << " id " << localmute.mID << " flags " << localmute.mFlags << llendl;
277 updateAdd(mute);
278 notifyObservers();
279 if(!(localmute.mFlags & LLMute::flagParticles))
280 {
281 //Kill all particle systems owned by muted task
282 if(localmute.mType == LLMute::AGENT || localmute.mType == LLMute::OBJECT)
283 {
284 gWorldPointer->mPartSim.cleanMutedParticles(localmute.mID);
285 }
286 }
287 return TRUE;
288 }
258 } 289 }
259 } 290 }
291
292 // If we were going to return success, we'd have done it by now.
293 return FALSE;
260} 294}
261 295
262void LLMuteList::updateAdd(const LLMute& mute) 296void LLMuteList::updateAdd(const LLMute& mute)
@@ -271,14 +305,14 @@ void LLMuteList::updateAdd(const LLMute& mute)
271 msg->addUUIDFast(_PREHASH_MuteID, mute.mID); 305 msg->addUUIDFast(_PREHASH_MuteID, mute.mID);
272 msg->addStringFast(_PREHASH_MuteName, mute.mName); 306 msg->addStringFast(_PREHASH_MuteName, mute.mName);
273 msg->addS32("MuteType", mute.mType); 307 msg->addS32("MuteType", mute.mType);
274 msg->addU32("MuteFlags", 0x0); // future 308 msg->addU32("MuteFlags", mute.mFlags);
275 gAgent.sendReliableMessage(); 309 gAgent.sendReliableMessage();
276 310
277 mIsLoaded = TRUE; 311 mIsLoaded = TRUE;
278} 312}
279 313
280 314
281BOOL LLMuteList::remove(const LLMute& mute) 315BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
282{ 316{
283 BOOL found = FALSE; 317 BOOL found = FALSE;
284 318
@@ -286,8 +320,46 @@ BOOL LLMuteList::remove(const LLMute& mute)
286 mute_set_t::iterator it = mMutes.find(mute); 320 mute_set_t::iterator it = mMutes.find(mute);
287 if (it != mMutes.end()) 321 if (it != mMutes.end())
288 { 322 {
289 updateRemove(*it); 323 LLMute localmute = *it;
324 bool remove = true;
325 if(flags)
326 {
327 // If the user passed mute flags, we may only want to turn some flags on.
328 localmute.mFlags |= flags;
329
330 if(localmute.mFlags == LLMute::flagAll)
331 {
332 // Every currently available mute property has been masked out.
333 // Remove the mute entry entirely.
334 }
335 else
336 {
337 // Only some of the properties are masked out. Update the entry.
338 remove = false;
339 }
340 }
341 else
342 {
343 // The caller didn't pass any flags -- just remove the mute entry entirely.
344 }
345
346 // Always remove the entry from the set -- it will be re-added with new flags if necessary.
290 mMutes.erase(it); 347 mMutes.erase(it);
348
349 if(remove)
350 {
351 // The entry was actually removed. Notify the server.
352 updateRemove(localmute);
353 llinfos << "Unmuting " << localmute.mName << " id " << localmute.mID << " flags " << localmute.mFlags << llendl;
354 }
355 else
356 {
357 // Flags were updated, the mute entry needs to be retransmitted to the server and re-added to the list.
358 mMutes.insert(localmute);
359 updateAdd(localmute);
360 llinfos << "Updating mute entry " << localmute.mName << " id " << localmute.mID << " flags " << localmute.mFlags << llendl;
361 }
362
291 // Must be after erase. 363 // Must be after erase.
292 notifyObservers(); 364 notifyObservers();
293 found = TRUE; 365 found = TRUE;
@@ -381,7 +453,7 @@ BOOL LLMuteList::loadFromFile(const LLString& filename)
381 buffer, " %d %254s %254[^|]| %u\n", &type, id_buffer, name_buffer, 453 buffer, " %d %254s %254[^|]| %u\n", &type, id_buffer, name_buffer,
382 &flags); 454 &flags);
383 LLUUID id = LLUUID(id_buffer); 455 LLUUID id = LLUUID(id_buffer);
384 LLMute mute(id, name_buffer, (LLMute::EType)type); 456 LLMute mute(id, name_buffer, (LLMute::EType)type, flags);
385 if (mute.mID.isNull() 457 if (mute.mID.isNull()
386 || mute.mType == LLMute::BY_NAME) 458 || mute.mType == LLMute::BY_NAME)
387 { 459 {
@@ -430,19 +502,27 @@ BOOL LLMuteList::saveToFile(const LLString& filename)
430 { 502 {
431 it->mID.toString(id_string); 503 it->mID.toString(id_string);
432 const LLString& name = it->mName; 504 const LLString& name = it->mName;
433 fprintf(fp, "%d %s %s|\n", (S32)it->mType, id_string, name.c_str()); 505 fprintf(fp, "%d %s %s|%u\n", (S32)it->mType, id_string, name.c_str(), it->mFlags);
434 } 506 }
435 fclose(fp); 507 fclose(fp);
436 return TRUE; 508 return TRUE;
437} 509}
438 510
439 511
440BOOL LLMuteList::isMuted(const LLUUID& id, const LLString& name) const 512BOOL LLMuteList::isMuted(const LLUUID& id, const LLString& name, U32 flags) const
441{ 513{
442 // don't need name or type for lookup 514 // don't need name or type for lookup
443 LLMute mute(id); 515 LLMute mute(id);
444 mute_set_t::const_iterator mute_it = mMutes.find(mute); 516 mute_set_t::const_iterator mute_it = mMutes.find(mute);
445 if (mute_it != mMutes.end()) return TRUE; 517 if (mute_it != mMutes.end())
518 {
519 // If any of the flags the caller passed are set, this item isn't considered muted for this caller.
520 if(flags & mute_it->mFlags)
521 {
522 return FALSE;
523 }
524 return TRUE;
525 }
446 526
447 // empty names can't be legacy-muted 527 // empty names can't be legacy-muted
448 if (name.empty()) return FALSE; 528 if (name.empty()) return FALSE;
diff --git a/linden/indra/newview/llmutelist.h b/linden/indra/newview/llmutelist.h
index d8f1bf6..4624bfd 100644
--- a/linden/indra/newview/llmutelist.h
+++ b/linden/indra/newview/llmutelist.h
@@ -43,8 +43,22 @@ public:
43 // Legacy mutes are BY_NAME and have null UUID. 43 // Legacy mutes are BY_NAME and have null UUID.
44 enum EType { BY_NAME = 0, AGENT = 1, OBJECT = 2, GROUP = 3, COUNT = 4 }; 44 enum EType { BY_NAME = 0, AGENT = 1, OBJECT = 2, GROUP = 3, COUNT = 4 };
45 45
46 LLMute(const LLUUID& id, const LLString& name = "", EType type = BY_NAME) 46 // Bits in the mute flags. For backwards compatibility (since any mute list entries that were created before the flags existed
47 : mID(id), mName(name), mType(type) { } 47 // will have a flags field of 0), some of the flags are "inverted".
48 // Note that it's possible, through flags, to completely disable an entry in the mute list. The code should detect this case
49 // and remove the mute list entry instead.
50 enum
51 {
52 flagTextChat = 0x00000001, // If set, don't mute user's text chat
53 flagVoiceChat = 0x00000002, // If set, don't mute user's voice chat
54 flagParticles = 0x00000004, // If set, don't mute user's particles
55 flagObjectSounds = 0x00000008, // If set, mute user's object sounds
56
57 flagAll = 0x0000000F // Mask of all currently defined flags
58 };
59
60 LLMute(const LLUUID& id, const LLString& name = "", EType type = BY_NAME, U32 flags = 0)
61 : mID(id), mName(name), mType(type),mFlags(flags) { }
48 62
49 // Returns name + suffix based on type 63 // Returns name + suffix based on type
50 // For example: "James Tester (resident)" 64 // For example: "James Tester (resident)"
@@ -59,6 +73,7 @@ public:
59 LLUUID mID; // agent or object id 73 LLUUID mID; // agent or object id
60 LLString mName; // agent or object name 74 LLString mName; // agent or object name
61 EType mType; // needed for UI display of existing mutes 75 EType mType; // needed for UI display of existing mutes
76 U32 mFlags; // flags pertaining to this mute entry
62}; 77};
63 78
64class LLMuteList 79class LLMuteList
@@ -70,14 +85,17 @@ public:
70 void addObserver(LLMuteListObserver* observer); 85 void addObserver(LLMuteListObserver* observer);
71 void removeObserver(LLMuteListObserver* observer); 86 void removeObserver(LLMuteListObserver* observer);
72 87
73 // Add either a normal or a BY_NAME mute. 88 // Add either a normal or a BY_NAME mute, for any or all properties.
74 BOOL add(const LLMute& mute); 89 BOOL add(const LLMute& mute, U32 flags = 0);
75 90
76 // Remove both normal and legacy mutes. 91 // Remove both normal and legacy mutes, for any or all properties.
77 BOOL remove(const LLMute& mute); 92 BOOL remove(const LLMute& mute, U32 flags = 0);
78 93
79 // Name is required to test against legacy text-only mutes. 94 // Name is required to test against legacy text-only mutes.
80 BOOL isMuted(const LLUUID& id, const LLString& name = LLString::null) const; 95 BOOL isMuted(const LLUUID& id, const LLString& name = LLString::null, U32 flags = 0) const;
96
97 // Alternate (convenience) form for places we don't need to pass the name, but do need flags
98 BOOL isMuted(const LLUUID& id, U32 flags) const { return isMuted(id, LLString::null, flags); };
81 99
82 BOOL isLinden(const LLString& name) const; 100 BOOL isLinden(const LLString& name) const;
83 101
diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp
index 2105521..4701aae 100644
--- a/linden/indra/newview/llnetmap.cpp
+++ b/linden/indra/newview/llnetmap.cpp
@@ -246,7 +246,7 @@ void LLNetMap::draw()
246 246
247 { 247 {
248 LLGLSNoTexture no_texture; 248 LLGLSNoTexture no_texture;
249 LLUI::setScissorRegionLocal(LLRect(0, mRect.getHeight(), mRect.getWidth(), 0)); 249 LLLocalClipRect clip(getLocalRect());
250 250
251 glMatrixMode(GL_MODELVIEW); 251 glMatrixMode(GL_MODELVIEW);
252 252
diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp
index 7822d00..4f5c64b 100644
--- a/linden/indra/newview/llnotify.cpp
+++ b/linden/indra/newview/llnotify.cpp
@@ -58,48 +58,106 @@ const F32 ANIMATION_TIME = 0.333f;
58S32 LLNotifyBox::sNotifyBoxCount = 0; 58S32 LLNotifyBox::sNotifyBoxCount = 0;
59const LLFontGL* LLNotifyBox::sFont = NULL; 59const LLFontGL* LLNotifyBox::sFont = NULL;
60const LLFontGL* LLNotifyBox::sFontSmall = NULL; 60const LLFontGL* LLNotifyBox::sFontSmall = NULL;
61std::map<LLString, LLNotifyBox*> LLNotifyBox::sOpenUniqueNotifyBoxes;
62LLPointer<LLNotifyBoxTemplate> LLNotifyBox::sDefaultTemplate;
63
61 64
62LLNotifyBox::template_map_t LLNotifyBox::sNotifyTemplates; 65LLNotifyBox::template_map_t LLNotifyBox::sNotifyTemplates;
63 66
67LLNotifyBox::LLNotifyBehavior::LLNotifyBehavior(notify_callback_t callback, void* data) :
68 mCallback(callback),
69 mData(data)
70{
71}
72
64//--------------------------------------------------------------------------- 73//---------------------------------------------------------------------------
65// LLNotifyBox 74// LLNotifyBox
66//--------------------------------------------------------------------------- 75//---------------------------------------------------------------------------
67 76
68//static 77//static
69void LLNotifyBox::showXml( const LLString& xml_desc, notify_callback_t callback, void *user_data) 78LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, notify_callback_t callback, void *user_data)
70{ 79{
71 return showXml(xml_desc, LLString::format_map_t(), callback, user_data); 80 return showXml(xml_desc, LLString::format_map_t(), callback, user_data);
72} 81}
73 82
74 83
75//static 84//static
76void LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, BOOL is_caution, 85LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, BOOL is_caution,
77 notify_callback_t callback, void *user_data) 86 notify_callback_t callback, void *user_data)
78{ 87{
79 // for script permission prompts 88 // for script permission prompts
80 LLNotifyBox* notify = new LLNotifyBox(xml_desc, args, callback, user_data, is_caution); 89 LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc);
81 gNotifyBoxView->addChild(notify); 90 LLNotifyBox* notify = findExistingNotify(xml_template, args);
91 if (notify)
92 {
93 delete notify->mBehavior;
94 notify->mBehavior = new LLNotifyBehavior(callback, user_data);
95 }
96 else
97 {
98 LLNotifyBox* notify = new LLNotifyBox(xml_template, args, callback, user_data, is_caution);
99 gNotifyBoxView->addChildAtEnd(notify);
100 notify->moveToBack();
101 }
102 return notify;
82} 103}
83 104
84//static 105//static
85void LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, 106LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args,
86 notify_callback_t callback, void *user_data) 107 notify_callback_t callback, void *user_data)
87{ 108{
88 LLNotifyBox* notify = new LLNotifyBox(xml_desc, args, callback, user_data); 109 LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc);
89 gNotifyBoxView->addChild(notify); 110 LLNotifyBox* notify = findExistingNotify(xml_template, args);
111 if (notify)
112 {
113 delete notify->mBehavior;
114 notify->mBehavior = new LLNotifyBehavior(callback, user_data);
115 }
116 else
117 {
118 notify = new LLNotifyBox(xml_template, args, callback, user_data);
119 gNotifyBoxView->addChildAtEnd(notify);
120 notify->moveToBack();
121 }
122 return notify;
90} 123}
91 124
92//static 125//static
93void LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, 126LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args,
94 notify_callback_t callback, void *user_data, 127 notify_callback_t callback, void *user_data,
95 const option_list_t& options, 128 const option_list_t& options,
96 BOOL layout_script_dialog) 129 BOOL layout_script_dialog)
97{ 130{
98 LLNotifyBox* notify = new LLNotifyBox(xml_desc, args, callback, user_data, FALSE, options, layout_script_dialog); 131 LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc);
99 gNotifyBoxView->addChild(notify); 132 LLNotifyBox* notify = findExistingNotify(xml_template, args);
133 if (notify)
134 {
135 delete notify->mBehavior;
136 notify->mBehavior = new LLNotifyBehavior(callback, user_data);
137 }
138 else
139 {
140 notify = new LLNotifyBox(xml_template, args, callback, user_data, FALSE, options, layout_script_dialog);
141 gNotifyBoxView->addChild(notify);
142 }
143 return notify;
100} 144}
101 145
102LLPointer<LLNotifyBoxTemplate> LLNotifyBox::sDefaultTemplate; 146//static
147LLNotifyBox* LLNotifyBox::findExistingNotify(LLPointer<LLNotifyBoxTemplate> notify_template, const LLString::format_map_t &args)
148{
149 if(notify_template->mUnique)
150 {
151 LLString message = notify_template->mMessage;
152 LLAlertDialog::format(message, args);
153 unique_map_t::iterator found_it = sOpenUniqueNotifyBoxes.find(notify_template->mLabel + message);
154 if (found_it != sOpenUniqueNotifyBoxes.end())
155 {
156 return found_it->second;
157 }
158 }
159 return NULL;
160}
103 161
104void LLNotifyBox::cleanup() 162void LLNotifyBox::cleanup()
105{ 163{
@@ -108,18 +166,17 @@ void LLNotifyBox::cleanup()
108 166
109//--------------------------------------------------------------------------- 167//---------------------------------------------------------------------------
110 168
111LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& args, 169LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLString::format_map_t& args,
112 notify_callback_t callback, void* user_data, BOOL is_caution, 170 notify_callback_t callback, void* user_data, BOOL is_caution,
113 const option_list_t& extra_options, 171 const option_list_t& extra_options,
114 BOOL layout_script_dialog) 172 BOOL layout_script_dialog)
115 : LLPanel("notify", LLRect(), BORDER_NO), 173 : LLPanel(xml_template->mLabel, LLRect(), BORDER_NO),
116 LLEventTimer(gSavedSettings.getF32("NotifyTipDuration")), 174 LLEventTimer(xml_template->mDuration),
117 mIsTip(FALSE), 175 mIsTip(FALSE),
118 mAnimating(TRUE), 176 mAnimating(TRUE),
119 mTimer(), 177 mUnique(xml_template->mUnique),
120 mNextBtn(NULL), 178 mNextBtn(NULL),
121 mCallback(callback), 179 mBehavior(new LLNotifyBehavior(callback, user_data)),
122 mData(user_data),
123 mNumOptions(0), 180 mNumOptions(0),
124 mDefaultOption(0) 181 mDefaultOption(0)
125{ 182{
@@ -133,31 +190,17 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
133 sFontSmall = LLFontGL::sSansSerifSmall; 190 sFontSmall = LLFontGL::sSansSerifSmall;
134 } 191 }
135 192
136 // get template 193 // setup paramaters
137
138 if (!sDefaultTemplate)
139 {
140 sDefaultTemplate = new LLNotifyBoxTemplate;
141 }
142 194
143 LLPointer<LLNotifyBoxTemplate> xml_template; 195 mMessage = xml_template->mMessage;
144 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); 196 LLAlertDialog::format(mMessage, args);
145 if (iter != sNotifyTemplates.end()) 197
146 { 198 // use name + formatted text as unique key
147 xml_template = iter->second; 199 if (mUnique)
148 }
149 else
150 { 200 {
151 LLString tmsg = "[Notification template not found:\n " + xml_desc + " ]"; 201 sOpenUniqueNotifyBoxes[xml_template->mLabel + mMessage] = this;
152 sDefaultTemplate->setMessage(tmsg);
153 xml_template = sDefaultTemplate;
154 } 202 }
155 203
156 // setup paramaters
157
158 LLString message = xml_template->mMessage;
159 LLAlertDialog::format(message, args);
160
161 option_list_t options = xml_template->mOptions; 204 option_list_t options = xml_template->mOptions;
162 options.insert(options.end(), extra_options.begin(), extra_options.end()); 205 options.insert(options.end(), extra_options.begin(), extra_options.end());
163 206
@@ -175,13 +218,16 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
175 // account for the special layout of a tip notification) 218 // account for the special layout of a tip notification)
176 mIsCaution = ((xml_template->mIsCaution | is_caution) && (!mIsTip)); 219 mIsCaution = ((xml_template->mIsCaution | is_caution) && (!mIsTip));
177 220
178 mAnimating = TRUE; 221 // Don't animate if behind other windows
179 mCallback = callback; 222 if( gNotifyBoxView->getChildCount() > 0 )
180 mData = user_data; 223 mAnimating = FALSE;
224 else
225 mAnimating = TRUE;
226
181 mNumOptions = options.size(); 227 mNumOptions = options.size();
182 mDefaultOption = xml_template->mDefaultOption; 228 mDefaultOption = xml_template->mDefaultOption;
183 229
184 LLRect rect = mIsTip ? getNotifyTipRect(message) 230 LLRect rect = mIsTip ? getNotifyTipRect(mMessage)
185 : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution); 231 : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution);
186 setRect(rect); 232 setRect(rect);
187 setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT)); 233 setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT));
@@ -255,7 +301,7 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
255 text = new LLTextEditor("box", 301 text = new LLTextEditor("box",
256 LLRect(x, y, mRect.getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), 302 LLRect(x, y, mRect.getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16),
257 MAX_LENGTH, 303 MAX_LENGTH,
258 message, 304 mMessage,
259 sFont, 305 sFont,
260 FALSE); 306 FALSE);
261 text->setWordWrap(TRUE); 307 text->setWordWrap(TRUE);
@@ -275,15 +321,15 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
275 if (mIsTip) 321 if (mIsTip)
276 { 322 {
277 // TODO: Make a separate archive for these. 323 // TODO: Make a separate archive for these.
278 LLChat chat(message); 324 LLChat chat(mMessage);
279 chat.mSourceType = CHAT_SOURCE_SYSTEM; 325 chat.mSourceType = CHAT_SOURCE_SYSTEM;
280 gFloaterChat->addChatHistory(chat); 326 LLFloaterChat::getInstance(LLSD())->addChatHistory(chat);
281 } 327 }
282 else 328 else
283 { 329 {
284 LLButton* btn; 330 LLButton* btn;
285 btn = new LLButton("next", 331 btn = new LLButton("next",
286 LLRect(mRect.getWidth()-24, BOTTOM_PAD+16, mRect.getWidth()-8, BOTTOM_PAD), 332 LLRect(mRect.getWidth()-18, BOTTOM_PAD+16, mRect.getWidth()-2, BOTTOM_PAD+2),
287 "notify_next.tga", 333 "notify_next.tga",
288 "notify_next.tga", 334 "notify_next.tga",
289 "", 335 "",
@@ -328,7 +374,7 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
328 userdata->mSelf = this; 374 userdata->mSelf = this;
329 userdata->mButton = i; 375 userdata->mButton = i;
330 376
331 mBtnCallbackData.put(userdata); 377 mBtnCallbackData.push_back(userdata);
332 378
333 btn = new LLButton(options[i], btn_rect, "", onClickButton, userdata); 379 btn = new LLButton(options[i], btn_rect, "", onClickButton, userdata);
334 btn->setFont(font); 380 btn->setFont(font);
@@ -361,10 +407,14 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
361// virtual 407// virtual
362LLNotifyBox::~LLNotifyBox() 408LLNotifyBox::~LLNotifyBox()
363{ 409{
364 S32 count = mBtnCallbackData.count(); 410 delete mBehavior;
365 for (S32 i = 0; i < count; i++) 411 mBehavior = NULL;
412
413 std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
414
415 if (mUnique)
366 { 416 {
367 delete mBtnCallbackData[i]; 417 sOpenUniqueNotifyBoxes.erase(mName + mMessage);
368 } 418 }
369} 419}
370 420
@@ -398,7 +448,7 @@ BOOL LLNotifyBox::handleRightMouseDown(S32 x, S32 y, MASK mask)
398// virtual 448// virtual
399void LLNotifyBox::draw() 449void LLNotifyBox::draw()
400{ 450{
401 F32 display_time = mTimer.getElapsedTimeF32(); 451 F32 display_time = mAnimateTimer.getElapsedTimeF32();
402 452
403 if (mAnimating && display_time < ANIMATION_TIME) 453 if (mAnimating && display_time < ANIMATION_TIME)
404 { 454 {
@@ -492,7 +542,10 @@ void LLNotifyBox::close()
492 gNotifyBoxView->showOnly(front); 542 gNotifyBoxView->showOnly(front);
493 // we're assuming that close is only called by user action (for non-tips), 543 // we're assuming that close is only called by user action (for non-tips),
494 // so we then give focus to the next close button 544 // so we then give focus to the next close button
495 front->mDefaultBtn->setFocus(TRUE); 545 if (front->mDefaultBtn)
546 {
547 front->mDefaultBtn->setFocus(TRUE);
548 }
496 gFocusMgr.triggerFocusFlash(); // TODO it's ugly to call this here 549 gFocusMgr.triggerFocusFlash(); // TODO it's ugly to call this here
497 } 550 }
498 } 551 }
@@ -681,9 +734,9 @@ void LLNotifyBox::onClickButton(void* data)
681 return; 734 return;
682 } 735 }
683 736
684 if (self->mCallback) 737 if (self->mBehavior->mCallback)
685 { 738 {
686 self->mCallback(button, self->mData); 739 self->mBehavior->mCallback(button, self->mBehavior->mData);
687 } 740 }
688 741
689 self->close(); 742 self->close();
@@ -697,10 +750,54 @@ void LLNotifyBox::onClickNext(void* data)
697 self->moveToBack(); 750 self->moveToBack();
698} 751}
699 752
753// static
754LLPointer<LLNotifyBoxTemplate> LLNotifyBox::getTemplate(const LLString& xml_desc)
755{
756 // get template
757
758 if (!sDefaultTemplate)
759 {
760 // default template is non-unique, of course
761 sDefaultTemplate = new LLNotifyBoxTemplate(FALSE, gSavedSettings.getF32("NotifyTipDuration"));
762 sDefaultTemplate->addOption("OK", FALSE);
763 }
764
765 LLPointer<LLNotifyBoxTemplate> xml_template;
766 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
767 if (iter != sNotifyTemplates.end())
768 {
769 xml_template = iter->second;
770 }
771 else
772 {
773 LLString tmsg = "[Notification template not found:\n " + xml_desc + " ]";
774 sDefaultTemplate->setMessage(tmsg);
775 xml_template = sDefaultTemplate;
776 }
777
778 return xml_template;
779}
780
700//----------------------------------------------------------------------------- 781//-----------------------------------------------------------------------------
701 782
702//static 783//static
703const LLString& LLNotifyBox::getTemplateMessage(const LLString& xml_desc) 784const LLString LLNotifyBox::getTemplateMessage(const LLString& xml_desc, const LLString::format_map_t& args)
785{
786 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
787 if (iter != sNotifyTemplates.end())
788 {
789 LLString message = iter->second->mMessage;
790 LLAlertDialog::format(message, args);
791 return message;
792 }
793 else
794 {
795 return xml_desc;
796 }
797}
798
799//static
800const LLString LLNotifyBox::getTemplateMessage(const LLString& xml_desc)
704{ 801{
705 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); 802 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
706 if (iter != sNotifyTemplates.end()) 803 if (iter != sNotifyTemplates.end())
@@ -747,8 +844,14 @@ bool LLNotifyBox::parseNotify(const LLString& xml_filename)
747 { 844 {
748 continue; 845 continue;
749 } 846 }
847
848 BOOL unique = FALSE;
849 notify->getAttributeBOOL("unique", unique);
850
851 F32 duration = gSavedSettings.getF32("NotifyTipDuration");
852 notify->getAttributeF32("duration", duration);
750 853
751 LLPointer<LLNotifyBoxTemplate> xml_template = new LLNotifyBoxTemplate; 854 LLPointer<LLNotifyBoxTemplate> xml_template = new LLNotifyBoxTemplate(unique, duration);
752 855
753 // label= 856 // label=
754 LLString notify_name; 857 LLString notify_name;
diff --git a/linden/indra/newview/llnotify.h b/linden/indra/newview/llnotify.h
index eec27ec..ad9b24a 100644
--- a/linden/indra/newview/llnotify.h
+++ b/linden/indra/newview/llnotify.h
@@ -31,8 +31,8 @@
31 31
32#include "llfontgl.h" 32#include "llfontgl.h"
33#include "llpanel.h" 33#include "llpanel.h"
34#include "lldarray.h"
35#include "lltimer.h" 34#include "lltimer.h"
35#include <vector>
36 36
37class LLButton; 37class LLButton;
38class LLNotifyBoxTemplate; 38class LLNotifyBoxTemplate;
@@ -44,33 +44,36 @@ public:
44 typedef void (*notify_callback_t)(S32 option, void* data); 44 typedef void (*notify_callback_t)(S32 option, void* data);
45 typedef std::vector<LLString> option_list_t; 45 typedef std::vector<LLString> option_list_t;
46 46
47 static void showXml( const LLString& xml_desc, 47 static LLNotifyBox* showXml( const LLString& xml_desc,
48 notify_callback_t callback = NULL, void *user_data = NULL); 48 notify_callback_t callback = NULL, void *user_data = NULL);
49 static void showXml( const LLString& xml_desc, const LLString::format_map_t& args, BOOL is_caution, 49 static LLNotifyBox* showXml( const LLString& xml_desc, const LLString::format_map_t& args, BOOL is_caution,
50 notify_callback_t callback = NULL, void *user_data = NULL); 50 notify_callback_t callback = NULL, void *user_data = NULL);
51 static void showXml( const LLString& xml_desc, const LLString::format_map_t& args, 51 static LLNotifyBox* showXml( const LLString& xml_desc, const LLString::format_map_t& args,
52 notify_callback_t callback = NULL, void *user_data = NULL); 52 notify_callback_t callback = NULL, void *user_data = NULL);
53 // For script notifications: 53 // For script notifications:
54 static void showXml( const LLString& xml_desc, const LLString::format_map_t& args, 54 static LLNotifyBox* showXml( const LLString& xml_desc, const LLString::format_map_t& args,
55 notify_callback_t callback, void *user_data, 55 notify_callback_t callback, void *user_data,
56 const option_list_t& options, 56 const option_list_t& options,
57 BOOL layout_script_dialog = FALSE); 57 BOOL layout_script_dialog = FALSE);
58 58
59 static bool parseNotify(const LLString& xml_filename); 59 static bool parseNotify(const LLString& xml_filename);
60 static const LLString& getTemplateMessage(const LLString& xml_desc); 60 static const LLString getTemplateMessage(const LLString& xml_desc, const LLString::format_map_t& args);
61 static const LLString getTemplateMessage(const LLString& xml_desc);
61 static BOOL getTemplateIsCaution(const LLString& xml_desc); 62 static BOOL getTemplateIsCaution(const LLString& xml_desc);
62 63
63 BOOL isTip() const { return mIsTip; } 64 BOOL isTip() const { return mIsTip; }
64 BOOL isCaution() const { return mIsCaution; } 65 BOOL isCaution() const { return mIsCaution; }
65 /*virtual*/ void setVisible(BOOL visible); 66 /*virtual*/ void setVisible(BOOL visible);
67 void stopAnimation() { mAnimating = FALSE; }
66 68
67 notify_callback_t getNotifyCallback() { return mCallback; } 69 notify_callback_t getNotifyCallback() { return mBehavior->mCallback; }
68 void* getUserData() { return mData; } 70 void* getUserData() { return mBehavior->mData; }
71 void close();
69 72
70 static void cleanup(); 73 static void cleanup();
71 74
72protected: 75protected:
73 LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& args, 76 LLNotifyBox(LLPointer<LLNotifyBoxTemplate> notify_template, const LLString::format_map_t& args,
74 notify_callback_t callback, void* user_data, 77 notify_callback_t callback, void* user_data,
75 BOOL is_caution = FALSE, 78 BOOL is_caution = FALSE,
76 const option_list_t& extra_options = option_list_t(), 79 const option_list_t& extra_options = option_list_t(),
@@ -85,7 +88,6 @@ protected:
85 /*virtual*/ void draw(); 88 /*virtual*/ void draw();
86 /*virtual*/ void tick(); 89 /*virtual*/ void tick();
87 90
88 void close();
89 void moveToBack(); 91 void moveToBack();
90 92
91 // Returns the rect, relative to gNotifyView, where this 93 // Returns the rect, relative to gNotifyView, where this
@@ -99,25 +101,40 @@ protected:
99 // for "next" button 101 // for "next" button
100 static void onClickNext(void* data); 102 static void onClickNext(void* data);
101 103
104 static LLPointer<LLNotifyBoxTemplate> getTemplate(const LLString& xml_desc);
105 static LLNotifyBox* findExistingNotify(LLPointer<LLNotifyBoxTemplate> notify_template, const LLString::format_map_t& args);
106
102private: 107private:
103 void drawBackground() const; 108 void drawBackground() const;
104 109
105 static LLPointer<LLNotifyBoxTemplate> sDefaultTemplate; 110 static LLPointer<LLNotifyBoxTemplate> sDefaultTemplate;
106 111
107protected: 112protected:
113 LLString mMessage;
114
108 BOOL mIsTip; 115 BOOL mIsTip;
109 BOOL mIsCaution; // is this a caution notification? 116 BOOL mIsCaution; // is this a caution notification?
110 BOOL mAnimating; // Are we sliding onscreen? 117 BOOL mAnimating; // Are we sliding onscreen?
118 BOOL mUnique;
111 119
112 // Time since this notification was displayed. 120 // Time since this notification was displayed.
113 // This is an LLTimer not a frame timer because I am concerned 121 // This is an LLTimer not a frame timer because I am concerned
114 // that I could be out-of-sync by one frame in the animation. 122 // that I could be out-of-sync by one frame in the animation.
115 LLTimer mTimer; 123 LLTimer mAnimateTimer;
116 124
117 LLButton* mNextBtn; 125 LLButton* mNextBtn;
118 126
119 notify_callback_t mCallback; 127 // keep response behavior isolated here
120 void* mData; 128 struct LLNotifyBehavior
129 {
130 LLNotifyBehavior(notify_callback_t callback, void* data);
131
132 notify_callback_t mCallback;
133 void* mData;
134
135 };
136 LLNotifyBehavior* mBehavior;
137
121 S32 mNumOptions; 138 S32 mNumOptions;
122 S32 mDefaultOption; 139 S32 mDefaultOption;
123 140
@@ -127,7 +144,7 @@ protected:
127 LLNotifyBox* mSelf; 144 LLNotifyBox* mSelf;
128 S32 mButton; 145 S32 mButton;
129 }; 146 };
130 LLDynamicArray<InstanceAndS32*> mBtnCallbackData; 147 std::vector<InstanceAndS32*> mBtnCallbackData;
131 148
132 typedef std::map<LLString, LLPointer<LLNotifyBoxTemplate> > template_map_t; 149 typedef std::map<LLString, LLPointer<LLNotifyBoxTemplate> > template_map_t;
133 static template_map_t sNotifyTemplates; // by mLabel 150 static template_map_t sNotifyTemplates; // by mLabel
@@ -135,6 +152,9 @@ protected:
135 static S32 sNotifyBoxCount; 152 static S32 sNotifyBoxCount;
136 static const LLFontGL* sFont; 153 static const LLFontGL* sFont;
137 static const LLFontGL* sFontSmall; 154 static const LLFontGL* sFontSmall;
155
156 typedef std::map<LLString, LLNotifyBox*> unique_map_t;
157 static unique_map_t sOpenUniqueNotifyBoxes;
138}; 158};
139 159
140class LLNotifyBoxView : public LLUICtrl 160class LLNotifyBoxView : public LLUICtrl
@@ -154,7 +174,13 @@ extern LLNotifyBoxView* gNotifyBoxView;
154class LLNotifyBoxTemplate : public LLRefCount 174class LLNotifyBoxTemplate : public LLRefCount
155{ 175{
156public: 176public:
157 LLNotifyBoxTemplate() : mIsTip(FALSE), mIsCaution(FALSE), mDefaultOption(0) {} 177 LLNotifyBoxTemplate(BOOL unique, F32 duration) :
178 mIsTip(FALSE),
179 mIsCaution(FALSE),
180 mUnique(unique),
181 mDuration(duration),
182 mDefaultOption(0)
183 {}
158 184
159 void setMessage(const LLString& message) 185 void setMessage(const LLString& message)
160 { 186 {
@@ -174,7 +200,9 @@ public:
174 LLString mLabel; // Handle for access from code, etc 200 LLString mLabel; // Handle for access from code, etc
175 LLString mMessage; // Message to display 201 LLString mMessage; // Message to display
176 BOOL mIsTip; 202 BOOL mIsTip;
177 BOOL mIsCaution; 203 BOOL mIsCaution;
204 BOOL mUnique;
205 F32 mDuration;
178 LLNotifyBox::option_list_t mOptions; 206 LLNotifyBox::option_list_t mOptions;
179 S32 mDefaultOption; 207 S32 mDefaultOption;
180}; 208};
diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp
index 401cb02..f5addd0 100644
--- a/linden/indra/newview/lloverlaybar.cpp
+++ b/linden/indra/newview/lloverlaybar.cpp
@@ -34,24 +34,26 @@
34#include "lloverlaybar.h" 34#include "lloverlaybar.h"
35 35
36#include "audioengine.h" 36#include "audioengine.h"
37#include "llparcel.h"
38
39#include "llagent.h" 37#include "llagent.h"
40#include "llbutton.h" 38#include "llbutton.h"
41#include "llviewercontrol.h" 39#include "llfocusmgr.h"
42#include "llimview.h" 40#include "llimview.h"
43#include "lltextbox.h"
44#include "llvoavatar.h"
45#include "llmediaengine.h" 41#include "llmediaengine.h"
46#include "viewer.h" 42#include "llpanelaudiovolume.h"
43#include "llparcel.h"
44#include "lltextbox.h"
47#include "llui.h" 45#include "llui.h"
46#include "llviewercontrol.h"
47#include "llviewerimagelist.h"
48#include "llviewermenu.h" // handle_reset_view() 48#include "llviewermenu.h" // handle_reset_view()
49#include "llviewerparcelmgr.h" 49#include "llviewerparcelmgr.h"
50#include "llwebbrowserctrl.h"
51#include "llvieweruictrlfactory.h" 50#include "llvieweruictrlfactory.h"
52#include "llviewerimagelist.h"
53#include "llviewerwindow.h" 51#include "llviewerwindow.h"
54#include "llfocusmgr.h" 52#include "llvoiceclient.h"
53#include "llvoavatar.h"
54#include "llvoiceremotectrl.h"
55#include "llwebbrowserctrl.h"
56#include "viewer.h"
55 57
56// 58//
57// Globals 59// Globals
@@ -67,38 +69,54 @@ extern S32 MENU_BAR_HEIGHT;
67 69
68 70
69//static 71//static
70void* LLOverlayBar::createMediaRemote(void* userdata) 72void* LLOverlayBar::createMasterRemote(void* userdata)
71{ 73{
72 74 LLOverlayBar *self = (LLOverlayBar*)userdata;
73 LLOverlayBar *self = (LLOverlayBar*)userdata; 75 self->mMasterRemote = new LLMediaRemoteCtrl ( "master_volume",
76 "volume",
77 LLRect(),
78 "panel_master_volume.xml");
79 return self->mMasterRemote;
80}
74 81
75 82void* LLOverlayBar::createMediaRemote(void* userdata)
83{
84 LLOverlayBar *self = (LLOverlayBar*)userdata;
76 self->mMediaRemote = new LLMediaRemoteCtrl ( "media_remote", 85 self->mMediaRemote = new LLMediaRemoteCtrl ( "media_remote",
77 "media", 86 "media",
78 LLRect(), 87 LLRect(),
79 "panel_media_remote.xml"); 88 "panel_media_remote.xml");
80 return self->mMediaRemote; 89 return self->mMediaRemote;
81} 90}
82 91
83
84
85void* LLOverlayBar::createMusicRemote(void* userdata) 92void* LLOverlayBar::createMusicRemote(void* userdata)
86{ 93{
87
88 LLOverlayBar *self = (LLOverlayBar*)userdata; 94 LLOverlayBar *self = (LLOverlayBar*)userdata;
89
90 self->mMusicRemote = new LLMediaRemoteCtrl ( "music_remote", 95 self->mMusicRemote = new LLMediaRemoteCtrl ( "music_remote",
91 "music", 96 "music",
92 LLRect(), 97 LLRect(),
93 "panel_music_remote.xml" ); 98 "panel_music_remote.xml" );
94 return self->mMusicRemote; 99 return self->mMusicRemote;
95} 100}
96 101
102void* LLOverlayBar::createVoiceRemote(void* userdata)
103{
104 LLOverlayBar *self = (LLOverlayBar*)userdata;
105 self->mVoiceRemote = new LLVoiceRemoteCtrl("voice_remote");
106 return self->mVoiceRemote;
107}
108
97 109
98 110
99 111
100LLOverlayBar::LLOverlayBar(const std::string& name, const LLRect& rect) 112LLOverlayBar::LLOverlayBar(const std::string& name, const LLRect& rect)
101: LLPanel(name, rect, FALSE) // not bordered 113 : LLPanel(name, rect, FALSE), // not bordered
114 mMasterRemote(NULL),
115 mMusicRemote(NULL),
116 mMediaRemote(NULL),
117 mVoiceRemote(NULL),
118 mMediaState(STOPPED),
119 mMusicState(STOPPED)
102{ 120{
103 setMouseOpaque(FALSE); 121 setMouseOpaque(FALSE);
104 setIsChrome(TRUE); 122 setIsChrome(TRUE);
@@ -106,8 +124,10 @@ LLOverlayBar::LLOverlayBar(const std::string& name, const LLRect& rect)
106 isBuilt = FALSE; 124 isBuilt = FALSE;
107 125
108 LLCallbackMap::map_t factory_map; 126 LLCallbackMap::map_t factory_map;
127 factory_map["master_volume"] = LLCallbackMap(LLOverlayBar::createMasterRemote, this);
109 factory_map["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this); 128 factory_map["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
110 factory_map["music_remote"] = LLCallbackMap(LLOverlayBar::createMusicRemote, this); 129 factory_map["music_remote"] = LLCallbackMap(LLOverlayBar::createMusicRemote, this);
130 factory_map["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this);
111 131
112 gUICtrlFactory->buildPanel(this, "panel_overlaybar.xml", &factory_map); 132 gUICtrlFactory->buildPanel(this, "panel_overlaybar.xml", &factory_map);
113 133
@@ -117,30 +137,17 @@ LLOverlayBar::LLOverlayBar(const std::string& name, const LLRect& rect)
117 childSetAction("Mouselook",onClickMouselook,this); 137 childSetAction("Mouselook",onClickMouselook,this);
118 childSetAction("Stand Up",onClickStandUp,this); 138 childSetAction("Stand Up",onClickStandUp,this);
119 139
120 mMusicRemote->addObserver ( this );
121
122 if ( gAudiop )
123 {
124 mMusicRemote->setVolume ( gSavedSettings.getF32 ( "AudioLevelMusic" ) );
125 mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Stop, FALSE );
126 };
127
128 mIsFocusRoot = TRUE; 140 mIsFocusRoot = TRUE;
129
130 mMediaRemote->addObserver ( this );
131 mMediaRemote->setVolume ( gSavedSettings.getF32 ( "MediaAudioVolume" ) );
132
133 isBuilt = true; 141 isBuilt = true;
134 142
143 // make overlay bar conform to window size
144 setRect(rect);
135 layoutButtons(); 145 layoutButtons();
136} 146}
137 147
138LLOverlayBar::~LLOverlayBar() 148LLOverlayBar::~LLOverlayBar()
139{ 149{
140 // LLView destructor cleans up children 150 // LLView destructor cleans up children
141
142 mMusicRemote->remObserver ( this );
143 mMediaRemote->remObserver ( this );
144} 151}
145 152
146EWidgetType LLOverlayBar::getWidgetType() const 153EWidgetType LLOverlayBar::getWidgetType() const
@@ -164,20 +171,28 @@ void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent)
164 } 171 }
165} 172}
166 173
167
168void LLOverlayBar::layoutButtons() 174void LLOverlayBar::layoutButtons()
169{ 175{
170 S32 width = mRect.getWidth(); 176 S32 width = mRect.getWidth();
171 if (width > 800) width = 800; 177 if (width > 1024) width = 1024;
172 178
173 S32 count = getChildCount(); 179 S32 count = getChildCount();
174 const S32 PAD = gSavedSettings.getS32("StatusBarPad"); 180 const S32 PAD = gSavedSettings.getS32("StatusBarPad");
175 181
176 F32 segment_width = (F32)(width) / (F32)count; 182 const S32 num_media_controls = 3;
183 S32 media_remote_width = mMediaRemote ? mMediaRemote->getRect().getWidth() : 0;
184 S32 music_remote_width = mMusicRemote ? mMusicRemote->getRect().getWidth() : 0;
185 S32 voice_remote_width = mVoiceRemote ? mVoiceRemote->getRect().getWidth() : 0;
186 S32 master_remote_width = mMasterRemote ? mMasterRemote->getRect().getWidth() : 0;
177 187
178 S32 btn_width = lltrunc(segment_width - PAD); 188 // total reserved width for all media remotes
189 const S32 ENDPAD = 20;
190 S32 remote_total_width = media_remote_width + PAD + music_remote_width + PAD + voice_remote_width + PAD + master_remote_width + ENDPAD;
179 191
180 S32 remote_width = mMusicRemote->getRect().getWidth(); 192 // calculate button widths
193 F32 segment_width = (F32)(width - remote_total_width) / (F32)(count - num_media_controls);
194
195 S32 btn_width = lltrunc(segment_width - PAD);
181 196
182 // Evenly space all views 197 // Evenly space all views
183 LLRect r; 198 LLRect r;
@@ -187,22 +202,47 @@ void LLOverlayBar::layoutButtons()
187 { 202 {
188 LLView *view = *child_iter; 203 LLView *view = *child_iter;
189 r = view->getRect(); 204 r = view->getRect();
190 r.mLeft = (width) - llround((i+1)*segment_width); 205 r.mLeft = (width) - llround(remote_total_width + (i-num_media_controls+1)*segment_width);
191 r.mRight = r.mLeft + btn_width; 206 r.mRight = r.mLeft + btn_width;
192 view->setRect(r); 207 view->setRect(r);
193 i++; 208 i++;
194 } 209 }
195 210
196 // Fix up remotes to have constant width because they can't shrink 211 // Fix up remotes to have constant width because they can't shrink
197 r = mMusicRemote->getRect(); 212 S32 right = mRect.getWidth() - remote_total_width - PAD;
198 r.mRight = r.mLeft + remote_width; 213 if (mMediaRemote)
199 mMusicRemote->setRect(r); 214 {
200 215 r = mMediaRemote->getRect();
201 r = mMediaRemote->getRect(); 216 r.mLeft = right + PAD;
202 r.mLeft = mMusicRemote->getRect().mRight + PAD; 217 right = r.mLeft + media_remote_width;
203 r.mRight = r.mLeft + remote_width; 218 r.mRight = right;
204 mMediaRemote->setRect(r); 219 mMediaRemote->setRect(r);
205 220 }
221 if (mMusicRemote)
222 {
223 r = mMusicRemote->getRect();
224 r.mLeft = right + PAD;
225 right = r.mLeft + music_remote_width;
226 r.mRight = right;
227 mMusicRemote->setRect(r);
228 }
229 if (mVoiceRemote)
230 {
231 r = mVoiceRemote->getRect();
232 r.mLeft = right + PAD;
233 right = r.mLeft + voice_remote_width;
234 r.mRight = right;
235 mVoiceRemote->setRect(r);
236 }
237 if (mMasterRemote)
238 {
239 r = mMasterRemote->getRect();
240 r.mLeft = right + PAD;
241 right = r.mLeft + master_remote_width;
242 r.mRight = right;
243 mMasterRemote->setRect(r);
244 }
245
206 updateRect(); 246 updateRect();
207} 247}
208 248
@@ -282,7 +322,7 @@ void LLOverlayBar::draw()
282// Per-frame updates of visibility 322// Per-frame updates of visibility
283void LLOverlayBar::refresh() 323void LLOverlayBar::refresh()
284{ 324{
285 BOOL im_received = gIMView->getIMReceived(); 325 BOOL im_received = gIMMgr->getIMReceived();
286 childSetVisible("IM Received", im_received); 326 childSetVisible("IM Received", im_received);
287 childSetEnabled("IM Received", im_received); 327 childSetEnabled("IM Received", im_received);
288 328
@@ -313,10 +353,10 @@ void LLOverlayBar::refresh()
313 353
314 } 354 }
315 355
316 if ( gAudiop ) 356 if ( mMusicRemote && gAudiop )
317 { 357 {
318 LLParcel* parcel = gParcelMgr->getAgentParcel(); 358 LLParcel* parcel = gParcelMgr->getAgentParcel();
319 if (!parcel 359 if (!parcel
320 || !parcel->getMusicURL() 360 || !parcel->getMusicURL()
321 || !parcel->getMusicURL()[0] 361 || !parcel->getMusicURL()[0]
322 || !gSavedSettings.getBOOL("AudioStreamingMusic")) 362 || !gSavedSettings.getBOOL("AudioStreamingMusic"))
@@ -332,50 +372,29 @@ void LLOverlayBar::refresh()
332 } 372 }
333 373
334 // if there is a url and a texture and media is enabled and available and media streaming is on... (phew!) 374 // if there is a url and a texture and media is enabled and available and media streaming is on... (phew!)
335 if ( LLMediaEngine::getInstance () && 375 if ( mMediaRemote )
336 LLMediaEngine::getInstance ()->getUrl ().length () &&
337 LLMediaEngine::getInstance ()->getImageUUID ().notNull () &&
338 LLMediaEngine::getInstance ()->isEnabled () &&
339 LLMediaEngine::getInstance ()->isAvailable () &&
340 gSavedSettings.getBOOL ( "AudioStreamingVideo" ) )
341 { 376 {
342 // display remote control 377 if (LLMediaEngine::getInstance () &&
343 mMediaRemote->setVisible ( TRUE ); 378 LLMediaEngine::getInstance ()->getUrl ().length () &&
344 mMediaRemote->setEnabled ( TRUE ); 379 LLMediaEngine::getInstance ()->getImageUUID ().notNull () &&
345 380 LLMediaEngine::getInstance ()->isEnabled () &&
346 if ( LLMediaEngine::getInstance ()->getMediaRenderer () ) 381 LLMediaEngine::getInstance ()->isAvailable () &&
382 gSavedSettings.getBOOL ( "AudioStreamingVideo" ) )
347 { 383 {
348 if ( LLMediaEngine::getInstance ()->getMediaRenderer ()->isPlaying () || 384 // display remote control
349 LLMediaEngine::getInstance ()->getMediaRenderer ()->isLooping () ) 385 mMediaRemote->setVisible ( TRUE );
350 { 386 mMediaRemote->setEnabled ( TRUE );
351 mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Pause, TRUE ); 387 }
352 } 388 else
353 else 389 {
354 if ( LLMediaEngine::getInstance ()->getMediaRenderer ()->isPaused () ) 390 mMediaRemote->setVisible ( FALSE );
355 { 391 mMediaRemote->setEnabled ( FALSE );
356 mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Play, TRUE ); 392 }
357 }
358 else
359 {
360 mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Stop, TRUE );
361 };
362 };
363 } 393 }
364 else 394 if (mVoiceRemote)
365 { 395 {
366 mMediaRemote->setVisible ( FALSE ); 396 mVoiceRemote->setVisible(LLVoiceClient::voiceEnabled());
367 mMediaRemote->setEnabled ( FALSE ); 397 }
368 mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Stop, TRUE );
369 };
370
371 BOOL any_button = (childIsVisible("IM Received")
372 || childIsVisible("Set Not Busy")
373 || childIsVisible("Release Keys")
374 || childIsVisible("Mouselook")
375 || childIsVisible("Stand Up")
376 || mMusicRemote->getVisible()
377 || mMediaRemote->getVisible() );
378
379 398
380 // turn off the whole bar in mouselook 399 // turn off the whole bar in mouselook
381 if (gAgent.cameraMouselook()) 400 if (gAgent.cameraMouselook())
@@ -384,8 +403,8 @@ void LLOverlayBar::refresh()
384 } 403 }
385 else 404 else
386 { 405 {
387 setVisible(any_button); 406 setVisible(TRUE);
388 }; 407 }
389} 408}
390 409
391//----------------------------------------------------------------------- 410//-----------------------------------------------------------------------
@@ -395,7 +414,7 @@ void LLOverlayBar::refresh()
395// static 414// static
396void LLOverlayBar::onClickIMReceived(void*) 415void LLOverlayBar::onClickIMReceived(void*)
397{ 416{
398 gIMView->setFloaterOpen(TRUE); 417 gIMMgr->setFloaterOpen(TRUE);
399} 418}
400 419
401 420
@@ -431,134 +450,162 @@ void LLOverlayBar::onClickStandUp(void*)
431} 450}
432 451
433//////////////////////////////////////////////////////////////////////////////// 452////////////////////////////////////////////////////////////////////////////////
434// 453// static media helpers
435// 454// *TODO: Move this into an audio manager abstraction
436void
437LLOverlayBar::
438onVolumeChange ( const LLMediaRemoteCtrlObserver::EventType& eventIn )
439{
440 LLUICtrl* control = eventIn.getControl ();
441 F32 value = eventIn.getValue ();
442 455
443 if ( control == mMusicRemote ) 456//static
457void LLOverlayBar::mediaPlay(void*)
458{
459 if (!gOverlayBar)
444 { 460 {
445 if (gAudiop) 461 return;
446 {
447 gAudiop->setInternetStreamGain ( value );
448 };
449 gSavedSettings.setF32 ( "AudioLevelMusic", value );
450 } 462 }
451 else 463 gOverlayBar->mMediaState = PLAYING; // desired state
452 if ( control == mMediaRemote ) 464 LLParcel* parcel = gParcelMgr->getAgentParcel();
465 if (parcel)
453 { 466 {
454 LLMediaEngine::getInstance ()->setVolume ( value ); 467 LLString path("");
455 gSavedSettings.setF32 ( "MediaAudioVolume", value ); 468 LLMediaEngine::getInstance()->convertImageAndLoadUrl( true, false, path );
456 469 }
457 };
458} 470}
459 471//static
460//////////////////////////////////////////////////////////////////////////////// 472void LLOverlayBar::mediaPause(void*)
461//
462//
463void
464LLOverlayBar::
465onStopButtonPressed ( const LLMediaRemoteCtrlObserver::EventType& eventIn )
466{ 473{
467 LLUICtrl* control = eventIn.getControl (); 474 if (!gOverlayBar)
468
469 if ( control == mMusicRemote )
470 { 475 {
471 if ( gAudiop ) 476 return;
472 {
473 gAudiop->stopInternetStream ();
474 };
475 mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Stop, FALSE );
476 } 477 }
477 else 478 gOverlayBar->mMediaState = PAUSED; // desired state
478 if ( control == mMediaRemote ) 479 LLMediaEngine::getInstance()->pause();
480}
481//static
482void LLOverlayBar::mediaStop(void*)
483{
484 if (!gOverlayBar)
479 { 485 {
480 LLMediaEngine::getInstance ()->stop (); 486 return;
481 mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Stop, TRUE ); 487 }
482 }; 488 gOverlayBar->mMediaState = STOPPED; // desired state
489 LLMediaEngine::getInstance()->stop();
483} 490}
484 491
485//////////////////////////////////////////////////////////////////////////////// 492//static
486// 493void LLOverlayBar::musicPlay(void*)
487//
488void LLOverlayBar::onPlayButtonPressed( const LLMediaRemoteCtrlObserver::EventType& eventIn )
489{ 494{
490 LLUICtrl* control = eventIn.getControl (); 495 if (!gOverlayBar)
491
492 LLParcel* parcel = gParcelMgr->getAgentParcel();
493 if ( control == mMusicRemote )
494 { 496 {
495 if (gAudiop) 497 return;
498 }
499 gOverlayBar->mMusicState = PLAYING; // desired state
500 if (gAudiop)
501 {
502 LLParcel* parcel = gParcelMgr->getAgentParcel();
503 if ( parcel )
496 { 504 {
497 if ( parcel ) 505 // this doesn't work properly when crossing parcel boundaries - even when the
506 // stream is stopped, it doesn't return the right thing - commenting out for now.
507// if ( gAudiop->isInternetStreamPlaying() == 0 )
498 { 508 {
499 // this doesn't work properly when crossing parcel boundaries - even when the 509 gAudiop->startInternetStream(parcel->getMusicURL());
500 // stream is stopped, it doesn't return the right thing - commenting out for now.
501 //if ( gAudiop->isInternetStreamPlaying() == 0 )
502 //{
503 const char* music_url = parcel->getMusicURL();
504
505 gAudiop->startInternetStream(music_url);
506
507 mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Play, FALSE );
508 //}
509 } 510 }
510 }; 511 }
511
512 // CP: this is the old way of doing things (click play each time on a parcel to start stream)
513 //if (gAudiop)
514 //{
515 // if (gAudiop->isInternetStreamPlaying() > 0)
516 // {
517 // gAudiop->pauseInternetStream ( 0 );
518 // }
519 // else
520 // {
521 // if (parcel)
522 // {
523 // const char* music_url = parcel->getMusicURL();
524 // gAudiop->startInternetStream(music_url);
525 // }
526 // }
527 //};
528 //mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Stop, FALSE );
529 } 512 }
530 else 513}
531 if ( control == mMediaRemote ) 514//static
515void LLOverlayBar::musicPause(void*)
516{
517 if (!gOverlayBar)
532 { 518 {
533 LLParcel* parcel = gParcelMgr->getAgentParcel(); 519 return;
534 if (parcel) 520 }
521 gOverlayBar->mMusicState = PAUSED; // desired state
522 if (gAudiop)
523 {
524 gAudiop->pauseInternetStream(1);
525 }
526}
527//static
528void LLOverlayBar::musicStop(void*)
529{
530 if (!gOverlayBar)
531 {
532 return;
533 }
534 gOverlayBar->mMusicState = STOPPED; // desired state
535 if (gAudiop)
536 {
537 gAudiop->stopInternetStream();
538 }
539}
540
541//static
542void LLOverlayBar::enableMusicButtons(LLPanel* panel)
543{
544 BOOL play_enabled = FALSE;
545 BOOL play_visible = TRUE;
546 BOOL pause_visible = FALSE;
547 BOOL stop_enabled = FALSE;
548 if ( gAudiop && gOverlayBar && gSavedSettings.getBOOL("AudioStreamingMusic"))
549 {
550 play_enabled = TRUE;
551 S32 is_playing = gAudiop->isInternetStreamPlaying();
552 if (is_playing == 1)
535 { 553 {
536 LLString path( "" ); 554 play_visible = FALSE;
537 LLMediaEngine::getInstance ()->convertImageAndLoadUrl( true, false, path ); 555 pause_visible = TRUE;
538 mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Play, TRUE ); 556 stop_enabled = TRUE;
539 } 557 }
540 }; 558 else if (is_playing == 2)
559 {
560 play_visible = TRUE;
561 pause_visible = FALSE;
562 stop_enabled = TRUE;
563 }
564 }
565 panel->childSetEnabled("music_play", play_enabled);
566 panel->childSetEnabled("music_pause", play_enabled);
567 panel->childSetVisible("music_play", play_visible);
568 panel->childSetVisible("music_pause", pause_visible);
569 panel->childSetEnabled("music_stop", stop_enabled);
541} 570}
542 571
543//////////////////////////////////////////////////////////////////////////////// 572//static
544// 573void LLOverlayBar::enableMediaButtons(LLPanel* panel)
545//
546void LLOverlayBar::onPauseButtonPressed( const LLMediaRemoteCtrlObserver::EventType& eventIn )
547{ 574{
548 LLUICtrl* control = eventIn.getControl (); 575 // Media
576 BOOL play_enabled = FALSE;
577 BOOL play_visible = TRUE;
578 BOOL pause_visible = FALSE;
579 BOOL stop_enabled = FALSE;
549 580
550 if ( control == mMusicRemote ) 581 if ( LLMediaEngine::getInstance() && gOverlayBar && gSavedSettings.getBOOL("AudioStreamingVideo") )
551 { 582 {
552 if (gAudiop) 583 play_enabled = TRUE;
584 if (LLMediaEngine::getInstance()->getMediaRenderer())
553 { 585 {
554 gAudiop->pauseInternetStream ( 1 ); 586 if ( LLMediaEngine::getInstance()->getMediaRenderer()->isPlaying() ||
555 }; 587 LLMediaEngine::getInstance()->getMediaRenderer()->isLooping() )
556 mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Play, FALSE ); 588 {
589 play_visible = FALSE;
590 pause_visible = TRUE;
591 stop_enabled = TRUE;
592 }
593 else if ( LLMediaEngine::getInstance()->getMediaRenderer()->isPaused() )
594 {
595 play_visible = TRUE;
596 pause_visible = FALSE;
597 stop_enabled = TRUE;
598 }
599 }
557 } 600 }
558 else 601 panel->childSetEnabled("media_play", play_enabled);
559 if ( control == mMediaRemote ) 602 panel->childSetEnabled("media_pause", play_enabled);
560 { 603 panel->childSetVisible("media_play", play_visible);
561 LLMediaEngine::getInstance ()->pause (); 604 panel->childSetVisible("media_pause", pause_visible);
562 mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Pause, TRUE ); 605 panel->childSetEnabled("media_stop", stop_enabled);
563 }; 606}
607
608void LLOverlayBar::toggleAudioVolumeFloater(void* user_data)
609{
610 LLFloaterAudioVolume::toggleInstance(LLSD());
564} 611}
diff --git a/linden/indra/newview/lloverlaybar.h b/linden/indra/newview/lloverlaybar.h
index 1f15023..de6c0ae 100644
--- a/linden/indra/newview/lloverlaybar.h
+++ b/linden/indra/newview/lloverlaybar.h
@@ -45,11 +45,10 @@ class LLUUID;
45class LLFrameTimer; 45class LLFrameTimer;
46class LLStatGraph; 46class LLStatGraph;
47class LLSlider; 47class LLSlider;
48class LLVolumeSliderCtrl; 48class LLVoiceRemoteCtrl;
49 49
50class LLOverlayBar 50class LLOverlayBar
51: public LLPanel, 51: public LLPanel
52 public LLMediaRemoteCtrlObserver
53{ 52{
54public: 53public:
55 LLOverlayBar(const std::string& name, const LLRect& rect ); 54 LLOverlayBar(const std::string& name, const LLRect& rect );
@@ -58,14 +57,16 @@ public:
58 virtual EWidgetType getWidgetType() const; 57 virtual EWidgetType getWidgetType() const;
59 virtual LLString getWidgetTag() const; 58 virtual LLString getWidgetTag() const;
60 59
61 virtual void reshape(S32 width, S32 height, BOOL called_from_parent); 60 /*virtual*/ void refresh();
62 61 /*virtual*/ void draw();
63 void refresh(); 62 /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
64 63
65 void layoutButtons(); 64 void layoutButtons();
66 65
67 /*virtual*/ void draw(); 66 // helpers for returning desired state
68 67 BOOL mediaPlaying() { return mMediaState == PLAYING; }
68 BOOL musicPlaying() { return mMusicState == PLAYING; }
69
69 static void onClickIMReceived(void* data); 70 static void onClickIMReceived(void* data);
70 static void onClickSetNotBusy(void* data); 71 static void onClickSetNotBusy(void* data);
71 static void onClickReleaseKeys(void* data); 72 static void onClickReleaseKeys(void* data);
@@ -73,23 +74,35 @@ public:
73 static void onClickStandUp(void* data); 74 static void onClickStandUp(void* data);
74 static void onClickResetView(void* data); 75 static void onClickResetView(void* data);
75 76
76 // observer overrides 77 //static media helper functions
77 void onVolumeChange ( const LLMediaRemoteCtrlObserver::EventType& eventIn ); 78 static void mediaPlay(void*);
78 void onStopButtonPressed ( const LLMediaRemoteCtrlObserver::EventType& eventIn ); 79 static void mediaPause(void*);
79 void onPlayButtonPressed ( const LLMediaRemoteCtrlObserver::EventType& eventIn ); 80 static void mediaStop(void*);
80 void onPauseButtonPressed ( const LLMediaRemoteCtrlObserver::EventType& eventIn ); 81
81 82 static void musicPlay(void*);
82 LLMediaRemoteCtrl* getMusicRemoteControl () { return mMusicRemote; }; 83 static void musicPause(void*);
84 static void musicStop(void*);
83 85
84protected: 86 static void toggleAudioVolumeFloater(void*);
87
88 static void enableMediaButtons(LLPanel* panel);
89 static void enableMusicButtons(LLPanel* panel);
85 90
91protected:
92 static void* createMasterRemote(void* userdata);
86 static void* createMusicRemote(void* userdata); 93 static void* createMusicRemote(void* userdata);
87 static void* createMediaRemote(void* userdata); 94 static void* createMediaRemote(void* userdata);
95 static void* createVoiceRemote(void* userdata);
88 96
89protected: 97protected:
98 LLMediaRemoteCtrl* mMasterRemote;
90 LLMediaRemoteCtrl* mMusicRemote; 99 LLMediaRemoteCtrl* mMusicRemote;
91 LLMediaRemoteCtrl* mMediaRemote; 100 LLMediaRemoteCtrl* mMediaRemote;
101 LLVoiceRemoteCtrl* mVoiceRemote;
92 BOOL isBuilt; 102 BOOL isBuilt;
103 enum { STOPPED=0, PLAYING=1, PAUSED=2 };
104 BOOL mMediaState;
105 BOOL mMusicState;
93}; 106};
94 107
95extern LLOverlayBar* gOverlayBar; 108extern LLOverlayBar* gOverlayBar;
diff --git a/linden/indra/newview/llpanelaudioprefs.cpp b/linden/indra/newview/llpanelaudioprefs.cpp
index 4a58cea..b28fb83 100644
--- a/linden/indra/newview/llpanelaudioprefs.cpp
+++ b/linden/indra/newview/llpanelaudioprefs.cpp
@@ -38,70 +38,58 @@
38#include "llfontgl.h" 38#include "llfontgl.h"
39 39
40// project includes 40// project includes
41#include "llviewerwindow.h" 41#include "audioengine.h"
42#include "llui.h"
43#include "llspinctrl.h"
44#include "llslider.h"
45#include "llradiogroup.h"
46#include "llsliderctrl.h"
47#include "llcheckboxctrl.h"
48#include "lltextbox.h"
49#include "llbutton.h" 42#include "llbutton.h"
43#include "llcheckboxctrl.h"
50#include "llcombobox.h" 44#include "llcombobox.h"
51#include "audioengine.h"
52#include "llmediaengine.h"
53#include "llfirstuse.h" 45#include "llfirstuse.h"
46#include "llmediaengine.h"
47#include "llnotify.h"
48#include "llpanelaudiovolume.h"
54#include "llparcel.h" 49#include "llparcel.h"
50#include "llradiogroup.h"
51#include "llresmgr.h"
52#include "llslider.h"
53#include "llsliderctrl.h"
54#include "llspinctrl.h"
55#include "lltextbox.h"
56#include "llui.h"
55#include "llviewerparcelmgr.h" 57#include "llviewerparcelmgr.h"
56#include "llnotify.h"
57#include "llvieweruictrlfactory.h" 58#include "llvieweruictrlfactory.h"
58#include "llresmgr.h" 59#include "llviewerwindow.h"
59#include "viewer.h" // do_disconnect 60#include "viewer.h" // do_disconnect
60 61
61// 62//
62// Imported globals
63//
64
65extern LLAudioEngine *gAudiop;
66
67//
68// Globals
69//
70
71
72//
73// Static functions 63// Static functions
74// 64//
75 65
76 66//static
77 67void* LLPanelAudioPrefs::createVolumePanel(void* data)
68{
69 LLPanelAudioVolume* panel = new LLPanelAudioVolume();
70 return panel;
71}
78 72
79LLPanelAudioPrefs::LLPanelAudioPrefs() 73LLPanelAudioPrefs::LLPanelAudioPrefs()
80{ 74{
81 75 mFactoryMap["Volume Panel"] = LLCallbackMap(createVolumePanel, NULL);
82 gUICtrlFactory->buildPanel(this, "panel_preferences_audio.xml"); 76
83 77 gUICtrlFactory->buildPanel(this, "panel_preferences_audio.xml", &getFactoryMap());
84
85} 78}
86 79
87
88LLPanelAudioPrefs::~LLPanelAudioPrefs() 80LLPanelAudioPrefs::~LLPanelAudioPrefs()
89{ 81{
90 // Children all cleaned up by default view destructor. 82 // Children all cleaned up by default view destructor.
91} 83}
92 84
93
94
95
96BOOL LLPanelAudioPrefs::postBuild() 85BOOL LLPanelAudioPrefs::postBuild()
97{ 86{
98
99
100 mPreviousMediaVolume = gSavedSettings.getF32("MediaAudioVolume");
101 mPreviousVolume = gSavedSettings.getF32("AudioLevelMaster"); 87 mPreviousVolume = gSavedSettings.getF32("AudioLevelMaster");
88 mPreviousSFX = gSavedSettings.getF32("AudioLevelSFX");
102 mPreviousUI = gSavedSettings.getF32("AudioLevelUI"); 89 mPreviousUI = gSavedSettings.getF32("AudioLevelUI");
103 mPreviousFootsteps = gSavedSettings.getF32("AudioLevelFootsteps"); 90 mPreviousEnvironment = gSavedSettings.getF32("AudioLevelAmbient");
104 mPreviousWind = gSavedSettings.getF32("AudioLevelWind"); 91 mPreviousMusicVolume = gSavedSettings.getF32("AudioLevelMusic");
92 mPreviousMediaVolume = gSavedSettings.getF32("AudioLevelMedia");
105 mPreviousDoppler = gSavedSettings.getF32("AudioLevelDoppler"); 93 mPreviousDoppler = gSavedSettings.getF32("AudioLevelDoppler");
106 mPreviousDistance = gSavedSettings.getF32("AudioLevelDistance"); 94 mPreviousDistance = gSavedSettings.getF32("AudioLevelDistance");
107 mPreviousRolloff = gSavedSettings.getF32("AudioLevelRolloff"); 95 mPreviousRolloff = gSavedSettings.getF32("AudioLevelRolloff");
@@ -117,87 +105,20 @@ BOOL LLPanelAudioPrefs::postBuild()
117 mPreviousMuteAudio = gSavedSettings.getBOOL("MuteAudio"); 105 mPreviousMuteAudio = gSavedSettings.getBOOL("MuteAudio");
118 mPreviousMuteWhenMinimized = gSavedSettings.getBOOL("MuteWhenMinimized"); 106 mPreviousMuteWhenMinimized = gSavedSettings.getBOOL("MuteWhenMinimized");
119 107
120
121
122 childSetCommitCallback("disable audio", onMuteAudio, this);
123
124 enable(!gSavedSettings.getBOOL("MuteAudio"));
125
126 return TRUE; 108 return TRUE;
127 109
128} 110}
129 111
130
131void LLPanelAudioPrefs::enable(BOOL b)
132{
133 childSetEnabled("mute_when_minimized", b);
134
135 childSetEnabled("streaming_text", b);
136 childSetEnabled("streaming_music", b);
137 childSetEnabled("streaming_video", b);
138
139 childSetEnabled("System Volume", b);
140 childSetEnabled("system_volume_text", b);
141
142 childSetEnabled("Wind Volume", b);
143 childSetEnabled("wind_volume_text", b);
144
145 childSetEnabled("Footsteps Volume", b);
146 childSetEnabled("footsteps_volume_text", b);
147
148 childSetEnabled("UI Volume", b);
149 childSetEnabled("ui_volume", b);
150
151 childSetEnabled("Doppler Effect", b);
152 childSetEnabled("doppler_effect_text", b);
153
154 childSetEnabled("Distance Factor", b);
155 childSetEnabled("distance_factor_text", b);
156
157 childSetEnabled("Rolloff Factor", b);
158 childSetEnabled("rolloff_factor_text", b);
159
160 childSetEnabled("L$ Change Threshold", b);
161
162 childSetEnabled("Health Change Threshold", b);
163
164 childSetEnabled("bitrate", b);
165 childSetEnabled("default_upload_bitrate_text", b);
166}
167
168struct LLPARestartData
169{
170 BOOL mMuteAudio;
171};
172
173
174
175void LLPanelAudioPrefs::apply()
176{
177
178}
179
180
181
182void LLPanelAudioPrefs::onMuteAudio(LLUICtrl* ctrl, void* userdata)
183{
184 LLPanelAudioPrefs* self = (LLPanelAudioPrefs*)userdata;
185 LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl;
186
187 self->enable(!check->get());
188
189}
190
191
192void LLPanelAudioPrefs::cancel() 112void LLPanelAudioPrefs::cancel()
193{ 113{
194 114
195 gSavedSettings.setS32("AudioDefaultBitrate", mPreviousBitrate); 115 gSavedSettings.setS32("AudioDefaultBitrate", mPreviousBitrate);
196 gSavedSettings.setF32("MediaAudioVolume", mPreviousMediaVolume);
197 gSavedSettings.setF32("AudioLevelMaster", mPreviousVolume ); 116 gSavedSettings.setF32("AudioLevelMaster", mPreviousVolume );
198 gSavedSettings.setF32("AudioLevelUI", mPreviousUI ); 117 gSavedSettings.setF32("AudioLevelUI", mPreviousUI );
199 gSavedSettings.setF32("AudioLevelFootsteps", mPreviousFootsteps ); 118 gSavedSettings.setF32("AudioLevelSFX", mPreviousSFX );
200 gSavedSettings.setF32("AudioLevelWind", mPreviousWind ); 119 gSavedSettings.setF32("AudioLevelAmbient", mPreviousEnvironment );
120 gSavedSettings.setF32("AudioLevelMusic", mPreviousMusicVolume);
121 gSavedSettings.setF32("AudioLevelMedia", mPreviousMediaVolume);
201 gSavedSettings.setF32("AudioLevelDoppler", mPreviousDoppler ); 122 gSavedSettings.setF32("AudioLevelDoppler", mPreviousDoppler );
202 gSavedSettings.setF32("AudioLevelDistance", mPreviousDistance ); 123 gSavedSettings.setF32("AudioLevelDistance", mPreviousDistance );
203 gSavedSettings.setF32("AudioLevelRolloff", mPreviousRolloff ); 124 gSavedSettings.setF32("AudioLevelRolloff", mPreviousRolloff );
@@ -211,7 +132,4 @@ void LLPanelAudioPrefs::cancel()
211 132
212 gSavedSettings.setBOOL("MuteAudio", mPreviousMuteAudio ); 133 gSavedSettings.setBOOL("MuteAudio", mPreviousMuteAudio );
213 gSavedSettings.setBOOL("MuteWhenMinimized", mPreviousMuteWhenMinimized ); 134 gSavedSettings.setBOOL("MuteWhenMinimized", mPreviousMuteWhenMinimized );
214
215
216
217} 135}
diff --git a/linden/indra/newview/llpanelaudioprefs.h b/linden/indra/newview/llpanelaudioprefs.h
index 63ac77b..9fd4e8d 100644
--- a/linden/indra/newview/llpanelaudioprefs.h
+++ b/linden/indra/newview/llpanelaudioprefs.h
@@ -43,24 +43,21 @@ class LLPanelAudioPrefs : public LLPanel
43public: 43public:
44 LLPanelAudioPrefs(); 44 LLPanelAudioPrefs();
45 virtual ~LLPanelAudioPrefs(); 45 virtual ~LLPanelAudioPrefs();
46 46
47 void apply(); // Apply the changed values.
48 void cancel(); // Cancel the changed values. 47 void cancel(); // Cancel the changed values.
49 48
50 void enable(BOOL b);
51 virtual BOOL postBuild(); 49 virtual BOOL postBuild();
52
53 static void restartCallback(S32 option, void *userdata);
54 static void onMuteAudio(LLUICtrl* ctrl, void* userdata);
55 50
51 static void* createVolumePanel(void* data);
52
56protected: 53protected:
57 54
58
59 F32 mPreviousVolume; 55 F32 mPreviousVolume;
56 F32 mPreviousMusicVolume;
60 F32 mPreviousMediaVolume; 57 F32 mPreviousMediaVolume;
58 F32 mPreviousSFX;
61 F32 mPreviousUI; 59 F32 mPreviousUI;
62 F32 mPreviousFootsteps; 60 F32 mPreviousEnvironment;
63 F32 mPreviousWind;
64 F32 mPreviousDoppler; 61 F32 mPreviousDoppler;
65 F32 mPreviousDistance; 62 F32 mPreviousDistance;
66 F32 mPreviousRolloff; 63 F32 mPreviousRolloff;
diff --git a/linden/indra/newview/llpanelaudiovolume.cpp b/linden/indra/newview/llpanelaudiovolume.cpp
new file mode 100644
index 0000000..902614e
--- /dev/null
+++ b/linden/indra/newview/llpanelaudiovolume.cpp
@@ -0,0 +1,109 @@
1/**
2 * @file llpanelaudiovolume.cpp
3 * @brief A remote control for media (video and music)
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "llviewerprecompiledheaders.h"
30
31#include "llpanelaudiovolume.h"
32
33#include "lloverlaybar.h"
34#include "llviewercontrol.h"
35#include "llvieweruictrlfactory.h"
36
37////////////////////////////////////////////////////////////////////////////////
38// Floater version of audio panel
39//
40
41//static
42void* LLFloaterAudioVolume::createVolumePanel(void* data)
43{
44 LLPanelAudioVolume* panel = new LLPanelAudioVolume();
45 return panel;
46}
47
48LLFloaterAudioVolume::LLFloaterAudioVolume(const LLSD& seed)
49{
50 mFactoryMap["Volume Panel"] = LLCallbackMap(createVolumePanel, NULL);
51 gUICtrlFactory->buildFloater(this, "floater_audio_volume.xml", &getFactoryMap());
52
53 S32 pos_x = mRect.mLeft;
54 S32 pos_y = mRect.mBottom;
55 LLView* volume_panel_view = gOverlayBar->getChildByName("master_volume");
56 if (volume_panel_view)
57 {
58 pos_x = volume_panel_view->getRect().mLeft;
59 pos_y = volume_panel_view->getRect().mTop;
60 }
61
62 setOrigin(pos_x, pos_y);
63 gFloaterView->adjustToFitScreen(this, FALSE);
64}
65
66////////////////////////////////////////////////////////////////////////////////
67//
68//
69LLPanelAudioVolume::LLPanelAudioVolume()
70{
71}
72
73BOOL LLPanelAudioVolume::postBuild()
74{
75 childSetAction("media_play",LLOverlayBar::mediaPlay,this);
76 childSetAction("media_stop",LLOverlayBar::mediaStop,this);
77 childSetAction("media_pause",LLOverlayBar::mediaPause,this);
78
79 childSetAction("music_play",LLOverlayBar::musicPlay,this);
80 childSetAction("music_stop",LLOverlayBar::musicStop,this);
81 childSetAction("music_pause",LLOverlayBar::musicPause,this);
82
83 return TRUE;
84}
85
86LLPanelAudioVolume::~LLPanelAudioVolume ()
87{
88}
89
90////////////////////////////////////////////////////////////////////////////////
91//
92//
93void LLPanelAudioVolume::draw()
94{
95 LLOverlayBar::enableMusicButtons(this);
96 LLOverlayBar::enableMediaButtons(this);
97 BOOL mute = gSavedSettings.getBOOL("MuteAudio");
98 bool enable = mute ? false : true;
99 childSetEnabled("System Volume", enable);
100 childSetEnabled("Music Volume", enable);
101 childSetEnabled("Media Volume", enable);
102 childSetEnabled("Voice Volume", enable);
103 childSetEnabled("SFX Volume", enable);
104 childSetEnabled("UI Volume", enable);
105 childSetEnabled("Wind Volume", enable);
106 childSetEnabled("Footsteps Volume", enable);
107 LLPanel::draw();
108}
109
diff --git a/linden/indra/newview/llaudiostatus.h b/linden/indra/newview/llpanelaudiovolume.h
index fe7b67f..8a824d2 100644
--- a/linden/indra/newview/llaudiostatus.h
+++ b/linden/indra/newview/llpanelaudiovolume.h
@@ -1,6 +1,6 @@
1/** 1/**
2 * @file llaudiostatus.h 2 * @file llpanelaudiovolume.h
3 * @brief Audio channel allocation information 3 * @brief Audio preference definitions
4 * 4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 * 6 *
@@ -26,27 +26,30 @@
26 * COMPLETENESS OR PERFORMANCE. 26 * COMPLETENESS OR PERFORMANCE.
27 */ 27 */
28 28
29#ifndef LL_LLAUDIOSTATUS_H 29#ifndef LL_LLPANELAUDIOVOLUME_H
30#define LL_LLAUDIOSTATUS_H 30#define LL_LLPANELAUDIOVOLUME_H
31 31
32#include "llmath.h" 32#include "llpanel.h"
33#include "llview.h" 33#include "llfloater.h"
34 34
35//const char TAB = '\t'; 35class LLFloaterAudioVolume :
36//const char DIVIDER[] = " / "; 36 public LLUISingleton<LLFloaterAudioVolume>,
37 public LLFloater
38{
39 friend class LLUISingleton<LLFloaterAudioVolume>;
40public:
41 LLFloaterAudioVolume(const LLSD& seed);
42 static void* createVolumePanel(void* data);
43};
37 44
38class LLAudiostatus : public LLView 45class LLPanelAudioVolume : public LLPanel
39{ 46{
40 public:
41 S32 mPage;
42protected:
43public: 47public:
44 LLAudiostatus(const std::string& name, const LLRect& rect); 48 LLPanelAudioVolume();
45 49 virtual ~LLPanelAudioVolume();
46 virtual EWidgetType getWidgetType() const;
47 virtual LLString getWidgetTag() const;
48 50
49 virtual void draw(); 51 virtual BOOL postBuild();
52 virtual void draw();
50}; 53};
51 54
52#endif 55#endif
diff --git a/linden/indra/newview/llpanelavatar.cpp b/linden/indra/newview/llpanelavatar.cpp
index 0180bb3..b79993f 100644
--- a/linden/indra/newview/llpanelavatar.cpp
+++ b/linden/indra/newview/llpanelavatar.cpp
@@ -91,6 +91,7 @@ BOOL LLPanelAvatar::sAllowFirstLife = FALSE;
91// RN: move these to lldbstrings.h 91// RN: move these to lldbstrings.h
92static const S32 DB_USER_FAVORITES_STR_LEN = 254; 92static const S32 DB_USER_FAVORITES_STR_LEN = 254;
93 93
94const char LOADING_MSG[] = "Loading...";
94static const char IM_DISABLED_TOOLTIP[] = "Instant Message (IM).\nDisabled because you do not have their card."; 95static const char IM_DISABLED_TOOLTIP[] = "Instant Message (IM).\nDisabled because you do not have their card.";
95static const char IM_ENABLED_TOOLTIP[] = "Instant Message (IM)"; 96static const char IM_ENABLED_TOOLTIP[] = "Instant Message (IM)";
96static const S32 LEFT = HPAD; 97static const S32 LEFT = HPAD;
@@ -830,7 +831,7 @@ void LLPanelAvatarNotes::refresh()
830 831
831void LLPanelAvatarNotes::clearControls() 832void LLPanelAvatarNotes::clearControls()
832{ 833{
833 childSetText("notes edit", "Loading..."); 834 childSetText("notes edit", LOADING_MSG);
834 childSetEnabled("notes edit", false); 835 childSetEnabled("notes edit", false);
835} 836}
836 837
@@ -1271,6 +1272,8 @@ LLPanelAvatar::LLPanelAvatar(
1271 mAvatarID( LLUUID::null ), // mAvatarID is set with 'setAvatar' or 'setAvatarID' 1272 mAvatarID( LLUUID::null ), // mAvatarID is set with 'setAvatar' or 'setAvatarID'
1272 mHaveProperties(FALSE), 1273 mHaveProperties(FALSE),
1273 mHaveStatistics(FALSE), 1274 mHaveStatistics(FALSE),
1275 mHaveNotes(false),
1276 mLastNotes(),
1274 mAllowEdit(allow_edit) 1277 mAllowEdit(allow_edit)
1275{ 1278{
1276 1279
@@ -1415,6 +1418,7 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const LLString &name,
1415 setOnlineStatus(online_status); 1418 setOnlineStatus(online_status);
1416 1419
1417 BOOL own_avatar = (mAvatarID == gAgent.getID() ); 1420 BOOL own_avatar = (mAvatarID == gAgent.getID() );
1421 BOOL avatar_is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
1418 1422
1419 mPanelSecondLife->enableControls(own_avatar && mAllowEdit); 1423 mPanelSecondLife->enableControls(own_avatar && mAllowEdit);
1420 mPanelWeb->enableControls(own_avatar && mAllowEdit); 1424 mPanelWeb->enableControls(own_avatar && mAllowEdit);
@@ -1460,6 +1464,8 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const LLString &name,
1460 1464
1461 mPanelNotes->clearControls(); 1465 mPanelNotes->clearControls();
1462 mPanelNotes->setDataRequested(false); 1466 mPanelNotes->setDataRequested(false);
1467 mHaveNotes = false;
1468 mLastNotes.clear();
1463 1469
1464 // Request just the first two pages of data. The picks, 1470 // Request just the first two pages of data. The picks,
1465 // classifieds, and notes will be requested when that panel 1471 // classifieds, and notes will be requested when that panel
@@ -1471,8 +1477,8 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const LLString &name,
1471 if (mAllowEdit) 1477 if (mAllowEdit)
1472 { 1478 {
1473 // OK button disabled until properties data arrives 1479 // OK button disabled until properties data arrives
1474 childSetVisible("OK",TRUE); 1480 childSetVisible("OK", true);
1475 childSetEnabled("OK",TRUE); 1481 childSetEnabled("OK", false);
1476 childSetVisible("Cancel",TRUE); 1482 childSetVisible("Cancel",TRUE);
1477 childSetEnabled("Cancel",TRUE); 1483 childSetEnabled("Cancel",TRUE);
1478 } 1484 }
@@ -1530,7 +1536,7 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const LLString &name,
1530 childSetToolTip("Show on Map",childGetValue("ShowOnMapFriendOnline").asString()); 1536 childSetToolTip("Show on Map",childGetValue("ShowOnMapFriendOnline").asString());
1531 } 1537 }
1532 childSetVisible("Add Friend...", true); 1538 childSetVisible("Add Friend...", true);
1533 childSetEnabled("Add Friend...", true); 1539 childSetEnabled("Add Friend...", !avatar_is_friend);
1534 childSetVisible("Pay...",TRUE); 1540 childSetVisible("Pay...",TRUE);
1535 childSetEnabled("Pay...",FALSE); 1541 childSetEnabled("Pay...",FALSE);
1536 } 1542 }
@@ -1604,12 +1610,12 @@ void LLPanelAvatar::resetGroupList()
1604void LLPanelAvatar::onClickIM(void* userdata) 1610void LLPanelAvatar::onClickIM(void* userdata)
1605{ 1611{
1606 LLPanelAvatar* self = (LLPanelAvatar*) userdata; 1612 LLPanelAvatar* self = (LLPanelAvatar*) userdata;
1607 gIMView->setFloaterOpen(TRUE); 1613 gIMMgr->setFloaterOpen(TRUE);
1608 1614
1609 std::string name; 1615 std::string name;
1610 LLNameEditor* nameedit = LLViewerUICtrlFactory::getNameEditorByName(self->mPanelSecondLife, "name"); 1616 LLNameEditor* nameedit = LLViewerUICtrlFactory::getNameEditorByName(self->mPanelSecondLife, "name");
1611 if (nameedit) name = nameedit->getText(); 1617 if (nameedit) name = nameedit->getText();
1612 gIMView->addSession(name, IM_NOTHING_SPECIAL, self->mAvatarID); 1618 gIMMgr->addSession(name, IM_NOTHING_SPECIAL, self->mAvatarID);
1613} 1619}
1614 1620
1615 1621
@@ -1639,7 +1645,7 @@ void LLPanelAvatar::onClickAddFriend(void* userdata)
1639 LLNameEditor* name_edit = LLViewerUICtrlFactory::getNameEditorByName(self->mPanelSecondLife, "name"); 1645 LLNameEditor* name_edit = LLViewerUICtrlFactory::getNameEditorByName(self->mPanelSecondLife, "name");
1640 if (name_edit) 1646 if (name_edit)
1641 { 1647 {
1642 LLFloaterFriends::requestFriendshipDialog(self->getAvatarID(), 1648 LLPanelFriends::requestFriendshipDialog(self->getAvatarID(),
1643 name_edit->getText()); 1649 name_edit->getText());
1644 } 1650 }
1645} 1651}
@@ -1767,7 +1773,19 @@ void LLPanelAvatar::sendAvatarPropertiesRequest()
1767void LLPanelAvatar::sendAvatarNotesUpdate() 1773void LLPanelAvatar::sendAvatarNotesUpdate()
1768{ 1774{
1769 std::string notes = mPanelNotes->childGetValue("notes edit").asString(); 1775 std::string notes = mPanelNotes->childGetValue("notes edit").asString();
1770 1776
1777 if (!mHaveNotes
1778 && (notes.empty() || notes == LOADING_MSG))
1779 {
1780 // no notes from server and no user updates
1781 return;
1782 }
1783 if (notes == mLastNotes)
1784 {
1785 // Avatar notes unchanged
1786 return;
1787 }
1788
1771 LLMessageSystem *msg = gMessageSystem; 1789 LLMessageSystem *msg = gMessageSystem;
1772 1790
1773 msg->newMessage("AvatarNotesUpdate"); 1791 msg->newMessage("AvatarNotesUpdate");
@@ -2175,6 +2193,8 @@ void LLPanelAvatar::processAvatarNotesReply(LLMessageSystem *msg, void**)
2175 msg->getString("Data", "Notes", DB_USER_NOTE_SIZE, text); 2193 msg->getString("Data", "Notes", DB_USER_NOTE_SIZE, text);
2176 self->childSetValue("notes edit", text); 2194 self->childSetValue("notes edit", text);
2177 self->childSetEnabled("notes edit", true); 2195 self->childSetEnabled("notes edit", true);
2196 self->mHaveNotes = true;
2197 self->mLastNotes = text;
2178 } 2198 }
2179} 2199}
2180 2200
diff --git a/linden/indra/newview/llpanelavatar.h b/linden/indra/newview/llpanelavatar.h
index b3b4e72..05b18c5 100644
--- a/linden/indra/newview/llpanelavatar.h
+++ b/linden/indra/newview/llpanelavatar.h
@@ -323,16 +323,15 @@ public:
323 static void onClickCSR( void *userdata); 323 static void onClickCSR( void *userdata);
324 static void onClickMute( void *userdata); 324 static void onClickMute( void *userdata);
325 325
326private:
327 void enableOKIfReady();
328
326 static void finishKick(S32 option, const LLString& text, void* userdata); 329 static void finishKick(S32 option, const LLString& text, void* userdata);
327 static void finishFreeze(S32 option, const LLString& text, void* userdata); 330 static void finishFreeze(S32 option, const LLString& text, void* userdata);
328 static void finishUnfreeze(S32 option, const LLString& text, void* userdata); 331 static void finishUnfreeze(S32 option, const LLString& text, void* userdata);
329 332
330 static void showProfileCallback(S32 option, void *userdata); 333 static void showProfileCallback(S32 option, void *userdata);
331 334
332 // Teen users are not allowed to see or enter data into the first life page,
333 // or their own about/interests text entry fields.
334 static BOOL sAllowFirstLife;
335
336 static void* createPanelAvatar(void* data); 335 static void* createPanelAvatar(void* data);
337 static void* createFloaterAvatarInfo(void* data); 336 static void* createFloaterAvatarInfo(void* data);
338 static void* createPanelAvatarSecondLife(void* data); 337 static void* createPanelAvatarSecondLife(void* data);
@@ -353,13 +352,20 @@ public:
353 LLPanelAvatarWeb* mPanelWeb; 352 LLPanelAvatarWeb* mPanelWeb;
354 353
355 LLDropTarget* mDropTarget; 354 LLDropTarget* mDropTarget;
355
356 // Teen users are not allowed to see or enter data into the first life page,
357 // or their own about/interests text entry fields.
358 static BOOL sAllowFirstLife;
356 359
357protected: 360private:
358 void enableOKIfReady();
359 LLUUID mAvatarID; // for which avatar is this window? 361 LLUUID mAvatarID; // for which avatar is this window?
360 BOOL mIsFriend; // Are we friends? 362 BOOL mIsFriend; // Are we friends?
361 BOOL mHaveProperties; 363 BOOL mHaveProperties;
362 BOOL mHaveStatistics; 364 BOOL mHaveStatistics;
365 // only update note if data received from database and
366 // note is changed from database version
367 bool mHaveNotes;
368 std::string mLastNotes;
363 LLTabContainerCommon* mTab; 369 LLTabContainerCommon* mTab;
364 BOOL mAllowEdit; 370 BOOL mAllowEdit;
365 371
diff --git a/linden/indra/newview/llpanelclassified.cpp b/linden/indra/newview/llpanelclassified.cpp
index 408f91a..f7ef441 100644
--- a/linden/indra/newview/llpanelclassified.cpp
+++ b/linden/indra/newview/llpanelclassified.cpp
@@ -105,20 +105,20 @@ LLPanelClassified::LLPanelClassified(BOOL in_finder)
105 mPriceForListing(0), 105 mPriceForListing(0),
106 mDataRequested(FALSE), 106 mDataRequested(FALSE),
107 mPaidFor(FALSE), 107 mPaidFor(FALSE),
108 mPosGlobal(), 108 mPosGlobal(),
109 mSnapshotCtrl(NULL), 109 mSnapshotCtrl(NULL),
110 mNameEditor(NULL), 110 mNameEditor(NULL),
111 mDescEditor(NULL), 111 mDescEditor(NULL),
112 mLocationEditor(NULL), 112 mLocationEditor(NULL),
113 mCategoryCombo(NULL), 113 mCategoryCombo(NULL),
114 mMatureCheck(NULL),
115 mAutoRenewCheck(NULL),
114 mUpdateBtn(NULL), 116 mUpdateBtn(NULL),
115 mTeleportBtn(NULL), 117 mTeleportBtn(NULL),
116 mMapBtn(NULL), 118 mMapBtn(NULL),
117 mProfileBtn(NULL), 119 mProfileBtn(NULL),
118 mInfoText(NULL), 120 mInfoText(NULL),
119 mMatureCheck(NULL), 121 mSetBtn(NULL),
120 mAutoRenewCheck(NULL),
121 mSetBtn(NULL),
122 mClickThroughText(NULL) 122 mClickThroughText(NULL)
123{ 123{
124 sAllPanels.push_back(this); 124 sAllPanels.push_back(this);
@@ -845,6 +845,7 @@ void LLPanelClassified::onCommitAny(LLUICtrl* ctrl, void* data)
845void LLPanelClassified::onFocusReceived(LLUICtrl* ctrl, void* data) 845void LLPanelClassified::onFocusReceived(LLUICtrl* ctrl, void* data)
846{ 846{
847 // allow the data to be saved 847 // allow the data to be saved
848 // Dave/Simon TODO: replace this with better isDirty() functionality
848 onCommitAny(ctrl, data); 849 onCommitAny(ctrl, data);
849} 850}
850 851
diff --git a/linden/indra/newview/llpanelclassified.h b/linden/indra/newview/llpanelclassified.h
index 0ebac2c..6f5e370 100644
--- a/linden/indra/newview/llpanelclassified.h
+++ b/linden/indra/newview/llpanelclassified.h
@@ -115,8 +115,8 @@ protected:
115 BOOL mInFinder; 115 BOOL mInFinder;
116 bool mDirty; 116 bool mDirty;
117 bool mForceClose; 117 bool mForceClose;
118 LLUUID mClassifiedID; 118 LLUUID mClassifiedID;
119 LLUUID mRequestedID; 119 LLUUID mRequestedID;
120 LLUUID mCreatorID; 120 LLUUID mCreatorID;
121 LLUUID mParcelID; 121 LLUUID mParcelID;
122 S32 mPriceForListing; 122 S32 mPriceForListing;
@@ -129,24 +129,25 @@ protected:
129 BOOL mPaidFor; 129 BOOL mPaidFor;
130 130
131 LLString mSimName; 131 LLString mSimName;
132 LLVector3d mPosGlobal; 132 LLVector3d mPosGlobal;
133 133
134 LLTextureCtrl* mSnapshotCtrl; 134 // Values the user may change
135 LLLineEditor* mNameEditor; 135 LLTextureCtrl* mSnapshotCtrl;
136 LLLineEditor* mNameEditor;
136 LLLineEditor* mDateEditor; 137 LLLineEditor* mDateEditor;
137 LLTextEditor* mDescEditor; 138 LLTextEditor* mDescEditor;
138 LLLineEditor* mLocationEditor; 139 LLLineEditor* mLocationEditor;
139 LLComboBox* mCategoryCombo; 140 LLComboBox* mCategoryCombo;
141 LLCheckBoxCtrl* mMatureCheck;
142 LLCheckBoxCtrl* mAutoRenewCheck;
140 143
141 LLButton* mUpdateBtn; 144 LLButton* mUpdateBtn;
142 LLButton* mTeleportBtn; 145 LLButton* mTeleportBtn;
143 LLButton* mMapBtn; 146 LLButton* mMapBtn;
144 LLButton* mProfileBtn; 147 LLButton* mProfileBtn;
145 148
146 LLTextBox* mInfoText; 149 LLTextBox* mInfoText;
147 LLCheckBoxCtrl* mMatureCheck; 150 LLButton* mSetBtn;
148 LLCheckBoxCtrl* mAutoRenewCheck;
149 LLButton* mSetBtn;
150 LLTextBox* mClickThroughText; 151 LLTextBox* mClickThroughText;
151 152
152 LLRect mSnapshotSize; 153 LLRect mSnapshotSize;
diff --git a/linden/indra/newview/llpaneldebug.cpp b/linden/indra/newview/llpaneldebug.cpp
index 3166a1d..0293c24 100644
--- a/linden/indra/newview/llpaneldebug.cpp
+++ b/linden/indra/newview/llpaneldebug.cpp
@@ -100,6 +100,7 @@ LLPanelDebug::LLPanelDebug(const std::string& name, const LLRect& rect)
100 RULER2 + SPINCTRL_DEFAULT_LABEL_WIDTH + SPINCTRL_BTN_WIDTH, 100 RULER2 + SPINCTRL_DEFAULT_LABEL_WIDTH + SPINCTRL_BTN_WIDTH,
101 TRUE, 101 TRUE,
102 TRUE, 102 TRUE,
103 FALSE,
103 NULL, NULL, 104 NULL, NULL,
104 (F32)gSavedSettings.getS32("DropShadowFloater"), 105 (F32)gSavedSettings.getS32("DropShadowFloater"),
105 0.f, 10.f, 1.0f, 106 0.f, 10.f, 1.0f,
@@ -118,6 +119,7 @@ LLPanelDebug::LLPanelDebug(const std::string& name, const LLRect& rect)
118 RULER2 + SPINCTRL_DEFAULT_LABEL_WIDTH + SPINCTRL_BTN_WIDTH, 119 RULER2 + SPINCTRL_DEFAULT_LABEL_WIDTH + SPINCTRL_BTN_WIDTH,
119 TRUE, 120 TRUE,
120 TRUE, 121 TRUE,
122 FALSE,
121 NULL, NULL, 123 NULL, NULL,
122 (F32)gSavedSettings.getS32("DropShadowButton"), 124 (F32)gSavedSettings.getS32("DropShadowButton"),
123 0.f, 10.f, 1.0f, 125 0.f, 10.f, 1.0f,
diff --git a/linden/indra/newview/llpaneldirbrowser.cpp b/linden/indra/newview/llpaneldirbrowser.cpp
index 52bd0f7..232ee35 100644
--- a/linden/indra/newview/llpaneldirbrowser.cpp
+++ b/linden/indra/newview/llpaneldirbrowser.cpp
@@ -1254,9 +1254,10 @@ void LLPanelDirBrowser::onKeystrokeName(LLLineEditor* line, void* data)
1254 } 1254 }
1255} 1255}
1256 1256
1257void LLPanelDirBrowser::onVisibilityChange(BOOL curVisibilityIn) 1257// setup results when shown
1258void LLPanelDirBrowser::onVisibilityChange(BOOL new_visibility)
1258{ 1259{
1259 if (curVisibilityIn) 1260 if (new_visibility)
1260 { 1261 {
1261 onCommitList(NULL, this); 1262 onCommitList(NULL, this);
1262 } 1263 }
diff --git a/linden/indra/newview/llpaneldisplay.cpp b/linden/indra/newview/llpaneldisplay.cpp
index d79dcb4..c4fa1dc 100644
--- a/linden/indra/newview/llpaneldisplay.cpp
+++ b/linden/indra/newview/llpaneldisplay.cpp
@@ -520,6 +520,7 @@ void LLPanelDisplay2::refreshEnabledState()
520 520
521void LLPanelDisplay2::apply() 521void LLPanelDisplay2::apply()
522{ 522{
523
523 // Anisotropic rendering 524 // Anisotropic rendering
524 BOOL old_anisotropic = LLImageGL::sGlobalUseAnisotropic; 525 BOOL old_anisotropic = LLImageGL::sGlobalUseAnisotropic;
525 LLImageGL::sGlobalUseAnisotropic = childGetValue("ani"); 526 LLImageGL::sGlobalUseAnisotropic = childGetValue("ani");
diff --git a/linden/indra/newview/llpanelgeneral.cpp b/linden/indra/newview/llpanelgeneral.cpp
index 10aef2c..7d1c778 100644
--- a/linden/indra/newview/llpanelgeneral.cpp
+++ b/linden/indra/newview/llpanelgeneral.cpp
@@ -58,8 +58,6 @@
58// Imported globals 58// Imported globals
59// 59//
60 60
61extern F32 gAFKTimeout;
62
63void set_crash_behavior(LLUICtrl* ctrl, void* data); 61void set_crash_behavior(LLUICtrl* ctrl, void* data);
64void set_start_location(LLUICtrl* ctrl, void* data); 62void set_start_location(LLUICtrl* ctrl, void* data);
65 63
diff --git a/linden/indra/newview/llpanelgroup.cpp b/linden/indra/newview/llpanelgroup.cpp
index 8061e42..5887cc0 100644
--- a/linden/indra/newview/llpanelgroup.cpp
+++ b/linden/indra/newview/llpanelgroup.cpp
@@ -125,16 +125,7 @@ void LLPanelGroupTab::handleClickHelp()
125 LLAlertDialog* dialogp = gViewerWindow->alertXml("GenericAlert", args); 125 LLAlertDialog* dialogp = gViewerWindow->alertXml("GenericAlert", args);
126 if (dialogp) 126 if (dialogp)
127 { 127 {
128 LLView* viewp = this; 128 LLFloater* root_floater = gFloaterView->getParentFloater(this);;
129 LLFloater* root_floater = NULL;
130 while(viewp)
131 {
132 if(viewp->getWidgetType() == WIDGET_TYPE_FLOATER)
133 {
134 root_floater = (LLFloater*)viewp;
135 }
136 viewp = viewp->getParent();
137 }
138 if (root_floater) 129 if (root_floater)
139 { 130 {
140 root_floater->addDependentFloater(dialogp); 131 root_floater->addDependentFloater(dialogp);
diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp
index 13f07c0..a7dc298 100644
--- a/linden/indra/newview/llpanelinventory.cpp
+++ b/linden/indra/newview/llpanelinventory.cpp
@@ -604,7 +604,7 @@ void LLTaskInvFVBridge::performAction(LLFolderView* folder, LLInventoryModel* mo
604 } 604 }
605 else 605 else
606 { 606 {
607 if (price > gStatusBar->getBalance()) 607 if (price > 0 && price > gStatusBar->getBalance())
608 { 608 {
609 LLFloaterBuyCurrency::buyCurrency("This costs", price); 609 LLFloaterBuyCurrency::buyCurrency("This costs", price);
610 } 610 }
diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp
index fdc431c..7a0482b 100644
--- a/linden/indra/newview/llpanellogin.cpp
+++ b/linden/indra/newview/llpanellogin.cpp
@@ -44,6 +44,7 @@
44#include "llcombobox.h" 44#include "llcombobox.h"
45#include "llviewercontrol.h" 45#include "llviewercontrol.h"
46#include "llfloaterabout.h" 46#include "llfloaterabout.h"
47#include "llfloatertest.h"
47#include "llfloaterpreference.h" 48#include "llfloaterpreference.h"
48#include "llfocusmgr.h" 49#include "llfocusmgr.h"
49#include "lllineeditor.h" 50#include "lllineeditor.h"
@@ -424,23 +425,30 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
424 return TRUE; 425 return TRUE;
425 } 426 }
426 427
427 #if LL_LIBXUL_ENABLED 428 if (('T' == key) && (MASK_CONTROL == mask))
429 {
430 new LLFloaterSimple("floater_test.xml");
431 return TRUE;
432 }
433
434#if LL_LIBXUL_ENABLED
428 if ( KEY_F1 == key ) 435 if ( KEY_F1 == key )
429 { 436 {
430 llinfos << "Spawning HTML help window" << llendl; 437 llinfos << "Spawning HTML help window" << llendl;
431 gViewerHtmlHelp.show(); 438 gViewerHtmlHelp.show();
432 return TRUE; 439 return TRUE;
433 }; 440 }
434 #if ! LL_RELEASE_FOR_DOWNLOAD 441
435 if ( KEY_F2 == key ) 442# if !LL_RELEASE_FOR_DOWNLOAD
436 { 443 if ( KEY_F2 == key )
437 llinfos << "Spawning floater TOS window" << llendl; 444 {
438 LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_TOS,""); 445 llinfos << "Spawning floater TOS window" << llendl;
439 tos_dialog->startModal(); 446 LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_TOS,"");
440 return TRUE; 447 tos_dialog->startModal();
441 }; 448 return TRUE;
442 #endif 449 }
443 #endif 450# endif
451#endif
444 452
445 if (!called_from_parent) 453 if (!called_from_parent)
446 { 454 {
diff --git a/linden/indra/newview/llpanellogin.h b/linden/indra/newview/llpanellogin.h
index 2133044..05590d3 100644
--- a/linden/indra/newview/llpanellogin.h
+++ b/linden/indra/newview/llpanellogin.h
@@ -35,6 +35,7 @@
35#include "llmemory.h" 35#include "llmemory.h"
36#include "llviewerimage.h" 36#include "llviewerimage.h"
37#include "llstring.h" 37#include "llstring.h"
38#include "llmd5.h"
38 39
39class LLTextBox; 40class LLTextBox;
40class LLLineEditor; 41class LLLineEditor;
diff --git a/linden/indra/newview/llpanelpermissions.cpp b/linden/indra/newview/llpanelpermissions.cpp
index 6e8a4ff..0cfef5c 100644
--- a/linden/indra/newview/llpanelpermissions.cpp
+++ b/linden/indra/newview/llpanelpermissions.cpp
@@ -807,14 +807,24 @@ void LLPanelPermissions::onClickOwner(void *data)
807 807
808void LLPanelPermissions::onClickGroup(void* data) 808void LLPanelPermissions::onClickGroup(void* data)
809{ 809{
810 LLPanelPermissions* panelp = (LLPanelPermissions*)data;
810 LLUUID owner_id; 811 LLUUID owner_id;
811 LLString name; 812 LLString name;
812 BOOL owners_identical = gSelectMgr->selectGetOwner(owner_id, name); 813 BOOL owners_identical = gSelectMgr->selectGetOwner(owner_id, name);
814 LLFloater* parent_floater = gFloaterView->getParentFloater(panelp);
815
813 if(owners_identical && (owner_id == gAgent.getID())) 816 if(owners_identical && (owner_id == gAgent.getID()))
814 { 817 {
815 LLFloaterGroups* fg; 818 LLFloaterGroupPicker* fg;
816 fg = LLFloaterGroups::show(gAgent.getID(), LLFloaterGroups::CHOOSE_ONE); 819 fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
817 fg->setOkCallback( cbGroupID, data ); 820 fg->setSelectCallback( cbGroupID, data );
821
822 if (parent_floater)
823 {
824 LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
825 fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
826 parent_floater->addDependentFloater(fg);
827 }
818 } 828 }
819} 829}
820 830
diff --git a/linden/indra/newview/llpolymesh.cpp b/linden/indra/newview/llpolymesh.cpp
index 1edb8f5..6cc3fc7 100644
--- a/linden/indra/newview/llpolymesh.cpp
+++ b/linden/indra/newview/llpolymesh.cpp
@@ -278,7 +278,10 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
278 // Read a chunk 278 // Read a chunk
279 //------------------------------------------------------------------------- 279 //-------------------------------------------------------------------------
280 char header[128]; /*Flawfinder: ignore*/ 280 char header[128]; /*Flawfinder: ignore*/
281 fread(header, sizeof(char), 128, fp); 281 if (fread(header, sizeof(char), 128, fp) != 128)
282 {
283 llwarns << "Short read" << llendl;
284 }
282 285
283 //------------------------------------------------------------------------- 286 //-------------------------------------------------------------------------
284 // Check for proper binary header 287 // Check for proper binary header
diff --git a/linden/indra/newview/llprefschat.cpp b/linden/indra/newview/llprefschat.cpp
index 70f7833..91cacd9 100644
--- a/linden/indra/newview/llprefschat.cpp
+++ b/linden/indra/newview/llprefschat.cpp
@@ -30,21 +30,8 @@
30#include "llviewerprecompiledheaders.h" 30#include "llviewerprecompiledheaders.h"
31 31
32#include "llprefschat.h" 32#include "llprefschat.h"
33
34#include "llcheckboxctrl.h"
35#include "llcolorswatch.h"
36#include "llpanel.h"
37#include "llradiogroup.h"
38
39#include "llchatbar.h"
40#include "llconsole.h"
41#include "llspinctrl.h"
42#include "llsliderctrl.h"
43#include "llviewercontrol.h" 33#include "llviewercontrol.h"
44#include "llvieweruictrlfactory.h" 34#include "llvieweruictrlfactory.h"
45#include "message.h"
46#include "viewer.h"
47#include "lltexteditor.h"
48 35
49class LLPrefsChatImpl : public LLPanel 36class LLPrefsChatImpl : public LLPanel
50{ 37{
diff --git a/linden/indra/newview/llprefsvoice.cpp b/linden/indra/newview/llprefsvoice.cpp
new file mode 100644
index 0000000..c66a3d0
--- /dev/null
+++ b/linden/indra/newview/llprefsvoice.cpp
@@ -0,0 +1,277 @@
1/**
2 * @file llprefsvoice.cpp
3 * @author Richard Nelson
4 * @brief Voice chat preferences panel
5 *
6 * Copyright (c) 2003-2007, Linden Research, Inc.
7 *
8 * Second Life Viewer Source Code
9 * The source code in this file ("Source Code") is provided by Linden Lab
10 * to you under the terms of the GNU General Public License, version 2.0
11 * ("GPL"), unless you have obtained a separate licensing agreement
12 * ("Other License"), formally executed by you and Linden Lab. Terms of
13 * the GPL can be found in doc/GPL-license.txt in this distribution, or
14 * online at http://secondlife.com/developers/opensource/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at http://secondlife.com/developers/opensource/flossexception
20 *
21 * By copying, modifying or distributing this software, you acknowledge
22 * that you have read and understood your obligations described above,
23 * and agree to abide by those obligations.
24 *
25 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
26 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27 * COMPLETENESS OR PERFORMANCE.
28 */
29
30#include "llviewerprecompiledheaders.h"
31
32#include "llprefsvoice.h"
33
34#include "llcheckboxctrl.h"
35#include "llcombobox.h"
36
37#include "llviewercontrol.h"
38#include "llvieweruictrlfactory.h"
39
40#include "llmodaldialog.h"
41#include "llkeyboard.h"
42#include "llfocusmgr.h"
43#include "llfloatervoicewizard.h"
44
45#include "viewer.h"
46
47#include "llvoiceclient.h"
48
49class LLVoiceHotkeySelectDialog : public LLModalDialog
50{
51private:
52 LLPrefsVoiceLogic *mParent;
53 LLFloater *mOldFrontmost;
54
55public:
56 LLVoiceHotkeySelectDialog( LLPrefsVoiceLogic *parent )
57 : LLModalDialog( "", 240, 100 ),
58 mParent( parent )
59 {
60 mOldFrontmost = gFloaterView->getFrontmost();
61
62 gUICtrlFactory->buildFloater(this, "floater_select_key.xml");
63
64 childSetAction("Cancel", LLVoiceHotkeySelectDialog::onCancel, this );
65 childSetFocus("Cancel");
66 }
67
68 /*virtual*/ void setFocus( BOOL b )
69 {
70 LLFloater::setFocus(b);
71
72 // This forces keyboard processing to happen at the raw key level instead of going through handleUnicodeChar.
73 gFocusMgr.removeKeyboardFocusWithoutCallback(gFocusMgr.getKeyboardFocus());
74 }
75
76 static void onCancel( void* userdata );
77
78 BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent );
79
80};
81
82LLPrefsVoiceLogic::LLPrefsVoiceLogic(LLPanel* panelp) :
83 mPanel(panelp)
84{
85 init();
86}
87
88void LLPrefsVoiceLogic::init()
89{
90 mEnableVoice = gSavedSettings.getBOOL("EnableVoiceChat");
91
92 mVoiceCallsFriendsOnly = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
93 mEnablePushToTalk = gSavedSettings.getBOOL("EnablePushToTalk");
94 mModifier = gSavedSettings.getString("PushToTalkButton");
95 mPushToTalkToggle = gSavedSettings.getBOOL("PushToTalkToggle");
96 mEarLocation = gSavedSettings.getS32("VoiceEarLocation");
97
98 mCtrlEarLocation = LLUICtrlFactory::getSelectionInterfaceByName(mPanel, "ear_location");
99 mCtrlEarLocation->selectByValue(LLSD(gSavedSettings.getS32("VoiceEarLocation")));
100 mPanel->childSetCommitCallback("ear_location", onEarLocationCommit, this );
101
102 mPanel->childSetAction("launch_voice_wizard_button", onClickLaunchWizard, this);
103 mPanel->childSetAction("set_voice_hotkey_button", onClickSetKey, this);
104 mPanel->childSetAction("set_voice_middlemouse_button", onClickSetMiddleMouse, this);
105
106 refresh();
107 mEatNextSetKeyClick = FALSE;
108}
109
110void LLPrefsVoiceLogic::refresh()
111{
112 mPanel->childSetVisible("voice_unavailable", gDisableVoice);
113 mPanel->childSetVisible("enable_voice_check", !gDisableVoice);
114 mPanel->childSetEnabled("enable_voice_check", !gDisableVoice);
115
116 bool enable = !gDisableVoice && gSavedSettings.getBOOL("EnableVoiceChat");
117
118 mPanel->childSetEnabled("push_to_talk_check", enable);
119 mPanel->childSetEnabled("push_to_talk_label", enable);
120 mPanel->childSetEnabled("voice_call_friends_only_check", enable);
121 mPanel->childSetEnabled("push_to_talk_toggle_check", enable /*&& gSavedSettings.getBOOL("EnablePushToTalk")*/);
122 mPanel->childSetEnabled("ear_location", enable);
123 mPanel->childSetEnabled("set_voice_hotkey_button", enable /*&& gSavedSettings.getBOOL("EnablePushToTalk")*/);
124 mPanel->childSetEnabled("set_voice_middlemouse_button", enable /*&& gSavedSettings.getBOOL("EnablePushToTalk")*/);
125}
126
127void LLPrefsVoiceLogic::cancel()
128{
129 gSavedSettings.setBOOL("EnableVoiceChat", mEnableVoice);
130 gSavedSettings.setBOOL("VoiceCallsFriendsOnly", mVoiceCallsFriendsOnly);
131 gSavedSettings.setBOOL("EnablePushToTalk", mEnablePushToTalk );
132 gSavedSettings.setString("PushToTalkButton", mModifier);
133 gSavedSettings.setBOOL("PushToTalkToggle", mPushToTalkToggle );
134 gSavedSettings.setS32("VoiceEarLocation", mEarLocation);
135}
136
137void LLPrefsVoiceLogic::apply()
138{
139}
140
141//static
142void LLPrefsVoiceLogic::onEarLocationCommit(LLUICtrl* ctrl, void* user_data)
143{
144 LLCtrlSelectionInterface* interfacep = ctrl->getSelectionInterface();
145 if (interfacep)
146 {
147 gSavedSettings.setS32("VoiceEarLocation", interfacep->getSimpleSelectedValue().asInteger());
148 }
149}
150
151//static
152void LLPrefsVoiceLogic::onClickLaunchWizard(void* user_data)
153{
154 LLFloaterVoiceWizard::showInstance();
155}
156
157// static
158void LLPrefsVoiceLogic::onClickSetKey(void* user_data)
159{
160 LLPrefsVoiceLogic* self=(LLPrefsVoiceLogic*)user_data;
161 if(self->mEatNextSetKeyClick)
162 {
163 self->mEatNextSetKeyClick = false;
164 }
165 else
166 {
167 LLVoiceHotkeySelectDialog* dialog = new LLVoiceHotkeySelectDialog( self );
168 dialog->startModal();
169 // dialog will delete itself
170 }
171}
172
173
174// static
175void LLPrefsVoiceLogic::onClickSetMiddleMouse(void* user_data)
176{
177// LLPrefsVoiceLogic* self=(LLPrefsVoiceLogic*)user_data;
178
179 gSavedSettings.setString("PushToTalkButton", "MiddleMouse");
180}
181
182void LLPrefsVoiceLogic::setKey(KEY key, MASK mask)
183{
184 std::string keystring = LLKeyboard::stringFromKey(key);
185 gSavedSettings.setString("PushToTalkButton", keystring);
186
187 if(key == ' ')
188 {
189 // This will cause the select dialog to immediately reopen.
190 // Eat the next click event.
191 mEatNextSetKeyClick = TRUE;
192 }
193}
194
195void LLVoiceHotkeySelectDialog::onCancel( void* userdata )
196{
197 LLVoiceHotkeySelectDialog* self = (LLVoiceHotkeySelectDialog*) userdata;
198 self->close(); // destroys this object
199 self->mOldFrontmost->setFrontmost(TRUE);
200}
201
202BOOL LLVoiceHotkeySelectDialog::handleKey(KEY key, MASK mask, BOOL called_from_parent )
203{
204 BOOL result = TRUE;
205
206 // Suck up all keystokes except CTRL-Q.
207 BOOL is_quit = ('Q' == key) && (MASK_CONTROL == mask);
208 if(is_quit)
209 {
210 result = FALSE;
211 }
212 else
213 {
214 mParent->setKey(key, mask);
215 }
216
217 close(); // destroys this object
218 mOldFrontmost->setFrontmost(TRUE);
219
220 return result;
221}
222
223//---------------------------------------------------------------------------
224
225
226LLPrefsVoice::LLPrefsVoice()
227: LLPanel("Voice Chat Panel")
228{
229 gUICtrlFactory->buildPanel(this, "panel_preferences_voice.xml");
230 mLogic = new LLPrefsVoiceLogic(this);
231 childSetAction("device_settings_btn", onClickDeviceSettingsBtn, this);
232
233 // create floater immediately and keep it hidden
234 // since it stores preference state for audio devices
235 mDeviceSettings = LLFloaterDeviceSettings::getInstance();
236 //*FIXME: getInstance() needs to not show the floater
237 LLFloaterDeviceSettings::hideInstance();
238}
239
240LLPrefsVoice::~LLPrefsVoice()
241{
242 delete mLogic;
243}
244
245void LLPrefsVoice::draw()
246{
247 bool enable = !gDisableVoice && gSavedSettings.getBOOL("EnableVoiceChat");
248 childSetEnabled("device_settings_btn", enable);
249
250 mLogic->refresh();
251 mDeviceSettings->refresh();
252 LLPanel::draw();
253}
254
255void LLPrefsVoice::apply()
256{
257 mLogic->apply();
258 mDeviceSettings->apply();
259}
260
261void LLPrefsVoice::cancel()
262{
263 mLogic->cancel();
264 mDeviceSettings->cancel();
265}
266
267//static
268void LLPrefsVoice::onClickDeviceSettingsBtn(void* user_data)
269{
270 LLPrefsVoice* prefs = (LLPrefsVoice*)user_data;
271 prefs->mDeviceSettings->open();
272 LLFloater* parent_floater = gFloaterView->getParentFloater(prefs);
273 if (parent_floater)
274 {
275 parent_floater->addDependentFloater(prefs->mDeviceSettings, FALSE);
276 }
277}
diff --git a/linden/indra/newview/llprefsvoice.h b/linden/indra/newview/llprefsvoice.h
new file mode 100644
index 0000000..e6b861d
--- /dev/null
+++ b/linden/indra/newview/llprefsvoice.h
@@ -0,0 +1,87 @@
1/**
2 * @file llprefsvoice.h
3 * @brief Voice chat preferences panel
4 *
5 * Copyright (c) 2003-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#ifndef LLPREFSVOICE_H
30#define LLPREFSVOICE_H
31
32#include "llpanel.h"
33
34class LLFloaterDeviceSettings;
35
36class LLPrefsVoiceLogic
37{
38public:
39 LLPrefsVoiceLogic(LLPanel* panelp);
40 virtual ~LLPrefsVoiceLogic(){};
41
42 virtual void init();
43
44 void apply();
45 void cancel();
46 void refresh();
47
48 void setKey(KEY key, MASK mask);
49
50protected:
51
52 static void onClickSetKey(void* user_data);
53 static void onClickSetMiddleMouse(void* user_data);
54 static void onEarLocationCommit(LLUICtrl* ctrl, void* user_data);
55 static void onClickLaunchWizard(void* user_data);
56
57 BOOL mEnableVoice;
58 BOOL mVoiceCallsFriendsOnly;
59 BOOL mEnablePushToTalk;
60 std::string mModifier;
61 BOOL mPushToTalkToggle;
62 S32 mEarLocation;
63 LLCtrlSelectionInterface *mCtrlEarLocation;
64
65 BOOL mEatNextSetKeyClick;
66
67 LLPanel* mPanel;
68};
69
70class LLPrefsVoice : public LLPanel
71{
72public:
73 LLPrefsVoice();
74 ~LLPrefsVoice();
75
76 /*virtual*/ void draw();
77 void apply();
78 void cancel();
79
80protected:
81 static void onClickDeviceSettingsBtn(void* user_data);
82
83 LLPrefsVoiceLogic* mLogic;
84 LLFloaterDeviceSettings* mDeviceSettings;
85};
86
87#endif // LLPREFSVOICE_H
diff --git a/linden/indra/newview/llpreview.cpp b/linden/indra/newview/llpreview.cpp
index 9b2d3f8..751a90f 100644
--- a/linden/indra/newview/llpreview.cpp
+++ b/linden/indra/newview/llpreview.cpp
@@ -62,7 +62,8 @@ LLPreview::LLPreview(const std::string& name) :
62 mForceClose(FALSE), 62 mForceClose(FALSE),
63 mUserResized(FALSE), 63 mUserResized(FALSE),
64 mCloseAfterSave(FALSE), 64 mCloseAfterSave(FALSE),
65 mAssetStatus(PREVIEW_ASSET_UNLOADED) 65 mAssetStatus(PREVIEW_ASSET_UNLOADED),
66 mItem(NULL)
66{ 67{
67 // don't add to instance list, since ItemID is null 68 // don't add to instance list, since ItemID is null
68 mAuxItem = new LLInventoryItem; // (LLPointer is auto-deleted) 69 mAuxItem = new LLInventoryItem; // (LLPointer is auto-deleted)
diff --git a/linden/indra/newview/llpreviewscript.cpp b/linden/indra/newview/llpreviewscript.cpp
index 9f3533e..a2ea141 100644
--- a/linden/indra/newview/llpreviewscript.cpp
+++ b/linden/indra/newview/llpreviewscript.cpp
@@ -1094,9 +1094,6 @@ LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect,
1094 1094
1095 gUICtrlFactory->buildFloater(this,"floater_script_preview.xml", &factory_map); 1095 gUICtrlFactory->buildFloater(this,"floater_script_preview.xml", &factory_map);
1096 1096
1097 moveResizeHandleToFront();
1098
1099
1100 const LLInventoryItem* item = getItem(); 1097 const LLInventoryItem* item = getItem();
1101 1098
1102 childSetCommitCallback("desc", LLPreview::onText, this); 1099 childSetCommitCallback("desc", LLPreview::onText, this);
@@ -1342,7 +1339,10 @@ void LLPreviewLSL::uploadAssetLegacy(const std::string& filename,
1342 LLString line; 1339 LLString line;
1343 while(!feof(fp)) 1340 while(!feof(fp))
1344 { 1341 {
1345 fgets(buffer, MAX_STRING, fp); 1342 if (fgets(buffer, MAX_STRING, fp) == NULL)
1343 {
1344 buffer[0] = '\0';
1345 }
1346 if(feof(fp)) 1346 if(feof(fp))
1347 { 1347 {
1348 break; 1348 break;
@@ -1617,8 +1617,6 @@ LLLiveLSLEditor::LLLiveLSLEditor(const std::string& name,
1617 LLCallbackMap::map_t factory_map; 1617 LLCallbackMap::map_t factory_map;
1618 factory_map["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this); 1618 factory_map["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this);
1619 1619
1620 moveResizeHandleToFront();
1621
1622 gUICtrlFactory->buildFloater(this,"floater_live_lsleditor.xml", &factory_map); 1620 gUICtrlFactory->buildFloater(this,"floater_live_lsleditor.xml", &factory_map);
1623 1621
1624 1622
@@ -1849,12 +1847,16 @@ void LLLiveLSLEditor::loadScriptText(const char* filename)
1849 { 1847 {
1850 // read in the whole file 1848 // read in the whole file
1851 fseek(file, 0L, SEEK_END); 1849 fseek(file, 0L, SEEK_END);
1852 S32 file_length = ftell(file); 1850 long file_length = ftell(file);
1853 fseek(file, 0L, SEEK_SET); 1851 fseek(file, 0L, SEEK_SET);
1854 char* buffer = new char[file_length+1]; 1852 char* buffer = new char[file_length+1];
1855 fread(buffer, file_length, 1, file); 1853 size_t nread = fread(buffer, 1, file_length, file);
1854 if (nread < (size_t) file_length)
1855 {
1856 llwarns << "Short read" << llendl;
1857 }
1858 buffer[nread] = '\0';
1856 fclose(file); 1859 fclose(file);
1857 buffer[file_length] = 0;
1858 mScriptEd->mEditor->setText(buffer); 1860 mScriptEd->mEditor->setText(buffer);
1859 mScriptEd->mEditor->makePristine(); 1861 mScriptEd->mEditor->makePristine();
1860 delete[] buffer; 1862 delete[] buffer;
@@ -2049,6 +2051,13 @@ void LLLiveLSLEditor::saveIfNeeded()
2049 return; 2051 return;
2050 } 2052 }
2051 LLString utf8text = mScriptEd->mEditor->getText(); 2053 LLString utf8text = mScriptEd->mEditor->getText();
2054
2055 // Special case for a completely empty script - stuff in one space so it can store properly. See SL-46889
2056 if ( utf8text.size() == 0 )
2057 {
2058 utf8text = " ";
2059 }
2060
2052 fputs(utf8text.c_str(), fp); 2061 fputs(utf8text.c_str(), fp);
2053 fclose(fp); 2062 fclose(fp);
2054 fp = NULL; 2063 fp = NULL;
@@ -2118,7 +2127,10 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename,
2118 while(!feof(fp)) 2127 while(!feof(fp))
2119 { 2128 {
2120 2129
2121 fgets(buffer, MAX_STRING, fp); 2130 if (fgets(buffer, MAX_STRING, fp) == NULL)
2131 {
2132 buffer[0] = '\0';
2133 }
2122 if(feof(fp)) 2134 if(feof(fp))
2123 { 2135 {
2124 break; 2136 break;
diff --git a/linden/indra/newview/llpreviewsound.cpp b/linden/indra/newview/llpreviewsound.cpp
index 4e12cd0..7c7afe6 100644
--- a/linden/indra/newview/llpreviewsound.cpp
+++ b/linden/indra/newview/llpreviewsound.cpp
@@ -28,15 +28,16 @@
28 28
29#include "llviewerprecompiledheaders.h" 29#include "llviewerprecompiledheaders.h"
30 30
31#include "llpreviewsound.h" 31#include "audioengine.h"
32#include "llagent.h" // gAgent
32#include "llbutton.h" 33#include "llbutton.h"
33#include "llresmgr.h"
34#include "llinventory.h" 34#include "llinventory.h"
35#include "llinventoryview.h" 35#include "llinventoryview.h"
36#include "audioengine.h"
37#include "llviewermessage.h" // send_guid_sound_trigger
38#include "llagent.h" // gAgent
39#include "lllineeditor.h" 36#include "lllineeditor.h"
37#include "llpreviewsound.h"
38#include "llresmgr.h"
39#include "llviewercontrol.h"
40#include "llviewermessage.h" // send_guid_sound_trigger
40#include "llvieweruictrlfactory.h" 41#include "llvieweruictrlfactory.h"
41 42
42extern LLAudioEngine* gAudiop; 43extern LLAudioEngine* gAudiop;
@@ -102,7 +103,7 @@ void LLPreviewSound::auditionSound( void *userdata )
102 if(item && gAudiop) 103 if(item && gAudiop)
103 { 104 {
104 LLVector3d lpos_global = gAgent.getPositionGlobal(); 105 LLVector3d lpos_global = gAgent.getPositionGlobal();
105 106 F32 volume = SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX");
106 gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), SOUND_GAIN, lpos_global); 107 gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), volume, lpos_global);
107 } 108 }
108} 109}
diff --git a/linden/indra/newview/llpreviewtexture.cpp b/linden/indra/newview/llpreviewtexture.cpp
index af727b9..5cba31d 100644
--- a/linden/indra/newview/llpreviewtexture.cpp
+++ b/linden/indra/newview/llpreviewtexture.cpp
@@ -435,7 +435,7 @@ void LLPreviewTexture::updateAspectRatio()
435 S32 old_left = mRect.mLeft; 435 S32 old_left = mRect.mLeft;
436 if (getHost()) 436 if (getHost())
437 { 437 {
438 getHost()->growToFit(this, view_width, view_height); 438 getHost()->growToFit(view_width, view_height);
439 } 439 }
440 else 440 else
441 { 441 {
diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp
index 0cf8b00..ec01d54 100644
--- a/linden/indra/newview/llselectmgr.cpp
+++ b/linden/indra/newview/llselectmgr.cpp
@@ -547,7 +547,7 @@ BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id)
547 return object_found; 547 return object_found;
548} 548}
549 549
550void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim) 550void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim, BOOL include_entire_object)
551{ 551{
552 // bail if nothing selected or if object wasn't selected in the first place 552 // bail if nothing selected or if object wasn't selected in the first place
553 if(!object) return; 553 if(!object) return;
@@ -555,7 +555,30 @@ void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_s
555 555
556 // Collect all of the objects, and remove them 556 // Collect all of the objects, and remove them
557 LLDynamicArray<LLViewerObject*> objects; 557 LLDynamicArray<LLViewerObject*> objects;
558 object = (LLViewerObject*)object->getRoot(); 558
559 if (include_entire_object)
560 {
561 // Since we're selecting a family, start at the root, but
562 // don't include an avatar.
563 LLViewerObject* root = object;
564
565 while(!root->isAvatar() && root->getParent() && !root->isJointChild())
566 {
567 LLViewerObject* parent = (LLViewerObject*)root->getParent();
568 if (parent->isAvatar())
569 {
570 break;
571 }
572 root = parent;
573 }
574
575 object = root;
576 }
577 else
578 {
579 object = (LLViewerObject*)object->getRoot();
580 }
581
559 object->addThisAndAllChildren(objects); 582 object->addThisAndAllChildren(objects);
560 remove(objects); 583 remove(objects);
561 584
@@ -3457,7 +3480,6 @@ void LLSelectMgr::deselectAll()
3457 mLastSentSelectionCenterGlobal.clearVec(); 3480 mLastSentSelectionCenterGlobal.clearVec();
3458 3481
3459 updatePointAt(); 3482 updatePointAt();
3460 gHUDManager->clearJoints();
3461 updateSelectionCenter(); 3483 updateSelectionCenter();
3462} 3484}
3463 3485
@@ -5494,7 +5516,7 @@ void LLSelectMgr::updateSelectionCenter()
5494 // have stuff selected 5516 // have stuff selected
5495 LLVector3d select_center; 5517 LLVector3d select_center;
5496 // keep a list of jointed objects for showing the joint HUDEffects 5518 // keep a list of jointed objects for showing the joint HUDEffects
5497 gHUDManager->clearJoints(); 5519
5498 LLDynamicArray < LLViewerObject *> jointed_objects; 5520 LLDynamicArray < LLViewerObject *> jointed_objects;
5499 5521
5500 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 5522 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
@@ -5520,10 +5542,6 @@ void LLSelectMgr::updateSelectionCenter()
5520 mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent); 5542 mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent);
5521 mSelectionBBox = bbox; 5543 mSelectionBBox = bbox;
5522 5544
5523 if (jointed_objects.count())
5524 {
5525 gHUDManager->showJoints(&jointed_objects);
5526 }
5527 } 5545 }
5528 5546
5529 if ( !(gAgentID == LLUUID::null) && gToolMgr) 5547 if ( !(gAgentID == LLUUID::null) && gToolMgr)
@@ -5754,6 +5772,12 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object)
5754 return TRUE; 5772 return TRUE;
5755} 5773}
5756 5774
5775BOOL LLSelectMgr::setForceSelection(BOOL force)
5776{
5777 std::swap(mForceSelection,force);
5778 return force;
5779}
5780
5757LLObjectSelection::LLObjectSelection() : 5781LLObjectSelection::LLObjectSelection() :
5758 std::list<LLSelectNode*>(), 5782 std::list<LLSelectNode*>(),
5759 LLRefCount(), 5783 LLRefCount(),
diff --git a/linden/indra/newview/llselectmgr.h b/linden/indra/newview/llselectmgr.h
index 7eff94a..fec3a0a 100644
--- a/linden/indra/newview/llselectmgr.h
+++ b/linden/indra/newview/llselectmgr.h
@@ -239,7 +239,8 @@ public:
239 void updateEffects(); // Update HUD effects 239 void updateEffects(); // Update HUD effects
240 void overrideObjectUpdates(); 240 void overrideObjectUpdates();
241 241
242 void setForceSelection(BOOL force) { mForceSelection = force; } 242 // Returns the previous value of mForceSelection
243 BOOL setForceSelection(BOOL force);
243 244
244 //////////////////////////////////////////////////////////////// 245 ////////////////////////////////////////////////////////////////
245 // Selection methods 246 // Selection methods
@@ -273,7 +274,7 @@ public:
273 //////////////////////////////////////////////////////////////// 274 ////////////////////////////////////////////////////////////////
274 275
275 void deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim = TRUE); 276 void deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim = TRUE);
276 void deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim = TRUE); 277 void deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim = TRUE, BOOL include_entire_object = FALSE);
277 278
278 // Send deselect messages to simulator, then clear the list 279 // Send deselect messages to simulator, then clear the list
279 void deselectAll(); 280 void deselectAll();
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index 7dbb107..208bb7c 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -85,6 +85,8 @@
85#include "lleventnotifier.h" 85#include "lleventnotifier.h"
86#include "llface.h" 86#include "llface.h"
87#include "llfeaturemanager.h" 87#include "llfeaturemanager.h"
88#include "llfirstuse.h"
89#include "llfloateractivespeakers.h"
88#include "llfloaterchat.h" 90#include "llfloaterchat.h"
89#include "llfloatergesture.h" 91#include "llfloatergesture.h"
90#include "llfloaterland.h" 92#include "llfloaterland.h"
@@ -153,6 +155,7 @@
153#include "llfasttimerview.h" 155#include "llfasttimerview.h"
154#include "llfloatermap.h" 156#include "llfloatermap.h"
155#include "llweb.h" 157#include "llweb.h"
158#include "llvoiceclient.h"
156 159
157#if LL_LIBXUL_ENABLED 160#if LL_LIBXUL_ENABLED
158#include "llmozlib.h" 161#include "llmozlib.h"
@@ -211,6 +214,7 @@ static bool gGotUseCircuitCodeAck = false;
211LLString gInitialOutfit; 214LLString gInitialOutfit;
212LLString gInitialOutfitGender; // "male" or "female" 215LLString gInitialOutfitGender; // "male" or "female"
213 216
217static bool gUseCircuitCallbackCalled = false;
214 218
215// 219//
216// local function declaration 220// local function declaration
@@ -783,12 +787,7 @@ BOOL idle_startup()
783 LLFile::mkdir(gDirUtilp->getChatLogsDir().c_str()); 787 LLFile::mkdir(gDirUtilp->getChatLogsDir().c_str());
784 LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir().c_str()); 788 LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir().c_str());
785 789
786
787#if LL_WINDOWS
788 if (gSavedSettings.getBOOL("UseDebugLogin") && show_connect_box)
789#else
790 if (show_connect_box) 790 if (show_connect_box)
791#endif
792 { 791 {
793 LLString server_label; 792 LLString server_label;
794 S32 domain_name_index; 793 S32 domain_name_index;
@@ -799,10 +798,16 @@ BOOL idle_startup()
799 { 798 {
800 snprintf(gUserServerName, MAX_STRING, "%s", server_label.c_str()); /* Flawfinder: ignore */ 799 snprintf(gUserServerName, MAX_STRING, "%s", server_label.c_str()); /* Flawfinder: ignore */
801 } 800 }
802 }
803 801
804 if (show_connect_box) 802 // Dave S temp reversion of SL-49082 fix - this code breaks command line urls. I'll fix this with
805 { 803 // the control isDirty() functionality tomorrow.
804
805 //if ( userPickedServer )
806 //{ // User picked a grid from the popup, so clear the stored urls so they will be re-generated from gUserServerChoice
807 // auth_uris.clear();
808 // resetURIs();
809 //}
810
806 LLString location; 811 LLString location;
807 LLPanelLogin::getLocation( location ); 812 LLPanelLogin::getLocation( location );
808 LLURLSimString::setString( location ); 813 LLURLSimString::setString( location );
@@ -1159,29 +1164,18 @@ BOOL idle_startup()
1159 case LLUserAuth::E_COULDNT_RESOLVE_HOST: 1164 case LLUserAuth::E_COULDNT_RESOLVE_HOST:
1160 case LLUserAuth::E_SSL_PEER_CERTIFICATE: 1165 case LLUserAuth::E_SSL_PEER_CERTIFICATE:
1161 case LLUserAuth::E_UNHANDLED_ERROR: 1166 case LLUserAuth::E_UNHANDLED_ERROR:
1167 case LLUserAuth::E_SSL_CACERT:
1168 case LLUserAuth::E_SSL_CONNECT_ERROR:
1162 default: 1169 default:
1163 if (auth_uri_num >= (int) auth_uris.size()) 1170 if (auth_uri_num >= (int) auth_uris.size() - 1)
1164 { 1171 {
1165 emsg << "Unable to connect to " << gSecondLife << ".\n"; 1172 emsg << "Unable to connect to " << gSecondLife << ".\n";
1166 emsg << gUserAuthp->errorMessage(); 1173 emsg << gUserAuthp->errorMessage();
1167 } else { 1174 } else {
1168 std::ostringstream s;
1169 s << "Logging in (attempt " << (auth_uri_num + 1) << "). ";
1170 auth_desc = s.str();
1171 gStartupState = STATE_LOGIN_AUTHENTICATE;
1172 auth_uri_num++; 1175 auth_uri_num++;
1173 return do_normal_idle;
1174 }
1175 break;
1176 case LLUserAuth::E_SSL_CACERT:
1177 case LLUserAuth::E_SSL_CONNECT_ERROR:
1178 if (auth_uri_num >= (int) auth_uris.size())
1179 {
1180 emsg << "Unable to establish a secure connection to the login server.\n";
1181 emsg << gUserAuthp->errorMessage();
1182 } else {
1183 std::ostringstream s; 1176 std::ostringstream s;
1184 s << "Logging in (attempt " << (auth_uri_num + 1) << "). "; 1177 s << "Previous login attempt failed. Logging in, attempt "
1178 << (auth_uri_num + 1) << ". ";
1185 auth_desc = s.str(); 1179 auth_desc = s.str();
1186 gStartupState = STATE_LOGIN_AUTHENTICATE; 1180 gStartupState = STATE_LOGIN_AUTHENTICATE;
1187 auth_uri_num++; 1181 auth_uri_num++;
@@ -1431,6 +1425,9 @@ BOOL idle_startup()
1431 gAutoLogin = FALSE; 1425 gAutoLogin = FALSE;
1432 show_connect_box = TRUE; 1426 show_connect_box = TRUE;
1433 } 1427 }
1428
1429 // Pass the user information to the voice chat server interface.
1430 gVoiceClient->userAuthorized(firstname, lastname, gAgentID);
1434 } 1431 }
1435 else 1432 else
1436 { 1433 {
@@ -1553,12 +1550,21 @@ BOOL idle_startup()
1553 { 1550 {
1554 update_texture_fetch(); 1551 update_texture_fetch();
1555 1552
1553 if ( gViewerWindow != NULL && gToolMgr != NULL )
1554 { // This isn't the first logon attempt, so show the UI
1555 gViewerWindow->setNormalControlsVisible( TRUE );
1556 }
1557
1556 // Initialize UI 1558 // Initialize UI
1557 if (!gNoRender) 1559 if (!gNoRender)
1558 { 1560 {
1559 // Initialize all our tools. Must be done after saved settings loaded. 1561 // Initialize all our tools. Must be done after saved settings loaded.
1560 gToolMgr = new LLToolMgr(); 1562 if ( gToolMgr == NULL )
1561 gToolMgr->initTools(); 1563 {
1564 gToolMgr = new LLToolMgr();
1565 gToolMgr->initTools();
1566 }
1567
1562 // Quickly get something onscreen to look at. 1568 // Quickly get something onscreen to look at.
1563 gViewerWindow->initWorldUI(); 1569 gViewerWindow->initWorldUI();
1564 1570
@@ -1589,14 +1595,20 @@ BOOL idle_startup()
1589 1595
1590 gXferManager->registerCallbacks(gMessageSystem); 1596 gXferManager->registerCallbacks(gMessageSystem);
1591 1597
1592 gCacheName = new LLCacheName(gMessageSystem); 1598 if ( gCacheName == NULL )
1593 gCacheName->addObserver(callback_cache_name); 1599 {
1594 1600 gCacheName = new LLCacheName(gMessageSystem);
1595 // Load stored cache if possible 1601 gCacheName->addObserver(callback_cache_name);
1596 load_name_cache(); 1602
1603 // Load stored cache if possible
1604 load_name_cache();
1605 }
1597 1606
1598 // Data storage for map of world. 1607 // Data storage for map of world.
1599 gWorldMap = new LLWorldMap(); 1608 if ( gWorldMap == NULL )
1609 {
1610 gWorldMap = new LLWorldMap();
1611 }
1600 1612
1601 // register null callbacks for audio until the audio system is initialized 1613 // register null callbacks for audio until the audio system is initialized
1602 gMessageSystem->setHandlerFuncFast(_PREHASH_SoundTrigger, null_message_callback, NULL); 1614 gMessageSystem->setHandlerFuncFast(_PREHASH_SoundTrigger, null_message_callback, NULL);
@@ -1678,6 +1690,9 @@ BOOL idle_startup()
1678 { 1690 {
1679 llwarns << "Attempting to connect to simulator with a zero circuit code!" << llendl; 1691 llwarns << "Attempting to connect to simulator with a zero circuit code!" << llendl;
1680 } 1692 }
1693
1694 gUseCircuitCallbackCalled = FALSE;
1695
1681 msg->enableCircuit(first_sim, TRUE); 1696 msg->enableCircuit(first_sim, TRUE);
1682 // now, use the circuit info to tell simulator about us! 1697 // now, use the circuit info to tell simulator about us!
1683 llinfos << "viewer: UserLoginLocationReply() Enabling " << first_sim << " with code " << msg->mOurCircuitCode << llendl; 1698 llinfos << "viewer: UserLoginLocationReply() Enabling " << first_sim << " with code " << msg->mOurCircuitCode << llendl;
@@ -1711,14 +1726,7 @@ BOOL idle_startup()
1711 { 1726 {
1712 if (gViewerWindow) 1727 if (gViewerWindow)
1713 { 1728 {
1714 if (gSavedSettings.getBOOL("MuteAudio")) 1729 audio_update_volume(true);
1715 {
1716 LLMediaEngine::updateClass( 0.0f );
1717 }
1718 else
1719 {
1720 LLMediaEngine::updateClass( gSavedSettings.getF32( "MediaAudioVolume" ) );
1721 }
1722 } 1730 }
1723 1731
1724 #if LL_QUICKTIME_ENABLED // windows only right now but will be ported to mac 1732 #if LL_QUICKTIME_ENABLED // windows only right now but will be ported to mac
@@ -2298,6 +2306,9 @@ BOOL idle_startup()
2298 // On first start, ask user for gender 2306 // On first start, ask user for gender
2299 dialog_choose_gender_first_start(); 2307 dialog_choose_gender_first_start();
2300 2308
2309 // setup voice
2310 LLFirstUse::useVoice();
2311
2301 // Start automatic replay if the flag is set. 2312 // Start automatic replay if the flag is set.
2302 if (gSavedSettings.getBOOL("StatsAutoRun")) 2313 if (gSavedSettings.getBOOL("StatsAutoRun"))
2303 { 2314 {
@@ -2325,7 +2336,7 @@ BOOL idle_startup()
2325 } 2336 }
2326 } 2337 }
2327 } 2338 }
2328 2339
2329 // Clean up the userauth stuff. 2340 // Clean up the userauth stuff.
2330 if (gUserAuthp) 2341 if (gUserAuthp)
2331 { 2342 {
@@ -2334,13 +2345,9 @@ BOOL idle_startup()
2334 } 2345 }
2335 2346
2336 gStartupState++; 2347 gStartupState++;
2337 //RN: unmute audio now that we are entering world 2348
2338 //JC: But only if the user wants audio working. 2349 // Unmute audio if desired and setup volumes
2339 if (gAudiop) 2350 audio_update_volume();
2340 {
2341 BOOL mute = gSavedSettings.getBOOL("MuteAudio");
2342 gAudiop->setMuted(mute);
2343 }
2344 2351
2345 // reset keyboard focus to sane state of pointing at world 2352 // reset keyboard focus to sane state of pointing at world
2346 gFocusMgr.setKeyboardFocus(NULL, NULL); 2353 gFocusMgr.setKeyboardFocus(NULL, NULL);
@@ -2362,9 +2369,15 @@ BOOL idle_startup()
2362void login_show() 2369void login_show()
2363{ 2370{
2364 llinfos << "Initializing Login Screen" << llendl; 2371 llinfos << "Initializing Login Screen" << llendl;
2365 2372
2373#ifdef LL_RELEASE_FOR_DOWNLOAD
2374 BOOL bUseDebugLogin = gSavedSettings.getBOOL("UseDebugLogin");
2375#else
2376 BOOL bUseDebugLogin = TRUE;
2377#endif
2378
2366 LLPanelLogin::show( gViewerWindow->getVirtualWindowRect(), 2379 LLPanelLogin::show( gViewerWindow->getVirtualWindowRect(),
2367 gSavedSettings.getBOOL("UseDebugLogin"), 2380 bUseDebugLogin,
2368 login_callback, NULL ); 2381 login_callback, NULL );
2369 2382
2370 llinfos << "Decoding Images" << llendl; 2383 llinfos << "Decoding Images" << llendl;
@@ -2516,7 +2529,10 @@ void save_password_to_disk(const char* hashed_password)
2516 LLXORCipher cipher(gMACAddress, 6); 2529 LLXORCipher cipher(gMACAddress, 6);
2517 cipher.encrypt(buffer, HASHED_LENGTH); 2530 cipher.encrypt(buffer, HASHED_LENGTH);
2518 2531
2519 fwrite(buffer, HASHED_LENGTH, 1, fp); 2532 if (fwrite(buffer, HASHED_LENGTH, 1, fp) != 1)
2533 {
2534 llwarns << "Short write" << llendl;
2535 }
2520 2536
2521 fclose(fp); 2537 fclose(fp);
2522 } 2538 }
@@ -2810,10 +2826,9 @@ void use_circuit_callback(void**, S32 result)
2810{ 2826{
2811 // bail if we're quitting. 2827 // bail if we're quitting.
2812 if(gQuit) return; 2828 if(gQuit) return;
2813 static bool called = false; 2829 if( !gUseCircuitCallbackCalled )
2814 if(!called)
2815 { 2830 {
2816 called = true; 2831 gUseCircuitCallbackCalled = true;
2817 if (result) 2832 if (result)
2818 { 2833 {
2819 // Make sure user knows something bad happened. JC 2834 // Make sure user knows something bad happened. JC
@@ -3731,5 +3746,8 @@ void reset_login()
3731{ 3746{
3732 gStartupState = STATE_LOGIN_SHOW; 3747 gStartupState = STATE_LOGIN_SHOW;
3733 3748
3734 // do cleanup here of in-world UI? 3749 if ( gViewerWindow )
3750 { // Hide menus and normal buttons
3751 gViewerWindow->setNormalControlsVisible( FALSE );
3752 }
3735} 3753}
diff --git a/linden/indra/newview/llstatusbar.cpp b/linden/indra/newview/llstatusbar.cpp
index f0c6ea5..9d6434f 100644
--- a/linden/indra/newview/llstatusbar.cpp
+++ b/linden/indra/newview/llstatusbar.cpp
@@ -70,11 +70,14 @@
70#include "llviewerparcelmgr.h" 70#include "llviewerparcelmgr.h"
71#include "llviewerthrottle.h" 71#include "llviewerthrottle.h"
72#include "llvieweruictrlfactory.h" 72#include "llvieweruictrlfactory.h"
73#include "llvoiceclient.h" // for gVoiceClient
73 74
74#include "lltoolmgr.h" 75#include "lltoolmgr.h"
75#include "llfocusmgr.h" 76#include "llfocusmgr.h"
76#include "viewer.h" 77#include "viewer.h"
77 78
79//#include "llfirstuse.h"
80
78// 81//
79// Globals 82// Globals
80// 83//
@@ -96,6 +99,18 @@ const F32 ICON_FLASH_FREQUENCY = 2.f;
96const S32 GRAPHIC_FUDGE = 4; 99const S32 GRAPHIC_FUDGE = 4;
97const S32 TEXT_HEIGHT = 18; 100const S32 TEXT_HEIGHT = 18;
98 101
102static void onClickParcelInfo(void*);
103static void onClickBalance(void*);
104static void onClickBuyCurrency(void*);
105static void onClickHealth(void*);
106static void onClickFly(void*);
107static void onClickPush(void*);
108static void onClickVoice(void*);
109static void onClickBuild(void*);
110static void onClickScripts(void*);
111static void onClickBuyLand(void*);
112static void onClickScriptDebug(void*);
113
99std::vector<std::string> LLStatusBar::sDays; 114std::vector<std::string> LLStatusBar::sDays;
100std::vector<std::string> LLStatusBar::sMonths; 115std::vector<std::string> LLStatusBar::sMonths;
101const U32 LLStatusBar::MAX_DATE_STRING_LENGTH = 2000; 116const U32 LLStatusBar::MAX_DATE_STRING_LENGTH = 2000;
@@ -126,15 +141,6 @@ LLStatusBar::LLStatusBar(const std::string& name, const LLRect& rect)
126 // build date necessary data (must do after panel built) 141 // build date necessary data (must do after panel built)
127 setupDate(); 142 setupDate();
128 143
129 mBtnScriptOut = LLUICtrlFactory::getButtonByName( this, "scriptout" );
130 mBtnHealth = LLUICtrlFactory::getButtonByName( this, "health" );
131 mBtnFly = LLUICtrlFactory::getButtonByName( this, "fly" );
132 mBtnBuild = LLUICtrlFactory::getButtonByName( this, "build" );
133 mBtnScripts = LLUICtrlFactory::getButtonByName( this, "scripts" );
134 mBtnPush = LLUICtrlFactory::getButtonByName( this, "restrictpush" );
135 mBtnBuyLand = LLUICtrlFactory::getButtonByName( this, "buyland" );
136 mBtnBuyCurrency = LLUICtrlFactory::getButtonByName( this, "buycurrency" );
137
138 mTextParcelName = LLUICtrlFactory::getTextBoxByName( this, "ParcelNameText" ); 144 mTextParcelName = LLUICtrlFactory::getTextBoxByName( this, "ParcelNameText" );
139 mTextBalance = LLUICtrlFactory::getTextBoxByName( this, "BalanceText" ); 145 mTextBalance = LLUICtrlFactory::getTextBoxByName( this, "BalanceText" );
140 146
@@ -196,6 +202,7 @@ BOOL LLStatusBar::postBuild()
196 childSetAction("build", onClickBuild, this ); 202 childSetAction("build", onClickBuild, this );
197 childSetAction("scripts", onClickScripts, this ); 203 childSetAction("scripts", onClickScripts, this );
198 childSetAction("restrictpush", onClickPush, this ); 204 childSetAction("restrictpush", onClickPush, this );
205 childSetAction("status_voice", onClickVoice, this );
199 206
200 childSetActionTextbox("ParcelNameText", onClickParcelInfo ); 207 childSetActionTextbox("ParcelNameText", onClickParcelInfo );
201 childSetActionTextbox("BalanceText", onClickBalance ); 208 childSetActionTextbox("BalanceText", onClickBalance );
@@ -305,13 +312,13 @@ void LLStatusBar::refresh()
305 { 312 {
306 childGetRect( "scriptout", buttonRect ); 313 childGetRect( "scriptout", buttonRect );
307 r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight()); 314 r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
308 mBtnScriptOut->setRect(r); 315 childSetRect("scriptout",r);
309 mBtnScriptOut->setVisible(TRUE); 316 childSetVisible("scriptout", true);
310 x += buttonRect.getWidth(); 317 x += buttonRect.getWidth();
311 } 318 }
312 else 319 else
313 { 320 {
314 mBtnScriptOut->setVisible(FALSE); 321 childSetVisible("scriptout", false);
315 } 322 }
316 323
317 if ((region && region->getAllowDamage()) || 324 if ((region && region->getAllowDamage()) ||
@@ -320,19 +327,19 @@ void LLStatusBar::refresh()
320 // set visibility based on flashing 327 // set visibility based on flashing
321 if( mHealthTimer->hasExpired() ) 328 if( mHealthTimer->hasExpired() )
322 { 329 {
323 mBtnHealth->setVisible( TRUE ); 330 childSetVisible("health", true);
324 } 331 }
325 else 332 else
326 { 333 {
327 BOOL flash = S32(mHealthTimer->getElapsedSeconds() * ICON_FLASH_FREQUENCY) & 1; 334 BOOL flash = S32(mHealthTimer->getElapsedSeconds() * ICON_FLASH_FREQUENCY) & 1;
328 mBtnHealth->setVisible( flash ); 335 childSetVisible("health", flash);
329 } 336 }
330 mTextHealth->setVisible(TRUE); 337 mTextHealth->setVisible(TRUE);
331 338
332 // Health 339 // Health
333 childGetRect( "health", buttonRect ); 340 childGetRect( "health", buttonRect );
334 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight()); 341 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
335 mBtnHealth->setRect(r); 342 childSetRect("health", r);
336 x += buttonRect.getWidth(); 343 x += buttonRect.getWidth();
337 344
338 const S32 health_width = S32( LLFontGL::sSansSerifSmall->getWidth("100%") ); 345 const S32 health_width = S32( LLFontGL::sSansSerifSmall->getWidth("100%") );
@@ -343,7 +350,7 @@ void LLStatusBar::refresh()
343 else 350 else
344 { 351 {
345 // invisible if region doesn't allow damage 352 // invisible if region doesn't allow damage
346 mBtnHealth->setVisible(FALSE); 353 childSetVisible("health", false);
347 mTextHealth->setVisible(FALSE); 354 mTextHealth->setVisible(FALSE);
348 } 355 }
349 356
@@ -352,24 +359,24 @@ void LLStatusBar::refresh()
352 { 359 {
353 // No Fly Zone 360 // No Fly Zone
354 childGetRect( "fly", buttonRect ); 361 childGetRect( "fly", buttonRect );
355 mBtnFly->setVisible(TRUE); 362 childSetVisible( "fly", true );
356 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight()); 363 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
357 mBtnFly->setRect(r); 364 childSetRect( "fly", r );
358 x += buttonRect.getWidth(); 365 x += buttonRect.getWidth();
359 } 366 }
360 else 367 else
361 { 368 {
362 mBtnFly->setVisible(FALSE); 369 childSetVisible("fly", false);
363 } 370 }
364 371
365 BOOL no_build = parcel && !parcel->getAllowModify(); 372 BOOL no_build = parcel && !parcel->getAllowModify();
366 mBtnBuild->setVisible( no_build ); 373 childSetVisible("build", no_build);
367 if (no_build) 374 if (no_build)
368 { 375 {
369 childGetRect( "build", buttonRect ); 376 childGetRect( "build", buttonRect );
370 // No Build Zone 377 // No Build Zone
371 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight()); 378 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
372 mBtnBuild->setRect(r); 379 childSetRect( "build", r );
373 x += buttonRect.getWidth(); 380 x += buttonRect.getWidth();
374 } 381 }
375 382
@@ -381,37 +388,46 @@ void LLStatusBar::refresh()
381 { 388 {
382 no_scripts = TRUE; 389 no_scripts = TRUE;
383 } 390 }
384 mBtnScripts->setVisible( no_scripts ); 391 childSetVisible("scripts", no_scripts);
385 if (no_scripts) 392 if (no_scripts)
386 { 393 {
387 // No scripts 394 // No scripts
388 childGetRect( "scripts", buttonRect ); 395 childGetRect( "scripts", buttonRect );
389 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight()); 396 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
390 mBtnScripts->setRect(r); 397 childSetRect( "scripts", r );
391 x += buttonRect.getWidth(); 398 x += buttonRect.getWidth();
392 } 399 }
393 400
394 BOOL no_region_push = (region && region->getRestrictPushObject()); 401 BOOL no_region_push = (region && region->getRestrictPushObject());
395 BOOL no_push = no_region_push || (parcel && parcel->getRestrictPushObject()); 402 BOOL no_push = no_region_push || (parcel && parcel->getRestrictPushObject());
396 mBtnPush->setVisible( no_push ); 403 childSetVisible("restrictpush", no_push);
397 if (no_push) 404 if (no_push)
398 { 405 {
399 childGetRect( "restrictpush", buttonRect ); 406 childGetRect( "restrictpush", buttonRect );
400 // No Push Zone
401 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight()); 407 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
402 mBtnPush->setRect(r); 408 childSetRect( "restrictpush", r );
409 x += buttonRect.getWidth();
410 }
411
412 BOOL have_voice = gVoiceClient->getAreaVoiceDisabled() ? FALSE : TRUE;
413 childSetVisible("status_voice", have_voice);
414 if (have_voice)
415 {
416 childGetRect( "status_voice", buttonRect );
417 r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
418 childSetRect( "status_voice", r );
403 x += buttonRect.getWidth(); 419 x += buttonRect.getWidth();
404 } 420 }
405 421
406 BOOL canBuyLand = parcel 422 BOOL canBuyLand = parcel
407 && !parcel->isPublic() 423 && !parcel->isPublic()
408 && gParcelMgr->canAgentBuyParcel(parcel, false); 424 && gParcelMgr->canAgentBuyParcel(parcel, false);
409 mBtnBuyLand->setVisible(canBuyLand); 425 childSetVisible("buyland", canBuyLand);
410 if (canBuyLand) 426 if (canBuyLand)
411 { 427 {
412 childGetRect( "buyland", buttonRect ); 428 childGetRect( "buyland", buttonRect );
413 r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight()); 429 r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
414 mBtnBuyLand->setRect(r); 430 childSetRect( "buyland", r );
415 x += buttonRect.getWidth(); 431 x += buttonRect.getWidth();
416 } 432 }
417 433
@@ -480,7 +496,7 @@ void LLStatusBar::setVisibleForMouselook(bool visible)
480 mTextTime->setVisible(visible); 496 mTextTime->setVisible(visible);
481 mSGBandwidth->setVisible(visible); 497 mSGBandwidth->setVisible(visible);
482 mSGPacketLoss->setVisible(visible); 498 mSGPacketLoss->setVisible(visible);
483 mBtnBuyCurrency->setVisible(visible); 499 childSetVisible("buycurrency", visible);
484 setBackgroundVisible(visible); 500 setBackgroundVisible(visible);
485} 501}
486 502
@@ -589,58 +605,55 @@ S32 LLStatusBar::getSquareMetersLeft() const
589 return mSquareMetersCredit - mSquareMetersCommitted; 605 return mSquareMetersCredit - mSquareMetersCommitted;
590} 606}
591 607
592// static 608static void onClickParcelInfo(void* data)
593void LLStatusBar::onClickParcelInfo(void* data)
594{ 609{
595 gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); 610 gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
596 611
597 LLFloaterLand::show(); 612 LLFloaterLand::show();
598} 613}
599 614
600// static 615static void onClickBalance(void* data)
601void LLStatusBar::onClickBalance(void* data)
602{ 616{
603 LLFloaterBuyCurrency::buyCurrency(); 617 LLFloaterBuyCurrency::buyCurrency();
604} 618}
605 619
606// static 620static void onClickBuyCurrency(void* data)
607void LLStatusBar::onClickBuyCurrency(void* data)
608{ 621{
609 LLFloaterBuyCurrency::buyCurrency(); 622 LLFloaterBuyCurrency::buyCurrency();
610} 623}
611 624
612// static 625static void onClickHealth(void* )
613void LLStatusBar::onClickHealth(void* )
614{ 626{
615 LLNotifyBox::showXml("NotSafe"); 627 LLNotifyBox::showXml("NotSafe");
616} 628}
617 629
618// static 630static void onClickScriptDebug(void*)
619void LLStatusBar::onClickScriptDebug(void*)
620{ 631{
621 LLFloaterScriptDebug::show(LLUUID::null); 632 LLFloaterScriptDebug::show(LLUUID::null);
622} 633}
623 634
624// static 635static void onClickFly(void* )
625void LLStatusBar::onClickFly(void* )
626{ 636{
627 LLNotifyBox::showXml("NoFly"); 637 LLNotifyBox::showXml("NoFly");
628} 638}
629 639
630// static 640static void onClickPush(void* )
631void LLStatusBar::onClickPush(void* )
632{ 641{
633 LLNotifyBox::showXml("PushRestricted"); 642 LLNotifyBox::showXml("PushRestricted");
634} 643}
635 644
636// static 645static void onClickVoice(void* )
637void LLStatusBar::onClickBuild(void*) 646{
647 LLNotifyBox::showXml("VoiceAvailablity");
648 //LLFirstUse::useVoice();
649}
650
651static void onClickBuild(void*)
638{ 652{
639 LLNotifyBox::showXml("NoBuild"); 653 LLNotifyBox::showXml("NoBuild");
640} 654}
641 655
642// static 656static void onClickScripts(void*)
643void LLStatusBar::onClickScripts(void*)
644{ 657{
645 LLViewerRegion* region = gAgent.getRegion(); 658 LLViewerRegion* region = gAgent.getRegion();
646 if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) 659 if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
@@ -657,8 +670,7 @@ void LLStatusBar::onClickScripts(void*)
657 } 670 }
658} 671}
659 672
660// static 673static void onClickBuyLand(void*)
661void LLStatusBar::onClickBuyLand(void*)
662{ 674{
663 gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); 675 gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
664 gParcelMgr->startBuyLand(); 676 gParcelMgr->startBuyLand();
diff --git a/linden/indra/newview/llstatusbar.h b/linden/indra/newview/llstatusbar.h
index e08066b..ff71ee3 100644
--- a/linden/indra/newview/llstatusbar.h
+++ b/linden/indra/newview/llstatusbar.h
@@ -81,19 +81,7 @@ public:
81 S32 getSquareMetersCommitted() const; 81 S32 getSquareMetersCommitted() const;
82 S32 getSquareMetersLeft() const; 82 S32 getSquareMetersLeft() const;
83 83
84protected: 84protected:
85 static void onClickParcelInfo(void*);
86 static void onClickBalance(void*);
87 static void onClickBuyCurrency(void*);
88 static void onClickRegionInfo(void*);
89 static void onClickHealth(void*);
90 static void onClickFly(void*);
91 static void onClickPush(void*);
92 static void onClickBuild(void*);
93 static void onClickScripts(void*);
94 static void onClickBuyLand(void*);
95 static void onClickScriptDebug(void*);
96
97 // simple method to setup the part that holds the date 85 // simple method to setup the part that holds the date
98 void setupDate(); 86 void setupDate();
99 87
@@ -102,15 +90,6 @@ protected:
102 LLTextBox *mTextHealth; 90 LLTextBox *mTextHealth;
103 LLTextBox *mTextTime; 91 LLTextBox *mTextTime;
104 92
105 LLButton *mBtnScriptOut;
106 LLButton *mBtnHealth;
107 LLButton *mBtnFly;
108 LLButton *mBtnBuild;
109 LLButton *mBtnScripts;
110 LLButton *mBtnPush;
111 LLButton *mBtnBuyLand;
112
113
114 LLTextBox* mTextParcelName; 93 LLTextBox* mTextParcelName;
115 94
116 LLStatGraph *mSGBandwidth; 95 LLStatGraph *mSGBandwidth;
@@ -127,7 +106,7 @@ protected:
127 106
128 static std::vector<std::string> sDays; 107 static std::vector<std::string> sDays;
129 static std::vector<std::string> sMonths; 108 static std::vector<std::string> sMonths;
130 static const U32 LLStatusBar::MAX_DATE_STRING_LENGTH; 109 static const U32 MAX_DATE_STRING_LENGTH;
131}; 110};
132 111
133// *HACK: Status bar owns your cached money balance. JC 112// *HACK: Status bar owns your cached money balance. JC
diff --git a/linden/indra/newview/lltoolbar.cpp b/linden/indra/newview/lltoolbar.cpp
index 3d065e1..d58cca0 100644
--- a/linden/indra/newview/lltoolbar.cpp
+++ b/linden/indra/newview/lltoolbar.cpp
@@ -46,6 +46,7 @@
46#include "llvoavatar.h" 46#include "llvoavatar.h"
47#include "lltooldraganddrop.h" 47#include "lltooldraganddrop.h"
48#include "llinventoryview.h" 48#include "llinventoryview.h"
49#include "llfloaterchatterbox.h"
49#include "llfloaterfriends.h" 50#include "llfloaterfriends.h"
50#include "llfloatersnapshot.h" 51#include "llfloatersnapshot.h"
51#include "lltoolmgr.h" 52#include "lltoolmgr.h"
@@ -114,15 +115,12 @@ LLToolBar::LLToolBar(const std::string& name, const LLRect& r)
114 115
115BOOL LLToolBar::postBuild() 116BOOL LLToolBar::postBuild()
116{ 117{
117 childSetAction("im_btn", onClickIM, this); 118 childSetAction("communicate_btn", onClickCommunicate, this);
118 childSetControlName("im_btn", "ShowIM"); 119 childSetControlName("communicate_btn", "ShowCommunicate");
119 120
120 childSetAction("chat_btn", onClickChat, this); 121 childSetAction("chat_btn", onClickChat, this);
121 childSetControlName("chat_btn", "ChatVisible"); 122 childSetControlName("chat_btn", "ChatVisible");
122 123
123 childSetAction("friends_btn", onClickFriends, this);
124 childSetControlName("friends_btn", "ShowFriends");
125
126 childSetAction("appearance_btn", onClickAppearance, this); 124 childSetAction("appearance_btn", onClickAppearance, this);
127 childSetControlName("appearance_btn", ""); 125 childSetControlName("appearance_btn", "");
128 126
@@ -333,24 +331,9 @@ void LLToolBar::refresh()
333 331
334 332
335// static 333// static
336void LLToolBar::onClickIM(void* user_data) 334void LLToolBar::onClickCommunicate(void* user_data)
337{ 335{
338 if(gIMView->getFloaterOpen()) 336 LLFloaterChatterBox::toggleInstance(LLSD());
339 {
340 // this is if we want Ctrl-T to be simply a toggle
341 // gIMView->setFloaterOpen( FALSE );
342 // three-state behavior follows
343 if(gFocusMgr.childHasKeyboardFocus(gIMView->getFloater()))
344 {
345 gIMView->setFloaterOpen( FALSE );
346 } else {
347 gIMView->getFloater()->setFocus( TRUE );
348 }
349 }
350 else
351 {
352 gIMView->setFloaterOpen( TRUE );
353 }
354} 337}
355 338
356 339
@@ -360,14 +343,6 @@ void LLToolBar::onClickChat(void* user_data)
360 handle_chat(NULL); 343 handle_chat(NULL);
361} 344}
362 345
363
364// static
365void LLToolBar::onClickFriends(void*)
366{
367 LLFloaterFriends::toggle();
368}
369
370
371// static 346// static
372void LLToolBar::onClickAppearance(void*) 347void LLToolBar::onClickAppearance(void*)
373{ 348{
diff --git a/linden/indra/newview/lltoolbar.h b/linden/indra/newview/lltoolbar.h
index 52da849..3e32881 100644
--- a/linden/indra/newview/lltoolbar.h
+++ b/linden/indra/newview/lltoolbar.h
@@ -67,9 +67,8 @@ public:
67 void refresh(); 67 void refresh();
68 68
69 // callbacks 69 // callbacks
70 static void onClickIM(void*); 70 static void onClickCommunicate(void*);
71 static void onClickChat(void* data); 71 static void onClickChat(void* data);
72 static void onClickFriends(void* data);
73 static void onClickAppearance(void* data); 72 static void onClickAppearance(void* data);
74 static void onClickClothing(void* data); 73 static void onClickClothing(void* data);
75 static void onClickFly(void*); 74 static void onClickFly(void*);
diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp
index 6196927..655a8dd 100644
--- a/linden/indra/newview/lltooldraganddrop.cpp
+++ b/linden/indra/newview/lltooldraganddrop.cpp
@@ -1239,7 +1239,6 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
1239 return FALSE; 1239 return FALSE;
1240 } 1240 }
1241 } 1241 }
1242std::cout << "ASSET ID: " << new_item->getAssetUUID() << "\n";
1243 hit_obj->updateInventory(new_item, TASK_INVENTORY_ASSET_KEY, true); 1242 hit_obj->updateInventory(new_item, TASK_INVENTORY_ASSET_KEY, true);
1244 } 1243 }
1245 else if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, 1244 else if(!item->getPermissions().allowOperationBy(PERM_TRANSFER,
@@ -1253,7 +1252,6 @@ std::cout << "ASSET ID: " << new_item->getAssetUUID() << "\n";
1253 // *FIX: may want to make sure agent can paint hit_obj. 1252 // *FIX: may want to make sure agent can paint hit_obj.
1254 1253
1255 // make sure the object has the texture in it's inventory. 1254 // make sure the object has the texture in it's inventory.
1256std::cout << "ASSET ID: " << new_item->getAssetUUID() << "\n";
1257 hit_obj->updateInventory(new_item, TASK_INVENTORY_ASSET_KEY, true); 1255 hit_obj->updateInventory(new_item, TASK_INVENTORY_ASSET_KEY, true);
1258 } 1256 }
1259 return TRUE; 1257 return TRUE;
diff --git a/linden/indra/newview/lltoolselect.cpp b/linden/indra/newview/lltoolselect.cpp
index 329801f..f400b53 100644
--- a/linden/indra/newview/lltoolselect.cpp
+++ b/linden/indra/newview/lltoolselect.cpp
@@ -135,7 +135,7 @@ LLHandle<LLObjectSelection> LLToolSelect::handleObjectSelection(LLViewerObject *
135 } 135 }
136 else 136 else
137 { 137 {
138 gSelectMgr->deselectObjectAndFamily(object); 138 gSelectMgr->deselectObjectAndFamily(object, TRUE, TRUE);
139 } 139 }
140 } 140 }
141 else 141 else
diff --git a/linden/indra/newview/lluserauth.cpp b/linden/indra/newview/lluserauth.cpp
index 1513175..f790fe7 100644
--- a/linden/indra/newview/lluserauth.cpp
+++ b/linden/indra/newview/lluserauth.cpp
@@ -57,6 +57,8 @@ static const char* PLATFORM_STRING = "Win";
57static const char* PLATFORM_STRING = "Mac"; 57static const char* PLATFORM_STRING = "Mac";
58#elif LL_LINUX 58#elif LL_LINUX
59static const char* PLATFORM_STRING = "Lnx"; 59static const char* PLATFORM_STRING = "Lnx";
60#elif LL_SOLARIS
61static const char* PLATFORM_STRING = "Sol";
60#else 62#else
61#error("Unknown platform defined!") 63#error("Unknown platform defined!")
62#endif 64#endif
diff --git a/linden/indra/newview/llviewercontrol.h b/linden/indra/newview/llviewercontrol.h
index 4324c38..46363b1 100644
--- a/linden/indra/newview/llviewercontrol.h
+++ b/linden/indra/newview/llviewercontrol.h
@@ -54,9 +54,11 @@ protected:
54 LLTextEditor* mComment; 54 LLTextEditor* mComment;
55}; 55};
56 56
57// These functions found in llcontroldef.cpp *TODO: clean this up!
57//setting variables are declared in this function 58//setting variables are declared in this function
58void declare_settings(); 59void declare_settings();
59void fixup_settings(); 60void fixup_settings();
61void settings_setup_listeners();
60 62
61// saved at end of session 63// saved at end of session
62extern LLControlGroup gSavedSettings; 64extern LLControlGroup gSavedSettings;
diff --git a/linden/indra/newview/llviewerimage.h b/linden/indra/newview/llviewerimage.h
index ee19cfb..9e7689f 100644
--- a/linden/indra/newview/llviewerimage.h
+++ b/linden/indra/newview/llviewerimage.h
@@ -189,9 +189,27 @@ public:
189 189
190 // New methods for determining image quality/priority 190 // New methods for determining image quality/priority
191 // texel_area_ratio is ("scaled" texel area)/(original texel area), approximately. 191 // texel_area_ratio is ("scaled" texel area)/(original texel area), approximately.
192 void addTextureStats(F32 pixel_area) const
193 {
194 mMaxCosAngle = 1.0f;
195 if (pixel_area > mMaxVirtualSize)
196 {
197 mMaxVirtualSize = pixel_area;
198 }
199 }
200 void addTextureStats(F32 pixel_area,
201 F32 texel_area_ratio) const
202 {
203 mMaxCosAngle = 1.0f;
204 F32 virtual_size = pixel_area / texel_area_ratio;
205 if (virtual_size > mMaxVirtualSize)
206 {
207 mMaxVirtualSize = virtual_size;
208 }
209 }
192 void addTextureStats(F32 pixel_area, 210 void addTextureStats(F32 pixel_area,
193 F32 texel_area_ratio = 1.0f, 211 F32 texel_area_ratio,
194 F32 cos_center_angle = 1.0f) const; 212 F32 cos_center_angle) const;
195 void resetTextureStats(BOOL zero = FALSE); 213 void resetTextureStats(BOOL zero = FALSE);
196 214
197 // Process image stats to determine priority/quality requirements. 215 // Process image stats to determine priority/quality requirements.
diff --git a/linden/indra/newview/llviewerimagelist.cpp b/linden/indra/newview/llviewerimagelist.cpp
index 6616bc6..2e3b964 100644
--- a/linden/indra/newview/llviewerimagelist.cpp
+++ b/linden/indra/newview/llviewerimagelist.cpp
@@ -129,6 +129,7 @@ void LLViewerImageList::doPreloadImages()
129 if (!gPreloadImages) return; 129 if (!gPreloadImages) return;
130 130
131 // Preload some images 131 // Preload some images
132 preloadImage("active_voice_tab.tga", LLUUID::null, FALSE);
132 preloadImage("button_anim_pause.tga", LLUUID::null, FALSE); 133 preloadImage("button_anim_pause.tga", LLUUID::null, FALSE);
133 preloadImage("button_anim_pause_selected.tga", LLUUID::null, FALSE); 134 preloadImage("button_anim_pause_selected.tga", LLUUID::null, FALSE);
134 preloadImage("button_anim_play.tga", LLUUID::null, FALSE); 135 preloadImage("button_anim_play.tga", LLUUID::null, FALSE);
@@ -205,11 +206,15 @@ void LLViewerImageList::doPreloadImages()
205 preloadImage("map_infohub.tga", LLUUID::null, FALSE); 206 preloadImage("map_infohub.tga", LLUUID::null, FALSE);
206 preloadImage("map_telehub.tga", LLUUID::null, FALSE); 207 preloadImage("map_telehub.tga", LLUUID::null, FALSE);
207 preloadImage("map_track_16.tga", LLUUID::null, FALSE); 208 preloadImage("map_track_16.tga", LLUUID::null, FALSE);
209 preloadImage("media_icon.tga", LLUUID::null, FALSE);
208 preloadImage("minimize.tga", LLUUID::null, FALSE); 210 preloadImage("minimize.tga", LLUUID::null, FALSE);
209 preloadImage("minimize_pressed.tga", LLUUID::null, FALSE); 211 preloadImage("minimize_pressed.tga", LLUUID::null, FALSE);
212 preloadImage("music_icon.tga", LLUUID::null, FALSE);
210 preloadImage("noentrylines.tga", LLUUID::null, TRUE); 213 preloadImage("noentrylines.tga", LLUUID::null, TRUE);
211 preloadImage("noentrypasslines.tga", LLUUID::null, TRUE); 214 preloadImage("noentrypasslines.tga", LLUUID::null, TRUE);
212 preloadImage("notify_tip_icon.tga", LLUUID::null, FALSE); 215 preloadImage("notify_tip_icon.tga", LLUUID::null, FALSE);
216 preloadImage("notify_caution_icon.tga", LLUUID::null, FALSE);
217 preloadImage("notify_box_icon.tga", LLUUID::null, FALSE);
213 preloadImage("object_cone.tga", LLUUID::null, FALSE); 218 preloadImage("object_cone.tga", LLUUID::null, FALSE);
214 preloadImage("object_cone_active.tga", LLUUID::null, FALSE); 219 preloadImage("object_cone_active.tga", LLUUID::null, FALSE);
215 preloadImage("object_cube.tga", LLUUID::null, FALSE); 220 preloadImage("object_cube.tga", LLUUID::null, FALSE);
@@ -283,7 +288,19 @@ void LLViewerImageList::doPreloadImages()
283 preloadImage("tool_dozer_active.tga", LLUUID::null, FALSE); 288 preloadImage("tool_dozer_active.tga", LLUUID::null, FALSE);
284 preloadImage("tool_zoom.tga", LLUUID::null, FALSE); 289 preloadImage("tool_zoom.tga", LLUUID::null, FALSE);
285 preloadImage("tool_zoom_active.tga", LLUUID::null, FALSE); 290 preloadImage("tool_zoom_active.tga", LLUUID::null, FALSE);
291 preloadImage("volume_icon.tga", LLUUID::null, FALSE);
286 preloadImage("white.tga", LLUUID::null, TRUE); 292 preloadImage("white.tga", LLUUID::null, TRUE);
293 preloadImage("icn_active-speakers-dot-lvl0.tga", LLUUID::null, FALSE);
294 preloadImage("icn_active-speakers-dot-lvl1.tga", LLUUID::null, FALSE);
295 preloadImage("icn_active-speakers-dot-lvl2.tga", LLUUID::null, FALSE);
296 preloadImage("icn_active-speakers-typing1.tga", LLUUID::null, FALSE);
297 preloadImage("icn_active-speakers-typing2.tga", LLUUID::null, FALSE);
298 preloadImage("icn_active-speakers-typing3.tga", LLUUID::null, FALSE);
299 preloadImage("icn_voice_ptt-off.tga", LLUUID::null, FALSE);
300 preloadImage("icn_voice_ptt-on.tga", LLUUID::null, FALSE);
301 preloadImage("icn_voice_ptt-on-lvl1.tga", LLUUID::null, FALSE);
302 preloadImage("icn_voice_ptt-on-lvl2.tga", LLUUID::null, FALSE);
303 preloadImage("icn_voice_ptt-on-lvl3.tga", LLUUID::null, FALSE);
287} 304}
288 305
289static std::string get_texture_list_name() 306static std::string get_texture_list_name()
diff --git a/linden/indra/newview/llviewerinventory.cpp b/linden/indra/newview/llviewerinventory.cpp
index f24b7c7..6372ba8 100644
--- a/linden/indra/newview/llviewerinventory.cpp
+++ b/linden/indra/newview/llviewerinventory.cpp
@@ -460,7 +460,11 @@ bool LLViewerInventoryCategory::importFileLocal(FILE* fp)
460 valuestr[0] = '\0'; 460 valuestr[0] = '\0';
461 while(!feof(fp)) 461 while(!feof(fp))
462 { 462 {
463 fgets(buffer, MAX_STRING, fp); 463 if (fgets(buffer, MAX_STRING, fp) == NULL)
464 {
465 buffer[0] = '\0';
466 }
467
464 sscanf( /* Flawfinder: ignore */ 468 sscanf( /* Flawfinder: ignore */
465 buffer, " %254s %254s", keyword, valuestr); 469 buffer, " %254s %254s", keyword, valuestr);
466 if(0 == strcmp("{",keyword)) 470 if(0 == strcmp("{",keyword))
diff --git a/linden/indra/newview/llviewerjointattachment.cpp b/linden/indra/newview/llviewerjointattachment.cpp
index cec2ae3..f75ac48 100644
--- a/linden/indra/newview/llviewerjointattachment.cpp
+++ b/linden/indra/newview/llviewerjointattachment.cpp
@@ -50,16 +50,17 @@ extern LLPipeline gPipeline;
50//----------------------------------------------------------------------------- 50//-----------------------------------------------------------------------------
51// LLViewerJointAttachment() 51// LLViewerJointAttachment()
52//----------------------------------------------------------------------------- 52//-----------------------------------------------------------------------------
53LLViewerJointAttachment::LLViewerJointAttachment() 53LLViewerJointAttachment::LLViewerJointAttachment() :
54mJoint(NULL),
55mAttachedObject(NULL),
56mAttachmentDirty(FALSE),
57mVisibleInFirst(FALSE),
58mGroup(0),
59mIsHUDAttachment(FALSE),
60mPieSlice(-1)
54{ 61{
55 mJoint = NULL;
56 mAttachedObject = NULL;
57 mAttachmentDirty = FALSE;
58 mGroup = 0;
59 mUpdateXform = FALSE;
60 mIsHUDAttachment = FALSE;
61 mValid = FALSE; 62 mValid = FALSE;
62 mPieSlice = -1; 63 mUpdateXform = FALSE;
63} 64}
64 65
65//----------------------------------------------------------------------------- 66//-----------------------------------------------------------------------------
diff --git a/linden/indra/newview/llviewerjointmesh.cpp b/linden/indra/newview/llviewerjointmesh.cpp
index c76990c..09fd015 100644
--- a/linden/indra/newview/llviewerjointmesh.cpp
+++ b/linden/indra/newview/llviewerjointmesh.cpp
@@ -31,14 +31,11 @@
31//----------------------------------------------------------------------------- 31//-----------------------------------------------------------------------------
32#include "llviewerprecompiledheaders.h" 32#include "llviewerprecompiledheaders.h"
33 33
34#if LL_WINDOWS // For Intel vector classes
35 #include "fvec.h"
36#endif
37
38#include "imageids.h" 34#include "imageids.h"
39#include "llfasttimer.h" 35#include "llfasttimer.h"
40 36
41#include "llagent.h" 37#include "llagent.h"
38#include "llapr.h"
42#include "llbox.h" 39#include "llbox.h"
43#include "lldrawable.h" 40#include "lldrawable.h"
44#include "lldrawpoolavatar.h" 41#include "lldrawpoolavatar.h"
@@ -49,14 +46,19 @@
49#include "llglheaders.h" 46#include "llglheaders.h"
50#include "lltexlayer.h" 47#include "lltexlayer.h"
51#include "llviewercamera.h" 48#include "llviewercamera.h"
49#include "llviewercontrol.h"
52#include "llviewerimagelist.h" 50#include "llviewerimagelist.h"
53#include "llviewerjointmesh.h" 51#include "llviewerjointmesh.h"
54#include "llvoavatar.h" 52#include "llvoavatar.h"
55#include "llsky.h" 53#include "llsky.h"
56#include "pipeline.h" 54#include "pipeline.h"
57#include "llglslshader.h" 55#include "llglslshader.h"
56#include "llmath.h"
57#include "v4math.h"
58#include "m3math.h"
59#include "m4math.h"
58 60
59#if !LL_DARWIN && !LL_LINUX 61#if !LL_DARWIN && !LL_LINUX && !LL_SOLARIS
60extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB; 62extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
61extern PFNGLWEIGHTFVARBPROC glWeightfvARB; 63extern PFNGLWEIGHTFVARBPROC glWeightfvARB;
62extern PFNGLVERTEXBLENDARBPROC glVertexBlendARB; 64extern PFNGLVERTEXBLENDARBPROC glVertexBlendARB;
@@ -68,6 +70,7 @@ static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX |
68 LLVertexBuffer::MAP_NORMAL | 70 LLVertexBuffer::MAP_NORMAL |
69 LLVertexBuffer::MAP_TEXCOORD; 71 LLVertexBuffer::MAP_TEXCOORD;
70 72
73
71//----------------------------------------------------------------------------- 74//-----------------------------------------------------------------------------
72//----------------------------------------------------------------------------- 75//-----------------------------------------------------------------------------
73// LLViewerJointMesh::LLSkinJoint 76// LLViewerJointMesh::LLSkinJoint
@@ -120,6 +123,7 @@ BOOL LLSkinJoint::setupSkinJoint( LLViewerJoint *joint)
120 return TRUE; 123 return TRUE;
121} 124}
122 125
126
123//----------------------------------------------------------------------------- 127//-----------------------------------------------------------------------------
124//----------------------------------------------------------------------------- 128//-----------------------------------------------------------------------------
125// LLViewerJointMesh 129// LLViewerJointMesh
@@ -414,9 +418,9 @@ const S32 NUM_AXES = 3;
414// rotation Z 0-n 418// rotation Z 0-n
415// pivot parent 0-n -- child = n+1 419// pivot parent 0-n -- child = n+1
416 420
417static LLMatrix4 gJointMat[32]; 421static LLMatrix4 gJointMatUnaligned[32];
418static LLMatrix3 gJointRot[32]; 422static LLMatrix3 gJointRotUnaligned[32];
419static LLVector4 gJointPivot[32]; 423static LLVector4 gJointPivot[32];
420 424
421//----------------------------------------------------------------------------- 425//-----------------------------------------------------------------------------
422// uploadJointMatrices() 426// uploadJointMatrices()
@@ -437,8 +441,8 @@ void LLViewerJointMesh::uploadJointMatrices()
437 { 441 {
438 joint_mat *= LLDrawPoolAvatar::getModelView(); 442 joint_mat *= LLDrawPoolAvatar::getModelView();
439 } 443 }
440 gJointMat[joint_num] = joint_mat; 444 gJointMatUnaligned[joint_num] = joint_mat;
441 gJointRot[joint_num] = joint_mat.getMat3(); 445 gJointRotUnaligned[joint_num] = joint_mat.getMat3();
442 } 446 }
443 447
444 BOOL last_pivot_uploaded = FALSE; 448 BOOL last_pivot_uploaded = FALSE;
@@ -475,8 +479,8 @@ void LLViewerJointMesh::uploadJointMatrices()
475 { 479 {
476 LLVector3 pivot; 480 LLVector3 pivot;
477 pivot = LLVector3(gJointPivot[i]); 481 pivot = LLVector3(gJointPivot[i]);
478 pivot = pivot * gJointRot[i]; 482 pivot = pivot * gJointRotUnaligned[i];
479 gJointMat[i].translate(pivot); 483 gJointMatUnaligned[i].translate(pivot);
480 } 484 }
481 485
482 // upload matrices 486 // upload matrices
@@ -487,11 +491,11 @@ void LLViewerJointMesh::uploadJointMatrices()
487 491
488 for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.count(); joint_num++) 492 for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.count(); joint_num++)
489 { 493 {
490 gJointMat[joint_num].transpose(); 494 gJointMatUnaligned[joint_num].transpose();
491 495
492 for (S32 axis = 0; axis < NUM_AXES; axis++) 496 for (S32 axis = 0; axis < NUM_AXES; axis++)
493 { 497 {
494 F32* vector = gJointMat[joint_num].mMatrix[axis]; 498 F32* vector = gJointMatUnaligned[joint_num].mMatrix[axis];
495 //glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, LL_CHARACTER_MAX_JOINTS_PER_MESH * axis + joint_num+5, (GLfloat*)vector); 499 //glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, LL_CHARACTER_MAX_JOINTS_PER_MESH * axis + joint_num+5, (GLfloat*)vector);
496 U32 offset = LL_CHARACTER_MAX_JOINTS_PER_MESH*axis+joint_num; 500 U32 offset = LL_CHARACTER_MAX_JOINTS_PER_MESH*axis+joint_num;
497 memcpy(mat+offset*4, vector, sizeof(GLfloat)*4); 501 memcpy(mat+offset*4, vector, sizeof(GLfloat)*4);
@@ -903,21 +907,9 @@ BOOL LLViewerJointMesh::updateLOD(F32 pixel_area, BOOL activate)
903 return (valid != activate); 907 return (valid != activate);
904} 908}
905 909
906 910// static
907void LLViewerJointMesh::updateGeometry() 911void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh)
908{ 912{
909 if (!(mValid
910 && mMesh
911 && mFace
912 && mMesh->hasWeights()
913 && mFace->mVertexBuffer.notNull()
914 && LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) == 0))
915 {
916 return;
917 }
918
919 uploadJointMatrices();
920
921 LLStrider<LLVector3> o_vertices; 913 LLStrider<LLVector3> o_vertices;
922 LLStrider<LLVector3> o_normals; 914 LLStrider<LLVector3> o_normals;
923 915
@@ -958,9 +950,9 @@ void LLViewerJointMesh::updateGeometry()
958 // No lerp required in this case. 950 // No lerp required in this case.
959 if (w == 1.0f) 951 if (w == 1.0f)
960 { 952 {
961 gBlendMat = gJointMat[joint+1]; 953 gBlendMat = gJointMatUnaligned[joint+1];
962 o_vertices[bidx] = coords[index] * gBlendMat; 954 o_vertices[bidx] = coords[index] * gBlendMat;
963 gBlendRotMat = gJointRot[joint+1]; 955 gBlendRotMat = gJointRotUnaligned[joint+1];
964 o_normals[bidx] = normals[index] * gBlendRotMat; 956 o_normals[bidx] = normals[index] * gBlendRotMat;
965 continue; 957 continue;
966 } 958 }
@@ -968,8 +960,8 @@ void LLViewerJointMesh::updateGeometry()
968 // Try to keep all the accesses to the matrix data as close 960 // Try to keep all the accesses to the matrix data as close
969 // together as possible. This function is a hot spot on the 961 // together as possible. This function is a hot spot on the
970 // Mac. JC 962 // Mac. JC
971 LLMatrix4 &m0 = gJointMat[joint+1]; 963 LLMatrix4 &m0 = gJointMatUnaligned[joint+1];
972 LLMatrix4 &m1 = gJointMat[joint+0]; 964 LLMatrix4 &m1 = gJointMatUnaligned[joint+0];
973 965
974 gBlendMat.mMatrix[VX][VX] = lerp(m1.mMatrix[VX][VX], m0.mMatrix[VX][VX], w); 966 gBlendMat.mMatrix[VX][VX] = lerp(m1.mMatrix[VX][VX], m0.mMatrix[VX][VX], w);
975 gBlendMat.mMatrix[VX][VY] = lerp(m1.mMatrix[VX][VY], m0.mMatrix[VX][VY], w); 967 gBlendMat.mMatrix[VX][VY] = lerp(m1.mMatrix[VX][VY], m0.mMatrix[VX][VY], w);
@@ -989,8 +981,8 @@ void LLViewerJointMesh::updateGeometry()
989 981
990 o_vertices[bidx] = coords[index] * gBlendMat; 982 o_vertices[bidx] = coords[index] * gBlendMat;
991 983
992 LLMatrix3 &n0 = gJointRot[joint+1]; 984 LLMatrix3 &n0 = gJointRotUnaligned[joint+1];
993 LLMatrix3 &n1 = gJointRot[joint+0]; 985 LLMatrix3 &n1 = gJointRotUnaligned[joint+0];
994 986
995 gBlendRotMat.mMatrix[VX][VX] = lerp(n1.mMatrix[VX][VX], n0.mMatrix[VX][VX], w); 987 gBlendRotMat.mMatrix[VX][VX] = lerp(n1.mMatrix[VX][VX], n0.mMatrix[VX][VX], w);
996 gBlendRotMat.mMatrix[VX][VY] = lerp(n1.mMatrix[VX][VY], n0.mMatrix[VX][VY], w); 988 gBlendRotMat.mMatrix[VX][VY] = lerp(n1.mMatrix[VX][VY], n0.mMatrix[VX][VY], w);
@@ -1008,6 +1000,161 @@ void LLViewerJointMesh::updateGeometry()
1008 } 1000 }
1009} 1001}
1010 1002
1003const U32 UPDATE_GEOMETRY_CALL_MASK = 0x1FFF; // 8K samples before overflow
1004const U32 UPDATE_GEOMETRY_CALL_OVERFLOW = ~UPDATE_GEOMETRY_CALL_MASK;
1005static bool sUpdateGeometryCallPointer = false;
1006static F64 sUpdateGeometryGlobalTime = 0.0 ;
1007static F64 sUpdateGeometryElapsedTime = 0.0 ;
1008static F64 sUpdateGeometryElapsedTimeOff = 0.0 ;
1009static F64 sUpdateGeometryElapsedTimeOn = 0.0 ;
1010static F64 sUpdateGeometryRunAvgOff[10];
1011static F64 sUpdateGeometryRunAvgOn[10];
1012static U32 sUpdateGeometryRunCount = 0 ;
1013static U32 sUpdateGeometryCalls = 0 ;
1014static U32 sUpdateGeometryLastProcessor = 0 ;
1015void (*LLViewerJointMesh::sUpdateGeometryFunc)(LLFace* face, LLPolyMesh* mesh);
1016
1017void LLViewerJointMesh::updateGeometry()
1018{
1019 extern BOOL gVectorizePerfTest;
1020 extern U32 gVectorizeProcessor;
1021
1022 if (!(mValid
1023 && mMesh
1024 && mFace
1025 && mMesh->hasWeights()
1026 && mFace->mVertexBuffer.notNull()
1027 && LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) == 0))
1028 {
1029 return;
1030 }
1031
1032 if (!gVectorizePerfTest)
1033 {
1034 // Once we've measured performance, just run the specified
1035 // code version.
1036 if(sUpdateGeometryFunc == updateGeometryOriginal)
1037 uploadJointMatrices();
1038 sUpdateGeometryFunc(mFace, mMesh);
1039 }
1040 else
1041 {
1042 // At startup, measure the amount of time in skinning and choose
1043 // the fastest one.
1044 LLTimer ug_timer ;
1045
1046 if (sUpdateGeometryCallPointer)
1047 {
1048 if(sUpdateGeometryFunc == updateGeometryOriginal)
1049 uploadJointMatrices();
1050 // call accelerated version for this processor
1051 sUpdateGeometryFunc(mFace, mMesh);
1052 }
1053 else
1054 {
1055 uploadJointMatrices();
1056 updateGeometryOriginal(mFace, mMesh);
1057 }
1058
1059 sUpdateGeometryElapsedTime += ug_timer.getElapsedTimeF64();
1060 ++sUpdateGeometryCalls;
1061 if(0 != (sUpdateGeometryCalls & UPDATE_GEOMETRY_CALL_OVERFLOW))
1062 {
1063 F64 time_since_app_start = ug_timer.getElapsedSeconds();
1064 if(sUpdateGeometryGlobalTime == 0.0
1065 || sUpdateGeometryLastProcessor != gVectorizeProcessor)
1066 {
1067 sUpdateGeometryGlobalTime = time_since_app_start;
1068 sUpdateGeometryElapsedTime = 0;
1069 sUpdateGeometryCalls = 0;
1070 sUpdateGeometryRunCount = 0;
1071 sUpdateGeometryLastProcessor = gVectorizeProcessor;
1072 sUpdateGeometryCallPointer = false;
1073 return;
1074 }
1075 F64 percent_time_in_function =
1076 ( sUpdateGeometryElapsedTime * 100.0 ) / ( time_since_app_start - sUpdateGeometryGlobalTime ) ;
1077 sUpdateGeometryGlobalTime = time_since_app_start;
1078 if (!sUpdateGeometryCallPointer)
1079 {
1080 // First set of run data is with vectorization off.
1081 sUpdateGeometryCallPointer = true;
1082 llinfos << "profile (avg of " << sUpdateGeometryCalls << " samples) = "
1083 << "vectorize off " << percent_time_in_function
1084 << "% of time with "
1085 << (sUpdateGeometryElapsedTime / (F64)sUpdateGeometryCalls)
1086 << " seconds per call "
1087 << llendl;
1088 sUpdateGeometryRunAvgOff[sUpdateGeometryRunCount] = percent_time_in_function;
1089 sUpdateGeometryElapsedTimeOff += sUpdateGeometryElapsedTime;
1090 sUpdateGeometryCalls = 0;
1091 }
1092 else
1093 {
1094 // Second set of run data is with vectorization on.
1095 sUpdateGeometryCallPointer = false;
1096 llinfos << "profile (avg of " << sUpdateGeometryCalls << " samples) = "
1097 << "VEC on " << percent_time_in_function
1098 << "% of time with "
1099 << (sUpdateGeometryElapsedTime / (F64)sUpdateGeometryCalls)
1100 << " seconds per call "
1101 << llendl;
1102 sUpdateGeometryRunAvgOn[sUpdateGeometryRunCount] = percent_time_in_function ;
1103 sUpdateGeometryElapsedTimeOn += sUpdateGeometryElapsedTime;
1104
1105 sUpdateGeometryCalls = 0;
1106 sUpdateGeometryRunCount++;
1107 F64 a = 0.0, b = 0.0;
1108 for(U32 i = 0; i<sUpdateGeometryRunCount; i++)
1109 {
1110 a += sUpdateGeometryRunAvgOff[i];
1111 b += sUpdateGeometryRunAvgOn[i];
1112 }
1113 a /= sUpdateGeometryRunCount;
1114 b /= sUpdateGeometryRunCount;
1115 F64 perf_boost = ( sUpdateGeometryElapsedTimeOff - sUpdateGeometryElapsedTimeOn ) / sUpdateGeometryElapsedTimeOn;
1116 llinfos << "run averages (" << (F64)sUpdateGeometryRunCount
1117 << "/10) vectorize off " << a
1118 << "% : vectorize type " << gVectorizeProcessor
1119 << " " << b
1120 << "% : performance boost "
1121 << perf_boost * 100.0
1122 << "%"
1123 << llendl ;
1124 if(sUpdateGeometryRunCount == 10)
1125 {
1126 // In case user runs test again, force reset of data on
1127 // next run.
1128 sUpdateGeometryGlobalTime = 0.0;
1129
1130 // We have data now on which version is faster. Switch to that
1131 // code and save the data for next run.
1132 gVectorizePerfTest = FALSE;
1133 gSavedSettings.setBOOL("VectorizePerfTest", FALSE);
1134
1135 if (perf_boost > 0.0)
1136 {
1137 llinfos << "Vectorization improves avatar skinning performance, "
1138 << "keeping on for future runs."
1139 << llendl;
1140 gSavedSettings.setBOOL("VectorizeSkin", TRUE);
1141 }
1142 else
1143 {
1144 // SIMD decreases performance, fall back to original code
1145 llinfos << "Vectorization decreases avatar skinning performance, "
1146 << "switching back to original code."
1147 << llendl;
1148
1149 gSavedSettings.setBOOL("VectorizeSkin", FALSE);
1150 }
1151 }
1152 }
1153 sUpdateGeometryElapsedTime = 0.0f;
1154 }
1155 }
1156}
1157
1011void LLViewerJointMesh::dump() 1158void LLViewerJointMesh::dump()
1012{ 1159{
1013 if (mValid) 1160 if (mValid)
diff --git a/linden/indra/newview/llviewerjointmesh.h b/linden/indra/newview/llviewerjointmesh.h
index f016da6..b40daed 100644
--- a/linden/indra/newview/llviewerjointmesh.h
+++ b/linden/indra/newview/llviewerjointmesh.h
@@ -146,6 +146,22 @@ public:
146 146
147 /*virtual*/ BOOL isAnimatable() { return FALSE; } 147 /*virtual*/ BOOL isAnimatable() { return FALSE; }
148 void writeCAL3D(apr_file_t* fp, S32 material_num, LLCharacter* characterp); 148 void writeCAL3D(apr_file_t* fp, S32 material_num, LLCharacter* characterp);
149
150 // Avatar vertex skinning is a significant performance issue on computers
151 // with avatar vertex programs turned off (for example, most Macs). We
152 // therefore have custom versions that use SIMD instructions.
153 //
154 // These functions require compiler options for SSE2, SSE, or neither, and
155 // hence are contained in separate individual .cpp files. JC
156 static void updateGeometryOriginal(LLFace* face, LLPolyMesh* mesh);
157 // generic vector code, used for Altivec
158 static void updateGeometryVectorized(LLFace* face, LLPolyMesh* mesh);
159 static void updateGeometrySSE(LLFace* face, LLPolyMesh* mesh);
160 static void updateGeometrySSE2(LLFace* face, LLPolyMesh* mesh);
161
162 // Use a fuction pointer to indicate which version we are running.
163 static void (*sUpdateGeometryFunc)(LLFace* face, LLPolyMesh* mesh);
164
149private: 165private:
150 // Allocate skin data 166 // Allocate skin data
151 BOOL allocateSkinData( U32 numSkinJoints ); 167 BOOL allocateSkinData( U32 numSkinJoints );
diff --git a/linden/indra/newview/llviewerjointmesh_sse.cpp b/linden/indra/newview/llviewerjointmesh_sse.cpp
new file mode 100644
index 0000000..95d621a
--- /dev/null
+++ b/linden/indra/newview/llviewerjointmesh_sse.cpp
@@ -0,0 +1,114 @@
1/**
2 * @file llviewerjointmesh_sse.cpp
3 * @brief SSE vectorized joint skinning code, only used when video card does
4 * not support avatar vertex programs.
5 *
6 * *NOTE: Disabled on Windows builds. See llv4math.h for details.
7 *
8 * Copyright (c) 2007-2007, Linden Research, Inc.
9 *
10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab
12 * to you under the terms of the GNU General Public License, version 2.0
13 * ("GPL"), unless you have obtained a separate licensing agreement
14 * ("Other License"), formally executed by you and Linden Lab. Terms of
15 * the GPL can be found in doc/GPL-license.txt in this distribution, or
16 * online at http://secondlife.com/developers/opensource/gplv2
17 *
18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/flossexception
22 *
23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations.
26 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE.
30 */
31
32//-----------------------------------------------------------------------------
33// Header Files
34//-----------------------------------------------------------------------------
35
36#include "llviewerprecompiledheaders.h"
37
38#include "llviewerjointmesh.h"
39
40// project includes
41#include "llface.h"
42#include "llpolymesh.h"
43
44// library includes
45#include "lldarray.h"
46#include "llv4math.h" // for LL_VECTORIZE
47#include "llv4matrix3.h"
48#include "llv4matrix4.h"
49#include "v3math.h"
50
51
52#if LL_VECTORIZE
53
54inline void matrix_translate(LLV4Matrix4& m, const LLMatrix4* w, const LLVector3& j)
55{
56 m.mV[VX] = _mm_loadu_ps(w->mMatrix[VX]);
57 m.mV[VY] = _mm_loadu_ps(w->mMatrix[VY]);
58 m.mV[VZ] = _mm_loadu_ps(w->mMatrix[VZ]);
59 m.mV[VW] = _mm_loadu_ps(w->mMatrix[VW]);
60 m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VX]), m.mV[VX])); // ( ax * vx ) + vw
61 m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VY]), m.mV[VY]));
62 m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VZ]), m.mV[VZ]));
63}
64
65// static
66void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
67{
68 // This cannot be a file-level static because it will be initialized
69 // before main() using SSE code, which will crash on non-SSE processors.
70 static LLV4Matrix4 sJointMat[32];
71 LLDynamicArray<LLJointRenderData*>& joint_data = mesh->getReferenceMesh()->mJointRenderData;
72
73 //upload joint pivots/matrices
74 for(S32 j = 0, jend = joint_data.count(); j < jend ; ++j )
75 {
76 matrix_translate(sJointMat[j], joint_data[j]->mWorldMatrix,
77 joint_data[j]->mSkinJoint ?
78 joint_data[j]->mSkinJoint->mRootToJointSkinOffset
79 : joint_data[j+1]->mSkinJoint->mRootToParentJointSkinOffset);
80 }
81
82 F32 weight = F32_MAX;
83 LLV4Matrix4 blend_mat;
84
85 LLStrider<LLVector3> o_vertices;
86 LLStrider<LLVector3> o_normals;
87
88 LLVertexBuffer *buffer = face->mVertexBuffer;
89 buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset);
90 buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset);
91
92 const F32* weights = mesh->getWeights();
93 const LLVector3* coords = mesh->getCoords();
94 const LLVector3* normals = mesh->getNormals();
95 for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
96 {
97 if( weight != weights[index])
98 {
99 S32 joint = llfloor(weight = weights[index]);
100 blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
101 }
102 blend_mat.multiply(coords[index], o_vertices[index]);
103 ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
104 }
105}
106
107#else
108
109void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
110{
111 LLViewerJointMesh::updateGeometryVectorized(face, mesh);
112}
113
114#endif
diff --git a/linden/indra/newview/llviewerjointmesh_sse2.cpp b/linden/indra/newview/llviewerjointmesh_sse2.cpp
new file mode 100644
index 0000000..27aab80
--- /dev/null
+++ b/linden/indra/newview/llviewerjointmesh_sse2.cpp
@@ -0,0 +1,121 @@
1/**
2 * @file llviewerjointmesh_sse2.cpp
3 * @brief SSE vectorized joint skinning code, only used when video card does
4 * not support avatar vertex programs.
5 *
6 * *NOTE: Disabled on Windows builds. See llv4math.h for details.
7 *
8 * Copyright (c) 2007-2007, Linden Research, Inc.
9 *
10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab
12 * to you under the terms of the GNU General Public License, version 2.0
13 * ("GPL"), unless you have obtained a separate licensing agreement
14 * ("Other License"), formally executed by you and Linden Lab. Terms of
15 * the GPL can be found in doc/GPL-license.txt in this distribution, or
16 * online at http://secondlife.com/developers/opensource/gplv2
17 *
18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/flossexception
22 *
23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations.
26 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE.
30 */
31
32// Visual Studio required settings for this file:
33// Precompiled Headers OFF
34// Code Generation: SSE2
35
36//-----------------------------------------------------------------------------
37// Header Files
38//-----------------------------------------------------------------------------
39
40#include "llviewerprecompiledheaders.h"
41
42#include "llviewerjointmesh.h"
43
44// project includes
45#include "llface.h"
46#include "llpolymesh.h"
47
48// library includes
49#include "lldarray.h"
50#include "llstrider.h"
51#include "llv4math.h" // for LL_VECTORIZE
52#include "llv4matrix3.h"
53#include "llv4matrix4.h"
54#include "m4math.h"
55#include "v3math.h"
56
57
58#if LL_VECTORIZE
59
60
61inline void matrix_translate(LLV4Matrix4& m, const LLMatrix4* w, const LLVector3& j)
62{
63 m.mV[VX] = _mm_loadu_ps(w->mMatrix[VX]);
64 m.mV[VY] = _mm_loadu_ps(w->mMatrix[VY]);
65 m.mV[VZ] = _mm_loadu_ps(w->mMatrix[VZ]);
66 m.mV[VW] = _mm_loadu_ps(w->mMatrix[VW]);
67 m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VX]), m.mV[VX])); // ( ax * vx ) + vw
68 m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VY]), m.mV[VY]));
69 m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VZ]), m.mV[VZ]));
70}
71
72// static
73void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh)
74{
75 // This cannot be a file-level static because it will be initialized
76 // before main() using SSE code, which will crash on non-SSE processors.
77 static LLV4Matrix4 sJointMat[32];
78 LLDynamicArray<LLJointRenderData*>& joint_data = mesh->getReferenceMesh()->mJointRenderData;
79
80 //upload joint pivots/matrices
81 for(S32 j = 0, jend = joint_data.count(); j < jend ; ++j )
82 {
83 matrix_translate(sJointMat[j], joint_data[j]->mWorldMatrix,
84 joint_data[j]->mSkinJoint ?
85 joint_data[j]->mSkinJoint->mRootToJointSkinOffset
86 : joint_data[j+1]->mSkinJoint->mRootToParentJointSkinOffset);
87 }
88
89 F32 weight = F32_MAX;
90 LLV4Matrix4 blend_mat;
91
92 LLStrider<LLVector3> o_vertices;
93 LLStrider<LLVector3> o_normals;
94
95 LLVertexBuffer *buffer = face->mVertexBuffer;
96 buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset);
97 buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset);
98
99 const F32* weights = mesh->getWeights();
100 const LLVector3* coords = mesh->getCoords();
101 const LLVector3* normals = mesh->getNormals();
102 for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
103 {
104 if( weight != weights[index])
105 {
106 S32 joint = llfloor(weight = weights[index]);
107 blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
108 }
109 blend_mat.multiply(coords[index], o_vertices[index]);
110 ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
111 }
112}
113
114#else
115
116void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh)
117{
118 LLViewerJointMesh::updateGeometryVectorized(face, mesh);
119}
120
121#endif
diff --git a/linden/indra/newview/llviewerjointmesh_vec.cpp b/linden/indra/newview/llviewerjointmesh_vec.cpp
new file mode 100644
index 0000000..39c50de
--- /dev/null
+++ b/linden/indra/newview/llviewerjointmesh_vec.cpp
@@ -0,0 +1,95 @@
1/**
2 * @file llviewerjointmesh_vec.cpp
3 * @brief Compiler-generated vectorized joint skinning code, works well on
4 * Altivec processors (PowerPC Mac)
5 *
6 * *NOTE: See llv4math.h for notes on SSE/Altivec vector code.
7 *
8 * Copyright (c) 2007-2007, Linden Research, Inc.
9 *
10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab
12 * to you under the terms of the GNU General Public License, version 2.0
13 * ("GPL"), unless you have obtained a separate licensing agreement
14 * ("Other License"), formally executed by you and Linden Lab. Terms of
15 * the GPL can be found in doc/GPL-license.txt in this distribution, or
16 * online at http://secondlife.com/developers/opensource/gplv2
17 *
18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/flossexception
22 *
23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations.
26 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE.
30 */
31
32//-----------------------------------------------------------------------------
33// Header Files
34//-----------------------------------------------------------------------------
35#include "llviewerprecompiledheaders.h"
36
37#include "llviewerjointmesh.h"
38
39#include "llface.h"
40#include "llpolymesh.h"
41#include "llv4math.h"
42#include "llv4matrix3.h"
43#include "llv4matrix4.h"
44
45// Generic vectorized code, uses compiler defaults, works well for Altivec
46// on PowerPC.
47
48// static
49void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh)
50{
51 static LLV4Matrix4 sJointMat[32];
52 LLDynamicArray<LLJointRenderData*>& joint_data = mesh->getReferenceMesh()->mJointRenderData;
53 S32 j, joint_num, joint_end = joint_data.count();
54 LLV4Vector3 pivot;
55
56 //upload joint pivots/matrices
57 for(j = joint_num = 0; joint_num < joint_end ; ++joint_num )
58 {
59 LLSkinJoint *sj;
60 const LLMatrix4 * wm = joint_data[joint_num]->mWorldMatrix;
61 if (NULL == (sj = joint_data[joint_num]->mSkinJoint))
62 {
63 sj = joint_data[++joint_num]->mSkinJoint;
64 ((LLV4Matrix3)(sJointMat[j] = *wm)).multiply(sj->mRootToParentJointSkinOffset, pivot);
65 sJointMat[j++].translate(pivot);
66 wm = joint_data[joint_num]->mWorldMatrix;
67 }
68 ((LLV4Matrix3)(sJointMat[j] = *wm)).multiply(sj->mRootToJointSkinOffset, pivot);
69 sJointMat[j++].translate(pivot);
70 }
71
72 F32 weight = F32_MAX;
73 LLV4Matrix4 blend_mat;
74
75 LLStrider<LLVector3> o_vertices;
76 LLStrider<LLVector3> o_normals;
77
78 LLVertexBuffer *buffer = face->mVertexBuffer;
79 buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset);
80 buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset);
81
82 const F32* weights = mesh->getWeights();
83 const LLVector3* coords = mesh->getCoords();
84 const LLVector3* normals = mesh->getNormals();
85 for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
86 {
87 if( weight != weights[index])
88 {
89 S32 joint = llfloor(weight = weights[index]);
90 blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
91 }
92 blend_mat.multiply(coords[index], o_vertices[index]);
93 ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
94 }
95}
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp
index 31d10df..4ac1da4 100644
--- a/linden/indra/newview/llviewermenu.cpp
+++ b/linden/indra/newview/llviewermenu.cpp
@@ -79,6 +79,8 @@
79#include "llfloater.h" 79#include "llfloater.h"
80#include "llfloaterabout.h" 80#include "llfloaterabout.h"
81#include "llfloaterbuycurrency.h" 81#include "llfloaterbuycurrency.h"
82#include "llfloateractivespeakers.h"
83#include "llfloateranimpreview.h"
82#include "llfloateravatarinfo.h" 84#include "llfloateravatarinfo.h"
83#include "llfloateravatartextures.h" 85#include "llfloateravatartextures.h"
84#include "llfloaterbuildoptions.h" 86#include "llfloaterbuildoptions.h"
@@ -91,6 +93,7 @@
91#include "llfloatercustomize.h" 93#include "llfloatercustomize.h"
92#include "llfloaterdirectory.h" 94#include "llfloaterdirectory.h"
93#include "llfloatereditui.h" 95#include "llfloatereditui.h"
96#include "llfloaterchatterbox.h"
94#include "llfloaterfriends.h" 97#include "llfloaterfriends.h"
95#include "llfloatergesture.h" 98#include "llfloatergesture.h"
96#include "llfloatergodtools.h" 99#include "llfloatergodtools.h"
@@ -735,7 +738,7 @@ void init_client_menu(LLMenuGL* menu)
735 738
736 // neither of these works particularly well at the moment 739 // neither of these works particularly well at the moment
737 /*menu->append(new LLMenuItemCallGL( "Reload UI XML", &reload_ui, 740 /*menu->append(new LLMenuItemCallGL( "Reload UI XML", &reload_ui,
738 NULL, NULL, 'R', MASK_ALT | MASK_CONTROL ) );*/ 741 NULL, NULL) );*/
739 /*menu->append(new LLMenuItemCallGL("Reload settings/colors", 742 /*menu->append(new LLMenuItemCallGL("Reload settings/colors",
740 &handle_reload_settings, NULL, NULL));*/ 743 &handle_reload_settings, NULL, NULL));*/
741 menu->append(new LLMenuItemCallGL("Reload personal setting overrides", 744 menu->append(new LLMenuItemCallGL("Reload personal setting overrides",
@@ -893,7 +896,7 @@ void init_client_menu(LLMenuGL* menu)
893 (void*)"LimitSelectDistance")); 896 (void*)"LimitSelectDistance"));
894 897
895 menu->append(new LLMenuItemToggleGL("Disable Camera Constraints", 898 menu->append(new LLMenuItemToggleGL("Disable Camera Constraints",
896 &LLViewerCamera::sDisableCameraConstraints)); 899 &LLViewerCamera::sDisableCameraConstraints, 'C', MASK_ALT | MASK_CONTROL ));
897 900
898 menu->append(new LLMenuItemCheckGL("Joystick Flycam", 901 menu->append(new LLMenuItemCheckGL("Joystick Flycam",
899 &handle_toggle_flycam,NULL,&check_flycam,NULL)); 902 &handle_toggle_flycam,NULL,&check_flycam,NULL));
@@ -980,6 +983,7 @@ extern BOOL gDebugClicks;
980extern BOOL gDebugWindowProc; 983extern BOOL gDebugWindowProc;
981extern BOOL gDebugTextEditorTips; 984extern BOOL gDebugTextEditorTips;
982extern BOOL gDebugSelectMgr; 985extern BOOL gDebugSelectMgr;
986extern BOOL gVectorizePerfTest;
983 987
984void init_debug_ui_menu(LLMenuGL* menu) 988void init_debug_ui_menu(LLMenuGL* menu)
985{ 989{
@@ -1094,39 +1098,39 @@ void init_debug_rendering_menu(LLMenuGL* menu)
1094 sub_menu->append(new LLMenuItemCheckGL("UI", 1098 sub_menu->append(new LLMenuItemCheckGL("UI",
1095 &LLPipeline::toggleRenderDebugFeature, NULL, 1099 &LLPipeline::toggleRenderDebugFeature, NULL,
1096 &LLPipeline::toggleRenderDebugFeatureControl, 1100 &LLPipeline::toggleRenderDebugFeatureControl,
1097 (void*)LLPipeline::RENDER_DEBUG_FEATURE_UI, '1', MASK_ALT|MASK_CONTROL)); 1101 (void*)LLPipeline::RENDER_DEBUG_FEATURE_UI, KEY_F1, MASK_ALT|MASK_CONTROL));
1098 sub_menu->append(new LLMenuItemCheckGL("Selected", 1102 sub_menu->append(new LLMenuItemCheckGL("Selected",
1099 &LLPipeline::toggleRenderDebugFeature, NULL, 1103 &LLPipeline::toggleRenderDebugFeature, NULL,
1100 &LLPipeline::toggleRenderDebugFeatureControl, 1104 &LLPipeline::toggleRenderDebugFeatureControl,
1101 (void*)LLPipeline::RENDER_DEBUG_FEATURE_SELECTED, '2', MASK_ALT|MASK_CONTROL)); 1105 (void*)LLPipeline::RENDER_DEBUG_FEATURE_SELECTED, KEY_F2, MASK_ALT|MASK_CONTROL));
1102 sub_menu->append(new LLMenuItemCheckGL("Highlighted", 1106 sub_menu->append(new LLMenuItemCheckGL("Highlighted",
1103 &LLPipeline::toggleRenderDebugFeature, NULL, 1107 &LLPipeline::toggleRenderDebugFeature, NULL,
1104 &LLPipeline::toggleRenderDebugFeatureControl, 1108 &LLPipeline::toggleRenderDebugFeatureControl,
1105 (void*)LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED, '3', MASK_ALT|MASK_CONTROL)); 1109 (void*)LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED, KEY_F3, MASK_ALT|MASK_CONTROL));
1106 sub_menu->append(new LLMenuItemCheckGL("Dynamic Textures", 1110 sub_menu->append(new LLMenuItemCheckGL("Dynamic Textures",
1107 &LLPipeline::toggleRenderDebugFeature, NULL, 1111 &LLPipeline::toggleRenderDebugFeature, NULL,
1108 &LLPipeline::toggleRenderDebugFeatureControl, 1112 &LLPipeline::toggleRenderDebugFeatureControl,
1109 (void*)LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES, '4', MASK_ALT|MASK_CONTROL)); 1113 (void*)LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES, KEY_F4, MASK_ALT|MASK_CONTROL));
1110 sub_menu->append(new LLMenuItemCheckGL( "Foot Shadows", 1114 sub_menu->append(new LLMenuItemCheckGL( "Foot Shadows",
1111 &LLPipeline::toggleRenderDebugFeature, NULL, 1115 &LLPipeline::toggleRenderDebugFeature, NULL,
1112 &LLPipeline::toggleRenderDebugFeatureControl, 1116 &LLPipeline::toggleRenderDebugFeatureControl,
1113 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS, '5', MASK_ALT|MASK_CONTROL)); 1117 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS, KEY_F5, MASK_ALT|MASK_CONTROL));
1114 sub_menu->append(new LLMenuItemCheckGL("Fog", 1118 sub_menu->append(new LLMenuItemCheckGL("Fog",
1115 &LLPipeline::toggleRenderDebugFeature, NULL, 1119 &LLPipeline::toggleRenderDebugFeature, NULL,
1116 &LLPipeline::toggleRenderDebugFeatureControl, 1120 &LLPipeline::toggleRenderDebugFeatureControl,
1117 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOG, '6', MASK_ALT|MASK_CONTROL)); 1121 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOG, KEY_F6, MASK_ALT|MASK_CONTROL));
1118 sub_menu->append(new LLMenuItemCheckGL("Palletized Textures", 1122 sub_menu->append(new LLMenuItemCheckGL("Palletized Textures",
1119 &LLPipeline::toggleRenderDebugFeature, NULL, 1123 &LLPipeline::toggleRenderDebugFeature, NULL,
1120 &LLPipeline::toggleRenderDebugFeatureControl, 1124 &LLPipeline::toggleRenderDebugFeatureControl,
1121 (void*)LLPipeline::RENDER_DEBUG_FEATURE_PALETTE, '7', MASK_ALT|MASK_CONTROL)); 1125 (void*)LLPipeline::RENDER_DEBUG_FEATURE_PALETTE, KEY_F7, MASK_ALT|MASK_CONTROL));
1122 sub_menu->append(new LLMenuItemCheckGL("Test FRInfo", 1126 sub_menu->append(new LLMenuItemCheckGL("Test FRInfo",
1123 &LLPipeline::toggleRenderDebugFeature, NULL, 1127 &LLPipeline::toggleRenderDebugFeature, NULL,
1124 &LLPipeline::toggleRenderDebugFeatureControl, 1128 &LLPipeline::toggleRenderDebugFeatureControl,
1125 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO, '8', MASK_ALT|MASK_CONTROL)); 1129 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO, KEY_F8, MASK_ALT|MASK_CONTROL));
1126 sub_menu->append(new LLMenuItemCheckGL( "Flexible Objects", 1130 sub_menu->append(new LLMenuItemCheckGL( "Flexible Objects",
1127 &LLPipeline::toggleRenderDebugFeature, NULL, 1131 &LLPipeline::toggleRenderDebugFeature, NULL,
1128 &LLPipeline::toggleRenderDebugFeatureControl, 1132 &LLPipeline::toggleRenderDebugFeatureControl,
1129 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE, '9', MASK_ALT|MASK_CONTROL)); 1133 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE, KEY_F9, MASK_ALT|MASK_CONTROL));
1130 sub_menu->createJumpKeys(); 1134 sub_menu->createJumpKeys();
1131 1135
1132 ///////////////////////////// 1136 /////////////////////////////
@@ -1189,6 +1193,8 @@ void init_debug_rendering_menu(LLMenuGL* menu)
1189 (void*)"ShowDepthBuffer")); 1193 (void*)"ShowDepthBuffer"));
1190 sub_menu->append(new LLMenuItemToggleGL("Show Select Buffer", &gDebugSelect)); 1194 sub_menu->append(new LLMenuItemToggleGL("Show Select Buffer", &gDebugSelect));
1191 1195
1196 sub_menu->append(new LLMenuItemToggleGL("Vectorize Perf Test", &gVectorizePerfTest));
1197
1192 sub_menu = new LLMenuGL("Render Tests"); 1198 sub_menu = new LLMenuGL("Render Tests");
1193 1199
1194 sub_menu->append(new LLMenuItemCheckGL("Camera Offset", 1200 sub_menu->append(new LLMenuItemCheckGL("Camera Offset",
@@ -1296,7 +1302,7 @@ void init_debug_avatar_menu(LLMenuGL* menu)
1296 menu->append(new LLMenuItemToggleGL( "Display Agent Target", &LLAgent::sDebugDisplayTarget)); 1302 menu->append(new LLMenuItemToggleGL( "Display Agent Target", &LLAgent::sDebugDisplayTarget));
1297 menu->append(new LLMenuItemToggleGL( "Debug Rotation", &gDebugAvatarRotation)); 1303 menu->append(new LLMenuItemToggleGL( "Debug Rotation", &gDebugAvatarRotation));
1298 menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments)); 1304 menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments));
1299 menu->append(new LLMenuItemCallGL("Rebake Textures", handle_rebake_textures)); 1305 menu->append(new LLMenuItemCallGL("Rebake Textures", handle_rebake_textures, NULL, NULL, 'R', MASK_ALT | MASK_CONTROL ));
1300#ifndef LL_RELEASE_FOR_DOWNLOAD 1306#ifndef LL_RELEASE_FOR_DOWNLOAD
1301 menu->append(new LLMenuItemCallGL("Debug Avatar Textures", handle_debug_avatar_textures, NULL, NULL, 'A', MASK_SHIFT|MASK_CONTROL|MASK_ALT)); 1307 menu->append(new LLMenuItemCallGL("Debug Avatar Textures", handle_debug_avatar_textures, NULL, NULL, 'A', MASK_SHIFT|MASK_CONTROL|MASK_ALT));
1302 menu->append(new LLMenuItemCallGL("Dump Local Textures", handle_dump_avatar_local_textures, NULL, NULL, 'M', MASK_SHIFT|MASK_ALT )); 1308 menu->append(new LLMenuItemCallGL("Dump Local Textures", handle_dump_avatar_local_textures, NULL, NULL, 'M', MASK_SHIFT|MASK_ALT ));
@@ -2339,10 +2345,11 @@ void handle_buy_object(LLSaleInfo sale_info)
2339 return; 2345 return;
2340 } 2346 }
2341 2347
2342 if(sale_info.getSalePrice() > gStatusBar->getBalance()) 2348 S32 price = sale_info.getSalePrice();
2349
2350 if (price > 0 && price > gStatusBar->getBalance())
2343 { 2351 {
2344 LLFloaterBuyCurrency::buyCurrency( 2352 LLFloaterBuyCurrency::buyCurrency("This object costs", price);
2345 "This object costs", sale_info.getSalePrice());
2346 return; 2353 return;
2347 } 2354 }
2348 2355
@@ -2470,7 +2477,7 @@ void set_god_level(U8 god_level)
2470 U8 old_god_level = gAgent.getGodLevel(); 2477 U8 old_god_level = gAgent.getGodLevel();
2471 gAgent.setGodLevel( god_level ); 2478 gAgent.setGodLevel( god_level );
2472 show_debug_menus(); 2479 show_debug_menus();
2473 gIMView->refresh(); 2480 gIMMgr->refresh();
2474 gParcelMgr->notifyObservers(); 2481 gParcelMgr->notifyObservers();
2475 2482
2476 // Some classifieds change visibility on god mode 2483 // Some classifieds change visibility on god mode
@@ -2554,7 +2561,7 @@ void load_url_local_file(const char* file_name)
2554 gAgent.changeCameraToDefault(); 2561 gAgent.changeCameraToDefault();
2555 } 2562 }
2556 2563
2557#if LL_DARWIN || LL_LINUX 2564#if LL_DARWIN || LL_LINUX || LL_SOLARIS
2558 // MBW -- If the Mac client is in fullscreen mode, it needs to go windowed so the browser will be visible. 2565 // MBW -- If the Mac client is in fullscreen mode, it needs to go windowed so the browser will be visible.
2559 if(gViewerWindow->mWindow->getFullscreen()) 2566 if(gViewerWindow->mWindow->getFullscreen())
2560 { 2567 {
@@ -2673,7 +2680,7 @@ void request_friendship(const LLUUID& dest_id)
2673 } 2680 }
2674 if (!fullname.empty()) 2681 if (!fullname.empty())
2675 { 2682 {
2676 LLFloaterFriends::requestFriendship(dest_id, fullname); 2683 LLPanelFriends::requestFriendship(dest_id, fullname);
2677 LLNotifyBox::showXml("OfferedFriendship", args); 2684 LLNotifyBox::showXml("OfferedFriendship", args);
2678 } 2685 }
2679 else 2686 else
@@ -5371,7 +5378,7 @@ class LLShowFloater : public view_listener_t
5371 } 5378 }
5372 else if (floater_name == "friends") 5379 else if (floater_name == "friends")
5373 { 5380 {
5374 LLFloaterFriends::toggle(NULL); 5381 LLFloaterMyFriends::toggleInstance(0);
5375 } 5382 }
5376 else if (floater_name == "preferences") 5383 else if (floater_name == "preferences")
5377 { 5384 {
@@ -5383,11 +5390,11 @@ class LLShowFloater : public view_listener_t
5383 } 5390 }
5384 else if (floater_name == "chat history") 5391 else if (floater_name == "chat history")
5385 { 5392 {
5386 LLFloaterChat::toggle(NULL); 5393 LLFloaterChat::toggleInstance(LLSD());
5387 } 5394 }
5388 else if (floater_name == "im") 5395 else if (floater_name == "im")
5389 { 5396 {
5390 LLToolBar::onClickIM(NULL); 5397 LLFloaterChatterBox::toggleInstance(LLSD());
5391 } 5398 }
5392 else if (floater_name == "inventory") 5399 else if (floater_name == "inventory")
5393 { 5400 {
@@ -5496,6 +5503,10 @@ class LLShowFloater : public view_listener_t
5496 { 5503 {
5497 LLFloaterAbout::show(NULL); 5504 LLFloaterAbout::show(NULL);
5498 } 5505 }
5506 else if (floater_name == "active speakers")
5507 {
5508 LLFloaterActiveSpeakers::toggleInstance(LLSD());
5509 }
5499 return true; 5510 return true;
5500 } 5511 }
5501}; 5512};
@@ -5509,7 +5520,7 @@ class LLFloaterVisible : public view_listener_t
5509 bool new_value = false; 5520 bool new_value = false;
5510 if (floater_name == "friends") 5521 if (floater_name == "friends")
5511 { 5522 {
5512 new_value = LLFloaterFriends::visible(NULL); 5523 new_value = LLFloaterMyFriends::instanceVisible(0);
5513 } 5524 }
5514 else if (floater_name == "toolbar") 5525 else if (floater_name == "toolbar")
5515 { 5526 {
@@ -5521,7 +5532,7 @@ class LLFloaterVisible : public view_listener_t
5521 } 5532 }
5522 else if (floater_name == "im") 5533 else if (floater_name == "im")
5523 { 5534 {
5524 new_value = gIMView && gIMView->mTalkFloater && gIMView->mTalkFloater->getVisible(); 5535 new_value = LLFloaterMyFriends::instanceVisible(0);
5525 } 5536 }
5526 else if (floater_name == "mute list") 5537 else if (floater_name == "mute list")
5527 { 5538 {
@@ -5539,6 +5550,10 @@ class LLFloaterVisible : public view_listener_t
5539 { 5550 {
5540 new_value = gDebugView->mStatViewp->getVisible(); 5551 new_value = gDebugView->mStatViewp->getVisible();
5541 } 5552 }
5553 else if (floater_name == "active speakers")
5554 {
5555 new_value = LLFloaterActiveSpeakers::instanceVisible(LLSD());
5556 }
5542 gMenuHolder->findControl(control_name)->setValue(new_value); 5557 gMenuHolder->findControl(control_name)->setValue(new_value);
5543 return true; 5558 return true;
5544 } 5559 }
@@ -5655,19 +5670,7 @@ class LLShowAgentGroups : public view_listener_t
5655{ 5670{
5656 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 5671 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5657 { 5672 {
5658 LLUUID agent_id; 5673 LLFloaterMyFriends::toggleInstance(1);
5659 if (userdata.asString() == "agent")
5660 {
5661 agent_id = gAgent.getID();
5662 }
5663 else
5664 {
5665 agent_id = userdata.asUUID();
5666 }
5667 if(agent_id.notNull())
5668 {
5669 LLFloaterGroups::show(agent_id, LLFloaterGroups::AGENT_GROUPS);
5670 }
5671 return true; 5674 return true;
5672 } 5675 }
5673}; 5676};
@@ -6167,10 +6170,10 @@ class LLAvatarSendIM : public view_listener_t
6167 name.append( last->getString() ); 6170 name.append( last->getString() );
6168 } 6171 }
6169 6172
6170 gIMView->setFloaterOpen(TRUE); 6173 gIMMgr->setFloaterOpen(TRUE);
6171 //EInstantMessage type = have_agent_callingcard(gLastHitObjectID) 6174 //EInstantMessage type = have_agent_callingcard(gLastHitObjectID)
6172 // ? IM_SESSION_ADD : IM_SESSION_CARDLESS_START; 6175 // ? IM_SESSION_ADD : IM_SESSION_CARDLESS_START;
6173 gIMView->addSession(name, 6176 gIMMgr->addSession(name,
6174 IM_NOTHING_SPECIAL, 6177 IM_NOTHING_SPECIAL,
6175 avatar->getID()); 6178 avatar->getID());
6176 } 6179 }
@@ -7316,22 +7319,66 @@ class LLViewToggleBeacon : public view_listener_t
7316 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 7319 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7317 { 7320 {
7318 LLString beacon = userdata.asString(); 7321 LLString beacon = userdata.asString();
7319 if (beacon == "scripts") 7322 if (beacon == "scriptsbeacon")
7320 { 7323 {
7321 LLPipeline::toggleRenderScriptedBeacons(NULL); 7324 LLPipeline::toggleRenderScriptedBeacons(NULL);
7325 gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons(NULL) );
7326 // toggle the other one off if it's on
7327 if (LLPipeline::getRenderScriptedBeacons(NULL) && LLPipeline::getRenderScriptedTouchBeacons(NULL))
7328 {
7329 LLPipeline::toggleRenderScriptedTouchBeacons(NULL);
7330 gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons(NULL) );
7331 }
7322 } 7332 }
7323 else if (beacon == "physical") 7333 else if (beacon == "physicalbeacon")
7324 { 7334 {
7325 LLPipeline::toggleRenderPhysicalBeacons(NULL); 7335 LLPipeline::toggleRenderPhysicalBeacons(NULL);
7336 gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons(NULL) );
7326 } 7337 }
7327 else if (beacon == "sounds") 7338 else if (beacon == "soundsbeacon")
7328 { 7339 {
7329 LLPipeline::toggleRenderSoundBeacons(NULL); 7340 LLPipeline::toggleRenderSoundBeacons(NULL);
7341 gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons(NULL) );
7330 } 7342 }
7331 else if (beacon == "particles") 7343 else if (beacon == "particlesbeacon")
7332 { 7344 {
7333 LLPipeline::toggleRenderParticleBeacons(NULL); 7345 LLPipeline::toggleRenderParticleBeacons(NULL);
7346 gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons(NULL) );
7334 } 7347 }
7348 else if (beacon == "scripttouchbeacon")
7349 {
7350 LLPipeline::toggleRenderScriptedTouchBeacons(NULL);
7351 gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons(NULL) );
7352 // toggle the other one off if it's on
7353 if (LLPipeline::getRenderScriptedBeacons(NULL) && LLPipeline::getRenderScriptedTouchBeacons(NULL))
7354 {
7355 LLPipeline::toggleRenderScriptedBeacons(NULL);
7356 gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons(NULL) );
7357 }
7358 }
7359 else if (beacon == "renderbeacons")
7360 {
7361 LLPipeline::toggleRenderBeacons(NULL);
7362 gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons(NULL) );
7363 // toggle the other one on if it's not
7364 if (!LLPipeline::getRenderBeacons(NULL) && !LLPipeline::getRenderHighlights(NULL))
7365 {
7366 LLPipeline::toggleRenderHighlights(NULL);
7367 gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights(NULL) );
7368 }
7369 }
7370 else if (beacon == "renderhighlights")
7371 {
7372 LLPipeline::toggleRenderHighlights(NULL);
7373 gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights(NULL) );
7374 // toggle the other one on if it's not
7375 if (!LLPipeline::getRenderBeacons(NULL) && !LLPipeline::getRenderHighlights(NULL))
7376 {
7377 LLPipeline::toggleRenderBeacons(NULL);
7378 gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons(NULL) );
7379 }
7380 }
7381
7335 return true; 7382 return true;
7336 } 7383 }
7337}; 7384};
@@ -7342,21 +7389,40 @@ class LLViewCheckBeaconEnabled : public view_listener_t
7342 { 7389 {
7343 LLString beacon = userdata["data"].asString(); 7390 LLString beacon = userdata["data"].asString();
7344 bool new_value = false; 7391 bool new_value = false;
7345 if (beacon == "scripts") 7392 if (beacon == "scriptsbeacon")
7393 {
7394 new_value = gSavedSettings.getBOOL( "scriptsbeacon");
7395 LLPipeline::setRenderScriptedBeacons(new_value);
7396 }
7397 else if (beacon == "physicalbeacon")
7398 {
7399 new_value = gSavedSettings.getBOOL( "physicalbeacon");
7400 LLPipeline::setRenderPhysicalBeacons(new_value);
7401 }
7402 else if (beacon == "soundsbeacon")
7403 {
7404 new_value = gSavedSettings.getBOOL( "soundsbeacon");
7405 LLPipeline::setRenderSoundBeacons(new_value);
7406 }
7407 else if (beacon == "particlesbeacon")
7346 { 7408 {
7347 new_value = LLPipeline::getRenderScriptedBeacons(NULL); 7409 new_value = gSavedSettings.getBOOL( "particlesbeacon");
7410 LLPipeline::setRenderParticleBeacons(new_value);
7348 } 7411 }
7349 else if (beacon == "physical") 7412 else if (beacon == "scripttouchbeacon")
7350 { 7413 {
7351 new_value = LLPipeline::getRenderPhysicalBeacons(NULL); 7414 new_value = gSavedSettings.getBOOL( "scripttouchbeacon");
7415 LLPipeline::setRenderScriptedTouchBeacons(new_value);
7352 } 7416 }
7353 else if (beacon == "sounds") 7417 else if (beacon == "renderbeacons")
7354 { 7418 {
7355 new_value = LLPipeline::getRenderSoundBeacons(NULL); 7419 new_value = gSavedSettings.getBOOL( "renderbeacons");
7420 LLPipeline::setRenderBeacons(new_value);
7356 } 7421 }
7357 else if (beacon == "particles") 7422 else if (beacon == "renderhighlights")
7358 { 7423 {
7359 new_value = LLPipeline::getRenderParticleBeacons(NULL); 7424 new_value = gSavedSettings.getBOOL( "renderhighlights");
7425 LLPipeline::setRenderHighlights(new_value);
7360 } 7426 }
7361 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); 7427 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7362 return true; 7428 return true;
@@ -7384,7 +7450,7 @@ class LLViewCheckRenderType : public view_listener_t
7384 bool new_value = false; 7450 bool new_value = false;
7385 if (type == "particles") 7451 if (type == "particles")
7386 { 7452 {
7387 new_value = LLPipeline::toggleRenderTypeControlNegated((void *)(S32)LLPipeline::RENDER_TYPE_PARTICLES); 7453 new_value = LLPipeline::toggleRenderTypeControlNegated((void *)LLPipeline::RENDER_TYPE_PARTICLES);
7388 } 7454 }
7389 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); 7455 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7390 return true; 7456 return true;
diff --git a/linden/indra/newview/llviewermenufile.cpp b/linden/indra/newview/llviewermenufile.cpp
index d0b8c73..4d46a8f 100644
--- a/linden/indra/newview/llviewermenufile.cpp
+++ b/linden/indra/newview/llviewermenufile.cpp
@@ -222,7 +222,7 @@ class LLFileUploadImage : public view_listener_t
222{ 222{
223 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 223 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
224 { 224 {
225 const char* filename = upload_pick((void *)(S32)LLFilePicker::FFLOAD_IMAGE); 225 const char* filename = upload_pick((void *)LLFilePicker::FFLOAD_IMAGE);
226 if (filename) 226 if (filename)
227 { 227 {
228 LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename); 228 LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename);
@@ -236,7 +236,7 @@ class LLFileUploadSound : public view_listener_t
236{ 236{
237 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 237 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
238 { 238 {
239 const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_WAV)); 239 const char* filename = upload_pick((void*)LLFilePicker::FFLOAD_WAV);
240 if (filename) 240 if (filename)
241 { 241 {
242 LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename); 242 LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
@@ -250,7 +250,7 @@ class LLFileUploadAnim : public view_listener_t
250{ 250{
251 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 251 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
252 { 252 {
253 const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_ANIM)); 253 const char* filename = upload_pick((void*)LLFilePicker::FFLOAD_ANIM);
254 if (filename) 254 if (filename)
255 { 255 {
256 LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename); 256 LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename);
@@ -691,7 +691,10 @@ void upload_new_resource(const LLString& src_filename, std::string name,
691 S16 type_num; 691 S16 type_num;
692 692
693 // read in and throw out most of the header except for the type 693 // read in and throw out most of the header except for the type
694 fread(buf, header_size, 1, in); 694 if (fread(buf, header_size, 1, in) != 1)
695 {
696 llwarns << "Short read" << llendl;
697 }
695 memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */ 698 memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */
696 asset_type = (LLAssetType::EType)type_num; 699 asset_type = (LLAssetType::EType)type_num;
697 } 700 }
@@ -702,7 +705,10 @@ void upload_new_resource(const LLString& src_filename, std::string name,
702 { 705 {
703 while((read = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */ 706 while((read = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
704 { 707 {
705 fwrite(buf, 1, read, out); /* Flawfinder: ignore */ 708 if (fwrite(buf, 1, read, out) != read)
709 {
710 llwarns << "Short write" << llendl;
711 }
706 } 712 }
707 fclose(out); 713 fclose(out);
708 } 714 }
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index d45cf34..6bca17e 100644
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -63,6 +63,7 @@
63#include "message.h" 63#include "message.h"
64#include "sound_ids.h" 64#include "sound_ids.h"
65#include "lltimer.h" 65#include "lltimer.h"
66#include "llmd5.h"
66 67
67#include "llagent.h" 68#include "llagent.h"
68#include "llcallingcard.h" 69#include "llcallingcard.h"
@@ -70,6 +71,7 @@
70#include "llviewercontrol.h" 71#include "llviewercontrol.h"
71#include "lldrawpool.h" 72#include "lldrawpool.h"
72#include "llfirstuse.h" 73#include "llfirstuse.h"
74#include "llfloateractivespeakers.h"
73#include "llfloaterbuycurrency.h" 75#include "llfloaterbuycurrency.h"
74#include "llfloaterbuyland.h" 76#include "llfloaterbuyland.h"
75#include "llfloaterchat.h" 77#include "llfloaterchat.h"
@@ -341,10 +343,15 @@ void export_complete()
341 343
342 FILE* fXML = LLFile::fopen(gExportedFile.c_str(), "rb"); /* Flawfinder: ignore */ 344 FILE* fXML = LLFile::fopen(gExportedFile.c_str(), "rb"); /* Flawfinder: ignore */
343 fseek(fXML, 0, SEEK_END); 345 fseek(fXML, 0, SEEK_END);
344 U32 length = ftell(fXML); 346 long length = ftell(fXML);
345 fseek(fXML, 0, SEEK_SET); 347 fseek(fXML, 0, SEEK_SET);
346 U8 *buffer = new U8[length]; 348 U8 *buffer = new U8[length + 1];
347 fread(buffer, 1, length, fXML); 349 size_t nread = fread(buffer, 1, length, fXML);
350 if (nread < (size_t) length)
351 {
352 llwarns << "Short read" << llendl;
353 }
354 buffer[nread] = '\0';
348 fclose(fXML); 355 fclose(fXML);
349 356
350 char *pos = (char *)buffer; 357 char *pos = (char *)buffer;
@@ -380,7 +387,10 @@ void export_complete()
380 } 387 }
381 388
382 FILE* fXMLOut = LLFile::fopen(gExportedFile.c_str(), "wb"); /* Flawfinder: ignore */ 389 FILE* fXMLOut = LLFile::fopen(gExportedFile.c_str(), "wb"); /* Flawfinder: ignore */
383 fwrite(buffer, 1, length, fXMLOut); 390 if (fwrite(buffer, 1, length, fXMLOut) != length)
391 {
392 llwarns << "Short write" << llendl;
393 }
384 fclose(fXMLOut); 394 fclose(fXMLOut);
385 395
386 delete [] buffer; 396 delete [] buffer;
@@ -442,7 +452,10 @@ void exported_j2c_complete(const LLTSCode status, void *user_data)
442 S32 length = ftell(fIn); 452 S32 length = ftell(fIn);
443 fseek(fIn, 0, SEEK_SET); 453 fseek(fIn, 0, SEEK_SET);
444 U8 *buffer = ImageUtility->allocateData(length); 454 U8 *buffer = ImageUtility->allocateData(length);
445 fread(buffer, 1, length, fIn); 455 if (fread(buffer, 1, length, fIn) != length)
456 {
457 llwarns << "Short read" << llendl;
458 }
446 fclose(fIn); 459 fclose(fIn);
447 LLFile::remove(filename.c_str()); 460 LLFile::remove(filename.c_str());
448 461
@@ -469,7 +482,10 @@ void exported_j2c_complete(const LLTSCode status, void *user_data)
469 strcpy(md5_hash_string, "00000000000000000000000000000000"); /* Flawfinder: ignore */ 482 strcpy(md5_hash_string, "00000000000000000000000000000000"); /* Flawfinder: ignore */
470 if (fOut) 483 if (fOut)
471 { 484 {
472 fwrite(data, 1, data_size, fOut); 485 if (fwrite(data, 1, data_size, fOut) != data_size)
486 {
487 llwarns << "Short write" << llendl;
488 }
473 fseek(fOut, 0, SEEK_SET); 489 fseek(fOut, 0, SEEK_SET);
474 fclose(fOut); 490 fclose(fOut);
475 fOut = LLFile::fopen(output_file.c_str(), "rb"); /* Flawfinder: ignore */ 491 fOut = LLFile::fopen(output_file.c_str(), "rb"); /* Flawfinder: ignore */
@@ -1322,7 +1338,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1322 time_t timestamp = (time_t)t; 1338 time_t timestamp = (time_t)t;
1323 1339
1324 BOOL is_busy = gAgent.getBusy(); 1340 BOOL is_busy = gAgent.getBusy();
1325 BOOL is_muted = gMuteListp->isMuted(from_id, name); 1341 BOOL is_muted = gMuteListp->isMuted(from_id, name, LLMute::flagTextChat);
1326 BOOL is_linden = gMuteListp->isLinden(name); 1342 BOOL is_linden = gMuteListp->isLinden(name);
1327 BOOL is_owned_by_me = FALSE; 1343 BOOL is_owned_by_me = FALSE;
1328 1344
@@ -1373,7 +1389,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1373 { 1389 {
1374 // return a standard "busy" message, but only do it to online IM 1390 // return a standard "busy" message, but only do it to online IM
1375 // (i.e. not other auto responses and not store-and-forward IM) 1391 // (i.e. not other auto responses and not store-and-forward IM)
1376 if (!gIMView->hasSession(session_id)) 1392 if (!gIMMgr->hasSession(session_id))
1377 { 1393 {
1378 // if there is not a panel for this conversation (i.e. it is a new IM conversation 1394 // if there is not a panel for this conversation (i.e. it is a new IM conversation
1379 // initiated by the other party) then... 1395 // initiated by the other party) then...
@@ -1398,14 +1414,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1398 1414
1399 snprintf(buffer, sizeof(buffer), "%s%s%s", name, separator_string, (message+message_offset)); /* Flawfinder: ignore */ 1415 snprintf(buffer, sizeof(buffer), "%s%s%s", name, separator_string, (message+message_offset)); /* Flawfinder: ignore */
1400 1416
1401 if(from_id == gAgentID)
1402 {
1403 from_id = LLUUID::null;
1404 }
1405 llinfos << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << llendl; 1417 llinfos << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << llendl;
1406 1418
1407 // add to IM panel, but do not bother the user 1419 // add to IM panel, but do not bother the user
1408 gIMView->addMessage( 1420 gIMMgr->addMessage(
1409 session_id, 1421 session_id,
1410 from_id, 1422 from_id,
1411 name, 1423 name,
@@ -1455,15 +1467,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1455 formatted_time(timestamp, time_buf)); 1467 formatted_time(timestamp, time_buf));
1456 } 1468 }
1457 snprintf(buffer, sizeof(buffer), "%s%s%s%s", name, separator_string, saved,(message+message_offset)); /* Flawfinder: ignore */ 1469 snprintf(buffer, sizeof(buffer), "%s%s%s%s", name, separator_string, saved,(message+message_offset)); /* Flawfinder: ignore */
1458 if(from_id == gAgentID) 1470
1459 {
1460 from_id = LLUUID::null;
1461 }
1462 llinfos << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << llendl; 1471 llinfos << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << llendl;
1463 1472
1464 if (!is_muted || is_linden) 1473 if (!is_muted || is_linden)
1465 { 1474 {
1466 gIMView->addMessage( 1475 gIMMgr->addMessage(
1467 session_id, 1476 session_id,
1468 from_id, 1477 from_id,
1469 name, 1478 name,
@@ -1494,14 +1503,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1494 case IM_TYPING_START: 1503 case IM_TYPING_START:
1495 { 1504 {
1496 LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem); 1505 LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
1497 gIMView->processIMTypingStart(im_info); 1506 gIMMgr->processIMTypingStart(im_info);
1498 } 1507 }
1499 break; 1508 break;
1500 1509
1501 case IM_TYPING_STOP: 1510 case IM_TYPING_STOP:
1502 { 1511 {
1503 LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem); 1512 LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
1504 gIMView->processIMTypingStop(im_info); 1513 gIMMgr->processIMTypingStop(im_info);
1505 } 1514 }
1506 break; 1515 break;
1507 1516
@@ -1734,12 +1743,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1734 return; 1743 return;
1735 } 1744 }
1736 1745
1737 // System messages, specifically "Foo Bar has left this session" 1746 // Only show messages if we have a session open (which
1738 // are not shown unless you actually have that session open. 1747 // should happen after you get an "invitation"
1739 // Band-aid. JC 1748 if ( !gIMMgr->hasSession(session_id) )
1740 if (offline == IM_ONLINE
1741 && chat.mFromName == SYSTEM_FROM
1742 && !gIMView->hasSession(session_id))
1743 { 1749 {
1744 return; 1750 return;
1745 } 1751 }
@@ -1759,10 +1765,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1759 BOOL is_this_agent = FALSE; 1765 BOOL is_this_agent = FALSE;
1760 if(from_id == gAgentID) 1766 if(from_id == gAgentID)
1761 { 1767 {
1762 from_id = LLUUID::null;
1763 is_this_agent = TRUE; 1768 is_this_agent = TRUE;
1764 } 1769 }
1765 gIMView->addMessage( 1770 gIMMgr->addMessage(
1766 session_id, 1771 session_id,
1767 from_id, 1772 from_id,
1768 name, 1773 name,
@@ -1813,7 +1818,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1813 else 1818 else
1814 { 1819 {
1815 // original code resumes 1820 // original code resumes
1816 gIMView->addMessage(session_id, from_id, name, message); 1821 gIMMgr->addMessage(session_id, from_id, name, message);
1817 } 1822 }
1818 break; 1823 break;
1819 1824
@@ -2079,7 +2084,7 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
2079 if(!source_name.empty()) 2084 if(!source_name.empty())
2080 { 2085 {
2081 if (gAgent.getBusy() 2086 if (gAgent.getBusy()
2082 || gMuteListp->isMuted(source_id, source_name)) 2087 || gMuteListp->isMuted(source_id, source_name, LLMute::flagTextChat))
2083 { 2088 {
2084 // automatically decline offer 2089 // automatically decline offer
2085 callingcard_offer_callback(1, (void*)offerdata); 2090 callingcard_offer_callback(1, (void*)offerdata);
@@ -2155,7 +2160,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2155 BOOL is_linden = FALSE; 2160 BOOL is_linden = FALSE;
2156 if (gMuteListp) 2161 if (gMuteListp)
2157 { 2162 {
2158 is_muted = gMuteListp->isMuted(from_id, from_name) 2163 is_muted = gMuteListp->isMuted(from_id, from_name, LLMute::flagTextChat)
2159 || gMuteListp->isMuted(owner_id); 2164 || gMuteListp->isMuted(owner_id);
2160 is_linden = gMuteListp->isLinden(from_name); 2165 is_linden = gMuteListp->isLinden(from_name);
2161 } 2166 }
@@ -2179,16 +2184,15 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2179 gWorldPointer->mPartSim.addPartSource(psc); 2184 gWorldPointer->mPartSim.addPartSource(psc);
2180 } 2185 }
2181 2186
2182 // only pay attention to other people chatting 2187 // record last audible utterance
2183 if (is_audible 2188 if (is_audible
2184 && (is_linden || (!is_muted && !is_busy)) 2189 && (is_linden || (!is_muted && !is_busy)))
2185 && chatter != gAgent.getAvatarObject())
2186 { 2190 {
2187 gAgent.heardChat(chat); 2191 if (chat.mChatType != CHAT_TYPE_START
2188 if (ll_rand(2) == 0) 2192 && chat.mChatType != CHAT_TYPE_STOP)
2189 { 2193 {
2190 gAgent.setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero); 2194 gAgent.heardChat(chat.mFromID);
2191 } 2195 }
2192 } 2196 }
2193 2197
2194 is_owned_by_me = chatter->permYouOwner(); 2198 is_owned_by_me = chatter->permYouOwner();
@@ -2219,6 +2223,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2219 // Look for the start of typing so we can put "..." in the bubbles. 2223 // Look for the start of typing so we can put "..." in the bubbles.
2220 if (CHAT_TYPE_START == chat.mChatType) 2224 if (CHAT_TYPE_START == chat.mChatType)
2221 { 2225 {
2226 gLocalSpeakerMgr->setSpeakerTyping(from_id, TRUE);
2227
2222 // Might not have the avatar constructed yet, eg on login. 2228 // Might not have the avatar constructed yet, eg on login.
2223 if (chatter && chatter->isAvatar()) 2229 if (chatter && chatter->isAvatar())
2224 { 2230 {
@@ -2228,6 +2234,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2228 } 2234 }
2229 else if (CHAT_TYPE_STOP == chat.mChatType) 2235 else if (CHAT_TYPE_STOP == chat.mChatType)
2230 { 2236 {
2237 gLocalSpeakerMgr->setSpeakerTyping(from_id, FALSE);
2238
2231 // Might not have the avatar constructed yet, eg on login. 2239 // Might not have the avatar constructed yet, eg on login.
2232 if (chatter && chatter->isAvatar()) 2240 if (chatter && chatter->isAvatar())
2233 { 2241 {
@@ -2239,6 +2247,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2239 // We have a real utterance now, so can stop showing "..." and proceed. 2247 // We have a real utterance now, so can stop showing "..." and proceed.
2240 if (chatter && chatter->isAvatar()) 2248 if (chatter && chatter->isAvatar())
2241 { 2249 {
2250 gLocalSpeakerMgr->setSpeakerTyping(from_id, FALSE);
2242 ((LLVOAvatar*)chatter)->stopTyping(); 2251 ((LLVOAvatar*)chatter)->stopTyping();
2243 2252
2244 if (!is_muted && !is_busy) 2253 if (!is_muted && !is_busy)
@@ -2367,7 +2376,7 @@ void process_teleport_start(LLMessageSystem *msg, void**)
2367 gTeleportDisplay = TRUE; 2376 gTeleportDisplay = TRUE;
2368 gAgent.setTeleportState( LLAgent::TELEPORT_START ); 2377 gAgent.setTeleportState( LLAgent::TELEPORT_START );
2369 make_ui_sound("UISndTeleportOut"); 2378 make_ui_sound("UISndTeleportOut");
2370 2379
2371 // Don't call LLFirstUse::useTeleport here because this could be 2380 // Don't call LLFirstUse::useTeleport here because this could be
2372 // due to being killed, which would send you home, not to a Telehub 2381 // due to being killed, which would send you home, not to a Telehub
2373 } 2382 }
@@ -2748,7 +2757,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
2748 { 2757 {
2749 avatarp->mFootPlane.clearVec(); 2758 avatarp->mFootPlane.clearVec();
2750 } 2759 }
2751 2760
2752 // reset always run status 2761 // reset always run status
2753 msg->newMessageFast(_PREHASH_SetAlwaysRun); 2762 msg->newMessageFast(_PREHASH_SetAlwaysRun);
2754 msg->nextBlockFast(_PREHASH_AgentData); 2763 msg->nextBlockFast(_PREHASH_AgentData);
@@ -3212,7 +3221,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
3212 if (!gParcelMgr->canHearSound(pos_global)) return; 3221 if (!gParcelMgr->canHearSound(pos_global)) return;
3213 3222
3214 // Don't play sounds triggered by someone you muted. 3223 // Don't play sounds triggered by someone you muted.
3215 if (gMuteListp->isMuted(owner_id)) return; 3224 if (gMuteListp->isMuted(owner_id, LLMute::flagObjectSounds)) return;
3216 3225
3217 // Don't play sounds from an object you muted 3226 // Don't play sounds from an object you muted
3218 if (gMuteListp->isMuted(object_id)) return; 3227 if (gMuteListp->isMuted(object_id)) return;
@@ -3224,7 +3233,8 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
3224 return; 3233 return;
3225 } 3234 }
3226 3235
3227 gAudiop->triggerSound(sound_id, owner_id, gain, pos_global); 3236 F32 volume = gain * gSavedSettings.getF32("AudioLevelSFX");
3237 gAudiop->triggerSound(sound_id, owner_id, volume, pos_global);
3228} 3238}
3229 3239
3230void process_preload_sound(LLMessageSystem *msg, void **user_data) 3240void process_preload_sound(LLMessageSystem *msg, void **user_data)
@@ -3246,7 +3256,7 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data)
3246 if (!objectp) return; 3256 if (!objectp) return;
3247 3257
3248 if (gMuteListp->isMuted(object_id)) return; 3258 if (gMuteListp->isMuted(object_id)) return;
3249 if (gMuteListp->isMuted(owner_id)) return; 3259 if (gMuteListp->isMuted(owner_id, LLMute::flagObjectSounds)) return;
3250 3260
3251 LLAudioSource *sourcep = objectp->getAudioSource(owner_id); 3261 LLAudioSource *sourcep = objectp->getAudioSource(owner_id);
3252 if (!sourcep) return; 3262 if (!sourcep) return;
@@ -3284,7 +3294,7 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data)
3284 3294
3285 if (gMuteListp->isMuted(object_id)) return; 3295 if (gMuteListp->isMuted(object_id)) return;
3286 3296
3287 if (gMuteListp->isMuted(owner_id)) return; 3297 if (gMuteListp->isMuted(owner_id, LLMute::flagObjectSounds)) return;
3288 3298
3289 objectp->setAttachedSound(sound_id, owner_id, gain, flags); 3299 objectp->setAttachedSound(sound_id, owner_id, gain, flags);
3290} 3300}
diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp
index d237614..f8095b8 100644
--- a/linden/indra/newview/llviewerobject.cpp
+++ b/linden/indra/newview/llviewerobject.cpp
@@ -176,6 +176,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
176 mLatestRecvPacketID(0), 176 mLatestRecvPacketID(0),
177 mData(NULL), 177 mData(NULL),
178 mAudioSourcep(NULL), 178 mAudioSourcep(NULL),
179 mAudioGain(1.f),
179 mAppAngle(0.f), 180 mAppAngle(0.f),
180 mPixelArea(1024.f), 181 mPixelArea(1024.f),
181 mInventory(NULL), 182 mInventory(NULL),
@@ -2717,6 +2718,12 @@ void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)
2717 2718
2718BOOL LLViewerObject::updateLOD() 2719BOOL LLViewerObject::updateLOD()
2719{ 2720{
2721 // Update volume of looping sounds
2722 if (mAudioSourcep && mAudioSourcep->isLoop())
2723 {
2724 F32 volume = mAudioGain * gSavedSettings.getF32("AudioLevelSFX");
2725 mAudioSourcep->setGain(volume);
2726 }
2720 return FALSE; 2727 return FALSE;
2721} 2728}
2722 2729
@@ -4057,7 +4064,7 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own
4057 { 4064 {
4058 LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num); 4065 LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num);
4059 //If the owner is muted, don't create the system 4066 //If the owner is muted, don't create the system
4060 if(gMuteListp->isMuted(owner_id)) return; 4067 if(gMuteListp->isMuted(owner_id, LLMute::flagParticles)) return;
4061 4068
4062 // We need to be able to deal with a particle source that hasn't changed, but still got an update! 4069 // We need to be able to deal with a particle source that hasn't changed, but still got an update!
4063 if (pss) 4070 if (pss)
@@ -4106,7 +4113,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_
4106 { 4113 {
4107 LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp); 4114 LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp);
4108 //If the owner is muted, don't create the system 4115 //If the owner is muted, don't create the system
4109 if(gMuteListp->isMuted(owner_id)) return; 4116 if(gMuteListp->isMuted(owner_id, LLMute::flagParticles)) return;
4110 // We need to be able to deal with a particle source that hasn't changed, but still got an update! 4117 // We need to be able to deal with a particle source that hasn't changed, but still got an update!
4111 if (pss) 4118 if (pss)
4112 { 4119 {
@@ -4224,7 +4231,9 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
4224 if (mAudioSourcep) 4231 if (mAudioSourcep)
4225 { 4232 {
4226 BOOL queue = flags & LL_SOUND_FLAG_QUEUE; 4233 BOOL queue = flags & LL_SOUND_FLAG_QUEUE;
4227 mAudioSourcep->setGain(gain); 4234 mAudioGain = gain;
4235 F32 volume = gain * gSavedSettings.getF32("AudioLevelSFX");
4236 mAudioSourcep->setGain(volume);
4228 mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP); 4237 mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP);
4229 mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER); 4238 mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER);
4230 mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE); 4239 mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE);
@@ -4259,12 +4268,12 @@ void LLViewerObject::adjustAudioGain(const F32 gain)
4259 { 4268 {
4260 return; 4269 return;
4261 } 4270 }
4262 4271 if (mAudioSourcep)
4263 if (!mAudioSourcep)
4264 { 4272 {
4265 return; 4273 mAudioGain = gain;
4274 F32 volume = mAudioGain * gSavedSettings.getF32("AudioLevelSFX");
4275 mAudioSourcep->setGain(volume);
4266 } 4276 }
4267 mAudioSourcep->setGain(gain);
4268} 4277}
4269 4278
4270//---------------------------------------------------------------------------- 4279//----------------------------------------------------------------------------
diff --git a/linden/indra/newview/llviewerobject.h b/linden/indra/newview/llviewerobject.h
index 2e92672..fcb246c 100644
--- a/linden/indra/newview/llviewerobject.h
+++ b/linden/indra/newview/llviewerobject.h
@@ -564,8 +564,9 @@ protected:
564 U8* mData; 564 U8* mData;
565 565
566 LLPointer<LLViewerPartSourceScript> mPartSourcep; // Particle source associated with this object. 566 LLPointer<LLViewerPartSourceScript> mPartSourcep; // Particle source associated with this object.
567 LLAudioSourceVO *mAudioSourcep; 567 LLAudioSourceVO* mAudioSourcep;
568 568 F32 mAudioGain;
569
569 F32 mAppAngle; // Apparent visual arc in degrees 570 F32 mAppAngle; // Apparent visual arc in degrees
570 F32 mPixelArea; // Apparent area in pixels 571 F32 mPixelArea; // Apparent area in pixels
571 572
diff --git a/linden/indra/newview/llviewerobjectlist.cpp b/linden/indra/newview/llviewerobjectlist.cpp
index 44aa5c7..9f008a4 100644
--- a/linden/indra/newview/llviewerobjectlist.cpp
+++ b/linden/indra/newview/llviewerobjectlist.cpp
@@ -61,7 +61,11 @@
61#include "u64.h" 61#include "u64.h"
62#include "llviewerimagelist.h" 62#include "llviewerimagelist.h"
63#include "lldatapacker.h" 63#include "lldatapacker.h"
64#include <zlib/zlib.h> 64#ifdef LL_STANDALONE
65#include <zlib.h>
66#else
67#include "zlib/zlib.h"
68#endif
65#include "object_flags.h" 69#include "object_flags.h"
66 70
67extern BOOL gVelocityInterpolate; 71extern BOOL gVelocityInterpolate;
diff --git a/linden/indra/newview/llviewerparcelmgr.cpp b/linden/indra/newview/llviewerparcelmgr.cpp
index ac56681..31c7d97 100644
--- a/linden/indra/newview/llviewerparcelmgr.cpp
+++ b/linden/indra/newview/llviewerparcelmgr.cpp
@@ -180,8 +180,7 @@ LLViewerParcelMgr::~LLViewerParcelMgr()
180 delete[] mCollisionSegments; 180 delete[] mCollisionSegments;
181 mCollisionSegments = NULL; 181 mCollisionSegments = NULL;
182 182
183 // weird, this crashes if I use an array delete on it! 183 delete[] sPackedOverlay;
184 delete sPackedOverlay;
185 sPackedOverlay = NULL; 184 sPackedOverlay = NULL;
186 185
187 delete[] mAgentParcelOverlay; 186 delete[] mAgentParcelOverlay;
@@ -1793,13 +1792,10 @@ void optionally_start_music(const LLString& music_url)
1793 1792
1794 // now only play music when you enter a new parcel if the control is in PLAY state 1793 // now only play music when you enter a new parcel if the control is in PLAY state
1795 // changed as part of SL-4878 1794 // changed as part of SL-4878
1796 if ( gOverlayBar->getMusicRemoteControl ()->getTransportState () == LLMediaRemoteCtrl::Play ) 1795 if ( gOverlayBar && gOverlayBar->musicPlaying() )
1797 { 1796 {
1798 if (gAudiop) 1797 LLOverlayBar::musicPlay(NULL);
1799 { 1798 }
1800 gAudiop->startInternetStream(music_url.c_str());
1801 }
1802 };
1803 } 1799 }
1804} 1800}
1805 1801
@@ -1812,12 +1808,7 @@ void callback_start_music(S32 option, void* data)
1812 { 1808 {
1813 gSavedSettings.setBOOL("AudioStreamingMusic", TRUE); 1809 gSavedSettings.setBOOL("AudioStreamingMusic", TRUE);
1814 llinfos << "Starting first parcel music " << music_url << llendl; 1810 llinfos << "Starting first parcel music " << music_url << llendl;
1815 if (gAudiop) 1811 LLOverlayBar::musicPlay(NULL);
1816 {
1817 gAudiop->startInternetStream(music_url->c_str());
1818 LLMediaRemoteCtrl* ctrl = gOverlayBar->getMusicRemoteControl();
1819 ctrl->setTransportState( LLMediaRemoteCtrl::Play, FALSE );
1820 }
1821 } 1812 }
1822 else 1813 else
1823 { 1814 {
diff --git a/linden/indra/newview/llviewerpartsim.cpp b/linden/indra/newview/llviewerpartsim.cpp
index 914eb2d..bc15317 100644
--- a/linden/indra/newview/llviewerpartsim.cpp
+++ b/linden/indra/newview/llviewerpartsim.cpp
@@ -41,7 +41,7 @@
41#include "llworld.h" 41#include "llworld.h"
42#include "pipeline.h" 42#include "pipeline.h"
43 43
44const S32 MAX_PART_COUNT = 4096; 44const S32 MAX_PART_COUNT = 8192; // VWR-1105
45 45
46const F32 PART_SIM_BOX_SIDE = 16.f; 46const F32 PART_SIM_BOX_SIDE = 16.f;
47const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE; 47const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE;
diff --git a/linden/indra/newview/llviewerpartsource.cpp b/linden/indra/newview/llviewerpartsource.cpp
index c0de13a..836748a 100644
--- a/linden/indra/newview/llviewerpartsource.cpp
+++ b/linden/indra/newview/llviewerpartsource.cpp
@@ -305,6 +305,12 @@ void LLViewerPartSourceScript::update(const F32 dt)
305 //llwarns << "Unknown source pattern " << (S32)mPartSysData.mPattern << llendl; 305 //llwarns << "Unknown source pattern " << (S32)mPartSysData.mPattern << llendl;
306 } 306 }
307 307
308 if (part->mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK || // SVC-193, VWR-717
309 part->mFlags & LLPartData::LL_PART_TARGET_LINEAR_MASK)
310 {
311 mPartSysData.mBurstRadius = 0;
312 }
313
308 gWorldPointer->mPartSim.addPart(part); 314 gWorldPointer->mPartSim.addPart(part);
309 } 315 }
310 316
diff --git a/linden/indra/newview/llviewerprecompiledheaders.h b/linden/indra/newview/llviewerprecompiledheaders.h
index cc2af01..632fa22 100644
--- a/linden/indra/newview/llviewerprecompiledheaders.h
+++ b/linden/indra/newview/llviewerprecompiledheaders.h
@@ -92,7 +92,6 @@
92#include "llmap.h" 92#include "llmap.h"
93#include "llmemory.h" 93#include "llmemory.h"
94#include "llnametable.h" 94#include "llnametable.h"
95#include "llpagemem.h"
96#include "llpriqueuemap.h" 95#include "llpriqueuemap.h"
97#include "llprocessor.h" 96#include "llprocessor.h"
98#include "llptrskiplist.h" 97#include "llptrskiplist.h"
@@ -138,7 +137,6 @@
138#include "llcoordframe.h" 137#include "llcoordframe.h"
139#include "llcrc.h" 138#include "llcrc.h"
140#include "llinterp.h" 139#include "llinterp.h"
141#include "llmd5.h"
142#include "llperlin.h" 140#include "llperlin.h"
143#include "llplane.h" 141#include "llplane.h"
144#include "llquantize.h" 142#include "llquantize.h"
diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp
index 0f20fd8..0a21e45 100644
--- a/linden/indra/newview/llviewerregion.cpp
+++ b/linden/indra/newview/llviewerregion.cpp
@@ -202,8 +202,9 @@ void LLViewerRegion::loadCache()
202 } 202 }
203 203
204 U32 zero; 204 U32 zero;
205 fread(&zero, 1, sizeof(U32), fp); 205 size_t nread;
206 if (zero) 206 nread = fread(&zero, sizeof(U32), 1, fp);
207 if (nread != 1 || zero)
207 { 208 {
208 // a non-zero value here means bad things! 209 // a non-zero value here means bad things!
209 // skip reading the cached values 210 // skip reading the cached values
@@ -213,8 +214,8 @@ void LLViewerRegion::loadCache()
213 } 214 }
214 215
215 U32 version; 216 U32 version;
216 fread(&version, 1, sizeof(U32), fp); 217 nread = fread(&version, sizeof(U32), 1, fp);
217 if (version != INDRA_OBJECT_CACHE_VERSION) 218 if (nread != 1 || version != INDRA_OBJECT_CACHE_VERSION)
218 { 219 {
219 // a version mismatch here means we've changed the binary format! 220 // a version mismatch here means we've changed the binary format!
220 // skip reading the cached values 221 // skip reading the cached values
@@ -224,8 +225,8 @@ void LLViewerRegion::loadCache()
224 } 225 }
225 226
226 LLUUID cache_id; 227 LLUUID cache_id;
227 fread(&cache_id.mData, UUID_BYTES, sizeof(U8), fp); 228 nread = fread(&cache_id.mData, 1, UUID_BYTES, fp);
228 if (mCacheID != cache_id) 229 if (nread != UUID_BYTES || mCacheID != cache_id)
229 { 230 {
230 llinfos << "Cache ID doesn't match for this region, discarding" 231 llinfos << "Cache ID doesn't match for this region, discarding"
231 << llendl; 232 << llendl;
@@ -234,7 +235,14 @@ void LLViewerRegion::loadCache()
234 } 235 }
235 236
236 S32 num_entries; 237 S32 num_entries;
237 fread(&num_entries, 1, sizeof(S32), fp); 238 nread = fread(&num_entries, sizeof(S32), 1, fp);
239 if (nread != 1)
240 {
241 llinfos << "Short read, discarding" << llendl;
242 fclose(fp);
243 return;
244 }
245
238 S32 i; 246 S32 i;
239 for (i = 0; i < num_entries; i++) 247 for (i = 0; i < num_entries; i++)
240 { 248 {
@@ -284,16 +292,28 @@ void LLViewerRegion::saveCache()
284 292
285 // write out zero to indicate a version cache file 293 // write out zero to indicate a version cache file
286 U32 zero = 0; 294 U32 zero = 0;
287 fwrite(&zero, 1, sizeof(U32), fp); 295 if (fwrite(&zero, sizeof(U32), 1, fp) != 1)
296 {
297 llwarns << "Short write" << llendl;
298 }
288 299
289 // write out version number 300 // write out version number
290 U32 version = INDRA_OBJECT_CACHE_VERSION; 301 U32 version = INDRA_OBJECT_CACHE_VERSION;
291 fwrite(&version, 1, sizeof(U32), fp); 302 if (fwrite(&version, sizeof(U32), 1, fp) != 1)
303 {
304 llwarns << "Short write" << llendl;
305 }
292 306
293 // write the cache id for this sim 307 // write the cache id for this sim
294 fwrite(&mCacheID.mData, UUID_BYTES, sizeof(U8), fp); 308 if (fwrite(&mCacheID.mData, 1, UUID_BYTES, fp) != UUID_BYTES)
309 {
310 llwarns << "Short write" << llendl;
311 }
295 312
296 fwrite(&num_entries, 1, sizeof(S32), fp); 313 if (fwrite(&num_entries, sizeof(S32), 1, fp) != 1)
314 {
315 llwarns << "Short write" << llendl;
316 }
297 317
298 LLVOCacheEntry *entry; 318 LLVOCacheEntry *entry;
299 319
@@ -321,89 +341,15 @@ void LLViewerRegion::sendReliableMessage()
321 gMessageSystem->sendReliable(mHost); 341 gMessageSystem->sendReliable(mHost);
322} 342}
323 343
324 344void LLViewerRegion::setFlags(BOOL b, U32 flags)
325void LLViewerRegion::setAllowDamage(BOOL b)
326{
327 if (b)
328 {
329 mRegionFlags |= REGION_FLAGS_ALLOW_DAMAGE;
330 }
331 else
332 {
333 mRegionFlags &= ~REGION_FLAGS_ALLOW_DAMAGE;
334 }
335}
336
337
338void LLViewerRegion::setAllowLandmark(BOOL b)
339{
340 if (b)
341 {
342 mRegionFlags |= REGION_FLAGS_ALLOW_LANDMARK;
343 }
344 else
345 {
346 mRegionFlags &= ~REGION_FLAGS_ALLOW_LANDMARK;
347 }
348}
349
350void LLViewerRegion::setAllowSetHome(BOOL b)
351{
352 if (b)
353 {
354 mRegionFlags |= REGION_FLAGS_ALLOW_SET_HOME;
355 }
356 else
357 {
358 mRegionFlags &= ~REGION_FLAGS_ALLOW_SET_HOME;
359 }
360}
361
362void LLViewerRegion::setResetHomeOnTeleport(BOOL b)
363{ 345{
364 if (b) 346 if (b)
365 { 347 {
366 mRegionFlags |= REGION_FLAGS_RESET_HOME_ON_TELEPORT; 348 mRegionFlags |= flags;
367 } 349 }
368 else 350 else
369 { 351 {
370 mRegionFlags &= ~REGION_FLAGS_RESET_HOME_ON_TELEPORT; 352 mRegionFlags &= ~flags;
371 }
372}
373
374void LLViewerRegion::setSunFixed(BOOL b)
375{
376 if (b)
377 {
378 mRegionFlags |= REGION_FLAGS_SUN_FIXED;
379 }
380 else
381 {
382 mRegionFlags &= ~REGION_FLAGS_SUN_FIXED;
383 }
384}
385
386void LLViewerRegion::setBlockFly(BOOL b)
387{
388 if (b)
389 {
390 mRegionFlags |= REGION_FLAGS_BLOCK_FLY;
391 }
392 else
393 {
394 mRegionFlags &= ~REGION_FLAGS_BLOCK_FLY;
395 }
396}
397
398void LLViewerRegion::setAllowDirectTeleport(BOOL b)
399{
400 if (b)
401 {
402 mRegionFlags |= REGION_FLAGS_ALLOW_DIRECT_TELEPORT;
403 }
404 else
405 {
406 mRegionFlags &= ~REGION_FLAGS_ALLOW_DIRECT_TELEPORT;
407 } 353 }
408} 354}
409 355
@@ -737,14 +683,7 @@ void LLViewerRegion::calculateCenterGlobal()
737 mCenterGlobal = mOriginGlobal; 683 mCenterGlobal = mOriginGlobal;
738 mCenterGlobal.mdV[VX] += 0.5 * mWidth; 684 mCenterGlobal.mdV[VX] += 0.5 * mWidth;
739 mCenterGlobal.mdV[VY] += 0.5 * mWidth; 685 mCenterGlobal.mdV[VY] += 0.5 * mWidth;
740 if (mLandp) 686 mCenterGlobal.mdV[VZ] = 0.5*mLandp->getMinZ() + mLandp->getMaxZ();
741 {
742 mCenterGlobal.mdV[VZ] = 0.5*mLandp->getMinZ() + mLandp->getMaxZ();
743 }
744 else
745 {
746 mCenterGlobal.mdV[VZ] = F64( getWaterHeight() );
747 }
748} 687}
749 688
750void LLViewerRegion::calculateCameraDistance() 689void LLViewerRegion::calculateCameraDistance()
@@ -867,13 +806,23 @@ F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)
867 806
868BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos) 807BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos)
869{ 808{
870 return mParcelOverlay->isOwnedSelf(pos); 809 if (mParcelOverlay)
810 {
811 return mParcelOverlay->isOwnedSelf(pos);
812 } else {
813 return FALSE;
814 }
871} 815}
872 816
873// Owned by a group you belong to? (officer or member) 817// Owned by a group you belong to? (officer or member)
874BOOL LLViewerRegion::isOwnedGroup(const LLVector3& pos) 818BOOL LLViewerRegion::isOwnedGroup(const LLVector3& pos)
875{ 819{
876 return mParcelOverlay->isOwnedGroup(pos); 820 if (mParcelOverlay)
821 {
822 return mParcelOverlay->isOwnedGroup(pos);
823 } else {
824 return FALSE;
825 }
877} 826}
878 827
879void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg) 828void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
@@ -1325,9 +1274,10 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
1325 capabilityNames.append("UntrustedSimulatorMessage"); 1274 capabilityNames.append("UntrustedSimulatorMessage");
1326 capabilityNames.append("ParcelVoiceInfoRequest"); 1275 capabilityNames.append("ParcelVoiceInfoRequest");
1327 capabilityNames.append("ChatSessionRequest"); 1276 capabilityNames.append("ChatSessionRequest");
1277 capabilityNames.append("ProvisionVoiceAccountRequest");
1328 1278
1329 llinfos << "posting to seed " << url << llendl; 1279 llinfos << "posting to seed " << url << llendl;
1330 1280
1331 LLHTTPClient::post(url, capabilityNames, BaseCapabilitiesComplete::build(this)); 1281 LLHTTPClient::post(url, capabilityNames, BaseCapabilitiesComplete::build(this));
1332} 1282}
1333 1283
diff --git a/linden/indra/newview/llviewerregion.h b/linden/indra/newview/llviewerregion.h
index 8ac5de2..6407f0c 100644
--- a/linden/indra/newview/llviewerregion.h
+++ b/linden/indra/newview/llviewerregion.h
@@ -83,13 +83,14 @@ public:
83 void setOriginGlobal(const LLVector3d &origin); 83 void setOriginGlobal(const LLVector3d &origin);
84 void setAgentOffset(const LLVector3d &offset); 84 void setAgentOffset(const LLVector3d &offset);
85 85
86 void setAllowDamage(BOOL b); 86 void setAllowDamage(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DAMAGE); }
87 void setAllowLandmark(BOOL b); 87 void setAllowLandmark(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_LANDMARK); }
88 void setAllowSetHome(BOOL b); 88 void setAllowSetHome(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_SET_HOME); }
89 void setResetHomeOnTeleport(BOOL b); 89 void setResetHomeOnTeleport(BOOL b) { setFlags(b, REGION_FLAGS_RESET_HOME_ON_TELEPORT); }
90 void setSunFixed(BOOL b); 90 void setSunFixed(BOOL b) { setFlags(b, REGION_FLAGS_SUN_FIXED); }
91 void setBlockFly(BOOL b); 91 void setBlockFly(BOOL b) { setFlags(b, REGION_FLAGS_BLOCK_FLY); }
92 void setAllowDirectTeleport(BOOL b); 92 void setAllowDirectTeleport(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DIRECT_TELEPORT); }
93
93 94
94 inline BOOL getAllowDamage() const; 95 inline BOOL getAllowDamage() const;
95 inline BOOL getAllowLandmark() const; 96 inline BOOL getAllowLandmark() const;
@@ -248,6 +249,7 @@ public:
248protected: 249protected:
249 void disconnectAllNeighbors(); 250 void disconnectAllNeighbors();
250 void initStats(); 251 void initStats();
252 void setFlags(BOOL b, U32 flags);
251 253
252public: 254public:
253 LLWind mWind; 255 LLWind mWind;
diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp
index f6829d4..3369125 100644
--- a/linden/indra/newview/llviewertexteditor.cpp
+++ b/linden/indra/newview/llviewertexteditor.cpp
@@ -1267,8 +1267,8 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item )
1267 const F32 SOUND_GAIN = 1.0f; 1267 const F32 SOUND_GAIN = 1.0f;
1268 if(gAudiop) 1268 if(gAudiop)
1269 { 1269 {
1270 gAudiop->triggerSound( 1270 F32 volume = SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX");
1271 item->getAssetUUID(), gAgentID, SOUND_GAIN, lpos_global); 1271 gAudiop->triggerSound(item->getAssetUUID(), gAgentID, volume, lpos_global);
1272 } 1272 }
1273 showCopyToInvDialog( item ); 1273 showCopyToInvDialog( item );
1274} 1274}
@@ -1437,7 +1437,7 @@ LLView* LLViewerTextEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlF
1437 LLViewerTextEditor* text_editor = new LLViewerTextEditor(name, 1437 LLViewerTextEditor* text_editor = new LLViewerTextEditor(name,
1438 rect, 1438 rect,
1439 max_text_length, 1439 max_text_length,
1440 text, 1440 "",
1441 font, 1441 font,
1442 allow_embedded_items); 1442 allow_embedded_items);
1443 1443
@@ -1453,7 +1453,18 @@ LLView* LLViewerTextEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlF
1453 node->getAttributeBOOL("hide_scrollbar",hide_scrollbar); 1453 node->getAttributeBOOL("hide_scrollbar",hide_scrollbar);
1454 text_editor->setHideScrollbarForShortDocs(hide_scrollbar); 1454 text_editor->setHideScrollbarForShortDocs(hide_scrollbar);
1455 1455
1456 BOOL hide_border = !text_editor->mBorder->getVisible();
1457 node->getAttributeBOOL("hide_border", hide_border);
1458 text_editor->setBorderVisible(!hide_border);
1459
1460 BOOL parse_html = text_editor->mParseHTML;
1461 node->getAttributeBOOL("allow_html", parse_html);
1462 text_editor->setParseHTML(parse_html);
1463
1456 text_editor->initFromXML(node, parent); 1464 text_editor->initFromXML(node, parent);
1457 1465
1466 // add text after all parameters have been set
1467 text_editor->appendStyledText(text, FALSE, FALSE, NULL);
1468
1458 return text_editor; 1469 return text_editor;
1459} 1470}
diff --git a/linden/indra/newview/llvieweruictrlfactory.cpp b/linden/indra/newview/llvieweruictrlfactory.cpp
index efab1cc..188c905 100644
--- a/linden/indra/newview/llvieweruictrlfactory.cpp
+++ b/linden/indra/newview/llvieweruictrlfactory.cpp
@@ -41,7 +41,6 @@
41#include "llnameeditor.h" 41#include "llnameeditor.h"
42#include "llnamelistctrl.h" 42#include "llnamelistctrl.h"
43#include "llwebbrowserctrl.h" 43#include "llwebbrowserctrl.h"
44#include "llvolumesliderctrl.h"
45#include "lljoystickbutton.h" 44#include "lljoystickbutton.h"
46#include "llmediaremotectrl.h" 45#include "llmediaremotectrl.h"
47#include "v4color.h" 46#include "v4color.h"
@@ -66,7 +65,6 @@ LLViewerUICtrlFactory::LLViewerUICtrlFactory()
66#if LL_LIBXUL_ENABLED 65#if LL_LIBXUL_ENABLED
67 LLUICtrlCreator<LLWebBrowserCtrl>::registerCreator(LL_WEB_BROWSER_CTRL_TAG, this); 66 LLUICtrlCreator<LLWebBrowserCtrl>::registerCreator(LL_WEB_BROWSER_CTRL_TAG, this);
68#endif 67#endif
69 LLUICtrlCreator<LLVolumeSliderCtrl>::registerCreator(LL_VOLUME_SLIDER_CTRL_TAG, this);
70 LLUICtrlCreator<LLJoystickAgentSlide>::registerCreator(LL_JOYSTICK_SLIDE, this); 68 LLUICtrlCreator<LLJoystickAgentSlide>::registerCreator(LL_JOYSTICK_SLIDE, this);
71 LLUICtrlCreator<LLJoystickAgentTurn>::registerCreator(LL_JOYSTICK_TURN, this); 69 LLUICtrlCreator<LLJoystickAgentTurn>::registerCreator(LL_JOYSTICK_TURN, this);
72 LLUICtrlCreator<LLMediaRemoteCtrl>::registerCreator(LL_MEDIA_REMOTE_CTRL_TAG, this); 70 LLUICtrlCreator<LLMediaRemoteCtrl>::registerCreator(LL_MEDIA_REMOTE_CTRL_TAG, this);
@@ -103,11 +101,6 @@ LLWebBrowserCtrl* LLViewerUICtrlFactory::getWebBrowserByName(LLPanel* panelp, co
103 return (LLWebBrowserCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_WEBBROWSER); 101 return (LLWebBrowserCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_WEBBROWSER);
104} 102}
105 103
106LLVolumeSliderCtrl* LLViewerUICtrlFactory::getVolumeSliderByName(LLPanel* panelp, const LLString& name)
107{
108 return (LLVolumeSliderCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_VOLUME_SLIDER);
109}
110
111LLViewerTextEditor* LLViewerUICtrlFactory::getViewerTextEditorByName(LLPanel* panelp, const LLString& name) 104LLViewerTextEditor* LLViewerUICtrlFactory::getViewerTextEditorByName(LLPanel* panelp, const LLString& name)
112{ 105{
113 return (LLViewerTextEditor*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXT_EDITOR); 106 return (LLViewerTextEditor*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXT_EDITOR);
diff --git a/linden/indra/newview/llvieweruictrlfactory.h b/linden/indra/newview/llvieweruictrlfactory.h
index de9964e..9664732 100644
--- a/linden/indra/newview/llvieweruictrlfactory.h
+++ b/linden/indra/newview/llvieweruictrlfactory.h
@@ -38,7 +38,6 @@ class LLNameListCtrl;
38class LLNameEditor; 38class LLNameEditor;
39class LLTextureCtrl; 39class LLTextureCtrl;
40class LLWebBrowserCtrl; 40class LLWebBrowserCtrl;
41class LLVolumeSliderCtrl;
42class LLViewerTextEditor; 41class LLViewerTextEditor;
43class LLMediaRemoteCtrl; 42class LLMediaRemoteCtrl;
44class LLJoystickAgentTurn; 43class LLJoystickAgentTurn;
@@ -56,7 +55,6 @@ public:
56 static LLNameListCtrl* getNameListByName(LLPanel* panelp, const LLString& name); 55 static LLNameListCtrl* getNameListByName(LLPanel* panelp, const LLString& name);
57 static LLTextureCtrl* getTexturePickerByName(LLPanel* panelp, const LLString& name); 56 static LLTextureCtrl* getTexturePickerByName(LLPanel* panelp, const LLString& name);
58 static LLWebBrowserCtrl* getWebBrowserByName(LLPanel* panelp, const LLString& name); 57 static LLWebBrowserCtrl* getWebBrowserByName(LLPanel* panelp, const LLString& name);
59 static LLVolumeSliderCtrl* getVolumeSliderByName( LLPanel* panelp, const LLString& name);
60 static LLViewerTextEditor* getViewerTextEditorByName( LLPanel* panelp, const LLString& name); 58 static LLViewerTextEditor* getViewerTextEditorByName( LLPanel* panelp, const LLString& name);
61 static LLNameEditor* getNameEditorByName(LLPanel* panelp, const LLString& name); 59 static LLNameEditor* getNameEditorByName(LLPanel* panelp, const LLString& name);
62 static LLMediaRemoteCtrl* getMediaRemoteByName(LLPanel* panelp, const LLString& name); 60 static LLMediaRemoteCtrl* getMediaRemoteByName(LLPanel* panelp, const LLString& name);
diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp
index d2190cc..13a4c41 100644
--- a/linden/indra/newview/llviewerwindow.cpp
+++ b/linden/indra/newview/llviewerwindow.cpp
@@ -39,6 +39,8 @@
39#include "llviewercamera.h" 39#include "llviewercamera.h"
40//#include "imdebug.h" 40//#include "imdebug.h"
41 41
42#include "llvoiceclient.h" // for push-to-talk button handling
43
42#ifdef SABINRIG 44#ifdef SABINRIG
43#include "cbw.h" 45#include "cbw.h"
44#endif //SABINRIG 46#endif //SABINRIG
@@ -87,9 +89,11 @@
87#include "llfeaturemanager.h" 89#include "llfeaturemanager.h"
88#include "llfilepicker.h" 90#include "llfilepicker.h"
89#include "llfloater.h" 91#include "llfloater.h"
92#include "llfloateractivespeakers.h"
90#include "llfloaterbuildoptions.h" 93#include "llfloaterbuildoptions.h"
91#include "llfloaterbuyland.h" 94#include "llfloaterbuyland.h"
92#include "llfloaterchat.h" 95#include "llfloaterchat.h"
96#include "llfloaterchatterbox.h"
93#include "llfloatercustomize.h" 97#include "llfloatercustomize.h"
94#include "llfloatereditui.h" // HACK JAMESDEBUG for ui editor 98#include "llfloatereditui.h" // HACK JAMESDEBUG for ui editor
95#include "llfloaterland.h" 99#include "llfloaterland.h"
@@ -227,7 +231,9 @@ BOOL gPickTransparent = TRUE;
227BOOL gDebugFastUIRender = FALSE; 231BOOL gDebugFastUIRender = FALSE;
228 232
229BOOL gbCapturing = FALSE; 233BOOL gbCapturing = FALSE;
234#if !LL_SOLARIS
230MovieMaker gMovieMaker; 235MovieMaker gMovieMaker;
236#endif
231 237
232S32 CHAT_BAR_HEIGHT = 28; 238S32 CHAT_BAR_HEIGHT = 28;
233S32 OVERLAY_BAR_HEIGHT = 20; 239S32 OVERLAY_BAR_HEIGHT = 20;
@@ -515,30 +521,40 @@ public:
515 ypos += y_inc; 521 ypos += y_inc;
516 } 522 }
517 523
518 if (LLPipeline::getRenderParticleBeacons(NULL)) 524 // only display these messages if we are actually rendering beacons at this moment
519 { 525 if (LLPipeline::getRenderBeacons(NULL) && LLPipeline::getProcessBeacons(NULL))
520 addText(xpos, ypos, "Viewing particle beacons (blue)");
521 ypos += y_inc;
522 }
523 if (LLPipeline::toggleRenderTypeControlNegated((void*)LLPipeline::RENDER_TYPE_PARTICLES))
524 {
525 addText(xpos, ypos, "Hiding particles");
526 ypos += y_inc;
527 }
528 if (LLPipeline::getRenderPhysicalBeacons(NULL))
529 {
530 addText(xpos, ypos, "Viewing physical object beacons (green)");
531 ypos += y_inc;
532 }
533 if (LLPipeline::getRenderScriptedBeacons(NULL))
534 {
535 addText(xpos, ypos, "Viewing scripted object beacons (red)");
536 ypos += y_inc;
537 }
538 if (LLPipeline::getRenderSoundBeacons(NULL))
539 { 526 {
540 addText(xpos, ypos, "Viewing sound beacons (yellow)"); 527 if (LLPipeline::getRenderParticleBeacons(NULL))
541 ypos += y_inc; 528 {
529 addText(xpos, ypos, "Viewing particle beacons (blue)");
530 ypos += y_inc;
531 }
532 if (LLPipeline::toggleRenderTypeControlNegated((void*)LLPipeline::RENDER_TYPE_PARTICLES))
533 {
534 addText(xpos, ypos, "Hiding particles");
535 ypos += y_inc;
536 }
537 if (LLPipeline::getRenderPhysicalBeacons(NULL))
538 {
539 addText(xpos, ypos, "Viewing physical object beacons (green)");
540 ypos += y_inc;
541 }
542 if (LLPipeline::getRenderScriptedBeacons(NULL))
543 {
544 addText(xpos, ypos, "Viewing scripted object beacons (red)");
545 ypos += y_inc;
546 }
547 else
548 if (LLPipeline::getRenderScriptedTouchBeacons(NULL))
549 {
550 addText(xpos, ypos, "Viewing scripted object with touch function beacons (red)");
551 ypos += y_inc;
552 }
553 if (LLPipeline::getRenderSoundBeacons(NULL))
554 {
555 addText(xpos, ypos, "Viewing sound beacons (yellow)");
556 ypos += y_inc;
557 }
542 } 558 }
543 } 559 }
544 560
@@ -596,6 +612,7 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
596 // Hide tooltips on mousedown 612 // Hide tooltips on mousedown
597 if( mToolTip ) 613 if( mToolTip )
598 { 614 {
615 mToolTipBlocked = TRUE;
599 mToolTip->setVisible( FALSE ); 616 mToolTip->setVisible( FALSE );
600 } 617 }
601 618
@@ -1096,6 +1113,21 @@ BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK m
1096 return TRUE; 1113 return TRUE;
1097} 1114}
1098 1115
1116BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
1117{
1118 gVoiceClient->middleMouseState(true);
1119
1120 // Always handled as far as the OS is concerned.
1121 return TRUE;
1122}
1123
1124BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
1125{
1126 gVoiceClient->middleMouseState(false);
1127
1128 // Always handled as far as the OS is concerned.
1129 return TRUE;
1130}
1099 1131
1100void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask) 1132void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask)
1101{ 1133{
@@ -1112,7 +1144,8 @@ void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask
1112 LLCoordGL prev_saved_mouse_point = mCurrentMousePoint; 1144 LLCoordGL prev_saved_mouse_point = mCurrentMousePoint;
1113 LLCoordGL mouse_point(x, y); 1145 LLCoordGL mouse_point(x, y);
1114 saveLastMouse(mouse_point); 1146 saveLastMouse(mouse_point);
1115 BOOL mouse_actually_moved = (prev_saved_mouse_point.mX != mCurrentMousePoint.mX) || (prev_saved_mouse_point.mY != mCurrentMousePoint.mY); 1147 BOOL mouse_actually_moved = !gFocusMgr.getMouseCapture() && // mouse is not currenty captured
1148 ((prev_saved_mouse_point.mX != mCurrentMousePoint.mX) || (prev_saved_mouse_point.mY != mCurrentMousePoint.mY)); // mouse moved from last recorded position
1116 1149
1117 gMouseIdleTimer.reset(); 1150 gMouseIdleTimer.reset();
1118 1151
@@ -1224,6 +1257,9 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
1224 1257
1225BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) 1258BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
1226{ 1259{
1260 // Let the voice chat code check for its PTT key. Note that this never affects event processing.
1261 gVoiceClient->keyDown(key, mask);
1262
1227 if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME) 1263 if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
1228 { 1264 {
1229 gAgent.clearAFK(); 1265 gAgent.clearAFK();
@@ -1243,6 +1279,9 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
1243 1279
1244BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) 1280BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
1245{ 1281{
1282 // Let the voice chat code check for its PTT key. Note that this never affects event processing.
1283 gVoiceClient->keyUp(key, mask);
1284
1246 return FALSE; 1285 return FALSE;
1247} 1286}
1248 1287
@@ -1285,21 +1324,14 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
1285 } 1324 }
1286 1325
1287 // Unmute audio 1326 // Unmute audio
1288 if (!gSavedSettings.getBOOL("MuteAudio")) 1327 audio_update_volume();
1289 {
1290 if (gAudiop) gAudiop->setMuted(FALSE);
1291 F32 volume = gSavedSettings.getF32("MediaAudioVolume");
1292 if(LLMediaEngine::getInstance())
1293 {
1294 LLMediaEngine::getInstance()->setVolume(volume);
1295 LLMediaEngine::updateClass(volume);
1296 }
1297 }
1298 } 1328 }
1299 else 1329 else
1300 { 1330 {
1301 mActive = FALSE; 1331 mActive = FALSE;
1302 gAgent.setAFK(); 1332 if (gAllowIdleAFK) {
1333 gAgent.setAFK();
1334 }
1303 send_agent_pause(); 1335 send_agent_pause();
1304 if (mWindow->getFullscreen() && !mIgnoreActivate) 1336 if (mWindow->getFullscreen() && !mIgnoreActivate)
1305 { 1337 {
@@ -1307,14 +1339,7 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
1307 stopGL(); 1339 stopGL();
1308 } 1340 }
1309 // Mute audio 1341 // Mute audio
1310 if (gSavedSettings.getBOOL("MuteWhenMinimized")) 1342 audio_update_volume();
1311 {
1312 llinfos << "Muting audio on minimize" << llendl;
1313 if (gAudiop) gAudiop->setMuted(TRUE);
1314 F32 volume = 0.f;
1315 LLMediaEngine::getInstance()->setVolume(volume);
1316 LLMediaEngine::updateClass(volume);
1317 }
1318 } 1343 }
1319 return TRUE; 1344 return TRUE;
1320} 1345}
@@ -1463,8 +1488,8 @@ LLViewerWindow::LLViewerWindow(
1463 if (NULL == mWindow) 1488 if (NULL == mWindow)
1464 { 1489 {
1465 LLSplashScreen::update("Shutting down..."); 1490 LLSplashScreen::update("Shutting down...");
1466#if LL_LINUX 1491#if LL_LINUX || LL_SOLARIS
1467 llwarns << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt for further information." 1492 llwarns << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt or README-solaris.txt for further information."
1468 << llendl; 1493 << llendl;
1469#else 1494#else
1470 llwarns << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings" 1495 llwarns << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
@@ -1714,7 +1739,7 @@ void LLViewerWindow::initBase()
1714 LLRect notify_rect = full_window; 1739 LLRect notify_rect = full_window;
1715 //notify_rect.mTop -= 24; 1740 //notify_rect.mTop -= 24;
1716 notify_rect.mBottom += STATUS_BAR_HEIGHT; 1741 notify_rect.mBottom += STATUS_BAR_HEIGHT;
1717 gNotifyBoxView = new LLNotifyBoxView("notify", notify_rect, FALSE, FOLLOWS_ALL); 1742 gNotifyBoxView = new LLNotifyBoxView("notify_container", notify_rect, FALSE, FOLLOWS_ALL);
1718 mRootView->addChild(gNotifyBoxView, -2); 1743 mRootView->addChild(gNotifyBoxView, -2);
1719 1744
1720 // Tooltips go above floaters 1745 // Tooltips go above floaters
@@ -1819,117 +1844,117 @@ void LLViewerWindow::initWorldUI()
1819 S32 width = mRootView->getRect().getWidth(); 1844 S32 width = mRootView->getRect().getWidth();
1820 LLRect full_window(0, height, width, 0); 1845 LLRect full_window(0, height, width, 0);
1821 1846
1822 LLRect bar_rect(-1, STATUS_BAR_HEIGHT, width+1, -1); 1847 if ( gToolBar == NULL ) // Don't re-enter if objects are alreay created
1823 gToolBar = new LLToolBar("toolbar", bar_rect); 1848 {
1849 LLRect bar_rect(-1, STATUS_BAR_HEIGHT, width+1, -1);
1850 gToolBar = new LLToolBar("toolbar", bar_rect);
1824 1851
1825 LLRect chat_bar_rect(-1,CHAT_BAR_HEIGHT, width+1, -1); 1852 LLRect chat_bar_rect(-1,CHAT_BAR_HEIGHT, width+1, -1);
1826 chat_bar_rect.translate(0, STATUS_BAR_HEIGHT-1); 1853 chat_bar_rect.translate(0, STATUS_BAR_HEIGHT-1);
1827 gChatBar = new LLChatBar("chat", chat_bar_rect); 1854 gChatBar = new LLChatBar("chat", chat_bar_rect);
1828 1855
1829 bar_rect.translate(0, STATUS_BAR_HEIGHT-1); 1856 bar_rect.translate(0, STATUS_BAR_HEIGHT-1);
1830 bar_rect.translate(0, CHAT_BAR_HEIGHT-1); 1857 bar_rect.translate(0, CHAT_BAR_HEIGHT-1);
1831 gOverlayBar = new LLOverlayBar("overlay", bar_rect); 1858 gOverlayBar = new LLOverlayBar("overlay", bar_rect);
1832 1859
1833 // panel containing chatbar, toolbar, and overlay, over floaters 1860 // panel containing chatbar, toolbar, and overlay, over floaters
1834 LLRect bottom_rect(-1, 2*STATUS_BAR_HEIGHT + CHAT_BAR_HEIGHT, width+1, -1); 1861 LLRect bottom_rect(-1, 2*STATUS_BAR_HEIGHT + CHAT_BAR_HEIGHT, width+1, -1);
1835 gBottomPanel = new LLBottomPanel("bottom panel", bottom_rect); 1862 gBottomPanel = new LLBottomPanel("bottom panel", bottom_rect);
1836 1863
1837 // the order here is important 1864 // the order here is important
1838 gBottomPanel->addChild(gChatBar); 1865 gBottomPanel->addChild(gChatBar);
1839 gBottomPanel->addChild(gToolBar); 1866 gBottomPanel->addChild(gToolBar);
1840 gBottomPanel->addChild(gOverlayBar); 1867 gBottomPanel->addChild(gOverlayBar);
1841 mRootView->addChild(gBottomPanel); 1868 mRootView->addChild(gBottomPanel);
1842 1869
1843 // View for hover information 1870 // View for hover information
1844 gHoverView = new LLHoverView("gHoverView", full_window); 1871 gHoverView = new LLHoverView("gHoverView", full_window);
1845 gHoverView->setVisible(TRUE); 1872 gHoverView->setVisible(TRUE);
1846 mRootView->addChild(gHoverView); 1873 mRootView->addChild(gHoverView);
1847 1874
1848 // 1875 //
1849 // Map 1876 // Map
1850 // 1877 //
1851 // TODO: Move instance management into class 1878 // TODO: Move instance management into class
1852 gFloaterMap = new LLFloaterMap("Map"); 1879 gFloaterMap = new LLFloaterMap("Map");
1853 gFloaterMap->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT); 1880 gFloaterMap->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
1854 gFloaterMap->setVisible( gSavedSettings.getBOOL("ShowMiniMap") ); 1881 gFloaterMap->setVisible( gSavedSettings.getBOOL("ShowMiniMap") );
1855 1882
1856 // keep onscreen 1883 // keep onscreen
1857 gFloaterView->adjustToFitScreen(gFloaterMap, FALSE); 1884 gFloaterView->adjustToFitScreen(gFloaterMap, FALSE);
1858 1885
1859 if (gSavedSettings.getBOOL("ShowCameraControls")) 1886 if (gSavedSettings.getBOOL("ShowCameraControls"))
1860 { 1887 {
1861 LLFloaterCamera::show(NULL); 1888 LLFloaterCamera::show(NULL);
1862 } 1889 }
1863 1890
1864 if (gSavedSettings.getBOOL("ShowMovementControls")) 1891 if (gSavedSettings.getBOOL("ShowMovementControls"))
1865 { 1892 {
1866 LLFloaterMove::show(NULL); 1893 LLFloaterMove::show(NULL);
1867 } 1894 }
1868 1895
1869 // Must have one global chat floater so it can actually store 1896 gIMMgr = LLIMMgr::getInstance();
1870 // the history. JC
1871 gFloaterChat = new LLFloaterChat();
1872 gFloaterChat->setVisible( FALSE );
1873
1874 if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) gFloaterChat->loadHistory();
1875 1897
1876 gIMView = new LLIMView("gIMView", LLRect() ); 1898 if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
1877 gIMView->setFollowsAll(); 1899 {
1878 mRootView->addChild(gIMView); 1900 LLFloaterChat::getInstance(LLSD())->loadHistory();
1901 }
1879 1902
1880 LLRect morph_view_rect = full_window; 1903 LLRect morph_view_rect = full_window;
1881 morph_view_rect.stretch( -STATUS_BAR_HEIGHT ); 1904 morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
1882 morph_view_rect.mTop = full_window.mTop - 32; 1905 morph_view_rect.mTop = full_window.mTop - 32;
1883 gMorphView = new LLMorphView("gMorphView", morph_view_rect ); 1906 gMorphView = new LLMorphView("gMorphView", morph_view_rect );
1884 mRootView->addChild(gMorphView); 1907 mRootView->addChild(gMorphView);
1885 gMorphView->setVisible(FALSE); 1908 gMorphView->setVisible(FALSE);
1886 1909
1887 gFloaterMute = new LLFloaterMute(); 1910 gFloaterMute = new LLFloaterMute();
1888 gFloaterMute->setVisible(FALSE); 1911 gFloaterMute->setVisible(FALSE);
1889 1912
1890 LLWorldMapView::initClass(); 1913 LLWorldMapView::initClass();
1891 1914
1892 LLRect world_map_rect = gSavedSettings.getRect("FloaterWorldMapRect"); 1915 LLRect world_map_rect = gSavedSettings.getRect("FloaterWorldMapRect");
1893 // if 0,0,0,0 then use fullscreen 1916 // if 0,0,0,0 then use fullscreen
1894 if (world_map_rect.mTop == 0 1917 if (world_map_rect.mTop == 0
1895 && world_map_rect.mLeft == 0 1918 && world_map_rect.mLeft == 0
1896 && world_map_rect.mRight == 0 1919 && world_map_rect.mRight == 0
1897 && world_map_rect.mBottom == 0) 1920 && world_map_rect.mBottom == 0)
1898 { 1921 {
1899 world_map_rect.set(0, height-TOOL_BAR_HEIGHT, width, STATUS_BAR_HEIGHT); 1922 world_map_rect.set(0, height-TOOL_BAR_HEIGHT, width, STATUS_BAR_HEIGHT);
1900 world_map_rect.stretch(-4); 1923 world_map_rect.stretch(-4);
1901 gSavedSettings.setRect("FloaterWorldMapRect", world_map_rect); 1924 gSavedSettings.setRect("FloaterWorldMapRect", world_map_rect);
1902 } 1925 }
1903 gFloaterWorldMap = new LLFloaterWorldMap(); 1926 gFloaterWorldMap = new LLFloaterWorldMap();
1904 gFloaterWorldMap->setVisible(FALSE); 1927 gFloaterWorldMap->setVisible(FALSE);
1905 1928
1906 // 1929 //
1907 // Tools for building 1930 // Tools for building
1908 // 1931 //
1909 1932
1910 // Toolbox floater 1933 // Toolbox floater
1911 init_menus(); 1934 init_menus();
1912 1935
1913 gFloaterTools = new LLFloaterTools(); 1936 gFloaterTools = new LLFloaterTools();
1914 gFloaterTools->setVisible(FALSE); 1937 gFloaterTools->setVisible(FALSE);
1915 1938
1916 // Status bar 1939 // Status bar
1917 S32 menu_bar_height = gMenuBarView->getRect().getHeight(); 1940 S32 menu_bar_height = gMenuBarView->getRect().getHeight();
1918 LLRect root_rect = gViewerWindow->getRootView()->getRect(); 1941 LLRect root_rect = gViewerWindow->getRootView()->getRect();
1919 LLRect status_rect(0, root_rect.getHeight(), root_rect.getWidth(), root_rect.getHeight() - menu_bar_height); 1942 LLRect status_rect(0, root_rect.getHeight(), root_rect.getWidth(), root_rect.getHeight() - menu_bar_height);
1920 gStatusBar = new LLStatusBar("status", status_rect); 1943 gStatusBar = new LLStatusBar("status", status_rect);
1921 gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP); 1944 gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
1922 1945
1923 gStatusBar->reshape(root_rect.getWidth(), gStatusBar->getRect().getHeight(), TRUE); 1946 gStatusBar->reshape(root_rect.getWidth(), gStatusBar->getRect().getHeight(), TRUE);
1924 gStatusBar->translate(0, root_rect.getHeight() - gStatusBar->getRect().getHeight()); 1947 gStatusBar->translate(0, root_rect.getHeight() - gStatusBar->getRect().getHeight());
1925 // sync bg color with menu bar 1948 // sync bg color with menu bar
1926 gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor() ); 1949 gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor() );
1927 1950
1951 LLFloaterChatterBox::createInstance(LLSD());
1928 1952
1929 gViewerWindow->getRootView()->addChild(gStatusBar); 1953 gViewerWindow->getRootView()->addChild(gStatusBar);
1930 1954
1931 // menu holder appears on top to get first pass at all mouse events 1955 // menu holder appears on top to get first pass at all mouse events
1932 gViewerWindow->getRootView()->sendChildToFront(gMenuHolder); 1956 gViewerWindow->getRootView()->sendChildToFront(gMenuHolder);
1957 }
1933} 1958}
1934 1959
1935 1960
@@ -1953,13 +1978,12 @@ LLViewerWindow::~LLViewerWindow()
1953 gFloaterTools = NULL; 1978 gFloaterTools = NULL;
1954 gStatusBar = NULL; 1979 gStatusBar = NULL;
1955 gFloaterCamera = NULL; 1980 gFloaterCamera = NULL;
1956 gIMView = NULL; 1981 gIMMgr = NULL;
1957 gHoverView = NULL; 1982 gHoverView = NULL;
1958 1983
1959 gFloaterView = NULL; 1984 gFloaterView = NULL;
1960 gMorphView = NULL; 1985 gMorphView = NULL;
1961 1986
1962 gFloaterChat = NULL;
1963 gFloaterMute = NULL; 1987 gFloaterMute = NULL;
1964 1988
1965 gFloaterMap = NULL; 1989 gFloaterMap = NULL;
@@ -2150,6 +2174,23 @@ void LLViewerWindow::reshape(S32 width, S32 height)
2150 } 2174 }
2151} 2175}
2152 2176
2177
2178// Hide normal UI when a logon fails
2179void LLViewerWindow::setNormalControlsVisible( BOOL visible )
2180{
2181 if ( gBottomPanel )
2182 gBottomPanel->setVisible( visible );
2183
2184 if ( gMenuBarView )
2185 gMenuBarView->setVisible( visible );
2186
2187 if ( gStatusBar )
2188 gStatusBar->setVisible( visible );
2189}
2190
2191
2192
2193
2153void LLViewerWindow::drawDebugText() 2194void LLViewerWindow::drawDebugText()
2154{ 2195{
2155 mDebugText->draw(); 2196 mDebugText->draw();
@@ -2703,16 +2744,29 @@ BOOL LLViewerWindow::handlePerFrameHover()
2703 } 2744 }
2704 } 2745 }
2705 2746
2747 gPipeline.sRenderProcessBeacons = FALSE;
2748 KEY key = gKeyboard->currentKey();
2749 if (((mask & MASK_CONTROL) && ('N' == key || 'n' == key)) || (gFloaterTools && gFloaterTools->getVisible()) || gSavedSettings.getBOOL("BeaconAlwaysOn"))
2750 {
2751 gPipeline.sRenderProcessBeacons = TRUE;
2752 }
2753
2754/*
2706 // Show joints while in edit mode and hold down alt key. 2755 // Show joints while in edit mode and hold down alt key.
2707 if (gHUDManager) 2756 if (gHUDManager)
2708 { 2757 {
2709 if (gSavedSettings.getBOOL("AltShowsPhysical") 2758 BOOL menuOption = gSavedSettings.getBOOL("AltShowsPhysical");
2759 if (menuOption
2710 || (gFloaterTools && gFloaterTools->getVisible())) 2760 || (gFloaterTools && gFloaterTools->getVisible()))
2711 { 2761 {
2712 gHUDManager->toggleShowPhysical( mask & MASK_ALT ); 2762 gHUDManager->toggleShowPhysical( mask & MASK_ALT );
2713 } 2763 }
2764 else
2765 {
2766 gHUDManager->toggleShowPhysical( FALSE );
2767 }
2714 } 2768 }
2715 2769*/
2716 BOOL handled = FALSE; 2770 BOOL handled = FALSE;
2717 2771
2718 BOOL handled_by_top_ctrl = FALSE; 2772 BOOL handled_by_top_ctrl = FALSE;
@@ -4143,11 +4197,15 @@ void LLViewerWindow::saveMovieNumbered(void*)
4143 S32 y = gViewerWindow->getWindowHeight(); 4197 S32 y = gViewerWindow->getWindowHeight();
4144 4198
4145 gbCapturing = TRUE; 4199 gbCapturing = TRUE;
4200#if !LL_SOLARIS
4146 gMovieMaker.StartCapture((char *)filepath.c_str(), x, y); 4201 gMovieMaker.StartCapture((char *)filepath.c_str(), x, y);
4202#endif
4147 } 4203 }
4148 else 4204 else
4149 { 4205 {
4206#if !LL_SOLARIS
4150 gMovieMaker.EndCapture(); 4207 gMovieMaker.EndCapture();
4208#endif
4151 gbCapturing = FALSE; 4209 gbCapturing = FALSE;
4152 } 4210 }
4153} 4211}
diff --git a/linden/indra/newview/llviewerwindow.h b/linden/indra/newview/llviewerwindow.h
index e6a9a14..4560427 100644
--- a/linden/indra/newview/llviewerwindow.h
+++ b/linden/indra/newview/llviewerwindow.h
@@ -85,6 +85,8 @@ public:
85 /*virtual*/ void handleQuit(LLWindow *window); 85 /*virtual*/ void handleQuit(LLWindow *window);
86 /*virtual*/ BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); 86 /*virtual*/ BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
87 /*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); 87 /*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
88 /*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
89 /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
88 /*virtual*/ void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); 90 /*virtual*/ void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
89 /*virtual*/ void handleMouseLeave(LLWindow *window); 91 /*virtual*/ void handleMouseLeave(LLWindow *window);
90 /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y); 92 /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y);
@@ -174,6 +176,9 @@ public:
174 BOOL handleKey(KEY key, MASK mask); 176 BOOL handleKey(KEY key, MASK mask);
175 void handleScrollWheel (S32 clicks); 177 void handleScrollWheel (S32 clicks);
176 178
179 // Hide normal UI when a logon fails, re-show everything when logon is attempted again
180 void setNormalControlsVisible( BOOL visible );
181
177 // Handle the application becoming active (frontmost) or inactive 182 // Handle the application becoming active (frontmost) or inactive
178 //BOOL handleActivate(BOOL activate); 183 //BOOL handleActivate(BOOL activate);
179 184
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp
index a375d84..3b9e8ea 100644
--- a/linden/indra/newview/llvoavatar.cpp
+++ b/linden/indra/newview/llvoavatar.cpp
@@ -116,6 +116,12 @@
116 116
117//#include "vtune/vtuneapi.h" 117//#include "vtune/vtuneapi.h"
118 118
119//Ventrella
120#include "llgesturemgr.h" //needed to trigger the voice gestculations
121#include "llvoicevisualizer.h"
122#include "llvoiceclient.h"
123//end Ventrella
124
119// Direct imports, evil 125// Direct imports, evil
120extern LLSky gSky; 126extern LLSky gSky;
121extern void set_avatar_character(void* charNameArg); 127extern void set_avatar_character(void* charNameArg);
@@ -147,9 +153,7 @@ const F32 PELVIS_LAG_WALKING = 0.4f; // ...while walking
147const F32 PELVIS_LAG_MOUSELOOK = 0.15f; 153const F32 PELVIS_LAG_MOUSELOOK = 0.15f;
148const F32 MOUSELOOK_PELVIS_FOLLOW_FACTOR = 0.5f; 154const F32 MOUSELOOK_PELVIS_FOLLOW_FACTOR = 0.5f;
149 155
150//Ventrella
151const F32 PELVIS_LAG_WHEN_FOLLOW_CAM_IS_ON = 0.0001f; // not zero! - something gets divided by this! 156const F32 PELVIS_LAG_WHEN_FOLLOW_CAM_IS_ON = 0.0001f; // not zero! - something gets divided by this!
152//end Ventrella
153 157
154#define PELVIS_ROT_THRESHOLD_SLOW 60.0f // amount of deviation allowed between 158#define PELVIS_ROT_THRESHOLD_SLOW 60.0f // amount of deviation allowed between
155#define PELVIS_ROT_THRESHOLD_FAST 2.0f // the pelvis and the view direction 159#define PELVIS_ROT_THRESHOLD_FAST 2.0f // the pelvis and the view direction
@@ -221,10 +225,6 @@ const F32 CHAT_FADE_TIME = 8.0;
221const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f; 225const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
222const S32 MAX_BUBBLES = 7; 226const S32 MAX_BUBBLES = 7;
223 227
224
225const bool USING_VENTRELLA_AVATAR_MOTION_TEST = false;
226
227
228S32 LLVOAvatar::sMaxVisible = 50; 228S32 LLVOAvatar::sMaxVisible = 50;
229 229
230LLVOAvatar::ETextureIndex LLVOAvatar::sBakedTextureIndices[BAKED_TEXTURE_COUNT] = 230LLVOAvatar::ETextureIndex LLVOAvatar::sBakedTextureIndices[BAKED_TEXTURE_COUNT] =
@@ -455,121 +455,16 @@ public:
455 // called after parameters have been set 455 // called after parameters have been set
456 // must return true to indicate success and be available for activation 456 // must return true to indicate success and be available for activation
457 virtual LLMotionInitStatus onInitialize(LLCharacter *character) 457 virtual LLMotionInitStatus onInitialize(LLCharacter *character)
458 { 458 {
459 //Ventrella
460 // I'm replacing the code below because I need to change
461 // the logic in order to add other body parts
462 /*
463 mCharacter = character; 459 mCharacter = character;
464
465 if (!mChestState.setJoint( character->getJoint("mChest")))
466 {
467 return STATUS_FAILURE;
468 }
469
470 mChestState.setUsage(LLJointState::ROT);
471
472 addJointState( &mChestState );
473 return STATUS_SUCCESS;
474 */
475
476
477 bool success = true; 460 bool success = true;
478 461
479 if ( !mChestState.setJoint( character->getJoint( "mChest" ) ) ) { success = false; } 462 if ( !mChestState.setJoint( character->getJoint( "mChest" ) ) ) { success = false; }
480 463
481 if ( USING_VENTRELLA_AVATAR_MOTION_TEST )
482 {
483 if ( !mNeckState.setJoint ( character->getJoint( "mNeck" )) ) { success = false; }
484
485 if ( !mCollarLeftState.setJoint ( character->getJoint( "mCollarLeft" )) ) { success = false; }
486 if ( !mShoulderLeftState.setJoint ( character->getJoint( "mShoulderLeft" )) ) { success = false; }
487 if ( !mElbowLeftState.setJoint ( character->getJoint( "mElbowLeft" )) ) { success = false; }
488 if ( !mWristLeftState.setJoint ( character->getJoint( "mWristLeft" )) ) { success = false; }
489
490 if ( !mCollarRightState.setJoint ( character->getJoint( "mCollarRight" )) ) { success = false; }
491 if ( !mShoulderRightState.setJoint ( character->getJoint( "mShoulderRight" )) ) { success = false; }
492 if ( !mElbowRightState.setJoint ( character->getJoint( "mElbowRight" )) ) { success = false; }
493 if ( !mWristRightState.setJoint ( character->getJoint( "mWristRight" )) ) { success = false; }
494
495 if ( !mHipLeftState.setJoint ( character->getJoint( "mHipLeft" )) ) { success = false; }
496 if ( !mKneeLeftState.setJoint ( character->getJoint( "mKneeLeft" )) ) { success = false; }
497 if ( !mAnkleLeftState.setJoint ( character->getJoint( "mAnkleLeft" )) ) { success = false; }
498
499 if ( !mHipRightState.setJoint ( character->getJoint( "mHipRight" )) ) { success = false; }
500 if ( !mKneeRightState.setJoint ( character->getJoint( "mKneeRight" )) ) { success = false; }
501 if ( !mAnkleRightState.setJoint ( character->getJoint( "mAnkleRight" )) ) { success = false; }
502 }
503
504 if ( success ) 464 if ( success )
505 { 465 {
506 mChestState.setUsage(LLJointState::ROT); 466 mChestState.setUsage(LLJointState::ROT);
507 addJointState( &mChestState ); 467 addJointState( &mChestState );
508
509 if ( USING_VENTRELLA_AVATAR_MOTION_TEST )
510 {
511 //-------------------------------------------
512 // neck
513 //-------------------------------------------
514 mNeckState.setUsage(LLJointState::ROT);
515 addJointState( &mNeckState );
516
517 //-------------------------------------------
518 // left arm
519 //-------------------------------------------
520 mCollarLeftState.setUsage(LLJointState::ROT);
521 addJointState( &mCollarLeftState );
522
523 mShoulderLeftState.setUsage(LLJointState::ROT);
524 addJointState( &mShoulderLeftState );
525
526 mElbowLeftState.setUsage(LLJointState::ROT);
527 addJointState( &mElbowLeftState );
528
529 mWristLeftState.setUsage(LLJointState::ROT);
530 addJointState( &mWristLeftState );
531
532
533 //-------------------------------------------
534 // right arm
535 //-------------------------------------------
536 mCollarRightState.setUsage(LLJointState::ROT);
537 addJointState( &mCollarRightState );
538
539 mShoulderRightState.setUsage(LLJointState::ROT);
540 addJointState( &mShoulderRightState );
541
542 mElbowRightState.setUsage(LLJointState::ROT);
543 addJointState( &mElbowRightState );
544
545 mWristRightState.setUsage(LLJointState::ROT);
546 addJointState( &mWristRightState );
547
548 //-------------------------------------------
549 // left leg
550 //-------------------------------------------
551 mHipLeftState.setUsage(LLJointState::ROT);
552 addJointState( &mHipLeftState );
553
554 mKneeLeftState.setUsage(LLJointState::ROT);
555 addJointState( &mKneeLeftState );
556
557 mAnkleLeftState.setUsage(LLJointState::ROT);
558 addJointState( &mAnkleLeftState );
559
560
561 //-------------------------------------------
562 // right leg
563 //-------------------------------------------
564 mHipRightState.setUsage(LLJointState::ROT);
565 addJointState( &mHipRightState );
566
567 mKneeRightState.setUsage(LLJointState::ROT);
568 addJointState( &mKneeRightState );
569
570 mAnkleRightState.setUsage(LLJointState::ROT);
571 addJointState( &mAnkleRightState );
572 }
573 } 468 }
574 469
575 if ( success ) 470 if ( success )
@@ -580,7 +475,6 @@ public:
580 { 475 {
581 return STATUS_FAILURE; 476 return STATUS_FAILURE;
582 } 477 }
583 //end Ventrella
584 } 478 }
585 479
586 // called when a motion is activated 480 // called when a motion is activated
@@ -599,37 +493,9 @@ public:
599 493
600 mChestState.setRotation(LLQuaternion(breathe_amt, LLVector3(0.f, 1.f, 0.f))); 494 mChestState.setRotation(LLQuaternion(breathe_amt, LLVector3(0.f, 1.f, 0.f)));
601 495
602 //Ventrella
603 if ( USING_VENTRELLA_AVATAR_MOTION_TEST )
604 {
605 F32 wave = ( sinf ( time * 2.0f ) * 0.5f );
606
607 mChestState.setRotation ( LLQuaternion( wave, LLVector3( -1.0f, 0.0f, 0.0f ) ) );
608
609 mCollarLeftState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) );
610 mShoulderLeftState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) );
611 mElbowLeftState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 0.0f, 1.0f ) ) );
612 mWristLeftState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) );
613
614 mCollarRightState.setRotation ( LLQuaternion( wave, LLVector3( -1.0f, 0.0f, 0.0f ) ) );
615 mShoulderRightState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) );
616 mElbowRightState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 0.0f, 1.0f ) ) );
617 mWristRightState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) );
618
619 mHipLeftState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 1.0f, 0.0f ) ) );
620 mKneeLeftState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, -1.0f, 0.0f ) ) );
621 mAnkleLeftState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 1.0f, 0.0f ) ) );
622
623 mHipRightState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 1.0f, 0.0f ) ) );
624 mKneeRightState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, -1.0f, 0.0f ) ) );
625 mAnkleRightState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 1.0f, 0.0f ) ) );
626 }
627 //end Ventrella
628
629 return TRUE; 496 return TRUE;
630 } 497 }
631 498
632
633 // called when a motion is deactivated 499 // called when a motion is deactivated
634 virtual void onDeactivate() {} 500 virtual void onDeactivate() {}
635 501
@@ -637,26 +503,7 @@ public:
637 //------------------------------------------------------------------------- 503 //-------------------------------------------------------------------------
638 // joint states to be animated 504 // joint states to be animated
639 //------------------------------------------------------------------------- 505 //-------------------------------------------------------------------------
640 LLJointState mChestState; 506 LLJointState mChestState;
641
642 //Ventrella
643 LLJointState mNeckState;
644 LLJointState mCollarLeftState;
645 LLJointState mShoulderLeftState;
646 LLJointState mElbowLeftState;
647 LLJointState mWristLeftState;
648 LLJointState mCollarRightState;
649 LLJointState mShoulderRightState;
650 LLJointState mElbowRightState;
651 LLJointState mWristRightState;
652 LLJointState mHipLeftState;
653 LLJointState mKneeLeftState;
654 LLJointState mAnkleLeftState;
655 LLJointState mHipRightState;
656 LLJointState mKneeRightState;
657 LLJointState mAnkleRightState;
658 //end Ventrella
659
660 F32 mBreatheRate; 507 F32 mBreatheRate;
661 LLCharacter* mCharacter; 508 LLCharacter* mCharacter;
662}; 509};
@@ -819,6 +666,10 @@ LLVOAvatar::LLVOAvatar(
819 LLMemType mt(LLMemType::MTYPE_AVATAR); 666 LLMemType mt(LLMemType::MTYPE_AVATAR);
820 667
821 //VTResume(); // VTune 668 //VTResume(); // VTune
669
670 // mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
671 bool needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
672 mVoiceVisualizer = ( LLVoiceVisualizer *)gHUDManager->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
822 673
823 lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl; 674 lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl;
824 675
@@ -1069,9 +920,13 @@ LLVOAvatar::LLVOAvatar(
1069 createMotion( ANIM_AGENT_CUSTOMIZE_DONE); 920 createMotion( ANIM_AGENT_CUSTOMIZE_DONE);
1070 921
1071 //VTPause(); // VTune 922 //VTPause(); // VTune
923
924 //Ventrella
925 mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) );
926 mCurrentGesticulationLevel = 0;
927 //END Ventrella
1072} 928}
1073 929
1074
1075//------------------------------------------------------------------------ 930//------------------------------------------------------------------------
1076// LLVOAvatar::~LLVOAvatar() 931// LLVOAvatar::~LLVOAvatar()
1077//------------------------------------------------------------------------ 932//------------------------------------------------------------------------
@@ -1143,6 +998,8 @@ void LLVOAvatar::markDead()
1143 sNumVisibleChatBubbles--; 998 sNumVisibleChatBubbles--;
1144 } 999 }
1145 1000
1001 mVoiceVisualizer->markDead();
1002
1146 mBeam = NULL; 1003 mBeam = NULL;
1147 LLViewerObject::markDead(); 1004 LLViewerObject::markDead();
1148} 1005}
@@ -2459,7 +2316,84 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
2459 2316
2460 updateCharacter(agent); 2317 updateCharacter(agent);
2461 2318
2319 //Ventrella
2320 bool voiceEnabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel();
2321 // disable voice visualizer when in mouselook
2322 mVoiceVisualizer->setVoiceEnabled( voiceEnabled && !(mIsSelf && gAgent.cameraMouselook()) );
2323 if ( voiceEnabled )
2324 {
2325 //----------------------------------------------------------------
2326 // Only do gesture triggering for your own avatar, and only when you're in a proximal channel.
2327 //----------------------------------------------------------------
2328 if( mIsSelf )
2329 {
2330 //----------------------------------------------------------------------------------------
2331 // The following takes the voice signal and uses that to trigger gesticulations.
2332 //----------------------------------------------------------------------------------------
2333 int lastGesticulationLevel = mCurrentGesticulationLevel;
2334 mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel();
2335
2336 //---------------------------------------------------------------------------------------------------
2337 // If "current gesticulation level" changes, we catch this, and trigger the new gesture
2338 //---------------------------------------------------------------------------------------------------
2339 if ( lastGesticulationLevel != mCurrentGesticulationLevel )
2340 {
2341 if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF )
2342 {
2343 LLString gestureString = "unInitialized";
2344 if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; }
2345 else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; }
2346 else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; }
2347 else { printf( "oops - CurrentGesticulationLevel can be only 0, 1, or 2\n" ); }
2348
2349 // this is the call that Karl S. created for triggering gestures from within the code.
2350 gGestureManager.triggerAndReviseString( gestureString );
2351 }
2352 }
2353
2354 } //if( mIsSelf )
2355
2356 //-----------------------------------------------------------------------------------------------------------------
2357 // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer.
2358 // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol.
2359 //
2360 // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
2361 // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking.
2362 //-----------------------------------------------------------------------------------------------------------------
2363 if ( gVoiceClient->getIsSpeaking( mID ) )
2364 {
2365 if ( ! mVoiceVisualizer->getCurrentlySpeaking() )
2366 {
2367 mVoiceVisualizer->setStartSpeaking();
2368
2369 //printf( "gAwayTimer.reset();\n" );
2370 }
2371
2372 mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) );
2373
2374 if( mIsSelf )
2375 {
2376 gAgent.clearAFK();
2377 }
2378 }
2379 else
2380 {
2381 if ( mVoiceVisualizer->getCurrentlySpeaking() )
2382 {
2383 mVoiceVisualizer->setStopSpeaking();
2384 }
2385 }
2386
2387 //--------------------------------------------------------------------------------------------
2388 // here we get the approximate head position and set as sound source for the voice symbol
2389 // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
2390 //--------------------------------------------------------------------------------------------
2391 LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
2392 mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
2462 2393
2394 }//if ( voiceEnabled )
2395 //End Ventrella
2396
2463 2397
2464 if (LLVOAvatar::sJointDebug) 2398 if (LLVOAvatar::sJointDebug)
2465 { 2399 {
@@ -2469,7 +2403,6 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
2469 LLJoint::sNumUpdates = 0; 2403 LLJoint::sNumUpdates = 0;
2470 LLJoint::sNumTouches = 0; 2404 LLJoint::sNumTouches = 0;
2471 2405
2472
2473 if (gNoRender) 2406 if (gNoRender)
2474 { 2407 {
2475 return TRUE; 2408 return TRUE;
@@ -3272,14 +3205,7 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
3272 3205
3273 LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV ); 3206 LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV );
3274 F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, PELVIS_ROT_THRESHOLD_SLOW, PELVIS_ROT_THRESHOLD_FAST); 3207 F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, PELVIS_ROT_THRESHOLD_SLOW, PELVIS_ROT_THRESHOLD_FAST);
3275 3208
3276 //Ventrella
3277 //if ( gAgent.getCameraMode() == CAMERA_MODE_FOLLOW )
3278 //{
3279 // pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, 1.0f, 1.0f);
3280 //}
3281 //end Ventrella
3282
3283 if (self_in_mouselook) 3209 if (self_in_mouselook)
3284 { 3210 {
3285 pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR; 3211 pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR;
@@ -3357,13 +3283,6 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
3357 pelvis_lag_time = PELVIS_LAG_WALKING; 3283 pelvis_lag_time = PELVIS_LAG_WALKING;
3358 } 3284 }
3359 3285
3360 //Ventrella
3361 //if ( gAgent.getCameraMode() == CAMERA_MODE_FOLLOW )
3362 //{
3363 // pelvis_lag_time = PELVIS_LAG_WHEN_FOLLOW_CAM_IS_ON;
3364 //}
3365 //end Ventrella
3366
3367 F32 u = llclamp((deltaTime / pelvis_lag_time), 0.0f, 1.0f); 3286 F32 u = llclamp((deltaTime / pelvis_lag_time), 0.0f, 1.0f);
3368 3287
3369 mRoot.setWorldRotation( slerp(u, mRoot.getWorldRotation(), wQv) ); 3288 mRoot.setWorldRotation( slerp(u, mRoot.getWorldRotation(), wQv) );
@@ -3481,13 +3400,13 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
3481// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED, 3400// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
3482// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN ); 3401// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
3483 3402
3484 F32 gain = gSavedSettings.getF32("AudioLevelFootsteps"); 3403 F32 gain = .30f * gSavedSettings.getF32("AudioLevelAmbient");
3485 LLUUID& step_sound_id = getStepSound(); 3404 LLUUID& step_sound_id = getStepSound();
3486 3405
3487 LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent); 3406 LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent);
3488 3407
3489 if (gParcelMgr && gParcelMgr->canHearSound(foot_pos_global) 3408 if (gParcelMgr && gParcelMgr->canHearSound(foot_pos_global)
3490 && gMuteListp && !gMuteListp->isMuted(getID())) 3409 && gMuteListp && !gMuteListp->isMuted(getID(), LLMute::flagObjectSounds))
3491 { 3410 {
3492 gAudiop->triggerSound(step_sound_id, getID(), gain, foot_pos_global); 3411 gAudiop->triggerSound(step_sound_id, getID(), gain, foot_pos_global);
3493 } 3412 }
@@ -3496,6 +3415,32 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
3496 3415
3497 mRoot.updateWorldMatrixChildren(); 3416 mRoot.updateWorldMatrixChildren();
3498 3417
3418 // Send the speaker position to the spatialized voice system.
3419 if(mIsSelf)
3420 {
3421 LLMatrix3 rot;
3422 LLVector3d pos;
3423#if 1
3424 // character rotation (stable, shouldn't move with animations)
3425 rot = mRoot.getWorldRotation().getMatrix3();
3426#else
3427 // actual head rotation (moves with animations, probably a bit too much)
3428 rot.setRows(
3429 LLVector3::x_axis * mSkullp->getWorldRotation(),
3430 LLVector3::y_axis * mSkullp->getWorldRotation(),
3431 LLVector3::z_axis * mSkullp->getWorldRotation());
3432#endif
3433
3434 pos = getPositionGlobal();
3435 pos += LLVector3d(mHeadOffset);
3436
3437 // MBW -- XXX -- Setting velocity to 0 for now. May figure it out later...
3438 gVoiceClient->setAvatarPosition(
3439 pos, // position
3440 LLVector3::zero, // velocity
3441 rot); // rotation matrix
3442 }
3443
3499 if (!mDebugText.size() && mText.notNull()) 3444 if (!mDebugText.size() && mText.notNull())
3500 { 3445 {
3501 mText->markDead(); 3446 mText->markDead();
@@ -4203,7 +4148,7 @@ void LLVOAvatar::updateTextures(LLAgent &agent)
4203 4148
4204 if( render_avatar ) 4149 if( render_avatar )
4205 { 4150 {
4206 mShadowImagep->addTextureStats(mPixelArea, 1.f); 4151 mShadowImagep->addTextureStats(mPixelArea);
4207 } 4152 }
4208} 4153}
4209 4154
@@ -4418,18 +4363,20 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
4418 { 4363 {
4419 LLVector3d char_pos_global = gAgent.getPosGlobalFromAgent(getCharacterPosition()); 4364 LLVector3d char_pos_global = gAgent.getPosGlobalFromAgent(getCharacterPosition());
4420 if (gParcelMgr && gParcelMgr->canHearSound(char_pos_global) 4365 if (gParcelMgr && gParcelMgr->canHearSound(char_pos_global)
4421 && gMuteListp && !gMuteListp->isMuted(getID())) 4366 && gMuteListp && !gMuteListp->isMuted(getID(), LLMute::flagObjectSounds))
4422 { 4367 {
4423 // RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed 4368 // RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed
4424 // to support both spatialized and non-spatialized instances of the same sound 4369 // to support both spatialized and non-spatialized instances of the same sound
4425 //if (mIsSelf) 4370 //if (mIsSelf)
4426 //{ 4371 //{
4427 // gAudiop->triggerSound(LLUUID(gSavedSettings.getString("UISndTyping")), 0.8f); 4372 // F32 volume = gain * gSavedSettings.getF32("AudioLevelUI")
4373 // gAudiop->triggerSound(LLUUID(gSavedSettings.getString("UISndTyping")), volume);
4428 //} 4374 //}
4429 //else 4375 //else
4430 { 4376 {
4431 LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping")); 4377 LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping"));
4432 gAudiop->triggerSound(sound_id, getID(), 1.f, char_pos_global); 4378 F32 volume = gSavedSettings.getF32("AudioLevelSFX");
4379 gAudiop->triggerSound(sound_id, getID(), volume, char_pos_global);
4433 } 4380 }
4434 } 4381 }
4435 } 4382 }
@@ -4818,7 +4765,6 @@ LLJoint *LLVOAvatar::getCharacterJoint( U32 num )
4818 return (LLJoint*)&mSkeleton[num]; 4765 return (LLJoint*)&mSkeleton[num];
4819} 4766}
4820 4767
4821
4822//----------------------------------------------------------------------------- 4768//-----------------------------------------------------------------------------
4823// requestStopMotion() 4769// requestStopMotion()
4824//----------------------------------------------------------------------------- 4770//-----------------------------------------------------------------------------
@@ -5810,7 +5756,7 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object)
5810{ 5756{
5811 LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object); 5757 LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object);
5812 5758
5813 if (!attachment->addObject(viewer_object)) 5759 if (!attachment || !attachment->addObject(viewer_object))
5814 { 5760 {
5815 return FALSE; 5761 return FALSE;
5816 } 5762 }
diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h
index 427293a..5b92445 100644
--- a/linden/indra/newview/llvoavatar.h
+++ b/linden/indra/newview/llvoavatar.h
@@ -52,6 +52,11 @@
52#include "llxmltree.h" 52#include "llxmltree.h"
53#include "llwearable.h" 53#include "llwearable.h"
54 54
55//Ventrella
56//#include "llvoiceclient.h"
57#include "llvoicevisualizer.h"
58//End Ventrella
59
55const S32 VOAVATAR_SCRATCH_TEX_WIDTH = 512; 60const S32 VOAVATAR_SCRATCH_TEX_WIDTH = 512;
56const S32 VOAVATAR_SCRATCH_TEX_HEIGHT = 512; 61const S32 VOAVATAR_SCRATCH_TEX_HEIGHT = 512;
57 62
@@ -947,6 +952,17 @@ protected:
947 LLTexLayerSet* getLayerSet(ETextureIndex index) const; 952 LLTexLayerSet* getLayerSet(ETextureIndex index) const;
948 LLHost getObjectHost() const; 953 LLHost getObjectHost() const;
949 S32 getLocalDiscardLevel( S32 index); 954 S32 getLocalDiscardLevel( S32 index);
955
956//Ventrella
957 //-----------------------------------------------------------------------------------------------
958 // the Voice Visualizer is responsible for detecting the user's voice signal, and when the
959 // user speaks, it puts a voice symbol over the avatar's head, and triggering gesticulations
960 //-----------------------------------------------------------------------------------------------
961 private:
962 LLVoiceVisualizer * mVoiceVisualizer;
963 int mCurrentGesticulationLevel;
964//End Ventrella
965
950}; 966};
951 967
952#endif // LL_VO_AVATAR_H 968#endif // LL_VO_AVATAR_H
diff --git a/linden/indra/newview/llvocache.cpp b/linden/indra/newview/llvocache.cpp
index f249c87..2b3569d 100644
--- a/linden/indra/newview/llvocache.cpp
+++ b/linden/indra/newview/llvocache.cpp
@@ -60,16 +60,25 @@ LLVOCacheEntry::LLVOCacheEntry()
60} 60}
61 61
62 62
63static inline void checkedRead(FILE *fp, void *data, size_t nbytes)
64{
65 if (fread(data, 1, nbytes, fp) != nbytes)
66 {
67 llwarns << "Short read" << llendl;
68 memset(data, 0, nbytes);
69 }
70}
71
63LLVOCacheEntry::LLVOCacheEntry(FILE *fp) 72LLVOCacheEntry::LLVOCacheEntry(FILE *fp)
64{ 73{
65 S32 size; 74 S32 size;
66 fread(&mLocalID, 1, sizeof(U32), fp); 75 checkedRead(fp, &mLocalID, sizeof(U32));
67 fread(&mCRC, 1, sizeof(U32), fp); 76 checkedRead(fp, &mCRC, sizeof(U32));
68 fread(&mHitCount, 1, sizeof(S32), fp); 77 checkedRead(fp, &mHitCount, sizeof(S32));
69 fread(&mDupeCount, 1, sizeof(S32), fp); 78 checkedRead(fp, &mDupeCount, sizeof(S32));
70 fread(&mCRCChangeCount, 1, sizeof(S32), fp); 79 checkedRead(fp, &mCRCChangeCount, sizeof(S32));
71 80
72 fread(&size, 1, sizeof(S32), fp); 81 checkedRead(fp, &size, sizeof(S32));
73 82
74 // Corruption in the cache entries 83 // Corruption in the cache entries
75 if ((size > 10000) || (size < 1)) 84 if ((size > 10000) || (size < 1))
@@ -85,7 +94,7 @@ LLVOCacheEntry::LLVOCacheEntry(FILE *fp)
85 } 94 }
86 95
87 mBuffer = new U8[size]; 96 mBuffer = new U8[size];
88 fread(mBuffer, 1, size, fp); 97 checkedRead(fp, mBuffer, size);
89 mDP.assignBuffer(mBuffer, size); 98 mDP.assignBuffer(mBuffer, size);
90} 99}
91 100
@@ -141,14 +150,22 @@ void LLVOCacheEntry::dump() const
141 << llendl; 150 << llendl;
142} 151}
143 152
153static inline void checkedWrite(FILE *fp, const void *data, size_t nbytes)
154{
155 if (fwrite(data, 1, nbytes, fp) != nbytes)
156 {
157 llwarns << "Short write" << llendl;
158 }
159}
160
144void LLVOCacheEntry::writeToFile(FILE *fp) const 161void LLVOCacheEntry::writeToFile(FILE *fp) const
145{ 162{
146 fwrite(&mLocalID, 1, sizeof(U32), fp); 163 checkedWrite(fp, &mLocalID, sizeof(U32));
147 fwrite(&mCRC, 1, sizeof(U32), fp); 164 checkedWrite(fp, &mCRC, sizeof(U32));
148 fwrite(&mHitCount, 1, sizeof(S32), fp); 165 checkedWrite(fp, &mHitCount, sizeof(S32));
149 fwrite(&mDupeCount, 1, sizeof(S32), fp); 166 checkedWrite(fp, &mDupeCount, sizeof(S32));
150 fwrite(&mCRCChangeCount, 1, sizeof(S32), fp); 167 checkedWrite(fp, &mCRCChangeCount, sizeof(S32));
151 S32 size = mDP.getBufferSize(); 168 S32 size = mDP.getBufferSize();
152 fwrite(&size, 1, sizeof(S32), fp); 169 checkedWrite(fp, &size, sizeof(S32));
153 fwrite(mBuffer, 1, size, fp); 170 checkedWrite(fp, mBuffer, size);
154} 171}
diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp
index 5d9c581..4725b33 100644
--- a/linden/indra/newview/llvograss.cpp
+++ b/linden/indra/newview/llvograss.cpp
@@ -336,16 +336,13 @@ void LLVOGrass::setPixelAreaAndAngle(LLAgent &agent)
336// BUG could speed this up by caching the relative_position and range calculations 336// BUG could speed this up by caching the relative_position and range calculations
337void LLVOGrass::updateTextures(LLAgent &agent) 337void LLVOGrass::updateTextures(LLAgent &agent)
338{ 338{
339 F32 texel_area_ratio = 1.f;
340 F32 cos_angle = 1.f;
341
342 if (getTEImage(0)) 339 if (getTEImage(0))
343 { 340 {
344 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) 341 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
345 { 342 {
346 setDebugText(llformat("%4.0f", fsqrtf(mPixelArea))); 343 setDebugText(llformat("%4.0f", fsqrtf(mPixelArea)));
347 } 344 }
348 getTEImage(0)->addTextureStats(mPixelArea, texel_area_ratio, cos_angle); 345 getTEImage(0)->addTextureStats(mPixelArea);
349 } 346 }
350} 347}
351 348
@@ -442,7 +439,8 @@ void LLVOGrass::getGeometry(S32 idx,
442 LLStrider<U32>& indicesp) 439 LLStrider<U32>& indicesp)
443{ 440{
444 mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); 441 mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
445 mLastPatchUpdateTime = mPatch->getLastUpdateTime(); 442 if (mPatch)
443 mLastPatchUpdateTime = mPatch->getLastUpdateTime();
446 444
447 LLVector3 position; 445 LLVector3 position;
448 // Create random blades of grass with gaussian distribution 446 // Create random blades of grass with gaussian distribution
diff --git a/linden/indra/newview/llvoiceclient.cpp b/linden/indra/newview/llvoiceclient.cpp
new file mode 100644
index 0000000..0bc42c6
--- /dev/null
+++ b/linden/indra/newview/llvoiceclient.cpp
@@ -0,0 +1,4076 @@
1/**
2 * @file llvoiceclient.cpp
3 * @brief Implementation of LLVoiceClient class which is the interface to the voice client process.
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include <boost/tokenizer.hpp>
30
31#include "llviewerprecompiledheaders.h"
32#include "llvoiceclient.h"
33
34#include "llsdutil.h"
35
36#include "llvoavatar.h"
37#include "llbufferstream.h"
38#include "llfile.h"
39#include "expat/expat.h"
40#include "llcallbacklist.h"
41#include "llviewerregion.h"
42#include "llviewernetwork.h" // for gUserServerChoice
43#include "llfloateractivespeakers.h" // for LLSpeakerMgr
44#include "llbase64.h"
45#include "llviewercontrol.h"
46#include "llkeyboard.h"
47#include "viewer.h" // for gDisconnected, gDisableVoice
48#include "llmutelist.h" // to check for muted avatars
49#include "llagent.h"
50#include "llcachename.h"
51#include "llimview.h" // for LLIMMgr
52#include "llimpanel.h" // for LLVoiceChannel
53#include "llparcel.h"
54#include "llviewerparcelmgr.h"
55#include "llfirstuse.h"
56#include "llviewerwindow.h"
57
58// for base64 decoding
59#include "apr-1/apr_base64.h"
60
61// for SHA1 hash
62#include "apr-1/apr_sha1.h"
63
64// If we are connecting to agni AND the user's last name is "Linden", join this channel instead of looking up the sim name.
65// If we are connecting to agni and the user's last name is NOT "Linden", disable voice.
66#define AGNI_LINDENS_ONLY_CHANNEL "SL"
67static bool sConnectingToAgni = false;
68F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f;
69
70const F32 SPEAKING_TIMEOUT = 1.f;
71
72const int VOICE_MAJOR_VERSION = 1;
73const int VOICE_MINOR_VERSION = 0;
74
75LLVoiceClient *gVoiceClient = NULL;
76
77// Don't retry connecting to the daemon more frequently than this:
78const F32 CONNECT_THROTTLE_SECONDS = 1.0f;
79
80// Don't send positional updates more frequently than this:
81const F32 UPDATE_THROTTLE_SECONDS = 0.1f;
82
83const F32 LOGIN_RETRY_SECONDS = 10.0f;
84const int MAX_LOGIN_RETRIES = 12;
85
86class LLViewerVoiceAccountProvisionResponder :
87 public LLHTTPClient::Responder
88{
89public:
90 LLViewerVoiceAccountProvisionResponder(int retries)
91 {
92 mRetries = retries;
93 }
94
95 virtual void error(U32 status, const std::string& reason)
96 {
97 if ( mRetries > 0 )
98 {
99 if ( gVoiceClient ) gVoiceClient->requestVoiceAccountProvision(
100 mRetries - 1);
101 }
102 else
103 {
104 //TODO: throw an error message?
105 if ( gVoiceClient ) gVoiceClient->giveUp();
106 }
107 }
108
109 virtual void result(const LLSD& content)
110 {
111 if ( gVoiceClient )
112 {
113 gVoiceClient->login(
114 content["username"].asString(),
115 content["password"].asString());
116 }
117 }
118
119private:
120 int mRetries;
121};
122
123/**
124 * @class LLVivoxProtocolParser
125 * @brief This class helps construct new LLIOPipe specializations
126 * @see LLIOPipe
127 *
128 * THOROUGH_DESCRIPTION
129 */
130class LLVivoxProtocolParser : public LLIOPipe
131{
132 LOG_CLASS(LLVivoxProtocolParser);
133public:
134 LLVivoxProtocolParser();
135 virtual ~LLVivoxProtocolParser();
136
137protected:
138 /* @name LLIOPipe virtual implementations
139 */
140 //@{
141 /**
142 * @brief Process the data in buffer
143 */
144 virtual EStatus process_impl(
145 const LLChannelDescriptors& channels,
146 buffer_ptr_t& buffer,
147 bool& eos,
148 LLSD& context,
149 LLPumpIO* pump);
150 //@}
151
152 std::string mInput;
153
154 // Expat control members
155 XML_Parser parser;
156 int responseDepth;
157 bool ignoringTags;
158 bool isEvent;
159 int ignoreDepth;
160
161 // Members for processing responses. The values are transient and only valid within a call to processResponse().
162 int returnCode;
163 int statusCode;
164 std::string statusString;
165 std::string uuidString;
166 std::string actionString;
167 std::string connectorHandle;
168 std::string accountHandle;
169 std::string sessionHandle;
170 std::string eventSessionHandle;
171
172 // Members for processing events. The values are transient and only valid within a call to processResponse().
173 std::string eventTypeString;
174 int state;
175 std::string uriString;
176 bool isChannel;
177 std::string nameString;
178 std::string audioMediaString;
179 std::string displayNameString;
180 int participantType;
181 bool isLocallyMuted;
182 bool isModeratorMuted;
183 bool isSpeaking;
184 int volume;
185 F32 energy;
186
187 // Members for processing text between tags
188 std::string textBuffer;
189 bool accumulateText;
190
191 void reset();
192
193 void processResponse(std::string tag);
194
195static void XMLCALL ExpatStartTag(void *data, const char *el, const char **attr);
196static void XMLCALL ExpatEndTag(void *data, const char *el);
197static void XMLCALL ExpatCharHandler(void *data, const XML_Char *s, int len);
198
199 void StartTag(const char *tag, const char **attr);
200 void EndTag(const char *tag);
201 void CharData(const char *buffer, int length);
202
203};
204
205LLVivoxProtocolParser::LLVivoxProtocolParser()
206{
207 parser = NULL;
208 parser = XML_ParserCreate(NULL);
209
210 reset();
211}
212
213void LLVivoxProtocolParser::reset()
214{
215 responseDepth = 0;
216 ignoringTags = false;
217 accumulateText = false;
218 textBuffer.clear();
219}
220
221//virtual
222LLVivoxProtocolParser::~LLVivoxProtocolParser()
223{
224 if (parser)
225 XML_ParserFree(parser);
226}
227
228// virtual
229LLIOPipe::EStatus LLVivoxProtocolParser::process_impl(
230 const LLChannelDescriptors& channels,
231 buffer_ptr_t& buffer,
232 bool& eos,
233 LLSD& context,
234 LLPumpIO* pump)
235{
236 LLBufferStream istr(channels, buffer.get());
237 std::ostringstream ostr;
238 while (istr.good())
239 {
240 char buf[1024];
241 istr.read(buf, sizeof(buf));
242 mInput.append(buf, istr.gcount());
243 }
244
245 // MBW -- XXX -- This should no longer be necessary. Or even possible.
246 // We've read all the data out of the buffer. Make sure it doesn't accumulate.
247// buffer->clear();
248
249 // Look for input delimiter(s) in the input buffer. If one is found, send the message to the xml parser.
250 int start = 0;
251 int delim;
252 while((delim = mInput.find("\n\n\n", start)) != std::string::npos)
253 {
254 // Turn this on to log incoming XML
255 if(0)
256 {
257 int foo = mInput.find("Set3DPosition", start);
258 int bar = mInput.find("ParticipantPropertiesEvent", start);
259 if(foo != std::string::npos && (foo < delim))
260 {
261 // This is a Set3DPosition response. Don't print it, since these are way too spammy.
262 }
263 else if(bar != std::string::npos && (bar < delim))
264 {
265 // This is a ParticipantPropertiesEvent response. Don't print it, since these are way too spammy.
266 }
267 else
268 {
269 llinfos << "parsing: " << mInput.substr(start, delim - start) << llendl;
270 }
271 }
272
273 // Reset internal state of the LLVivoxProtocolParser (no effect on the expat parser)
274 reset();
275
276 XML_ParserReset(parser, NULL);
277 XML_SetElementHandler(parser, ExpatStartTag, ExpatEndTag);
278 XML_SetCharacterDataHandler(parser, ExpatCharHandler);
279 XML_SetUserData(parser, this);
280 XML_Parse(parser, mInput.data() + start, delim - start, false);
281
282 start = delim + 3;
283 }
284
285 if(start != 0)
286 mInput = mInput.substr(start);
287
288// llinfos << "at end, mInput is: " << mInput << llendl;
289
290 if(!gVoiceClient->mConnected)
291 {
292 // If voice has been disabled, we just want to close the socket. This does so.
293 llinfos << "returning STATUS_STOP" << llendl;
294 return STATUS_STOP;
295 }
296
297 return STATUS_OK;
298}
299
300void XMLCALL LLVivoxProtocolParser::ExpatStartTag(void *data, const char *el, const char **attr)
301{
302 if (data)
303 {
304 LLVivoxProtocolParser *object = (LLVivoxProtocolParser*)data;
305 object->StartTag(el, attr);
306 }
307}
308
309// --------------------------------------------------------------------------------
310
311void XMLCALL LLVivoxProtocolParser::ExpatEndTag(void *data, const char *el)
312{
313 if (data)
314 {
315 LLVivoxProtocolParser *object = (LLVivoxProtocolParser*)data;
316 object->EndTag(el);
317 }
318}
319
320// --------------------------------------------------------------------------------
321
322void XMLCALL LLVivoxProtocolParser::ExpatCharHandler(void *data, const XML_Char *s, int len)
323{
324 if (data)
325 {
326 LLVivoxProtocolParser *object = (LLVivoxProtocolParser*)data;
327 object->CharData(s, len);
328 }
329}
330
331// --------------------------------------------------------------------------------
332
333
334void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
335{
336 // Reset the text accumulator. We shouldn't have strings that are inturrupted by new tags
337 textBuffer.clear();
338 // only accumulate text if we're not ignoring tags.
339 accumulateText = !ignoringTags;
340
341 if (responseDepth == 0)
342 {
343 isEvent = strcmp("Event", tag) == 0;
344
345 if (strcmp("Response", tag) == 0 || isEvent)
346 {
347 // Grab the attributes
348 while (*attr)
349 {
350 const char *key = *attr++;
351 const char *value = *attr++;
352
353 if (strcmp("requestId", key) == 0)
354 {
355 uuidString = value;
356 }
357 else if (strcmp("action", key) == 0)
358 {
359 actionString = value;
360 }
361 else if (strcmp("type", key) == 0)
362 {
363 eventTypeString = value;
364 }
365 }
366 }
367 //llinfos << tag << " (" << responseDepth << ")" << llendl;
368 }
369 else
370 {
371 if (ignoringTags)
372 {
373 //llinfos << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << llendl;
374 }
375 else
376 {
377 //llinfos << tag << " (" << responseDepth << ")" << llendl;
378
379 // Ignore the InputXml stuff so we don't get confused
380 if (strcmp("InputXml", tag) == 0)
381 {
382 ignoringTags = true;
383 ignoreDepth = responseDepth;
384 accumulateText = false;
385
386 //llinfos << "starting ignore, ignoreDepth is " << ignoreDepth << llendl;
387 }
388 else if (strcmp("CaptureDevices", tag) == 0)
389 {
390 gVoiceClient->clearCaptureDevices();
391 }
392 else if (strcmp("RenderDevices", tag) == 0)
393 {
394 gVoiceClient->clearRenderDevices();
395 }
396 }
397 }
398 responseDepth++;
399}
400
401// --------------------------------------------------------------------------------
402
403void LLVivoxProtocolParser::EndTag(const char *tag)
404{
405 const char *string = textBuffer.c_str();
406 bool clearbuffer = true;
407
408 responseDepth--;
409
410 if (ignoringTags)
411 {
412 if (ignoreDepth == responseDepth)
413 {
414 //llinfos << "end of ignore" << llendl;
415 ignoringTags = false;
416 }
417 else
418 {
419 //llinfos << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << llendl;
420 }
421 }
422
423 if (!ignoringTags)
424 {
425 //llinfos << "processing tag " << tag << " (depth = " << responseDepth << ")" << llendl;
426
427 // Closing a tag. Finalize the text we've accumulated and reset
428 if (strcmp("ReturnCode", tag) == 0)
429 returnCode = strtol(string, NULL, 10);
430 else if (strcmp("StatusCode", tag) == 0)
431 statusCode = strtol(string, NULL, 10);
432 else if (strcmp("ConnectorHandle", tag) == 0)
433 connectorHandle = string;
434 else if (strcmp("AccountHandle", tag) == 0)
435 accountHandle = string;
436 else if (strcmp("SessionHandle", tag) == 0)
437 {
438 if (isEvent)
439 eventSessionHandle = string;
440 else
441 sessionHandle = string;
442 }
443 else if (strcmp("StatusString", tag) == 0)
444 statusString = string;
445 else if (strcmp("State", tag) == 0)
446 state = strtol(string, NULL, 10);
447 else if (strcmp("URI", tag) == 0)
448 uriString = string;
449 else if (strcmp("IsChannel", tag) == 0)
450 isChannel = strcmp(string, "true") == 0;
451 else if (strcmp("Name", tag) == 0)
452 nameString = string;
453 else if (strcmp("AudioMedia", tag) == 0)
454 audioMediaString = string;
455 else if (strcmp("ChannelName", tag) == 0)
456 nameString = string;
457 else if (strcmp("ParticipantURI", tag) == 0)
458 uriString = string;
459 else if (strcmp("DisplayName", tag) == 0)
460 displayNameString = string;
461 else if (strcmp("AccountName", tag) == 0)
462 nameString = string;
463 else if (strcmp("ParticipantTyppe", tag) == 0)
464 participantType = strtol(string, NULL, 10);
465 else if (strcmp("IsLocallyMuted", tag) == 0)
466 isLocallyMuted = strcmp(string, "true") == 0;
467 else if (strcmp("IsModeratorMuted", tag) == 0)
468 isModeratorMuted = strcmp(string, "true") == 0;
469 else if (strcmp("IsSpeaking", tag) == 0)
470 isSpeaking = strcmp(string, "true") == 0;
471 else if (strcmp("Volume", tag) == 0)
472 volume = strtol(string, NULL, 10);
473 else if (strcmp("Energy", tag) == 0)
474 energy = (F32)strtod(string, NULL);
475 else if (strcmp("MicEnergy", tag) == 0)
476 energy = (F32)strtod(string, NULL);
477 else if (strcmp("ChannelName", tag) == 0)
478 nameString = string;
479 else if (strcmp("ChannelURI", tag) == 0)
480 uriString = string;
481 else if (strcmp("ChannelListResult", tag) == 0)
482 {
483 gVoiceClient->addChannelMapEntry(nameString, uriString);
484 }
485 else if (strcmp("Device", tag) == 0)
486 {
487 // This closing tag shouldn't clear the accumulated text.
488 clearbuffer = false;
489 }
490 else if (strcmp("CaptureDevice", tag) == 0)
491 {
492 gVoiceClient->addCaptureDevice(textBuffer);
493 }
494 else if (strcmp("RenderDevice", tag) == 0)
495 {
496 gVoiceClient->addRenderDevice(textBuffer);
497 }
498
499 if(clearbuffer)
500 {
501 textBuffer.clear();
502 accumulateText= false;
503 }
504
505 if (responseDepth == 0)
506 {
507 // We finished all of the XML, process the data
508 processResponse(tag);
509 }
510 }
511}
512
513// --------------------------------------------------------------------------------
514
515void LLVivoxProtocolParser::CharData(const char *buffer, int length)
516{
517 /*
518 This method is called for anything that isn't a tag, which can be text you
519 want that lies between tags, and a lot of stuff you don't want like file formatting
520 (tabs, spaces, CR/LF, etc).
521
522 Only copy text if we are in accumulate mode...
523 */
524 if (accumulateText)
525 textBuffer.append(buffer, length);
526}
527
528// --------------------------------------------------------------------------------
529
530void LLVivoxProtocolParser::processResponse(std::string tag)
531{
532// llinfos << tag << llendl;
533
534 if (isEvent)
535 {
536 if (eventTypeString == "LoginStateChangeEvent")
537 {
538 gVoiceClient->loginStateChangeEvent(accountHandle, statusCode, statusString, state);
539 }
540 else if (eventTypeString == "SessionNewEvent")
541 {
542 gVoiceClient->sessionNewEvent(accountHandle, eventSessionHandle, state, nameString, uriString);
543 }
544 else if (eventTypeString == "SessionStateChangeEvent")
545 {
546 gVoiceClient->sessionStateChangeEvent(uriString, statusCode, statusString, eventSessionHandle, state, isChannel, nameString);
547 }
548 else if (eventTypeString == "ParticipantStateChangeEvent")
549 {
550 gVoiceClient->participantStateChangeEvent(uriString, statusCode, statusString, state, nameString, displayNameString, participantType);
551
552 }
553 else if (eventTypeString == "ParticipantPropertiesEvent")
554 {
555 gVoiceClient->participantPropertiesEvent(uriString, statusCode, statusString, isLocallyMuted, isModeratorMuted, isSpeaking, volume, energy);
556 }
557 else if (eventTypeString == "AuxAudioPropertiesEvent")
558 {
559 gVoiceClient->auxAudioPropertiesEvent(energy);
560 }
561 }
562 else
563 {
564 if (actionString == "Connector.Create.1")
565 {
566 gVoiceClient->connectorCreateResponse(statusCode, statusString, connectorHandle);
567 }
568 else if (actionString == "Account.Login.1")
569 {
570 gVoiceClient->loginResponse(statusCode, statusString, accountHandle);
571 }
572 else if (actionString == "Session.Create.1")
573 {
574 gVoiceClient->sessionCreateResponse(statusCode, statusString, sessionHandle);
575 }
576 else if (actionString == "Session.Connect.1")
577 {
578 gVoiceClient->sessionConnectResponse(statusCode, statusString);
579 }
580 else if (actionString == "Session.Terminate.1")
581 {
582 gVoiceClient->sessionTerminateResponse(statusCode, statusString);
583 }
584 else if (actionString == "Account.Logout.1")
585 {
586 gVoiceClient->logoutResponse(statusCode, statusString);
587 }
588 else if (actionString == "Connector.InitiateShutdown.1")
589 {
590 gVoiceClient->connectorShutdownResponse(statusCode, statusString);
591 }
592 else if (actionString == "Account.ChannelGetList.1")
593 {
594 gVoiceClient->channelGetListResponse(statusCode, statusString);
595 }
596/*
597 else if (actionString == "Connector.AccountCreate.1")
598 {
599
600 }
601 else if (actionString == "Connector.MuteLocalMic.1")
602 {
603
604 }
605 else if (actionString == "Connector.MuteLocalSpeaker.1")
606 {
607
608 }
609 else if (actionString == "Connector.SetLocalMicVolume.1")
610 {
611
612 }
613 else if (actionString == "Connector.SetLocalSpeakerVolume.1")
614 {
615
616 }
617 else if (actionString == "Session.ListenerSetPosition.1")
618 {
619
620 }
621 else if (actionString == "Session.SpeakerSetPosition.1")
622 {
623
624 }
625 else if (actionString == "Session.Set3DPosition.1")
626 {
627
628 }
629 else if (actionString == "Session.AudioSourceSetPosition.1")
630 {
631
632 }
633 else if (actionString == "Session.GetChannelParticipants.1")
634 {
635
636 }
637 else if (actionString == "Account.ChannelCreate.1")
638 {
639
640 }
641 else if (actionString == "Account.ChannelUpdate.1")
642 {
643
644 }
645 else if (actionString == "Account.ChannelDelete.1")
646 {
647
648 }
649 else if (actionString == "Account.ChannelCreateAndInvite.1")
650 {
651
652 }
653 else if (actionString == "Account.ChannelFolderCreate.1")
654 {
655
656 }
657 else if (actionString == "Account.ChannelFolderUpdate.1")
658 {
659
660 }
661 else if (actionString == "Account.ChannelFolderDelete.1")
662 {
663
664 }
665 else if (actionString == "Account.ChannelAddModerator.1")
666 {
667
668 }
669 else if (actionString == "Account.ChannelDeleteModerator.1")
670 {
671
672 }
673*/
674 }
675}
676
677///////////////////////////////////////////////////////////////////////////////////////////////
678
679class LLVoiceClientPrefsListener: public LLSimpleListener
680{
681 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
682 {
683 // Note: Ignore the specific event value, look up the ones we want
684
685 gVoiceClient->setVoiceEnabled(gSavedSettings.getBOOL("EnableVoiceChat"));
686 gVoiceClient->setUsePTT(gSavedSettings.getBOOL("PTTCurrentlyEnabled"));
687 std::string keyString = gSavedSettings.getString("PushToTalkButton");
688 gVoiceClient->setPTTKey(keyString);
689 gVoiceClient->setPTTIsToggle(gSavedSettings.getBOOL("PushToTalkToggle"));
690 gVoiceClient->setEarLocation(gSavedSettings.getS32("VoiceEarLocation"));
691 std::string serverName = gSavedSettings.getString("VivoxDebugServerName");
692 gVoiceClient->setVivoxDebugServerName(serverName);
693
694 std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
695 gVoiceClient->setCaptureDevice(inputDevice);
696 std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
697 gVoiceClient->setRenderDevice(outputDevice);
698
699 return true;
700 }
701};
702static LLVoiceClientPrefsListener voice_prefs_listener;
703
704class LLVoiceClientMuteListObserver : public LLMuteListObserver
705{
706 /* virtual */ void onChange() { gVoiceClient->muteListChanged();}
707};
708static LLVoiceClientMuteListObserver mutelist_listener;
709static bool sMuteListListener_listening = false;
710
711///////////////////////////////////////////////////////////////////////////////////////////////
712
713class LLVoiceClientCapResponder : public LLHTTPClient::Responder
714{
715public:
716 LLVoiceClientCapResponder(void){};
717
718 virtual void error(U32 status, const std::string& reason); // called with bad status codes
719 virtual void result(const LLSD& content);
720
721private:
722};
723
724void LLVoiceClientCapResponder::error(U32 status, const std::string& reason)
725{
726 llwarns << "LLVoiceClientCapResponder::error("
727 << status << ": " << reason << ")"
728 << llendl;
729}
730
731void LLVoiceClientCapResponder::result(const LLSD& content)
732{
733 LLSD::map_const_iterator iter;
734 for(iter = content.beginMap(); iter != content.endMap(); ++iter)
735 {
736 llinfos << "LLVoiceClientCapResponder::result got "
737 << iter->first << llendl;
738 }
739
740 if ( content.has("voice_credentials") )
741 {
742 LLSD voice_credentials = content["voice_credentials"];
743 std::string uri;
744 std::string credentials;
745
746 if ( voice_credentials.has("channel_uri") )
747 {
748 uri = voice_credentials["channel_uri"].asString();
749 }
750 if ( voice_credentials.has("channel_credentials") )
751 {
752 credentials =
753 voice_credentials["channel_credentials"].asString();
754 }
755
756 gVoiceClient->setSpatialChannel(uri, credentials);
757 }
758}
759
760
761
762#if LL_WINDOWS
763static HANDLE sGatewayHandle = 0;
764
765static bool isGatewayRunning()
766{
767 bool result = false;
768 if(sGatewayHandle != 0)
769 {
770 DWORD waitresult = WaitForSingleObject(sGatewayHandle, 0);
771 if(waitresult != WAIT_OBJECT_0)
772 {
773 result = true;
774 }
775 }
776 return result;
777}
778static void killGateway()
779{
780 if(sGatewayHandle != 0)
781 {
782 TerminateProcess(sGatewayHandle,0);
783 }
784}
785
786#else // Mac and linux
787
788static pid_t sGatewayPID = 0;
789static bool isGatewayRunning()
790{
791 bool result = false;
792 if(sGatewayPID != 0)
793 {
794 // A kill with signal number 0 has no effect, just does error checking. It should return an error if the process no longer exists.
795 if(kill(sGatewayPID, 0) == 0)
796 {
797 result = true;
798 }
799 }
800 return result;
801}
802
803static void killGateway()
804{
805 if(sGatewayPID != 0)
806 {
807 kill(sGatewayPID, SIGTERM);
808 }
809}
810
811#endif
812
813///////////////////////////////////////////////////////////////////////////////////////////////
814
815LLVoiceClient::LLVoiceClient()
816{
817 gVoiceClient = this;
818 mWriteInProgress = false;
819 mAreaVoiceDisabled = false;
820 mPTT = true;
821 mUserPTTState = false;
822 mMuteMic = false;
823 mSessionTerminateRequested = false;
824 mCommandCookie = 0;
825 mNonSpatialChannel = false;
826 mNextSessionSpatial = true;
827 mNextSessionNoReconnect = false;
828 mSessionP2P = false;
829 mCurrentParcelLocalID = 0;
830 mLoginRetryCount = 0;
831 mVivoxErrorStatusCode = 0;
832
833 mNextSessionResetOnClose = false;
834 mSessionResetOnClose = false;
835 mSpeakerVolume = 0;
836 mMicVolume = 0;
837
838 // Initial dirty state
839 mSpatialCoordsDirty = false;
840 mPTTDirty = true;
841 mVolumeDirty = true;
842 mSpeakerVolumeDirty = true;
843 mMicVolumeDirty = true;
844 mCaptureDeviceDirty = false;
845 mRenderDeviceDirty = false;
846
847 // Load initial state from prefs.
848 mVoiceEnabled = gSavedSettings.getBOOL("EnableVoiceChat");
849 mUsePTT = gSavedSettings.getBOOL("EnablePushToTalk");
850 std::string keyString = gSavedSettings.getString("PushToTalkButton");
851 setPTTKey(keyString);
852 mPTTIsToggle = gSavedSettings.getBOOL("PushToTalkToggle");
853 mEarLocation = gSavedSettings.getS32("VoiceEarLocation");
854 setVoiceVolume(gSavedSettings.getF32("AudioLevelVoice"));
855 std::string captureDevice = gSavedSettings.getString("VoiceInputAudioDevice");
856 setCaptureDevice(captureDevice);
857 std::string renderDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
858 setRenderDevice(renderDevice);
859
860 // Set up our listener to get updates on all prefs values we care about.
861 gSavedSettings.getControl("EnableVoiceChat")->addListener(&voice_prefs_listener);
862 gSavedSettings.getControl("PTTCurrentlyEnabled")->addListener(&voice_prefs_listener);
863 gSavedSettings.getControl("PushToTalkButton")->addListener(&voice_prefs_listener);
864 gSavedSettings.getControl("PushToTalkToggle")->addListener(&voice_prefs_listener);
865 gSavedSettings.getControl("VoiceEarLocation")->addListener(&voice_prefs_listener);
866 gSavedSettings.getControl("VivoxDebugServerName")->addListener(&voice_prefs_listener);
867 gSavedSettings.getControl("VoiceInputAudioDevice")->addListener(&voice_prefs_listener);
868 gSavedSettings.getControl("VoiceOutputAudioDevice")->addListener(&voice_prefs_listener);
869
870 mTuningMode = false;
871 mTuningEnergy = 0.0f;
872 mTuningMicVolume = 0;
873 mTuningMicVolumeDirty = true;
874 mTuningSpeakerVolume = 0;
875 mTuningSpeakerVolumeDirty = true;
876 mTuningCaptureRunning = false;
877
878 // gMuteListp isn't set up at this point, so we defer this until later.
879// gMuteListp->addObserver(&mutelist_listener);
880
881 mParticipantMapChanged = false;
882
883 // stash the pump for later use
884 // This now happens when init() is called instead.
885 mPump = NULL;
886
887#if LL_DARWIN || LL_LINUX
888 // MBW -- XXX -- THIS DOES NOT BELONG HERE
889 // When the vivox daemon dies, the next write attempt on our socket generates a SIGPIPE, which kills us.
890 // This should cause us to ignore SIGPIPE and handle the error through proper channels.
891 // This should really be set up elsewhere. Where should it go?
892 signal(SIGPIPE, SIG_IGN);
893
894 // Since we're now launching the gateway with fork/exec instead of system(), we need to deal with zombie processes.
895 // Ignoring SIGCHLD should prevent zombies from being created. Alternately, we could use wait(), but I'd rather not do that.
896 signal(SIGCHLD, SIG_IGN);
897#endif
898
899 // set up state machine
900 setState(stateDisabled);
901
902 gIdleCallbacks.addFunction(idle, this);
903}
904
905//---------------------------------------------------
906
907LLVoiceClient::~LLVoiceClient()
908{
909}
910
911//----------------------------------------------
912
913
914
915void LLVoiceClient::init(LLPumpIO *pump)
916{
917 // constructor will set up gVoiceClient
918 LLVoiceClient::getInstance()->mPump = pump;
919}
920
921void LLVoiceClient::terminate()
922{
923 if(gVoiceClient)
924 {
925 gVoiceClient->sessionTerminateSendMessage();
926 gVoiceClient->logout();
927 gVoiceClient->connectorShutdown();
928 gVoiceClient->closeSocket(); // Need to do this now -- bad things happen if the destructor does it later.
929
930 // This will do unpleasant things on windows.
931// killGateway();
932
933 // Don't do this anymore -- LLSingleton will take care of deleting the object.
934// delete gVoiceClient;
935
936 // Hint to other code not to access the voice client anymore.
937 gVoiceClient = NULL;
938 }
939}
940
941
942/////////////////////////////
943// utility functions
944
945bool LLVoiceClient::writeString(const std::string &str)
946{
947 bool result = false;
948 if(mConnected)
949 {
950 apr_status_t err;
951 apr_size_t size = (apr_size_t)str.size();
952 apr_size_t written = size;
953
954// llinfos << "sending: " << str << llendl;
955
956 // MBW -- XXX -- check return code - sockets will fail (broken, etc.)
957 err = apr_socket_send(
958 mSocket->getSocket(),
959 (const char*)str.data(),
960 &written);
961
962 if(err == 0)
963 {
964 // Success.
965 result = true;
966 }
967 // MBW -- XXX -- handle partial writes (written is number of bytes written)
968 // Need to set socket to non-blocking before this will work.
969// else if(APR_STATUS_IS_EAGAIN(err))
970// {
971// //
972// }
973 else
974 {
975 // Assume any socket error means something bad. For now, just close the socket.
976 char buf[MAX_STRING];
977 llwarns << "apr error " << err << " ("<< apr_strerror(err, buf, MAX_STRING) << ") sending data to vivox daemon." << llendl;
978 daemonDied();
979 }
980 }
981
982 return result;
983}
984
985
986/////////////////////////////
987// session control messages
988void LLVoiceClient::connectorCreate()
989{
990 std::ostringstream stream;
991 std::string logpath;
992 std::string loglevel = "0";
993
994 // Transition to stateConnectorStarted when the connector handle comes back.
995 setState(stateConnectorStarting);
996
997 std::string savedLogLevel = gSavedSettings.getString("VivoxDebugLevel");
998
999 if(savedLogLevel != "-1")
1000 {
1001 llinfos << "creating connector with logging enabled" << llendl;
1002 loglevel = "10";
1003 logpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
1004 }
1005
1006 stream
1007 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.Create.1\">"
1008 << "<ClientName>V2 SDK</ClientName>"
1009 << "<AccountManagementServer>" << mAccountServerURI << "</AccountManagementServer>"
1010 << "<Logging>"
1011 << "<Enabled>false</Enabled>"
1012 << "<Folder>" << logpath << "</Folder>"
1013 << "<FileNamePrefix>Connector</FileNamePrefix>"
1014 << "<FileNameSuffix>.log</FileNameSuffix>"
1015 << "<LogLevel>" << loglevel << "</LogLevel>"
1016 << "</Logging>"
1017 << "</Request>\n\n\n";
1018
1019 writeString(stream.str());
1020}
1021
1022void LLVoiceClient::connectorShutdown()
1023{
1024 setState(stateConnectorStopping);
1025
1026 if(!mConnectorHandle.empty())
1027 {
1028 std::ostringstream stream;
1029 stream
1030 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.InitiateShutdown.1\">"
1031 << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>"
1032 << "</Request>"
1033 << "\n\n\n";
1034
1035 mConnectorHandle.clear();
1036
1037 writeString(stream.str());
1038 }
1039}
1040
1041void LLVoiceClient::userAuthorized(const std::string& firstName, const std::string& lastName, const LLUUID &agentID)
1042{
1043 mAccountFirstName = firstName;
1044 mAccountLastName = lastName;
1045
1046 mAccountDisplayName = firstName;
1047 mAccountDisplayName += " ";
1048 mAccountDisplayName += lastName;
1049
1050 llinfos << "name \"" << mAccountDisplayName << "\" , ID " << agentID << llendl;
1051
1052 std::string userserver = gUserServerName;
1053 LLString::toLower(userserver);
1054 if((gUserServerChoice == USERSERVER_AGNI) ||
1055 ((gUserServerChoice == USERSERVER_OTHER) && (userserver.find("agni") != std::string::npos)))
1056 {
1057 sConnectingToAgni = true;
1058 }
1059
1060 // MBW -- XXX -- Enable this when the bhd.vivox.com server gets a real ssl cert.
1061 if(sConnectingToAgni)
1062 {
1063 // Use the release account server
1064 mAccountServerName = "bhr.vivox.com";
1065 mAccountServerURI = "https://www." + mAccountServerName + "/api2/";
1066 }
1067 else
1068 {
1069 // Use the development account server
1070 mAccountServerName = gSavedSettings.getString("VivoxDebugServerName");
1071 mAccountServerURI = "https://www." + mAccountServerName + "/api2/";
1072 }
1073
1074 mAccountName = nameFromID(agentID);
1075}
1076
1077void LLVoiceClient::requestVoiceAccountProvision(S32 retries)
1078{
1079 if ( gAgent.getRegion() && mVoiceEnabled )
1080 {
1081 std::string url =
1082 gAgent.getRegion()->getCapability(
1083 "ProvisionVoiceAccountRequest");
1084
1085 if ( url == "" ) return;
1086
1087 LLHTTPClient::post(
1088 url,
1089 LLSD(),
1090 new LLViewerVoiceAccountProvisionResponder(retries));
1091 }
1092}
1093
1094void LLVoiceClient::login(
1095 const std::string& accountName,
1096 const std::string &password)
1097{
1098 if((getState() >= stateLoggingIn) && (getState() < stateLoggedOut))
1099 {
1100 // Already logged in. This is an internal error.
1101 llerrs << "called from wrong state." << llendl;
1102 }
1103 else if ( accountName != mAccountName )
1104 {
1105 //TODO: error?
1106 llinfos << "Wrong account name! " << accountName
1107 << " instead of " << mAccountName << llendl;
1108 }
1109 else
1110 {
1111 mAccountPassword = password;
1112 }
1113}
1114
1115void LLVoiceClient::idle(void* user_data)
1116{
1117 LLVoiceClient* self = (LLVoiceClient*)user_data;
1118 self->stateMachine();
1119}
1120
1121const char *LLVoiceClient::state2string(LLVoiceClient::state inState)
1122{
1123 const char *result = "UNKNOWN";
1124
1125 // Prevent copy-paste errors when updating this list...
1126#define CASE(x) case x: result = #x; break
1127
1128 switch(inState)
1129 {
1130 CASE(stateDisabled);
1131 CASE(stateStart);
1132 CASE(stateDaemonLaunched);
1133 CASE(stateConnecting);
1134 CASE(stateIdle);
1135 CASE(stateConnectorStart);
1136 CASE(stateConnectorStarting);
1137 CASE(stateConnectorStarted);
1138 CASE(stateMicTuningNoLogin);
1139 CASE(stateLoginRetry);
1140 CASE(stateLoginRetryWait);
1141 CASE(stateNeedsLogin);
1142 CASE(stateLoggingIn);
1143 CASE(stateLoggedIn);
1144 CASE(stateNoChannel);
1145 CASE(stateMicTuningLoggedIn);
1146 CASE(stateSessionCreate);
1147 CASE(stateSessionConnect);
1148 CASE(stateJoiningSession);
1149 CASE(stateSessionJoined);
1150 CASE(stateRunning);
1151 CASE(stateLeavingSession);
1152 CASE(stateSessionTerminated);
1153 CASE(stateLoggingOut);
1154 CASE(stateLoggedOut);
1155 CASE(stateConnectorStopping);
1156 CASE(stateConnectorStopped);
1157 CASE(stateConnectorFailed);
1158 CASE(stateConnectorFailedWaiting);
1159 CASE(stateLoginFailed);
1160 CASE(stateLoginFailedWaiting);
1161 CASE(stateJoinSessionFailed);
1162 CASE(stateJoinSessionFailedWaiting);
1163 CASE(stateJail);
1164 }
1165
1166#undef CASE
1167
1168 return result;
1169}
1170
1171const char *LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserver::EStatusType inStatus)
1172{
1173 const char *result = "UNKNOWN";
1174
1175 // Prevent copy-paste errors when updating this list...
1176#define CASE(x) case x: result = #x; break
1177
1178 switch(inStatus)
1179 {
1180 CASE(STATUS_JOINING);
1181 CASE(STATUS_JOINED);
1182 CASE(STATUS_LEFT_CHANNEL);
1183 CASE(ERROR_CHANNEL_FULL);
1184 CASE(ERROR_CHANNEL_LOCKED);
1185 CASE(ERROR_UNKNOWN);
1186 default:
1187 break;
1188 }
1189
1190#undef CASE
1191
1192 return result;
1193}
1194
1195void LLVoiceClient::setState(state inState)
1196{
1197 llinfos << "entering state " << state2string(inState) << llendl;
1198
1199 mState = inState;
1200}
1201
1202void LLVoiceClient::stateMachine()
1203{
1204 if(gDisconnected)
1205 {
1206 // The viewer has been disconnected from the sim. Disable voice.
1207 setVoiceEnabled(false);
1208 }
1209
1210 if(!mVoiceEnabled)
1211 {
1212 if(getState() != stateDisabled)
1213 {
1214 // User turned off voice support. Send the cleanup messages, close the socket, and reset.
1215 if(!mConnected)
1216 {
1217 // if voice was turned off after the daemon was launched but before we could connect to it, we may need to issue a kill.
1218 llinfos << "Disabling voice before connection to daemon, terminating." << llendl;
1219 killGateway();
1220 }
1221
1222 sessionTerminateSendMessage();
1223 logout();
1224 connectorShutdown();
1225 closeSocket();
1226 removeAllParticipants();
1227
1228 setState(stateDisabled);
1229 }
1230 }
1231
1232 // Check for parcel boundary crossing
1233 {
1234 LLViewerRegion *region = gAgent.getRegion();
1235 LLParcel *parcel = NULL;
1236
1237 if(gParcelMgr)
1238 {
1239 parcel = gParcelMgr->getAgentParcel();
1240 }
1241
1242 if(region && parcel)
1243 {
1244 S32 parcelLocalID = parcel->getLocalID();
1245 std::string regionName = region->getName();
1246 std::string capURI = region->getCapability("ParcelVoiceInfoRequest");
1247
1248// llinfos << "Region name = \"" << regionName <<"\", " << "parcel local ID = " << parcelLocalID << llendl;
1249
1250 // The region name starts out empty and gets filled in later.
1251 // Also, the cap gets filled in a short time after the region cross, but a little too late for our purposes.
1252 // If either is empty, wait for the next time around.
1253 if(!regionName.empty() && !capURI.empty())
1254 {
1255 if((parcelLocalID != mCurrentParcelLocalID) || (regionName != mCurrentRegionName))
1256 {
1257 // We have changed parcels. Initiate a parcel channel lookup.
1258 mCurrentParcelLocalID = parcelLocalID;
1259 mCurrentRegionName = regionName;
1260
1261 parcelChanged();
1262 }
1263 }
1264 }
1265 }
1266
1267 switch(getState())
1268 {
1269 case stateDisabled:
1270 if(mVoiceEnabled && (!mAccountName.empty() || mTuningMode))
1271 {
1272 setState(stateStart);
1273 }
1274 break;
1275
1276 case stateStart:
1277 if(gDisableVoice)
1278 {
1279 // Voice is locked out, we must not launch the vivox daemon.
1280 setState(stateJail);
1281 }
1282 else if(!isGatewayRunning())
1283 {
1284 if(true)
1285 {
1286 // Launch the voice daemon
1287 std::string exe_path = gDirUtilp->getAppRODataDir();
1288 exe_path += gDirUtilp->getDirDelimiter();
1289#if LL_WINDOWS
1290 exe_path += "SLVoice.exe";
1291#else
1292 // This will be the same for mac and linux
1293 exe_path += "SLVoice";
1294#endif
1295 // See if the vivox executable exists
1296 llstat s;
1297 if(!LLFile::stat(exe_path.c_str(), &s))
1298 {
1299 // vivox executable exists. Build the command line and launch the daemon.
1300 std::string args = " -p tcp -h -c";
1301 std::string cmd;
1302 std::string loglevel = gSavedSettings.getString("VivoxDebugLevel");
1303
1304 if(loglevel.empty())
1305 {
1306 loglevel = "-1"; // turn logging off completely
1307 }
1308
1309 args += " -ll ";
1310 args += loglevel;
1311
1312// llinfos << "Args for SLVoice: " << args << llendl;
1313
1314#if LL_WINDOWS
1315 PROCESS_INFORMATION pinfo;
1316 STARTUPINFOA sinfo;
1317 memset(&sinfo, 0, sizeof(sinfo));
1318 std::string exe_dir = gDirUtilp->getAppRODataDir();
1319 cmd = "SLVoice.exe";
1320 cmd += args;
1321
1322 // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string...
1323 char *args2 = new char[args.size() + 1];
1324 strcpy(args2, args.c_str());
1325
1326 if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, exe_dir.c_str(), &sinfo, &pinfo))
1327 {
1328// DWORD dwErr = GetLastError();
1329 }
1330 else
1331 {
1332 // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on
1333 // CloseHandle(pinfo.hProcess); // stops leaks - nothing else
1334 sGatewayHandle = pinfo.hProcess;
1335 CloseHandle(pinfo.hThread); // stops leaks - nothing else
1336 }
1337
1338 delete args2;
1339#else // LL_WINDOWS
1340 // This should be the same for mac and linux
1341 {
1342 std::vector<std::string> arglist;
1343 arglist.push_back(exe_path.c_str());
1344
1345 // Split the argument string into separate strings for each argument
1346 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
1347 boost::char_separator<char> sep(" ");
1348 tokenizer tokens(args, sep);
1349 tokenizer::iterator token_iter;
1350
1351 for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
1352 {
1353 arglist.push_back(*token_iter);
1354 }
1355
1356 // create an argv vector for the child process
1357 char **fakeargv = new char*[arglist.size() + 1];
1358 int i;
1359 for(i=0; i < arglist.size(); i++)
1360 fakeargv[i] = const_cast<char*>(arglist[i].c_str());
1361
1362 fakeargv[i] = NULL;
1363
1364 pid_t id = vfork();
1365 if(id == 0)
1366 {
1367 // child
1368 execv(exe_path.c_str(), fakeargv);
1369
1370 // If we reach this point, the exec failed.
1371 // Use _exit() instead of exit() per the vfork man page.
1372 _exit(0);
1373 }
1374
1375 // parent
1376 delete[] fakeargv;
1377 sGatewayPID = id;
1378 }
1379#endif // LL_WINDOWS
1380 mDaemonHost = LLHost("127.0.0.1", 44124);
1381 }
1382 else
1383 {
1384 llinfos << exe_path << "not found." << llendl
1385 }
1386 }
1387 else
1388 {
1389 // We can connect to a client gateway running on another host. This is useful for testing.
1390 // To do this, launch the gateway on a nearby host like this:
1391 // vivox-gw.exe -p tcp -i 0.0.0.0:44124
1392 // and put that host's IP address here.
1393 mDaemonHost = LLHost("127.0.0.1", 44124);
1394 }
1395
1396 mUpdateTimer.start();
1397 mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS);
1398
1399 setState(stateDaemonLaunched);
1400
1401 // Dirty the states we'll need to sync with the daemon when it comes up.
1402 mPTTDirty = true;
1403 mSpeakerVolumeDirty = true;
1404 // These only need to be set if they're not default (i.e. empty string).
1405 mCaptureDeviceDirty = !mCaptureDevice.empty();
1406 mRenderDeviceDirty = !mRenderDevice.empty();
1407 }
1408 break;
1409
1410 case stateDaemonLaunched:
1411// llinfos << "Connecting to vivox daemon" << llendl;
1412 if(mUpdateTimer.hasExpired())
1413 {
1414 mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS);
1415
1416 if(!mSocket)
1417 {
1418 mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
1419 }
1420
1421 mConnected = mSocket->blockingConnect(mDaemonHost);
1422 if(mConnected)
1423 {
1424 setState(stateConnecting);
1425 }
1426 else
1427 {
1428 // If the connect failed, the socket may have been put into a bad state. Delete it.
1429 closeSocket();
1430 }
1431 }
1432 break;
1433
1434 case stateConnecting:
1435 // Can't do this until we have the pump available.
1436 if(mPump)
1437 {
1438 // MBW -- Note to self: pumps and pipes examples in
1439 // indra/test/io.cpp
1440 // indra/test/llpipeutil.{cpp|h}
1441
1442 // Attach the pumps and pipes
1443
1444 LLPumpIO::chain_t readChain;
1445
1446 readChain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(mSocket)));
1447 readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser()));
1448
1449 mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS);
1450
1451 setState(stateIdle);
1452 }
1453
1454 break;
1455
1456 case stateIdle:
1457 // Initial devices query
1458 getCaptureDevicesSendMessage();
1459 getRenderDevicesSendMessage();
1460
1461 mLoginRetryCount = 0;
1462
1463 setState(stateConnectorStart);
1464
1465 break;
1466
1467 case stateConnectorStart:
1468 if(!mVoiceEnabled)
1469 {
1470 // We were never logged in. This will shut down the connector.
1471 setState(stateLoggedOut);
1472 }
1473 else if(!mAccountServerURI.empty())
1474 {
1475 connectorCreate();
1476 }
1477 else if(mTuningMode)
1478 {
1479 setState(stateMicTuningNoLogin);
1480 }
1481 break;
1482
1483 case stateConnectorStarting: // waiting for connector handle
1484 // connectorCreateResponse() will transition from here to stateConnectorStarted.
1485 break;
1486
1487 case stateConnectorStarted: // connector handle received
1488 if(!mVoiceEnabled)
1489 {
1490 // We were never logged in. This will shut down the connector.
1491 setState(stateLoggedOut);
1492 }
1493 else if(!mAccountName.empty())
1494 {
1495 LLViewerRegion *region = gAgent.getRegion();
1496
1497 if(region)
1498 {
1499 if ( region->getCapability("ProvisionVoiceAccountRequest") != "" )
1500 {
1501 if ( mAccountPassword.empty() )
1502 {
1503 requestVoiceAccountProvision();
1504 }
1505 setState(stateNeedsLogin);
1506 }
1507 }
1508 }
1509 break;
1510
1511 case stateMicTuningNoLogin:
1512 case stateMicTuningLoggedIn:
1513 {
1514 // Both of these behave essentially the same. The only difference is where the exit transition goes to.
1515 if(mTuningMode && mVoiceEnabled && !mSessionTerminateRequested)
1516 {
1517 if(!mTuningCaptureRunning)
1518 {
1519 // duration parameter is currently unused, per Mike S.
1520 tuningCaptureStartSendMessage(10000);
1521 }
1522
1523 if(mTuningMicVolumeDirty || mTuningSpeakerVolumeDirty || mCaptureDeviceDirty || mRenderDeviceDirty)
1524 {
1525 std::ostringstream stream;
1526
1527 if(mTuningMicVolumeDirty)
1528 {
1529 stream
1530 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetMicLevel.1\">"
1531 << "<Level>" << mTuningMicVolume << "</Level>"
1532 << "</Request>\n\n\n";
1533 }
1534
1535 if(mTuningSpeakerVolumeDirty)
1536 {
1537 stream
1538 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetSpeakerLevel.1\">"
1539 << "<Level>" << mTuningSpeakerVolume << "</Level>"
1540 << "</Request>\n\n\n";
1541 }
1542
1543 if(mCaptureDeviceDirty)
1544 {
1545 buildSetCaptureDevice(stream);
1546 }
1547
1548 if(mRenderDeviceDirty)
1549 {
1550 buildSetRenderDevice(stream);
1551 }
1552
1553 mTuningMicVolumeDirty = false;
1554 mTuningSpeakerVolumeDirty = false;
1555 mCaptureDeviceDirty = false;
1556 mRenderDeviceDirty = false;
1557
1558 if(!stream.str().empty())
1559 {
1560 writeString(stream.str());
1561 }
1562 }
1563 }
1564 else
1565 {
1566 // transition out of mic tuning
1567 if(mTuningCaptureRunning)
1568 {
1569 tuningCaptureStopSendMessage();
1570 }
1571
1572 if(getState() == stateMicTuningNoLogin)
1573 {
1574 setState(stateConnectorStart);
1575 }
1576 else
1577 {
1578 setState(stateNoChannel);
1579 }
1580 }
1581 }
1582 break;
1583
1584 case stateLoginRetry:
1585 if(mLoginRetryCount == 0)
1586 {
1587 // First retry -- display a message to the user
1588 notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGIN_RETRY);
1589 }
1590
1591 mLoginRetryCount++;
1592
1593 if(mLoginRetryCount > MAX_LOGIN_RETRIES)
1594 {
1595 llinfos << "too many login retries, giving up." << llendl;
1596 setState(stateLoginFailed);
1597 }
1598 else
1599 {
1600 llinfos << "will retry login in " << LOGIN_RETRY_SECONDS << " seconds." << llendl;
1601 mUpdateTimer.start();
1602 mUpdateTimer.setTimerExpirySec(LOGIN_RETRY_SECONDS);
1603 setState(stateLoginRetryWait);
1604 }
1605 break;
1606
1607 case stateLoginRetryWait:
1608 if(mUpdateTimer.hasExpired())
1609 {
1610 setState(stateNeedsLogin);
1611 }
1612 break;
1613
1614 case stateNeedsLogin:
1615 if(!mAccountPassword.empty())
1616 {
1617 setState(stateLoggingIn);
1618 loginSendMessage();
1619 }
1620 break;
1621
1622 case stateLoggingIn: // waiting for account handle
1623 // loginResponse() will transition from here to stateLoggedIn.
1624 break;
1625
1626 case stateLoggedIn: // account handle received
1627 // Initial kick-off of channel lookup logic
1628 parcelChanged();
1629
1630 notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGGED_IN);
1631
1632 // Set up the mute list observer if it hasn't been set up already.
1633 if((!sMuteListListener_listening) && (gMuteListp))
1634 {
1635 gMuteListp->addObserver(&mutelist_listener);
1636 sMuteListListener_listening = true;
1637 }
1638
1639 setState(stateNoChannel);
1640 break;
1641
1642 case stateNoChannel:
1643 if(mSessionTerminateRequested || !mVoiceEnabled)
1644 {
1645 // MBW -- XXX -- Is this the right way out of this state?
1646 setState(stateSessionTerminated);
1647 }
1648 else if(mTuningMode)
1649 {
1650 setState(stateMicTuningLoggedIn);
1651 }
1652 else if(!mNextSessionHandle.empty())
1653 {
1654 setState(stateSessionConnect);
1655 }
1656 else if(!mNextSessionURI.empty())
1657 {
1658 setState(stateSessionCreate);
1659 }
1660 break;
1661
1662 case stateSessionCreate:
1663 sessionCreateSendMessage();
1664 notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING);
1665 setState(stateJoiningSession);
1666 break;
1667
1668 case stateSessionConnect:
1669 sessionConnectSendMessage();
1670 notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING);
1671 setState(stateJoiningSession);
1672 break;
1673
1674 case stateJoiningSession: // waiting for session handle
1675 // sessionCreateResponse() will transition from here to stateSessionJoined.
1676 if(!mVoiceEnabled)
1677 {
1678 // User bailed out during connect -- jump straight to teardown.
1679 setState(stateSessionTerminated);
1680 }
1681 else if(mSessionTerminateRequested)
1682 {
1683 if(!mSessionHandle.empty())
1684 {
1685 // Only allow direct exits from this state in p2p calls (for cancelling an invite).
1686 // Terminating a half-connected session on other types of calls seems to break something in the vivox gateway.
1687 if(mSessionP2P)
1688 {
1689 sessionTerminateSendMessage();
1690 setState(stateSessionTerminated);
1691 }
1692 }
1693 }
1694 break;
1695
1696 case stateSessionJoined: // session handle received
1697 // MBW -- XXX -- It appears that I need to wait for BOTH the Session.Create response and the SessionStateChangeEvent with state 4
1698 // before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck.
1699 // For now, the Session.Create response handler sets mSessionHandle and the SessionStateChangeEvent handler transitions to stateSessionJoined.
1700 // This is a cheap way to make sure both have happened before proceeding.
1701 if(!mSessionHandle.empty())
1702 {
1703 // Events that need to happen when a session is joined could go here.
1704 // Maybe send initial spatial data?
1705 notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED);
1706
1707 // Dirty state that may need to be sync'ed with the daemon.
1708 mPTTDirty = true;
1709 mSpeakerVolumeDirty = true;
1710 mSpatialCoordsDirty = true;
1711
1712 setState(stateRunning);
1713
1714 // Start the throttle timer
1715 mUpdateTimer.start();
1716 mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS);
1717 }
1718 else if(!mVoiceEnabled)
1719 {
1720 // User bailed out during connect -- jump straight to teardown.
1721 setState(stateSessionTerminated);
1722 }
1723 else if(mSessionTerminateRequested)
1724 {
1725 // Only allow direct exits from this state in p2p calls (for cancelling an invite).
1726 // Terminating a half-connected session on other types of calls seems to break something in the vivox gateway.
1727 if(mSessionP2P)
1728 {
1729 sessionTerminateSendMessage();
1730 setState(stateSessionTerminated);
1731 }
1732 }
1733 break;
1734
1735 case stateRunning: // steady state
1736 // sessionTerminateSendMessage() will transition from here to stateLeavingSession
1737
1738 // Disabling voice or disconnect requested.
1739 if(!mVoiceEnabled || mSessionTerminateRequested)
1740 {
1741 sessionTerminateSendMessage();
1742 }
1743 else
1744 {
1745
1746 // Figure out whether the PTT state needs to change
1747 {
1748 bool newPTT;
1749 if(mUsePTT)
1750 {
1751 // If configured to use PTT, track the user state.
1752 newPTT = mUserPTTState;
1753 }
1754 else
1755 {
1756 // If not configured to use PTT, it should always be true (otherwise the user will be unable to speak).
1757 newPTT = true;
1758 }
1759
1760 if(mMuteMic)
1761 {
1762 // This always overrides any other PTT setting.
1763 newPTT = false;
1764 }
1765
1766 // Dirty if state changed.
1767 if(newPTT != mPTT)
1768 {
1769 mPTT = newPTT;
1770 mPTTDirty = true;
1771 }
1772 }
1773
1774 if(mNonSpatialChannel)
1775 {
1776 // When in a non-spatial channel, never send positional updates.
1777 mSpatialCoordsDirty = false;
1778 }
1779 else
1780 {
1781 // Do the calculation that enforces the listener<->speaker tether (and also updates the real camera position)
1782 enforceTether();
1783 }
1784
1785 // Send an update if the ptt state has changed (which shouldn't be able to happen that often -- the user can only click so fast)
1786 // or every 10hz, whichever is sooner.
1787 if(mVolumeDirty || mPTTDirty || mSpeakerVolumeDirty || mUpdateTimer.hasExpired())
1788 {
1789 mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS);
1790 sendPositionalUpdate();
1791 }
1792 }
1793 break;
1794
1795 case stateLeavingSession: // waiting for terminate session response
1796 // The handler for the Session.Terminate response will transition from here to stateSessionTerminated.
1797 break;
1798
1799 case stateSessionTerminated:
1800 // Always reset the terminate request flag when we get here.
1801 mSessionTerminateRequested = false;
1802
1803 notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
1804
1805 if(mVoiceEnabled)
1806 {
1807 // SPECIAL CASE: if going back to spatial but in a parcel with an empty URI, transfer the non-spatial flag now.
1808 // This fixes the case where you come out of a group chat in a parcel with voice disabled, and get stuck unable to rejoin spatial chat thereafter.
1809 if(mNextSessionSpatial && mNextSessionURI.empty())
1810 {
1811 mNonSpatialChannel = !mNextSessionSpatial;
1812 }
1813
1814 // Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state).
1815 setState(stateNoChannel);
1816 }
1817 else
1818 {
1819 // Shutting down voice, continue with disconnecting.
1820 logout();
1821 }
1822
1823 break;
1824
1825 case stateLoggingOut: // waiting for logout response
1826 // The handler for the Account.Logout response will transition from here to stateLoggedOut.
1827 break;
1828 case stateLoggedOut: // logout response received
1829 // shut down the connector
1830 connectorShutdown();
1831 break;
1832
1833 case stateConnectorStopping: // waiting for connector stop
1834 // The handler for the Connector.InitiateShutdown response will transition from here to stateConnectorStopped.
1835 break;
1836
1837 case stateConnectorStopped: // connector stop received
1838 // Clean up and reset everything.
1839 closeSocket();
1840 removeAllParticipants();
1841 setState(stateDisabled);
1842 break;
1843
1844 case stateConnectorFailed:
1845 setState(stateConnectorFailedWaiting);
1846 break;
1847 case stateConnectorFailedWaiting:
1848 break;
1849
1850 case stateLoginFailed:
1851 setState(stateLoginFailedWaiting);
1852 break;
1853 case stateLoginFailedWaiting:
1854 // No way to recover from these. Yet.
1855 break;
1856
1857 case stateJoinSessionFailed:
1858 // Transition to error state. Send out any notifications here.
1859 llwarns << "stateJoinSessionFailed: (" << mVivoxErrorStatusCode << "): " << mVivoxErrorStatusString << llendl;
1860 notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN);
1861 setState(stateJoinSessionFailedWaiting);
1862 break;
1863
1864 case stateJoinSessionFailedWaiting:
1865 // Joining a channel failed, either due to a failed channel name -> sip url lookup or an error from the join message.
1866 // Region crossings may leave this state and try the join again.
1867 if(mSessionTerminateRequested)
1868 {
1869 setState(stateSessionTerminated);
1870 }
1871 break;
1872
1873 case stateJail:
1874 // We have given up. Do nothing.
1875 break;
1876 }
1877
1878 if(mParticipantMapChanged)
1879 {
1880 mParticipantMapChanged = false;
1881 notifyObservers();
1882 }
1883
1884}
1885
1886void LLVoiceClient::closeSocket(void)
1887{
1888 mSocket.reset();
1889 mConnected = false;
1890}
1891
1892void LLVoiceClient::loginSendMessage()
1893{
1894 std::ostringstream stream;
1895 stream
1896 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.Login.1\">"
1897 << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>"
1898 << "<AccountName>" << mAccountName << "</AccountName>"
1899 << "<AccountPassword>" << mAccountPassword << "</AccountPassword>"
1900 << "<AudioSessionAnswerMode>VerifyAnswer</AudioSessionAnswerMode>"
1901 << "</Request>\n\n\n";
1902
1903 writeString(stream.str());
1904}
1905
1906void LLVoiceClient::logout()
1907{
1908 mAccountPassword = "";
1909 setState(stateLoggingOut);
1910 logoutSendMessage();
1911}
1912
1913void LLVoiceClient::logoutSendMessage()
1914{
1915 if(!mAccountHandle.empty())
1916 {
1917 std::ostringstream stream;
1918 stream
1919 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.Logout.1\">"
1920 << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
1921 << "</Request>"
1922 << "\n\n\n";
1923
1924 mAccountHandle.clear();
1925
1926 writeString(stream.str());
1927 }
1928}
1929
1930void LLVoiceClient::channelGetListSendMessage()
1931{
1932 std::ostringstream stream;
1933 stream
1934 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.ChannelGetList.1\">"
1935 << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
1936 << "</Request>\n\n\n";
1937
1938 writeString(stream.str());
1939}
1940
1941void LLVoiceClient::sessionCreateSendMessage()
1942{
1943 llinfos << "requesting join: " << mNextSessionURI << llendl;
1944
1945 mSessionURI = mNextSessionURI;
1946 mNonSpatialChannel = !mNextSessionSpatial;
1947 mSessionResetOnClose = mNextSessionResetOnClose;
1948 mNextSessionResetOnClose = false;
1949 if(mNextSessionNoReconnect)
1950 {
1951 // Clear the stashed URI so it can't reconnect
1952 mNextSessionURI.clear();
1953 }
1954 // Only p2p sessions are created with "no reconnect".
1955 mSessionP2P = mNextSessionNoReconnect;
1956
1957 std::ostringstream stream;
1958 stream
1959 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Create.1\">"
1960 << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
1961 << "<URI>" << mSessionURI << "</URI>";
1962
1963 static const std::string allowed_chars =
1964 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
1965 "0123456789"
1966 "-._~";
1967
1968 if(!mNextSessionHash.empty())
1969 {
1970 stream
1971 << "<Password>" << LLURI::escape(mNextSessionHash, allowed_chars) << "</Password>"
1972 << "<PasswordHashAlgorithm>SHA1UserName</PasswordHashAlgorithm>";
1973 }
1974
1975 stream
1976 << "<Name>" << mChannelName << "</Name>"
1977 << "</Request>\n\n\n";
1978 writeString(stream.str());
1979}
1980
1981void LLVoiceClient::sessionConnectSendMessage()
1982{
1983 llinfos << "connecting to session handle: " << mNextSessionHandle << llendl;
1984
1985 mSessionHandle = mNextSessionHandle;
1986 mSessionURI = mNextP2PSessionURI;
1987 mNextSessionHandle.clear(); // never want to re-use these.
1988 mNextP2PSessionURI.clear();
1989 mNonSpatialChannel = !mNextSessionSpatial;
1990 mSessionResetOnClose = mNextSessionResetOnClose;
1991 mNextSessionResetOnClose = false;
1992 // Joining by session ID is only used to answer p2p invitations, so we know this is a p2p session.
1993 mSessionP2P = true;
1994
1995 std::ostringstream stream;
1996
1997 stream
1998 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Connect.1\">"
1999 << "<SessionHandle>" << mSessionHandle << "</SessionHandle>"
2000 << "<AudioMedia>default</AudioMedia>"
2001 << "</Request>\n\n\n";
2002 writeString(stream.str());
2003}
2004
2005void LLVoiceClient::sessionTerminate()
2006{
2007 mSessionTerminateRequested = true;
2008}
2009
2010void LLVoiceClient::sessionTerminateSendMessage()
2011{
2012 llinfos << "leaving session: " << mSessionURI << llendl;
2013
2014 switch(getState())
2015 {
2016 case stateNoChannel:
2017 // In this case, we want to pretend the join failed so our state machine doesn't get stuck.
2018 // Skip the join failed transition state so we don't send out error notifications.
2019 setState(stateJoinSessionFailedWaiting);
2020 break;
2021 case stateJoiningSession:
2022 case stateSessionJoined:
2023 case stateRunning:
2024 if(!mSessionHandle.empty())
2025 {
2026 sessionTerminateByHandle(mSessionHandle);
2027 setState(stateLeavingSession);
2028 }
2029 else
2030 {
2031 llwarns << "called with no session handle" << llendl;
2032 setState(stateSessionTerminated);
2033 }
2034 break;
2035 case stateJoinSessionFailed:
2036 case stateJoinSessionFailedWaiting:
2037 setState(stateSessionTerminated);
2038 break;
2039
2040 default:
2041 llwarns << "called from unknown state" << llendl;
2042 break;
2043 }
2044}
2045
2046void LLVoiceClient::sessionTerminateByHandle(std::string &sessionHandle)
2047{
2048 llinfos << "Sending Session.Terminate with handle " << sessionHandle << llendl;
2049
2050 std::ostringstream stream;
2051 stream
2052 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Terminate.1\">"
2053 << "<SessionHandle>" << sessionHandle << "</SessionHandle>"
2054 << "</Request>"
2055 << "\n\n\n";
2056
2057 writeString(stream.str());
2058}
2059
2060void LLVoiceClient::getCaptureDevicesSendMessage()
2061{
2062 std::ostringstream stream;
2063 stream
2064 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.GetCaptureDevices.1\">"
2065 << "</Request>\n\n\n";
2066
2067 writeString(stream.str());
2068}
2069
2070void LLVoiceClient::getRenderDevicesSendMessage()
2071{
2072 std::ostringstream stream;
2073 stream
2074 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.GetRenderDevices.1\">"
2075 << "</Request>\n\n\n";
2076
2077 writeString(stream.str());
2078}
2079
2080void LLVoiceClient::clearCaptureDevices()
2081{
2082 // MBW -- XXX -- do something here
2083 llinfos << "called" << llendl;
2084 mCaptureDevices.clear();
2085}
2086
2087void LLVoiceClient::addCaptureDevice(const std::string& name)
2088{
2089 // MBW -- XXX -- do something here
2090 llinfos << name << llendl;
2091
2092 mCaptureDevices.push_back(name);
2093}
2094
2095LLVoiceClient::deviceList *LLVoiceClient::getCaptureDevices()
2096{
2097 return &mCaptureDevices;
2098}
2099
2100void LLVoiceClient::setCaptureDevice(const std::string& name)
2101{
2102 if(name == "Default")
2103 {
2104 if(!mCaptureDevice.empty())
2105 {
2106 mCaptureDevice.clear();
2107 mCaptureDeviceDirty = true;
2108 }
2109 }
2110 else
2111 {
2112 if(mCaptureDevice != name)
2113 {
2114 mCaptureDevice = name;
2115 mCaptureDeviceDirty = true;
2116 }
2117 }
2118}
2119
2120void LLVoiceClient::clearRenderDevices()
2121{
2122 // MBW -- XXX -- do something here
2123 llinfos << "called" << llendl;
2124 mRenderDevices.clear();
2125}
2126
2127void LLVoiceClient::addRenderDevice(const std::string& name)
2128{
2129 // MBW -- XXX -- do something here
2130 llinfos << name << llendl;
2131 mRenderDevices.push_back(name);
2132}
2133
2134LLVoiceClient::deviceList *LLVoiceClient::getRenderDevices()
2135{
2136 return &mRenderDevices;
2137}
2138
2139void LLVoiceClient::setRenderDevice(const std::string& name)
2140{
2141 if(name == "Default")
2142 {
2143 if(!mRenderDevice.empty())
2144 {
2145 mRenderDevice.clear();
2146 mRenderDeviceDirty = true;
2147 }
2148 }
2149 else
2150 {
2151 if(mRenderDevice != name)
2152 {
2153 mRenderDevice = name;
2154 mRenderDeviceDirty = true;
2155 }
2156 }
2157
2158}
2159
2160void LLVoiceClient::tuningStart()
2161{
2162 mTuningMode = true;
2163 if(getState() >= stateNoChannel)
2164 {
2165 sessionTerminate();
2166 }
2167}
2168
2169void LLVoiceClient::tuningStop()
2170{
2171 mTuningMode = false;
2172}
2173
2174bool LLVoiceClient::inTuningMode()
2175{
2176 bool result = false;
2177 switch(getState())
2178 {
2179 case stateMicTuningNoLogin:
2180 case stateMicTuningLoggedIn:
2181 result = true;
2182 default:
2183 break;
2184 }
2185 return result;
2186}
2187
2188void LLVoiceClient::tuningRenderStartSendMessage(const std::string& name, bool loop)
2189{
2190 if(!inTuningMode())
2191 return;
2192
2193 mTuningAudioFile = name;
2194 std::ostringstream stream;
2195 stream
2196 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.RenderAudioStart.1\">"
2197 << "<SoundFilePath>" << mTuningAudioFile << "</SoundFilePath>"
2198 << "<Loop>" << (loop?"1":"0") << "</Loop>"
2199 << "</Request>\n\n\n";
2200
2201 writeString(stream.str());
2202}
2203
2204void LLVoiceClient::tuningRenderStopSendMessage()
2205{
2206 if(!inTuningMode())
2207 return;
2208
2209 std::ostringstream stream;
2210 stream
2211 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.RenderAudioStop.1\">"
2212 << "<SoundFilePath>" << mTuningAudioFile << "</SoundFilePath>"
2213 << "</Request>\n\n\n";
2214
2215 writeString(stream.str());
2216}
2217
2218void LLVoiceClient::tuningCaptureStartSendMessage(int duration)
2219{
2220 if(!inTuningMode())
2221 return;
2222
2223 std::ostringstream stream;
2224 stream
2225 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.CaptureAudioStart.1\">"
2226 << "<Duration>" << duration << "</Duration>"
2227 << "</Request>\n\n\n";
2228
2229 writeString(stream.str());
2230
2231 mTuningCaptureRunning = true;
2232}
2233
2234void LLVoiceClient::tuningCaptureStopSendMessage()
2235{
2236 if(!inTuningMode())
2237 return;
2238
2239 std::ostringstream stream;
2240 stream
2241 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.CaptureAudioStop.1\">"
2242 << "</Request>\n\n\n";
2243
2244 writeString(stream.str());
2245
2246 mTuningCaptureRunning = false;
2247}
2248
2249void LLVoiceClient::tuningSetMicVolume(float volume)
2250{
2251 int scaledVolume = ((int)(volume * 100.0f)) - 100;
2252 if(scaledVolume != mTuningMicVolume)
2253 {
2254 mTuningMicVolume = scaledVolume;
2255 mTuningMicVolumeDirty = true;
2256 }
2257}
2258
2259void LLVoiceClient::tuningSetSpeakerVolume(float volume)
2260{
2261 int scaledVolume = ((int)(volume * 100.0f)) - 100;
2262 if(scaledVolume != mTuningSpeakerVolume)
2263 {
2264 mTuningSpeakerVolume = ((int)(volume * 100.0f)) - 100;
2265 mTuningSpeakerVolumeDirty = true;
2266 }
2267}
2268
2269float LLVoiceClient::tuningGetEnergy(void)
2270{
2271 return mTuningEnergy;
2272}
2273
2274bool LLVoiceClient::deviceSettingsAvailable()
2275{
2276 bool result = true;
2277
2278 if(!mConnected)
2279 result = false;
2280
2281 if(mRenderDevices.empty())
2282 result = false;
2283
2284 return result;
2285}
2286
2287void LLVoiceClient::refreshDeviceLists(bool clearCurrentList)
2288{
2289 if(clearCurrentList)
2290 {
2291 clearCaptureDevices();
2292 clearRenderDevices();
2293 }
2294 getCaptureDevicesSendMessage();
2295 getRenderDevicesSendMessage();
2296}
2297
2298void LLVoiceClient::daemonDied()
2299{
2300 // The daemon died, so the connection is gone. Reset everything and start over.
2301 llwarns << "Connection to vivox daemon lost. Resetting state."<< llendl;
2302
2303 closeSocket();
2304 removeAllParticipants();
2305
2306 // Try to relaunch the daemon
2307 setState(stateDisabled);
2308}
2309
2310void LLVoiceClient::giveUp()
2311{
2312 // All has failed. Clean up and stop trying.
2313 closeSocket();
2314 removeAllParticipants();
2315
2316 setState(stateJail);
2317}
2318
2319void LLVoiceClient::sendPositionalUpdate(void)
2320{
2321 std::ostringstream stream;
2322
2323 if(mSpatialCoordsDirty)
2324 {
2325 LLVector3 l, u, a;
2326
2327 // Always send both speaker and listener positions together.
2328 stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Set3DPosition.1\">"
2329 << "<SessionHandle>" << mSessionHandle << "</SessionHandle>";
2330
2331 stream << "<SpeakerPosition>";
2332
2333 l = mAvatarRot.getLeftRow();
2334 u = mAvatarRot.getUpRow();
2335 a = mAvatarRot.getFwdRow();
2336
2337// llinfos << "Sending speaker position " << mSpeakerPosition << llendl;
2338
2339 stream
2340 << "<Position>"
2341 << "<X>" << mAvatarPosition[VX] << "</X>"
2342 << "<Y>" << mAvatarPosition[VZ] << "</Y>"
2343 << "<Z>" << mAvatarPosition[VY] << "</Z>"
2344 << "</Position>"
2345 << "<Velocity>"
2346 << "<X>" << mAvatarVelocity[VX] << "</X>"
2347 << "<Y>" << mAvatarVelocity[VZ] << "</Y>"
2348 << "<Z>" << mAvatarVelocity[VY] << "</Z>"
2349 << "</Velocity>"
2350 << "<AtOrientation>"
2351 << "<X>" << l.mV[VX] << "</X>"
2352 << "<Y>" << u.mV[VX] << "</Y>"
2353 << "<Z>" << a.mV[VX] << "</Z>"
2354 << "</AtOrientation>"
2355 << "<UpOrientation>"
2356 << "<X>" << l.mV[VZ] << "</X>"
2357 << "<Y>" << u.mV[VY] << "</Y>"
2358 << "<Z>" << a.mV[VZ] << "</Z>"
2359 << "</UpOrientation>"
2360 << "<LeftOrientation>"
2361 << "<X>" << l.mV [VY] << "</X>"
2362 << "<Y>" << u.mV [VZ] << "</Y>"
2363 << "<Z>" << a.mV [VY] << "</Z>"
2364 << "</LeftOrientation>";
2365
2366 stream << "</SpeakerPosition>";
2367
2368 stream << "<ListenerPosition>";
2369
2370 LLVector3d earPosition;
2371 LLVector3 earVelocity;
2372 LLMatrix3 earRot;
2373
2374 switch(mEarLocation)
2375 {
2376 case earLocCamera:
2377 default:
2378 earPosition = mCameraPosition;
2379 earVelocity = mCameraVelocity;
2380 earRot = mCameraRot;
2381 break;
2382
2383 case earLocAvatar:
2384 earPosition = mAvatarPosition;
2385 earVelocity = mAvatarVelocity;
2386 earRot = mAvatarRot;
2387 break;
2388
2389 case earLocMixed:
2390 earPosition = mAvatarPosition;
2391 earVelocity = mAvatarVelocity;
2392 earRot = mCameraRot;
2393 break;
2394 }
2395
2396 l = earRot.getLeftRow();
2397 u = earRot.getUpRow();
2398 a = earRot.getFwdRow();
2399
2400// llinfos << "Sending listener position " << mListenerPosition << llendl;
2401
2402 stream
2403 << "<Position>"
2404 << "<X>" << earPosition[VX] << "</X>"
2405 << "<Y>" << earPosition[VZ] << "</Y>"
2406 << "<Z>" << earPosition[VY] << "</Z>"
2407 << "</Position>"
2408 << "<Velocity>"
2409 << "<X>" << earVelocity[VX] << "</X>"
2410 << "<Y>" << earVelocity[VZ] << "</Y>"
2411 << "<Z>" << earVelocity[VY] << "</Z>"
2412 << "</Velocity>"
2413 << "<AtOrientation>"
2414 << "<X>" << l.mV[VX] << "</X>"
2415 << "<Y>" << u.mV[VX] << "</Y>"
2416 << "<Z>" << a.mV[VX] << "</Z>"
2417 << "</AtOrientation>"
2418 << "<UpOrientation>"
2419 << "<X>" << l.mV[VZ] << "</X>"
2420 << "<Y>" << u.mV[VY] << "</Y>"
2421 << "<Z>" << a.mV[VZ] << "</Z>"
2422 << "</UpOrientation>"
2423 << "<LeftOrientation>"
2424 << "<X>" << l.mV [VY] << "</X>"
2425 << "<Y>" << u.mV [VZ] << "</Y>"
2426 << "<Z>" << a.mV [VY] << "</Z>"
2427 << "</LeftOrientation>";
2428
2429 stream << "</ListenerPosition>";
2430
2431 stream << "</Request>\n\n\n";
2432 }
2433
2434 if(mPTTDirty)
2435 {
2436 // Send a local mute command.
2437 // NOTE that the state of "PTT" is the inverse of "local mute".
2438 // (i.e. when PTT is true, we send a mute command with "false", and vice versa)
2439
2440// llinfos << "Sending MuteLocalMic command with parameter " << (mPTT?"false":"true") << llendl;
2441
2442 stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalMic.1\">"
2443 << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>"
2444 << "<Value>" << (mPTT?"false":"true") << "</Value>"
2445 << "</Request>\n\n\n";
2446
2447 }
2448
2449 if(mVolumeDirty)
2450 {
2451 participantMap::iterator iter = mParticipantMap.begin();
2452
2453 for(; iter != mParticipantMap.end(); iter++)
2454 {
2455 participantState *p = iter->second;
2456
2457 if(p->mVolumeDirty)
2458 {
2459 int volume = p->mOnMuteList?0:p->mUserVolume;
2460
2461 llinfos << "Setting volume for avatar " << p->mAvatarID << " to " << volume << llendl;
2462
2463 // Send a mute/unumte command for the user (actually "volume for me").
2464 stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.SetParticipantVolumeForMe.1\">"
2465 << "<SessionHandle>" << mSessionHandle << "</SessionHandle>"
2466 << "<ParticipantURI>" << p->mURI << "</ParticipantURI>"
2467 << "<Volume>" << volume << "</Volume>"
2468 << "</Request>\n\n\n";
2469
2470 p->mVolumeDirty = false;
2471 }
2472 }
2473 }
2474
2475 if(mSpeakerMuteDirty)
2476 {
2477 const char *muteval = ((mSpeakerVolume == -100)?"true":"false");
2478 llinfos << "Setting speaker mute to " << muteval << llendl;
2479
2480 stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalSpeaker.1\">"
2481 << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>"
2482 << "<Value>" << muteval << "</Value>"
2483 << "</Request>\n\n\n";
2484 }
2485
2486 if(mSpeakerVolumeDirty)
2487 {
2488 llinfos << "Setting speaker volume to " << mSpeakerVolume << llendl;
2489
2490 stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.SetLocalSpeakerVolume.1\">"
2491 << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>"
2492 << "<Value>" << mSpeakerVolume << "</Value>"
2493 << "</Request>\n\n\n";
2494 }
2495
2496 if(mMicVolumeDirty)
2497 {
2498 llinfos << "Setting mic volume to " << mMicVolume << llendl;
2499
2500 stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.SetLocalMicVolume.1\">"
2501 << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>"
2502 << "<Value>" << mMicVolume << "</Value>"
2503 << "</Request>\n\n\n";
2504 }
2505
2506
2507 // MBW -- XXX -- Maybe check to make sure the capture/render devices are in the current list here?
2508 if(mCaptureDeviceDirty)
2509 {
2510 buildSetCaptureDevice(stream);
2511 }
2512
2513 if(mRenderDeviceDirty)
2514 {
2515 buildSetRenderDevice(stream);
2516 }
2517
2518 mSpatialCoordsDirty = false;
2519 mPTTDirty = false;
2520 mVolumeDirty = false;
2521 mSpeakerVolumeDirty = false;
2522 mMicVolumeDirty = false;
2523 mSpeakerMuteDirty = false;
2524 mCaptureDeviceDirty = false;
2525 mRenderDeviceDirty = false;
2526
2527 if(!stream.str().empty())
2528 {
2529 writeString(stream.str());
2530 }
2531}
2532
2533void LLVoiceClient::buildSetCaptureDevice(std::ostringstream &stream)
2534{
2535 llinfos << "Setting input device = \"" << mCaptureDevice << "\"" << llendl;
2536
2537 stream
2538 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetCaptureDevice.1\">"
2539 << "<CaptureDeviceSpecifier>" << mCaptureDevice << "</CaptureDeviceSpecifier>"
2540 << "</Request>"
2541 << "\n\n\n";
2542}
2543
2544void LLVoiceClient::buildSetRenderDevice(std::ostringstream &stream)
2545{
2546 llinfos << "Setting output device = \"" << mRenderDevice << "\"" << llendl;
2547
2548 stream
2549 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetRenderDevice.1\">"
2550 << "<RenderDeviceSpecifier>" << mRenderDevice << "</RenderDeviceSpecifier>"
2551 << "</Request>"
2552 << "\n\n\n";
2553}
2554
2555/////////////////////////////
2556// Response/Event handlers
2557
2558void LLVoiceClient::connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle)
2559{
2560 if(statusCode != 0)
2561 {
2562 llwarns << "Connector.Create response failure: " << statusString << llendl;
2563 setState(stateConnectorFailed);
2564 }
2565 else
2566 {
2567 // Connector created, move forward.
2568 mConnectorHandle = connectorHandle;
2569 if(getState() == stateConnectorStarting)
2570 {
2571 setState(stateConnectorStarted);
2572 }
2573 }
2574}
2575
2576void LLVoiceClient::loginResponse(int statusCode, std::string &statusString, std::string &accountHandle)
2577{
2578 llinfos << "Account.Login response (" << statusCode << "): " << statusString << llendl;
2579
2580 // Status code of 20200 means "bad password". We may want to special-case that at some point.
2581
2582 if ( statusCode == 401 )
2583 {
2584 // Login failure which is probably caused by the delay after a user's password being updated.
2585 llinfos << "Account.Login response failure (" << statusCode << "): " << statusString << llendl;
2586 setState(stateLoginRetry);
2587 }
2588 else if(statusCode != 0)
2589 {
2590 llwarns << "Account.Login response failure (" << statusCode << "): " << statusString << llendl;
2591 setState(stateLoginFailed);
2592 }
2593 else
2594 {
2595 // Login succeeded, move forward.
2596 mAccountHandle = accountHandle;
2597 // MBW -- XXX -- This needs to wait until the LoginStateChangeEvent is received.
2598// if(getState() == stateLoggingIn)
2599// {
2600// setState(stateLoggedIn);
2601// }
2602 }
2603}
2604
2605void LLVoiceClient::channelGetListResponse(int statusCode, std::string &statusString)
2606{
2607 if(statusCode != 0)
2608 {
2609 llwarns << "Account.ChannelGetList response failure: " << statusString << llendl;
2610 switchChannel();
2611 }
2612 else
2613 {
2614 // Got the channel list, try to do a lookup.
2615 std::string uri = findChannelURI(mChannelName);
2616 if(uri.empty())
2617 {
2618 // Lookup failed, can't join a channel for this area.
2619 llinfos << "failed to map channel name: " << mChannelName << llendl;
2620 }
2621 else
2622 {
2623 // We have a sip URL for this area.
2624 llinfos << "mapped channel " << mChannelName << " to URI "<< uri << llendl;
2625 }
2626
2627 // switchChannel with an empty uri string will do the right thing (leave channel and not rejoin)
2628 switchChannel(uri);
2629 }
2630}
2631
2632void LLVoiceClient::sessionCreateResponse(int statusCode, std::string &statusString, std::string &sessionHandle)
2633{
2634 if(statusCode != 0)
2635 {
2636 llwarns << "Session.Create response failure (" << statusCode << "): " << statusString << llendl;
2637// if(statusCode == 1015)
2638// {
2639// if(getState() == stateJoiningSession)
2640// {
2641// // this happened during a real join. Going to sessionTerminated should cause a retry in appropriate cases.
2642// llwarns << "session handle \"" << sessionHandle << "\", mSessionStateEventHandle \"" << mSessionStateEventHandle << "\""<< llendl;
2643// if(!sessionHandle.empty())
2644// {
2645// // This session is bad. Terminate it.
2646// mSessionHandle = sessionHandle;
2647// sessionTerminateByHandle(sessionHandle);
2648// setState(stateLeavingSession);
2649// }
2650// else if(!mSessionStateEventHandle.empty())
2651// {
2652// mSessionHandle = mSessionStateEventHandle;
2653// sessionTerminateByHandle(mSessionStateEventHandle);
2654// setState(stateLeavingSession);
2655// }
2656// else
2657// {
2658// setState(stateSessionTerminated);
2659// }
2660// }
2661// else
2662// {
2663// // We didn't think we were in the middle of a join. Don't change state.
2664// llwarns << "Not in stateJoiningSession, ignoring" << llendl;
2665// }
2666// }
2667// else
2668 {
2669 mVivoxErrorStatusCode = statusCode;
2670 mVivoxErrorStatusString = statusString;
2671 setState(stateJoinSessionFailed);
2672 }
2673 }
2674 else
2675 {
2676 llinfos << "Session.Create response received (success), session handle is " << sessionHandle << llendl;
2677 if(getState() == stateJoiningSession)
2678 {
2679 // This is also grabbed in the SessionStateChangeEvent handler, but it might be useful to have it early...
2680 mSessionHandle = sessionHandle;
2681 }
2682 else
2683 {
2684 // We should never get a session.create response in any state except stateJoiningSession. Things are out of sync. Kill this session.
2685 sessionTerminateByHandle(sessionHandle);
2686 }
2687 }
2688}
2689
2690void LLVoiceClient::sessionConnectResponse(int statusCode, std::string &statusString)
2691{
2692 if(statusCode != 0)
2693 {
2694 llwarns << "Session.Connect response failure (" << statusCode << "): " << statusString << llendl;
2695// if(statusCode == 1015)
2696// {
2697// llwarns << "terminating existing session" << llendl;
2698// sessionTerminate();
2699// }
2700// else
2701 {
2702 mVivoxErrorStatusCode = statusCode;
2703 mVivoxErrorStatusString = statusString;
2704 setState(stateJoinSessionFailed);
2705 }
2706 }
2707 else
2708 {
2709 llinfos << "Session.Connect response received (success)" << llendl;
2710 }
2711}
2712
2713void LLVoiceClient::sessionTerminateResponse(int statusCode, std::string &statusString)
2714{
2715 if(statusCode != 0)
2716 {
2717 llwarns << "Session.Terminate response failure: (" << statusCode << "): " << statusString << llendl;
2718 if(getState() == stateLeavingSession)
2719 {
2720 // This is probably "(404): Server reporting Failure. Not a member of this conference."
2721 // Do this so we don't get stuck.
2722 setState(stateSessionTerminated);
2723 }
2724 }
2725
2726}
2727
2728void LLVoiceClient::logoutResponse(int statusCode, std::string &statusString)
2729{
2730 if(statusCode != 0)
2731 {
2732 llwarns << "Account.Logout response failure: " << statusString << llendl;
2733 // MBW -- XXX -- Should this ever fail? do we care if it does?
2734 }
2735
2736 if(getState() == stateLoggingOut)
2737 {
2738 setState(stateLoggedOut);
2739 }
2740}
2741
2742void LLVoiceClient::connectorShutdownResponse(int statusCode, std::string &statusString)
2743{
2744 if(statusCode != 0)
2745 {
2746 llwarns << "Connector.InitiateShutdown response failure: " << statusString << llendl;
2747 // MBW -- XXX -- Should this ever fail? do we care if it does?
2748 }
2749
2750 mConnected = false;
2751
2752 if(getState() == stateConnectorStopping)
2753 {
2754 setState(stateConnectorStopped);
2755 }
2756}
2757
2758void LLVoiceClient::sessionStateChangeEvent(
2759 std::string &uriString,
2760 int statusCode,
2761 std::string &statusString,
2762 std::string &sessionHandle,
2763 int state,
2764 bool isChannel,
2765 std::string &nameString)
2766{
2767 switch(state)
2768 {
2769 case 4: // I see this when joining the session
2770 llinfos << "joined session " << uriString << ", name " << nameString << " handle " << mNextSessionHandle << llendl;
2771
2772 // Session create succeeded, move forward.
2773 mSessionStateEventHandle = sessionHandle;
2774 mSessionStateEventURI = uriString;
2775 if(sessionHandle == mSessionHandle)
2776 {
2777 // This is the session we're joining.
2778 if(getState() == stateJoiningSession)
2779 {
2780 setState(stateSessionJoined);
2781 //RN: the uriString being returned by vivox here is actually your account uri, not the channel
2782 // you are attempting to join, so ignore it
2783 //llinfos << "received URI " << uriString << "(previously " << mSessionURI << ")" << llendl;
2784 //mSessionURI = uriString;
2785 }
2786 }
2787 else if(sessionHandle == mNextSessionHandle)
2788 {
2789// llinfos << "received URI " << uriString << ", name " << nameString << " for next session (handle " << mNextSessionHandle << ")" << llendl;
2790 }
2791 else
2792 {
2793 llwarns << "joining unknown session handle " << sessionHandle << ", URI " << uriString << ", name " << nameString << llendl;
2794 // MBW -- XXX -- Should we send a Session.Terminate here?
2795 }
2796
2797 break;
2798 case 5: // I see this when leaving the session
2799 llinfos << "left session " << uriString << ", name " << nameString << " handle " << mNextSessionHandle << llendl;
2800
2801 // Set the session handle to the empty string. If we get back to stateJoiningSession, we'll want to wait for the new session handle.
2802 if(sessionHandle == mSessionHandle)
2803 {
2804 // MBW -- XXX -- I think this is no longer necessary, now that we've got mNextSessionURI/mNextSessionHandle
2805 // mSessionURI.clear();
2806 // clear the session handle here just for sanity.
2807 mSessionHandle.clear();
2808 if(mSessionResetOnClose)
2809 {
2810 mSessionResetOnClose = false;
2811 mNonSpatialChannel = false;
2812 mNextSessionSpatial = true;
2813 parcelChanged();
2814 }
2815
2816 removeAllParticipants();
2817
2818 switch(getState())
2819 {
2820 case stateJoiningSession:
2821 case stateSessionJoined:
2822 case stateRunning:
2823 case stateLeavingSession:
2824 case stateJoinSessionFailed:
2825 case stateJoinSessionFailedWaiting:
2826 // normal transition
2827 llinfos << "left session " << sessionHandle << "in state " << state2string(getState()) << llendl;
2828 setState(stateSessionTerminated);
2829 break;
2830
2831 case stateSessionTerminated:
2832 // this will happen sometimes -- there are cases where we send the terminate and then go straight to this state.
2833 llwarns << "left session " << sessionHandle << "in state " << state2string(getState()) << llendl;
2834 break;
2835
2836 default:
2837 llwarns << "unexpected SessionStateChangeEvent (left session) in state " << state2string(getState()) << llendl;
2838 setState(stateSessionTerminated);
2839 break;
2840 }
2841
2842 // store status values for later notification of observers
2843 mVivoxErrorStatusCode = statusCode;
2844 mVivoxErrorStatusString = statusString;
2845 }
2846 else
2847 {
2848 llinfos << "leaving unknown session handle " << sessionHandle << ", URI " << uriString << ", name " << nameString << llendl;
2849 }
2850
2851 mSessionStateEventHandle.clear();
2852 mSessionStateEventURI.clear();
2853 break;
2854 default:
2855 llwarns << "unknown state: " << state << llendl;
2856 break;
2857 }
2858}
2859
2860void LLVoiceClient::loginStateChangeEvent(
2861 std::string &accountHandle,
2862 int statusCode,
2863 std::string &statusString,
2864 int state)
2865{
2866 llinfos << "state is " << state << llendl;
2867 /*
2868 According to Mike S., status codes for this event are:
2869 login_state_logged_out=0,
2870 login_state_logged_in = 1,
2871 login_state_logging_in = 2,
2872 login_state_logging_out = 3,
2873 login_state_resetting = 4,
2874 login_state_error=100
2875 */
2876
2877 switch(state)
2878 {
2879 case 1:
2880 if(getState() == stateLoggingIn)
2881 {
2882 setState(stateLoggedIn);
2883 }
2884 break;
2885
2886 default:
2887// llwarns << "unknown state: " << state << llendl;
2888 break;
2889 }
2890}
2891
2892void LLVoiceClient::sessionNewEvent(
2893 std::string &accountHandle,
2894 std::string &eventSessionHandle,
2895 int state,
2896 std::string &nameString,
2897 std::string &uriString)
2898{
2899// llinfos << "state is " << state << llendl;
2900
2901 switch(state)
2902 {
2903 case 0:
2904 {
2905 llinfos << "session handle = " << eventSessionHandle << ", name = " << nameString << ", uri = " << uriString << llendl;
2906
2907 LLUUID caller_id;
2908 if(IDFromName(nameString, caller_id))
2909 {
2910 gIMMgr->inviteToSession(LLIMMgr::computeSessionID(IM_SESSION_P2P_INVITE, caller_id),
2911 LLString::null,
2912 caller_id,
2913 LLString::null,
2914 IM_SESSION_P2P_INVITE,
2915 eventSessionHandle);
2916 }
2917 else
2918 {
2919 llwarns << "Could not generate caller id from uri " << uriString << llendl;
2920 }
2921 }
2922 break;
2923
2924 default:
2925 llwarns << "unknown state: " << state << llendl;
2926 break;
2927 }
2928}
2929
2930void LLVoiceClient::participantStateChangeEvent(
2931 std::string &uriString,
2932 int statusCode,
2933 std::string &statusString,
2934 int state,
2935 std::string &nameString,
2936 std::string &displayNameString,
2937 int participantType)
2938{
2939 participantState *participant = NULL;
2940 llinfos << "state is " << state << llendl;
2941
2942 switch(state)
2943 {
2944 case 7: // I see this when a participant joins
2945 participant = addParticipant(uriString);
2946 if(participant)
2947 {
2948 participant->mName = nameString;
2949 llinfos << "added participant \"" << participant->mName
2950 << "\" (" << participant->mAvatarID << ")"<< llendl;
2951 }
2952 break;
2953 case 9: // I see this when a participant leaves
2954 participant = findParticipant(uriString);
2955 if(participant)
2956 {
2957 removeParticipant(participant);
2958 }
2959 break;
2960 default:
2961// llwarns << "unknown state: " << state << llendl;
2962 break;
2963 }
2964}
2965
2966void LLVoiceClient::participantPropertiesEvent(
2967 std::string &uriString,
2968 int statusCode,
2969 std::string &statusString,
2970 bool isLocallyMuted,
2971 bool isModeratorMuted,
2972 bool isSpeaking,
2973 int volume,
2974 F32 energy)
2975{
2976 participantState *participant = findParticipant(uriString);
2977 if(participant)
2978 {
2979 participant->mPTT = !isLocallyMuted;
2980 participant->mIsSpeaking = isSpeaking;
2981 if (isSpeaking)
2982 {
2983 participant->mSpeakingTimeout.reset();
2984 }
2985 participant->mPower = energy;
2986 participant->mVolume = volume;
2987 }
2988 else
2989 {
2990 llwarns << "unknown participant: " << uriString << llendl;
2991 }
2992}
2993
2994void LLVoiceClient::auxAudioPropertiesEvent(F32 energy)
2995{
2996// llinfos << "got energy " << energy << llendl;
2997 mTuningEnergy = energy;
2998}
2999
3000void LLVoiceClient::muteListChanged()
3001{
3002 // The user's mute list has been updated. Go through the current participant list and sync it with the mute list.
3003
3004 participantMap::iterator iter = mParticipantMap.begin();
3005
3006 for(; iter != mParticipantMap.end(); iter++)
3007 {
3008 participantState *p = iter->second;
3009
3010 // Check to see if this participant is on the mute list already
3011 updateMuteState(p);
3012 }
3013}
3014
3015/////////////////////////////
3016// Managing list of participants
3017LLVoiceClient::participantState::participantState(const std::string &uri) :
3018 mURI(uri), mPTT(false), mIsSpeaking(false), mPower(0.0), mServiceType(serviceTypeUnknown),
3019 mOnMuteList(false), mUserVolume(100), mVolumeDirty(false), mAvatarIDValid(false)
3020{
3021}
3022
3023LLVoiceClient::participantState *LLVoiceClient::addParticipant(const std::string &uri)
3024{
3025 participantState *result = NULL;
3026
3027 participantMap::iterator iter = mParticipantMap.find(uri);
3028
3029 if(iter != mParticipantMap.end())
3030 {
3031 // Found a matching participant already in the map.
3032 result = iter->second;
3033 }
3034
3035 if(!result)
3036 {
3037 // participant isn't already in one list or the other.
3038 result = new participantState(uri);
3039 mParticipantMap.insert(participantMap::value_type(uri, result));
3040 mParticipantMapChanged = true;
3041
3042 // Try to do a reverse transform on the URI to get the GUID back.
3043 {
3044 LLUUID id;
3045 if(IDFromName(uri, id))
3046 {
3047 result->mAvatarIDValid = true;
3048 result->mAvatarID = id;
3049
3050 updateMuteState(result);
3051 }
3052 }
3053
3054 llinfos << "participant \"" << result->mURI << "\" added." << llendl;
3055 }
3056
3057 return result;
3058}
3059
3060void LLVoiceClient::updateMuteState(participantState *p)
3061{
3062 if(p->mAvatarIDValid)
3063 {
3064 bool isMuted = gMuteListp->isMuted(p->mAvatarID, LLMute::flagVoiceChat);
3065 if(p->mOnMuteList != isMuted)
3066 {
3067 p->mOnMuteList = isMuted;
3068 p->mVolumeDirty = true;
3069 mVolumeDirty = true;
3070 }
3071 }
3072}
3073
3074void LLVoiceClient::removeParticipant(LLVoiceClient::participantState *participant)
3075{
3076 if(participant)
3077 {
3078 participantMap::iterator iter = mParticipantMap.find(participant->mURI);
3079
3080 llinfos << "participant \"" << participant->mURI << "\" (" << participant->mAvatarID << ") removed." << llendl;
3081
3082 mParticipantMap.erase(iter);
3083 delete participant;
3084 mParticipantMapChanged = true;
3085 }
3086}
3087
3088void LLVoiceClient::removeAllParticipants()
3089{
3090 llinfos << "called" << llendl;
3091
3092 while(!mParticipantMap.empty())
3093 {
3094 removeParticipant(mParticipantMap.begin()->second);
3095 }
3096}
3097
3098LLVoiceClient::participantMap *LLVoiceClient::getParticipantList(void)
3099{
3100 return &mParticipantMap;
3101}
3102
3103
3104LLVoiceClient::participantState *LLVoiceClient::findParticipant(const std::string &uri)
3105{
3106 participantState *result = NULL;
3107
3108 // Don't find any participants if we're not connected. This is so that we don't continue to get stale data
3109 // after the daemon dies.
3110 if(mConnected)
3111 {
3112 participantMap::iterator iter = mParticipantMap.find(uri);
3113
3114 if(iter != mParticipantMap.end())
3115 {
3116 result = iter->second;
3117 }
3118 }
3119
3120 return result;
3121}
3122
3123
3124LLVoiceClient::participantState *LLVoiceClient::findParticipantByAvatar(LLVOAvatar *avatar)
3125{
3126 participantState * result = NULL;
3127
3128 // You'd think this would work, but it doesn't...
3129// std::string uri = sipURIFromAvatar(avatar);
3130
3131 // Currently, the URI is just the account name.
3132 std::string loginName = nameFromAvatar(avatar);
3133 result = findParticipant(loginName);
3134
3135 if(result != NULL)
3136 {
3137 if(!result->mAvatarIDValid)
3138 {
3139 result->mAvatarID = avatar->getID();
3140 result->mAvatarIDValid = true;
3141
3142 // We just figured out the avatar ID, so the participant list has "changed" from the perspective of anyone who uses that to identify participants.
3143 mParticipantMapChanged = true;
3144
3145 updateMuteState(result);
3146 }
3147
3148
3149 }
3150
3151 return result;
3152}
3153
3154LLVoiceClient::participantState* LLVoiceClient::findParticipantByID(const LLUUID& id)
3155{
3156 participantState * result = NULL;
3157
3158 // Currently, the URI is just the account name.
3159 std::string loginName = nameFromID(id);
3160 result = findParticipant(loginName);
3161
3162 return result;
3163}
3164
3165
3166void LLVoiceClient::clearChannelMap(void)
3167{
3168 mChannelMap.clear();
3169}
3170
3171void LLVoiceClient::addChannelMapEntry(std::string &name, std::string &uri)
3172{
3173// llinfos << "Adding channel name mapping: " << name << " -> " << uri << llendl;
3174 mChannelMap.insert(channelMap::value_type(name, uri));
3175}
3176
3177std::string LLVoiceClient::findChannelURI(std::string &name)
3178{
3179 std::string result;
3180
3181 channelMap::iterator iter = mChannelMap.find(name);
3182
3183 if(iter != mChannelMap.end())
3184 {
3185 result = iter->second;
3186 }
3187
3188 return result;
3189}
3190
3191void LLVoiceClient::parcelChanged()
3192{
3193 if(getState() >= stateLoggedIn)
3194 {
3195 // If the user is logged in, start a channel lookup.
3196 llinfos << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << llendl;
3197
3198 std::string url = gAgent.getRegion()->getCapability("ParcelVoiceInfoRequest");
3199 LLSD data;
3200 data["method"] = "call";
3201 LLHTTPClient::post(
3202 url,
3203 data,
3204 new LLVoiceClientCapResponder);
3205 }
3206 else
3207 {
3208 // The transition to stateLoggedIn needs to kick this off again.
3209 llinfos << "not logged in yet, deferring" << llendl;
3210 }
3211}
3212
3213void LLVoiceClient::switchChannel(
3214 std::string uri,
3215 bool spatial,
3216 bool noReconnect,
3217 std::string hash)
3218{
3219 bool needsSwitch = false;
3220
3221 llinfos << "called in state " << state2string(getState()) << " with uri \"" << uri << "\"" << llendl;
3222
3223 switch(getState())
3224 {
3225 case stateJoinSessionFailed:
3226 case stateJoinSessionFailedWaiting:
3227 case stateNoChannel:
3228 // Always switch to the new URI from these states.
3229 needsSwitch = true;
3230 break;
3231
3232 default:
3233 if(mSessionTerminateRequested)
3234 {
3235 // If a terminate has been requested, we need to compare against where the URI we're already headed to.
3236 if(mNextSessionURI != uri)
3237 needsSwitch = true;
3238 }
3239 else
3240 {
3241 // Otherwise, compare against the URI we're in now.
3242 if(mSessionURI != uri)
3243 needsSwitch = true;
3244 }
3245 break;
3246 }
3247
3248 if(needsSwitch)
3249 {
3250 mNextSessionURI = uri;
3251 mNextSessionHash = hash;
3252 mNextSessionHandle.clear();
3253 mNextP2PSessionURI.clear();
3254 mNextSessionSpatial = spatial;
3255 mNextSessionNoReconnect = noReconnect;
3256
3257 if(uri.empty())
3258 {
3259 // Leave any channel we may be in
3260 llinfos << "leaving channel" << llendl;
3261 }
3262 else
3263 {
3264 llinfos << "switching to channel " << uri << llendl;
3265 }
3266
3267 if(getState() <= stateNoChannel)
3268 {
3269 // We're already set up to join a channel, just needed to fill in the session URI
3270 }
3271 else
3272 {
3273 // State machine will come around and rejoin if uri/handle is not empty.
3274 sessionTerminate();
3275 }
3276 }
3277}
3278
3279void LLVoiceClient::joinSession(std::string handle, std::string uri)
3280{
3281 mNextSessionURI.clear();
3282 mNextSessionHash.clear();
3283 mNextP2PSessionURI = uri;
3284 mNextSessionHandle = handle;
3285 mNextSessionSpatial = false;
3286 mNextSessionNoReconnect = false;
3287
3288 if(getState() <= stateNoChannel)
3289 {
3290 // We're already set up to join a channel, just needed to fill in the session handle
3291 }
3292 else
3293 {
3294 // State machine will come around and rejoin if uri/handle is not empty.
3295 sessionTerminate();
3296 }
3297}
3298
3299void LLVoiceClient::setNonSpatialChannel(
3300 const std::string &uri,
3301 const std::string &credentials)
3302{
3303 switchChannel(uri, false, false, credentials);
3304}
3305
3306void LLVoiceClient::setSpatialChannel(
3307 const std::string &uri,
3308 const std::string &credentials)
3309{
3310 mSpatialSessionURI = uri;
3311 mAreaVoiceDisabled = mSpatialSessionURI.empty();
3312
3313 llinfos << "got spatial channel uri: \"" << uri << "\"" << llendl;
3314
3315 if(mNonSpatialChannel || !mNextSessionSpatial)
3316 {
3317 // User is in a non-spatial chat or joining a non-spatial chat. Don't switch channels.
3318 llinfos << "in non-spatial chat, not switching channels" << llendl;
3319 }
3320 else
3321 {
3322 switchChannel(mSpatialSessionURI, true, false, credentials);
3323 }
3324}
3325
3326void LLVoiceClient::callUser(LLUUID &uuid)
3327{
3328 std::string userURI = sipURIFromID(uuid);
3329
3330 switchChannel(userURI, false, true);
3331}
3332
3333void LLVoiceClient::answerInvite(std::string &sessionHandle, LLUUID& other_user_id)
3334{
3335 joinSession(sessionHandle, sipURIFromID(other_user_id));
3336}
3337
3338void LLVoiceClient::declineInvite(std::string &sessionHandle)
3339{
3340 sessionTerminateByHandle(sessionHandle);
3341}
3342
3343void LLVoiceClient::leaveNonSpatialChannel()
3344{
3345 switchChannel(mSpatialSessionURI);
3346}
3347
3348std::string LLVoiceClient::getCurrentChannel()
3349{
3350 if((getState() == stateRunning) && !mSessionTerminateRequested)
3351 {
3352 return mSessionURI;
3353 }
3354
3355 return "";
3356}
3357
3358bool LLVoiceClient::inProximalChannel()
3359{
3360 bool result = false;
3361
3362 if((getState() == stateRunning) && !mSessionTerminateRequested)
3363 {
3364 result = !mNonSpatialChannel;
3365 }
3366
3367 return result;
3368}
3369
3370std::string LLVoiceClient::sipURIFromID(const LLUUID &id)
3371{
3372 std::string result;
3373 result = "sip:";
3374 result += nameFromID(id);
3375 result += "@";
3376 result += mAccountServerName;
3377
3378 return result;
3379}
3380
3381std::string LLVoiceClient::sipURIFromAvatar(LLVOAvatar *avatar)
3382{
3383 std::string result;
3384 if(avatar)
3385 {
3386 result = "sip:";
3387 result += nameFromID(avatar->getID());
3388 result += "@";
3389 result += mAccountServerName;
3390 }
3391
3392 return result;
3393}
3394
3395std::string LLVoiceClient::nameFromAvatar(LLVOAvatar *avatar)
3396{
3397 std::string result;
3398 if(avatar)
3399 {
3400 result = nameFromID(avatar->getID());
3401 }
3402 return result;
3403}
3404
3405std::string LLVoiceClient::nameFromID(const LLUUID &uuid)
3406{
3407 std::string result;
3408 U8 rawuuid[UUID_BYTES + 1];
3409 uuid.toCompressedString((char*)rawuuid);
3410
3411 // Prepending this apparently prevents conflicts with reserved names inside the vivox and diamondware code.
3412 result = "x";
3413
3414 // Base64 encode and replace the pieces of base64 that are less compatible
3415 // with e-mail local-parts.
3416 // See RFC-4648 "Base 64 Encoding with URL and Filename Safe Alphabet"
3417 result += LLBase64::encode(rawuuid, UUID_BYTES);
3418 LLString::replaceChar(result, '+', '-');
3419 LLString::replaceChar(result, '/', '_');
3420
3421 // If you need to transform a GUID to this form on the Mac OS X command line, this will do so:
3422 // echo -n x && (echo e669132a-6c43-4ee1-a78d-6c82fff59f32 |xxd -r -p |openssl base64|tr '/+' '_-')
3423
3424 return result;
3425}
3426
3427bool LLVoiceClient::IDFromName(const std::string name, LLUUID &uuid)
3428{
3429 bool result = false;
3430
3431 // This will only work if the name is of the proper form.
3432 // As an example, the account name for Monroe Linden (UUID 1673cfd3-8229-4445-8d92-ec3570e5e587) is:
3433 // "xFnPP04IpREWNkuw1cOXlhw=="
3434
3435 if((name.size() == 25) && (name[0] == 'x') && (name[23] == '=') && (name[24] == '='))
3436 {
3437 // The name appears to have the right form.
3438
3439 // Reverse the transforms done by nameFromID
3440 std::string temp = name;
3441 LLString::replaceChar(temp, '-', '+');
3442 LLString::replaceChar(temp, '_', '/');
3443
3444 U8 rawuuid[UUID_BYTES + 1];
3445 int len = apr_base64_decode_binary(rawuuid, temp.c_str() + 1);
3446 if(len == UUID_BYTES)
3447 {
3448 // The decode succeeded. Stuff the bits into the result's UUID
3449 // MBW -- XXX -- there's no analogue of LLUUID::toCompressedString that allows you to set a UUID from binary data.
3450 // The data field is public, so we cheat thusly:
3451 memcpy(uuid.mData, rawuuid, UUID_BYTES);
3452 result = true;
3453 }
3454 }
3455
3456 return result;
3457}
3458
3459std::string LLVoiceClient::displayNameFromAvatar(LLVOAvatar *avatar)
3460{
3461 return avatar->getFullname();
3462}
3463
3464std::string LLVoiceClient::sipURIFromName(std::string &name)
3465{
3466 std::string result;
3467 result = "sip:";
3468 result += name;
3469 result += "@";
3470 result += mAccountServerName;
3471
3472// LLString::toLower(result);
3473
3474 return result;
3475}
3476
3477/////////////////////////////
3478// Sending updates of current state
3479
3480void LLVoiceClient::enforceTether(void)
3481{
3482 LLVector3d tethered = mCameraRequestedPosition;
3483
3484 // constrain 'tethered' to within 50m of mAvatarPosition.
3485 {
3486 F32 max_dist = 50.0f;
3487 LLVector3d camera_offset = mCameraRequestedPosition - mAvatarPosition;
3488 F32 camera_distance = (F32)camera_offset.magVec();
3489 if(camera_distance > max_dist)
3490 {
3491 tethered = mAvatarPosition +
3492 (max_dist / camera_distance) * camera_offset;
3493 }
3494 }
3495
3496 if(dist_vec(mCameraPosition, tethered) > 0.1)
3497 {
3498 mCameraPosition = tethered;
3499 mSpatialCoordsDirty = true;
3500 }
3501}
3502
3503void LLVoiceClient::setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot)
3504{
3505 mCameraRequestedPosition = position;
3506
3507 if(mCameraVelocity != velocity)
3508 {
3509 mCameraVelocity = velocity;
3510 mSpatialCoordsDirty = true;
3511 }
3512
3513 if(mCameraRot != rot)
3514 {
3515 mCameraRot = rot;
3516 mSpatialCoordsDirty = true;
3517 }
3518}
3519
3520void LLVoiceClient::setAvatarPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot)
3521{
3522 if(dist_vec(mAvatarPosition, position) > 0.1)
3523 {
3524 mAvatarPosition = position;
3525 mSpatialCoordsDirty = true;
3526 }
3527
3528 if(mAvatarVelocity != velocity)
3529 {
3530 mAvatarVelocity = velocity;
3531 mSpatialCoordsDirty = true;
3532 }
3533
3534 if(mAvatarRot != rot)
3535 {
3536 mAvatarRot = rot;
3537 mSpatialCoordsDirty = true;
3538 }
3539}
3540
3541bool LLVoiceClient::channelFromRegion(LLViewerRegion *region, std::string &name)
3542{
3543 bool result = false;
3544
3545 if(region)
3546 {
3547 name = region->getName();
3548 }
3549
3550 if(!name.empty())
3551 result = true;
3552
3553 return result;
3554}
3555
3556void LLVoiceClient::leaveChannel(void)
3557{
3558 if(getState() == stateRunning)
3559 {
3560// llinfos << "leaving channel for teleport/logout" << llendl;
3561 mChannelName.clear();
3562 sessionTerminate();
3563 }
3564}
3565
3566void LLVoiceClient::setMuteMic(bool muted)
3567{
3568 mMuteMic = muted;
3569}
3570
3571void LLVoiceClient::setUserPTTState(bool ptt)
3572{
3573 mUserPTTState = ptt;
3574}
3575
3576bool LLVoiceClient::getUserPTTState()
3577{
3578 return mUserPTTState;
3579}
3580
3581void LLVoiceClient::toggleUserPTTState(void)
3582{
3583 mUserPTTState = !mUserPTTState;
3584}
3585
3586void LLVoiceClient::setVoiceEnabled(bool enabled)
3587{
3588 if (enabled != mVoiceEnabled)
3589 {
3590 mVoiceEnabled = enabled;
3591 if (enabled)
3592 {
3593 LLVoiceChannel::getCurrentVoiceChannel()->activate();
3594 }
3595 else
3596 {
3597 // for now, leave active channel, to auto join when turning voice back on
3598 //LLVoiceChannel::getCurrentVoiceChannel->deactivate();
3599 }
3600 }
3601}
3602
3603bool LLVoiceClient::voiceEnabled()
3604{
3605 return gSavedSettings.getBOOL("EnableVoiceChat") && !gDisableVoice;
3606}
3607
3608void LLVoiceClient::setUsePTT(bool usePTT)
3609{
3610 if(usePTT && !mUsePTT)
3611 {
3612 // When the user turns on PTT, reset the current state.
3613 mUserPTTState = false;
3614 }
3615 mUsePTT = usePTT;
3616}
3617
3618void LLVoiceClient::setPTTIsToggle(bool PTTIsToggle)
3619{
3620 if(!PTTIsToggle && mPTTIsToggle)
3621 {
3622 // When the user turns off toggle, reset the current state.
3623 mUserPTTState = false;
3624 }
3625
3626 mPTTIsToggle = PTTIsToggle;
3627}
3628
3629
3630void LLVoiceClient::setPTTKey(std::string &key)
3631{
3632 if(key == "MiddleMouse")
3633 {
3634 mPTTIsMiddleMouse = true;
3635 }
3636 else
3637 {
3638 mPTTIsMiddleMouse = false;
3639 if(!LLKeyboard::keyFromString(key, &mPTTKey))
3640 {
3641 // If the call failed, don't match any key.
3642 key = KEY_NONE;
3643 }
3644 }
3645}
3646
3647void LLVoiceClient::setEarLocation(S32 loc)
3648{
3649 if(mEarLocation != loc)
3650 {
3651 llinfos << "Setting mEarLocation to " << loc << llendl;
3652
3653 mEarLocation = loc;
3654 mSpatialCoordsDirty = true;
3655 }
3656}
3657
3658void LLVoiceClient::setVoiceVolume(F32 volume)
3659{
3660 int scaledVolume = ((int)(volume * 100.0f)) - 100;
3661 if(scaledVolume != mSpeakerVolume)
3662 {
3663 if((scaledVolume == -100) || (mSpeakerVolume == -100))
3664 {
3665 mSpeakerMuteDirty = true;
3666 }
3667
3668 mSpeakerVolume = scaledVolume;
3669 mSpeakerVolumeDirty = true;
3670 }
3671}
3672
3673void LLVoiceClient::setMicGain(F32 volume)
3674{
3675 int scaledVolume = ((int)(volume * 100.0f)) - 100;
3676 if(scaledVolume != mMicVolume)
3677 {
3678 mMicVolume = scaledVolume;
3679 mMicVolumeDirty = true;
3680 }
3681}
3682
3683void LLVoiceClient::setVivoxDebugServerName(std::string &serverName)
3684{
3685 if(!mAccountServerName.empty())
3686 {
3687 // The name has been filled in already, which means we know whether we're connecting to agni or not.
3688 if(!sConnectingToAgni)
3689 {
3690 // Only use the setting if we're connecting to a development grid -- always use bhr when on agni.
3691 mAccountServerName = serverName;
3692 }
3693 }
3694}
3695
3696void LLVoiceClient::keyDown(KEY key, MASK mask)
3697{
3698// llinfos << "key is " << LLKeyboard::stringFromKey(key) << llendl;
3699
3700 if (gKeyboard->getKeyRepeated(key))
3701 {
3702 // ignore auto-repeat keys
3703 return;
3704 }
3705
3706 if(!mPTTIsMiddleMouse)
3707 {
3708 if(mPTTIsToggle)
3709 {
3710 if(key == mPTTKey)
3711 {
3712 toggleUserPTTState();
3713 }
3714 }
3715 else if(mPTTKey != KEY_NONE)
3716 {
3717 setUserPTTState(gKeyboard->getKeyDown(mPTTKey));
3718 }
3719 }
3720}
3721void LLVoiceClient::keyUp(KEY key, MASK mask)
3722{
3723 if(!mPTTIsMiddleMouse)
3724 {
3725 if(!mPTTIsToggle && (mPTTKey != KEY_NONE))
3726 {
3727 setUserPTTState(gKeyboard->getKeyDown(mPTTKey));
3728 }
3729 }
3730}
3731void LLVoiceClient::middleMouseState(bool down)
3732{
3733 if(mPTTIsMiddleMouse)
3734 {
3735 if(mPTTIsToggle)
3736 {
3737 if(down)
3738 {
3739 toggleUserPTTState();
3740 }
3741 }
3742 else
3743 {
3744 setUserPTTState(down);
3745 }
3746 }
3747}
3748
3749/////////////////////////////
3750// Accessors for data related to nearby speakers
3751BOOL LLVoiceClient::getVoiceEnabled(const LLUUID& id)
3752{
3753 BOOL result = FALSE;
3754 participantState *participant = findParticipantByID(id);
3755 if(participant)
3756 {
3757 // I'm not sure what the semantics of this should be.
3758 // For now, if we have any data about the user that came through the chat channel, assume they're voice-enabled.
3759 result = TRUE;
3760 }
3761
3762 return result;
3763}
3764
3765BOOL LLVoiceClient::getIsSpeaking(const LLUUID& id)
3766{
3767 BOOL result = FALSE;
3768
3769 participantState *participant = findParticipantByID(id);
3770 if(participant)
3771 {
3772 if (participant->mSpeakingTimeout.getElapsedTimeF32() > SPEAKING_TIMEOUT)
3773 {
3774 participant->mIsSpeaking = FALSE;
3775 }
3776 result = participant->mIsSpeaking;
3777 }
3778
3779 return result;
3780}
3781
3782F32 LLVoiceClient::getCurrentPower(const LLUUID& id)
3783{
3784 F32 result = 0;
3785 participantState *participant = findParticipantByID(id);
3786 if(participant)
3787 {
3788 result = participant->mPower;
3789 }
3790
3791 return result;
3792}
3793
3794
3795LLString LLVoiceClient::getDisplayName(const LLUUID& id)
3796{
3797 LLString result;
3798 participantState *participant = findParticipantByID(id);
3799 if(participant)
3800 {
3801 result = participant->mDisplayName;
3802 }
3803
3804 return result;
3805}
3806
3807
3808BOOL LLVoiceClient::getUsingPTT(const LLUUID& id)
3809{
3810 BOOL result = FALSE;
3811
3812 participantState *participant = findParticipantByID(id);
3813 if(participant)
3814 {
3815 // I'm not sure what the semantics of this should be.
3816 // Does "using PTT" mean they're configured with a push-to-talk button?
3817 // For now, we know there's no PTT mechanism in place, so nobody is using it.
3818 }
3819
3820 return result;
3821}
3822
3823BOOL LLVoiceClient::getPTTPressed(const LLUUID& id)
3824{
3825 BOOL result = FALSE;
3826
3827 participantState *participant = findParticipantByID(id);
3828 if(participant)
3829 {
3830 result = participant->mPTT;
3831 }
3832
3833 return result;
3834}
3835
3836BOOL LLVoiceClient::getOnMuteList(const LLUUID& id)
3837{
3838 BOOL result = FALSE;
3839
3840 participantState *participant = findParticipantByID(id);
3841 if(participant)
3842 {
3843 result = participant->mOnMuteList;
3844 }
3845
3846 return result;
3847}
3848
3849// External accessiors. Maps 0.0 to 1.0 to internal values 0-400 with .5 == 100
3850// internal = 400 * external^2
3851F32 LLVoiceClient::getUserVolume(const LLUUID& id)
3852{
3853 F32 result = 0.0f;
3854
3855 participantState *participant = findParticipantByID(id);
3856 if(participant)
3857 {
3858 S32 ires = participant->mUserVolume; // 0-400
3859 result = sqrtf(((F32)ires) / 400.f);
3860 }
3861
3862 return result;
3863}
3864
3865void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
3866{
3867 participantState *participant = findParticipantByID(id);
3868 if (participant)
3869 {
3870 // volume can amplify by as much as 4x!
3871 S32 ivol = (S32)(400.f * volume * volume);
3872 participant->mUserVolume = llclamp(ivol, 0, 400);
3873 participant->mVolumeDirty = TRUE;
3874 mVolumeDirty = TRUE;
3875 }
3876}
3877
3878
3879
3880LLVoiceClient::serviceType LLVoiceClient::getServiceType(const LLUUID& id)
3881{
3882 serviceType result = serviceTypeUnknown;
3883
3884 participantState *participant = findParticipantByID(id);
3885 if(participant)
3886 {
3887 result = participant->mServiceType;
3888 }
3889
3890 return result;
3891}
3892
3893std::string LLVoiceClient::getGroupID(const LLUUID& id)
3894{
3895 std::string result;
3896
3897 participantState *participant = findParticipantByID(id);
3898 if(participant)
3899 {
3900 result = participant->mGroupID;
3901 }
3902
3903 return result;
3904}
3905
3906BOOL LLVoiceClient::getAreaVoiceDisabled()
3907{
3908 return mAreaVoiceDisabled;
3909}
3910
3911void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer)
3912{
3913 mObservers.insert(observer);
3914}
3915
3916void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer)
3917{
3918 mObservers.erase(observer);
3919}
3920
3921void LLVoiceClient::notifyObservers()
3922{
3923 for (observer_set_t::iterator it = mObservers.begin();
3924 it != mObservers.end();
3925 )
3926 {
3927 LLVoiceClientParticipantObserver* observer = *it;
3928 observer->onChange();
3929 // In case onChange() deleted an entry.
3930 it = mObservers.upper_bound(observer);
3931 }
3932}
3933
3934void LLVoiceClient::addStatusObserver(LLVoiceClientStatusObserver* observer)
3935{
3936 mStatusObservers.insert(observer);
3937}
3938
3939void LLVoiceClient::removeStatusObserver(LLVoiceClientStatusObserver* observer)
3940{
3941 mStatusObservers.erase(observer);
3942}
3943
3944void LLVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status)
3945{
3946 if(status == LLVoiceClientStatusObserver::ERROR_UNKNOWN)
3947 {
3948 switch(mVivoxErrorStatusCode)
3949 {
3950 case 20713: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_FULL; break;
3951 case 20714: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_LOCKED; break;
3952 }
3953
3954 // Reset the error code to make sure it won't be reused later by accident.
3955 mVivoxErrorStatusCode = 0;
3956 }
3957
3958 if (status == LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL
3959 //NOT_FOUND || TEMPORARILY_UNAVAILABLE || REQUEST_TIMEOUT
3960 && (mVivoxErrorStatusCode == 404 || mVivoxErrorStatusCode == 480 || mVivoxErrorStatusCode == 408))
3961 {
3962 // call failed because other user was not available
3963 // treat this as an error case
3964 status = LLVoiceClientStatusObserver::ERROR_NOT_AVAILABLE;
3965
3966 // Reset the error code to make sure it won't be reused later by accident.
3967 mVivoxErrorStatusCode = 0;
3968 }
3969
3970 llinfos << " " << LLVoiceClientStatusObserver::status2string(status) << ", session URI " << mSessionURI << llendl;
3971
3972 for (status_observer_set_t::iterator it = mStatusObservers.begin();
3973 it != mStatusObservers.end();
3974 )
3975 {
3976 LLVoiceClientStatusObserver* observer = *it;
3977 observer->onChange(status, mSessionURI, !mNonSpatialChannel);
3978 // In case onError() deleted an entry.
3979 it = mStatusObservers.upper_bound(observer);
3980 }
3981
3982}
3983
3984//static
3985void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data)
3986{
3987 participantState* statep = gVoiceClient->findParticipantByID(id);
3988
3989 if (statep)
3990 {
3991 statep->mDisplayName = llformat("%s %s", first, last);
3992 }
3993
3994 gVoiceClient->notifyObservers();
3995}
3996
3997class LLViewerParcelVoiceInfo : public LLHTTPNode
3998{
3999 virtual void post(
4000 LLHTTPNode::ResponsePtr response,
4001 const LLSD& context,
4002 const LLSD& input) const
4003 {
4004 //the parcel you are in has changed something about its
4005 //voice information
4006
4007 if ( input.has("body") )
4008 {
4009 LLSD body = input["body"];
4010
4011 //body has "region_name" (str), "parcel_local_id"(int),
4012 //"voice_credentials" (map).
4013
4014 //body["voice_credentials"] has "channel_uri" (str),
4015 //body["voice_credentials"] has "channel_credentials" (str)
4016 if ( body.has("voice_credentials") )
4017 {
4018 LLSD voice_credentials = body["voice_credentials"];
4019 std::string uri;
4020 std::string credentials;
4021
4022 if ( voice_credentials.has("channel_uri") )
4023 {
4024 uri = voice_credentials["channel_uri"].asString();
4025 }
4026 if ( voice_credentials.has("channel_credentials") )
4027 {
4028 credentials =
4029 voice_credentials["channel_credentials"].asString();
4030 }
4031
4032 gVoiceClient->setSpatialChannel(uri, credentials);
4033 }
4034 }
4035 }
4036};
4037
4038class LLViewerRequiredVoiceVersion : public LLHTTPNode
4039{
4040 static BOOL sAlertedUser;
4041 virtual void post(
4042 LLHTTPNode::ResponsePtr response,
4043 const LLSD& context,
4044 const LLSD& input) const
4045 {
4046 //You received this messsage (most likely on region cross or
4047 //teleport)
4048 if ( input.has("body") && input["body"].has("major_version") )
4049 {
4050 int major_voice_version =
4051 input["body"]["major_version"].asInteger();
4052// int minor_voice_version =
4053// input["body"]["minor_version"].asInteger();
4054
4055 if (gVoiceClient &&
4056 (major_voice_version > VOICE_MAJOR_VERSION) )
4057 {
4058 if (!sAlertedUser)
4059 {
4060 //sAlertedUser = TRUE;
4061 gViewerWindow->alertXml("VoiceVersionMismatch");
4062 gSavedSettings.setBOOL("EnableVoiceChat", FALSE); // toggles listener
4063 }
4064 }
4065 }
4066 }
4067};
4068BOOL LLViewerRequiredVoiceVersion::sAlertedUser = FALSE;
4069
4070LLHTTPRegistration<LLViewerParcelVoiceInfo>
4071 gHTTPRegistrationMessageParcelVoiceInfo(
4072 "/message/ParcelVoiceInfo");
4073
4074LLHTTPRegistration<LLViewerRequiredVoiceVersion>
4075 gHTTPRegistrationMessageRequiredVoiceVersion(
4076 "/message/RequiredVoiceVersion");
diff --git a/linden/indra/newview/llvoiceclient.h b/linden/indra/newview/llvoiceclient.h
new file mode 100644
index 0000000..f65aa58
--- /dev/null
+++ b/linden/indra/newview/llvoiceclient.h
@@ -0,0 +1,523 @@
1/**
2 * @file llvoiceclient.h
3 * @brief Declaration of LLVoiceClient class which is the interface to the voice client process.
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28#ifndef LL_VOICE_CLIENT_H
29#define LL_VOICE_CLIENT_H
30
31// This would create a circular reference -- just do a forward definition of necessary class names.
32//#include "llvoavatar.h"
33class LLVOAvatar;
34class LLVivoxProtocolParser;
35
36#include "lliopipe.h"
37#include "llpumpio.h"
38#include "llchainio.h"
39#include "lliosocket.h"
40#include "v3math.h"
41#include "llframetimer.h"
42#include "llviewerregion.h"
43
44class LLVoiceClientParticipantObserver
45{
46public:
47 virtual ~LLVoiceClientParticipantObserver() { }
48 virtual void onChange() = 0;
49};
50
51class LLVoiceClientStatusObserver
52{
53public:
54 typedef enum e_voice_status_type
55 {
56 STATUS_LOGIN_RETRY,
57 STATUS_LOGGED_IN,
58 STATUS_JOINING,
59 STATUS_JOINED,
60 STATUS_LEFT_CHANNEL,
61 BEGIN_ERROR_STATUS,
62 ERROR_CHANNEL_FULL,
63 ERROR_CHANNEL_LOCKED,
64 ERROR_NOT_AVAILABLE,
65 ERROR_UNKNOWN
66 } EStatusType;
67
68 virtual ~LLVoiceClientStatusObserver() { }
69 virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal) = 0;
70
71 static const char *status2string(EStatusType inStatus);
72};
73
74class LLVoiceClient: public LLSingleton<LLVoiceClient>
75{
76 LOG_CLASS(LLVoiceClient);
77 public:
78 LLVoiceClient();
79 ~LLVoiceClient();
80
81 public:
82 static void init(LLPumpIO *pump); // Call this once at application startup (creates connector)
83 static void terminate(); // Call this to clean up during shutdown
84
85 protected:
86 bool writeString(const std::string &str);
87
88 public:
89
90 enum serviceType
91 {
92 serviceTypeUnknown, // Unknown, returned if no data on the avatar is available
93 serviceTypeA, // spatialized local chat
94 serviceTypeB, // remote multi-party chat
95 serviceTypeC // one-to-one and small group chat
96 };
97 static F32 OVERDRIVEN_POWER_LEVEL;
98
99 /////////////////////////////
100 // session control messages
101 void connect();
102
103 void connectorCreate();
104 void connectorShutdown();
105
106 void requestVoiceAccountProvision(S32 retries = 3);
107 void userAuthorized(
108 const std::string& firstName,
109 const std::string& lastName,
110 const LLUUID &agentID);
111 void login(const std::string& accountName, const std::string &password);
112 void loginSendMessage();
113 void logout();
114 void logoutSendMessage();
115
116 void channelGetListSendMessage();
117 void sessionCreateSendMessage();
118 void sessionConnectSendMessage();
119 void sessionTerminate();
120 void sessionTerminateSendMessage();
121 void sessionTerminateByHandle(std::string &sessionHandle);
122
123 void getCaptureDevicesSendMessage();
124 void getRenderDevicesSendMessage();
125
126 void clearCaptureDevices();
127 void addCaptureDevice(const std::string& name);
128 void setCaptureDevice(const std::string& name);
129
130 void clearRenderDevices();
131 void addRenderDevice(const std::string& name);
132 void setRenderDevice(const std::string& name);
133
134 void tuningStart();
135 void tuningStop();
136 bool inTuningMode();
137
138 void tuningRenderStartSendMessage(const std::string& name, bool loop);
139 void tuningRenderStopSendMessage();
140
141 void tuningCaptureStartSendMessage(int duration);
142 void tuningCaptureStopSendMessage();
143
144 void tuningSetMicVolume(float volume);
145 void tuningSetSpeakerVolume(float volume);
146 float tuningGetEnergy(void);
147
148 // This returns true when it's safe to bring up the "device settings" dialog in the prefs.
149 // i.e. when the daemon is running and connected, and the device lists are populated.
150 bool deviceSettingsAvailable();
151
152 // Requery the vivox daemon for the current list of input/output devices.
153 // If you pass true for clearCurrentList, deviceSettingsAvailable() will be false until the query has completed
154 // (use this if you want to know when it's done).
155 // If you pass false, you'll have no way to know when the query finishes, but the device lists will not appear empty in the interim.
156 void refreshDeviceLists(bool clearCurrentList = true);
157
158 // Call this if the connection to the daemon terminates unexpectedly. It will attempt to reset everything and relaunch.
159 void daemonDied();
160
161 // Call this if we're just giving up on voice (can't provision an account, etc.). It will clean up and go away.
162 void giveUp();
163
164 /////////////////////////////
165 // Response/Event handlers
166 void connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle);
167 void loginResponse(int statusCode, std::string &statusString, std::string &accountHandle);
168 void channelGetListResponse(int statusCode, std::string &statusString);
169 void sessionCreateResponse(int statusCode, std::string &statusString, std::string &sessionHandle);
170 void sessionConnectResponse(int statusCode, std::string &statusString);
171 void sessionTerminateResponse(int statusCode, std::string &statusString);
172 void logoutResponse(int statusCode, std::string &statusString);
173 void connectorShutdownResponse(int statusCode, std::string &statusString);
174
175 void loginStateChangeEvent(std::string &accountHandle, int statusCode, std::string &statusString, int state);
176 void sessionNewEvent(std::string &accountHandle, std::string &eventSessionHandle, int state, std::string &nameString, std::string &uriString);
177 void sessionStateChangeEvent(std::string &uriString, int statusCode, std::string &statusString, std::string &sessionHandle, int state, bool isChannel, std::string &nameString);
178 void participantStateChangeEvent(std::string &uriString, int statusCode, std::string &statusString, int state, std::string &nameString, std::string &displayNameString, int participantType);
179 void participantPropertiesEvent(std::string &uriString, int statusCode, std::string &statusString, bool isLocallyMuted, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy);
180 void auxAudioPropertiesEvent(F32 energy);
181
182 void muteListChanged();
183
184 /////////////////////////////
185 // Sending updates of current state
186 void setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
187 void setAvatarPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
188 bool channelFromRegion(LLViewerRegion *region, std::string &name);
189 void leaveChannel(void); // call this on logout or teleport begin
190
191
192 void setMuteMic(bool muted); // Use this to mute the local mic (for when the client is minimized, etc), ignoring user PTT state.
193 void setUserPTTState(bool ptt);
194 bool getUserPTTState();
195 void toggleUserPTTState(void);
196 void setVoiceEnabled(bool enabled);
197 static bool voiceEnabled();
198 void setUsePTT(bool usePTT);
199 void setPTTIsToggle(bool PTTIsToggle);
200 void setPTTKey(std::string &key);
201 void setEarLocation(S32 loc);
202 void setVoiceVolume(F32 volume);
203 void setMicGain(F32 volume);
204 void setUserVolume(const LLUUID& id, F32 volume); // set's volume for specified agent, from 0-1 (where .5 is nominal)
205 void setVivoxDebugServerName(std::string &serverName);
206
207 // PTT key triggering
208 void keyDown(KEY key, MASK mask);
209 void keyUp(KEY key, MASK mask);
210 void middleMouseState(bool down);
211
212 /////////////////////////////
213 // Accessors for data related to nearby speakers
214 BOOL getVoiceEnabled(const LLUUID& id); // true if we've received data for this avatar
215 BOOL getIsSpeaking(const LLUUID& id);
216 F32 getCurrentPower(const LLUUID& id); // "power" is related to "amplitude" in a defined way. I'm just not sure what the formula is...
217 BOOL getPTTPressed(const LLUUID& id); // This is the inverse of the "locally muted" property.
218 BOOL getOnMuteList(const LLUUID& id);
219 F32 getUserVolume(const LLUUID& id);
220 LLString getDisplayName(const LLUUID& id);
221
222 // MBW -- XXX -- Not sure how to get this data out of the TVC
223 BOOL getUsingPTT(const LLUUID& id);
224 serviceType getServiceType(const LLUUID& id); // type of chat the user is involved in (see bHear scope doc for definitions of A/B/C)
225 std::string getGroupID(const LLUUID& id); // group ID if the user is in group chat (empty string if not applicable)
226
227 /////////////////////////////
228 BOOL getAreaVoiceDisabled(); // returns true if the area the avatar is in is speech-disabled.
229 // Use this to determine whether to show a "no speech" icon in the menu bar.
230
231 struct participantState
232 {
233 public:
234 participantState(const std::string &uri);
235 std::string mURI;
236 std::string mName;
237 std::string mDisplayName;
238 bool mPTT;
239 bool mIsSpeaking;
240 LLFrameTimer mSpeakingTimeout;
241 F32 mLastSpokeTimestamp;
242 F32 mPower;
243 int mVolume;
244 serviceType mServiceType;
245 std::string mGroupID;
246 bool mOnMuteList; // true if this avatar is on the user's mute list (and should be muted)
247 int mUserVolume;
248 bool mVolumeDirty; // true if this participant needs a volume command sent (either mOnMuteList or mUserVolume has changed)
249 bool mAvatarIDValid;
250 LLUUID mAvatarID;
251 };
252 typedef std::map<std::string, participantState*> participantMap;
253
254 participantState *findParticipant(const std::string &uri);
255 participantState *findParticipantByAvatar(LLVOAvatar *avatar);
256 participantState *findParticipantByID(const LLUUID& id);
257
258 participantMap *getParticipantList(void);
259
260 void addObserver(LLVoiceClientParticipantObserver* observer);
261 void removeObserver(LLVoiceClientParticipantObserver* observer);
262
263 void addStatusObserver(LLVoiceClientStatusObserver* observer);
264 void removeStatusObserver(LLVoiceClientStatusObserver* observer);
265
266 static void onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data);
267 typedef std::vector<std::string> deviceList;
268
269 deviceList *getCaptureDevices();
270 deviceList *getRenderDevices();
271
272 void setNonSpatialChannel(
273 const std::string &uri,
274 const std::string &credentials);
275 void setSpatialChannel(
276 const std::string &uri,
277 const std::string &credentials);
278 void callUser(LLUUID &uuid);
279 void answerInvite(std::string &sessionHandle, LLUUID& other_user_id);
280 void declineInvite(std::string &sessionHandle);
281 void leaveNonSpatialChannel();
282
283 // Returns the URI of the current channel, or an empty string if not currently in a channel.
284 // NOTE that it will return an empty string if it's in the process of joining a channel.
285 std::string getCurrentChannel();
286
287 // returns true iff the user is currently in a proximal (local spatial) channel.
288 // Note that gestures should only fire if this returns true.
289 bool inProximalChannel();
290
291 std::string sipURIFromID(const LLUUID &id);
292
293 private:
294
295 // internal state for a simple state machine. This is used to deal with the asynchronous nature of some of the messages.
296 // Note: if you change this list, please make corresponding changes to LLVoiceClient::state2string().
297 enum state
298 {
299 stateDisabled, // Voice is turned off.
300 stateStart, // Class is initialized, socket is created
301 stateDaemonLaunched, // Daemon has been launched
302 stateConnecting, // connect() call has been issued
303 stateIdle, // socket is connected, ready for messaging
304 stateConnectorStart, // connector needs to be started
305 stateConnectorStarting, // waiting for connector handle
306 stateConnectorStarted, // connector handle received
307 stateMicTuningNoLogin, // mic tuning before login
308 stateLoginRetry, // need to retry login (failed due to changing password)
309 stateLoginRetryWait, // waiting for retry timer
310 stateNeedsLogin, // send login request
311 stateLoggingIn, // waiting for account handle
312 stateLoggedIn, // account handle received
313 stateNoChannel, //
314 stateMicTuningLoggedIn, // mic tuning for a logged in user
315 stateSessionCreate, // need to send Session.Create command
316 stateSessionConnect, // need to send Session.Connect command
317 stateJoiningSession, // waiting for session handle
318 stateSessionJoined, // session handle received
319 stateRunning, // in session, steady state
320 stateLeavingSession, // waiting for terminate session response
321 stateSessionTerminated, // waiting for terminate session response
322
323 stateLoggingOut, // waiting for logout response
324 stateLoggedOut, // logout response received
325 stateConnectorStopping, // waiting for connector stop
326 stateConnectorStopped, // connector stop received
327
328 // We go to this state if the login fails because the account needs to be provisioned.
329
330 // error states. No way to recover from these yet.
331 stateConnectorFailed,
332 stateConnectorFailedWaiting,
333 stateLoginFailed,
334 stateLoginFailedWaiting,
335 stateJoinSessionFailed,
336 stateJoinSessionFailedWaiting,
337
338 stateJail // Go here when all else has failed. Nothing will be retried, we're done.
339 };
340
341 state mState;
342 bool mSessionTerminateRequested;
343 bool mNonSpatialChannel;
344
345 void setState(state inState);
346 state getState(void) { return mState; };
347 static const char *state2string(state inState);
348
349 void stateMachine();
350 static void idle(void *user_data);
351
352 LLHost mDaemonHost;
353 LLSocket::ptr_t mSocket;
354 bool mConnected;
355
356 void closeSocket(void);
357
358 LLPumpIO *mPump;
359 friend class LLVivoxProtocolParser;
360
361 std::string mAccountName;
362 std::string mAccountPassword;
363 std::string mAccountDisplayName;
364 std::string mAccountFirstName;
365 std::string mAccountLastName;
366
367 std::string mNextP2PSessionURI; // URI of the P2P session to join next
368 std::string mNextSessionURI; // URI of the session to join next
369 std::string mNextSessionHandle; // Session handle of the session to join next
370 std::string mNextSessionHash; // Password hash for the session to join next
371 bool mNextSessionSpatial; // Will next session be a spatial chat?
372 bool mNextSessionNoReconnect; // Next session should not auto-reconnect (i.e. user -> user chat)
373 bool mNextSessionResetOnClose; // If this is true, go back to spatial chat when the next session terminates.
374
375 std::string mSessionStateEventHandle; // session handle received in SessionStateChangeEvents
376 std::string mSessionStateEventURI; // session URI received in SessionStateChangeEvents
377
378 bool mTuningMode;
379 float mTuningEnergy;
380 std::string mTuningAudioFile;
381 int mTuningMicVolume;
382 bool mTuningMicVolumeDirty;
383 int mTuningSpeakerVolume;
384 bool mTuningSpeakerVolumeDirty;
385 bool mTuningCaptureRunning;
386
387 std::string mSpatialSessionURI;
388
389 bool mSessionResetOnClose;
390
391 int mVivoxErrorStatusCode;
392 std::string mVivoxErrorStatusString;
393
394 std::string mChannelName; // Name of the channel to be looked up
395 bool mAreaVoiceDisabled;
396 std::string mSessionURI; // URI of the session we're in.
397 bool mSessionP2P; // true if this session is a p2p call
398
399 S32 mCurrentParcelLocalID; // Used to detect parcel boundary crossings
400 std::string mCurrentRegionName; // Used to detect parcel boundary crossings
401
402 std::string mConnectorHandle; // returned by "Create Connector" message
403 std::string mAccountHandle; // returned by login message
404 std::string mSessionHandle; // returned by ?
405 U32 mCommandCookie;
406
407 std::string mAccountServerName;
408 std::string mAccountServerURI;
409
410 int mLoginRetryCount;
411
412 participantMap mParticipantMap;
413 bool mParticipantMapChanged;
414
415 deviceList mCaptureDevices;
416 deviceList mRenderDevices;
417
418 std::string mCaptureDevice;
419 std::string mRenderDevice;
420 bool mCaptureDeviceDirty;
421 bool mRenderDeviceDirty;
422
423 participantState *addParticipant(const std::string &uri);
424 // Note: after removeParticipant returns, the participant* that was passed to it will have been deleted.
425 // Take care not to use the pointer again after that.
426 void removeParticipant(participantState *participant);
427 void removeAllParticipants();
428
429 void updateMuteState(participantState *participant);
430
431 typedef std::map<std::string, std::string> channelMap;
432 channelMap mChannelMap;
433
434 // These are used by the parser when processing a channel list response.
435 void clearChannelMap(void);
436 void addChannelMapEntry(std::string &name, std::string &uri);
437 std::string findChannelURI(std::string &name);
438
439 // This should be called when the code detects we have changed parcels.
440 // It initiates the call to the server that gets the parcel channel.
441 void parcelChanged();
442
443 void switchChannel(std::string uri = "", bool spatial = true, bool noReconnect = false, std::string hash = "");
444 void joinSession(std::string handle, std::string uri);
445
446 std::string nameFromAvatar(LLVOAvatar *avatar);
447 std::string nameFromID(const LLUUID &id);
448 bool IDFromName(const std::string name, LLUUID &uuid);
449 std::string displayNameFromAvatar(LLVOAvatar *avatar);
450 std::string sipURIFromAvatar(LLVOAvatar *avatar);
451 std::string sipURIFromName(std::string &name);
452
453 void sendPositionalUpdate(void);
454
455 void buildSetCaptureDevice(std::ostringstream &stream);
456 void buildSetRenderDevice(std::ostringstream &stream);
457
458 void enforceTether(void);
459
460 bool mSpatialCoordsDirty;
461
462 LLVector3d mCameraPosition;
463 LLVector3d mCameraRequestedPosition;
464 LLVector3 mCameraVelocity;
465 LLMatrix3 mCameraRot;
466
467 LLVector3d mAvatarPosition;
468 LLVector3 mAvatarVelocity;
469 LLMatrix3 mAvatarRot;
470
471 bool mPTTDirty;
472 bool mPTT;
473
474 bool mUsePTT;
475 bool mPTTIsMiddleMouse;
476 KEY mPTTKey;
477 bool mPTTIsToggle;
478 bool mUserPTTState;
479 bool mMuteMic;
480
481 // Set to true when the mute state of someone in the participant list changes.
482 // The code will have to walk the list to find the changed participant(s).
483 bool mVolumeDirty;
484
485 enum
486 {
487 earLocCamera = 0, // ear at camera
488 earLocAvatar, // ear at avatar
489 earLocMixed // ear at avatar location/camera direction
490 };
491
492 S32 mEarLocation;
493
494 bool mSpeakerVolumeDirty;
495 bool mSpeakerMuteDirty;
496 int mSpeakerVolume;
497
498 int mMicVolume;
499 bool mMicVolumeDirty;
500
501 bool mVoiceEnabled;
502 bool mWriteInProgress;
503 std::string mWriteString;
504 size_t mWriteOffset;
505
506 LLTimer mUpdateTimer;
507
508 typedef std::set<LLVoiceClientParticipantObserver*> observer_set_t;
509 observer_set_t mObservers;
510
511 void notifyObservers();
512
513 typedef std::set<LLVoiceClientStatusObserver*> status_observer_set_t;
514 status_observer_set_t mStatusObservers;
515
516 void notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status);
517};
518
519extern LLVoiceClient *gVoiceClient;
520
521#endif //LL_VOICE_CLIENT_H
522
523
diff --git a/linden/indra/newview/llvoiceremotectrl.cpp b/linden/indra/newview/llvoiceremotectrl.cpp
new file mode 100644
index 0000000..720eb17
--- /dev/null
+++ b/linden/indra/newview/llvoiceremotectrl.cpp
@@ -0,0 +1,180 @@
1/**
2 * @file llvoiceremotectrl.cpp
3 * @brief A remote control for voice chat
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "llviewerprecompiledheaders.h"
30
31#include "llvoiceremotectrl.h"
32
33#include "llagent.h"
34#include "llui.h"
35#include "llbutton.h"
36#include "llvieweruictrlfactory.h"
37#include "llviewercontrol.h"
38#include "llvoiceclient.h"
39#include "llimpanel.h"
40#include "llfloateractivespeakers.h"
41#include "lliconctrl.h"
42
43LLVoiceRemoteCtrl::LLVoiceRemoteCtrl (const LLString& name) : LLPanel(name)
44{
45 setIsChrome(TRUE);
46
47 gUICtrlFactory->buildPanel(this, "panel_voice_remote.xml");
48
49 mTalkBtn = LLUICtrlFactory::getButtonByName(this, "push_to_talk");
50 mTalkBtn->setClickedCallback(onBtnTalkClicked);
51 mTalkBtn->setHeldDownCallback(onBtnTalkHeld);
52 mTalkBtn->setMouseUpCallback(onBtnTalkReleased);
53
54 mTalkLockBtn = LLUICtrlFactory::getButtonByName(this, "ptt_lock");
55 mTalkLockBtn->setClickedCallback(onBtnLock);
56
57 mSpeakersBtn = LLUICtrlFactory::getButtonByName(this, "speakers_btn");
58 mSpeakersBtn->setClickedCallback(onClickSpeakers);
59
60 mIsFocusRoot = TRUE;
61}
62
63LLVoiceRemoteCtrl::~LLVoiceRemoteCtrl()
64{
65}
66
67void LLVoiceRemoteCtrl::draw()
68{
69 BOOL voice_active = FALSE;
70 LLVoiceChannel* channelp = LLVoiceChannel::getCurrentVoiceChannel();
71 if (channelp)
72 {
73 voice_active = channelp->isActive();
74 }
75
76 mTalkBtn->setEnabled(voice_active);
77 mTalkLockBtn->setEnabled(voice_active);
78
79// if (voice_active)
80// {
81// mTalkBtn->setToolTip("");
82// mTalkLockBtn->setToolTip("");
83// }
84// else
85// {
86// mTalkBtn->setToolTip("");
87// mTalkLockBtn->setToolTip("");
88// }
89
90 // propagate ptt state to button display,
91 if (!mTalkBtn->hasMouseCapture())
92 {
93 // not in push to talk mode, or push to talk is active means I'm talking
94 mTalkBtn->setToggleState(!gSavedSettings.getBOOL("PTTCurrentlyEnabled") || gVoiceClient->getUserPTTState());
95 }
96 mSpeakersBtn->setToggleState(LLFloaterActiveSpeakers::instanceVisible(LLSD()));
97 mTalkLockBtn->setToggleState(!gSavedSettings.getBOOL("PTTCurrentlyEnabled"));
98
99 LLUUID talk_blip_image_id;
100 if (gVoiceClient->getIsSpeaking(gAgent.getID()))
101 {
102 F32 voice_power = gVoiceClient->getCurrentPower(gAgent.getID());
103
104 if (voice_power > LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
105 {
106 talk_blip_image_id = LLUUID(gViewerArt.getString("icn_voice_ptt-on-lvl3.tga"));
107 }
108 else
109 {
110 F32 power = gVoiceClient->getCurrentPower(gAgent.getID());
111 S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
112
113 switch(icon_image_idx)
114 {
115 case 0:
116 talk_blip_image_id = LLUUID(gViewerArt.getString("icn_voice_ptt-on.tga"));
117 break;
118 case 1:
119 talk_blip_image_id = LLUUID(gViewerArt.getString("icn_voice_ptt-on-lvl1.tga"));
120 break;
121 case 2:
122 talk_blip_image_id = LLUUID(gViewerArt.getString("icn_voice_ptt-on-lvl2.tga"));
123 break;
124 }
125 }
126 }
127 else
128 {
129 talk_blip_image_id = LLUUID(gViewerArt.getString("icn_voice_ptt-off.tga"));
130 }
131
132 LLIconCtrl* icon = LLUICtrlFactory::getIconByName(this, "voice_volume");
133 if (icon)
134 {
135 icon->setImage(talk_blip_image_id);
136 }
137
138 LLPanel::draw();
139}
140
141void LLVoiceRemoteCtrl::onBtnTalkClicked(void *user_data)
142{
143 // when in toggle mode, clicking talk button turns mic on/off
144 if (gSavedSettings.getBOOL("PushToTalkToggle"))
145 {
146 gVoiceClient->toggleUserPTTState();
147 }
148}
149
150void LLVoiceRemoteCtrl::onBtnTalkHeld(void *user_data)
151{
152 // when not in toggle mode, holding down talk button turns on mic
153 if (!gSavedSettings.getBOOL("PushToTalkToggle"))
154 {
155 gVoiceClient->setUserPTTState(true);
156 }
157}
158
159void LLVoiceRemoteCtrl::onBtnTalkReleased(void* user_data)
160{
161 // when not in toggle mode, releasing talk button turns off mic
162 if (!gSavedSettings.getBOOL("PushToTalkToggle"))
163 {
164 gVoiceClient->setUserPTTState(false);
165 }
166}
167
168void LLVoiceRemoteCtrl::onBtnLock(void* user_data)
169{
170 LLVoiceRemoteCtrl* remotep = (LLVoiceRemoteCtrl*)user_data;
171
172 remotep->mTalkLockBtn->toggleState();
173 gSavedSettings.setBOOL("PTTCurrentlyEnabled", !remotep->mTalkLockBtn->getToggleState());
174}
175
176void LLVoiceRemoteCtrl::onClickSpeakers(void *user_data)
177{
178 LLFloaterActiveSpeakers::toggleInstance(LLSD());
179}
180
diff --git a/linden/indra/newview/llvolumesliderctrl.h b/linden/indra/newview/llvoiceremotectrl.h
index 096ecc3..46ed709 100644
--- a/linden/indra/newview/llvolumesliderctrl.h
+++ b/linden/indra/newview/llvoiceremotectrl.h
@@ -1,8 +1,8 @@
1/** 1/**
2 * @file llvolumesliderctrl.h 2 * @file llvoiceremotectrl.h
3 * @brief A horizontal volume slider. 3 * @brief A remote control for voice chat
4 * 4 *
5 * Copyright (c) 2004-2007, Linden Research, Inc. 5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 * 6 *
7 * Second Life Viewer Source Code 7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab 8 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -26,31 +26,31 @@
26 * COMPLETENESS OR PERFORMANCE. 26 * COMPLETENESS OR PERFORMANCE.
27 */ 27 */
28 28
29#ifndef LL_LLVOLUMESLIDERCTRL_H 29#ifndef LL_LLVOICEREMOTECTRL_H
30#define LL_LLVOLUMESLIDERCTRL_H 30#define LL_LLVOICEREMOTECTRL_H
31 31
32#include "llslider.h" 32#include "llpanel.h"
33 33
34class LLButton;
34 35
35class LLVolumeSliderCtrl 36class LLVoiceRemoteCtrl : public LLPanel
36: public LLSlider
37{ 37{
38public: 38public:
39 39 LLVoiceRemoteCtrl (const LLString& name);
40 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_VOLUME_SLIDER; } 40 virtual ~LLVoiceRemoteCtrl();
41 virtual LLString getWidgetTag() const { return LL_VOLUME_SLIDER_CTRL_TAG; }
42 41
43 virtual LLXMLNodePtr getXML(bool save_children = true) const; 42 /*virtual*/ void draw();
44 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
45 43
46 LLVolumeSliderCtrl(const std::string& name, 44 static void onBtnLock(void* user_data);
47 const LLRect& rect, 45 static void onBtnTalkHeld(void *user_data);
48 void (*commit_callback)(LLUICtrl* ctrl, void* data), 46 static void onBtnTalkReleased(void* user_data);
49 void* callback_data); 47 static void onBtnTalkClicked(void* user_data);
50 virtual ~LLVolumeSliderCtrl(); 48 static void onClickSpeakers(void *user_data);
51 49
52 virtual void draw(); 50protected:
51 LLButton* mTalkBtn;
52 LLButton* mTalkLockBtn;
53 LLButton* mSpeakersBtn;
53}; 54};
54 55
55 56#endif // LL_LLVOICEREMOTECTRL_H
56#endif
diff --git a/linden/indra/newview/llvoicevisualizer.cpp b/linden/indra/newview/llvoicevisualizer.cpp
new file mode 100644
index 0000000..fca2226
--- /dev/null
+++ b/linden/indra/newview/llvoicevisualizer.cpp
@@ -0,0 +1,431 @@
1//----------------------------------------------------------------------
2// Voice Visualizer
3// author: JJ Ventrella
4// (information about this stuff can be found in "llvoicevisualizer.h")
5//----------------------------------------------------------------------
6#include "llviewerprecompiledheaders.h"
7#include "llviewercontrol.h"
8#include "llglheaders.h"
9#include "llsphere.h"
10#include "llvoicevisualizer.h"
11#include "llviewercamera.h"
12#include "llviewerobject.h"
13#include "llimagegl.h"
14#include "llviewerimage.h"
15#include "llviewerimagelist.h"
16#include "llvoiceclient.h"
17
18//brent's wave image
19//29de489d-0491-fb00-7dab-f9e686d31e83
20
21
22//--------------------------------------------------------------------------------------
23// sound symbol constants
24//--------------------------------------------------------------------------------------
25const F32 HEIGHT_ABOVE_HEAD = 0.3f; // how many meters vertically above the av's head the voice symbol will appear
26const F32 RED_THRESHOLD = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; // value above which speaking amplitude causes the voice symbol to turn red
27const F32 GREEN_THRESHOLD = 0.2f; // value above which speaking amplitude causes the voice symbol to turn green
28const F32 FADE_OUT_DURATION = 0.4f; // how many seconds it takes for a pair of waves to fade away
29const F32 EXPANSION_RATE = 1.0f; // how many seconds it takes for the waves to expand to twice their original size
30const F32 EXPANSION_MAX = 1.5f; // maximum size scale to which the waves can expand before popping back to 1.0
31const F32 WAVE_WIDTH_SCALE = 0.03f; // base width of the waves
32const F32 WAVE_HEIGHT_SCALE = 0.02f; // base height of the waves
33const F32 BASE_BRIGHTNESS = 0.7f; // gray level of the voice indicator when quiet (below green threshold)
34const F32 DOT_SIZE = 0.05f; // size of the dot billboard texture
35const F32 DOT_OPACITY = 0.7f; // how opaque the dot is
36const F32 WAVE_MOTION_RATE = 1.5f; // scalar applied to consecutive waves as a function of speaking amplitude
37
38//--------------------------------------------------------------------------------------
39// gesticulation constants
40//--------------------------------------------------------------------------------------
41const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE = 0.2f;
42const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE = 1.0f;
43
44//--------------------------------------------------------------------------------------
45// other constants
46//--------------------------------------------------------------------------------------
47const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code.
48const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
49
50//-----------------------------------------------
51// constructor
52//-----------------------------------------------
53LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
54:LLHUDEffect( type )
55{
56 mCurrentTime = mTimer.getTotalSeconds();
57 mPreviousTime = mCurrentTime;
58 mVoiceSourceWorldPosition = LLVector3( 0.0f, 0.0f, 0.0f );
59 mSpeakingAmplitude = 0.0f;
60 mCurrentlySpeaking = false;
61 mVoiceEnabled = false;
62 mMinGesticulationAmplitude = DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
63 mMaxGesticulationAmplitude = DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
64 mSoundSymbol.mActive = true;
65 mSoundSymbol.mPosition = LLVector3( 0.0f, 0.0f, 0.0f );
66
67 mTimer.reset();
68
69 LLUUID sound_level_img[] =
70 {
71 LLUUID(gSavedSettings.getString("VoiceImageLevel0")),
72 LLUUID(gSavedSettings.getString("VoiceImageLevel1")),
73 LLUUID(gSavedSettings.getString("VoiceImageLevel2")),
74 LLUUID(gSavedSettings.getString("VoiceImageLevel3")),
75 LLUUID(gSavedSettings.getString("VoiceImageLevel4")),
76 LLUUID(gSavedSettings.getString("VoiceImageLevel5")),
77 LLUUID(gSavedSettings.getString("VoiceImageLevel6"))
78 };
79
80 for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
81 {
82 mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
83 mSoundSymbol.mTexture [i] = gImageList.getUIImageByID(sound_level_img[i]);
84 mSoundSymbol.mWaveActive [i] = false;
85 mSoundSymbol.mWaveOpacity [i] = 1.0f;
86 mSoundSymbol.mWaveExpansion [i] = 1.0f;
87 }
88
89}//---------------------------------------------------
90
91//---------------------------------------------------
92void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
93{
94 mMinGesticulationAmplitude = m;
95
96}//---------------------------------------------------
97
98//---------------------------------------------------
99void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
100{
101 mMaxGesticulationAmplitude = m;
102
103}//---------------------------------------------------
104
105//---------------------------------------------------
106void LLVoiceVisualizer::setVoiceEnabled( bool v )
107{
108 mVoiceEnabled = v;
109
110}//---------------------------------------------------
111
112//---------------------------------------------------
113void LLVoiceVisualizer::setStartSpeaking()
114{
115 mCurrentlySpeaking = true;
116 mSoundSymbol.mActive = true;
117
118}//---------------------------------------------------
119
120
121//---------------------------------------------------
122bool LLVoiceVisualizer::getCurrentlySpeaking()
123{
124 return mCurrentlySpeaking;
125
126}//---------------------------------------------------
127
128
129//---------------------------------------------------
130void LLVoiceVisualizer::setStopSpeaking()
131{
132 mCurrentlySpeaking = false;
133 mSpeakingAmplitude = 0.0f;
134
135}//---------------------------------------------------
136
137
138//---------------------------------------------------
139void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
140{
141 mSpeakingAmplitude = a;
142
143}//---------------------------------------------------
144
145
146//---------------------------------------------------
147// this method is inherited from HUD Effect
148//---------------------------------------------------
149void LLVoiceVisualizer::render()
150{
151 if ( ! mVoiceEnabled )
152 {
153 return;
154 }
155
156 if ( mSoundSymbol.mActive )
157 {
158 mPreviousTime = mCurrentTime;
159 mCurrentTime = mTimer.getTotalSeconds();
160
161 //---------------------------------------------------------------
162 // set the sound symbol position over the source (avatar's head)
163 //---------------------------------------------------------------
164 mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
165
166 //---------------------------------------------------------------
167 // some gl state
168 //---------------------------------------------------------------
169 LLGLEnable tex( GL_TEXTURE_2D );
170 LLGLEnable blend( GL_BLEND );
171
172 //-------------------------------------------------------------
173 // create coordinates of the geometry for the dot
174 //-------------------------------------------------------------
175 LLVector3 l = gCamera->getLeftAxis() * DOT_SIZE;
176 LLVector3 u = gCamera->getUpAxis() * DOT_SIZE;
177
178 LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
179 LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
180 LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
181 LLVector3 topRight = mSoundSymbol.mPosition - l + u;
182
183 //-----------------------------
184 // bind texture 0 (the dot)
185 //-----------------------------
186 mSoundSymbol.mTexture[0]->bind();
187
188 //-------------------------------------------------------------
189 // now render the dot
190 //-------------------------------------------------------------
191 glColor4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );
192
193 glBegin( GL_TRIANGLE_STRIP );
194 glTexCoord2i( 0, 0 ); glVertex3fv( bottomLeft.mV );
195 glTexCoord2i( 1, 0 ); glVertex3fv( bottomRight.mV );
196 glTexCoord2i( 0, 1 ); glVertex3fv( topLeft.mV );
197 glEnd();
198
199 glBegin( GL_TRIANGLE_STRIP );
200 glTexCoord2i( 1, 0 ); glVertex3fv( bottomRight.mV );
201 glTexCoord2i( 1, 1 ); glVertex3fv( topRight.mV );
202 glTexCoord2i( 0, 1 ); glVertex3fv( topLeft.mV );
203 glEnd();
204
205
206
207 //--------------------------------------------------------------------------------------
208 // if currently speaking, trigger waves (1 through 6) based on speaking amplitude
209 //--------------------------------------------------------------------------------------
210 if ( mCurrentlySpeaking )
211 {
212 F32 min = 0.2f;
213 F32 max = 0.7f;
214 F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
215
216 // in case mSpeakingAmplitude > max....
217 if ( fraction > 1.0f )
218 {
219 fraction = 1.0f;
220 }
221
222 S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
223
224 for (int i=0; i<level+1; i++)
225 {
226 mSoundSymbol.mWaveActive [i] = true;
227 mSoundSymbol.mWaveOpacity [i] = 1.0f;
228 mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
229 }
230
231 } // if currently speaking
232
233 //---------------------------------------------------
234 // determine color
235 //---------------------------------------------------
236 F32 red = 0.0f;
237 F32 green = 0.0f;
238 F32 blue = 0.0f;
239 if ( mSpeakingAmplitude < RED_THRESHOLD )
240 {
241 if ( mSpeakingAmplitude < GREEN_THRESHOLD )
242 {
243 red = BASE_BRIGHTNESS;
244 green = BASE_BRIGHTNESS;
245 blue = BASE_BRIGHTNESS;
246 }
247 else
248 {
249 //---------------------------------------------------
250 // fade from gray to bright green
251 //---------------------------------------------------
252 F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
253 red = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
254 green = BASE_BRIGHTNESS + fraction * ( 1.0f - BASE_BRIGHTNESS );
255 blue = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
256 }
257 }
258 else
259 {
260 //---------------------------------------------------
261 // redish
262 //---------------------------------------------------
263 red = 1.0f;
264 green = 0.2f;
265 blue = 0.2f;
266 }
267
268 for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
269 {
270 if ( mSoundSymbol.mWaveActive[i] )
271 {
272 F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
273
274 mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
275
276 if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
277 {
278 mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
279 mSoundSymbol.mWaveOpacity [i] = 0.0f;
280 mSoundSymbol.mWaveActive [i] = false;
281 }
282
283 //----------------------------------------------------------------------------------
284 // This is where we calculate the expansion of the waves - that is, the
285 // rate at which they are scaled greater than 1.0 so that they grow over time.
286 //----------------------------------------------------------------------------------
287 F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
288 F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
289 mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
290
291 if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
292 {
293 mSoundSymbol.mWaveExpansion[i] = 1.0f;
294 }
295
296 //----------------------------------------------------------------------------------
297 // create geometry for the wave billboard textures
298 //----------------------------------------------------------------------------------
299 F32 width = i * WAVE_WIDTH_SCALE * mSoundSymbol.mWaveExpansion[i];
300 F32 height = i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
301
302 LLVector3 l = gCamera->getLeftAxis() * width;
303 LLVector3 u = gCamera->getUpAxis() * height;
304
305 LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
306 LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
307 LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
308 LLVector3 topRight = mSoundSymbol.mPosition - l + u;
309
310 glColor4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );
311 mSoundSymbol.mTexture[i]->bind();
312
313 //---------------------------------------------------
314 // now, render the mofo
315 //---------------------------------------------------
316 glBegin( GL_TRIANGLE_STRIP );
317 glTexCoord2i( 0, 0 ); glVertex3fv( bottomLeft.mV );
318 glTexCoord2i( 1, 0 ); glVertex3fv( bottomRight.mV );
319 glTexCoord2i( 0, 1 ); glVertex3fv( topLeft.mV );
320 glEnd();
321
322 glBegin( GL_TRIANGLE_STRIP );
323 glTexCoord2i( 1, 0 ); glVertex3fv( bottomRight.mV );
324 glTexCoord2i( 1, 1 ); glVertex3fv( topRight.mV );
325 glTexCoord2i( 0, 1 ); glVertex3fv( topLeft.mV );
326 glEnd();
327
328 } //if ( mSoundSymbol.mWaveActive[i] )
329
330 }// for loop
331
332 }//if ( mSoundSymbol.mActive )
333
334}//---------------------------------------------------
335
336
337
338
339
340//---------------------------------------------------
341void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
342{
343 mVoiceSourceWorldPosition = p;
344
345}//---------------------------------------------------
346
347//---------------------------------------------------
348VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
349{
350 VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
351
352 //-----------------------------------------------------------------------------------------
353 // Within the range of gesticulation amplitudes, the sound signal is split into
354 // three equal amplitude regimes, each specifying one of three gesticulation levels.
355 //-----------------------------------------------------------------------------------------
356 F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
357
358 if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.66666f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH; }
359 else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.33333f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM; }
360 else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW; }
361
362 return gesticulationLevel;
363
364}//---------------------------------------------------
365
366
367
368//------------------------------------
369// Destructor
370//------------------------------------
371LLVoiceVisualizer::~LLVoiceVisualizer()
372{
373}//----------------------------------------------
374
375
376//---------------------------------------------------
377// "packData" is inherited from HUDEffect
378//---------------------------------------------------
379void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
380{
381 // Pack the default data
382 LLHUDEffect::packData(mesgsys);
383
384 // TODO -- pack the relevant data for voice effects
385 // we'll come up with some cool configurations....TBD
386 //U8 packed_data[41];
387 //mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
388 U8 packed_data = 0;
389 mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
390}
391
392
393//---------------------------------------------------
394// "unpackData" is inherited from HUDEffect
395//---------------------------------------------------
396void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
397{
398 // TODO -- find the speaker, unpack binary data, set the properties of this effect
399 /*
400 LLHUDEffect::unpackData(mesgsys, blocknum);
401 LLUUID source_id;
402 LLUUID target_id;
403 S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
404 if (size != 1)
405 {
406 llwarns << "Voice effect with bad size " << size << llendl;
407 return;
408 }
409 mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
410 */
411}
412
413
414//------------------------------------------------------------------
415// this method is inherited from HUD Effect
416//------------------------------------------------------------------
417void LLVoiceVisualizer::markDead()
418{
419 mCurrentlySpeaking = false;
420 mVoiceEnabled = false;
421 mSoundSymbol.mActive = false;
422
423}//------------------------------------------------------------------
424
425
426
427
428
429
430
431
diff --git a/linden/indra/newview/llvoicevisualizer.h b/linden/indra/newview/llvoicevisualizer.h
new file mode 100644
index 0000000..ea53372
--- /dev/null
+++ b/linden/indra/newview/llvoicevisualizer.h
@@ -0,0 +1,111 @@
1//--------------------------------------------------------------------
2//
3// VOICE VISUALIZER
4// author: JJ Ventrella, Linden Lab
5// (latest update to this info: Jan 18, 2007)
6//
7// The Voice Visualizer is responsible for taking realtime signals from actual users speaking and
8// visualizing this speech in two forms:
9//
10// (1) as a dynamic sound symbol (also referred to as the "voice indicator" that appears over the avatar's head
11// (2) as gesticulation events that are used to trigger avatr gestures
12//
13// The input for the voice visualizer is a continual stream of voice amplitudes.
14
15//-----------------------------------------------------------------------------
16#ifndef LL_VOICE_VISUALIZER_H
17#define LL_VOICE_VISUALIZER_H
18
19#include "llhudeffect.h"
20
21//-----------------------------------------------------------------------------------------------
22// The values of voice gesticulation represent energy levels for avatar animation, based on
23// amplitude surge events parsed from the voice signal. These are made available so that
24// the appropriate kind of avatar animation can be triggered, and thereby simulate the physical
25// motion effects of speech. It is recommended that multiple body parts be animated as well as
26// lips, such as head, shoulders, and hands, with large gestures used when the energy level is high.
27//-----------------------------------------------------------------------------------------------
28enum VoiceGesticulationLevel
29{
30 VOICE_GESTICULATION_LEVEL_OFF = -1,
31 VOICE_GESTICULATION_LEVEL_LOW = 0,
32 VOICE_GESTICULATION_LEVEL_MEDIUM,
33 VOICE_GESTICULATION_LEVEL_HIGH,
34 NUM_VOICE_GESTICULATION_LEVELS
35};
36
37const static int NUM_VOICE_SYMBOL_WAVES = 7;
38
39//----------------------------------------------------
40// LLVoiceVisualizer class
41//----------------------------------------------------
42class LLVoiceVisualizer : public LLHUDEffect
43{
44 //---------------------------------------------------
45 // public methods
46 //---------------------------------------------------
47 public:
48 LLVoiceVisualizer ( const U8 type ); //constructor
49 ~LLVoiceVisualizer(); //destructor
50
51 friend class LLHUDObject;
52
53 void setVoiceSourceWorldPosition( const LLVector3 &p ); // this should be the position of the speaking avatar's head
54 void setMinGesticulationAmplitude( F32 ); // the lower range of meaningful amplitude for setting gesticulation level
55 void setMaxGesticulationAmplitude( F32 ); // the upper range of meaningful amplitude for setting gesticulation level
56 void setStartSpeaking(); // tell me when the av starts speaking
57 void setVoiceEnabled( bool ); // tell me whether or not the user is voice enabled
58 void setSpeakingAmplitude( F32 ); // tell me how loud the av is speaking (ranges from 0 to 1)
59 void setStopSpeaking(); // tell me when the av stops speaking
60 bool getCurrentlySpeaking(); // the get for the above set
61 VoiceGesticulationLevel getCurrentGesticulationLevel(); // based on voice amplitude, I'll give you the current "energy level" of avatar speech
62
63 void render(); // inherited from HUD Effect
64 void packData(LLMessageSystem *mesgsys); // inherited from HUD Effect
65 void unpackData(LLMessageSystem *mesgsys, S32 blocknum); // inherited from HUD Effect
66 void markDead(); // inherited from HUD Effect
67
68 //----------------------------------------------------------------------------------------------
69 // "setMaxGesticulationAmplitude" and "setMinGesticulationAmplitude" allow for the tuning of the
70 // gesticulation level detector to be responsive to different kinds of signals. For instance, we
71 // may find that the average voice amplitude rarely exceeds 0.7 (in a range from 0 to 1), and
72 // therefore we may want to set 0.7 as the max, so we can more easily catch all the variance
73 // within that range. Also, we may find that there is often noise below a certain range like 0.1,
74 // and so we would want to set 0.1 as the min so as not to accidentally use this as signal.
75 //----------------------------------------------------------------------------------------------
76 void setMaxGesticulationAmplitude();
77 void setMinGesticulationAmplitude();
78
79 //---------------------------------------------------
80 // private members
81 //---------------------------------------------------
82 private:
83
84 struct SoundSymbol
85 {
86 F32 mWaveExpansion [ NUM_VOICE_SYMBOL_WAVES ];
87 bool mWaveActive [ NUM_VOICE_SYMBOL_WAVES ];
88 F64 mWaveFadeOutStartTime [ NUM_VOICE_SYMBOL_WAVES ];
89 F32 mWaveOpacity [ NUM_VOICE_SYMBOL_WAVES ];
90 LLPointer<LLImageGL> mTexture [ NUM_VOICE_SYMBOL_WAVES ];
91 bool mActive;
92 LLVector3 mPosition;
93 };
94
95 LLFrameTimer mTimer; // so I can ask the current time in seconds
96 F64 mCurrentTime; // current time in seconds, captured every step
97 F64 mPreviousTime; // copy of "current time" from last frame
98 SoundSymbol mSoundSymbol; // the sound symbol that appears over the avatar's head
99 bool mVoiceEnabled; // if off, no rendering should happen
100 bool mCurrentlySpeaking; // is the user currently speaking?
101 LLVector3 mVoiceSourceWorldPosition; // give this to me every step - I need it to update the sound symbol
102 F32 mSpeakingAmplitude; // this should be set as often as possible when the user is speaking
103 F32 mMaxGesticulationAmplitude; // this is the upper-limit of the envelope of detectable gesticulation leves
104 F32 mMinGesticulationAmplitude; // this is the lower-limit of the envelope of detectable gesticulation leves
105
106};//-----------------------------------------------------------------
107 // end of LLVoiceVisualizer class
108//------------------------------------------------------------------
109
110#endif //LL_VOICE_VISUALIZER_H
111
diff --git a/linden/indra/newview/llvolumesliderctrl.cpp b/linden/indra/newview/llvolumesliderctrl.cpp
deleted file mode 100644
index 54cfa30..0000000
--- a/linden/indra/newview/llvolumesliderctrl.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
1/**
2 * @file llvolumesliderctrl.cpp
3 * @brief Horizontal volume slider.
4 *
5 * Copyright (c) 2004-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "llviewerprecompiledheaders.h"
30
31#include "llvolumesliderctrl.h"
32
33#include "llfocusmgr.h"
34
35#include "llui.h"
36
37const F32 VOL_DEFAULT = 0.125f;
38const F32 VOL_MIN = 0.f;
39const F32 VOL_MAX = 0.5f;
40const F32 VOL_INC = 0.01f;
41
42LLVolumeSliderCtrl::LLVolumeSliderCtrl(const std::string& name,
43 const LLRect& rect,
44 void (*commit_callback)(LLUICtrl*, void*),
45 void* callback_data)
46 :
47LLSlider(name, rect, commit_callback, callback_data,
48 VOL_DEFAULT,
49 VOL_MIN,
50 VOL_MAX,
51 VOL_INC)
52{ }
53
54LLVolumeSliderCtrl::~LLVolumeSliderCtrl()
55{ }
56
57// virtual
58void LLVolumeSliderCtrl::draw()
59{
60 if(!getVisible()) return;
61
62 F32 opacity = mEnabled ? 1.f : 0.3f;
63
64 // Track
65 LLRect track(0, mRect.getHeight(), mRect.getWidth(), 0);
66
67 track.mBottom += 3;
68 track.mTop -= 1;
69 track.mRight -= 1;
70
71 LLColor4 center_color = (mThumbCenterColor % opacity);
72 LLColor4 outline_color = (mThumbOutlineColor % opacity);
73
74 gl_triangle_2d(track.mLeft, track.mBottom,
75 track.mRight, track.mBottom,
76 track.mRight, track.mTop,
77 center_color,
78 TRUE);
79 gl_triangle_2d(track.mLeft, track.mBottom,
80 track.mRight, track.mBottom,
81 track.mRight, track.mTop,
82 outline_color,
83 FALSE);
84
85 if (hasMouseCapture())
86 {
87 // Thumb
88 LLRect rect(mDragStartThumbRect);
89 gl_rect_2d( rect, outline_color );
90 rect.stretch(-1);
91 gl_rect_2d( rect, mThumbCenterColor % 0.3f );
92
93 // Thumb
94 if (gFocusMgr.childHasKeyboardFocus(this))
95 {
96 LLRect thumb_rect = mThumbRect;
97 thumb_rect.stretch(llround(lerp(1.f, 3.f, gFocusMgr.getFocusFlashAmt())));
98 gl_rect_2d(thumb_rect, gFocusMgr.getFocusColor());
99 }
100 gl_rect_2d( mThumbRect, mThumbOutlineColor );
101 }
102 else
103 {
104 LLRect rect(mThumbRect);
105 // Thumb
106 if (gFocusMgr.childHasKeyboardFocus(this))
107 {
108 LLRect thumb_rect = mThumbRect;
109 thumb_rect.stretch(llround(lerp(1.f, 3.f, gFocusMgr.getFocusFlashAmt())));
110 gl_rect_2d(thumb_rect, gFocusMgr.getFocusColor());
111 }
112
113 // Thumb
114 gl_rect_2d(rect, outline_color);
115 rect.stretch(-1);
116 gl_rect_2d( rect, center_color);
117 }
118
119 LLUICtrl::draw();
120}
121
122// virtual
123LLXMLNodePtr LLVolumeSliderCtrl::getXML(bool save_children) const
124{
125 LLXMLNodePtr node = LLUICtrl::getXML();
126
127 LLString control_name = getControlName();
128 if (!control_name.empty())
129 {
130 node->createChild("control_name", TRUE)->setStringValue(control_name);
131 }
132 node->createChild("initial_val", TRUE)->setFloatValue(getInitialValue());
133 node->createChild("min_val", TRUE)->setFloatValue(getMinValue());
134 node->createChild("max_val", TRUE)->setFloatValue(getMaxValue());
135 node->createChild("increment", TRUE)->setFloatValue(getIncrement());
136
137 return node;
138}
139
140LLView* LLVolumeSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
141{ LLString name("volume_slider");
142
143 node->getAttributeString("name", name);
144
145 LLString label;
146 node->getAttributeString("label", label);
147
148 LLRect rect;
149 createRect(node, rect, parent, LLRect());
150
151 LLFontGL* font = LLView::selectFont(node);
152
153 // HACK: Font might not be specified.
154 if (!font)
155 {
156 font = LLFontGL::sSansSerifSmall;
157 }
158
159 S32 label_width = font->getWidth(label) + 8;
160 node->getAttributeS32("label_width", label_width);
161
162 LLString control_name;
163 node->getAttributeString("control_name", control_name);
164
165 BOOL show_text = TRUE;
166 node->getAttributeBOOL("show_text", show_text);
167
168 BOOL can_edit_text = FALSE;
169 node->getAttributeBOOL("can_edit_text", can_edit_text);
170
171 F32 initial_value = 0.f;
172 node->getAttributeF32("initial_val", initial_value);
173
174 F32 min_value = 0.f;
175 node->getAttributeF32("min_val", min_value);
176
177 F32 max_value = 1.f;
178 node->getAttributeF32("max_val", max_value);
179
180 F32 increment = 0.1f;
181 node->getAttributeF32("increment", increment);
182
183 U32 precision = 3;
184 node->getAttributeU32("decimal_digits", precision);
185
186
187 LLVolumeSliderCtrl* slider = new LLVolumeSliderCtrl(name,rect,NULL,NULL);
188
189 slider->initFromXML(node, parent);
190
191 return slider;
192}
193
diff --git a/linden/indra/newview/llvopartgroup.cpp b/linden/indra/newview/llvopartgroup.cpp
index 94027a3..791b4ab 100644
--- a/linden/indra/newview/llvopartgroup.cpp
+++ b/linden/indra/newview/llvopartgroup.cpp
@@ -435,7 +435,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
435 drawablep->updateFaceSize(j); 435 drawablep->updateFaceSize(j);
436 436
437 LLFace* facep = drawablep->getFace(j); 437 LLFace* facep = drawablep->getFace(j);
438 if (!facep->hasGeometry()) 438 if ( !facep || !facep->hasGeometry())
439 { 439 {
440 continue; 440 continue;
441 } 441 }
diff --git a/linden/indra/newview/llvosky.cpp b/linden/indra/newview/llvosky.cpp
index 2d31bf4..442ef23 100644
--- a/linden/indra/newview/llvosky.cpp
+++ b/linden/indra/newview/llvosky.cpp
@@ -1406,17 +1406,17 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
1406 const F32 camera_height = mCameraPosAgent.mV[2]; 1406 const F32 camera_height = mCameraPosAgent.mV[2];
1407 const F32 height_above_water = camera_height - water_height; 1407 const F32 height_above_water = camera_height - water_height;
1408 1408
1409 BOOL sun = FALSE; 1409 BOOL sun_flag = FALSE;
1410 1410
1411 if (mSun.isVisible()) 1411 if (mSun.isVisible())
1412 { 1412 {
1413 if (mMoon.isVisible()) 1413 if (mMoon.isVisible())
1414 { 1414 {
1415 sun = look_at * mSun.getDirection() > 0; 1415 sun_flag = look_at * mSun.getDirection() > 0;
1416 } 1416 }
1417 else 1417 else
1418 { 1418 {
1419 sun = TRUE; 1419 sun_flag = TRUE;
1420 } 1420 }
1421 } 1421 }
1422 1422
@@ -1427,7 +1427,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
1427#else 1427#else
1428 BOOL render_ref = !(gPipeline.getVertexShaderLevel(LLPipeline::SHADER_ENVIRONMENT) >= LLDrawPoolWater::SHADER_LEVEL_RIPPLE); 1428 BOOL render_ref = !(gPipeline.getVertexShaderLevel(LLPipeline::SHADER_ENVIRONMENT) >= LLDrawPoolWater::SHADER_LEVEL_RIPPLE);
1429#endif 1429#endif
1430 if (sun) 1430 if (sun_flag)
1431 { 1431 {
1432 setDrawRefl(0); 1432 setDrawRefl(0);
1433 if (render_ref) 1433 if (render_ref)
diff --git a/linden/indra/newview/llvotree.cpp b/linden/indra/newview/llvotree.cpp
index 45a9e0a..a752fca 100644
--- a/linden/indra/newview/llvotree.cpp
+++ b/linden/indra/newview/llvotree.cpp
@@ -406,15 +406,13 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent)
406 406
407void LLVOTree::updateTextures(LLAgent &agent) 407void LLVOTree::updateTextures(LLAgent &agent)
408{ 408{
409 F32 texel_area_ratio = 1.f;
410 F32 cos_angle = 1.f;
411 if (mTreeImagep) 409 if (mTreeImagep)
412 { 410 {
413 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) 411 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
414 { 412 {
415 setDebugText(llformat("%4.0f", fsqrtf(mPixelArea))); 413 setDebugText(llformat("%4.0f", fsqrtf(mPixelArea)));
416 } 414 }
417 mTreeImagep->addTextureStats(mPixelArea, texel_area_ratio, cos_angle); 415 mTreeImagep->addTextureStats(mPixelArea);
418 } 416 }
419 417
420} 418}
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp
index ccf0cba..a0a83f5 100644
--- a/linden/indra/newview/llvovolume.cpp
+++ b/linden/indra/newview/llvovolume.cpp
@@ -800,6 +800,8 @@ BOOL LLVOVolume::updateLOD()
800 mLODChanged = TRUE; 800 mLODChanged = TRUE;
801 } 801 }
802 802
803 lod_changed |= LLViewerObject::updateLOD();
804
803 return lod_changed; 805 return lod_changed;
804} 806}
805 807
@@ -1128,7 +1130,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
1128 mSculptChanged = FALSE; 1130 mSculptChanged = FALSE;
1129 mFaceMappingChanged = FALSE; 1131 mFaceMappingChanged = FALSE;
1130 1132
1131 return TRUE; 1133 return LLViewerObject::updateGeometry(drawable);
1132} 1134}
1133 1135
1134void LLVOVolume::updateFaceSize(S32 idx) 1136void LLVOVolume::updateFaceSize(S32 idx)
diff --git a/linden/indra/newview/llweb.cpp b/linden/indra/newview/llweb.cpp
index 910f0c4..d15d4c4 100644
--- a/linden/indra/newview/llweb.cpp
+++ b/linden/indra/newview/llweb.cpp
@@ -47,7 +47,9 @@ void LLWeb::loadURL(std::string url)
47void LLWeb::loadURLExternal(std::string url) 47void LLWeb::loadURLExternal(std::string url)
48{ 48{
49 std::string escaped_url = escapeURL(url); 49 std::string escaped_url = escapeURL(url);
50#if LL_LIBXUL_ENABLED
50 spawn_web_browser(escaped_url.c_str()); 51 spawn_web_browser(escaped_url.c_str());
52#endif
51} 53}
52 54
53 55
diff --git a/linden/indra/newview/llwebbrowserctrl.cpp b/linden/indra/newview/llwebbrowserctrl.cpp
index bd671fa..26e5076 100644
--- a/linden/indra/newview/llwebbrowserctrl.cpp
+++ b/linden/indra/newview/llwebbrowserctrl.cpp
@@ -280,10 +280,10 @@ BOOL LLWebBrowserCtrl::handleUnicodeChar(llwchar uni_char, BOOL called_from_pare
280 280
281//////////////////////////////////////////////////////////////////////////////// 281////////////////////////////////////////////////////////////////////////////////
282// 282//
283void LLWebBrowserCtrl::onVisibilityChange ( BOOL curVisibilityIn ) 283void LLWebBrowserCtrl::onVisibilityChange ( BOOL new_visibility )
284{ 284{
285 // set state of frequent updates automatically if visibility changes 285 // set state of frequent updates automatically if visibility changes
286 if ( curVisibilityIn ) 286 if ( new_visibility )
287 { 287 {
288 mFrequentUpdates = true; 288 mFrequentUpdates = true;
289 } 289 }
diff --git a/linden/indra/newview/llworldmap.cpp b/linden/indra/newview/llworldmap.cpp
index db7ac19..82e6b6e 100644
--- a/linden/indra/newview/llworldmap.cpp
+++ b/linden/indra/newview/llworldmap.cpp
@@ -245,20 +245,25 @@ LLSimInfo* LLWorldMap::simInfoFromName(const LLString& sim_name)
245 return sim_info; 245 return sim_info;
246} 246}
247 247
248LLString LLWorldMap::simNameFromPosGlobal(const LLVector3d& pos_global) 248bool LLWorldMap::simNameFromPosGlobal(const LLVector3d& pos_global, LLString & outSimName )
249{ 249{
250 bool gotSimName = true;
251
250 U64 handle = to_region_handle(pos_global); 252 U64 handle = to_region_handle(pos_global);
251 253
252 sim_info_map_t::iterator it = mSimInfoMap.find(handle); 254 sim_info_map_t::iterator it = mSimInfoMap.find(handle);
253 if (it != mSimInfoMap.end()) 255 if (it != mSimInfoMap.end())
254 { 256 {
255 LLSimInfo* info = (*it).second; 257 LLSimInfo* info = (*it).second;
256 return info->mName.c_str(); 258 outSimName = info->mName.c_str();
257 } 259 }
258 else 260 else
259 { 261 {
260 return "(unknown region)"; 262 gotSimName = false;
263 outSimName = "(unknown region)";
261 } 264 }
265
266 return gotSimName;
262} 267}
263 268
264void LLWorldMap::setCurrentLayer(S32 layer, bool request_layer) 269void LLWorldMap::setCurrentLayer(S32 layer, bool request_layer)
diff --git a/linden/indra/newview/llworldmap.h b/linden/indra/newview/llworldmap.h
index c4af7d8..5aaff63 100644
--- a/linden/indra/newview/llworldmap.h
+++ b/linden/indra/newview/llworldmap.h
@@ -135,8 +135,8 @@ public:
135 // Returns simulator information for named sim, or NULL if non-existent 135 // Returns simulator information for named sim, or NULL if non-existent
136 LLSimInfo* simInfoFromName(const LLString& sim_name); 136 LLSimInfo* simInfoFromName(const LLString& sim_name);
137 137
138 // Returns simulator name 138 // Gets simulator name for a global position, returns true if it was found
139 LLString simNameFromPosGlobal(const LLVector3d& pos_global); 139 bool simNameFromPosGlobal(const LLVector3d& pos_global, LLString & outSimName );
140 140
141 // Sets the current layer 141 // Sets the current layer
142 void setCurrentLayer(S32 layer, bool request_layer = false); 142 void setCurrentLayer(S32 layer, bool request_layer = false);
diff --git a/linden/indra/newview/llworldmapview.cpp b/linden/indra/newview/llworldmapview.cpp
index 328af72..0c98305 100644
--- a/linden/indra/newview/llworldmapview.cpp
+++ b/linden/indra/newview/llworldmapview.cpp
@@ -312,8 +312,7 @@ void LLWorldMapView::draw()
312 const S32 half_height = height / 2; 312 const S32 half_height = height / 2;
313 LLVector3d camera_global = gAgent.getCameraPositionGlobal(); 313 LLVector3d camera_global = gAgent.getCameraPositionGlobal();
314 314
315 LLGLEnable scissor_test(GL_SCISSOR_TEST); 315 LLLocalClipRect clip(getLocalRect());
316 LLUI::setScissorRegionLocal(LLRect(0, height, width, 0));
317 { 316 {
318 LLGLSNoTexture no_texture; 317 LLGLSNoTexture no_texture;
319 318
diff --git a/linden/indra/newview/llxmlrpctransaction.cpp b/linden/indra/newview/llxmlrpctransaction.cpp
index 887b69d..55074a4 100644
--- a/linden/indra/newview/llxmlrpctransaction.cpp
+++ b/linden/indra/newview/llxmlrpctransaction.cpp
@@ -240,6 +240,8 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
240 curl_easy_setopt(mCurl, CURLOPT_CAINFO, gDirUtilp->getCAFile().c_str()); 240 curl_easy_setopt(mCurl, CURLOPT_CAINFO, gDirUtilp->getCAFile().c_str());
241 curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, (long) gVerifySSLCert); 241 curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, (long) gVerifySSLCert);
242 curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYHOST, gVerifySSLCert? 2L : 0L); 242 curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYHOST, gVerifySSLCert? 2L : 0L);
243 // Be a little impatient about establishing connections.
244 curl_easy_setopt(mCurl, CURLOPT_CONNECTTIMEOUT, 40L);
243 245
244 /* Setting the DNS cache timeout to -1 disables it completely. 246 /* Setting the DNS cache timeout to -1 disables it completely.
245 This might help with bug #503 */ 247 This might help with bug #503 */
diff --git a/linden/indra/newview/macview.xcodeproj/project.pbxproj b/linden/indra/newview/macview.xcodeproj/project.pbxproj
index 08e64b4..669833e 100644
--- a/linden/indra/newview/macview.xcodeproj/project.pbxproj
+++ b/linden/indra/newview/macview.xcodeproj/project.pbxproj
@@ -27,6 +27,9 @@
27 1A0201850B7A861200D5C589 /* llblowfishcipher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A02017E0B7A861200D5C589 /* llblowfishcipher.cpp */; }; 27 1A0201850B7A861200D5C589 /* llblowfishcipher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A02017E0B7A861200D5C589 /* llblowfishcipher.cpp */; };
28 1A0201860B7A861200D5C589 /* llnullcipher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0201810B7A861200D5C589 /* llnullcipher.cpp */; }; 28 1A0201860B7A861200D5C589 /* llnullcipher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0201810B7A861200D5C589 /* llnullcipher.cpp */; };
29 1A0201870B7A861200D5C589 /* llxorcipher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0201830B7A861200D5C589 /* llxorcipher.cpp */; }; 29 1A0201870B7A861200D5C589 /* llxorcipher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0201830B7A861200D5C589 /* llxorcipher.cpp */; };
30 1A0DA5130C3AC07800361F49 /* llviewerjointmesh_vec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DA5100C3AC07700361F49 /* llviewerjointmesh_vec.cpp */; };
31 1A0DA5140C3AC07800361F49 /* llviewerjointmesh_sse2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DA5110C3AC07700361F49 /* llviewerjointmesh_sse2.cpp */; };
32 1A0DA5150C3AC07800361F49 /* llviewerjointmesh_sse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DA5120C3AC07700361F49 /* llviewerjointmesh_sse.cpp */; };
30 1A1C61620847AEE6005D7227 /* llvolumemgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1C615E0847AEE6005D7227 /* llvolumemgr.cpp */; }; 33 1A1C61620847AEE6005D7227 /* llvolumemgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1C615E0847AEE6005D7227 /* llvolumemgr.cpp */; };
31 1A1C61630847AEE6005D7227 /* llvolume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1C615F0847AEE6005D7227 /* llvolume.cpp */; }; 34 1A1C61630847AEE6005D7227 /* llvolume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1C615F0847AEE6005D7227 /* llvolume.cpp */; };
32 1A1C61760847B307005D7227 /* llvolumemessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1C61740847B307005D7227 /* llvolumemessage.cpp */; }; 35 1A1C61760847B307005D7227 /* llvolumemessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1C61740847B307005D7227 /* llvolumemessage.cpp */; };
@@ -260,7 +263,6 @@
260 5503BC2505446B20003D051F /* llfloatermap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AAD051F61DF00A80050 /* llfloatermap.cpp */; }; 263 5503BC2505446B20003D051F /* llfloatermap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AAD051F61DF00A80050 /* llfloatermap.cpp */; };
261 5503BC2705446B20003D051F /* llregionposition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AAF051F61DF00A80050 /* llregionposition.cpp */; }; 264 5503BC2705446B20003D051F /* llregionposition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AAF051F61DF00A80050 /* llregionposition.cpp */; };
262 5503BC2905446B20003D051F /* llasynchostbyname.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AB2051F61DF00A80050 /* llasynchostbyname.cpp */; }; 265 5503BC2905446B20003D051F /* llasynchostbyname.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AB2051F61DF00A80050 /* llasynchostbyname.cpp */; };
263 5503BC2A05446B20003D051F /* llaudiostatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AB3051F61DF00A80050 /* llaudiostatus.cpp */; };
264 5503BC2B05446B20003D051F /* llpanelavatar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AB4051F61DF00A80050 /* llpanelavatar.cpp */; }; 266 5503BC2B05446B20003D051F /* llpanelavatar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AB4051F61DF00A80050 /* llpanelavatar.cpp */; };
265 5503BC2C05446B20003D051F /* llpanelaudioprefs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AB5051F61DF00A80050 /* llpanelaudioprefs.cpp */; }; 267 5503BC2C05446B20003D051F /* llpanelaudioprefs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AB5051F61DF00A80050 /* llpanelaudioprefs.cpp */; };
266 5503BC2D05446B20003D051F /* llfloaterbuy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AB6051F61DF00A80050 /* llfloaterbuy.cpp */; }; 268 5503BC2D05446B20003D051F /* llfloaterbuy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F52AB6051F61DF00A80050 /* llfloaterbuy.cpp */; };
@@ -423,6 +425,7 @@
423 61923D6C074AE3C0005E1F34 /* llstatemachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923D25074AE3C0005E1F34 /* llstatemachine.cpp */; }; 425 61923D6C074AE3C0005E1F34 /* llstatemachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923D25074AE3C0005E1F34 /* llstatemachine.cpp */; };
424 61923D6E074AE3C0005E1F34 /* lltargetingmotion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923D27074AE3C0005E1F34 /* lltargetingmotion.cpp */; }; 426 61923D6E074AE3C0005E1F34 /* lltargetingmotion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923D27074AE3C0005E1F34 /* lltargetingmotion.cpp */; };
425 61923D70074AE3C0005E1F34 /* llvisualparam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923D29074AE3C0005E1F34 /* llvisualparam.cpp */; }; 427 61923D70074AE3C0005E1F34 /* llvisualparam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923D29074AE3C0005E1F34 /* llvisualparam.cpp */; };
428 79256EA30C57D6A5000AAFA4 /* llfloatervoicewizard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79256EA10C57D6A4000AAFA4 /* llfloatervoicewizard.cpp */; };
426 84401E2F0A13CC9A006720A5 /* llfloatergroupinvite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84401E2D0A13CC9A006720A5 /* llfloatergroupinvite.cpp */; }; 429 84401E2F0A13CC9A006720A5 /* llfloatergroupinvite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84401E2D0A13CC9A006720A5 /* llfloatergroupinvite.cpp */; };
427 84401E320A13CCB2006720A5 /* llpanelgroupinvite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84401E300A13CCB2006720A5 /* llpanelgroupinvite.cpp */; }; 430 84401E320A13CCB2006720A5 /* llpanelgroupinvite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84401E300A13CCB2006720A5 /* llpanelgroupinvite.cpp */; };
428 8833693F0C18AF33007F52DA /* llimagepng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8833693B0C18AF33007F52DA /* llimagepng.cpp */; }; 431 8833693F0C18AF33007F52DA /* llimagepng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8833693B0C18AF33007F52DA /* llimagepng.cpp */; };
@@ -431,7 +434,6 @@
431 88A95BCA0C14D92C0027E363 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 88A95BC90C14D92C0027E363 /* libresolv.dylib */; }; 434 88A95BCA0C14D92C0027E363 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 88A95BC90C14D92C0027E363 /* libresolv.dylib */; };
432 88AA282C0C17720D0032DF53 /* libpng12.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 88AA282B0C17720D0032DF53 /* libpng12.a */; }; 435 88AA282C0C17720D0032DF53 /* libpng12.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 88AA282B0C17720D0032DF53 /* libpng12.a */; };
433 9104C0CC0778AE0F001EC4F6 /* llpanelmsgs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9104C0CB0778AE0F001EC4F6 /* llpanelmsgs.cpp */; }; 436 9104C0CC0778AE0F001EC4F6 /* llpanelmsgs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9104C0CB0778AE0F001EC4F6 /* llpanelmsgs.cpp */; };
434 910D255306484F1A0034E66F /* llvolumesliderctrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910D255206484F1A0034E66F /* llvolumesliderctrl.cpp */; };
435 9117EAA20BF24A6100845BD2 /* llpacketack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9117EAA10BF24A6100845BD2 /* llpacketack.cpp */; }; 437 9117EAA20BF24A6100845BD2 /* llpacketack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9117EAA10BF24A6100845BD2 /* llpacketack.cpp */; };
436 9118669B07F4FAF700E3D5BC /* llmediaremotectrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9118669907F4FAF700E3D5BC /* llmediaremotectrl.cpp */; }; 438 9118669B07F4FAF700E3D5BC /* llmediaremotectrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9118669907F4FAF700E3D5BC /* llmediaremotectrl.cpp */; };
437 911CAD87075BE87B00CD1090 /* llinventoryview.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 911CAD86075BE87B00CD1090 /* llinventoryview.cpp */; }; 439 911CAD87075BE87B00CD1090 /* llinventoryview.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 911CAD86075BE87B00CD1090 /* llinventoryview.cpp */; };
@@ -496,9 +498,13 @@
496 9928ACA5056D9353003865BE /* CrashReporter.nib in Resources */ = {isa = PBXBuildFile; fileRef = 9928ACA4056D9353003865BE /* CrashReporter.nib */; }; 498 9928ACA5056D9353003865BE /* CrashReporter.nib in Resources */ = {isa = PBXBuildFile; fileRef = 9928ACA4056D9353003865BE /* CrashReporter.nib */; };
497 9930A8E40B8FB10A00197ECA /* language.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9930A8E30B8FB10A00197ECA /* language.txt */; }; 499 9930A8E40B8FB10A00197ECA /* language.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9930A8E30B8FB10A00197ECA /* language.txt */; };
498 99321B14081DD26000678159 /* llworkerthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99321B12081DD26000678159 /* llworkerthread.cpp */; }; 500 99321B14081DD26000678159 /* llworkerthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99321B12081DD26000678159 /* llworkerthread.cpp */; };
501 99374E4E0B5C6059008DB4BE /* lliosocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99374E460B5C603E008DB4BE /* lliosocket.cpp */; };
502 993A3E050B546D47007A0790 /* llvoiceclient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 993A3E040B546D47007A0790 /* llvoiceclient.cpp */; };
499 994ADAE30A8016E600061DFB /* libllmozlib.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 994ADAE20A8016E500061DFB /* libllmozlib.dylib */; }; 503 994ADAE30A8016E600061DFB /* libllmozlib.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 994ADAE20A8016E500061DFB /* libllmozlib.dylib */; };
500 9950AF460B3762A1007E36E0 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; }; 504 9950AF460B3762A1007E36E0 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
501 9950AF610B3763DF007E36E0 /* libfmodwrapper.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 9967E9090B37533F0087BD1B /* libfmodwrapper.dylib */; }; 505 9950AF610B3763DF007E36E0 /* libfmodwrapper.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 9967E9090B37533F0087BD1B /* libfmodwrapper.dylib */; };
506 9956CAFD0B96679C00F58C6D /* llprefsvoice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9956CAFC0B96679C00F58C6D /* llprefsvoice.cpp */; };
507 996209690B864D0E00392531 /* SLVoiceAgent.app in Resources */ = {isa = PBXBuildFile; fileRef = 996209680B864D0E00392531 /* SLVoiceAgent.app */; };
502 9967E9200B3754800087BD1B /* libfmodwrapper.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9967E9090B37533F0087BD1B /* libfmodwrapper.dylib */; }; 508 9967E9200B3754800087BD1B /* libfmodwrapper.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9967E9090B37533F0087BD1B /* libfmodwrapper.dylib */; };
503 9967E98D0B375B0E0087BD1B /* fmodwrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9967E9520B37564D0087BD1B /* fmodwrapper.cpp */; }; 509 9967E98D0B375B0E0087BD1B /* fmodwrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9967E9520B37564D0087BD1B /* fmodwrapper.cpp */; };
504 9967E9B30B375D9D0087BD1B /* libfmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FDE8765009BEA39600AF6316 /* libfmod.a */; }; 510 9967E9B30B375D9D0087BD1B /* libfmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FDE8765009BEA39600AF6316 /* libfmod.a */; };
@@ -511,6 +517,7 @@
511 99BB5176099AC2A4004BF9F2 /* llconfirmationmanager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99BB5174099AC2A4004BF9F2 /* llconfirmationmanager.cpp */; }; 517 99BB5176099AC2A4004BF9F2 /* llconfirmationmanager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99BB5174099AC2A4004BF9F2 /* llconfirmationmanager.cpp */; };
512 99C6BFAA0A1BBD4800419AE7 /* llfloaterhtmlfind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99C6BFA90A1BBD4800419AE7 /* llfloaterhtmlfind.cpp */; }; 518 99C6BFAA0A1BBD4800419AE7 /* llfloaterhtmlfind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99C6BFA90A1BBD4800419AE7 /* llfloaterhtmlfind.cpp */; };
513 99C7B320081F128400499A23 /* llvfsthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91A154F8081DC15E0089988C /* llvfsthread.cpp */; }; 519 99C7B320081F128400499A23 /* llvfsthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91A154F8081DC15E0089988C /* llvfsthread.cpp */; };
520 99C9FA670B6AD9BF00A1BBA6 /* SLVoice in Resources */ = {isa = PBXBuildFile; fileRef = 99C9FA660B6AD9BF00A1BBA6 /* SLVoice */; };
514 99DB67DF07C161A500CF3185 /* llmediaimplquicktime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99DB67DB07C161A500CF3185 /* llmediaimplquicktime.cpp */; }; 521 99DB67DF07C161A500CF3185 /* llmediaimplquicktime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99DB67DB07C161A500CF3185 /* llmediaimplquicktime.cpp */; };
515 99E4326D092D5996003AE728 /* llassettype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E4326B092D5996003AE728 /* llassettype.cpp */; }; 522 99E4326D092D5996003AE728 /* llassettype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E4326B092D5996003AE728 /* llassettype.cpp */; };
516 99E4350C092D644F003AE728 /* llmortician.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E4350B092D644F003AE728 /* llmortician.cpp */; }; 523 99E4350C092D644F003AE728 /* llmortician.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E4350B092D644F003AE728 /* llmortician.cpp */; };
@@ -518,6 +525,10 @@
518 99E43514092D64CC003AE728 /* llmemoryview.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E43513092D64CC003AE728 /* llmemoryview.cpp */; }; 525 99E43514092D64CC003AE728 /* llmemoryview.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E43513092D64CC003AE728 /* llmemoryview.cpp */; };
519 99E43517092D64E6003AE728 /* llvoinventorylistener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E43516092D64E6003AE728 /* llvoinventorylistener.cpp */; }; 526 99E43517092D64E6003AE728 /* llvoinventorylistener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E43516092D64E6003AE728 /* llvoinventorylistener.cpp */; };
520 99E4351A092D6535003AE728 /* llcommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E43519092D6535003AE728 /* llcommon.cpp */; }; 527 99E4351A092D6535003AE728 /* llcommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E43519092D6535003AE728 /* llcommon.cpp */; };
528 99E63DFF0BCADD2F000C1751 /* libalut.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 99E63DEF0BCADD14000C1751 /* libalut.dylib */; };
529 99E63E000BCADD2F000C1751 /* libopenal.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 99E63DF20BCADD14000C1751 /* libopenal.dylib */; };
530 99E63E010BCADD2F000C1751 /* libortp.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 99E63DF00BCADD14000C1751 /* libortp.dylib */; };
531 99E63E020BCADD2F000C1751 /* libvivoxsdk.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 99E63DF10BCADD14000C1751 /* libvivoxsdk.dylib */; };
521 99E64039081F1CB80009003F /* llgl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E64036081F1CB80009003F /* llgl.cpp */; }; 532 99E64039081F1CB80009003F /* llgl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E64036081F1CB80009003F /* llgl.cpp */; };
522 99EDDF5C05892E720031B20D /* llfloaterlandholdings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99EDDF5B05892E720031B20D /* llfloaterlandholdings.cpp */; }; 533 99EDDF5C05892E720031B20D /* llfloaterlandholdings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99EDDF5B05892E720031B20D /* llfloaterlandholdings.cpp */; };
523 99EDE33705896DC10031B20D /* SecondLife.nib in Resources */ = {isa = PBXBuildFile; fileRef = 99EDE33605896DC10031B20D /* SecondLife.nib */; }; 534 99EDE33705896DC10031B20D /* SecondLife.nib in Resources */ = {isa = PBXBuildFile; fileRef = 99EDE33605896DC10031B20D /* SecondLife.nib */; };
@@ -563,6 +574,7 @@
563 AA02B9BC0B0CE44D00F2996D /* lltexturefetch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA02B9BA0B0CE44D00F2996D /* lltexturefetch.cpp */; }; 574 AA02B9BC0B0CE44D00F2996D /* lltexturefetch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA02B9BA0B0CE44D00F2996D /* lltexturefetch.cpp */; };
564 AA0E2A610A2FDAEE0066250A /* llcontrol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA0E2A5F0A2FDAEE0066250A /* llcontrol.cpp */; }; 575 AA0E2A610A2FDAEE0066250A /* llcontrol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA0E2A5F0A2FDAEE0066250A /* llcontrol.cpp */; };
565 AA0E2A640A2FDB340066250A /* lltoolpipette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA0E2A620A2FDB340066250A /* lltoolpipette.cpp */; }; 576 AA0E2A640A2FDB340066250A /* lltoolpipette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA0E2A620A2FDB340066250A /* lltoolpipette.cpp */; };
577 AA1183500C1DF9C400FDE5BA /* llpanelaudiovolume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA11834E0C1DF9C400FDE5BA /* llpanelaudiovolume.cpp */; };
566 AA348DFA0B0EAB31002C3015 /* llcurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA348DF80B0EAB31002C3015 /* llcurl.cpp */; }; 578 AA348DFA0B0EAB31002C3015 /* llcurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA348DF80B0EAB31002C3015 /* llcurl.cpp */; };
567 AAA1336B0A3F94D000419F7C /* lluistring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAA133690A3F94D000419F7C /* lluistring.cpp */; }; 579 AAA1336B0A3F94D000419F7C /* lluistring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAA133690A3F94D000419F7C /* lluistring.cpp */; };
568 AAC121A50A93A8380080E8A9 /* llfloatersellland.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAC121A30A93A8380080E8A9 /* llfloatersellland.cpp */; }; 580 AAC121A50A93A8380080E8A9 /* llfloatersellland.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAC121A30A93A8380080E8A9 /* llfloatersellland.cpp */; };
@@ -584,7 +596,11 @@
584 D64594680B3B732200FAB68F /* llimagejpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923DA2074AE4F2005E1F34 /* llimagejpeg.cpp */; }; 596 D64594680B3B732200FAB68F /* llimagejpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923DA2074AE4F2005E1F34 /* llimagejpeg.cpp */; };
585 D64594690B3B732300FAB68F /* llimagetga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923DA4074AE4F2005E1F34 /* llimagetga.cpp */; }; 597 D64594690B3B732300FAB68F /* llimagetga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61923DA4074AE4F2005E1F34 /* llimagetga.cpp */; };
586 D651349D0B3C40870042C56E /* llqueuedthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AF9D84F08B405630094E8E7 /* llqueuedthread.cpp */; }; 598 D651349D0B3C40870042C56E /* llqueuedthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AF9D84F08B405630094E8E7 /* llqueuedthread.cpp */; };
599 D6B766800BFE8E9B00DC8153 /* llfloaterchatterbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6B7667F0BFE8E9A00DC8153 /* llfloaterchatterbox.cpp */; };
587 D6F77CBC0B445C3B0040826D /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9985A1270AC1FE4E00579AFB /* AppKit.framework */; }; 600 D6F77CBC0B445C3B0040826D /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9985A1270AC1FE4E00579AFB /* AppKit.framework */; };
601 D8CA570F0BAF74FC0093D6D4 /* llvoicevisualizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D8CA570E0BAF74FC0093D6D4 /* llvoicevisualizer.cpp */; };
602 D8EAB8B60BE7B3D10067DBB3 /* llfloateractivespeakers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D8EAB8B40BE7B3D10067DBB3 /* llfloateractivespeakers.cpp */; };
603 D8EAB8BA0BE7B4490067DBB3 /* llvoiceremotectrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D8EAB8B80BE7B4490067DBB3 /* llvoiceremotectrl.cpp */; };
588 DA4B141B0B978815003F64DE /* llhttpsender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA4B14140B978815003F64DE /* llhttpsender.cpp */; }; 604 DA4B141B0B978815003F64DE /* llhttpsender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA4B14140B978815003F64DE /* llhttpsender.cpp */; };
589 DA4B141C0B978815003F64DE /* llsdmessagebuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA4B14170B978815003F64DE /* llsdmessagebuilder.cpp */; }; 605 DA4B141C0B978815003F64DE /* llsdmessagebuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA4B14170B978815003F64DE /* llsdmessagebuilder.cpp */; };
590 DA4B141D0B978815003F64DE /* llsdmessagereader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA4B14190B978815003F64DE /* llsdmessagereader.cpp */; }; 606 DA4B141D0B978815003F64DE /* llsdmessagereader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA4B14190B978815003F64DE /* llsdmessagereader.cpp */; };
@@ -820,6 +836,9 @@
820 1A0201820B7A861200D5C589 /* llnullcipher.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llnullcipher.h; sourceTree = "<group>"; }; 836 1A0201820B7A861200D5C589 /* llnullcipher.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llnullcipher.h; sourceTree = "<group>"; };
821 1A0201830B7A861200D5C589 /* llxorcipher.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llxorcipher.cpp; sourceTree = "<group>"; }; 837 1A0201830B7A861200D5C589 /* llxorcipher.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llxorcipher.cpp; sourceTree = "<group>"; };
822 1A0201840B7A861200D5C589 /* llxorcipher.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llxorcipher.h; sourceTree = "<group>"; }; 838 1A0201840B7A861200D5C589 /* llxorcipher.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llxorcipher.h; sourceTree = "<group>"; };
839 1A0DA5100C3AC07700361F49 /* llviewerjointmesh_vec.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llviewerjointmesh_vec.cpp; sourceTree = "<group>"; };
840 1A0DA5110C3AC07700361F49 /* llviewerjointmesh_sse2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llviewerjointmesh_sse2.cpp; sourceTree = "<group>"; };
841 1A0DA5120C3AC07700361F49 /* llviewerjointmesh_sse.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llviewerjointmesh_sse.cpp; sourceTree = "<group>"; };
823 1A1C615E0847AEE6005D7227 /* llvolumemgr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvolumemgr.cpp; sourceTree = "<group>"; }; 842 1A1C615E0847AEE6005D7227 /* llvolumemgr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvolumemgr.cpp; sourceTree = "<group>"; };
824 1A1C615F0847AEE6005D7227 /* llvolume.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvolume.cpp; sourceTree = "<group>"; }; 843 1A1C615F0847AEE6005D7227 /* llvolume.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvolume.cpp; sourceTree = "<group>"; };
825 1A1C61600847AEE6005D7227 /* llvolumemgr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvolumemgr.h; sourceTree = "<group>"; }; 844 1A1C61600847AEE6005D7227 /* llvolumemgr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvolumemgr.h; sourceTree = "<group>"; };
@@ -1091,7 +1110,6 @@
1091 26F52AAD051F61DF00A80050 /* llfloatermap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloatermap.cpp; sourceTree = SOURCE_ROOT; }; 1110 26F52AAD051F61DF00A80050 /* llfloatermap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloatermap.cpp; sourceTree = SOURCE_ROOT; };
1092 26F52AAF051F61DF00A80050 /* llregionposition.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llregionposition.cpp; sourceTree = SOURCE_ROOT; }; 1111 26F52AAF051F61DF00A80050 /* llregionposition.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llregionposition.cpp; sourceTree = SOURCE_ROOT; };
1093 26F52AB2051F61DF00A80050 /* llasynchostbyname.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llasynchostbyname.cpp; sourceTree = SOURCE_ROOT; }; 1112 26F52AB2051F61DF00A80050 /* llasynchostbyname.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llasynchostbyname.cpp; sourceTree = SOURCE_ROOT; };
1094 26F52AB3051F61DF00A80050 /* llaudiostatus.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llaudiostatus.cpp; sourceTree = SOURCE_ROOT; };
1095 26F52AB4051F61DF00A80050 /* llpanelavatar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpanelavatar.cpp; sourceTree = SOURCE_ROOT; }; 1113 26F52AB4051F61DF00A80050 /* llpanelavatar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpanelavatar.cpp; sourceTree = SOURCE_ROOT; };
1096 26F52AB5051F61DF00A80050 /* llpanelaudioprefs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpanelaudioprefs.cpp; sourceTree = SOURCE_ROOT; }; 1114 26F52AB5051F61DF00A80050 /* llpanelaudioprefs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpanelaudioprefs.cpp; sourceTree = SOURCE_ROOT; };
1097 26F52AB6051F61DF00A80050 /* llfloaterbuy.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloaterbuy.cpp; sourceTree = SOURCE_ROOT; }; 1115 26F52AB6051F61DF00A80050 /* llfloaterbuy.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloaterbuy.cpp; sourceTree = SOURCE_ROOT; };
@@ -1271,7 +1289,6 @@
1271 619221B2074A9B58005E1F34 /* v4coloru.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = v4coloru.h; sourceTree = "<group>"; }; 1289 619221B2074A9B58005E1F34 /* v4coloru.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = v4coloru.h; sourceTree = "<group>"; };
1272 619221B3074A9B58005E1F34 /* v4math.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = v4math.cpp; sourceTree = "<group>"; }; 1290 619221B3074A9B58005E1F34 /* v4math.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = v4math.cpp; sourceTree = "<group>"; };
1273 619221B4074A9B58005E1F34 /* v4math.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = v4math.h; sourceTree = "<group>"; }; 1291 619221B4074A9B58005E1F34 /* v4math.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = v4math.h; sourceTree = "<group>"; };
1274 619221B5074A9B58005E1F34 /* vmath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vmath.h; sourceTree = "<group>"; };
1275 619221B6074A9B58005E1F34 /* xform.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = xform.cpp; sourceTree = "<group>"; }; 1292 619221B6074A9B58005E1F34 /* xform.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = xform.cpp; sourceTree = "<group>"; };
1276 619221B7074A9B58005E1F34 /* xform.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = xform.h; sourceTree = "<group>"; }; 1293 619221B7074A9B58005E1F34 /* xform.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = xform.h; sourceTree = "<group>"; };
1277 619221B9074A9B59005E1F34 /* llassetstorage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llassetstorage.cpp; sourceTree = "<group>"; }; 1294 619221B9074A9B59005E1F34 /* llassetstorage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llassetstorage.cpp; sourceTree = "<group>"; };
@@ -1292,7 +1309,6 @@
1292 619221D7074A9B59005E1F34 /* llinstantmessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llinstantmessage.h; sourceTree = "<group>"; }; 1309 619221D7074A9B59005E1F34 /* llinstantmessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llinstantmessage.h; sourceTree = "<group>"; };
1293 619221D8074A9B59005E1F34 /* llinvite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llinvite.h; sourceTree = "<group>"; }; 1310 619221D8074A9B59005E1F34 /* llinvite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llinvite.h; sourceTree = "<group>"; };
1294 619221D9074A9B59005E1F34 /* llloginflags.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llloginflags.h; sourceTree = "<group>"; }; 1311 619221D9074A9B59005E1F34 /* llloginflags.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llloginflags.h; sourceTree = "<group>"; };
1295 619221DA074A9B59005E1F34 /* lllsltransmit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lllsltransmit.h; sourceTree = "<group>"; };
1296 619221DB074A9B59005E1F34 /* llmail.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llmail.cpp; sourceTree = "<group>"; }; 1312 619221DB074A9B59005E1F34 /* llmail.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llmail.cpp; sourceTree = "<group>"; };
1297 619221DC074A9B59005E1F34 /* llmail.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llmail.h; sourceTree = "<group>"; }; 1313 619221DC074A9B59005E1F34 /* llmail.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llmail.h; sourceTree = "<group>"; };
1298 619221DD074A9B59005E1F34 /* llnamevalue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llnamevalue.cpp; sourceTree = "<group>"; }; 1314 619221DD074A9B59005E1F34 /* llnamevalue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llnamevalue.cpp; sourceTree = "<group>"; };
@@ -1422,7 +1438,6 @@
1422 61923CE0074AE2CB005E1F34 /* listener_openal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = listener_openal.h; sourceTree = "<group>"; }; 1438 61923CE0074AE2CB005E1F34 /* listener_openal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = listener_openal.h; sourceTree = "<group>"; };
1423 61923CE1074AE2CB005E1F34 /* llaudiodecodemgr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llaudiodecodemgr.cpp; sourceTree = "<group>"; }; 1439 61923CE1074AE2CB005E1F34 /* llaudiodecodemgr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llaudiodecodemgr.cpp; sourceTree = "<group>"; };
1424 61923CE2074AE2CB005E1F34 /* llaudiodecodemgr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llaudiodecodemgr.h; sourceTree = "<group>"; }; 1440 61923CE2074AE2CB005E1F34 /* llaudiodecodemgr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llaudiodecodemgr.h; sourceTree = "<group>"; };
1425 61923CE3074AE2CB005E1F34 /* llaudiosource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llaudiosource.h; sourceTree = "<group>"; };
1426 61923CE5074AE2CB005E1F34 /* vorbisdecode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = vorbisdecode.cpp; sourceTree = "<group>"; }; 1441 61923CE5074AE2CB005E1F34 /* vorbisdecode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = vorbisdecode.cpp; sourceTree = "<group>"; };
1427 61923CE6074AE2CB005E1F34 /* vorbisdecode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vorbisdecode.h; sourceTree = "<group>"; }; 1442 61923CE6074AE2CB005E1F34 /* vorbisdecode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vorbisdecode.h; sourceTree = "<group>"; };
1428 61923CE7074AE2CB005E1F34 /* vorbisencode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = vorbisencode.cpp; sourceTree = "<group>"; }; 1443 61923CE7074AE2CB005E1F34 /* vorbisencode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = vorbisencode.cpp; sourceTree = "<group>"; };
@@ -1482,6 +1497,8 @@
1482 61923DA5074AE4F2005E1F34 /* llimagetga.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llimagetga.h; sourceTree = "<group>"; }; 1497 61923DA5074AE4F2005E1F34 /* llimagetga.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llimagetga.h; sourceTree = "<group>"; };
1483 61923DA8074AE4F3005E1F34 /* llmapimagetype.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llmapimagetype.h; sourceTree = "<group>"; }; 1498 61923DA8074AE4F3005E1F34 /* llmapimagetype.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llmapimagetype.h; sourceTree = "<group>"; };
1484 6192E764074A7CE9005E1F34 /* libllcommon.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libllcommon.a; sourceTree = BUILT_PRODUCTS_DIR; }; 1499 6192E764074A7CE9005E1F34 /* libllcommon.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libllcommon.a; sourceTree = BUILT_PRODUCTS_DIR; };
1500 79256EA10C57D6A4000AAFA4 /* llfloatervoicewizard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloatervoicewizard.cpp; sourceTree = "<group>"; };
1501 79256EA20C57D6A4000AAFA4 /* llfloatervoicewizard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatervoicewizard.h; sourceTree = "<group>"; };
1485 84401E2D0A13CC9A006720A5 /* llfloatergroupinvite.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloatergroupinvite.cpp; sourceTree = "<group>"; }; 1502 84401E2D0A13CC9A006720A5 /* llfloatergroupinvite.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloatergroupinvite.cpp; sourceTree = "<group>"; };
1486 84401E2E0A13CC9A006720A5 /* llfloatergroupinvite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergroupinvite.h; sourceTree = "<group>"; }; 1503 84401E2E0A13CC9A006720A5 /* llfloatergroupinvite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergroupinvite.h; sourceTree = "<group>"; };
1487 84401E300A13CCB2006720A5 /* llpanelgroupinvite.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpanelgroupinvite.cpp; sourceTree = "<group>"; }; 1504 84401E300A13CCB2006720A5 /* llpanelgroupinvite.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpanelgroupinvite.cpp; sourceTree = "<group>"; };
@@ -1497,7 +1514,6 @@
1497 8B2ECFA00534C21A00A80059 /* llfirstuse.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfirstuse.cpp; sourceTree = "<group>"; }; 1514 8B2ECFA00534C21A00A80059 /* llfirstuse.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfirstuse.cpp; sourceTree = "<group>"; };
1498 9104C0CB0778AE0F001EC4F6 /* llpanelmsgs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpanelmsgs.cpp; sourceTree = "<group>"; }; 1515 9104C0CB0778AE0F001EC4F6 /* llpanelmsgs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpanelmsgs.cpp; sourceTree = "<group>"; };
1499 9104C0CD0778AE20001EC4F6 /* llpanelmsgs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelmsgs.h; sourceTree = "<group>"; }; 1516 9104C0CD0778AE20001EC4F6 /* llpanelmsgs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelmsgs.h; sourceTree = "<group>"; };
1500 910D255206484F1A0034E66F /* llvolumesliderctrl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvolumesliderctrl.cpp; sourceTree = "<group>"; };
1501 9117EAA10BF24A6100845BD2 /* llpacketack.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpacketack.cpp; sourceTree = "<group>"; }; 1517 9117EAA10BF24A6100845BD2 /* llpacketack.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpacketack.cpp; sourceTree = "<group>"; };
1502 9118669907F4FAF700E3D5BC /* llmediaremotectrl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llmediaremotectrl.cpp; sourceTree = "<group>"; }; 1518 9118669907F4FAF700E3D5BC /* llmediaremotectrl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llmediaremotectrl.cpp; sourceTree = "<group>"; };
1503 9118669A07F4FAF700E3D5BC /* llmediaremotectrl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llmediaremotectrl.h; sourceTree = "<group>"; }; 1519 9118669A07F4FAF700E3D5BC /* llmediaremotectrl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llmediaremotectrl.h; sourceTree = "<group>"; };
@@ -1611,7 +1627,14 @@
1611 99321B11081DD26000678159 /* llworkerthread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llworkerthread.h; sourceTree = "<group>"; }; 1627 99321B11081DD26000678159 /* llworkerthread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llworkerthread.h; sourceTree = "<group>"; };
1612 99321B12081DD26000678159 /* llworkerthread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llworkerthread.cpp; sourceTree = "<group>"; }; 1628 99321B12081DD26000678159 /* llworkerthread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llworkerthread.cpp; sourceTree = "<group>"; };
1613 9932ED1F056C1F0900554101 /* crashreporter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = crashreporter.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1629 9932ED1F056C1F0900554101 /* crashreporter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = crashreporter.app; sourceTree = BUILT_PRODUCTS_DIR; };
1630 99374E450B5C603E008DB4BE /* lliosocket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lliosocket.h; sourceTree = "<group>"; };
1631 99374E460B5C603E008DB4BE /* lliosocket.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lliosocket.cpp; sourceTree = "<group>"; };
1632 993A3E030B546D47007A0790 /* llvoiceclient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvoiceclient.h; sourceTree = "<group>"; };
1633 993A3E040B546D47007A0790 /* llvoiceclient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvoiceclient.cpp; sourceTree = "<group>"; };
1614 994ADAE20A8016E500061DFB /* libllmozlib.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libllmozlib.dylib; path = "../../libraries/universal-darwin/lib_release/libllmozlib.dylib"; sourceTree = SOURCE_ROOT; }; 1634 994ADAE20A8016E500061DFB /* libllmozlib.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libllmozlib.dylib; path = "../../libraries/universal-darwin/lib_release/libllmozlib.dylib"; sourceTree = SOURCE_ROOT; };
1635 9956CAFB0B96679C00F58C6D /* llprefsvoice.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llprefsvoice.h; sourceTree = "<group>"; };
1636 9956CAFC0B96679C00F58C6D /* llprefsvoice.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 30; path = llprefsvoice.cpp; sourceTree = "<group>"; };
1637 996209680B864D0E00392531 /* SLVoiceAgent.app */ = {isa = PBXFileReference; lastKnownFileType = wrapper.application; name = SLVoiceAgent.app; path = "vivox-runtime/universal-darwin/SLVoiceAgent.app"; sourceTree = SOURCE_ROOT; };
1615 9967E9090B37533F0087BD1B /* libfmodwrapper.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libfmodwrapper.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 1638 9967E9090B37533F0087BD1B /* libfmodwrapper.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libfmodwrapper.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
1616 9967E9520B37564D0087BD1B /* fmodwrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fmodwrapper.cpp; sourceTree = "<group>"; }; 1639 9967E9520B37564D0087BD1B /* fmodwrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fmodwrapper.cpp; sourceTree = "<group>"; };
1617 997B4BD006015820001B0407 /* viewer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = viewer.h; sourceTree = SOURCE_ROOT; }; 1640 997B4BD006015820001B0407 /* viewer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = viewer.h; sourceTree = SOURCE_ROOT; };
@@ -1715,7 +1738,6 @@
1715 997B4C5C06015821001B0407 /* llpreviewtexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewtexture.h; sourceTree = SOURCE_ROOT; }; 1738 997B4C5C06015821001B0407 /* llpreviewtexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewtexture.h; sourceTree = SOURCE_ROOT; };
1716 997B4C5D06015821001B0407 /* llpreviewsound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewsound.h; sourceTree = SOURCE_ROOT; }; 1739 997B4C5D06015821001B0407 /* llpreviewsound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewsound.h; sourceTree = SOURCE_ROOT; };
1717 997B4C5E06015821001B0407 /* llpreviewscript.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewscript.h; sourceTree = SOURCE_ROOT; }; 1740 997B4C5E06015821001B0407 /* llpreviewscript.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewscript.h; sourceTree = SOURCE_ROOT; };
1718 997B4C5F06015821001B0407 /* llpreviewobject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewobject.h; sourceTree = SOURCE_ROOT; };
1719 997B4C6006015821001B0407 /* llpreviewnotecard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewnotecard.h; sourceTree = SOURCE_ROOT; }; 1741 997B4C6006015821001B0407 /* llpreviewnotecard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewnotecard.h; sourceTree = SOURCE_ROOT; };
1720 997B4C6106015821001B0407 /* llpreviewlandmark.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewlandmark.h; sourceTree = SOURCE_ROOT; }; 1742 997B4C6106015821001B0407 /* llpreviewlandmark.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreviewlandmark.h; sourceTree = SOURCE_ROOT; };
1721 997B4C6206015821001B0407 /* llpreview.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreview.h; sourceTree = SOURCE_ROOT; }; 1743 997B4C6206015821001B0407 /* llpreview.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpreview.h; sourceTree = SOURCE_ROOT; };
@@ -1728,7 +1750,6 @@
1728 997B4C6C06015821001B0407 /* llpanelobject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelobject.h; sourceTree = SOURCE_ROOT; }; 1750 997B4C6C06015821001B0407 /* llpanelobject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelobject.h; sourceTree = SOURCE_ROOT; };
1729 997B4C6D06015822001B0407 /* llpanelnetwork.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelnetwork.h; sourceTree = SOURCE_ROOT; }; 1751 997B4C6D06015822001B0407 /* llpanelnetwork.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelnetwork.h; sourceTree = SOURCE_ROOT; };
1730 997B4C6F06015822001B0407 /* llpanelmorph.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelmorph.h; sourceTree = SOURCE_ROOT; }; 1752 997B4C6F06015822001B0407 /* llpanelmorph.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelmorph.h; sourceTree = SOURCE_ROOT; };
1731 997B4C7106015822001B0407 /* llpanelleaderboard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelleaderboard.h; sourceTree = SOURCE_ROOT; };
1732 997B4C7206015822001B0407 /* llpanelland.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelland.h; sourceTree = SOURCE_ROOT; }; 1753 997B4C7206015822001B0407 /* llpanelland.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelland.h; sourceTree = SOURCE_ROOT; };
1733 997B4C7306015822001B0407 /* llpanelinventory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelinventory.h; sourceTree = SOURCE_ROOT; }; 1754 997B4C7306015822001B0407 /* llpanelinventory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelinventory.h; sourceTree = SOURCE_ROOT; };
1734 997B4C7406015822001B0407 /* llpanelinput.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelinput.h; sourceTree = SOURCE_ROOT; }; 1755 997B4C7406015822001B0407 /* llpanelinput.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelinput.h; sourceTree = SOURCE_ROOT; };
@@ -1739,7 +1760,6 @@
1739 997B4C7C06015822001B0407 /* llpaneldisplay.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldisplay.h; sourceTree = SOURCE_ROOT; }; 1760 997B4C7C06015822001B0407 /* llpaneldisplay.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldisplay.h; sourceTree = SOURCE_ROOT; };
1740 997B4C7D06015822001B0407 /* llpaneldirpopular.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirpopular.h; sourceTree = SOURCE_ROOT; }; 1761 997B4C7D06015822001B0407 /* llpaneldirpopular.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirpopular.h; sourceTree = SOURCE_ROOT; };
1741 997B4C7E06015822001B0407 /* llpaneldirplaces.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirplaces.h; sourceTree = SOURCE_ROOT; }; 1762 997B4C7E06015822001B0407 /* llpaneldirplaces.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirplaces.h; sourceTree = SOURCE_ROOT; };
1742 997B4C7F06015822001B0407 /* llpaneldirpicks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirpicks.h; sourceTree = SOURCE_ROOT; };
1743 997B4C8006015822001B0407 /* llpaneldirpeople.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirpeople.h; sourceTree = SOURCE_ROOT; }; 1763 997B4C8006015822001B0407 /* llpaneldirpeople.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirpeople.h; sourceTree = SOURCE_ROOT; };
1744 997B4C8206015822001B0407 /* llpaneldirland.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirland.h; sourceTree = SOURCE_ROOT; }; 1764 997B4C8206015822001B0407 /* llpaneldirland.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirland.h; sourceTree = SOURCE_ROOT; };
1745 997B4C8306015822001B0407 /* llpaneldirgroups.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirgroups.h; sourceTree = SOURCE_ROOT; }; 1765 997B4C8306015822001B0407 /* llpaneldirgroups.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirgroups.h; sourceTree = SOURCE_ROOT; };
@@ -1747,7 +1767,6 @@
1747 997B4C8506015822001B0407 /* llpaneldirevents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirevents.h; sourceTree = SOURCE_ROOT; }; 1767 997B4C8506015822001B0407 /* llpaneldirevents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirevents.h; sourceTree = SOURCE_ROOT; };
1748 997B4C8606015822001B0407 /* llpaneldirbrowser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirbrowser.h; sourceTree = SOURCE_ROOT; }; 1768 997B4C8606015822001B0407 /* llpaneldirbrowser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldirbrowser.h; sourceTree = SOURCE_ROOT; };
1749 997B4C8906015822001B0407 /* llpaneldebug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldebug.h; sourceTree = SOURCE_ROOT; }; 1769 997B4C8906015822001B0407 /* llpaneldebug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpaneldebug.h; sourceTree = SOURCE_ROOT; };
1750 997B4C8A06015822001B0407 /* llpanelcreate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelcreate.h; sourceTree = SOURCE_ROOT; };
1751 997B4C8B06015822001B0407 /* llpanelcontents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelcontents.h; sourceTree = SOURCE_ROOT; }; 1770 997B4C8B06015822001B0407 /* llpanelcontents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelcontents.h; sourceTree = SOURCE_ROOT; };
1752 997B4C8D06015822001B0407 /* llpanelavatar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelavatar.h; sourceTree = SOURCE_ROOT; }; 1771 997B4C8D06015822001B0407 /* llpanelavatar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelavatar.h; sourceTree = SOURCE_ROOT; };
1753 997B4C8E06015822001B0407 /* llpanelaudioprefs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelaudioprefs.h; sourceTree = SOURCE_ROOT; }; 1772 997B4C8E06015822001B0407 /* llpanelaudioprefs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelaudioprefs.h; sourceTree = SOURCE_ROOT; };
@@ -1804,7 +1823,6 @@
1804 997B4CD106015822001B0407 /* llfloaterlandholdings.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloaterlandholdings.h; sourceTree = SOURCE_ROOT; }; 1823 997B4CD106015822001B0407 /* llfloaterlandholdings.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloaterlandholdings.h; sourceTree = SOURCE_ROOT; };
1805 997B4CD206015822001B0407 /* llfloaterland.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloaterland.h; sourceTree = SOURCE_ROOT; }; 1824 997B4CD206015822001B0407 /* llfloaterland.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloaterland.h; sourceTree = SOURCE_ROOT; };
1806 997B4CD406015822001B0407 /* llfloatergroups.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergroups.h; sourceTree = SOURCE_ROOT; }; 1825 997B4CD406015822001B0407 /* llfloatergroups.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergroups.h; sourceTree = SOURCE_ROOT; };
1807 997B4CD506015822001B0407 /* llfloatergroupprofile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergroupprofile.h; sourceTree = SOURCE_ROOT; };
1808 997B4CD606015822001B0407 /* llfloatergroupinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergroupinfo.h; sourceTree = SOURCE_ROOT; }; 1826 997B4CD606015822001B0407 /* llfloatergroupinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergroupinfo.h; sourceTree = SOURCE_ROOT; };
1809 997B4CD806015822001B0407 /* llfloatergodtools.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergodtools.h; sourceTree = SOURCE_ROOT; }; 1827 997B4CD806015822001B0407 /* llfloatergodtools.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergodtools.h; sourceTree = SOURCE_ROOT; };
1810 997B4CD906015822001B0407 /* llfloatergesture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergesture.h; sourceTree = SOURCE_ROOT; }; 1828 997B4CD906015822001B0407 /* llfloatergesture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloatergesture.h; sourceTree = SOURCE_ROOT; };
@@ -1828,7 +1846,6 @@
1828 997B4CF206015822001B0407 /* llemote.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llemote.h; sourceTree = SOURCE_ROOT; }; 1846 997B4CF206015822001B0407 /* llemote.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llemote.h; sourceTree = SOURCE_ROOT; };
1829 997B4CF406015822001B0407 /* lldriverparam.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldriverparam.h; sourceTree = SOURCE_ROOT; }; 1847 997B4CF406015822001B0407 /* lldriverparam.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldriverparam.h; sourceTree = SOURCE_ROOT; };
1830 997B4CF506015823001B0407 /* lldrawpoolwater.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpoolwater.h; sourceTree = SOURCE_ROOT; }; 1848 997B4CF506015823001B0407 /* lldrawpoolwater.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpoolwater.h; sourceTree = SOURCE_ROOT; };
1831 997B4CF606015823001B0407 /* lldrawpooltreenew.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpooltreenew.h; sourceTree = SOURCE_ROOT; };
1832 997B4CF706015823001B0407 /* lldrawpooltree.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpooltree.h; sourceTree = SOURCE_ROOT; }; 1849 997B4CF706015823001B0407 /* lldrawpooltree.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpooltree.h; sourceTree = SOURCE_ROOT; };
1833 997B4CF806015823001B0407 /* lldrawpoolterrain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpoolterrain.h; sourceTree = SOURCE_ROOT; }; 1850 997B4CF806015823001B0407 /* lldrawpoolterrain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpoolterrain.h; sourceTree = SOURCE_ROOT; };
1834 997B4CFA06015823001B0407 /* lldrawpoolsky.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpoolsky.h; sourceTree = SOURCE_ROOT; }; 1851 997B4CFA06015823001B0407 /* lldrawpoolsky.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpoolsky.h; sourceTree = SOURCE_ROOT; };
@@ -1840,7 +1857,6 @@
1840 997B4D0006015823001B0407 /* lldrawpool.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpool.h; sourceTree = SOURCE_ROOT; }; 1857 997B4D0006015823001B0407 /* lldrawpool.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawpool.h; sourceTree = SOURCE_ROOT; };
1841 997B4D0106015823001B0407 /* lldrawable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawable.h; sourceTree = SOURCE_ROOT; }; 1858 997B4D0106015823001B0407 /* lldrawable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldrawable.h; sourceTree = SOURCE_ROOT; };
1842 997B4D0306015823001B0407 /* lldebugview.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldebugview.h; sourceTree = SOURCE_ROOT; }; 1859 997B4D0306015823001B0407 /* lldebugview.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lldebugview.h; sourceTree = SOURCE_ROOT; };
1843 997B4D0506015823001B0407 /* llconversation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llconversation.h; sourceTree = SOURCE_ROOT; };
1844 997B4D0606015823001B0407 /* llcontainerview.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llcontainerview.h; sourceTree = SOURCE_ROOT; }; 1860 997B4D0606015823001B0407 /* llcontainerview.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llcontainerview.h; sourceTree = SOURCE_ROOT; };
1845 997B4D0706015823001B0407 /* llconsole.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llconsole.h; sourceTree = SOURCE_ROOT; }; 1861 997B4D0706015823001B0407 /* llconsole.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llconsole.h; sourceTree = SOURCE_ROOT; };
1846 997B4D0806015823001B0407 /* llcompilequeue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llcompilequeue.h; sourceTree = SOURCE_ROOT; }; 1862 997B4D0806015823001B0407 /* llcompilequeue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llcompilequeue.h; sourceTree = SOURCE_ROOT; };
@@ -1856,8 +1872,6 @@
1856 997B4D1806015823001B0407 /* llbbox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llbbox.h; sourceTree = SOURCE_ROOT; }; 1872 997B4D1806015823001B0407 /* llbbox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llbbox.h; sourceTree = SOURCE_ROOT; };
1857 997B4D1C06015823001B0407 /* llaudiostatus.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llaudiostatus.h; sourceTree = SOURCE_ROOT; }; 1873 997B4D1C06015823001B0407 /* llaudiostatus.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llaudiostatus.h; sourceTree = SOURCE_ROOT; };
1858 997B4D1E06015823001B0407 /* llappearance.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llappearance.h; sourceTree = SOURCE_ROOT; }; 1874 997B4D1E06015823001B0407 /* llappearance.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llappearance.h; sourceTree = SOURCE_ROOT; };
1859 997B4D2006015823001B0407 /* llagparray.inl */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 30; path = llagparray.inl; sourceTree = SOURCE_ROOT; };
1860 997B4D2106015823001B0407 /* llagparray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llagparray.h; sourceTree = SOURCE_ROOT; };
1861 997B4D2206015823001B0407 /* llagentpilot.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llagentpilot.h; sourceTree = SOURCE_ROOT; }; 1875 997B4D2206015823001B0407 /* llagentpilot.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llagentpilot.h; sourceTree = SOURCE_ROOT; };
1862 997B4D2306015823001B0407 /* llagent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llagent.h; sourceTree = SOURCE_ROOT; }; 1876 997B4D2306015823001B0407 /* llagent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llagent.h; sourceTree = SOURCE_ROOT; };
1863 997B4D2406015823001B0407 /* head.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = head.h; sourceTree = SOURCE_ROOT; }; 1877 997B4D2406015823001B0407 /* head.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = head.h; sourceTree = SOURCE_ROOT; };
@@ -1879,6 +1893,7 @@
1879 99BB5175099AC2A4004BF9F2 /* llconfirmationmanager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llconfirmationmanager.h; sourceTree = SOURCE_ROOT; }; 1893 99BB5175099AC2A4004BF9F2 /* llconfirmationmanager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llconfirmationmanager.h; sourceTree = SOURCE_ROOT; };
1880 99C6BFA80A1BBD4800419AE7 /* llfloaterhtmlfind.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloaterhtmlfind.h; sourceTree = "<group>"; }; 1894 99C6BFA80A1BBD4800419AE7 /* llfloaterhtmlfind.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloaterhtmlfind.h; sourceTree = "<group>"; };
1881 99C6BFA90A1BBD4800419AE7 /* llfloaterhtmlfind.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloaterhtmlfind.cpp; sourceTree = "<group>"; }; 1895 99C6BFA90A1BBD4800419AE7 /* llfloaterhtmlfind.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloaterhtmlfind.cpp; sourceTree = "<group>"; };
1896 99C9FA660B6AD9BF00A1BBA6 /* SLVoice */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = SLVoice; path = "vivox-runtime/universal-darwin/SLVoice"; sourceTree = SOURCE_ROOT; };
1882 99D5703305BDEFD7004DE704 /* AutoUpdater.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoUpdater.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1897 99D5703305BDEFD7004DE704 /* AutoUpdater.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoUpdater.app; sourceTree = BUILT_PRODUCTS_DIR; };
1883 99D5703505BDEFD8004DE704 /* AutoUpdater-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "AutoUpdater-Info.plist"; sourceTree = SOURCE_ROOT; }; 1898 99D5703505BDEFD8004DE704 /* AutoUpdater-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "AutoUpdater-Info.plist"; sourceTree = SOURCE_ROOT; };
1884 99D8B25508735BFE002F8938 /* material_codes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = material_codes.h; sourceTree = "<group>"; }; 1899 99D8B25508735BFE002F8938 /* material_codes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = material_codes.h; sourceTree = "<group>"; };
@@ -1896,6 +1911,10 @@
1896 99E43516092D64E6003AE728 /* llvoinventorylistener.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvoinventorylistener.cpp; sourceTree = SOURCE_ROOT; }; 1911 99E43516092D64E6003AE728 /* llvoinventorylistener.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvoinventorylistener.cpp; sourceTree = SOURCE_ROOT; };
1897 99E43518092D6535003AE728 /* llcommon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = llcommon.h; path = ../llcommon/llcommon.h; sourceTree = SOURCE_ROOT; }; 1912 99E43518092D6535003AE728 /* llcommon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = llcommon.h; path = ../llcommon/llcommon.h; sourceTree = SOURCE_ROOT; };
1898 99E43519092D6535003AE728 /* llcommon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = llcommon.cpp; path = ../llcommon/llcommon.cpp; sourceTree = SOURCE_ROOT; }; 1913 99E43519092D6535003AE728 /* llcommon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = llcommon.cpp; path = ../llcommon/llcommon.cpp; sourceTree = SOURCE_ROOT; };
1914 99E63DEF0BCADD14000C1751 /* libalut.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libalut.dylib; path = "vivox-runtime/universal-darwin/libalut.dylib"; sourceTree = SOURCE_ROOT; };
1915 99E63DF00BCADD14000C1751 /* libortp.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libortp.dylib; path = "vivox-runtime/universal-darwin/libortp.dylib"; sourceTree = SOURCE_ROOT; };
1916 99E63DF10BCADD14000C1751 /* libvivoxsdk.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvivoxsdk.dylib; path = "vivox-runtime/universal-darwin/libvivoxsdk.dylib"; sourceTree = SOURCE_ROOT; };
1917 99E63DF20BCADD14000C1751 /* libopenal.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libopenal.dylib; path = "vivox-runtime/universal-darwin/libopenal.dylib"; sourceTree = SOURCE_ROOT; };
1899 99E64035081F1CB80009003F /* llglheaders.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llglheaders.h; sourceTree = "<group>"; }; 1918 99E64035081F1CB80009003F /* llglheaders.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llglheaders.h; sourceTree = "<group>"; };
1900 99E64036081F1CB80009003F /* llgl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llgl.cpp; sourceTree = "<group>"; }; 1919 99E64036081F1CB80009003F /* llgl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llgl.cpp; sourceTree = "<group>"; };
1901 99E64037081F1CB80009003F /* llgl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llgl.h; sourceTree = "<group>"; }; 1920 99E64037081F1CB80009003F /* llgl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llgl.h; sourceTree = "<group>"; };
@@ -1969,6 +1988,8 @@
1969 AA0E2A600A2FDAEE0066250A /* llcontrol.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llcontrol.h; sourceTree = "<group>"; }; 1988 AA0E2A600A2FDAEE0066250A /* llcontrol.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llcontrol.h; sourceTree = "<group>"; };
1970 AA0E2A620A2FDB340066250A /* lltoolpipette.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lltoolpipette.cpp; sourceTree = "<group>"; }; 1989 AA0E2A620A2FDB340066250A /* lltoolpipette.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lltoolpipette.cpp; sourceTree = "<group>"; };
1971 AA0E2A630A2FDB340066250A /* lltoolpipette.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lltoolpipette.h; sourceTree = "<group>"; }; 1990 AA0E2A630A2FDB340066250A /* lltoolpipette.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lltoolpipette.h; sourceTree = "<group>"; };
1991 AA11834E0C1DF9C400FDE5BA /* llpanelaudiovolume.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llpanelaudiovolume.cpp; sourceTree = "<group>"; };
1992 AA11834F0C1DF9C400FDE5BA /* llpanelaudiovolume.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llpanelaudiovolume.h; sourceTree = "<group>"; };
1972 AA348DF80B0EAB31002C3015 /* llcurl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llcurl.cpp; sourceTree = "<group>"; }; 1993 AA348DF80B0EAB31002C3015 /* llcurl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llcurl.cpp; sourceTree = "<group>"; };
1973 AA348DF90B0EAB31002C3015 /* llcurl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llcurl.h; sourceTree = "<group>"; }; 1994 AA348DF90B0EAB31002C3015 /* llcurl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llcurl.h; sourceTree = "<group>"; };
1974 AAA133690A3F94D000419F7C /* lluistring.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lluistring.cpp; sourceTree = "<group>"; }; 1995 AAA133690A3F94D000419F7C /* lluistring.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lluistring.cpp; sourceTree = "<group>"; };
@@ -1981,6 +2002,8 @@
1981 AAEAAF260A8104D8005F0707 /* llscrollingpanellist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llscrollingpanellist.h; sourceTree = "<group>"; }; 2002 AAEAAF260A8104D8005F0707 /* llscrollingpanellist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llscrollingpanellist.h; sourceTree = "<group>"; };
1982 AAF5FFD00B13F71900D28A84 /* lltexturecache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lltexturecache.cpp; sourceTree = "<group>"; }; 2003 AAF5FFD00B13F71900D28A84 /* lltexturecache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lltexturecache.cpp; sourceTree = "<group>"; };
1983 AAF5FFD10B13F71900D28A84 /* lltexturecache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lltexturecache.h; sourceTree = "<group>"; }; 2004 AAF5FFD10B13F71900D28A84 /* lltexturecache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lltexturecache.h; sourceTree = "<group>"; };
2005 AB058FE40B3B74AD003C59D8 /* llvoicevisualizer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvoicevisualizer.h; sourceTree = "<group>"; };
2006 ABD8702D0B3C68630007C63B /* llvoavatar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvoavatar.h; sourceTree = "<group>"; };
1984 C16C084E0B4AE6C7009AD67F /* llfloaterinspect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloaterinspect.cpp; sourceTree = "<group>"; }; 2007 C16C084E0B4AE6C7009AD67F /* llfloaterinspect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloaterinspect.cpp; sourceTree = "<group>"; };
1985 C16C084F0B4AE6C7009AD67F /* llfloaterinspect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloaterinspect.h; sourceTree = "<group>"; }; 2008 C16C084F0B4AE6C7009AD67F /* llfloaterinspect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloaterinspect.h; sourceTree = "<group>"; };
1986 C1F5D0A30B138AEB00827F1D /* lluserrelations.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lluserrelations.cpp; sourceTree = "<group>"; }; 2009 C1F5D0A30B138AEB00827F1D /* lluserrelations.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lluserrelations.cpp; sourceTree = "<group>"; };
@@ -2001,6 +2024,14 @@
2001 D62831620B4F3FA200F8830F /* llimagegl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llimagegl.h; sourceTree = "<group>"; }; 2024 D62831620B4F3FA200F8830F /* llimagegl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llimagegl.h; sourceTree = "<group>"; };
2002 D62831640B4F3FA200F8830F /* llvertexprogramgl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvertexprogramgl.cpp; sourceTree = "<group>"; }; 2025 D62831640B4F3FA200F8830F /* llvertexprogramgl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvertexprogramgl.cpp; sourceTree = "<group>"; };
2003 D62831650B4F3FA200F8830F /* llvertexprogramgl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvertexprogramgl.h; sourceTree = "<group>"; }; 2026 D62831650B4F3FA200F8830F /* llvertexprogramgl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvertexprogramgl.h; sourceTree = "<group>"; };
2027 D6B7667F0BFE8E9A00DC8153 /* llfloaterchatterbox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloaterchatterbox.cpp; sourceTree = "<group>"; };
2028 D6B766820BFE8ED700DC8153 /* llfloaterchatterbox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloaterchatterbox.h; sourceTree = "<group>"; };
2029 D8CA570D0BAF74FC0093D6D4 /* llvoicevisualizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = llvoicevisualizer.h; sourceTree = "<group>"; };
2030 D8CA570E0BAF74FC0093D6D4 /* llvoicevisualizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = llvoicevisualizer.cpp; sourceTree = "<group>"; };
2031 D8EAB8B40BE7B3D10067DBB3 /* llfloateractivespeakers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloateractivespeakers.cpp; sourceTree = "<group>"; };
2032 D8EAB8B50BE7B3D10067DBB3 /* llfloateractivespeakers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llfloateractivespeakers.h; sourceTree = "<group>"; };
2033 D8EAB8B80BE7B4490067DBB3 /* llvoiceremotectrl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvoiceremotectrl.cpp; sourceTree = "<group>"; };
2034 D8EAB8B90BE7B4490067DBB3 /* llvoiceremotectrl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvoiceremotectrl.h; sourceTree = "<group>"; };
2004 DA4B14140B978815003F64DE /* llhttpsender.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llhttpsender.cpp; sourceTree = "<group>"; }; 2035 DA4B14140B978815003F64DE /* llhttpsender.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llhttpsender.cpp; sourceTree = "<group>"; };
2005 DA4B14150B978815003F64DE /* llhttpsender.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llhttpsender.h; sourceTree = "<group>"; }; 2036 DA4B14150B978815003F64DE /* llhttpsender.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llhttpsender.h; sourceTree = "<group>"; };
2006 DA4B14160B978815003F64DE /* llmessagetemplate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llmessagetemplate.h; sourceTree = "<group>"; }; 2037 DA4B14160B978815003F64DE /* llmessagetemplate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llmessagetemplate.h; sourceTree = "<group>"; };
@@ -2083,7 +2114,6 @@
2083 EB3EE713083AC23D002BF676 /* llviewertexteditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llviewertexteditor.h; sourceTree = "<group>"; }; 2114 EB3EE713083AC23D002BF676 /* llviewertexteditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llviewertexteditor.h; sourceTree = "<group>"; };
2084 EB3EE714083AC23D002BF676 /* llvieweruictrlfactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvieweruictrlfactory.cpp; sourceTree = "<group>"; }; 2115 EB3EE714083AC23D002BF676 /* llvieweruictrlfactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llvieweruictrlfactory.cpp; sourceTree = "<group>"; };
2085 EB3EE715083AC23D002BF676 /* llvieweruictrlfactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvieweruictrlfactory.h; sourceTree = "<group>"; }; 2116 EB3EE715083AC23D002BF676 /* llvieweruictrlfactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvieweruictrlfactory.h; sourceTree = "<group>"; };
2086 EB3EE716083AC23D002BF676 /* llvolumesliderctrl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llvolumesliderctrl.h; sourceTree = "<group>"; };
2087 EB3EE725083AC2F2002BF676 /* llimagedxt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llimagedxt.cpp; sourceTree = "<group>"; }; 2117 EB3EE725083AC2F2002BF676 /* llimagedxt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llimagedxt.cpp; sourceTree = "<group>"; };
2088 EB3EE726083AC2F2002BF676 /* llimagedxt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llimagedxt.h; sourceTree = "<group>"; }; 2118 EB3EE726083AC2F2002BF676 /* llimagedxt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llimagedxt.h; sourceTree = "<group>"; };
2089 EB9E8314082AEEF2007B4479 /* llmenugl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llmenugl.cpp; sourceTree = "<group>"; }; 2119 EB9E8314082AEEF2007B4479 /* llmenugl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llmenugl.cpp; sourceTree = "<group>"; };
@@ -2327,7 +2357,13 @@
2327 children = ( 2357 children = (
2328 019200F204DD7D3500A800A7 /* macview.r */, 2358 019200F204DD7D3500A800A7 /* macview.r */,
2329 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */, 2359 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */,
2360 99C9FA660B6AD9BF00A1BBA6 /* SLVoice */,
2361 996209680B864D0E00392531 /* SLVoiceAgent.app */,
2330 9930A8E30B8FB10A00197ECA /* language.txt */, 2362 9930A8E30B8FB10A00197ECA /* language.txt */,
2363 99E63DEF0BCADD14000C1751 /* libalut.dylib */,
2364 99E63DF00BCADD14000C1751 /* libortp.dylib */,
2365 99E63DF10BCADD14000C1751 /* libvivoxsdk.dylib */,
2366 99E63DF20BCADD14000C1751 /* libopenal.dylib */,
2331 ); 2367 );
2332 name = Resources; 2368 name = Resources;
2333 sourceTree = "<group>"; 2369 sourceTree = "<group>";
@@ -2345,6 +2381,25 @@
2345 26F529A0051F61CD00A80050 /* newview */ = { 2381 26F529A0051F61CD00A80050 /* newview */ = {
2346 isa = PBXGroup; 2382 isa = PBXGroup;
2347 children = ( 2383 children = (
2384 79256EA10C57D6A4000AAFA4 /* llfloatervoicewizard.cpp */,
2385 79256EA20C57D6A4000AAFA4 /* llfloatervoicewizard.h */,
2386 AA11834E0C1DF9C400FDE5BA /* llpanelaudiovolume.cpp */,
2387 AA11834F0C1DF9C400FDE5BA /* llpanelaudiovolume.h */,
2388 D6B766820BFE8ED700DC8153 /* llfloaterchatterbox.h */,
2389 D6B7667F0BFE8E9A00DC8153 /* llfloaterchatterbox.cpp */,
2390 D8EAB8B80BE7B4490067DBB3 /* llvoiceremotectrl.cpp */,
2391 D8EAB8B90BE7B4490067DBB3 /* llvoiceremotectrl.h */,
2392 D8EAB8B40BE7B3D10067DBB3 /* llfloateractivespeakers.cpp */,
2393 D8EAB8B50BE7B3D10067DBB3 /* llfloateractivespeakers.h */,
2394 9956CAFB0B96679C00F58C6D /* llprefsvoice.h */,
2395 9956CAFC0B96679C00F58C6D /* llprefsvoice.cpp */,
2396 993A3E030B546D47007A0790 /* llvoiceclient.h */,
2397 993A3E040B546D47007A0790 /* llvoiceclient.cpp */,
2398 ABD8702D0B3C68630007C63B /* llvoavatar.h */,
2399 AB058FE40B3B74AD003C59D8 /* llvoicevisualizer.h */,
2400 1A0DA5100C3AC07700361F49 /* llviewerjointmesh_vec.cpp */,
2401 1A0DA5110C3AC07700361F49 /* llviewerjointmesh_sse2.cpp */,
2402 1A0DA5120C3AC07700361F49 /* llviewerjointmesh_sse.cpp */,
2348 26F52A9D051F61DF00A80050 /* head.cpp */, 2403 26F52A9D051F61DF00A80050 /* head.cpp */,
2349 26F52A41051F61DF00A80050 /* llagent.cpp */, 2404 26F52A41051F61DF00A80050 /* llagent.cpp */,
2350 1A758C910A436FCA00589675 /* llagentdata.cpp */, 2405 1A758C910A436FCA00589675 /* llagentdata.cpp */,
@@ -2353,7 +2408,6 @@
2353 FD59ED5E0AF2AF460086642A /* llassetuploadresponders.h */, 2408 FD59ED5E0AF2AF460086642A /* llassetuploadresponders.h */,
2354 26F52AB2051F61DF00A80050 /* llasynchostbyname.cpp */, 2409 26F52AB2051F61DF00A80050 /* llasynchostbyname.cpp */,
2355 918166CA06516C59005727DC /* llaudiosourcevo.cpp */, 2410 918166CA06516C59005727DC /* llaudiosourcevo.cpp */,
2356 26F52AB3051F61DF00A80050 /* llaudiostatus.cpp */,
2357 26F52A33051F61DF00A80050 /* llbbox.cpp */, 2411 26F52A33051F61DF00A80050 /* llbbox.cpp */,
2358 26F52ABF051F61DF00A80050 /* llbox.cpp */, 2412 26F52ABF051F61DF00A80050 /* llbox.cpp */,
2359 26F529F0051F61DF00A80050 /* llcallbacklist.cpp */, 2413 26F529F0051F61DF00A80050 /* llcallbacklist.cpp */,
@@ -2703,8 +2757,6 @@
2703 26F529CF051F61DF00A80050 /* llvoground.cpp */, 2757 26F529CF051F61DF00A80050 /* llvoground.cpp */,
2704 99E43516092D64E6003AE728 /* llvoinventorylistener.cpp */, 2758 99E43516092D64E6003AE728 /* llvoinventorylistener.cpp */,
2705 99E43515092D64E6003AE728 /* llvoinventorylistener.h */, 2759 99E43515092D64E6003AE728 /* llvoinventorylistener.h */,
2706 910D255206484F1A0034E66F /* llvolumesliderctrl.cpp */,
2707 EB3EE716083AC23D002BF676 /* llvolumesliderctrl.h */,
2708 26F529CD051F61DF00A80050 /* llvopartgroup.cpp */, 2760 26F529CD051F61DF00A80050 /* llvopartgroup.cpp */,
2709 26F529CC051F61DF00A80050 /* llvosky.cpp */, 2761 26F529CC051F61DF00A80050 /* llvosky.cpp */,
2710 A3077C0509DCB8140059ED75 /* llvostars.cpp */, 2762 A3077C0509DCB8140059ED75 /* llvostars.cpp */,
@@ -2730,6 +2782,8 @@
2730 26F529BD051F61DF00A80050 /* noise.cpp */, 2782 26F529BD051F61DF00A80050 /* noise.cpp */,
2731 26F529BA051F61DF00A80050 /* pipeline.cpp */, 2783 26F529BA051F61DF00A80050 /* pipeline.cpp */,
2732 26E79A760520BEC400A80050 /* viewer.cpp */, 2784 26E79A760520BEC400A80050 /* viewer.cpp */,
2785 D8CA570D0BAF74FC0093D6D4 /* llvoicevisualizer.h */,
2786 D8CA570E0BAF74FC0093D6D4 /* llvoicevisualizer.cpp */,
2733 ); 2787 );
2734 name = newview; 2788 name = newview;
2735 sourceTree = "<group>"; 2789 sourceTree = "<group>";
@@ -2960,7 +3014,6 @@
2960 619221B2074A9B58005E1F34 /* v4coloru.h */, 3014 619221B2074A9B58005E1F34 /* v4coloru.h */,
2961 619221B3074A9B58005E1F34 /* v4math.cpp */, 3015 619221B3074A9B58005E1F34 /* v4math.cpp */,
2962 619221B4074A9B58005E1F34 /* v4math.h */, 3016 619221B4074A9B58005E1F34 /* v4math.h */,
2963 619221B5074A9B58005E1F34 /* vmath.h */,
2964 619221B6074A9B58005E1F34 /* xform.cpp */, 3017 619221B6074A9B58005E1F34 /* xform.cpp */,
2965 619221B7074A9B58005E1F34 /* xform.h */, 3018 619221B7074A9B58005E1F34 /* xform.h */,
2966 ); 3019 );
@@ -2971,6 +3024,8 @@
2971 619221B8074A9B58005E1F34 /* llmessage */ = { 3024 619221B8074A9B58005E1F34 /* llmessage */ = {
2972 isa = PBXGroup; 3025 isa = PBXGroup;
2973 children = ( 3026 children = (
3027 99374E450B5C603E008DB4BE /* lliosocket.h */,
3028 99374E460B5C603E008DB4BE /* lliosocket.cpp */,
2974 9117EAA10BF24A6100845BD2 /* llpacketack.cpp */, 3029 9117EAA10BF24A6100845BD2 /* llpacketack.cpp */,
2975 9CC281000BE79746006D8BDC /* llmessagetemplateparser.h */, 3030 9CC281000BE79746006D8BDC /* llmessagetemplateparser.h */,
2976 9CC280FE0BE79737006D8BDC /* llmessagetemplateparser.cpp */, 3031 9CC280FE0BE79737006D8BDC /* llmessagetemplateparser.cpp */,
@@ -3053,7 +3108,6 @@
3053 619221D7074A9B59005E1F34 /* llinstantmessage.h */, 3108 619221D7074A9B59005E1F34 /* llinstantmessage.h */,
3054 619221D8074A9B59005E1F34 /* llinvite.h */, 3109 619221D8074A9B59005E1F34 /* llinvite.h */,
3055 619221D9074A9B59005E1F34 /* llloginflags.h */, 3110 619221D9074A9B59005E1F34 /* llloginflags.h */,
3056 619221DA074A9B59005E1F34 /* lllsltransmit.h */,
3057 619221DB074A9B59005E1F34 /* llmail.cpp */, 3111 619221DB074A9B59005E1F34 /* llmail.cpp */,
3058 619221DC074A9B59005E1F34 /* llmail.h */, 3112 619221DC074A9B59005E1F34 /* llmail.h */,
3059 619221DD074A9B59005E1F34 /* llnamevalue.cpp */, 3113 619221DD074A9B59005E1F34 /* llnamevalue.cpp */,
@@ -3394,7 +3448,6 @@
3394 61923CE0074AE2CB005E1F34 /* listener_openal.h */, 3448 61923CE0074AE2CB005E1F34 /* listener_openal.h */,
3395 61923CE1074AE2CB005E1F34 /* llaudiodecodemgr.cpp */, 3449 61923CE1074AE2CB005E1F34 /* llaudiodecodemgr.cpp */,
3396 61923CE2074AE2CB005E1F34 /* llaudiodecodemgr.h */, 3450 61923CE2074AE2CB005E1F34 /* llaudiodecodemgr.h */,
3397 61923CE3074AE2CB005E1F34 /* llaudiosource.h */,
3398 61923CE5074AE2CB005E1F34 /* vorbisdecode.cpp */, 3451 61923CE5074AE2CB005E1F34 /* vorbisdecode.cpp */,
3399 61923CE6074AE2CB005E1F34 /* vorbisdecode.h */, 3452 61923CE6074AE2CB005E1F34 /* vorbisdecode.h */,
3400 61923CE7074AE2CB005E1F34 /* vorbisencode.cpp */, 3453 61923CE7074AE2CB005E1F34 /* vorbisencode.cpp */,
@@ -3525,8 +3578,6 @@
3525 997B4D2306015823001B0407 /* llagent.h */, 3578 997B4D2306015823001B0407 /* llagent.h */,
3526 1A758C990A43700400589675 /* llagentdata.h */, 3579 1A758C990A43700400589675 /* llagentdata.h */,
3527 997B4D2206015823001B0407 /* llagentpilot.h */, 3580 997B4D2206015823001B0407 /* llagentpilot.h */,
3528 997B4D2106015823001B0407 /* llagparray.h */,
3529 997B4D2006015823001B0407 /* llagparray.inl */,
3530 997B4D1E06015823001B0407 /* llappearance.h */, 3581 997B4D1E06015823001B0407 /* llappearance.h */,
3531 997B4D2506015823001B0407 /* llasynchostbyname.h */, 3582 997B4D2506015823001B0407 /* llasynchostbyname.h */,
3532 997B4D1C06015823001B0407 /* llaudiostatus.h */, 3583 997B4D1C06015823001B0407 /* llaudiostatus.h */,
@@ -3544,7 +3595,6 @@
3544 997B4D0806015823001B0407 /* llcompilequeue.h */, 3595 997B4D0806015823001B0407 /* llcompilequeue.h */,
3545 997B4D0706015823001B0407 /* llconsole.h */, 3596 997B4D0706015823001B0407 /* llconsole.h */,
3546 997B4D0606015823001B0407 /* llcontainerview.h */, 3597 997B4D0606015823001B0407 /* llcontainerview.h */,
3547 997B4D0506015823001B0407 /* llconversation.h */,
3548 997B4CEF06015822001B0407 /* llcubemap.h */, 3598 997B4CEF06015822001B0407 /* llcubemap.h */,
3549 997B4CEE06015822001B0407 /* llcylinder.h */, 3599 997B4CEE06015822001B0407 /* llcylinder.h */,
3550 997B4D0306015823001B0407 /* lldebugview.h */, 3600 997B4D0306015823001B0407 /* lldebugview.h */,
@@ -3558,7 +3608,6 @@
3558 997B4CFA06015823001B0407 /* lldrawpoolsky.h */, 3608 997B4CFA06015823001B0407 /* lldrawpoolsky.h */,
3559 997B4CF806015823001B0407 /* lldrawpoolterrain.h */, 3609 997B4CF806015823001B0407 /* lldrawpoolterrain.h */,
3560 997B4CF706015823001B0407 /* lldrawpooltree.h */, 3610 997B4CF706015823001B0407 /* lldrawpooltree.h */,
3561 997B4CF606015823001B0407 /* lldrawpooltreenew.h */,
3562 997B4CF506015823001B0407 /* lldrawpoolwater.h */, 3611 997B4CF506015823001B0407 /* lldrawpoolwater.h */,
3563 997B4CF406015822001B0407 /* lldriverparam.h */, 3612 997B4CF406015822001B0407 /* lldriverparam.h */,
3564 997B4CF206015822001B0407 /* llemote.h */, 3613 997B4CF206015822001B0407 /* llemote.h */,
@@ -3588,7 +3637,6 @@
3588 997B4CD806015822001B0407 /* llfloatergodtools.h */, 3637 997B4CD806015822001B0407 /* llfloatergodtools.h */,
3589 997B4CD606015822001B0407 /* llfloatergroupinfo.h */, 3638 997B4CD606015822001B0407 /* llfloatergroupinfo.h */,
3590 84401E2E0A13CC9A006720A5 /* llfloatergroupinvite.h */, 3639 84401E2E0A13CC9A006720A5 /* llfloatergroupinvite.h */,
3591 997B4CD506015822001B0407 /* llfloatergroupprofile.h */,
3592 997B4CD406015822001B0407 /* llfloatergroups.h */, 3640 997B4CD406015822001B0407 /* llfloatergroups.h */,
3593 997B4CD206015822001B0407 /* llfloaterland.h */, 3641 997B4CD206015822001B0407 /* llfloaterland.h */,
3594 997B4CD106015822001B0407 /* llfloaterlandholdings.h */, 3642 997B4CD106015822001B0407 /* llfloaterlandholdings.h */,
@@ -3656,7 +3704,6 @@
3656 997B4C8D06015822001B0407 /* llpanelavatar.h */, 3704 997B4C8D06015822001B0407 /* llpanelavatar.h */,
3657 99FBB048087363B00048A5CC /* llpanelclassified.h */, 3705 99FBB048087363B00048A5CC /* llpanelclassified.h */,
3658 997B4C8B06015822001B0407 /* llpanelcontents.h */, 3706 997B4C8B06015822001B0407 /* llpanelcontents.h */,
3659 997B4C8A06015822001B0407 /* llpanelcreate.h */,
3660 997B4C8906015822001B0407 /* llpaneldebug.h */, 3707 997B4C8906015822001B0407 /* llpaneldebug.h */,
3661 997B4C8606015822001B0407 /* llpaneldirbrowser.h */, 3708 997B4C8606015822001B0407 /* llpaneldirbrowser.h */,
3662 99FBB090087366930048A5CC /* llpaneldirclassified.h */, 3709 99FBB090087366930048A5CC /* llpaneldirclassified.h */,
@@ -3665,7 +3712,6 @@
3665 997B4C8306015822001B0407 /* llpaneldirgroups.h */, 3712 997B4C8306015822001B0407 /* llpaneldirgroups.h */,
3666 997B4C8206015822001B0407 /* llpaneldirland.h */, 3713 997B4C8206015822001B0407 /* llpaneldirland.h */,
3667 997B4C8006015822001B0407 /* llpaneldirpeople.h */, 3714 997B4C8006015822001B0407 /* llpaneldirpeople.h */,
3668 997B4C7F06015822001B0407 /* llpaneldirpicks.h */,
3669 997B4C7E06015822001B0407 /* llpaneldirplaces.h */, 3715 997B4C7E06015822001B0407 /* llpaneldirplaces.h */,
3670 997B4C7D06015822001B0407 /* llpaneldirpopular.h */, 3716 997B4C7D06015822001B0407 /* llpaneldirpopular.h */,
3671 997B4C7C06015822001B0407 /* llpaneldisplay.h */, 3717 997B4C7C06015822001B0407 /* llpaneldisplay.h */,
@@ -3684,7 +3730,6 @@
3684 997B4C7206015822001B0407 /* llpanelland.h */, 3730 997B4C7206015822001B0407 /* llpanelland.h */,
3685 1A758C970A436FF000589675 /* llpanellandobjects.h */, 3731 1A758C970A436FF000589675 /* llpanellandobjects.h */,
3686 1A758C980A436FF400589675 /* llpanellandoptions.h */, 3732 1A758C980A436FF400589675 /* llpanellandoptions.h */,
3687 997B4C7106015822001B0407 /* llpanelleaderboard.h */,
3688 A3AF6BD00A544F0A005B5E2C /* llpanellogin.h */, 3733 A3AF6BD00A544F0A005B5E2C /* llpanellogin.h */,
3689 997B4C6F06015822001B0407 /* llpanelmorph.h */, 3734 997B4C6F06015822001B0407 /* llpanelmorph.h */,
3690 9104C0CD0778AE20001EC4F6 /* llpanelmsgs.h */, 3735 9104C0CD0778AE20001EC4F6 /* llpanelmsgs.h */,
@@ -3702,7 +3747,6 @@
3702 91FC1D4606527FEC009CF498 /* llpreviewgesture.h */, 3747 91FC1D4606527FEC009CF498 /* llpreviewgesture.h */,
3703 997B4C6106015821001B0407 /* llpreviewlandmark.h */, 3748 997B4C6106015821001B0407 /* llpreviewlandmark.h */,
3704 997B4C6006015821001B0407 /* llpreviewnotecard.h */, 3749 997B4C6006015821001B0407 /* llpreviewnotecard.h */,
3705 997B4C5F06015821001B0407 /* llpreviewobject.h */,
3706 997B4C5E06015821001B0407 /* llpreviewscript.h */, 3750 997B4C5E06015821001B0407 /* llpreviewscript.h */,
3707 997B4C5D06015821001B0407 /* llpreviewsound.h */, 3751 997B4C5D06015821001B0407 /* llpreviewsound.h */,
3708 997B4C5C06015821001B0407 /* llpreviewtexture.h */, 3752 997B4C5C06015821001B0407 /* llpreviewtexture.h */,
@@ -4052,6 +4096,12 @@
4052 99EDE33705896DC10031B20D /* SecondLife.nib in Resources */, 4096 99EDE33705896DC10031B20D /* SecondLife.nib in Resources */,
4053 FD53B3C309BDD5F900BFE3BC /* AutoUpdater.app in Resources */, 4097 FD53B3C309BDD5F900BFE3BC /* AutoUpdater.app in Resources */,
4054 FD53B3C409BDD5FA00BFE3BC /* crashreporter.app in Resources */, 4098 FD53B3C409BDD5FA00BFE3BC /* crashreporter.app in Resources */,
4099 99C9FA670B6AD9BF00A1BBA6 /* SLVoice in Resources */,
4100 99E63DFF0BCADD2F000C1751 /* libalut.dylib in Resources */,
4101 99E63E000BCADD2F000C1751 /* libopenal.dylib in Resources */,
4102 99E63E010BCADD2F000C1751 /* libortp.dylib in Resources */,
4103 99E63E020BCADD2F000C1751 /* libvivoxsdk.dylib in Resources */,
4104 996209690B864D0E00392531 /* SLVoiceAgent.app in Resources */,
4055 9930A8E40B8FB10A00197ECA /* language.txt in Resources */, 4105 9930A8E40B8FB10A00197ECA /* language.txt in Resources */,
4056 ); 4106 );
4057 runOnlyForDeploymentPostprocessing = 0; 4107 runOnlyForDeploymentPostprocessing = 0;
@@ -4302,7 +4352,6 @@
4302 5503BC2505446B20003D051F /* llfloatermap.cpp in Sources */, 4352 5503BC2505446B20003D051F /* llfloatermap.cpp in Sources */,
4303 5503BC2705446B20003D051F /* llregionposition.cpp in Sources */, 4353 5503BC2705446B20003D051F /* llregionposition.cpp in Sources */,
4304 5503BC2905446B20003D051F /* llasynchostbyname.cpp in Sources */, 4354 5503BC2905446B20003D051F /* llasynchostbyname.cpp in Sources */,
4305 5503BC2A05446B20003D051F /* llaudiostatus.cpp in Sources */,
4306 5503BC2B05446B20003D051F /* llpanelavatar.cpp in Sources */, 4355 5503BC2B05446B20003D051F /* llpanelavatar.cpp in Sources */,
4307 5503BC2C05446B20003D051F /* llpanelaudioprefs.cpp in Sources */, 4356 5503BC2C05446B20003D051F /* llpanelaudioprefs.cpp in Sources */,
4308 5503BC2D05446B20003D051F /* llfloaterbuy.cpp in Sources */, 4357 5503BC2D05446B20003D051F /* llfloaterbuy.cpp in Sources */,
@@ -4349,7 +4398,6 @@
4349 91F8BBAC062DF91A00DE42BA /* llgesturemgr.cpp in Sources */, 4398 91F8BBAC062DF91A00DE42BA /* llgesturemgr.cpp in Sources */,
4350 91B9EB8306370586007B3F3E /* lldynamictexture.cpp in Sources */, 4399 91B9EB8306370586007B3F3E /* lldynamictexture.cpp in Sources */,
4351 91B9EC4D06370E4E007B3F3E /* llfloaterimagepreview.cpp in Sources */, 4400 91B9EC4D06370E4E007B3F3E /* llfloaterimagepreview.cpp in Sources */,
4352 910D255306484F1A0034E66F /* llvolumesliderctrl.cpp in Sources */,
4353 916083930649560B00CAF63E /* llfloateranimpreview.cpp in Sources */, 4401 916083930649560B00CAF63E /* llfloateranimpreview.cpp in Sources */,
4354 918166CC06516C59005727DC /* llaudiosourcevo.cpp in Sources */, 4402 918166CC06516C59005727DC /* llaudiosourcevo.cpp in Sources */,
4355 91FC1C8806527F19009CF498 /* llpreviewanim.cpp in Sources */, 4403 91FC1C8806527F19009CF498 /* llpreviewanim.cpp in Sources */,
@@ -4534,6 +4582,7 @@
4534 1AEF0A5B0B2DFE72003F107C /* llrootview.cpp in Sources */, 4582 1AEF0A5B0B2DFE72003F107C /* llrootview.cpp in Sources */,
4535 A30273570B3A13D800704420 /* llvertexbuffer.cpp in Sources */, 4583 A30273570B3A13D800704420 /* llvertexbuffer.cpp in Sources */,
4536 1A1F130C0B3919F100845A6C /* lleditmenuhandler.cpp in Sources */, 4584 1A1F130C0B3919F100845A6C /* lleditmenuhandler.cpp in Sources */,
4585 993A3E050B546D47007A0790 /* llvoiceclient.cpp in Sources */,
4537 C16C08500B4AE6C7009AD67F /* llfloaterinspect.cpp in Sources */, 4586 C16C08500B4AE6C7009AD67F /* llfloaterinspect.cpp in Sources */,
4538 A32748C10B5F38A80099BE18 /* llfont.cpp in Sources */, 4587 A32748C10B5F38A80099BE18 /* llfont.cpp in Sources */,
4539 A32748BF0B5F38A00099BE18 /* llfontgl.cpp in Sources */, 4588 A32748BF0B5F38A00099BE18 /* llfontgl.cpp in Sources */,
@@ -4542,6 +4591,8 @@
4542 1A0201850B7A861200D5C589 /* llblowfishcipher.cpp in Sources */, 4591 1A0201850B7A861200D5C589 /* llblowfishcipher.cpp in Sources */,
4543 1A0201860B7A861200D5C589 /* llnullcipher.cpp in Sources */, 4592 1A0201860B7A861200D5C589 /* llnullcipher.cpp in Sources */,
4544 1A0201870B7A861200D5C589 /* llxorcipher.cpp in Sources */, 4593 1A0201870B7A861200D5C589 /* llxorcipher.cpp in Sources */,
4594 9956CAFD0B96679C00F58C6D /* llprefsvoice.cpp in Sources */,
4595 D8CA570F0BAF74FC0093D6D4 /* llvoicevisualizer.cpp in Sources */,
4545 1A83767E0BA2169600F28979 /* llviewergenericmessage.cpp in Sources */, 4596 1A83767E0BA2169600F28979 /* llviewergenericmessage.cpp in Sources */,
4546 38D0FA6C0B4BF898003323BA /* lltemplatemessagebuilder.cpp in Sources */, 4597 38D0FA6C0B4BF898003323BA /* lltemplatemessagebuilder.cpp in Sources */,
4547 38D0FA6D0B4BF898003323BA /* llmessagetemplate.cpp in Sources */, 4598 38D0FA6D0B4BF898003323BA /* llmessagetemplate.cpp in Sources */,
@@ -4555,12 +4606,20 @@
4555 9C659A870BAB0B6E00D2EB60 /* llmessageconfig.cpp in Sources */, 4606 9C659A870BAB0B6E00D2EB60 /* llmessageconfig.cpp in Sources */,
4556 A3C20E4A0BB0BCDF007E872B /* llglslshader.cpp in Sources */, 4607 A3C20E4A0BB0BCDF007E872B /* llglslshader.cpp in Sources */,
4557 A3C20E4C0BB0BD12007E872B /* llviewerjoystick.cpp in Sources */, 4608 A3C20E4C0BB0BD12007E872B /* llviewerjoystick.cpp in Sources */,
4609 D8EAB8B60BE7B3D10067DBB3 /* llfloateractivespeakers.cpp in Sources */,
4610 D8EAB8BA0BE7B4490067DBB3 /* llvoiceremotectrl.cpp in Sources */,
4558 1A8870D50BCC5A6300E89AA6 /* llinventorytype.cpp in Sources */, 4611 1A8870D50BCC5A6300E89AA6 /* llinventorytype.cpp in Sources */,
4559 1A8870E50BCC5A9500E89AA6 /* llviewermenufile.cpp in Sources */, 4612 1A8870E50BCC5A9500E89AA6 /* llviewermenufile.cpp in Sources */,
4613 D6B766800BFE8E9B00DC8153 /* llfloaterchatterbox.cpp in Sources */,
4614 AA1183500C1DF9C400FDE5BA /* llpanelaudiovolume.cpp in Sources */,
4560 9CC280FF0BE79737006D8BDC /* llmessagetemplateparser.cpp in Sources */, 4615 9CC280FF0BE79737006D8BDC /* llmessagetemplateparser.cpp in Sources */,
4561 88A95BB20C14D5FC0027E363 /* llsrv.cpp in Sources */, 4616 88A95BB20C14D5FC0027E363 /* llsrv.cpp in Sources */,
4562 8833693F0C18AF33007F52DA /* llimagepng.cpp in Sources */, 4617 8833693F0C18AF33007F52DA /* llimagepng.cpp in Sources */,
4563 883369400C18AF33007F52DA /* llpngwrapper.cpp in Sources */, 4618 883369400C18AF33007F52DA /* llpngwrapper.cpp in Sources */,
4619 1A0DA5130C3AC07800361F49 /* llviewerjointmesh_vec.cpp in Sources */,
4620 1A0DA5140C3AC07800361F49 /* llviewerjointmesh_sse2.cpp in Sources */,
4621 1A0DA5150C3AC07800361F49 /* llviewerjointmesh_sse.cpp in Sources */,
4622 79256EA30C57D6A5000AAFA4 /* llfloatervoicewizard.cpp in Sources */,
4564 ); 4623 );
4565 runOnlyForDeploymentPostprocessing = 0; 4624 runOnlyForDeploymentPostprocessing = 0;
4566 }; 4625 };
@@ -4731,6 +4790,7 @@
4731 D64594690B3B732300FAB68F /* llimagetga.cpp in Sources */, 4790 D64594690B3B732300FAB68F /* llimagetga.cpp in Sources */,
4732 D651349D0B3C40870042C56E /* llqueuedthread.cpp in Sources */, 4791 D651349D0B3C40870042C56E /* llqueuedthread.cpp in Sources */,
4733 91469E7B0B4486C10009E8F9 /* llmime.cpp in Sources */, 4792 91469E7B0B4486C10009E8F9 /* llmime.cpp in Sources */,
4793 99374E4E0B5C6059008DB4BE /* lliosocket.cpp in Sources */,
4734 913B26990B4DDCDA0030C3EC /* lllandmark.cpp in Sources */, 4794 913B26990B4DDCDA0030C3EC /* lllandmark.cpp in Sources */,
4735 DA9C40E00B54B4BA00DD6F44 /* llformat.cpp in Sources */, 4795 DA9C40E00B54B4BA00DD6F44 /* llformat.cpp in Sources */,
4736 DA9C41140B54B8CA00DD6F44 /* lllivefile.cpp in Sources */, 4796 DA9C41140B54B8CA00DD6F44 /* lllivefile.cpp in Sources */,
@@ -4846,6 +4906,7 @@
4846 9919347D09786FF300BF6EE0 /* Universal */ = { 4906 9919347D09786FF300BF6EE0 /* Universal */ = {
4847 isa = XCBuildConfiguration; 4907 isa = XCBuildConfiguration;
4848 buildSettings = { 4908 buildSettings = {
4909 LIBRARY_SEARCH_PATHS = "$(inherited)";
4849 PRODUCT_NAME = llcommon; 4910 PRODUCT_NAME = llcommon;
4850 }; 4911 };
4851 name = Universal; 4912 name = Universal;
@@ -4856,13 +4917,7 @@
4856 GCC_PRECOMPILE_PREFIX_HEADER = YES; 4917 GCC_PRECOMPILE_PREFIX_HEADER = YES;
4857 GCC_PREFIX_HEADER = macutil_Prefix.h; 4918 GCC_PREFIX_HEADER = macutil_Prefix.h;
4858 INFOPLIST_FILE = "AutoUpdater-Info.plist"; 4919 INFOPLIST_FILE = "AutoUpdater-Info.plist";
4859 LIBRARY_SEARCH_PATHS = ( 4920 LIBRARY_SEARCH_PATHS = "$(inherited)";
4860 "$(inherited)",
4861 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
4862 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
4863 );
4864 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Universal\"";
4865 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/build/Universal\"";
4866 PRODUCT_NAME = AutoUpdater; 4921 PRODUCT_NAME = AutoUpdater;
4867 }; 4922 };
4868 name = Universal; 4923 name = Universal;
@@ -4873,13 +4928,7 @@
4873 GCC_PRECOMPILE_PREFIX_HEADER = YES; 4928 GCC_PRECOMPILE_PREFIX_HEADER = YES;
4874 GCC_PREFIX_HEADER = macutil_Prefix.h; 4929 GCC_PREFIX_HEADER = macutil_Prefix.h;
4875 INFOPLIST_FILE = "crashreporter-Info.plist"; 4930 INFOPLIST_FILE = "crashreporter-Info.plist";
4876 LIBRARY_SEARCH_PATHS = ( 4931 LIBRARY_SEARCH_PATHS = "$(inherited)";
4877 "$(inherited)",
4878 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
4879 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
4880 );
4881 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Universal\"";
4882 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/build/Universal\"";
4883 PRODUCT_NAME = crashreporter; 4932 PRODUCT_NAME = crashreporter;
4884 }; 4933 };
4885 name = Universal; 4934 name = Universal;
@@ -4895,9 +4944,9 @@
4895 INFOPLIST_FILE = "Info-SecondLife.plist"; 4944 INFOPLIST_FILE = "Info-SecondLife.plist";
4896 INSTALL_PATH = Applications; 4945 INSTALL_PATH = Applications;
4897 LIBRARY_SEARCH_PATHS = ( 4946 LIBRARY_SEARCH_PATHS = (
4898 "$(BUILT_PRODUCTS_DIR)", 4947 "$(inherited)",
4899 "$(LIBRARY_SEARCH_PATHS)",
4900 "$(SRCROOT)/../../libraries/universal-darwin/lib_release", 4948 "$(SRCROOT)/../../libraries/universal-darwin/lib_release",
4949 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
4901 ); 4950 );
4902 PRODUCT_NAME = "Second Life"; 4951 PRODUCT_NAME = "Second Life";
4903 SEPARATE_STRIP = YES; 4952 SEPARATE_STRIP = YES;
@@ -4914,11 +4963,12 @@
4914 i386, 4963 i386,
4915 ppc, 4964 ppc,
4916 ); 4965 );
4966 DEBUG_INFORMATION_FORMAT = dwarf;
4917 GCC_ALTIVEC_EXTENSIONS = YES; 4967 GCC_ALTIVEC_EXTENSIONS = YES;
4918 GCC_OPTIMIZATION_LEVEL = 3; 4968 GCC_OPTIMIZATION_LEVEL = 3;
4919 GCC_TREAT_WARNINGS_AS_ERRORS = YES; 4969 GCC_TREAT_WARNINGS_AS_ERRORS = YES;
4920 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; 4970 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
4921 GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 4971 GCC_WARN_ABOUT_MISSING_NEWLINE = NO;
4922 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 4972 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
4923 GCC_WARN_ABOUT_RETURN_TYPE = YES; 4973 GCC_WARN_ABOUT_RETURN_TYPE = YES;
4924 GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; 4974 GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
@@ -4941,6 +4991,7 @@
4941 ../../libraries/include, 4991 ../../libraries/include,
4942 ../llcommon, 4992 ../llcommon,
4943 ); 4993 );
4994 LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
4944 MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; 4995 MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
4945 MACOSX_DEPLOYMENT_TARGET_ppc = 10.3; 4996 MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
4946 OTHER_CFLAGS = ( 4997 OTHER_CFLAGS = (
@@ -4963,6 +5014,7 @@
4963 "-Wno-sign-compare", 5014 "-Wno-sign-compare",
4964 "-Wno-switch", 5015 "-Wno-switch",
4965 ); 5016 );
5017 ZERO_LINK = NO;
4966 }; 5018 };
4967 name = Universal; 5019 name = Universal;
4968 }; 5020 };
@@ -4980,7 +5032,7 @@
4980 GENERATE_MASTER_OBJECT_FILE = NO; 5032 GENERATE_MASTER_OBJECT_FILE = NO;
4981 INSTALL_PATH = "@executable_path/../Resources/"; 5033 INSTALL_PATH = "@executable_path/../Resources/";
4982 KEEP_PRIVATE_EXTERNS = NO; 5034 KEEP_PRIVATE_EXTERNS = NO;
4983 LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; 5035 LIBRARY_SEARCH_PATHS = "$(inherited)";
4984 PREBINDING = NO; 5036 PREBINDING = NO;
4985 PRELINK_LIBS = ""; 5037 PRELINK_LIBS = "";
4986 PRODUCT_NAME = fmodwrapper; 5038 PRODUCT_NAME = fmodwrapper;
@@ -5001,7 +5053,7 @@
5001 GENERATE_MASTER_OBJECT_FILE = NO; 5053 GENERATE_MASTER_OBJECT_FILE = NO;
5002 INSTALL_PATH = "@executable_path/../Resources/"; 5054 INSTALL_PATH = "@executable_path/../Resources/";
5003 KEEP_PRIVATE_EXTERNS = NO; 5055 KEEP_PRIVATE_EXTERNS = NO;
5004 LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; 5056 LIBRARY_SEARCH_PATHS = "$(inherited)";
5005 PREBINDING = NO; 5057 PREBINDING = NO;
5006 PRELINK_LIBS = ""; 5058 PRELINK_LIBS = "";
5007 PRODUCT_NAME = fmodwrapper; 5059 PRODUCT_NAME = fmodwrapper;
@@ -5020,7 +5072,7 @@
5020 GENERATE_MASTER_OBJECT_FILE = NO; 5072 GENERATE_MASTER_OBJECT_FILE = NO;
5021 INSTALL_PATH = "@executable_path/../Resources/"; 5073 INSTALL_PATH = "@executable_path/../Resources/";
5022 KEEP_PRIVATE_EXTERNS = NO; 5074 KEEP_PRIVATE_EXTERNS = NO;
5023 LIBRARY_SEARCH_PATHS = ""; 5075 LIBRARY_SEARCH_PATHS = "$(inherited)";
5024 OTHER_LDFLAGS = ""; 5076 OTHER_LDFLAGS = "";
5025 PREBINDING = NO; 5077 PREBINDING = NO;
5026 PRELINK_LIBS = ""; 5078 PRELINK_LIBS = "";
@@ -5033,6 +5085,7 @@
5033 9994843B0883114200EFC621 /* Development */ = { 5085 9994843B0883114200EFC621 /* Development */ = {
5034 isa = XCBuildConfiguration; 5086 isa = XCBuildConfiguration;
5035 buildSettings = { 5087 buildSettings = {
5088 LIBRARY_SEARCH_PATHS = "$(inherited)";
5036 PRODUCT_NAME = llcommon; 5089 PRODUCT_NAME = llcommon;
5037 }; 5090 };
5038 name = Development; 5091 name = Development;
@@ -5040,6 +5093,7 @@
5040 9994843C0883114200EFC621 /* Deployment */ = { 5093 9994843C0883114200EFC621 /* Deployment */ = {
5041 isa = XCBuildConfiguration; 5094 isa = XCBuildConfiguration;
5042 buildSettings = { 5095 buildSettings = {
5096 LIBRARY_SEARCH_PATHS = "$(inherited)";
5043 PRODUCT_NAME = llcommon; 5097 PRODUCT_NAME = llcommon;
5044 }; 5098 };
5045 name = Deployment; 5099 name = Deployment;
@@ -5050,13 +5104,7 @@
5050 GCC_PRECOMPILE_PREFIX_HEADER = YES; 5104 GCC_PRECOMPILE_PREFIX_HEADER = YES;
5051 GCC_PREFIX_HEADER = macutil_Prefix.h; 5105 GCC_PREFIX_HEADER = macutil_Prefix.h;
5052 INFOPLIST_FILE = "crashreporter-Info.plist"; 5106 INFOPLIST_FILE = "crashreporter-Info.plist";
5053 LIBRARY_SEARCH_PATHS = ( 5107 LIBRARY_SEARCH_PATHS = "$(inherited)";
5054 "$(inherited)",
5055 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
5056 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
5057 );
5058 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Universal\"";
5059 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/build/Universal\"";
5060 PRODUCT_NAME = crashreporter; 5108 PRODUCT_NAME = crashreporter;
5061 }; 5109 };
5062 name = Development; 5110 name = Development;
@@ -5067,13 +5115,7 @@
5067 GCC_PRECOMPILE_PREFIX_HEADER = YES; 5115 GCC_PRECOMPILE_PREFIX_HEADER = YES;
5068 GCC_PREFIX_HEADER = macutil_Prefix.h; 5116 GCC_PREFIX_HEADER = macutil_Prefix.h;
5069 INFOPLIST_FILE = "crashreporter-Info.plist"; 5117 INFOPLIST_FILE = "crashreporter-Info.plist";
5070 LIBRARY_SEARCH_PATHS = ( 5118 LIBRARY_SEARCH_PATHS = "$(inherited)";
5071 "$(inherited)",
5072 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
5073 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
5074 );
5075 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Universal\"";
5076 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/build/Universal\"";
5077 PRODUCT_NAME = crashreporter; 5119 PRODUCT_NAME = crashreporter;
5078 }; 5120 };
5079 name = Deployment; 5121 name = Deployment;
@@ -5084,13 +5126,7 @@
5084 GCC_PRECOMPILE_PREFIX_HEADER = YES; 5126 GCC_PRECOMPILE_PREFIX_HEADER = YES;
5085 GCC_PREFIX_HEADER = macutil_Prefix.h; 5127 GCC_PREFIX_HEADER = macutil_Prefix.h;
5086 INFOPLIST_FILE = "AutoUpdater-Info.plist"; 5128 INFOPLIST_FILE = "AutoUpdater-Info.plist";
5087 LIBRARY_SEARCH_PATHS = ( 5129 LIBRARY_SEARCH_PATHS = "$(inherited)";
5088 "$(inherited)",
5089 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
5090 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
5091 );
5092 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Universal\"";
5093 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/build/Universal\"";
5094 PRODUCT_NAME = AutoUpdater; 5130 PRODUCT_NAME = AutoUpdater;
5095 }; 5131 };
5096 name = Development; 5132 name = Development;
@@ -5101,13 +5137,7 @@
5101 GCC_PRECOMPILE_PREFIX_HEADER = YES; 5137 GCC_PRECOMPILE_PREFIX_HEADER = YES;
5102 GCC_PREFIX_HEADER = macutil_Prefix.h; 5138 GCC_PREFIX_HEADER = macutil_Prefix.h;
5103 INFOPLIST_FILE = "AutoUpdater-Info.plist"; 5139 INFOPLIST_FILE = "AutoUpdater-Info.plist";
5104 LIBRARY_SEARCH_PATHS = ( 5140 LIBRARY_SEARCH_PATHS = "$(inherited)";
5105 "$(inherited)",
5106 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
5107 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
5108 );
5109 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Universal\"";
5110 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/build/Universal\"";
5111 PRODUCT_NAME = AutoUpdater; 5141 PRODUCT_NAME = AutoUpdater;
5112 }; 5142 };
5113 name = Deployment; 5143 name = Deployment;
@@ -5123,14 +5153,11 @@
5123 INFOPLIST_FILE = "Info-SecondLife.plist"; 5153 INFOPLIST_FILE = "Info-SecondLife.plist";
5124 INSTALL_PATH = "$(HOME)/Applications"; 5154 INSTALL_PATH = "$(HOME)/Applications";
5125 LIBRARY_SEARCH_PATHS = ( 5155 LIBRARY_SEARCH_PATHS = (
5126 "$(BUILT_PRODUCTS_DIR)", 5156 "$(inherited)",
5127 "$(LIBRARY_SEARCH_PATHS)",
5128 "$(SRCROOT)/../../libraries/universal-darwin/lib_release", 5157 "$(SRCROOT)/../../libraries/universal-darwin/lib_release",
5129 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", 5158 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
5130 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
5131 ); 5159 );
5132 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Universal\""; 5160 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/vivox-runtime/universal-darwin\"";
5133 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/build/Universal\"";
5134 OTHER_LDFLAGS = "-weak-lllmozlib"; 5161 OTHER_LDFLAGS = "-weak-lllmozlib";
5135 PRODUCT_NAME = "Second Life"; 5162 PRODUCT_NAME = "Second Life";
5136 SHARED_PRECOMPS_DIR = "$(BUILD_DIR)/Caches/com.apple.Xcode.$(UID)/SharedPrecompiledHeaders"; 5163 SHARED_PRECOMPS_DIR = "$(BUILD_DIR)/Caches/com.apple.Xcode.$(UID)/SharedPrecompiledHeaders";
@@ -5155,13 +5182,11 @@
5155 INFOPLIST_FILE = "Info-SecondLife.plist"; 5182 INFOPLIST_FILE = "Info-SecondLife.plist";
5156 INSTALL_PATH = "$(HOME)/Applications"; 5183 INSTALL_PATH = "$(HOME)/Applications";
5157 LIBRARY_SEARCH_PATHS = ( 5184 LIBRARY_SEARCH_PATHS = (
5158 "$(BUILT_PRODUCTS_DIR)", 5185 "$(inherited)",
5159 "$(LIBRARY_SEARCH_PATHS)",
5160 "$(SRCROOT)/../../libraries/universal-darwin/lib_release", 5186 "$(SRCROOT)/../../libraries/universal-darwin/lib_release",
5161 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", 5187 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
5162 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
5163 ); 5188 );
5164 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Universal\""; 5189 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/vivox-runtime/universal-darwin\"";
5165 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/build/Universal\""; 5190 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/build/Universal\"";
5166 OTHER_LDFLAGS = "-lllmozlib"; 5191 OTHER_LDFLAGS = "-lllmozlib";
5167 PRODUCT_NAME = "Second Life"; 5192 PRODUCT_NAME = "Second Life";
@@ -5174,11 +5199,12 @@
5174 999484590883114300EFC621 /* Development */ = { 5199 999484590883114300EFC621 /* Development */ = {
5175 isa = XCBuildConfiguration; 5200 isa = XCBuildConfiguration;
5176 buildSettings = { 5201 buildSettings = {
5202 DEBUG_INFORMATION_FORMAT = dwarf;
5177 GCC_ALTIVEC_EXTENSIONS = YES; 5203 GCC_ALTIVEC_EXTENSIONS = YES;
5178 GCC_OPTIMIZATION_LEVEL = 0; 5204 GCC_OPTIMIZATION_LEVEL = 0;
5179 GCC_TREAT_WARNINGS_AS_ERRORS = YES; 5205 GCC_TREAT_WARNINGS_AS_ERRORS = YES;
5180 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; 5206 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
5181 GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 5207 GCC_WARN_ABOUT_MISSING_NEWLINE = NO;
5182 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 5208 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
5183 GCC_WARN_ABOUT_RETURN_TYPE = YES; 5209 GCC_WARN_ABOUT_RETURN_TYPE = YES;
5184 GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; 5210 GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
@@ -5201,6 +5227,7 @@
5201 ../../libraries/include, 5227 ../../libraries/include,
5202 ../llcommon, 5228 ../llcommon,
5203 ); 5229 );
5230 LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
5204 MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; 5231 MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
5205 MACOSX_DEPLOYMENT_TARGET_ppc = 10.3; 5232 MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
5206 OTHER_CFLAGS = ( 5233 OTHER_CFLAGS = (
@@ -5222,17 +5249,19 @@
5222 "-Wno-sign-compare", 5249 "-Wno-sign-compare",
5223 "-Wno-switch", 5250 "-Wno-switch",
5224 ); 5251 );
5252 ZERO_LINK = YES;
5225 }; 5253 };
5226 name = Development; 5254 name = Development;
5227 }; 5255 };
5228 9994845A0883114300EFC621 /* Deployment */ = { 5256 9994845A0883114300EFC621 /* Deployment */ = {
5229 isa = XCBuildConfiguration; 5257 isa = XCBuildConfiguration;
5230 buildSettings = { 5258 buildSettings = {
5259 DEBUG_INFORMATION_FORMAT = dwarf;
5231 GCC_ALTIVEC_EXTENSIONS = YES; 5260 GCC_ALTIVEC_EXTENSIONS = YES;
5232 GCC_OPTIMIZATION_LEVEL = 3; 5261 GCC_OPTIMIZATION_LEVEL = 3;
5233 GCC_TREAT_WARNINGS_AS_ERRORS = YES; 5262 GCC_TREAT_WARNINGS_AS_ERRORS = YES;
5234 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; 5263 GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
5235 GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 5264 GCC_WARN_ABOUT_MISSING_NEWLINE = NO;
5236 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 5265 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
5237 GCC_WARN_ABOUT_RETURN_TYPE = YES; 5266 GCC_WARN_ABOUT_RETURN_TYPE = YES;
5238 GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; 5267 GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
@@ -5255,6 +5284,7 @@
5255 ../../libraries/include, 5284 ../../libraries/include,
5256 ../llcommon, 5285 ../llcommon,
5257 ); 5286 );
5287 LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
5258 MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; 5288 MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
5259 MACOSX_DEPLOYMENT_TARGET_ppc = 10.3; 5289 MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
5260 OTHER_CFLAGS = ( 5290 OTHER_CFLAGS = (
@@ -5277,6 +5307,7 @@
5277 "-Wno-sign-compare", 5307 "-Wno-sign-compare",
5278 "-Wno-switch", 5308 "-Wno-switch",
5279 ); 5309 );
5310 ZERO_LINK = NO;
5280 }; 5311 };
5281 name = Deployment; 5312 name = Deployment;
5282 }; 5313 };
@@ -5291,13 +5322,7 @@
5291 GCC_MODEL_TUNING = G5; 5322 GCC_MODEL_TUNING = G5;
5292 GCC_OPTIMIZATION_LEVEL = 0; 5323 GCC_OPTIMIZATION_LEVEL = 0;
5293 INSTALL_PATH = "@executable_path/../Resources/"; 5324 INSTALL_PATH = "@executable_path/../Resources/";
5294 LIBRARY_SEARCH_PATHS = ( 5325 LIBRARY_SEARCH_PATHS = "$(inherited)";
5295 "$(inherited)",
5296 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
5297 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
5298 );
5299 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Development\"";
5300 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../libraries/powerpc-darwin/lib_debug\"";
5301 PREBINDING = NO; 5326 PREBINDING = NO;
5302 PRODUCT_NAME = llkdu; 5327 PRODUCT_NAME = llkdu;
5303 ZERO_LINK = YES; 5328 ZERO_LINK = YES;
@@ -5313,11 +5338,7 @@
5313 GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 5338 GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
5314 GCC_MODEL_TUNING = G5; 5339 GCC_MODEL_TUNING = G5;
5315 INSTALL_PATH = "@executable_path/../Resources/"; 5340 INSTALL_PATH = "@executable_path/../Resources/";
5316 LIBRARY_SEARCH_PATHS = ( 5341 LIBRARY_SEARCH_PATHS = "$(inherited)";
5317 "$(inherited)",
5318 "$(LIBRARY_SEARCH_PATHS_QUOTED_1)",
5319 "$(LIBRARY_SEARCH_PATHS_QUOTED_2)",
5320 );
5321 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Deployment\""; 5342 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Deployment\"";
5322 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../libraries/powerpc-darwin/lib_release\""; 5343 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../libraries/powerpc-darwin/lib_release\"";
5323 PREBINDING = NO; 5344 PREBINDING = NO;
@@ -5333,12 +5354,7 @@
5333 GCC_ENABLE_FIX_AND_CONTINUE = YES; 5354 GCC_ENABLE_FIX_AND_CONTINUE = YES;
5334 GCC_MODEL_TUNING = G5; 5355 GCC_MODEL_TUNING = G5;
5335 INSTALL_PATH = "@executable_path/../Resources/"; 5356 INSTALL_PATH = "@executable_path/../Resources/";
5336 LIBRARY_SEARCH_PATHS = ( 5357 LIBRARY_SEARCH_PATHS = "$(inherited)";
5337 "$(BUILT_PRODUCTS_DIR)",
5338 "$(inherited)",
5339 "$(SRCROOT)/../../libraries/i386-darwin/lib_release",
5340 "$(SRCROOT)/../../libraries/powerpc-darwin/lib_release",
5341 );
5342 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Deployment"; 5358 LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Deployment";
5343 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../libraries/powerpc-darwin/lib_release\""; 5359 LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../libraries/powerpc-darwin/lib_release\"";
5344 PREBINDING = NO; 5360 PREBINDING = NO;
diff --git a/linden/indra/newview/moviemaker.cpp b/linden/indra/newview/moviemaker.cpp
index 6a7da3f..34e5a16 100644
--- a/linden/indra/newview/moviemaker.cpp
+++ b/linden/indra/newview/moviemaker.cpp
@@ -36,6 +36,7 @@
36#include <stdio.h> 36#include <stdio.h>
37#include <stdlib.h> 37#include <stdlib.h>
38#include <memory.h> 38#include <memory.h>
39#include "llmemtype.h"
39 40
40#if LL_WINDOWS 41#if LL_WINDOWS
41 42
@@ -515,8 +516,9 @@ OSStatus MovieMaker::setupMovie()
515 516
516 rowBytes = width * 4; 517 rowBytes = width * 4;
517 bufferSize = height * rowBytes; 518 bufferSize = height * rowBytes;
518 buffer = (char*)malloc(bufferSize); 519 LLMemType mt(LLMemType::MTYPE_SCRIPT);
519 invertedBuffer = (char*)malloc(bufferSize); 520 buffer = (char*) new char(bufferSize);
521 invertedBuffer = (char*) new char(bufferSize);
520 522
521 rect.left = 0; 523 rect.left = 0;
522 rect.top = 0; 524 rect.top = 0;
@@ -684,13 +686,13 @@ void MovieMaker::EndCapture()
684 686
685 if(buffer) 687 if(buffer)
686 { 688 {
687 free(buffer); 689 delete(buffer);
688 buffer = NULL; 690 buffer = NULL;
689 } 691 }
690 692
691 if(invertedBuffer) 693 if(invertedBuffer)
692 { 694 {
693 free(invertedBuffer); 695 delete(invertedBuffer);
694 invertedBuffer = NULL; 696 invertedBuffer = NULL;
695 } 697 }
696} 698}
diff --git a/linden/indra/newview/newview.vcproj b/linden/indra/newview/newview.vcproj
index 955d71a..199083f 100644
--- a/linden/indra/newview/newview.vcproj
+++ b/linden/indra/newview/newview.vcproj
@@ -224,7 +224,7 @@
224 Name="VCCustomBuildTool"/> 224 Name="VCCustomBuildTool"/>
225 <Tool 225 <Tool
226 Name="VCLinkerTool" 226 Name="VCLinkerTool"
227 AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib fmodvc.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc71-mt-s.lib libcurl.lib libeay32.lib libexpatMT.lib LibOpenJPEG.lib llmozlib.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ogg_static_mt.lib ole32.lib oleaut32.lib opengl32.lib png12.lib qtmlclient.lib png12.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib vorbis_static_mt.lib vorbisenc_static_mt.lib vorbisfile_static_mt.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib dnsapi.lib" 227 AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib fmodvc.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc71-mt-s.lib libcurl.lib libeay32.lib libexpatMT.lib LibOpenJPEG.lib llmozlib.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ogg_static_mt.lib ole32.lib oleaut32.lib opengl32.lib png12.lib qtmlclient.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib vorbis_static_mt.lib vorbisenc_static_mt.lib vorbisfile_static_mt.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib dnsapi.lib"
228 OutputFile="$(ConfigurationName)/newview_noopt.exe" 228 OutputFile="$(ConfigurationName)/newview_noopt.exe"
229 LinkIncremental="2" 229 LinkIncremental="2"
230 AdditionalLibraryDirectories="&quot;../lib_releasenoopt/i686-win32&quot;;&quot;../../libraries/i686-win32/lib_release&quot;" 230 AdditionalLibraryDirectories="&quot;../lib_releasenoopt/i686-win32&quot;;&quot;../../libraries/i686-win32/lib_release&quot;"
@@ -271,6 +271,9 @@
271 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" 271 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
272 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> 272 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
273 <File 273 <File
274 RelativePath=".\fakevoicesoundsignal.cpp">
275 </File>
276 <File
274 RelativePath=".\head.cpp"> 277 RelativePath=".\head.cpp">
275 </File> 278 </File>
276 <File 279 <File
@@ -295,9 +298,6 @@
295 RelativePath=".\llaudiosourcevo.cpp"> 298 RelativePath=".\llaudiosourcevo.cpp">
296 </File> 299 </File>
297 <File 300 <File
298 RelativePath=".\llaudiostatus.cpp">
299 </File>
300 <File
301 RelativePath=".\llbbox.cpp"> 301 RelativePath=".\llbbox.cpp">
302 </File> 302 </File>
303 <File 303 <File
@@ -448,6 +448,9 @@
448 RelativePath=".\llfloaterabout.cpp"> 448 RelativePath=".\llfloaterabout.cpp">
449 </File> 449 </File>
450 <File 450 <File
451 RelativePath=".\llfloateractivespeakers.cpp">
452 </File>
453 <File
451 RelativePath=".\llfloateranimpreview.cpp"> 454 RelativePath=".\llfloateranimpreview.cpp">
452 </File> 455 </File>
453 <File 456 <File
@@ -484,6 +487,9 @@
484 RelativePath=".\llfloaterchat.cpp"> 487 RelativePath=".\llfloaterchat.cpp">
485 </File> 488 </File>
486 <File 489 <File
490 RelativePath=".\llfloaterchatterbox.cpp">
491 </File>
492 <File
487 RelativePath=".\llfloaterclothing.cpp"> 493 RelativePath=".\llfloaterclothing.cpp">
488 </File> 494 </File>
489 <File 495 <File
@@ -601,6 +607,9 @@
601 RelativePath=".\llfloatertos.cpp"> 607 RelativePath=".\llfloatertos.cpp">
602 </File> 608 </File>
603 <File 609 <File
610 RelativePath=".\llfloatervoicewizard.cpp">
611 </File>
612 <File
604 RelativePath=".\llfloaterworldmap.cpp"> 613 RelativePath=".\llfloaterworldmap.cpp">
605 </File> 614 </File>
606 <File 615 <File
@@ -766,6 +775,9 @@
766 RelativePath=".\llpanelaudioprefs.cpp"> 775 RelativePath=".\llpanelaudioprefs.cpp">
767 </File> 776 </File>
768 <File 777 <File
778 RelativePath=".\llpanelaudiovolume.cpp">
779 </File>
780 <File
769 RelativePath=".\llpanelavatar.cpp"> 781 RelativePath=".\llpanelavatar.cpp">
770 </File> 782 </File>
771 <File 783 <File
@@ -898,6 +910,9 @@
898 RelativePath=".\llprefsim.cpp"> 910 RelativePath=".\llprefsim.cpp">
899 </File> 911 </File>
900 <File 912 <File
913 RelativePath=".\llprefsvoice.cpp">
914 </File>
915 <File
901 RelativePath=".\llpreview.cpp"> 916 RelativePath=".\llpreview.cpp">
902 </File> 917 </File>
903 <File 918 <File
@@ -1108,6 +1123,71 @@
1108 RelativePath=".\llviewerjointmesh.cpp"> 1123 RelativePath=".\llviewerjointmesh.cpp">
1109 </File> 1124 </File>
1110 <File 1125 <File
1126 RelativePath=".\llviewerjointmesh_sse.cpp">
1127 <FileConfiguration
1128 Name="Debug|Win32">
1129 <Tool
1130 Name="VCCLCompilerTool"
1131 EnableEnhancedInstructionSet="0"
1132 UsePrecompiledHeader="3"/>
1133 </FileConfiguration>
1134 <FileConfiguration
1135 Name="Release|Win32">
1136 <Tool
1137 Name="VCCLCompilerTool"
1138 EnableEnhancedInstructionSet="0"
1139 UsePrecompiledHeader="3"/>
1140 </FileConfiguration>
1141 <FileConfiguration
1142 Name="ReleaseForDownload|Win32">
1143 <Tool
1144 Name="VCCLCompilerTool"
1145 EnableEnhancedInstructionSet="0"
1146 UsePrecompiledHeader="3"/>
1147 </FileConfiguration>
1148 <FileConfiguration
1149 Name="ReleaseNoOpt|Win32">
1150 <Tool
1151 Name="VCCLCompilerTool"
1152 EnableEnhancedInstructionSet="0"
1153 UsePrecompiledHeader="3"/>
1154 </FileConfiguration>
1155 </File>
1156 <File
1157 RelativePath=".\llviewerjointmesh_sse2.cpp">
1158 <FileConfiguration
1159 Name="Debug|Win32">
1160 <Tool
1161 Name="VCCLCompilerTool"
1162 EnableEnhancedInstructionSet="0"
1163 UsePrecompiledHeader="3"/>
1164 </FileConfiguration>
1165 <FileConfiguration
1166 Name="Release|Win32">
1167 <Tool
1168 Name="VCCLCompilerTool"
1169 EnableEnhancedInstructionSet="0"
1170 UsePrecompiledHeader="0"/>
1171 </FileConfiguration>
1172 <FileConfiguration
1173 Name="ReleaseForDownload|Win32">
1174 <Tool
1175 Name="VCCLCompilerTool"
1176 EnableEnhancedInstructionSet="0"
1177 UsePrecompiledHeader="0"/>
1178 </FileConfiguration>
1179 <FileConfiguration
1180 Name="ReleaseNoOpt|Win32">
1181 <Tool
1182 Name="VCCLCompilerTool"
1183 EnableEnhancedInstructionSet="0"
1184 UsePrecompiledHeader="3"/>
1185 </FileConfiguration>
1186 </File>
1187 <File
1188 RelativePath=".\llviewerjointmesh_vec.cpp">
1189 </File>
1190 <File
1111 RelativePath=".\llviewerjointshape.cpp"> 1191 RelativePath=".\llviewerjointshape.cpp">
1112 </File> 1192 </File>
1113 <File 1193 <File
@@ -1195,10 +1275,16 @@
1195 RelativePath=".\llvoground.cpp"> 1275 RelativePath=".\llvoground.cpp">
1196 </File> 1276 </File>
1197 <File 1277 <File
1198 RelativePath=".\llvoinventorylistener.cpp"> 1278 RelativePath=".\llvoiceclient.cpp">
1199 </File> 1279 </File>
1200 <File 1280 <File
1201 RelativePath=".\llvolumesliderctrl.cpp"> 1281 RelativePath=".\llvoiceremotectrl.cpp">
1282 </File>
1283 <File
1284 RelativePath=".\llvoicevisualizer.cpp">
1285 </File>
1286 <File
1287 RelativePath=".\llvoinventorylistener.cpp">
1202 </File> 1288 </File>
1203 <File 1289 <File
1204 RelativePath=".\llvopartgroup.cpp"> 1290 RelativePath=".\llvopartgroup.cpp">
@@ -1275,6 +1361,9 @@
1275 RelativePath=".\audiosettings.h"> 1361 RelativePath=".\audiosettings.h">
1276 </File> 1362 </File>
1277 <File 1363 <File
1364 RelativePath=".\fakevoicesoundsignal.h">
1365 </File>
1366 <File
1278 RelativePath=".\head.h"> 1367 RelativePath=".\head.h">
1279 </File> 1368 </File>
1280 <File 1369 <File
@@ -1293,13 +1382,13 @@
1293 RelativePath=".\llappearance.h"> 1382 RelativePath=".\llappearance.h">
1294 </File> 1383 </File>
1295 <File 1384 <File
1296 RelativePath=".\llasynchostbyname.h"> 1385 RelativePath=".\llassetuploadresponders.h">
1297 </File> 1386 </File>
1298 <File 1387 <File
1299 RelativePath=".\llaudiosourcevo.h"> 1388 RelativePath=".\llasynchostbyname.h">
1300 </File> 1389 </File>
1301 <File 1390 <File
1302 RelativePath=".\llaudiostatus.h"> 1391 RelativePath=".\llaudiosourcevo.h">
1303 </File> 1392 </File>
1304 <File 1393 <File
1305 RelativePath=".\llautocomplete.h"> 1394 RelativePath=".\llautocomplete.h">
@@ -1455,6 +1544,9 @@
1455 RelativePath=".\llfloaterabout.h"> 1544 RelativePath=".\llfloaterabout.h">
1456 </File> 1545 </File>
1457 <File 1546 <File
1547 RelativePath=".\llfloateractivespeakers.h">
1548 </File>
1549 <File
1458 RelativePath=".\llfloateranimpreview.h"> 1550 RelativePath=".\llfloateranimpreview.h">
1459 </File> 1551 </File>
1460 <File 1552 <File
@@ -1491,6 +1583,9 @@
1491 RelativePath=".\llfloaterchat.h"> 1583 RelativePath=".\llfloaterchat.h">
1492 </File> 1584 </File>
1493 <File 1585 <File
1586 RelativePath=".\llfloaterchatterbox.h">
1587 </File>
1588 <File
1494 RelativePath=".\llfloaterclothing.h"> 1589 RelativePath=".\llfloaterclothing.h">
1495 </File> 1590 </File>
1496 <File 1591 <File
@@ -1608,6 +1703,9 @@
1608 RelativePath=".\llfloatertos.h"> 1703 RelativePath=".\llfloatertos.h">
1609 </File> 1704 </File>
1610 <File 1705 <File
1706 RelativePath=".\llfloatervoicewizard.h">
1707 </File>
1708 <File
1611 RelativePath=".\llfloaterworldmap.h"> 1709 RelativePath=".\llfloaterworldmap.h">
1612 </File> 1710 </File>
1613 <File 1711 <File
@@ -1905,6 +2003,9 @@
1905 RelativePath=".\llprefsim.h"> 2003 RelativePath=".\llprefsim.h">
1906 </File> 2004 </File>
1907 <File 2005 <File
2006 RelativePath=".\llprefsvoice.h">
2007 </File>
2008 <File
1908 RelativePath=".\llpreview.h"> 2009 RelativePath=".\llpreview.h">
1909 </File> 2010 </File>
1910 <File 2011 <File
@@ -2217,10 +2318,16 @@
2217 RelativePath=".\llvoground.h"> 2318 RelativePath=".\llvoground.h">
2218 </File> 2319 </File>
2219 <File 2320 <File
2220 RelativePath=".\llvoinventorylistener.h"> 2321 RelativePath=".\llvoiceclient.h">
2322 </File>
2323 <File
2324 RelativePath=".\llvoiceremotectrl.h">
2221 </File> 2325 </File>
2222 <File 2326 <File
2223 RelativePath=".\llvolumesliderctrl.h"> 2327 RelativePath=".\llvoicevisualizer.h">
2328 </File>
2329 <File
2330 RelativePath=".\llvoinventorylistener.h">
2224 </File> 2331 </File>
2225 <File 2332 <File
2226 RelativePath=".\llvopartgroup.h"> 2333 RelativePath=".\llvopartgroup.h">
@@ -2339,12 +2446,18 @@
2339 RelativePath=".\skins\xui\en-us\floater_account_history.xml"> 2446 RelativePath=".\skins\xui\en-us\floater_account_history.xml">
2340 </File> 2447 </File>
2341 <File 2448 <File
2449 RelativePath=".\skins\xui\en-us\floater_active_speakers.xml">
2450 </File>
2451 <File
2342 RelativePath=".\skins\xui\en-us\floater_animation_preview.xml"> 2452 RelativePath=".\skins\xui\en-us\floater_animation_preview.xml">
2343 </File> 2453 </File>
2344 <File 2454 <File
2345 RelativePath=".\skins\xui\en-us\floater_auction.xml"> 2455 RelativePath=".\skins\xui\en-us\floater_auction.xml">
2346 </File> 2456 </File>
2347 <File 2457 <File
2458 RelativePath=".\skins\xui\en-us\floater_audio_volume.xml">
2459 </File>
2460 <File
2348 RelativePath=".\skins\xui\en-us\floater_avatar_picker.xml"> 2461 RelativePath=".\skins\xui\en-us\floater_avatar_picker.xml">
2349 </File> 2462 </File>
2350 <File 2463 <File
@@ -2372,6 +2485,9 @@
2372 RelativePath=".\skins\xui\en-us\floater_chat_history.xml"> 2485 RelativePath=".\skins\xui\en-us\floater_chat_history.xml">
2373 </File> 2486 </File>
2374 <File 2487 <File
2488 RelativePath=".\skins\xui\en-us\floater_chatterbox.xml">
2489 </File>
2490 <File
2375 RelativePath=".\skins\xui\en-us\floater_choose_group.xml"> 2491 RelativePath=".\skins\xui\en-us\floater_choose_group.xml">
2376 </File> 2492 </File>
2377 <File 2493 <File
@@ -2426,6 +2542,12 @@
2426 RelativePath=".\skins\xui\en-us\floater_instant_message.xml"> 2542 RelativePath=".\skins\xui\en-us\floater_instant_message.xml">
2427 </File> 2543 </File>
2428 <File 2544 <File
2545 RelativePath=".\skins\xui\en-us\floater_instant_message_ad_hoc.xml">
2546 </File>
2547 <File
2548 RelativePath=".\skins\xui\en-us\floater_instant_message_group.xml">
2549 </File>
2550 <File
2429 RelativePath=".\skins\xui\en-us\floater_inventory.xml"> 2551 RelativePath=".\skins\xui\en-us\floater_inventory.xml">
2430 </File> 2552 </File>
2431 <File 2553 <File
@@ -2435,18 +2557,27 @@
2435 RelativePath=".\skins\xui\en-us\floater_inventory_view_finder.xml"> 2557 RelativePath=".\skins\xui\en-us\floater_inventory_view_finder.xml">
2436 </File> 2558 </File>
2437 <File 2559 <File
2560 RelativePath=".\skins\xui\en-us\floater_joystick.xml">
2561 </File>
2562 <File
2438 RelativePath=".\skins\xui\en-us\floater_land_holdings.xml"> 2563 RelativePath=".\skins\xui\en-us\floater_land_holdings.xml">
2439 </File> 2564 </File>
2440 <File 2565 <File
2441 RelativePath=".\skins\xui\en-us\floater_live_lsleditor.xml"> 2566 RelativePath=".\skins\xui\en-us\floater_live_lsleditor.xml">
2442 </File> 2567 </File>
2443 <File 2568 <File
2569 RelativePath=".\skins\xui\en-us\floater_lsl_guide.xml">
2570 </File>
2571 <File
2444 RelativePath=".\skins\xui\en-us\floater_moveview.xml"> 2572 RelativePath=".\skins\xui\en-us\floater_moveview.xml">
2445 </File> 2573 </File>
2446 <File 2574 <File
2447 RelativePath=".\skins\xui\en-us\floater_mute.xml"> 2575 RelativePath=".\skins\xui\en-us\floater_mute.xml">
2448 </File> 2576 </File>
2449 <File 2577 <File
2578 RelativePath=".\skins\xui\en-us\floater_my_friends.xml">
2579 </File>
2580 <File
2450 RelativePath=".\skins\xui\en-us\floater_name_description.xml"> 2581 RelativePath=".\skins\xui\en-us\floater_name_description.xml">
2451 </File> 2582 </File>
2452 <File 2583 <File
@@ -2534,6 +2665,9 @@
2534 RelativePath=".\skins\xui\en-us\floater_script_search.xml"> 2665 RelativePath=".\skins\xui\en-us\floater_script_search.xml">
2535 </File> 2666 </File>
2536 <File 2667 <File
2668 RelativePath=".\skins\xui\en-us\floater_select_key.xml">
2669 </File>
2670 <File
2537 RelativePath=".\skins\xui\en-us\floater_sell_land.xml"> 2671 RelativePath=".\skins\xui\en-us\floater_sell_land.xml">
2538 </File> 2672 </File>
2539 <File 2673 <File
@@ -2561,6 +2695,9 @@
2561 RelativePath=".\skins\xui\en-us\floater_tos.xml"> 2695 RelativePath=".\skins\xui\en-us\floater_tos.xml">
2562 </File> 2696 </File>
2563 <File 2697 <File
2698 RelativePath=".\skins\xui\en-us\floater_voice_wizard.xml">
2699 </File>
2700 <File
2564 RelativePath=".\skins\xui\en-us\floater_wearable_save_as.xml"> 2701 RelativePath=".\skins\xui\en-us\floater_wearable_save_as.xml">
2565 </File> 2702 </File>
2566 <File 2703 <File
@@ -2678,6 +2815,12 @@
2678 RelativePath=".\skins\xui\en-us\panel_account_transactions.xml"> 2815 RelativePath=".\skins\xui\en-us\panel_account_transactions.xml">
2679 </File> 2816 </File>
2680 <File 2817 <File
2818 RelativePath=".\skins\xui\en-us\panel_audio.xml">
2819 </File>
2820 <File
2821 RelativePath=".\skins\xui\en-us\panel_audio_device.xml">
2822 </File>
2823 <File
2681 RelativePath=".\skins\xui\en-us\panel_avatar.xml"> 2824 RelativePath=".\skins\xui\en-us\panel_avatar.xml">
2682 </File> 2825 </File>
2683 <File 2826 <File
@@ -2699,6 +2842,9 @@
2699 RelativePath=".\skins\xui\en-us\panel_event.xml"> 2842 RelativePath=".\skins\xui\en-us\panel_event.xml">
2700 </File> 2843 </File>
2701 <File 2844 <File
2845 RelativePath=".\skins\xui\en-us\panel_friends.xml">
2846 </File>
2847 <File
2702 RelativePath=".\skins\xui\en-us\panel_group.xml"> 2848 RelativePath=".\skins\xui\en-us\panel_group.xml">
2703 </File> 2849 </File>
2704 <File 2850 <File
@@ -2723,12 +2869,18 @@
2723 RelativePath=".\skins\xui\en-us\panel_group_voting.xml"> 2869 RelativePath=".\skins\xui\en-us\panel_group_voting.xml">
2724 </File> 2870 </File>
2725 <File 2871 <File
2872 RelativePath=".\skins\xui\en-us\panel_groups.xml">
2873 </File>
2874 <File
2726 RelativePath=".\skins\xui\en-us\panel_land_covenant.xml"> 2875 RelativePath=".\skins\xui\en-us\panel_land_covenant.xml">
2727 </File> 2876 </File>
2728 <File 2877 <File
2729 RelativePath=".\skins\xui\en-us\panel_login.xml"> 2878 RelativePath=".\skins\xui\en-us\panel_login.xml">
2730 </File> 2879 </File>
2731 <File 2880 <File
2881 RelativePath=".\skins\xui\en-us\panel_master_volume.xml">
2882 </File>
2883 <File
2732 RelativePath=".\skins\xui\en-us\panel_media_remote.xml"> 2884 RelativePath=".\skins\xui\en-us\panel_media_remote.xml">
2733 </File> 2885 </File>
2734 <File 2886 <File
@@ -2774,6 +2926,12 @@
2774 RelativePath=".\skins\xui\en-us\panel_preferences_popups.xml"> 2926 RelativePath=".\skins\xui\en-us\panel_preferences_popups.xml">
2775 </File> 2927 </File>
2776 <File 2928 <File
2929 RelativePath=".\skins\xui\en-us\panel_preferences_voice.xml">
2930 </File>
2931 <File
2932 RelativePath=".\skins\xui\en-us\panel_preferences_web.xml">
2933 </File>
2934 <File
2777 RelativePath=".\skins\xui\en-us\panel_region_covenant.xml"> 2935 RelativePath=".\skins\xui\en-us\panel_region_covenant.xml">
2778 </File> 2936 </File>
2779 <File 2937 <File
@@ -2822,6 +2980,15 @@
2822 RelativePath=".\skins\xui\en-us\panel_top_pick.xml"> 2980 RelativePath=".\skins\xui\en-us\panel_top_pick.xml">
2823 </File> 2981 </File>
2824 <File 2982 <File
2983 RelativePath=".\skins\xui\en-us\panel_voice_enable.xml">
2984 </File>
2985 <File
2986 RelativePath=".\skins\xui\en-us\panel_voice_options.xml">
2987 </File>
2988 <File
2989 RelativePath=".\skins\xui\en-us\panel_voice_remote.xml">
2990 </File>
2991 <File
2825 RelativePath=".\app_settings\popups.xml"> 2992 RelativePath=".\app_settings\popups.xml">
2826 </File> 2993 </File>
2827 <File 2994 <File
@@ -2840,6 +3007,12 @@
2840 RelativePath=".\app_settings\std_bump.ini"> 3007 RelativePath=".\app_settings\std_bump.ini">
2841 </File> 3008 </File>
2842 <File 3009 <File
3010 RelativePath=".\skins\xui\en-us\teleport_strings.xml">
3011 </File>
3012 <File
3013 RelativePath=".\skins\textures\textures.xml">
3014 </File>
3015 <File
2843 RelativePath=".\res\toolbuy.cur"> 3016 RelativePath=".\res\toolbuy.cur">
2844 </File> 3017 </File>
2845 <File 3018 <File
@@ -2860,6 +3033,9 @@
2860 <File 3033 <File
2861 RelativePath=".\app_settings\trees.xml"> 3034 RelativePath=".\app_settings\trees.xml">
2862 </File> 3035 </File>
3036 <File
3037 RelativePath=".\skins\xui\en-us\xui_version.xml">
3038 </File>
2863 </Filter> 3039 </Filter>
2864 <File 3040 <File
2865 RelativePath=".\files.lst"> 3041 RelativePath=".\files.lst">
@@ -2901,7 +3077,8 @@
2901 <Tool 3077 <Tool
2902 Name="VCCustomBuildTool" 3078 Name="VCCustomBuildTool"
2903 Description="Copying message.xml" 3079 Description="Copying message.xml"
2904 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml" 3080 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml
3081"
2905 Outputs="./app_settings/message.xml"/> 3082 Outputs="./app_settings/message.xml"/>
2906 </FileConfiguration> 3083 </FileConfiguration>
2907 <FileConfiguration 3084 <FileConfiguration
@@ -2909,7 +3086,8 @@
2909 <Tool 3086 <Tool
2910 Name="VCCustomBuildTool" 3087 Name="VCCustomBuildTool"
2911 Description="Copying message.xml" 3088 Description="Copying message.xml"
2912 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml" 3089 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml
3090"
2913 Outputs="./app_settings/message.xml"/> 3091 Outputs="./app_settings/message.xml"/>
2914 </FileConfiguration> 3092 </FileConfiguration>
2915 <FileConfiguration 3093 <FileConfiguration
@@ -2917,7 +3095,8 @@
2917 <Tool 3095 <Tool
2918 Name="VCCustomBuildTool" 3096 Name="VCCustomBuildTool"
2919 Description="Copying message.xml" 3097 Description="Copying message.xml"
2920 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml" 3098 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml
3099"
2921 Outputs="./app_settings/message.xml"/> 3100 Outputs="./app_settings/message.xml"/>
2922 </FileConfiguration> 3101 </FileConfiguration>
2923 <FileConfiguration 3102 <FileConfiguration
@@ -2925,7 +3104,8 @@
2925 <Tool 3104 <Tool
2926 Name="VCCustomBuildTool" 3105 Name="VCCustomBuildTool"
2927 Description="Copying message.xml" 3106 Description="Copying message.xml"
2928 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml" 3107 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml
3108"
2929 Outputs="./app_settings/message.xml"/> 3109 Outputs="./app_settings/message.xml"/>
2930 </FileConfiguration> 3110 </FileConfiguration>
2931 </File> 3111 </File>
diff --git a/linden/indra/newview/newview_vc8.vcproj b/linden/indra/newview/newview_vc8.vcproj
index 032a6bf..ba05819 100644
--- a/linden/indra/newview/newview_vc8.vcproj
+++ b/linden/indra/newview/newview_vc8.vcproj
@@ -428,10 +428,6 @@
428 > 428 >
429 </File> 429 </File>
430 <File 430 <File
431 RelativePath=".\llaudiostatus.cpp"
432 >
433 </File>
434 <File
435 RelativePath=".\llbbox.cpp" 431 RelativePath=".\llbbox.cpp"
436 > 432 >
437 </File> 433 </File>
@@ -632,6 +628,10 @@
632 > 628 >
633 </File> 629 </File>
634 <File 630 <File
631 RelativePath=".\llfloateractivespeakers.cpp"
632 >
633 </File>
634 <File
635 RelativePath=".\llfloateranimpreview.cpp" 635 RelativePath=".\llfloateranimpreview.cpp"
636 > 636 >
637 </File> 637 </File>
@@ -680,6 +680,10 @@
680 > 680 >
681 </File> 681 </File>
682 <File 682 <File
683 RelativePath=".\llfloaterchatterbox.cpp"
684 >
685 </File>
686 <File
683 RelativePath=".\llfloaterclothing.cpp" 687 RelativePath=".\llfloaterclothing.cpp"
684 > 688 >
685 </File> 689 </File>
@@ -836,6 +840,10 @@
836 > 840 >
837 </File> 841 </File>
838 <File 842 <File
843 RelativePath=".\llfloatervoicewizard.cpp"
844 >
845 </File>
846 <File
839 RelativePath=".\llfloaterworldmap.cpp" 847 RelativePath=".\llfloaterworldmap.cpp"
840 > 848 >
841 </File> 849 </File>
@@ -1056,6 +1064,10 @@
1056 > 1064 >
1057 </File> 1065 </File>
1058 <File 1066 <File
1067 RelativePath=".\llpanelaudiovolume.cpp"
1068 >
1069 </File>
1070 <File
1059 RelativePath=".\llpanelavatar.cpp" 1071 RelativePath=".\llpanelavatar.cpp"
1060 > 1072 >
1061 </File> 1073 </File>
@@ -1232,6 +1244,10 @@
1232 > 1244 >
1233 </File> 1245 </File>
1234 <File 1246 <File
1247 RelativePath=".\llprefsvoice.cpp"
1248 >
1249 </File>
1250 <File
1235 RelativePath=".\llpreview.cpp" 1251 RelativePath=".\llpreview.cpp"
1236 > 1252 >
1237 </File> 1253 </File>
@@ -1512,6 +1528,98 @@
1512 > 1528 >
1513 </File> 1529 </File>
1514 <File 1530 <File
1531 RelativePath=".\llviewerjointmesh_sse.cpp"
1532 >
1533 <FileConfiguration
1534 Name="Debug|Win32"
1535 >
1536 <Tool
1537 Name="VCCLCompilerTool"
1538 EnableEnhancedInstructionSet="0"
1539 UsePrecompiledHeader="2"
1540 WarnAsError="false"
1541 />
1542 </FileConfiguration>
1543 <FileConfiguration
1544 Name="Release|Win32"
1545 >
1546 <Tool
1547 Name="VCCLCompilerTool"
1548 EnableEnhancedInstructionSet="0"
1549 UsePrecompiledHeader="2"
1550 WarnAsError="false"
1551 />
1552 </FileConfiguration>
1553 <FileConfiguration
1554 Name="ReleaseForDownload|Win32"
1555 >
1556 <Tool
1557 Name="VCCLCompilerTool"
1558 EnableEnhancedInstructionSet="0"
1559 UsePrecompiledHeader="2"
1560 WarnAsError="false"
1561 />
1562 </FileConfiguration>
1563 <FileConfiguration
1564 Name="ReleaseNoOpt|Win32"
1565 >
1566 <Tool
1567 Name="VCCLCompilerTool"
1568 EnableEnhancedInstructionSet="0"
1569 UsePrecompiledHeader="2"
1570 WarnAsError="false"
1571 />
1572 </FileConfiguration>
1573 </File>
1574 <File
1575 RelativePath=".\llviewerjointmesh_sse2.cpp"
1576 >
1577 <FileConfiguration
1578 Name="Debug|Win32"
1579 >
1580 <Tool
1581 Name="VCCLCompilerTool"
1582 EnableEnhancedInstructionSet="0"
1583 UsePrecompiledHeader="2"
1584 WarnAsError="false"
1585 />
1586 </FileConfiguration>
1587 <FileConfiguration
1588 Name="Release|Win32"
1589 >
1590 <Tool
1591 Name="VCCLCompilerTool"
1592 EnableEnhancedInstructionSet="0"
1593 UsePrecompiledHeader="2"
1594 WarnAsError="false"
1595 />
1596 </FileConfiguration>
1597 <FileConfiguration
1598 Name="ReleaseForDownload|Win32"
1599 >
1600 <Tool
1601 Name="VCCLCompilerTool"
1602 EnableEnhancedInstructionSet="0"
1603 UsePrecompiledHeader="2"
1604 WarnAsError="false"
1605 />
1606 </FileConfiguration>
1607 <FileConfiguration
1608 Name="ReleaseNoOpt|Win32"
1609 >
1610 <Tool
1611 Name="VCCLCompilerTool"
1612 EnableEnhancedInstructionSet="0"
1613 UsePrecompiledHeader="2"
1614 WarnAsError="false"
1615 />
1616 </FileConfiguration>
1617 </File>
1618 <File
1619 RelativePath=".\llviewerjointmesh_vec.cpp"
1620 >
1621 </File>
1622 <File
1515 RelativePath=".\llviewerjointshape.cpp" 1623 RelativePath=".\llviewerjointshape.cpp"
1516 > 1624 >
1517 </File> 1625 </File>
@@ -1628,11 +1736,19 @@
1628 > 1736 >
1629 </File> 1737 </File>
1630 <File 1738 <File
1631 RelativePath=".\llvoinventorylistener.cpp" 1739 RelativePath=".\llvoiceclient.cpp"
1632 > 1740 >
1633 </File> 1741 </File>
1634 <File 1742 <File
1635 RelativePath=".\llvolumesliderctrl.cpp" 1743 RelativePath=".\llvoiceremotectrl.cpp"
1744 >
1745 </File>
1746 <File
1747 RelativePath=".\llvoicevisualizer.cpp"
1748 >
1749 </File>
1750 <File
1751 RelativePath=".\llvoinventorylistener.cpp"
1636 > 1752 >
1637 </File> 1753 </File>
1638 <File 1754 <File
@@ -1766,10 +1882,6 @@
1766 > 1882 >
1767 </File> 1883 </File>
1768 <File 1884 <File
1769 RelativePath=".\llaudiostatus.h"
1770 >
1771 </File>
1772 <File
1773 RelativePath=".\llautocomplete.h" 1885 RelativePath=".\llautocomplete.h"
1774 > 1886 >
1775 </File> 1887 </File>
@@ -1974,6 +2086,10 @@
1974 > 2086 >
1975 </File> 2087 </File>
1976 <File 2088 <File
2089 RelativePath=".\llfloateractivespeakers.h"
2090 >
2091 </File>
2092 <File
1977 RelativePath=".\llfloateranimpreview.h" 2093 RelativePath=".\llfloateranimpreview.h"
1978 > 2094 >
1979 </File> 2095 </File>
@@ -2022,6 +2138,10 @@
2022 > 2138 >
2023 </File> 2139 </File>
2024 <File 2140 <File
2141 RelativePath=".\llfloaterchatterbox.h"
2142 >
2143 </File>
2144 <File
2025 RelativePath=".\llfloaterclothing.h" 2145 RelativePath=".\llfloaterclothing.h"
2026 > 2146 >
2027 </File> 2147 </File>
@@ -2178,6 +2298,10 @@
2178 > 2298 >
2179 </File> 2299 </File>
2180 <File 2300 <File
2301 RelativePath=".\llfloatervoicewizard.h"
2302 >
2303 </File>
2304 <File
2181 RelativePath=".\llfloaterworldmap.h" 2305 RelativePath=".\llfloaterworldmap.h"
2182 > 2306 >
2183 </File> 2307 </File>
@@ -2390,6 +2514,10 @@
2390 > 2514 >
2391 </File> 2515 </File>
2392 <File 2516 <File
2517 RelativePath=".\llpanelaudiovolume.h"
2518 >
2519 </File>
2520 <File
2393 RelativePath=".\llpanelavatar.h" 2521 RelativePath=".\llpanelavatar.h"
2394 > 2522 >
2395 </File> 2523 </File>
@@ -2574,6 +2702,10 @@
2574 > 2702 >
2575 </File> 2703 </File>
2576 <File 2704 <File
2705 RelativePath=".\llprefsvoice.h"
2706 >
2707 </File>
2708 <File
2577 RelativePath=".\llpreview.h" 2709 RelativePath=".\llpreview.h"
2578 > 2710 >
2579 </File> 2711 </File>
@@ -2986,11 +3118,19 @@
2986 > 3118 >
2987 </File> 3119 </File>
2988 <File 3120 <File
2989 RelativePath=".\llvoinventorylistener.h" 3121 RelativePath=".\llvoiceclient.h"
3122 >
3123 </File>
3124 <File
3125 RelativePath=".\llvoiceremotectrl.h"
3126 >
3127 </File>
3128 <File
3129 RelativePath=".\llvoicevisualizer.h"
2990 > 3130 >
2991 </File> 3131 </File>
2992 <File 3132 <File
2993 RelativePath=".\llvolumesliderctrl.h" 3133 RelativePath=".\llvoinventorylistener.h"
2994 > 3134 >
2995 </File> 3135 </File>
2996 <File 3136 <File
@@ -3897,6 +4037,50 @@
3897 > 4037 >
3898 </File> 4038 </File>
3899 <File 4039 <File
4040 RelativePath="..\..\etc\message.xml"
4041 >
4042 <FileConfiguration
4043 Name="Debug|Win32"
4044 >
4045 <Tool
4046 Name="VCCustomBuildTool"
4047 Description="Copying message.xml"
4048 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml&#x0D;&#x0A;"
4049 Outputs="./app_settings/message.xml"
4050 />
4051 </FileConfiguration>
4052 <FileConfiguration
4053 Name="Release|Win32"
4054 >
4055 <Tool
4056 Name="VCCustomBuildTool"
4057 Description="Copying message.xml"
4058 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml&#x0D;&#x0A;"
4059 Outputs="./app_settings/message.xml"
4060 />
4061 </FileConfiguration>
4062 <FileConfiguration
4063 Name="ReleaseForDownload|Win32"
4064 >
4065 <Tool
4066 Name="VCCustomBuildTool"
4067 Description="Copying message.xml"
4068 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml&#x0D;&#x0A;"
4069 Outputs="./app_settings/message.xml"
4070 />
4071 </FileConfiguration>
4072 <FileConfiguration
4073 Name="ReleaseNoOpt|Win32"
4074 >
4075 <Tool
4076 Name="VCCustomBuildTool"
4077 Description="Copying message.xml"
4078 CommandLine="copy &quot;$(InputPath)&quot; .\app_settings\message.xml&#x0D;&#x0A;"
4079 Outputs="./app_settings/message.xml"
4080 />
4081 </FileConfiguration>
4082 </File>
4083 <File
3900 RelativePath="..\..\scripts\messages\message_template.msg" 4084 RelativePath="..\..\scripts\messages\message_template.msg"
3901 > 4085 >
3902 <FileConfiguration 4086 <FileConfiguration
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp
index 7d03e64..16eaa22 100644
--- a/linden/indra/newview/pipeline.cpp
+++ b/linden/indra/newview/pipeline.cpp
@@ -163,10 +163,14 @@ U32 nhpo2(U32 v)
163S32 LLPipeline::sCompiles = 0; 163S32 LLPipeline::sCompiles = 0;
164 164
165BOOL LLPipeline::sShowHUDAttachments = TRUE; 165BOOL LLPipeline::sShowHUDAttachments = TRUE;
166BOOL LLPipeline::sRenderPhysicalBeacons = FALSE; 166BOOL LLPipeline::sRenderPhysicalBeacons = TRUE;
167BOOL LLPipeline::sRenderScriptedBeacons = FALSE; 167BOOL LLPipeline::sRenderScriptedBeacons = FALSE;
168BOOL LLPipeline::sRenderScriptedTouchBeacons = TRUE;
168BOOL LLPipeline::sRenderParticleBeacons = FALSE; 169BOOL LLPipeline::sRenderParticleBeacons = FALSE;
169BOOL LLPipeline::sRenderSoundBeacons = FALSE; 170BOOL LLPipeline::sRenderSoundBeacons = FALSE;
171BOOL LLPipeline::sRenderBeacons = FALSE;
172BOOL LLPipeline::sRenderHighlight = TRUE;
173BOOL LLPipeline::sRenderProcessBeacons = FALSE;
170BOOL LLPipeline::sUseOcclusion = FALSE; 174BOOL LLPipeline::sUseOcclusion = FALSE;
171BOOL LLPipeline::sSkipUpdate = FALSE; 175BOOL LLPipeline::sSkipUpdate = FALSE;
172BOOL LLPipeline::sDynamicReflections = FALSE; 176BOOL LLPipeline::sDynamicReflections = FALSE;
@@ -376,14 +380,22 @@ void LLPipeline::releaseGLBuffers()
376 380
377 if (mCubeFrameBuffer) 381 if (mCubeFrameBuffer)
378 { 382 {
383#if !defined(__sparc)
379 glDeleteFramebuffersEXT(1, &mCubeFrameBuffer); 384 glDeleteFramebuffersEXT(1, &mCubeFrameBuffer);
380 glDeleteRenderbuffersEXT(1, &mCubeDepth); 385 glDeleteRenderbuffersEXT(1, &mCubeDepth);
386#else
387#error Can we generalize this without a CPU architecture test?
388#endif
381 mCubeDepth = mCubeFrameBuffer = 0; 389 mCubeDepth = mCubeFrameBuffer = 0;
382 } 390 }
383 391
384 if (mFramebuffer[0]) 392 if (mFramebuffer[0])
385 { 393 {
394#if !defined(__sparc)
386 glDeleteFramebuffersEXT(2, mFramebuffer); 395 glDeleteFramebuffersEXT(2, mFramebuffer);
396#else
397#error Can we generalize this without a CPU architecture test?
398#endif
387 mFramebuffer[0] = mFramebuffer[1] = 0; 399 mFramebuffer[0] = mFramebuffer[1] = 0;
388 } 400 }
389} 401}
@@ -1489,7 +1501,44 @@ void renderScriptedBeacons(LLDrawable* drawablep)
1489 && !vobj->getParent() 1501 && !vobj->getParent()
1490 && vobj->flagScripted()) 1502 && vobj->flagScripted())
1491 { 1503 {
1492 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); 1504 if (gPipeline.sRenderBeacons)
1505 {
1506 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
1507 }
1508
1509 if (gPipeline.sRenderHighlight)
1510 {
1511 S32 face_id;
1512 for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++)
1513 {
1514 gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
1515 }
1516 }
1517 }
1518}
1519
1520void renderScriptedTouchBeacons(LLDrawable* drawablep)
1521{
1522 LLViewerObject *vobj = drawablep->getVObj();
1523 if (vobj
1524 && !vobj->isAvatar()
1525 && !vobj->getParent()
1526 && vobj->flagScripted()
1527 && vobj->flagHandleTouch())
1528 {
1529 if (gPipeline.sRenderBeacons)
1530 {
1531 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
1532 }
1533
1534 if (gPipeline.sRenderHighlight)
1535 {
1536 S32 face_id;
1537 for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++)
1538 {
1539 gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
1540 }
1541 }
1493 } 1542 }
1494} 1543}
1495 1544
@@ -1501,7 +1550,19 @@ void renderPhysicalBeacons(LLDrawable* drawablep)
1501 && !vobj->getParent() 1550 && !vobj->getParent()
1502 && vobj->usePhysics()) 1551 && vobj->usePhysics())
1503 { 1552 {
1504 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); 1553 if (gPipeline.sRenderBeacons)
1554 {
1555 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
1556 }
1557
1558 if (gPipeline.sRenderHighlight)
1559 {
1560 S32 face_id;
1561 for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++)
1562 {
1563 gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
1564 }
1565 }
1505 } 1566 }
1506} 1567}
1507 1568
@@ -1512,20 +1573,13 @@ void renderParticleBeacons(LLDrawable* drawablep)
1512 if (vobj 1573 if (vobj
1513 && vobj->isParticleSource()) 1574 && vobj->isParticleSource())
1514 { 1575 {
1515 LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f); 1576 if (gPipeline.sRenderBeacons)
1516 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); 1577 {
1517 } 1578 LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f);
1518} 1579 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
1580 }
1519 1581
1520void LLPipeline::highlightPhysical(LLDrawable* drawablep) 1582 if (gPipeline.sRenderHighlight)
1521{
1522 LLMemType mt(LLMemType::MTYPE_PIPELINE);
1523 LLViewerObject *vobj;
1524 vobj = drawablep->getVObj();
1525 if (vobj && !vobj->isAvatar())
1526 {
1527 if (!vobj->isAvatar() &&
1528 (vobj->usePhysics() || vobj->flagHandleTouch()))
1529 { 1583 {
1530 S32 face_id; 1584 S32 face_id;
1531 for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) 1585 for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++)
@@ -1699,42 +1753,49 @@ void LLPipeline::postSort(LLCamera& camera)
1699 std::sort(mAlphaGroups.begin(), mAlphaGroups.end(), LLSpatialGroup::CompareDepthGreater()); 1753 std::sort(mAlphaGroups.begin(), mAlphaGroups.end(), LLSpatialGroup::CompareDepthGreater());
1700 std::sort(mAlphaGroupsPostWater.begin(), mAlphaGroupsPostWater.end(), LLSpatialGroup::CompareDepthGreater()); 1754 std::sort(mAlphaGroupsPostWater.begin(), mAlphaGroupsPostWater.end(), LLSpatialGroup::CompareDepthGreater());
1701 1755
1702 if (sRenderScriptedBeacons) 1756 // only render if the flag is set. The flag is only set if the right key is pressed, we are in edit mode or the toggle is set in the menus
1757 if (sRenderProcessBeacons)
1703 { 1758 {
1704 // Only show the beacon on the root object. 1759 if (sRenderScriptedTouchBeacons)
1705 forAllVisibleDrawables(renderScriptedBeacons); 1760 {
1706 } 1761 // Only show the beacon on the root object.
1707 1762 forAllVisibleDrawables(renderScriptedTouchBeacons);
1708 if (sRenderPhysicalBeacons) 1763 }
1709 { 1764 else
1710 // Only show the beacon on the root object. 1765 if (sRenderScriptedBeacons)
1711 forAllVisibleDrawables(renderPhysicalBeacons); 1766 {
1712 } 1767 // Only show the beacon on the root object.
1768 forAllVisibleDrawables(renderScriptedBeacons);
1769 }
1713 1770
1714 if (sRenderParticleBeacons) 1771 if (sRenderPhysicalBeacons)
1715 { 1772 {
1716 forAllVisibleDrawables(renderParticleBeacons); 1773 // Only show the beacon on the root object.
1717 } 1774 forAllVisibleDrawables(renderPhysicalBeacons);
1775 }
1718 1776
1719 // Draw physical objects in red. 1777 if (sRenderParticleBeacons)
1720 if (gHUDManager->getShowPhysical()) 1778 {
1721 { 1779 forAllVisibleDrawables(renderParticleBeacons);
1722 forAllVisibleDrawables(highlightPhysical); 1780 }
1723 }
1724 1781
1725 // If god mode, also show audio cues 1782 // If god mode, also show audio cues
1726 if (sRenderSoundBeacons && gAudiop) 1783 if (sRenderSoundBeacons && gAudiop)
1727 {
1728 // Update all of our audio sources, clean up dead ones.
1729 LLAudioEngine::source_map::iterator iter;
1730 for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter)
1731 { 1784 {
1732 LLAudioSource *sourcep = iter->second; 1785 // Update all of our audio sources, clean up dead ones.
1786 LLAudioEngine::source_map::iterator iter;
1787 for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter)
1788 {
1789 LLAudioSource *sourcep = iter->second;
1733 1790
1734 LLVector3d pos_global = sourcep->getPositionGlobal(); 1791 LLVector3d pos_global = sourcep->getPositionGlobal();
1735 LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global); 1792 LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global);
1736 //pos += LLVector3(0.f, 0.f, 0.2f); 1793 if (gPipeline.sRenderBeacons)
1737 gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); 1794 {
1795 //pos += LLVector3(0.f, 0.f, 0.2f);
1796 gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
1797 }
1798 }
1738 } 1799 }
1739 } 1800 }
1740 1801
@@ -3448,6 +3509,12 @@ BOOL LLPipeline::toggleRenderDebugFeatureControl(void* data)
3448} 3509}
3449 3510
3450// static 3511// static
3512void LLPipeline::setRenderScriptedBeacons(BOOL val)
3513{
3514 sRenderScriptedBeacons = val;
3515}
3516
3517// static
3451void LLPipeline::toggleRenderScriptedBeacons(void*) 3518void LLPipeline::toggleRenderScriptedBeacons(void*)
3452{ 3519{
3453 sRenderScriptedBeacons = !sRenderScriptedBeacons; 3520 sRenderScriptedBeacons = !sRenderScriptedBeacons;
@@ -3460,6 +3527,30 @@ BOOL LLPipeline::getRenderScriptedBeacons(void*)
3460} 3527}
3461 3528
3462// static 3529// static
3530void LLPipeline::setRenderScriptedTouchBeacons(BOOL val)
3531{
3532 sRenderScriptedTouchBeacons = val;
3533}
3534
3535// static
3536void LLPipeline::toggleRenderScriptedTouchBeacons(void*)
3537{
3538 sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons;
3539}
3540
3541// static
3542BOOL LLPipeline::getRenderScriptedTouchBeacons(void*)
3543{
3544 return sRenderScriptedTouchBeacons;
3545}
3546
3547// static
3548void LLPipeline::setRenderPhysicalBeacons(BOOL val)
3549{
3550 sRenderPhysicalBeacons = val;
3551}
3552
3553// static
3463void LLPipeline::toggleRenderPhysicalBeacons(void*) 3554void LLPipeline::toggleRenderPhysicalBeacons(void*)
3464{ 3555{
3465 sRenderPhysicalBeacons = !sRenderPhysicalBeacons; 3556 sRenderPhysicalBeacons = !sRenderPhysicalBeacons;
@@ -3472,6 +3563,12 @@ BOOL LLPipeline::getRenderPhysicalBeacons(void*)
3472} 3563}
3473 3564
3474// static 3565// static
3566void LLPipeline::setRenderParticleBeacons(BOOL val)
3567{
3568 sRenderParticleBeacons = val;
3569}
3570
3571// static
3475void LLPipeline::toggleRenderParticleBeacons(void*) 3572void LLPipeline::toggleRenderParticleBeacons(void*)
3476{ 3573{
3477 sRenderParticleBeacons = !sRenderParticleBeacons; 3574 sRenderParticleBeacons = !sRenderParticleBeacons;
@@ -3484,6 +3581,12 @@ BOOL LLPipeline::getRenderParticleBeacons(void*)
3484} 3581}
3485 3582
3486// static 3583// static
3584void LLPipeline::setRenderSoundBeacons(BOOL val)
3585{
3586 sRenderSoundBeacons = val;
3587}
3588
3589// static
3487void LLPipeline::toggleRenderSoundBeacons(void*) 3590void LLPipeline::toggleRenderSoundBeacons(void*)
3488{ 3591{
3489 sRenderSoundBeacons = !sRenderSoundBeacons; 3592 sRenderSoundBeacons = !sRenderSoundBeacons;
@@ -3495,6 +3598,48 @@ BOOL LLPipeline::getRenderSoundBeacons(void*)
3495 return sRenderSoundBeacons; 3598 return sRenderSoundBeacons;
3496} 3599}
3497 3600
3601// static
3602void LLPipeline::setRenderBeacons(BOOL val)
3603{
3604 sRenderBeacons = val;
3605}
3606
3607// static
3608void LLPipeline::toggleRenderBeacons(void*)
3609{
3610 sRenderBeacons = !sRenderBeacons;
3611}
3612
3613// static
3614BOOL LLPipeline::getRenderBeacons(void*)
3615{
3616 return sRenderBeacons;
3617}
3618
3619// static
3620void LLPipeline::setRenderHighlights(BOOL val)
3621{
3622 sRenderHighlight = val;
3623}
3624
3625// static
3626void LLPipeline::toggleRenderHighlights(void*)
3627{
3628 sRenderHighlight = !sRenderHighlight;
3629}
3630
3631// static
3632BOOL LLPipeline::getRenderHighlights(void*)
3633{
3634 return sRenderHighlight;
3635}
3636
3637// static
3638BOOL LLPipeline::getProcessBeacons(void* data)
3639{
3640 return sRenderProcessBeacons;
3641}
3642
3498LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) 3643LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision)
3499{ 3644{
3500 LLDrawable* drawable = mObjectPartition[PARTITION_VOLUME]->pickDrawable(start, end, collision); 3645 LLDrawable* drawable = mObjectPartition[PARTITION_VOLUME]->pickDrawable(start, end, collision);
@@ -3633,8 +3778,12 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
3633 BOOL reattach = FALSE; 3778 BOOL reattach = FALSE;
3634 if (mCubeFrameBuffer == 0) 3779 if (mCubeFrameBuffer == 0)
3635 { 3780 {
3781#if !defined(__sparc)
3636 glGenFramebuffersEXT(1, &mCubeFrameBuffer); 3782 glGenFramebuffersEXT(1, &mCubeFrameBuffer);
3637 glGenRenderbuffersEXT(1, &mCubeDepth); 3783 glGenRenderbuffersEXT(1, &mCubeDepth);
3784#else
3785#error Can we generalize this without a CPU architecture test?
3786#endif
3638 reattach = TRUE; 3787 reattach = TRUE;
3639 } 3788 }
3640 3789
@@ -3705,6 +3854,7 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
3705 3854
3706 if (reattach) 3855 if (reattach)
3707 { 3856 {
3857#if !defined(__sparc)
3708 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth); 3858 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth);
3709 GLint res_x, res_y; 3859 GLint res_x, res_y;
3710 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &res_x); 3860 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &res_x);
@@ -3716,15 +3866,22 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
3716 } 3866 }
3717 3867
3718 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); 3868 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
3869#else
3870#error Can we generalize this without a CPU architecture test?
3871#endif
3719 } 3872 }
3720 3873
3721 for (S32 i = 0; i < 6; i++) 3874 for (S32 i = 0; i < 6; i++)
3722 { 3875 {
3876#if !defined(__sparc)
3723 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer); 3877 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer);
3724 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 3878 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
3725 cube_face[i], cube_map->getGLName(), 0); 3879 cube_face[i], cube_map->getGLName(), 0);
3726 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, 3880 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
3727 GL_RENDERBUFFER_EXT, mCubeDepth); 3881 GL_RENDERBUFFER_EXT, mCubeDepth);
3882#else
3883#error Can we generalize this without a CPU architecture test?
3884#endif
3728 glMatrixMode(GL_PROJECTION); 3885 glMatrixMode(GL_PROJECTION);
3729 glLoadIdentity(); 3886 glLoadIdentity();
3730 gluPerspective(90.f, 1.f, 0.1f, 1024.f); 3887 gluPerspective(90.f, 1.f, 0.1f, 1024.f);
@@ -3744,7 +3901,11 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam,
3744 gPipeline.renderGeom(cube_cam); 3901 gPipeline.renderGeom(cube_cam);
3745 } 3902 }
3746 3903
3904#if !defined(__sparc)
3747 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 3905 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
3906#else
3907#error Can we generalize this without a CPU architecture test?
3908#endif
3748 3909
3749 cube_cam.setOrigin(origin); 3910 cube_cam.setOrigin(origin);
3750 gPipeline.resetDrawOrders(); 3911 gPipeline.resetDrawOrders();
@@ -3953,10 +4114,14 @@ void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res,
3953 LLGLDisable blend(GL_BLEND); 4114 LLGLDisable blend(GL_BLEND);
3954 LLGLDisable cull(GL_CULL_FACE); 4115 LLGLDisable cull(GL_CULL_FACE);
3955 4116
4117#if !defined(__sparc)
3956 if (mFramebuffer[0] == 0) 4118 if (mFramebuffer[0] == 0)
3957 { 4119 {
3958 glGenFramebuffersEXT(2, mFramebuffer); 4120 glGenFramebuffersEXT(2, mFramebuffer);
3959 } 4121 }
4122#else
4123#error Can we generalize this without a CPU architecture test?
4124#endif
3960 4125
3961 GLint viewport[4]; 4126 GLint viewport[4];
3962 glGetIntegerv(GL_VIEWPORT, viewport); 4127 glGetIntegerv(GL_VIEWPORT, viewport);
@@ -3979,11 +4144,15 @@ void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res,
3979 4144
3980 for (S32 i = 0; i < kernel; i++) 4145 for (S32 i = 0; i < kernel; i++)
3981 { 4146 {
4147#if !defined(__sparc)
3982 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebuffer[i%2]); 4148 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebuffer[i%2]);
3983 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 4149 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
3984 GL_COLOR_ATTACHMENT0_EXT, 4150 GL_COLOR_ATTACHMENT0_EXT,
3985 GL_TEXTURE_2D, 4151 GL_TEXTURE_2D,
3986 i%2 == 0 ? buffer : dest, 0); 4152 i%2 == 0 ? buffer : dest, 0);
4153#else
4154#error Can we generalize this without a CPU architecture test?
4155#endif
3987 4156
3988 glBindTexture(GL_TEXTURE_2D, i == 0 ? source : 4157 glBindTexture(GL_TEXTURE_2D, i == 0 ? source :
3989 i%2==0 ? dest : 4158 i%2==0 ? dest :
@@ -4010,7 +4179,11 @@ void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res,
4010 4179
4011 } 4180 }
4012 4181
4182#if !defined(__sparc)
4013 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 4183 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
4184#else
4185#error Can we generalize this without a CPU architecture test?
4186#endif
4014 gGlowProgram.unbind(); 4187 gGlowProgram.unbind();
4015 4188
4016 glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); 4189 glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
diff --git a/linden/indra/newview/pipeline.h b/linden/indra/newview/pipeline.h
index a687e12..218f920 100644
--- a/linden/indra/newview/pipeline.h
+++ b/linden/indra/newview/pipeline.h
@@ -154,7 +154,6 @@ public:
154 void postSort(LLCamera& camera); 154 void postSort(LLCamera& camera);
155 void forAllDrawables(LLSpatialGroup::sg_vector_t& groups, void (*func)(LLDrawable*)); 155 void forAllDrawables(LLSpatialGroup::sg_vector_t& groups, void (*func)(LLDrawable*));
156 void forAllVisibleDrawables(void (*func)(LLDrawable*)); 156 void forAllVisibleDrawables(void (*func)(LLDrawable*));
157 static void highlightPhysical(LLDrawable* drawablep);
158 157
159 void renderObjects(U32 type, U32 mask, BOOL texture = TRUE); 158 void renderObjects(U32 type, U32 mask, BOOL texture = TRUE);
160 159
@@ -207,18 +206,36 @@ public:
207 static BOOL toggleRenderDebugControl(void* data); 206 static BOOL toggleRenderDebugControl(void* data);
208 static BOOL toggleRenderDebugFeatureControl(void* data); 207 static BOOL toggleRenderDebugFeatureControl(void* data);
209 208
209 static void setRenderParticleBeacons(BOOL val);
210 static void toggleRenderParticleBeacons(void* data); 210 static void toggleRenderParticleBeacons(void* data);
211 static BOOL getRenderParticleBeacons(void* data); 211 static BOOL getRenderParticleBeacons(void* data);
212 212
213 static void setRenderSoundBeacons(BOOL val);
213 static void toggleRenderSoundBeacons(void* data); 214 static void toggleRenderSoundBeacons(void* data);
214 static BOOL getRenderSoundBeacons(void* data); 215 static BOOL getRenderSoundBeacons(void* data);
215 216
217 static void setRenderPhysicalBeacons(BOOL val);
216 static void toggleRenderPhysicalBeacons(void* data); 218 static void toggleRenderPhysicalBeacons(void* data);
217 static BOOL getRenderPhysicalBeacons(void* data); 219 static BOOL getRenderPhysicalBeacons(void* data);
218 220
221 static void setRenderScriptedBeacons(BOOL val);
219 static void toggleRenderScriptedBeacons(void* data); 222 static void toggleRenderScriptedBeacons(void* data);
220 static BOOL getRenderScriptedBeacons(void* data); 223 static BOOL getRenderScriptedBeacons(void* data);
221 224
225 static void setRenderScriptedTouchBeacons(BOOL val);
226 static void toggleRenderScriptedTouchBeacons(void* data);
227 static BOOL getRenderScriptedTouchBeacons(void* data);
228
229 static void setRenderBeacons(BOOL val);
230 static void toggleRenderBeacons(void* data);
231 static BOOL getRenderBeacons(void* data);
232
233 static void setRenderHighlights(BOOL val);
234 static void toggleRenderHighlights(void* data);
235 static BOOL getRenderHighlights(void* data);
236
237 static BOOL getProcessBeacons(void* data);
238
222private: 239private:
223 void initShaders(BOOL force); 240 void initShaders(BOOL force);
224 void unloadShaders(); 241 void unloadShaders();
@@ -494,8 +511,9 @@ protected:
494 LLDrawPool* mBumpPool; 511 LLDrawPool* mBumpPool;
495 // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar 512 // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
496 513
497 514public:
498 std::vector<LLFace*> mHighlightFaces; // highlight faces on physical objects 515 std::vector<LLFace*> mHighlightFaces; // highlight faces on physical objects
516protected:
499 std::vector<LLFace*> mSelectedFaces; 517 std::vector<LLFace*> mSelectedFaces;
500 518
501 LLPointer<LLViewerImage> mFaceSelectImagep; 519 LLPointer<LLViewerImage> mFaceSelectImagep;
@@ -508,9 +526,14 @@ protected:
508 F32 mSunShadowFactor; 526 F32 mSunShadowFactor;
509 527
510 static BOOL sRenderPhysicalBeacons; 528 static BOOL sRenderPhysicalBeacons;
529 static BOOL sRenderScriptedTouchBeacons;
511 static BOOL sRenderScriptedBeacons; 530 static BOOL sRenderScriptedBeacons;
512 static BOOL sRenderParticleBeacons; 531 static BOOL sRenderParticleBeacons;
513 static BOOL sRenderSoundBeacons; 532 static BOOL sRenderSoundBeacons;
533public:
534 static BOOL sRenderBeacons;
535 static BOOL sRenderHighlight;
536 static BOOL sRenderProcessBeacons;
514}; 537};
515 538
516void render_bbox(const LLVector3 &min, const LLVector3 &max); 539void render_bbox(const LLVector3 &min, const LLVector3 &max);
diff --git a/linden/indra/newview/postbuild.bat b/linden/indra/newview/postbuild.bat
index 76bedbe..d71a81e 100644
--- a/linden/indra/newview/postbuild.bat
+++ b/linden/indra/newview/postbuild.bat
@@ -10,7 +10,6 @@ goto end
10 10
11:debug 11:debug
12echo copying debug files 12echo copying debug files
13if exist .\debug\freebl3.dll goto end
14copy ..\..\libraries\i686-win32\lib_debug\freebl3.dll .\debug\ /y 13copy ..\..\libraries\i686-win32\lib_debug\freebl3.dll .\debug\ /y
15copy ..\..\libraries\i686-win32\lib_debug\gksvggdiplus.dll .\debug\ /y 14copy ..\..\libraries\i686-win32\lib_debug\gksvggdiplus.dll .\debug\ /y
16copy ..\..\libraries\i686-win32\lib_debug\js3250.dll .\debug\ /y 15copy ..\..\libraries\i686-win32\lib_debug\js3250.dll .\debug\ /y
@@ -27,6 +26,18 @@ copy ..\..\libraries\i686-win32\lib_debug\xul.dll .\debug\ /y
27rem --- this is required for mozilla debug builds and displays the aborty/retry/ignore dialog on an assert - crashes without it --- 26rem --- this is required for mozilla debug builds and displays the aborty/retry/ignore dialog on an assert - crashes without it ---
28copy ..\..\libraries\i686-win32\lib_debug\windbgdlg.exe .\debug\ /y 27copy ..\..\libraries\i686-win32\lib_debug\windbgdlg.exe .\debug\ /y
29 28
29rem --- runtime pieces for the bHear stuff.
30copy .\vivox-runtime\i686-win32\tntk.dll .\ /y
31copy .\vivox-runtime\i686-win32\libeay32.dll .\ /y
32copy .\vivox-runtime\i686-win32\SLVoice.exe .\ /y
33copy .\vivox-runtime\i686-win32\ssleay32.dll .\ /y
34copy .\vivox-runtime\i686-win32\SLVoiceAgent.exe .\ /y
35copy .\vivox-runtime\i686-win32\srtp.dll .\ /y
36copy .\vivox-runtime\i686-win32\alut.dll .\ /y
37copy .\vivox-runtime\i686-win32\vivoxsdk.dll .\ /y
38copy .\vivox-runtime\i686-win32\ortp.dll .\ /y
39copy .\vivox-runtime\i686-win32\wrap_oal.dll .\ /y
40
30@IF NOT EXIST ..\llkdu\Debug\llkdu.dll ( 41@IF NOT EXIST ..\llkdu\Debug\llkdu.dll (
31 @IF EXIST ..\..\libraries\i686-win32\lib_debug\llkdu.dll ( 42 @IF EXIST ..\..\libraries\i686-win32\lib_debug\llkdu.dll (
32 SET KDU_DLL=..\..\libraries\i686-win32\lib_debug\llkdu.dll 43 SET KDU_DLL=..\..\libraries\i686-win32\lib_debug\llkdu.dll
@@ -41,7 +52,6 @@ goto end
41 52
42:release 53:release
43echo copying release files 54echo copying release files
44if exist .\Release\freebl3.dll goto end
45copy ..\..\libraries\i686-win32\lib_release\freebl3.dll .\Release\ /y 55copy ..\..\libraries\i686-win32\lib_release\freebl3.dll .\Release\ /y
46copy ..\..\libraries\i686-win32\lib_release\gksvggdiplus.dll .\Release\ /y 56copy ..\..\libraries\i686-win32\lib_release\gksvggdiplus.dll .\Release\ /y
47copy ..\..\libraries\i686-win32\lib_release\js3250.dll .\Release\ /y 57copy ..\..\libraries\i686-win32\lib_release\js3250.dll .\Release\ /y
@@ -56,6 +66,18 @@ copy ..\..\libraries\i686-win32\lib_release\ssl3.dll .\Release\ /y
56copy ..\..\libraries\i686-win32\lib_release\xpcom.dll .\Release\ /y 66copy ..\..\libraries\i686-win32\lib_release\xpcom.dll .\Release\ /y
57copy ..\..\libraries\i686-win32\lib_release\xul.dll .\Release\ /y 67copy ..\..\libraries\i686-win32\lib_release\xul.dll .\Release\ /y
58 68
69rem --- runtime pieces for the bHear stuff.
70copy .\vivox-runtime\i686-win32\tntk.dll .\ /y
71copy .\vivox-runtime\i686-win32\libeay32.dll .\ /y
72copy .\vivox-runtime\i686-win32\SLVoice.exe .\ /y
73copy .\vivox-runtime\i686-win32\ssleay32.dll .\ /y
74copy .\vivox-runtime\i686-win32\SLVoiceAgent.exe .\ /y
75copy .\vivox-runtime\i686-win32\srtp.dll .\ /y
76copy .\vivox-runtime\i686-win32\alut.dll .\ /y
77copy .\vivox-runtime\i686-win32\vivoxsdk.dll .\ /y
78copy .\vivox-runtime\i686-win32\ortp.dll .\ /y
79copy .\vivox-runtime\i686-win32\wrap_oal.dll .\ /y
80
59@IF NOT EXIST ..\llkdu\Release\llkdu.dll ( 81@IF NOT EXIST ..\llkdu\Release\llkdu.dll (
60 copy ..\..\libraries\i686-win32\lib_release\llkdu.dll .\Release\ /y 82 copy ..\..\libraries\i686-win32\lib_release\llkdu.dll .\Release\ /y
61) ELSE ( 83) ELSE (
@@ -65,7 +87,6 @@ goto end
65 87
66:releasenoopt 88:releasenoopt
67echo copying releasenoopt files 89echo copying releasenoopt files
68if exist .\ReleaseNoOpt\freebl3.dll goto end
69copy ..\..\libraries\i686-win32\lib_release\freebl3.dll .\ReleaseNoOpt\ /y 90copy ..\..\libraries\i686-win32\lib_release\freebl3.dll .\ReleaseNoOpt\ /y
70copy ..\..\libraries\i686-win32\lib_release\gksvggdiplus.dll .\ReleaseNoOpt\ /y 91copy ..\..\libraries\i686-win32\lib_release\gksvggdiplus.dll .\ReleaseNoOpt\ /y
71copy ..\..\libraries\i686-win32\lib_release\js3250.dll .\ReleaseNoOpt\ /y 92copy ..\..\libraries\i686-win32\lib_release\js3250.dll .\ReleaseNoOpt\ /y
@@ -80,6 +101,18 @@ copy ..\..\libraries\i686-win32\lib_release\ssl3.dll .\ReleaseNoOpt\ /y
80copy ..\..\libraries\i686-win32\lib_release\xpcom.dll .\ReleaseNoOpt\ /y 101copy ..\..\libraries\i686-win32\lib_release\xpcom.dll .\ReleaseNoOpt\ /y
81copy ..\..\libraries\i686-win32\lib_release\xul.dll .\ReleaseNoOpt\ /y 102copy ..\..\libraries\i686-win32\lib_release\xul.dll .\ReleaseNoOpt\ /y
82 103
104rem --- runtime pieces for the bHear stuff.
105copy .\vivox-runtime\i686-win32\tntk.dll . /y
106copy .\vivox-runtime\i686-win32\libeay32.dll . /y
107copy .\vivox-runtime\i686-win32\SLVoice.exe . /y
108copy .\vivox-runtime\i686-win32\ssleay32.dll . /y
109copy .\vivox-runtime\i686-win32\SLVoiceAgent.exe . /y
110copy .\vivox-runtime\i686-win32\srtp.dll . /y
111copy .\vivox-runtime\i686-win32\alut.dll . /y
112copy .\vivox-runtime\i686-win32\vivoxsdk.dll . /y
113copy .\vivox-runtime\i686-win32\ortp.dll . /y
114copy .\vivox-runtime\i686-win32\wrap_oal.dll . /y
115
83@IF NOT EXIST ..\llkdu\ReleaseNoOpt\llkdu.dll ( 116@IF NOT EXIST ..\llkdu\ReleaseNoOpt\llkdu.dll (
84 copy ..\..\libraries\i686-win32\lib_release\llkdu.dll .\ReleaseNoOpt\ /y 117 copy ..\..\libraries\i686-win32\lib_release\llkdu.dll .\ReleaseNoOpt\ /y
85) ELSE ( 118) ELSE (
@@ -89,7 +122,6 @@ goto end
89 122
90:releasefordownload 123:releasefordownload
91echo copying releasefordownload files 124echo copying releasefordownload files
92if exist .\ReleaseForDownload\freebl3.dll goto end
93copy ..\..\libraries\i686-win32\lib_release\freebl3.dll .\ReleaseForDownload\ /y 125copy ..\..\libraries\i686-win32\lib_release\freebl3.dll .\ReleaseForDownload\ /y
94copy ..\..\libraries\i686-win32\lib_release\gksvggdiplus.dll .\ReleaseForDownload\ /y 126copy ..\..\libraries\i686-win32\lib_release\gksvggdiplus.dll .\ReleaseForDownload\ /y
95copy ..\..\libraries\i686-win32\lib_release\js3250.dll .\ReleaseForDownload\ /y 127copy ..\..\libraries\i686-win32\lib_release\js3250.dll .\ReleaseForDownload\ /y
@@ -103,6 +135,18 @@ copy ..\..\libraries\i686-win32\lib_release\softokn3.dll .\ReleaseForDownload\
103copy ..\..\libraries\i686-win32\lib_release\ssl3.dll .\ReleaseForDownload\ /y 135copy ..\..\libraries\i686-win32\lib_release\ssl3.dll .\ReleaseForDownload\ /y
104copy ..\..\libraries\i686-win32\lib_release\xpcom.dll .\ReleaseForDownload\ /y 136copy ..\..\libraries\i686-win32\lib_release\xpcom.dll .\ReleaseForDownload\ /y
105copy ..\..\libraries\i686-win32\lib_release\xul.dll .\ReleaseForDownload\ /y 137copy ..\..\libraries\i686-win32\lib_release\xul.dll .\ReleaseForDownload\ /y
138rem --- runtime pieces for the bHear stuff.
139copy .\vivox-runtime\i686-win32\tntk.dll .\ /y
140copy .\vivox-runtime\i686-win32\libeay32.dll .\ /y
141copy .\vivox-runtime\i686-win32\SLVoice.exe .\ /y
142copy .\vivox-runtime\i686-win32\ssleay32.dll .\ /y
143copy .\vivox-runtime\i686-win32\SLVoiceAgent.exe .\ /y
144copy .\vivox-runtime\i686-win32\srtp.dll .\ /y
145copy .\vivox-runtime\i686-win32\alut.dll .\ /y
146copy .\vivox-runtime\i686-win32\vivoxsdk.dll .\ /y
147copy .\vivox-runtime\i686-win32\ortp.dll .\ /y
148copy .\vivox-runtime\i686-win32\wrap_oal.dll .\ /y
149
106@IF NOT EXIST ..\llkdu\Release\llkdu.dll ( 150@IF NOT EXIST ..\llkdu\Release\llkdu.dll (
107 copy ..\..\libraries\i686-win32\lib_release\llkdu.dll .\ReleaseForDownload\ /y 151 copy ..\..\libraries\i686-win32\lib_release\llkdu.dll .\ReleaseForDownload\ /y
108) ELSE ( 152) ELSE (
diff --git a/linden/indra/newview/releasenotes.txt b/linden/indra/newview/releasenotes.txt
index 34b68c6..a1454be 100644
--- a/linden/indra/newview/releasenotes.txt
+++ b/linden/indra/newview/releasenotes.txt
@@ -1,3 +1,80 @@
1Release Notes for Second Life 1.18.1(2) August 2, 2007
2=====================================
3
4New Features:
5* In-World Voice Chat
6** In-world Voice Chat is now part of the main viewer.
7** You can see and manage all voice settings in Edit > Preferences > Voice Chat.
8** Voice is off by default. To enable (and disable) voice, visit Edit > Preferences > Voice Chat and check/uncheck the box beside "Enable voice chat".
9** A voice set-up wizard appears during first voice use to help residents set up voice and adjust their mic volume and tuning. You should run the voice set-up wizard even if you only want the ability to hear others and do not wish to speak.
10** Push-to-Talk is part of the Voice feature. Push-to-Talk is ON by default, which means Resident mics are OFF by default.
11** Speech gestures for voice are included in the Library, in Gestures > Speech Gestures. These gestures need to be activated in order to work; they are off by default.
12* Streaming video support for Linux client.
13
14Changes:
15* Shortcut keys for menu items in the Client & Server menus are now disabled if the menus are hidden.
16* Text from objects can be muted.
17
18Bug fixes:
19* VWR-1797: Remove mention of "Live Help" from Crash Logger
20* VWR-1732: Pressing Enter, with multiple inventory objects selected, crashes viewer
21* VWR-1729: indra/lscript/lscript_compile/indra.l: avoid yyunput hack on Windows build
22* VWR-1723: Possible crash in llvopartgroup
23* VWR-1706: Minor quirk (and cleanup) in llfloater.cpp
24* VWR-1705: indra/lscript/lscript_compile/indra.y: disable compiler warning #4065 for 'switch' statements
25* VWR-1704: indra/llui/files.lst: delete llhtmlhelp.h entry
26* VWR-1698: Clean up parcel flag manipulation
27* VWR-1655: Script Warnings/errors window is hard to resize, resets size after closing tabs.
28* VWR-1646: Possible crash when login server is unavailable.
29* VWR-1626: Patch to avoid IM window from resizing when sessions open or close
30* VWR-1613: Overuse of virtual
31* VWR-1612: LLRenderPass::Pushbatch and LLViewerImage::addTextureStats tuning
32* VWR-1586: Mismatched delete in llviewerparcelmgr.cpp
33* VWR-1578: Two quirks in IM regarding "xxxx is typing"
34* VWR-1471: Inspect (Pie menu > More > More > Inspect) shows nothing on first use when "only select own objects" is enabled
35* VWR-1470: Buttons (IM, Teleport, Profile, ...) in friends list are disabled when opening friends list window
36* VWR-1468: LoginPacketNeverReceived dialog text is incorrect
37* VWR-1462: Order of right-click menu on Inventory is confusing
38* VWR-1453: A few old-school changes for llviewerregion.cpp
39* VWR-1434: Null pointer crash when terraforming
40* VWR-1406: Unchecking "Go Away/AFK when idle" has no effect in 1.17.2.0
41* VWR-1382: Some scripted objects are highlighted in red while pressing Alt with tools open
42* VWR-1381: libpng12.a for MacOS X is missing in 1.17.1.0 and build fails.
43* VWR-1358: Physical objects remain red if tools window is closed while holding Alt key
44* VWR-1358: Physical objects remain red if tools window is closed while holding Alt key
45* VWR-1353: Misleading variable names in LLTextEditor
46* VWR-1344: Reverse order of popups, so that new ones appear underneath existing ones rather than on top.
47* VWR-1318: Selecting Cancel while saving a snapshot to disk still triggers snapshot gesture
48* VWR-1314: Multiple selection then individual deselection of attachments broken
49* VWR-1294: Possibly threads not fully cleaned up at end of program
50* VWR-1289: On logging in, sound volume for stream is low, despite the actual setting in the music control
51* VWR-1282: Better error handling when fonts are missing
52* VWR-1270: Script error window keeps reverting to a very small size
53* VWR-1246: Mac: File menu > Snapshot to Disk lists wrong shortcut key
54* VWR-1105: Set internal limit of particle count to max value from GUI preferences.
55* VWR-1092: Disable mouse hover text on HUDs, since it always only shows the owner's name and generally gets in the way of HUD functionality.
56* VWR-727: Torn of IM windows should be minimizable (was re: VWR-233: ... resizeable and minimizable)
57* VWR-447: Allow minimized windows to be repositioned in client
58* VWR-353: Rebake command - add a keyboard shortcut and put in tools menu
59* VWR-349: Change keyboard shortcuts, because entering { [ ] } on German and some other international keyboards (AltGr 7, 8, 9, 0) triggers Rendering Features accelerators Ctrl-Alt-7, 8, 9, 0 (previously resulting in unstable viewer)
60* VWR-238: Permissions of Roles and Rights in the german version are mased up.
61* VWR-102: md5 slow
62* SVC-371: Fix the legibility and grammar/consistency of the new llOwnerSay implementation
63* SVC-193: llParticleSystem - halo of rogue particles around original particle system after 1.15 update* SVC-373: Deleting a script's code results in a non-existent file and "missing from database" error
64* Fixed preference for showing or hiding server combo box was not preserved
65* Fixed residents with negative L$ balance can't purchase items set for sale "Original" or "Copy" that are being sold for L$0
66* "Copy SLURL to clipboard" is now enabled for an avatar's current coordinates
67* Macintosh viewer now correctly opens the map and selects the destination on a SLURL request
68* Leading and trailing spaces are now automatically trimmed from parcel media URLs
69* Corrected the spacing of the yellow "next dialog" chevron (was partially blocked by the Mute button)
70* Corrected the error message shown when adding 11th Estate Manager
71* Added CPU detection for Intel Core Duo/Solo and Intel Core 2 Duo
72* "Set Window Size..." setting is now correctly resumed after being minimized
73* Added link to Qa wiki in the viewer bug reporter menu.
74* Updated text in Second Life Crash Logger with new support portal information
75* Corrected an issue with UI font scaling in the bug reporter window
76
77
1Release Notes for Second Life 1.18.0(6) July 11, 2007 78Release Notes for Second Life 1.18.0(6) July 11, 2007
2===================================== 79=====================================
3Changes: 80Changes:
@@ -43,9 +120,6 @@ Release Notes for Second Life 1.17.2(0) June 27, 2007
43Bug fixes: 120Bug fixes:
44* VWR-1369: Creating, re-rezzing, then editing an object results in a viewer crash 121* VWR-1369: Creating, re-rezzing, then editing an object results in a viewer crash
45 122
46Not for public:
47* SL-46373 VWR-1369: Creating, re-rezzing, then editing an object results in a viewer crash
48
49 123
50Release Notes for Second Life 1.17.1(0) June 25, 2007 124Release Notes for Second Life 1.17.1(0) June 25, 2007
51===================================== 125=====================================
diff --git a/linden/indra/newview/res/newViewRes.rc b/linden/indra/newview/res/newViewRes.rc
index b1992cf..9a86533 100644
--- a/linden/indra/newview/res/newViewRes.rc
+++ b/linden/indra/newview/res/newViewRes.rc
@@ -227,8 +227,8 @@ TOOLPIPETTE CURSOR "toolpipette.cur"
227// 227//
228 228
229VS_VERSION_INFO VERSIONINFO 229VS_VERSION_INFO VERSIONINFO
230 FILEVERSION 1,18,0,6 230 FILEVERSION 1,18,1,2
231 PRODUCTVERSION 1,18,0,6 231 PRODUCTVERSION 1,18,1,2
232 FILEFLAGSMASK 0x3fL 232 FILEFLAGSMASK 0x3fL
233#ifdef _DEBUG 233#ifdef _DEBUG
234 FILEFLAGS 0x1L 234 FILEFLAGS 0x1L
@@ -245,12 +245,12 @@ BEGIN
245 BEGIN 245 BEGIN
246 VALUE "CompanyName", "Linden Lab" 246 VALUE "CompanyName", "Linden Lab"
247 VALUE "FileDescription", "Second Life" 247 VALUE "FileDescription", "Second Life"
248 VALUE "FileVersion", "1.18.0.6" 248 VALUE "FileVersion", "1.18.1.2"
249 VALUE "InternalName", "Second Life" 249 VALUE "InternalName", "Second Life"
250 VALUE "LegalCopyright", "Copyright © 2001-2007, Linden Research, Inc." 250 VALUE "LegalCopyright", "Copyright © 2001-2007, Linden Research, Inc."
251 VALUE "OriginalFilename", "SecondLife.exe" 251 VALUE "OriginalFilename", "SecondLife.exe"
252 VALUE "ProductName", "Second Life" 252 VALUE "ProductName", "Second Life"
253 VALUE "ProductVersion", "1.18.0.6" 253 VALUE "ProductVersion", "1.18.1.2"
254 END 254 END
255 END 255 END
256 BLOCK "VarFileInfo" 256 BLOCK "VarFileInfo"
diff --git a/linden/indra/newview/secondlife setup build voicebeta.bat b/linden/indra/newview/secondlife setup build voicebeta.bat
new file mode 100644
index 0000000..293cf82
--- /dev/null
+++ b/linden/indra/newview/secondlife setup build voicebeta.bat
@@ -0,0 +1,4 @@
1@rem Invoke the script which preps then runs the installer.
2@rem This batch file is customized per grid.
3
4@"secondlife setup build.bat" --grid=aditi --channel="Second Life Voice Beta"
diff --git a/linden/indra/newview/secondlife setup build firstlook.bat b/linden/indra/newview/secondlife setup build voicefirstlook.bat
index 73e47ec..ebb74ea 100644
--- a/linden/indra/newview/secondlife setup build firstlook.bat
+++ b/linden/indra/newview/secondlife setup build voicefirstlook.bat
@@ -1,4 +1,4 @@
1@rem Invoke the script which preps then runs the installer. 1@rem Invoke the script which preps then runs the installer.
2@rem This batch file is customized per grid. 2@rem This batch file is customized per grid.
3 3
4@"secondlife setup build.bat" --grid=firstlook 4@"secondlife setup build.bat" --channel="Second Life Voice First Look"
diff --git a/linden/indra/newview/skins/textures/textures.xml b/linden/indra/newview/skins/textures/textures.xml
index 79e910a..1c02ce4 100644
--- a/linden/indra/newview/skins/textures/textures.xml
+++ b/linden/indra/newview/skins/textures/textures.xml
@@ -304,6 +304,7 @@
304 <account_id_orange.tga value="fbe89371-1251-4e77-d2d8-8eeccffe3ca8"/> 304 <account_id_orange.tga value="fbe89371-1251-4e77-d2d8-8eeccffe3ca8"/>
305 <account_id_green.tga value="3bf64d5a-38d3-b752-cf52-3d9f8fca353a"/> 305 <account_id_green.tga value="3bf64d5a-38d3-b752-cf52-3d9f8fca353a"/>
306 <status_push.tga value="07d1f523-e327-4d10-20d6-8bc22a6e8f56"/> 306 <status_push.tga value="07d1f523-e327-4d10-20d6-8bc22a6e8f56"/>
307 <status_voice.tga value="c49b0b3b-fe04-46ee-abab-777fa0b462b6"/>
307 <ff_visible_online.tga value="d609a41f-34c0-7aae-b2c6-2fc3ab26d916"/> 308 <ff_visible_online.tga value="d609a41f-34c0-7aae-b2c6-2fc3ab26d916"/>
308 <ff_visible_map.tga value="20b52706-c1ab-414a-9dea-1cb788ad5689"/> 309 <ff_visible_map.tga value="20b52706-c1ab-414a-9dea-1cb788ad5689"/>
309 <ff_edit_mine.tga value="1baee0b9-4b89-39eb-8815-866d82300ab5"/> 310 <ff_edit_mine.tga value="1baee0b9-4b89-39eb-8815-866d82300ab5"/>
@@ -314,6 +315,8 @@
314 <ff_edit_theirs_button.tga value="ca229f65-d7e0-133e-1bc2-674abc33f3d5"/> 315 <ff_edit_theirs_button.tga value="ca229f65-d7e0-133e-1bc2-674abc33f3d5"/>
315 <ff_edit_mine_button.tga value="57f05b46-63d8-c3d5-66d6-8b915746b956"/> 316 <ff_edit_mine_button.tga value="57f05b46-63d8-c3d5-66d6-8b915746b956"/>
316 <ff_online_status_button.tga value="3b1b6a53-9c8c-568a-22c5-2a8f3e5286f5"/> 317 <ff_online_status_button.tga value="3b1b6a53-9c8c-568a-22c5-2a8f3e5286f5"/>
318 <ptt_lock_on.tga value="e0c447a5-87dd-4778-bedb-0ccab01fe078"/>
319 <ptt_lock_off.tga value="1de17e87-b392-4a7d-80d1-852e1e518ff0"/>
317 <oi_hud_cen_0_0.tga value="3c650257-9caf-7cad-b26c-84c9eca560f1"/> 320 <oi_hud_cen_0_0.tga value="3c650257-9caf-7cad-b26c-84c9eca560f1"/>
318 <oi_hud_intro.tga value="7611fb3d-9ff2-abd3-d98f-805c1c87e757"/> 321 <oi_hud_intro.tga value="7611fb3d-9ff2-abd3-d98f-805c1c87e757"/>
319 <oi_hud_underwater.tga value="cde61aea-83c2-3001-d598-6b348f7a8e0b"/> 322 <oi_hud_underwater.tga value="cde61aea-83c2-3001-d598-6b348f7a8e0b"/>
@@ -391,5 +394,22 @@
391 <oi_hud_mov_3_0.tga value="f5ff1f08-4c92-8606-1854-cc5b9d3e445c"/> 394 <oi_hud_mov_3_0.tga value="f5ff1f08-4c92-8606-1854-cc5b9d3e445c"/>
392 <oi_hud_mov_1_2.tga value="1e3abeed-e893-c44e-1f9d-5ecc76d21e5d"/> 395 <oi_hud_mov_1_2.tga value="1e3abeed-e893-c44e-1f9d-5ecc76d21e5d"/>
393 <oi_hud_mov_1_0.tga value="e300fc95-aa94-8e31-c501-ce903cac8b7c"/> 396 <oi_hud_mov_1_0.tga value="e300fc95-aa94-8e31-c501-ce903cac8b7c"/>
397 <circle.tga value="0498c309-5306-43cd-82a2-ae31d096cdef"/>
398 <mute_icon.tga value="37c8e000-6aa2-41ef-8f86-e0c2e60bfa42"/>
399 <active_speakers.tga value="c97bdfb5-b0da-4741-877c-7c1553957d30"/>
400 <active_voice_tab.tga value="33281629-74b3-4b0e-98e7-a6383eb277fa"/>
401 <music_icon.tga value="9de3ef3d-ab90-4963-be15-ae77a122a484"/>
402 <media_icon.tga value="9724ad2b-b0ec-4b8c-9558-73f36661db26"/>
403 <volume_icon.tga value="eb510e2b-3815-4434-b502-b18712db65cc"/>
404 <icn_active-speakers-dot-lvl0.tga value="73577b7b-19c3-4050-a19d-36bc2408aa79"/>
405 <icn_active-speakers-dot-lvl1.tga value="8f761ce3-5939-4d3a-8991-00064fdfacf9"/>
406 <icn_active-speakers-dot-lvl2.tga value="0e82d24e-ed45-41bc-b090-94c97c1caab2"/>
407 <icn_active-speakers-typing1.tga value="f9bbb2fe-584b-4c01-86fc-599c69534c1b"/>
408 <icn_active-speakers-typing2.tga value="e3369e02-93e1-43dc-b9c0-4533db0963d0"/>
409 <icn_active-speakers-typing3.tga value="13dd1d96-6836-461e-8a4c-36003065c59b"/>
410 <icn_voice_ptt-off.tga value="ce19b99f-bd2d-4324-88ab-975c357f9e4e"/>
411 <icn_voice_ptt-on.tga value="67f672e1-576f-42ee-973f-c796cc8eefb1"/>
412 <icn_voice_ptt-on-lvl1.tga value="24ebff50-ced7-4d52-8b74-77a5a901e701"/>
413 <icn_voice_ptt-on-lvl2.tga value="1a803501-0da7-4b80-80db-1f79a7842368"/>
414 <icn_voice_ptt-on-lvl3.tga value="3342bfc4-0bd9-4c89-8e87-e5980aee00e5"/>
394</textures> 415</textures>
395
diff --git a/linden/indra/newview/skins/xui/de/role_actions.xml b/linden/indra/newview/skins/xui/de/role_actions.xml
index d907591..4265342 100644
--- a/linden/indra/newview/skins/xui/de/role_actions.xml
+++ b/linden/indra/newview/skins/xui/de/role_actions.xml
@@ -5,39 +5,39 @@
5 name="Membership"> 5 name="Membership">
6 <action description="Personen zu dieser Gruppe einladen" 6 <action description="Personen zu dieser Gruppe einladen"
7 longdescription="Laden Sie Personen zu dieser Gruppe ein. Dazu verwenden Sie die Schaltfläche &apos;Neue Person einladen...&apos; auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Mitglieder&apos;." 7 longdescription="Laden Sie Personen zu dieser Gruppe ein. Dazu verwenden Sie die Schaltfläche &apos;Neue Person einladen...&apos; auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Mitglieder&apos;."
8 name="member invite" /> 8 name="member invite" value="1" />
9 <action description="Mitglieder aus dieser Gruppe ausschließen" 9 <action description="Mitglieder aus dieser Gruppe ausschließen"
10 longdescription="Schließen Sie Mitglieder mit Hilfe der Schaltfläche &apos;Aus Gruppe ausschließen&apos; auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Mitglieder&apos; aus dieser Gruppe aus. Ein Eigentümer kann alle anderen Benutzer außer einem anderen Eigentümer ausschließen. Sind Sie kein Eigentümer, kann ein Mitglied nur aus einer Gruppe ausgeschlossen werden, wenn es die Rolle &apos;Alle&apos; hat, aber KEINE anderen Rollen. Um Mitglieder aus Rollen zu entfernen, müssen Sie die Fähigkeit &apos;Mitglieder aus Rollen entfernen&apos; aufweisen." 10 longdescription="Schließen Sie Mitglieder mit Hilfe der Schaltfläche &apos;Aus Gruppe ausschließen&apos; auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Mitglieder&apos; aus dieser Gruppe aus. Ein Eigentümer kann alle anderen Benutzer außer einem anderen Eigentümer ausschließen. Sind Sie kein Eigentümer, kann ein Mitglied nur aus einer Gruppe ausgeschlossen werden, wenn es die Rolle &apos;Alle&apos; hat, aber KEINE anderen Rollen. Um Mitglieder aus Rollen zu entfernen, müssen Sie die Fähigkeit &apos;Mitglieder aus Rollen entfernen&apos; aufweisen."
11 name="member eject" /> 11 name="member eject" value="2" />
12 <action 12 <action
13 description="&apos;Offene Teilnahme&apos; ein- und ausschalten und &apos;Registrierungsgebühr&apos; ändern&apos;" 13 description="&apos;Offene Teilnahme&apos; ein- und ausschalten und &apos;Registrierungsgebühr&apos; ändern&apos;"
14 longdescription="Aktivieren Sie &apos;Registrierung offen&apos;, um neue Mitglieder ohne Einladung beitreten zu lassen, und ändern Sie &apos;Registrierungsgebühr&apos; im Abschnitt &apos;Gruppeneinstellungen&apos; der Registerkarte &apos;Allgemein&apos;." 14 longdescription="Aktivieren Sie &apos;Registrierung offen&apos;, um neue Mitglieder ohne Einladung beitreten zu lassen, und ändern Sie &apos;Registrierungsgebühr&apos; im Abschnitt &apos;Gruppeneinstellungen&apos; der Registerkarte &apos;Allgemein&apos;."
15 name="member options" /> 15 name="member options" value="3" />
16 </action_set> 16 </action_set>
17 <action_set 17 <action_set
18 description="Diese Fähigkeiten umfassen die Möglichkeit, Gruppenrollen hinzuzufügen, zu entfernen und zu ändern, Mitglieder in Rollen hinzuzufügen und zu entfernen und Rollen Fähigkeiten zuzuweisen." 18 description="Diese Fähigkeiten umfassen die Möglichkeit, Gruppenrollen hinzuzufügen, zu entfernen und zu ändern, Mitglieder in Rollen hinzuzufügen und zu entfernen und Rollen Fähigkeiten zuzuweisen."
19 name="Roles"> 19 name="Roles">
20 <action description="Neue Rollen erstellen" 20 <action description="Neue Rollen erstellen"
21 longdescription="Erstellen Sie neue Rollen auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Rollen&apos;." 21 longdescription="Erstellen Sie neue Rollen auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Rollen&apos;."
22 name="role create" /> 22 name="role create" value="4" />
23 <action description="Rollen löschen" 23 <action description="Rollen löschen"
24 longdescription="Löschen Sie Rollen auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Rollen&apos;." 24 longdescription="Löschen Sie Rollen auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Rollen&apos;."
25 name="role delete" /> 25 name="role delete" value="5" />
26 <action description="Rollennamen, Titel und Beschreibungen ändern" 26 <action description="Rollennamen, Titel und Beschreibungen ändern"
27 longdescription="Ändern Sie Rollennamen, Titel und Beschreibungen unten auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Rollen&apos;, nachdem Sie eine Rolle ausgewählt haben." 27 longdescription="Ändern Sie Rollennamen, Titel und Beschreibungen unten auf der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregister &apos;Rollen&apos;, nachdem Sie eine Rolle ausgewählt haben."
28 name="role properties" /> 28 name="role properties" value="6" />
29 <action description="Mitglieder Rollen des Zuweisenden zuweisen" 29 <action description="Mitglieder Rollen des Zuweisenden zuweisen"
30 longdescription="Weisen Sie Mitglieder im Abschnitt &apos;Zugewiesene Rollen&apos; der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregisterkarte &apos;Mitglieder&apos; Rollen zu. Ein Mitglied mit dieser Fähigkeit kann nur Mitglieder einer Rolle zuweisen, in der sich der Zuweisende bereits befindet." 30 longdescription="Weisen Sie Mitglieder im Abschnitt &apos;Zugewiesene Rollen&apos; der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregisterkarte &apos;Mitglieder&apos; Rollen zu. Ein Mitglied mit dieser Fähigkeit kann nur Mitglieder einer Rolle zuweisen, in der sich der Zuweisende bereits befindet."
31 name="role assign member limited" /> 31 name="role assign member limited" value="7" />
32 <action description="Mitglieder beliebiger Rolle zuweisen" 32 <action description="Mitglieder beliebiger Rolle zuweisen"
33 longdescription="Weisen Sie Mitglieder einer beliebigen Rolle im Abschnitt &apos;Zugewiesene Rollen&apos; der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregisterkarte &apos;Mitglieder&apos; zu. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und allen anderen Nichteigentümer-Mitgliedern Rollen zuweisen, die mehr Fähigkeiten haben, als sie selbst derzeit haben, so dass sie sich potenziell Eigentümer-gleiche Kräfte verleihen. Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen." 33 longdescription="Weisen Sie Mitglieder einer beliebigen Rolle im Abschnitt &apos;Zugewiesene Rollen&apos; der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregisterkarte &apos;Mitglieder&apos; zu. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und allen anderen Nichteigentümer-Mitgliedern Rollen zuweisen, die mehr Fähigkeiten haben, als sie selbst derzeit haben, so dass sie sich potenziell Eigentümer-gleiche Kräfte verleihen. Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen."
34 name="role assign member" /> 34 name="role assign member" value="8" />
35 <action description="Mitglieder aus Rollen entfernen" 35 <action description="Mitglieder aus Rollen entfernen"
36 longdescription="Entfernen Sie Mitglieder im Abschnitt &apos;Zugewiesene Rollen&apos; der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregisterkarte &apos;Mitglieder&apos; aus Rollen. Eigentümer können nicht entfernt werden." 36 longdescription="Entfernen Sie Mitglieder im Abschnitt &apos;Zugewiesene Rollen&apos; der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregisterkarte &apos;Mitglieder&apos; aus Rollen. Eigentümer können nicht entfernt werden."
37 name="role remove member" /> 37 name="role remove member" value="9" />
38 <action description="Fähigkeiten in Rollen zuweisen und entfernen" 38 <action description="Fähigkeiten in Rollen zuweisen und entfernen"
39 longdescription="Weisen Sie im Abschnitt &apos;Zugewiesene Rollen&apos; der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregisterkarte &apos;Rollen&apos; Rollen bestimmte Fähigkeiten zu bzw. entfernen Sie diese. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und allen anderen Nichteigentümer-Mitgliedern alle Fähigkeiten zuweisen, so dass sie sich potenziell Eigentümer-gleiche Kräfte verleihen. Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen." 39 longdescription="Weisen Sie im Abschnitt &apos;Zugewiesene Rollen&apos; der Registerkarte &apos;Mitglieder und Rollen&apos; &gt; Unterregisterkarte &apos;Rollen&apos; Rollen bestimmte Fähigkeiten zu bzw. entfernen Sie diese. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und allen anderen Nichteigentümer-Mitgliedern alle Fähigkeiten zuweisen, so dass sie sich potenziell Eigentümer-gleiche Kräfte verleihen. Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen."
40 name="role change actions" /> 40 name="role change actions" value="10" />
41 </action_set> 41 </action_set>
42 <action_set 42 <action_set
43 description="Diese Fähigkeiten umfassen die Möglichkeit, die Identität dieser Gruppe zu modifizieren, z. B. die öffentliche Visibilität, Charta und Insignien zu ändern." 43 description="Diese Fähigkeiten umfassen die Möglichkeit, die Identität dieser Gruppe zu modifizieren, z. B. die öffentliche Visibilität, Charta und Insignien zu ändern."
@@ -52,16 +52,16 @@
52 name="Parcel Management"> 52 name="Parcel Management">
53 <action description="Land übertragen und für Gruppe kaufen" 53 <action description="Land übertragen und für Gruppe kaufen"
54 longdescription="Land übertragen und für Gruppe kaufen. Dies erfolgt in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Allgemein&apos;." 54 longdescription="Land übertragen und für Gruppe kaufen. Dies erfolgt in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Allgemein&apos;."
55 name="land deed" /> 55 name="land deed" value="12" />
56 <action description="Land an Gouverneur Linden aufgeben" 56 <action description="Land an Gouverneur Linden aufgeben"
57 longdescription="Land an Gouverneur Linden aufgeben. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann Land in Gruppenbesitz auf der Registerkarte &apos;Info zu Land&apos; &gt; &apos;Allgemein&apos; aufgeben und es in Linden-Eigentum zurückführen, ohne es zu verkaufen! Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen." 57 longdescription="Land an Gouverneur Linden aufgeben. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann Land in Gruppenbesitz auf der Registerkarte &apos;Info zu Land&apos; &gt; &apos;Allgemein&apos; aufgeben und es in Linden-Eigentum zurückführen, ohne es zu verkaufen! Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen."
58 name="land release" /> 58 name="land release" value="13" />
59 <action description="Land zu verkaufen-Info einstellen" 59 <action description="Land zu verkaufen-Info einstellen"
60 longdescription="Land zu verkaufen-Info einstellen. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann Land in Gruppenbesitz auf der Registerkarte &apos;Info zu Land&apos; &gt; &apos;Allgemein&apos; nach Wunsch verkaufen! Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen." 60 longdescription="Land zu verkaufen-Info einstellen. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann Land in Gruppenbesitz auf der Registerkarte &apos;Info zu Land&apos; &gt; &apos;Allgemein&apos; nach Wunsch verkaufen! Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen."
61 name="land set sale info" /> 61 name="land set sale info" value="14" />
62 <action description="Parzellen unterteilen und zusammenfügen" 62 <action description="Parzellen unterteilen und zusammenfügen"
63 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. " 63 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. "
64 name="land divide join" /> 64 name="land divide join" value="15" />
65 </action_set> 65 </action_set>
66 <action_set 66 <action_set
67 description="Diese Fähigkeiten umfassen die Möglichkeit, Parzellennamen, Veröffentlichungseinstellungen, Suchverzeichnis-Visibilität sowie Landepunkt und Teleport Routing-Optionen zu ändern." 67 description="Diese Fähigkeiten umfassen die Möglichkeit, Parzellennamen, Veröffentlichungseinstellungen, Suchverzeichnis-Visibilität sowie Landepunkt und Teleport Routing-Optionen zu ändern."
@@ -69,119 +69,119 @@
69 <action 69 <action
70 description="&apos;In „Orte suchen“ anzeigen&apos; ein- und ausschalten Kategorie festlegen" 70 description="&apos;In „Orte suchen“ anzeigen&apos; ein- und ausschalten Kategorie festlegen"
71 longdescription="Aktivieren Sie &apos;In &quot;Orte suchen&apos; anzeigen&apos; und stellen Sie eine Parzellenkategorie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; ein." 71 longdescription="Aktivieren Sie &apos;In &quot;Orte suchen&apos; anzeigen&apos; und stellen Sie eine Parzellenkategorie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; ein."
72 name="land find places" /> 72 name="land find places" value="17" />
73 <action 73 <action
74 description="Parzellenname, Beschreibung und Einstellungen für &apos;Im Web veröffentlichen&apos; ändern" 74 description="Parzellenname, Beschreibung und Einstellungen für &apos;Im Web veröffentlichen&apos; ändern"
75 longdescription="Parzellenname, Beschreibung und Einstellungen für &apos;Im Web veröffentlichen&apos; ändern. Dies erfolgt in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos;." 75 longdescription="Parzellenname, Beschreibung und Einstellungen für &apos;Im Web veröffentlichen&apos; ändern. Dies erfolgt in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos;."
76 name="land change identity" /> 76 name="land change identity" value="18" />
77 <action description="Landepunkt und Teleport Routing einstellen" 77 <action description="Landepunkt und Teleport Routing einstellen"
78 longdescription="Auf einer Parzelle in Gruppenbesitz können Mitglieder in einer Rolle mit dieser Fähigkeit einen Landepunkt festlegen, um anzugeben, wo ankommende Teleports eintreffen. Sie können auch die Teleport-Route festlegen, um noch mehr Kontrolle zu haben. Dies erfolgt in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos;." 78 longdescription="Auf einer Parzelle in Gruppenbesitz können Mitglieder in einer Rolle mit dieser Fähigkeit einen Landepunkt festlegen, um anzugeben, wo ankommende Teleports eintreffen. Sie können auch die Teleport-Route festlegen, um noch mehr Kontrolle zu haben. Dies erfolgt in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos;."
79 name="land set landing point" /> 79 name="land set landing point" value="19" />
80 </action_set> 80 </action_set>
81 <action_set 81 <action_set
82 description="Diese Fähigkeiten umfassen Möglichkeiten, die sich auf Parzellenoptionen auswirken, z. B. &apos;Objekte erstellen&apos;, &apos;Terrain bearbeiten&apos; sowie Musik- und Medieneinstellungen." 82 description="Diese Fähigkeiten umfassen Möglichkeiten, die sich auf Parzellenoptionen auswirken, z. B. &apos;Objekte erstellen&apos;, &apos;Terrain bearbeiten&apos; sowie Musik- und Medieneinstellungen."
83 name="Parcel Settings"> 83 name="Parcel Settings">
84 <action description="Musik- und Medieneinstellungen ändern" 84 <action description="Musik- und Medieneinstellungen ändern"
85 longdescription="Einstellungen für Streaming-Musik und Movies ändern in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Medien&apos;." 85 longdescription="Einstellungen für Streaming-Musik und Movies ändern in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Medien&apos;."
86 name="land change media" /> 86 name="land change media" value="20" />
87 <action description="&apos;Terrain bearbeiten&apos; ein- und ausschalten" 87 <action description="&apos;Terrain bearbeiten&apos; ein- und ausschalten"
88 longdescription="&apos;Terrain bearbeiten&apos; ein- und ausschalten. *WARNUNG* &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; &gt; &apos;Terrain bearbeiten&apos; ermöglicht allen Benutzern, Ihr Land terrazuformen und Linden-Pflanzen zu setzen und zu bewegen. Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen. Die Terrain-Bearbeitung wird in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; ein- und ausgeschaltet." 88 longdescription="&apos;Terrain bearbeiten&apos; ein- und ausschalten. *WARNUNG* &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; &gt; &apos;Terrain bearbeiten&apos; ermöglicht allen Benutzern, Ihr Land terrazuformen und Linden-Pflanzen zu setzen und zu bewegen. Sie müssen sich dessen bewusst sein, bevor Sie diese Fähigkeit zuweisen. Die Terrain-Bearbeitung wird in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; ein- und ausgeschaltet."
89 name="land edit" /> 89 name="land edit" value="21" />
90 <action 90 <action
91 description="Verschiedene Einstellungen für Info zu Land &gt; Optionen ein- und ausschalten" 91 description="Verschiedene Einstellungen für Info zu Land &gt; Optionen ein- und ausschalten"
92 longdescription="Aktivieren Sie &apos;Sicher (kein Schaden)&apos;, &apos;Fliegen&apos; und gestatten Sie Einwohnern folgendes: &apos;Objekte erstellen&apos;, &apos;Terrain bearbeiten&apos;, &apos;Landmarken erstellen&apos; und &apos;Scripts ausführen&apos; auf Land in Gruppenbesitz in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos;." 92 longdescription="Aktivieren Sie &apos;Sicher (kein Schaden)&apos;, &apos;Fliegen&apos; und gestatten Sie Einwohnern folgendes: &apos;Objekte erstellen&apos;, &apos;Terrain bearbeiten&apos;, &apos;Landmarken erstellen&apos; und &apos;Scripts ausführen&apos; auf Land in Gruppenbesitz in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos;."
93 name="land options" /> 93 name="land options" value="22" />
94 </action_set> 94 </action_set>
95 <action_set 95 <action_set
96 description="Diese Fähigkeiten umfassen Möglichkeiten, die Mitgliedern gestatten, Beschränkungen von Parzellen in Gruppenbesitz zu umgehen." 96 description="Diese Fähigkeiten umfassen Möglichkeiten, die Mitgliedern gestatten, Beschränkungen von Parzellen in Gruppenbesitz zu umgehen."
97 name="Parcel Powers"> 97 name="Parcel Powers">
98 <action description="&apos;Terrain bearbeiten&apos; immer zulassen" 98 <action description="&apos;Terrain bearbeiten&apos; immer zulassen"
99 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Terrain auf einer Parzelle in Gruppenbesitz bearbeiten, selbst wenn sie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; deaktiviert ist." 99 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Terrain auf einer Parzelle in Gruppenbesitz bearbeiten, selbst wenn sie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; deaktiviert ist."
100 name="land allow edit land" /> 100 name="land allow edit land" value="23" />
101 <action description="&apos;Fliegen&apos; immer zulassen" 101 <action description="&apos;Fliegen&apos; immer zulassen"
102 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können auf einer Parzelle in Gruppenbesitz fliegen, selbst wenn sie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; deaktiviert ist." 102 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können auf einer Parzelle in Gruppenbesitz fliegen, selbst wenn sie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; deaktiviert ist."
103 name="land allow fly" /> 103 name="land allow fly" value="24" />
104 <action description="&apos;Objekte erstellen&apos; immer zulassen" 104 <action description="&apos;Objekte erstellen&apos; immer zulassen"
105 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Objekte auf einer Parzelle in Gruppenbesitz erstellen, selbst wenn sie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; deaktiviert ist." 105 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Objekte auf einer Parzelle in Gruppenbesitz erstellen, selbst wenn sie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; deaktiviert ist."
106 name="land allow create" /> 106 name="land allow create" value="25" />
107 <action description="Landmarke setzen&apos; immer zulassen" 107 <action description="Landmarke setzen&apos; immer zulassen"
108 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können eine Parzelle in Gruppenbesitz als landmarken verwenden, selbst wenn sie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; deaktiviert ist." 108 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können eine Parzelle in Gruppenbesitz als landmarken verwenden, selbst wenn sie in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Optionen&apos; deaktiviert ist."
109 name="land allow landmark" /> 109 name="land allow landmark" value="26" />
110 <action description="&apos;Zuhause auf hier einstellen&apos; auf Gruppenland zulassen" 110 <action description="&apos;Zuhause auf hier einstellen&apos; auf Gruppenland zulassen"
111 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können das Menü &apos;Welt&apos; &gt; &apos;Hier als Zuhause wählen&apos; auf einer Gruppenparzelle verwenden (Land, das für diese Gruppe eingestellt ist oder ihr übertragen wurde)." 111 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können das Menü &apos;Welt&apos; &gt; &apos;Hier als Zuhause wählen&apos; auf einer Gruppenparzelle verwenden (Land, das für diese Gruppe eingestellt ist oder ihr übertragen wurde)."
112 name="land allow set home" /> 112 name="land allow set home" value="28" />
113 </action_set> 113 </action_set>
114 <action_set 114 <action_set
115 description="Diese Fähigkeiten umfassen die Möglichkeit, den Zugriff auf Parzellen in Gruppenbesitz zuzulassen oder zu beschränken, einschließlich Einfrieren und Ausschließen von Einwohnern." 115 description="Diese Fähigkeiten umfassen die Möglichkeit, den Zugriff auf Parzellen in Gruppenbesitz zuzulassen oder zu beschränken, einschließlich Einfrieren und Ausschließen von Einwohnern."
116 name="Parcel Access"> 116 name="Parcel Access">
117 <action description="Parzellenzugangslisten verwalten" 117 <action description="Parzellenzugangslisten verwalten"
118 longdescription="Die Parzellenzugriffslisten werden unter &apos;Info zu Land&apos; &gt; Registerkarte &apos;Zugriff&apos; verwaltet." 118 longdescription="Die Parzellenzugriffslisten werden unter &apos;Info zu Land&apos; &gt; Registerkarte &apos;Zugriff&apos; verwaltet."
119 name="land manage allowed" /> 119 name="land manage allowed" value="29" />
120 <action description="Parzellenverbannungslisten verwalten" 120 <action description="Parzellenverbannungslisten verwalten"
121 longdescription="Die Parzellenverbannungslisten werden unter &apos;Info zu Land&apos; &gt; Registerkarte &apos;Verbannen&apos; verwaltet." 121 longdescription="Die Parzellenverbannungslisten werden unter &apos;Info zu Land&apos; &gt; Registerkarte &apos;Verbannen&apos; verwaltet."
122 name="land manage banned" /> 122 name="land manage banned" value="30" />
123 <action description="Einstellungen &apos;Pässe, die...&apos; der Parzelle ändern" 123 <action description="Einstellungen &apos;Pässe, die...&apos; der Parzelle ändern"
124 longdescription="Einstellungen &apos;Pässe, die...&apos; der Parzelle ändern in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Zugriff&apos;." 124 longdescription="Einstellungen &apos;Pässe, die...&apos; der Parzelle ändern in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Zugriff&apos;."
125 name="land manage passes" /> 125 name="land manage passes" value="31" />
126 <action description="Einwohner ausschließen und auf Parzellen einfrieren" 126 <action description="Einwohner ausschließen und auf Parzellen einfrieren"
127 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können mit einem nicht willkommenen Einwohner auf einer Parzelle in Gruppenbesitz durch Rechtsklicken auf den Einwohner, &apos;Mehr&apos; &gt; und Auswählen von &apos;Ausschließen...&apos; oder &apos;Einfrieren...&apos; umgehen." 127 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können mit einem nicht willkommenen Einwohner auf einer Parzelle in Gruppenbesitz durch Rechtsklicken auf den Einwohner, &apos;Mehr&apos; &gt; und Auswählen von &apos;Ausschließen...&apos; oder &apos;Einfrieren...&apos; umgehen."
128 name="land admin" /> 128 name="land admin" value="32" />
129 </action_set> 129 </action_set>
130 <action_set 130 <action_set
131 description="Diese Fähigkeiten umfassen die Möglichkeit, Mitgliedern zu gestatten, Objekte zurückzugeben und Linden-Pflanzen zu platzieren und zu verschieben. Dies ist für Mitglieder nützlich, um Abfall zu entfernen und Gartenarbeiten zu verrichten, sollte aber vorsichtig eingesetzt werden, weil das Zurückgeben von Objekten nicht rückgängig gemacht werden kann." 131 description="Diese Fähigkeiten umfassen die Möglichkeit, Mitgliedern zu gestatten, Objekte zurückzugeben und Linden-Pflanzen zu platzieren und zu verschieben. Dies ist für Mitglieder nützlich, um Abfall zu entfernen und Gartenarbeiten zu verrichten, sollte aber vorsichtig eingesetzt werden, weil das Zurückgeben von Objekten nicht rückgängig gemacht werden kann."
132 name="Parcel Content"> 132 name="Parcel Content">
133 <action description="Objekte in Gruppenbesitz zurückgeben" 133 <action description="Objekte in Gruppenbesitz zurückgeben"
134 longdescription="Führen Sie Objekte auf Parzellen in Gruppenbesitz, die der Gruppe gehören, in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Objekte&apos; zurück." 134 longdescription="Führen Sie Objekte auf Parzellen in Gruppenbesitz, die der Gruppe gehören, in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Objekte&apos; zurück."
135 name="land return group owned" /> 135 name="land return group owned" value="48" />
136 <action description="Auf Gruppe eingestellte Objekte zurückgeben" 136 <action description="Auf Gruppe eingestellte Objekte zurückgeben"
137 longdescription="Führen Sie Objekte auf Parzellen in Gruppenbesitz, die auf die Gruppe eingestellt sind, in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Objekte&apos; zurück." 137 longdescription="Führen Sie Objekte auf Parzellen in Gruppenbesitz, die auf die Gruppe eingestellt sind, in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Objekte&apos; zurück."
138 name="land return group set" /> 138 name="land return group set" value="33" />
139 <action description="Nichtgruppenobjekte zurückgeben" 139 <action description="Nichtgruppenobjekte zurückgeben"
140 longdescription="Führen Sie Objekte auf Parzellen in Gruppenbesitz, die nicht der Gruppe gehören, in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Objekte&apos; zurück." 140 longdescription="Führen Sie Objekte auf Parzellen in Gruppenbesitz, die nicht der Gruppe gehören, in &apos;Info zu Land&apos; &gt; Registerkarte &apos;Objekte&apos; zurück."
141 name="land return non group" /> 141 name="land return non group" value="34" />
142 <action description="Gartenarbeiten mit Linden-Pflanzen" 142 <action description="Gartenarbeiten mit Linden-Pflanzen"
143 longdescription="Gärtnereifähigkeit zum Pflanzen und versetzen von Linden-Bäumen, Pflanzen und Gräsern. Diese Objekte finden Sie in Ihrer Inventarbibliothek &gt; Ordner &apos;Objekte&apos;, oder sie können mit Hilfe der Schaltfläche &apos;Bauen&apos; erstellt werden." 143 longdescription="Gärtnereifähigkeit zum Pflanzen und versetzen von Linden-Bäumen, Pflanzen und Gräsern. Diese Objekte finden Sie in Ihrer Inventarbibliothek &gt; Ordner &apos;Objekte&apos;, oder sie können mit Hilfe der Schaltfläche &apos;Bauen&apos; erstellt werden."
144 name="land gardening" /> 144 name="land gardening" value="35" />
145 </action_set> 145 </action_set>
146 <action_set 146 <action_set
147 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. " 147 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. "
148 name="Object Management"> 148 name="Object Management">
149 <action description="Objekte an Gruppe übertragen" 149 <action description="Objekte an Gruppe übertragen"
150 longdescription="Übertragen Sie Objekte einer Gruppe unter &apos;Werkzeug bearbeiten&apos; &gt; Registerkarte &apos;Allgemein&apos;." 150 longdescription="Übertragen Sie Objekte einer Gruppe unter &apos;Werkzeug bearbeiten&apos; &gt; Registerkarte &apos;Allgemein&apos;."
151 name="object deed" /> 151 name="object deed" value="36" />
152 <action 152 <action
153 description="Objekte in Gruppenbesitz manipulieren (verschieben, kopieren, modifizieren)" 153 description="Objekte in Gruppenbesitz manipulieren (verschieben, kopieren, modifizieren)"
154 longdescription="Objekte in Gruppenbesitz werden unter &apos;Werkzeug bearbeiten&apos; &gt; Registerkarte &apos;Allgemein&apos; manipuliert (Verschieben, Kopieren, Modifizieren)." 154 longdescription="Objekte in Gruppenbesitz werden unter &apos;Werkzeug bearbeiten&apos; &gt; Registerkarte &apos;Allgemein&apos; manipuliert (Verschieben, Kopieren, Modifizieren)."
155 name="object manipulate" /> 155 name="object manipulate" value="38" />
156 <action description="Objekte in Gruppenbesitz zum Verkauf einstellen" 156 <action description="Objekte in Gruppenbesitz zum Verkauf einstellen"
157 longdescription="Stellen Sie Sie Objekte in Gruppenbesitz unter &apos;Werkzeug bearbeiten&apos; &gt; Registerkarte &apos;Allgemein&apos; zum Verkauf ein." 157 longdescription="Stellen Sie Sie Objekte in Gruppenbesitz unter &apos;Werkzeug bearbeiten&apos; &gt; Registerkarte &apos;Allgemein&apos; zum Verkauf ein."
158 name="object set sale" /> 158 name="object set sale" value="39" />
159 </action_set> 159 </action_set>
160 <action_set 160 <action_set
161 description="Diese Fähigkeiten umfassen die Möglichkeit, von Mitgliedern zu verlangen, Gruppenverpflichtungen zu bezahlen und Gruppendividenden zu erhalten, sowie den Zugriff auf den Konto-Verlauf der Gruppe zu beschränken." 161 description="Diese Fähigkeiten umfassen die Möglichkeit, von Mitgliedern zu verlangen, Gruppenverpflichtungen zu bezahlen und Gruppendividenden zu erhalten, sowie den Zugriff auf den Konto-Verlauf der Gruppe zu beschränken."
162 name="Accounting"> 162 name="Accounting">
163 <action description="Gruppenverpflichtungen bezahlen und Gruppendividenden erhalten" 163 <action description="Gruppenverpflichtungen bezahlen und Gruppendividenden erhalten"
164 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. " 164 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. "
165 name="accounting accountable" /> 165 name="accounting accountable" value="40" />
166 </action_set> 166 </action_set>
167 <action_set 167 <action_set
168 description="Diese Fähigkeiten umfassen die Möglichkeit, Mitgliedern zu gestatten, Gruppenmitteilungen zu senden, zu empfangen und anzuzeigen." 168 description="Diese Fähigkeiten umfassen die Möglichkeit, Mitgliedern zu gestatten, Gruppenmitteilungen zu senden, zu empfangen und anzuzeigen."
169 name="Notices"> 169 name="Notices">
170 <action description="Mitteilungen senden" 170 <action description="Mitteilungen senden"
171 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Mitteilungen in &apos;Gruppeninformationen&apos; &gt; Registerkarte &apos;Mitteilungen&apos; senden." 171 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Mitteilungen in &apos;Gruppeninformationen&apos; &gt; Registerkarte &apos;Mitteilungen&apos; senden."
172 name="notices send" /> 172 name="notices send" value="42" />
173 <action description="Mitteilungen erhalten und vergangene Mitteilungen anzeigen" 173 <action description="Mitteilungen erhalten und vergangene Mitteilungen anzeigen"
174 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Mitteilungen erhalten und vergangene Mitteilungen in &apos;Gruppeninformationen&apos; &gt; Registerkarte &apos;Mitteilungen&apos; anzeigen." 174 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Mitteilungen erhalten und vergangene Mitteilungen in &apos;Gruppeninformationen&apos; &gt; Registerkarte &apos;Mitteilungen&apos; anzeigen."
175 name="notices receive" /> 175 name="notices receive" value="43" />
176 </action_set> 176 </action_set>
177 <action_set 177 <action_set
178 description="Diese Fähigkeiten umfassen die Möglichkeit, Mitgliedern zu gestatten, Angebote zu erstellen, darüber abzustimmen und den Abstimmverlauf anzuzeigen." 178 description="Diese Fähigkeiten umfassen die Möglichkeit, Mitgliedern zu gestatten, Angebote zu erstellen, darüber abzustimmen und den Abstimmverlauf anzuzeigen."
179 name="Proposals"> 179 name="Proposals">
180 <action description="Angebote erstellen" 180 <action description="Angebote erstellen"
181 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Angebote erstellen, die in &apos;Gruppeninformationen&apos; &gt; Registerkarte &apos;Angebote&apos; zur Abstimmung kommen." 181 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können Angebote erstellen, die in &apos;Gruppeninformationen&apos; &gt; Registerkarte &apos;Angebote&apos; zur Abstimmung kommen."
182 name="proposal start" /> 182 name="proposal start" value="44" />
183 <action description="Über Angebote abstimmen" 183 <action description="Über Angebote abstimmen"
184 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können über Angebote abstimmen in &apos;Gruppeninformationen&apos; &gt; Registerkarte &apos;Angebote&apos;." 184 longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können über Angebote abstimmen in &apos;Gruppeninformationen&apos; &gt; Registerkarte &apos;Angebote&apos;."
185 name="proposal vote" /> 185 name="proposal vote" value="45" />
186 </action_set> 186 </action_set>
187</role_actions> 187</role_actions>
diff --git a/linden/indra/newview/skins/xui/en-us/alerts.xml b/linden/indra/newview/skins/xui/en-us/alerts.xml
index 319e495..d294ae8 100644
--- a/linden/indra/newview/skins/xui/en-us/alerts.xml
+++ b/linden/indra/newview/skins/xui/en-us/alerts.xml
@@ -1087,7 +1087,7 @@ for advice and a link to the system status web page.
1087 </alert> 1087 </alert>
1088 <alert modal="true" name="CannotConnectNoReplyFromLogin"> 1088 <alert modal="true" name="CannotConnectNoReplyFromLogin">
1089 <message name="message"> 1089 <message name="message">
1090 Unable to connect. No reply from login database. 1090 Unable to connect. No login ack from simulator.
1091 1091
1092Please try again in a few minutes, or click Help 1092Please try again in a few minutes, or click Help
1093for advice and a link to the system status web page. 1093for advice and a link to the system status web page.
@@ -2594,7 +2594,7 @@ and the default for the &apos;Revert&apos; tool?
2594 </alert> 2594 </alert>
2595 <alert modal="true" name="MaxManagersOnRegion"> 2595 <alert modal="true" name="MaxManagersOnRegion">
2596 <message name="message"> 2596 <message name="message">
2597 You can only have [MAX_MANAGER] Banned Residents. 2597 You can only have [MAX_MANAGER] Estate Managers.
2598 </message> 2598 </message>
2599 </alert> 2599 </alert>
2600 <alert modal="true" name="OwnerCanNotBeDenied"> 2600 <alert modal="true" name="OwnerCanNotBeDenied">
@@ -2794,6 +2794,20 @@ also appear higher when people search for keywords.
2794 Cancel 2794 Cancel
2795 </option> 2795 </option>
2796 </alert> 2796 </alert>
2797 <alert modal="true" name="WebLaunchQAWiki">
2798 <message name="message">
2799 Visit the [SECOND_LIFE] QA Wiki.
2800 </message>
2801 <ignore name="ignore">
2802 When launching web browser to view the QA Wiki
2803 </ignore>
2804 <option name="Gotopage">
2805 OK
2806 </option>
2807 <option name="Cancel">
2808 Cancel
2809 </option>
2810 </alert>
2797 <alert modal="true" name="WebLaunchPublicIssue"> 2811 <alert modal="true" name="WebLaunchPublicIssue">
2798 <message name="message"> 2812 <message name="message">
2799 Visit the [SECOND_LIFE] Public Issue Tracker, Where you can Report Bugs and other Issues. 2813 Visit the [SECOND_LIFE] Public Issue Tracker, Where you can Report Bugs and other Issues.
@@ -3826,6 +3840,20 @@ Default: off
3826regardless of any other settings. 3840regardless of any other settings.
3827 </message> 3841 </message>
3828 </alert> 3842 </alert>
3843 <alert modal="true" name="HelpEstateVoiceChat" title="Allow Voice Chat">
3844 <message name="message">
3845 Parcels in this estate are allowed to have their own voice
3846 channels in which residents may hear and talk with others
3847 nearby.
3848
3849 Default: off
3850 </message>
3851 </alert>
3852 <alert modal="true" name="VoiceVersionMismatch" title="Voice Version Mismatch">
3853 <message name="message">
3854This version of Second Life is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update Second Life.
3855 </message>
3856 </alert>
3829 <alert modal="true" name="HelpEstateCovenant" title="Estate Covenant"> 3857 <alert modal="true" name="HelpEstateCovenant" title="Estate Covenant">
3830 <message name="message"> 3858 <message name="message">
3831 Setting an estate covenant enables you to sell parcels 3859 Setting an estate covenant enables you to sell parcels
@@ -4082,7 +4110,7 @@ will only work if a script is added with a money() event.
4082 Visit the Second Life Support Web site? 4110 Visit the Second Life Support Web site?
4083 </message> 4111 </message>
4084 <ignore name="ignore"> 4112 <ignore name="ignore">
4085 Ignore 4113 When visiting the Second Life Support Website.
4086 </ignore> 4114 </ignore>
4087 <option name="Gotopage"> 4115 <option name="Gotopage">
4088 Go 4116 Go
@@ -4096,7 +4124,7 @@ will only work if a script is added with a money() event.
4096 Are you sure you want to quit? 4124 Are you sure you want to quit?
4097 </message> 4125 </message>
4098 <ignore name="ignore"> 4126 <ignore name="ignore">
4099 Ignore 4127 When Quitting Second Life.
4100 </ignore> 4128 </ignore>
4101 <option name="Quit"> 4129 <option name="Quit">
4102 Quit 4130 Quit
@@ -4143,9 +4171,10 @@ restrict access to the entirety of Second Life.
4143 </alert> 4171 </alert>
4144 <alert modal="true" name="HelpReportBug"> 4172 <alert modal="true" name="HelpReportBug">
4145 <message name="message"> 4173 <message name="message">
4146 Use this tool to *only* report technical features that do not perform as 4174Use this tool to *only* report technical features that do not perform
4147described or expected, please provide as much detail as possible, You 4175as described or expected, please provide as much detail as possible,
4148may reply to the auto-response email to add more details to your report. 4176You may reply to the auto-response email to add more details to your
4177report.
4149All bug reports are investigated and assessed. No email response will be sent. 4178All bug reports are investigated and assessed. No email response will be sent.
4150- 4179-
4151If you are having a technical difficulty, please contact Support at: 4180If you are having a technical difficulty, please contact Support at:
@@ -4338,25 +4367,25 @@ the contents of your Lost And Found folder?
4338 When copying a SLURL to your clipboard 4367 When copying a SLURL to your clipboard
4339 </ignore> 4368 </ignore>
4340 </alert> 4369 </alert>
4341 <alert modal="true" name="IMSessionStartError"> 4370 <alert modal="true" name="ChatterBoxSessionStartError">
4342 <message name="message"> 4371 <message name="message">
4343 Error starting a new IM session with [RECIPIENT]. 4372 Error starting a new chat session with [RECIPIENT].
4344 [REASON] 4373 [REASON]
4345 </message> 4374 </message>
4346 <option default="true" name="OK"> 4375 <option default="true" name="OK">
4347 OK 4376 OK
4348 </option> 4377 </option>
4349 </alert> 4378 </alert>
4350 <alert modal="true" name="IMSessionStartNotVerified"> 4379 <alert modal="true" name="ChatterBoxSessionStartNotVerified">
4351 <message name="message"> 4380 <message name="message">
4352 Error starting a new IM session with [RECIPIENT]. 4381 Error starting a new chat session with [RECIPIENT].
4353 [REASON] 4382 [REASON]
4354 </message> 4383 </message>
4355 <option default="true" name="OK"> 4384 <option default="true" name="OK">
4356 OK 4385 OK
4357 </option> 4386 </option>
4358 </alert> 4387 </alert>
4359 <alert modal="true" name="IMSessionEventError"> 4388 <alert modal="true" name="ChatterBoxSessionEventError">
4360 <message name="message"> 4389 <message name="message">
4361 Error [EVENT] [RECIPIENT]. 4390 Error [EVENT] [RECIPIENT].
4362 [REASON] 4391 [REASON]
@@ -4365,9 +4394,9 @@ the contents of your Lost And Found folder?
4365 OK 4394 OK
4366 </option> 4395 </option>
4367 </alert> 4396 </alert>
4368 <alert modal="true" name="ForceCloseIMSession"> 4397 <alert modal="true" name="ForceCloseChatterBoxSession">
4369 <message name="messsage"> 4398 <message name="messsage">
4370 Your IM session with [NAME] must close. 4399 Your chat session with [NAME] must close.
4371 [REASON] 4400 [REASON]
4372 </message> 4401 </message>
4373 <option default="true" name="OK"> 4402 <option default="true" name="OK">
@@ -4383,7 +4412,7 @@ the contents of your Lost And Found folder?
4383 <!-- alert for more information about the debit permission --> 4412 <!-- alert for more information about the debit permission -->
4384 <alert modal="true" name="DebitPermissionDetails" title="About Requests for the Debit Permission"> 4413 <alert modal="true" name="DebitPermissionDetails" title="About Requests for the Debit Permission">
4385 <message name="message"> 4414 <message name="message">
4386 <p>Granting this request gives a script ongoing permission to take Linden dollars (L$) from your account. To revoke this permission, the object's owner must delete the object or reset the scripts in the object.</p> 4415 <p>Granting this request gives a script ongoing permission to take Linden dollars (L$) from your account. To revoke this permission, the object owner must delete the object or reset the scripts in the object.</p>
4387 </message> 4416 </message>
4388 <option default="true" name="OK"> 4417 <option default="true" name="OK">
4389 OK 4418 OK
diff --git a/linden/indra/newview/skins/xui/en-us/floater_about.xml b/linden/indra/newview/skins/xui/en-us/floater_about.xml
index e9bb109..20a97f6 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_about.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_about.xml
@@ -9,7 +9,9 @@
9 text_color="1, 1, 1, 1" text_readonly_color="1, 1, 1, 1" width="458" 9 text_color="1, 1, 1, 1" text_readonly_color="1, 1, 1, 1" width="458"
10 word_wrap="true">Second Life is brought to you by Philip, Andrew, Tessa, Cory, Frank, James, Doug, Hunter, Richard, John, Eric, Avi, AaronB, AaronY, Ian, Peter, Mark, Robin, Stephen, Tracy, Ryan, Alberto, Haney, Tanya, JimJ, Dan, Ben, Stephanie, Tim, Evan, Catherine, Colin, Chris, Reuben, Charity, Jeska, James, JonHenry, Kelly, Callum, Char, Daniel, DavidF, Don, Jeff, Lauren, Lee, Michael, Ramzi, Vektor, Steve, TomY, Tess, Kona, Brent, Clarissa, PeterP, Jesse, Annette, Cyn, Blue, Ginsu, Jonathan, Karen, Adam, Nova, Deana, Lizzie, Patsy, DavidK, Isaac, Pathfinder, Monroe, Jill, Benny, Altruima, Rheya, Jennifer, Jack, DaveP, Brad, Mick, Babbage, Elisabeth, Brian, Beth, Data, Ethan, Wendy, Nicole, Sky, Jeffrey, Zero, Coffee, Tesla, Kenny, Makiko, Nigel, Teeple, Lucy, Mia, Dee, Guy, Harry, Liana, Branka, Jimbo, Aura, Vasuda, SarahD, bethanye, Torley, Runitai, MikeS, PaulM, Milo, Hermia, JoeM, Melanie, Rejean, DSmith, SMiller, Susan, Jose, DongYun, Justin, Andrey, Syrah, Donovan, Henrik, Nora, Lexie, AC, Donna, ChrisC, Alex, Leyla, Kyle, Mathew, Devin, Joshua, DanC, Jessica, Harmony, Claudia, Tramel, Glenn, Betsy, Fritz, Jun, Adam, Cassandra, Ken, RyanW, Spike, Varas, Andy, Luke, RobLa, Chiyo, JohnZ, Dustin, George, Del, PeterP, Migyeong, Matthew, RMullane, CChampion, JTurbin, JamesC, Viola, Lightfoot, Jacqui, Sturm, Adrian, Buttercup, Alfred, Sunil, Alfred, Noel, Irfan, Jill, Yool, Jane, Yuki, Yoz, Matthew, Arthur, Jennifer, Karl, Brian, Ben, Janine, Christopher, Madhavi, Everett, Anthony, Joon, Jake, sean, Adreanne, Stephany, KellyJo, Jeremy, Pramod, Joshua, Sean, Christopher, Amy, Ceren, Katherine, jon, Sudheendra, James, Stephan, Kari, Kartic, Todd, Thomas, Joki, Rebecca, Belinda, Bert, Roger, Bridie, Kristi, Brian, Maria, John, Aric, Nathanel, Melinda, Darrell, Jennifer, Sandy, Greg, Rob, Brad, Chris, Eric, Palmer, Asi, Katja, Lisa, Minda, Jen, Aaron, Bryan, Mark, Jonathan, Jamie, Laurel, William, Matthew, Steve, David, Remy, James, Tim, Lee, Brian, Ashlei, Sam, Mike, Ethan, Austin, Wanda, Paul, Brian, Rachel, Valentyn, Emma Williams, Autum, Steven, Laley, Charles, Jessica, Sue, Gillian, CG, Kip, Kristen, Shamiran, Blake, Brett, Erica, Kent, Joel, Plexus, Twilight, Joppa and many others. 10 word_wrap="true">Second Life is brought to you by Philip, Andrew, Tessa, Cory, Frank, James, Doug, Hunter, Richard, John, Eric, Avi, AaronB, AaronY, Ian, Peter, Mark, Robin, Stephen, Tracy, Ryan, Alberto, Haney, Tanya, JimJ, Dan, Ben, Stephanie, Tim, Evan, Catherine, Colin, Chris, Reuben, Charity, Jeska, James, JonHenry, Kelly, Callum, Char, Daniel, DavidF, Don, Jeff, Lauren, Lee, Michael, Ramzi, Vektor, Steve, TomY, Tess, Kona, Brent, Clarissa, PeterP, Jesse, Annette, Cyn, Blue, Ginsu, Jonathan, Karen, Adam, Nova, Deana, Lizzie, Patsy, DavidK, Isaac, Pathfinder, Monroe, Jill, Benny, Altruima, Rheya, Jennifer, Jack, DaveP, Brad, Mick, Babbage, Elisabeth, Brian, Beth, Data, Ethan, Wendy, Nicole, Sky, Jeffrey, Zero, Coffee, Tesla, Kenny, Makiko, Nigel, Teeple, Lucy, Mia, Dee, Guy, Harry, Liana, Branka, Jimbo, Aura, Vasuda, SarahD, bethanye, Torley, Runitai, MikeS, PaulM, Milo, Hermia, JoeM, Melanie, Rejean, DSmith, SMiller, Susan, Jose, DongYun, Justin, Andrey, Syrah, Donovan, Henrik, Nora, Lexie, AC, Donna, ChrisC, Alex, Leyla, Kyle, Mathew, Devin, Joshua, DanC, Jessica, Harmony, Claudia, Tramel, Glenn, Betsy, Fritz, Jun, Adam, Cassandra, Ken, RyanW, Spike, Varas, Andy, Luke, RobLa, Chiyo, JohnZ, Dustin, George, Del, PeterP, Migyeong, Matthew, RMullane, CChampion, JTurbin, JamesC, Viola, Lightfoot, Jacqui, Sturm, Adrian, Buttercup, Alfred, Sunil, Alfred, Noel, Irfan, Jill, Yool, Jane, Yuki, Yoz, Matthew, Arthur, Jennifer, Karl, Brian, Ben, Janine, Christopher, Madhavi, Everett, Anthony, Joon, Jake, sean, Adreanne, Stephany, KellyJo, Jeremy, Pramod, Joshua, Sean, Christopher, Amy, Ceren, Katherine, jon, Sudheendra, James, Stephan, Kari, Kartic, Todd, Thomas, Joki, Rebecca, Belinda, Bert, Roger, Bridie, Kristi, Brian, Maria, John, Aric, Nathanel, Melinda, Darrell, Jennifer, Sandy, Greg, Rob, Brad, Chris, Eric, Palmer, Asi, Katja, Lisa, Minda, Jen, Aaron, Bryan, Mark, Jonathan, Jamie, Laurel, William, Matthew, Steve, David, Remy, James, Tim, Lee, Brian, Ashlei, Sam, Mike, Ethan, Austin, Wanda, Paul, Brian, Rachel, Valentyn, Emma Williams, Autum, Steven, Laley, Charles, Jessica, Sue, Gillian, CG, Kip, Kristen, Shamiran, Blake, Brett, Erica, Kent, Joel, Plexus, Twilight, Joppa and many others.
11 11
12Thank you to the following residents for helping to ensure that this is the best version yet: Gate Bates, Henri Beauchamp, zinoplatinium Burton, Celeste Eerie, Sara Flinker, skyking Heron, sakura Jannings, Arth Karas, Trevor Langdon, tamara Levitsky, Donuma Masala, Keith Mathieson, Ima Mechanique, Venus Medusa, Alice Obscure, Glenn Rotaru, Norm Schack, Singular Seoul, Rhyph Somme, Amy Sukra, Omei Turnbull, Fehan Villota 12In Memory of Jesse Malthus, you will be fondly remembered by all who heard your voice.
13
14Thank you to the following residents for helping to ensure that this is the best version yet: Aces Spade, Adrian Buckler, Adrienne LeShelle, Amanda Ascot, AnnaQuay Heart, Aquamina Khalifa, Arienne Anatine, Aston Hildyard, Ayami Kamachi, Badinage Odets, Biffy Berjis, Bigfox Pye, BigJohn Jade, BigRick Byrd, Brettus Tripsa, Brock Fitzgerald, Broker Allen, Browse by Name, Chiria Celt, Christopher Prudhomme, dale Cao, dale Lynch, Dante Tucker, DaQbet Kish, Dargon Pacer, Darius Antonelli, Deira Llanfair, DeviantBone Xi, Dore Dorado, Englishwob Etchegaray, Enya Masala, Eric Renneville, Fairfax Michinaga, FireFox Bancroft, FOXI Cortes, Frederick Earp, Geo Meek, Gotthilf Fischer, Hallo Loon, Hawk Carter, Hazel Kyrgyz, Hecter Barbosa, Hex Link, Ice Pak, Ideasu Mukerji, Itoku Kamachi, Jared Halleck, Jaykob Carter, Jennifer Drumheller, JensMartin Tomsen, JIAB Boa, Jim Gustafson, JimmyJet Fossett, Joseph Rustamova, Jt Volos, Karilyn Kidomen, Kaysha Sion, Keaton Nacon, Kevin Susenko, Khashai Steinbeck, Kira Cuddihy, Kit Massiel, Kojo Dixon, KUieTSToRm Lightcloud, Kwai Kyong, Kyrtis Daehlie, LazyGunGuy Bartlett, Lewcas Zapedzki, Lioc Cioc, LLIB Utu, Lou Liebknecht, Luca Draken, Maci Homewood, Major Sewell, Mari Todriya, MarieElize Noel, matt27 Churchill, Maverick Miasma, maydaysos Young, Mediaho Ball, Mikayla Gillespie, Mike Faulkland, Modfire Milland, MollyBrown Foxley, Mosley Jewell, Nuahs Zapedzki, Nyx Divine, Panther Farber, Paul Bumi, PrincessNina Prefect, Prio Serpentine, Rainbow Drake, Randall Rall, Randy Kazan, Reinhart Mokeev, Rhyph Somme, Rico Roizman, Ruge Dryke, Ryan Orbit, Safira Rosher, Samantha Bainbridge, Sammy Foxley, Sash Furst, Saturn Ariantho, Sienna Summers, Skye Enoch, Sofie Kanno, Solar Legion, Sonic Oki, Sunra Saenz, Taina Heart, Taryn Sprawl, tenerife Wei, TomDragon Nilsson, Trebla Reve, Trouble Carnell, user1cat Orbit, Vance Merlin, Veritas Variscan, Web Page, Wi3g3ht3s Ihnen, WinDrftr DeFarge, Yuu Nakamichi, Zac Delec, Zed Fairweather, Zimmo Hallard.
13 15
14APR Copyright (C) 2000-2004 The Apache Software Foundation 16APR Copyright (C) 2000-2004 The Apache Software Foundation
15Cg Copyright (C) 2002, NVIDIA Corporationa. 17Cg Copyright (C) 2002, NVIDIA Corporationa.
@@ -32,6 +34,7 @@ All rights reserved. See licenses.txt for details.
32 34
33 35
34Viva la Liberación!</text_editor> 36Viva la Liberación!</text_editor>
37
35 <text_editor bg_readonly_color="0, 0, 0, 0" bottom_delta="174" embedded_items="false" 38 <text_editor bg_readonly_color="0, 0, 0, 0" bottom_delta="174" embedded_items="false"
36 follows="left|top|right|bottom" font="SansSerif" height="238" left="6" 39 follows="left|top|right|bottom" font="SansSerif" height="238" left="6"
37 max_length="65536" mouse_opaque="true" name="support_editor" 40 max_length="65536" mouse_opaque="true" name="support_editor"
diff --git a/linden/indra/newview/skins/xui/en-us/floater_about_land.xml b/linden/indra/newview/skins/xui/en-us/floater_about_land.xml
index 9366154..681b2fd 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_about_land.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_about_land.xml
@@ -652,60 +652,92 @@
652 <panel border="true" bottom="-349" enabled="true" follows="left|top|right|bottom" 652 <panel border="true" bottom="-349" enabled="true" follows="left|top|right|bottom"
653 height="333" hidden="false" label="Media" left="1" mouse_opaque="true" 653 height="333" hidden="false" label="Media" left="1" mouse_opaque="true"
654 name="land_media_panel" width="458"> 654 name="land_media_panel" width="458">
655 <check_box bottom="-20" enabled="true" follows="left|top" font="SansSerifSmall"
656 height="16" hidden="false" initial_value="false"
657 label="Restrict spatialized sound to this parcel" left="76"
658 mouse_opaque="true" name="check sound local" radio_style="false"
659 width="292" />
660 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 655 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
661 bottom="-48" drop_shadow_visible="true" enabled="true" follows="left|top" 656 bottom="-26" drop_shadow_visible="true" enabled="true" follows="left|top"
662 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
663 left="4" mouse_opaque="true" name="Music URL:" v_pad="0" width="364">
664 Music URL:
665 </text>
666 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="-48"
667 enabled="true" follows="left|top|right" font="SansSerifSmall"
668 handle_edit_keys_directly="false" height="16" hidden="false" left="76"
669 max_length="255" mouse_opaque="true" name="music_url"
670 select_all_on_focus_received="true" select_on_focus="true"
671 text_readonly_color="0.576471 0.662745 0.835294 1" width="370" />
672 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
673 bottom="-76" drop_shadow_visible="true" enabled="true" follows="left|top"
674 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false" 657 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
675 left="4" mouse_opaque="true" name="Media texture:" v_pad="0" width="364"> 658 left="4" mouse_opaque="true" name="Media texture:" v_pad="0" width="364">
676 Media 659 Media
677texture: 660texture:
678 </text> 661 </text>
679 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 662 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
680 bottom="-76" drop_shadow_visible="true" enabled="true" follows="left|top" 663 bottom_delta="0" drop_shadow_visible="true" enabled="true" follows="left|top"
681 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false" 664 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
682 left="76" mouse_opaque="true" name="Replace this texture:" v_pad="0" 665 left="76" mouse_opaque="true" name="Replace this texture:" v_pad="0"
683 width="292"> 666 width="292">
684 Replace this texture: 667 Replace this texture:
685 </text> 668 </text>
686 <texture_picker allow_no_texture="true" bottom="-144" can_apply_immediately="false" 669 <texture_picker allow_no_texture="true" bottom_delta="-68" can_apply_immediately="false"
687 default_image_name="Default" enabled="true" follows="left|top" height="64" 670 default_image_name="Default" enabled="true" follows="left|top" height="64"
688 hidden="false" label="" left="76" mouse_opaque="true" name="media texture" 671 hidden="false" label="" left="76" mouse_opaque="true" name="media texture"
689 tool_tip="Click to choose a picture" width="64" /> 672 tool_tip="Click to choose a picture" width="64" />
690 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 673 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
691 bottom="-154" drop_shadow_visible="true" enabled="true" follows="left|top" 674 bottom_delta="-10" drop_shadow_visible="true" enabled="true" follows="left|top"
692 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false" 675 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
693 left="76" mouse_opaque="true" name="with content from this URL:" v_pad="0" 676 left="76" mouse_opaque="true" name="with content from this URL:" v_pad="0"
694 width="292"> 677 width="292">
695 with content from this URL: 678 with content from this URL:
696 </text> 679 </text>
697 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="-172" 680 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-18"
698 enabled="true" follows="left|top|right" font="SansSerifSmall" 681 enabled="true" follows="left|top|right" font="SansSerifSmall"
699 handle_edit_keys_directly="false" height="16" hidden="false" left="76" 682 handle_edit_keys_directly="false" height="16" hidden="false" left="76"
700 max_length="255" mouse_opaque="true" name="media_url" 683 max_length="255" mouse_opaque="true" name="media_url"
701 select_all_on_focus_received="true" select_on_focus="true" 684 select_all_on_focus_received="true" select_on_focus="true"
702 text_readonly_color="0.576471 0.662745 0.835294 1" width="370" /> 685 text_readonly_color="0.576471 0.662745 0.835294 1" width="370" />
703 <check_box bottom="-208" enabled="true" follows="left|top" font="SansSerifSmall" 686 <check_box bottom_delta="-24" enabled="true" follows="left|top" font="SansSerifSmall"
704 height="16" hidden="false" initial_value="false" 687 height="16" hidden="false" initial_value="false"
705 label="Auto scale content (slower and reduced visual quality)" left="76" 688 label="Auto scale content (slower and reduced visual quality)" left="76"
706 mouse_opaque="true" name="media_auto_scale" radio_style="false" 689 mouse_opaque="true" name="media_auto_scale" radio_style="false"
707 tool_tip="Checking this option will scale the content for this parcel automatically. It may be slightly slower and lower quality visually but no other texture scaling or alignment will be required." 690 tool_tip="Checking this option will scale the content for this parcel automatically. It may be slightly slower and lower quality visually but no other texture scaling or alignment will be required."
708 width="308" /> 691 width="308" />
692 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
693 bottom_delta="-45" drop_shadow_visible="true" enabled="true" follows="left|top"
694 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
695 left="8" mouse_opaque="true" name="Media texture:" v_pad="0" width="364">
696 Sound
697Settings:
698 </text>
699 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
700 bottom_delta="0" drop_shadow_visible="true" enabled="true" follows="left|top"
701 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
702 left="76" mouse_opaque="true" name="Music URL:" v_pad="0" width="364">
703 Music URL:
704 </text>
705 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-18"
706 enabled="true" follows="left|right|top" font="SansSerifSmall"
707 handle_edit_keys_directly="false" height="16" hidden="false" left="76"
708 max_length="255" mouse_opaque="true" name="music_url"
709 select_all_on_focus_received="true" select_on_focus="true"
710 text_readonly_color="0.576471 0.662745 0.835294 1" width="370" />
711
712 <check_box bottom_delta="-26" enabled="true" follows="left|top" font="SansSerifSmall"
713 height="16" hidden="false" initial_value="false"
714 label="Restrict spatialized sound to this parcel" left="76"
715 mouse_opaque="true" name="check sound local" radio_style="false"
716 width="292" />
717 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
718 bottom="-268" enabled="true" follows="left|top" font="SansSerifSmall"
719 h_pad="0" halign="left" height="16" hidden="false" left="8"
720 mouse_opaque="false" name="Voice settings:" tab_stop="false" v_pad="0"
721 width="364">
722 Voice
723Settings:
724 </text>
725 <radio_group bottom="-306" draw_border="true" enabled="true" follows="left|top" height="54"
726 hidden="false" left="76" mouse_opaque="true" name="parcel_voice_channel"
727 tab_stop="true" width="219">
728 <radio_item type="string" length="1" bottom="-19" enabled="true" follows="left|top" height="16" hidden="false"
729 left="3" mouse_opaque="true" name="Estate" width="463">
730 Use the Estate spatial channel
731 </radio_item>
732 <radio_item type="string" length="1" bottom="-35" enabled="true" follows="left|top" height="16" hidden="false"
733 left="3" mouse_opaque="true" name="Private" width="463">
734 Use a private spatial channel
735 </radio_item>
736 <radio_item type="string" length="1" bottom="-51" enabled="true" follows="left|top" height="16" hidden="false"
737 left="3" mouse_opaque="true" name="Disabled" width="463">
738 Disable spatial audio on this parcel
739 </radio_item>
740 </radio_group>
709 </panel> 741 </panel>
710 <panel border="true" bottom="-349" enabled="true" follows="left|top|right|bottom" 742 <panel border="true" bottom="-349" enabled="true" follows="left|top|right|bottom"
711 height="333" hidden="false" label="Access" left="1" mouse_opaque="true" 743 height="333" hidden="false" label="Access" left="1" mouse_opaque="true"
diff --git a/linden/indra/newview/skins/xui/en-us/floater_active_speakers.xml b/linden/indra/newview/skins/xui/en-us/floater_active_speakers.xml
new file mode 100644
index 0000000..bf7734e
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_active_speakers.xml
@@ -0,0 +1,72 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes"?>
2<floater
3 name="active_speakers"
4 title="Active Speakers"
5 width="250"
6 height="300"
7 rect_control="FloaterActiveSpeakersRect"
8 can_resize="true"
9 can_minimize="true"
10 can_close="true"
11 can_drag_on_left="false"
12 min_width="220"
13 min_height="200"
14 >
15 <panel name="active_speakers_panel" left="0" bottom="0" right="250" top="300" follows="left|top|right|bottom" mouse_opaque="false">
16 <scroll_list
17 name="speakers_list"
18 left="10"
19 right="-10"
20 top="-20"
21 bottom="60"
22 column_padding="0"
23 can_resize="true"
24 follows="left|top|bottom|right"
25 draw_heading="true"
26 draw_stripes="false"
27 multi_select="false"
28 search_column="1"
29 >
30 <column name="icon_speaking_status" width="20" sort="speaking_status"/>
31 <column name="speaker_name" label="Name" dynamicwidth="true" />
32 <column name="speaking_status" label="" width="0" />
33 </scroll_list>
34 <panel
35 name="volume_container"
36 left="10"
37 right="-10"
38 height="30"
39 bottom="20"
40 border="true"
41 mouse_opaque="true"
42 bevel_style="in"
43 background_visible="false"
44 background_opaque="false"
45 follows="left|right|bottom"
46 bg_opaque_color="0,0,0,0.3"
47 bg_alpha_color="0,0,0,0"
48 can_resize="false"
49 >
50 <volume_slider
51 name="speaker_volume"
52 left_delta="10"
53 width="110"
54 bottom="5"
55 height="15"
56 follows="left|bottom"
57 min_val="0.0"
58 max_val="1.0"
59 increment="0.05"
60 initial_val="0.5"
61 />
62 <button
63 name="mute_btn"
64 left_delta="115"
65 bottom_delta="-2"
66 width="70"
67 height="25"
68 label="Mute"
69 />
70 </panel>
71 </panel>
72</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_audio_volume.xml b/linden/indra/newview/skins/xui/en-us/floater_audio_volume.xml
new file mode 100644
index 0000000..dc31951
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_audio_volume.xml
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater bottom="40" left="40" height="225" width="180"
3 rect_control="FloaterAudioVolumeRect"
4 can_resize="false" can_close="true" can_drag_on_left="false" can_minimize="true"
5 name="Volume" title="Volume">
6 <panel border="true" bottom="-210" enabled="true" follows="left|top|right|bottom"
7 hidden="false" label="Volume" left="10" height="180" width="205"
8 mouse_opaque="true" name="Volume Panel"
9 filename="panel_audio.xml">
10 </panel>
11</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_buy_contents.xml b/linden/indra/newview/skins/xui/en-us/floater_buy_contents.xml
index 9a37e07..09233ce 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_buy_contents.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_buy_contents.xml
@@ -14,7 +14,7 @@
14 follows="left|top|right|bottom" height="148" left="15" mouse_opaque="true" 14 follows="left|top|right|bottom" height="148" left="15" mouse_opaque="true"
15 multi_select="false" name="item_list" width="281"> 15 multi_select="false" name="item_list" width="281">
16 <column name="icon" width="16" /> 16 <column name="icon" width="16" />
17 <column name="text" width="300" /> 17 <column name="text" relwidth="1.0" />
18 </scroll_list> 18 </scroll_list>
19 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 19 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
20 bottom_delta="-28" drop_shadow_visible="true" follows="left|right|bottom" 20 bottom_delta="-28" drop_shadow_visible="true" follows="left|right|bottom"
diff --git a/linden/indra/newview/skins/xui/en-us/floater_chat_history.xml b/linden/indra/newview/skins/xui/en-us/floater_chat_history.xml
index c37074a..a57326c 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_chat_history.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_chat_history.xml
@@ -1,30 +1,112 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater bottom="27" can_close="true" can_drag_on_left="false" can_minimize="false" 2<floater bottom="27" can_close="true" can_drag_on_left="false" can_minimize="false"
3 can_resize="true" can_tear_off="true" enabled="true" height="235" 3 can_resize="true" can_tear_off="true" enabled="true" height="270"
4 hidden="false" left="15" min_height="100" min_width="440" 4 hidden="false" left="15" min_height="150" min_width="425"
5 mouse_opaque="true" name="chat floater" rect_control="FloaterChatRect" 5 mouse_opaque="true" name="chat floater" rect_control="FloaterChatRect"
6 title="Chat History" width="440" default_tab_group="1"> 6 title="Residents Near Me (Chat History)" short_title="Near Me" width="435">
7 <button bottom="-42" enabled="true" follows="left|top" font="SansSerif" halign="center" 7
8 height="20" hidden="false" label="Chat" left="6" mouse_opaque="true" 8 <string name="ringing">Connecting to in-world Voice Chat...</string>
9 name="Chat" scale_image="true" width="55" /> 9 <string name="connected">Connected</string>
10 <button bottom="-42" enabled="false" follows="left|top" font="SansSerif" 10 <string name="hang_up">Disconnected from in-world Voice Chat</string>
11 halign="center" height="20" hidden="false" label="Mute" left="63" 11
12 mouse_opaque="true" name="Mute resident" scale_image="true" width="55" /> 12 <layout_stack border="false" left="2" bottom="2" width="430" height="250" follows="left|top|right|bottom" orientation="horizontal">
13 <combo_box allow_text_entry="false" bottom="-42" enabled="true" follows="left|top" 13 <layout_panel border="false" name="im_contents_panel" min_width="275" left="0" bottom="0" width="305" height="130" default_tab_group="1">
14 height="20" hidden="false" left="122" max_chars="20" mouse_opaque="true" 14
15 name="chatter combobox" width="200" /> 15 <combo_box left="4"
16 <check_box bottom="-42" enabled="true" follows="left|top" font="SansSerifSmall" 16 height="20"
17 height="20" hidden="false" initial_value="false" label="Show Muted Text" 17 width="120"
18 left="328" mouse_opaque="true" name="show mutes" radio_style="false" 18 label="Gestures"
19 width="116" /> 19 follows="left|top"
20 <text_editor type="string" length="1" bottom="-229" embedded_items="false" enabled="false" 20 name="Gesture">
21 follows="left|top|right|bottom" font="SansSerif" height="181" 21 <combo_item name="Gestures">
22 hidden="false" left="6" max_length="2147483647" mouse_opaque="true" 22 Gestures
23 name="Chat History Editor" tab_group="1" text_color="1 1 1 1" 23 </combo_item>
24 text_readonly_color="1 1 1 1" width="428" word_wrap="true" /> 24 </combo_box>
25 <text_editor type="string" length="1" bottom="-229" embedded_items="false" enabled="false" 25
26 follows="left|top|right|bottom" font="SansSerif" height="181" 26 <check_box bottom_delta="0" enabled="true" follows="left|top" font="SansSerifSmall"
27 hidden="false" left="6" max_length="2147483647" mouse_opaque="true" 27 height="20" initial_value="false" label="Show Muted Text"
28 name="Chat History Editor with mute" tab_group="1" text_color="1 1 1 1" 28 left_delta="125" name="show mutes" radio_style="false"
29 text_readonly_color="1 1 1 1" width="428" word_wrap="true" /> 29 width="116" />
30
31 <button left="270" right="303" bottom_delta="0" height="20" width="70" label="&lt; &lt;" label_selected="&gt; &gt;" follows="right|top" name="toggle_active_speakers_btn" visible="true" tool_tip="Click here to show list of active partipants in this IM session."/>
32
33 <text_editor type="string" length="1" bottom="28" embedded_items="false" enabled="false"
34 follows="left|top|right|bottom" font="SansSerif" height="70"
35 hidden="false" left="6" max_length="2147483647" mouse_opaque="true"
36 name="Chat History Editor" text_color="1 1 1 1"
37 text_readonly_color="1 1 1 1" width="300" word_wrap="true" />
38 <text_editor type="string" length="1" bottom="28" embedded_items="false" enabled="false"
39 follows="left|top|right|bottom" font="SansSerif" height="70"
40 hidden="false" left="6" max_length="2147483647" mouse_opaque="true"
41 name="Chat History Editor with mute" text_color="1 1 1 1"
42 text_readonly_color="1 1 1 1" width="300" word_wrap="true" />
43
44 <panel name="chat_panel" bottom="3" left="5" right="-5" top="25" tab_group="1" follows="left|right|bottom">
45 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="0"
46 enabled="true" follows="left|right|bottom" font="SansSerif"
47 handle_edit_keys_directly="false" height="20" hidden="false"
48 label="Click here to chat." left="0" right="-120" max_length="254"
49 mouse_opaque="true" name="Chat Editor" select_all_on_focus_received="false"
50 select_on_focus="false" tab_group="1"/>
51 <button bottom="0" follows="bottom|right" font="SansSerif"
52 halign="center" height="20" label="Say" left="-115"
53 mouse_opaque="true" name="Say" scale_image="true" width="50" />
54 <button bottom="0" follows="bottom|right" font="SansSerif"
55 halign="center" height="20" label="Shout" left="-60"
56 mouse_opaque="true" name="Shout" scale_image="true" width="50" />
57 </panel>
58
59 </layout_panel>
60
61 <layout_panel name="active_speakers_panel" auto_resize="false" left="0" bottom="0" right="140" height="120" min_width="140" visible="false">
62 <scroll_list name="speakers_list" left="0" right="140" top="120" bottom="78" column_padding="0" follows="left|top|bottom|right" draw_heading="true" draw_stripes="false" multi_select="false" search_column="1">
63 <column name="icon_speaking_status" width="20" sort="speaking_status"/>
64 <column name="speaker_name" label="Name" dynamicwidth="true"/>
65 <column name="speaking_status" label="" width="0"/>
66 </scroll_list>
67 <panel name="volume_container" left="0" right="140" bottom="0" border="true" mouse_opaque="true" bevel_style="in" can_resize="false" height="77" follows="left|bottom|right">
68 <button left="0" right="30" bottom="-28" height="24" name="profile_btn" follows="left|top" label="" image_overlay="icon_avatar_offline.tga" enabled="false"/>
69 <text left_delta="34" bottom_delta="9" name="resident_name" valign="center" follows="left|top" width="140" font="SansSerif">Rumplstiltskin Califragilistic</text>
70 <volume_slider
71 name="speaker_volume"
72 left="5"
73 width="85"
74 bottom_delta="-29"
75 height="15"
76 follows="left|top"
77 min_val="0.0"
78 max_val="1.0"
79 increment="0.05"
80 initial_val="0.5"
81 />
82 <text type="string" width="45" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
83 drop_shadow_visible="true" enabled="true" follows="left|top"
84 font="SansSerifSmall" height="16" hidden="false"
85 left="4" mouse_opaque="true" bottom_delta="-25" name="Mute:" v_pad="0">
86 Mute:
87 </text>
88 <check_box
89 name="mute_text_btn"
90 width="50"
91 bottom_delta="0"
92 left_delta="32"
93 follows="left|top"
94 height="25"
95 enabled="false"
96 label="Text"
97 />
98 <check_box
99 name="mute_btn"
100 follows="left|top"
101 width="50"
102 bottom_delta="0"
103 left_delta="45"
104 height="25"
105 enabled="false"
106 label="Voice"
107 />
108 </panel>
109 </layout_panel>
110 </layout_stack>
111
30</floater> 112</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_chatterbox.xml b/linden/indra/newview/skins/xui/en-us/floater_chatterbox.xml
new file mode 100644
index 0000000..807d833
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_chatterbox.xml
@@ -0,0 +1,6 @@
1<multi_floater can_close="true" can_drag_on_left="false" can_minimize="true" can_resize="true"
2 height="390" min_height="340" min_width="400" name="floater_chatterbox"
3 title="Communicate" width="392" rect_control="ChatterboxRect">
4 <tab_container bottom="2" follows="left|right|top|bottom" height="370" left="0"
5 name="chatterbox_tabs" tab_position="bottom" tab_width="80" width="395" />
6</multi_floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_device_settings.xml b/linden/indra/newview/skins/xui/en-us/floater_device_settings.xml
new file mode 100644
index 0000000..3c95030
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_device_settings.xml
@@ -0,0 +1,4 @@
1<floater bottom="0" can_resize="false" can_minimize="true" height="260" left="0" name="floater_device_settings"
2 title="Voice Chat Device Settings" width="405">
3 <panel bottom="0" name="device_settings" filename="panel_audio_device.xml" left="2" top="-20" right="-5"/>
4</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_friends.xml b/linden/indra/newview/skins/xui/en-us/floater_friends.xml
index d80452c..49b1d14 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_friends.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_friends.xml
@@ -1,165 +1,64 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes"?> 1<floater can_close="true" can_drag_on_left="false" can_minimize="true" can_resize="true"
2<floater 2 min_height="300" min_width="350" name="friends"
3 name="friends" 3 rect_control="FloaterFriendsRect" title="Friends">
4 title="Friends" 4 <scroll_list bottom="90" can_resize="true" column_padding="0" draw_heading="true"
5 can_resize="true" 5 follows="left|top|bottom|right" left="10" multi_select="true"
6 can_minimize="true" 6 name="friend_list" right="-100" search_column="1"
7 can_close="true" 7 tool_tip="Hold shift or control while clicking to select multiple friends"
8 can_drag_on_left="false" 8 top="-20">
9 rect_control="FloaterFriendsRect" 9 <column image="ff_online_status_button.tga" name="icon_online_status" width="20" />
10 min_width="293" 10 <column dynamicwidth="true" label="Name" name="friend_name" />
11 min_height="300" 11 <column image="ff_visible_online_button.tga" name="icon_visible_online" width="20" />
12 > 12 <column image="ff_visible_map_button.tga" name="icon_visible_map" width="20" />
13 <!-- <text 13 <column image="ff_edit_mine_button.tga" name="icon_edit_mine" width="20" />
14 name="help_label" 14 <column image="ff_edit_theirs_button.tga" name="icon_edit_theirs" width="20" />
15 bottom="-30"
16 left="15"
17 font="SansSerifSmall"
18 follows="top|left"
19 >
20 </text> -->
21
22 <scroll_list
23 name="friend_list"
24 left="10"
25 right="-10"
26 top="-20"
27 bottom="130"
28 column_padding="0"
29 can_resize="true"
30 follows="left|top|bottom|right"
31 draw_heading="true"
32 multi_select="true"
33 search_column="1"
34 tool_tip="Hold shift or control while clicking to select multiple friends"
35 >
36 <column name="icon_online_status" image="ff_online_status_button.tga" width="20"/>
37 <column name="friend_name" label="Name" dynamicwidth="true" />
38 <column name="icon_visible_online" image="ff_visible_online_button.tga" width="20"/>
39 <column name="icon_visible_map" image="ff_visible_map_button.tga" width="20"/>
40 <column name="icon_edit_mine" image="ff_edit_mine_button.tga" width="20"/>
41 <column name="icon_edit_theirs" image="ff_edit_theirs_button.tga" width="20"/>
42 </scroll_list> 15 </scroll_list>
43<panel 16 <panel background_opaque="true" background_visible="true" bevel_style="in"
44 name="rights_container" 17 bg_alpha_color="blue" bg_opaque_color="0,0,0,0.3" border="true" bottom="10"
45 left="10" 18 can_resize="false" follows="left|right|bottom" height="70" left="10"
46 right="-10" 19 mouse_opaque="true" name="rights_container" right="-100">
47 height="70" 20 <text bottom_delta="-11" follows="top|left" font="SansSerifSmall" left="10"
48 bottom="50" 21 name="friend_name_label">
49 border="true" 22 Select friend(s) to change rights...
50 mouse_opaque="true" 23 </text>
51 bevel_style="in" 24 <check_box bottom_delta="-21" enabled="false" follows="bottom|left" font="SansSerifSmall"
52 background_visible="true" 25 height="16" hidden="false" initial_value="false"
53 background_opaque="true" 26 label="Can see my online status" left="10" mouse_opaque="true"
54 follows="left|right|bottom" 27 name="online_status_cb" radio_style="false"
55 bg_opaque_color="0,0,0,0.3" 28 tool_tip="Set whether this friend see my online status in their friends list or calling cards"
56 bg_alpha_color="blue" 29 width="200" />
57 can_resize="false" 30 <check_box bottom_delta="-18" enabled="false" follows="bottom|left" font="SansSerifSmall"
58 > 31 height="16" hidden="false" initial_value="false"
59 <text 32 label="Can see me on the map" left="25" mouse_opaque="true"
60 name="friend_name_label" 33 name="map_status_cb" radio_style="false"
61 bottom_delta="-11" 34 tool_tip="Set whether this friend see my location on their map" width="200" />
62 left="10" 35 <check_box bottom_delta="-18" enabled="false" follows="bottom|left" font="SansSerifSmall"
63 font="SansSerifSmall" 36 height="16" hidden="false" initial_value="false"
64 follows="top|left" 37 label="Can modify my objects" left="10" mouse_opaque="true"
65 > 38 name="modify_status_cb" radio_style="false"
66 Select friend(s) to change rights... 39 tool_tip="Set whether this friend can modify my objects" width="200" />
67 </text> 40 <text bottom_delta="25" follows="top|left" font="SansSerif" left="10"
68 <check_box height="16" label="Can see my online status" 41 name="process_rights_label">
69 left="10" bottom_delta="-21" name="online_status_cb" 42 Processing rights change...
70 width="200" follows="bottom|left" 43 </text>
71 hidden="false" mouse_opaque="true" font="SansSerifSmall" 44 </panel>
72 initial_value="false" enabled="false" radio_style="false" 45 <pad bottom="-17" height="0" left="-90" width="1" />
73 tool_tip="Set whether this friend see my online status in their friends list or calling cards" /> 46 <button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
74 <check_box height="16" label="Can see me on the map" 47 label="Profile" left_delta="0" name="profile_btn"
75 left="25" bottom_delta="-18" name="map_status_cb" 48 tool_tip="Show picture, groups, and other information" width="80" />
76 width="200" follows="bottom|left" 49 <button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
77 hidden="false" mouse_opaque="true" font="SansSerifSmall" 50 label="IM/Call" left_delta="0" name="im_btn"
78 initial_value="false" enabled="false" radio_style="false" 51 tool_tip="Open Instant Message session" width="80" />
79 tool_tip="Set whether this friend see my location on their map" /> 52 <button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
80 <check_box height="16" label="Can modify my objects" 53 label="Teleport..." left_delta="0" name="offer_teleport_btn"
81 left="10" bottom_delta="-18" name="modify_status_cb" 54 tool_tip="Offer this friend a teleport to your current location" width="80" />
82 width="200" follows="bottom|left" 55 <button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
83 hidden="false" mouse_opaque="true" font="SansSerifSmall" 56 label="Pay..." left_delta="0" name="pay_btn"
84 initial_value="false" enabled="false" radio_style="false" 57 tool_tip="Give Linden dollars (L$) to this friend" width="80" />
85 tool_tip="Set whether this friend can modify my objects" /> 58 <button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
86 <text 59 label="Remove..." left_delta="0" name="remove_btn"
87 name="process_rights_label" 60 tool_tip="Remove this person from your friends list" width="80" />
88 bottom_delta="25" 61 <button bottom_delta="-35" follows="top|right" font="SansSerif" height="22"
89 left="10" 62 label="Add..." left_delta="0" name="add_btn"
90 font="SansSerif" 63 tool_tip="Offer friendship to a resident" width="80" />
91 follows="top|left"
92 >
93 Processing rights change...
94 </text>
95
96</panel>
97 <button
98 name="im_btn"
99 label="IM"
100 tool_tip="Open Instant Message session"
101 left="10"
102 bottom_delta="-22"
103 width="70"
104 height="20"
105 font="SansSerifSmall"
106 follows="bottom|left"
107 />
108
109 <button
110 name="offer_teleport_btn"
111 label="Teleport..."
112 tool_tip="Offer this friend a teleport to your current location"
113 left="85"
114 bottom_delta="0"
115 width="70"
116 height="20"
117 font="SansSerifSmall"
118 follows="bottom|left"
119 />
120
121 <button
122 name="add_btn"
123 label="Add..."
124 tool_tip="Offer friendship to a resident"
125 left="165"
126 bottom_delta="0"
127 width="70"
128 height="20"
129 font="SansSerifSmall"
130 follows="bottom|left"
131 />
132 <button
133 name="profile_btn"
134 label="Profile"
135 tool_tip="Show picture, groups, and other information"
136 left="10"
137 bottom_delta="-20"
138 width="70"
139 height="20"
140 font="SansSerifSmall"
141 follows="bottom|left"
142 />
143 <button
144 name="pay_btn"
145 label="Pay..."
146 tool_tip="Give Linden dollars (L$) to this friend"
147 left="85"
148 bottom_delta="0"
149 width="70"
150 height="20"
151 font="SansSerifSmall"
152 follows="bottom|left"
153 />
154 <button
155 name="remove_btn"
156 label="Remove..."
157 tool_tip="Remove this person from your friends list"
158 left="165"
159 bottom_delta="0"
160 width="70"
161 height="20"
162 font="SansSerifSmall"
163 follows="bottom|left"
164 />
165</floater> 64</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_groups.xml b/linden/indra/newview/skins/xui/en-us/floater_groups.xml
index 7b12684..1e08fb2 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_groups.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_groups.xml
@@ -1,57 +1,45 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater bottom="-371" can_close="true" can_drag_on_left="false" can_minimize="true" 1<floater bottom="-371" can_close="true" can_drag_on_left="false" can_minimize="true"
3 can_resize="true" can_tear_off="false" enabled="true" follows="left|top" 2 can_resize="true" can_tear_off="false" enabled="true" follows="left|top"
4 height="300" hidden="false" left="280" min_height="200" min_width="275" 3 height="300" hidden="false" left="280" min_height="250" min_width="350"
5 mouse_opaque="true" name="groups" title="Groups" width="280"> 4 mouse_opaque="true" name="groups" title="Groups" width="350">
5 <scroll_list background_visible="true" bottom="45" column_padding="5" draw_border="true"
6 draw_heading="false" draw_stripes="true" enabled="true"
7 follows="left|top|right|bottom" hidden="false" left="10"
8 mouse_opaque="true" multi_select="false" name="group list" tab_stop="true"
9 top="-20" width="240">
10 <column label="" name="name" width="248" />
11 </scroll_list>
6 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 12 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
7 bottom="-36" drop_shadow_visible="true" enabled="true" follows="left|top" 13 bottom="22" drop_shadow_visible="true" enabled="true" follows="left|bottom"
8 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false" 14 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
9 left="12" mouse_opaque="false" name="groupdesc" tab_stop="false" v_pad="0" 15 left="12" mouse_opaque="false" name="groupdesc" v_pad="0"
10 width="248"> 16 width="248">
11 Your currently active group is displayed in bold. 17 Your currently active group is displayed in bold.
12 </text> 18 </text>
13 <scroll_list background_visible="true" bottom="-228" column_padding="5" draw_border="true"
14 draw_heading="false" draw_stripes="true" enabled="true"
15 follows="left|top|right|bottom" height="190" hidden="false" left="12"
16 mouse_opaque="true" multi_select="false" name="group list" tab_stop="true"
17 width="248">
18 <column label="" name="name" width="248" />
19 </scroll_list>
20 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 19 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
21 bottom="-246" drop_shadow_visible="true" enabled="true" 20 bottom="5" drop_shadow_visible="true" enabled="true" follows="left|bottom"
22 follows="left|bottom" font="SansSerifSmall" h_pad="0" halign="left" 21 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
23 height="16" hidden="false" left="12" mouse_opaque="false" name="groupcount" 22 left="12" mouse_opaque="false" name="groupcount" v_pad="0"
24 tab_stop="false" v_pad="0" width="248"> 23 width="248">
25 You belong to [COUNT] groups (of [MAX] maximum). 24 You belong to [COUNT] groups (of [MAX] maximum).
26 </text> 25 </text>
27 <button border_height="16" border_width="16" bottom="-268" enabled="false" 26 <pad bottom="-17" height="0" left="-90" width="1" />
28 follows="left|bottom" font="SansSerif" halign="center" height="20" 27 <button border_height="16" border_width="16" bottom_delta="-25" follows="top|right"
29 hidden="false" label="Activate" 28 font="SansSerif" height="22" hidden="false" label="Info" name="Info"
30 label_selected="Activate" left="12" mouse_opaque="true" name="Activate" 29 width="80" />
31 scale_image="true" tab_stop="true" width="80" /> 30 <button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
32 <button border_height="16" border_width="16" bottom="-268" enabled="true" 31 label="IM/Call" left_delta="0" name="IM"
33 follows="left|bottom" font="SansSerif" halign="center" height="20" 32 tool_tip="Open Instant Message session" width="80" />
34 hidden="false" label="Info" 33 <button border_height="16" border_width="16" bottom_delta="-25" follows="top|right"
35 label_selected="Info" left="100" mouse_opaque="true" name="Info" 34 font="SansSerif" height="22" hidden="false" label="Activate"
36 scale_image="true" tab_stop="true" width="80" /> 35 name="Activate" width="80" />
37 <button border_height="16" border_width="16" bottom="-268" enabled="true" 36 <button border_height="16" border_width="16" bottom_delta="-25" follows="top|right"
38 follows="left|bottom" font="SansSerif" halign="center" height="20" 37 font="SansSerif" height="22" hidden="false" label="Leave" name="Leave"
39 hidden="false" label="Leave" 38 width="80" />
40 label_selected="Leave" left="188" mouse_opaque="true" name="Leave" 39 <button border_height="16" border_width="16" bottom_delta="-35" follows="top|right"
41 scale_image="true" tab_stop="true" width="80" /> 40 font="SansSerif" height="22" hidden="false" label="Create..." name="Create"
42 <button border_height="16" border_width="16" bottom="-292" enabled="true" 41 width="80" />
43 follows="left|bottom" font="SansSerif" halign="center" height="20" 42 <button border_height="16" border_width="16" bottom_delta="-25" follows="top|right"
44 hidden="false" label="Create" 43 font="SansSerif" height="22" hidden="false" label="Search..."
45 label_selected="Create" left="12" mouse_opaque="true" name="Create" 44 name="Search..." width="80" />
46 scale_image="true" tab_stop="true" width="80" />
47 <button border_height="16" border_width="16" bottom="-292" enabled="true"
48 follows="left|bottom" font="SansSerif" halign="center" height="20"
49 hidden="false" label="Search..."
50 label_selected="Search..." left="100" mouse_opaque="true" name="Search..."
51 scale_image="true" tab_stop="true" width="80" />
52 <button border_height="16" border_width="16" bottom="-292" enabled="true"
53 follows="left|bottom" font="SansSerif" halign="center" height="20"
54 hidden="false" label="Close"
55 label_selected="Close" left="188" mouse_opaque="true" name="Close"
56 scale_image="true" tab_stop="true" width="80" />
57</floater> 45</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_im.xml b/linden/indra/newview/skins/xui/en-us/floater_im.xml
index 89595a9..fee153a 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_im.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_im.xml
@@ -7,31 +7,34 @@
7 <tab_container border="false" bottom="-422" enabled="true" follows="left|top|right|bottom" 7 <tab_container border="false" bottom="-422" enabled="true" follows="left|top|right|bottom"
8 height="406" hidden="false" left="1" mouse_opaque="false" 8 height="406" hidden="false" left="1" mouse_opaque="false"
9 name="Preview Tabs" tab_position="bottom" width="417" /> 9 name="Preview Tabs" tab_position="bottom" width="417" />
10 <text follows="left|bottom" hidden="true" name="only_user_message"> 10 <string name="only_user_message">
11 You are the only user in this session. 11 You are the only user in this session.
12 </text> 12 </string>
13 <text follows="left|bottom" hidden="true" name="offline_message"> 13 <string name="offline_message">
14 [FIRST] [LAST] is offline. 14 [FIRST] [LAST] is offline.
15 </text> 15 </string>
16 <text hidden="true" name="generic_request_error"> 16 <string name="generic_request_error">
17 Error making request, please try again later. 17 Error making request, please try again later.
18 </text> 18 </string>
19 <text hidden="true" name="insufficient_perms_error"> 19 <string name="insufficient_perms_error">
20 You do not have sufficient permissions. 20 You do not have sufficient permissions.
21 </text> 21 </string>
22 <text hidden="true" name="user_no_help"> 22 <string name="user_no_help">
23 The requested user is no longer in the help session. 23 The requested user is no longer in the help session.
24 </text> 24 </string>
25 <text hidden="true" name="add_session_event"> 25 <string name="add_session_event">
26 adding agents to chat session with 26 adding agents to chat session with
27 </text> 27 </string>
28 <text hidden="true" name="message_session_event"> 28 <string name="message_session_event">
29 messaging chat session with 29 messaging chat session with
30 </text> 30 </string>
31 <text hidden="true" name="teleport_session_event"> 31 <string name="teleport_session_event">
32 teleporting to creator of 32 teleporting to creator of
33 </text> 33 </string>
34 <text hidden="true" name="removed_from_group"> 34 <string name="removed_from_group">
35 You have been removed from the group. 35 You have been removed from the group.
36 </text> 36 </string>
37 <string name="invite_message">
38 Click the [BUTTON NAME] button to accept/connect to this voice chat.
39 </string>
37</multi_floater> 40</multi_floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_instant_message.xml b/linden/indra/newview/skins/xui/en-us/floater_instant_message.xml
index f5b11d6..637c8ba 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_instant_message.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_instant_message.xml
@@ -4,7 +4,7 @@
4 bottom="-298" 4 bottom="-298"
5 can_close="true" 5 can_close="true"
6 can_drag_on_left="false" 6 can_drag_on_left="false"
7 can_minimize="false" 7 can_minimize="true"
8 can_resize="true" 8 can_resize="true"
9 enabled="true" 9 enabled="true"
10 follows="left|top|right|bottom" 10 follows="left|top|right|bottom"
@@ -12,33 +12,60 @@
12 hidden="false" 12 hidden="false"
13 label="(unknown)" 13 label="(unknown)"
14 left="1" 14 left="1"
15 min_height="130" 15 min_height="155"
16 min_width="200" 16 min_width="345"
17 mouse_opaque="true" 17 mouse_opaque="true"
18 name="im_floater" 18 name="im_floater"
19 rect_control="" 19 rect_control=""
20 title="(unknown)" 20 title="(unknown)"
21 width="501" 21 width="501"
22 default_tab_group="1"> 22 default_tab_group="1">
23 <string name="ringing">Calling...</string>
24 <string name="connected">Connected, click End Call to hang up</string>
25 <string name="hang_up">Call ended</string>
26
27 <button left="4" bottom="-40" height="20" width="70" label="Profile..." follows="left|top" name="profile_callee_btn"/>
28 <button left_delta="75" bottom="-40" height="20" width="70" label="Call" follows="left|top" name="start_call_btn"/>
29 <button left_delta="0" bottom="-40" height="20" width="70" label="End Call" follows="left|top" name="end_call_btn" visible="false"/>
30 <panel left_delta="72" bottom="-40" height="20" width="344" border="false" name="speaker_controls" follows="left|top|right">
31 <volume_slider
32 name="speaker_volume"
33 enabled="false"
34 left="0"
35 width="80"
36 bottom="0"
37 height="15"
38 follows="left|bottom"
39 min_val="0.0"
40 max_val="1.0"
41 increment="0.05"
42 initial_val="0.5"
43 />
44 <check_box
45 name="mute_btn"
46 enabled="false"
47 left_delta="85"
48 bottom_delta="0"
49 width="70"
50 height="25"
51 label="Mute voice chat"
52 />
53 </panel>
23 <text_editor type="string" length="1" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor" 54 <text_editor type="string" length="1" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor"
24 bottom="-275" embedded_items="false" enabled="false" 55 bottom="28" embedded_items="false" enabled="false"
25 follows="left|top|right|bottom" font="SansSerif" height="257" 56 follows="left|top|right|bottom" font="SansSerif" height="225"
26 hidden="false" left="4" max_length="2147483647" mouse_opaque="true" 57 hidden="false" left="4" max_length="2147483647" mouse_opaque="true"
27 name="im_history" text_color="ChatHistoryTextColor" 58 name="im_history" text_color="ChatHistoryTextColor"
28 text_readonly_color="ChatHistoryTextColor" width="490" word_wrap="true" /> 59 text_readonly_color="ChatHistoryTextColor" width="490" word_wrap="true" />
29 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="-295" 60 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="5"
30 enabled="true" follows="left|right|bottom" font="SansSerif" 61 enabled="true" follows="left|right|bottom" font="SansSerif"
31 handle_edit_keys_directly="false" height="20" hidden="false" left="4" 62 handle_edit_keys_directly="false" height="20" hidden="false" left="6"
32 max_length="1022" mouse_opaque="true" name="chat_editor" 63 max_length="1022" mouse_opaque="true" name="chat_editor"
33 select_all_on_focus_received="false" select_on_focus="false" tab_group="1" 64 select_all_on_focus_received="false" select_on_focus="false" tab_group="1"
34 width="345" label="Click here to instant message" /> 65 width="421" label="Click here to instant message" />
35 <button bottom="-295" enabled="true" follows="right|bottom" font="SansSerif" 66 <button bottom="4" enabled="true" follows="right|bottom" font="SansSerif"
36 halign="center" height="20" hidden="false" label="Profile..." 67 halign="center" height="20" hidden="false" label="Send"
37 label_selected="Profile..." left="355" mouse_opaque="true" 68 left="432" mouse_opaque="true" name="send_btn"
38 name="profile_btn" scale_image="true" width="70" />
39 <button bottom="-295" enabled="true" follows="right|bottom" font="SansSerif"
40 halign="center" height="20" hidden="false" label="Close"
41 label_selected="Close" left="430" mouse_opaque="true" name="close_btn"
42 scale_image="true" width="60" /> 69 scale_image="true" width="60" />
43 <text hidden="true" name="live_help_dialog" wordwrap="false"> 70 <text hidden="true" name="live_help_dialog" wordwrap="false">
44 *** Welcome to Help Request *** 71 *** Welcome to Help Request ***
diff --git a/linden/indra/newview/skins/xui/en-us/floater_instant_message_ad_hoc.xml b/linden/indra/newview/skins/xui/en-us/floater_instant_message_ad_hoc.xml
new file mode 100644
index 0000000..f58273e
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_instant_message_ad_hoc.xml
@@ -0,0 +1,119 @@
1<!-- This is the _embedded_ instant message panel, not the floater that
2 contains all the instant messages. See floater_im.xml. JC -->
3<floater border="true"
4 bottom="-298"
5 can_close="true"
6 can_drag_on_left="false"
7 can_minimize="false"
8 can_resize="true"
9 enabled="true"
10 follows="left|top|right|bottom"
11 height="297"
12 hidden="false"
13 label="(unknown)"
14 left="1"
15 min_height="225"
16 min_width="265"
17 mouse_opaque="true"
18 name="im_floater"
19 rect_control=""
20 title="(unknown)"
21 width="501"
22 default_tab_group="1">
23
24 <string name="ringing">Joining Voice Chat...</string>
25 <string name="connected">Connected, click End Call to hang up</string>
26 <string name="hang_up">Left Voice Chat</string>
27
28 <layout_stack border="false" left="2" bottom="1" width="495" height="277" follows="left|top|right|bottom" orientation="horizontal" tab_group="1">
29 <layout_panel border="false" name="im_contents_panel" min_width="115" left="0" bottom="0" width="495" height="295" follows="left|top|bottom|right" default_tab_group="1">
30 <button left="4" bottom="-24" height="20" width="70" label="Call" enabled="false" follows="left|top" name="start_call_btn"/>
31 <button left_delta="0" bottom_delta="0" height="20" width="70" label="End Call" follows="left|top" name="end_call_btn" visible="false"/>
32 <button left="460" right="493" bottom_delta="0" height="20" width="70" label="&lt; &lt;" label_selected="&gt; &gt;" follows="right|top" name="toggle_active_speakers_btn" visible="true" tool_tip="Click here to show list of active partipants in this IM session."/>
33
34 <text_editor type="string" length="1" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor"
35 bottom="-268" embedded_items="false" enabled="false"
36 follows="left|top|right|bottom" font="SansSerif" height="240"
37 hidden="false" left="4" max_length="2147483647" mouse_opaque="true"
38 name="im_history" text_color="ChatHistoryTextColor"
39 text_readonly_color="ChatHistoryTextColor" width="490" word_wrap="true" />
40 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="4"
41 enabled="true" follows="left|right|bottom" font="SansSerif"
42 handle_edit_keys_directly="false" height="20" hidden="false" left="4"
43 max_length="1022" mouse_opaque="true" name="chat_editor"
44 select_all_on_focus_received="false" select_on_focus="false" tab_group="1"
45 width="425" label="Click here to instant message" />
46 <button bottom_delta="-1" enabled="true" follows="right|bottom" font="SansSerif"
47 halign="center" height="20" hidden="false" label="Send"
48 left="433" mouse_opaque="true" name="send_btn"
49 scale_image="true" width="60" />
50 </layout_panel>
51
52
53 <layout_panel auto_resize="false" can_resize="true" min_width="145" name="active_speakers_panel" top_delta="0" left="0" bottom="0" width="145" height="120" visible="false">
54 <scroll_list name="speakers_list" left="0" right="145" top="120" bottom="78" column_padding="0" can_resize="false" follows="left|top|bottom|right" draw_heading="true" draw_stripes="false" multi_select="false" search_column="1">
55 <column name="icon_speaking_status" width="20" sort="speaking_status"/>
56 <column name="speaker_name" label="Name" dynamicwidth="true"/>
57 <column name="speaking_status" label="" width="0"/>
58 </scroll_list>
59 <panel name="volume_container" follows="left|bottom|right" left="0" right="145" bottom="0" border="true" mouse_opaque="true" bevel_style="in" can_resize="false" height="77">
60 <button left="0" right="30" bottom="-28" height="24" name="profile_btn" follows="left|top" label="" image_overlay="icon_avatar_offline.tga" enabled="false"/>
61 <text left_delta="34" bottom_delta="9" name="resident_name" valign="center" follows="left|top|right" width="110" font="SansSerif">Rumplstiltskin Califragilistic</text>
62 <volume_slider
63 name="speaker_volume"
64 left="5"
65 width="85"
66 bottom_delta="-29"
67 height="15"
68 follows="left|top"
69 min_val="0.0"
70 max_val="1.0"
71 increment="0.05"
72 initial_val="0.5"
73 />
74 <text type="string" width="45" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
75 drop_shadow_visible="true" enabled="true" follows="left|top"
76 font="SansSerifSmall" height="16" hidden="false"
77 left="4" mouse_opaque="true" bottom_delta="-25" name="Mute:" v_pad="0">
78 Mute:
79 </text>
80 <check_box
81 name="mute_text_btn"
82 width="50"
83 bottom_delta="0"
84 left_delta="32"
85 follows="left|top"
86 height="25"
87 enabled="false"
88 label="Text"
89 />
90 <check_box
91 name="mute_btn"
92 follows="left|top"
93 width="50"
94 bottom_delta="0"
95 left_delta="45"
96 height="25"
97 enabled="false"
98 label="Voice"
99 />
100
101 </panel>
102 </layout_panel>
103 </layout_stack>
104 <text hidden="true" name="live_help_dialog" wordwrap="false">
105 *** Welcome to Help Request ***
106Please first check our SL Help Pages by pressing F1, or by accessing the Knowledge Base http://secondlife.com/knowledgebase/
107If your answer is not there, please enter your question to begin, then allow a few moments for available helpers to respond.
108-=-=- Response times will vary, especially during peak times -=-=-
109 </text>
110 <text hidden="true" name="title_string">
111 Instant Message with [NAME]
112 </text>
113 <text hidden="true" name="typing_start_string">
114 [NAME] is typing...
115 </text>
116 <text hidden="true" name="session_start_string">
117 Starting session with [NAME] please wait.
118 </text>
119</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_instant_message_group.xml b/linden/indra/newview/skins/xui/en-us/floater_instant_message_group.xml
new file mode 100644
index 0000000..1b7dd4e
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_instant_message_group.xml
@@ -0,0 +1,160 @@
1<!-- This is the _embedded_ instant message panel, not the floater that
2 contains all the instant messages. See floater_im.xml. JC -->
3<floater border="true"
4 bottom="-297"
5 can_close="true"
6 can_drag_on_left="false"
7 can_minimize="false"
8 can_resize="true"
9 enabled="true"
10 follows="left|top|right|bottom"
11 height="296"
12 hidden="false"
13 label="(unknown)"
14 left="1"
15 min_height="200"
16 min_width="340"
17 mouse_opaque="true"
18 name="im_floater"
19 rect_control=""
20 title="(unknown)"
21 width="501"
22 default_tab_group="1">
23
24 <string name="ringing">Joining Voice Chat...</string>
25 <string name="connected">Connected, click End Call to hang up</string>
26 <string name="hang_up">Left Voice Chat</string>
27
28 <layout_stack border="false" left="2" bottom="1" width="495" height="276" follows="left|top|right|bottom" orientation="horizontal" tab_group="1">
29 <layout_panel border="false" name="im_contents_panel" min_width="185" left="0" bottom="0" width="175" height="130" follows="left|top|bottom|right" default_tab_group="1">
30
31 <button left="4"
32 height="20"
33 width="70"
34 tab_group="0"
35 label="Group Info..."
36 follows="left|top"
37 name="group_info_btn"/>
38
39 <button left_delta="75"
40 bottom_delta="0"
41 height="20"
42 width="70"
43 label="Join Call"
44 enabled="false"
45 follows="left|top"
46 name="start_call_btn"/>
47
48 <button bottom_delta="0" height="20" left_delta="0" width="70" label="End Call" follows="left|top" name="end_call_btn" visible="false"/>
49 <button left="140" right="173" bottom_delta="0" height="20" width="70" label="&lt; &lt;" label_selected="&gt; &gt;" follows="right|top" name="toggle_active_speakers_btn" visible="true" tool_tip="Click here to show list of active partipants in this IM session."/>
50
51 <text_editor type="string"
52 length="1"
53 bg_readonly_color="ChatHistoryBgColor"
54 bg_writeable_color="ChatHistoryBgColor"
55 bottom="27"
56 top="102"
57 embedded_items="false"
58 enabled="false"
59 follows="left|top|right|bottom"
60 font="SansSerif"
61 hidden="false"
62 left="4"
63 max_length="2147483647"
64 mouse_opaque="true"
65 name="im_history"
66 text_color="ChatHistoryTextColor"
67 text_readonly_color="ChatHistoryTextColor"
68 width="170"
69 word_wrap="true"/>
70
71 <line_editor bevel_style="in"
72 border_style="line"
73 border_thickness="1"
74 bottom="4" enabled="true"
75 follows="left|right|bottom"
76 font="SansSerif"
77 handle_edit_keys_directly="false"
78 height="20"
79 hidden="false"
80 left="4"
81 max_length="1022"
82 mouse_opaque="true"
83 name="chat_editor"
84 select_all_on_focus_received="false"
85 select_on_focus="false"
86 tab_group="1"
87 width="105"
88 label="Click here to instant message"/>
89
90 <button bottom="3" enabled="true" follows="right|bottom" font="SansSerif" halign="center" height="20" hidden="false" label="Send" left="113" mouse_opaque="true" name="send_btn" scale_image="true" width="60"/>
91 <text hidden="true" name="live_help_dialog" wordwrap="false">
92 *** Welcome to Help Request ***
93 Please first check our SL Help Pages by pressing F1, or by accessing the Knowledge Base http://secondlife.com/knowledgebase/
94 If your answer is not there, please enter your question to begin, then allow a few moments for available helpers to respond.
95 -=-=- Response times will vary, especially during peak times -=-=-
96 </text>
97 <text hidden="true" name="title_string">
98 Instant Message with [NAME]
99 </text>
100 <text hidden="true" name="typing_start_string">
101 [NAME] is typing...
102 </text>
103 <text hidden="true" name="session_start_string">
104 Starting session with [NAME] please wait.
105 </text>
106 </layout_panel>
107
108 <layout_panel auto_resize="false" can_resize="true" min_width="145" name="active_speakers_panel" top_delta="0" left="0" bottom="0" width="145" height="120" visible="false">
109 <scroll_list name="speakers_list" left="0" right="145" top="120" bottom="78" column_padding="0" can_resize="false" follows="left|top|bottom|right" draw_heading="true" draw_stripes="false" multi_select="false" search_column="1">
110 <column name="icon_speaking_status" width="20" sort="speaking_status"/>
111 <column name="speaker_name" label="Name" dynamicwidth="true"/>
112 <column name="speaking_status" label="" width="0"/>
113 </scroll_list>
114 <panel name="volume_container" follows="left|bottom|right" auto_resize="false" left="0" right="145" bottom="0" border="true" mouse_opaque="true" bevel_style="in" can_resize="false" height="77">
115 <button left="0" right="30" bottom="-28" height="24" name="profile_btn" follows="left|top" label="" image_overlay="icon_avatar_offline.tga" enabled="false"/>
116 <text left_delta="34" bottom_delta="9" name="resident_name" valign="center" follows="left|top|right" width="110" font="SansSerif">Rumplstiltskin Califragilistic</text>
117 <volume_slider
118 name="speaker_volume"
119 left="5"
120 width="85"
121 bottom_delta="-29"
122 height="15"
123 follows="left|top"
124 min_val="0.0"
125 max_val="1.0"
126 increment="0.05"
127 initial_val="0.5"
128 />
129 <text type="string" width="45" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
130 drop_shadow_visible="true" enabled="true" follows="left|top"
131 font="SansSerifSmall" height="16" hidden="false"
132 left="4" mouse_opaque="true" bottom_delta="-25" name="Mute:" v_pad="0">
133 Mute:
134 </text>
135 <check_box
136 name="mute_text_btn"
137 width="50"
138 bottom_delta="0"
139 left_delta="32"
140 follows="left|top"
141 height="25"
142 enabled="false"
143 label="Text"
144 />
145 <check_box
146 name="mute_btn"
147 follows="left|top"
148 width="50"
149 bottom_delta="0"
150 left_delta="45"
151 height="25"
152 enabled="false"
153 label="Voice"
154 />
155
156 </panel>
157 </layout_panel>
158
159 </layout_stack>
160</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_inventory_item_properties.xml b/linden/indra/newview/skins/xui/en-us/floater_inventory_item_properties.xml
index d3bc3fa..040406e 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_inventory_item_properties.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_inventory_item_properties.xml
@@ -34,7 +34,7 @@
34 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 34 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
35 bottom="-81" drop_shadow_visible="true" follows="left|top" 35 bottom="-81" drop_shadow_visible="true" follows="left|top"
36 font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="78" 36 font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="78"
37 mouse_opaque="true" name="LabelCreatorName" v_pad="0" width="88"> 37 mouse_opaque="true" name="LabelCreatorName" v_pad="0" width="200">
38 Nicole Linden 38 Nicole Linden
39 </text> 39 </text>
40 <button bottom="-81" follows="top|right" font="SansSerifSmall" halign="center" 40 <button bottom="-81" follows="top|right" font="SansSerifSmall" halign="center"
@@ -49,7 +49,7 @@
49 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 49 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
50 bottom="-101" drop_shadow_visible="true" follows="left|top" 50 bottom="-101" drop_shadow_visible="true" follows="left|top"
51 font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="78" 51 font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="78"
52 mouse_opaque="true" name="LabelOwnerName" v_pad="0" width="88"> 52 mouse_opaque="true" name="LabelOwnerName" v_pad="0" width="200">
53 Thrax Linden 53 Thrax Linden
54 </text> 54 </text>
55 <button bottom="-101" follows="top|right" font="SansSerifSmall" halign="center" 55 <button bottom="-101" follows="top|right" font="SansSerifSmall" halign="center"
diff --git a/linden/indra/newview/skins/xui/en-us/floater_my_friends.xml b/linden/indra/newview/skins/xui/en-us/floater_my_friends.xml
new file mode 100644
index 0000000..50c69c6
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_my_friends.xml
@@ -0,0 +1,9 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater can_close="false" can_minimize="true" can_drag_on_left="false" can_tear_off="false" can_resize="true" height="390" min_height="240" min_width="365" name="floater_my_friends"
3 title="Contacts"
4 width="395">
5 <tab_container bottom="10" height="360" tab_width="80" follows="left|right|top|bottom" left="0" name="friends_and_groups" tab_position="left" width="388">
6 <panel label="Friends" filename="panel_friends.xml" bottom="0" left="0" width="370" name="friends_panel"/>
7 <panel label="Groups" filename="panel_groups.xml" bottom="0" left="0" width="370" name="groups_panel"/>
8 </tab_container>
9</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_report_bug.xml b/linden/indra/newview/skins/xui/en-us/floater_report_bug.xml
index bafb11c..916ee85 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_report_bug.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_report_bug.xml
@@ -71,7 +71,7 @@
71 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 71 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
72 bottom="-160" drop_shadow_visible="true" follows="left|top" 72 bottom="-160" drop_shadow_visible="true" follows="left|top"
73 font="SansSerifSmall" h_pad="0" halign="left" height="16" left="16" 73 font="SansSerifSmall" h_pad="0" halign="left" height="16" left="16"
74 mouse_opaque="true" name="category_label" v_pad="0" width="50"> 74 mouse_opaque="true" name="category_label" v_pad="0" width="60">
75 Category: 75 Category:
76 </text> 76 </text>
77 <combo_box bottom_delta="-20" follows="left|top" height="20" left="16" mouse_opaque="true" 77 <combo_box bottom_delta="-20" follows="left|top" height="20" left="16" mouse_opaque="true"
@@ -136,7 +136,7 @@
136 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 136 <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
137 bottom_delta="-25" drop_shadow_visible="true" follows="left|top" 137 bottom_delta="-25" drop_shadow_visible="true" follows="left|top"
138 font="SansSerifSmall" h_pad="0" halign="left" height="16" left="16" 138 font="SansSerifSmall" h_pad="0" halign="left" height="16" left="16"
139 mouse_opaque="true" name="sum_title" v_pad="0" width="50"> 139 mouse_opaque="true" name="sum_title" v_pad="0" width="60">
140 Summary: 140 Summary:
141 </text> 141 </text>
142 <line_editor bevel_style="in" bg_readonly_color="0, 0, 0, 0" border_style="line" 142 <line_editor bevel_style="in" bg_readonly_color="0, 0, 0, 0" border_style="line"
diff --git a/linden/indra/newview/skins/xui/en-us/floater_select_key.xml b/linden/indra/newview/skins/xui/en-us/floater_select_key.xml
new file mode 100644
index 0000000..7c2221f
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_select_key.xml
@@ -0,0 +1,15 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater border="true" bottom="372" can_close="false" can_drag_on_left="false"
3 can_minimize="false" can_resize="false" can_tear_off="true" enabled="true"
4 height="100" hidden="false" left="415" min_height="100" min_width="100"
5 mouse_opaque="true" name="modal container" title=" " width="240">
6 <button bottom="-90" enabled="true" font="SansSerif" halign="center" height="20"
7 hidden="false" label="Cancel" label_selected="Cancel" left="138"
8 mouse_opaque="true" name="Cancel" scale_image="true" width="82" />
9 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
10 bottom="-26" drop_shadow_visible="true" enabled="true" follows="left|top"
11 font="SansSerif" h_pad="0" halign="left" height="16" hidden="false"
12 left="20" mouse_opaque="true" name="Save item as:" v_pad="0" width="200">
13 Press a key to select
14 </text>
15</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_settings_debug.xml b/linden/indra/newview/skins/xui/en-us/floater_settings_debug.xml
index 994aa70..43c6aa0 100644
--- a/linden/indra/newview/skins/xui/en-us/floater_settings_debug.xml
+++ b/linden/indra/newview/skins/xui/en-us/floater_settings_debug.xml
@@ -3,8 +3,8 @@
3 title="Debug Settings" width="350"> 3 title="Debug Settings" width="350">
4 <combo_box allow_text_entry="true" bottom="-50" follows="top|left" font="SansSerifSmall" 4 <combo_box allow_text_entry="true" bottom="-50" follows="top|left" font="SansSerifSmall"
5 height="20" left="15" max_chars="255" name="settings_combo" /> 5 height="20" left="15" max_chars="255" name="settings_combo" />
6 <text_editor bottom_delta="-75" enabled="false" height="60" name="comment_text" 6 <text_editor bottom_delta="-75" enabled="false" height="60" hide_scrollbar="true"
7 word_wrap="true" /> 7 name="comment_text" word_wrap="true" />
8 <combo_box bottom_delta="-30" follows="top|left" font="SansSerifSmall" height="20" 8 <combo_box bottom_delta="-30" follows="top|left" font="SansSerifSmall" height="20"
9 left="15" name="boolean_combo" visible="false"> 9 left="15" name="boolean_combo" visible="false">
10 <combo_item name="TRUE" value="true"> 10 <combo_item name="TRUE" value="true">
@@ -25,5 +25,6 @@
25 max_val="10000000" name="val_spinner_3" visible="false" width="120" /> 25 max_val="10000000" name="val_spinner_3" visible="false" width="120" />
26 <spinner bottom_delta="0" height="20" label="x" label_width="40" left_delta="135" 26 <spinner bottom_delta="0" height="20" label="x" label_width="40" left_delta="135"
27 max_val="10000000" name="val_spinner_4" visible="false" width="120" /> 27 max_val="10000000" name="val_spinner_4" visible="false" width="120" />
28 <button bottom="5" left="15" height="20" width="150" name="default_btn" label="Reset to default"/> 28 <button bottom="5" height="20" label="Reset to default" left="15" name="default_btn"
29 width="150" />
29</floater> 30</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_test.xml b/linden/indra/newview/skins/xui/en-us/floater_test.xml
new file mode 100644
index 0000000..354cc73
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_test.xml
@@ -0,0 +1,5 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater bottom="40" left="40" height="225" width="180"
3 can_resize="false" can_close="true" can_drag_on_left="false" can_minimize="true"
4 name="Test" title="Test">
5</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/floater_voice_wizard.xml b/linden/indra/newview/skins/xui/en-us/floater_voice_wizard.xml
new file mode 100644
index 0000000..d17cb56
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/floater_voice_wizard.xml
@@ -0,0 +1,17 @@
1<floater bottom="0" can_resize="false" can_minimize="true" height="300" left="0" name="floater_voice_wizard"
2 title="Voice Setup" width="420">
3 <tab_container name="wizard_tabs" hide_tabs="true" bottom="30" left="4" top="-20" right="-2" tab_position="bottom">
4 <panel bottom="0" filename="panel_voice_enable.xml" left="0" right="0"/>
5 <panel bottom="0" filename="panel_voice_options.xml" left="0" right="0"/>
6 <panel bottom="0" name="device_settings" filename="panel_audio_device.xml" left="0" right="0"/>
7 </tab_container>
8 <panel border="false" bottom="8" height="20" left="8" mouse_opaque="true"
9 name="content_panel" width="404">
10 <!--<button bottom="0" height="20" label="Help" left="0" name="help_btn" width="70" />-->
11 <button bottom="0" height="20" label="Previous" left="105" name="back_btn" width="70" />
12 <button bottom="0" height="20" label="Next" left_delta="75" name="next_btn" width="70" />
13 <button bottom="0" height="20" label="Finish" left_delta="80" name="ok_btn" width="70" />
14 <button bottom="0" height="20" label="Cancel" left_delta="75" name="cancel_btn"
15 width="70" />
16 </panel>
17</floater>
diff --git a/linden/indra/newview/skins/xui/en-us/menu_inventory.xml b/linden/indra/newview/skins/xui/en-us/menu_inventory.xml
index bd955e3..a57a8b6 100644
--- a/linden/indra/newview/skins/xui/en-us/menu_inventory.xml
+++ b/linden/indra/newview/skins/xui/en-us/menu_inventory.xml
@@ -160,6 +160,10 @@
160 <on_click filter="" function="Inventory.DoToSelected" userdata="delete" /> 160 <on_click filter="" function="Inventory.DoToSelected" userdata="delete" />
161 </menu_item_call> 161 </menu_item_call>
162 <menu_item_separator name="Folder Wearables Separator" /> 162 <menu_item_separator name="Folder Wearables Separator" />
163 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Take Off Items" left="0"
164 mouse_opaque="true" name="Take Off Items" width="128">
165 <on_click filter="" function="Inventory.DoToSelected" userdata="removefromoutfit" />
166 </menu_item_call>
163 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Add To Outfit" left="0" 167 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Add To Outfit" left="0"
164 mouse_opaque="true" name="Add To Outfit" width="128"> 168 mouse_opaque="true" name="Add To Outfit" width="128">
165 <on_click filter="" function="Inventory.DoToSelected" userdata="addtooutfit" /> 169 <on_click filter="" function="Inventory.DoToSelected" userdata="addtooutfit" />
@@ -168,10 +172,6 @@
168 mouse_opaque="true" name="Replace Outfit" width="128"> 172 mouse_opaque="true" name="Replace Outfit" width="128">
169 <on_click filter="" function="Inventory.DoToSelected" userdata="replaceoutfit" /> 173 <on_click filter="" function="Inventory.DoToSelected" userdata="replaceoutfit" />
170 </menu_item_call> 174 </menu_item_call>
171 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Take Off Items" left="0"
172 mouse_opaque="true" name="Take Off Items" width="128">
173 <on_click filter="" function="Inventory.DoToSelected" userdata="removefromoutfit" />
174 </menu_item_call>
175 <menu_item_separator name="Calling Card Separator" /> 175 <menu_item_separator name="Calling Card Separator" />
176 <menu_item_call bottom_delta="-18" height="18" hidden="false" 176 <menu_item_call bottom_delta="-18" height="18" hidden="false"
177 label="Start Conference Chat" left="0" mouse_opaque="true" 177 label="Start Conference Chat" left="0" mouse_opaque="true"
@@ -235,14 +235,14 @@
235 mouse_opaque="true" name="Attach To HUD" opaque="true" tear_off="false" 235 mouse_opaque="true" name="Attach To HUD" opaque="true" tear_off="false"
236 width="128" /> 236 width="128" />
237 <menu_item_separator name="Wearable Separator" /> 237 <menu_item_separator name="Wearable Separator" />
238 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Wear" left="0"
239 mouse_opaque="true" name="Wearable Wear" width="128">
240 <on_click filter="" function="Inventory.DoToSelected" userdata="wear" />
241 </menu_item_call>
242 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Edit" left="0" 238 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Edit" left="0"
243 mouse_opaque="true" name="Wearable Edit" width="128"> 239 mouse_opaque="true" name="Wearable Edit" width="128">
244 <on_click filter="" function="Inventory.DoToSelected" userdata="edit" /> 240 <on_click filter="" function="Inventory.DoToSelected" userdata="edit" />
245 </menu_item_call> 241 </menu_item_call>
242 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Wear" left="0"
243 mouse_opaque="true" name="Wearable Wear" width="128">
244 <on_click filter="" function="Inventory.DoToSelected" userdata="wear" />
245 </menu_item_call>
246 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Take Off" left="0" 246 <menu_item_call bottom_delta="-18" height="18" hidden="false" label="Take Off" left="0"
247 mouse_opaque="true" name="Take Off" width="128"> 247 mouse_opaque="true" name="Take Off" width="128">
248 <on_click filter="" function="Inventory.DoToSelected" userdata="take_off" /> 248 <on_click filter="" function="Inventory.DoToSelected" userdata="take_off" />
diff --git a/linden/indra/newview/skins/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/xui/en-us/menu_viewer.xml
index c14ba4b..4d30c05 100644
--- a/linden/indra/newview/skins/xui/en-us/menu_viewer.xml
+++ b/linden/indra/newview/skins/xui/en-us/menu_viewer.xml
@@ -62,7 +62,7 @@
62 </menu_item_call> 62 </menu_item_call>
63 <menu_item_call bottom="-186" enabled="true" height="19" hidden="false" 63 <menu_item_call bottom="-186" enabled="true" height="19" hidden="false"
64 label="Snapshot to Disk" left="0" mouse_opaque="true" 64 label="Snapshot to Disk" left="0" mouse_opaque="true"
65 name="Snapshot to Disk" shortcut="control|`" width="243"> 65 name="Snapshot to Disk" shortcut="control|`" useMacCtrl="true" width="243">
66 <on_click function="File.TakeSnapshotToDisk" userdata="" /> 66 <on_click function="File.TakeSnapshotToDisk" userdata="" />
67 </menu_item_call> 67 </menu_item_call>
68 <menu_item_separator bottom="-194" enabled="true" height="8" hidden="false" label="-----------" 68 <menu_item_separator bottom="-194" enabled="true" height="8" hidden="false" label="-----------"
@@ -318,6 +318,11 @@
318 width="211"> 318 width="211">
319 <on_click function="ShowFloater" userdata="inventory" /> 319 <on_click function="ShowFloater" userdata="inventory" />
320 </menu_item_call> 320 </menu_item_call>
321 <menu_item_check bottom="-189" enabled="true" height="19" hidden="false" label="Active Speakers"
322 left="0" mouse_opaque="true" name="Active Speakers" width="211">
323 <on_click function="ShowFloater" userdata="active speakers" />
324 <on_check function="FloaterVisible" userdata="active speakers" />
325 </menu_item_check>
321 <menu_item_check bottom="-189" enabled="true" height="19" hidden="false" label="Mute List" 326 <menu_item_check bottom="-189" enabled="true" height="19" hidden="false" label="Mute List"
322 left="0" mouse_opaque="true" name="Mute List" width="211"> 327 left="0" mouse_opaque="true" name="Mute List" width="211">
323 <on_click function="ShowFloater" userdata="mute list" /> 328 <on_click function="ShowFloater" userdata="mute list" />
@@ -396,10 +401,10 @@
396 </menu_item_check> 401 </menu_item_check>
397 </menu> 402 </menu>
398 <menu_item_check bottom="-384" enabled="true" height="19" hidden="false" 403 <menu_item_check bottom="-384" enabled="true" height="19" hidden="false"
399 label="Alt Shows Physical" left="0" mouse_opaque="true" 404 label="Beacons Always On" left="0" mouse_opaque="true"
400 name="Alt Shows Physical" width="211"> 405 name="Beacons Always On" width="211" shortcut="control|N">
401 <on_click function="ToggleControl" userdata="AltShowsPhysical" /> 406 <on_click function="ToggleControl" userdata="BeaconAlwaysOn" />
402 <on_check control="AltShowsPhysical" /> 407 <on_check control="BeaconAlwaysOn" />
403 </menu_item_check> 408 </menu_item_check>
404 <menu_item_check bottom="-403" enabled="true" height="19" hidden="false" 409 <menu_item_check bottom="-403" enabled="true" height="19" hidden="false"
405 label="Highlight Transparent" left="0" mouse_opaque="true" 410 label="Highlight Transparent" left="0" mouse_opaque="true"
@@ -410,32 +415,49 @@
410 <menu bottom="-554" color="0 0 0 1" drop_shadow="true" enabled="true" height="117" 415 <menu bottom="-554" color="0 0 0 1" drop_shadow="true" enabled="true" height="117"
411 hidden="false" label="Beacons" left="0" mouse_opaque="false" name="Beacons" 416 hidden="false" label="Beacons" left="0" mouse_opaque="false" name="Beacons"
412 opaque="true" tear_off="true" create_jump_keys="true" width="129"> 417 opaque="true" tear_off="true" create_jump_keys="true" width="129">
413 <menu_item_check bottom="-29" enabled="true" height="19" hidden="false" label="Scripted Objects" 418 <menu_item_check bottom="-29" enabled="true" height="19" hidden="false" label="Scripted Objects with Touch Only"
419 left="0" mouse_opaque="true" name="Scripted Objects With Touch Only" width="129">
420 <on_click function="View.ToggleBeacon" userdata="scripttouchbeacon" />
421 <on_check function="View.CheckBeaconEnabled" userdata="scripttouchbeacon" />
422 </menu_item_check>
423 <menu_item_check bottom="-48" enabled="true" height="19" hidden="false" label="Scripted Objects"
414 left="0" mouse_opaque="true" name="Scripted Objects" width="129"> 424 left="0" mouse_opaque="true" name="Scripted Objects" width="129">
415 <on_click function="View.ToggleBeacon" userdata="scripts" /> 425 <on_click function="View.ToggleBeacon" userdata="scriptsbeacon" />
416 <on_check function="View.CheckBeaconEnabled" userdata="scripts" /> 426 <on_check function="View.CheckBeaconEnabled" userdata="scriptsbeacon" />
417 </menu_item_check> 427 </menu_item_check>
418 <menu_item_check bottom="-48" enabled="true" height="19" hidden="false" label="Physical Objects" 428 <menu_item_check bottom="-67" enabled="true" height="19" hidden="false" label="Physical Objects"
419 left="0" mouse_opaque="true" name="Physical Objects" width="129"> 429 left="0" mouse_opaque="true" name="Physical Objects" width="129">
420 <on_click function="View.ToggleBeacon" userdata="physical" /> 430 <on_click function="View.ToggleBeacon" userdata="physicalbeacon" />
421 <on_check function="View.CheckBeaconEnabled" userdata="physical" /> 431 <on_check function="View.CheckBeaconEnabled" userdata="physicalbeacon" />
422 </menu_item_check> 432 </menu_item_check>
423 <menu_item_check bottom="-67" enabled="true" height="19" hidden="false" label="Sound Sources" 433 <menu_item_check bottom="-86" enabled="true" height="19" hidden="false" label="Sound Sources"
424 left="0" mouse_opaque="true" name="Sound Sources" width="129"> 434 left="0" mouse_opaque="true" name="Sound Sources" width="129">
425 <on_click function="View.ToggleBeacon" userdata="sounds" /> 435 <on_click function="View.ToggleBeacon" userdata="soundsbeacon" />
426 <on_check function="View.CheckBeaconEnabled" userdata="sounds" /> 436 <on_check function="View.CheckBeaconEnabled" userdata="soundsbeacon" />
427 </menu_item_check> 437 </menu_item_check>
428 <menu_item_check bottom="-86" enabled="true" height="19" hidden="false" label="Particle Sources" 438 <menu_item_check bottom="-105" enabled="true" height="19" hidden="false" label="Particle Sources"
429 left="0" mouse_opaque="true" name="Particle Sources" width="129"> 439 left="0" mouse_opaque="true" name="Particle Sources" width="129">
430 <on_click function="View.ToggleBeacon" userdata="particles" /> 440 <on_click function="View.ToggleBeacon" userdata="particlesbeacon" />
431 <on_check function="View.CheckBeaconEnabled" userdata="particles" /> 441 <on_check function="View.CheckBeaconEnabled" userdata="particlesbeacon" />
432 </menu_item_check> 442 </menu_item_check>
433 <menu_item_separator bottom="-94" enabled="true" height="8" hidden="false" label="-----------" 443 <menu_item_separator bottom="-113" enabled="true" height="8" hidden="false" label="-----------"
434 left="0" mouse_opaque="true" name="separator" width="129" /> 444 left="0" mouse_opaque="true" name="separator" width="129" />
435 <menu_item_check bottom="-113" enabled="true" height="19" hidden="false" label="Hide Particles" 445 <menu_item_check bottom="-121" enabled="true" height="19" hidden="false" label="Render Highlights"
446 left="0" mouse_opaque="true" name="Render Highlights" width="129">
447 <on_click function="View.ToggleBeacon" userdata="renderhighlights" />
448 <on_check function="View.CheckBeaconEnabled" userdata="renderhighlights" />
449 </menu_item_check>
450 <menu_item_check bottom="-140" enabled="true" height="19" hidden="false" label="Render Beacons"
451 left="0" mouse_opaque="true" name="Render Beacons" width="129">
452 <on_click function="View.ToggleBeacon" userdata="renderbeacons" />
453 <on_check function="View.CheckBeaconEnabled" userdata="renderbeacons" />
454 </menu_item_check>
455 <menu_item_separator bottom="-159" enabled="true" height="8" hidden="false" label="-----------"
456 left="0" mouse_opaque="true" name="separator" width="129" />
457 <menu_item_check bottom="-167" enabled="true" height="19" hidden="false" label="Hide Particles"
436 left="0" mouse_opaque="true" name="Hide Particles" width="129"> 458 left="0" mouse_opaque="true" name="Hide Particles" width="129">
437 <on_click function="View.ToggleRenderType" userdata="particles" /> 459 <on_click function="View.ToggleRenderType" userdata="hideparticles" />
438 <on_check function="View.CheckRenderType" userdata="particles" /> 460 <on_check function="View.CheckRenderType" userdata="hideparticles" />
439 </menu_item_check> 461 </menu_item_check>
440 </menu> 462 </menu>
441 <menu_item_check bottom="-441" enabled="true" height="19" hidden="false" 463 <menu_item_check bottom="-441" enabled="true" height="19" hidden="false"
@@ -806,6 +828,12 @@
806 <on_click function="PromptShowURL" 828 <on_click function="PromptShowURL"
807 userdata="WebLaunchSecurityIssues,https://wiki.secondlife.com/wiki/Security_issues" /> 829 userdata="WebLaunchSecurityIssues,https://wiki.secondlife.com/wiki/Security_issues" />
808 </menu_item_call> 830 </menu_item_call>
831 <menu_item_call bottom="-94" enabled="true" height="19" hidden="false"
832 label="QA Wiki..." left="0" mouse_opaque="true"
833 name="QA Wiki..." width="166">
834 <on_click function="PromptShowURL"
835 userdata="WebLaunchQAWiki,https://wiki.secondlife.com/wiki/QA_Portal" />
836 </menu_item_call>
809 <menu_item_separator bottom="-411" enabled="true" height="8" hidden="false" label="-----------" 837 <menu_item_separator bottom="-411" enabled="true" height="8" hidden="false" label="-----------"
810 left="0" mouse_opaque="true" name="separator7" width="250" /> 838 left="0" mouse_opaque="true" name="separator7" width="250" />
811 <menu_item_call bottom="-94" enabled="true" height="19" hidden="false" 839 <menu_item_call bottom="-94" enabled="true" height="19" hidden="false"
diff --git a/linden/indra/newview/skins/xui/en-us/notify.xml b/linden/indra/newview/skins/xui/en-us/notify.xml
index 8e51bcb..b21325e 100644
--- a/linden/indra/newview/skins/xui/en-us/notify.xml
+++ b/linden/indra/newview/skins/xui/en-us/notify.xml
@@ -360,25 +360,30 @@ Non-transferable objects that are deeded to the group have been deleted.
360 The objects on the selected parcel that are NOT owned by you have been returned to their owners. 360 The objects on the selected parcel that are NOT owned by you have been returned to their owners.
361 </message> 361 </message>
362 </notify> 362 </notify>
363 <notify name="NotSafe" tip="false"> 363 <notify name="NotSafe" tip="false" unique="true">
364 <message name="message"> 364 <message name="message">
365 This land has damage enabled (&apos;not safe&apos;). 365 This land has damage enabled (&apos;not safe&apos;).
366You can be hurt here. If you die, you will be teleported to your home location. 366You can be hurt here. If you die, you will be teleported to your home location.
367 </message> 367 </message>
368 </notify> 368 </notify>
369 <notify name="NoFly" tip="false"> 369 <notify name="NoFly" tip="false" unique="true">
370 <message name="message"> 370 <message name="message">
371 This land has flying disabled (&apos;no fly&apos;). 371 This land has flying disabled (&apos;no fly&apos;).
372You cannot fly here. 372You cannot fly here.
373 </message> 373 </message>
374 </notify> 374 </notify>
375 <notify name="PushRestricted" tip="false"> 375 <notify name="PushRestricted" tip="false" unique="true">
376 <message name="message"> 376 <message name="message">
377 This land is &apos;llPushObject Restricted&apos;. 377 This land is &apos;llPushObject Restricted&apos;.
378You cannot push others here unless you own the land. 378You cannot push others here unless you own the land.
379 </message> 379 </message>
380 </notify> 380 </notify>
381 <notify name="NoBuild" tip="false"> 381 <notify name="VoiceAvailablity" tip="false" unique="true">
382 <message name="message">
383 This land has voice enabled.
384 </message>
385 </notify>
386 <notify name="NoBuild" tip="false" unique="true">
382 <message name="message"> 387 <message name="message">
383 This land has building disabled (&apos;no build&apos;). 388 This land has building disabled (&apos;no build&apos;).
384You cannot create objects here. 389You cannot create objects here.
@@ -868,4 +873,84 @@ You can find example sculpted textures in the system library.
868from this list. 873from this list.
869 </message> 874 </message>
870 </notify> 875 </notify>
876 <notify name="VoiceInviteP2P" tip="false" unique="true">
877 <message name="message">
878 [NAME] is inviting you to a Voice Chat call.
879Click Accept to join the call or Decline to decline the invitation. Click Mute to mute this caller.
880 </message>
881 <option name="Accept">
882 Accept
883 </option>
884 <option name="Decline">
885 Decline
886 </option>
887 <option name="Mute">
888 Mute
889 </option>
890 </notify>
891 <notify name="VoiceInviteGroup" tip="false" unique="true">
892 <message name="message">
893 [NAME] has joined a Voice Chat call with the group [GROUP].
894Click Accept to join the call or Decline to decline the invitation. Click Mute to mute this caller.
895 </message>
896 <option name="Accept">
897 Accept
898 </option>
899 <option name="Decline">
900 Decline
901 </option>
902 <option name="Mute">
903 Mute
904 </option>
905 </notify>
906 <notify name="VoiceInviteAdHoc" tip="false" unique="true">
907 <message name="message">
908 [NAME] is inviting you to a Voice Chat conference call.
909Click Accept to join the call or Decline to decline the invitation. Click Mute to mute this caller.
910 </message>
911 <option name="Accept">
912 Accept
913 </option>
914 <option name="Decline">
915 Decline
916 </option>
917 <option name="Mute">
918 Mute
919 </option>
920 </notify>
921 <notify name="VoiceChannelFull" tip="true" unique="true">
922 <message name="message">
923 The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later.
924 </message>
925 </notify>
926 <notify name="ProximalVoiceChannelFull" tip="true" unique="true">
927 <message name="message">
928 We're sorry. This area has has reached maximum capacity for voice conversations. Please try to use voice in another area.
929 </message>
930 </notify>
931 <notify name="VoiceChannelDisconnected" tip="true" unique="true">
932 <message name="message">
933 You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to spatial voice chat.
934 </message>
935 </notify>
936 <notify name="VoiceChannelDisconnectedP2P" tip="true" unique="true">
937 <message name="message">
938 [VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to spatial voice chat.
939 </message>
940 </notify>
941 <notify name="P2PCallDeclined" tip="true" unique="true">
942 <message name="message">
943 [VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to spatial voice chat.
944 </message>
945 </notify>
946 <notify name="P2PCallNoAnswer" tip="true" unique="true">
947 <message name="message">
948 [VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to spatial voice chat.
949 </message>
950 </notify>
951 <notify name="VoiceLoginRetry" tip="true" unique="true" duration="10">
952 <message name="message">
953 We are creating a voice channel for you. This may take up to one minute.
954 </message>
955 </notify>
871</notifications> 956</notifications>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_audio.xml b/linden/indra/newview/skins/xui/en-us/panel_audio.xml
new file mode 100644
index 0000000..203f70e
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/panel_audio.xml
@@ -0,0 +1,39 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes"?>
2<panel border="true" enabled="true" follows="left|top|right|bottom"
3 height="180" hidden="false" label="Audio &amp; Video"
4 mouse_opaque="true" name="Media panel" width="160">
5 <check_box bottom="-25" control_name="MuteAudio" enabled="true" follows="left|top"
6 font="SansSerifSmall" height="16" hidden="false" initial_value="false"
7 label="Mute" left="10" mouse_opaque="true" name="disable audio"
8 radio_style="false" width="134" />
9
10 <slider bottom_delta="-20" control_name="AudioLevelMaster" enabled="true" follows="left|top"
11 height="15" hidden="false" increment="0.05" initial_val="0.5" left="10"
12 max_val="1" min_val="0" mouse_opaque="true" name="System Volume" width="120"
13 label="Master" show_text="false" label_width="50" volume="true" />
14 <slider bottom_delta="-20" control_name="AudioLevelMusic" enabled="true" follows="left|top"
15 height="15" hidden="false" increment="0.05" initial_val="0.5" left="10"
16 max_val="1" min_val="0" mouse_opaque="true" name="Music Volume" width="120"
17 label="Music" show_text="false" label_width="50" volume="true" />
18 <slider bottom_delta="-20" control_name="AudioLevelMedia" enabled="true" follows="left|top"
19 height="15" hidden="false" increment="0.05" initial_val="0.5" left="10"
20 max_val="1" min_val="0" mouse_opaque="true" name="Media Volume" width="120"
21 label="Media" show_text="false" label_width="50" volume="true" />
22 <slider bottom_delta="-20" control_name="AudioLevelVoice" enabled="true" follows="left|top"
23 height="15" hidden="false" increment="0.05" initial_val="0.5" left="10"
24 max_val="1" min_val="0" mouse_opaque="true" name="Voice Volume" width="120"
25 label="Voice" show_text="false" label_width="50" volume="true" />
26
27 <slider bottom_delta="-20" control_name="AudioLevelSFX" enabled="true" follows="left|top"
28 height="15" hidden="false" increment="0.05" initial_val="0.5" left="10"
29 max_val="1" min_val="0" mouse_opaque="true" name="SFX Volume" width="120"
30 label="Sounds" show_text="false" label_width="50" volume="true" />
31 <slider bottom_delta="-20" control_name="AudioLevelAmbient" enabled="true" follows="left|top"
32 height="15" hidden="false" increment="0.05" initial_val="0.5" left="10"
33 max_val="1" min_val="0" mouse_opaque="true" name="Wind Volume" width="120"
34 label="Ambient" show_text="false" label_width="50" volume="true" />
35 <slider bottom_delta="-20" control_name="AudioLevelUI" enabled="true" follows="left|top"
36 height="15" hidden="false" increment="0.05" initial_val="0.5" left="10"
37 max_val="1" min_val="0" mouse_opaque="true" name="UI Volume" width="120"
38 label="UI" show_text="false" label_width="50" volume="true" />
39</panel>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_audio_device.xml b/linden/indra/newview/skins/xui/en-us/panel_audio_device.xml
new file mode 100644
index 0000000..e895085
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/panel_audio_device.xml
@@ -0,0 +1,77 @@
1 <panel
2 border="false"
3 enabled="true"
4 hidden="false"
5 left="8"
6 bottom="0"
7 mouse_opaque="true"
8 name="device_settings"
9 width="404"
10 height="240">
11
12 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
13 drop_shadow_visible="true" enabled="true" follows="left|top"
14 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
15 left="6" mouse_opaque="true" name="Input device (microphone):" v_pad="0" width="200">
16 Audio Devices
17 </text>
18
19 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
20 bottom_delta="-22" drop_shadow_visible="true" enabled="true" follows="left|top"
21 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
22 left="20" mouse_opaque="true" name="Input device (microphone):" v_pad="0" width="200">
23 Input device (microphone):
24 </text>
25 <combo_box allow_text_entry="false" bottom_delta="-20" enabled="true" follows="left|top"
26 height="18" hidden="false" left_delta="0" max_chars="128" mouse_opaque="true"
27 name="voice_input_device" width="225" />
28
29 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
30 bottom_delta="-25" drop_shadow_visible="true" enabled="true" follows="left|top"
31 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
32 left_delta="0" mouse_opaque="true" name="Output device (speakers):" v_pad="0" width="200">
33 Output device (speakers):
34 </text>
35 <combo_box allow_text_entry="false" bottom_delta="-20" enabled="true" follows="left|top"
36 height="18" hidden="false" left_delta="0" max_chars="128" mouse_opaque="true"
37 name="voice_output_device" width="225" />
38
39 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
40 bottom_delta="-30" drop_shadow_visible="true" enabled="true" follows="left|top"
41 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
42 left="6" mouse_opaque="true" name="Input device (microphone):" v_pad="0" width="200">
43 Input Level
44 </text>
45
46 <text_editor
47 name="voice_intro_text1"
48 type="string"
49 enabled="false"
50 bg_readonly_color="0 0 0 0"
51 font="SansSerifSmall"
52 left_delta="10"
53 width="380"
54 height="60"
55 length="1"
56 max_length="65535"
57 hidden="false"
58 hide_border="true"
59 hide_scrollbar="true"
60 embedded_items="false"
61 allow_html="false"
62 mouse_opaque="true"
63 tab_stop="false"
64 word_wrap="true">Adjust the slider to control how loud you sound to other Residents. To test the input level, simply speak into your microphone.</text_editor>
65
66 <volume_slider bottom_delta="-18" enabled="true" follows="left|top" height="17" hidden="false"
67 increment="0.05" initial_val="0.5" left_delta="5" max_val="1" min_val="0"
68 mouse_opaque="true" name="mic_volume_slider" width="60"
69 tool_tip="Change the volume using this slider" />
70
71 <text name="wait_text" left_delta="70" bottom_delta="-4" width="200" height="20" follows="left|top">
72 Please wait
73 </text>
74 <!--<icon name="voice_volume" left_delta="70" bottom_delta="1" width="16" height="16" image_name="icn_voice_ptt-off.tga" follows="left|top"/>-->
75
76
77 </panel> \ No newline at end of file
diff --git a/linden/indra/newview/skins/xui/en-us/panel_friends.xml b/linden/indra/newview/skins/xui/en-us/panel_friends.xml
new file mode 100644
index 0000000..eb14d4b
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/panel_friends.xml
@@ -0,0 +1,62 @@
1<panel name="friends" border="true">
2 <scroll_list bottom="90" can_resize="true" column_padding="0" draw_heading="true"
3 follows="left|top|bottom|right" left="10" multi_select="true"
4 name="friend_list" right="-100" search_column="1"
5 tool_tip="Hold shift or control while clicking to select multiple friends"
6 top="-10">
7 <column image="ff_online_status_button.tga" name="icon_online_status" width="20" />
8 <column dynamicwidth="true" label="Name" name="friend_name" />
9 <column image="ff_visible_online_button.tga" name="icon_visible_online" width="20" />
10 <column image="ff_visible_map_button.tga" name="icon_visible_map" width="20" />
11 <column image="ff_edit_mine_button.tga" name="icon_edit_mine" width="20" />
12 <column image="ff_edit_theirs_button.tga" name="icon_edit_theirs" width="20" />
13 </scroll_list>
14 <panel background_opaque="true" background_visible="true" bevel_style="in"
15 bg_alpha_color="blue" bg_opaque_color="0,0,0,0.3" border="true" bottom="10"
16 can_resize="false" follows="left|right|bottom" height="70" left="10"
17 mouse_opaque="true" name="rights_container" right="-100">
18 <text bottom_delta="-11" follows="top|left" font="SansSerifSmall" left="10"
19 name="friend_name_label" width="200">
20 Select friend(s) to change rights...
21 </text>
22 <check_box bottom_delta="-21" enabled="false" follows="bottom|left" font="SansSerifSmall"
23 height="16" hidden="false" initial_value="false"
24 label="Can see my online status" left="10" mouse_opaque="true"
25 name="online_status_cb" radio_style="false"
26 tool_tip="Set whether this friend see my online status in their friends list or calling cards"
27 width="200" />
28 <check_box bottom_delta="-18" enabled="false" follows="bottom|left" font="SansSerifSmall"
29 height="16" hidden="false" initial_value="false"
30 label="Can see me on the map" left="25" mouse_opaque="true"
31 name="map_status_cb" radio_style="false"
32 tool_tip="Set whether this friend see my location on their map" width="200" />
33 <check_box bottom_delta="-18" enabled="false" follows="bottom|left" font="SansSerifSmall"
34 height="16" hidden="false" initial_value="false"
35 label="Can modify my objects" left="10" mouse_opaque="true"
36 name="modify_status_cb" radio_style="false"
37 tool_tip="Set whether this friend can modify my objects" width="200" />
38 <text bottom_delta="25" follows="top|left" font="SansSerif" left="10"
39 name="process_rights_label">
40 Processing rights change...
41 </text>
42 </panel>
43 <pad bottom="-7" height="0" left="-90" width="1" />
44 <button bottom_delta="-25" follows="top|right" height="22"
45 label="IM/Call" left_delta="0" name="im_btn"
46 tool_tip="Open Instant Message session" width="80" />
47 <button bottom_delta="-25" follows="top|right" height="22"
48 label="Profile" left_delta="0" name="profile_btn"
49 tool_tip="Show picture, groups, and other information" width="80" />
50 <button bottom_delta="-25" follows="top|right" height="22"
51 label="Teleport..." left_delta="0" name="offer_teleport_btn"
52 tool_tip="Offer this friend a teleport to your current location" width="80" />
53 <button bottom_delta="-25" follows="top|right" height="22"
54 label="Pay..." left_delta="0" name="pay_btn"
55 tool_tip="Give Linden dollars (L$) to this friend" width="80" />
56 <button bottom_delta="-25" follows="top|right" height="22"
57 label="Remove..." left_delta="0" name="remove_btn"
58 tool_tip="Remove this person from your friends list" width="80" />
59 <button bottom_delta="-35" follows="top|right" height="22"
60 label="Add..." left_delta="0" name="add_btn"
61 tool_tip="Offer friendship to a resident" width="80" />
62</panel>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_group_roles.xml b/linden/indra/newview/skins/xui/en-us/panel_group_roles.xml
index 3f6acf8..202d505 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_group_roles.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_group_roles.xml
@@ -153,6 +153,7 @@ including the Everyone and Owner Roles.
153 fg_disable_color="grey" fg_selected_color="black" 153 fg_disable_color="grey" fg_selected_color="black"
154 fg_unselected_color="black" follows="left|top" height="134" left="6" 154 fg_unselected_color="black" follows="left|top" height="134" left="6"
155 mouse_opaque="true" multi_select="true" name="action_list" 155 mouse_opaque="true" multi_select="true" name="action_list"
156 search_column="1"
156 tool_tip="Select an Ability to view more details." width="392"> 157 tool_tip="Select an Ability to view more details." width="392">
157 <column label="" name="icon" width="18" /> 158 <column label="" name="icon" width="18" />
158 <column label="" name="action" width="356" /> 159 <column label="" name="action" width="356" />
@@ -248,6 +249,7 @@ things in this group. There&apos;s a broad variety of Abilities.
248 <scroll_list bottom_delta="0" draw_border="true" draw_heading="false" height="125" 249 <scroll_list bottom_delta="0" draw_border="true" draw_heading="false" height="125"
249 left="150" multi_select="false" name="role_allowed_actions" 250 left="150" multi_select="false" name="role_allowed_actions"
250 tool_tip="For Details of each Allowed Ability see the Abilities tab." 251 tool_tip="For Details of each Allowed Ability see the Abilities tab."
252 search_column="2"
251 width="254"> 253 width="254">
252 <column label="" name="icon" width="2" /> 254 <column label="" name="icon" width="2" />
253 <column label="" name="checkbox" width="16" /> 255 <column label="" name="checkbox" width="16" />
diff --git a/linden/indra/newview/skins/xui/en-us/panel_groups.xml b/linden/indra/newview/skins/xui/en-us/panel_groups.xml
new file mode 100644
index 0000000..9dd0461
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/panel_groups.xml
@@ -0,0 +1,43 @@
1<panel bottom="-371" height="300" hidden="false" left="280"
2 mouse_opaque="true" name="groups" width="350" border="true">
3 <scroll_list background_visible="true" bottom="45" column_padding="5" draw_border="true"
4 draw_heading="false" draw_stripes="true" enabled="true"
5 follows="left|top|right|bottom" hidden="false" left="10"
6 mouse_opaque="true" multi_select="false" name="group list" tab_stop="true"
7 top="-10" width="240">
8 <column label="" name="name" width="248" />
9 </scroll_list>
10 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
11 bottom="22" drop_shadow_visible="true" enabled="true" follows="left|bottom"
12 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
13 left="12" mouse_opaque="false" name="groupdesc" v_pad="0"
14 width="248">
15 Your currently active group is displayed in bold.
16 </text>
17 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
18 bottom="5" drop_shadow_visible="true" enabled="true" follows="left|bottom"
19 font="SansSerifSmall" h_pad="0" halign="left" height="16" hidden="false"
20 left="12" mouse_opaque="false" name="groupcount" v_pad="0"
21 width="248">
22 You belong to [COUNT] groups (of [MAX] maximum).
23 </text>
24 <pad bottom="-7" height="0" left="-90" width="1" />
25 <button bottom_delta="-25" follows="top|right" font="SansSerif" height="22"
26 label="IM/Call" left_delta="0" name="IM"
27 tool_tip="Open Instant Message session" width="80" />
28 <button border_height="16" border_width="16" bottom_delta="-25" follows="top|right"
29 font="SansSerif" height="22" hidden="false" label="Info" name="Info"
30 width="80" />
31 <button border_height="16" border_width="16" bottom_delta="-25" follows="top|right"
32 font="SansSerif" height="22" hidden="false" label="Activate"
33 name="Activate" width="80" />
34 <button border_height="16" border_width="16" bottom_delta="-25" follows="top|right"
35 font="SansSerif" height="22" hidden="false" label="Leave" name="Leave"
36 width="80" />
37 <button border_height="16" border_width="16" bottom_delta="-35" follows="top|right"
38 font="SansSerif" height="22" hidden="false" label="Create..." name="Create"
39 width="80" />
40 <button border_height="16" border_width="16" bottom_delta="-25" follows="top|right"
41 font="SansSerif" height="22" hidden="false" label="Search..."
42 name="Search..." width="80" />
43</panel>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_master_volume.xml b/linden/indra/newview/skins/xui/en-us/panel_master_volume.xml
new file mode 100644
index 0000000..ac1a46f
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/panel_master_volume.xml
@@ -0,0 +1,13 @@
1<panel bg_visible="false" border="false" border_visible="false" bottom="-34"
2 enabled="true" follows="left|top" hidden="false"
3 mouse_opaque="true" name="music_remote">
4<!-- <button bottom="-22" height="22" label="Volume" left="2" name="volume" -->
5<!-- tool_tip="Master Volume Control, click for volume settings" width="55" /> -->
6 <button bottom="-22" height="22" label="" image_overlay="volume_icon.tga" left="2" name="volume"
7 tool_tip="Master Volume Control, click for volume settings" width="28" />
8 <volume_slider control_name="AudioLevelMaster"
9 bottom="-20" enabled="true" follows="left|top" height="17" hidden="false"
10 increment="0.05" initial_val="0.5" left_delta="25" max_val="1" min_val="0"
11 mouse_opaque="true" name="volume_slider" width="40"
12 tool_tip="Change the volume using this slider" />
13</panel>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_media_remote.xml b/linden/indra/newview/skins/xui/en-us/panel_media_remote.xml
index 71e74b6..f14ec61 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_media_remote.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_media_remote.xml
@@ -1,26 +1,23 @@
1<panel bg_visible="false" border="false" border_visible="false" bottom="-34" 1<panel bg_visible="false" border="false" border_visible="false" bottom="-34"
2 enabled="true" follows="left|top" height="20" hidden="false" left="571" 2 enabled="true" follows="left|top" hidden="false" left="571"
3 mouse_opaque="true" name="music_remote" width="110"> 3 mouse_opaque="true" name="music_remote" >
4 <text type="string" length="6" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 4<!-- <text type="string" length="6" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" -->
5 bottom="-15" drop_shadow_visible="true" enabled="true" follows="left|top" 5<!-- bottom="-15" drop_shadow_visible="true" enabled="true" follows="left|top" -->
6 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false" 6<!-- font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false" -->
7 left="2" mouse_opaque="true" name="text" v_pad="0" width="77"> 7<!-- left="2" mouse_opaque="true" name="text" v_pad="0" width="77"> -->
8 Movies 8<!-- Movies -->
9 </text> 9<!-- </text> -->
10 <volume_slider bottom="-20" enabled="true" follows="left|top" height="17" hidden="false" 10 <icon name="media_icon" left="5" bottom="-19" width="16" height="16" image_name="media_icon.tga"/>
11 increment="0.05" initial_val="0.125" left="33" max_val="1" min_val="0"
12 mouse_opaque="true" name="volume_slider"
13 tool_tip="Change the volume using this slider" width="42" />
14 <button bottom="-20" enabled="false" follows="left|top" font="SansSerif" 11 <button bottom="-20" enabled="false" follows="left|top" font="SansSerif"
15 halign="center" height="17" hidden="false" 12 halign="center" height="17" hidden="false"
16 image_selected="button_anim_stop_selected.tga" 13 image_selected="button_anim_stop_selected.tga"
17 image_unselected="button_anim_stop.tga" label="" label_selected="" 14 image_unselected="button_anim_stop.tga" label="" label_selected=""
18 left="76" mouse_opaque="true" name="stop_btn" scale_image="true" 15 left_delta="25" mouse_opaque="true" name="media_stop" scale_image="true"
19 tool_tip="Stop media" width="17" /> 16 tool_tip="Stop media" width="17" />
20 <button bottom="-20" enabled="true" follows="left|top" font="SansSerif" halign="center" 17 <button bottom="-20" enabled="true" follows="left|top" font="SansSerif" halign="center"
21 height="17" hidden="false" image_selected="button_anim_play_selected.tga" 18 height="17" hidden="false" image_selected="button_anim_play_selected.tga"
22 image_unselected="button_anim_play.tga" label="" label_selected="" 19 image_unselected="button_anim_play.tga" label="" label_selected=""
23 left="92" mouse_opaque="true" name="play_btn" scale_image="true" 20 left_delta="15" mouse_opaque="true" name="media_play" scale_image="true"
24 tool_tip="Play media stream" width="17" /> 21 tool_tip="Play media stream" width="17" />
25 <button bottom="-20" enabled="false" follows="left|top" font="SansSerif" 22 <button bottom="-20" enabled="false" follows="left|top" font="SansSerif"
26 halign="center" height="17" hidden="false" 23 halign="center" height="17" hidden="false"
@@ -28,6 +25,6 @@
28 image_disabled_selected="button_disabled_32x128.tga" 25 image_disabled_selected="button_disabled_32x128.tga"
29 image_selected="button_anim_pause_selected.tga" 26 image_selected="button_anim_pause_selected.tga"
30 image_unselected="button_anim_pause.tga" label="" label_selected="" 27 image_unselected="button_anim_pause.tga" label="" label_selected=""
31 left="92" mouse_opaque="true" name="pause_btn" scale_image="true" 28 left_delta="0" mouse_opaque="true" name="media_pause" scale_image="true"
32 tool_tip="Pause media stream" width="17" /> 29 tool_tip="Pause media stream" width="17" />
33</panel> 30</panel>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_music_remote.xml b/linden/indra/newview/skins/xui/en-us/panel_music_remote.xml
index e0c9bb1..a99333e 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_music_remote.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_music_remote.xml
@@ -1,26 +1,23 @@
1<panel bg_visible="false" border="false" border_visible="false" bottom="-34" 1<panel bg_visible="false" border="false" border_visible="false" bottom="-34"
2 enabled="true" follows="left|top" height="20" hidden="false" left="571" 2 enabled="true" follows="left|top" hidden="false"
3 mouse_opaque="true" name="music_remote" width="110"> 3 mouse_opaque="true" name="music_remote">
4 <text type="string" length="6" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 4<!-- <text type="string" length="6" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" -->
5 bottom="-15" drop_shadow_visible="true" enabled="true" follows="left|top" 5<!-- bottom="-15" drop_shadow_visible="true" enabled="true" follows="left|top" -->
6 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false" 6<!-- font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false" -->
7 left="2" mouse_opaque="true" name="text" v_pad="0" width="77"> 7<!-- left="2" mouse_opaque="true" name="text" v_pad="0" width="77"> -->
8 Music 8<!-- Music -->
9 </text> 9<!-- </text> -->
10 <volume_slider bottom="-20" enabled="true" follows="left|top" height="17" hidden="false" 10 <icon name="music_icon" left="5" bottom="-19" width="16" height="16" image_name="music_icon.tga"/>
11 increment="0.05" initial_val="0.125" left="33" max_val="1" min_val="0"
12 mouse_opaque="true" name="volume_slider"
13 tool_tip="Change the volume using this slider" width="42" />
14 <button bottom="-20" enabled="false" follows="left|top" font="SansSerif" 11 <button bottom="-20" enabled="false" follows="left|top" font="SansSerif"
15 halign="center" height="17" hidden="false" 12 halign="center" height="17" hidden="false"
16 image_selected="button_anim_stop_selected.tga" 13 image_selected="button_anim_stop_selected.tga"
17 image_unselected="button_anim_stop.tga" label="" label_selected="" 14 image_unselected="button_anim_stop.tga" label="" label_selected=""
18 left="76" mouse_opaque="true" name="stop_btn" scale_image="true" 15 left_delta="25" mouse_opaque="true" name="music_stop" scale_image="true"
19 tool_tip="Stop media" width="17" /> 16 tool_tip="Stop media" width="17" />
20 <button bottom="-20" enabled="true" follows="left|top" font="SansSerif" halign="center" 17 <button bottom="-20" enabled="true" follows="left|top" font="SansSerif" halign="center"
21 height="17" hidden="false" image_selected="button_anim_play_selected.tga" 18 height="17" hidden="false" image_selected="button_anim_play_selected.tga"
22 image_unselected="button_anim_play.tga" label="" label_selected="" 19 image_unselected="button_anim_play.tga" label="" label_selected=""
23 left="92" mouse_opaque="true" name="play_btn" scale_image="true" 20 left_delta="17" mouse_opaque="true" name="music_play" scale_image="true"
24 tool_tip="Play media stream" width="17" /> 21 tool_tip="Play media stream" width="17" />
25 <button bottom="-20" enabled="false" follows="left|top" font="SansSerif" 22 <button bottom="-20" enabled="false" follows="left|top" font="SansSerif"
26 halign="center" height="17" hidden="false" 23 halign="center" height="17" hidden="false"
@@ -28,6 +25,6 @@
28 image_disabled_selected="button_disabled_32x128.tga" 25 image_disabled_selected="button_disabled_32x128.tga"
29 image_selected="button_anim_pause_selected.tga" 26 image_selected="button_anim_pause_selected.tga"
30 image_unselected="button_anim_pause.tga" label="" label_selected="" 27 image_unselected="button_anim_pause.tga" label="" label_selected=""
31 left="92" mouse_opaque="true" name="pause_btn" scale_image="true" 28 left_delta="0" mouse_opaque="true" name="music_pause" scale_image="true"
32 tool_tip="Pause media stream" width="17" /> 29 tool_tip="Pause media stream" width="17" />
33</panel> 30</panel>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_overlaybar.xml b/linden/indra/newview/skins/xui/en-us/panel_overlaybar.xml
index d24cb43..acb453b 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_overlaybar.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_overlaybar.xml
@@ -1,6 +1,6 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<panel bottom="51" enabled="true" follows="left|right|bottom" height="42" 2<panel bottom="51" enabled="true" follows="left|right|bottom" height="42"
3 hidden="false" left="-1" mouse_opaque="false" name="overlay" width="1682"> 3 hidden="false" left="-1" mouse_opaque="false" name="overlay" width="800">
4 <button bottom="-41" enabled="true" follows="left|top" font="SansSerif" halign="center" 4 <button bottom="-41" enabled="true" follows="left|top" font="SansSerif" halign="center"
5 height="20" hidden="false" label="IM Received" label_selected="IM Received" 5 height="20" hidden="false" label="IM Received" label_selected="IM Received"
6 left="0" mouse_opaque="true" name="IM Received" scale_image="true" 6 left="0" mouse_opaque="true" name="IM Received" scale_image="true"
@@ -28,9 +28,16 @@
28 left="457" mouse_opaque="true" name="Stand Up" scale_image="true" 28 left="457" mouse_opaque="true" name="Stand Up" scale_image="true"
29 tool_tip="Click here to stand up." width="102" /> 29 tool_tip="Click here to stand up." width="102" />
30 <panel background_visible="false" border="false" bottom="-41" enabled="true" 30 <panel background_visible="false" border="false" bottom="-41" enabled="true"
31 follows="left|top" height="20" hidden="false" left="571" 31 follows="right|top" height="20" hidden="false" left="400"
32 mouse_opaque="true" name="music_remote" width="110" /> 32 mouse_opaque="true" name="media_remote" width="75" />
33 <panel background_visible="false" border="false" bottom="-41" enabled="true" 33 <panel background_visible="false" border="false" bottom="-41" enabled="true"
34 follows="left|top" height="20" hidden="false" left="700" 34 follows="right|top" height="20" hidden="false" left="500"
35 mouse_opaque="true" name="media_remote" width="110" /> 35 mouse_opaque="true" name="music_remote" width="75" />
36 <panel background_visible="false" border="false" bottom="-41" enabled="true"
37 follows="right|top" height="20" hidden="false" left="600"
38 mouse_opaque="true" name="voice_remote" width="108" />
39 <panel background_visible="false" border="false" bottom="-41" enabled="true"
40 follows="right|top" height="20" hidden="false" left="700"
41 mouse_opaque="true" name="master_volume" width="75" />
42
36</panel> 43</panel>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_preferences_audio.xml b/linden/indra/newview/skins/xui/en-us/panel_preferences_audio.xml
index db387f1..cb65ba9 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_preferences_audio.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_preferences_audio.xml
@@ -6,125 +6,82 @@
6 bottom="-22" drop_shadow_visible="true" enabled="true" follows="left|top" 6 bottom="-22" drop_shadow_visible="true" enabled="true" follows="left|top"
7 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false" 7 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false"
8 left="10" mouse_opaque="true" name="muting_text" v_pad="0" width="128"> 8 left="10" mouse_opaque="true" name="muting_text" v_pad="0" width="128">
9 Muting: 9 Volume:
10 </text>
11 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
12 bottom="-215" drop_shadow_visible="true" enabled="true" follows="left|top"
13 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false"
14 left="10" mouse_opaque="true" name="doppler_effect_text" v_pad="0"
15 width="128">
16 Streaming Preferences:
10 </text> 17 </text>
11 <check_box bottom="-26" control_name="MuteAudio" enabled="true" follows="left|top"
12 font="SansSerifSmall" height="16" hidden="false" initial_value="false"
13 label="Mute Audio" left="142" mouse_opaque="true" name="disable audio"
14 radio_style="false" width="134" />
15 <check_box bottom="-46" control_name="MuteWhenMinimized" enabled="true" follows="left|top"
16 font="SansSerifSmall" height="16" hidden="false" initial_value="true"
17 label="Mute Audio When Window Minimized" left="142" mouse_opaque="true"
18 name="mute_when_minimized" radio_style="false" width="215" />
19 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 18 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
20 bottom="-62" drop_shadow_visible="true" enabled="true" follows="left|top" 19 bottom="-260" drop_shadow_visible="true" enabled="true" follows="left|top"
21 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false" 20 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false"
22 left="10" mouse_opaque="true" name="streaming_text" v_pad="0" width="128"> 21 left="10" mouse_opaque="true" name="doppler_effect_text" v_pad="0"
23 Streaming: 22 width="128">
23 Audio Preferences:
24 </text>
25 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
26 bottom="-385" drop_shadow_visible="true" enabled="true" follows="left|top"
27 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false"
28 left="10" mouse_opaque="true" name="default_upload_bitrate_text" v_pad="0"
29 width="150">
30 Default Upload Bitrate:
24 </text> 31 </text>
25 <check_box bottom="-66" control_name="AudioStreamingMusic" enabled="true" 32
33 <panel border="true" bottom="-195" enabled="true" follows="left|top|right|bottom"
34 hidden="false" label="Volume" left="148" height="180" width="205"
35 mouse_opaque="true" name="Volume Panel"
36 filename="panel_audio.xml">
37 </panel>
38
39 <check_box bottom="-220" control_name="AudioStreamingMusic" enabled="true"
26 follows="left|top" font="SansSerifSmall" height="16" hidden="false" 40 follows="left|top" font="SansSerifSmall" height="16" hidden="false"
27 initial_value="true" 41 initial_value="true"
28 label="Play Streaming Music When Available (uses more bandwidth)" 42 label="Play Streaming Music When Available (uses more bandwidth)"
29 left="142" mouse_opaque="true" name="streaming_music" radio_style="false" 43 left="142" mouse_opaque="true" name="streaming_music" radio_style="false"
30 width="339" /> 44 width="339" />
31 <check_box bottom="-86" control_name="AudioStreamingVideo" enabled="true" 45 <check_box bottom_delta="-20" control_name="AudioStreamingVideo" enabled="true"
32 follows="left|top" font="SansSerifSmall" height="16" hidden="false" 46 follows="left|top" font="SansSerifSmall" height="16" hidden="false"
33 initial_value="true" 47 initial_value="true"
34 label="Play Streaming Video When Available (uses more bandwidth)" 48 label="Play Streaming Video When Available (uses more bandwidth)"
35 left="142" mouse_opaque="true" name="streaming_video" radio_style="false" 49 left="142" mouse_opaque="true" name="streaming_video" radio_style="false"
36 width="338" /> 50 width="338" />
37 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 51
38 bottom="-102" drop_shadow_visible="true" enabled="true" follows="left|top" 52
39 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false" 53 <check_box bottom_delta="-25" control_name="MuteWhenMinimized" enabled="true" follows="left|top"
40 left="10" mouse_opaque="true" name="system_volume_text" v_pad="0" 54 font="SansSerifSmall" height="16" hidden="false" initial_value="true"
41 width="128"> 55 label="Mute Audio When Window Minimized" left="142" mouse_opaque="true"
42 Sound Effects: 56 name="mute_when_minimized" radio_style="false" width="215" />
43 </text> 57 <slider bottom_delta="-20" control_name="AudioLevelDoppler" enabled="true"
44 <slider_bar bottom="-102" control_name="AudioLevelMaster" enabled="true" follows="left|top" 58 follows="left|top" height="15" hidden="false" increment="0.1"
45 height="12" hidden="false" increment="0.01" initial_val="1" left="148" 59 initial_val="1" left="148" max_val="2" min_val="0" mouse_opaque="true"
46 max_val="1" min_val="0" mouse_opaque="true" name="System Volume" 60 name="Doppler Effect" width="250"
47 width="128" /> 61 label="Doppler Effect" show_text="true" edit_text="true" label_width="100" />
48 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 62 <slider bottom_delta="-20" control_name="AudioLevelDistance" enabled="true"
49 bottom="-126" drop_shadow_visible="true" enabled="true" follows="left|top" 63 follows="left|top" height="15" hidden="false" increment="0.1"
50 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false" 64 initial_val="1" left="148" max_val="2" min_val="0" mouse_opaque="true"
51 left="10" mouse_opaque="true" name="wind_volume_text" v_pad="0" width="128"> 65 name="Distance Factor" width="250"
52 Wind Volume: 66 label="Distance Factor" show_text="true" edit_text="true" label_width="100" />
53 </text> 67 <slider bottom_delta="-20" control_name="AudioLevelRolloff" enabled="true"
54 <slider_bar bottom="-126" control_name="AudioLevelWind" enabled="true" follows="left|top" 68 follows="left|top" height="15" hidden="false" increment="0.1"
55 height="12" hidden="false" increment="0.01" initial_val="0.5" left="148" 69 initial_val="1" left="148" max_val="2" min_val="0" mouse_opaque="true"
56 max_val="1" min_val="0" mouse_opaque="true" name="Wind Volume" width="128" /> 70 name="Rolloff Factor" width="250"
57 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 71 label="Rolloff Factor" show_text="true" edit_text="true" label_width="100" />
58 bottom="-142" drop_shadow_visible="true" enabled="true" follows="left|top" 72
59 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false" 73 <spinner bottom_delta="-20" control_name="UISndMoneyChangeThreshold" decimal_digits="0"
60 left="10" mouse_opaque="true" name="footsteps_volume_text" v_pad="0"
61 width="128">
62 Footsteps Volume:
63 </text>
64 <slider_bar bottom="-142" control_name="AudioLevelFootsteps" enabled="true"
65 follows="left|top" height="12" hidden="false" increment="0.01"
66 initial_val="0.5" left="148" max_val="1" min_val="0" mouse_opaque="true"
67 name="Footsteps Volume" width="128" />
68 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
69 bottom="-158" drop_shadow_visible="true" enabled="true" follows="left|top"
70 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false"
71 left="10" mouse_opaque="true" name="ui_volume_text" v_pad="0" width="128">
72 UI Volume:
73 </text>
74 <slider_bar bottom="-158" control_name="AudioLevelUI" enabled="true" follows="left|top"
75 height="12" hidden="false" increment="0.01" initial_val="0.5" left="148"
76 max_val="1" min_val="0" mouse_opaque="true" name="UI Volume" width="128" />
77 <spinner bottom="-178" control_name="UISndMoneyChangeThreshold" decimal_digits="0"
78 enabled="true" follows="left|top" height="16" hidden="false" increment="10" 74 enabled="true" follows="left|top" height="16" hidden="false" increment="10"
79 initial_val="10" label="L$ Change Threshold" label_width="128" left="20" 75 initial_val="10" label="L$ Change Threshold" label_width="128" left="148"
80 max_val="10000" min_val="0" mouse_opaque="true" name="L$ Change Threshold" 76 max_val="10000" min_val="0" mouse_opaque="true" name="L$ Change Threshold"
81 width="192" /> 77 width="192" />
82 <spinner bottom="-194" control_name="UISndHealthReductionThreshold" decimal_digits="0" 78 <spinner bottom_delta="-20" control_name="UISndHealthReductionThreshold" decimal_digits="0"
83 enabled="true" follows="left|top" height="16" hidden="false" increment="10" 79 enabled="true" follows="left|top" height="16" hidden="false" increment="10"
84 initial_val="20" label="Health Change Threshold" label_width="128" 80 initial_val="20" label="Health Change Threshold" label_width="128"
85 left="20" max_val="10000" min_val="0" mouse_opaque="true" 81 left="148" max_val="10000" min_val="0" mouse_opaque="true"
86 name="Health Change Threshold" width="192" /> 82 name="Health Change Threshold" width="192" />
87 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 83
88 bottom="-214" drop_shadow_visible="true" enabled="true" follows="left|top" 84 <radio_group bottom_delta="-25" control_name="AudioDefaultBitrate" draw_border="true"
89 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false"
90 left="10" mouse_opaque="true" name="doppler_effect_text" v_pad="0"
91 width="128">
92 Doppler Effect:
93 </text>
94 <slider_bar bottom="-214" control_name="AudioLevelDoppler" enabled="true"
95 follows="left|top" height="12" hidden="false" increment="0.01"
96 initial_val="1" left="148" max_val="2" min_val="0" mouse_opaque="true"
97 name="Doppler Effect" width="128" />
98 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
99 bottom="-230" drop_shadow_visible="true" enabled="true" follows="left|top"
100 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false"
101 left="10" mouse_opaque="true" name="distance_factor_text" v_pad="0"
102 width="128">
103 Distance Factor:
104 </text>
105 <slider_bar bottom="-230" control_name="AudioLevelDistance" enabled="true"
106 follows="left|top" height="12" hidden="false" increment="0.01"
107 initial_val="1" left="148" max_val="2" min_val="0" mouse_opaque="true"
108 name="Distance Factor" width="128" />
109 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
110 bottom="-246" drop_shadow_visible="true" enabled="true" follows="left|top"
111 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false"
112 left="10" mouse_opaque="true" name="rolloff_factor_text" v_pad="0"
113 width="128">
114 Rolloff Factor:
115 </text>
116 <slider_bar bottom="-246" control_name="AudioLevelRolloff" enabled="true"
117 follows="left|top" height="12" hidden="false" increment="0.01"
118 initial_val="1" left="148" max_val="2" min_val="0" mouse_opaque="true"
119 name="Rolloff Factor" width="128" />
120 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
121 bottom="-266" drop_shadow_visible="true" enabled="true" follows="left|top"
122 font="SansSerifSmall" h_pad="0" halign="left" height="12" hidden="false"
123 left="10" mouse_opaque="true" name="default_upload_bitrate_text" v_pad="0"
124 width="128">
125 Default Upload Bitrate:
126 </text>
127 <radio_group bottom="-272" control_name="AudioDefaultBitrate" draw_border="true"
128 enabled="true" follows="left|top" height="18" hidden="false" left="148" 85 enabled="true" follows="left|top" height="18" hidden="false" left="148"
129 mouse_opaque="true" name="bitrate" width="320"> 86 mouse_opaque="true" name="bitrate" width="320">
130 <radio_item type="string" length="1" bottom="-17" enabled="true" follows="left|top" height="16" hidden="false" 87 <radio_item type="string" length="1" bottom="-17" enabled="true" follows="left|top" height="16" hidden="false"
diff --git a/linden/indra/newview/skins/xui/en-us/panel_preferences_chat.xml b/linden/indra/newview/skins/xui/en-us/panel_preferences_chat.xml
index 20ccfe9..d24a8e9 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_preferences_chat.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_preferences_chat.xml
@@ -1,6 +1,6 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom" 2<panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom"
3 height="408" hidden="false" label="Chat" left="102" mouse_opaque="true" 3 height="408" hidden="false" label="Text Chat" left="102" mouse_opaque="true"
4 name="chat" width="517"> 4 name="chat" width="517">
5 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 5 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
6 bottom="-20" drop_shadow_visible="true" enabled="true" follows="left|top" 6 bottom="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
diff --git a/linden/indra/newview/skins/xui/en-us/panel_preferences_graphics3.xml b/linden/indra/newview/skins/xui/en-us/panel_preferences_graphics3.xml
index fd48f34..83cc3bc 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_preferences_graphics3.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_preferences_graphics3.xml
@@ -106,7 +106,7 @@
106 </text> 106 </text>
107 <spinner bottom="-264" control_name="DebugBeaconLineWidth" decimal_digits="0" 107 <spinner bottom="-264" control_name="DebugBeaconLineWidth" decimal_digits="0"
108 enabled="true" follows="left|top" height="16" hidden="false" 108 enabled="true" follows="left|top" height="16" hidden="false"
109 increment="1" initial_val="1" label="Debug Beacon Line Width:" 109 increment="1" initial_val="8" label="Debug Beacon Line Width:"
110 label_width="138" left="10" max_val="127" min_val="1" mouse_opaque="true" 110 label_width="138" left="10" max_val="127" min_val="1" mouse_opaque="true"
111 name="debug beacon line width" width="202" /> 111 name="debug beacon line width" width="202" />
112 <check_box bottom="-304" control_name="ProbeHardwareOnStartup" enabled="true" 112 <check_box bottom="-304" control_name="ProbeHardwareOnStartup" enabled="true"
diff --git a/linden/indra/newview/skins/xui/en-us/panel_preferences_voice.xml b/linden/indra/newview/skins/xui/en-us/panel_preferences_voice.xml
new file mode 100644
index 0000000..137616c
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/panel_preferences_voice.xml
@@ -0,0 +1,89 @@
1<panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom"
2 height="408" hidden="false" label="Voice Chat" left="102"
3 mouse_opaque="true" name="chat" width="517">
4 <text_editor type="string" length="1" allow_html="false" bg_readonly_color="0 0 0 0" bottom_delta="-26"
5 embedded_items="false" enabled="false" follows="left|top"
6 font="SansSerifSmall" height="20" hidden="false" hide_border="true"
7 hide_scrollbar="true" left_delta="8" max_length="65535"
8 mouse_opaque="true" name="voice_unavailable" width="450" tab_stop="false"
9 word_wrap="true">
10 Voice Chat Is Not Available
11 </text_editor>
12 <check_box bottom_delta="0" control_name="EnableVoiceChat" enabled="true"
13 follows="left|top" font="SansSerifSmall" height="16" hidden="false"
14 initial_value="false" label="Enable voice chat" left="8"
15 mouse_opaque="true" name="enable_voice_check" radio_style="false"
16 width="200" />
17 <radio_group bottom_delta="-40" draw_border="false"
18 follows="left|top" height="40" left_delta="20" name="ear_location" width="364">
19 <radio_item type="string" length="1" bottom="-19" follows="left|top" height="16" left="3" name="0" width="315">
20 Hear Voice Chat from camera position.
21 </radio_item>
22 <radio_item type="string" length="1" bottom="-35" follows="left|top" height="16" left="3" name="1" width="315">
23 Hear Voice Chat from avatar position.
24 </radio_item>
25 </radio_group>
26
27 <text type="string" length="1" allow_html="false" bg_readonly_color="0 0 0 0" bottom_delta="-20"
28 embedded_items="false" enabled="true" follows="left|top"
29 font="SansSerifSmall" height="16" hidden="false" hide_border="true"
30 hide_scrollbar="true" left_delta="0" max_length="65535" mouse_opaque="true"
31 name="push_to_talk_heading" width="445" word_wrap="true">
32 Push To Talk
33 </text>
34 <text_editor type="string" length="1" allow_html="false" bg_readonly_color="0 0 0 0" bottom_delta="-60"
35 embedded_items="false" enabled="false" follows="left|top"
36 font="SansSerifSmall" height="65" hidden="false" hide_border="true"
37 hide_scrollbar="true" left_delta="20" max_length="65535"
38 mouse_opaque="true" name="voice_chat_description" width="450" tab_stop="false"
39 word_wrap="true">Push-to-Talk mode lets you control when your voice is transmitted. When in toggle mode, press and release the push-to-talk trigger to switch your microphone on and off. When not in toggle mode, the microphone is active only when the trigger is held down.</text_editor>
40 <check_box bottom_delta="-20" control_name="EnablePushToTalk" enabled="true"
41 follows="left|top" font="SansSerifSmall" height="16" hidden="false"
42 initial_value="false" label="Start Viewer in Push-to-Talk mode" left_delta="0"
43 mouse_opaque="true" name="push_to_talk_check" radio_style="false"
44 width="200" />
45 <check_box bottom_delta="-20" control_name="PushToTalkToggle" enabled="true"
46 follows="left|top" font="SansSerifSmall" height="16" hidden="false"
47 initial_value="false" label="Use Push-to-Talk in toggle mode" left_delta="0"
48 mouse_opaque="true" name="push_to_talk_toggle_check" radio_style="false"
49 width="200" />
50 <text type="string" length="1" allow_html="false" bg_readonly_color="0 0 0 0" bottom_delta="-20"
51 embedded_items="false" enabled="true" follows="left|top"
52 font="SansSerifSmall" height="16" hidden="false" hide_border="true"
53 hide_scrollbar="true" left_delta="4" max_length="65535" mouse_opaque="true"
54 name="push_to_talk_label" width="445" word_wrap="true">
55 Push-to-Talk trigger:
56 </text>
57
58 <line_editor border_drop_shadow_visible="false" border_visible="false" bottom_delta="-20"
59 drop_shadow_visible="true" enabled="false" follows="top|left"
60 font="SansSerifSmall" halign="right" height="19" left_delta="0"
61 max_length="254" mouse_opaque="false" name="modifier_combo" control_name="PushToTalkButton" width="255" />
62
63 <button bottom_delta="-25" follows="left|top" font="SansSerif" halign="center"
64 height="20" label="Set Key" left_delta="0"
65 mouse_opaque="true" name="set_voice_hotkey_button" width="90" />
66 <button bottom_delta="0" follows="left" font="SansSerif" halign="center"
67 height="20" label="Middle Mouse Button" left_delta="95"
68 mouse_opaque="true" name="set_voice_middlemouse_button" width="160" />
69
70 <text allow_html="false" bg_readonly_color="0 0 0 0" bottom_delta="-25"
71 embedded_items="false" enabled="true" follows="left|top"
72 height="16" hidden="false"
73 left_delta="-120"
74 name="privacy_heading" width="445">
75 Privacy Options
76 </text>
77 <check_box bottom_delta="-20" enabled="true" control_name="VoiceCallsFriendsOnly"
78 follows="left|top" font="SansSerifSmall" height="16" hidden="false"
79 initial_value="false" label="Only accept voice calls from people on My Friends list" left_delta="20"
80 mouse_opaque="true" name="voice_call_friends_only_check" radio_style="false"
81 width="200" />
82
83 <button bottom_delta="-30" follows="left|top" font="SansSerif"
84 height="20" label="Device Settings..." left_delta="-20"
85 mouse_opaque="true" name="device_settings_btn" width="120" />
86 <button bottom_delta="-30" follows="left|top" font="SansSerif"
87 height="20" label="Run Voice Setup Wizard..." left_delta="0"
88 mouse_opaque="true" name="launch_voice_wizard_button" width="170" />
89</panel>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_region_estate.xml b/linden/indra/newview/skins/xui/en-us/panel_region_estate.xml
index b15b0bf..176164c 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_region_estate.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_region_estate.xml
@@ -51,6 +51,11 @@
51 left="15" name="externally_visible_check" width="200" /> 51 left="15" name="externally_visible_check" width="200" />
52 <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" 52 <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?"
53 left="185" name="externally_visible_help" width="18" /> 53 left="185" name="externally_visible_help" width="18" />
54 <check_box bottom_delta="-20" follows="left|top" height="20" label="Allow Voice Chat"
55 left="15" name="voice_chat_check" width="200" />
56 <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?"
57 left="185" name="voice_chat_help" width="18" />
58
54<!-- 59<!--
55<check_box name="mainland_visible_check" 60<check_box name="mainland_visible_check"
56 label="Mainland Visible From Here" 61 label="Mainland Visible From Here"
@@ -70,7 +75,7 @@
70 font="SansSerifSmall" 75 font="SansSerifSmall"
71 /> 76 />
72--> 77-->
73 <check_box bottom_delta="-40" follows="left|top" height="20" label="Allow Direct Teleport" 78 <check_box bottom_delta="-20" follows="left|top" height="20" label="Allow Direct Teleport"
74 left="15" name="allow_direct_teleport" width="80" /> 79 left="15" name="allow_direct_teleport" width="80" />
75 <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" 80 <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?"
76 left="185" name="allow_direct_teleport_help" width="18" /> 81 left="185" name="allow_direct_teleport_help" width="18" />
diff --git a/linden/indra/newview/skins/xui/en-us/panel_status_bar.xml b/linden/indra/newview/skins/xui/en-us/panel_status_bar.xml
index b584151..51338f1 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_status_bar.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_status_bar.xml
@@ -94,13 +94,19 @@
94 image_unselected="status_push.tga" label="" label_selected="" left="521" 94 image_unselected="status_push.tga" label="" label_selected="" left="521"
95 mouse_opaque="true" name="restrictpush" scale_image="false" 95 mouse_opaque="true" name="restrictpush" scale_image="false"
96 tool_tip="Restrict llPushObject" width="24" /> 96 tool_tip="Restrict llPushObject" width="24" />
97 <button bottom="-22" enabled="true" follows="right|bottom" font="SansSerif"
98 halign="center" height="24" hidden="false" image_disabled="status_voice.tga"
99 image_disabled_selected="status_voice.tga" image_selected="status_voice.tga"
100 image_unselected="status_voice.tga" label="" label_selected="" left="545"
101 mouse_opaque="true" name="status_voice" scale_image="false"
102 tool_tip="Voice Enabled" width="24" />
97 <button bottom="-18" enabled="true" follows="right|bottom" font="SansSerif" 103 <button bottom="-18" enabled="true" follows="right|bottom" font="SansSerif"
98 halign="center" height="16" hidden="false" 104 halign="center" height="16" hidden="false"
99 image_disabled="status_buy_land.tga" 105 image_disabled="status_buy_land.tga"
100 image_disabled_selected="status_buy_land_pressed.tga" 106 image_disabled_selected="status_buy_land_pressed.tga"
101 image_selected="status_buy_land_pressed.tga" 107 image_selected="status_buy_land_pressed.tga"
102 image_unselected="status_buy_land.tga" label="" label_selected="" 108 image_unselected="status_buy_land.tga" label="" label_selected=""
103 left="545" mouse_opaque="true" name="buyland" scale_image="true" 109 left="569" mouse_opaque="true" name="buyland" scale_image="true"
104 tool_tip="Buy this parcel" width="16" /> 110 tool_tip="Buy this parcel" width="16" />
105 <text hidden="true" name="packet_loss_tooltip"> 111 <text hidden="true" name="packet_loss_tooltip">
106 Packet Loss 112 Packet Loss
diff --git a/linden/indra/newview/skins/xui/en-us/panel_toolbar.xml b/linden/indra/newview/skins/xui/en-us/panel_toolbar.xml
index 655d869..2a2affe 100644
--- a/linden/indra/newview/skins/xui/en-us/panel_toolbar.xml
+++ b/linden/indra/newview/skins/xui/en-us/panel_toolbar.xml
@@ -2,13 +2,10 @@
2<panel background_opaque="true" background_visible="true" can_close="true" 2<panel background_opaque="true" background_visible="true" can_close="true"
3 can_minimize="false" can_resize="false" follows="left|right|bottom" 3 can_minimize="false" can_resize="false" follows="left|right|bottom"
4 height="26" name="panel_toolbar" width="1024"> 4 height="26" name="panel_toolbar" width="1024">
5 <button bottom="0" font="SansSerif" height="24" label="IM" left="0" name="im_btn" 5 <button bottom="0" font="SansSerif" height="24" label="Communicate" left="0" name="communicate_btn"
6 tool_tip="Instant Message your friends." width="50" /> 6 tool_tip="Communicate with your Friends and Groups." width="50" />
7 <button bottom="0" font="SansSerif" height="24" label="Chat" left="0" name="chat_btn" 7 <button bottom="0" font="SansSerif" height="24" label="Chat" left="0" name="chat_btn"
8 tool_tip="Talk to people nearby. (Enter)" width="50" /> 8 tool_tip="Talk to people nearby. (Enter)" width="50" />
9 <button bottom="0" font="SansSerif" height="24" label="Friends" left="0"
10 name="friends_btn" tool_tip="Find and communicate with your buddies."
11 width="50" />
12 <button bottom="0" font="SansSerif" height="24" label="Fly" 9 <button bottom="0" font="SansSerif" height="24" label="Fly"
13 label_selected="Stop Flying" left="0" name="fly_btn" 10 label_selected="Stop Flying" left="0" name="fly_btn"
14 tool_tip="Start flying. Use E/C or PgUp/PgDn to fly up and down." 11 tool_tip="Start flying. Use E/C or PgUp/PgDn to fly up and down."
diff --git a/linden/indra/newview/skins/xui/en-us/panel_voice_enable.xml b/linden/indra/newview/skins/xui/en-us/panel_voice_enable.xml
new file mode 100644
index 0000000..3a25ccc
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/panel_voice_enable.xml
@@ -0,0 +1,98 @@
1 <panel
2 border="false"
3 enabled="true"
4 left="8"
5 bottom="4"
6 mouse_opaque="true"
7 name="content_panel"
8 width="404"
9 height="240">
10
11 <text_editor
12 name="voice_intro_text1"
13 type="string"
14 enabled="false"
15 bg_readonly_color="0 0 0 0"
16 font="SansSerifSmall"
17 left_delta="0"
18 width="400"
19 height="65"
20 length="1"
21 max_length="65535"
22 hide_border="true"
23 hide_scrollbar="true"
24 embedded_items="false"
25 allow_html="false"
26 mouse_opaque="true"
27 tab_stop="false"
28 word_wrap="true">Welcome to Second Life Voice Chat! Voice Chat enables you to speak with other Residents. This wizard will guide you through the steps necessary to set up Voice Chat. Note that Voice Chat requires a stereo headset with a microphone; click the Help button for more information. </text_editor>
29
30 <text_editor
31 name="voice_intro_text2"
32 type="string"
33 enabled="false"
34 bg_readonly_color="0 0 0 0"
35 font="SansSerifSmall"
36 left_delta="0"
37 width="400"
38 height="30"
39 length="1"
40 max_length="65535"
41 hide_border="true"
42 hide_scrollbar="true"
43 embedded_items="false"
44 allow_html="false"
45 mouse_opaque="true"
46 tab_stop="false"
47 word_wrap="true">Do you want to enable Voice Chat now?</text_editor>
48
49 <radio_group draw_border="false" enabled="true"
50 follows="left|top" height="40" left="10"
51 mouse_opaque="true" name="voice_enable" width="364">
52 <radio_item type="string" length="1" bottom="-19" follows="left|top" height="16"
53 left="3" name="1" width="315">
54 Yes, enable Voice Chat.
55 </radio_item>
56 <radio_item type="string" length="1" bottom="-35" follows="left|top" height="16"
57 left="3" name="0" width="315">
58 No, do not enable Voice Chat at this time.
59 </radio_item>
60 </radio_group>
61
62 <text_editor
63 name="voice_intro_text3"
64 enabled="false"
65 bottom_delta="-50"
66 bg_readonly_color="0 0 0 0"
67 font="SansSerifSmall"
68 left="0"
69 width="400"
70 height="40"
71 length="1"
72 max_length="65535"
73 hide_border="true"
74 hide_scrollbar="true"
75 embedded_items="false"
76 allow_html="false"
77 tab_stop="false"
78 word_wrap="true">You can enable Voice Chat at any time by going to the Voice Chat tab in Preferences.</text_editor>
79
80 <text_editor
81 name="voice_intro_text4"
82 enabled="false"
83 bg_readonly_color="0 0 0 0"
84 bottom_delta="0"
85 font="SansSerifSmall"
86 left="0"
87 width="400"
88 height="40"
89 length="1"
90 max_length="65535"
91 hide_border="true"
92 hide_scrollbar="true"
93 embedded_items="false"
94 allow_html="false"
95 tab_stop="false"
96 word_wrap="true">Click the Next button to configure Voice Chat preferences or click Finish to continue using Second Life.</text_editor>
97
98 </panel> \ No newline at end of file
diff --git a/linden/indra/newview/skins/xui/en-us/panel_voice_options.xml b/linden/indra/newview/skins/xui/en-us/panel_voice_options.xml
new file mode 100644
index 0000000..040782b
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/panel_voice_options.xml
@@ -0,0 +1,46 @@
1<panel border="false" bottom="36" height="240" left="8" name="content_panel"
2 width="404">
3 <text_editor type="string" length="1" allow_html="false" bg_readonly_color="0 0 0 0" embedded_items="false"
4 enabled="false" font="SansSerifSmall" height="30" hide_border="true"
5 hide_scrollbar="true" left_delta="0" max_length="65535"
6 name="voice_intro_text1" tab_stop="false" width="414" word_wrap="true">
7 Use the options below to configure your Voice Chat experience.
8 </text_editor>
9 <radio_group bottom_delta="-40" draw_border="false"
10 follows="left|top" height="40" left="10" name="ear_location" width="364">
11 <radio_item type="string" length="1" bottom="-19" follows="left|top" height="16" left="3" name="0" width="315">
12 Hear Voice Chat from camera position.
13 </radio_item>
14 <radio_item type="string" length="1" bottom="-35" follows="left|top" height="16" left="3" name="1" width="315">
15 Hear Voice Chat from avatar position.
16 </radio_item>
17 </radio_group>
18 <check_box bottom_delta="-20" control_name="VoiceCallsFriendsOnly" follows="left|top"
19 font="SansSerifSmall" height="16" initial_value="false"
20 label="Only allow Friends to initiate Voice Calls with me" left="20"
21 left_delta="2" name="push_to_talk_check" width="200" />
22 <check_box bottom_delta="-20" control_name="EnablePushToTalk" follows="left|top"
23 font="SansSerifSmall" height="16" initial_value="false"
24 label="Start Viewer in Push-to-Talk mode" left_delta="0"
25 name="push_to_talk_check" width="200" />
26 <check_box bottom_delta="-20" control_name="PushToTalkToggle" follows="left|top"
27 font="SansSerifSmall" height="16" initial_value="false"
28 label="Use Push-to-Talk in toggle mode" left_delta="0"
29 name="push_to_talk_toggle_check" width="200" />
30 <text type="string" length="1" allow_html="false" bg_readonly_color="0 0 0 0" bottom_delta="-20"
31 embedded_items="false" follows="left|top" font="SansSerifSmall" height="16"
32 hide_border="true" hide_scrollbar="true" left_delta="4" max_length="65535"
33 name="push_to_talk_label" width="445" word_wrap="true">
34 Push-to-Talk trigger:
35 </text>
36 <line_editor border_drop_shadow_visible="false" border_visible="false" bottom_delta="-20"
37 control_name="PushToTalkButton" drop_shadow_visible="true" enabled="false"
38 follows="top|left" font="SansSerifSmall" halign="right" height="19"
39 left_delta="0" max_length="254" name="modifier_combo" width="255" />
40 <button bottom_delta="-25" follows="left|top" font="SansSerif" halign="center"
41 height="20" label="Set Key" left_delta="0" name="set_voice_hotkey_button"
42 width="90" />
43 <button bottom_delta="0" follows="left|top" font="SansSerif" halign="center"
44 height="20" label="Middle Mouse Button" left_delta="95"
45 name="set_voice_middlemouse_button" width="160" />
46</panel>
diff --git a/linden/indra/newview/skins/xui/en-us/panel_voice_remote.xml b/linden/indra/newview/skins/xui/en-us/panel_voice_remote.xml
new file mode 100644
index 0000000..28cead3
--- /dev/null
+++ b/linden/indra/newview/skins/xui/en-us/panel_voice_remote.xml
@@ -0,0 +1,12 @@
1<panel bg_visible="false" border="false" border_visible="false" bottom="-34"
2 enabled="true" follows="left|top" hidden="false"
3 mouse_opaque="true" name="music_remote" >
4 <button bottom="-22" height="22" label="" image_overlay="active_speakers.tga" left="2" name="speakers_btn"
5 tool_tip="Show list of residents using voice chat around you" width="38" />
6 <button bottom="-22" height="22" label="Talk" left_delta="40" name="push_to_talk"
7 tab_stop="false" tool_tip="Hold the button to talk" width="64" />
8 <button bottom="-19" height="16" image_selected="ptt_lock_on.tga"
9 image_unselected="ptt_lock_off.tga" label="" left_delta="4" name="ptt_lock"
10 scale_image="true" tool_tip="Click lock to switch to talk mode" width="16" />
11 <icon name="voice_volume" left_delta="40" bottom="-19" width="16" height="16" image_name="icn_voice_ptt-off.tga"/>
12</panel>
diff --git a/linden/indra/newview/skins/xui/es/role_actions.xml b/linden/indra/newview/skins/xui/es/role_actions.xml
index 0632b23..1e10ccf 100644
--- a/linden/indra/newview/skins/xui/es/role_actions.xml
+++ b/linden/indra/newview/skins/xui/es/role_actions.xml
@@ -1,186 +1,186 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<role_actions> 2<role_actions>
3 <action_set 3 <action_set
4 description="Estas habilidades incluyen poderes de adicionar o remover miembros del grupo y permitir que nuevos miembros se junten sin una invitación." 4 description="Estas habilidades incluyen poderes de adicionar o remover miembros del grupo y permitir que nuevos miembros se junten sin una invitación."
5 name="Membership"> 5 name="Membership">
6 <action description="Invitar personas para este grupo" 6 <action description="Invitar personas para este grupo"
7 longdescription="Invite personas para este grupo usando el botón &apos;Invitar nueva persona...&apos; en Miembros &amp; pestaña Funciones &gt; subpestaña Miembros." 7 longdescription="Invite personas para este grupo usando el botón &apos;Invitar nueva persona...&apos; en Miembros &amp; pestaña Funciones &gt; subpestaña Miembros."
8 name="member invite" /> 8 name="member invite" value="1" />
9 <action description="Expulsar a miembros de este grupo" 9 <action description="Expulsar a miembros de este grupo"
10 longdescription="Expulse a miembros de este grupo usando el botón &apos;Expulsar del grupo&apos; en Miembros &amp; pestaña Funciones &gt; subpestaña Miembros. Un propietario puede expulsar a cualquiera, excepto a otro propietario. Si usted no es un propietario, un miembro puede a expulsarlo del grupo si, y solamente si, él apenas tiene la función de todos y no otras funciones. Para remover miembros de funciones, necesita tener la habilidad &apos;Remover miembros de funciones&apos;." 10 longdescription="Expulse a miembros de este grupo usando el botón &apos;Expulsar del grupo&apos; en Miembros &amp; pestaña Funciones &gt; subpestaña Miembros. Un propietario puede expulsar a cualquiera, excepto a otro propietario. Si usted no es un propietario, un miembro puede a expulsarlo del grupo si, y solamente si, él apenas tiene la función de todos y no otras funciones. Para remover miembros de funciones, necesita tener la habilidad &apos;Remover miembros de funciones&apos;."
11 name="member eject" /> 11 name="member eject" value="2" />
12 <action 12 <action
13 description="Activar/desactivar &apos;Abrir registro&apos; y cambiar &apos;Tasa de suscripción&apos;" 13 description="Activar/desactivar &apos;Abrir registro&apos; y cambiar &apos;Tasa de suscripción&apos;"
14 longdescription="Active/desactive &apos;Abrir registro&apos; para permitir que nuevos miembros se unan sin una invitación, y cambie &apos;Tasa de registro&apos; en la sección Preferencia de grupo de la pestaña General." 14 longdescription="Active/desactive &apos;Abrir registro&apos; para permitir que nuevos miembros se unan sin una invitación, y cambie &apos;Tasa de registro&apos; en la sección Preferencia de grupo de la pestaña General."
15 name="member options" /> 15 name="member options" value="3" />
16 </action_set> 16 </action_set>
17 <action_set 17 <action_set
18 description="Estas habilidades incluyen poderes de adicionar, remover y cambiar funciones del grupo; adicionar y remover miembros en funciones y designar habilidades a funciones." 18 description="Estas habilidades incluyen poderes de adicionar, remover y cambiar funciones del grupo; adicionar y remover miembros en funciones y designar habilidades a funciones."
19 name="Roles"> 19 name="Roles">
20 <action description="Crear nuevas funciones" 20 <action description="Crear nuevas funciones"
21 longdescription="Cree nuevas funciones en Miembros &amp; pestaña Funciones &gt; subpestaña Funciones." 21 longdescription="Cree nuevas funciones en Miembros &amp; pestaña Funciones &gt; subpestaña Funciones."
22 name="role create" /> 22 name="role create" value="4" />
23 <action description="Borrar funciones" 23 <action description="Borrar funciones"
24 longdescription="Borra funciones en Miembros &amp; pestaña Funciones &gt; subpestaña Funciones." 24 longdescription="Borra funciones en Miembros &amp; pestaña Funciones &gt; subpestaña Funciones."
25 name="role delete" /> 25 name="role delete" value="5" />
26 <action description="Cambiar nombres de funciones, títulos y descripciones" 26 <action description="Cambiar nombres de funciones, títulos y descripciones"
27 longdescription="Cambie el nombre de funciones, títulos y descripciones en la parte inferior de Miembros &amp; pestaña Funciones &gt; subpestaña Funciones después de seleccionar una función." 27 longdescription="Cambie el nombre de funciones, títulos y descripciones en la parte inferior de Miembros &amp; pestaña Funciones &gt; subpestaña Funciones después de seleccionar una función."
28 name="role properties" /> 28 name="role properties" value="6" />
29 <action description="Designar miembros para la función&apos;s del asignador" 29 <action description="Designar miembros para la función&apos;s del asignador"
30 longdescription="Designe miembros para funciones en la sección de funciones designadas de Miembros &amp; pestaña Funciones &gt; subpestaña Miembros. Un miembro con este poder puede solamente adicionar miembros para la función que el asignador ya posee." 30 longdescription="Designe miembros para funciones en la sección de funciones designadas de Miembros &amp; pestaña Funciones &gt; subpestaña Miembros. Un miembro con este poder puede solamente adicionar miembros para la función que el asignador ya posee."
31 name="role assign member limited" /> 31 name="role assign member limited" value="7" />
32 <action description="Designar miembros para cualquier función" 32 <action description="Designar miembros para cualquier función"
33 longdescription="Designe miembros para cualquier función en la sección de funciones designadas de Miembros &amp; pestaña Funciones &gt; subpestaña Miembros. *AVISO* Cualesquiera miembros en una función con esta habilidad pueden designar a sí propios--y cualesquiera otros miembros no propietarios--para funciones que tienen más poderes que las actuales, promocionándolos a poderes próximos al del propietario. Asegúrese de saber lo que está haciendo antes de designar esta habilidad." 33 longdescription="Designe miembros para cualquier función en la sección de funciones designadas de Miembros &amp; pestaña Funciones &gt; subpestaña Miembros. *AVISO* Cualesquiera miembros en una función con esta habilidad pueden designar a sí propios--y cualesquiera otros miembros no propietarios--para funciones que tienen más poderes que las actuales, promocionándolos a poderes próximos al del propietario. Asegúrese de saber lo que está haciendo antes de designar esta habilidad."
34 name="role assign member" /> 34 name="role assign member" value="8" />
35 <action description="Remover miembros de las funciones" 35 <action description="Remover miembros de las funciones"
36 longdescription="Remueva miembros de funciones en la sección de funciones designadas de Miembros &amp; pestaña Funciones &gt; subpestaña Miembros. Propietarios no pueden&apos; ser removidos." 36 longdescription="Remueva miembros de funciones en la sección de funciones designadas de Miembros &amp; pestaña Funciones &gt; subpestaña Miembros. Propietarios no pueden&apos; ser removidos."
37 name="role remove member" /> 37 name="role remove member" value="9" />
38 <action description="Determinar y remover habilidades en función" 38 <action description="Determinar y remover habilidades en función"
39 longdescription="Designe y remueva habilidades en funciones en la sección habilidades permitidas de Miembros &amp; pestaña Funciones &gt; subpestaña Funciones. *AVISO* Cualesquiera miembros en una función con esta habilidad pueden designar a sí propios--y cualesquiera otros miembros no propietarios--todas las habilidades, promocionándolos a poderes próximos al del propietario. Asegúrese de saber lo que está haciendo antes de designar esta habilidad." 39 longdescription="Designe y remueva habilidades en funciones en la sección habilidades permitidas de Miembros &amp; pestaña Funciones &gt; subpestaña Funciones. *AVISO* Cualesquiera miembros en una función con esta habilidad pueden designar a sí propios--y cualesquiera otros miembros no propietarios--todas las habilidades, promocionándolos a poderes próximos al del propietario. Asegúrese de saber lo que está haciendo antes de designar esta habilidad."
40 name="role change actions" /> 40 name="role change actions" value="10" />
41 </action_set> 41 </action_set>
42 <action_set 42 <action_set
43 description="Estas habilidades incluyen poderes para modificar esta identidad de grupo, como cambiar la visibilidad pública, presentación y insignia." 43 description="Estas habilidades incluyen poderes para modificar esta identidad de grupo, como cambiar la visibilidad pública, presentación y insignia."
44 name="Group Identity"> 44 name="Group Identity">
45 <action 45 <action
46 description="Cambiar presentación, insignia, &apos;Publicar en la web&apos;, y cuales miembros están públicamente visibles en Informaciones del Grupo." 46 description="Cambiar presentación, insignia, &apos;Publicar en la web&apos;, y cuales miembros están públicamente visibles en Informaciones del Grupo."
47 longdescription="Cambie la presentación, insignia, &apos;Publicar en la web&apos; y cuales miembros están públicamente visibles en Informaciones del grupo. Es hecho en la pestaña General." 47 longdescription="Cambie la presentación, insignia, &apos;Publicar en la web&apos; y cuales miembros están públicamente visibles en Informaciones del grupo. Es hecho en la pestaña General."
48 name="group change identity" /> 48 name="group change identity" value="11" />
49 </action_set> 49 </action_set>
50 <action_set 50 <action_set
51 description="Estas habilidades incluyen poderes para transferir, modificar y vender terrenos del grupo. Vaya para la ventana Sobre el terreno, haga clic con el botón derecho en el terreno y seleccione &apos;Sobre el terreno...&apos; o haga clic en la información de la parcela en la barra del menú." 51 description="Estas habilidades incluyen poderes para transferir, modificar y vender terrenos del grupo. Vaya para la ventana Sobre el terreno, haga clic con el botón derecho en el terreno y seleccione &apos;Sobre el terreno...&apos; o haga clic en la información de la parcela en la barra del menú."
52 name="Parcel Management"> 52 name="Parcel Management">
53 <action description="Transferir y comprar terreno para el grupo" 53 <action description="Transferir y comprar terreno para el grupo"
54 longdescription="Transfiere y compre terreno para el grupo. Es hecho en Sobre el terreno &gt; pestaña General." 54 longdescription="Transfiere y compre terreno para el grupo. Es hecho en Sobre el terreno &gt; pestaña General."
55 name="land deed" /> 55 name="land deed" value="12" />
56 <action description="Abandonar al terreno para Gobernador Linden" 56 <action description="Abandonar al terreno para Gobernador Linden"
57 longdescription="Abandone al terreno para Gobernador Linden. *AVISO* Cualquier miembro en una función con esta habilidad puede abandonar al terreno perteneciente al grupo en Sobre el terreno &gt; pestaña General, revirtiendo a la posesión Linden sin una venta! Asegúrese de saber lo que está haciendo antes de designar esta habilidad." 57 longdescription="Abandone al terreno para Gobernador Linden. *AVISO* Cualquier miembro en una función con esta habilidad puede abandonar al terreno perteneciente al grupo en Sobre el terreno &gt; pestaña General, revirtiendo a la posesión Linden sin una venta! Asegúrese de saber lo que está haciendo antes de designar esta habilidad."
58 name="land release" /> 58 name="land release" value="13" />
59 <action description="Definir terreno para información de venta" 59 <action description="Definir terreno para información de venta"
60 longdescription="Defina informaciones de venta para terreno. *AVISO* Cualquier miembro en una función con esta habilidad puede vender terrenos pertenecientes al grupo en Sobre el terreno &gt; pestaña General ¡cómo quiera! Asegúrese de saber lo que está haciendo antes de designar esta habilidad." 60 longdescription="Defina informaciones de venta para terreno. *AVISO* Cualquier miembro en una función con esta habilidad puede vender terrenos pertenecientes al grupo en Sobre el terreno &gt; pestaña General ¡cómo quiera! Asegúrese de saber lo que está haciendo antes de designar esta habilidad."
61 name="land set sale info" /> 61 name="land set sale info" value="14" />
62 <action description="Subdividir y unir parcelas" 62 <action description="Subdividir y unir parcelas"
63 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. " 63 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. "
64 name="land divide join" /> 64 name="land divide join" value="15" />
65 </action_set> 65 </action_set>
66 <action_set 66 <action_set
67 description="Estas habilidades incluyen poderes para cambiar el nombre de las parcelas y configuraciones de publicación, visibilidad de la búsqueda de directorio y punto de aterrizaje &amp; opciones de ruta de TP." 67 description="Estas habilidades incluyen poderes para cambiar el nombre de las parcelas y configuraciones de publicación, visibilidad de la búsqueda de directorio y punto de aterrizaje &amp; opciones de ruta de TP."
68 name="Parcel Identity"> 68 name="Parcel Identity">
69 <action 69 <action
70 description="Activar/desactivar &apos;Exhibir en locales de encuentro&apos; y definir categoría" 70 description="Activar/desactivar &apos;Exhibir en locales de encuentro&apos; y definir categoría"
71 longdescription="Activar/desactivar &apos;Exhibir en locales de encuentro&apos; y configurar una categoría de parcela en Sobre el terreno &gt; pestaña Opciones." 71 longdescription="Activar/desactivar &apos;Exhibir en locales de encuentro&apos; y configurar una categoría de parcela en Sobre el terreno &gt; pestaña Opciones."
72 name="land find places" /> 72 name="land find places" value="17" />
73 <action 73 <action
74 description="Cambiar nombre de la parcela, descripción, y configuraciones &apos;Publicar en la web&apos;" 74 description="Cambiar nombre de la parcela, descripción, y configuraciones &apos;Publicar en la web&apos;"
75 longdescription="Cambie el nombre de la parcela, descripción y configuraciones de &apos;Publicar en la web&apos;. Es hecho en Sobre el terreno &gt; pestaña Opciones." 75 longdescription="Cambie el nombre de la parcela, descripción y configuraciones de &apos;Publicar en la web&apos;. Es hecho en Sobre el terreno &gt; pestaña Opciones."
76 name="land change identity" /> 76 name="land change identity" value="18" />
77 <action description="Definir punto de aterrizaje y ruta de teletransporte" 77 <action description="Definir punto de aterrizaje y ruta de teletransporte"
78 longdescription="En una parcela perteneciente al grupo, miembros en una función con esta habilidad pueden definir un punto de aterrizaje para especificar donde los teletransportes llegan y también definir la ruta del teletransporte para un mayor control. Es hecho en Sobre el terreno &gt; pestaña Opciones." 78 longdescription="En una parcela perteneciente al grupo, miembros en una función con esta habilidad pueden definir un punto de aterrizaje para especificar donde los teletransportes llegan y también definir la ruta del teletransporte para un mayor control. Es hecho en Sobre el terreno &gt; pestaña Opciones."
79 name="land set landing point" /> 79 name="land set landing point" value="19" />
80 </action_set> 80 </action_set>
81 <action_set 81 <action_set
82 description="Estas habilidades incluyen poderes que afectan opciones de parcela, como &apos;Crear objetos&apos;, &apos;Editar terreno&apos; y música &amp; configuraciones de multimedia." 82 description="Estas habilidades incluyen poderes que afectan opciones de parcela, como &apos;Crear objetos&apos;, &apos;Editar terreno&apos; y música &amp; configuraciones de multimedia."
83 name="Parcel Settings"> 83 name="Parcel Settings">
84 <action description="Cambiar música &amp; configuraciones de multimedia" 84 <action description="Cambiar música &amp; configuraciones de multimedia"
85 longdescription="Cambie streaming de música y configuraciones de vídeo en Sobre el terreno &gt; pestaña Multimedia." 85 longdescription="Cambie streaming de música y configuraciones de vídeo en Sobre el terreno &gt; pestaña Multimedia."
86 name="land change media" /> 86 name="land change media" value="20" />
87 <action description="Activar/desactivar &apos;Editar terreno&apos;" 87 <action description="Activar/desactivar &apos;Editar terreno&apos;"
88 longdescription="Active/desactive &apos;Editar terreno&apos;. *AVISO* Sobre el terreno &gt; pestaña Opciones &gt; Editar terreno permite a cualquiera alterar las formas de su terreno&apos;, sustituir y mover plantas Linden. Asegúrese de saber lo que está haciendo antes de designar esta habilidad. La edición de terreno es activada/desactivada en Sobre el terreno &gt; pestaña Opciones." 88 longdescription="Active/desactive &apos;Editar terreno&apos;. *AVISO* Sobre el terreno &gt; pestaña Opciones &gt; Editar terreno permite a cualquiera alterar las formas de su terreno&apos;, sustituir y mover plantas Linden. Asegúrese de saber lo que está haciendo antes de designar esta habilidad. La edición de terreno es activada/desactivada en Sobre el terreno &gt; pestaña Opciones."
89 name="land edit" /> 89 name="land edit" value="21" />
90 <action 90 <action
91 description="Activar/desactivar variados Sobre el Terreno &gt; Opciones de configuraciones" 91 description="Activar/desactivar variados Sobre el Terreno &gt; Opciones de configuraciones"
92 longdescription="Active/desactive &apos;Seguro (sin daño)&apos;, &apos;Volar&apos;, y permita a otros residentes: &apos;Crear objetos&apos;, &apos;Editar terreno&apos;, &apos;Crear puntos de referencia&apos;, y &apos;Ejecutar scripts&apos; en un terreno perteneciente al grupo en Sobre el terreno &gt; pestaña Opciones." 92 longdescription="Active/desactive &apos;Seguro (sin daño)&apos;, &apos;Volar&apos;, y permita a otros residentes: &apos;Crear objetos&apos;, &apos;Editar terreno&apos;, &apos;Crear puntos de referencia&apos;, y &apos;Ejecutar scripts&apos; en un terreno perteneciente al grupo en Sobre el terreno &gt; pestaña Opciones."
93 name="land options" /> 93 name="land options" value="22" />
94 </action_set> 94 </action_set>
95 <action_set 95 <action_set
96 description="Estas habilidades incluyen poderes que permiten a miembros rebasar restricciones en parcelas pertenecientes al grupo." 96 description="Estas habilidades incluyen poderes que permiten a miembros rebasar restricciones en parcelas pertenecientes al grupo."
97 name="Parcel Powers"> 97 name="Parcel Powers">
98 <action description="Siempre permitir &apos;Editar terreno&apos;" 98 <action description="Siempre permitir &apos;Editar terreno&apos;"
99 longdescription="Miembros en una función con esta habilidad pueden editar terreno en una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno &gt; pestaña Opciones." 99 longdescription="Miembros en una función con esta habilidad pueden editar terreno en una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno &gt; pestaña Opciones."
100 name="land allow edit land" /> 100 name="land allow edit land" value="23" />
101 <action description="Siempre permitir &apos;Volar&apos;" 101 <action description="Siempre permitir &apos;Volar&apos;"
102 longdescription="Miembros en una función con esta habilidad pueden volar sobre una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno &gt; pestaña Opciones." 102 longdescription="Miembros en una función con esta habilidad pueden volar sobre una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno &gt; pestaña Opciones."
103 name="land allow fly" /> 103 name="land allow fly" value="24" />
104 <action description="Siempre permitir &apos;Crear objetos&apos;" 104 <action description="Siempre permitir &apos;Crear objetos&apos;"
105 longdescription="Miembros en una función con esta habilidad pueden crear objetos en una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno &gt; pestaña Opciones." 105 longdescription="Miembros en una función con esta habilidad pueden crear objetos en una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno &gt; pestaña Opciones."
106 name="land allow create" /> 106 name="land allow create" value="25" />
107 <action description="Siempre permitir &apos;Crear punto de referencia&apos;" 107 <action description="Siempre permitir &apos;Crear punto de referencia&apos;"
108 longdescription="Miembros en una función con esta habilidad pueden poner un punto de referencia en una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno &gt; pestaña Opciones." 108 longdescription="Miembros en una función con esta habilidad pueden poner un punto de referencia en una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno &gt; pestaña Opciones."
109 name="land allow landmark" /> 109 name="land allow landmark" value="26" />
110 <action description="Permitir &apos;Colocar casa aquí&apos; en el terreno del grupo" 110 <action description="Permitir &apos;Colocar casa aquí&apos; en el terreno del grupo"
111 longdescription="Miembros en una función con esta habilidad pueden usar el menú Mundo &gt; Definir hogar aquí en una parcela del grupo (definir terreno o transferir para este grupo)." 111 longdescription="Miembros en una función con esta habilidad pueden usar el menú Mundo &gt; Definir hogar aquí en una parcela del grupo (definir terreno o transferir para este grupo)."
112 name="land allow set home" /> 112 name="land allow set home" value="28" />
113 </action_set> 113 </action_set>
114 <action_set 114 <action_set
115 description="Estas habilidades incluyen poderes de permitir o restringir acceso a parcelas pertenecientes al grupo, incluyendo congelar y expulsar a residentes." 115 description="Estas habilidades incluyen poderes de permitir o restringir acceso a parcelas pertenecientes al grupo, incluyendo congelar y expulsar a residentes."
116 name="Parcel Access"> 116 name="Parcel Access">
117 <action description="Administrar listas de acceso a la parcela" 117 <action description="Administrar listas de acceso a la parcela"
118 longdescription="Administre la lista de acceso a la parcela en Sobre el terreno &gt; pestaña Acceso." 118 longdescription="Administre la lista de acceso a la parcela en Sobre el terreno &gt; pestaña Acceso."
119 name="land manage allowed" /> 119 name="land manage allowed" value="29" />
120 <action description="Administrar lista de desterrados de la parcela" 120 <action description="Administrar lista de desterrados de la parcela"
121 longdescription="Administre la lista de desterrados de la parcela en Sobre el terreno &gt; pestaña Desterrado." 121 longdescription="Administre la lista de desterrados de la parcela en Sobre el terreno &gt; pestaña Desterrado."
122 name="land manage banned" /> 122 name="land manage banned" value="30" />
123 <action description="Cambiar configuraciones de parcela &apos;Vender pases...&apos;" 123 <action description="Cambiar configuraciones de parcela &apos;Vender pases...&apos;"
124 longdescription="Cambie configuraciones de &apos;Vender pases...&apos; en Sobre el terreno &gt; pestaña Acceso." 124 longdescription="Cambie configuraciones de &apos;Vender pases...&apos; en Sobre el terreno &gt; pestaña Acceso."
125 name="land manage passes" /> 125 name="land manage passes" value="31" />
126 <action description="Expulsar y congelar residentes en las parcelas" 126 <action description="Expulsar y congelar residentes en las parcelas"
127 longdescription="Miembros en una función con esta habilidad pueden lidiar con un residente indeseado en una parcela perteneciente al grupo haciendo clic con el botón derecho sobre él, Más &gt; y seleccionando &apos;Expulsar...&apos; o &apos;Congelar...&apos;." 127 longdescription="Miembros en una función con esta habilidad pueden lidiar con un residente indeseado en una parcela perteneciente al grupo haciendo clic con el botón derecho sobre él, Más &gt; y seleccionando &apos;Expulsar...&apos; o &apos;Congelar...&apos;."
128 name="land admin" /> 128 name="land admin" value="32" />
129 </action_set> 129 </action_set>
130 <action_set 130 <action_set
131 description="Estas habilidades incluyen poderes de permitir a miembros devolver objetos y poner y mover plantas Linden. Útil para que miembros organicen el paisaje, pero debe ser usado con cuidado, debido a no ser posible deshacer la mudanza de los objetos." 131 description="Estas habilidades incluyen poderes de permitir a miembros devolver objetos y poner y mover plantas Linden. Útil para que miembros organicen el paisaje, pero debe ser usado con cuidado, debido a no ser posible deshacer la mudanza de los objetos."
132 name="Parcel Content"> 132 name="Parcel Content">
133 <action description="Devolver objetos que pertenecen al grupo" 133 <action description="Devolver objetos que pertenecen al grupo"
134 longdescription="Devuelva objetos en parcelas pertenecientes al grupo que pertenecen al grupo en Sobre el terreno &gt; pestaña Objetos." 134 longdescription="Devuelva objetos en parcelas pertenecientes al grupo que pertenecen al grupo en Sobre el terreno &gt; pestaña Objetos."
135 name="land return group owned" /> 135 name="land return group owned" value="48" />
136 <action description="Devolver objetos definidos para el grupo" 136 <action description="Devolver objetos definidos para el grupo"
137 longdescription="Devuelva objetos en parcelas pertenecientes al grupo en Sobre el terreno &gt; pestaña Objetos." 137 longdescription="Devuelva objetos en parcelas pertenecientes al grupo en Sobre el terreno &gt; pestaña Objetos."
138 name="land return group set" /> 138 name="land return group set" value="33" />
139 <action description="Devolver objetos que no pertenecen al grupo" 139 <action description="Devolver objetos que no pertenecen al grupo"
140 longdescription="Devuelva objetos en las parcelas pertenecientes a un grupo que está sin grupo en el Sobre el terreno &gt; pestaña Objetos." 140 longdescription="Devuelva objetos en las parcelas pertenecientes a un grupo que está sin grupo en el Sobre el terreno &gt; pestaña Objetos."
141 name="land return non group" /> 141 name="land return non group" value="34" />
142 <action description="Enjardinar usando plantas Linden" 142 <action description="Enjardinar usando plantas Linden"
143 longdescription="La habilidad de enjardinar permite poner y mover árboles Linden, plantas y céspedes. Estos ítems pueden ser encontrados en la&apos;s Biblioteca de su inventario &gt; carpeta Objetos o pueden ser criados a través del botón Construir." 143 longdescription="La habilidad de enjardinar permite poner y mover árboles Linden, plantas y céspedes. Estos ítems pueden ser encontrados en la&apos;s Biblioteca de su inventario &gt; carpeta Objetos o pueden ser criados a través del botón Construir."
144 name="land gardening" /> 144 name="land gardening" value="35" />
145 </action_set> 145 </action_set>
146 <action_set 146 <action_set
147 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. " 147 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. "
148 name="Object Management"> 148 name="Object Management">
149 <action description="Transferir objetos para el grupo" 149 <action description="Transferir objetos para el grupo"
150 longdescription="Transfiere objetos para el grupo en Editar herramientas &gt; pestaña General." 150 longdescription="Transfiere objetos para el grupo en Editar herramientas &gt; pestaña General."
151 name="object deed" /> 151 name="object deed" value="36" />
152 <action description="Manipular (mover, copiar, modificar) objetos del grupo" 152 <action description="Manipular (mover, copiar, modificar) objetos del grupo"
153 longdescription="Manipule (mover,copiar, modificar) objetos pertenecientes al grupo en Editar Herramientas &gt; pestaña General." 153 longdescription="Manipule (mover,copiar, modificar) objetos pertenecientes al grupo en Editar Herramientas &gt; pestaña General."
154 name="object manipulate" /> 154 name="object manipulate" value="38" />
155 <action description="Definir objetos pertenecientes al grupo para venta" 155 <action description="Definir objetos pertenecientes al grupo para venta"
156 longdescription="Defina objetos pertenecientes al grupo para venta en Editar Herramientas &gt; pestaña General." 156 longdescription="Defina objetos pertenecientes al grupo para venta en Editar Herramientas &gt; pestaña General."
157 name="object set sale" /> 157 name="object set sale" value="39" />
158 </action_set> 158 </action_set>
159 <action_set 159 <action_set
160 description="Estas habilidades incluyen poderes que requieren que miembros paguen deudas y reciban dividendos del grupo, y restringen acceso al historial de cuenta del grupo." 160 description="Estas habilidades incluyen poderes que requieren que miembros paguen deudas y reciban dividendos del grupo, y restringen acceso al historial de cuenta del grupo."
161 name="Accounting"> 161 name="Accounting">
162 <action description="Pagar débitos y reciber dividendos del grupo" 162 <action description="Pagar débitos y reciber dividendos del grupo"
163 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. " 163 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. "
164 name="accounting accountable" /> 164 name="accounting accountable" value="40" />
165 </action_set> 165 </action_set>
166 <action_set 166 <action_set
167 description="Estas habilidades incluyen poderes de permitir enviar, recibir y ver avisos de grupo." 167 description="Estas habilidades incluyen poderes de permitir enviar, recibir y ver avisos de grupo."
168 name="Notices"> 168 name="Notices">
169 <action description="Enviar aviso" 169 <action description="Enviar aviso"
170 longdescription="Miembros en una función con esta habilidad pueden enviar avisos en Informaciones de grupo &gt; pestaña Avisos." 170 longdescription="Miembros en una función con esta habilidad pueden enviar avisos en Informaciones de grupo &gt; pestaña Avisos."
171 name="notices send" /> 171 name="notices send" value="42" />
172 <action description="Reciber nuevos avisos y ver los anteriores" 172 <action description="Reciber nuevos avisos y ver los anteriores"
173 longdescription="Miembros en una función con esta habilidad pueden recibir los nuevos avisos y ver los anteriores en Informaciones de grupo &gt; pestaña Avisos." 173 longdescription="Miembros en una función con esta habilidad pueden recibir los nuevos avisos y ver los anteriores en Informaciones de grupo &gt; pestaña Avisos."
174 name="notices receive" /> 174 name="notices receive" value="43" />
175 </action_set> 175 </action_set>
176 <action_set 176 <action_set
177 description="Estas habilidades incluyen poderes de permitir a miembros definir y votar en propuestas y ver historial de votación." 177 description="Estas habilidades incluyen poderes de permitir a miembros definir y votar en propuestas y ver historial de votación."
178 name="Proposals"> 178 name="Proposals">
179 <action description="Crear propuesta" 179 <action description="Crear propuesta"
180 longdescription="Miembros en una función con esta habilidad pueden crear propuestas para que sean votadas en Informaciones de grupo &gt; pestaña Propuestas." 180 longdescription="Miembros en una función con esta habilidad pueden crear propuestas para que sean votadas en Informaciones de grupo &gt; pestaña Propuestas."
181 name="proposal start" /> 181 name="proposal start" value="44" />
182 <action description="Votar en propuestas" 182 <action description="Votar en propuestas"
183 longdescription="Miembros en una función con esta habilidad pueden votar en propuestas en Informaciones de grupo &gt; pestaña Propuestas." 183 longdescription="Miembros en una función con esta habilidad pueden votar en propuestas en Informaciones de grupo &gt; pestaña Propuestas."
184 name="proposal vote" /> 184 name="proposal vote" value="45" />
185 </action_set> 185 </action_set>
186</role_actions> 186</role_actions>
diff --git a/linden/indra/newview/skins/xui/fr/role_actions.xml b/linden/indra/newview/skins/xui/fr/role_actions.xml
index 12c8cc6..c3d6ffe 100644
--- a/linden/indra/newview/skins/xui/fr/role_actions.xml
+++ b/linden/indra/newview/skins/xui/fr/role_actions.xml
@@ -1,189 +1,189 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<role_actions> 2<role_actions>
3 <action_set 3 <action_set
4 description="Ces Facultés confèrent le pouvoir d&apos;ajouter et supprimer des Membres du groupe, et d&apos;autoriser de nouveaux Membres à s&apos;inscrire sans invitation." 4 description="Ces Facultés confèrent le pouvoir d&apos;ajouter et supprimer des Membres du groupe, et d&apos;autoriser de nouveaux Membres à s&apos;inscrire sans invitation."
5 name="Membership"> 5 name="Membership">
6 <action description="Inviter quelqu&apos;un dans ce groupe" 6 <action description="Inviter quelqu&apos;un dans ce groupe"
7 longdescription="Invitez des personnes dans ce Groupe à l&apos;aide du bouton &apos;Inviter&apos; dans l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Membres." 7 longdescription="Invitez des personnes dans ce Groupe à l&apos;aide du bouton &apos;Inviter&apos; dans l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Membres."
8 name="member invite" /> 8 name="member invite" value="1" />
9 <action description="Ejecter des Membres du Groupe" 9 <action description="Ejecter des Membres du Groupe"
10 longdescription="Ejectez des Membres de ce groupe à l&apos;aide du bouton &apos;Ejecter du groupe&apos; dans l&apos;onglet Membres &amp; Rôles &gt; Membres. Un propriétaire peut éjecter tout le monde, sauf un autre propriétaire. Si vous n&apos;êtes pas propriétaire, vous pouvez éjecter un Membre si et seulement si il est dans le Rôle &apos;Tout le monde&apos; et AUCUN autre.Pour destituer des Membres d&apos;un Rôle, vous devez disposer de la Faculté &apos;Destituer Membres d&apos;un Rôle&apos;." 10 longdescription="Ejectez des Membres de ce groupe à l&apos;aide du bouton &apos;Ejecter du groupe&apos; dans l&apos;onglet Membres &amp; Rôles &gt; Membres. Un propriétaire peut éjecter tout le monde, sauf un autre propriétaire. Si vous n&apos;êtes pas propriétaire, vous pouvez éjecter un Membre si et seulement si il est dans le Rôle &apos;Tout le monde&apos; et AUCUN autre.Pour destituer des Membres d&apos;un Rôle, vous devez disposer de la Faculté &apos;Destituer Membres d&apos;un Rôle&apos;."
11 name="member eject" /> 11 name="member eject" value="2" />
12 <action 12 <action
13 description="Basculer &apos;Inscription libre&apos; et modifier &apos;Frais d&apos;inscription&apos;" 13 description="Basculer &apos;Inscription libre&apos; et modifier &apos;Frais d&apos;inscription&apos;"
14 longdescription="Basculez &apos;Inscription libre&apos; pour permettre à de nouveaux Membres de s&apos;inscrire sans invitation, et modifiez &apos;Frais d&apos;inscription&apos; dans les Préférences du Groupe, onglet Général." 14 longdescription="Basculez &apos;Inscription libre&apos; pour permettre à de nouveaux Membres de s&apos;inscrire sans invitation, et modifiez &apos;Frais d&apos;inscription&apos; dans les Préférences du Groupe, onglet Général."
15 name="member options" /> 15 name="member options" value="3" />
16 </action_set> 16 </action_set>
17 <action_set 17 <action_set
18 description="Ces Facultés confèrent le pouvoir d&apos;ajouter, supprimer et modifier les Rôles dans le groupe, d&apos;ajouter et supprimer des Membres affectés à des Rôles, et d&apos;attribuer des Facultés aux Rôles." 18 description="Ces Facultés confèrent le pouvoir d&apos;ajouter, supprimer et modifier les Rôles dans le groupe, d&apos;ajouter et supprimer des Membres affectés à des Rôles, et d&apos;attribuer des Facultés aux Rôles."
19 name="Roles"> 19 name="Roles">
20 <action description="Créer de nouveaux rôles" 20 <action description="Créer de nouveaux rôles"
21 longdescription="Créez de nouveaux Rôles dans l&apos;onglet &apos;Membres et Rôles&apos; &gt; sous-onglet Rôles." 21 longdescription="Créez de nouveaux Rôles dans l&apos;onglet &apos;Membres et Rôles&apos; &gt; sous-onglet Rôles."
22 name="role create" /> 22 name="role create" value="4" />
23 <action description="Supprimer des Rôles" 23 <action description="Supprimer des Rôles"
24 longdescription="Supprimez des Rôles dans l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Rôles." 24 longdescription="Supprimez des Rôles dans l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Rôles."
25 name="role delete" /> 25 name="role delete" value="5" />
26 <action description="Modifier les noms, titres et descriptions des Rôles" 26 <action description="Modifier les noms, titres et descriptions des Rôles"
27 longdescription="Modifiez les noms, titres et descriptions des Rôles dans l&apos;onglet Membres et Rôles &gt; sous-onglet Rôles après avoir sélectionné un Rôle." 27 longdescription="Modifiez les noms, titres et descriptions des Rôles dans l&apos;onglet Membres et Rôles &gt; sous-onglet Rôles après avoir sélectionné un Rôle."
28 name="role properties" /> 28 name="role properties" value="6" />
29 <action description="Affecter des Membres à des rôles d&apos;attribution" 29 <action description="Affecter des Membres à des rôles d&apos;attribution"
30 longdescription="Affectez des Membres à des Rôles dans la section &apos;Rôles Attribués&apos; de l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Membres. Un Membre disposant de ce pouvoir ne peut affecter de nouveaux membres qu&apos;à un rôle auquel il est lui-même affecté." 30 longdescription="Affectez des Membres à des Rôles dans la section &apos;Rôles Attribués&apos; de l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Membres. Un Membre disposant de ce pouvoir ne peut affecter de nouveaux membres qu&apos;à un rôle auquel il est lui-même affecté."
31 name="role assign member limited" /> 31 name="role assign member limited" value="7" />
32 <action description="Affecter des Membres à tous types de Rôles" 32 <action description="Affecter des Membres à tous types de Rôles"
33 longdescription="Affectez des Membres à tous types de rôles dans la section &apos;Rôles Attribués&apos; de l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Membres. *AVERTISSEMENT* Tout membre disposant de cette faculté peut s&apos;affecter lui-même --ainsi que tout autre Membre non-propriétaire du groupe-- à des Rôles disposant de pouvoirs plus grands, et accéder potentiellement à des pouvoirs proches de ceux d&apos;un propriétaire. Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté." 33 longdescription="Affectez des Membres à tous types de rôles dans la section &apos;Rôles Attribués&apos; de l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Membres. *AVERTISSEMENT* Tout membre disposant de cette faculté peut s&apos;affecter lui-même --ainsi que tout autre Membre non-propriétaire du groupe-- à des Rôles disposant de pouvoirs plus grands, et accéder potentiellement à des pouvoirs proches de ceux d&apos;un propriétaire. Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté."
34 name="role assign member" /> 34 name="role assign member" value="8" />
35 <action description="Destituer des Membres de leurs Rôles" 35 <action description="Destituer des Membres de leurs Rôles"
36 longdescription="Retirez des Membres de Rôles dans la section Rôles Attribués de l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Membres. Les Propriétaires ne peuvent être retirés." 36 longdescription="Retirez des Membres de Rôles dans la section Rôles Attribués de l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Membres. Les Propriétaires ne peuvent être retirés."
37 name="role remove member" /> 37 name="role remove member" value="9" />
38 <action description="Attribuer et retirer des Facultés d&apos;un Rôle" 38 <action description="Attribuer et retirer des Facultés d&apos;un Rôle"
39 longdescription="Attribuez et retirez des Facultés de Rôles dans la section Facultés Attribuées de l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Rôles. *AVERTISSEMENT* Tout membre disposant de cette faculté peut s&apos;affecter lui-même --ainsi que tout autre Membre non-propriétaire du groupe-- à des Rôles disposant de pouvoirs plus grands, et accéder potentiellement à des pouvoirs proches de ceux d&apos;un propriétaire. Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté." 39 longdescription="Attribuez et retirez des Facultés de Rôles dans la section Facultés Attribuées de l&apos;onglet Membres &amp; Rôles &gt; sous-onglet Rôles. *AVERTISSEMENT* Tout membre disposant de cette faculté peut s&apos;affecter lui-même --ainsi que tout autre Membre non-propriétaire du groupe-- à des Rôles disposant de pouvoirs plus grands, et accéder potentiellement à des pouvoirs proches de ceux d&apos;un propriétaire. Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté."
40 name="role change actions" /> 40 name="role change actions" value="10" />
41 </action_set> 41 </action_set>
42 <action_set 42 <action_set
43 description="Ces Facultés confèrent le pouvoir de modifier l&apos;identité du Groupe, c&apos;est-à-dire sa visibilité publique, sa charte et son insigne." 43 description="Ces Facultés confèrent le pouvoir de modifier l&apos;identité du Groupe, c&apos;est-à-dire sa visibilité publique, sa charte et son insigne."
44 name="Group Identity"> 44 name="Group Identity">
45 <action 45 <action
46 description="Modifier la Charte, l&apos;Insigne, &apos;Publier sur le web&apos;, et quels Membres apparaissent dans les Informations du Groupe" 46 description="Modifier la Charte, l&apos;Insigne, &apos;Publier sur le web&apos;, et quels Membres apparaissent dans les Informations du Groupe"
47 longdescription="Modifiez la Charte, l&apos;Insigne, &apos;Publier sur le web&apos; et la visibilité publique des Membres dans les Informations du Groupe. Ces opérations s&apos;effectuent dans l&apos;onglet Général." 47 longdescription="Modifiez la Charte, l&apos;Insigne, &apos;Publier sur le web&apos; et la visibilité publique des Membres dans les Informations du Groupe. Ces opérations s&apos;effectuent dans l&apos;onglet Général."
48 name="group change identity" /> 48 name="group change identity" value="11" />
49 </action_set> 49 </action_set>
50 <action_set 50 <action_set
51 description="Ces Facultés confèrent le pouvoir de transférer, modifier, et vendre du terrain appartenant au patrimoine du Groupe. Pour accéder au menu du terrain, cliquez-droit sur le sol et sélectionnez &apos;A propos du terrain...&apos;, ou cliquez sur l&apos;info de parcelle dans la barre de menus." 51 description="Ces Facultés confèrent le pouvoir de transférer, modifier, et vendre du terrain appartenant au patrimoine du Groupe. Pour accéder au menu du terrain, cliquez-droit sur le sol et sélectionnez &apos;A propos du terrain...&apos;, ou cliquez sur l&apos;info de parcelle dans la barre de menus."
52 name="Parcel Management"> 52 name="Parcel Management">
53 <action description="Transférer du terrain et acheter du terrain pour le groupe" 53 <action description="Transférer du terrain et acheter du terrain pour le groupe"
54 longdescription="Transférez du terrain et achetez du terrain pour le compte d&apos;un groupe. Ces opérations s&apos;effectuent dans &apos;A propos du terrain&apos; &gt; onglet Général." 54 longdescription="Transférez du terrain et achetez du terrain pour le compte d&apos;un groupe. Ces opérations s&apos;effectuent dans &apos;A propos du terrain&apos; &gt; onglet Général."
55 name="land deed" /> 55 name="land deed" value="12" />
56 <action description="Céder terrain au Gouverneur Linden" 56 <action description="Céder terrain au Gouverneur Linden"
57 longdescription="Céder terrain au Gouverneur Linden. *AVERTISSEMENT* Tout Membre disposant de cette Faculté peut céder du terrain dans &apos;A propos du terrain&apos; &gt; onglet Général, et rétrocéder la propriété aux Linden sans effectuer de vente ! Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté." 57 longdescription="Céder terrain au Gouverneur Linden. *AVERTISSEMENT* Tout Membre disposant de cette Faculté peut céder du terrain dans &apos;A propos du terrain&apos; &gt; onglet Général, et rétrocéder la propriété aux Linden sans effectuer de vente ! Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté."
58 name="land release" /> 58 name="land release" value="13" />
59 <action description="Définir des infos de vente de terrain" 59 <action description="Définir des infos de vente de terrain"
60 longdescription="Définissez les informations de vente du terrain. *AVERTISSEMENT* Tout Membre dans un Rôle avec cette Faculté peut vendre du terrain appartenant au groupe dans &apos;A propos du Terrain&apos; &gt; onglet General quand il le souhaite ! Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté." 60 longdescription="Définissez les informations de vente du terrain. *AVERTISSEMENT* Tout Membre dans un Rôle avec cette Faculté peut vendre du terrain appartenant au groupe dans &apos;A propos du Terrain&apos; &gt; onglet General quand il le souhaite ! Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté."
61 name="land set sale info" /> 61 name="land set sale info" value="14" />
62 <action description="Subdiviser et fusionner des parcelles" 62 <action description="Subdiviser et fusionner des parcelles"
63 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. " 63 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. "
64 name="land divide join" /> 64 name="land divide join" value="15" />
65 </action_set> 65 </action_set>
66 <action_set 66 <action_set
67 description="Ces Facultés confèrent le pouvoir de modifier le nom de la parcelle et les réglages de confidentialité, la visibilité dans l&apos;annuaire, le point d&apos;atterrissage et les options de routage de téléportation." 67 description="Ces Facultés confèrent le pouvoir de modifier le nom de la parcelle et les réglages de confidentialité, la visibilité dans l&apos;annuaire, le point d&apos;atterrissage et les options de routage de téléportation."
68 name="Parcel Identity"> 68 name="Parcel Identity">
69 <action 69 <action
70 description="Basculer &apos;Afficher dans Rechercher un lieu&apos; et définir une catégorie" 70 description="Basculer &apos;Afficher dans Rechercher un lieu&apos; et définir une catégorie"
71 longdescription="Basculez &apos;Afficher dans Rechercher un Lieu&apos; et définissez une catégorie pour la parcelle dans &apos;A propos du Terrain&apos; &gt; onglet Options." 71 longdescription="Basculez &apos;Afficher dans Rechercher un Lieu&apos; et définissez une catégorie pour la parcelle dans &apos;A propos du Terrain&apos; &gt; onglet Options."
72 name="land find places" /> 72 name="land find places" value="17" />
73 <action 73 <action
74 description="Modifier le nom et la description de la parcelle, et les réglages de &apos;Publier sur le web&apos;" 74 description="Modifier le nom et la description de la parcelle, et les réglages de &apos;Publier sur le web&apos;"
75 longdescription="Modifiez le nom de la parcelle, sa description et les réglages de &apos;Publier sur le web&apos;. Ces modifications s&apos;effectuent dans &apos;A propos du terrain&apos;, onglet Options." 75 longdescription="Modifiez le nom de la parcelle, sa description et les réglages de &apos;Publier sur le web&apos;. Ces modifications s&apos;effectuent dans &apos;A propos du terrain&apos;, onglet Options."
76 name="land change identity" /> 76 name="land change identity" value="18" />
77 <action 77 <action
78 description="Définir le point d&apos;atterrissage et le routage de téléportation" 78 description="Définir le point d&apos;atterrissage et le routage de téléportation"
79 longdescription="Sur une parcelle appartenant au groupe, les Membres dans un Rôle avec cette Faculté peuvent définir un point d&apos;atterrissage pour les téléportations entrantes, et définir le routage de téléportation pour plus de contrôle. Ceci s&apos;effectue dans A propos du Terrain &gt; onglet Options." 79 longdescription="Sur une parcelle appartenant au groupe, les Membres dans un Rôle avec cette Faculté peuvent définir un point d&apos;atterrissage pour les téléportations entrantes, et définir le routage de téléportation pour plus de contrôle. Ceci s&apos;effectue dans A propos du Terrain &gt; onglet Options."
80 name="land set landing point" /> 80 name="land set landing point" value="19" />
81 </action_set> 81 </action_set>
82 <action_set 82 <action_set
83 description="Ces Facultés confèrent des pouvoirs sur les options de la parcelle, comme &apos;Créer objets&apos;, &apos;Modifier Relief&apos;, ainsi que les réglages audio et vidéo." 83 description="Ces Facultés confèrent des pouvoirs sur les options de la parcelle, comme &apos;Créer objets&apos;, &apos;Modifier Relief&apos;, ainsi que les réglages audio et vidéo."
84 name="Parcel Settings"> 84 name="Parcel Settings">
85 <action description="Modifier les réglages de la musique et des media" 85 <action description="Modifier les réglages de la musique et des media"
86 longdescription="Modifiez les réglages des flux audio et vidéo dans &apos;A propos du terrain&apos; &gt; onglet Media." 86 longdescription="Modifiez les réglages des flux audio et vidéo dans &apos;A propos du terrain&apos; &gt; onglet Media."
87 name="land change media" /> 87 name="land change media" value="20" />
88 <action description="Basculer &apos;Modifier relief&apos;" 88 <action description="Basculer &apos;Modifier relief&apos;"
89 longdescription="Basculez &apos;Modifier Relief&apos;. *AVERTISSEMENT* A propos du Terrain &gt; onglet Options &gt; Modifier Relief permet à tout le monde de terraformer votre terrain, disposer et déplacer des plantes Linden. Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté. Modifier Terrain s&apos;effectue dans A propos du terrain &gt; onglet Options." 89 longdescription="Basculez &apos;Modifier Relief&apos;. *AVERTISSEMENT* A propos du Terrain &gt; onglet Options &gt; Modifier Relief permet à tout le monde de terraformer votre terrain, disposer et déplacer des plantes Linden. Assurez-vous de savoir ce que vous faites avant d&apos;attribuer cette Faculté. Modifier Terrain s&apos;effectue dans A propos du terrain &gt; onglet Options."
90 name="land edit" /> 90 name="land edit" value="21" />
91 <action description="Basculer divers réglages de A propos du Terrain &gt; Options" 91 <action description="Basculer divers réglages de A propos du Terrain &gt; Options"
92 longdescription="Basculez &apos;Sans danger (pas de dégâts)&apos;, &apos;Voler&apos;, et autorisez d&apos;autres résidents à : &apos;Créer des objets&apos;, &apos;Modifier le Relief&apos;, &apos;Créer un repère&apos;, et &apos;Exécuter des Scripts&apos; sur un terrain appartenant au Groupe dans &apos;A propos du Terrain&apos; &gt; onglet Options." 92 longdescription="Basculez &apos;Sans danger (pas de dégâts)&apos;, &apos;Voler&apos;, et autorisez d&apos;autres résidents à : &apos;Créer des objets&apos;, &apos;Modifier le Relief&apos;, &apos;Créer un repère&apos;, et &apos;Exécuter des Scripts&apos; sur un terrain appartenant au Groupe dans &apos;A propos du Terrain&apos; &gt; onglet Options."
93 name="land options" /> 93 name="land options" value="22" />
94 </action_set> 94 </action_set>
95 <action_set 95 <action_set
96 description="Ces Facultés confèrent des pouvoirs qui permettent aux Membres de contourner les restrictions sur des parcelles appartenant à un groupe." 96 description="Ces Facultés confèrent des pouvoirs qui permettent aux Membres de contourner les restrictions sur des parcelles appartenant à un groupe."
97 name="Parcel Powers"> 97 name="Parcel Powers">
98 <action description="Toujours autoriser &apos;Modifier relief&apos;" 98 <action description="Toujours autoriser &apos;Modifier relief&apos;"
99 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent modifier le relief d&apos;une parcelle de groupe, même si l&apos;option est désactivée dans A Propos du Terrain &gt; onglet Options." 99 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent modifier le relief d&apos;une parcelle de groupe, même si l&apos;option est désactivée dans A Propos du Terrain &gt; onglet Options."
100 name="land allow edit land" /> 100 name="land allow edit land" value="23" />
101 <action description="Toujours autoriser le vol" 101 <action description="Toujours autoriser le vol"
102 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent voler sur une parcelle de groupe, même si le vol est désactivé dans A Propos du Terrain &gt; onglet Options." 102 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent voler sur une parcelle de groupe, même si le vol est désactivé dans A Propos du Terrain &gt; onglet Options."
103 name="land allow fly" /> 103 name="land allow fly" value="24" />
104 <action description="Toujours autoriser &apos;Créer objets&apos;" 104 <action description="Toujours autoriser &apos;Créer objets&apos;"
105 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent créer des objets sur une parcelle de groupe, même si l&apos;option est désactivée dans A Propos du Terrain &gt; onglet Options." 105 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent créer des objets sur une parcelle de groupe, même si l&apos;option est désactivée dans A Propos du Terrain &gt; onglet Options."
106 name="land allow create" /> 106 name="land allow create" value="25" />
107 <action description="Toujours autoriser &apos;Créer repère&apos;" 107 <action description="Toujours autoriser &apos;Créer repère&apos;"
108 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent créer un repère sur une parcelle de groupe, même si l&apos;option est désactivée dans A Propos du Terrain &gt; onglet Options." 108 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent créer un repère sur une parcelle de groupe, même si l&apos;option est désactivée dans A Propos du Terrain &gt; onglet Options."
109 name="land allow landmark" /> 109 name="land allow landmark" value="26" />
110 <action 110 <action
111 description="Autoriser &apos;Définir son domicile ici&apos; sur le terrain du groupe" 111 description="Autoriser &apos;Définir son domicile ici&apos; sur le terrain du groupe"
112 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent utiliser le menu Monde &gt; Définir Domicile Ici sur une parcelle de groupe (terrain attribué ou transféré au groupe)." 112 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent utiliser le menu Monde &gt; Définir Domicile Ici sur une parcelle de groupe (terrain attribué ou transféré au groupe)."
113 name="land allow set home" /> 113 name="land allow set home" value="28" />
114 </action_set> 114 </action_set>
115 <action_set 115 <action_set
116 description="Ces Facultés confèrent le pouvoir d&apos;autoriser ou restreindre l&apos;accès à des parcelles appartenant au Groupe, y compris de bloquer ou éjecter des résidents." 116 description="Ces Facultés confèrent le pouvoir d&apos;autoriser ou restreindre l&apos;accès à des parcelles appartenant au Groupe, y compris de bloquer ou éjecter des résidents."
117 name="Parcel Access"> 117 name="Parcel Access">
118 <action description="Gérer les listes d&apos;accès à cette parcelle" 118 <action description="Gérer les listes d&apos;accès à cette parcelle"
119 longdescription="Gérez les listes d&apos;accès à la parcelle dans &apos;A propos du terrain&apos; &gt; Accès." 119 longdescription="Gérez les listes d&apos;accès à la parcelle dans &apos;A propos du terrain&apos; &gt; Accès."
120 name="land manage allowed" /> 120 name="land manage allowed" value="29" />
121 <action description="Gérer les listes noires de cette parcelle" 121 <action description="Gérer les listes noires de cette parcelle"
122 longdescription="Gérez les listes de bannissement de la parcelle dans &apos;A propos du terrain&apos; &gt; Bannir." 122 longdescription="Gérez les listes de bannissement de la parcelle dans &apos;A propos du terrain&apos; &gt; Bannir."
123 name="land manage banned" /> 123 name="land manage banned" value="30" />
124 <action 124 <action
125 description="Modifier réglages de &apos;Vendre des laissez-passer...&apos; sur cette parcelle" 125 description="Modifier réglages de &apos;Vendre des laissez-passer...&apos; sur cette parcelle"
126 longdescription="Modifiez les réglages de &apos;Vendre des laissez-passer&apos; de la parcelle dans &apos;A propos du terrain&apos; &gt; onglet &apos;Accès&apos;." 126 longdescription="Modifiez les réglages de &apos;Vendre des laissez-passer&apos; de la parcelle dans &apos;A propos du terrain&apos; &gt; onglet &apos;Accès&apos;."
127 name="land manage passes" /> 127 name="land manage passes" value="31" />
128 <action description="Ejecter et bloquer des Résidents sur les parcelles" 128 <action description="Ejecter et bloquer des Résidents sur les parcelles"
129 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent intervenir auprès d&apos;un Résident indésirable sur une parcelle de groupe en cliquant-droit sur eux, Plus &gt;, et &apos;Ejecter...&apos; ou &apos;Bloquer...&apos;." 129 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent intervenir auprès d&apos;un Résident indésirable sur une parcelle de groupe en cliquant-droit sur eux, Plus &gt;, et &apos;Ejecter...&apos; ou &apos;Bloquer...&apos;."
130 name="land admin" /> 130 name="land admin" value="32" />
131 </action_set> 131 </action_set>
132 <action_set 132 <action_set
133 description="Ces Facultés confèrent le pouvoir d&apos;autoriser les Membres à renvoyer des objets, placer et déplacer des plantes Linden. Ceci permet aux Membres de traiter les déchets et d&apos;aménager le paysage. A utiliser avec précaution, car les objets renvoyés le sont définitivement." 133 description="Ces Facultés confèrent le pouvoir d&apos;autoriser les Membres à renvoyer des objets, placer et déplacer des plantes Linden. Ceci permet aux Membres de traiter les déchets et d&apos;aménager le paysage. A utiliser avec précaution, car les objets renvoyés le sont définitivement."
134 name="Parcel Content"> 134 name="Parcel Content">
135 <action description="Renvoyer des objets appartenant au groupe." 135 <action description="Renvoyer des objets appartenant au groupe."
136 longdescription="Renvoyez des objets sur des parcelles appartenant au groupe dans A propos du Terrain &gt; onglet Objets." 136 longdescription="Renvoyez des objets sur des parcelles appartenant au groupe dans A propos du Terrain &gt; onglet Objets."
137 name="land return group owned" /> 137 name="land return group owned" value="48" />
138 <action description="Renvoyer des objets attribués au groupe" 138 <action description="Renvoyer des objets attribués au groupe"
139 longdescription="Renvoyez des objets sur des parcelles appartenant au groupe et attribuées au groupe dans A propos du Terrain &gt; onglet Objets." 139 longdescription="Renvoyez des objets sur des parcelles appartenant au groupe et attribuées au groupe dans A propos du Terrain &gt; onglet Objets."
140 name="land return group set" /> 140 name="land return group set" value="33" />
141 <action description="Renvoyer des objets n&apos;appartenant pas au groupe." 141 <action description="Renvoyer des objets n&apos;appartenant pas au groupe."
142 longdescription="Renvoyez des objets sur des parcelles appartenant au groupe et non attribuées au groupe dans A propos du Terrain &gt; onglet Objets." 142 longdescription="Renvoyez des objets sur des parcelles appartenant au groupe et non attribuées au groupe dans A propos du Terrain &gt; onglet Objets."
143 name="land return non group" /> 143 name="land return non group" value="34" />
144 <action description="Aménager le paysage avec des plantes Linden" 144 <action description="Aménager le paysage avec des plantes Linden"
145 longdescription="Faculté de placer et déplacer des arbres, plantes et pelouses Linden. Ces eléments sont disponibles dans le dossier Objets de la Bibliothèque de votre Inventaire ou peuvent être créés à l&apos;aide du bouton Construire." 145 longdescription="Faculté de placer et déplacer des arbres, plantes et pelouses Linden. Ces eléments sont disponibles dans le dossier Objets de la Bibliothèque de votre Inventaire ou peuvent être créés à l&apos;aide du bouton Construire."
146 name="land gardening" /> 146 name="land gardening" value="35" />
147 </action_set> 147 </action_set>
148 <action_set 148 <action_set
149 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. " 149 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. "
150 name="Object Management"> 150 name="Object Management">
151 <action description="Transférer des objets au groupe" 151 <action description="Transférer des objets au groupe"
152 longdescription="Transférez des objets à un groupe dans Outils d&apos;Edition &gt; onglet Général." 152 longdescription="Transférez des objets à un groupe dans Outils d&apos;Edition &gt; onglet Général."
153 name="object deed" /> 153 name="object deed" value="36" />
154 <action 154 <action
155 description="Manipuler (déplacer, copier, modifier) des objets appartenant au groupe" 155 description="Manipuler (déplacer, copier, modifier) des objets appartenant au groupe"
156 longdescription="Manipulez (déplacez, copiez, modifiez) les objets appartenant au groupe dans Outils d&apos;Edition &gt; onglet Général." 156 longdescription="Manipulez (déplacez, copiez, modifiez) les objets appartenant au groupe dans Outils d&apos;Edition &gt; onglet Général."
157 name="object manipulate" /> 157 name="object manipulate" value="38" />
158 <action description="Mettre en vente des objets appartenant au groupe" 158 <action description="Mettre en vente des objets appartenant au groupe"
159 longdescription="Définissez les objets à vendre du groupe dans Outils d&apos;Edition &gt; onglet Général." 159 longdescription="Définissez les objets à vendre du groupe dans Outils d&apos;Edition &gt; onglet Général."
160 name="object set sale" /> 160 name="object set sale" value="39" />
161 </action_set> 161 </action_set>
162 <action_set 162 <action_set
163 description="Ces Facultés confèrent des pouvoirs qui requièrent que les Membres paient les en-cours et reçoivent des dividendes du Groupe, ainsi que le pouvoir de restreindre l&apos;accès à l&apos;historique comptable du Groupe." 163 description="Ces Facultés confèrent des pouvoirs qui requièrent que les Membres paient les en-cours et reçoivent des dividendes du Groupe, ainsi que le pouvoir de restreindre l&apos;accès à l&apos;historique comptable du Groupe."
164 name="Accounting"> 164 name="Accounting">
165 <action description="Payer le passif du groupe et recevoir les dividendes du groupe" 165 <action description="Payer le passif du groupe et recevoir les dividendes du groupe"
166 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. " 166 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. "
167 name="accounting accountable" /> 167 name="accounting accountable" value="40" />
168 </action_set> 168 </action_set>
169 <action_set 169 <action_set
170 description="Ces Facultés confèrent le pouvoir d&apos;autoriser les Membres à envoyer, recevoir, et voir les Notifications de groupe." 170 description="Ces Facultés confèrent le pouvoir d&apos;autoriser les Membres à envoyer, recevoir, et voir les Notifications de groupe."
171 name="Notices"> 171 name="Notices">
172 <action description="Envoyer des Notifications" 172 <action description="Envoyer des Notifications"
173 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent envoyer des Notifications dans Informations du Groupe &gt; onglet Notifications." 173 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent envoyer des Notifications dans Informations du Groupe &gt; onglet Notifications."
174 name="notices send" /> 174 name="notices send" value="42" />
175 <action description="Recevoir Notifications et voir Notifications passées" 175 <action description="Recevoir Notifications et voir Notifications passées"
176 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent recevoir les Notifications et afficher les Notifications passées dans Informations du Groupe &gt; onglet Notifications." 176 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent recevoir les Notifications et afficher les Notifications passées dans Informations du Groupe &gt; onglet Notifications."
177 name="notices receive" /> 177 name="notices receive" value="43" />
178 </action_set> 178 </action_set>
179 <action_set 179 <action_set
180 description="Ces Facultés confèrent le pouvoir d&apos;autoriser les Membres à soumettre des Propositions, les voter, et voir l&apos;historique des votes." 180 description="Ces Facultés confèrent le pouvoir d&apos;autoriser les Membres à soumettre des Propositions, les voter, et voir l&apos;historique des votes."
181 name="Proposals"> 181 name="Proposals">
182 <action description="Créer des propositions" 182 <action description="Créer des propositions"
183 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent créer des propositions à voter dans Informations du Groupe &gt; onglet Propositions." 183 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent créer des propositions à voter dans Informations du Groupe &gt; onglet Propositions."
184 name="proposal start" /> 184 name="proposal start" value="44" />
185 <action description="Voter les propositions" 185 <action description="Voter les propositions"
186 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent voter les propositions dans Informations du Groupe &gt; onglet Propositions." 186 longdescription="Les Membres dans un Rôle avec cette Faculté peuvent voter les propositions dans Informations du Groupe &gt; onglet Propositions."
187 name="proposal vote" /> 187 name="proposal vote" value="45" />
188 </action_set> 188 </action_set>
189</role_actions> 189</role_actions>
diff --git a/linden/indra/newview/skins/xui/ja/role_actions.xml b/linden/indra/newview/skins/xui/ja/role_actions.xml
index dc3010d..c0c98b3 100644
--- a/linden/indra/newview/skins/xui/ja/role_actions.xml
+++ b/linden/indra/newview/skins/xui/ja/role_actions.xml
@@ -5,38 +5,38 @@
5 name="Membership"> 5 name="Membership">
6 <action description="ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«äººã‚’招待" 6 <action description="ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«äººã‚’招待"
7 longdescription="グループã«äººã‚’招待ã™ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[メンãƒãƒ¼]サブタブã®[æ–°ã—ã„人を招待...]ボタンを使ã„ã¾ã™ã€‚" 7 longdescription="グループã«äººã‚’招待ã™ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[メンãƒãƒ¼]サブタブã®[æ–°ã—ã„人を招待...]ボタンを使ã„ã¾ã™ã€‚"
8 name="member invite" /> 8 name="member invite" value="1" />
9 <action description="メンãƒãƒ¼ã‚’ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰è¿½æ”¾" 9 <action description="メンãƒãƒ¼ã‚’ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰è¿½æ”¾"
10 longdescription="メンãƒãƒ¼ã‚’ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰è¿½æ”¾ã™ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ &gt; [役割]サブタブã®[グループã‹ã‚‰è¿½æ”¾]を使ã„ã¾ã™ã€‚ オーナーã¯ã€ä»–ã®ã‚ªãƒ¼ãƒŠãƒ¼ä»¥å¤–ã®ä»»æ„ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’追放ã§ãã¾ã™ã€‚ オーナーã§ãªã„ユーザーãŒã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰ãƒ¡ãƒ³ãƒãƒ¼ã‚’追放ã§ãã‚‹ã®ã¯ã€ãã®ãƒ¡ãƒ³ãƒãƒ¼ãŒã€Œå…¨å“¡ã€ã®å½¹å‰²ã«ã®ã¿æ‰€å±žã—ã¦ãŠã‚Šã€ä»–ã®å½¹å‰²ã«æ‰€å±žã—ã¦ã„ãªã„å ´åˆã ã‘ã§ã™ã€‚ 役割ã‹ã‚‰ãƒ¡ãƒ³ãƒãƒ¼ã‚’除外ã™ã‚‹ã«ã¯ã€ã€Œå½¹å‰²ã‹ã‚‰ãƒ¡ãƒ³ãƒãƒ¼ã‚’除外ã€èƒ½åŠ›ã‚’æœ‰ã—ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" 10 longdescription="メンãƒãƒ¼ã‚’ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰è¿½æ”¾ã™ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ &gt; [役割]サブタブã®[グループã‹ã‚‰è¿½æ”¾]を使ã„ã¾ã™ã€‚ オーナーã¯ã€ä»–ã®ã‚ªãƒ¼ãƒŠãƒ¼ä»¥å¤–ã®ä»»æ„ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’追放ã§ãã¾ã™ã€‚ オーナーã§ãªã„ユーザーãŒã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰ãƒ¡ãƒ³ãƒãƒ¼ã‚’追放ã§ãã‚‹ã®ã¯ã€ãã®ãƒ¡ãƒ³ãƒãƒ¼ãŒã€Œå…¨å“¡ã€ã®å½¹å‰²ã«ã®ã¿æ‰€å±žã—ã¦ãŠã‚Šã€ä»–ã®å½¹å‰²ã«æ‰€å±žã—ã¦ã„ãªã„å ´åˆã ã‘ã§ã™ã€‚ 役割ã‹ã‚‰ãƒ¡ãƒ³ãƒãƒ¼ã‚’除外ã™ã‚‹ã«ã¯ã€ã€Œå½¹å‰²ã‹ã‚‰ãƒ¡ãƒ³ãƒãƒ¼ã‚’除外ã€èƒ½åŠ›ã‚’æœ‰ã—ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚"
11 name="member eject" /> 11 name="member eject" value="2" />
12 <action description="[会員募集]ã«åˆ‡ã‚Šæ›¿ãˆã€[入会費]を変更。" 12 <action description="[会員募集]ã«åˆ‡ã‚Šæ›¿ãˆã€[入会費]を変更。"
13 longdescription="招待状ãªã—ã«æ–°ãƒ¡ãƒ³ãƒãƒ¼ãŒåŠ å…¥ã§ãるよã†ã«[会員募集]ã«åˆ‡ã‚Šæ›¿ãˆã€[一般]タブã®[グループ環境設定]セクションã‹ã‚‰[入会費]を変更ã—ã¾ã™ã€‚" 13 longdescription="招待状ãªã—ã«æ–°ãƒ¡ãƒ³ãƒãƒ¼ãŒåŠ å…¥ã§ãるよã†ã«[会員募集]ã«åˆ‡ã‚Šæ›¿ãˆã€[一般]タブã®[グループ環境設定]セクションã‹ã‚‰[入会費]を変更ã—ã¾ã™ã€‚"
14 name="member options" /> 14 name="member options" value="3" />
15 </action_set> 15 </action_set>
16 <action_set 16 <action_set
17 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—内ã®å½¹å‰²ã‚’追加ã€å‰Šé™¤ã€å¤‰æ›´ã—ã€å½¹å‰²ã«ãƒ¡ãƒ³ãƒãƒ¼ã‚’追加ã€å‰Šé™¤ã—ã€ã•らã«å½¹å‰²ã¸èƒ½åŠ›ã‚’å‰²ã‚Šå½“ã¦ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" 17 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—内ã®å½¹å‰²ã‚’追加ã€å‰Šé™¤ã€å¤‰æ›´ã—ã€å½¹å‰²ã«ãƒ¡ãƒ³ãƒãƒ¼ã‚’追加ã€å‰Šé™¤ã—ã€ã•らã«å½¹å‰²ã¸èƒ½åŠ›ã‚’å‰²ã‚Šå½“ã¦ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚"
18 name="Roles"> 18 name="Roles">
19 <action description="æ–°ã—ã„役割を作æˆ" 19 <action description="æ–°ã—ã„役割を作æˆ"
20 longdescription="[メンãƒãƒ¼ã¨å½¹å‰²]タブ &gt; [役割]ã‚µãƒ–ã‚¿ãƒ–ã§æ–°ã—ã„役割を作æˆ" 20 longdescription="[メンãƒãƒ¼ã¨å½¹å‰²]タブ &gt; [役割]ã‚µãƒ–ã‚¿ãƒ–ã§æ–°ã—ã„役割を作æˆ"
21 name="role create" /> 21 name="role create" value="4" />
22 <action description="役割を削除" 22 <action description="役割を削除"
23 longdescription="役割を削除ã™ã‚‹ã«ã¯ã€ãƒ¡ãƒ³ãƒãƒ¼ã¨å½¹å‰²ã‚¿ãƒ– &gt; 役割サブタブを使ã„ã¾ã™ã€‚" 23 longdescription="役割を削除ã™ã‚‹ã«ã¯ã€ãƒ¡ãƒ³ãƒãƒ¼ã¨å½¹å‰²ã‚¿ãƒ– &gt; 役割サブタブを使ã„ã¾ã™ã€‚"
24 name="role delete" /> 24 name="role delete" value="5" />
25 <action description="役割åã€ã‚¿ã‚¤ãƒˆãƒ«ã€èª¬æ˜Žã‚’変更" 25 <action description="役割åã€ã‚¿ã‚¤ãƒˆãƒ«ã€èª¬æ˜Žã‚’変更"
26 longdescription="役割åã€ã‚¿ã‚¤ãƒˆãƒ«ã€èª¬æ˜Žã‚’変更ã™ã‚‹ã«ã¯ã€å½¹å‰²ã‚’é¸æŠžã—ãŸå¾Œã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ &gt; [役割]サブタブã®ä¸‹éƒ¨åˆ†ã‚’使ã„ã¾ã™ã€‚" 26 longdescription="役割åã€ã‚¿ã‚¤ãƒˆãƒ«ã€èª¬æ˜Žã‚’変更ã™ã‚‹ã«ã¯ã€å½¹å‰²ã‚’é¸æŠžã—ãŸå¾Œã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ &gt; [役割]サブタブã®ä¸‹éƒ¨åˆ†ã‚’使ã„ã¾ã™ã€‚"
27 name="role properties" /> 27 name="role properties" value="6" />
28 <action description="メンãƒãƒ¼ã‚’割り当ã¦äººã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹" 28 <action description="メンãƒãƒ¼ã‚’割り当ã¦äººã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹"
29 longdescription="メンãƒãƒ¼ã‚’割り当ã¦äººã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[役割]サブタブã®å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸå½¹å‰²ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’使ã„ã¾ã™ã€‚ ã“ã®èƒ½åŠ›ã‚’æŒã¤ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€å‰²ã‚Šå½“ã¦äººãŒç¾åœ¨æ‰€å±žã—ã¦ã„る役割ã«å¯¾ã—ã¦ã®ã¿ãƒ¡ãƒ³ãƒãƒ¼ã‚’追加ã§ãã¾ã™ã€‚" 29 longdescription="メンãƒãƒ¼ã‚’割り当ã¦äººã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[役割]サブタブã®å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸå½¹å‰²ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’使ã„ã¾ã™ã€‚ ã“ã®èƒ½åŠ›ã‚’æŒã¤ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€å‰²ã‚Šå½“ã¦äººãŒç¾åœ¨æ‰€å±žã—ã¦ã„る役割ã«å¯¾ã—ã¦ã®ã¿ãƒ¡ãƒ³ãƒãƒ¼ã‚’追加ã§ãã¾ã™ã€‚"
30 name="role assign member limited" /> 30 name="role assign member limited" value="7" />
31 <action description="メンãƒãƒ¼ã‚’ä»»æ„ã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹" 31 <action description="メンãƒãƒ¼ã‚’ä»»æ„ã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹"
32 longdescription="メンãƒãƒ¼ã‚’ä»»æ„ã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[役割]サブタブã®å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸå½¹å‰²ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’使ã„ã¾ã™ã€‚ *警告* ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€è‡ªåˆ†è‡ªèº«ã‚„ä»–ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’ç¾åœ¨ã®å½¹å‰²ã‚ˆã‚Šã‚‚強力ãªå½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“ã®ãŸã‚ã€ã‚ªãƒ¼ãƒŠãƒ¼ä»¥å¤–ã®ãƒ¡ãƒ³ãƒãƒ¼ã«å¯¾ã—ã¦ã€ã‚ªãƒ¼ãƒŠãƒ¼ã«è¿‘ã„パワーを与ãˆã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚ ã“ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¯ã€ãã®ã“ã¨ã‚’ç†è§£ã—ãŸä¸Šã§è¡Œã£ã¦ãã ã•ã„。" 32 longdescription="メンãƒãƒ¼ã‚’ä»»æ„ã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[役割]サブタブã®å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸå½¹å‰²ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’使ã„ã¾ã™ã€‚ *警告* ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€è‡ªåˆ†è‡ªèº«ã‚„ä»–ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’ç¾åœ¨ã®å½¹å‰²ã‚ˆã‚Šã‚‚強力ãªå½¹å‰²ã«å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“ã®ãŸã‚ã€ã‚ªãƒ¼ãƒŠãƒ¼ä»¥å¤–ã®ãƒ¡ãƒ³ãƒãƒ¼ã«å¯¾ã—ã¦ã€ã‚ªãƒ¼ãƒŠãƒ¼ã«è¿‘ã„パワーを与ãˆã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚ ã“ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¯ã€ãã®ã“ã¨ã‚’ç†è§£ã—ãŸä¸Šã§è¡Œã£ã¦ãã ã•ã„。"
33 name="role assign member" /> 33 name="role assign member" value="8" />
34 <action description="役割ã‹ã‚‰ãƒ¡ãƒ³ãƒãƒ¼ã‚’解除" 34 <action description="役割ã‹ã‚‰ãƒ¡ãƒ³ãƒãƒ¼ã‚’解除"
35 longdescription="メンãƒãƒ¼ã‚’役割ã‹ã‚‰è§£é™¤ã™ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[メンãƒãƒ¼]サブタブã®[割り当ã¦ã‚‰ã‚ŒãŸå½¹å‰²]セクションを使ã„ã¾ã™ã€‚ オーナーã¯è§£é™¤ã§ãã¾ã›ã‚“。" 35 longdescription="メンãƒãƒ¼ã‚’役割ã‹ã‚‰è§£é™¤ã™ã‚‹ã«ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[メンãƒãƒ¼]サブタブã®[割り当ã¦ã‚‰ã‚ŒãŸå½¹å‰²]セクションを使ã„ã¾ã™ã€‚ オーナーã¯è§£é™¤ã§ãã¾ã›ã‚“。"
36 name="role remove member" /> 36 name="role remove member" value="9" />
37 <action description="役割ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¨è§£é™¤" 37 <action description="役割ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¨è§£é™¤"
38 longdescription="役割ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¨è§£é™¤ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[役割]サブタブã®è¨±å¯ã•れãŸèƒ½åŠ›ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã§è¡Œã„ã¾ã™ã€‚ *警告* ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã™ã¹ã¦ã®èƒ½åŠ›ã‚’è‡ªåˆ†è‡ªèº«ã‚„ä»–ã®ãƒ¡ãƒ³ãƒãƒ¼ã«å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“ã®ãŸã‚ã€ã‚ªãƒ¼ãƒŠãƒ¼ä»¥å¤–ã®ãƒ¡ãƒ³ãƒãƒ¼ã«å¯¾ã—ã¦ã€ã‚ªãƒ¼ãƒŠãƒ¼ã«è¿‘ã„パワーをæŒãŸã›ã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚ ã“ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¯ã€ãã®ã“ã¨ã‚’ç†è§£ã—ãŸä¸Šã§è¡Œã£ã¦ãã ã•ã„。" 38 longdescription="役割ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¨è§£é™¤ã¯ã€[メンãƒãƒ¼ã¨å½¹å‰²]タブ>[役割]サブタブã®è¨±å¯ã•れãŸèƒ½åŠ›ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã§è¡Œã„ã¾ã™ã€‚ *警告* ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã™ã¹ã¦ã®èƒ½åŠ›ã‚’è‡ªåˆ†è‡ªèº«ã‚„ä»–ã®ãƒ¡ãƒ³ãƒãƒ¼ã«å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“ã®ãŸã‚ã€ã‚ªãƒ¼ãƒŠãƒ¼ä»¥å¤–ã®ãƒ¡ãƒ³ãƒãƒ¼ã«å¯¾ã—ã¦ã€ã‚ªãƒ¼ãƒŠãƒ¼ã«è¿‘ã„パワーをæŒãŸã›ã‚‹ã“ã¨ã‚‚å¯èƒ½ã§ã™ã€‚ ã“ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¯ã€ãã®ã“ã¨ã‚’ç†è§£ã—ãŸä¸Šã§è¡Œã£ã¦ãã ã•ã„。"
39 name="role change actions" /> 39 name="role change actions" value="10" />
40 </action_set> 40 </action_set>
41 <action_set 41 <action_set
42 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—ã®å…¬é–‹æ€§ã‚„憲章ã€è¨˜ç« ã®å¤‰æ›´ã¨ã„ã£ãŸã€ã‚°ãƒ«ãƒ¼ãƒ—ã®ã‚¢ã‚¤ãƒ‡ãƒ³ãƒ†ã‚£ãƒ†ã‚£ã‚’修正ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" 42 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—ã®å…¬é–‹æ€§ã‚„憲章ã€è¨˜ç« ã®å¤‰æ›´ã¨ã„ã£ãŸã€ã‚°ãƒ«ãƒ¼ãƒ—ã®ã‚¢ã‚¤ãƒ‡ãƒ³ãƒ†ã‚£ãƒ†ã‚£ã‚’修正ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚"
@@ -44,141 +44,141 @@
44 <action 44 <action
45 description="特権ã€è¨˜ç« ã€ã€ŒWeb上ã§å…¬é–‹ã€ã€ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ—情報内ã§å¯è¦–ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’変更。" 45 description="特権ã€è¨˜ç« ã€ã€ŒWeb上ã§å…¬é–‹ã€ã€ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ—情報内ã§å¯è¦–ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’変更。"
46 longdescription="特権ã€è¨˜ç« ã€ã€ŒWeb上ã§å…¬é–‹ã€ã€ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ—情報内ã§å¯è¦–ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’変更ã—ã¾ã™ã€‚ ã“ã®æ“作ã«ã¯ã€ä¸€èˆ¬ã‚¿ãƒ–を使用ã—ã¾ã™ã€‚" 46 longdescription="特権ã€è¨˜ç« ã€ã€ŒWeb上ã§å…¬é–‹ã€ã€ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ—情報内ã§å¯è¦–ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’変更ã—ã¾ã™ã€‚ ã“ã®æ“作ã«ã¯ã€ä¸€èˆ¬ã‚¿ãƒ–を使用ã—ã¾ã™ã€‚"
47 name="group change identity" /> 47 name="group change identity" value="11" />
48 </action_set> 48 </action_set>
49 <action_set 49 <action_set
50 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åœŸåœ°ã‚’譲渡ã€ä¿®æ­£ã€è²©å£²ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚ [土地情報]ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‹ãã«ã¯ã€åœ°é¢ã‚’å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦[土地情報]ã‚’é¸æŠžã™ã‚‹ã‹ã€ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒãƒ¼ã®[区画情報]をクリックã—ã¾ã™ã€‚" 50 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åœŸåœ°ã‚’譲渡ã€ä¿®æ­£ã€è²©å£²ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚ [土地情報]ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‹ãã«ã¯ã€åœ°é¢ã‚’å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦[土地情報]ã‚’é¸æŠžã™ã‚‹ã‹ã€ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒãƒ¼ã®[区画情報]をクリックã—ã¾ã™ã€‚"
51 name="Parcel Management"> 51 name="Parcel Management">
52 <action description="グループ用ã®åœŸåœ°ã®è­²æ¸¡ã¨è³¼å…¥" 52 <action description="グループ用ã®åœŸåœ°ã®è­²æ¸¡ã¨è³¼å…¥"
53 longdescription="グループ用ã®åœŸåœ°ã®è­²æ¸¡ã¨è³¼å…¥ã‚’行ã„ã¾ã™ã€‚ ã“ã®æ“作ã«ã¯ã€åœŸåœ°æƒ…å ±ç”»é¢ &gt; 一般タブを使ã„ã¾ã™ã€‚" 53 longdescription="グループ用ã®åœŸåœ°ã®è­²æ¸¡ã¨è³¼å…¥ã‚’行ã„ã¾ã™ã€‚ ã“ã®æ“作ã«ã¯ã€åœŸåœ°æƒ…å ±ç”»é¢ &gt; 一般タブを使ã„ã¾ã™ã€‚"
54 name="land deed" /> 54 name="land deed" value="12" />
55 <action description="Lindenç·ç£ã«åœŸåœ°ã‚’æ˜Žã‘æ¸¡ã™" 55 <action description="Lindenç·ç£ã«åœŸåœ°ã‚’æ˜Žã‘æ¸¡ã™"
56 longdescription="Lindenç·ç£ã«åœŸåœ°ã‚’æ˜Žã‘æ¸¡ã—ã¾ã™ã€‚ *警告* ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€[土地情報]>[一般]ã§ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åœŸåœ°ã‚’放棄ã—ã¦ã€å£²ã‚Šä¸Šã’ãªã—ã§Lindenç·ç£ã«æ˜Žã‘渡ã™ã“ã¨ãŒã§ãã¾ã™ã€‚ ã“ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¯ã€ãã®ã“ã¨ã‚’ç†è§£ã—ãŸä¸Šã§è¡Œã£ã¦ãã ã•ã„。" 56 longdescription="Lindenç·ç£ã«åœŸåœ°ã‚’æ˜Žã‘æ¸¡ã—ã¾ã™ã€‚ *警告* ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€[土地情報]>[一般]ã§ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åœŸåœ°ã‚’放棄ã—ã¦ã€å£²ã‚Šä¸Šã’ãªã—ã§Lindenç·ç£ã«æ˜Žã‘渡ã™ã“ã¨ãŒã§ãã¾ã™ã€‚ ã“ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¯ã€ãã®ã“ã¨ã‚’ç†è§£ã—ãŸä¸Šã§è¡Œã£ã¦ãã ã•ã„。"
57 name="land release" /> 57 name="land release" value="13" />
58 <action description="売り地情報ã®è¨­å®š" 58 <action description="売り地情報ã®è¨­å®š"
59 longdescription="売り地情報を設定ã—ã¾ã™ã€‚ *警告* ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€[土地情報]>[一般]タブã§ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åœŸåœ°ã‚’è‡ªåˆ†ã®æ€ã„ã©ãŠã‚Šã«è²©å£²ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ ã“ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¯ã€ãã®ã“ã¨ã‚’ç†è§£ã—ãŸä¸Šã§è¡Œã£ã¦ãã ã•ã„。" 59 longdescription="売り地情報を設定ã—ã¾ã™ã€‚ *警告* ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€[土地情報]>[一般]タブã§ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åœŸåœ°ã‚’è‡ªåˆ†ã®æ€ã„ã©ãŠã‚Šã«è²©å£²ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ ã“ã®èƒ½åŠ›ã®å‰²ã‚Šå½“ã¦ã¯ã€ãã®ã“ã¨ã‚’ç†è§£ã—ãŸä¸Šã§è¡Œã£ã¦ãã ã•ã„。"
60 name="land set sale info" /> 60 name="land set sale info" value="14" />
61 <action description="区画ã®å†åˆ†å‰²ã¨çµ±åˆ" 61 <action description="区画ã®å†åˆ†å‰²ã¨çµ±åˆ"
62 longdescription="区画をå†åˆ†å‰²ãŠã‚ˆã³çµ±åˆã—ã¾ã™ã€‚ ã“ã®æ“作を実行ã™ã‚‹ã«ã¯ã€åœ°é¢ã‚’å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ï¼»åœ°å½¢ã‚’ç·¨é›†ï¼½ã‚’é¸æŠžã—ã€åœŸåœ°ã®ä¸Šã§ãƒžã‚¦ã‚¹ã‚’ドラッグã—ã¦ç¯„å›²ã‚’é¸æŠžã—ã¾ã™ã€‚ å†åˆ†å‰²ã™ã‚‹ã«ã¯ã€åˆ†å‰²å¯¾è±¡ã‚’é¸æŠžã—ãŸå¾Œã€ï¼»å†åˆ†å‰²...]をクリックã—ã¾ã™ã€‚ çµ±åˆã™ã‚‹ã«ã¯ã€è¤‡æ•°ã®éš£æŽ¥ã™ã‚‹åŒºç”»ã‚’é¸æŠžã—ãŸå¾Œã€ï¼»çµ±åˆ...]をクリックã—ã¾ã™ã€‚" 62 longdescription="区画をå†åˆ†å‰²ãŠã‚ˆã³çµ±åˆã—ã¾ã™ã€‚ ã“ã®æ“作を実行ã™ã‚‹ã«ã¯ã€åœ°é¢ã‚’å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ï¼»åœ°å½¢ã‚’ç·¨é›†ï¼½ã‚’é¸æŠžã—ã€åœŸåœ°ã®ä¸Šã§ãƒžã‚¦ã‚¹ã‚’ドラッグã—ã¦ç¯„å›²ã‚’é¸æŠžã—ã¾ã™ã€‚ å†åˆ†å‰²ã™ã‚‹ã«ã¯ã€åˆ†å‰²å¯¾è±¡ã‚’é¸æŠžã—ãŸå¾Œã€ï¼»å†åˆ†å‰²...]をクリックã—ã¾ã™ã€‚ çµ±åˆã™ã‚‹ã«ã¯ã€è¤‡æ•°ã®éš£æŽ¥ã™ã‚‹åŒºç”»ã‚’é¸æŠžã—ãŸå¾Œã€ï¼»çµ±åˆ...]をクリックã—ã¾ã™ã€‚"
63 name="land divide join" /> 63 name="land divide join" value="15" />
64 </action_set> 64 </action_set>
65 <action_set 65 <action_set
66 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€åŒºç”»åã€å…¬é–‹è¨­å®šã€æ¤œç´¢ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¸ã®ç™»éŒ²ã€ç€åœ°ç‚¹ãªã‚‰ã³ã«TPルートã®ã‚ªãƒ—ションを変更ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" 66 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€åŒºç”»åã€å…¬é–‹è¨­å®šã€æ¤œç´¢ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¸ã®ç™»éŒ²ã€ç€åœ°ç‚¹ãªã‚‰ã³ã«TPルートã®ã‚ªãƒ—ションを変更ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚"
67 name="Parcel Identity"> 67 name="Parcel Identity">
68 <action description="[場所検索ã«è¡¨ç¤º]ã«åˆ‡ã‚Šæ›¿ãˆã€ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚’設定" 68 <action description="[場所検索ã«è¡¨ç¤º]ã«åˆ‡ã‚Šæ›¿ãˆã€ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚’設定"
69 longdescription="[場所検索ã«è¡¨ç¤º]ã«åˆ‡ã‚Šæ›¿ãˆã€[土地情報]>[オプション]タブã§ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚’設定" 69 longdescription="[場所検索ã«è¡¨ç¤º]ã«åˆ‡ã‚Šæ›¿ãˆã€[土地情報]>[オプション]タブã§ã‚«ãƒ†ã‚´ãƒªãƒ¼ã‚’設定"
70 name="land find places" /> 70 name="land find places" value="17" />
71 <action description="区画åã€èª¬æ˜Žã€ã€ŒWeb上ã§å…¬é–‹ã€ã®è¨­å®šã‚’変更" 71 <action description="区画åã€èª¬æ˜Žã€ã€ŒWeb上ã§å…¬é–‹ã€ã®è¨­å®šã‚’変更"
72 longdescription="区画åã€èª¬æ˜Žã€ã€ŒWeb上ã§å…¬é–‹ã€ã®è¨­å®šã‚’変更。 ã“ã®æ“作ã«ã¯ã€[土地情報] &gt; [オプション]タブを使ã„ã¾ã™ã€‚" 72 longdescription="区画åã€èª¬æ˜Žã€ã€ŒWeb上ã§å…¬é–‹ã€ã®è¨­å®šã‚’変更。 ã“ã®æ“作ã«ã¯ã€[土地情報] &gt; [オプション]タブを使ã„ã¾ã™ã€‚"
73 name="land change identity" /> 73 name="land change identity" value="18" />
74 <action description="ç€åœ°ç‚¹ãŠã‚ˆã³ãƒ†ãƒ¬ãƒãƒ¼ãƒˆãƒ»ãƒ«ãƒ¼ãƒˆã‚’設定" 74 <action description="ç€åœ°ç‚¹ãŠã‚ˆã³ãƒ†ãƒ¬ãƒãƒ¼ãƒˆãƒ»ãƒ«ãƒ¼ãƒˆã‚’設定"
75 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã§ç€åœ°ç‚¹ã‚’設定ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šå¤–部ã‹ã‚‰ã®ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã®åˆ°ç€ä½ç½®ã‚’指定ã§ãã‚‹ã¨å…±ã«ã€ãƒ†ãƒ¬ãƒãƒ¼ãƒˆãƒ»ãƒ«ãƒ¼ãƒˆã‚’設定ã—ã¦ç´°ã‹ã制御ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ ã“ã®æ“作ã¯ã€[土地情報]>[オプション]タブã§è¡Œã„ã¾ã™ã€‚" 75 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã§ç€åœ°ç‚¹ã‚’設定ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šå¤–部ã‹ã‚‰ã®ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã®åˆ°ç€ä½ç½®ã‚’指定ã§ãã‚‹ã¨å…±ã«ã€ãƒ†ãƒ¬ãƒãƒ¼ãƒˆãƒ»ãƒ«ãƒ¼ãƒˆã‚’設定ã—ã¦ç´°ã‹ã制御ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ ã“ã®æ“作ã¯ã€[土地情報]>[オプション]タブã§è¡Œã„ã¾ã™ã€‚"
76 name="land set landing point" /> 76 name="land set landing point" value="19" />
77 </action_set> 77 </action_set>
78 <action_set 78 <action_set
79 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€[オブジェクトを作æˆ]ã€[地形を編集]ã€éŸ³æ¥½ã¨ãƒ¡ãƒ‡ã‚£ã‚¢ã®è¨­å®šãªã©ã€åŒºç”»ã®ã‚ªãƒ—ションã«é–¢é€£ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" 79 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€[オブジェクトを作æˆ]ã€[地形を編集]ã€éŸ³æ¥½ã¨ãƒ¡ãƒ‡ã‚£ã‚¢ã®è¨­å®šãªã©ã€åŒºç”»ã®ã‚ªãƒ—ションã«é–¢é€£ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚"
80 name="Parcel Settings"> 80 name="Parcel Settings">
81 <action description="音楽ã¨ãƒ¡ãƒ‡ã‚£ã‚¢ã®è¨­å®šã‚’変更" 81 <action description="音楽ã¨ãƒ¡ãƒ‡ã‚£ã‚¢ã®è¨­å®šã‚’変更"
82 longdescription="ストリーミング・ミュージックã¨å‹•ç”»ã®è¨­å®šã‚’変更ã™ã‚‹ã«ã¯ã€[土地情報] &gt; [メディア]タブを使ã„ã¾ã™ã€‚" 82 longdescription="ストリーミング・ミュージックã¨å‹•ç”»ã®è¨­å®šã‚’変更ã™ã‚‹ã«ã¯ã€[土地情報] &gt; [メディア]タブを使ã„ã¾ã™ã€‚"
83 name="land change media" /> 83 name="land change media" value="20" />
84 <action description="[地形を編集]ã«åˆ‡ã‚Šæ›¿ãˆ" 84 <action description="[地形を編集]ã«åˆ‡ã‚Šæ›¿ãˆ"
85 longdescription="[地形を編集]ã«åˆ‡ã‚Šæ›¿ãˆã¾ã™ã€‚ *警告* [土地情報]>[オプション]>[地形を編集]ã®é †ã§é€²ã‚€ã¨ã€èª°ã§ã‚‚ã‚ãªãŸã®åœŸåœ°ã®å½¢ã®æ•´å‚™ã‚„ã€ãƒªãƒ³ãƒ‡ãƒ³ãƒ—ラントã®è¨­ç½®ã€ç§»å‹•ãŒã§ãã¾ã™ã€‚ ã“ã®èƒ½åŠ›ã‚’å‰²ã‚ŠæŒ¯ã‚‹å‰ã«ã€ã“ã®ã“ã¨ã‚’よãç†è§£ã—ã¦ãŠã„ã¦ãã ã•ã„。 [土地情報]>[オプション]タブã‹ã‚‰[地形を編集]ã«åˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚" 85 longdescription="[地形を編集]ã«åˆ‡ã‚Šæ›¿ãˆã¾ã™ã€‚ *警告* [土地情報]>[オプション]>[地形を編集]ã®é †ã§é€²ã‚€ã¨ã€èª°ã§ã‚‚ã‚ãªãŸã®åœŸåœ°ã®å½¢ã®æ•´å‚™ã‚„ã€ãƒªãƒ³ãƒ‡ãƒ³ãƒ—ラントã®è¨­ç½®ã€ç§»å‹•ãŒã§ãã¾ã™ã€‚ ã“ã®èƒ½åŠ›ã‚’å‰²ã‚ŠæŒ¯ã‚‹å‰ã«ã€ã“ã®ã“ã¨ã‚’よãç†è§£ã—ã¦ãŠã„ã¦ãã ã•ã„。 [土地情報]>[オプション]タブã‹ã‚‰[地形を編集]ã«åˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚"
86 name="land edit" /> 86 name="land edit" value="21" />
87 <action 87 <action
88 description="[土地情報]>[オプション]タブ内ã®ã•ã¾ã–ã¾ãªè¨­å®šã‚’切り替ãˆ" 88 description="[土地情報]>[オプション]タブ内ã®ã•ã¾ã–ã¾ãªè¨­å®šã‚’切り替ãˆ"
89 longdescription="[安全(ダメージãªã—)]ã€[飛ã¶]ã«åˆ‡ã‚Šæ›¿ãˆã€[土地情報]>[オプション]タブã‹ã‚‰ã€ ä»–ã®ä½äººãŒã‚°ãƒ«ãƒ¼ãƒ—所有ã®åœŸåœ°ã§[オブジェクトを作æˆ]ã€[地形を編集]ã€[ランドマークを作æˆ]ã€[スクリプトを実行]ã§ãるよã†ã«ã—ã¾ã™ã€‚" 89 longdescription="[安全(ダメージãªã—)]ã€[飛ã¶]ã«åˆ‡ã‚Šæ›¿ãˆã€[土地情報]>[オプション]タブã‹ã‚‰ã€ ä»–ã®ä½äººãŒã‚°ãƒ«ãƒ¼ãƒ—所有ã®åœŸåœ°ã§[オブジェクトを作æˆ]ã€[地形を編集]ã€[ランドマークを作æˆ]ã€[スクリプトを実行]ã§ãるよã†ã«ã—ã¾ã™ã€‚"
90 name="land options" /> 90 name="land options" value="22" />
91 </action_set> 91 </action_set>
92 <action_set 92 <action_set
93 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ã«é–¢ã™ã‚‹è¦åˆ¶ã‚’迂回ã™ã‚‹ã“ã¨ã‚’ã€ãƒ¡ãƒ³ãƒãƒ¼ã«è¨±å¯ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" 93 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ã«é–¢ã™ã‚‹è¦åˆ¶ã‚’迂回ã™ã‚‹ã“ã¨ã‚’ã€ãƒ¡ãƒ³ãƒãƒ¼ã«è¨±å¯ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚"
94 name="Parcel Powers"> 94 name="Parcel Powers">
95 <action description="常ã«ã€Œåœ°å½¢ã‚’編集ã€ã‚’許å¯" 95 <action description="常ã«ã€Œåœ°å½¢ã‚’編集ã€ã‚’許å¯"
96 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã§åœ°å½¢ã‚’編集ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãã®åŒºç”»ãŒ[土地情報]>[オプション]タブã§ã‚ªãƒ•ã«ãªã£ã¦ã„ã¦ã‚‚ã€åœ°å½¢ã®ç·¨é›†ãŒå¯èƒ½ã§ã™ã€‚" 96 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã§åœ°å½¢ã‚’編集ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãã®åŒºç”»ãŒ[土地情報]>[オプション]タブã§ã‚ªãƒ•ã«ãªã£ã¦ã„ã¦ã‚‚ã€åœ°å½¢ã®ç·¨é›†ãŒå¯èƒ½ã§ã™ã€‚"
97 name="land allow edit land" /> 97 name="land allow edit land" value="23" />
98 <action description="常ã«ã€Œé£›è¡Œã€ã‚’許å¯" 98 <action description="常ã«ã€Œé£›è¡Œã€ã‚’許å¯"
99 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã‚’飛行ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãã®åŒºç”»ãŒ[土地情報]>[オプション]タブã§ã‚ªãƒ•ã«ãªã£ã¦ã„ã¦ã‚‚ã€é£›è¡ŒãŒå¯èƒ½ã§ã™ã€‚" 99 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã‚’飛行ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãã®åŒºç”»ãŒ[土地情報]>[オプション]タブã§ã‚ªãƒ•ã«ãªã£ã¦ã„ã¦ã‚‚ã€é£›è¡ŒãŒå¯èƒ½ã§ã™ã€‚"
100 name="land allow fly" /> 100 name="land allow fly" value="24" />
101 <action description="常ã«ã€Œã‚ªãƒ–ジェクト作æˆã€ã‚’許å¯" 101 <action description="常ã«ã€Œã‚ªãƒ–ジェクト作æˆã€ã‚’許å¯"
102 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã«ã‚ªãƒ–ジェクトを作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãã®åŒºç”»ãŒ[土地情報]>[オプション]タブã§ã‚ªãƒ•ã«ãªã£ã¦ã„ã¦ã‚‚ã€ã‚ªãƒ–ジェクトã®ä½œæˆãŒå¯èƒ½ã§ã™ã€‚" 102 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã«ã‚ªãƒ–ジェクトを作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãã®åŒºç”»ãŒ[土地情報]>[オプション]タブã§ã‚ªãƒ•ã«ãªã£ã¦ã„ã¦ã‚‚ã€ã‚ªãƒ–ジェクトã®ä½œæˆãŒå¯èƒ½ã§ã™ã€‚"
103 name="land allow create" /> 103 name="land allow create" value="25" />
104 <action description="常ã«ã€Œãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’作æˆã€ã‚’許å¯" 104 <action description="常ã«ã€Œãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’作æˆã€ã‚’許å¯"
105 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã«ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãã®åŒºç”»ãŒ[土地情報]>[オプション]タブã§ã‚ªãƒ•ã«ãªã£ã¦ã„ã¦ã‚‚ã€ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã®ä½œæˆãŒå¯èƒ½ã§ã™ã€‚" 105 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã«ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãã®åŒºç”»ãŒ[土地情報]>[オプション]タブã§ã‚ªãƒ•ã«ãªã£ã¦ã„ã¦ã‚‚ã€ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã®ä½œæˆãŒå¯èƒ½ã§ã™ã€‚"
106 name="land allow landmark" /> 106 name="land allow landmark" value="26" />
107 <action description="グループã®åœŸåœ°ã¸ã®ã€Œãƒ›ãƒ¼ãƒ è¨­å®šã€ã‚’許å¯" 107 <action description="グループã®åœŸåœ°ã¸ã®ã€Œãƒ›ãƒ¼ãƒ è¨­å®šã€ã‚’許å¯"
108 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€[ワールド]メニュー>[ホームをã“ã“ã«è¨­å®š]を使用ã—ã¦ã€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«è­²æ¸¡ã•れãŸåŒºç”»ã‚’ホームã«è¨­å®šã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" 108 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€[ワールド]メニュー>[ホームをã“ã“ã«è¨­å®š]を使用ã—ã¦ã€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«è­²æ¸¡ã•れãŸåŒºç”»ã‚’ホームã«è¨­å®šã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
109 name="land allow set home" /> 109 name="land allow set home" value="28" />
110 </action_set> 110 </action_set>
111 <action_set 111 <action_set
112 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ä½äººã®å‡çµã‚„追放をå«ã‚€ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ã€åˆ¶é™ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" 112 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ä½äººã®å‡çµã‚„追放をå«ã‚€ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ã€åˆ¶é™ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚"
113 name="Parcel Access"> 113 name="Parcel Access">
114 <action description="区画アクセス・リストã®ç®¡ç†" 114 <action description="区画アクセス・リストã®ç®¡ç†"
115 longdescription="区画アクセス・リストã®ç®¡ç†ã¯ã€[土地情報]>[アクセス]タブã§è¡Œã„ã¾ã™ã€‚" 115 longdescription="区画アクセス・リストã®ç®¡ç†ã¯ã€[土地情報]>[アクセス]タブã§è¡Œã„ã¾ã™ã€‚"
116 name="land manage allowed" /> 116 name="land manage allowed" value="29" />
117 <action description="åŒºç”»ç¦æ­¢ãƒªã‚¹ãƒˆã®ç®¡ç†" 117 <action description="åŒºç”»ç¦æ­¢ãƒªã‚¹ãƒˆã®ç®¡ç†"
118 longdescription="åŒºç”»ç¦æ­¢ãƒªã‚¹ãƒˆã®ç®¡ç†ã¯ã€[土地情報]>[ç¦æ­¢]タブã§è¡Œã„ã¾ã™ã€‚" 118 longdescription="åŒºç”»ç¦æ­¢ãƒªã‚¹ãƒˆã®ç®¡ç†ã¯ã€[土地情報]>[ç¦æ­¢]タブã§è¡Œã„ã¾ã™ã€‚"
119 name="land manage banned" /> 119 name="land manage banned" value="30" />
120 <action description="区画ã®ã€Œãƒ‘ス販売ã€ã®è¨­å®šã‚’変更" 120 <action description="区画ã®ã€Œãƒ‘ス販売ã€ã®è¨­å®šã‚’変更"
121 longdescription="区画ã®ã€Œãƒ‘ス販売ã€ã®è¨­å®šã‚’変更ã™ã‚‹ã«ã¯ã€[土地情報] &gt; [アクセス]タブを使ã„ã¾ã™ã€‚" 121 longdescription="区画ã®ã€Œãƒ‘ス販売ã€ã®è¨­å®šã‚’変更ã™ã‚‹ã«ã¯ã€[土地情報] &gt; [アクセス]タブを使ã„ã¾ã™ã€‚"
122 name="land manage passes" /> 122 name="land manage passes" value="31" />
123 <action description="区画上ã®ä½äººã®è¿½æ”¾ã¨å‡çµ" 123 <action description="区画上ã®ä½äººã®è¿½æ”¾ã¨å‡çµ"
124 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ã«å•題ã®ã‚ã‚‹ä½äººãŒã„ã‚‹å ´åˆã«ã€å³ã‚¯ãƒªãƒƒã‚¯ãƒ»ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰[詳細>]ã‚’é¸æŠžã—ã€[追放...]ã¾ãŸã¯[フリーズ...]ã‚’é¸æŠžã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ãã®ä½äººã‚’処ç†ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" 124 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ã«å•題ã®ã‚ã‚‹ä½äººãŒã„ã‚‹å ´åˆã«ã€å³ã‚¯ãƒªãƒƒã‚¯ãƒ»ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰[詳細>]ã‚’é¸æŠžã—ã€[追放...]ã¾ãŸã¯[フリーズ...]ã‚’é¸æŠžã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ãã®ä½äººã‚’処ç†ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
125 name="land admin" /> 125 name="land admin" value="32" />
126 </action_set> 126 </action_set>
127 <action_set 127 <action_set
128 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚ªãƒ–ジェクトã®è¿”å´ã€ãƒªãƒ³ãƒ‡ãƒ³ãƒ—ラントã®è¨­ç½®ã‚„移動をã€ãƒ¡ãƒ³ãƒãƒ¼ã«è¨±å¯ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚ ã“れã¯ãƒ¡ãƒ³ãƒãƒ¼ãŒã‚´ãƒŸå‡¦ç†ã‚„景観作æˆã‚’ã™ã‚‹éš›ã«ä¾¿åˆ©ã§ã™ãŒã€è¿”å´ã—ãŸã‚ªãƒ–ジェクトã¯å…ƒã«æˆ»ã›ãªã„ã®ã§ã€æ³¨æ„ã—ã¦è¡Œã„ã¾ã—ょã†ã€‚" 128 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚ªãƒ–ジェクトã®è¿”å´ã€ãƒªãƒ³ãƒ‡ãƒ³ãƒ—ラントã®è¨­ç½®ã‚„移動をã€ãƒ¡ãƒ³ãƒãƒ¼ã«è¨±å¯ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚ ã“れã¯ãƒ¡ãƒ³ãƒãƒ¼ãŒã‚´ãƒŸå‡¦ç†ã‚„景観作æˆã‚’ã™ã‚‹éš›ã«ä¾¿åˆ©ã§ã™ãŒã€è¿”å´ã—ãŸã‚ªãƒ–ジェクトã¯å…ƒã«æˆ»ã›ãªã„ã®ã§ã€æ³¨æ„ã—ã¦è¡Œã„ã¾ã—ょã†ã€‚"
129 name="Parcel Content"> 129 name="Parcel Content">
130 <action description="グループ所有オブジェクトã®è¿”å´" 130 <action description="グループ所有オブジェクトã®è¿”å´"
131 longdescription="グループ所有ã®åŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã®ã†ã¡ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®ã‚ªãƒ–ジェクトを返å´ã™ã‚‹ã«ã¯ã€[土地情報]>[オブジェクト]タブを使ã„ã¾ã™ã€‚" 131 longdescription="グループ所有ã®åŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã®ã†ã¡ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®ã‚ªãƒ–ジェクトを返å´ã™ã‚‹ã«ã¯ã€[土地情報]>[オブジェクト]タブを使ã„ã¾ã™ã€‚"
132 name="land return group owned" /> 132 name="land return group owned" value="48" />
133 <action description="グループã«è¨­å®šã•れã¦ã„るオブジェクトを返å´" 133 <action description="グループã«è¨­å®šã•れã¦ã„るオブジェクトを返å´"
134 longdescription="グループ所有ã®åŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã®ã†ã¡ã€ã‚°ãƒ«ãƒ¼ãƒ—ã«è¨­å®šã•れã¦ã„るオブジェクトを返å´ã™ã‚‹ã«ã¯ã€[土地情報]>[オブジェクト]タブを使ã„ã¾ã™ã€‚" 134 longdescription="グループ所有ã®åŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã®ã†ã¡ã€ã‚°ãƒ«ãƒ¼ãƒ—ã«è¨­å®šã•れã¦ã„るオブジェクトを返å´ã™ã‚‹ã«ã¯ã€[土地情報]>[オブジェクト]タブを使ã„ã¾ã™ã€‚"
135 name="land return group set" /> 135 name="land return group set" value="33" />
136 <action description="éžã‚°ãƒ«ãƒ¼ãƒ—・オブジェクトã®è¿”å´" 136 <action description="éžã‚°ãƒ«ãƒ¼ãƒ—・オブジェクトã®è¿”å´"
137 longdescription="グループ所有ã®åŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã®ã†ã¡ã€ã‚°ãƒ«ãƒ¼ãƒ—以外ã®ã‚ªãƒ–ジェクトを返å´ã™ã‚‹ã«ã¯ã€[土地情報]>[オブジェクト]タブを使ã„ã¾ã™ã€‚" 137 longdescription="グループ所有ã®åŒºç”»ä¸Šã®ã‚ªãƒ–ジェクトã®ã†ã¡ã€ã‚°ãƒ«ãƒ¼ãƒ—以外ã®ã‚ªãƒ–ジェクトを返å´ã™ã‚‹ã«ã¯ã€[土地情報]>[オブジェクト]タブを使ã„ã¾ã™ã€‚"
138 name="land return non group" /> 138 name="land return non group" value="34" />
139 <action description="Lindenè£½ã®æ¤ç‰©ã‚’使用ã—ã¦æ™¯è¦³ä½œæˆ" 139 <action description="Lindenè£½ã®æ¤ç‰©ã‚’使用ã—ã¦æ™¯è¦³ä½œæˆ"
140 longdescription="景観作æˆèƒ½åŠ›ã«ã‚ˆã‚Šã€ãƒªãƒ³ãƒ‡ãƒ³è£½ã®æ¨¹æœ¨ã€æ¤ç‰©ã€è‰ã‚’é…ç½®ãŠã‚ˆã³ç§»å‹•ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã€è‡ªåˆ†ã®æŒã¡ç‰©ã®ãƒ©ã‚¤ãƒ–ラリ>オブジェクト・フォルダã‹ã‚‰æ¤œç´¢ã§ãã‚‹ã»ã‹ã€ã€Œä½œæˆã€ãƒœã‚¿ãƒ³ã§ä½œæˆã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚" 140 longdescription="景観作æˆèƒ½åŠ›ã«ã‚ˆã‚Šã€ãƒªãƒ³ãƒ‡ãƒ³è£½ã®æ¨¹æœ¨ã€æ¤ç‰©ã€è‰ã‚’é…ç½®ãŠã‚ˆã³ç§»å‹•ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã€è‡ªåˆ†ã®æŒã¡ç‰©ã®ãƒ©ã‚¤ãƒ–ラリ>オブジェクト・フォルダã‹ã‚‰æ¤œç´¢ã§ãã‚‹ã»ã‹ã€ã€Œä½œæˆã€ãƒœã‚¿ãƒ³ã§ä½œæˆã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
141 name="land gardening" /> 141 name="land gardening" value="35" />
142 </action_set> 142 </action_set>
143 <action_set 143 <action_set
144 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®ã‚ªãƒ–ジェクトを譲渡ã€ä¿®æ­£ã€è²©å£²ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚ ã“ã†ã—ãŸå¤‰æ›´ã¯ã€ï¼»ç·¨é›†ãƒ„ール]&gt;[一般]タブã§è¡Œã‚れã¾ã™ã€‚ オブジェクトをå³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ï¼»ç·¨é›†ï¼½ã‚’é–‹ãã¨ã€è¨­å®šå†…容を表示ã§ãã¾ã™ã€‚" 144 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®ã‚ªãƒ–ジェクトを譲渡ã€ä¿®æ­£ã€è²©å£²ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚ ã“ã†ã—ãŸå¤‰æ›´ã¯ã€ï¼»ç·¨é›†ãƒ„ール]&gt;[一般]タブã§è¡Œã‚れã¾ã™ã€‚ オブジェクトをå³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ï¼»ç·¨é›†ï¼½ã‚’é–‹ãã¨ã€è¨­å®šå†…容を表示ã§ãã¾ã™ã€‚"
145 name="Object Management"> 145 name="Object Management">
146 <action description="グループã«ã‚ªãƒ–ジェクトを譲渡" 146 <action description="グループã«ã‚ªãƒ–ジェクトを譲渡"
147 longdescription="グループã«ã‚ªãƒ–ジェクトを譲渡ã™ã‚‹ã«ã¯ã€ç·¨é›†ãƒ„ール>一般タブを使ã„ã¾ã™ã€‚" 147 longdescription="グループã«ã‚ªãƒ–ジェクトを譲渡ã™ã‚‹ã«ã¯ã€ç·¨é›†ãƒ„ール>一般タブを使ã„ã¾ã™ã€‚"
148 name="object deed" /> 148 name="object deed" value="36" />
149 <action 149 <action
150 description="ã‚°ãƒ«ãƒ¼ãƒ—æ‰€æœ‰ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ“作(移動ã€ã‚³ãƒ”ーã€ä¿®æ­£ï¼‰" 150 description="ã‚°ãƒ«ãƒ¼ãƒ—æ‰€æœ‰ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ“作(移動ã€ã‚³ãƒ”ーã€ä¿®æ­£ï¼‰"
151 longdescription="ã‚°ãƒ«ãƒ¼ãƒ—æ‰€æœ‰ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ“作(移動ã€ã‚³ãƒ”ーã€ä¿®æ­£ï¼‰ã¯ã€[編集ツール]>[一般]タブã§è¡Œã„ã¾ã™ã€‚" 151 longdescription="ã‚°ãƒ«ãƒ¼ãƒ—æ‰€æœ‰ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ“作(移動ã€ã‚³ãƒ”ーã€ä¿®æ­£ï¼‰ã¯ã€[編集ツール]>[一般]タブã§è¡Œã„ã¾ã™ã€‚"
152 name="object manipulate" /> 152 name="object manipulate" value="38" />
153 <action description="グループ所有オブジェクトを販売å¯èƒ½ã«è¨­å®š" 153 <action description="グループ所有オブジェクトを販売å¯èƒ½ã«è¨­å®š"
154 longdescription="グループ所有オブジェクトを販売å¯èƒ½ã«è¨­å®šã«ã™ã‚‹ã«ã¯ã€[編集ツール]>[一般]タブを使ã„ã¾ã™ã€‚" 154 longdescription="グループ所有オブジェクトを販売å¯èƒ½ã«è¨­å®šã«ã™ã‚‹ã«ã¯ã€[編集ツール]>[一般]タブを使ã„ã¾ã™ã€‚"
155 name="object set sale" /> 155 name="object set sale" value="39" />
156 </action_set> 156 </action_set>
157 <action_set 157 <action_set
158 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ãƒ¡ãƒ³ãƒãƒ¼ã«ã€ã‚°ãƒ«ãƒ¼ãƒ—ã®è² å‚µã®æ”¯æ‰•ã„ã¨åˆ©å­å—ã‘å–ã‚Šã‚’è¦æ±‚ã™ã‚‹æ¨©é™ã€ã‚°ãƒ«ãƒ¼ãƒ—å£åº§å±¥æ­´ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’制é™ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" 158 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ãƒ¡ãƒ³ãƒãƒ¼ã«ã€ã‚°ãƒ«ãƒ¼ãƒ—ã®è² å‚µã®æ”¯æ‰•ã„ã¨åˆ©å­å—ã‘å–ã‚Šã‚’è¦æ±‚ã™ã‚‹æ¨©é™ã€ã‚°ãƒ«ãƒ¼ãƒ—å£åº§å±¥æ­´ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’制é™ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚"
159 name="Accounting"> 159 name="Accounting">
160 <action description="グループ負債ã®è¿”済ã¨ã‚°ãƒ«ãƒ¼ãƒ—é…当ã®å—é ˜" 160 <action description="グループ負債ã®è¿”済ã¨ã‚°ãƒ«ãƒ¼ãƒ—é…当ã®å—é ˜"
161 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã«ã¤ã„ã¦ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—è² å‚µã®æ”¯æ‰•ã„ã¨ã‚°ãƒ«ãƒ¼ãƒ—é…当ã®å—ã‘å–りãŒè‡ªå‹•çš„ã«è¡Œã‚れã¾ã™ã€‚ ã¤ã¾ã‚Šã€ã“れらã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€æ¯Žæ—¥é…当ã•れるグループ所有ã®åœŸåœ°ã®å£²ã‚Šä¸Šã’金ã®ä¸€éƒ¨ã‚’å—ã‘å–ã‚‹ã¨å…±ã«ã€åŒºç”»ã®åºƒå‘Šè²»ãªã©ã‚’è² æ‹…ã™ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚" 161 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã«ã¤ã„ã¦ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—è² å‚µã®æ”¯æ‰•ã„ã¨ã‚°ãƒ«ãƒ¼ãƒ—é…当ã®å—ã‘å–りãŒè‡ªå‹•çš„ã«è¡Œã‚れã¾ã™ã€‚ ã¤ã¾ã‚Šã€ã“れらã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€æ¯Žæ—¥é…当ã•れるグループ所有ã®åœŸåœ°ã®å£²ã‚Šä¸Šã’金ã®ä¸€éƒ¨ã‚’å—ã‘å–ã‚‹ã¨å…±ã«ã€åŒºç”»ã®åºƒå‘Šè²»ãªã©ã‚’è² æ‹…ã™ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚"
162 name="accounting accountable" /> 162 name="accounting accountable" value="40" />
163 </action_set> 163 </action_set>
164 <action_set 164 <action_set
165 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—通知ã®é€ä¿¡ã€å—ä¿¡ã€è¡¨ç¤ºã‚’メンãƒãƒ¼ã«è¨±å¯ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" 165 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—通知ã®é€ä¿¡ã€å—ä¿¡ã€è¡¨ç¤ºã‚’メンãƒãƒ¼ã«è¨±å¯ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚"
166 name="Notices"> 166 name="Notices">
167 <action description="通知をé€ä¿¡" 167 <action description="通知をé€ä¿¡"
168 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€[グループ情報]>[通知]タブã§é€šçŸ¥ã‚’é€ä¿¡ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" 168 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€[グループ情報]>[通知]タブã§é€šçŸ¥ã‚’é€ä¿¡ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
169 name="notices send" /> 169 name="notices send" value="42" />
170 <action description="通知ã®å—ä¿¡ã¨éŽåŽ»ã®é€šçŸ¥ã®é–²è¦§" 170 <action description="通知ã®å—ä¿¡ã¨éŽåŽ»ã®é€šçŸ¥ã®é–²è¦§"
171 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€é€šçŸ¥ã‚’å—ã‘å–ã‚‹ã“ã¨ãŒã§ãã€[グループ情報]>[通知]タブã§éŽåŽ»ã®é€šçŸ¥ã‚’閲覧ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" 171 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€é€šçŸ¥ã‚’å—ã‘å–ã‚‹ã“ã¨ãŒã§ãã€[グループ情報]>[通知]タブã§éŽåŽ»ã®é€šçŸ¥ã‚’閲覧ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
172 name="notices receive" /> 172 name="notices receive" value="43" />
173 </action_set> 173 </action_set>
174 <action_set 174 <action_set
175 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ææ¡ˆã®ä½œæˆã¨æŠ•ç¥¨ã€æŠ•ç¥¨å±¥æ­´ã®è¡¨ç¤ºã‚’メンãƒãƒ¼ã«è¨±å¯ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" 175 description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ææ¡ˆã®ä½œæˆã¨æŠ•ç¥¨ã€æŠ•ç¥¨å±¥æ­´ã®è¡¨ç¤ºã‚’メンãƒãƒ¼ã«è¨±å¯ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚"
176 name="Proposals"> 176 name="Proposals">
177 <action description="ææ¡ˆã‚’作æˆ" 177 <action description="ææ¡ˆã‚’作æˆ"
178 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€æŠ•票ã®å¯¾è±¡ã¨ãªã‚‹å•題æèµ·ã‚’[グループ情報]>[å•題æèµ·]タブ上ã§ä½œæˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" 178 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€æŠ•票ã®å¯¾è±¡ã¨ãªã‚‹å•題æèµ·ã‚’[グループ情報]>[å•題æèµ·]タブ上ã§ä½œæˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
179 name="proposal start" /> 179 name="proposal start" value="44" />
180 <action description="å•題æèµ·ã«æŠ•票ã™ã‚‹" 180 <action description="å•題æèµ·ã«æŠ•票ã™ã‚‹"
181 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—æƒ…å ±ï¼žææ¡ˆã‚¿ãƒ–ã§ææ¡ˆã«æŠ•ç¥¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" 181 longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—æƒ…å ±ï¼žææ¡ˆã‚¿ãƒ–ã§ææ¡ˆã«æŠ•ç¥¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
182 name="proposal vote" /> 182 name="proposal vote" value="45" />
183 </action_set> 183 </action_set>
184</role_actions> 184</role_actions>
diff --git a/linden/indra/newview/skins/xui/ko/role_actions.xml b/linden/indra/newview/skins/xui/ko/role_actions.xml
index 848393e..9e06970 100644
--- a/linden/indra/newview/skins/xui/ko/role_actions.xml
+++ b/linden/indra/newview/skins/xui/ko/role_actions.xml
@@ -5,39 +5,39 @@
5 name="Membership"> 5 name="Membership">
6 <action description="ì´ ê·¸ë£¹ì— ì‚¬ëžŒë“¤ 초대" 6 <action description="ì´ ê·¸ë£¹ì— ì‚¬ëžŒë“¤ 초대"
7 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ íƒ­ì— ìžˆëŠ” &apos;새로운 사람 초대’ ë²„íŠ¼ì„ ì‚¬ìš©í•˜ì—¬ ì´ ê·¸ë£¹ì— ì‚¬ëžŒë“¤ì„ ì´ˆëŒ€í•©ë‹ˆë‹¤." 7 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ íƒ­ì— ìžˆëŠ” &apos;새로운 사람 초대’ ë²„íŠ¼ì„ ì‚¬ìš©í•˜ì—¬ ì´ ê·¸ë£¹ì— ì‚¬ëžŒë“¤ì„ ì´ˆëŒ€í•©ë‹ˆë‹¤."
8 name="member invite" /> 8 name="member invite" value="1" />
9 <action description="ì´ ê·¸ë£¹ì—서 íšŒì› ê°•í‡´" 9 <action description="ì´ ê·¸ë£¹ì—서 íšŒì› ê°•í‡´"
10 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ 탭ì—서 &apos;그룹ì—서 강퇴&apos; ë²„íŠ¼ì„ ì‚¬ìš©í•˜ì—¬ ì´ ê·¸ë£¹ì—서 íšŒì› ê°•í‡´ë¥¼ 수행합니다. 소유주는 다른 소유주를 제외한 모든 ì‚¬ëžŒì„ ì¶”ë°©í•  수 있습니다. 소유주가 아닌 회ì›ì¸ 경우ì—는 모든 사람 ì—­í• ì— ì†í•œ 경우ì—ë§Œ 그룹ì—서 강퇴ë˜ë©° 다른 ì—­í• ì¸ ê²½ìš°ì—는 추방ë˜ì§€ 않습니다. 회ì›ì„ ì—­í• ì—서 제거하려면 &apos;ì—­í• ì—서 íšŒì› ì‚­ì œ&apos; ê¶Œí•œì´ ìžˆì–´ì•¼ 합니다." 10 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ 탭ì—서 &apos;그룹ì—서 강퇴&apos; ë²„íŠ¼ì„ ì‚¬ìš©í•˜ì—¬ ì´ ê·¸ë£¹ì—서 íšŒì› ê°•í‡´ë¥¼ 수행합니다. 소유주는 다른 소유주를 제외한 모든 ì‚¬ëžŒì„ ì¶”ë°©í•  수 있습니다. 소유주가 아닌 회ì›ì¸ 경우ì—는 모든 사람 ì—­í• ì— ì†í•œ 경우ì—ë§Œ 그룹ì—서 강퇴ë˜ë©° 다른 ì—­í• ì¸ ê²½ìš°ì—는 추방ë˜ì§€ 않습니다. 회ì›ì„ ì—­í• ì—서 제거하려면 &apos;ì—­í• ì—서 íšŒì› ì‚­ì œ&apos; ê¶Œí•œì´ ìžˆì–´ì•¼ 합니다."
11 name="member eject" /> 11 name="member eject" value="2" />
12 <action 12 <action
13 description="&apos;ìžìœ  가입&apos; 토글 ë° &apos;가입 수수료&apos; 변경" 13 description="&apos;ìžìœ  가입&apos; 토글 ë° &apos;가입 수수료&apos; 변경"
14 longdescription="초대 ì—†ì´ ìƒˆ 회ì›ì„ 가입시키려면 &apos;ìžìœ  가입&apos;ì„ í† ê¸€í•˜ê³  ì¼ë°˜ íƒ­ì˜ ê·¸ë£¹ 환경 설정 섹션ì—서 &apos;가입 수수료&apos;를 변경합니다." 14 longdescription="초대 ì—†ì´ ìƒˆ 회ì›ì„ 가입시키려면 &apos;ìžìœ  가입&apos;ì„ í† ê¸€í•˜ê³  ì¼ë°˜ íƒ­ì˜ ê·¸ë£¹ 환경 설정 섹션ì—서 &apos;가입 수수료&apos;를 변경합니다."
15 name="member options" /> 15 name="member options" value="3" />
16 </action_set> 16 </action_set>
17 <action_set 17 <action_set
18 description="ì´ëŸ¬í•œ 권한ì—는 그룹 ì—­í• ì„ ì¶”ê°€, ì‚­ì œ ë° ë³€ê²½, 특정 ì—­í• ì— íšŒì›ì„ 추가 ë° ì‚­ì œí•˜ë©° 특정 ì—­í• ì— ë‹¤ë¥¸ ê¶Œí•œì„ í• ë‹¹í•˜ëŠ” ê²ƒì„ í¬í•¨í•©ë‹ˆë‹¤." 18 description="ì´ëŸ¬í•œ 권한ì—는 그룹 ì—­í• ì„ ì¶”ê°€, ì‚­ì œ ë° ë³€ê²½, 특정 ì—­í• ì— íšŒì›ì„ 추가 ë° ì‚­ì œí•˜ë©° 특정 ì—­í• ì— ë‹¤ë¥¸ ê¶Œí•œì„ í• ë‹¹í•˜ëŠ” ê²ƒì„ í¬í•¨í•©ë‹ˆë‹¤."
19 name="Roles"> 19 name="Roles">
20 <action description="새 ì—­í•  ìƒì„±" 20 <action description="새 ì—­í•  ìƒì„±"
21 longdescription="íšŒì› ë° ì—­í•  탭 &gt; ì—­í•  하위 탭ì—서 새 ì—­í• ì„ ìƒì„±í•©ë‹ˆë‹¤." 21 longdescription="íšŒì› ë° ì—­í•  탭 &gt; ì—­í•  하위 탭ì—서 새 ì—­í• ì„ ìƒì„±í•©ë‹ˆë‹¤."
22 name="role create" /> 22 name="role create" value="4" />
23 <action description="역할 삭제" 23 <action description="역할 삭제"
24 longdescription="íšŒì› ë° ì—­í•  탭 &gt; ì—­í•  하위 탭ì—서 ì—­í• ì„ ì‚­ì œí•©ë‹ˆë‹¤." 24 longdescription="íšŒì› ë° ì—­í•  탭 &gt; ì—­í•  하위 탭ì—서 ì—­í• ì„ ì‚­ì œí•©ë‹ˆë‹¤."
25 name="role delete" /> 25 name="role delete" value="5" />
26 <action description="ì—­í•  ì´ë¦„, 타ì´í‹€ ë° ì„¤ëª… 변경" 26 <action description="ì—­í•  ì´ë¦„, 타ì´í‹€ ë° ì„¤ëª… 변경"
27 longdescription="ì—­í• ì„ ì„ íƒí•œ 후 íšŒì› ë° ì—­í•  탭 &gt; ì—­í•  하위 탭 맨 아래ì—서 ì—­í•  ì´ë¦„, 타ì´í‹€ ë° ì„¤ëª…ì„ ë³€ê²½í•©ë‹ˆë‹¤." 27 longdescription="ì—­í• ì„ ì„ íƒí•œ 후 íšŒì› ë° ì—­í•  탭 &gt; ì—­í•  하위 탭 맨 아래ì—서 ì—­í•  ì´ë¦„, 타ì´í‹€ ë° ì„¤ëª…ì„ ë³€ê²½í•©ë‹ˆë‹¤."
28 name="role properties" /> 28 name="role properties" value="6" />
29 <action description="회ì›ì—게 할당ìžì˜ ì—­í•  할당" 29 <action description="회ì›ì—게 할당ìžì˜ ì—­í•  할당"
30 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ íƒ­ì˜ í• ë‹¹ëœ ì—­í•  섹션ì—서 회ì›ì—게 ì—­í• ì„ í• ë‹¹í•©ë‹ˆë‹¤. ì´ ê¶Œí•œì„ ê°€ì§„ 회ì›ì€ 할당ìžê°€ ì´ë¯¸ ì†í•´ 있는 ì—­í• ì—ë§Œ 회ì›ì„ 추가할 수 있습니다." 30 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ íƒ­ì˜ í• ë‹¹ëœ ì—­í•  섹션ì—서 회ì›ì—게 ì—­í• ì„ í• ë‹¹í•©ë‹ˆë‹¤. ì´ ê¶Œí•œì„ ê°€ì§„ 회ì›ì€ 할당ìžê°€ ì´ë¯¸ ì†í•´ 있는 ì—­í• ì—ë§Œ 회ì›ì„ 추가할 수 있습니다."
31 name="role assign member limited" /> 31 name="role assign member limited" value="7" />
32 <action description="회ì›ì—게 모든 ì—­í•  할당" 32 <action description="회ì›ì—게 모든 ì—­í•  할당"
33 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ íƒ­ì˜ í• ë‹¹ëœ ì—­í•  섹션ì—서 회ì›ì—게 모든 ì—­í•  í• ë‹¹ì„ ìˆ˜í–‰í•©ë‹ˆë‹¤. *경고* ì´ ê¶Œí•œì„ ê°€ì§„ ì—­í•  회ì›ì€ 소유ìžê°€ 아닌 다른 íšŒì› ë° ìžê¸° ìžì‹ ì—게 현재 보유한 권한 ì´ìƒì˜ ì—­í• ì„ í• ë‹¹í•˜ì—¬ 소유ìžì— í•„ì í•˜ëŠ” ê¶Œí•œì„ ê°€ì§€ë„ë¡ í•  수 있습니다. ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´ 해야 합니다." 33 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ íƒ­ì˜ í• ë‹¹ëœ ì—­í•  섹션ì—서 회ì›ì—게 모든 ì—­í•  í• ë‹¹ì„ ìˆ˜í–‰í•©ë‹ˆë‹¤. *경고* ì´ ê¶Œí•œì„ ê°€ì§„ ì—­í•  회ì›ì€ 소유ìžê°€ 아닌 다른 íšŒì› ë° ìžê¸° ìžì‹ ì—게 현재 보유한 권한 ì´ìƒì˜ ì—­í• ì„ í• ë‹¹í•˜ì—¬ 소유ìžì— í•„ì í•˜ëŠ” ê¶Œí•œì„ ê°€ì§€ë„ë¡ í•  수 있습니다. ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´ 해야 합니다."
34 name="role assign member" /> 34 name="role assign member" value="8" />
35 <action description="ì—­í• ì—서 íšŒì› ì‚­ì œ" 35 <action description="ì—­í• ì—서 íšŒì› ì‚­ì œ"
36 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ íƒ­ì˜ í• ë‹¹ëœ ì—­í• ì—서 회ì›ë“¤ë¡œë¶€í„° ì—­í•  제거. 소유ìžë“¤ì€ ì œê±°ë  ìˆ˜ ì—†ìŒ." 36 longdescription="íšŒì› ë° ì—­í•  탭 &gt; íšŒì› í•˜ìœ„ íƒ­ì˜ í• ë‹¹ëœ ì—­í• ì—서 회ì›ë“¤ë¡œë¶€í„° ì—­í•  제거. 소유ìžë“¤ì€ ì œê±°ë  ìˆ˜ ì—†ìŒ."
37 name="role remove member" /> 37 name="role remove member" value="9" />
38 <action description="ì—­í• ì˜ ê¶Œí•œì„ í• ë‹¹ ë° ì‚­ì œ" 38 <action description="ì—­í• ì˜ ê¶Œí•œì„ í• ë‹¹ ë° ì‚­ì œ"
39 longdescription="íšŒì› ë° ì—­í•  탭 &gt; ì—­í•  하위 íƒ­ì˜ í—ˆìš©ëœ ê¶Œí•œ 섹션ì—서 ì—­í• ì˜ ê¶Œí•œì„ í• ë‹¹ ë° ì‚­ì œí•©ë‹ˆë‹¤. *경고* ì´ ê¶Œí•œì„ ê°€ì§„ ì—­í•  회ì›ì€ 소유ìžê°€ 아닌 다른 íšŒì› ë° ìžê¸° ìžì‹ ì—게 모든 ê¶Œí•œì„ í• ë‹¹í•˜ì—¬ 소유ìžì— í•„ì í•˜ëŠ” ê¶Œí•œì„ ê°€ì§€ë„ë¡ í•  수 있습니다. ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´ 해야 합니다." 39 longdescription="íšŒì› ë° ì—­í•  탭 &gt; ì—­í•  하위 íƒ­ì˜ í—ˆìš©ëœ ê¶Œí•œ 섹션ì—서 ì—­í• ì˜ ê¶Œí•œì„ í• ë‹¹ ë° ì‚­ì œí•©ë‹ˆë‹¤. *경고* ì´ ê¶Œí•œì„ ê°€ì§„ ì—­í•  회ì›ì€ 소유ìžê°€ 아닌 다른 íšŒì› ë° ìžê¸° ìžì‹ ì—게 모든 ê¶Œí•œì„ í• ë‹¹í•˜ì—¬ 소유ìžì— í•„ì í•˜ëŠ” ê¶Œí•œì„ ê°€ì§€ë„ë¡ í•  수 있습니다. ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´ 해야 합니다."
40 name="role change actions" /> 40 name="role change actions" value="10" />
41 </action_set> 41 </action_set>
42 <action_set 42 <action_set
43 description="ì´ëŸ¬í•œ 권한ì—는 공공 가시성, 설립 ì¡°í•­, 휘장 변경과 ê°™ì€ ê·¸ë£¹ì˜ ì‹ ë¶„ì„ ìˆ˜ì •í•  ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤." 43 description="ì´ëŸ¬í•œ 권한ì—는 공공 가시성, 설립 ì¡°í•­, 휘장 변경과 ê°™ì€ ê·¸ë£¹ì˜ ì‹ ë¶„ì„ ìˆ˜ì •í•  ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤."
@@ -45,139 +45,139 @@
45 <action 45 <action
46 description="설립 ì¡°í•­, 로고, &apos;ì›¹ì— ê²Œì‹œ&apos;, 그룹 ì •ë³´ì— í‘œì‹œë˜ëŠ” íšŒì› ë“±ì„ ë³€ê²½í•©ë‹ˆë‹¤." 46 description="설립 ì¡°í•­, 로고, &apos;ì›¹ì— ê²Œì‹œ&apos;, 그룹 ì •ë³´ì— í‘œì‹œë˜ëŠ” íšŒì› ë“±ì„ ë³€ê²½í•©ë‹ˆë‹¤."
47 longdescription="설립 ì¡°í•­, 로고, &apos;ì›¹ì— ê²Œì‹œ&apos;, 그룹 ì •ë³´ì— í‘œì‹œë˜ëŠ” íšŒì› ë“±ì„ ë³€ê²½í•©ë‹ˆë‹¤. ì¼ë°˜ 탭ì—서 수행합니다." 47 longdescription="설립 ì¡°í•­, 로고, &apos;ì›¹ì— ê²Œì‹œ&apos;, 그룹 ì •ë³´ì— í‘œì‹œë˜ëŠ” íšŒì› ë“±ì„ ë³€ê²½í•©ë‹ˆë‹¤. ì¼ë°˜ 탭ì—서 수행합니다."
48 name="group change identity" /> 48 name="group change identity" value="11" />
49 </action_set> 49 </action_set>
50 <action_set 50 <action_set
51 description="ì´ëŸ¬í•œ 권한ì—는 ì´ ê·¸ë£¹ 소유 토지를 ì–‘ë„, 수정 ë° íŒë§¤í•˜ëŠ” ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤. 토지 소개 ì°½ì— ê°€ë ¤ë©´ í† ì§€ì˜ ì¼ë¶€ë¥¼ 마우스 오른쪽 í´ë¦­í•˜ê³  &apos;토지 소개...&apos;를 ì„ íƒí•˜ê±°ë‚˜ 메뉴 ë°”ì—서 êµ¬íš ì •ë³´ë¥¼ í´ë¦­í•©ë‹ˆë‹¤." 51 description="ì´ëŸ¬í•œ 권한ì—는 ì´ ê·¸ë£¹ 소유 토지를 ì–‘ë„, 수정 ë° íŒë§¤í•˜ëŠ” ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤. 토지 소개 ì°½ì— ê°€ë ¤ë©´ í† ì§€ì˜ ì¼ë¶€ë¥¼ 마우스 오른쪽 í´ë¦­í•˜ê³  &apos;토지 소개...&apos;를 ì„ íƒí•˜ê±°ë‚˜ 메뉴 ë°”ì—서 êµ¬íš ì •ë³´ë¥¼ í´ë¦­í•©ë‹ˆë‹¤."
52 name="Parcel Management"> 52 name="Parcel Management">
53 <action description="토지 ì–‘ë„ ë° ê·¸ë£¹ì„ ìœ„í•œ 토지 구매" 53 <action description="토지 ì–‘ë„ ë° ê·¸ë£¹ì„ ìœ„í•œ 토지 구매"
54 longdescription="토지를 ì–‘ë„하고 ê·¸ë£¹ì„ ìœ„í•œ 토지를 구매합니다. 토지 소개 &gt; ì¼ë°˜ 탭ì—서 수행합니다." 54 longdescription="토지를 ì–‘ë„하고 ê·¸ë£¹ì„ ìœ„í•œ 토지를 구매합니다. 토지 소개 &gt; ì¼ë°˜ 탭ì—서 수행합니다."
55 name="land deed" /> 55 name="land deed" value="12" />
56 <action description="린든ì—게 토지 버리기" 56 <action description="린든ì—게 토지 버리기"
57 longdescription="린든ì—게 토지를 버립니다. *경고* ì´ ê¶Œí•œì„ ê°€ì§„ ì—­í•  회ì›ì€ 토지 소개 &gt; ì¼ë°˜ 탭ì—서 그룹 ì†Œìœ ì˜ í† ì§€ë¥¼ íŒë§¤í•˜ì§€ 않고 버려 린든 소유로 ë˜ëŒë¦´ 수 있습니다. ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´í•´ì•¼ 합니다." 57 longdescription="린든ì—게 토지를 버립니다. *경고* ì´ ê¶Œí•œì„ ê°€ì§„ ì—­í•  회ì›ì€ 토지 소개 &gt; ì¼ë°˜ 탭ì—서 그룹 ì†Œìœ ì˜ í† ì§€ë¥¼ íŒë§¤í•˜ì§€ 않고 버려 린든 소유로 ë˜ëŒë¦´ 수 있습니다. ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´í•´ì•¼ 합니다."
58 name="land release" /> 58 name="land release" value="13" />
59 <action description="토지 íŒë§¤ ì •ë³´ 설정" 59 <action description="토지 íŒë§¤ ì •ë³´ 설정"
60 longdescription="토지 íŒë§¤ ì •ë³´ 설정 *경고* ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; ì¼ë°˜ íƒ­ì„ ì‚¬ìš©í•˜ì—¬ ì›í•˜ëŠ” 대로 그룹 소유 토지를 íŒë§¤í•  수 있습니다! ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´í•´ì•¼ 합니다." 60 longdescription="토지 íŒë§¤ ì •ë³´ 설정 *경고* ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; ì¼ë°˜ íƒ­ì„ ì‚¬ìš©í•˜ì—¬ ì›í•˜ëŠ” 대로 그룹 소유 토지를 íŒë§¤í•  수 있습니다! ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´í•´ì•¼ 합니다."
61 name="land set sale info" /> 61 name="land set sale info" value="14" />
62 <action description="êµ¬íš ë¶„í•  ë° ê²°í•©" 62 <action description="êµ¬íš ë¶„í•  ë° ê²°í•©"
63 longdescription="êµ¬íš ë¶„í•  ë° ê²°í•©. ì´ë ‡ê²Œ 하려면 토지, &apos;지형 편집&apos;ì„ ë§ˆìš°ìŠ¤ 오른쪽 버튼으로 í´ë¦­í•˜ê³  ì„ íƒí•  토지로 마우스를 드래그하십시오. 구íšì„ 분할하려면 ë¶„í• í•  구íšì„ ì„ íƒí•˜ê³  &apos;세분…&apos;ì„ í´ë¦­í•©ë‹ˆë‹¤. 구íšì„ 결합하려면 2ê°œ ì´ìƒì˜ ì¸ì ‘한 구íšì„ ì„ íƒí•˜ê³  &apos;결합…&apos;ì„ í´ë¦­í•©ë‹ˆë‹¤. " 63 longdescription="êµ¬íš ë¶„í•  ë° ê²°í•©. ì´ë ‡ê²Œ 하려면 토지, &apos;지형 편집&apos;ì„ ë§ˆìš°ìŠ¤ 오른쪽 버튼으로 í´ë¦­í•˜ê³  ì„ íƒí•  토지로 마우스를 드래그하십시오. 구íšì„ 분할하려면 ë¶„í• í•  구íšì„ ì„ íƒí•˜ê³  &apos;세분…&apos;ì„ í´ë¦­í•©ë‹ˆë‹¤. 구íšì„ 결합하려면 2ê°œ ì´ìƒì˜ ì¸ì ‘한 구íšì„ ì„ íƒí•˜ê³  &apos;결합…&apos;ì„ í´ë¦­í•©ë‹ˆë‹¤. "
64 name="land divide join" /> 64 name="land divide join" value="15" />
65 </action_set> 65 </action_set>
66 <action_set 66 <action_set
67 description="ì´ëŸ¬í•œ 권한ì—는 êµ¬íš ì´ë¦„ ë° ê²Œì‹œ 설정, ì—°ë½ì²˜ 찾기, 착륙 ì§€ì  ë° í…”ë¦¬í¬íЏ 경로 옵션 ë“±ì„ ë³€ê²½í•  수 있는 ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤." 67 description="ì´ëŸ¬í•œ 권한ì—는 êµ¬íš ì´ë¦„ ë° ê²Œì‹œ 설정, ì—°ë½ì²˜ 찾기, 착륙 ì§€ì  ë° í…”ë¦¬í¬íЏ 경로 옵션 ë“±ì„ ë³€ê²½í•  수 있는 ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤."
68 name="Parcel Identity"> 68 name="Parcel Identity">
69 <action description="&apos;장소 찾기&apos;를 토글 ë° ì¹´í…Œê³ ë¦¬ 설정" 69 <action description="&apos;장소 찾기&apos;를 토글 ë° ì¹´í…Œê³ ë¦¬ 설정"
70 longdescription="토지 소개 &gt; 옵션 탭ì—서 &apos;장소 찾기&apos;를 토글하고 구íšì˜ 카테고리를 설정합니다." 70 longdescription="토지 소개 &gt; 옵션 탭ì—서 &apos;장소 찾기&apos;를 토글하고 구íšì˜ 카테고리를 설정합니다."
71 name="land find places" /> 71 name="land find places" value="17" />
72 <action description="êµ¬íš ì´ë¦„, 설명, &apos;ì›¹ì— ê²Œì‹œ&apos; 설정 변경" 72 <action description="êµ¬íš ì´ë¦„, 설명, &apos;ì›¹ì— ê²Œì‹œ&apos; 설정 변경"
73 longdescription="êµ¬íš ì´ë¦„, 설명 ë° &apos;ì›¹ì— ê²Œì‹œ&apos;ì— ëŒ€í•œ ì„¤ì •ì„ ë³€ê²½í•©ë‹ˆë‹¤. 토지 소개 &gt; 옵션 탭ì—서 수행합니다." 73 longdescription="êµ¬íš ì´ë¦„, 설명 ë° &apos;ì›¹ì— ê²Œì‹œ&apos;ì— ëŒ€í•œ ì„¤ì •ì„ ë³€ê²½í•©ë‹ˆë‹¤. 토지 소개 &gt; 옵션 탭ì—서 수행합니다."
74 name="land change identity" /> 74 name="land change identity" value="18" />
75 <action description="텔레í¬íЏ ë„ì°©ì§€ ë° í…”ë ˆí¬íЏ 경로 설정" 75 <action description="텔레í¬íЏ ë„ì°©ì§€ ë° í…”ë ˆí¬íЏ 경로 설정"
76 longdescription="그룹 소유 구íšì—서, ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 수신 텔레í¬íŠ¸ì˜ ë„착지를 설정하고, 향후 제어할 수 있는 텔레í¬íЏ ì°©ì‹  ì „í™˜ë„ ì„¤ì •í•  수 있습니다. ì´ëŠ” 토지 소개 &gt; 옵션 탭ì—서 ì´ë£¨ì–´ 집니다." 76 longdescription="그룹 소유 구íšì—서, ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 수신 텔레í¬íŠ¸ì˜ ë„착지를 설정하고, 향후 제어할 수 있는 텔레í¬íЏ ì°©ì‹  ì „í™˜ë„ ì„¤ì •í•  수 있습니다. ì´ëŠ” 토지 소개 &gt; 옵션 탭ì—서 ì´ë£¨ì–´ 집니다."
77 name="land set landing point" /> 77 name="land set landing point" value="19" />
78 </action_set> 78 </action_set>
79 <action_set 79 <action_set
80 description="ì´ëŸ¬í•œ 기능ì—는 &apos;오브ì íЏ 만들기’, &apos;지형 편집&apos;, ìŒì•…ê³¼ 미디어 설정과 ê°™ì€ êµ¬íš ì˜µì…˜ì— ì˜í–¥ì„ 주는 ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤." 80 description="ì´ëŸ¬í•œ 기능ì—는 &apos;오브ì íЏ 만들기’, &apos;지형 편집&apos;, ìŒì•…ê³¼ 미디어 설정과 ê°™ì€ êµ¬íš ì˜µì…˜ì— ì˜í–¥ì„ 주는 ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤."
81 name="Parcel Settings"> 81 name="Parcel Settings">
82 <action description="ìŒì•… ë° ë¯¸ë””ì–´ 설정 변경" 82 <action description="ìŒì•… ë° ë¯¸ë””ì–´ 설정 변경"
83 longdescription="토지 소개 &gt; 미디어 탭ì—서 ìŠ¤íŠ¸ë¦¬ë° ìŒì•… ë° ë™ì˜ìƒ ì„¤ì •ì„ ë³€ê²½í•©ë‹ˆë‹¤." 83 longdescription="토지 소개 &gt; 미디어 탭ì—서 ìŠ¤íŠ¸ë¦¬ë° ìŒì•… ë° ë™ì˜ìƒ ì„¤ì •ì„ ë³€ê²½í•©ë‹ˆë‹¤."
84 name="land change media" /> 84 name="land change media" value="20" />
85 <action description="&apos;지형 편집&apos; 토글" 85 <action description="&apos;지형 편집&apos; 토글"
86 longdescription="&apos;지형 편집&apos; 토글. *경고* 토지 소개 &gt; 옵션 탭 &gt; 지형 편집 ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ë©´ 다른 모든 ì‚¬ëžŒë“¤ì´ ê·€í•˜ì˜ í† ì§€ ëª¨ìŠµì„ ë³€í˜•í•˜ì—¬ 린든 ì‹œì„¤ì— ë°°ì¹˜ ë° ì´ë™í•  수 있습니다. ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´í•´ì•¼ 합니다. 지형 편집 ê¸°ëŠ¥ì€ í† ì§€ 소개 &gt; 옵션 탭ì—서 전환할 수 있습니다." 86 longdescription="&apos;지형 편집&apos; 토글. *경고* 토지 소개 &gt; 옵션 탭 &gt; 지형 편집 ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ë©´ 다른 모든 ì‚¬ëžŒë“¤ì´ ê·€í•˜ì˜ í† ì§€ ëª¨ìŠµì„ ë³€í˜•í•˜ì—¬ 린든 ì‹œì„¤ì— ë°°ì¹˜ ë° ì´ë™í•  수 있습니다. ì´ ê¶Œí•œì„ í• ë‹¹í•˜ê¸° ì „ì— í˜„ìž¬ ìƒíƒœì— 대해 ì´í•´í•´ì•¼ 합니다. 지형 편집 ê¸°ëŠ¥ì€ í† ì§€ 소개 &gt; 옵션 탭ì—서 전환할 수 있습니다."
87 name="land edit" /> 87 name="land edit" value="21" />
88 <action description="토지 소개 &gt; 옵션 설정 토글" 88 <action description="토지 소개 &gt; 옵션 설정 토글"
89 longdescription="안전(ë°ë¯¸ì§€ ì—†ìŒ)&apos;, &apos;비행&apos;ì„ í† ê¸€í•˜ë©´ 다른 ì£¼ë¯¼ë“¤ì´ í† ì§€ 소개 &gt; 옵션 탭ì—서 ê·¸ë£¹ì´ ì†Œìœ í•œ í† ì§€ì— ëŒ€í•´ &apos;오브ì íЏ 만들기&apos;, &apos;지형 편집&apos; ë° &apos;스í¬ë¦½íЏ 실행&apos; ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 있습니다." 89 longdescription="안전(ë°ë¯¸ì§€ ì—†ìŒ)&apos;, &apos;비행&apos;ì„ í† ê¸€í•˜ë©´ 다른 ì£¼ë¯¼ë“¤ì´ í† ì§€ 소개 &gt; 옵션 탭ì—서 ê·¸ë£¹ì´ ì†Œìœ í•œ í† ì§€ì— ëŒ€í•´ &apos;오브ì íЏ 만들기&apos;, &apos;지형 편집&apos; ë° &apos;스í¬ë¦½íЏ 실행&apos; ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 있습니다."
90 name="land options" /> 90 name="land options" value="22" />
91 </action_set> 91 </action_set>
92 <action_set 92 <action_set
93 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ 그룹 ì†Œìœ ì˜ êµ¬íšì—서 ì œì•½ì„ ìš°íšŒí•  수 있는 ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤." 93 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ 그룹 ì†Œìœ ì˜ êµ¬íšì—서 ì œì•½ì„ ìš°íšŒí•  수 있는 ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤."
94 name="Parcel Powers"> 94 name="Parcel Powers">
95 <action description="&apos;지형 편집&apos; í•­ìƒ í—ˆìš©" 95 <action description="&apos;지형 편집&apos; í•­ìƒ í—ˆìš©"
96 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; 옵션 탭ì—서 꺼져 ìžˆì–´ë„ ê·¸ë£¹ 소유 구íšì—서 오브ì íŠ¸ë¥¼ 편집할 수 있습니다." 96 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; 옵션 탭ì—서 꺼져 ìžˆì–´ë„ ê·¸ë£¹ 소유 구íšì—서 오브ì íŠ¸ë¥¼ 편집할 수 있습니다."
97 name="land allow edit land" /> 97 name="land allow edit land" value="23" />
98 <action description="&apos;비행&apos; í•­ìƒ í—ˆìš©" 98 <action description="&apos;비행&apos; í•­ìƒ í—ˆìš©"
99 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; 옵션 탭ì—서 꺼져 ìžˆì–´ë„ ê·¸ë£¹ 소유 구íšì—서 비행할 수 있습니다." 99 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; 옵션 탭ì—서 꺼져 ìžˆì–´ë„ ê·¸ë£¹ 소유 구íšì—서 비행할 수 있습니다."
100 name="land allow fly" /> 100 name="land allow fly" value="24" />
101 <action description="&apos;오브ì íЏ 만들기&apos; í•­ìƒ í—ˆìš©" 101 <action description="&apos;오브ì íЏ 만들기&apos; í•­ìƒ í—ˆìš©"
102 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; 옵션 탭ì—서 꺼져 ìžˆì–´ë„ ê·¸ë£¹ 소유 구íšì—서 오브ì íŠ¸ë¥¼ 만들 수 있습니다." 102 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; 옵션 탭ì—서 꺼져 ìžˆì–´ë„ ê·¸ë£¹ 소유 구íšì—서 오브ì íŠ¸ë¥¼ 만들 수 있습니다."
103 name="land allow create" /> 103 name="land allow create" value="25" />
104 <action description="&apos;ëžœë“œë§ˆí¬ ë§Œë“¤ê¸°&apos; í•­ìƒ í—ˆìš©" 104 <action description="&apos;ëžœë“œë§ˆí¬ ë§Œë“¤ê¸°&apos; í•­ìƒ í—ˆìš©"
105 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; 옵션 탭ì—서 꺼져 ìžˆì–´ë„ ê·¸ë£¹ 소유 구íšì—서 ëžœë“œë§ˆí¬ í•  수 있습니다." 105 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 토지 소개 &gt; 옵션 탭ì—서 꺼져 ìžˆì–´ë„ ê·¸ë£¹ 소유 구íšì—서 ëžœë“œë§ˆí¬ í•  수 있습니다."
106 name="land allow landmark" /> 106 name="land allow landmark" value="26" />
107 <action description="그룹 í† ì§€ì— &apos;ì´ê³³ì„ 홈으로 설정&apos; 허용" 107 <action description="그룹 í† ì§€ì— &apos;ì´ê³³ì„ 홈으로 설정&apos; 허용"
108 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ ì´ ê·¸ë£¹ì— ì–‘ë„ëœ êµ¬íšì—서 월드 메뉴 &gt; ì´ê³³ì„ 홈으로 ì„¤ì •ì„ ì´ìš©í•  수 있습니다." 108 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ ì´ ê·¸ë£¹ì— ì–‘ë„ëœ êµ¬íšì—서 월드 메뉴 &gt; ì´ê³³ì„ 홈으로 ì„¤ì •ì„ ì´ìš©í•  수 있습니다."
109 name="land allow set home" /> 109 name="land allow set home" value="28" />
110 </action_set> 110 </action_set>
111 <action_set 111 <action_set
112 description="ì´ëŸ¬í•œ 권한ì—는 주민 ë™ê²° ë° ê°•í‡´ë¥¼ í¬í•¨í•˜ì—¬ 그룹 소유 구íšì— 대한 ì ‘ê·¼ì„ í—ˆìš© ë˜ëŠ” 제한하는 ê²ƒì´ í¬í•¨ë©ë‹ˆë‹¤." 112 description="ì´ëŸ¬í•œ 권한ì—는 주민 ë™ê²° ë° ê°•í‡´ë¥¼ í¬í•¨í•˜ì—¬ 그룹 소유 구íšì— 대한 ì ‘ê·¼ì„ í—ˆìš© ë˜ëŠ” 제한하는 ê²ƒì´ í¬í•¨ë©ë‹ˆë‹¤."
113 name="Parcel Access"> 113 name="Parcel Access">
114 <action description="êµ¬íš ì‚¬ìš© 권한 ëª©ë¡ ê´€ë¦¬" 114 <action description="êµ¬íš ì‚¬ìš© 권한 ëª©ë¡ ê´€ë¦¬"
115 longdescription="토지 소개 &gt; 사용 권한 íƒ­ì˜ êµ¬íš ì‚¬ìš© 권한 ëª©ë¡ ê´€ë¦¬" 115 longdescription="토지 소개 &gt; 사용 권한 íƒ­ì˜ êµ¬íš ì‚¬ìš© 권한 ëª©ë¡ ê´€ë¦¬"
116 name="land manage allowed" /> 116 name="land manage allowed" value="29" />
117 <action description="êµ¬íš ì°¨ë‹¨ ëª©ë¡ ê´€ë¦¬" 117 <action description="êµ¬íš ì°¨ë‹¨ ëª©ë¡ ê´€ë¦¬"
118 longdescription="토지 소개 &gt; 차단 íƒ­ì— ìžˆëŠ” êµ¬íš ì°¨ë‹¨ 목ë¡ì„ 관리합니다." 118 longdescription="토지 소개 &gt; 차단 íƒ­ì— ìžˆëŠ” êµ¬íš ì°¨ë‹¨ 목ë¡ì„ 관리합니다."
119 name="land manage banned" /> 119 name="land manage banned" value="30" />
120 <action description="êµ¬íš &apos;임시 통행권 íŒë§¤&apos; 설정 변경" 120 <action description="êµ¬íš &apos;임시 통행권 íŒë§¤&apos; 설정 변경"
121 longdescription="토지 소개 &gt; 사용 권한 탭ì—서 êµ¬íš &apos;임시 통행권 íŒë§¤&apos; ì„¤ì •ì„ ë³€ê²½í•©ë‹ˆë‹¤." 121 longdescription="토지 소개 &gt; 사용 권한 탭ì—서 êµ¬íš &apos;임시 통행권 íŒë§¤&apos; ì„¤ì •ì„ ë³€ê²½í•©ë‹ˆë‹¤."
122 name="land manage passes" /> 122 name="land manage passes" value="31" />
123 <action description="구íšì˜ 주민 강퇴 ë° ì •ì§€" 123 <action description="구íšì˜ 주민 강퇴 ë° ì •ì§€"
124 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 소유 구íšì—서 환ì˜í•˜ì§€ 않는 ì£¼ë¯¼ì„ ë§ˆìš°ìŠ¤ 오른쪽 í´ë¦­, ë” ë³´ê¸°&gt;, ‘추방’, ë˜ëŠ” ‘ë™ê²°â€™ì„ ì„ íƒí•˜ì—¬ 해당 ì£¼ë¯¼ì„ ì²˜ë¦¬í•  수 있습니다." 124 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 소유 구íšì—서 환ì˜í•˜ì§€ 않는 ì£¼ë¯¼ì„ ë§ˆìš°ìŠ¤ 오른쪽 í´ë¦­, ë” ë³´ê¸°&gt;, ‘추방’, ë˜ëŠ” ‘ë™ê²°â€™ì„ ì„ íƒí•˜ì—¬ 해당 ì£¼ë¯¼ì„ ì²˜ë¦¬í•  수 있습니다."
125 name="land admin" /> 125 name="land admin" value="32" />
126 </action_set> 126 </action_set>
127 <action_set 127 <action_set
128 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ 오브ì íŠ¸ì™€ 장소를 반환하고 린든 ì‹œì„¤ë“¤ì„ ì‚­ì œí•  수 있는 ê¸°ëŠ¥ì´ í¬í•¨ë©ë‹ˆë‹¤. 회ì›ì´ 쓰레기를 청소하고 조경할 때 유용하지만 반환 오브ì íŠ¸ì— ëŒ€í•´ 취소를 í•  수 없으므로 주ì˜í•´ì„œ 사용해야 합니다." 128 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ 오브ì íŠ¸ì™€ 장소를 반환하고 린든 ì‹œì„¤ë“¤ì„ ì‚­ì œí•  수 있는 ê¸°ëŠ¥ì´ í¬í•¨ë©ë‹ˆë‹¤. 회ì›ì´ 쓰레기를 청소하고 조경할 때 유용하지만 반환 오브ì íŠ¸ì— ëŒ€í•´ 취소를 í•  수 없으므로 주ì˜í•´ì„œ 사용해야 합니다."
129 name="Parcel Content"> 129 name="Parcel Content">
130 <action description="Return objects owned by group" 130 <action description="Return objects owned by group"
131 longdescription="토지 소개 &gt; 오브ì íЏ íƒ­ì— ìžˆëŠ” 그룹 ì†Œìœ ì˜ ì˜¤ë¸Œì íŠ¸ë¥¼ 그룹 소유 구íšì— 반환합니다." 131 longdescription="토지 소개 &gt; 오브ì íЏ íƒ­ì— ìžˆëŠ” 그룹 ì†Œìœ ì˜ ì˜¤ë¸Œì íŠ¸ë¥¼ 그룹 소유 구íšì— 반환합니다."
132 name="land return group owned" /> 132 name="land return group owned" value="48" />
133 <action description="ê·¸ë£¹ì— ì„¤ì •ëœ ì˜¤ë¸Œì íЏ 반환" 133 <action description="ê·¸ë£¹ì— ì„¤ì •ëœ ì˜¤ë¸Œì íЏ 반환"
134 longdescription="토지 소개 &gt; 오브ì íЏ 탭ì—서 ê·¸ë£¹ì— ì„¤ì •ëœ ì˜¤ë¸Œì íŠ¸ë¥¼ 그룹 소유 구íšì— 반환합니다." 134 longdescription="토지 소개 &gt; 오브ì íЏ 탭ì—서 ê·¸ë£¹ì— ì„¤ì •ëœ ì˜¤ë¸Œì íŠ¸ë¥¼ 그룹 소유 구íšì— 반환합니다."
135 name="land return group set" /> 135 name="land return group set" value="33" />
136 <action description="비그룹 오브ì íЏ 반환" 136 <action description="비그룹 오브ì íЏ 반환"
137 longdescription="토지 소개 &gt; 오브ì íЏ íƒ­ì— ìžˆëŠ” ë¹„ê·¸ë£¹ì˜ ì˜¤ë¸Œì íŠ¸ë¥¼ 그룹 소유 구íšì— 반환합니다." 137 longdescription="토지 소개 &gt; 오브ì íЏ íƒ­ì— ìžˆëŠ” ë¹„ê·¸ë£¹ì˜ ì˜¤ë¸Œì íŠ¸ë¥¼ 그룹 소유 구íšì— 반환합니다."
138 name="land return non group" /> 138 name="land return non group" value="34" />
139 <action description="린든 ì‹ë¬¼ì„ 사용한 ì¡°ê²½" 139 <action description="린든 ì‹ë¬¼ì„ 사용한 ì¡°ê²½"
140 longdescription="린든 나무, ì‹ë¬¼, ìž”ë””ì˜ ì¡°ê²½ 권한. ì´ëŸ¬í•œ ì•„ì´í…œì€ ì¸ë²¤í† ë¦¬ì˜ ë¼ì´ë¸ŒëŸ¬ë¦¬ &gt; 오브ì íЏ í´ë”ì— ìžˆê±°ë‚˜ ì§ì ‘ 만들 수 있습니다." 140 longdescription="린든 나무, ì‹ë¬¼, ìž”ë””ì˜ ì¡°ê²½ 권한. ì´ëŸ¬í•œ ì•„ì´í…œì€ ì¸ë²¤í† ë¦¬ì˜ ë¼ì´ë¸ŒëŸ¬ë¦¬ &gt; 오브ì íЏ í´ë”ì— ìžˆê±°ë‚˜ ì§ì ‘ 만들 수 있습니다."
141 name="land gardening" /> 141 name="land gardening" value="35" />
142 </action_set> 142 </action_set>
143 <action_set 143 <action_set
144 description="ì´ëŸ¬í•œ 권한ì—는 그룹 소유 오브ì íŠ¸ë¥¼ ì–‘ë„, 수정, íŒë§¤í•˜ëŠ” ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤. ì´ëŸ¬í•œ ë³€ê²½ì€ '편집 ë„구 &gt; ì¼ë°˜ 탭'ì—서 수행ë©ë‹ˆë‹¤. 오브ì íŠ¸ë¥¼ 마우스 오른쪽 í´ë¦­í•˜ê³  '편집'ì„ ì„ íƒí•´ ì„¤ì •ì„ ë´…ë‹ˆë‹¤." 144 description="ì´ëŸ¬í•œ 권한ì—는 그룹 소유 오브ì íŠ¸ë¥¼ ì–‘ë„, 수정, íŒë§¤í•˜ëŠ” ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤. ì´ëŸ¬í•œ ë³€ê²½ì€ '편집 ë„구 &gt; ì¼ë°˜ 탭'ì—서 수행ë©ë‹ˆë‹¤. 오브ì íŠ¸ë¥¼ 마우스 오른쪽 í´ë¦­í•˜ê³  '편집'ì„ ì„ íƒí•´ ì„¤ì •ì„ ë´…ë‹ˆë‹¤."
145 name="Object Management"> 145 name="Object Management">
146 <action description="그룹ì—게 오브ì íЏ ì–‘ë„" 146 <action description="그룹ì—게 오브ì íЏ ì–‘ë„"
147 longdescription="편집 ë„구 &gt; ì¼ë°˜ 탭ì—서 오브ì íŠ¸ë¥¼ ê·¸ë£¹ì— ì–‘ë„합니다." 147 longdescription="편집 ë„구 &gt; ì¼ë°˜ 탭ì—서 오브ì íŠ¸ë¥¼ ê·¸ë£¹ì— ì–‘ë„합니다."
148 name="object deed" /> 148 name="object deed" value="36" />
149 <action description="그룹 소유 오브ì íЏ ì¡°ìž‘(ì´ë™, 복사, 수정)" 149 <action description="그룹 소유 오브ì íЏ ì¡°ìž‘(ì´ë™, 복사, 수정)"
150 longdescription="ë„구 편집 ì¼ë°˜ íƒ­ì— ìžˆëŠ” 그룹 소유 오브ì íŠ¸ë¥¼ 조작합니다(ì´ë™, 복사, 수정)." 150 longdescription="ë„구 편집 ì¼ë°˜ íƒ­ì— ìžˆëŠ” 그룹 소유 오브ì íŠ¸ë¥¼ 조작합니다(ì´ë™, 복사, 수정)."
151 name="object manipulate" /> 151 name="object manipulate" value="38" />
152 <action description="그룹 소유 오브ì íŠ¸ë¥¼ íŒë§¤ë¡œ 설정" 152 <action description="그룹 소유 오브ì íŠ¸ë¥¼ íŒë§¤ë¡œ 설정"
153 longdescription="편집 ë„구 &gt; ì¼ë°˜ 탭ì—서 그룹 소유 오브ì íŠ¸ë¥¼ íŒë§¤ 오브ì íŠ¸ë¡œ 설정하십시오." 153 longdescription="편집 ë„구 &gt; ì¼ë°˜ 탭ì—서 그룹 소유 오브ì íŠ¸ë¥¼ íŒë§¤ 오브ì íŠ¸ë¡œ 설정하십시오."
154 name="object set sale" /> 154 name="object set sale" value="39" />
155 </action_set> 155 </action_set>
156 <action_set 156 <action_set
157 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ 그룹 부채를 지불하고 그룹 ë°°ë‹¹ê¸ˆì„ ìˆ˜ë ¹í•´ì•¼ 하며 그룹 계정 기ë¡ì— 대한 ì ‘ê·¼ì„ ì œí•œí•˜ëŠ” ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤." 157 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ 그룹 부채를 지불하고 그룹 ë°°ë‹¹ê¸ˆì„ ìˆ˜ë ¹í•´ì•¼ 하며 그룹 계정 기ë¡ì— 대한 ì ‘ê·¼ì„ ì œí•œí•˜ëŠ” ê¶Œí•œì´ í¬í•¨ë©ë‹ˆë‹¤."
158 name="Accounting"> 158 name="Accounting">
159 <action description="그룹 부채 지불과 그룹 배당금 수령" 159 <action description="그룹 부채 지불과 그룹 배당금 수령"
160 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 부채를 ìžë™ 지불하고 그룹 ë°°ë‹¹ê¸ˆì„ ìˆ˜ë ¹í•©ë‹ˆë‹¤. ì´ëŠ” 회ì›ì´ 그룹 소유 토지 íŒë§¤ì—서 ë§¤ì¼ ë¶„ë°°ë˜ëŠ” ì¼ì • ë¶€ë¶„ì„ ìˆ˜ë ¹í•˜ê³  êµ¬íš ê²Œìž¬ 비용 ë“±ì„ ê¸°ë¶€í•¨ì„ ì˜ë¯¸í•©ë‹ˆë‹¤. " 160 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 부채를 ìžë™ 지불하고 그룹 ë°°ë‹¹ê¸ˆì„ ìˆ˜ë ¹í•©ë‹ˆë‹¤. ì´ëŠ” 회ì›ì´ 그룹 소유 토지 íŒë§¤ì—서 ë§¤ì¼ ë¶„ë°°ë˜ëŠ” ì¼ì • ë¶€ë¶„ì„ ìˆ˜ë ¹í•˜ê³  êµ¬íš ê²Œìž¬ 비용 ë“±ì„ ê¸°ë¶€í•¨ì„ ì˜ë¯¸í•©ë‹ˆë‹¤. "
161 name="accounting accountable" /> 161 name="accounting accountable" value="40" />
162 </action_set> 162 </action_set>
163 <action_set 163 <action_set
164 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ 그룹 통지를 전송, 수령 ë° ë³¼ 수 있게 하는 ê²ƒì´ í¬í•¨ë©ë‹ˆë‹¤." 164 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ 그룹 통지를 전송, 수령 ë° ë³¼ 수 있게 하는 ê²ƒì´ í¬í•¨ë©ë‹ˆë‹¤."
165 name="Notices"> 165 name="Notices">
166 <action description="공지 전송" 166 <action description="공지 전송"
167 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 ì •ë³´ &gt; 공지 탭ì—서 공지를 발송할 수 있습니다." 167 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 ì •ë³´ &gt; 공지 탭ì—서 공지를 발송할 수 있습니다."
168 name="notices send" /> 168 name="notices send" value="42" />
169 <action description="공지 수령 ë° ê³¼ê±° 공지 보기" 169 <action description="공지 수령 ë° ê³¼ê±° 공지 보기"
170 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 공지를 수령하고 그룹 ì •ë³´ &gt; 공지 탭ì—서 지난 공지 ì‚¬í•­ì„ ë³¼ 수 있습니다." 170 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 공지를 수령하고 그룹 ì •ë³´ &gt; 공지 탭ì—서 지난 공지 ì‚¬í•­ì„ ë³¼ 수 있습니다."
171 name="notices receive" /> 171 name="notices receive" value="43" />
172 </action_set> 172 </action_set>
173 <action_set 173 <action_set
174 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ ì œì•ˆì„ ì„¤ì •í•˜ê³  ì œì•ˆì— íˆ¬í‘œí•˜ë©° 투표 기ë¡ì„ ë³¼ 수 있게 하는 ê²ƒì´ í¬í•¨ë©ë‹ˆë‹¤." 174 description="ì´ëŸ¬í•œ 권한ì—는 회ì›ì´ ì œì•ˆì„ ì„¤ì •í•˜ê³  ì œì•ˆì— íˆ¬í‘œí•˜ë©° 투표 기ë¡ì„ ë³¼ 수 있게 하는 ê²ƒì´ í¬í•¨ë©ë‹ˆë‹¤."
175 name="Proposals"> 175 name="Proposals">
176 <action description="제안 만들기" 176 <action description="제안 만들기"
177 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 ì •ë³´ &gt; 제안 탭ì—서 투표 가능한 ì œì•ˆì„ ë§Œë“¤ 수 있습니다." 177 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 ì •ë³´ &gt; 제안 탭ì—서 투표 가능한 ì œì•ˆì„ ë§Œë“¤ 수 있습니다."
178 name="proposal start" /> 178 name="proposal start" value="44" />
179 <action description="ì œì•ˆì— íˆ¬í‘œ" 179 <action description="ì œì•ˆì— íˆ¬í‘œ"
180 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 ì •ë³´ &gt; 제안 탭ì—서 ì œì•ˆì— ê´€í•œ 투표를 í•  수 있습니다." 180 longdescription="ì—­í• ì— ì´ ê¶Œí•œì´ ìžˆëŠ” 회ì›ì€ 그룹 ì •ë³´ &gt; 제안 탭ì—서 ì œì•ˆì— ê´€í•œ 투표를 í•  수 있습니다."
181 name="proposal vote" /> 181 name="proposal vote" value="45" />
182 </action_set> 182 </action_set>
183</role_actions> 183</role_actions>
diff --git a/linden/indra/newview/skins/xui/pt/role_actions.xml b/linden/indra/newview/skins/xui/pt/role_actions.xml
index 91ca2a4..7267e60 100644
--- a/linden/indra/newview/skins/xui/pt/role_actions.xml
+++ b/linden/indra/newview/skins/xui/pt/role_actions.xml
@@ -1,186 +1,186 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<role_actions> 2<role_actions>
3 <action_set 3 <action_set
4 description="Esta habilidades incluem poderes de adicionar ou remover membros do grupo e permitir que novos membros se juntem sem um convite." 4 description="Esta habilidades incluem poderes de adicionar ou remover membros do grupo e permitir que novos membros se juntem sem um convite."
5 name="Membership"> 5 name="Membership">
6 <action description="Convidar pessoas para este grupo" 6 <action description="Convidar pessoas para este grupo"
7 longdescription="Convide pessoas para este grupo usando o botão &apos;Convidar nova pessoa...&apos; em Membros &amp; aba Funções &gt; sub-aba Membros." 7 longdescription="Convide pessoas para este grupo usando o botão &apos;Convidar nova pessoa...&apos; em Membros &amp; aba Funções &gt; sub-aba Membros."
8 name="member invite" /> 8 name="member invite" value="1" />
9 <action description="Expulsar membros deste grupo" 9 <action description="Expulsar membros deste grupo"
10 longdescription="Expulse membros deste grupo usando o botão &apos;Expulsar do grupo&apos; em Membros &amp; aba Funções &gt; sub-aba Membros. Um proprietário pode expulsar qualquer um, exceto outro proprietário. Se você não é um proprietário, um membro pode expulsá-lo do grupo se, e somente se, ele apenas tiver a função de todos e não outras funções. Para remover membros de funções, você precisa ter a habilidade &apos;Remover membros de funções&apos;." 10 longdescription="Expulse membros deste grupo usando o botão &apos;Expulsar do grupo&apos; em Membros &amp; aba Funções &gt; sub-aba Membros. Um proprietário pode expulsar qualquer um, exceto outro proprietário. Se você não é um proprietário, um membro pode expulsá-lo do grupo se, e somente se, ele apenas tiver a função de todos e não outras funções. Para remover membros de funções, você precisa ter a habilidade &apos;Remover membros de funções&apos;."
11 name="member eject" /> 11 name="member eject" value="2" />
12 <action 12 <action
13 description="Ativar/desativar &apos;Abrir registro&apos; e mudar &apos;Taxa de assinatura&apos;" 13 description="Ativar/desativar &apos;Abrir registro&apos; e mudar &apos;Taxa de assinatura&apos;"
14 longdescription="Ative/desative &apos;Abrir registro&apos; para permitir que novos membros se unam sem um convite, e mude a &apos;Taxa de registro&apos; na seção Preferência de grupo da aba Geral." 14 longdescription="Ative/desative &apos;Abrir registro&apos; para permitir que novos membros se unam sem um convite, e mude a &apos;Taxa de registro&apos; na seção Preferência de grupo da aba Geral."
15 name="member options" /> 15 name="member options" value="3" />
16 </action_set> 16 </action_set>
17 <action_set 17 <action_set
18 description="Estas habilidades incluem poderes de adicionar, remover e mudar funções do grupo; adicionar e remover membros em funções e designar habilidades a funções." 18 description="Estas habilidades incluem poderes de adicionar, remover e mudar funções do grupo; adicionar e remover membros em funções e designar habilidades a funções."
19 name="Roles"> 19 name="Roles">
20 <action description="Criar novas funções" 20 <action description="Criar novas funções"
21 longdescription="Crie novas funções em Membros &amp; aba Funções &gt; sub-aba Funções." 21 longdescription="Crie novas funções em Membros &amp; aba Funções &gt; sub-aba Funções."
22 name="role create" /> 22 name="role create" value="4" />
23 <action description="Apagar funções" 23 <action description="Apagar funções"
24 longdescription="Apague funções em Membros &amp; aba Funções &gt; sub-aba Funções." 24 longdescription="Apague funções em Membros &amp; aba Funções &gt; sub-aba Funções."
25 name="role delete" /> 25 name="role delete" value="5" />
26 <action description="Mudar nomes de função, títulos e descrições" 26 <action description="Mudar nomes de função, títulos e descrições"
27 longdescription="Mude o nome de funções, títulos e descrições na parte inferior de Membros &amp; aba Funções &gt; sub-aba Funções após selecionar uma função." 27 longdescription="Mude o nome de funções, títulos e descrições na parte inferior de Membros &amp; aba Funções &gt; sub-aba Funções após selecionar uma função."
28 name="role properties" /> 28 name="role properties" value="6" />
29 <action description="Designar membros para a função do designador" 29 <action description="Designar membros para a função do designador"
30 longdescription="Designe membros a funções na seção de funções designadas de Membros &amp; aba Funções &gt; sub-aba Membros. Um membro com este poder pode somente adicionar membros para a função que o designador já possui." 30 longdescription="Designe membros a funções na seção de funções designadas de Membros &amp; aba Funções &gt; sub-aba Membros. Um membro com este poder pode somente adicionar membros para a função que o designador já possui."
31 name="role assign member limited" /> 31 name="role assign member limited" value="7" />
32 <action description="Designar membros para qualquer função" 32 <action description="Designar membros para qualquer função"
33 longdescription="Designe membros a qualquer função na seção de funções designadas de Membros &amp; aba Funções &gt; sub-aba Membros. *AVISO* Quaisquer membros em uma função com esta habilidade podem designar a si próprios--e quaisquer outros membros não proprietários--para funções que têm mais poderes do que as atuais, elevando-os a poderes próximos ao do proprietário. Certifique-se de saber o que está fazendo antes de designar esta habilidade." 33 longdescription="Designe membros a qualquer função na seção de funções designadas de Membros &amp; aba Funções &gt; sub-aba Membros. *AVISO* Quaisquer membros em uma função com esta habilidade podem designar a si próprios--e quaisquer outros membros não proprietários--para funções que têm mais poderes do que as atuais, elevando-os a poderes próximos ao do proprietário. Certifique-se de saber o que está fazendo antes de designar esta habilidade."
34 name="role assign member" /> 34 name="role assign member" value="8" />
35 <action description="Remover membros das funções" 35 <action description="Remover membros das funções"
36 longdescription="Remova membros de funções na seção de funções designadas de Membros &amp; aba Funções &gt; sub-aba Membros. Proprietários não podem ser removidos." 36 longdescription="Remova membros de funções na seção de funções designadas de Membros &amp; aba Funções &gt; sub-aba Membros. Proprietários não podem ser removidos."
37 name="role remove member" /> 37 name="role remove member" value="9" />
38 <action description="Determinar e remover habilidades em funções" 38 <action description="Determinar e remover habilidades em funções"
39 longdescription="Designe e remova habilidades em funções na seção habilidades pertmitidas de Membros &amp; aba Funções &gt; sub-aba Funções. *AVISO* Quaisquer membros em uma função com esta habilidade podem desginar a si próprios--e quaisquer outros membros não proprietários--todas as habilidades, elevando-os a poderes próximos ao do proprietário. Certifique-se de saber o que está fazendo antes de designar esta habilidade." 39 longdescription="Designe e remova habilidades em funções na seção habilidades pertmitidas de Membros &amp; aba Funções &gt; sub-aba Funções. *AVISO* Quaisquer membros em uma função com esta habilidade podem desginar a si próprios--e quaisquer outros membros não proprietários--todas as habilidades, elevando-os a poderes próximos ao do proprietário. Certifique-se de saber o que está fazendo antes de designar esta habilidade."
40 name="role change actions" /> 40 name="role change actions" value="10" />
41 </action_set> 41 </action_set>
42 <action_set 42 <action_set
43 description="Estas habilidade incluem poderes para modificar esta identidade de grupo, como mudar a visibilidade pública, apresentação e insígnia." 43 description="Estas habilidade incluem poderes para modificar esta identidade de grupo, como mudar a visibilidade pública, apresentação e insígnia."
44 name="Group Identity"> 44 name="Group Identity">
45 <action 45 <action
46 description="Mudar apresentação, insígnia, &apos;Publicar na web&apos;, e quais membros estão publicamente visíveis em Informações do Grupo." 46 description="Mudar apresentação, insígnia, &apos;Publicar na web&apos;, e quais membros estão publicamente visíveis em Informações do Grupo."
47 longdescription="Mude a apresentação, insígnia, &apos;Publicar na web&apos; e quais membros estão publicamente visíveis em Informações do grupo. É feito na aba Geral." 47 longdescription="Mude a apresentação, insígnia, &apos;Publicar na web&apos; e quais membros estão publicamente visíveis em Informações do grupo. É feito na aba Geral."
48 name="group change identity" /> 48 name="group change identity" value="11" />
49 </action_set> 49 </action_set>
50 <action_set 50 <action_set
51 description="Estas habilidades incluem poderes para transferir, modificar e vender terrenos do grupo. Vá pra a janela Sobre o terreno, clique com o botão direito no terreno e selecione &apos;Sobre o terreno...&apos; ou clique na informação da parcela na barra do menu." 51 description="Estas habilidades incluem poderes para transferir, modificar e vender terrenos do grupo. Vá pra a janela Sobre o terreno, clique com o botão direito no terreno e selecione &apos;Sobre o terreno...&apos; ou clique na informação da parcela na barra do menu."
52 name="Parcel Management"> 52 name="Parcel Management">
53 <action description="Transferir e comprar terreno para o grupo" 53 <action description="Transferir e comprar terreno para o grupo"
54 longdescription="Transfere e compre terreno para o grupo. É feito em Sobre o terreno &gt; aba Geral." 54 longdescription="Transfere e compre terreno para o grupo. É feito em Sobre o terreno &gt; aba Geral."
55 name="land deed" /> 55 name="land deed" value="12" />
56 <action description="Abandonar terreno para Governador Linden" 56 <action description="Abandonar terreno para Governador Linden"
57 longdescription="Abandone terreno para Governador Linden. *AVISO* Qualquer membro em uma função com esta habilidade pode abandonar o terreno pertencente ao grupo em Sobre o terreno &gt; aba Geral, revertendo à posse Linden sem uma venda! Certifique-se de saber o que está fazendo antes de designar esta habilidade." 57 longdescription="Abandone terreno para Governador Linden. *AVISO* Qualquer membro em uma função com esta habilidade pode abandonar o terreno pertencente ao grupo em Sobre o terreno &gt; aba Geral, revertendo à posse Linden sem uma venda! Certifique-se de saber o que está fazendo antes de designar esta habilidade."
58 name="land release" /> 58 name="land release" value="13" />
59 <action description="Definir terreno para informação de venda" 59 <action description="Definir terreno para informação de venda"
60 longdescription="Defina informações de venda para terreno. *AVISO* Qualquer membro em uma função com esta habilidade pode vender terrenos pertencentes ao grupo em Sobre o terreno &gt; aba Geral como quiser! Certifique-se de sabe o que está fazendo antes de designar esta habilidade." 60 longdescription="Defina informações de venda para terreno. *AVISO* Qualquer membro em uma função com esta habilidade pode vender terrenos pertencentes ao grupo em Sobre o terreno &gt; aba Geral como quiser! Certifique-se de sabe o que está fazendo antes de designar esta habilidade."
61 name="land set sale info" /> 61 name="land set sale info" value="14" />
62 <action description="Subdividir e unir parcelas" 62 <action description="Subdividir e unir parcelas"
63 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. " 63 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. "
64 name="land divide join" /> 64 name="land divide join" value="15" />
65 </action_set> 65 </action_set>
66 <action_set 66 <action_set
67 description="Estas habilidades incluem poderes para mudar o nome da parcelas e configurações de publicação, visibilidade da busca de diretório e ponto de aterrissagem &amp; opções de rota de TP." 67 description="Estas habilidades incluem poderes para mudar o nome da parcelas e configurações de publicação, visibilidade da busca de diretório e ponto de aterrissagem &amp; opções de rota de TP."
68 name="Parcel Identity"> 68 name="Parcel Identity">
69 <action 69 <action
70 description="Ativar/desativar &apos;Exibir em locais de encontro&apos; e definir categoria" 70 description="Ativar/desativar &apos;Exibir em locais de encontro&apos; e definir categoria"
71 longdescription="Ativar/desativar &apos;Exibir em locais de encontro&apos; e configurar uma categoria de parcela em Sobre o terreno &gt; aba Opções." 71 longdescription="Ativar/desativar &apos;Exibir em locais de encontro&apos; e configurar uma categoria de parcela em Sobre o terreno &gt; aba Opções."
72 name="land find places" /> 72 name="land find places" value="17" />
73 <action 73 <action
74 description="Mudar nome da parcela, descrição, e configurações &apos;Publicar na web&apos;" 74 description="Mudar nome da parcela, descrição, e configurações &apos;Publicar na web&apos;"
75 longdescription="Mude o nome da parcela, descrição e configurações de &apos;Publicar na web&apos;. É feito em Sobre o terreno &gt; aba Opções." 75 longdescription="Mude o nome da parcela, descrição e configurações de &apos;Publicar na web&apos;. É feito em Sobre o terreno &gt; aba Opções."
76 name="land change identity" /> 76 name="land change identity" value="18" />
77 <action description="Definir ponto de aterrissagem e rota de teletransporte" 77 <action description="Definir ponto de aterrissagem e rota de teletransporte"
78 longdescription="Em uma parcela pertencente ao grupo, membros em uma função com esta habilidade podem definir um ponto de aterrissagem para especificar onde os teletransportes chegam e também definir a rota do teletransporte para um maior controle. É feito em Sobre o terreno &gt; aba Opções." 78 longdescription="Em uma parcela pertencente ao grupo, membros em uma função com esta habilidade podem definir um ponto de aterrissagem para especificar onde os teletransportes chegam e também definir a rota do teletransporte para um maior controle. É feito em Sobre o terreno &gt; aba Opções."
79 name="land set landing point" /> 79 name="land set landing point" value="19" />
80 </action_set> 80 </action_set>
81 <action_set 81 <action_set
82 description="Estas habilidade incluem poderes que afetam opções de parcela, como &apos;Criar objetos&apos;, &apos;Editar terreno&apos; e música &amp; configurações de mídia." 82 description="Estas habilidade incluem poderes que afetam opções de parcela, como &apos;Criar objetos&apos;, &apos;Editar terreno&apos; e música &amp; configurações de mídia."
83 name="Parcel Settings"> 83 name="Parcel Settings">
84 <action description="Mudar música &amp; configurações de mídia" 84 <action description="Mudar música &amp; configurações de mídia"
85 longdescription="Mude streaming de música e configurações de vídeo em Sobre o terreno &gt; aba Mídia." 85 longdescription="Mude streaming de música e configurações de vídeo em Sobre o terreno &gt; aba Mídia."
86 name="land change media" /> 86 name="land change media" value="20" />
87 <action description="Ativar/desativar &apos;Editar terreno&apos;" 87 <action description="Ativar/desativar &apos;Editar terreno&apos;"
88 longdescription="Ative/desative &apos;Editar terreno&apos;. *AVISO* Sobre o terreno &gt; aba Opções &gt; Editar terreno permite a qualquer um alterar as formas de seu terreno, substituir e mover plantas Linden. Certifique-se de saber o que está fazendo antes de desginar esta habilidade. A edição de terreno é ativada/desativada em Sobre o terreno &gt; aba Opções." 88 longdescription="Ative/desative &apos;Editar terreno&apos;. *AVISO* Sobre o terreno &gt; aba Opções &gt; Editar terreno permite a qualquer um alterar as formas de seu terreno, substituir e mover plantas Linden. Certifique-se de saber o que está fazendo antes de desginar esta habilidade. A edição de terreno é ativada/desativada em Sobre o terreno &gt; aba Opções."
89 name="land edit" /> 89 name="land edit" value="21" />
90 <action 90 <action
91 description="Ativar/desativar variados Sobre o Terreno &gt; Opções de configuração" 91 description="Ativar/desativar variados Sobre o Terreno &gt; Opções de configuração"
92 longdescription="Ative/desative &apos;Seguro (sem dano)&apos;, &apos;Voar&apos;, e permita a outros residentes: &apos;Criar objetos&apos;, &apos;Editar terreno&apos;, &apos;Criar pontos de referência&apos;, e &apos;Executar scripts&apos; em um terreno pertencente ao grupo em Sobre o terreno &gt; aba Opções." 92 longdescription="Ative/desative &apos;Seguro (sem dano)&apos;, &apos;Voar&apos;, e permita a outros residentes: &apos;Criar objetos&apos;, &apos;Editar terreno&apos;, &apos;Criar pontos de referência&apos;, e &apos;Executar scripts&apos; em um terreno pertencente ao grupo em Sobre o terreno &gt; aba Opções."
93 name="land options" /> 93 name="land options" value="22" />
94 </action_set> 94 </action_set>
95 <action_set 95 <action_set
96 description="Estas habilidades incluem poderes que permitem a membros ultrapassar restrições em parcelas pertencentes ao grupo." 96 description="Estas habilidades incluem poderes que permitem a membros ultrapassar restrições em parcelas pertencentes ao grupo."
97 name="Parcel Powers"> 97 name="Parcel Powers">
98 <action description="Sempre permitir &apos;Editar terreno&apos;" 98 <action description="Sempre permitir &apos;Editar terreno&apos;"
99 longdescription="Membros em uma função com esta habilidade podem editar terreno em uma parcela pertencente ao grupo, mesmo se estiver desativada em Sobre o terreno &gt; aba Opções." 99 longdescription="Membros em uma função com esta habilidade podem editar terreno em uma parcela pertencente ao grupo, mesmo se estiver desativada em Sobre o terreno &gt; aba Opções."
100 name="land allow edit land" /> 100 name="land allow edit land" value="23" />
101 <action description="Sempre permitir &apos;Voar&apos;" 101 <action description="Sempre permitir &apos;Voar&apos;"
102 longdescription="Membros em uma função com esta habilidade podem voar sobre uma parcela pertencente ao grupo, mesmo se estiver desativada em Sobre o terreno &gt; aba Opções." 102 longdescription="Membros em uma função com esta habilidade podem voar sobre uma parcela pertencente ao grupo, mesmo se estiver desativada em Sobre o terreno &gt; aba Opções."
103 name="land allow fly" /> 103 name="land allow fly" value="24" />
104 <action description="Sempre permitir &apos;Criar objetos&apos;" 104 <action description="Sempre permitir &apos;Criar objetos&apos;"
105 longdescription="Membros em uma função com esta habilidade podem criar objetos em uma parcela pertencente ao grupo, mesmo se estiver desativada em Sobre o terreno &gt; aba Opções." 105 longdescription="Membros em uma função com esta habilidade podem criar objetos em uma parcela pertencente ao grupo, mesmo se estiver desativada em Sobre o terreno &gt; aba Opções."
106 name="land allow create" /> 106 name="land allow create" value="25" />
107 <action description="Sempre permitir &apos;Criar ponto de referência&apos;" 107 <action description="Sempre permitir &apos;Criar ponto de referência&apos;"
108 longdescription="Membros em uma função com esta habilidade podem colocar um ponto de referência uma parcela pertencente ao grupo, mesmo se estiver desativada em Sobre o terreno &gt; aba Opções." 108 longdescription="Membros em uma função com esta habilidade podem colocar um ponto de referência uma parcela pertencente ao grupo, mesmo se estiver desativada em Sobre o terreno &gt; aba Opções."
109 name="land allow landmark" /> 109 name="land allow landmark" value="26" />
110 <action description="Permitir &apos;Colocar casa aqui&apos; no terreno do grupo" 110 <action description="Permitir &apos;Colocar casa aqui&apos; no terreno do grupo"
111 longdescription="Membros em uma função com esta habilidade podem usar o menu Mundo &gt; Definir lar aqui em uma parcela do grupo (definir terreno ou transferir para este grupo)." 111 longdescription="Membros em uma função com esta habilidade podem usar o menu Mundo &gt; Definir lar aqui em uma parcela do grupo (definir terreno ou transferir para este grupo)."
112 name="land allow set home" /> 112 name="land allow set home" value="28" />
113 </action_set> 113 </action_set>
114 <action_set 114 <action_set
115 description="Estas habilidades incluem poderes de permitir ou restringir acesso a parcelas pertencentes ao grupo, incluindo congelar e expulsar residentes." 115 description="Estas habilidades incluem poderes de permitir ou restringir acesso a parcelas pertencentes ao grupo, incluindo congelar e expulsar residentes."
116 name="Parcel Access"> 116 name="Parcel Access">
117 <action description="Gerenciar listas de acesso à parcela" 117 <action description="Gerenciar listas de acesso à parcela"
118 longdescription="Gerencie a lista de acesso à parcela em Sobre o terreno &gt; aba Acesso." 118 longdescription="Gerencie a lista de acesso à parcela em Sobre o terreno &gt; aba Acesso."
119 name="land manage allowed" /> 119 name="land manage allowed" value="29" />
120 <action description="Gerenciar lista de banidos da parcela" 120 <action description="Gerenciar lista de banidos da parcela"
121 longdescription="Gerencie a lista de banidos da parcela em Sobre o terreno &gt; aba Banido." 121 longdescription="Gerencie a lista de banidos da parcela em Sobre o terreno &gt; aba Banido."
122 name="land manage banned" /> 122 name="land manage banned" value="30" />
123 <action description="Mudar configurações de parcela &apos;Vender passes...&apos;" 123 <action description="Mudar configurações de parcela &apos;Vender passes...&apos;"
124 longdescription="Mude configurações de &apos;Vender passes...&apos; em Sobre o terreno &gt; aba Acesso." 124 longdescription="Mude configurações de &apos;Vender passes...&apos; em Sobre o terreno &gt; aba Acesso."
125 name="land manage passes" /> 125 name="land manage passes" value="31" />
126 <action description="Expulsar e congelar residentes nas parcelas" 126 <action description="Expulsar e congelar residentes nas parcelas"
127 longdescription="Membros em uma função com esta habilidade podem lidar com um residente indesejado em uma parcela pertencente ao grupo clicando com o botão direitos sobre ele, Mais &gt; e selecionado &apos;Expulsar...&apos; ou &apos;Congelar...&apos;." 127 longdescription="Membros em uma função com esta habilidade podem lidar com um residente indesejado em uma parcela pertencente ao grupo clicando com o botão direitos sobre ele, Mais &gt; e selecionado &apos;Expulsar...&apos; ou &apos;Congelar...&apos;."
128 name="land admin" /> 128 name="land admin" value="32" />
129 </action_set> 129 </action_set>
130 <action_set 130 <action_set
131 description="Estas habilidades incluem poderes de permitir a membros retornar objetos e colocar e mover plantas Linden. Útil para que membros organizem a paisagem, porém deve ser usado com cuidado, devido a não ser possível desfazer a mudança dos objetos." 131 description="Estas habilidades incluem poderes de permitir a membros retornar objetos e colocar e mover plantas Linden. Útil para que membros organizem a paisagem, porém deve ser usado com cuidado, devido a não ser possível desfazer a mudança dos objetos."
132 name="Parcel Content"> 132 name="Parcel Content">
133 <action description="Retornar objetos que pertencem ao grupo" 133 <action description="Retornar objetos que pertencem ao grupo"
134 longdescription="Retorne objetos em parcelas pertencentes ao grupo que pertencem ao grupo em Sobre o terreno &gt; aba Objetos." 134 longdescription="Retorne objetos em parcelas pertencentes ao grupo que pertencem ao grupo em Sobre o terreno &gt; aba Objetos."
135 name="land return group owned" /> 135 name="land return group owned" value="48" />
136 <action description="Retornar objetos definidos para o grupo" 136 <action description="Retornar objetos definidos para o grupo"
137 longdescription="Retorne objetos em parcelas pertencentes ao grupo que em Sobre o terrreno &gt; aba Objetos." 137 longdescription="Retorne objetos em parcelas pertencentes ao grupo que em Sobre o terrreno &gt; aba Objetos."
138 name="land return group set" /> 138 name="land return group set" value="33" />
139 <action description="Retornar objetos que não pertencem ao grupo" 139 <action description="Retornar objetos que não pertencem ao grupo"
140 longdescription="Retorne objetos nas parcelas pertencentes a um grupo que estão sem grupo em em Sobre o terreno &gt; aba Objetos." 140 longdescription="Retorne objetos nas parcelas pertencentes a um grupo que estão sem grupo em em Sobre o terreno &gt; aba Objetos."
141 name="land return non group" /> 141 name="land return non group" value="34" />
142 <action description="Ajardinar usando plantas Linden" 142 <action description="Ajardinar usando plantas Linden"
143 longdescription="A habilidade de ajardinar permite colocar e mover árvores Linden, plantas e gramas. Estes itens podem ser encontrando na Biblioteca de seu inventário &gt; pasta Objetos ou podem ser criados através do botão Construir." 143 longdescription="A habilidade de ajardinar permite colocar e mover árvores Linden, plantas e gramas. Estes itens podem ser encontrando na Biblioteca de seu inventário &gt; pasta Objetos ou podem ser criados através do botão Construir."
144 name="land gardening" /> 144 name="land gardening" value="35" />
145 </action_set> 145 </action_set>
146 <action_set 146 <action_set
147 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. " 147 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. "
148 name="Object Management"> 148 name="Object Management">
149 <action description="Transferir objetos para o grupo" 149 <action description="Transferir objetos para o grupo"
150 longdescription="Transfere objetos para o grupo em Editar ferramentas &gt; aba Geral." 150 longdescription="Transfere objetos para o grupo em Editar ferramentas &gt; aba Geral."
151 name="object deed" /> 151 name="object deed" value="36" />
152 <action description="Manipular (mover, copiar, modificar) objetos do grupo" 152 <action description="Manipular (mover, copiar, modificar) objetos do grupo"
153 longdescription="Manipule (mover,copiar, modificar) objetos pertencentes ao grupo em Editar Ferramentas &gt; aba Geral." 153 longdescription="Manipule (mover,copiar, modificar) objetos pertencentes ao grupo em Editar Ferramentas &gt; aba Geral."
154 name="object manipulate" /> 154 name="object manipulate" value="38" />
155 <action description="Definir objetos pertencentes ao grupo para venda" 155 <action description="Definir objetos pertencentes ao grupo para venda"
156 longdescription="Defina objetos pertencentes ao grupo para venda em Editar Ferramentas &gt; aba Geral." 156 longdescription="Defina objetos pertencentes ao grupo para venda em Editar Ferramentas &gt; aba Geral."
157 name="object set sale" /> 157 name="object set sale" value="39" />
158 </action_set> 158 </action_set>
159 <action_set 159 <action_set
160 description="Estas habilidades incluem poderes que requerem que membros paguem dívidas e recebam dividendos do grupo, e restringem acesso ao histórico de conta do grupo." 160 description="Estas habilidades incluem poderes que requerem que membros paguem dívidas e recebam dividendos do grupo, e restringem acesso ao histórico de conta do grupo."
161 name="Accounting"> 161 name="Accounting">
162 <action description="Pagar débitos e receber dividendos do grupo" 162 <action description="Pagar débitos e receber dividendos do grupo"
163 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. " 163 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. "
164 name="accounting accountable" /> 164 name="accounting accountable" value="40" />
165 </action_set> 165 </action_set>
166 <action_set 166 <action_set
167 description="Estas habilidade incluem poderes de permitir enviar, receber e ver avisos de grupo." 167 description="Estas habilidade incluem poderes de permitir enviar, receber e ver avisos de grupo."
168 name="Notices"> 168 name="Notices">
169 <action description="Enviar aviso" 169 <action description="Enviar aviso"
170 longdescription="Membros em uma função com esta habiliade podem enviar avisos em Informações de grupo &gt; aba Avisos." 170 longdescription="Membros em uma função com esta habiliade podem enviar avisos em Informações de grupo &gt; aba Avisos."
171 name="notices send" /> 171 name="notices send" value="42" />
172 <action description="Receber novos avisos e ver os anteriores" 172 <action description="Receber novos avisos e ver os anteriores"
173 longdescription="Membros em uma função com esta habilidade podem receber os novos avisos e ver os anteriores em Informações de grupo &gt; aba Avisos." 173 longdescription="Membros em uma função com esta habilidade podem receber os novos avisos e ver os anteriores em Informações de grupo &gt; aba Avisos."
174 name="notices receive" /> 174 name="notices receive" value="43" />
175 </action_set> 175 </action_set>
176 <action_set 176 <action_set
177 description="Estas habilidades incluem poderes de permitir a membros definir e votar em propostas e ver histórico de votação." 177 description="Estas habilidades incluem poderes de permitir a membros definir e votar em propostas e ver histórico de votação."
178 name="Proposals"> 178 name="Proposals">
179 <action description="Criar proposta" 179 <action description="Criar proposta"
180 longdescription="Membros em uma função com esta habilidade podem criar proposta para serem votadas em Informações de grupo &gt; aba Propostas." 180 longdescription="Membros em uma função com esta habilidade podem criar proposta para serem votadas em Informações de grupo &gt; aba Propostas."
181 name="proposal start" /> 181 name="proposal start" value="44" />
182 <action description="Votar em propostas" 182 <action description="Votar em propostas"
183 longdescription="Membros em uma função com esta habilidade podem votar em propostas em Informações de grupo &gt; aba Propostas." 183 longdescription="Membros em uma função com esta habilidade podem votar em propostas em Informações de grupo &gt; aba Propostas."
184 name="proposal vote" /> 184 name="proposal vote" value="45" />
185 </action_set> 185 </action_set>
186</role_actions> 186</role_actions>
diff --git a/linden/indra/newview/skins/xui/zh/role_actions.xml b/linden/indra/newview/skins/xui/zh/role_actions.xml
index ec59576..9f6f957 100644
--- a/linden/indra/newview/skins/xui/zh/role_actions.xml
+++ b/linden/indra/newview/skins/xui/zh/role_actions.xml
@@ -1,183 +1,183 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<role_actions> 2<role_actions>
3 <action_set 3 <action_set
4 description="这些能力包括添加或移除社团æˆå‘˜çš„æƒåˆ©ï¼Œå¹¶ä¸”æœ‰æƒåˆ©æŽ¥çº³æ²¡æœ‰é‚€è¯·å‡½çš„æˆå‘˜" 4 description="这些能力包括添加或移除社团æˆå‘˜çš„æƒåˆ©ï¼Œå¹¶ä¸”æœ‰æƒåˆ©æŽ¥çº³æ²¡æœ‰é‚€è¯·å‡½çš„æˆå‘˜"
5 name="Membership"> 5 name="Membership">
6 <action description="邀请朋å‹åŠ å…¥ç¤¾å›¢" 6 <action description="邀请朋å‹åŠ å…¥ç¤¾å›¢"
7 longdescription="Invite People to this Group using the &apos;Invite New Person...&apos; button in the Members &amp; Roles tab &gt; Members sub-tab." 7 longdescription="Invite People to this Group using the &apos;Invite New Person...&apos; button in the Members &amp; Roles tab &gt; Members sub-tab."
8 name="member invite" /> 8 name="member invite" value="1" />
9 <action description="从社团驱é€ä¼šå‘˜" 9 <action description="从社团驱é€ä¼šå‘˜"
10 longdescription="Eject Members from this Group using the &apos;Eject From Group&apos; button in the Members &amp; Roles tab &gt; Members sub-tab. An Owner can eject anyone except another Owner. If you&apos;re not an Owner, a Member can be ejected from a group if, and only if, they&apos;re only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the &apos;Remove Members from Roles&apos; Ability." 10 longdescription="Eject Members from this Group using the &apos;Eject From Group&apos; button in the Members &amp; Roles tab &gt; Members sub-tab. An Owner can eject anyone except another Owner. If you&apos;re not an Owner, a Member can be ejected from a group if, and only if, they&apos;re only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the &apos;Remove Members from Roles&apos; Ability."
11 name="member eject" /> 11 name="member eject" value="2" />
12 <action description="绑定 &apos;打开登记&apos;并更改&apos;登记费用&apos;" 12 <action description="绑定 &apos;打开登记&apos;并更改&apos;登记费用&apos;"
13 longdescription="Toggle &apos;Open Enrollment&apos; to let new Members join without an invitation, and change &apos;Signup Fee&apos; in the Group Preferences section of the General tab." 13 longdescription="Toggle &apos;Open Enrollment&apos; to let new Members join without an invitation, and change &apos;Signup Fee&apos; in the Group Preferences section of the General tab."
14 name="member options" /> 14 name="member options" value="3" />
15 </action_set> 15 </action_set>
16 <action_set 16 <action_set
17 description="这些能力包括添加,移除或改å˜ç¤¾å›¢è§’色的æƒåˆ©ï¼Œä»Žè§’色中添加或移除组员的æƒåˆ©ï¼Œä»¥åŠä¸ºè§’色分é…能力的æƒåˆ©" 17 description="这些能力包括添加,移除或改å˜ç¤¾å›¢è§’色的æƒåˆ©ï¼Œä»Žè§’色中添加或移除组员的æƒåˆ©ï¼Œä»¥åŠä¸ºè§’色分é…能力的æƒåˆ©"
18 name="Roles"> 18 name="Roles">
19 <action description="创建新角色" 19 <action description="创建新角色"
20 longdescription="Create new Roles in the Members &amp; Roles tab &gt; Roles sub-tab." 20 longdescription="Create new Roles in the Members &amp; Roles tab &gt; Roles sub-tab."
21 name="role create" /> 21 name="role create" value="4" />
22 <action description="删除角色" 22 <action description="删除角色"
23 longdescription="Delete Roles in the Members &amp; Roles tab &gt; Roles sub-tab." 23 longdescription="Delete Roles in the Members &amp; Roles tab &gt; Roles sub-tab."
24 name="role delete" /> 24 name="role delete" value="5" />
25 <action description="改å˜è§’色的åå­—, 头衔和其他æè¿°" 25 <action description="改å˜è§’色的åå­—, 头衔和其他æè¿°"
26 longdescription="Change Role names, titles, and descriptions at the bottom of the the Members &amp; Roles tab &gt; Roles sub-tab after selecting a Role." 26 longdescription="Change Role names, titles, and descriptions at the bottom of the the Members &amp; Roles tab &gt; Roles sub-tab after selecting a Role."
27 name="role properties" /> 27 name="role properties" value="6" />
28 <action description="给会员分é…分é…者的角色" 28 <action description="给会员分é…分é…者的角色"
29 longdescription="Assign Members to Roles in the Assigned Roles section of the Members &amp; Roles tab &gt; Members sub-tab. A member with this power can only add members to a role the assigner is already in." 29 longdescription="Assign Members to Roles in the Assigned Roles section of the Members &amp; Roles tab &gt; Members sub-tab. A member with this power can only add members to a role the assigner is already in."
30 name="role assign member limited" /> 30 name="role assign member limited" value="7" />
31 <action description="给会员分é…任何角色" 31 <action description="给会员分é…任何角色"
32 longdescription="Assign Members to Any Role in the Assigned Roles section of the Members &amp; Roles tab &gt; Members sub-tab. *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability." 32 longdescription="Assign Members to Any Role in the Assigned Roles section of the Members &amp; Roles tab &gt; Members sub-tab. *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability."
33 name="role assign member" /> 33 name="role assign member" value="8" />
34 <action description="ç¦æ­¢ä¼šå‘˜ç»§ç»­æ‰®æ¼”该项角色" 34 <action description="ç¦æ­¢ä¼šå‘˜ç»§ç»­æ‰®æ¼”该项角色"
35 longdescription="Remove Members from Roles in the Assigned Roles section of the Members &amp; Roles tab &gt; Members sub-tab. Owners can&apos;t be removed." 35 longdescription="Remove Members from Roles in the Assigned Roles section of the Members &amp; Roles tab &gt; Members sub-tab. Owners can&apos;t be removed."
36 name="role remove member" /> 36 name="role remove member" value="9" />
37 <action description="åˆ†é…æˆ–移除角色的能力" 37 <action description="åˆ†é…æˆ–移除角色的能力"
38 longdescription="Assign and Remove Abilities in Roles in the Allowed Abilities section of the Members &amp; Roles tab &gt; Roles sub-tab. *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability." 38 longdescription="Assign and Remove Abilities in Roles in the Allowed Abilities section of the Members &amp; Roles tab &gt; Roles sub-tab. *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability."
39 name="role change actions" /> 39 name="role change actions" value="10" />
40 </action_set> 40 </action_set>
41 <action_set 41 <action_set
42 description="这些能力包括修改社团身份的æƒåˆ©ï¼Œä¾‹å¦‚更改公众å¯è§åº¦ï¼Œå®ªç« å’Œå¾½ç« " 42 description="这些能力包括修改社团身份的æƒåˆ©ï¼Œä¾‹å¦‚更改公众å¯è§åº¦ï¼Œå®ªç« å’Œå¾½ç« "
43 name="Group Identity"> 43 name="Group Identity">
44 <action 44 <action
45 description="改å˜å®ªç« ,徽章, &apos;在网络上å‘布&apos;,公开会员在社团中的信æ¯" 45 description="改å˜å®ªç« ,徽章, &apos;在网络上å‘布&apos;,公开会员在社团中的信æ¯"
46 longdescription="Change Charter, Insignia, &apos;Publish on the Web&apos;, and which members are publicly visible in Group Information. This is done in the General tab." 46 longdescription="Change Charter, Insignia, &apos;Publish on the Web&apos;, and which members are publicly visible in Group Information. This is done in the General tab."
47 name="group change identity" /> 47 name="group change identity" value="11" />
48 </action_set> 48 </action_set>
49 <action_set 49 <action_set
50 description="这些能力包括转让,修改,并出售社团所拥有的部分土地的æƒåˆ©ã€‚转到“关于土地“窗å£ï¼Œç‚¹å‡»å³é”®å¹¶é€‰æ‹©â€œå…³äºŽåœŸåœ°...“,或者点击在èœå•æ¡ä¸Šçš„土地信æ¯ã€‚" 50 description="这些能力包括转让,修改,并出售社团所拥有的部分土地的æƒåˆ©ã€‚转到“关于土地“窗å£ï¼Œç‚¹å‡»å³é”®å¹¶é€‰æ‹©â€œå…³äºŽåœŸåœ°...“,或者点击在èœå•æ¡ä¸Šçš„土地信æ¯ã€‚"
51 name="Parcel Management"> 51 name="Parcel Management">
52 <action description="转让土地或购买土地给社团" 52 <action description="转让土地或购买土地给社团"
53 longdescription="Deed land and buy land for group. This is done in About Land &gt; General tab." 53 longdescription="Deed land and buy land for group. This is done in About Land &gt; General tab."
54 name="land deed" /> 54 name="land deed" value="12" />
55 <action description="把土地放弃还给林登长官" 55 <action description="把土地放弃还给林登长官"
56 longdescription="Abandon land to Governor Linden. *WARNING* Any Member in a Role with this Ability can abandon group-owned land in About Land &gt; General tab, reverting it to Linden ownership without a sale! Be sure you know what you&apos;re doing before assigning this Ability." 56 longdescription="Abandon land to Governor Linden. *WARNING* Any Member in a Role with this Ability can abandon group-owned land in About Land &gt; General tab, reverting it to Linden ownership without a sale! Be sure you know what you&apos;re doing before assigning this Ability."
57 name="land release" /> 57 name="land release" value="13" />
58 <action description="设置待售土地的信æ¯" 58 <action description="设置待售土地的信æ¯"
59 longdescription="Set land for sale info. *WARNING* Any Member in a Role with this Ability can sell group-owned land in About Land &gt; General tab as they wish! Be sure you know what you&apos;re doing before assigning this Ability." 59 longdescription="Set land for sale info. *WARNING* Any Member in a Role with this Ability can sell group-owned land in About Land &gt; General tab as they wish! Be sure you know what you&apos;re doing before assigning this Ability."
60 name="land set sale info" /> 60 name="land set sale info" value="14" />
61 <action description="划分并加入土地" 61 <action description="划分并加入土地"
62 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. " 62 longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. "
63 name="land divide join" /> 63 name="land divide join" value="15" />
64 </action_set> 64 </action_set>
65 <action_set 65 <action_set
66 description="这些能力包括改å˜åœŸåœ°åç§°å’Œå‘布设置,查找目的地å¯è§åº¦ï¼Œé€‰æ‹©ç€é™†ç‚¹å’Œé—ªç”µä¼ è¿ç‚¹çš„路线的æƒåˆ©ã€‚" 66 description="这些能力包括改å˜åœŸåœ°åç§°å’Œå‘布设置,查找目的地å¯è§åº¦ï¼Œé€‰æ‹©ç€é™†ç‚¹å’Œé—ªç”µä¼ è¿ç‚¹çš„路线的æƒåˆ©ã€‚"
67 name="Parcel Identity"> 67 name="Parcel Identity">
68 <action description="绑定&apos;在查找地点中显示&apos;并设定分类" 68 <action description="绑定&apos;在查找地点中显示&apos;并设定分类"
69 longdescription="Toggle &apos;Show in Find Places&apos; and setting a parcel&apos;s category in About Land &gt; Options tab." 69 longdescription="Toggle &apos;Show in Find Places&apos; and setting a parcel&apos;s category in About Land &gt; Options tab."
70 name="land find places" /> 70 name="land find places" value="17" />
71 <action 71 <action
72 description="改å˜åœŸåœ°åç§°, æè¿°å’Œ &apos;在网络上å‘布&apos;的设置" 72 description="改å˜åœŸåœ°åç§°, æè¿°å’Œ &apos;在网络上å‘布&apos;的设置"
73 longdescription="Change parcel name, description, and &apos;Publish on the Web&apos; settings. This is done in About Land &gt; Options tab." 73 longdescription="Change parcel name, description, and &apos;Publish on the Web&apos; settings. This is done in About Land &gt; Options tab."
74 name="land change identity" /> 74 name="land change identity" value="18" />
75 <action description="设置ç€é™†ç‚¹ï¼Œå¹¶è®¾ç½®é—ªç”µä¼ é€è·¯å¾„" 75 <action description="设置ç€é™†ç‚¹ï¼Œå¹¶è®¾ç½®é—ªç”µä¼ é€è·¯å¾„"
76 longdescription="On a group-owned parcel, Members in a Role with this Ability can set a landing point to specify where incoming teleports arrive, and also set teleport routing for further control. This is done in About Land &gt; Options tab." 76 longdescription="On a group-owned parcel, Members in a Role with this Ability can set a landing point to specify where incoming teleports arrive, and also set teleport routing for further control. This is done in About Land &gt; Options tab."
77 name="land set landing point" /> 77 name="land set landing point" value="19" />
78 </action_set> 78 </action_set>
79 <action_set 79 <action_set
80 description="这些能力包括影å“å½±å“土地选项的æƒåˆ©ï¼Œä¾‹å¦‚“创建东东â€ï¼Œâ€œç¼–辑地形â€ï¼ŒéŸ³ä¹å’Œåª’体设置等。" 80 description="这些能力包括影å“å½±å“土地选项的æƒåˆ©ï¼Œä¾‹å¦‚“创建东东â€ï¼Œâ€œç¼–辑地形â€ï¼ŒéŸ³ä¹å’Œåª’体设置等。"
81 name="Parcel Settings"> 81 name="Parcel Settings">
82 <action description="改å˜éŸ³ä¹å’Œå¤šåª’体设置" 82 <action description="改å˜éŸ³ä¹å’Œå¤šåª’体设置"
83 longdescription="Change streaming music and movie settings in About Land &gt; Media tab." 83 longdescription="Change streaming music and movie settings in About Land &gt; Media tab."
84 name="land change media" /> 84 name="land change media" value="20" />
85 <action description="绑定&apos;编辑地形&apos;" 85 <action description="绑定&apos;编辑地形&apos;"
86 longdescription="Toggle &apos;Edit Terrain&apos;. *WARNING* About Land &gt; Options tab &gt; Edit Terrain allows anyone to terraform your land&apos;s shape, and place and move Linden plants. Be sure you know what you&apos;re doing before assigning this Ability. Editing terrain is toggled in About Land &gt; Options tab." 86 longdescription="Toggle &apos;Edit Terrain&apos;. *WARNING* About Land &gt; Options tab &gt; Edit Terrain allows anyone to terraform your land&apos;s shape, and place and move Linden plants. Be sure you know what you&apos;re doing before assigning this Ability. Editing terrain is toggled in About Land &gt; Options tab."
87 name="land edit" /> 87 name="land edit" value="21" />
88 <action description="绑定å„项步骤:关于土地&gt;选择设定" 88 <action description="绑定å„项步骤:关于土地&gt;选择设定"
89 longdescription="Toggle &apos;Safe (no damage)&apos;, &apos;Fly&apos;, and allow other Residents to: &apos;Create Objects&apos;, &apos;Edit Terrain&apos;, &apos;Create Landmarks&apos;, and &apos;Run Scripts&apos; on group-owned land in About Land &gt; Options tab." 89 longdescription="Toggle &apos;Safe (no damage)&apos;, &apos;Fly&apos;, and allow other Residents to: &apos;Create Objects&apos;, &apos;Edit Terrain&apos;, &apos;Create Landmarks&apos;, and &apos;Run Scripts&apos; on group-owned land in About Land &gt; Options tab."
90 name="land options" /> 90 name="land options" value="22" />
91 </action_set> 91 </action_set>
92 <action_set 92 <action_set
93 description="这些能力包括å…许组员绕过社团拥有土地的é™åˆ¶çš„æƒåˆ©" 93 description="这些能力包括å…许组员绕过社团拥有土地的é™åˆ¶çš„æƒåˆ©"
94 name="Parcel Powers"> 94 name="Parcel Powers">
95 <action description="永远å…许 &apos;编辑地形&apos;" 95 <action description="永远å…许 &apos;编辑地形&apos;"
96 longdescription="Members in a Role with this Ability can edit terrain on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab." 96 longdescription="Members in a Role with this Ability can edit terrain on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
97 name="land allow edit land" /> 97 name="land allow edit land" value="23" />
98 <action description="永远å…许 &apos;起飞&apos;" 98 <action description="永远å…许 &apos;起飞&apos;"
99 longdescription="Members in a Role with this Ability can fly on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab." 99 longdescription="Members in a Role with this Ability can fly on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
100 name="land allow fly" /> 100 name="land allow fly" value="24" />
101 <action description="永远å…许&apos;创建东东&apos;" 101 <action description="永远å…许&apos;创建东东&apos;"
102 longdescription="Members in a Role with this Ability can create objects on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab." 102 longdescription="Members in a Role with this Ability can create objects on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
103 name="land allow create" /> 103 name="land allow create" value="25" />
104 <action description="永远å…许 &apos;创建地标&apos;" 104 <action description="永远å…许 &apos;创建地标&apos;"
105 longdescription="Members in a Role with this Ability can landmark a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab." 105 longdescription="Members in a Role with this Ability can landmark a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
106 name="land allow landmark" /> 106 name="land allow landmark" value="26" />
107 <action description="å…许在社团土地上&apos;把家建在这里&apos;" 107 <action description="å…许在社团土地上&apos;把家建在这里&apos;"
108 longdescription="Members in a Role with this Ability can use World menu &gt; Set Home to Here on a group parcel (either land set or deeded to this group)." 108 longdescription="Members in a Role with this Ability can use World menu &gt; Set Home to Here on a group parcel (either land set or deeded to this group)."
109 name="land allow set home" /> 109 name="land allow set home" value="28" />
110 </action_set> 110 </action_set>
111 <action_set 111 <action_set
112 description="这些能力包括å…许或é™åˆ¶é€šå¾€ç¤¾å›¢æ‹¥æœ‰çš„土地的æƒåˆ©ï¼ŒåŒ…括冻结和驱é€ç»„员æƒåˆ©ã€‚" 112 description="这些能力包括å…许或é™åˆ¶é€šå¾€ç¤¾å›¢æ‹¥æœ‰çš„土地的æƒåˆ©ï¼ŒåŒ…括冻结和驱é€ç»„员æƒåˆ©ã€‚"
113 name="Parcel Access"> 113 name="Parcel Access">
114 <action description="管ç†å¯è¿›å…¥åœŸåœ°åå•" 114 <action description="管ç†å¯è¿›å…¥åœŸåœ°åå•"
115 longdescription="Manage parcel Access lists in About Land &gt; Access tab." 115 longdescription="Manage parcel Access lists in About Land &gt; Access tab."
116 name="land manage allowed" /> 116 name="land manage allowed" value="29" />
117 <action description="管ç†ä¸å¯è¿›å…¥åœŸåœ°åå•" 117 <action description="管ç†ä¸å¯è¿›å…¥åœŸåœ°åå•"
118 longdescription="Manage parcel Ban lists in About Land &gt; Ban tab." 118 longdescription="Manage parcel Ban lists in About Land &gt; Ban tab."
119 name="land manage banned" /> 119 name="land manage banned" value="30" />
120 <action description="改å˜åœŸåœ°ä¸Š &apos;出售通行è¯...&apos;的设置" 120 <action description="改å˜åœŸåœ°ä¸Š &apos;出售通行è¯...&apos;的设置"
121 longdescription="Change parcel &apos;Sell passes...&apos; settings in About Land &gt; Access tab." 121 longdescription="Change parcel &apos;Sell passes...&apos; settings in About Land &gt; Access tab."
122 name="land manage passes" /> 122 name="land manage passes" value="31" />
123 <action description="ä»ŽåœŸåœ°ä¸Šé©±é€æˆ–冻结居民" 123 <action description="ä»ŽåœŸåœ°ä¸Šé©±é€æˆ–冻结居民"
124 longdescription="Members in a Role with this Ability can handle an unwelcome Resident on a group-owned parcel by right-clicking them, More &gt;, and selecting &apos;Eject...&apos; or &apos;Freeze...&apos;." 124 longdescription="Members in a Role with this Ability can handle an unwelcome Resident on a group-owned parcel by right-clicking them, More &gt;, and selecting &apos;Eject...&apos; or &apos;Freeze...&apos;."
125 name="land admin" /> 125 name="land admin" value="32" />
126 </action_set> 126 </action_set>
127 <action_set 127 <action_set
128 description="这些能力包括å…è®¸ç»„å‘˜å½’è¿˜ä¸œä¸œï¼Œå®šä½æˆ–移动林登设备的æƒåˆ©ã€‚这对组员清ç†åžƒåœ¾å’Œç¾ŽåŒ–景观时很有用,当这项能力在使用时应该注æ„,因为一旦选择归还东东åŽåˆ™æ— æ³•撤销。" 128 description="这些能力包括å…è®¸ç»„å‘˜å½’è¿˜ä¸œä¸œï¼Œå®šä½æˆ–移动林登设备的æƒåˆ©ã€‚这对组员清ç†åžƒåœ¾å’Œç¾ŽåŒ–景观时很有用,当这项能力在使用时应该注æ„,因为一旦选择归还东东åŽåˆ™æ— æ³•撤销。"
129 name="Parcel Content"> 129 name="Parcel Content">
130 <action description="归还社团拥有的东东" 130 <action description="归还社团拥有的东东"
131 longdescription="Return objects on group-owned parcels that are owned by the group in About Land &gt; Objects tab." 131 longdescription="Return objects on group-owned parcels that are owned by the group in About Land &gt; Objects tab."
132 name="land return group owned" /> 132 name="land return group owned" value="48" />
133 <action description="归还放置在社团处的东东" 133 <action description="归还放置在社团处的东东"
134 longdescription="Return objects on group-owned parcels that are set to the group in About Land &gt; Objects tab." 134 longdescription="Return objects on group-owned parcels that are set to the group in About Land &gt; Objects tab."
135 name="land return group set" /> 135 name="land return group set" value="33" />
136 <action description="归还éžç¤¾å›¢æ‰€æœ‰çš„东东" 136 <action description="归还éžç¤¾å›¢æ‰€æœ‰çš„东东"
137 longdescription="Return objects on group-owned parcels that are non-group in About Land &gt; Objects tab." 137 longdescription="Return objects on group-owned parcels that are non-group in About Land &gt; Objects tab."
138 name="land return non group" /> 138 name="land return non group" value="34" />
139 <action description="使用林登æ¤ç‰©ç¾ŽåŒ–土地" 139 <action description="使用林登æ¤ç‰©ç¾ŽåŒ–土地"
140 longdescription="Landscaping ability to place and move Linden trees, plants, and grasses. These items can be found in your inventory&apos;s Library &gt; Objects folder or they can be created via the Build button." 140 longdescription="Landscaping ability to place and move Linden trees, plants, and grasses. These items can be found in your inventory&apos;s Library &gt; Objects folder or they can be created via the Build button."
141 name="land gardening" /> 141 name="land gardening" value="35" />
142 </action_set> 142 </action_set>
143 <action_set 143 <action_set
144 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. " 144 description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. "
145 name="Object Management"> 145 name="Object Management">
146 <action description="转让东东给社团" 146 <action description="转让东东给社团"
147 longdescription="Deed objects to group in the Edit Tools &gt; General Tab." 147 longdescription="Deed objects to group in the Edit Tools &gt; General Tab."
148 name="object deed" /> 148 name="object deed" value="36" />
149 <action description="处ç†(移动,å¤åˆ¶ï¼Œä¿®æ”¹)社团所有的东东" 149 <action description="处ç†(移动,å¤åˆ¶ï¼Œä¿®æ”¹)社团所有的东东"
150 longdescription="Manipulate (move, copy, modify) group-owned objects in the Edit Tools &gt; General Tab." 150 longdescription="Manipulate (move, copy, modify) group-owned objects in the Edit Tools &gt; General Tab."
151 name="object manipulate" /> 151 name="object manipulate" value="38" />
152 <action description="把社团拥有的东东èˆç»´å¾…å”®" 152 <action description="把社团拥有的东东èˆç»´å¾…å”®"
153 longdescription="Set group-owned objects for sale in the Edit Tools &gt; General tab." 153 longdescription="Set group-owned objects for sale in the Edit Tools &gt; General tab."
154 name="object set sale" /> 154 name="object set sale" value="39" />
155 </action_set> 155 </action_set>
156 <action_set 156 <action_set
157 description="è¿™äº›èƒ½åŠ›åŒ…æ‹¬è¦æ±‚组员å¿è¿˜ç¤¾å›¢è´·æ¬¾å’ŒèŽ·å¾—ç¤¾å›¢çº¢åˆ©ï¼Œä»¥åŠé™åˆ¶è¿›å…¥ç¤¾å›¢å¸å·åކå²çºªå½•çš„æƒåˆ©ã€‚" 157 description="è¿™äº›èƒ½åŠ›åŒ…æ‹¬è¦æ±‚组员å¿è¿˜ç¤¾å›¢è´·æ¬¾å’ŒèŽ·å¾—ç¤¾å›¢çº¢åˆ©ï¼Œä»¥åŠé™åˆ¶è¿›å…¥ç¤¾å›¢å¸å·åކå²çºªå½•çš„æƒåˆ©ã€‚"
158 name="Accounting"> 158 name="Accounting">
159 <action description="å¿è¿˜ç¤¾å›¢å€ºåŠ¡/获得社团红利" 159 <action description="å¿è¿˜ç¤¾å›¢å€ºåŠ¡/获得社团红利"
160 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. " 160 longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. "
161 name="accounting accountable" /> 161 name="accounting accountable" value="40" />
162 </action_set> 162 </action_set>
163 <action_set 163 <action_set
164 description="这些能力包括å…许组员å‘é€ï¼ŒæŽ¥å—å’Œæµè§ˆç¤¾å›¢é€šçŸ¥çš„æƒåˆ©" 164 description="这些能力包括å…许组员å‘é€ï¼ŒæŽ¥å—å’Œæµè§ˆç¤¾å›¢é€šçŸ¥çš„æƒåˆ©"
165 name="Notices"> 165 name="Notices">
166 <action description="å‘é€é€šçŸ¥" 166 <action description="å‘é€é€šçŸ¥"
167 longdescription="Members in a Role with this Ability can send Notices in Group Information &gt; Notices tab." 167 longdescription="Members in a Role with this Ability can send Notices in Group Information &gt; Notices tab."
168 name="notices send" /> 168 name="notices send" value="42" />
169 <action description="接å—通知/回顾原æ¥çš„通知" 169 <action description="接å—通知/回顾原æ¥çš„通知"
170 longdescription="Members in a Role with this Ability can receive Notices and view past Notices in Group Information &gt; Notices tab." 170 longdescription="Members in a Role with this Ability can receive Notices and view past Notices in Group Information &gt; Notices tab."
171 name="notices receive" /> 171 name="notices receive" value="43" />
172 </action_set> 172 </action_set>
173 <action_set 173 <action_set
174 description="这些能力包括å…许组员æå‡ºè®®æ¡ˆï¼Œä¸ºè®®æ¡ˆæŠ•票,和æµè§ˆæŠ•票历å²çºªå½•çš„æƒåˆ©" 174 description="这些能力包括å…许组员æå‡ºè®®æ¡ˆï¼Œä¸ºè®®æ¡ˆæŠ•票,和æµè§ˆæŠ•票历å²çºªå½•çš„æƒåˆ©"
175 name="Proposals"> 175 name="Proposals">
176 <action description="创建æè®®æœ¬" 176 <action description="创建æè®®æœ¬"
177 longdescription="Members in a Role with this Ability can create proposals to be voted on in Group Information &gt; Proposals tab." 177 longdescription="Members in a Role with this Ability can create proposals to be voted on in Group Information &gt; Proposals tab."
178 name="proposal start" /> 178 name="proposal start" value="44" />
179 <action description="为议案投票" 179 <action description="为议案投票"
180 longdescription="Members in a Role with this Ability can vote on proposals in Group Information &gt; Proposals tab." 180 longdescription="Members in a Role with this Ability can vote on proposals in Group Information &gt; Proposals tab."
181 name="proposal vote" /> 181 name="proposal vote" value="45" />
182 </action_set> 182 </action_set>
183</role_actions> 183</role_actions>
diff --git a/linden/indra/newview/viewer.cpp b/linden/indra/newview/viewer.cpp
index 9bfa373..2890269 100644
--- a/linden/indra/newview/viewer.cpp
+++ b/linden/indra/newview/viewer.cpp
@@ -71,7 +71,7 @@
71#include "smrtheap/smrtheap.h" 71#include "smrtheap/smrtheap.h"
72#endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP 72#endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
73 73
74#elif LL_DARWIN || LL_LINUX 74#elif LL_DARWIN || LL_LINUX || LL_SOLARIS
75 75
76 # include <sys/socket.h> 76 # include <sys/socket.h>
77// # include <sys/stat.h> // mkdir() 77// # include <sys/stat.h> // mkdir()
@@ -88,6 +88,11 @@
88 # include <cxxabi.h> // for symbol demangling 88 # include <cxxabi.h> // for symbol demangling
89 # include "ELFIO.h" // for better backtraces 89 # include "ELFIO.h" // for better backtraces
90 # endif // LL_ELFBIN 90 # endif // LL_ELFBIN
91 #elif LL_SOLARIS
92 # include <sys/types.h>
93 # include <unistd.h>
94 # include <fcntl.h>
95 # include <ucontext.h>
91 #endif 96 #endif
92 97
93 #if LL_DARWIN 98 #if LL_DARWIN
@@ -164,6 +169,7 @@
164#include "llfasttimerview.h" 169#include "llfasttimerview.h"
165#include "llfeaturemanager.h" 170#include "llfeaturemanager.h"
166#include "llfirstuse.h" 171#include "llfirstuse.h"
172#include "llfloateractivespeakers.h"
167#include "llfloatertools.h" 173#include "llfloatertools.h"
168#include "llfloaterworldmap.h" 174#include "llfloaterworldmap.h"
169#include "llfloaterhtmlhelp.h" 175#include "llfloaterhtmlhelp.h"
@@ -177,6 +183,7 @@
177#include "llhudmanager.h" 183#include "llhudmanager.h"
178#include "llhttpclient.h" 184#include "llhttpclient.h"
179#include "llimview.h" 185#include "llimview.h"
186#include "llimpanel.h"
180#include "llinventorymodel.h" 187#include "llinventorymodel.h"
181#include "llinventoryview.h" 188#include "llinventoryview.h"
182#include "llkeyboard.h" 189#include "llkeyboard.h"
@@ -202,9 +209,11 @@
202#include "lltoolmgr.h" 209#include "lltoolmgr.h"
203#include "lltracker.h" 210#include "lltracker.h"
204#include "llurlwhitelist.h" 211#include "llurlwhitelist.h"
212#include "llv4math.h" // LL_VECTORIZE
205#include "llviewerbuild.h" 213#include "llviewerbuild.h"
206#include "llviewercamera.h" 214#include "llviewercamera.h"
207#include "llviewercontrol.h" 215#include "llviewercontrol.h"
216#include "llviewerjointmesh.h"
208#include "llviewerimagelist.h" 217#include "llviewerimagelist.h"
209#include "llviewerkeyboard.h" 218#include "llviewerkeyboard.h"
210#include "llviewermenu.h" 219#include "llviewermenu.h"
@@ -234,6 +243,7 @@
234#include "llface.h" 243#include "llface.h"
235#include "audiosettings.h" 244#include "audiosettings.h"
236#include "res/resource.h" 245#include "res/resource.h"
246#include "llvoiceclient.h"
237 247
238#if LL_WINDOWS 248#if LL_WINDOWS
239#include "llwindebug.h" 249#include "llwindebug.h"
@@ -253,6 +263,12 @@
253#endif 263#endif
254#endif 264#endif
255 265
266#if LL_GSTREAMER_ENABLED
267// ugh, do this instead of pulling in the gstreamer headers which indirectly
268// clash with expat in the monster that is viewer.cpp ... sigh.
269void UnloadGStreamer();
270#endif // LL_GSTREAMER_ENABLED
271
256#include "llmediaengine.h" 272#include "llmediaengine.h"
257 273
258#if LL_LIBXUL_ENABLED 274#if LL_LIBXUL_ENABLED
@@ -267,6 +283,7 @@ void errorCallback(const std::string &error_string);
267S32 gCrashBehavior = CRASH_BEHAVIOR_ASK; 283S32 gCrashBehavior = CRASH_BEHAVIOR_ASK;
268void (*gCrashCallback)(void) = NULL; 284void (*gCrashCallback)(void) = NULL;
269BOOL gReportedCrash = FALSE; 285BOOL gReportedCrash = FALSE;
286
270bool gVerifySSLCert = true; 287bool gVerifySSLCert = true;
271 288
272BOOL gHandleKeysAsync = FALSE; 289BOOL gHandleKeysAsync = FALSE;
@@ -295,15 +312,9 @@ const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user fl
295const char *VFS_DATA_FILE_BASE = "data.db2.x."; 312const char *VFS_DATA_FILE_BASE = "data.db2.x.";
296const char *VFS_INDEX_FILE_BASE = "index.db2.x."; 313const char *VFS_INDEX_FILE_BASE = "index.db2.x.";
297 314
298const F32 MAX_USER_FOG_RATIO = 4.f;
299const F32 MIN_USER_FOG_RATIO = 0.5f;
300
301F32 gSimLastTime; 315F32 gSimLastTime;
302F32 gSimFrames; 316F32 gSimFrames;
303 317
304const S32 MAX_USER_COMPOSITE_LIMIT = 100;
305const S32 MIN_USER_COMPOSITE_LIMIT = 0;
306
307//#define RENDER_CLOUD_DENSITY // uncomment to look at cloud density 318//#define RENDER_CLOUD_DENSITY // uncomment to look at cloud density
308 319
309///////////////////////////////////////////////////////////////////////////////// 320/////////////////////////////////////////////////////////////////////////////////
@@ -321,9 +332,6 @@ LLString gDisabledMessage;
321BOOL gHideLinks = FALSE; 332BOOL gHideLinks = FALSE;
322 333
323// This is whether or not we are connect to a production grid. 334// This is whether or not we are connect to a production grid.
324// HACK/TEMP - the code that used to set this based on the userserver selection
325// is gone, so there is no code that currently sets this to TRUE. Since we don't
326// want to ship as "FALSE", hardcoding it to TRUE for now. Please fix.
327BOOL gInProductionGrid = FALSE; 335BOOL gInProductionGrid = FALSE;
328 336
329//#define APPLE_PREVIEW // Define this if you're doing a preview build on the Mac 337//#define APPLE_PREVIEW // Define this if you're doing a preview build on the Mac
@@ -365,6 +373,7 @@ BOOL gMultipleViewersOK = FALSE;
365BOOL gMultipleViewersOK = TRUE; 373BOOL gMultipleViewersOK = TRUE;
366#endif 374#endif
367BOOL gSecondInstance = FALSE; 375BOOL gSecondInstance = FALSE;
376BOOL gDisableVoice = FALSE;
368 377
369LLString gArgs; 378LLString gArgs;
370 379
@@ -514,6 +523,7 @@ static const char USAGE[] = "\n"
514" -noinvlib Do not request inventory library\n" 523" -noinvlib Do not request inventory library\n"
515" -multiple allow multiple viewers\n" 524" -multiple allow multiple viewers\n"
516" -nomultiple block multiple viewers\n" 525" -nomultiple block multiple viewers\n"
526" -novoice disable voice\n"
517" -ignorepixeldepth ignore pixel depth settings\n" 527" -ignorepixeldepth ignore pixel depth settings\n"
518" -cooperative [ms] yield some idle time to local host\n" 528" -cooperative [ms] yield some idle time to local host\n"
519" -skin ui/branding skin folder to use\n" 529" -skin ui/branding skin folder to use\n"
@@ -633,10 +643,11 @@ OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *
633OSStatus DisplayReleaseNotes(void); 643OSStatus DisplayReleaseNotes(void);
634#endif // LL_DARWIN 644#endif // LL_DARWIN
635 645
636void ui_audio_callback(const LLUUID& uuid, F32 volume) 646void ui_audio_callback(const LLUUID& uuid)
637{ 647{
638 if (gAudiop) 648 if (gAudiop)
639 { 649 {
650 F32 volume = gSavedSettings.getF32("AudioLevelUI");
640 gAudiop->triggerSound(uuid, gAgent.getID(), volume); 651 gAudiop->triggerSound(uuid, gAgent.getID(), volume);
641 } 652 }
642} 653}
@@ -793,6 +804,10 @@ int main( int argc, char **argv )
793#endif 804#endif
794{ 805{
795 LLMemType mt1(LLMemType::MTYPE_STARTUP); 806 LLMemType mt1(LLMemType::MTYPE_STARTUP);
807
808#if LL_SOLARIS && defined(__sparc)
809 asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC
810#endif
796 811
797#if 1 812#if 1
798 // This will eventually be done in LLApp 813 // This will eventually be done in LLApp
@@ -924,6 +939,11 @@ int main( int argc, char **argv )
924 // Hack to detect -multiple so we can disable the marker file check (which will always fail) 939 // Hack to detect -multiple so we can disable the marker file check (which will always fail)
925 gMultipleViewersOK = TRUE; 940 gMultipleViewersOK = TRUE;
926 } 941 }
942 else if (!strcmp(argv[j], "-novoice"))
943 {
944 // May need to know this early also
945 gDisableVoice = TRUE;
946 }
927 else if (!strcmp(argv[j], "-url") && (++j < argc)) 947 else if (!strcmp(argv[j], "-url") && (++j < argc))
928 { 948 {
929 LLURLSimString::setString(argv[j]); 949 LLURLSimString::setString(argv[j]);
@@ -1084,8 +1104,10 @@ int main( int argc, char **argv )
1084 // Initialize apple menubar and various callbacks 1104 // Initialize apple menubar and various callbacks
1085 init_apple_menu(gSecondLife.c_str()); 1105 init_apple_menu(gSecondLife.c_str());
1086 1106
1107#if __ppc__
1087 // If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further. 1108 // If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further.
1088 if(!gSysCPU.hasSSE()) 1109 // Only test PowerPC - all Intel Macs have SSE.
1110 if(!gSysCPU.hasAltivec())
1089 { 1111 {
1090 std::ostringstream msg; 1112 std::ostringstream msg;
1091 msg << gSecondLife << " requires a processor with AltiVec (G4 or later)."; 1113 msg << gSecondLife << " requires a processor with AltiVec (G4 or later).";
@@ -1096,6 +1118,7 @@ int main( int argc, char **argv )
1096 remove_marker_file(); 1118 remove_marker_file();
1097 return 1; 1119 return 1;
1098 } 1120 }
1121#endif
1099 1122
1100#endif // LL_DARWIN 1123#endif // LL_DARWIN
1101 1124
@@ -1218,10 +1241,14 @@ int main( int argc, char **argv )
1218 // XXX -- We need to exit fullscreen mode for this to work. 1241 // XXX -- We need to exit fullscreen mode for this to work.
1219 // XXX -- system() also doesn't wait for completion. Hmm... 1242 // XXX -- system() also doesn't wait for completion. Hmm...
1220 system(command_str.c_str()); /* Flawfinder: Ignore */ 1243 system(command_str.c_str()); /* Flawfinder: Ignore */
1221#elif LL_LINUX 1244#elif LL_LINUX || LL_SOLARIS
1222 std::string cmd =gDirUtilp->getAppRODataDir(); 1245 std::string cmd =gDirUtilp->getAppRODataDir();
1223 cmd += gDirUtilp->getDirDelimiter(); 1246 cmd += gDirUtilp->getDirDelimiter();
1247#if LL_LINUX
1224 cmd += "linux-crash-logger.bin"; 1248 cmd += "linux-crash-logger.bin";
1249#else // LL_SOLARIS
1250 cmd += "bin/solaris-crash-logger";
1251#endif
1225 char* const cmdargv[] = 1252 char* const cmdargv[] =
1226 {(char*)cmd.c_str(), 1253 {(char*)cmd.c_str(),
1227 (char*)"-previous", 1254 (char*)"-previous",
@@ -1259,17 +1286,18 @@ int main( int argc, char **argv )
1259 { 1286 {
1260 gSecondInstance = another_instance_running(); 1287 gSecondInstance = another_instance_running();
1261 1288
1262 /* Don't start another instance if using -multiple
1263 if (gSecondInstance) 1289 if (gSecondInstance)
1264 { 1290 {
1291 gDisableVoice = TRUE;
1292 /* Don't start another instance if using -multiple
1265 //RN: if we received a URL, hand it off to the existing instance 1293 //RN: if we received a URL, hand it off to the existing instance
1266 if (LLURLSimString::parse()) 1294 if (LLURLSimString::parse())
1267 { 1295 {
1268 LLURLSimString::send_to_other_instance(); 1296 LLURLSimString::send_to_other_instance();
1269 return 1; 1297 return 1;
1270 } 1298 }
1299 */
1271 } 1300 }
1272 */
1273 1301
1274 init_marker_file(); 1302 init_marker_file();
1275 } 1303 }
@@ -1377,22 +1405,20 @@ int main( int argc, char **argv )
1377 if (gUserServerChoice == USERSERVER_NONE) 1405 if (gUserServerChoice == USERSERVER_NONE)
1378 { 1406 {
1379 // Development version: load last server choice by default (overridden by cmd line args) 1407 // Development version: load last server choice by default (overridden by cmd line args)
1380 if (gSavedSettings.getBOOL("UseDebugLogin")) 1408
1409 S32 server = gSavedSettings.getS32("ServerChoice");
1410 if (server != 0)
1411 gUserServerChoice = (EUserServerDomain)llclamp(server, 0, (S32)USERSERVER_COUNT - 1);
1412 if (server == USERSERVER_OTHER)
1381 { 1413 {
1382 S32 server = gSavedSettings.getS32("ServerChoice"); 1414 LLString custom_server = gSavedSettings.getString("CustomServer");
1383 if (server != 0) 1415 if (custom_server.empty())
1384 gUserServerChoice = (EUserServerDomain)llclamp(server, 0, (S32)USERSERVER_COUNT - 1);
1385 if (server == USERSERVER_OTHER)
1386 { 1416 {
1387 LLString custom_server = gSavedSettings.getString("CustomServer"); 1417 snprintf(gUserServerName, MAX_STRING, "none"); /* Flawfinder: ignore */
1388 if (custom_server.empty()) 1418 }
1389 { 1419 else
1390 snprintf(gUserServerName, MAX_STRING, "none"); /* Flawfinder: ignore */ 1420 {
1391 } 1421 snprintf(gUserServerName, MAX_STRING, "%s", custom_server.c_str()); /* Flawfinder: ignore */
1392 else
1393 {
1394 snprintf(gUserServerName, MAX_STRING, "%s", custom_server.c_str()); /* Flawfinder: ignore */
1395 }
1396 } 1422 }
1397 } 1423 }
1398 } 1424 }
@@ -1785,7 +1811,10 @@ void check_for_events()
1785 1811
1786#include "moviemaker.h" 1812#include "moviemaker.h"
1787extern BOOL gbCapturing; 1813extern BOOL gbCapturing;
1814
1815#if !LL_SOLARIS
1788extern MovieMaker gMovieMaker; 1816extern MovieMaker gMovieMaker;
1817#endif
1789 1818
1790void main_loop() 1819void main_loop()
1791{ 1820{
@@ -1793,7 +1822,14 @@ void main_loop()
1793 gServicePump = new LLPumpIO(gAPRPoolp); 1822 gServicePump = new LLPumpIO(gAPRPoolp);
1794 LLHTTPClient::setPump(*gServicePump); 1823 LLHTTPClient::setPump(*gServicePump);
1795 LLHTTPClient::setCABundle(gDirUtilp->getCAFile()); 1824 LLHTTPClient::setCABundle(gDirUtilp->getCAFile());
1825
1826 // initialize voice stuff here
1827 gLocalSpeakerMgr = new LLLocalSpeakerMgr();
1828 gActiveChannelSpeakerMgr = new LLActiveSpeakerMgr();
1796 1829
1830 LLVoiceChannel::initClass();
1831 LLVoiceClient::init(gServicePump);
1832
1797 LLMemType mt1(LLMemType::MTYPE_MAIN); 1833 LLMemType mt1(LLMemType::MTYPE_MAIN);
1798 LLTimer frameTimer,idleTimer; 1834 LLTimer frameTimer,idleTimer;
1799 LLTimer debugTime; 1835 LLTimer debugTime;
@@ -1853,10 +1889,12 @@ void main_loop()
1853 1889
1854 LLFloaterSnapshot::update(); // take snapshots 1890 LLFloaterSnapshot::update(); // take snapshots
1855 1891
1892#if !LL_SOLARIS
1856 if (gbCapturing) 1893 if (gbCapturing)
1857 { 1894 {
1858 gMovieMaker.Snap(); 1895 gMovieMaker.Snap();
1859 } 1896 }
1897#endif
1860 } 1898 }
1861 1899
1862 } 1900 }
@@ -2023,6 +2061,12 @@ void remove_marker_file()
2023 2061
2024void init_marker_file() 2062void init_marker_file()
2025{ 2063{
2064#if LL_SOLARIS
2065 struct flock fl;
2066 fl.l_whence = SEEK_SET;
2067 fl.l_start = 0;
2068 fl.l_len = 1;
2069#endif
2026 // We create a marker file when the program starts and remove the file when it finishes. 2070 // We create a marker file when the program starts and remove the file when it finishes.
2027 // If the file is currently locked, that means another process is already running. 2071 // If the file is currently locked, that means another process is already running.
2028 // If the file exists and isn't locked, we crashed on the last run. 2072 // If the file exists and isn't locked, we crashed on the last run.
@@ -2069,7 +2113,12 @@ void init_marker_file()
2069 { 2113 {
2070 int fd = fileno(gMarkerFile); 2114 int fd = fileno(gMarkerFile);
2071 // Attempt to lock 2115 // Attempt to lock
2116#if LL_SOLARIS
2117 fl.l_type = F_WRLCK;
2118 if (fcntl(fd, F_SETLK, &fl) == -1)
2119#else
2072 if (flock(fd, LOCK_EX | LOCK_NB) == -1) 2120 if (flock(fd, LOCK_EX | LOCK_NB) == -1)
2121#endif
2073 { 2122 {
2074 llinfos << "Failed to lock file." << llendl; 2123 llinfos << "Failed to lock file." << llendl;
2075 } 2124 }
@@ -2121,12 +2170,12 @@ void init_logging()
2121 "SecondLife.old"); 2170 "SecondLife.old");
2122 LLFile::remove(old_log_file.c_str()); 2171 LLFile::remove(old_log_file.c_str());
2123 2172
2124#if LL_LINUX 2173#if LL_LINUX || LL_SOLARIS
2125 // Remove the last stack trace, if any 2174 // Remove the last stack trace, if any
2126 std::string old_stack_file = 2175 std::string old_stack_file =
2127 gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); 2176 gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
2128 LLFile::remove(old_stack_file.c_str()); 2177 LLFile::remove(old_stack_file.c_str());
2129#endif // LL_LINUX 2178#endif // LL_LINUX || LL_SOLARIS
2130 2179
2131 // Rename current log file to ".old" 2180 // Rename current log file to ".old"
2132 std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, 2181 std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
@@ -2245,7 +2294,7 @@ std::string get_serial_number()
2245 } 2294 }
2246 return serial_md5; 2295 return serial_md5;
2247 2296
2248#elif LL_DARWIN 2297#elif LL_DARWIN
2249 // JC: Sample code from http://developer.apple.com/technotes/tn/tn1103.html 2298 // JC: Sample code from http://developer.apple.com/technotes/tn/tn1103.html
2250 CFStringRef serialNumber = NULL; 2299 CFStringRef serialNumber = NULL;
2251 io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, 2300 io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
@@ -2270,7 +2319,7 @@ std::string get_serial_number()
2270 2319
2271 return serial_md5; 2320 return serial_md5;
2272 2321
2273#elif LL_LINUX 2322#elif LL_LINUX || LL_SOLARIS
2274 // TODO 2323 // TODO
2275 return serial_md5; 2324 return serial_md5;
2276 2325
@@ -2481,6 +2530,29 @@ static inline bool being_debugged()
2481 return debugged == yes; 2530 return debugged == yes;
2482} 2531}
2483 2532
2533#ifdef LL_SOLARIS
2534static inline BOOL do_basic_glibc_backtrace()
2535{
2536 BOOL success = FALSE;
2537
2538 std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
2539 llinfos << "Opening stack trace file " << strace_filename << llendl;
2540 FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w");
2541 if (!StraceFile)
2542 {
2543 llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl;
2544 StraceFile = stderr;
2545 }
2546
2547 printstack(fileno(StraceFile));
2548
2549 if (StraceFile != stderr)
2550 fclose(StraceFile);
2551
2552 return success;
2553}
2554#endif // LL_SOLARIS
2555
2484void viewer_crash_callback() 2556void viewer_crash_callback()
2485{ 2557{
2486 // This will drop us into the debugger. 2558 // This will drop us into the debugger.
@@ -2575,7 +2647,7 @@ void viewer_crash_callback()
2575 // Sometimes signals don't seem to quit the viewer. 2647 // Sometimes signals don't seem to quit the viewer.
2576 // Make sure we exit so as to not totally confuse the user. 2648 // Make sure we exit so as to not totally confuse the user.
2577 exit(1); 2649 exit(1);
2578#elif LL_LINUX 2650#elif LL_LINUX || LL_SOLARIS
2579 // Always generate the report, have the logger do the asking, and 2651 // Always generate the report, have the logger do the asking, and
2580 // don't wait for the logger before exiting (-> total cleanup). 2652 // don't wait for the logger before exiting (-> total cleanup).
2581 if (CRASH_BEHAVIOR_NEVER_SEND != gCrashBehavior) 2653 if (CRASH_BEHAVIOR_NEVER_SEND != gCrashBehavior)
@@ -2895,6 +2967,7 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
2895 LLURLSimString::sInstance.mX, 2967 LLURLSimString::sInstance.mX,
2896 LLURLSimString::sInstance.mY, 2968 LLURLSimString::sInstance.mY,
2897 LLURLSimString::sInstance.mZ); 2969 LLURLSimString::sInstance.mZ);
2970 LLFloaterWorldMap::show(NULL, TRUE);
2898 } 2971 }
2899 } 2972 }
2900 } 2973 }
@@ -3218,9 +3291,9 @@ void idle_shutdown()
3218 } 3291 }
3219 3292
3220 // close IM interface 3293 // close IM interface
3221 if(gIMView) 3294 if(gIMMgr)
3222 { 3295 {
3223 gIMView->disconnectAllSessions(); 3296 gIMMgr->disconnectAllSessions();
3224 } 3297 }
3225 3298
3226 // Wait for all floaters to get resolved 3299 // Wait for all floaters to get resolved
@@ -3933,78 +4006,22 @@ void idle()
3933 gObjectList.updateApparentAngles(gAgent); 4006 gObjectList.updateApparentAngles(gAgent);
3934 } 4007 }
3935 4008
3936 //////////////////////////////////////
3937 //
3938 // Audio stuff
3939 //
3940 //
3941
3942 if (gSavedSettings.getBOOL("MuteAudio"))
3943 { 4009 {
3944 LLMediaEngine::updateClass( 0.0f );
3945 }
3946 else
3947 {
3948 // only restore the volume if we're not minimized
3949 if ( ! gViewerWindow->mWindow->getMinimized() )
3950 LLMediaEngine::updateClass( gSavedSettings.getF32( "MediaAudioVolume" ) );
3951 };
3952
3953 if (gAudiop)
3954 {
3955 LLFastTimer t(LLFastTimer::FTM_AUDIO_UPDATE);
3956
3957 gFrameStats.start(LLFrameStats::AUDIO); 4010 gFrameStats.start(LLFrameStats::AUDIO);
3958 // update listener position because agent has moved 4011 LLFastTimer t(LLFastTimer::FTM_AUDIO_UPDATE);
3959
3960 LLVector3d lpos_global = gAgent.getCameraPositionGlobal();
3961 LLVector3 lpos_global_f;
3962 lpos_global_f.setVec(lpos_global);
3963
3964 gAudiop->setListener(lpos_global_f,
3965 // gCameraVelocitySmoothed,
3966 // LLVector3::zero,
3967 gAgent.getVelocity(), // !!! BUG need to replace this with smoothed velocity!
3968 gCamera->getUpAxis(),
3969 gCamera->getAtAxis());
3970 4012
3971 // this line rotates the wind vector to be listener (agent) relative 4013 audio_update_volume(false);
3972 // unfortunately we have to pre-translate to undo the translation that 4014 audio_update_listener();
3973 // occurs in the transform call 4015 audio_update_wind(false);
3974 gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal(gWindVec - gAgent.getVelocity());
3975 4016
3976#ifdef kAUDIO_ENABLE_WIND 4017 if (gAudiop)
3977 //
3978 // Extract height above water to modulate filter by whether above/below water
3979 //
3980 static F32 last_camera_water_height = -1000.f;
3981 LLVector3 camera_pos = gAgent.getCameraPositionAgent();
3982 F32 camera_water_height = camera_pos.mV[VZ] - gAgent.getRegion()->getWaterHeight();
3983
3984 //
3985 // Don't update rolloff factor unless water surface has been crossed
3986 //
3987 if ((last_camera_water_height * camera_water_height) < 0.f)
3988 { 4018 {
3989 if (camera_water_height < 0.f) 4019 // this line actually commits the changes we've made to source positions, etc.
3990 { 4020 const F32 max_audio_decode_time = 0.002f; // 2 ms decode time
3991 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff") * LL_ROLLOFF_MULTIPLIER_UNDER_WATER); 4021 gAudiop->idle(max_audio_decode_time);
3992 }
3993 else
3994 {
3995 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
3996 }
3997 } 4022 }
3998 last_camera_water_height = camera_water_height;
3999 gAudiop->updateWind(gRelativeWindVec, camera_water_height);
4000#endif
4001
4002
4003 // this line actually commits the changes we've made to source positions, etc.
4004 const F32 max_audio_decode_time = 0.002f; // 2 ms decode time
4005 gAudiop->idle(max_audio_decode_time);
4006 } 4023 }
4007 4024
4008 // Handle shutdown process, for example, 4025 // Handle shutdown process, for example,
4009 // wait for floaters to close, send quit message, 4026 // wait for floaters to close, send quit message,
4010 // forcibly quit if it has taken too long 4027 // forcibly quit if it has taken too long
@@ -4031,35 +4048,6 @@ F32 mouse_y_from_center(S32 y)
4031 4048
4032///////////////////////////////////////////////////////// 4049/////////////////////////////////////////////////////////
4033 4050
4034class AudioSettingsListener: public LLSimpleListener
4035{
4036 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4037 {
4038 // Note: Ignore the specific event value, look up the ones we want
4039 if (!gAudiop) return true;
4040 gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
4041 gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance"));
4042#ifdef kAUDIO_ENABLE_WIND
4043 // Wind Gain
4044 gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelWind");
4045 // Rolloff
4046 LLVector3 camera_pos = gAgent.getCameraPositionAgent();
4047 LLViewerRegion* region = gAgent.getRegion();
4048 F32 camera_water_height = region ? camera_pos.mV[VZ] - region->getWaterHeight() : 0.f;
4049 if (camera_water_height < 0.f)
4050 {
4051 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff") * LL_ROLLOFF_MULTIPLIER_UNDER_WATER);
4052 }
4053 else
4054 {
4055 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
4056 }
4057#endif
4058 return true;
4059 }
4060};
4061static AudioSettingsListener audio_settings_listener;
4062
4063void init_audio() 4051void init_audio()
4064{ 4052{
4065 if (!gAudiop) 4053 if (!gAudiop)
@@ -4125,24 +4113,133 @@ void init_audio()
4125 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen"))); 4113 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen")));
4126 } 4114 }
4127 4115
4116 audio_update_volume(true);
4117}
4118
4119void audio_update_volume(bool force_update)
4120{
4121 F32 master_volume = gSavedSettings.getF32("AudioLevelMaster");
4122 BOOL mute_audio = gSavedSettings.getBOOL("MuteAudio");
4123 if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
4124 {
4125 mute_audio = TRUE;
4126 }
4127 F32 mute_volume = mute_audio ? 0.0f : 1.0f;
4128
4129 // Sound Effects
4130 if (gAudiop)
4131 {
4132 gAudiop->setMasterGain ( master_volume );
4133
4134 gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
4135 gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance"));
4136 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
4128#ifdef kAUDIO_ENABLE_WIND 4137#ifdef kAUDIO_ENABLE_WIND
4129 gAudiop->enableWind(!mute_audio); 4138 gAudiop->enableWind(!mute_audio);
4130 gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelWind");
4131 gSavedSettings.getControl("AudioLevelWind")->addListener(&audio_settings_listener);
4132 gSavedSettings.getControl("AudioLevelRolloff")->addListener(&audio_settings_listener);
4133 // don't use the setter setMaxWindGain() because we don't
4134 // want to screw up the fade-in on startup by setting actual source gain
4135 // outside the fade-in.
4136#endif 4139#endif
4137 4140
4138 gAudiop->setMasterGain ( gSavedSettings.getF32 ( "AudioLevelMaster" ) ); 4141 gAudiop->setMuted(mute_audio);
4142
4143 if (force_update)
4144 {
4145 audio_update_wind(true);
4146 }
4147 }
4148
4149 // Streaming Music
4150 if (gAudiop)
4151 {
4152 F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
4153 music_volume = mute_volume * master_volume * (music_volume*music_volume);
4154 gAudiop->setInternetStreamGain ( music_volume );
4155 }
4156
4157 // Streaming Media
4158 if(LLMediaEngine::getInstance())
4159 {
4160 F32 media_volume = gSavedSettings.getF32("AudioLevelMedia");
4161 media_volume = mute_volume * master_volume * (media_volume*media_volume);
4162 LLMediaEngine::getInstance()->setVolume(media_volume);
4163 }
4164
4165 // Voice
4166 if (gVoiceClient)
4167 {
4168 F32 voice_volume = gSavedSettings.getF32("AudioLevelVoice");
4169 voice_volume = mute_volume * master_volume * voice_volume;
4170 gVoiceClient->setVoiceVolume(voice_volume);
4171 gVoiceClient->setMicGain(gSavedSettings.getF32("AudioLevelMic"));
4172
4173 if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
4174 {
4175 gVoiceClient->setMuteMic(true);
4176 }
4177 else
4178 {
4179 gVoiceClient->setMuteMic(false);
4180 }
4181 }
4182}
4183
4184void audio_update_listener()
4185{
4186 if (gAudiop)
4187 {
4188 // update listener position because agent has moved
4189 LLVector3d lpos_global = gAgent.getCameraPositionGlobal();
4190 LLVector3 lpos_global_f;
4191 lpos_global_f.setVec(lpos_global);
4192
4193 gAudiop->setListener(lpos_global_f,
4194 // gCameraVelocitySmoothed,
4195 // LLVector3::zero,
4196 gAgent.getVelocity(), // !!! *TODO: need to replace this with smoothed velocity!
4197 gCamera->getUpAxis(),
4198 gCamera->getAtAxis());
4199 }
4200}
4201
4202void audio_update_wind(bool force_update)
4203{
4204#ifdef kAUDIO_ENABLE_WIND
4205 //
4206 // Extract height above water to modulate filter by whether above/below water
4207 //
4208 LLViewerRegion* region = gAgent.getRegion();
4209 if (region)
4210 {
4211 static F32 last_camera_water_height = -1000.f;
4212 LLVector3 camera_pos = gAgent.getCameraPositionAgent();
4213 F32 camera_water_height = camera_pos.mV[VZ] - region->getWaterHeight();
4214
4215 //
4216 // Don't update rolloff factor unless water surface has been crossed
4217 //
4218 if (force_update || (last_camera_water_height * camera_water_height) < 0.f)
4219 {
4220 if (camera_water_height < 0.f)
4221 {
4222 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff") * LL_ROLLOFF_MULTIPLIER_UNDER_WATER);
4223 }
4224 else
4225 {
4226 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
4227 }
4228 }
4229 // this line rotates the wind vector to be listener (agent) relative
4230 // unfortunately we have to pre-translate to undo the translation that
4231 // occurs in the transform call
4232 gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal(gWindVec - gAgent.getVelocity());
4139 4233
4140 gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler")); 4234 // don't use the setter setMaxWindGain() because we don't
4141 gSavedSettings.getControl("AudioLevelDoppler")->addListener(&audio_settings_listener); 4235 // want to screw up the fade-in on startup by setting actual source gain
4142 gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance")); 4236 // outside the fade-in.
4143 gSavedSettings.getControl("AudioLevelDistance")->addListener(&audio_settings_listener); 4237 gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelAmbient");
4144 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff")); 4238
4145 gAudiop->setMuted(mute_audio); 4239 last_camera_water_height = camera_water_height;
4240 gAudiop->updateWind(gRelativeWindVec, camera_water_height);
4241 }
4242#endif
4146} 4243}
4147 4244
4148 4245
@@ -4291,7 +4388,8 @@ BOOL add_object( LLPCode pcode, S32 x, S32 y, U8 use_physics )
4291 // Play creation sound 4388 // Play creation sound
4292 if (gAudiop) 4389 if (gAudiop)
4293 { 4390 {
4294 gAudiop->triggerSound( LLUUID(gSavedSettings.getString("UISndObjectCreate")), gAgent.getID(), 1.f); 4391 F32 volume = gSavedSettings.getF32("AudioLevelUI");
4392 gAudiop->triggerSound( LLUUID(gSavedSettings.getString("UISndObjectCreate")), gAgent.getID(), volume);
4295 } 4393 }
4296 4394
4297 gMessageSystem->newMessageFast(_PREHASH_ObjectAdd); 4395 gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
@@ -4547,422 +4645,89 @@ void create_console()
4547} 4645}
4548#endif 4646#endif
4549 4647
4550class LLAFKTimeoutListener: public LLSimpleListener
4551{
4552 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4553 {
4554 gAFKTimeout = (F32) event->getValue().asReal();
4555 return true;
4556 }
4557};
4558static LLAFKTimeoutListener afk_timeout_listener;
4559
4560class LLMouseSensitivityListener: public LLSimpleListener
4561{
4562 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4563 {
4564 gMouseSensitivity = (F32) event->getValue().asReal();
4565 return true;
4566 }
4567};
4568static LLMouseSensitivityListener mouse_sensitivity_listener;
4569
4570
4571class LLInvertMouseListener: public LLSimpleListener
4572{
4573 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4574 {
4575 gInvertMouse = event->getValue().asBoolean();
4576 return true;
4577 }
4578};
4579static LLInvertMouseListener invert_mouse_listener;
4580
4581class LLRenderAvatarMouselookListener: public LLSimpleListener
4582{
4583 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4584 {
4585 LLVOAvatar::sVisibleInFirstPerson = event->getValue().asBoolean();
4586 return true;
4587 }
4588};
4589static LLRenderAvatarMouselookListener render_avatar_mouselook_listener;
4590
4591class LLRenderFarClipListener: public LLSimpleListener
4592{
4593 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4594 {
4595 F32 draw_distance = (F32) event->getValue().asReal();
4596 gAgent.mDrawDistance = draw_distance;
4597 if (gWorldPointer)
4598 {
4599 gWorldPointer->setLandFarClip(draw_distance);
4600 }
4601 return true;
4602 }
4603};
4604static LLRenderFarClipListener render_far_clip_listener;
4605
4606class LLTerrainDetailListener: public LLSimpleListener
4607{
4608 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4609 {
4610 LLDrawPoolTerrain::sDetailMode = event->getValue().asInteger();
4611 return true;
4612 }
4613};
4614static LLTerrainDetailListener terrain_detail_listener;
4615
4616
4617class LLSetShaderListener: public LLSimpleListener
4618{
4619 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4620 {
4621 LLShaderMgr::setShaders();
4622 return true;
4623 }
4624};
4625static LLSetShaderListener set_shader_listener;
4626
4627class LLReleaseGLBufferListener: public LLSimpleListener
4628{
4629 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4630 {
4631 gPipeline.releaseGLBuffers();
4632 LLShaderMgr::setShaders();
4633 return true;
4634 }
4635};
4636static LLReleaseGLBufferListener release_gl_buffer_listener;
4637 4648
4638class LLVolumeLODListener: public LLSimpleListener
4639{
4640 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4641 {
4642 LLVOVolume::sLODFactor = (F32) event->getValue().asReal();
4643 LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
4644 return true;
4645 }
4646};
4647static LLVolumeLODListener volume_lod_listener;
4648 4649
4649class LLAvatarLODListener: public LLSimpleListener 4650//-------------------------------------------------------------------
4650{ 4651//-------------------------------------------------------------------
4651 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 4652// Vector Performance Options
4652 { 4653//-------------------------------------------------------------------
4653 LLVOAvatar::sLODFactor = (F32) event->getValue().asReal(); 4654//-------------------------------------------------------------------
4654 return true;
4655 }
4656};
4657static LLAvatarLODListener avatar_lod_listener;
4658 4655
4659class LLTreeLODListener: public LLSimpleListener 4656// Initially, we test the performance of the vectorization code, then
4660{ 4657// turn it off if it ends up being slower. JC
4661 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 4658BOOL gVectorizePerfTest = TRUE;
4662 { 4659BOOL gVectorizeEnable = FALSE;
4663 LLVOTree::sTreeFactor = (F32) event->getValue().asReal(); 4660U32 gVectorizeProcessor = 0;
4664 return true; 4661BOOL gVectorizeSkin = FALSE;
4665 }
4666};
4667static LLTreeLODListener tree_lod_listener;
4668 4662
4669class LLFlexLODListener: public LLSimpleListener 4663void update_vector_performances(void)
4670{ 4664{
4671 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 4665 char *vp;
4672 { 4666
4673 LLVolumeImplFlexible::sUpdateFactor = (F32) event->getValue().asReal(); 4667 switch(gVectorizeProcessor)
4674 return true;
4675 }
4676};
4677static LLFlexLODListener flex_lod_listener;
4678
4679class LLGammaListener: public LLSimpleListener
4680{
4681 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4682 {
4683 F32 gamma = (F32) event->getValue().asReal();
4684 if (gamma == 0.0f)
4685 {
4686 gamma = 1.0f; // restore normal gamma
4687 }
4688 if (gamma != gViewerWindow->getWindow()->getGamma())
4689 {
4690 // Only save it if it's changed
4691 if (!gViewerWindow->getWindow()->setGamma(gamma))
4692 {
4693 llwarns << "setGamma failed!" << llendl;
4694 }
4695 }
4696
4697 return true;
4698 }
4699};
4700static LLGammaListener gamma_listener;
4701
4702class LLNightBrightnessListener: public LLSimpleListener
4703{
4704 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4705 {
4706 LLVOSky::sNighttimeBrightness = (F32) event->getValue().asReal();
4707 return true;
4708 }
4709};
4710static LLNightBrightnessListener night_brightness_listener;
4711
4712class LLFogRatioListener: public LLSimpleListener
4713{
4714 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4715 {
4716 F32 fog_ratio = llmax(MIN_USER_FOG_RATIO,
4717 llmin((F32) event->getValue().asReal(),
4718 MAX_USER_FOG_RATIO));
4719 gSky.setFogRatio(fog_ratio);
4720 return true;
4721 }
4722};
4723static LLFogRatioListener fog_ratio_listener;
4724
4725class LLMaxPartCountListener: public LLSimpleListener
4726{
4727 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4728 {
4729 LLViewerPartSim::setMaxPartCount(event->getValue().asInteger());
4730 return true;
4731 }
4732};
4733static LLMaxPartCountListener max_partCount_listener;
4734
4735class LLCompositeLimitListener: public LLSimpleListener
4736{
4737 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4738 {
4739 S32 composite_limit = llmax(MIN_USER_COMPOSITE_LIMIT,
4740 llmin((S32)event->getValue().asInteger(),
4741 MAX_USER_COMPOSITE_LIMIT));
4742 LLVOAvatar::sMaxOtherAvatarsToComposite = composite_limit;
4743 return true;
4744 }
4745};
4746static LLCompositeLimitListener composite_limit_listener;
4747
4748class LLVideoMemoryListener: public LLSimpleListener
4749{
4750 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4751 {
4752 gImageList.updateMaxResidentTexMem(event->getValue().asInteger());
4753 return true;
4754 }
4755};
4756static LLVideoMemoryListener video_memory_listener;
4757
4758class LLBandwidthListener: public LLSimpleListener
4759{
4760 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4761 {
4762 gViewerThrottle.setMaxBandwidth((F32) event->getValue().asReal());
4763 return true;
4764 }
4765};
4766static LLBandwidthListener bandwidth_listener;
4767
4768class LLChatFontSizeListener: public LLSimpleListener
4769{
4770 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4771 {
4772 gConsole->setFontSize(event->getValue().asInteger());
4773 return true;
4774 }
4775};
4776static LLChatFontSizeListener chat_font_size_listener;
4777
4778class LLChatPersistTimeListener: public LLSimpleListener
4779{
4780 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4781 {
4782 gConsole->setLinePersistTime((F32) event->getValue().asReal());
4783 return true;
4784 }
4785};
4786static LLChatPersistTimeListener chat_persist_time_listener;
4787
4788class LLConsoleMaxLinesListener: public LLSimpleListener
4789{
4790 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4791 {
4792 gConsole->setMaxLines(event->getValue().asInteger());
4793 return true;
4794 }
4795};
4796static LLConsoleMaxLinesListener console_max_lines_listener;
4797
4798
4799class LLMasterAudioListener: public LLSimpleListener
4800{
4801 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4802 {
4803 if(gAudiop)
4804 {
4805 gAudiop->setMasterGain ((F32) event->getValue().asReal() );
4806 }
4807
4808 if (LLMediaEngine::getInstance ()->isAvailable())
4809 {
4810 LLMediaEngine::getInstance ()->setVolume ((F32) event->getValue().asReal() );
4811 }
4812
4813 return true;
4814 }
4815};
4816
4817class LLJoystickListener : public LLSimpleListener
4818{
4819 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4820 {
4821 LLViewerJoystick::updateCamera(TRUE);
4822 return true;
4823 }
4824};
4825static LLJoystickListener joystick_listener;
4826
4827void stop_video();
4828void prepare_video(const LLParcel *parcel);
4829
4830static LLMasterAudioListener master_audio_listener;
4831
4832
4833class LLAudioStreamMusicListener: public LLSimpleListener
4834{
4835 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4836 { 4668 {
4837 if (gAudiop) 4669 case 2: vp = "SSE2"; break; // *TODO: replace the magic #s
4838 { 4670 case 1: vp = "SSE"; break;
4839 if ( event->getValue().asBoolean() ) 4671 default: vp = "COMPILER DEFAULT"; break;
4840 {
4841 if (gParcelMgr
4842 && gParcelMgr->getAgentParcel()
4843 && gParcelMgr->getAgentParcel()->getMusicURL())
4844 {
4845 // if stream is already playing, don't call this
4846 // otherwise music will briefly stop
4847 if ( ! gAudiop->isInternetStreamPlaying () )
4848 {
4849 gAudiop->startInternetStream(
4850 gParcelMgr->getAgentParcel()->getMusicURL());
4851 }
4852 }
4853 }
4854 else
4855 {
4856 gAudiop->stopInternetStream();
4857 }
4858 }
4859 return true;
4860 } 4672 }
4861}; 4673 llinfos << "Vectorization : " << ( gVectorizeEnable ? "ENABLED" : "DISABLED" ) << llendl ;
4862 4674 llinfos << "Vector Processor : " << vp << llendl ;
4863static LLAudioStreamMusicListener audio_stream_music_listener; 4675 llinfos << "Vectorized Skinning : " << ( gVectorizeSkin ? "ENABLED" : "DISABLED" ) << llendl ;
4864 4676
4865 4677 if(gVectorizeEnable && gVectorizeSkin)
4866
4867class LLAudioStreamMediaListener: public LLSimpleListener
4868{
4869 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4870 { 4678 {
4871 if (LLMediaEngine::getInstance() && LLMediaEngine::getInstance()->isAvailable()) 4679 switch(gVectorizeProcessor)
4872 { 4680 {
4873 if (event->getValue().asBoolean()) 4681 case 2:
4874 { 4682 LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometrySSE2;
4875 gMessageSystem->setHandlerFunc ( "ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media ); 4683 break;
4876 gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update ); 4684 case 1:
4877 if ( ( gParcelMgr ) && 4685 LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometrySSE;
4878 ( gParcelMgr->getAgentParcel () ) && 4686 break;
4879 ( gParcelMgr->getAgentParcel()->getMediaURL () ) ) 4687 default:
4880 { 4688 LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometryVectorized;
4881 prepare_video ( gParcelMgr->getAgentParcel () ); 4689 break;
4882 }
4883 }
4884 else
4885 {
4886 gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback);
4887 gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback );
4888 stop_video();
4889 }
4890 }
4891 else
4892 {
4893 if (gSavedSettings.getWarning("QuickTimeInstalled"))
4894 {
4895 gSavedSettings.setWarning("QuickTimeInstalled", FALSE);
4896
4897 LLNotifyBox::showXml("NoQuickTime" );
4898 }
4899 } 4690 }
4900
4901 return true;
4902 } 4691 }
4903}; 4692 else
4904
4905static LLAudioStreamMediaListener audio_stream_media_listener;
4906
4907
4908class LLAudioMuteListener: public LLSimpleListener
4909{
4910 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4911 { 4693 {
4912 if (gAudiop) 4694 LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometryOriginal;
4913 {
4914 gAudiop->setMuted(event->getValue().asBoolean());
4915 }
4916 return true;
4917 } 4695 }
4918}; 4696}
4919
4920static LLAudioMuteListener audio_mute_listener;
4921 4697
4922class LLUseOcclusionListener: public LLSimpleListener
4923{
4924 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4925 {
4926 LLPipeline::sUseOcclusion = (event->getValue().asBoolean() && gGLManager.mHasOcclusionQuery &&
4927 !gUseWireframe);
4928 return true;
4929 }
4930};
4931static LLUseOcclusionListener use_occlusion_listener;
4932 4698
4933class LLNumpadControlListener: public LLSimpleListener 4699class LLVectorizationEnableListener: public LLSimpleListener
4934{ 4700{
4935 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 4701 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4936 { 4702 {
4937 if (gKeyboard) 4703 gVectorizeEnable = event->getValue().asBoolean();
4938 { 4704 update_vector_performances();
4939 gKeyboard->setNumpadDistinct(static_cast<LLKeyboard::e_numpad_distinct>(event->getValue().asInteger()));
4940 }
4941 return true; 4705 return true;
4942 } 4706 }
4943}; 4707};
4708static LLVectorizationEnableListener vectorization_enable_listener;
4944 4709
4945static LLNumpadControlListener numpad_control_listener; 4710class LLVectorizeSkinListener: public LLSimpleListener
4946
4947class LLRenderUseVBOListener: public LLSimpleListener
4948{ 4711{
4949 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 4712 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4950 { 4713 {
4951 gPipeline.setUseVBO(event->getValue().asBoolean()); 4714 gVectorizeSkin = event->getValue().asBoolean();
4715 update_vector_performances();
4952 return true; 4716 return true;
4953 } 4717 }
4954}; 4718};
4955static LLRenderUseVBOListener render_use_vbo_listener; 4719static LLVectorizeSkinListener vectorize_skin_listener;
4956 4720
4957class LLRenderLightingDetailListener: public LLSimpleListener 4721class LLVectorProcessorListener: public LLSimpleListener
4958{ 4722{
4959 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) 4723 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4960 { 4724 {
4961 gPipeline.setLightingDetail(event->getValue().asInteger()); 4725 gVectorizeProcessor = event->getValue().asInteger();
4726 update_vector_performances();
4962 return true; 4727 return true;
4963 } 4728 }
4964}; 4729};
4965static LLRenderLightingDetailListener render_lighting_detail_listener; 4730static LLVectorProcessorListener vector_processor_listener;
4966 4731
4967// Use these strictly for things that are constructed at startup, 4732// Use these strictly for things that are constructed at startup,
4968// or for things that are performance critical. JC 4733// or for things that are performance critical. JC
@@ -5015,53 +4780,59 @@ void saved_settings_to_globals()
5015 gHandleKeysAsync = gSavedSettings.getBOOL("AsyncKeyboard"); 4780 gHandleKeysAsync = gSavedSettings.getBOOL("AsyncKeyboard");
5016 LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips"); 4781 LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips");
5017 4782
4783#if LL_VECTORIZE
4784 if (gSysCPU.hasAltivec())
4785 {
4786 gSavedSettings.setBOOL("VectorizeEnable", TRUE );
4787 gSavedSettings.setU32("VectorizeProcessor", 0 );
4788 }
4789 else
4790 if (gSysCPU.hasSSE2())
4791 {
4792 gSavedSettings.setBOOL("VectorizeEnable", TRUE );
4793 gSavedSettings.setU32("VectorizeProcessor", 2 );
4794 }
4795 else
4796 if (gSysCPU.hasSSE())
4797 {
4798 gSavedSettings.setBOOL("VectorizeEnable", TRUE );
4799 gSavedSettings.setU32("VectorizeProcessor", 1 );
4800 }
4801 else
4802 {
4803 // Don't bother testing or running if CPU doesn't support it. JC
4804 gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
4805 gSavedSettings.setBOOL("VectorizeEnable", FALSE );
4806 gSavedSettings.setU32("VectorizeProcessor", 0 );
4807 gSavedSettings.setBOOL("VectorizeSkin", FALSE);
4808 }
4809#else
4810 // This build target doesn't support SSE, don't test/run.
4811 gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
4812 gSavedSettings.setBOOL("VectorizeEnable", FALSE );
4813 gSavedSettings.setU32("VectorizeProcessor", 0 );
4814 gSavedSettings.setBOOL("VectorizeSkin", FALSE);
4815#endif
4816
4817 gVectorizePerfTest = gSavedSettings.getBOOL("VectorizePerfTest");
4818 gVectorizeEnable = gSavedSettings.getBOOL("VectorizeEnable");
4819 gVectorizeProcessor = gSavedSettings.getU32("VectorizeProcessor");
4820 gVectorizeSkin = gSavedSettings.getBOOL("VectorizeSkin");
4821 update_vector_performances();
4822
5018 // Into a global in case we corrupt the list on crash. 4823 // Into a global in case we corrupt the list on crash.
5019 gCrashBehavior = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING); 4824 gCrashBehavior = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING);
5020 4825
5021 //various listeners 4826 // propagate push to talk preference to current status
5022 gSavedSettings.getControl("FirstPersonAvatarVisible")->addListener(&render_avatar_mouselook_listener); 4827 gSavedSettings.setBOOL("PTTCurrentlyEnabled", gSavedSettings.getBOOL("EnablePushToTalk"));
5023 gSavedSettings.getControl("MouseSensitivity")->addListener(&mouse_sensitivity_listener); 4828
5024 gSavedSettings.getControl("InvertMouse")->addListener(&invert_mouse_listener); 4829 settings_setup_listeners();
5025 gSavedSettings.getControl("AFKTimeout")->addListener(&afk_timeout_listener);
5026 gSavedSettings.getControl("RenderFarClip")->addListener(&render_far_clip_listener);
5027 gSavedSettings.getControl("RenderTerrainDetail")->addListener(&terrain_detail_listener);
5028 gSavedSettings.getControl("RenderRippleWater")->addListener(&set_shader_listener);
5029 gSavedSettings.getControl("RenderAvatarVP")->addListener(&set_shader_listener);
5030 gSavedSettings.getControl("VertexShaderEnable")->addListener(&set_shader_listener);
5031 gSavedSettings.getControl("RenderDynamicReflections")->addListener(&set_shader_listener);
5032 gSavedSettings.getControl("RenderGlow")->addListener(&release_gl_buffer_listener);
5033 gSavedSettings.getControl("RenderGlowResolution")->addListener(&release_gl_buffer_listener);
5034 gSavedSettings.getControl("RenderAvatarMode")->addListener(&set_shader_listener);
5035 gSavedSettings.getControl("RenderVolumeLODFactor")->addListener(&volume_lod_listener);
5036 gSavedSettings.getControl("RenderAvatarLODFactor")->addListener(&avatar_lod_listener);
5037 gSavedSettings.getControl("RenderTreeLODFactor")->addListener(&tree_lod_listener);
5038 gSavedSettings.getControl("RenderFlexTimeFactor")->addListener(&flex_lod_listener);
5039 gSavedSettings.getControl("ThrottleBandwidthKBPS")->addListener(&bandwidth_listener);
5040 gSavedSettings.getControl("RenderGamma")->addListener(&gamma_listener);
5041 gSavedSettings.getControl("RenderNightBrightness")->addListener(&night_brightness_listener);
5042 gSavedSettings.getControl("RenderFogRatio")->addListener(&fog_ratio_listener);
5043 gSavedSettings.getControl("RenderMaxPartCount")->addListener(&max_partCount_listener);
5044 gSavedSettings.getControl("AvatarCompositeLimit")->addListener(&composite_limit_listener);
5045 gSavedSettings.getControl("GraphicsCardMemorySetting")->addListener(&video_memory_listener);
5046 gSavedSettings.getControl("ChatFontSize")->addListener(&chat_font_size_listener);
5047 gSavedSettings.getControl("ChatPersistTime")->addListener(&chat_persist_time_listener);
5048 gSavedSettings.getControl("ConsoleMaxLines")->addListener(&console_max_lines_listener);
5049 gSavedSettings.getControl("UseOcclusion")->addListener(&use_occlusion_listener);
5050 gSavedSettings.getControl("AudioLevelMaster")->addListener(&master_audio_listener);
5051 gSavedSettings.getControl("AudioStreamingMusic")->addListener(&audio_stream_music_listener);
5052 gSavedSettings.getControl("AudioStreamingVideo")->addListener(&audio_stream_media_listener);
5053 gSavedSettings.getControl("MuteAudio")->addListener(&audio_mute_listener);
5054 gSavedSettings.getControl("RenderVBOEnable")->addListener(&render_use_vbo_listener);
5055 gSavedSettings.getControl("RenderLightingDetail")->addListener(&render_lighting_detail_listener);
5056 gSavedSettings.getControl("NumpadControl")->addListener(&numpad_control_listener);
5057 gSavedSettings.getControl("FlycamAxis0")->addListener(&joystick_listener);
5058 gSavedSettings.getControl("FlycamAxis1")->addListener(&joystick_listener);
5059 gSavedSettings.getControl("FlycamAxis2")->addListener(&joystick_listener);
5060 gSavedSettings.getControl("FlycamAxis3")->addListener(&joystick_listener);
5061 gSavedSettings.getControl("FlycamAxis4")->addListener(&joystick_listener);
5062 gSavedSettings.getControl("FlycamAxis5")->addListener(&joystick_listener);
5063 gSavedSettings.getControl("FlycamAxis6")->addListener(&joystick_listener);
5064 4830
4831 // these are currently static in this file, so they can't move to settings_setup_listeners
4832 gSavedSettings.getControl("VectorizeEnable")->addListener(&vectorization_enable_listener);
4833 gSavedSettings.getControl("VectorizeProcessor")->addListener(&vector_processor_listener);
4834 gSavedSettings.getControl("VectorizeSkin")->addListener(&vectorize_skin_listener);
4835
5065 // gAgent.init() also loads from saved settings. 4836 // gAgent.init() also loads from saved settings.
5066} 4837}
5067 4838
@@ -5491,7 +5262,7 @@ void signal_handlers(S32 s)
5491 return; 5262 return;
5492 } 5263 }
5493 5264
5494# if LL_LINUX 5265# if LL_LINUX || LL_SOLARIS
5495 // Really useful to know what KIND of crash we got. 5266 // Really useful to know what KIND of crash we got.
5496 // Might want this on OSX too! 5267 // Might want this on OSX too!
5497 llwarns << "*** Caught signal " << s << llendl; 5268 llwarns << "*** Caught signal " << s << llendl;
@@ -5532,7 +5303,7 @@ void catch_signals()
5532 signal(SIGSYS, signal_handlers); 5303 signal(SIGSYS, signal_handlers);
5533 5304
5534 // SIGEMT is an 'emulator trap' which is not defined on linux. 5305 // SIGEMT is an 'emulator trap' which is not defined on linux.
5535#if !LL_LINUX 5306#if !LL_LINUX && !LL_SOLARIS
5536 signal(SIGEMT, signal_handlers); 5307 signal(SIGEMT, signal_handlers);
5537#endif 5308#endif
5538 5309
@@ -5847,6 +5618,10 @@ int parse_args(int argc, char **argv)
5847 { 5618 {
5848 gMultipleViewersOK = FALSE; 5619 gMultipleViewersOK = FALSE;
5849 } 5620 }
5621 else if (!strcmp(argv[j], "-novoice"))
5622 {
5623 gDisableVoice = TRUE;
5624 }
5850 else if (!strcmp(argv[j], "-nothread")) 5625 else if (!strcmp(argv[j], "-nothread"))
5851 { 5626 {
5852 LLVFile::ALLOW_ASYNC = FALSE; 5627 LLVFile::ALLOW_ASYNC = FALSE;
@@ -6232,6 +6007,8 @@ void send_logout_request()
6232 gLogoutTimer.reset(); 6007 gLogoutTimer.reset();
6233 gLogoutMaxTime = LOGOUT_REQUEST_TIME; 6008 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
6234 gLogoutRequestSent = TRUE; 6009 gLogoutRequestSent = TRUE;
6010
6011 gVoiceClient->leaveChannel();
6235 } 6012 }
6236} 6013}
6237 6014
@@ -6319,6 +6096,8 @@ void cleanup_app()
6319 // to ensure shutdown order 6096 // to ensure shutdown order
6320 LLMortician::setZealous(TRUE); 6097 LLMortician::setZealous(TRUE);
6321 6098
6099 LLVoiceClient::terminate();
6100
6322 disconnect_viewer(NULL); 6101 disconnect_viewer(NULL);
6323 6102
6324 llinfos << "Viewer disconnected" << llendflush; 6103 llinfos << "Viewer disconnected" << llendflush;
@@ -6362,6 +6141,9 @@ void cleanup_app()
6362 delete gGlobalEconomy; 6141 delete gGlobalEconomy;
6363 gGlobalEconomy = NULL; 6142 gGlobalEconomy = NULL;
6364 6143
6144 delete gLocalSpeakerMgr;
6145 gLocalSpeakerMgr = NULL;
6146
6365 LLNotifyBox::cleanup(); 6147 LLNotifyBox::cleanup();
6366 6148
6367 llinfos << "Global stuff deleted" << llendflush; 6149 llinfos << "Global stuff deleted" << llendflush;
@@ -6383,7 +6165,7 @@ void cleanup_app()
6383 6165
6384 LLMediaEngine::cleanupClass(); 6166 LLMediaEngine::cleanupClass();
6385 6167
6386 #if LL_QUICKTIME_ENABLED 6168#if LL_QUICKTIME_ENABLED
6387 if (gQuickTimeInitialized) 6169 if (gQuickTimeInitialized)
6388 { 6170 {
6389 // clean up media stuff 6171 // clean up media stuff
@@ -6394,9 +6176,14 @@ void cleanup_app()
6394 TerminateQTML (); 6176 TerminateQTML ();
6395 #endif 6177 #endif
6396 } 6178 }
6397 #endif
6398
6399 llinfos << "Quicktime cleaned up" << llendflush; 6179 llinfos << "Quicktime cleaned up" << llendflush;
6180#endif
6181
6182#if LL_GSTREAMER_ENABLED
6183 llinfos << "Cleaning up GStreamer" << llendl;
6184 UnloadGStreamer();
6185 llinfos << "GStreamer cleaned up" << llendflush;
6186#endif
6400 6187
6401 llinfos << "Cleaning up feature manager" << llendflush; 6188 llinfos << "Cleaning up feature manager" << llendflush;
6402 delete gFeatureManagerp; 6189 delete gFeatureManagerp;
@@ -6495,7 +6282,7 @@ void cleanup_app()
6495 llinfos << "VFS cleaned up" << llendflush; 6282 llinfos << "VFS cleaned up" << llendflush;
6496 6283
6497 // Store the time of our current logoff 6284 // Store the time of our current logoff
6498 gSavedPerAccountSettings.setU32("LastLogoff", time_corrected()); 6285 gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
6499 6286
6500 // Must do this after all panels have been deleted because panels that have persistent rects 6287 // Must do this after all panels have been deleted because panels that have persistent rects
6501 // save their rects on delete. 6288 // save their rects on delete.
@@ -6598,6 +6385,13 @@ void cleanup_app()
6598 end_messaging_system(); 6385 end_messaging_system();
6599} 6386}
6600 6387
6388// Clear URIs when picking a new server
6389void resetURIs()
6390{
6391 gLoginURIs.clear();
6392 gHelperURI.clear();
6393}
6394
6601const std::vector<std::string>& getLoginURIs() 6395const std::vector<std::string>& getLoginURIs()
6602{ 6396{
6603 if (gLoginURIs.empty()) 6397 if (gLoginURIs.empty())
diff --git a/linden/indra/newview/viewer.h b/linden/indra/newview/viewer.h
index 74ca366..ef975e7 100644
--- a/linden/indra/newview/viewer.h
+++ b/linden/indra/newview/viewer.h
@@ -104,6 +104,7 @@ extern const char* DEFAULT_SETTINGS_FILE;
104extern const U32 PATCH_SIZE; 104extern const U32 PATCH_SIZE;
105extern const LLVector3 DEFAULT_OBJECT_SCALE; 105extern const LLVector3 DEFAULT_OBJECT_SCALE;
106extern BOOL gDisconnected; 106extern BOOL gDisconnected;
107extern BOOL gDisableVoice;
107extern BOOL gQuit; // We're done, quit after processing this message. 108extern BOOL gQuit; // We're done, quit after processing this message.
108extern BOOL gQuitRequested; // User wants to quit, may have modified documents open. 109extern BOOL gQuitRequested; // User wants to quit, may have modified documents open.
109extern BOOL gLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. 110extern BOOL gLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim.
@@ -136,6 +137,7 @@ extern BOOL gDisplayFOV;
136extern BOOL gForceRenderLandFence; 137extern BOOL gForceRenderLandFence;
137 138
138extern BOOL gAllowIdleAFK; 139extern BOOL gAllowIdleAFK;
140extern F32 gAFKTimeout;
139extern BOOL gShowObjectUpdates; 141extern BOOL gShowObjectUpdates;
140 142
141extern BOOL gTeleportDisplay; 143extern BOOL gTeleportDisplay;
@@ -283,6 +285,10 @@ void kill_all_trees();
283void move_sun(); 285void move_sun();
284BOOL raycast_for_new_obj_pos( S32 x, S32 y, LLViewerObject** hit_obj, S32* hit_face, BOOL* b_hit_land, LLVector3* ray_start_region, LLVector3* ray_end_region, LLViewerRegion** region ); 286BOOL raycast_for_new_obj_pos( S32 x, S32 y, LLViewerObject** hit_obj, S32* hit_face, BOOL* b_hit_land, LLVector3* ray_start_region, LLVector3* ray_end_region, LLViewerRegion** region );
285 287
288void audio_update_volume(bool force_update = true);
289void audio_update_listener();
290void audio_update_wind(bool force_update = true);
291
286// Saves the final snapshot, but only once. 292// Saves the final snapshot, but only once.
287void save_final_snapshot(void*); 293void save_final_snapshot(void*);
288 294
@@ -336,5 +342,6 @@ void agent_send_reliable_message();
336// Helpers for URIs 342// Helpers for URIs
337const std::vector<std::string>& getLoginURIs(); 343const std::vector<std::string>& getLoginURIs();
338const std::string& getHelperURI(); 344const std::string& getHelperURI();
345void resetURIs();
339 346
340#endif 347#endif
diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py
index ccd6c6e..ecbeda2 100755
--- a/linden/indra/newview/viewer_manifest.py
+++ b/linden/indra/newview/viewer_manifest.py
@@ -32,7 +32,7 @@ import re
32import tarfile 32import tarfile
33viewer_dir = os.path.dirname(__file__) 33viewer_dir = os.path.dirname(__file__)
34# add llmanifest library to our path so we don't have to muck with PYTHONPATH 34# add llmanifest library to our path so we don't have to muck with PYTHONPATH
35sys.path.append(os.path.join(viewer_dir, '../lib/python/indra')) 35sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util'))
36from llmanifest import LLManifest, main, proper_windows_path, path_ancestors 36from llmanifest import LLManifest, main, proper_windows_path, path_ancestors
37 37
38class ViewerManifest(LLManifest): 38class ViewerManifest(LLManifest):
@@ -89,25 +89,42 @@ class ViewerManifest(LLManifest):
89 self.path("lsl_guide.html") 89 self.path("lsl_guide.html")
90 self.path("gpu_table.txt") 90 self.path("gpu_table.txt")
91 91
92 def channel_unique(self):
93 return self.args['channel'].replace("Second Life", "").strip()
94 def channel_oneword(self):
95 return "".join(self.channel_unique().split())
96 def channel_lowerword(self):
97 return self.channel_oneword().lower()
98
92 def flags_list(self): 99 def flags_list(self):
93 """ Convenience function that returns the command-line flags for the grid""" 100 """ Convenience function that returns the command-line flags for the grid"""
94 if(self.args['grid'] == ''): 101 channel_flags = ''
95 return "" 102 grid_flags = ''
96 elif(self.args['grid'] == 'firstlook'): 103 if not self.default_grid():
97 return '-settings settings_firstlook.xml' 104 if self.default_channel():
98 else: 105 # beta grid viewer
99 return ("-settings settings_beta.xml --%(grid)s -helperuri http://preview-%(grid)s.secondlife.com/helpers/" % {'grid':self.args['grid']}) 106 channel_flags = '-settings settings_beta.xml'
107 grid_flags = "--%(grid)s -helperuri http://preview-%(grid)s.secondlife.com/helpers/" % {'grid':self.args['grid']}
108
109 if not self.default_channel():
110 # some channel on some grid
111 channel_flags = '-settings settings_%s.xml -channel "%s"' % (self.channel_lowerword(), self.args['channel'])
112 return " ".join((grid_flags, channel_flags)).strip()
100 113
101 def login_url(self): 114 def login_url(self):
102 """ Convenience function that returns the appropriate login url for the grid""" 115 """ Convenience function that returns the appropriate login url for the grid"""
103 if(self.args.get('login_url')): 116 if(self.args.get('login_url')):
104 return self.args['login_url'] 117 return self.args['login_url']
105 else: 118 else:
106 if(self.args['grid'] == ''): 119 if(self.default_grid()):
107 return 'http://secondlife.com/app/login/' 120 if(self.default_channel()):
108 elif(self.args['grid'] == 'firstlook'): 121 # agni release
109 return 'http://secondlife.com/app/login/firstlook/' 122 return 'http://secondlife.com/app/login/'
123 else:
124 # first look (or other) on agni
125 return 'http://secondlife.com/app/login/%s/' % self.channel_lowerword()
110 else: 126 else:
127 # beta grid
111 return 'http://secondlife.com/app/login/beta/' 128 return 'http://secondlife.com/app/login/beta/'
112 129
113 def replace_login_url(self): 130 def replace_login_url(self):
@@ -117,14 +134,14 @@ class ViewerManifest(LLManifest):
117 134
118class WindowsManifest(ViewerManifest): 135class WindowsManifest(ViewerManifest):
119 def final_exe(self): 136 def final_exe(self):
120 # *NOTE: these are the only two executable names that the crash reporter recognizes 137 if self.default_channel():
121 if self.args['grid'] == '': 138 if self.default_grid():
122 return "SecondLife.exe" 139 return "SecondLife.exe"
123 elif self.args['grid'] == 'firstlook': 140 else:
124 return "SecondLifeFirstLook.exe" 141 return "SecondLifePreview.exe"
125 else: 142 else:
126 return "SecondLifePreview.exe" 143 return ''.join(self.args['channel'].split()) + '.exe'
127 # return "SecondLifePreview%s.exe" % (self.args['grid'], ) 144
128 145
129 def construct(self): 146 def construct(self):
130 super(WindowsManifest, self).construct() 147 super(WindowsManifest, self).construct()
@@ -174,6 +191,20 @@ class WindowsManifest(ViewerManifest):
174 self.path("res/*/*") 191 self.path("res/*/*")
175 self.end_prefix() 192 self.end_prefix()
176 193
194 # Vivox runtimes
195 if self.prefix(src="vivox-runtime/i686-win32", dst=""):
196 self.path("SLVoice.exe")
197 self.path("SLVoiceAgent.exe")
198 self.path("libeay32.dll")
199 self.path("srtp.dll")
200 self.path("ssleay32.dll")
201 self.path("tntk.dll")
202 self.path("alut.dll")
203 self.path("vivoxsdk.dll")
204 self.path("ortp.dll")
205 self.path("wrap_oal.dll")
206 self.end_prefix()
207
177# # pull in the crash logger and updater from other projects 208# # pull in the crash logger and updater from other projects
178# self.path(src="../win_crash_logger/win_crash_logger.exe", dst="win_crash_logger.exe") 209# self.path(src="../win_crash_logger/win_crash_logger.exe", dst="win_crash_logger.exe")
179 self.path(src="../win_updater/updater.exe", dst="updater.exe") 210 self.path(src="../win_updater/updater.exe", dst="updater.exe")
@@ -223,49 +254,75 @@ class WindowsManifest(ViewerManifest):
223 return result 254 return result
224 255
225 def package_finish(self): 256 def package_finish(self):
226 version_vars_template = """ 257 # a standard map of strings for replacing in the templates
258 substitution_strings = {
259 'version' : '.'.join(self.args['version']),
260 'version_short' : '.'.join(self.args['version'][:-1]),
261 'version_dashes' : '-'.join(self.args['version']),
262 'final_exe' : self.final_exe(),
263 'grid':self.args['grid'],
264 'grid_caps':self.args['grid'].upper(),
265 # escape quotes becase NSIS doesn't handle them well
266 'flags':self.flags_list().replace('"', '$\\"'),
267 'channel':self.args['channel'],
268 'channel_oneword':self.channel_oneword(),
269 'channel_unique':self.channel_unique(),
270 }
271
272 version_vars = """
227 !define INSTEXE "%(final_exe)s" 273 !define INSTEXE "%(final_exe)s"
228 !define VERSION "%(version_short)s" 274 !define VERSION "%(version_short)s"
229 !define VERSION_LONG "%(version)s" 275 !define VERSION_LONG "%(version)s"
230 !define VERSION_DASHES "%(version_dashes)s" 276 !define VERSION_DASHES "%(version_dashes)s"
231 """ 277 """ % substitution_strings
232 if(self.args['grid'] == ''): 278 if self.default_channel():
233 installer_file = "Second Life %(version_dashes)s Setup.exe" 279 if self.default_grid():
234 grid_vars_template = """ 280 # release viewer
235 OutFile "%(outfile)s" 281 installer_file = "Second Life %(version_dashes)s Setup.exe"
236 !define INSTFLAGS "%(flags)s" 282 grid_vars_template = """
237 !define INSTNAME "SecondLife" 283 OutFile "%(installer_file)s"
238 !define SHORTCUT "Second Life" 284 !define INSTFLAGS "%(flags)s"
239 !define URLNAME "secondlife" 285 !define INSTNAME "SecondLife"
240 Caption "Second Life ${VERSION}" 286 !define SHORTCUT "Second Life"
241 """ 287 !define URLNAME "secondlife"
288 Caption "Second Life ${VERSION}"
289 """
290 else:
291 # beta grid viewer
292 installer_file = "Second Life %(version_dashes)s (%(grid_caps)s) Setup.exe"
293 grid_vars_template = """
294 OutFile "%(installer_file)s"
295 !define INSTFLAGS "%(flags)s"
296 !define INSTNAME "SecondLife%(grid_caps)s"
297 !define SHORTCUT "Second Life (%(grid_caps)s)"
298 !define URLNAME "secondlife%(grid)s"
299 !define UNINSTALL_SETTINGS 1
300 Caption "Second Life %(grid)s ${VERSION}"
301 """
242 else: 302 else:
243 installer_file = "Second Life %(version_dashes)s (%(grid_caps)s) Setup.exe" 303 # some other channel on some grid
304 installer_file = "Second Life %(version_dashes)s %(channel_unique)s Setup.exe"
244 grid_vars_template = """ 305 grid_vars_template = """
245 OutFile "%(outfile)s" 306 OutFile "%(installer_file)s"
246 !define INSTFLAGS "%(flags)s" 307 !define INSTFLAGS "%(flags)s"
247 !define INSTNAME "SecondLife%(grid_caps)s" 308 !define INSTNAME "SecondLife%(channel_oneword)s"
248 !define SHORTCUT "Second Life (%(grid_caps)s)" 309 !define SHORTCUT "%(channel)s"
249 !define URLNAME "secondlife%(grid)s" 310 !define URLNAME "secondlife"
250 !define UNINSTALL_SETTINGS 1 311 !define UNINSTALL_SETTINGS 1
251 Caption "Second Life %(grid)s ${VERSION}" 312 Caption "%(channel)s ${VERSION}"
252 """ 313 """
253 if(self.args.has_key('installer_name')): 314 if(self.args.has_key('installer_name')):
254 installer_file = self.args['installer_name'] 315 installer_file = self.args['installer_name']
255 else: 316 else:
256 installer_file = installer_file % {'version_dashes' : '-'.join(self.args['version']), 317 installer_file = installer_file % substitution_strings
257 'grid_caps' : self.args['grid'].upper()} 318 substitution_strings['installer_file'] = installer_file
258 tempfile = "../secondlife_setup.nsi" 319
259 # the following is an odd sort of double-string replacement 320 tempfile = "../secondlife_setup_tmp.nsi"
321 # the following replaces strings in the nsi template
322 # it also does python-style % substitution
260 self.replace_in("installers/windows/installer_template.nsi", tempfile, { 323 self.replace_in("installers/windows/installer_template.nsi", tempfile, {
261 "%%VERSION%%":version_vars_template%{'version_short' : '.'.join(self.args['version'][:-1]), 324 "%%VERSION%%":version_vars,
262 'version' : '.'.join(self.args['version']), 325 "%%GRID_VARS%%":grid_vars_template % substitution_strings,
263 'version_dashes' : '-'.join(self.args['version']),
264 'final_exe' : self.final_exe()},
265 "%%GRID_VARS%%":grid_vars_template%{'grid':self.args['grid'],
266 'grid_caps':self.args['grid'].upper(),
267 'outfile':installer_file,
268 'flags':self.flags_list()},
269 "%%INSTALL_FILES%%":self.nsi_file_commands(True), 326 "%%INSTALL_FILES%%":self.nsi_file_commands(True),
270 "%%DELETE_FILES%%":self.nsi_file_commands(False)}) 327 "%%DELETE_FILES%%":self.nsi_file_commands(False)})
271 328
@@ -327,16 +384,26 @@ class DarwinManifest(ViewerManifest):
327 384
328 385
329 def package_finish(self): 386 def package_finish(self):
387 channel_standin = 'Second Life' # hah, our default channel is not usable on its own
388 if not self.default_channel():
389 channel_standin = self.args['channel']
390
330 imagename="SecondLife_" + '_'.join(self.args['version']) 391 imagename="SecondLife_" + '_'.join(self.args['version'])
331 if(self.args['grid'] != ''): 392 if self.default_channel():
332 imagename = imagename + '_' + self.args['grid'].upper() 393 if not self.default_grid():
394 # beta case
395 imagename = imagename + '_' + self.args['grid'].upper()
396 else:
397 # first look, etc
398 imagename = imagename + '_' + self.channel_oneword().upper()
333 399
334 sparsename = imagename + ".sparseimage" 400 sparsename = imagename + ".sparseimage"
335 finalname = imagename + ".dmg" 401 finalname = imagename + ".dmg"
336 # make sure we don't have stale files laying about 402 # make sure we don't have stale files laying about
337 self.remove(sparsename, finalname) 403 self.remove(sparsename, finalname)
338 404
339 self.run_command('hdiutil create "%(sparse)s" -volname "Second Life" -fs HFS+ -type SPARSE -megabytes 300' % {'sparse':sparsename}) 405 self.run_command('hdiutil create "%(sparse)s" -volname "Second Life" -fs HFS+ -type SPARSE -megabytes 300' % {
406 'sparse':sparsename})
340 407
341 # mount the image and get the name of the mount point and device node 408 # mount the image and get the name of the mount point and device node
342 hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"') 409 hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"')
@@ -344,15 +411,17 @@ class DarwinManifest(ViewerManifest):
344 volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip() 411 volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
345 412
346 # Copy everything in to the mounted .dmg 413 # Copy everything in to the mounted .dmg
347 # TODO change name of .app once mac_updater can handle it. 414 if self.default_channel() and not self.default_grid():
348 for s,d in { 415 app_name = "Second Life " + self.args['grid']
349 self.get_dst_prefix():"Second Life.app", 416 else:
350 "lsl_guide.html":"Linden Scripting Language Guide.html", 417 app_name = channel_standin.strip()
351 "releasenotes.txt":"Release Notes.txt",
352 "installers/darwin/mac_image_hidden":".hidden",
353 "installers/darwin/mac_image_background.tga":"background.tga",
354 "installers/darwin/mac_image_DS_Store":".DS_Store"}.items():
355 418
419 for s,d in {self.get_dst_prefix():app_name + ".app",
420 "lsl_guide.html":"Linden Scripting Language Guide.html",
421 "releasenotes.txt":"Release Notes.txt",
422 "installers/darwin/mac_image_hidden":".hidden",
423 "installers/darwin/mac_image_background.tga":"background.tga",
424 "installers/darwin/mac_image_DS_Store":".DS_Store"}.items():
356 print "Copying to dmg", s, d 425 print "Copying to dmg", s, d
357 self.copy_action(self.src_path_of(s), os.path.join(volpath, d)) 426 self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
358 427
@@ -390,8 +459,8 @@ class LinuxManifest(ViewerManifest):
390 if(self.args.has_key('installer_name')): 459 if(self.args.has_key('installer_name')):
391 installer_name = self.args['installer_name'] 460 installer_name = self.args['installer_name']
392 else: 461 else:
393 installer_name = '_'.join('SecondLife_', self.args.get('arch'), *self.args['version']) 462 installer_name = '_'.join(['SecondLife', self.args.get('arch'), '_'.join(self.args['version'])])
394 if grid != '': 463 if not self.default_grid():
395 installer_name += "_" + grid.upper() 464 installer_name += "_" + grid.upper()
396 465
397 # temporarily move directory tree so that it has the right name in the tarfile 466 # temporarily move directory tree so that it has the right name in the tarfile
@@ -433,8 +502,10 @@ class Linux_i686Manifest(LinuxManifest):
433# self.path("libstdc++.so.6") 502# self.path("libstdc++.so.6")
434 self.path("libuuid.so", "libuuid.so.1") 503 self.path("libuuid.so", "libuuid.so.1")
435 self.path("libSDL-1.2.so.0") 504 self.path("libSDL-1.2.so.0")
436 #self.path("libtcmalloc.so.0") 505 self.path("libELFIO.so")
437 #self.path("libstacktrace.so.0") 506 #self.path("libresolv.so") - don't bundle
507 #self.path("libtcmalloc.so.0") - bugged
508 #self.path("libstacktrace.so.0") - probably bugged
438# self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason 509# self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason
439 self.end_prefix("lib") 510 self.end_prefix("lib")
440 511
diff --git a/linden/indra/test/files.lst b/linden/indra/test/files.lst
index 8063bfd..d923d8f 100644
--- a/linden/indra/test/files.lst
+++ b/linden/indra/test/files.lst
@@ -8,6 +8,7 @@ test/llbuffer_tut.cpp
8test/lldate_tut.cpp 8test/lldate_tut.cpp
9test/llerror_tut.cpp 9test/llerror_tut.cpp
10test/llhost_tut.cpp 10test/llhost_tut.cpp
11test/llhttpdate_tut.cpp
11test/llhttpclient_tut.cpp 12test/llhttpclient_tut.cpp
12test/llhttpnode_tut.cpp 13test/llhttpnode_tut.cpp
13test/llinventoryparcel_tut.cpp 14test/llinventoryparcel_tut.cpp
diff --git a/linden/indra/test/llbuffer_tut.cpp b/linden/indra/test/llbuffer_tut.cpp
index bf58abb..afe3133 100644
--- a/linden/indra/test/llbuffer_tut.cpp
+++ b/linden/indra/test/llbuffer_tut.cpp
@@ -31,8 +31,10 @@
31#include <tut/tut.h> 31#include <tut/tut.h>
32#include "lltut.h" 32#include "lltut.h"
33#include "llbuffer.h" 33#include "llbuffer.h"
34#include "llerror.h"
34#include "llmemtype.h" 35#include "llmemtype.h"
35 36
37
36namespace tut 38namespace tut
37{ 39{
38 struct buffer 40 struct buffer
diff --git a/linden/indra/test/llhttpdate_tut.cpp b/linden/indra/test/llhttpdate_tut.cpp
new file mode 100644
index 0000000..5279a81
--- /dev/null
+++ b/linden/indra/test/llhttpdate_tut.cpp
@@ -0,0 +1,92 @@
1/**
2 * @file llhttpdate_tut.cpp
3 * @author Kartic Krishnamurthy
4 * @date Wednesday, 18 Jul 2007 17:00:00 GMT :)
5 *
6 * Copyright (c) 2007-2007, Linden Research, Inc.
7 *
8 * Second Life Viewer Source Code
9 * The source code in this file ("Source Code") is provided by Linden Lab
10 * to you under the terms of the GNU General Public License, version 2.0
11 * ("GPL"), unless you have obtained a separate licensing agreement
12 * ("Other License"), formally executed by you and Linden Lab. Terms of
13 * the GPL can be found in doc/GPL-license.txt in this distribution, or
14 * online at http://secondlife.com/developers/opensource/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at http://secondlife.com/developers/opensource/flossexception
20 *
21 * By copying, modifying or distributing this software, you acknowledge
22 * that you have read and understood your obligations described above,
23 * and agree to abide by those obligations.
24 *
25 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
26 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27 * COMPLETENESS OR PERFORMANCE.
28 */
29
30#include "linden_common.h"
31#include "lltut.h"
32
33#include "lldate.h"
34#include "llframetimer.h"
35
36#include <string>
37#include <time.h>
38
39namespace tut
40{
41 struct httpdate_data
42 {
43 LLDate some_date;
44 };
45 typedef test_group<httpdate_data> httpdate_test;
46 typedef httpdate_test::object httpdate_object;
47 tut::httpdate_test httpdate("httpdate");
48
49 template<> template<>
50 void httpdate_object::test<1>()
51 {
52 static std::string epoch_expected = "Thursday, 01 Jan 1970 00:00:00 GMT" ;
53 ensure("Check Epoch in RFC 1123", ( epoch_expected == some_date.asRFC1123()));
54 }
55
56 template<> template<>
57 void httpdate_object::test<2>()
58 {
59 static std::string expected = "Wednesday, 18 Jul 2007 22:17:24 GMT" ;
60 some_date = LLDate(1184797044.037586);
61 ensure("Check some timestamp in RFC 1123", ( expected == some_date.asRFC1123()));
62 }
63
64 // This test of course most generic.. runs off current time
65 template<> template<>
66 void httpdate_object::test<3>()
67 {
68 //F64 sometime = LLFrameTimer::getTotalSeconds();
69 time_t sometime;
70 time(&sometime);
71 some_date = LLDate((F64) sometime);
72 struct tm result;
73 char expected[255], *actual;
74
75 gmtime_r((time_t *)&sometime, &result);
76 /*
77 std::cout << " seconds: "<< result.tm_sec
78 << ", minutes: " << result.tm_min
79 << ", hours: " << result.tm_hour
80 << ", day of the month: " << result.tm_mday
81 << ", month: " << result.tm_mon
82 << ", year: " << result.tm_year
83 << ", day of the week: " << result.tm_wday
84 << ", day in the year: " << result.tm_yday
85 << ", DST: " << result.tm_isdst << std::endl;
86 */
87 strftime(expected, 255, "%A, %d %h %Y %H:%M:%S GMT", &result);
88 actual = (char *) some_date.asRFC1123().c_str();
89 // probably not a good idea to use strcmp but this is just a unit test
90 ensure("Current time in RFC 1123", (strcmp(expected, actual) == 0));
91 }
92}
diff --git a/linden/indra/test/llmessagetemplateparser_tut.cpp b/linden/indra/test/llmessagetemplateparser_tut.cpp
index 74b4c55..7e1f5a3 100644
--- a/linden/indra/test/llmessagetemplateparser_tut.cpp
+++ b/linden/indra/test/llmessagetemplateparser_tut.cpp
@@ -29,6 +29,7 @@
29 29
30#include <tut/tut.h> 30#include <tut/tut.h>
31#include "lltut.h" 31#include "lltut.h"
32#include "linden_common.h"
32#include "llmessagetemplateparser.h" 33#include "llmessagetemplateparser.h"
33 34
34namespace tut 35namespace tut
diff --git a/linden/indra/test/llpermissions_tut.cpp b/linden/indra/test/llpermissions_tut.cpp
index 0c9082b..3b2cee0 100644
--- a/linden/indra/test/llpermissions_tut.cpp
+++ b/linden/indra/test/llpermissions_tut.cpp
@@ -29,6 +29,7 @@
29 */ 29 */
30 30
31#include <tut/tut.h> 31#include <tut/tut.h>
32#include "linden_common.h"
32#include "lltut.h" 33#include "lltut.h"
33#include "message.h" 34#include "message.h"
34#include "llpermissions.h" 35#include "llpermissions.h"
diff --git a/linden/indra/test/llsdmessagereader_tut.cpp b/linden/indra/test/llsdmessagereader_tut.cpp
index 5b644d0..0dd8974 100755
--- a/linden/indra/test/llsdmessagereader_tut.cpp
+++ b/linden/indra/test/llsdmessagereader_tut.cpp
@@ -28,6 +28,7 @@
28 */ 28 */
29 29
30#include <tut/tut.h> 30#include <tut/tut.h>
31#include "linden_common.h"
31#include "lltut.h" 32#include "lltut.h"
32 33
33#include "message.h" 34#include "message.h"
diff --git a/linden/indra/test/llservicebuilder_tut.cpp b/linden/indra/test/llservicebuilder_tut.cpp
index 762aa46..3b9d8b4 100644
--- a/linden/indra/test/llservicebuilder_tut.cpp
+++ b/linden/indra/test/llservicebuilder_tut.cpp
@@ -92,5 +92,22 @@ namespace tut
92 std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map); 92 std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map);
93 ensure_equals("Replacement URL Creation for Non-existant Service", test_url , "/agent/{$agent-id}/name"); 93 ensure_equals("Replacement URL Creation for Non-existant Service", test_url , "/agent/{$agent-id}/name");
94 } 94 }
95
96 template<> template<>
97 void ServiceBuilderTestObject::test<5>()
98 {
99 LLSD test_block;
100 test_block["service-builder"] = "/proc/{$proc}{%params}";
101 mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]);
102 LLSD data_map;
103 data_map["proc"] = "do/something/useful";
104 data_map["params"]["estate_id"] = 1;
105 data_map["params"]["query"] = "public";
106 std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map);
107 ensure_equals(
108 "two part URL Creation",
109 test_url ,
110 "/proc/do/something/useful?estate_id=1&query=public");
111 }
95} 112}
96 113
diff --git a/linden/indra/test/lltemplatemessagebuilder_tut.cpp b/linden/indra/test/lltemplatemessagebuilder_tut.cpp
index d25e57e..5f58660 100644
--- a/linden/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/linden/indra/test/lltemplatemessagebuilder_tut.cpp
@@ -28,6 +28,7 @@
28 */ 28 */
29 29
30#include <tut/tut.h> 30#include <tut/tut.h>
31#include "linden_common.h"
31#include "lltut.h" 32#include "lltut.h"
32 33
33#include "llapr.h" 34#include "llapr.h"
diff --git a/linden/indra/test/lluri_tut.cpp b/linden/indra/test/lluri_tut.cpp
index a08fe4e..b49f6dd 100644
--- a/linden/indra/test/lluri_tut.cpp
+++ b/linden/indra/test/lluri_tut.cpp
@@ -165,8 +165,8 @@ namespace tut
165 query["123"] = "12"; 165 query["123"] = "12";
166 query["abcd"] = "abc"; 166 query["abcd"] = "abc";
167 checkParts(LLURI::buildHTTP("host", path, query), 167 checkParts(LLURI::buildHTTP("host", path, query),
168 "http", "//host/x/123?123=12&abcd=abc&", 168 "http", "//host/x/123?123=12&abcd=abc",
169 "host", "/x/123", "123=12&abcd=abc&"); 169 "host", "/x/123", "123=12&abcd=abc");
170 } 170 }
171 171
172 template<> template<> 172 template<> template<>
@@ -191,8 +191,8 @@ namespace tut
191 query["123"] = "?&*#//"; 191 query["123"] = "?&*#//";
192 query["**@&?//"] = "abc"; 192 query["**@&?//"] = "abc";
193 checkParts(LLURI::buildHTTP("host", path, query), 193 checkParts(LLURI::buildHTTP("host", path, query),
194 "http", "//host/x/123?**@&?//=abc&123=?&*#//&", 194 "http", "//host/x/123?**@&?//=abc&123=?&*#//",
195 "host", "/x/123", "**@&?//=abc&123=?&*#//&"); 195 "host", "/x/123", "**@&?//=abc&123=?&*#//");
196 } 196 }
197 197
198 template<> template<> 198 template<> template<>
@@ -206,8 +206,8 @@ namespace tut
206 query["123"] = "12"; 206 query["123"] = "12";
207 query["abcd"] = "abc"; 207 query["abcd"] = "abc";
208 checkParts(LLURI::buildHTTP("hi123*33--}{:portstuffs", path, query), 208 checkParts(LLURI::buildHTTP("hi123*33--}{:portstuffs", path, query),
209 "http", "//hi123*33--}{:portstuffs/x/123?123=12&abcd=abc&", 209 "http", "//hi123*33--}{:portstuffs/x/123?123=12&abcd=abc",
210 "hi123*33--}{:portstuffs", "/x/123", "123=12&abcd=abc&"); 210 "hi123*33--}{:portstuffs", "/x/123", "123=12&abcd=abc");
211 } 211 }
212 212
213 template<> template<> 213 template<> template<>
diff --git a/linden/indra/test/message_tut.cpp b/linden/indra/test/message_tut.cpp
index 366c2b4..3425315 100644
--- a/linden/indra/test/message_tut.cpp
+++ b/linden/indra/test/message_tut.cpp
@@ -28,6 +28,7 @@
28 */ 28 */
29 29
30#include <tut/tut.h> 30#include <tut/tut.h>
31#include "linden_common.h"
31#include "lltut.h" 32#include "lltut.h"
32 33
33#include "llapr.h" 34#include "llapr.h"
diff --git a/linden/indra/test/test_llmanifest.py b/linden/indra/test/test_llmanifest.py
index f503cbe..8bfca24 100644
--- a/linden/indra/test/test_llmanifest.py
+++ b/linden/indra/test/test_llmanifest.py
@@ -26,7 +26,7 @@
26# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 26# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27# COMPLETENESS OR PERFORMANCE. 27# COMPLETENESS OR PERFORMANCE.
28 28
29from indra import llmanifest 29from indra.util import llmanifest
30import os.path 30import os.path
31import os 31import os
32import unittest 32import unittest
diff --git a/linden/indra/win_crash_logger/resource.h b/linden/indra/win_crash_logger/resource.h
index fb7ae29..ee6bf3d 100644
--- a/linden/indra/win_crash_logger/resource.h
+++ b/linden/indra/win_crash_logger/resource.h
@@ -1,31 +1,3 @@
1/**
2 * @file resource.h
3 * @brief Resources for windows crash logger
4 *
5 * Copyright (c) 2003-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29//{{NO_DEPENDENCIES}} 1//{{NO_DEPENDENCIES}}
30// Microsoft Visual C++ generated include file. 2// Microsoft Visual C++ generated include file.
31// Used by win_crash_logger.rc 3// Used by win_crash_logger.rc
diff --git a/linden/indra/win_crash_logger/win_crash_logger.rc b/linden/indra/win_crash_logger/win_crash_logger.rc
index f4c7eaa..2c46859 100644
--- a/linden/indra/win_crash_logger/win_crash_logger.rc
+++ b/linden/indra/win_crash_logger/win_crash_logger.rc
@@ -81,14 +81,10 @@ BEGIN
81 BS_AUTOCHECKBOX | WS_TABSTOP,4,106,89,13 81 BS_AUTOCHECKBOX | WS_TABSTOP,4,106,89,13
82 LTEXT "Sending crash reports is the best way to help us improve the quality of %s.", 82 LTEXT "Sending crash reports is the best way to help us improve the quality of %s.",
83 IDC_STATIC_MOTIVATION,4,38,288,8 83 IDC_STATIC_MOTIVATION,4,38,288,8
84 LTEXT "If you continue to experience this problem, please try one of the following:", 84 LTEXT "If you continue to experience this problem, please try:",
85 IDC_STATIC,4,57,251,8 85 IDC_STATIC,4,57,251,8
86 LTEXT "- Contact support by email at support@lindenlab.com", 86 LTEXT "- Contacting support by visiting http://www.secondlife.com/support",
87 IDC_STATIC,4,67,179,8 87 IDC_STATIC,4,67,231,8
88 LTEXT "- If you can log-in, please contact Live Help by using menu Help > Live Help.",
89 IDC_STATIC,4,87,249,8
90 LTEXT "- Search the Second Life Knowledge Base at http://secondlife.com/knowledgebase/",
91 IDC_STATIC,4,77,281,8,SS_NOTIFY
92END 88END
93 89
94IDD_PREVREPORTBOX DIALOG 100, 100, 232, 213 90IDD_PREVREPORTBOX DIALOG 100, 100, 232, 213
diff --git a/linden/scripts/template_verifier.py b/linden/scripts/template_verifier.py
index 1bc03e7..68d82ca 100755
--- a/linden/scripts/template_verifier.py
+++ b/linden/scripts/template_verifier.py
@@ -42,37 +42,49 @@ import os
42import sys 42import sys
43import urllib 43import urllib
44 44
45from indra import compatibility 45from indra.ipc import compatibility
46from indra import llmessage 46from indra.ipc import tokenstream
47 47from indra.ipc import llmessage
48def die(msg):
49 print >>sys.stderr, msg
50 sys.exit(1)
51
52MESSAGE_TEMPLATE = 'message_template.msg'
53
54PRODUCTION_ACCEPTABLE = (compatibility.Same, compatibility.Newer)
55DEVELOPMENT_ACCEPTABLE = (
56 compatibility.Same, compatibility.Newer,
57 compatibility.Older, compatibility.Mixed)
58 48
59def getstatusall(command): 49def getstatusall(command):
60 """ Like commands.getstatusoutput, but returns stdout and 50 """ Like commands.getstatusoutput, but returns stdout and
61 stderr separately(to get around "killed by signal 15" getting 51 stderr separately(to get around "killed by signal 15" getting
62 included as part of the file). Also, works on Windows.""" 52 included as part of the file). Also, works on Windows."""
63 (input, out, err) = os.popen3(command, 't') 53 (input, out, err) = os.popen3(command, 't')
64 input.close() # send no input to the command 54 status = input.close() # send no input to the command
65 output = out.read() 55 output = out.read()
66 error = err.read() 56 error = err.read()
67 out.close() 57 status = out.close()
68 status = err.close() # the status comes from the *last* pipe you close 58 status = err.close() # the status comes from the *last* pipe that is closed
69 return status, output, error 59 return status, output, error
70 60
71def getstatusoutput(command): 61def getstatusoutput(command):
72 status, output, error = getstatusall(command) 62 status, output, error = getstatusall(command)
73 return status, output 63 return status, output
74 64
75def compare(base, current, mode): 65
66def die(msg):
67 print >>sys.stderr, msg
68 sys.exit(1)
69
70MESSAGE_TEMPLATE = 'message_template.msg'
71
72PRODUCTION_ACCEPTABLE = (compatibility.Same, compatibility.Newer)
73DEVELOPMENT_ACCEPTABLE = (
74 compatibility.Same, compatibility.Newer,
75 compatibility.Older, compatibility.Mixed)
76
77MAX_MASTER_AGE = 60 * 60 * 4 # refresh master cache every 4 hours
78
79def retry(times, function, *args, **kwargs):
80 for i in range(times):
81 try:
82 return function(*args, **kwargs)
83 except Exception, e:
84 if i == times - 1:
85 raise e # we retried all the times we could
86
87def compare(base_parsed, current_parsed, mode):
76 """Compare the current template against the base template using the given 88 """Compare the current template against the base template using the given
77 'mode' strictness: 89 'mode' strictness:
78 90
@@ -85,10 +97,8 @@ def compare(base, current, mode):
85 Returns a tuple of (bool, Compatibility) 97 Returns a tuple of (bool, Compatibility)
86 Return True if they are compatible in this mode, False if not. 98 Return True if they are compatible in this mode, False if not.
87 """ 99 """
88 base = llmessage.parseTemplateString(base)
89 current = llmessage.parseTemplateString(current)
90 100
91 compat = current.compatibleWithBase(base) 101 compat = current_parsed.compatibleWithBase(base_parsed)
92 if mode == 'production': 102 if mode == 'production':
93 acceptable = PRODUCTION_ACCEPTABLE 103 acceptable = PRODUCTION_ACCEPTABLE
94 else: 104 else:
@@ -98,12 +108,61 @@ def compare(base, current, mode):
98 return True, compat 108 return True, compat
99 return False, compat 109 return False, compat
100 110
111def fetch(url):
112 if url.startswith('file://'):
113 # just open the file directly because urllib is dumb about these things
114 file_name = url[len('file://'):]
115 return open(file_name).read()
116 else:
117 # *FIX: this doesn't throw an exception for a 404, and oddly enough the sl.com 404 page actually gets parsed successfully
118 return ''.join(urllib.urlopen(url).readlines())
119
120def cache_master(master_url):
121 """Using the url for the master, updates the local cache, and returns an url to the local cache."""
122 master_cache = local_master_cache_filename()
123 master_cache_url = 'file://' + master_cache
124 # decide whether to refresh the master cache based on its age
125 import time
126 if (os.path.exists(master_cache)
127 and time.time() - os.path.getmtime(master_cache) < MAX_MASTER_AGE):
128 return master_cache_url # our cache is fresh
129 # new master doesn't exist or isn't fresh
130 print "Refreshing master cache from %s" % master_url
131 def get_and_test_master():
132 new_master_contents = fetch(master_url)
133 llmessage.parseTemplateString(new_master_contents)
134 return new_master_contents
135 try:
136 new_master_contents = retry(3, get_and_test_master)
137 except IOError, e:
138 # the refresh failed, so we should just soldier on
139 print "WARNING: unable to download new master, probably due to network error. Your message template compatibility may be suspect."
140 print "Cause: %s" % e
141 return master_cache_url
142 try:
143 mc = open(master_cache, 'wb')
144 mc.write(new_master_contents)
145 mc.close()
146 except IOError, e:
147 print "WARNING: Unable to write master message template to %s, proceeding without cache." % master_cache
148 print "Cause: %s" % e
149 return master_url
150 return master_cache_url
151
101def local_template_filename(): 152def local_template_filename():
102 """Returns the message template's default location relative to template_verifier.py: 153 """Returns the message template's default location relative to template_verifier.py:
103 ./messages/message_template.msg.""" 154 ./messages/message_template.msg."""
104 d = os.path.dirname(os.path.realpath(__file__)) 155 d = os.path.dirname(os.path.realpath(__file__))
105 return os.path.join(d, 'messages', MESSAGE_TEMPLATE) 156 return os.path.join(d, 'messages', MESSAGE_TEMPLATE)
106 157
158def local_master_cache_filename():
159 """Returns the location of the master template cache (which is in the system tempdir)
160 <temp_dir>/master_message_template_cache.msg"""
161 import tempfile
162 d = tempfile.gettempdir()
163 return os.path.join(d, 'master_message_template_cache.msg')
164
165
107def run(sysargs): 166def run(sysargs):
108 parser = optparse.OptionParser( 167 parser = optparse.OptionParser(
109 usage="usage: %prog [FILE] [FILE]", 168 usage="usage: %prog [FILE] [FILE]",
@@ -120,43 +179,69 @@ http://wiki.secondlife.com/wiki/Template_verifier.py
120 '-u', '--master_url', type='string', dest='master_url', 179 '-u', '--master_url', type='string', dest='master_url',
121 default='http://secondlife.com/app/message_template/master_message_template.msg', 180 default='http://secondlife.com/app/message_template/master_message_template.msg',
122 help="""The url of the master message template.""") 181 help="""The url of the master message template.""")
182 parser.add_option(
183 '-c', '--cache_master', action='store_true', dest='cache_master',
184 default=False, help="""Set to true to attempt use local cached copy of the master template.""")
123 185
124 options, args = parser.parse_args(sysargs) 186 options, args = parser.parse_args(sysargs)
125 187
188 if options.mode == 'production':
189 options.cache_master = False
190
126 # both current and master supplied in positional params 191 # both current and master supplied in positional params
127 if len(args) == 2: 192 if len(args) == 2:
128 master_filename, current_filename = args 193 master_filename, current_filename = args
129 print "base:", master_filename 194 print "master:", master_filename
130 print "current:", current_filename 195 print "current:", current_filename
131 master = file(master_filename).read() 196 master_url = 'file://%s' % master_filename
132 current = file(current_filename).read() 197 current_url = 'file://%s' % current_filename
133 # only current supplied in positional param 198 # only current supplied in positional param
134 elif len(args) == 1: 199 elif len(args) == 1:
135 master = None 200 master_url = None
136 current_filename = args[0] 201 current_filename = args[0]
137 print "base: <master template from repository>" 202 print "master:", options.master_url
138 print "current:", current_filename 203 print "current:", current_filename
139 current = file(current_filename).read() 204 current_url = 'file://%s' % current_filename
140 # nothing specified, use defaults for everything 205 # nothing specified, use defaults for everything
141 elif len(args) == 0: 206 elif len(args) == 0:
142 master = None 207 master_url = None
143 current = None 208 current_url = None
144 else: 209 else:
145 die("Too many arguments") 210 die("Too many arguments")
146 211
147 # fetch the master from the url (default or supplied) 212 if master_url is None:
148 if master is None: 213 master_url = options.master_url
149 master = urllib.urlopen(options.master_url).read() 214
150 215 if current_url is None:
151 # fetch the template for this build
152 if current is None:
153 current_filename = local_template_filename() 216 current_filename = local_template_filename()
154 print "base: <master template from repository>" 217 print "master:", options.master_url
155 print "current:", current_filename 218 print "current:", current_filename
156 current = file(current_filename).read() 219 current_url = 'file://%s' % current_filename
220
221 # retrieve the contents of the local template and check for syntax
222 current = fetch(current_url)
223 current_parsed = llmessage.parseTemplateString(current)
224
225 if options.cache_master:
226 # optionally return a url to a locally-cached master so we don't hit the network all the time
227 master_url = cache_master(master_url)
157 228
229 def parse_master_url():
230 master = fetch(master_url)
231 return llmessage.parseTemplateString(master)
232 try:
233 master_parsed = retry(3, parse_master_url)
234 except (IOError, tokenstream.ParseError), e:
235 if options.mode == 'production':
236 raise e
237 else:
238 print "WARNING: problems retrieving the master from %s." % master_url
239 print "Syntax-checking the local template ONLY, no compatibility check is being run."
240 print "Cause: %s\n\n" % e
241 return 0
242
158 acceptable, compat = compare( 243 acceptable, compat = compare(
159 master, current, options.mode) 244 master_parsed, current_parsed, options.mode)
160 245
161 def explain(header, compat): 246 def explain(header, compat):
162 print header 247 print header