From c07901e29ed545bbb02e3bddf148fe1104b94e9f Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Fri, 15 Aug 2008 23:44:56 -0500 Subject: Second Life viewer sources 1.15.1.3 --- linden/doc/contributions.txt | 14 +- linden/indra/SConstruct | 25 +- linden/indra/llaudio/audioengine.cpp | 24 +- linden/indra/llaudio/audioengine_fmod.cpp | 2 +- linden/indra/llcharacter/llkeyframemotion.cpp | 89 +- linden/indra/llcharacter/llkeyframemotionparam.cpp | 6 + linden/indra/llcharacter/llstatemachine.cpp | 30 +- linden/indra/llcharacter/llvisualparam.cpp | 12 +- linden/indra/llcommon/llstat.cpp | 6 +- linden/indra/llcommon/llstring.h | 2 +- linden/indra/llcommon/llstringtable.h | 6 - linden/indra/llcommon/lluri.cpp | 84 +- linden/indra/llcommon/lluri.h | 2 + linden/indra/llcommon/llversion.h | 4 +- linden/indra/llimage/llimage.cpp | 2 +- linden/indra/llinventory/files.lst | 1 + linden/indra/llinventory/lleconomy.cpp | 2 + linden/indra/llinventory/lleconomy.h | 2 + linden/indra/llinventory/llinventory.cpp | 225 +---- linden/indra/llinventory/llinventory.h | 58 +- linden/indra/llinventory/llinventory.vcproj | 9 + linden/indra/llinventory/llinventorytype.cpp | 222 +++++ linden/indra/llinventory/llinventorytype.h | 94 ++ linden/indra/llinventory/llparcel.cpp | 20 +- linden/indra/llinventory/llparcel.h | 10 +- linden/indra/llinventory/llpermissions.cpp | 8 - linden/indra/llmath/llcamera.cpp | 2 +- linden/indra/llmath/llmath.h | 21 + linden/indra/llmath/llrand.cpp | 4 +- linden/indra/llmath/lluuid.cpp | 2 +- linden/indra/llmath/llvolume.cpp | 27 +- linden/indra/llmessage/llassetstorage.cpp | 41 - linden/indra/llmessage/llassetstorage.h | 11 +- linden/indra/llmessage/llcachename.cpp | 95 +- linden/indra/llmessage/llcachename.h | 3 +- linden/indra/llmessage/llcircuit.cpp | 8 +- linden/indra/llmessage/llcircuit.h | 4 +- linden/indra/llmessage/lldatapacker.cpp | 80 +- linden/indra/llmessage/llhttpassetstorage.cpp | 39 + linden/indra/llmessage/llhttpassetstorage.h | 4 + linden/indra/llmessage/llhttpclient.cpp | 9 + linden/indra/llmessage/llhttpclient.h | 1 + linden/indra/llmessage/lliohttpserver.cpp | 44 +- linden/indra/llmessage/lliohttpserver.h | 20 +- linden/indra/llmessage/lliosocket.cpp | 15 +- linden/indra/llmessage/llmail.cpp | 2 +- linden/indra/llmessage/llmessage.vcproj | 3 + linden/indra/llmessage/llpacketbuffer.cpp | 10 +- linden/indra/llmessage/llregionflags.h | 3 +- linden/indra/llmessage/lltransfermanager.cpp | 1 + linden/indra/llmessage/llurlrequest.cpp | 5 +- linden/indra/llmessage/llxfer_file.cpp | 23 +- linden/indra/llmessage/llxfer_mem.cpp | 3 +- linden/indra/llmessage/llxfermanager.cpp | 8 +- linden/indra/llmessage/message.cpp | 45 +- linden/indra/llprimitive/llprimitive.cpp | 15 +- linden/indra/llrender/llfontgl.cpp | 32 +- linden/indra/llrender/llfontgl.h | 3 +- linden/indra/llrender/llimagegl.cpp | 24 +- linden/indra/llui/llbutton.cpp | 2 +- linden/indra/llui/llcombobox.cpp | 22 +- linden/indra/llui/llcombobox.h | 3 +- linden/indra/llui/lldraghandle.cpp | 1 + linden/indra/llui/llfloater.cpp | 21 +- linden/indra/llui/lllineeditor.cpp | 10 +- linden/indra/llui/llmemberlistener.h | 0 linden/indra/llui/llmenugl.cpp | 20 +- linden/indra/llui/llpanel.cpp | 2 +- linden/indra/llui/lltabcontainer.cpp | 8 +- linden/indra/llui/lltabcontainervertical.cpp | 4 +- linden/indra/llui/lltextbox.cpp | 16 +- linden/indra/llui/lltextbox.h | 4 +- linden/indra/llui/lltexteditor.cpp | 20 +- linden/indra/llui/llui.cpp | 18 + linden/indra/llui/lluistring.cpp | 0 linden/indra/llui/lluistring.h | 0 linden/indra/llui/llviewborder.cpp | 2 +- linden/indra/llui/llviewborder.h | 2 +- linden/indra/llvfs/llvfs.cpp | 7 +- linden/indra/llwindow/llwindow_vc8.vcproj | 240 ++++- linden/indra/llwindow/llwindowsdl.cpp | 288 +++--- linden/indra/llwindow/llwindowwin32.cpp | 53 +- linden/indra/llwindow/llwindowwin32.h | 2 +- linden/indra/llxml/llxmlnode.cpp | 6 + linden/indra/lscript/lscript_alloc.h | 4 +- .../indra/lscript/lscript_compile/lscript_tree.cpp | 2 + .../lscript/lscript_execute/lscript_execute.cpp | 120 ++- .../lscript/lscript_execute/lscript_readlso.cpp | 1 - .../lscript/lscript_library/lscript_library.cpp | 7 +- .../indra/newview/English.lproj/InfoPlist.strings | 4 +- linden/indra/newview/Info-SecondLife.plist | 2 +- linden/indra/newview/app_settings/keys.ini | 22 + linden/indra/newview/featuretable_linux.txt | 173 ++++ linden/indra/newview/files.lst | 1 + linden/indra/newview/gpu_table.txt | 8 +- linden/indra/newview/linux_tools/client-readme.txt | 1 - linden/indra/newview/linux_tools/launch_url.sh | 2 +- linden/indra/newview/linux_tools/wrapper.sh | 2 + linden/indra/newview/llagent.cpp | 2 +- linden/indra/newview/llassetuploadresponders.cpp | 2 +- linden/indra/newview/llcallingcard.cpp | 31 +- linden/indra/newview/llchatbar.cpp | 3 +- linden/indra/newview/llcontroldef.cpp | 15 +- linden/indra/newview/lldebugmessagebox.cpp | 22 +- linden/indra/newview/lldrawpoolavatar.cpp | 11 +- linden/indra/newview/lldriverparam.cpp | 2 +- linden/indra/newview/lleventpoll.cpp | 2 +- linden/indra/newview/llfasttimerview.cpp | 9 + linden/indra/newview/llfeaturemanager.cpp | 2 + linden/indra/newview/llfilepicker.cpp | 15 +- linden/indra/newview/llfloateranimpreview.cpp | 8 +- linden/indra/newview/llfloateravatarinfo.cpp | 6 +- linden/indra/newview/llfloaterfriends.cpp | 4 +- linden/indra/newview/llfloatergroupinfo.cpp | 4 +- linden/indra/newview/llfloaterhtml.cpp | 22 +- linden/indra/newview/llfloaterhtml.h | 4 +- linden/indra/newview/llfloaterimport.cpp | 8 +- linden/indra/newview/llfloaterinspect.cpp | 80 +- linden/indra/newview/llfloaterland.cpp | 37 +- linden/indra/newview/llfloaternamedesc.cpp | 9 +- linden/indra/newview/llfloaternewim.cpp | 11 +- linden/indra/newview/llfloaterpreference.cpp | 60 ++ linden/indra/newview/llfloaterpreference.h | 1 + linden/indra/newview/llfloaterregioninfo.cpp | 19 - linden/indra/newview/llfloaterreporter.cpp | 5 +- linden/indra/newview/llfloatersellland.cpp | 0 linden/indra/newview/llfloatersellland.h | 0 linden/indra/newview/llfloatersnapshot.cpp | 2 +- linden/indra/newview/llfloatertest.cpp | 3 +- linden/indra/newview/llfloatertools.cpp | 2 +- linden/indra/newview/llfloatertos.cpp | 1 - linden/indra/newview/llfolderview.cpp | 668 +++++++------ linden/indra/newview/llfolderview.h | 49 +- linden/indra/newview/llgenepool.cpp | 8 + linden/indra/newview/llgivemoney.cpp | 13 +- linden/indra/newview/llglsandbox.cpp | 2 +- linden/indra/newview/llglslshader.cpp | 4 +- linden/indra/newview/llgroupnotify.cpp | 12 +- linden/indra/newview/llhoverview.cpp | 1 - linden/indra/newview/llhudeffecttrail.cpp | 8 +- linden/indra/newview/llimview.cpp | 67 +- linden/indra/newview/llimview.h | 4 + linden/indra/newview/llinventoryactions.cpp | 17 + linden/indra/newview/llinventorybridge.cpp | 85 +- linden/indra/newview/llinventorybridge.h | 0 linden/indra/newview/llinventorymodel.cpp | 134 +-- linden/indra/newview/llinventorymodel.h | 29 +- linden/indra/newview/llinventoryview.cpp | 74 +- linden/indra/newview/llnetmap.cpp | 2 +- linden/indra/newview/llpanelavatar.cpp | 59 +- linden/indra/newview/llpanelcontents.cpp | 16 +- linden/indra/newview/llpaneldisplay.cpp | 14 +- linden/indra/newview/llpaneldisplay.h | 3 +- linden/indra/newview/llpanelface.cpp | 35 +- linden/indra/newview/llpanelgeneral.cpp | 13 +- linden/indra/newview/llpanelgeneral.h | 2 +- linden/indra/newview/llpanelgroup.cpp | 2 +- linden/indra/newview/llpanelgroupgeneral.cpp | 28 +- linden/indra/newview/llpanelgroupnotices.cpp | 8 +- linden/indra/newview/llpanelgrouproles.cpp | 23 +- linden/indra/newview/llpanelinventory.cpp | 113 ++- linden/indra/newview/llpanelmsgs.cpp | 25 +- linden/indra/newview/llpanelpermissions.cpp | 17 +- linden/indra/newview/llpatchvertexarray.cpp | 10 +- linden/indra/newview/llpolymesh.cpp | 32 +- linden/indra/newview/llpolymorph.cpp | 12 +- linden/indra/newview/llpreview.cpp | 24 +- linden/indra/newview/llpreview.h | 6 + linden/indra/newview/llpreviewgesture.cpp | 7 +- linden/indra/newview/llpreviewnotecard.cpp | 11 +- linden/indra/newview/llpreviewscript.cpp | 28 +- linden/indra/newview/llpreviewtexture.cpp | 63 +- linden/indra/newview/llresourcedata.h | 44 + linden/indra/newview/llselectmgr.cpp | 110 +-- linden/indra/newview/llselectmgr.h | 1 - linden/indra/newview/llspatialpartition.cpp | 7 + linden/indra/newview/llstartup.cpp | 4 +- linden/indra/newview/llstartup.h | 1 + linden/indra/newview/llstatusbar.cpp | 5 + linden/indra/newview/llstatusbar.h | 3 + linden/indra/newview/lltexlayer.cpp | 2 +- linden/indra/newview/lltexturectrl.cpp | 43 +- linden/indra/newview/lltooldraganddrop.cpp | 18 +- linden/indra/newview/lltoolgrab.cpp | 8 +- linden/indra/newview/lltoolpie.cpp | 8 +- linden/indra/newview/lltoolpipette.cpp | 0 linden/indra/newview/lltoolpipette.h | 0 linden/indra/newview/llviewerassetstorage.cpp | 13 +- linden/indra/newview/llviewercontrol.cpp | 8 + linden/indra/newview/llviewerdisplay.cpp | 6 +- linden/indra/newview/llviewergenericmessage.cpp | 154 +-- linden/indra/newview/llviewergenericmessage.h | 52 +- linden/indra/newview/llviewerimagelist.cpp | 38 +- linden/indra/newview/llviewerinventory.cpp | 4 - linden/indra/newview/llviewerjointmesh.cpp | 8 +- linden/indra/newview/llviewerkeyboard.cpp | 13 +- linden/indra/newview/llviewermenu.cpp | 993 +------------------ linden/indra/newview/llviewermenu.h | 29 - linden/indra/newview/llviewermenufile.cpp | 1022 ++++++++++++++++++++ linden/indra/newview/llviewermenufile.h | 59 ++ linden/indra/newview/llviewermessage.cpp | 520 ++++++---- linden/indra/newview/llviewermessage.h | 9 + linden/indra/newview/llviewerobject.cpp | 29 +- linden/indra/newview/llviewerparceloverlay.cpp | 15 +- linden/indra/newview/llviewerwindow.cpp | 23 +- linden/indra/newview/llvlcomposition.cpp | 7 + linden/indra/newview/llvoavatar.cpp | 6 +- linden/indra/newview/llvoclouds.cpp | 12 + linden/indra/newview/llvopartgroup.cpp | 13 +- linden/indra/newview/llwindebug.cpp | 2 + linden/indra/newview/llworldmap.cpp | 2 +- linden/indra/newview/llworldmapview.cpp | 1 - .../newview/macview.xcodeproj/project.pbxproj | 14 + linden/indra/newview/newview.vcproj | 12 + linden/indra/newview/newview_vc8.vcproj | 76 +- linden/indra/newview/pipeline.cpp | 12 +- linden/indra/newview/releasenotes.txt | 50 +- linden/indra/newview/res/newViewRes.rc | 8 +- .../indra/newview/secondlife setup build uma.bat | 8 +- .../indra/newview/secondlife setup build vaak.bat | 8 +- .../indra/newview/secondlife setup build yami.bat | 8 +- linden/indra/newview/skins/xui/en-us/alerts.xml | 820 ++++++++-------- .../skins/xui/en-us/floater_avatar_picker.xml | 4 +- .../newview/skins/xui/en-us/floater_inventory.xml | 5 + .../newview/skins/xui/en-us/floater_lsl_guide.xml | 30 +- .../indra/newview/skins/xui/en-us/floater_mute.xml | 4 +- .../newview/skins/xui/en-us/floater_sell_land.xml | 0 .../newview/skins/xui/en-us/menu_inventory.xml | 0 .../skins/xui/en-us/menu_pie_attachment.xml | 0 .../newview/skins/xui/en-us/menu_pie_avatar.xml | 0 .../newview/skins/xui/en-us/menu_pie_land.xml | 0 .../newview/skins/xui/en-us/menu_pie_object.xml | 0 .../newview/skins/xui/en-us/menu_pie_self.xml | 0 .../indra/newview/skins/xui/en-us/menu_viewer.xml | 45 +- linden/indra/newview/skins/xui/en-us/notify.xml | 4 +- .../skins/xui/en-us/panel_preferences_general.xml | 7 +- .../xui/en-us/panel_preferences_graphics3.xml | 7 + .../newview/skins/xui/en-us/panel_status_bar.xml | 2 +- linden/indra/newview/viewer.cpp | 36 +- linden/indra/newview/viewer.h | 34 +- linden/indra/newview/viewer_manifest.py | 5 +- linden/indra/test/common.cpp | 2 +- linden/indra/test/files.lst | 2 + linden/indra/test/llbitpack_tut.cpp | 119 +++ linden/indra/test/lldatapacker_tut.cpp | 571 +++++++++++ linden/indra/test/llhttpclient_tut.cpp | 9 +- linden/indra/test/llinventoryparcel_tut.cpp | 70 ++ linden/indra/test/lliohttpserver_tut.cpp | 2 +- linden/indra/test/llpartdata_tut.cpp | 217 +++++ linden/indra/test/llrandom_tut.cpp | 0 linden/indra/test/llsdserialize_tut.cpp | 5 + linden/indra/test/llservicebuilder_tut.cpp | 152 +-- linden/indra/test/llstring_tut.cpp | 498 ++++++++++ linden/indra/test/lltut.h | 16 + linden/indra/test/llxfer_tut.cpp | 61 ++ linden/indra/test/m3math_tut.cpp | 320 ++++++ linden/indra/test/v2math_tut.cpp | 447 +++++++++ linden/indra/test/v3dmath_tut.cpp | 402 ++++++++ linden/indra/test/v3math_tut.cpp | 568 +++++++++++ linden/indra/test/xform_tut.cpp | 247 +++++ linden/indra/win_crash_logger/win_crash_logger.cpp | 13 +- 261 files changed, 9221 insertions(+), 3787 deletions(-) create mode 100644 linden/indra/llinventory/llinventorytype.cpp create mode 100644 linden/indra/llinventory/llinventorytype.h mode change 100755 => 100644 linden/indra/llui/llmemberlistener.h mode change 100755 => 100644 linden/indra/llui/lluistring.cpp mode change 100755 => 100644 linden/indra/llui/lluistring.h create mode 100644 linden/indra/newview/featuretable_linux.txt mode change 100755 => 100644 linden/indra/newview/llfloatersellland.cpp mode change 100755 => 100644 linden/indra/newview/llfloatersellland.h mode change 100755 => 100644 linden/indra/newview/llinventorybridge.h create mode 100644 linden/indra/newview/llresourcedata.h mode change 100755 => 100644 linden/indra/newview/lltoolpipette.cpp mode change 100755 => 100644 linden/indra/newview/lltoolpipette.h create mode 100644 linden/indra/newview/llviewermenufile.cpp create mode 100644 linden/indra/newview/llviewermenufile.h mode change 100755 => 100644 linden/indra/newview/skins/xui/en-us/floater_inventory.xml mode change 100755 => 100644 linden/indra/newview/skins/xui/en-us/floater_sell_land.xml mode change 100755 => 100644 linden/indra/newview/skins/xui/en-us/menu_inventory.xml mode change 100755 => 100644 linden/indra/newview/skins/xui/en-us/menu_pie_attachment.xml mode change 100755 => 100644 linden/indra/newview/skins/xui/en-us/menu_pie_avatar.xml mode change 100755 => 100644 linden/indra/newview/skins/xui/en-us/menu_pie_land.xml mode change 100755 => 100644 linden/indra/newview/skins/xui/en-us/menu_pie_object.xml mode change 100755 => 100644 linden/indra/newview/skins/xui/en-us/menu_pie_self.xml mode change 100755 => 100644 linden/indra/newview/skins/xui/en-us/menu_viewer.xml create mode 100644 linden/indra/test/llbitpack_tut.cpp create mode 100644 linden/indra/test/lldatapacker_tut.cpp create mode 100644 linden/indra/test/llinventoryparcel_tut.cpp create mode 100644 linden/indra/test/llpartdata_tut.cpp mode change 100755 => 100644 linden/indra/test/llrandom_tut.cpp create mode 100644 linden/indra/test/llstring_tut.cpp create mode 100644 linden/indra/test/llxfer_tut.cpp create mode 100644 linden/indra/test/m3math_tut.cpp create mode 100644 linden/indra/test/v2math_tut.cpp create mode 100644 linden/indra/test/v3dmath_tut.cpp create mode 100644 linden/indra/test/v3math_tut.cpp create mode 100644 linden/indra/test/xform_tut.cpp diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index 705dfb6..dbb18f2 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -2,24 +2,28 @@ Linden Lab would like to acknowledge source code contributions from the following residents. The Second Life resident name is given below, along with the issue identifier corresponding to the patches we've received from them. To see more about these contributions, visit -http://jira.secondlife.com/ , and enter the issue identifier. +http://jira.secondlife.com/ and enter the issue identifier. -Alissa Sabre - VWR-81, VWR-83 +Alissa Sabre - VWR-81, VWR-83, VWR-414, VWR-415 blino Nakamura - VWR-17 +bushing Spatula - VWR-424 Drewan Keats - VWR-28 Dylan Haskell - VWR-72 Dzonatas Sol - VWR-198 Eddy Stryker - VWR-15, VWR-23 +Gigs Taggart - VWR-71, VWR-326 Ginko Bayliss - VWR-4 -Hiro Sommambulist - VWR-66, VWR-97, VWR-100, VWR-105, VWR-108, VWR-118 -Jacek Antonelli - VWR-188 +Hikkoshi Sakai - VWR-429 +Hiro Sommambulist - VWR-66, VWR-97, VWR-100, VWR-105, VWR-108, VWR-118, VWR-136 +Jacek Antonelli - VWR-165, VWR-188 Joghert LeSabre - VWR-64 Kage Pixel - VWR-11 Kunnis Basiat - VWR-82 Paul Churchill - VWR-20 Paula Innis - VWR-30 Peekay Semyorka - VWR-7, VWR-19, VWR-49 +SignpostMarv Martin - VWR-154, VWR-155 SpacedOut Frye - VWR-57, VWR-94, VWR-121, VWR-123 -Strife Onizuka - VWR-74, VWR-85, SVC-9 +Strife Onizuka - SVC-9, VWR-74, VWR-85, VWR-148 Zipherius Turas - VWR-76, VWR-77 diff --git a/linden/indra/SConstruct b/linden/indra/SConstruct index 0174b2d..cbf2029 100644 --- a/linden/indra/SConstruct +++ b/linden/indra/SConstruct @@ -55,6 +55,7 @@ opts.AddOptions( allowed_values=('client', 'server', 'all')), BoolOption('DISTCC', 'Enabled distcc', True), BoolOption('MOZLIB', 'Enabled llmozlib/mozilla support', True), + BoolOption('FMOD', 'Enabled FMOD audio support', True), BoolOption('COLORGCC', 'Enabled colorgcc', True), EnumOption('GRID', 'Client package\'s default grid', 'default', allowed_values=('default', 'aditi', 'agni', 'dmz', 'durga', 'firstlook', 'ganga', 'shakti', 'siva', 'soma', 'uma', 'vaak')), @@ -68,6 +69,7 @@ arch = optenv['ARCH'] target_param = optenv['BTARGET'] enable_distcc = optenv['DISTCC'] enable_mozlib = optenv['MOZLIB'] +enable_fmod = optenv['FMOD'] enable_colorgcc = optenv['COLORGCC'] grid = optenv['GRID'] opensource = optenv['OPENSOURCE'] @@ -180,7 +182,7 @@ for build_target in targets: flags += '-DLL_LINUX=1 ' if build_target == 'client': flags += '-DAPPID=secondlife -DLL_SDL=1 ' - if arch == 'x86_64' or arch == 'x86_64cross': + if arch == 'x86_64' or arch == 'x86_64cross' or not enable_fmod: flags += '-DLL_FMOD=0 ' flags += '-DLL_X11=1 -DLL_GTK=1 ' client_external_libs += [ 'gtk-x11-2.0', 'elfio' ] @@ -302,13 +304,14 @@ for build_target in targets: list_file = open('./' + module + '/' + source_fname, 'r') list = Split(list_file.read()) for x in list: - file = os.path.join(build_dir, x) - if x == 'newsim/lltask.cpp': - print 'Found lltask!' - obj = env_no_distcc.Object(file) - new_list.append(obj) - else: - new_list.append(file) + if not x.startswith('#'): + file = os.path.join(build_dir, x) + if x == 'newsim/lltask.cpp': + print 'Found lltask!' + obj = env_no_distcc.Object(file) + new_list.append(obj) + else: + new_list.append(file) list_file.close() except IOError, val: print 'Error: unable to open file list',source_fname, @@ -415,7 +418,7 @@ for build_target in targets: external_libs = client_external_libs + common_external_libs + [ 'freetype', 'jpeg', 'SDL', 'GL', 'GLU', 'ogg', 'vorbisenc', 'vorbisfile', 'vorbis', 'db-4.2', 'openjpeg' ] - if arch != 'x86_64' and arch != 'x86_64cross': + if arch != 'x86_64' and arch != 'x86_64cross' and enable_fmod: external_libs += [ 'fmod-3.75' ] external_libs.remove('cares') @@ -492,7 +495,7 @@ for build_target in targets: # Dataserver Depends('dataserver/dataserver', 'launcher/launcher' + file_suffix) - external_libs = common_external_libs + ['boost_regex-gcc-mt', 'mysqlclient'] + external_libs = common_external_libs + ['boost_regex-gcc-mt', 'mysqlclient', 'tcmalloc', 'stacktrace'] internal_libs = [ 'llcharacter', 'lldatabase', 'llimage', 'llinventory', 'llscene', 'llmessage', 'llvfs', 'llxml', 'llcommon', 'llmath' ] create_executable('dataserver/dataserver' + file_suffix, 'dataserver', @@ -535,7 +538,7 @@ for build_target in targets: # Simulator Depends('newsim/simulator' + file_suffix, 'mapserver/mapserver' + file_suffix) - external_libs = common_external_libs + ['hkdynamics', 'hkgeometry', 'hkmath', 'hkbase', 'hkcollide', 'hkactions', 'boost_regex-gcc-mt', 'dl', 'kdu', 'mysqlclient', 'iconv'] + external_libs = common_external_libs + ['hkdynamics', 'hkgeometry', 'hkmath', 'hkbase', 'hkcollide', 'hkactions', 'boost_regex-gcc-mt', 'dl', 'kdu', 'mysqlclient', 'iconv', 'tcmalloc', 'stacktrace'] internal_libs = [ 'lscript', 'llprimitive', 'llscene', 'llhavok', 'llinventory', 'llimage', 'llcharacter', 'llxml', 'lldatabase', 'llkdustatic', diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp index edfa123..d5c2a40 100644 --- a/linden/indra/llaudio/audioengine.cpp +++ b/linden/indra/llaudio/audioengine.cpp @@ -134,28 +134,22 @@ void LLAudioEngine::shutdown() // Clean up channels S32 i; - if (mChannels) + for (i = 0; i < MAX_CHANNELS; i++) { - for (i = 0; i < MAX_CHANNELS; i++) + if (mChannels[i]) { - if (mChannels[i]) - { - delete mChannels[i]; - mChannels[i] = NULL; - } + delete mChannels[i]; + mChannels[i] = NULL; } } // Clean up buffers - if (mBuffers) + for (i = 0; i < MAX_BUFFERS; i++) { - for (i = 0; i < MAX_BUFFERS; i++) + if (mBuffers[i]) { - if (mBuffers[i]) - { - delete mBuffers[i]; - mBuffers[i] = NULL; - } + delete mBuffers[i]; + mBuffers[i] = NULL; } } } @@ -575,7 +569,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) } } - if (min_priority > priority) + if (min_priority > priority || !min_channelp) { // All playing channels have higher priority, return. return NULL; diff --git a/linden/indra/llaudio/audioengine_fmod.cpp b/linden/indra/llaudio/audioengine_fmod.cpp index 485b95b..4574a57 100644 --- a/linden/indra/llaudio/audioengine_fmod.cpp +++ b/linden/indra/llaudio/audioengine_fmod.cpp @@ -950,7 +950,7 @@ void LLAudioEngine_FMOD::pauseInternetStream(int pause) stopInternetStream(); } } - else if (mInternetStreamURL) + else { startInternetStream(mInternetStreamURL); } diff --git a/linden/indra/llcharacter/llkeyframemotion.cpp b/linden/indra/llcharacter/llkeyframemotion.cpp index 94e45b6..e5d610a 100644 --- a/linden/indra/llcharacter/llkeyframemotion.cpp +++ b/linden/indra/llcharacter/llkeyframemotion.cpp @@ -1409,6 +1409,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!success) { llwarns << "can't read rotation key (" << k << ")" << llendl; + delete rot_key; return FALSE; } @@ -1527,6 +1528,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!dp.unpackU8(byte, "chain_length")) { llwarns << "can't read constraint chain length" << llendl; + delete constraintp; return FALSE; } constraintp->mChainLength = (S32) byte; @@ -1534,6 +1536,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!dp.unpackU8(byte, "constraint_type")) { llwarns << "can't read constraint type" << llendl; + delete constraintp; return FALSE; } constraintp->mConstraintType = (EConstraintType)byte; @@ -1543,6 +1546,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "source_volume")) { llwarns << "can't read source volume name" << llendl; + delete constraintp; return FALSE; } @@ -1553,12 +1557,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!dp.unpackVector3(constraintp->mSourceConstraintOffset, "source_offset")) { llwarns << "can't read constraint source offset" << llendl; + delete constraintp; return FALSE; } if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "target_volume")) { llwarns << "can't read target volume name" << llendl; + delete constraintp; return FALSE; } @@ -1578,12 +1584,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!dp.unpackVector3(constraintp->mTargetConstraintOffset, "target_offset")) { llwarns << "can't read constraint target offset" << llendl; + delete constraintp; return FALSE; } if (!dp.unpackVector3(constraintp->mTargetConstraintDir, "target_dir")) { llwarns << "can't read constraint target direction" << llendl; + delete constraintp; return FALSE; } @@ -1596,24 +1604,28 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start")) { llwarns << "can't read constraint ease in start time" << llendl; + delete constraintp; return FALSE; } if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop")) { llwarns << "can't read constraint ease in stop time" << llendl; + delete constraintp; return FALSE; } if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start")) { llwarns << "can't read constraint ease out start time" << llendl; + delete constraintp; return FALSE; } if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop")) { llwarns << "can't read constraint ease out stop time" << llendl; + delete constraintp; return FALSE; } @@ -1739,29 +1751,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset"); if (shared_constraintp->mConstraintTargetType == TYPE_GROUND) { - success &= dp.packU8(shared_constraintp->mChainLength, "chain_length"); - success &= dp.packU8(shared_constraintp->mConstraintType, "constraint_type"); - char volume_name[16]; /* Flawfinder: ignore */ - snprintf(volume_name, sizeof(volume_name), "%s", /* Flawfinder: ignore */ - mCharacter->findCollisionVolume(shared_constraintp->mSourceConstraintVolume)->getName().c_str()); - success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "source_volume"); - success &= dp.packVector3(shared_constraintp->mSourceConstraintOffset, "source_offset"); - if (shared_constraintp->mConstraintTargetType == TYPE_GROUND) - { - snprintf(volume_name,sizeof(volume_name), "%s", "GROUND"); /* Flawfinder: ignore */ - } - else - { - snprintf(volume_name, sizeof(volume_name),"%s", /* Flawfinder: ignore */ - mCharacter->findCollisionVolume(shared_constraintp->mTargetConstraintVolume)->getName().c_str()); - } - success &= dp.packBinaryDataFixed((U8*)volume_name, 16, "target_volume"); - success &= dp.packVector3(shared_constraintp->mTargetConstraintOffset, "target_offset"); - success &= dp.packVector3(shared_constraintp->mTargetConstraintDir, "target_dir"); - success &= dp.packF32(shared_constraintp->mEaseInStartTime, "ease_in_start"); - success &= dp.packF32(shared_constraintp->mEaseInStopTime, "ease_in_stop"); - success &= dp.packF32(shared_constraintp->mEaseOutStartTime, "ease_out_start"); - success &= dp.packF32(shared_constraintp->mEaseOutStopTime, "ease_out_stop"); + snprintf(volume_name,sizeof(volume_name), "%s", "GROUND"); /* Flawfinder: ignore */ } else { @@ -1967,39 +1957,46 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, // create an instance of this motion (it may or may not already exist) LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->createMotion(asset_uuid); - if (0 == status && motionp) + if (motionp) { - if (motionp->mAssetStatus == ASSET_LOADED) - { - // asset already loaded - return; - } - LLVFile file(vfs, asset_uuid, type, LLVFile::READ); - S32 size = file.getSize(); - - U8* buffer = new U8[size]; - file.read((U8*)buffer, size); /*Flawfinder: ignore*/ - - lldebugs << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << llendl; - - LLDataPackerBinaryBuffer dp(buffer, size); - if (motionp->deserialize(dp)) + if (0 == status) { - motionp->mAssetStatus = ASSET_LOADED; + if (motionp->mAssetStatus == ASSET_LOADED) + { + // asset already loaded + return; + } + LLVFile file(vfs, asset_uuid, type, LLVFile::READ); + S32 size = file.getSize(); + + U8* buffer = new U8[size]; + file.read((U8*)buffer, size); /*Flawfinder: ignore*/ + + lldebugs << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << llendl; + + LLDataPackerBinaryBuffer dp(buffer, size); + if (motionp->deserialize(dp)) + { + motionp->mAssetStatus = ASSET_LOADED; + } + else + { + llwarns << "Failed to decode asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl; + motionp->mAssetStatus = ASSET_FETCH_FAILED; + } + + delete []buffer; } else { - llwarns << "Failed to decode asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl; + llwarns << "Failed to load asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl; motionp->mAssetStatus = ASSET_FETCH_FAILED; } - - delete []buffer; - } else { - llwarns << "Failed to load asset for animation " << motionp->getName() << ":" << motionp->getID() << llendl; - motionp->mAssetStatus = ASSET_FETCH_FAILED; + // motionp is NULL + llwarns << "Failed to createMotion() for asset UUID " << asset_uuid << llendl; } } diff --git a/linden/indra/llcharacter/llkeyframemotionparam.cpp b/linden/indra/llcharacter/llkeyframemotionparam.cpp index 5970909..d24b8a6 100644 --- a/linden/indra/llcharacter/llkeyframemotionparam.cpp +++ b/linden/indra/llcharacter/llkeyframemotionparam.cpp @@ -187,6 +187,12 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) ParameterizedMotion* firstMotion = NULL; ParameterizedMotion* secondMotion = NULL; + if (NULL == paramValue) // unexpected, but... + { + llwarns << "paramValue == NULL" << llendl; + continue; + } + for (ParameterizedMotion* paramMotion = motionList->getFirstData(); paramMotion; paramMotion = motionList->getNextData()) { paramMotion->first->onUpdate(time, joint_mask); diff --git a/linden/indra/llcharacter/llstatemachine.cpp b/linden/indra/llcharacter/llstatemachine.cpp index 1ad81be..d7ecae4 100644 --- a/linden/indra/llcharacter/llstatemachine.cpp +++ b/linden/indra/llcharacter/llstatemachine.cpp @@ -362,28 +362,28 @@ void LLStateMachine::processTransition(LLFSMTransition& transition, void* user_d { llassert(mStateDiagram); + if (NULL == mCurrentState) + { + llwarns << "mCurrentState == NULL; aborting processTransition()" << llendl; + return; + } + LLFSMState* new_state = mStateDiagram->processTransition(*mCurrentState, transition); + if (NULL == new_state) + { + llwarns << "new_state == NULL; aborting processTransition()" << llendl; + return; + } + mLastTransition = &transition; mLastState = mCurrentState; if (*mCurrentState != *new_state) { - if (mCurrentState && new_state && *mCurrentState != *new_state) - { - mCurrentState->onExit(user_data); - } - if (new_state) - { - if (!mCurrentState || *mCurrentState != *new_state) - { - mCurrentState = new_state; - if (mCurrentState) - { - mCurrentState->onEntry(user_data); - } - } - } + mCurrentState->onExit(user_data); + mCurrentState = new_state; + mCurrentState->onEntry(user_data); #if FSM_PRINT_STATE_TRANSITIONS llinfos << "Entering state " << mCurrentState->getName() << " on transition " << transition.getName() << " from state " << diff --git a/linden/indra/llcharacter/llvisualparam.cpp b/linden/indra/llcharacter/llvisualparam.cpp index de163eb..d1c08f9 100644 --- a/linden/indra/llcharacter/llvisualparam.cpp +++ b/linden/indra/llcharacter/llvisualparam.cpp @@ -232,16 +232,16 @@ void LLVisualParam::setWeight(F32 weight, BOOL set_by_user) //----------------------------------------------------------------------------- void LLVisualParam::setAnimationTarget(F32 target_value, BOOL set_by_user) { - if (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (mInfo) { - if (mInfo) + if (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) { mTargetWeight = llclamp(target_value, mInfo->mMinWeight, mInfo->mMaxWeight); } - else - { - mTargetWeight = target_value; - } + } + else + { + mTargetWeight = target_value; } mIsAnimating = TRUE; diff --git a/linden/indra/llcommon/llstat.cpp b/linden/indra/llcommon/llstat.cpp index 4e43923..7e6090f 100644 --- a/linden/indra/llcommon/llstat.cpp +++ b/linden/indra/llcommon/llstat.cpp @@ -119,9 +119,9 @@ void LLStatAccum::impl::sum(F64 value, U64 when) } if (when < mLastTime) { - // JAMESDEBUG spams on Athlon - //llwarns << "LLStatAccum::sum clock has gone backwards from " - // << mLastTime << " to " << when << ", resetting" << llendl; + // This happens a LOT on some dual core systems. + lldebugs << "LLStatAccum::sum clock has gone backwards from " + << mLastTime << " to " << when << ", resetting" << llendl; reset(when); return; diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h index d901e61..8a2c24c 100644 --- a/linden/indra/llcommon/llstring.h +++ b/linden/indra/llcommon/llstring.h @@ -1043,7 +1043,7 @@ void LLStringBase::copyInto(std::basic_string& dst, const std::basic_strin } else { - LLWString tail = dst.substr(offset); + std::basic_string tail = dst.substr(offset); dst = dst.substr(0, offset); dst += src; diff --git a/linden/indra/llcommon/llstringtable.h b/linden/indra/llcommon/llstringtable.h index 337d937..8d91680 100644 --- a/linden/indra/llcommon/llstringtable.h +++ b/linden/indra/llcommon/llstringtable.h @@ -48,12 +48,6 @@ #include #endif -// string_table.h -// LLStringTable class header file -// Provides a _fast_ method for finding unique copies of strings -// -// Copyright 2001-2002, Linden Research, Inc. - const U32 MAX_STRINGS_LENGTH = 256; class LLStringTableEntry diff --git a/linden/indra/llcommon/lluri.cpp b/linden/indra/llcommon/lluri.cpp index f85f294..c838b25 100644 --- a/linden/indra/llcommon/lluri.cpp +++ b/linden/indra/llcommon/lluri.cpp @@ -114,6 +114,13 @@ namespace { return LLURI::escape(s, unreserved() + ":@!$'()*+,="); } // sub_delims - "&;" + ":@" } +// TODO: USE CURL!! After http textures gets merged everywhere. +// static +std::string LLURI::escape(const std::string& str) +{ + return escape(str,unreserved() + ":@!$'()*+,="); +} + LLURI::LLURI() { } @@ -238,24 +245,11 @@ LLURI LLURI::buildHTTP(const std::string& prefix, const LLSD& path, const LLSD& query) { - LLURI result = buildHTTP(prefix, path); + LLURI uri = buildHTTP(prefix, path); + uri.mEscapedQuery = mapToQueryString(query); // break out and escape each query component - if (query.isMap()) - { - for (LLSD::map_const_iterator it = query.beginMap(); - it != query.endMap(); - it++) - { - result.mEscapedQuery += escapeQueryVariable(it->first) + - (it->second.isUndefined() ? "" : "=" + escapeQueryValue(it->second.asString())) + - "&"; - } - if (query.size() > 0) - { - result.mEscapedOpaque += "?" + result.mEscapedQuery; - } - } - return result; + uri.mEscapedOpaque += "?" + uri.mEscapedQuery ; + return uri; } // static @@ -275,7 +269,6 @@ LLURI LLURI::buildHTTP(const std::string& host, return LLURI::buildHTTP(llformat("%s:%u", host.c_str(), port), path, query); } - namespace { LLURI buildBackboneURL(LLApp* app, const std::string& p1 = "", @@ -317,6 +310,23 @@ LLURI LLURI::buildBulkAgentNamesURI(LLApp* app) } // static +LLURI LLURI::buildBulkAgentNamesURI(LLApp* app) +{ + std::string host = "localhost:12040"; + + if (app) + { + host = app->getOption("backbone-host-port").asString(); + } + + LLSD path = LLSD::emptyArray(); + path.append("agent"); + path.append("names"); + + return buildHTTP(host, path); +} + +// static LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app) { return buildBackboneURL(app, "agent", agent_id.asString(), "session"); @@ -341,6 +351,24 @@ LLURI LLURI::buildAgentNameURI(const LLUUID& agent_id, LLApp* app) } // static +LLURI LLURI::buildAgentNameURI(const LLUUID& agent_id, LLApp* app) +{ + std::string host = "localhost:12040"; + + if (app) + { + host = app->getOption("backbone-host-port").asString(); + } + + LLSD path = LLSD::emptyArray(); + path.append("agent"); + path.append(agent_id); + path.append("name"); + + return buildHTTP(host, path); +} + +// static LLURI LLURI::buildAgentLoginInfoURI(const LLUUID& agent_id, const std::string& dataserver) { LLSD path = LLSD::emptyArray(); @@ -492,3 +520,23 @@ LLSD LLURI::queryMap(std::string escaped_query_string) return result; } +std::string LLURI::mapToQueryString(const LLSD& queryMap) +{ + std::string query_string; + + if (queryMap.isMap()) + { + for (LLSD::map_const_iterator iter = queryMap.beginMap(); + iter != queryMap.endMap(); + iter++) + { + query_string += escapeQueryVariable(iter->first) + + (iter->second.isUndefined() ? "" : "=" + escapeQueryValue(iter->second.asString())) + "&" ; + } + //if (queryMap.size() > 0) + //{ + // query_string += "?" + query_string ; + //} + } + return query_string; +} diff --git a/linden/indra/llcommon/lluri.h b/linden/indra/llcommon/lluri.h index 77de595..d1499b8 100644 --- a/linden/indra/llcommon/lluri.h +++ b/linden/indra/llcommon/lluri.h @@ -90,9 +90,11 @@ public: std::string query() const; // ex.: "x=34", section after "?" LLSD queryMap() const; // above decoded into a map static LLSD queryMap(std::string escaped_query_string); + static std::string mapToQueryString(const LLSD& queryMap); // Escaping Utilities // Escape a string by urlencoding all the characters that aren't in the allowed string. + static std::string escape(const std::string& str); static std::string escape(const std::string& str, const std::string & allowed); static std::string unescape(const std::string& str); diff --git a/linden/indra/llcommon/llversion.h b/linden/indra/llcommon/llversion.h index 426eff0..a76551d 100644 --- a/linden/indra/llcommon/llversion.h +++ b/linden/indra/llcommon/llversion.h @@ -31,7 +31,7 @@ const S32 LL_VERSION_MAJOR = 1; const S32 LL_VERSION_MINOR = 15; -const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 2; +const S32 LL_VERSION_PATCH = 1; +const S32 LL_VERSION_BUILD = 3; #endif diff --git a/linden/indra/llimage/llimage.cpp b/linden/indra/llimage/llimage.cpp index a7d8bdd..5175314 100644 --- a/linden/indra/llimage/llimage.cpp +++ b/linden/indra/llimage/llimage.cpp @@ -1422,7 +1422,7 @@ void LLImageFormatted::sanityCheck() BOOL LLImageFormatted::copyData(U8 *data, S32 size) { - if ( (data && data != getData()) || (size != getDataSize()) ) + if ( data && ((data != getData()) || (size != getDataSize())) ) { deleteData(); allocateData(size); diff --git a/linden/indra/llinventory/files.lst b/linden/indra/llinventory/files.lst index c96cd03..b918b06 100644 --- a/linden/indra/llinventory/files.lst +++ b/linden/indra/llinventory/files.lst @@ -1,6 +1,7 @@ llinventory/llcategory.cpp llinventory/lleconomy.cpp llinventory/llinventory.cpp +llinventory/llinventorytype.cpp llinventory/lllandmark.cpp llinventory/llnotecard.cpp llinventory/llparcel.cpp diff --git a/linden/indra/llinventory/lleconomy.cpp b/linden/indra/llinventory/lleconomy.cpp index 837acfe..e3e909b 100644 --- a/linden/indra/llinventory/lleconomy.cpp +++ b/linden/indra/llinventory/lleconomy.cpp @@ -32,6 +32,8 @@ #include "message.h" #include "v3math.h" +LLGlobalEconomy *gGlobalEconomy = NULL; + LLGlobalEconomy::LLGlobalEconomy() : mObjectCount( -1 ), mObjectCapacity( -1 ), diff --git a/linden/indra/llinventory/lleconomy.h b/linden/indra/llinventory/lleconomy.h index b381663..acda67e 100644 --- a/linden/indra/llinventory/lleconomy.h +++ b/linden/indra/llinventory/lleconomy.h @@ -133,4 +133,6 @@ private: }; +extern LLGlobalEconomy* gGlobalEconomy; + #endif diff --git a/linden/indra/llinventory/llinventory.cpp b/linden/indra/llinventory/llinventory.cpp index 85fc47f..93c480e 100644 --- a/linden/indra/llinventory/llinventory.cpp +++ b/linden/indra/llinventory/llinventory.cpp @@ -40,8 +40,6 @@ #include "llsdutil.h" -#include "llsdutil.h" - ///---------------------------------------------------------------------------- /// exported functions ///---------------------------------------------------------------------------- @@ -67,187 +65,8 @@ static const std::string INV_CREATION_DATE_LABEL("created_at"); const U8 TASK_INVENTORY_ITEM_KEY = 0; const U8 TASK_INVENTORY_ASSET_KEY = 1; -const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730"); - -// helper function which returns true if inventory type and asset type -// are potentially compatible. For example, an attachment must be an -// object, but a wearable can be a bodypart or clothing asset. -bool inventory_and_asset_types_match( - LLInventoryType::EType inventory_type, - LLAssetType::EType asset_type); - +const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730"); -///---------------------------------------------------------------------------- -/// Class LLInventoryType -///---------------------------------------------------------------------------- - -// Unlike asset type names, not limited to 8 characters. -// Need not match asset type names. -static const char* INVENTORY_TYPE_NAMES[LLInventoryType::IT_COUNT] = -{ - "texture", // 0 - "sound", - "callcard", - "landmark", - NULL, - NULL, // 5 - "object", - "notecard", - "category", - "root", - "script", // 10 - NULL, - NULL, - NULL, - NULL, - "snapshot", // 15 - NULL, - "attach", - "wearable", - "animation", - "gesture", // 20 -}; - -// This table is meant for decoding to human readable form. Put any -// and as many printable characters you want in each one. -// See also LLAssetType::mAssetTypeHumanNames -static const char* INVENTORY_TYPE_HUMAN_NAMES[LLInventoryType::IT_COUNT] = -{ - "texture", // 0 - "sound", - "calling card", - "landmark", - NULL, - NULL, // 5 - "object", - "note card", - "folder", - "root", - "script", // 10 - NULL, - NULL, - NULL, - NULL, - "snapshot", // 15 - NULL, - "attachment", - "wearable", - "animation", - "gesture", // 20 -}; - -// Maps asset types to the default inventory type for that kind of asset. -// Thus, "Lost and Found" is a "Category" -static const LLInventoryType::EType -DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = -{ - LLInventoryType::IT_TEXTURE, // AT_TEXTURE - LLInventoryType::IT_SOUND, // AT_SOUND - LLInventoryType::IT_CALLINGCARD, // AT_CALLINGCARD - LLInventoryType::IT_LANDMARK, // AT_LANDMARK - LLInventoryType::IT_LSL, // AT_SCRIPT - LLInventoryType::IT_WEARABLE, // AT_CLOTHING - LLInventoryType::IT_OBJECT, // AT_OBJECT - LLInventoryType::IT_NOTECARD, // AT_NOTECARD - LLInventoryType::IT_CATEGORY, // AT_CATEGORY - LLInventoryType::IT_ROOT_CATEGORY, // AT_ROOT_CATEGORY - LLInventoryType::IT_LSL, // AT_LSL_TEXT - LLInventoryType::IT_LSL, // AT_LSL_BYTECODE - LLInventoryType::IT_TEXTURE, // AT_TEXTURE_TGA - LLInventoryType::IT_WEARABLE, // AT_BODYPART - LLInventoryType::IT_CATEGORY, // AT_TRASH - LLInventoryType::IT_CATEGORY, // AT_SNAPSHOT_CATEGORY - LLInventoryType::IT_CATEGORY, // AT_LOST_AND_FOUND - LLInventoryType::IT_SOUND, // AT_SOUND_WAV - LLInventoryType::IT_NONE, // AT_IMAGE_TGA - LLInventoryType::IT_NONE, // AT_IMAGE_JPEG - LLInventoryType::IT_ANIMATION, // AT_ANIMATION - LLInventoryType::IT_GESTURE, // AT_GESTURE -}; - -static const int MAX_POSSIBLE_ASSET_TYPES = 2; -static const LLAssetType::EType -INVENTORY_TO_ASSET_TYPE[LLInventoryType::IT_COUNT][MAX_POSSIBLE_ASSET_TYPES] = -{ - { LLAssetType::AT_TEXTURE, LLAssetType::AT_NONE }, // IT_TEXTURE - { LLAssetType::AT_SOUND, LLAssetType::AT_NONE }, // IT_SOUND - { LLAssetType::AT_CALLINGCARD, LLAssetType::AT_NONE }, // IT_CALLINGCARD - { LLAssetType::AT_LANDMARK, LLAssetType::AT_NONE }, // IT_LANDMARK - { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, - { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, - { LLAssetType::AT_OBJECT, LLAssetType::AT_NONE }, // IT_OBJECT - { LLAssetType::AT_NOTECARD, LLAssetType::AT_NONE }, // IT_NOTECARD - { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, // IT_CATEGORY - { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, // IT_ROOT_CATEGORY - { LLAssetType::AT_LSL_TEXT, LLAssetType::AT_LSL_BYTECODE }, // IT_LSL - { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, - { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, - { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, - { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, - { LLAssetType::AT_TEXTURE, LLAssetType::AT_NONE }, // IT_SNAPSHOT - { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, - { LLAssetType::AT_OBJECT, LLAssetType::AT_NONE }, // IT_ATTACHMENT - { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART }, // IT_WEARABLE - { LLAssetType::AT_ANIMATION, LLAssetType::AT_NONE }, // IT_ANIMATION - { LLAssetType::AT_GESTURE, LLAssetType::AT_NONE }, // IT_GESTURE -}; - -// static -const char* LLInventoryType::lookup(EType type) -{ - if((type >= 0) && (type < IT_COUNT)) - { - return INVENTORY_TYPE_NAMES[S32(type)]; - } - else - { - return NULL; - } -} - -// static -LLInventoryType::EType LLInventoryType::lookup(const char* name) -{ - for(S32 i = 0; i < IT_COUNT; ++i) - { - if((INVENTORY_TYPE_NAMES[i]) - && (0 == strcmp(name, INVENTORY_TYPE_NAMES[i]))) - { - // match - return (EType)i; - } - } - return IT_NONE; -} - -// XUI:translate -// translation from a type to a human readable form. -// static -const char* LLInventoryType::lookupHumanReadable(EType type) -{ - if((type >= 0) && (type < IT_COUNT)) - { - return INVENTORY_TYPE_HUMAN_NAMES[S32(type)]; - } - else - { - return NULL; - } -} - -// return the default inventory for the given asset type. -// static -LLInventoryType::EType LLInventoryType::defaultForAssetType(LLAssetType::EType asset_type) -{ - if((asset_type >= 0) && (asset_type < LLAssetType::AT_COUNT)) - { - return DEFAULT_ASSET_FOR_INV_TYPE[S32(asset_type)]; - } - else - { - return IT_NONE; - } -} ///---------------------------------------------------------------------------- /// Class LLInventoryObject @@ -351,10 +170,6 @@ BOOL LLInventoryObject::importLegacyStream(std::istream& input_stream) { input_stream.getline(buffer, MAX_STRING); sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */ - if(!keyword) - { - continue; - } if(0 == strcmp("{",keyword)) { continue; @@ -722,10 +537,6 @@ BOOL LLInventoryItem::importFile(FILE* fp) { fgets(buffer, MAX_STRING, fp); sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */ - if(!keyword) - { - continue; - } if(0 == strcmp("{",keyword)) { continue; @@ -927,10 +738,6 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream) buffer, " %254s %254s", keyword, valuestr); - if(!keyword) - { - continue; - } if(0 == strcmp("{",keyword)) { continue; @@ -1419,7 +1226,8 @@ void LLInventoryItem::unpackBinaryBucket(U8* bin_bucket, S32 bin_bucket_size) } else { - llerrs << "unpackBinaryBucket failed. item_buffer or bin_bucket is Null." << llendl; + llerrs << "unpackBinaryBucket failed. item_buffer or bin_bucket is Null." << llendl; + delete[] item_buffer; return; } item_buffer[bin_bucket_size] = '\0'; @@ -1588,10 +1396,6 @@ BOOL LLInventoryCategory::importFile(FILE* fp) buffer, " %254s %254s", keyword, valuestr); - if(!keyword) - { - continue; - } if(0 == strcmp("{",keyword)) { continue; @@ -1671,10 +1475,6 @@ BOOL LLInventoryCategory::importLegacyStream(std::istream& input_stream) buffer, " %254s %254s", keyword, valuestr); - if(!keyword) - { - continue; - } if(0 == strcmp("{",keyword)) { continue; @@ -1739,25 +1539,6 @@ BOOL LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, BOOL) /// Local function definitions ///---------------------------------------------------------------------------- -bool inventory_and_asset_types_match( - LLInventoryType::EType inventory_type, - LLAssetType::EType asset_type) -{ - bool rv = false; - if((inventory_type >= 0) && (inventory_type < LLInventoryType::IT_COUNT)) - { - for(S32 i = 0; i < MAX_POSSIBLE_ASSET_TYPES; ++i) - { - if(INVENTORY_TO_ASSET_TYPE[inventory_type][i] == asset_type) - { - rv = true; - break; - } - } - } - return rv; -} - LLSD ll_create_sd_from_inventory_item(LLPointer item) { LLSD rv; diff --git a/linden/indra/llinventory/llinventory.h b/linden/indra/llinventory/llinventory.h index 6e64412..b24fe79 100644 --- a/linden/indra/llinventory/llinventory.h +++ b/linden/indra/llinventory/llinventory.h @@ -33,6 +33,7 @@ #include "llassetstorage.h" #include "lldarray.h" +#include "llinventorytype.h" #include "llmemtype.h" #include "llpermissions.h" #include "llsaleinfo.h" @@ -51,63 +52,6 @@ enum MAX_INVENTORY_BUFFER_SIZE = 1024 }; -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLInventoryType -// -// Class used to encapsulate operations around inventory type. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLInventoryType -{ -public: - enum EType - { - IT_TEXTURE = 0, - IT_SOUND = 1, - IT_CALLINGCARD = 2, - IT_LANDMARK = 3, - //IT_SCRIPT = 4, - //IT_CLOTHING = 5, - IT_OBJECT = 6, - IT_NOTECARD = 7, - IT_CATEGORY = 8, - IT_ROOT_CATEGORY = 9, - IT_LSL = 10, - //IT_LSL_BYTECODE = 11, - //IT_TEXTURE_TGA = 12, - //IT_BODYPART = 13, - //IT_TRASH = 14, - IT_SNAPSHOT = 15, - //IT_LOST_AND_FOUND = 16, - IT_ATTACHMENT = 17, - IT_WEARABLE = 18, - IT_ANIMATION = 19, - IT_GESTURE = 20, - IT_COUNT = 21, - - IT_NONE = -1 - }; - - // machine transation between type and strings - static EType lookup(const char* name); - static const char* lookup(EType type); - - // translation from a type to a human readable form. - static const char* lookupHumanReadable(EType type); - - // return the default inventory for the given asset type. - static EType defaultForAssetType(LLAssetType::EType asset_type); - -private: - // don't instantiate or derive one of these objects - LLInventoryType( void ) {} - ~LLInventoryType( void ) {} - -//private: -// static const char* mInventoryTypeNames[]; -// static const char* mInventoryTypeHumanNames[]; -// static LLInventoryType::EType mInventoryAssetType[]; -}; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/linden/indra/llinventory/llinventory.vcproj b/linden/indra/llinventory/llinventory.vcproj index 1c76808..66c580e 100644 --- a/linden/indra/llinventory/llinventory.vcproj +++ b/linden/indra/llinventory/llinventory.vcproj @@ -158,6 +158,9 @@ RelativePath=".\llinventory.cpp"> + + + + + + diff --git a/linden/indra/llinventory/llinventorytype.cpp b/linden/indra/llinventory/llinventorytype.cpp new file mode 100644 index 0000000..96dfb5e --- /dev/null +++ b/linden/indra/llinventory/llinventorytype.cpp @@ -0,0 +1,222 @@ +/** + * @file llinventorytype.cpp + * @brief Inventory item type, more specific than an asset type. + * + * Copyright (c) 2001-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + */ + +#include "linden_common.h" + +#include "llinventorytype.h" + +///---------------------------------------------------------------------------- +/// Class LLInventoryType +///---------------------------------------------------------------------------- + +// Unlike asset type names, not limited to 8 characters. +// Need not match asset type names. +static const char* INVENTORY_TYPE_NAMES[LLInventoryType::IT_COUNT] = +{ + "texture", // 0 + "sound", + "callcard", + "landmark", + NULL, + NULL, // 5 + "object", + "notecard", + "category", + "root", + "script", // 10 + NULL, + NULL, + NULL, + NULL, + "snapshot", // 15 + NULL, + "attach", + "wearable", + "animation", + "gesture", // 20 +}; + +// This table is meant for decoding to human readable form. Put any +// and as many printable characters you want in each one. +// See also LLAssetType::mAssetTypeHumanNames +static const char* INVENTORY_TYPE_HUMAN_NAMES[LLInventoryType::IT_COUNT] = +{ + "texture", // 0 + "sound", + "calling card", + "landmark", + NULL, + NULL, // 5 + "object", + "note card", + "folder", + "root", + "script", // 10 + NULL, + NULL, + NULL, + NULL, + "snapshot", // 15 + NULL, + "attachment", + "wearable", + "animation", + "gesture", // 20 +}; + +// Maps asset types to the default inventory type for that kind of asset. +// Thus, "Lost and Found" is a "Category" +static const LLInventoryType::EType +DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = +{ + LLInventoryType::IT_TEXTURE, // AT_TEXTURE + LLInventoryType::IT_SOUND, // AT_SOUND + LLInventoryType::IT_CALLINGCARD, // AT_CALLINGCARD + LLInventoryType::IT_LANDMARK, // AT_LANDMARK + LLInventoryType::IT_LSL, // AT_SCRIPT + LLInventoryType::IT_WEARABLE, // AT_CLOTHING + LLInventoryType::IT_OBJECT, // AT_OBJECT + LLInventoryType::IT_NOTECARD, // AT_NOTECARD + LLInventoryType::IT_CATEGORY, // AT_CATEGORY + LLInventoryType::IT_ROOT_CATEGORY, // AT_ROOT_CATEGORY + LLInventoryType::IT_LSL, // AT_LSL_TEXT + LLInventoryType::IT_LSL, // AT_LSL_BYTECODE + LLInventoryType::IT_TEXTURE, // AT_TEXTURE_TGA + LLInventoryType::IT_WEARABLE, // AT_BODYPART + LLInventoryType::IT_CATEGORY, // AT_TRASH + LLInventoryType::IT_CATEGORY, // AT_SNAPSHOT_CATEGORY + LLInventoryType::IT_CATEGORY, // AT_LOST_AND_FOUND + LLInventoryType::IT_SOUND, // AT_SOUND_WAV + LLInventoryType::IT_NONE, // AT_IMAGE_TGA + LLInventoryType::IT_NONE, // AT_IMAGE_JPEG + LLInventoryType::IT_ANIMATION, // AT_ANIMATION + LLInventoryType::IT_GESTURE, // AT_GESTURE +}; + +static const int MAX_POSSIBLE_ASSET_TYPES = 2; +static const LLAssetType::EType +INVENTORY_TO_ASSET_TYPE[LLInventoryType::IT_COUNT][MAX_POSSIBLE_ASSET_TYPES] = +{ + { LLAssetType::AT_TEXTURE, LLAssetType::AT_NONE }, // IT_TEXTURE + { LLAssetType::AT_SOUND, LLAssetType::AT_NONE }, // IT_SOUND + { LLAssetType::AT_CALLINGCARD, LLAssetType::AT_NONE }, // IT_CALLINGCARD + { LLAssetType::AT_LANDMARK, LLAssetType::AT_NONE }, // IT_LANDMARK + { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, + { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, + { LLAssetType::AT_OBJECT, LLAssetType::AT_NONE }, // IT_OBJECT + { LLAssetType::AT_NOTECARD, LLAssetType::AT_NONE }, // IT_NOTECARD + { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, // IT_CATEGORY + { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, // IT_ROOT_CATEGORY + { LLAssetType::AT_LSL_TEXT, LLAssetType::AT_LSL_BYTECODE }, // IT_LSL + { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, + { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, + { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, + { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, + { LLAssetType::AT_TEXTURE, LLAssetType::AT_NONE }, // IT_SNAPSHOT + { LLAssetType::AT_NONE, LLAssetType::AT_NONE }, + { LLAssetType::AT_OBJECT, LLAssetType::AT_NONE }, // IT_ATTACHMENT + { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART }, // IT_WEARABLE + { LLAssetType::AT_ANIMATION, LLAssetType::AT_NONE }, // IT_ANIMATION + { LLAssetType::AT_GESTURE, LLAssetType::AT_NONE }, // IT_GESTURE +}; + +// static +const char* LLInventoryType::lookup(EType type) +{ + if((type >= 0) && (type < IT_COUNT)) + { + return INVENTORY_TYPE_NAMES[S32(type)]; + } + else + { + return NULL; + } +} + +// static +LLInventoryType::EType LLInventoryType::lookup(const char* name) +{ + for(S32 i = 0; i < IT_COUNT; ++i) + { + if((INVENTORY_TYPE_NAMES[i]) + && (0 == strcmp(name, INVENTORY_TYPE_NAMES[i]))) + { + // match + return (EType)i; + } + } + return IT_NONE; +} + +// XUI:translate +// translation from a type to a human readable form. +// static +const char* LLInventoryType::lookupHumanReadable(EType type) +{ + if((type >= 0) && (type < IT_COUNT)) + { + return INVENTORY_TYPE_HUMAN_NAMES[S32(type)]; + } + else + { + return NULL; + } +} + +// return the default inventory for the given asset type. +// static +LLInventoryType::EType LLInventoryType::defaultForAssetType(LLAssetType::EType asset_type) +{ + if((asset_type >= 0) && (asset_type < LLAssetType::AT_COUNT)) + { + return DEFAULT_ASSET_FOR_INV_TYPE[S32(asset_type)]; + } + else + { + return IT_NONE; + } +} + +bool inventory_and_asset_types_match( + LLInventoryType::EType inventory_type, + LLAssetType::EType asset_type) +{ + bool rv = false; + if((inventory_type >= 0) && (inventory_type < LLInventoryType::IT_COUNT)) + { + for(S32 i = 0; i < MAX_POSSIBLE_ASSET_TYPES; ++i) + { + if(INVENTORY_TO_ASSET_TYPE[inventory_type][i] == asset_type) + { + rv = true; + break; + } + } + } + return rv; +} diff --git a/linden/indra/llinventory/llinventorytype.h b/linden/indra/llinventory/llinventorytype.h new file mode 100644 index 0000000..7d34c87 --- /dev/null +++ b/linden/indra/llinventory/llinventorytype.h @@ -0,0 +1,94 @@ +/** + * @file llinventorytype.h + * @brief Inventory item type, more specific than an asset type. + * + * Copyright (c) 2001-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + */ + +#ifndef LLINVENTORYTYPE_H +#define LLINVENTORYTYPE_H + +#include "llassettype.h" + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLInventoryType +// +// Class used to encapsulate operations around inventory type. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLInventoryType +{ +public: + enum EType + { + IT_TEXTURE = 0, + IT_SOUND = 1, + IT_CALLINGCARD = 2, + IT_LANDMARK = 3, + //IT_SCRIPT = 4, + //IT_CLOTHING = 5, + IT_OBJECT = 6, + IT_NOTECARD = 7, + IT_CATEGORY = 8, + IT_ROOT_CATEGORY = 9, + IT_LSL = 10, + //IT_LSL_BYTECODE = 11, + //IT_TEXTURE_TGA = 12, + //IT_BODYPART = 13, + //IT_TRASH = 14, + IT_SNAPSHOT = 15, + //IT_LOST_AND_FOUND = 16, + IT_ATTACHMENT = 17, + IT_WEARABLE = 18, + IT_ANIMATION = 19, + IT_GESTURE = 20, + IT_COUNT = 21, + + IT_NONE = -1 + }; + + // machine transation between type and strings + static EType lookup(const char* name); + static const char* lookup(EType type); + + // translation from a type to a human readable form. + static const char* lookupHumanReadable(EType type); + + // return the default inventory for the given asset type. + static EType defaultForAssetType(LLAssetType::EType asset_type); + +private: + // don't instantiate or derive one of these objects + LLInventoryType( void ); + ~LLInventoryType( void ); +}; + +// helper function which returns true if inventory type and asset type +// are potentially compatible. For example, an attachment must be an +// object, but a wearable can be a bodypart or clothing asset. +bool inventory_and_asset_types_match( + LLInventoryType::EType inventory_type, + LLAssetType::EType asset_type); + +#endif diff --git a/linden/indra/llinventory/llparcel.cpp b/linden/indra/llinventory/llparcel.cpp index c37a4d6..5b2052f 100644 --- a/linden/indra/llinventory/llparcel.cpp +++ b/linden/indra/llinventory/llparcel.cpp @@ -1214,6 +1214,24 @@ BOOL LLParcel::exportStream(std::ostream& output_stream) return TRUE; } +// virtual +LLSD LLParcel::asLLSD() const +{ + LLSD p; + p["parcel-id"] = getID(); + p["name"] = getName(); + p["desc"] = getDesc(); + p["owner-id"] = getOwnerID(); + p["group-id"] = getGroupID(); + p["group-owned"] = (bool)getIsGroupOwned(); + p["auction-id"] = (S32)getAuctionID(); + p["snapshot-id"] = getSnapshotID(); + p["authorized-buyer-id"] = getAuthorizedBuyerID(); + p["sale-price"] = getSalePrice(); + p["parcel-flags"] = (S32)getParcelFlags(); + // NOTE: This list is incomplete, as this is used only for search. JC + return p; +} // Assumes we are in a block "ParcelData" void LLParcel::packMessage(LLMessageSystem* msg) @@ -1786,7 +1804,7 @@ const char* category_to_ui_string(LLParcel::ECategory category) else { // C_ANY = -1 , but the "Any" string is at the end of the list - index = ((S32) LLParcel::C_COUNT) + 1; + index = ((S32) LLParcel::C_COUNT); } return PARCEL_CATEGORY_UI_STRING[index]; } diff --git a/linden/indra/llinventory/llparcel.h b/linden/indra/llinventory/llparcel.h index 29e393a..cc20182 100644 --- a/linden/indra/llinventory/llparcel.h +++ b/linden/indra/llinventory/llparcel.h @@ -246,6 +246,7 @@ public: BOOL importStream(std::istream& input_stream); BOOL importAccessEntry(std::istream& input_stream, LLAccessEntry* entry); BOOL exportStream(std::ostream& output_stream); + virtual LLSD asLLSD() const; void packMessage(LLMessageSystem* msg); void unpackMessage(LLMessageSystem* msg); @@ -274,7 +275,7 @@ public: BOOL removeFromBanList(const LLUUID& agent_id); // ACCESSORS - const LLUUID& getID() { return mID; } + const LLUUID& getID() const { return mID; } const char* getName() const { return mName.c_str(); } const char* getDesc() const { return mDesc.c_str(); } const char* getMusicURL() const { return mMusicURL.c_str(); } @@ -283,14 +284,13 @@ public: const U8 getMediaAutoScale() const { return mMediaAutoScale; } S32 getLocalID() const { return mLocalID; } const LLUUID& getOwnerID() const { return mOwnerID; } - const LLUUID& getGroupID() const { return mGroupID; } - //const char* getGroupName() const { return mGroupName.c_str(); } + const LLUUID& getGroupID() const { return mGroupID; } S32 getPassPrice() const { return mPassPrice; } F32 getPassHours() const { return mPassHours; } BOOL getIsGroupOwned() const { return mGroupOwned; } - U32 getAuctionID() { return mAuctionID; } - bool isInEscrow() const { return mInEscrow; } + U32 getAuctionID() const { return mAuctionID; } + bool isInEscrow() const { return mInEscrow; } BOOL isPublic() const; diff --git a/linden/indra/llinventory/llpermissions.cpp b/linden/indra/llinventory/llpermissions.cpp index 86ab57c..ae4360a 100644 --- a/linden/indra/llinventory/llpermissions.cpp +++ b/linden/indra/llinventory/llpermissions.cpp @@ -531,10 +531,6 @@ BOOL LLPermissions::importFile(FILE* fp) buffer, " %255s %255s", keyword, valuestr); - if (!keyword) - { - continue; - } if (!strcmp("{", keyword)) { continue; @@ -669,10 +665,6 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream) buffer, " %255s %255s", keyword, valuestr); - if (!keyword) - { - continue; - } if (!strcmp("{", keyword)) { continue; diff --git a/linden/indra/llmath/llcamera.cpp b/linden/indra/llmath/llcamera.cpp index 2197066..c32bb67 100644 --- a/linden/indra/llmath/llcamera.cpp +++ b/linden/indra/llmath/llcamera.cpp @@ -506,7 +506,7 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]); //cache plane octant facing mask for use in AABBInFrustum - for (int i = 0; i < 8; i++) + for (int i = 0; i < 6; i++) { U8 mask = 0; LLPlane p = mAgentPlanes[i]; diff --git a/linden/indra/llmath/llmath.h b/linden/indra/llmath/llmath.h index dbd825d..dd44e0c 100644 --- a/linden/indra/llmath/llmath.h +++ b/linden/indra/llmath/llmath.h @@ -99,6 +99,27 @@ inline BOOL is_approx_equal(F32 x, F32 y) return (abs((S32) ((U32&)x - (U32&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); } +inline BOOL is_approx_equal_fraction(F32 x, F32 y, U32 frac_bits) +{ + BOOL ret = TRUE; + F32 diff = (F32) fabs(x - y); + + S32 diffInt = (S32) diff; + S32 diffFracTolerance = (S32) ((diff - (F32) diffInt) * (1 << frac_bits)); + + // if integer portion is not equal, not enough bits were used for packing + // so error out since either the use case is not correct OR there is + // an issue with pack/unpack. should fail in either case. + // for decimal portion, make sure that the delta is no more than 1 + // based on the number of bits used for packing decimal portion. + if (diffInt != 0 || diffFracTolerance > 1) + { + ret = FALSE; + } + + return ret; +} + inline S32 llabs(const S32 a) { return S32(labs(a)); diff --git a/linden/indra/llmath/llrand.cpp b/linden/indra/llmath/llrand.cpp index f62bd71..e6c4cc5 100644 --- a/linden/indra/llmath/llrand.cpp +++ b/linden/indra/llmath/llrand.cpp @@ -106,7 +106,7 @@ inline F64 ll_internal_random_double() // occasionally give an obviously incorrect random number -- like // 5^15 or something. Sooooo, clamp it as described above. F64 rv = gRandomGenerator(); - if(!((rv >= 0.0) && (rv < 1.0))) return 0.0; + if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0); return rv; } @@ -114,7 +114,7 @@ inline F32 ll_internal_random_float() { // The clamping rules are described above. F32 rv = (F32)gRandomGenerator(); - if(!((rv >= 0.0f) && (rv < 1.0f))) return 0.0f; + if(!((rv >= 0.0f) && (rv < 1.0f))) return fmod(rv, 1.f); return rv; } #endif diff --git a/linden/indra/llmath/lluuid.cpp b/linden/indra/llmath/lluuid.cpp index 78dc8e6..0fed6b3 100644 --- a/linden/indra/llmath/lluuid.cpp +++ b/linden/indra/llmath/lluuid.cpp @@ -486,7 +486,7 @@ S32 LLUUID::getNodeID(unsigned char * node_id) Ncb.ncb_command = NCBASTAT; Ncb.ncb_lana_num = lenum.lana[i]; - strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */ + strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */ Ncb.ncb_buffer = (unsigned char *)&Adapter; Ncb.ncb_length = sizeof(Adapter); diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp index bb3b24d..89644a5 100644 --- a/linden/indra/llmath/llvolume.cpp +++ b/linden/indra/llmath/llvolume.cpp @@ -742,10 +742,6 @@ BOOL LLProfileParams::importFile(FILE *fp) buffer, " %255s %255s", keyword, valuestr); - if (!keyword) - { - continue; - } if (!strcmp("{", keyword)) { continue; @@ -818,10 +814,6 @@ BOOL LLProfileParams::importLegacyStream(std::istream& input_stream) " %255s %255s", keyword, valuestr); - if (!keyword) - { - continue; - } if (!strcmp("{", keyword)) { continue; @@ -1245,10 +1237,6 @@ BOOL LLPathParams::importFile(FILE *fp) buffer, " %255s %255s", keyword, valuestr); - if (!keyword) - { - continue; - } if (!strcmp("{", keyword)) { continue; @@ -1389,10 +1377,6 @@ BOOL LLPathParams::importLegacyStream(std::istream& input_stream) buffer, " %255s %255s", keyword, valuestr); - if (!keyword) - { - continue; - } if (!strcmp("{", keyword)) { continue; @@ -3287,6 +3271,9 @@ BOOL LLVolume::cleanupTriangleData( const S32 num_input_vertices, if (new_num_triangles == 0) { llwarns << "Created volume object with 0 faces." << llendl; + delete[] new_triangles; + delete[] vertex_mapping; + delete[] new_vertices; return FALSE; } @@ -3381,10 +3368,6 @@ BOOL LLVolumeParams::importFile(FILE *fp) { fgets(buffer, BUFSIZE, fp); sscanf(buffer, " %255s", keyword); /* Flawfinder: ignore */ - if (!keyword) - { - continue; - } if (!strcmp("{", keyword)) { continue; @@ -3435,10 +3418,6 @@ BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream) { input_stream.getline(buffer, BUFSIZE); sscanf(buffer, " %255s", keyword); - if (!keyword) - { - continue; - } if (!strcmp("{", keyword)) { continue; diff --git a/linden/indra/llmessage/llassetstorage.cpp b/linden/indra/llmessage/llassetstorage.cpp index 4f4fc0c..c8610a7 100644 --- a/linden/indra/llmessage/llassetstorage.cpp +++ b/linden/indra/llmessage/llassetstorage.cpp @@ -57,10 +57,6 @@ LLAssetStorage *gAssetStorage = NULL; const LLUUID CATEGORIZE_LOST_AND_FOUND_ID("00000000-0000-0000-0000-000000000010"); -const F32 LL_ASSET_STORAGE_TIMEOUT = 300.0f; // anything that takes longer than this will abort - - - ///---------------------------------------------------------------------------- /// LLAssetInfo ///---------------------------------------------------------------------------- @@ -837,43 +833,6 @@ void LLAssetStorage::downloadInvItemCompleteCallback( // Store routines ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// virtual -void LLAssetStorage::cancelStoreAsset( - const LLUUID& uuid, - LLAssetType::EType atype) -{ - bool do_callback = true; - LLAssetRequest* req = NULL; - - if(mPendingUploads.size() > 0) - { - req = mPendingUploads.front(); - if((req->getUUID() == uuid) && (req->getType() == atype)) - { - // This is probably because the request is in progress - do - // not attempt to cancel. - do_callback = false; - } - } - - if (mPendingLocalUploads.size() > 0) - { - req = mPendingLocalUploads.front(); - if((req->getUUID() == uuid) && (req->getType() == atype)) - { - // This is probably because the request is in progress - do - // not attempt to cancel. - do_callback = false; - } - } - - if (do_callback) - { - // clear it out of the upload queue if it is there. - _callUploadCallbacks(uuid, atype, FALSE); - } -} - // static void LLAssetStorage::uploadCompleteCallback(const LLUUID& uuid, void *user_data, S32 result) // StoreAssetData callback (fixed) { diff --git a/linden/indra/llmessage/llassetstorage.h b/linden/indra/llmessage/llassetstorage.h index 3c7a709..f80a77d 100644 --- a/linden/indra/llmessage/llassetstorage.h +++ b/linden/indra/llmessage/llassetstorage.h @@ -48,6 +48,10 @@ class LLAssetStorage; class LLVFS; class LLSD; +// anything that takes longer than this to download will abort. +// HTTP Uploads also timeout if they take longer than this. +const F32 LL_ASSET_STORAGE_TIMEOUT = 5 * 60.0f; + class LLAssetInfo { protected: @@ -264,13 +268,6 @@ public: bool store_local = false, const LLUUID& requesting_agent_id = LLUUID::null); - // This call will attempt to clear a store asset. This will only - // attempt to cancel an upload that has not yet begun. The - // callback will be called with an error code. - virtual void cancelStoreAsset( - const LLUUID& uuid, - LLAssetType::EType oatype); - virtual void checkForTimeouts(); void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, diff --git a/linden/indra/llmessage/llcachename.cpp b/linden/indra/llmessage/llcachename.cpp index 5df62b3..1cc7e09 100644 --- a/linden/indra/llmessage/llcachename.cpp +++ b/linden/indra/llmessage/llcachename.cpp @@ -52,6 +52,10 @@ const char* CN_NONE = "(none)"; const char* CN_HIPPOS = "(hippos)"; const F32 HIPPO_PROBABILITY = 0.01f; +// We track name requests in flight for up to this long. +// We won't re-request a name during this time +const U32 PENDING_TIMEOUT_SECS = 5 * 60; + // File version number const S32 CN_FILE_VERSION = 2; @@ -182,8 +186,9 @@ namespace { } - typedef std::vector AskQueue; + typedef std::set AskQueue; typedef std::vector ReplyQueue; + typedef std::map PendingQueue; typedef std::map Cache; typedef std::vector Observers; }; @@ -200,6 +205,9 @@ public: AskQueue mAskNameQueue; AskQueue mAskGroupQueue; // UUIDs to ask our upstream host about + + PendingQueue mPendingQueue; + // UUIDs that have been requested but are not in cache yet. ReplyQueue mReplyQueue; // requests awaiting replies from us @@ -214,6 +222,7 @@ public: void processPendingAsks(); void processPendingReplies(); void sendRequest(const char* msg_name, const AskQueue& queue); + bool isRequestPending(const LLUUID& id); // Message system callbacks. void processUUIDRequest(LLMessageSystem* msg, bool isGroup); @@ -456,7 +465,10 @@ BOOL LLCacheName::getName(const LLUUID& id, char* first, char* last) : CN_WAITING); strcpy(last, ""); /*Flawfinder: ignore*/ - impl.mAskNameQueue.push_back(id); + if (!impl.isRequestPending(id)) + { + impl.mAskNameQueue.insert(id); + } return FALSE; } @@ -496,8 +508,10 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, char* group) // The function signature needs to change to pass in the length // of first and last. strcpy(group, CN_WAITING); /*Flawfinder: ignore*/ - - impl.mAskGroupQueue.push_back(id); + if (!impl.isRequestPending(id)) + { + impl.mAskGroupQueue.insert(id); + } return FALSE; } } @@ -525,13 +539,16 @@ void LLCacheName::get(const LLUUID& id, BOOL is_group, LLCacheNameCallback callb } else { - if (!is_group) - { - impl.mAskNameQueue.push_back(id); - } - else + if (!impl.isRequestPending(id)) { - impl.mAskGroupQueue.push_back(id); + if (!is_group) + { + impl.mAskNameQueue.insert(id); + } + else + { + impl.mAskGroupQueue.insert(id); + } } impl.mReplyQueue.push_back(PendingReply(id, callback, user_data)); } @@ -570,6 +587,19 @@ void LLCacheName::deleteEntriesOlderThan(S32 secs) impl.mCache.erase(curiter); } } + + // These are pending requests that we never heard back from. + U32 pending_expire_time = now - PENDING_TIMEOUT_SECS; + for(PendingQueue::iterator p_iter = impl.mPendingQueue.begin(); + p_iter != impl.mPendingQueue.end(); ) + { + PendingQueue::iterator p_curitor = p_iter++; + + if (p_curitor->second < pending_expire_time) + { + impl.mPendingQueue.erase(p_curitor); + } + } } @@ -599,6 +629,18 @@ void LLCacheName::dump() } } +void LLCacheName::dumpStats() +{ + llinfos << "Queue sizes: " + << " Cache=" << impl.mCache.size() + << " AskName=" << impl.mAskNameQueue.size() + << " AskGroup=" << impl.mAskGroupQueue.size() + << " Pending=" << impl.mPendingQueue.size() + << " Reply=" << impl.mReplyQueue.size() + << " Observers=" << impl.mObservers.size() + << llendl; +} + void LLCacheName::Impl::processPendingAsks() { sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue); @@ -702,7 +744,23 @@ void LLCacheName::Impl::notifyObservers(const LLUUID& id, } } +bool LLCacheName::Impl::isRequestPending(const LLUUID& id) +{ + U32 now = (U32)time(NULL); + U32 expire_time = now - PENDING_TIMEOUT_SECS; + PendingQueue::iterator iter = mPendingQueue.find(id); + + if (iter == mPendingQueue.end() + || (iter->second < expire_time) ) + { + mPendingQueue[id] = now; + return false; + } + + return true; +} + void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup) { // You should only get this message if the cache is at the simulator @@ -740,13 +798,16 @@ void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup) } else { - if (isGroup) + if (!isRequestPending(id)) { - mAskGroupQueue.push_back(id); - } - else - { - mAskNameQueue.push_back(id); + if (isGroup) + { + mAskGroupQueue.insert(id); + } + else + { + mAskNameQueue.insert(id); + } } mReplyQueue.push_back(PendingReply(id, fromHost)); @@ -770,6 +831,8 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup) mCache[id] = entry; } + mPendingQueue.erase(id); + entry->mIsGroup = isGroup; entry->mCreateTime = (U32)time(NULL); if (!isGroup) diff --git a/linden/indra/llmessage/llcachename.h b/linden/indra/llmessage/llcachename.h index 9009b1f..7d606e6 100644 --- a/linden/indra/llmessage/llcachename.h +++ b/linden/indra/llmessage/llcachename.h @@ -98,7 +98,8 @@ public: void deleteEntriesOlderThan(S32 secs); // Debugging - void dump(); + void dump(); // Dumps the contents of the cache + void dumpStats(); // Dumps the sizes of the cache and associated queues. private: class Impl; diff --git a/linden/indra/llmessage/llcircuit.cpp b/linden/indra/llmessage/llcircuit.cpp index 5e93e0a..239c1df 100644 --- a/linden/indra/llmessage/llcircuit.cpp +++ b/linden/indra/llmessage/llcircuit.cpp @@ -1167,13 +1167,13 @@ std::ostream& operator<<(std::ostream& s, LLCircuitData& circuit) return s; } -const char* LLCircuitData::getInfoString() const +const LLString LLCircuitData::getInfoString() const { std::ostringstream info; info << "Circuit: " << mHost << std::endl << (mbAlive ? "Alive" : "Not Alive") << std::endl << "Age: " << mExistenceTimer.getElapsedTimeF32() << std::endl; - return info.str().c_str(); + return LLString(info.str()); } void LLCircuitData::dumpResendCountAndReset() @@ -1197,7 +1197,7 @@ std::ostream& operator<<(std::ostream& s, LLCircuit &circuit) return s; } -const char* LLCircuit::getInfoString() const +const LLString LLCircuit::getInfoString() const { std::ostringstream info; info << "Circuit Info:" << std::endl; @@ -1207,7 +1207,7 @@ const char* LLCircuit::getInfoString() const { info << (*it).second->getInfoString() << std::endl; } - return info.str().c_str(); + return LLString(info.str()); } void LLCircuit::getCircuitRange( diff --git a/linden/indra/llmessage/llcircuit.h b/linden/indra/llmessage/llcircuit.h index e3a5779..1eea203 100644 --- a/linden/indra/llmessage/llcircuit.h +++ b/linden/indra/llmessage/llcircuit.h @@ -151,7 +151,7 @@ public: // void checkPeriodTime(); // Reset per-period counters if necessary. friend std::ostream& operator<<(std::ostream& s, LLCircuitData &circuit); - const char* getInfoString() const; + const LLString getInfoString() const; friend class LLCircuit; friend class LLMessageSystem; @@ -297,7 +297,7 @@ public: void sendAcks(); friend std::ostream& operator<<(std::ostream& s, LLCircuit &circuit); - const char* getInfoString() const; + const LLString getInfoString() const; void dumpResends(); diff --git a/linden/indra/llmessage/lldatapacker.cpp b/linden/indra/llmessage/lldatapacker.cpp index 2448c40..3cdaa25 100644 --- a/linden/indra/llmessage/lldatapacker.cpp +++ b/linden/indra/llmessage/lldatapacker.cpp @@ -972,11 +972,11 @@ BOOL LLDataPackerAsciiBuffer::packF32(const F32 value, const char *name) int numCopied = 0; if (mWriteEnabled) { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g\n", value); /* Flawfinder: ignore */ + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f\n", value); /* Flawfinder: ignore */ } else { - numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%g\n", value); /* Flawfinder: ignore */ + numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%f\n", value); /* Flawfinder: ignore */ } // snprintf returns number of bytes that would have been written // had the output not being truncated. In that case, it will @@ -1004,7 +1004,7 @@ BOOL LLDataPackerAsciiBuffer::unpackF32(F32 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g", &value); + sscanf(valuestr,"%f", &value); return success; } @@ -1016,11 +1016,11 @@ BOOL LLDataPackerAsciiBuffer::packColor4(const LLColor4 &value, const char *name int numCopied = 0; if (mWriteEnabled) { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ } else { - numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ } // snprintf returns number of bytes that would have been written // had the output not being truncated. In that case, it will @@ -1048,7 +1048,7 @@ BOOL LLDataPackerAsciiBuffer::unpackColor4(LLColor4 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); return success; } @@ -1109,11 +1109,11 @@ BOOL LLDataPackerAsciiBuffer::packVector2(const LLVector2 &value, const char *na int numCopied = 0; if (mWriteEnabled) { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ } else { - numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f\n", value.mV[0], value.mV[1]); /* Flawfinder: ignore */ } // snprintf returns number of bytes that would have been written // had the output not being truncated. In that case, it will @@ -1141,7 +1141,7 @@ BOOL LLDataPackerAsciiBuffer::unpackVector2(LLVector2 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g %g", &value.mV[0], &value.mV[1]); + sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]); return success; } @@ -1153,11 +1153,11 @@ BOOL LLDataPackerAsciiBuffer::packVector3(const LLVector3 &value, const char *na int numCopied = 0; if (mWriteEnabled) { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g %g\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ } else { - numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g %g\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); /* Flawfinder: ignore */ } // snprintf returns number of bytes that would have been written // had the output not being truncated. In that case, it will @@ -1185,7 +1185,7 @@ BOOL LLDataPackerAsciiBuffer::unpackVector3(LLVector3 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g %g %g", &value.mV[0], &value.mV[1], &value.mV[2]); + sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]); return success; } @@ -1196,11 +1196,11 @@ BOOL LLDataPackerAsciiBuffer::packVector4(const LLVector4 &value, const char *na int numCopied = 0; if (mWriteEnabled) { - numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + numCopied = snprintf(mCurBufferp,getBufferSize()-getCurrentSize(),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ } else { - numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ + numCopied = snprintf(DUMMY_BUFFER,sizeof(DUMMY_BUFFER),"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); /* Flawfinder: ignore */ } // snprintf returns number of bytes that would have been written // had the output not being truncated. In that case, it will @@ -1228,7 +1228,7 @@ BOOL LLDataPackerAsciiBuffer::unpackVector4(LLVector4 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); return success; } @@ -1359,6 +1359,19 @@ BOOL LLDataPackerAsciiBuffer::getValueStr(const char *name, char *out_value, S32 return success; } +// helper function used by LLDataPackerAsciiFile +// to convert F32 into a string. This is to avoid +// << operator writing F32 value into a stream +// since it does not seem to preserve the float value +std::string convertF32ToString(F32 val) +{ + std::string str; + char buf[20]; + snprintf(buf, 20, "%f", val); + str = buf; + return str; +} + //--------------------------------------------------------------------------- // LLDataPackerAsciiFile implementation //--------------------------------------------------------------------------- @@ -1633,11 +1646,11 @@ BOOL LLDataPackerAsciiFile::packF32(const F32 value, const char *name) writeIndentedName(name); if (mFP) { - fprintf(mFP,"%g\n", value); + fprintf(mFP,"%f\n", value); } else if (mOutputStream) { - *mOutputStream <<"" << value << "\n"; + *mOutputStream <<"" << convertF32ToString(value) << "\n"; } return success; } @@ -1652,7 +1665,7 @@ BOOL LLDataPackerAsciiFile::unpackF32(F32 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g", &value); + sscanf(valuestr,"%f", &value); return success; } @@ -1663,11 +1676,11 @@ BOOL LLDataPackerAsciiFile::packColor4(const LLColor4 &value, const char *name) writeIndentedName(name); if (mFP) { - fprintf(mFP,"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); } else if (mOutputStream) { - *mOutputStream << value.mV[0] << " " << value.mV[1] << " " << value.mV[2] << " " << value.mV[3] << "\n"; + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n"; } return success; } @@ -1682,7 +1695,7 @@ BOOL LLDataPackerAsciiFile::unpackColor4(LLColor4 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); return success; } @@ -1728,11 +1741,11 @@ BOOL LLDataPackerAsciiFile::packVector2(const LLVector2 &value, const char *name writeIndentedName(name); if (mFP) { - fprintf(mFP,"%g %g\n", value.mV[0], value.mV[1]); + fprintf(mFP,"%f %f\n", value.mV[0], value.mV[1]); } else if (mOutputStream) { - *mOutputStream << value.mV[0] << " " << value.mV[1] << "\n"; + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << "\n"; } return success; } @@ -1747,7 +1760,7 @@ BOOL LLDataPackerAsciiFile::unpackVector2(LLVector2 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g %g", &value.mV[0], &value.mV[1]); + sscanf(valuestr,"%f %f", &value.mV[0], &value.mV[1]); return success; } @@ -1758,11 +1771,11 @@ BOOL LLDataPackerAsciiFile::packVector3(const LLVector3 &value, const char *name writeIndentedName(name); if (mFP) { - fprintf(mFP,"%g %g %g\n", value.mV[0], value.mV[1], value.mV[2]); + fprintf(mFP,"%f %f %f\n", value.mV[0], value.mV[1], value.mV[2]); } else if (mOutputStream) { - *mOutputStream << value.mV[0] << " " << value.mV[1] << " " << value.mV[2] << "\n"; + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << "\n"; } return success; } @@ -1777,7 +1790,7 @@ BOOL LLDataPackerAsciiFile::unpackVector3(LLVector3 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g %g %g", &value.mV[0], &value.mV[1], &value.mV[2]); + sscanf(valuestr,"%f %f %f", &value.mV[0], &value.mV[1], &value.mV[2]); return success; } @@ -1787,11 +1800,11 @@ BOOL LLDataPackerAsciiFile::packVector4(const LLVector4 &value, const char *name writeIndentedName(name); if (mFP) { - fprintf(mFP,"%g %g %g %g\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); + fprintf(mFP,"%f %f %f %f\n", value.mV[0], value.mV[1], value.mV[2], value.mV[3]); } else if (mOutputStream) { - *mOutputStream << value.mV[0] << " " << value.mV[1] << " " << value.mV[2] << " " << value.mV[3] << "\n"; + *mOutputStream << convertF32ToString(value.mV[0]) << " " << convertF32ToString(value.mV[1]) << " " << convertF32ToString(value.mV[2]) << " " << convertF32ToString(value.mV[3]) << "\n"; } return success; } @@ -1806,7 +1819,7 @@ BOOL LLDataPackerAsciiFile::unpackVector4(LLVector4 &value, const char *name) return FALSE; } - sscanf(valuestr,"%g %g %g %g", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); + sscanf(valuestr,"%f %f %f %f", &value.mV[0], &value.mV[1], &value.mV[2], &value.mV[3]); return success; } @@ -1848,7 +1861,8 @@ BOOL LLDataPackerAsciiFile::unpackUUID(LLUUID &value, const char *name) void LLDataPackerAsciiFile::writeIndentedName(const char *name) { - char indent_buf[64]; /*Flawfinder: ignore*/ + std::string indent_buf; + indent_buf.reserve(mIndent+1); S32 i; for(i = 0; i < mIndent; i++) @@ -1858,11 +1872,11 @@ void LLDataPackerAsciiFile::writeIndentedName(const char *name) indent_buf[i] = 0; if (mFP) { - fprintf(mFP,"%s%s\t",indent_buf, name); + fprintf(mFP,"%s%s\t",indent_buf.c_str(), name); } else if (mOutputStream) { - *mOutputStream << indent_buf << name << "\t"; + *mOutputStream << indent_buf.c_str() << name << "\t"; } } diff --git a/linden/indra/llmessage/llhttpassetstorage.cpp b/linden/indra/llmessage/llhttpassetstorage.cpp index 8e328ce..5a0cdad 100644 --- a/linden/indra/llmessage/llhttpassetstorage.cpp +++ b/linden/indra/llmessage/llhttpassetstorage.cpp @@ -34,6 +34,7 @@ #include #include "indra_constants.h" +#include "message.h" #include "llvfile.h" #include "llvfs.h" @@ -517,6 +518,8 @@ void LLHTTPAssetStorage::storeAssetData( callback(LLUUID::null, user_data, LL_ERR_CANNOT_OPEN_FILE); } } + // Coverity CID-269 says there's a leak of 'legacy' here, but + // legacyStoreDataCallback() will delete it somewhere down the line. } // virtual @@ -937,9 +940,45 @@ void LLHTTPAssetStorage::checkForTimeouts() } while (curl_msg && queue_length > 0); + // Cleanup + // We want to bump to the back of the line any running uploads that have timed out. + bumpTimedOutUploads(); + LLAssetStorage::checkForTimeouts(); } +void LLHTTPAssetStorage::bumpTimedOutUploads() +{ + // No point bumping currently running uploads if there are no others in line. + if (!(mPendingUploads.size() > mRunningUploads.size())) + { + return; + } + + F64 mt_secs = LLMessageSystem::getMessageTimeSeconds(); + + // deletePendingRequest will modify the mRunningUploads list so we don't want to iterate over it. + request_list_t temp_running = mRunningUploads; + + request_list_t::iterator it = temp_running.begin(); + request_list_t::iterator end = temp_running.end(); + for ( ; it != end; ++it) + { + //request_list_t::iterator curiter = iter++; + LLAssetRequest* req = *it; + + if ( LL_ASSET_STORAGE_TIMEOUT < (mt_secs - req->mTime) ) + { + llwarns << "Asset upload request timed out for " + << req->getUUID() << "." + << LLAssetType::lookup(req->getType()) + << ", bumping to the back of the line!" << llendl; + + deletePendingRequest(RT_UPLOAD, req->getType(), req->getUUID()); + } + } +} + // static size_t LLHTTPAssetStorage::curlDownCallback(void *data, size_t size, size_t nmemb, void *user_data) { diff --git a/linden/indra/llmessage/llhttpassetstorage.h b/linden/indra/llmessage/llhttpassetstorage.h index b5ab56b..2977301 100644 --- a/linden/indra/llmessage/llhttpassetstorage.h +++ b/linden/indra/llmessage/llhttpassetstorage.h @@ -133,6 +133,10 @@ private: // This will return the correct base URI for any http asset request std::string getBaseURL(const LLUUID& asset_id, LLAssetType::EType asset_type); + // Check for running uploads that have timed out + // Bump these to the back of the line to let other uploads complete. + void bumpTimedOutUploads(); + protected: std::string mBaseURL; std::string mLocalBaseURL; diff --git a/linden/indra/llmessage/llhttpclient.cpp b/linden/indra/llmessage/llhttpclient.cpp index 1d38a13..8cb8344 100644 --- a/linden/indra/llmessage/llhttpclient.cpp +++ b/linden/indra/llmessage/llhttpclient.cpp @@ -37,6 +37,7 @@ #include "llsdserialize.h" #include "llvfile.h" #include "llvfs.h" +#include "lluri.h" #include "message.h" #include @@ -283,6 +284,14 @@ void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const F32 request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout); } +void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const F32 timeout) +{ + LLURI uri; + + uri = LLURI::buildHTTP(url, LLSD::emptyArray(), query); + get(uri.asString(), responder, timeout); +} + // A simple class for managing data returned from a curl http request. class LLHTTPBuffer { diff --git a/linden/indra/llmessage/llhttpclient.h b/linden/indra/llmessage/llhttpclient.h index 136577c..c2dfb5d 100644 --- a/linden/indra/llmessage/llhttpclient.h +++ b/linden/indra/llmessage/llhttpclient.h @@ -73,6 +73,7 @@ public: typedef boost::intrusive_ptr ResponderPtr; static void get(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + static void get(const std::string& url, const LLSD& query, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); static void put(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); ///< non-blocking 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 9ea7272..d7fc54e 100644 --- a/linden/indra/llmessage/lliohttpserver.cpp +++ b/linden/indra/llmessage/lliohttpserver.cpp @@ -29,9 +29,8 @@ */ #include "linden_common.h" -#include "lliohttpserver.h" -#include "boost/tokenizer.hpp" +#include "lliohttpserver.h" #include "llapr.h" #include "llbuffer.h" @@ -46,9 +45,12 @@ #include "llsd.h" #include "llsdserialize_xml.h" #include "llstl.h" +#include "lltimer.h" #include +#include "boost/tokenizer.hpp" + static const char HTTP_VERSION_STR[] = "HTTP/1.0"; static const std::string CONTEXT_REQUEST("request"); static const std::string HTTP_VERB_GET("GET"); @@ -56,6 +58,8 @@ static const std::string HTTP_VERB_PUT("PUT"); static const std::string HTTP_VERB_POST("POST"); static const std::string HTTP_VERB_DELETE("DELETE"); +static LLIOHTTPServer::timing_callback_t sTimingCallback = NULL; +static void* sTimingCallbackData = NULL; class LLHTTPPipe : public LLIOPipe { @@ -151,6 +155,12 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( // TODO: Babbage: Parameterize parser? LLBufferStream istr(channels, buffer.get()); + static LLTimer timer; + if (sTimingCallback) + { + timer.reset(); + } + std::string verb = context[CONTEXT_REQUEST]["verb"]; if(verb == HTTP_VERB_GET) { @@ -179,6 +189,18 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( mResponse->methodNotAllowed(); } + if (sTimingCallback) + { + LLHTTPNode::Description desc; + mNode.describe(desc); + LLSD info = desc.getInfo(); + std::string timing_name = info["description"]; + timing_name += " "; + timing_name += verb; + F32 delta = timer.getElapsedTimeF32(); + sTimingCallback(timing_name.c_str(), delta, sTimingCallbackData); + } + // Log Internal Server Errors if(mStatusCode == 500) { @@ -819,9 +841,9 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl( } - -void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, - const LLHTTPNode& root, const LLSD& ctx) +// static +void LLIOHTTPServer::createPipe(LLPumpIO::chain_t& chain, + const LLHTTPNode& root, const LLSD& ctx) { chain.push_back(LLIOPipe::ptr_t(new LLHTTPResponder(root, ctx))); } @@ -832,7 +854,7 @@ class LLHTTPResponseFactory : public LLChainIOFactory public: bool build(LLPumpIO::chain_t& chain, LLSD ctx) const { - LLCreateHTTPPipe(chain, mTree, ctx); + LLIOHTTPServer::createPipe(chain, mTree, ctx); return true; } @@ -843,7 +865,8 @@ private: }; -LLHTTPNode& LLCreateHTTPServer( +// static +LLHTTPNode& LLIOHTTPServer::create( apr_pool_t* pool, LLPumpIO& pump, U16 port) { LLSocket::ptr_t socket = LLSocket::create( @@ -867,3 +890,10 @@ LLHTTPNode& LLCreateHTTPServer( return factory->getRootNode(); } +// static +void LLIOHTTPServer::setTimingCallback(timing_callback_t callback, + void* data) +{ + sTimingCallback = callback; + sTimingCallbackData = data; +} diff --git a/linden/indra/llmessage/lliohttpserver.h b/linden/indra/llmessage/lliohttpserver.h index 64dce63..8a6c8d4 100644 --- a/linden/indra/llmessage/lliohttpserver.h +++ b/linden/indra/llmessage/lliohttpserver.h @@ -36,7 +36,12 @@ class LLPumpIO; -LLHTTPNode& LLCreateHTTPServer(apr_pool_t* pool, LLPumpIO& pump, U16 port); +class LLIOHTTPServer +{ +public: + typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data); + + static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port); /**< Creates an HTTP wire server on the pump for the given TCP port. * * Returns the root node of the new server. Add LLHTTPNode instances @@ -51,14 +56,23 @@ LLHTTPNode& LLCreateHTTPServer(apr_pool_t* pool, LLPumpIO& pump, U16 port); * for example), use the helper templates below. */ -void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, - const LLHTTPNode& root, const LLSD& ctx); + static void createPipe(LLPumpIO::chain_t& chain, + const LLHTTPNode& root, const LLSD& ctx); /**< Create a pipe on the chain that handles HTTP requests. * The requests are served by the node tree given at root. * * This is primarily useful for unit testing. */ + static void setTimingCallback(timing_callback_t callback, void* data); + /**< Register a callback function that will be called every time + * a GET, PUT, POST, or DELETE is handled. + * + * This is used to time the LLHTTPNode handler code, which often hits + * the database or does other, slow operations. JC + */ +}; + /* @name Helper Templates * * These templates make it easy to create nodes that use thier own protocol diff --git a/linden/indra/llmessage/lliosocket.cpp b/linden/indra/llmessage/lliosocket.cpp index af22180..0ceb436 100644 --- a/linden/indra/llmessage/lliosocket.cpp +++ b/linden/indra/llmessage/lliosocket.cpp @@ -423,23 +423,35 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl( bool done = false; while(it != end) { + PUMP_DEBUG; if((*it).isOnChannel(channels.in())) { PUMP_DEBUG; // *FIX: check return code - sockets will fail (broken, etc.) len = (apr_size_t)segment.size(); - apr_socket_send( + apr_status_t status = apr_socket_send( mDestination->getSocket(), (const char*)segment.data(), &len); + // We sometimes get a 'non-blocking socket operation could not be + // completed immediately' error from apr_socket_send. In this + // case we break and the data will be sent the next time the chain + // is pumped. +#if LL_WINDOWS + if (status == 730035) + break; +#endif mLastWritten = segment.data() + len - 1; + PUMP_DEBUG; if((S32)len < segment.size()) { break; } + } + ++it; if(it != end) { @@ -449,6 +461,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl( { done = true; } + } PUMP_DEBUG; if(done && eos) diff --git a/linden/indra/llmessage/llmail.cpp b/linden/indra/llmessage/llmail.cpp index 793cb19..633a2a3 100644 --- a/linden/indra/llmessage/llmail.cpp +++ b/linden/indra/llmessage/llmail.cpp @@ -64,7 +64,7 @@ static apr_sockaddr_t* gSockAddr; static apr_socket_t* gMailSocket; // According to RFC2822 -static const boost::regex valid_subject_chars("[\\x1-\\x9\\xb\\xc\\xe-\\x7f]+"); +static const boost::regex valid_subject_chars("[\\x1-\\x9\\xb\\xc\\xe-\\x7f]*"); bool connect_smtp(); void disconnect_smtp(); diff --git a/linden/indra/llmessage/llmessage.vcproj b/linden/indra/llmessage/llmessage.vcproj index ac16f52..d3e0d89 100644 --- a/linden/indra/llmessage/llmessage.vcproj +++ b/linden/indra/llmessage/llmessage.vcproj @@ -440,6 +440,9 @@ RelativePath=".\llhttpsender.h"> + + " << NET_BUFFER_SIZE << " of size " << size << llendl; } - - if (datap != NULL) + else // we previously relied on llerrs being fatal to not get here... { - memcpy(mData, datap, size); /*Flawfinder: ignore*/ - mSize = size; + if (datap != NULL) + { + memcpy(mData, datap, size); + mSize = size; + } } } diff --git a/linden/indra/llmessage/llregionflags.h b/linden/indra/llmessage/llregionflags.h index 6a23544..fb9bf5b 100644 --- a/linden/indra/llmessage/llregionflags.h +++ b/linden/indra/llmessage/llregionflags.h @@ -63,7 +63,7 @@ const U32 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid const U32 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13); const U32 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics const U32 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15); -const U32 REGION_FLAGS_MAINLAND_VISIBLE = (1 << 16); +//const U32 REGION_FLAGS_MAINLAND_VISIBLE = (1 << 16); const U32 REGION_FLAGS_PUBLIC_ALLOWED = (1 << 17); const U32 REGION_FLAGS_BLOCK_DWELL = (1 << 18); @@ -99,7 +99,6 @@ const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK | REGION_FLAGS_ALLOW_SET_HOME; const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE - | REGION_FLAGS_MAINLAND_VISIBLE | REGION_FLAGS_PUBLIC_ALLOWED | REGION_FLAGS_SUN_FIXED | REGION_FLAGS_DENY_ANONYMOUS diff --git a/linden/indra/llmessage/lltransfermanager.cpp b/linden/indra/llmessage/lltransfermanager.cpp index 12e1728..f42ce45 100644 --- a/linden/indra/llmessage/lltransfermanager.cpp +++ b/linden/indra/llmessage/lltransfermanager.cpp @@ -958,6 +958,7 @@ void LLTransferTargetChannel::requestTransfer( if (!ttp) { llwarns << "LLTransferManager::requestTransfer aborting due to target creation failure!" << llendl; + return; } ttp->applyParams(target_params); diff --git a/linden/indra/llmessage/llurlrequest.cpp b/linden/indra/llmessage/llurlrequest.cpp index b3dfb52..1c7648b 100644 --- a/linden/indra/llmessage/llurlrequest.cpp +++ b/linden/indra/llmessage/llurlrequest.cpp @@ -544,7 +544,10 @@ size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) int statusCode = atoi(status.c_str()); if (statusCode > 0) { - complete->httpStatus((U32)statusCode, reason); + if (complete) + { + complete->httpStatus((U32)statusCode, reason); + } } } diff --git a/linden/indra/llmessage/llxfer_file.cpp b/linden/indra/llmessage/llxfer_file.cpp index 297d163..33db248 100644 --- a/linden/indra/llmessage/llxfer_file.cpp +++ b/linden/indra/llmessage/llxfer_file.cpp @@ -82,7 +82,8 @@ void LLXfer_File::init (const LLString& local_filename, BOOL delete_local_on_com if (!local_filename.empty()) { - strncpy(mLocalFilename, local_filename.c_str(), LL_MAX_PATH); /* Flawfinder : ignore */ + strncpy(mLocalFilename, local_filename.c_str(), LL_MAX_PATH-1); + mLocalFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy. // You can only automatically delete .tmp file as a safeguard against nasty messages. mDeleteLocalOnCompletion = (delete_local_on_completion && (strstr(mLocalFilename,".tmp") == &mLocalFilename[strlen(mLocalFilename)-4])); /* Flawfinder : ignore */ @@ -117,19 +118,21 @@ void LLXfer_File::free () /////////////////////////////////////////////////////////// S32 LLXfer_File::initializeRequest(U64 xfer_id, - const LLString& local_filename, - const LLString& remote_filename, - ELLPath remote_path, - const LLHost& remote_host, - BOOL delete_remote_on_completion, - void (*callback)(void**,S32), - void** user_data) + const LLString& local_filename, + const LLString& remote_filename, + ELLPath remote_path, + const LLHost& remote_host, + BOOL delete_remote_on_completion, + void (*callback)(void**,S32), + void** user_data) { S32 retval = 0; // presume success mID = xfer_id; - strncpy(mLocalFilename, local_filename.c_str(), LL_MAX_PATH); /* Flawfinder : ignore */ - strncpy(mRemoteFilename,remote_filename.c_str(), LL_MAX_PATH); /* Flawfinder : ignore */ + strncpy(mLocalFilename, local_filename.c_str(), LL_MAX_PATH-1); + mLocalFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy. + strncpy(mRemoteFilename,remote_filename.c_str(), LL_MAX_PATH-1); + mRemoteFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy. mRemotePath = remote_path; mRemoteHost = remote_host; mDeleteRemoteOnCompletion = delete_remote_on_completion; diff --git a/linden/indra/llmessage/llxfer_mem.cpp b/linden/indra/llmessage/llxfer_mem.cpp index e9b4224..0f055c8 100644 --- a/linden/indra/llmessage/llxfer_mem.cpp +++ b/linden/indra/llmessage/llxfer_mem.cpp @@ -162,7 +162,8 @@ S32 LLXfer_Mem::initializeRequest(U64 xfer_id, mCallbackDataHandle = user_data; mCallbackResult = LL_ERR_NOERR; - strncpy(mRemoteFilename, remote_filename.c_str(), LL_MAX_PATH); /* Flawfinder : ignore */ + strncpy(mRemoteFilename, remote_filename.c_str(), LL_MAX_PATH-1); + mRemoteFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy. mRemotePath = remote_path; mDeleteRemoteOnCompletion = delete_remote_on_completion; diff --git a/linden/indra/llmessage/llxfermanager.cpp b/linden/indra/llmessage/llxfermanager.cpp index 914488e..7758a32 100644 --- a/linden/indra/llmessage/llxfermanager.cpp +++ b/linden/indra/llmessage/llxfermanager.cpp @@ -223,8 +223,8 @@ LLXfer *LLXferManager::findXfer (U64 id, LLXfer *list_head) void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head) { - LLXfer *xferp; - + // This function assumes that delp will only occur in the list + // zero or one times. if (delp) { if (*list_head == delp) @@ -234,14 +234,14 @@ void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head) } else { - xferp = *list_head; + LLXfer *xferp = *list_head; while (xferp->mNext) { if (xferp->mNext == delp) { xferp->mNext = delp->mNext; delete (delp); - continue; + break; } xferp = xferp->mNext; } diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp index ef22b63..29f232c 100644 --- a/linden/indra/llmessage/message.cpp +++ b/linden/indra/llmessage/message.cpp @@ -535,6 +535,8 @@ void LLMessageSystem::loadTemplateFile(const char* filename) if(!filename) { llerrs << "No template filename specified" << llendl; + mbError = TRUE; + return; } char token[MAX_MESSAGE_INTERNAL_NAME_SIZE]; /* Flawfinder: ignore */ @@ -655,6 +657,13 @@ void LLMessageSystem::loadTemplateFile(const char* filename) // add data! // we've gotten a complete variable! hooray! // add it! + if (NULL == templatep) + { + llerrs << "Trying to addTemplate a NULL templatep during load." << llendl; + mbError = TRUE; + fclose(messagefilep); + return; + } addTemplate(templatep); //llinfos << "Read template: "templatep->mNametemp_str @@ -672,7 +681,13 @@ void LLMessageSystem::loadTemplateFile(const char* filename) // add data! // we've gotten a complete variable! hooray! // add it to template - + if (NULL == templatep) + { + llerrs << "Trying to addBlock to NULL templatep during load." << llendl; + mbError = TRUE; + fclose(messagefilep); + return; + } templatep->addBlock(blockp); // start working on it! @@ -876,10 +891,24 @@ void LLMessageSystem::loadTemplateFile(const char* filename) if (strcmp(token, "Trusted") == 0) { + if (NULL == templatep) + { + llerrs << "Trying to setTrust for NULL templatep during load." << llendl; + mbError = TRUE; + fclose(messagefilep); + return; + } templatep->setTrust(MT_TRUST); } else if (strcmp(token, "NotTrusted") == 0) { + if (NULL == templatep) + { + llerrs << "Trying to setTrust for NULL templatep during load." << llendl; + mbError = TRUE; + fclose(messagefilep); + return; + } templatep->setTrust(MT_NOTRUST); } else @@ -912,10 +941,24 @@ void LLMessageSystem::loadTemplateFile(const char* filename) if(0 == strcmp(token, "Unencoded")) { + if (NULL == templatep) + { + llerrs << "Trying to setEncoding for NULL templatep during load." << llendl; + mbError = TRUE; + fclose(messagefilep); + return; + } templatep->setEncoding(ME_UNENCODED); } else if(0 == strcmp(token, "Zerocoded")) { + if (NULL == templatep) + { + llerrs << "Trying to setEncoding for NULL templatep during load." << llendl; + mbError = TRUE; + fclose(messagefilep); + return; + } templatep->setEncoding(ME_ZEROCODED); } else diff --git a/linden/indra/llprimitive/llprimitive.cpp b/linden/indra/llprimitive/llprimitive.cpp index e2cf7e3..9ab44f7 100644 --- a/linden/indra/llprimitive/llprimitive.cpp +++ b/linden/indra/llprimitive/llprimitive.cpp @@ -797,14 +797,14 @@ const char * LLPrimitive::pCodeToString(const LLPCode pcode) { snprintf(mask, sizeof(mask), "hemi"); /* Flawfinder: ignore */ } - else if (mask != 0) + else { snprintf(mask, sizeof(mask), "%x", mask_code); /* Flawfinder: ignore */ } - else - { - mask[0] = 0; - } + + // extra sanity against snprintf() being naturally crap + mask[sizeof(mask)-1] = '\0'; + shape[sizeof(shape)-1] = '\0'; if (mask[0]) { @@ -815,6 +815,11 @@ const char * LLPrimitive::pCodeToString(const LLPCode pcode) snprintf(pcode_string, sizeof(pcode_string), "%s", shape); /* Flawfinder: ignore */ } } + + // Be really sure that pcode_string is nul-terminated after we've + // been using crappy snprintf() to build it. + pcode_string[sizeof(pcode_string)-1] = '\0'; + return pcode_string; } diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp index 7ee89c7..23f02c2 100644 --- a/linden/indra/llrender/llfontgl.cpp +++ b/linden/indra/llrender/llfontgl.cpp @@ -70,7 +70,7 @@ const F32 PIXEL_BORDER_THRESHOLD = 0.0001f; const F32 PIXEL_CORRECTION_DISTANCE = 0.01f; const F32 PAD_AMT = 0.5f; -const F32 DROP_SHADOW_STRENGTH = 0.3f; +const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f; F32 llfont_round_x(F32 x) { @@ -106,6 +106,14 @@ U8 LLFontGL::getStyleFromString(const LLString &style) { ret |= UNDERLINE; } + if (style.find("SHADOW") != style.npos) + { + ret |= DROP_SHADOW; + } + if (style.find("SOFT_SHADOW") != style.npos) + { + ret |= DROP_SHADOW_SOFT; + } return ret; } @@ -571,14 +579,14 @@ S32 LLFontGL::render(const LLWString &wstr, } F32 drop_shadow_strength = 0.f; - if (style & DROP_SHADOW) + if (style & (DROP_SHADOW | DROP_SHADOW_SOFT)) { F32 luminance; color.calcHSL(NULL, NULL, &luminance); - drop_shadow_strength = clamp_rescale(luminance, 0.35f, 0.6f, 0.f, DROP_SHADOW_STRENGTH); + drop_shadow_strength = clamp_rescale(luminance, 0.35f, 0.6f, 0.f, 1.f); if (luminance < 0.35f) { - style = style & ~DROP_SHADOW; + style = style & ~(DROP_SHADOW | DROP_SHADOW_SOFT); } } @@ -769,6 +777,7 @@ S32 LLFontGL::render(const LLWString &wstr, if (!fgi) { llerrs << "Missing Glyph Info" << llendl; + break; } if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth)) { @@ -1334,10 +1343,10 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con renderQuad(screen_rect_offset, uv_rect, slant_offset); } } - else if (style & DROP_SHADOW) + else if (style & DROP_SHADOW_SOFT) { LLColor4 shadow_color = LLFontGL::sShadowColor; - shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength; + shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH; glColor4fv(shadow_color.mV); for (S32 pass = 0; pass < 5; pass++) { @@ -1367,6 +1376,17 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con glColor4fv(color.mV); renderQuad(screen_rect, uv_rect, slant_offset); } + else if (style & DROP_SHADOW) + { + LLColor4 shadow_color = LLFontGL::sShadowColor; + shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength; + glColor4fv(shadow_color.mV); + LLRectf screen_rect_shadow = screen_rect; + screen_rect_shadow.translate(1.f, -1.f); + renderQuad(screen_rect_shadow, uv_rect, slant_offset); + glColor4fv(color.mV); + renderQuad(screen_rect, uv_rect, slant_offset); + } else // normal rendering { glColor4fv(color.mV); diff --git a/linden/indra/llrender/llfontgl.h b/linden/indra/llrender/llfontgl.h index 98a7a55..2cd62c6 100644 --- a/linden/indra/llrender/llfontgl.h +++ b/linden/indra/llrender/llfontgl.h @@ -65,7 +65,8 @@ public: BOLD = 1, ITALIC = 2, UNDERLINE = 4, - DROP_SHADOW = 8 + DROP_SHADOW = 8, + DROP_SHADOW_SOFT = 16 }; // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC" diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp index 464507e..e2c4a59 100644 --- a/linden/indra/llrender/llimagegl.cpp +++ b/linden/indra/llrender/llimagegl.cpp @@ -129,19 +129,27 @@ void LLImageGL::bindExternalTexture(LLGLuint gl_name, S32 stage, LLGLenum bind_t // static void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target) { - glActiveTextureARB(GL_TEXTURE0_ARB + stage); - glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); - glBindTexture(bind_target, 0); - sCurrentBoundTextures[stage] = 0; + // LLGLSLShader can return -1 + if (stage >= 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB + stage); + glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); + glBindTexture(bind_target, 0); + sCurrentBoundTextures[stage] = 0; + } } // static (duplicated for speed and to avoid GL_TEXTURE_2D default argument which requires GL header dependency) void LLImageGL::unbindTexture(S32 stage) { - glActiveTextureARB(GL_TEXTURE0_ARB + stage); - glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); - glBindTexture(GL_TEXTURE_2D, 0); - sCurrentBoundTextures[stage] = 0; + // LLGLSLShader can return -1 + if (stage >= 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB + stage); + glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); + glBindTexture(GL_TEXTURE_2D, 0); + sCurrentBoundTextures[stage] = 0; + } } // static diff --git a/linden/indra/llui/llbutton.cpp b/linden/indra/llui/llbutton.cpp index d35dd57..1d44537 100644 --- a/linden/indra/llui/llbutton.cpp +++ b/linden/indra/llui/llbutton.cpp @@ -648,7 +648,7 @@ void LLButton::draw() mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset), label_color, mHAlign, LLFontGL::BOTTOM, - mDropShadowedText ? LLFontGL::DROP_SHADOW : LLFontGL::NORMAL, + mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL, U32_MAX, drawable_width, NULL, FALSE, FALSE); } diff --git a/linden/indra/llui/llcombobox.cpp b/linden/indra/llui/llcombobox.cpp index 983dd43..e00454a 100644 --- a/linden/indra/llui/llcombobox.cpp +++ b/linden/indra/llui/llcombobox.cpp @@ -55,8 +55,7 @@ S32 LLCOMBOBOX_WIDTH = 0; LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString& label, void (*commit_callback)(LLUICtrl*,void*), - void *callback_userdata, - S32 list_width + void *callback_userdata ) : LLUICtrl(name, rect, TRUE, commit_callback, callback_userdata, FOLLOWS_LEFT | FOLLOWS_TOP), @@ -99,10 +98,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString addChild(mButton); // Default size, will be set by arrange() call in button callback. - if (list_width == 0) - { - list_width = mRect.getWidth() + SCROLLBAR_SIZE; - } + S32 list_width = mRect.getWidth() + SCROLLBAR_SIZE; r.setOriginAndSize(0, 16, list_width, 220); // disallow multiple selection @@ -503,12 +499,14 @@ void LLComboBox::showList() LLRect rect = mList->getRect(); + S32 list_width = mRect.getWidth() + SCROLLBAR_SIZE; + if (mListPosition == BELOW) { if (rect.getHeight() <= -root_view_local.mBottom) { // Move rect so it hangs off the bottom of this view - rect.setLeftTopAndSize(0, 0, rect.getWidth(), rect.getHeight() ); + rect.setLeftTopAndSize(0, 0, list_width, rect.getHeight() ); } else { @@ -516,12 +514,12 @@ void LLComboBox::showList() if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) { // Move rect so it hangs off the bottom of this view - rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-root_view_local.mBottom, rect.getHeight())); + rect.setLeftTopAndSize(0, 0, list_width, llmin(-root_view_local.mBottom, rect.getHeight())); } else { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, mRect.getHeight(), list_width, llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); } } } @@ -530,7 +528,7 @@ void LLComboBox::showList() if (rect.getHeight() <= root_view_local.mTop - mRect.getHeight()) { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, mRect.getHeight(), list_width, llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); } else { @@ -538,12 +536,12 @@ void LLComboBox::showList() if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) { // Move rect so it hangs off the bottom of this view - rect.setLeftTopAndSize(0, 0, rect.getWidth(), llmin(-root_view_local.mBottom, rect.getHeight())); + rect.setLeftTopAndSize(0, 0, list_width, llmin(-root_view_local.mBottom, rect.getHeight())); } else { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), rect.getWidth(), llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, mRect.getHeight(), list_width, llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); } } diff --git a/linden/indra/llui/llcombobox.h b/linden/indra/llui/llcombobox.h index 8c317ee..d77224a 100644 --- a/linden/indra/llui/llcombobox.h +++ b/linden/indra/llui/llcombobox.h @@ -65,8 +65,7 @@ public: const LLRect &rect, const LLString& label, void (*commit_callback)(LLUICtrl*, void*) = NULL, - void *callback_userdata = NULL, - S32 list_width = 0 + void *callback_userdata = NULL ); virtual ~LLComboBox(); diff --git a/linden/indra/llui/lldraghandle.cpp b/linden/indra/llui/lldraghandle.cpp index 9e80c99..a3d28ad 100644 --- a/linden/indra/llui/lldraghandle.cpp +++ b/linden/indra/llui/lldraghandle.cpp @@ -122,6 +122,7 @@ void LLDragHandleTop::setTitle(const LLString& title) const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); mTitleBox = new LLTextBox( "Drag Handle Title", mRect, trimmed_title, font ); mTitleBox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); + mTitleBox->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); reshapeTitleBox(); // allow empty titles, as default behavior replaces them with title box name diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp index 12758b3..1613fd7 100644 --- a/linden/indra/llui/llfloater.cpp +++ b/linden/indra/llui/llfloater.cpp @@ -696,7 +696,13 @@ void LLFloater::translate(S32 x, S32 y) BOOL LLFloater::canSnapTo(LLView* other_view) { - if (other_view && other_view != getParent()) + if (NULL == other_view) + { + llwarns << "other_view is NULL" << llendl; + return FALSE; + } + + if (other_view != getParent()) { LLFloater* other_floaterp = (LLFloater*)other_view; @@ -1933,7 +1939,11 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) LLFloater* floaterp = (LLFloater*)(*view_it); sendChildToFront(floaterp); - floaterp->setMinimized(FALSE); + // always unminimize dependee, but allow dependents to stay minimized + if (!floaterp->isDependent()) + { + floaterp->setMinimized(FALSE); + } } floaters_to_move.clear(); @@ -1945,7 +1955,9 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) if (dependent) { sendChildToFront(dependent); - dependent->setMinimized(FALSE); + //don't un-minimize dependent windows automatically + // respect user's wishes + //dependent->setMinimized(FALSE); } ++dependent_it; } @@ -2555,6 +2567,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, if (!mTabContainer) { llerrs << "Tab Container used without having been initialized." << llendl; + return; } if (floaterp->getHost() == this) @@ -2718,7 +2731,7 @@ void LLMultiFloater::setVisible(BOOL visible) BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) { if (getEnabled() - && mask == (MASK_CONTROL|MASK_SHIFT)) + && mask == MASK_CONTROL) { if (key == 'W') { diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index ec156ba..a2cd9af 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -711,11 +711,11 @@ S32 LLLineEditor::prevWordPos(S32 cursorPos) const S32 LLLineEditor::nextWordPos(S32 cursorPos) const { const LLWString& wtext = mText.getWString(); - while( (cursorPos < getLength()) && isPartOfWord( wtext[cursorPos+1] ) ) + while( (cursorPos < getLength()) && isPartOfWord( wtext[cursorPos] ) ) { cursorPos++; } - while( (cursorPos < getLength()) && (wtext[cursorPos+1] == ' ') ) + while( (cursorPos < getLength()) && (wtext[cursorPos] == ' ') ) { cursorPos++; } @@ -1035,7 +1035,8 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) break; case KEY_LEFT: - if (!mIgnoreArrowKeys) + if (!mIgnoreArrowKeys + && mask != MASK_ALT) { if( hasSelection() ) { @@ -1060,7 +1061,8 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) break; case KEY_RIGHT: - if (!mIgnoreArrowKeys) + if (!mIgnoreArrowKeys + && mask != MASK_ALT) { if (hasSelection()) { diff --git a/linden/indra/llui/llmemberlistener.h b/linden/indra/llui/llmemberlistener.h old mode 100755 new mode 100644 diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp index 1920aac..9530f26 100644 --- a/linden/indra/llui/llmenugl.cpp +++ b/linden/indra/llui/llmenugl.cpp @@ -517,7 +517,7 @@ void LLMenuItemGL::draw( void ) U8 font_style = mStyle; if (LLMenuItemGL::sDropShadowText && getEnabled() && !mDrawTextDisabled ) { - font_style |= LLFontGL::DROP_SHADOW; + font_style |= LLFontGL::DROP_SHADOW_SOFT; } if ( getEnabled() && getHighlight() ) @@ -729,14 +729,18 @@ void LLMenuItemTearOffGL::doIt() LLFloater* parent_floater = LLFloater::getFloaterByHandle(mParentHandle); LLFloater* tear_off_menu = LLTearOffMenu::create(getMenu()); - if (parent_floater && tear_off_menu) + + if (tear_off_menu) { - parent_floater->addDependentFloater(tear_off_menu, FALSE); - } + if (parent_floater) + { + parent_floater->addDependentFloater(tear_off_menu, FALSE); + } - // give focus to torn off menu because it will have been taken away - // when parent menu closes - tear_off_menu->setFocus(TRUE); + // give focus to torn off menu because it will have + // been taken away when parent menu closes + tear_off_menu->setFocus(TRUE); + } } LLMenuItemGL::doIt(); } @@ -1744,7 +1748,7 @@ void LLMenuItemBranchDownGL::draw( void ) U8 font_style = mStyle; if (LLMenuItemGL::sDropShadowText && getEnabled() && !mDrawTextDisabled ) { - font_style |= LLFontGL::DROP_SHADOW; + font_style |= LLFontGL::DROP_SHADOW_SOFT; } LLColor4 color; diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp index 9e444c1..f0b5b25 100644 --- a/linden/indra/llui/llpanel.cpp +++ b/linden/indra/llui/llpanel.cpp @@ -362,7 +362,7 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) // If we have a default button, click it when // return is pressed, unless current focus is a return-capturing button // in which case *that* button will handle the return key - if (!(cur_focus->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast(cur_focus)->getCommitOnReturn())) + if (cur_focus && !(cur_focus->getWidgetType() == WIDGET_TYPE_BUTTON && static_cast(cur_focus)->getCommitOnReturn())) { // RETURN key means hit default button in this case if (key == KEY_RETURN && mask == MASK_NONE diff --git a/linden/indra/llui/lltabcontainer.cpp b/linden/indra/llui/lltabcontainer.cpp index db09717..61cfde4 100644 --- a/linden/indra/llui/lltabcontainer.cpp +++ b/linden/indra/llui/lltabcontainer.cpp @@ -941,8 +941,8 @@ void LLTabContainer::addTabPanel(LLPanel* child, else { LLString tooltip = trimmed_label; - tooltip += "\nCtrl-[ for previous tab"; - tooltip += "\nCtrl-] for next tab"; + tooltip += "\nAlt-Left arrow for previous tab"; + tooltip += "\nAlt-Right arrow for next tab"; LLButton* btn = new LLButton( LLString(child->getName()) + " tab", @@ -1486,12 +1486,12 @@ BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) if (!gFocusMgr.childHasKeyboardFocus(this)) return FALSE; BOOL handled = FALSE; - if (key == '[' && mask == MASK_CONTROL) + if (key == KEY_LEFT && mask == MASK_ALT) { selectPrevTab(); handled = TRUE; } - else if (key == ']' && mask == MASK_CONTROL) + else if (key == KEY_RIGHT && mask == MASK_ALT) { selectNextTab(); handled = TRUE; diff --git a/linden/indra/llui/lltabcontainervertical.cpp b/linden/indra/llui/lltabcontainervertical.cpp index a921b4b..317b7ca 100644 --- a/linden/indra/llui/lltabcontainervertical.cpp +++ b/linden/indra/llui/lltabcontainervertical.cpp @@ -557,12 +557,12 @@ BOOL LLTabContainerVertical::handleKeyHere(KEY key, MASK mask, BOOL called_from_ BOOL handled = FALSE; if (getEnabled()) { - if (key == '[' && mask == MASK_CONTROL) + if (key == KEY_LEFT && mask == MASK_ALT) { selectPrevTab(); handled = TRUE; } - else if (key == ']' && mask == MASK_CONTROL) + else if (key == KEY_RIGHT && mask == MASK_ALT) { selectNextTab(); handled = TRUE; diff --git a/linden/indra/llui/lltextbox.cpp b/linden/indra/llui/lltextbox.cpp index 884d638..c4f2cea 100644 --- a/linden/indra/llui/lltextbox.cpp +++ b/linden/indra/llui/lltextbox.cpp @@ -48,7 +48,7 @@ LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& t mBorderColor( LLUI::sColorsGroup->getColor( "DefaultHighlightLight" ) ), mBackgroundVisible( FALSE ), mBorderVisible( FALSE ), - mDropshadowVisible( TRUE ), + mFontStyle(LLFontGL::DROP_SHADOW_SOFT), mBorderDropShadowVisible( FALSE ), mHPad(0), mVPad(0), @@ -73,7 +73,7 @@ LLTextBox::LLTextBox(const LLString& name, const LLString& text, F32 max_width, mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")), mBackgroundVisible(FALSE), mBorderVisible(FALSE), - mDropshadowVisible(TRUE), + mFontStyle(LLFontGL::DROP_SHADOW_SOFT), mBorderDropShadowVisible(FALSE), mHPad(0), mVPad(0), @@ -363,7 +363,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) S32 line_length = *iter; mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color, mHAlign, mVAlign, - mDropshadowVisible ? LLFontGL::DROP_SHADOW : LLFontGL::NORMAL, + mFontStyle, line_length, mRect.getWidth(), NULL, TRUE ); cur_pos += line_length + 1; y -= llfloor(mFontGL->getLineHeight()); @@ -373,7 +373,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) { mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, mHAlign, mVAlign, - mDropshadowVisible ? LLFontGL::DROP_SHADOW : LLFontGL::NORMAL, + mFontStyle, S32_MAX, mRect.getWidth(), NULL, TRUE); } } @@ -406,8 +406,6 @@ LLXMLNodePtr LLTextBox::getXML(bool save_children) const node->createChild("border_visible", TRUE)->setBoolValue(mBorderVisible); - node->createChild("drop_shadow_visible", TRUE)->setBoolValue(mDropshadowVisible); - node->createChild("border_drop_shadow_visible", TRUE)->setBoolValue(mBorderDropShadowVisible); node->createChild("h_pad", TRUE)->setIntValue(mHPad); @@ -447,6 +445,12 @@ LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f text_box->initFromXML(node, parent); + LLString font_style; + if (node->getAttributeString("font-style", font_style)) + { + text_box->mFontStyle = LLFontGL::getStyleFromString(font_style); + } + if(node->hasAttribute("text_color")) { LLColor4 color; diff --git a/linden/indra/llui/lltextbox.h b/linden/indra/llui/lltextbox.h index 45d6acb..e8d4690 100644 --- a/linden/indra/llui/lltextbox.h +++ b/linden/indra/llui/lltextbox.h @@ -74,7 +74,7 @@ public: void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; } void setBorderVisible(BOOL visible) { mBorderVisible = visible; } - void setDropshadowVisible(BOOL visible) { mDropshadowVisible = visible; } + void setFontStyle(U8 style) { mFontStyle = style; } void setBorderDropshadowVisible(BOOL visible){ mBorderDropShadowVisible = visible; } void setHPad(S32 pixels) { mHPad = pixels; } void setVPad(S32 pixels) { mVPad = pixels; } @@ -112,7 +112,7 @@ protected: BOOL mBackgroundVisible; BOOL mBorderVisible; - BOOL mDropshadowVisible; // Draws black dropshadow below and to the right of the text. + U8 mFontStyle; // style bit flags for font BOOL mBorderDropShadowVisible; S32 mHPad; diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index 787eba5..ba991c2 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp @@ -723,11 +723,11 @@ S32 LLTextEditor::prevWordPos(S32 cursorPos) const S32 LLTextEditor::nextWordPos(S32 cursorPos) const { const LLWString& wtext = mWText; - while( (cursorPos < getLength()) && isPartOfWord( wtext[cursorPos+1] ) ) + while( (cursorPos < getLength()) && isPartOfWord( wtext[cursorPos] ) ) { cursorPos++; } - while( (cursorPos < getLength()) && (wtext[cursorPos+1] == ' ') ) + while( (cursorPos < getLength()) && (wtext[cursorPos] == ' ') ) { cursorPos++; } @@ -3667,10 +3667,18 @@ void LLTextEditor::pruneSegments() break; // done } } - // erase invalid segments - ++iter; - std::for_each(iter, mSegments.end(), DeletePointer()); - mSegments.erase(iter, mSegments.end()); + if (iter != mSegments.end()) + { + // erase invalid segments + ++iter; + std::for_each(iter, mSegments.end(), DeletePointer()); + mSegments.erase(iter, mSegments.end()); + } + else + { + llwarns << "Tried to erase end of empty LLTextEditor" + << llendl; + } } void LLTextEditor::findEmbeddedItemSegments() diff --git a/linden/indra/llui/llui.cpp b/linden/indra/llui/llui.cpp index 9d689b5..a725281 100644 --- a/linden/indra/llui/llui.cpp +++ b/linden/indra/llui/llui.cpp @@ -421,6 +421,12 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border stop_glerror(); F32 border_scale = 1.f; + if (NULL == image) + { + llwarns << "image == NULL; aborting function" << llendl; + return; + } + if (border_height * 2 > height) { border_scale = (F32)height / ((F32)border_height * 2.f); @@ -599,6 +605,12 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LL void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLImageGL* image, const LLColor4& color) { + if (NULL == image) + { + llwarns << "image == NULL; aborting function" << llendl; + return; + } + LLGLSUIDefault gls_ui; glPushMatrix(); @@ -639,6 +651,12 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color) { + if (NULL == image) + { + llwarns << "image == NULL; aborting function" << llendl; + return; + } + LLGLSUIDefault gls_ui; glPushMatrix(); diff --git a/linden/indra/llui/lluistring.cpp b/linden/indra/llui/lluistring.cpp old mode 100755 new mode 100644 diff --git a/linden/indra/llui/lluistring.h b/linden/indra/llui/lluistring.h old mode 100755 new mode 100644 diff --git a/linden/indra/llui/llviewborder.cpp b/linden/indra/llui/llviewborder.cpp index 4c2b602..84f396b 100644 --- a/linden/indra/llui/llviewborder.cpp +++ b/linden/indra/llui/llviewborder.cpp @@ -59,7 +59,7 @@ LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bev } // virtual -BOOL LLViewBorder::isCtrl() +BOOL LLViewBorder::isCtrl() const { return FALSE; } diff --git a/linden/indra/llui/llviewborder.h b/linden/indra/llui/llviewborder.h index 7e5de4b..38d6c9f 100644 --- a/linden/indra/llui/llviewborder.h +++ b/linden/indra/llui/llviewborder.h @@ -54,7 +54,7 @@ public: virtual EWidgetType getWidgetType() const; virtual LLString getWidgetTag() const; - virtual BOOL isCtrl(); + virtual BOOL isCtrl() const; // llview functionality virtual void draw(); diff --git a/linden/indra/llvfs/llvfs.cpp b/linden/indra/llvfs/llvfs.cpp index a41aa78..b83d12c 100644 --- a/linden/indra/llvfs/llvfs.cpp +++ b/linden/indra/llvfs/llvfs.cpp @@ -307,6 +307,8 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r { llwarns << "Couldn't open vfs data file after trying many alternates" << llendl; mValid = VFSVALID_BAD_CANNOT_CREATE; + delete[] temp_index; + delete[] temp_data; return; } @@ -394,7 +396,6 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r // to heal after some errors. JC if (block->mLength > 0 && (U32)block->mLength <= data_size && - block->mLocation >= 0 && block->mLocation < data_size && block->mSize > 0 && block->mSize <= block->mLength && @@ -435,7 +436,7 @@ LLVFS::LLVFS(const char *index_filename, const char *data_filename, const BOOL r delete block; } - tmp_ptr += block->SERIAL_SIZE; + tmp_ptr += LLVFSFileBlock::SERIAL_SIZE; } delete[] buffer; @@ -658,6 +659,7 @@ void LLVFS::presizeDataFile(const U32 size) if (!mDataFP) { llerrs << "LLVFS::presizeDataFile() with no data file open" << llendl; + return; } // we're creating this file for the first time, size it @@ -1731,7 +1733,6 @@ void LLVFS::audit() // do sanity check on this block if (block->mLength >= 0 && - block->mLocation >= 0 && block->mSize >= 0 && block->mSize <= block->mLength && block->mFileType >= LLAssetType::AT_NONE && diff --git a/linden/indra/llwindow/llwindow_vc8.vcproj b/linden/indra/llwindow/llwindow_vc8.vcproj index b04477f..4d6bbcb 100644 --- a/linden/indra/llwindow/llwindow_vc8.vcproj +++ b/linden/indra/llwindow/llwindow_vc8.vcproj @@ -4,6 +4,7 @@ Version="8.00" Name="llwindow" ProjectGUID="{B5B53617-416F-404A-BF10-22EBCCA0E4FB}" + RootNamespace="llwindow" Keyword="Win32Proj" > @@ -40,17 +41,15 @@ @@ -108,16 +107,12 @@ /> @@ -243,15 +237,13 @@ @@ -386,6 +378,222 @@ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llwindow/llwindowsdl.cpp b/linden/indra/llwindow/llwindowsdl.cpp index c375e32..f7b4071 100644 --- a/linden/indra/llwindow/llwindowsdl.cpp +++ b/linden/indra/llwindow/llwindowsdl.cpp @@ -1,6 +1,6 @@ /** * @file llwindowsdl.cpp - * @brief Platform-dependent implementation of llwindow + * @brief SDL implementation of LLWindow class * * Copyright (c) 2001-2007, Linden Research, Inc. * @@ -55,12 +55,6 @@ extern BOOL gDebugWindowProc; -// culled from winuser.h -//const S32 WHEEL_DELTA = 120; /* Value for rolling one detent */ -// On the Mac, the scroll wheel reports a delta of 1 for each detent. -// There's also acceleration for faster scrolling, based on a slider in the system preferences. -const S32 WHEEL_DELTA = 1; /* Value for rolling one detent */ -const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; // @@ -74,37 +68,11 @@ const S32 MAX_NUM_RESOLUTIONS = 32; // TOFU HACK -- (*exactly* the same hack as LLWindowMacOSX for a similar // set of reasons): Stash a pointer to the LLWindowSDL object here and // maintain in the constructor and destructor. This assumes that there will -// be only one object of this class at any time. Hopefully this is true. +// be only one object of this class at any time. Currently this is true. static LLWindowSDL *gWindowImplementation = NULL; static BOOL was_fullscreen = FALSE; -// Cross-platform bits: - -void show_window_creation_error(const char* title) -{ - llwarns << title << llendl; - shell_open( "help/window_creation_error.html"); - /* - OSMessageBox( - "Second Life is unable to run because it can't set up your display.\n" - "We need to be able to make a 32-bit color window at 1024x768, with\n" - "an 8 bit alpha channel.\n" - "\n" - "First, be sure your monitor is set to True Color (32-bit) in\n" - "Start -> Control Panels -> Display -> Settings.\n" - "\n" - "Otherwise, this may be due to video card driver issues.\n" - "Please make sure you have the latest video card drivers installed.\n" - "ATI drivers are available at http://www.ati.com/\n" - "nVidia drivers are available at http://www.nvidia.com/\n" - "\n" - "If you continue to receive this message, contact customer service.", - title, - OSMB_OK); - */ -} - void maybe_lock_display(void) { @@ -275,7 +243,7 @@ LLWindowSDL::LLWindowSDL(char *title, S32 x, S32 y, S32 width, #endif // LL_GTK // Get the original aspect ratio of the main device. - mOriginalAspectRatio = 1024.0 / 768.0; // !!! FIXME //(double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay); + mOriginalAspectRatio = 1024.0 / 768.0; // !!! *FIX: ? //(double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay); if (!title) title = "SDL Window"; // *FIX: (???) @@ -325,6 +293,105 @@ static SDL_Surface *Load_BMP_Resource(const char *basename) return SDL_LoadBMP(path_buffer); } +#if LL_X11 +// This is an XFree86/XOrg-specific hack for detecting the amount of Video RAM +// on this machine. It works by searching /var/log/var/log/Xorg.?.log or +// /var/log/XFree86.?.log for a ': VideoRAM: (%d+) kB' regex, where '?' is +// the X11 display number derived from $DISPLAY +static int x11_detect_VRAM_kb_fp(FILE *fp) +{ + const int line_buf_size = 1000; + char line_buf[line_buf_size]; + while (fgets(line_buf, line_buf_size, fp)) + { + //lldebugs << "XLOG: " << line_buf << llendl; + + // Why the ad-hoc parser instead of using a regex? Our + // favourite regex implementation - libboost_regex - is + // quite a heavy and troublesome dependency for the client, so + // it seems a shame to introduce it for such a simple task. + const char part1_template[] = ": VideoRAM: "; + const char part2_template[] = " kB"; + char *part1 = strstr(line_buf, part1_template); + if (part1) // found start of matching line + { + part1 = &part1[strlen(part1_template)]; // -> after + char *part2 = strstr(part1, part2_template); + if (part2) // found end of matching line + { + // now everything between part1 and part2 is + // supposed to be numeric, describing the + // number of kB of Video RAM supported + int rtn = 0; + for (; part1 < part2; ++part1) + { + //lldebugs << "kB" << *part1 << llendl; + if (*part1 < '0' || *part1 > '9') + { + // unexpected char, abort parse + rtn = 0; + break; + } + rtn *= 10; + rtn += (*part1) - '0'; + } + if (rtn > 0) + { + // got the kB number. return it now. + return rtn; + } + } + } + } + return 0; // 'could not detect' +} +static int x11_detect_VRAM_kb() +{ + std::string x_log_location("/var/log/"); + std::string fname; + int rtn = 0; // 'could not detect' + int display_num = 0; + FILE *fp; + char *display_env = getenv("DISPLAY"); // e.g. :0 or :0.0 or :1.0 etc + // parse DISPLAY number so we can go grab the right log file + if (display_env[0] == ':' && + display_env[1] >= '0' && display_env[1] <= '9') + { + display_num = display_env[1] - '0'; + } + + // *TODO: we could be smarter and see which of Xorg/XFree86 has the + // freshest time-stamp. + + // Try XOrg log first + fname = x_log_location; + fname += "Xorg."; + fname += ('0' + display_num); + fname += ".log"; + fp = fopen(fname.c_str(), "r"); + if (fp) + { + rtn = x11_detect_VRAM_kb_fp(fp); + fclose(fp); + } + // Try old XFree86 log otherwise + if (rtn == 0) + { + fname = x_log_location; + fname += "XFree86."; + fname += ('0' + display_num); + fname += ".log"; + fp = fopen(fname.c_str(), "r"); + if (fp) + { + rtn = x11_detect_VRAM_kb_fp(fp); + fclose(fp); + } + } + return rtn; +} +#endif // LL_X11 + BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) { //bool glneedsinit = false; @@ -511,67 +578,40 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B { llinfos << "createContext: SKIPPING - !fullscreen, but +mWindow " << width << "x" << height << "x" << bits << llendl; } - - /*if (!load_all_glsyms(gllibname)) - { - SDL_QuitSubSystem(SDL_INIT_VIDEO); - return FALSE; - }*/ - - gGLManager.mVRAM = videoInfo->video_mem / 1024; + + // Detect video memory size. +# if LL_X11 + gGLManager.mVRAM = x11_detect_VRAM_kb() / 1024; if (gGLManager.mVRAM != 0) { - llinfos << "Detected " << gGLManager.mVRAM << "MB VRAM." << llendl; - } - // If VRAM is not detected, that is handled later - -#if 0 // *FIX: all video cards suck under Linux. :) - // Since we just created the context, it needs to be set up. - glNeedsInit = TRUE; - if(glNeedsInit) - { - // Check for some explicitly unsupported cards. - const char* RENDERER = (const char*) glGetString(GL_RENDERER); - - const char* CARD_LIST[] = - { "RAGE 128", - "RIVA TNT2", - "Intel 810", - "3Dfx/Voodoo3", - "Radeon 7000", - "Radeon 7200", - "Radeon 7500", - "Radeon DDR", - "Radeon VE", - "GDI Generic" }; - const S32 CARD_COUNT = sizeof(CARD_LIST)/sizeof(char*); - - // Future candidates: - // ProSavage/Twister - // SuperSavage - - S32 i; - for (i = 0; i < CARD_COUNT; i++) + llinfos << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << llendl; + } else +# endif // LL_X11 + { + // fallback to letting SDL detect VRAM. + // note: I've not seen SDL's detection ever actually find + // VRAM != 0, but if SDL *does* detect it then that's a bonus. + gGLManager.mVRAM = videoInfo->video_mem / 1024; + if (gGLManager.mVRAM != 0) { - if (check_for_card(RENDERER, CARD_LIST[i])) - { - close(); - shell_open( "help/unsupported_card.html" ); - return FALSE; - } + llinfos << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << llendl; } } -#endif + // If VRAM is not detected, that is handled later - GLint depthBits, stencilBits, redBits, greenBits, blueBits, alphaBits; + // *TODO: Now would be an appropriate time to check for some + // explicitly unsupported cards. + //const char* RENDERER = (const char*) glGetString(GL_RENDERER); - glGetIntegerv(GL_RED_BITS, &redBits); - glGetIntegerv(GL_GREEN_BITS, &greenBits); - glGetIntegerv(GL_BLUE_BITS, &blueBits); - glGetIntegerv(GL_ALPHA_BITS, &alphaBits); - glGetIntegerv(GL_DEPTH_BITS, &depthBits); - glGetIntegerv(GL_STENCIL_BITS, &stencilBits); + GLint depthBits, stencilBits, redBits, greenBits, blueBits, alphaBits; + glGetIntegerv(GL_RED_BITS, &redBits); + glGetIntegerv(GL_GREEN_BITS, &greenBits); + glGetIntegerv(GL_BLUE_BITS, &blueBits); + glGetIntegerv(GL_ALPHA_BITS, &alphaBits); + glGetIntegerv(GL_DEPTH_BITS, &depthBits); + glGetIntegerv(GL_STENCIL_BITS, &stencilBits); + llinfos << "GL buffer:" << llendl llinfos << " Red Bits " << S32(redBits) << llendl llinfos << " Green Bits " << S32(greenBits) << llendl @@ -1022,7 +1062,9 @@ void LLWindowSDL::beforeDialog() { // Everything that we/SDL asked for should happen before we // potentially hand control over to GTK. + maybe_lock_display(); XSync(mSDL_Display, False); + maybe_unlock_display(); } #endif // LL_X11 @@ -1066,6 +1108,7 @@ void LLWindowSDL::x11_set_urgent(BOOL urgent) llinfos << "X11 hint for urgency, " << urgent << llendl; + maybe_lock_display(); wm_hints = XGetWMHints(mSDL_Display, mSDL_XWindowID); if (!wm_hints) wm_hints = XAllocWMHints(); @@ -1078,6 +1121,7 @@ void LLWindowSDL::x11_set_urgent(BOOL urgent) XSetWMHints(mSDL_Display, mSDL_XWindowID, wm_hints); XFree(wm_hints); XSync(mSDL_Display, False); + maybe_unlock_display(); } } #endif // LL_X11 @@ -1782,10 +1826,12 @@ BOOL LLWindowSDL::SDLReallyCaptureInput(BOOL capture) { //llinfos << "X11 POINTER GRABBY" << llendl; //newmode = SDL_WM_GrabInput(wantmode); + maybe_lock_display(); result = XGrabPointer(mSDL_Display, mSDL_XWindowID, True, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + maybe_unlock_display(); if (GrabSuccess == result) newmode = SDL_GRAB_ON; else @@ -1795,10 +1841,12 @@ BOOL LLWindowSDL::SDLReallyCaptureInput(BOOL capture) //llinfos << "X11 POINTER UNGRABBY" << llendl; newmode = SDL_GRAB_OFF; //newmode = SDL_WM_GrabInput(SDL_GRAB_OFF); - + + maybe_lock_display(); XUngrabPointer(mSDL_Display, CurrentTime); // Make sure the ungrab happens RIGHT NOW. XSync(mSDL_Display, False); + maybe_unlock_display(); } else { newmode = SDL_GRAB_QUERY; // neutral @@ -1875,7 +1923,7 @@ void LLWindowSDL::gatherInput() std::string saved_locale = setlocale(LC_ALL, NULL); // Do a limited number of pumps so SL doesn't starve! - // FIXME - this should ideally be time-limited, not count-limited. + // *TODO: this should ideally be time-limited, not count-limited. gtk_main_iteration_do(0); // Always do one non-blocking pump for (int iter=0; iter<10; ++iter) if (gtk_events_pending()) @@ -2101,8 +2149,8 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty if (bmpsurface && bmpsurface->w%8==0) { SDL_Surface *cursurface; - llinfos << "Loaded cursor file " << filename << " " - << bmpsurface->w << "x" << bmpsurface->h << llendl; + lldebugs << "Loaded cursor file " << filename << " " + << bmpsurface->w << "x" << bmpsurface->h << llendl; cursurface = SDL_CreateRGBSurface (SDL_SWSURFACE, bmpsurface->w, bmpsurface->h, @@ -2282,14 +2330,14 @@ void LLWindowSDL::hideCursor() { if(!mCursorHidden) { - // llinfos << "hideCursor: hiding" << llendl; + // llinfos << "hideCursor: hiding" << llendl; mCursorHidden = TRUE; mHideCursorPermanent = TRUE; SDL_ShowCursor(0); } else { - // llinfos << "hideCursor: already hidden" << llendl; + // llinfos << "hideCursor: already hidden" << llendl; } adjustCursorDecouple(); @@ -2299,14 +2347,14 @@ void LLWindowSDL::showCursor() { if(mCursorHidden) { - // llinfos << "showCursor: showing" << llendl; + // llinfos << "showCursor: showing" << llendl; mCursorHidden = FALSE; mHideCursorPermanent = FALSE; SDL_ShowCursor(1); } else { - // llinfos << "showCursor: already visible" << llendl; + // llinfos << "showCursor: already visible" << llendl; } adjustCursorDecouple(); @@ -2332,7 +2380,8 @@ void LLWindowSDL::hideCursorUntilMouseMove() // -// LLSplashScreenSDL +// LLSplashScreenSDL - I don't think we'll bother to implement this; it's +// fairly obsolete at this point. // LLSplashScreenSDL::LLSplashScreenSDL() { @@ -2350,7 +2399,6 @@ void LLSplashScreenSDL::updateImpl(const char* mesg) { } - void LLSplashScreenSDL::hideImpl() { } @@ -2438,7 +2486,7 @@ S32 OSMessageBoxSDL(const char* text, const char* caption, U32 type) G_CALLBACK (response_callback), &response); - // we should be able to us a gtk_dialog_run(), but it's + // we should be able to use a gtk_dialog_run(), but it's // apparently not written to exist in a world without a higher // gtk_main(), so we manage its signal/destruction outselves. gtk_widget_show_all (win); @@ -2460,7 +2508,7 @@ S32 OSMessageBoxSDL(const char* text, const char* caption, U32 type) } else { - fprintf(stderr, "MSGBOX: %s: %s\n", caption, text); + llinfos << "MSGBOX: " << caption << ": " << text << llendl; llinfos << "Skipping dialog because we're in fullscreen mode or GTK is not happy." << llendl; rtn = OSBTN_OK; } @@ -2556,7 +2604,7 @@ BOOL LLWindowSDL::dialog_color_picker ( F32 *r, F32 *g, F32 *b) #else S32 OSMessageBoxSDL(const char* text, const char* caption, U32 type) { - fprintf(stderr, "MSGBOX: %s: %s\n", caption, text); + llinfos << "MSGBOX: " << caption << ": " << text << llendl; return 0; } @@ -2573,11 +2621,15 @@ void spawn_web_browser(const char* escaped_url) llinfos << "spawn_web_browser: " << escaped_url << llendl; #if LL_LINUX -# if LL_X11 - if (gWindowImplementation && - gWindowImplementation->mSDL_Display) // Just in case - before forking. +# if LL_X11 + if (gWindowImplementation && gWindowImplementation->mSDL_Display) + { + maybe_lock_display(); + // Just in case - before forking. XSync(gWindowImplementation->mSDL_Display, False); -# endif // LL_X11 + maybe_unlock_display(); + } +# endif // LL_X11 std::string cmd; cmd = gDirUtilp->getAppRODataDir().c_str(); @@ -2615,8 +2667,8 @@ void spawn_web_browser(const char* escaped_url) void shell_open( const char* file_path ) { - // *FIX: (???) - fprintf(stderr, "shell_open: %s\n", file_path); + // *TODO: This function is deprecated and should probably go away. + llwarns << "Deprecated shell_open(): " << file_path << llendl; } void *LLWindowSDL::getPlatformWindow() @@ -2624,18 +2676,14 @@ void *LLWindowSDL::getPlatformWindow() #if LL_GTK && LL_LIBXUL_ENABLED if (ll_try_gtk_init()) { + maybe_lock_display(); GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - // These hacks were attempts to get Gecko to see the keyboard, - // but I think they're doomed to fail. - //GdkWindow *gdkwin = gdk_window_foreign_new(SDL_XWindowID); - //GTK_WIDGET(win)->window = gdkwin; - //gtk_widget_set_parent_window(win, gdkwin); - // show the hidden-widget while debugging (needs mozlib change) //gtk_widget_show_all(GTK_WIDGET(win)); gtk_widget_realize(GTK_WIDGET(win)); + maybe_unlock_display(); return win; } #endif // LL_GTK && LL_LIBXUL_ENABLED @@ -2645,8 +2693,18 @@ void *LLWindowSDL::getPlatformWindow() void LLWindowSDL::bringToFront() { - // *FIX: (???) - fprintf(stderr, "bringToFront\n"); + // This is currently used when we are 'launched' to a specific + // map position externally. + llinfos << "bringToFront" << llendl; +#if LL_X11 + if (mSDL_Display && !mFullscreen) + { + maybe_lock_display(); + XRaiseWindow(mSDL_Display, mSDL_XWindowID); + XSync(mSDL_Display, False); + maybe_unlock_display(); + } +#endif // LL_X11 } #endif // LL_SDL diff --git a/linden/indra/llwindow/llwindowwin32.cpp b/linden/indra/llwindow/llwindowwin32.cpp index 7c3ec01..3c2e730 100644 --- a/linden/indra/llwindow/llwindowwin32.cpp +++ b/linden/indra/llwindow/llwindowwin32.cpp @@ -54,8 +54,12 @@ #include "indra_constants.h" // culled from winuser.h +#ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */ const S32 WM_MOUSEWHEEL = 0x020A; +#endif +#ifndef WHEEL_DELTA /* Added to be compatible with later SDK's */ const S32 WHEEL_DELTA = 120; /* Value for rolling one detent */ +#endif const S32 MAX_MESSAGE_PER_UPDATE = 20; const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; @@ -1646,7 +1650,7 @@ void LLWindowWin32::setCursor(ECursorType cursor) } } -ECursorType LLWindowWin32::getCursor() +ECursorType LLWindowWin32::getCursor() const { return mCurrentCursor; } @@ -2299,7 +2303,7 @@ BOOL LLWindowWin32::convertCoords(LLCoordGL from, LLCoordScreen *to) BOOL LLWindowWin32::isClipboardTextAvailable() { - return IsClipboardFormatAvailable(CF_UNICODETEXT) || IsClipboardFormatAvailable( CF_TEXT ); + return IsClipboardFormatAvailable(CF_UNICODETEXT); } @@ -2326,27 +2330,6 @@ BOOL LLWindowWin32::pasteTextFromClipboard(LLWString &dst) CloseClipboard(); } } - else if (IsClipboardFormatAvailable(CF_TEXT)) - { - // This must be an OLD OS. We don't do non-ASCII for old OSes - if (OpenClipboard(mWindowHandle)) - { - HGLOBAL h_data = GetClipboardData(CF_TEXT); - if (h_data) - { - char* str = (char*) GlobalLock(h_data); - if (str) - { - // Strip non-ASCII characters - dst = utf8str_to_wstring(mbcsstring_makeASCII(str)); - LLWString::removeCRLF(dst); - GlobalUnlock(h_data); - success = TRUE; - } - } - CloseClipboard(); - } - } return success; } @@ -2383,30 +2366,6 @@ BOOL LLWindowWin32::copyTextToClipboard(const LLWString& wstr) } } - // Also provide a copy as raw ASCII text. - LLWString ascii_string(wstr); - LLWString::_makeASCII(ascii_string); - LLWString::addCRLF(ascii_string); - std::string out_s = wstring_to_utf8str(ascii_string); - const size_t size = (out_s.length() + 1) * sizeof(char); - - // Memory is allocated and then ownership of it is transfered to the system. - HGLOBAL hglobal_copy = GlobalAlloc(GMEM_MOVEABLE, size); - if (hglobal_copy) - { - char* copy = (char*) GlobalLock(hglobal_copy); - if( copy ) - { - memcpy(copy, out_s.c_str(), size); /* Flawfinder: ignore */ - GlobalUnlock(hglobal_copy); - - if (SetClipboardData(CF_TEXT, hglobal_copy)) - { - success = TRUE; - } - } - } - CloseClipboard(); } diff --git a/linden/indra/llwindow/llwindowwin32.h b/linden/indra/llwindow/llwindowwin32.h index 040c9ab..691c648 100644 --- a/linden/indra/llwindow/llwindowwin32.h +++ b/linden/indra/llwindow/llwindowwin32.h @@ -65,7 +65,7 @@ public: /*virtual*/ void hideCursorUntilMouseMove(); /*virtual*/ BOOL isCursorHidden(); /*virtual*/ void setCursor(ECursorType cursor); - /*virtual*/ ECursorType getCursor(); + /*virtual*/ ECursorType getCursor() const; /*virtual*/ void captureMouse(); /*virtual*/ void releaseMouse(); /*virtual*/ void setMouseClipping( BOOL b ); diff --git a/linden/indra/llxml/llxmlnode.cpp b/linden/indra/llxml/llxmlnode.cpp index eb48b41..b83555a 100644 --- a/linden/indra/llxml/llxmlnode.cpp +++ b/linden/indra/llxml/llxmlnode.cpp @@ -311,6 +311,12 @@ void XMLCALL StartXMLNode(void *userData, // Set the parent-child relationship with the current active node LLXMLNode* parent = (LLXMLNode *)userData; + if (NULL == parent) + { + llwarns << "parent (userData) is NULL; aborting function" << llendl; + return; + } + new_node_ptr->mParser = parent->mParser; // Set the current active node to the new node diff --git a/linden/indra/lscript/lscript_alloc.h b/linden/indra/lscript/lscript_alloc.h index b195e3a..8179446 100644 --- a/linden/indra/lscript/lscript_alloc.h +++ b/linden/indra/lscript/lscript_alloc.h @@ -287,7 +287,9 @@ inline LLScriptLibData *lsa_bubble_sort(LLScriptLibData *src, S32 stride, S32 as src->mListp = NULL; - return sortarray[0]; + temp = sortarray[0]; + delete[] sortarray; + return temp; } diff --git a/linden/indra/lscript/lscript_compile/lscript_tree.cpp b/linden/indra/lscript/lscript_compile/lscript_tree.cpp index 1d7cc7b..df679ed 100644 --- a/linden/indra/lscript/lscript_compile/lscript_tree.cpp +++ b/linden/indra/lscript/lscript_compile/lscript_tree.cpp @@ -9936,6 +9936,8 @@ void LLScriptScript::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass code->build(fp, bcfp); fclose(bcfp); + + delete code; } break; case LSCP_EMIT_CIL_ASSEMBLY: diff --git a/linden/indra/lscript/lscript_execute/lscript_execute.cpp b/linden/indra/lscript/lscript_execute/lscript_execute.cpp index cc2c141..4d8389a 100644 --- a/linden/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/linden/indra/lscript/lscript_execute/lscript_execute.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lscript_execute.cpp * @brief classes to execute bytecode * @@ -75,7 +75,7 @@ LLScriptExecute::LLScriptExecute(FILE *fp) LLScriptExecute::LLScriptExecute(U8 *buffer) { - mBuffer = buffer; + mBuffer = buffer; init(); } @@ -1001,7 +1001,7 @@ BOOL run_loadgsp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) S32 address = lscript_global_get(buffer, arg); if (address) lsa_decrease_ref_count(buffer, address); - + lscript_global_store(buffer, arg, value); return FALSE; } @@ -1019,7 +1019,7 @@ BOOL run_loadglp(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) S32 address = lscript_global_get(buffer, arg); if (address) lsa_decrease_ref_count(buffer, address); - + lscript_global_store(buffer, arg, value); return FALSE; } @@ -1386,14 +1386,31 @@ void integer_integer_operation(U8 *buffer, LSCRIPTOpCodesEnum opcode) result = lside * rside; break; case LOPC_DIV: - if (rside) - result = lside / rside; + if (rside){ + if( ( rside == -1 ) || ( rside == 0xffffffff ) )// division by -1 can have funny results: multiplication is OK: SL-31252 + { + result = -1 * lside; + } + else + { + result = lside / rside; + } + } else set_fault(buffer, LSRF_MATH); break; case LOPC_MOD: if (rside) - result = lside % rside; + { + if (rside == -1 || rside == 1 ) // mod(1) = mod(-1) = 0: SL-31252 + { + result = 0; + } + else + { + result = lside % rside; + } + } else set_fault(buffer, LSRF_MATH); break; @@ -2945,14 +2962,14 @@ BOOL run_return(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) return FALSE; } -S32 axtoi(char *hexStg) +S32 axtoi(char *hexStg) { S32 n = 0; // position in string S32 m = 0; // position in digit[] to shift S32 count; // loop index S32 intValue = 0; // integer value of hex string S32 digit[9]; // hold values to convert - while (n < 8) + while (n < 8) { if (hexStg[n]=='\0') break; @@ -2968,7 +2985,7 @@ S32 axtoi(char *hexStg) count = n; m = n - 1; n = 0; - while(n < count) + while(n < count) { // digit[n] is value of hex digit at position n // (m << 2) is the number of positions to shift @@ -3140,7 +3157,7 @@ BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) bytestream2char(arg, buffer, string); F32 dest = (F32)atof(arg); - + lscript_push(buffer, dest); delete [] arg; } @@ -3338,7 +3355,7 @@ BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) delete list_root; char *tmp = strdup(dest.str().c_str()); LLScriptLibData *string = new LLScriptLibData(tmp); - free(tmp); + free(tmp); tmp = NULL; S32 destaddress = lsa_heap_add_data(buffer, string, get_max_heap_size(buffer), TRUE); lscript_push(buffer, destaddress); @@ -3393,7 +3410,7 @@ void lscript_stacktol_pop_variable(LLScriptLibData *data, U8 *buffer, char type) break; case LST_KEY: data->mType = LST_KEY; - + base_address = lscript_pop_int(buffer); // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization // and function clean up of ref counts isn't based on scope (a mistake, I know) @@ -3617,48 +3634,53 @@ BOOL run_print(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) void lscript_run(char *filename, BOOL b_debug) { LLTimer timer; - char *error; - BOOL b_state; - LLScriptExecute *execute = NULL; if (filename == NULL) { - llerrs << "filename is empty" << llendl; + llerrs << "filename is NULL" << llendl; // Just reporting error is likely not enough. Need // to check how to abort or error out gracefully // from this function. XXXTBD } - FILE* file = LLFile::fopen(filename, "r"); /* Flawfinder: ignore */ - if (file) - { - execute = new LLScriptExecute(file); - fclose(file); - } - file = LLFile::fopen(filename, "r"); /* Flawfinder: ignore */ - if (file) - { - FILE* fp = LLFile::fopen("lscript.parse", "w"); /*Flawfinder: ignore*/ - LLScriptLSOParse *parse = new LLScriptLSOParse(file); - parse->printData(fp); - fclose(file); - fclose(fp); - } - file = LLFile::fopen(filename, "r"); /*Flawfinder: ignore*/ - if (file && execute) + else { - timer.reset(); - while (!execute->run(b_debug, LLUUID::null, &error, b_state)) - ; - F32 time = timer.getElapsedTimeF32(); - F32 ips = execute->mInstructionCount / time; - llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl; - llinfos << ips/1000 << "K instructions per second" << llendl; - printf("ip: 0x%X\n", get_register(execute->mBuffer, LREG_IP)); - printf("sp: 0x%X\n", get_register(execute->mBuffer, LREG_SP)); - printf("bp: 0x%X\n", get_register(execute->mBuffer, LREG_BP)); - printf("hr: 0x%X\n", get_register(execute->mBuffer, LREG_HR)); - printf("hp: 0x%X\n", get_register(execute->mBuffer, LREG_HP)); - delete execute; - fclose(file); + char *error; + BOOL b_state; + LLScriptExecute *execute = NULL; + + FILE* file = LLFile::fopen(filename, "r"); + if (file) + { + execute = new LLScriptExecute(file); + // note: LLScriptExecute() closes file for us + } + file = LLFile::fopen(filename, "r"); + if (file) + { + FILE* fp = LLFile::fopen("lscript.parse", "w"); /*Flawfinder: ignore*/ + LLScriptLSOParse *parse = new LLScriptLSOParse(file); + parse->printData(fp); + delete parse; + fclose(file); + fclose(fp); + } + file = LLFile::fopen(filename, "r"); + if (file && execute) + { + timer.reset(); + while (!execute->run(b_debug, LLUUID::null, &error, b_state)) + ; + F32 time = timer.getElapsedTimeF32(); + F32 ips = execute->mInstructionCount / time; + llinfos << execute->mInstructionCount << " instructions in " << time << " seconds" << llendl; + llinfos << ips/1000 << "K instructions per second" << llendl; + printf("ip: 0x%X\n", get_register(execute->mBuffer, LREG_IP)); + printf("sp: 0x%X\n", get_register(execute->mBuffer, LREG_SP)); + printf("bp: 0x%X\n", get_register(execute->mBuffer, LREG_BP)); + printf("hr: 0x%X\n", get_register(execute->mBuffer, LREG_HR)); + printf("hp: 0x%X\n", get_register(execute->mBuffer, LREG_HP)); + delete execute; + fclose(file); + } } } @@ -3679,7 +3701,7 @@ void lscript_pop_variable(LLScriptLibData *data, U8 *buffer, char type) break; case 'k': data->mType = LST_KEY; - + base_address = lscript_pop_int(buffer); // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization // and function clean up of ref counts isn't based on scope (a mistake, I know) diff --git a/linden/indra/lscript/lscript_execute/lscript_readlso.cpp b/linden/indra/lscript/lscript_execute/lscript_readlso.cpp index d750535..077e47c 100644 --- a/linden/indra/lscript/lscript_execute/lscript_readlso.cpp +++ b/linden/indra/lscript/lscript_execute/lscript_readlso.cpp @@ -42,7 +42,6 @@ LLScriptLSOParse::LLScriptLSOParse(FILE *fp) mRawData = new U8[filesize]; fseek(fp, 0, SEEK_SET); fread(mRawData, 1, filesize, fp); - fclose(fp); initOpCodePrinting(); } diff --git a/linden/indra/lscript/lscript_library/lscript_library.cpp b/linden/indra/lscript/lscript_library/lscript_library.cpp index ec1cc03..7d38621 100644 --- a/linden/indra/lscript/lscript_library/lscript_library.cpp +++ b/linden/indra/lscript/lscript_library/lscript_library.cpp @@ -401,7 +401,7 @@ void LLScriptLibrary::init() addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCameraParams", NULL, "l", "llSetCameraParams(list rules)\nSets multiple camera parameters at once.\nList format is [ rule1, data1, rule2, data2 . . . rulen, datan ]")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llClearCameraParams", NULL, NULL, "llClearCameraParams()\nResets all camera parameters to default values and turns off scripted camera control.")); - addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListStatistics", "f", "il", "integer llListStatistics(integer operation, list l)\nPerform statistical aggregate functions on list l using LIST_STAT_* operations.")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListStatistics", "f", "il", "float llListStatistics(integer operation, list l)\nPerform statistical aggregate functions on list l using LIST_STAT_* operations.")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetUnixTime", "i", NULL, "integer llGetUnixTime()\nGet the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock.")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetParcelFlags", "i", "v", "integer llGetParcelFlags(vector pos)\nGet the parcel flags (PARCEL_FLAG_*) for the parcel including the point pos.")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionFlags", "i", NULL, "integer llGetRegionFlags()\nGet the region flags (REGION_FLAG_*) for the region the object is in.")); @@ -548,12 +548,7 @@ void LLScriptLibData::print_separator(std::ostream& ostr, BOOL b_prepend_sep, ch } //print(ostr, FALSE); { - BOOL b_prepend_comma = FALSE; char tmp[1024]; /* Flawfinder: ignore */ - if (b_prepend_comma) - { - ostr << ", "; - } switch (mType) { case LST_INTEGER: diff --git a/linden/indra/newview/English.lproj/InfoPlist.strings b/linden/indra/newview/English.lproj/InfoPlist.strings index 54687b1..e9cd858 100644 --- a/linden/indra/newview/English.lproj/InfoPlist.strings +++ b/linden/indra/newview/English.lproj/InfoPlist.strings @@ -1,5 +1,5 @@ /* Localized versions of Info.plist keys */ CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 1.15.0.2"; -CFBundleGetInfoString = "Second Life version 1.15.0.2, Copyright 2004-2007 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 1.15.1.3"; +CFBundleGetInfoString = "Second Life version 1.15.1.3, Copyright 2004-2007 Linden Research, Inc."; diff --git a/linden/indra/newview/Info-SecondLife.plist b/linden/indra/newview/Info-SecondLife.plist index 0908e18..108f716 100644 --- a/linden/indra/newview/Info-SecondLife.plist +++ b/linden/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@ CFBundleVersion - 1.15.0.2 + 1.15.1.3 CSResourcesFileMapped diff --git a/linden/indra/newview/app_settings/keys.ini b/linden/indra/newview/app_settings/keys.ini index b7fc6f9..3a1e9ea 100644 --- a/linden/indra/newview/app_settings/keys.ini +++ b/linden/indra/newview/app_settings/keys.ini @@ -235,6 +235,13 @@ EDIT PAD_PGUP ALT jump EDIT PAD_PGDN ALT push_down EDIT PAD_ENTER ALT start_chat +SITTING A ALT spin_around_cw +SITTING D ALT spin_around_ccw +SITTING W ALT move_forward +SITTING S ALT move_backward +SITTING E ALT spin_over_sitting +SITTING C ALT spin_under_sitting + SITTING LEFT ALT spin_around_cw SITTING RIGHT ALT spin_around_ccw SITTING UP ALT move_forward @@ -242,6 +249,21 @@ SITTING DOWN ALT move_backward SITTING PGUP ALT spin_over SITTING PGDN ALT spin_under +SITTING A CTL_ALT spin_around_cw +SITTING D CTL_ALT spin_around_ccw +SITTING W CTL_ALT spin_over +SITTING S CTL_ALT spin_under +SITTING E CTL_ALT spin_over +SITTING C CTL_ALT spin_under + +SITTING LEFT CTL_ALT spin_around_cw +SITTING RIGHT CTL_ALT spin_around_ccw +SITTING UP CTL_ALT spin_over +SITTING DOWN CTL_ALT spin_under +SITTING PGUP CTL_ALT spin_over +SITTING PGDN CTL_ALT spin_under + + SITTING A NONE spin_around_cw_sitting SITTING D NONE spin_around_ccw_sitting SITTING W NONE move_forward_sitting diff --git a/linden/indra/newview/featuretable_linux.txt b/linden/indra/newview/featuretable_linux.txt new file mode 100644 index 0000000..6c7acfa --- /dev/null +++ b/linden/indra/newview/featuretable_linux.txt @@ -0,0 +1,173 @@ +version 10 + +// NOTE: This is mostly identical to featuretable.txt with a few differences +// Should be combined into one table + +// +// Generates lists of feature mask that can be applied on top of each other. +// +// // Begin comments +// list +// Starts a feature list named +// +// is the name of a feature +// is 0 or 1, whether the feature is available +// is an S32 which is the recommended value +// +// For now, the first list read sets up all of the default values +// + + +// +// All contains everything at their default settings for high end machines +// NOTE: All settings are set to the MIN of applied values, including 'all'! +// +list all +RenderVBO 1 1 +RenderAniso 1 0 +RenderAvatarMode 1 2 +RenderAvatarVP 1 1 +RenderDistance 1 128 +RenderLighting 1 1 +RenderObjectBump 1 1 +RenderParticleCount 1 4096 +RenderRippleWater 1 1 +RenderTerrainDetail 1 2 +VertexShaderEnable 1 1 + +// +// Class 0 Hardware (Unknown or just old) +// +list Class0 +VertexShaderEnable 1 0 +RenderVBO 1 0 +RenderDistance 1 64 +RenderAvatarVP 1 0 +RenderAvatarMode 1 0 +RenderLighting 1 0 +RenderObjectBump 1 0 +RenderRippleWater 1 0 + +// +// Class 1 Hardware +// +list Class1 +VertexShaderEnable 1 0 +RenderVBO 1 1 +RenderDistance 1 96 +RenderAvatarVP 1 1 +RenderAvatarMode 1 0 +RenderLighting 1 0 +RenderObjectBump 1 0 +RenderRippleWater 1 0 + +// +// Class 2 Hardware (make it purty) +// +list Class2 +VertexShaderEnable 1 1 +RenderAvatarVP 1 1 +RenderAvatarMode 1 1 +RenderLighting 1 1 +RenderObjectBump 1 1 +RenderRippleWater 1 1 + +// +// Class 3 Hardware (make it purty) +// +list Class3 +VertexShaderEnable 1 1 +RenderAvatarVP 1 1 +RenderAvatarMode 1 1 +RenderLighting 1 1 +RenderObjectBump 1 1 +RenderRippleWater 1 1 + +// +// No Pixel Shaders available +// +list NoPixelShaders +VertexShaderEnable 0 0 +RenderAvatarVP 0 0 + +// +// No Vertex Shaders available +// +list NoVertexShaders +VertexShaderEnable 0 0 +RenderAvatarVP 0 0 + +// +// "Default" setups for safe, low, medium, high +// +list safe +RenderVBO 1 0 +RenderAniso 1 0 +RenderAvatarVP 0 0 +RenderLighting 1 0 +RenderParticleCount 1 1024 +RenderTerrainDetail 1 0 + + +list low +RenderVBO 1 0 +RenderAniso 1 0 +RenderLighting 1 0 + +list medium +RenderLighting 1 0 + + +// +// CPU based feature masks +// + +// 1Ghz or less (equiv) +list CPUSlow +RenderParticleCount 1 1024 + + +// +// RAM based feature masks +// +list RAM256MB +RenderObjectBump 0 0 + + +// +// Graphics card based feature masks +// +list OpenGLPre15 +RenderVBO 1 0 + +list Intel +RenderVBO 1 0 +RenderAniso 1 0 +RenderLighting 1 0 +RenderTerrainDetail 1 0 + +list GeForce2 +RenderVBO 1 1 +RenderAniso 1 0 +RenderLighting 1 0 +RenderParticleCount 1 2048 +RenderTerrainDetail 1 0 + +list GeForce3 + +list ATI + +list Radeon8500 +RenderLighting 1 0 +RenderParticleCount 1 4096 + +// Hacked to be paranoid "safe" +list Radeon9700 +RenderParticleCount 1 4096 + +// Hacked to be paranoid "safe" +list MobilityRadeon9000 +RenderLighting 1 0 +RenderParticleCount 1 4096 + +list GeForceFX diff --git a/linden/indra/newview/files.lst b/linden/indra/newview/files.lst index 8fdd239..2967bed 100644 --- a/linden/indra/newview/files.lst +++ b/linden/indra/newview/files.lst @@ -282,6 +282,7 @@ newview/llviewerjoystick.cpp newview/llviewerkeyboard.cpp newview/llviewerlayer.cpp newview/llviewermenu.cpp +newview/llviewermenufile.cpp newview/llviewermessage.cpp newview/llviewernetwork.cpp newview/llviewerobject.cpp diff --git a/linden/indra/newview/gpu_table.txt b/linden/indra/newview/gpu_table.txt index 4e6373d..a6d1dee 100644 --- a/linden/indra/newview/gpu_table.txt +++ b/linden/indra/newview/gpu_table.txt @@ -22,11 +22,9 @@ ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 ATI ASUS X1xxx .*ASUS X1.* 3 ATI Mobility Radeon X1xxx .*ATI.*Mobility.*X1.* 2 -// HACK: We crash on startup on some Mobility Radeon chips, with 1.15.0 -// in FMOD (!). Try defaulting them to class 0. JC -ATI Mobility Radeon X3xx .*ATI.*Mobility.*X3.* 0 -ATI Mobility Radeon X6xx .*ATI.*Mobility.*X6.* 0 -ATI Mobility Radeon X7xx .*ATI.*Mobility.*X7.* 0 +ATI Mobility Radeon X3xx .*ATI.*Mobility.*X3.* 1 +ATI Mobility Radeon X6xx .*ATI.*Mobility.*X6.* 1 +ATI Mobility Radeon X7xx .*ATI.*Mobility.*X7.* 1 ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 3 ATI Diamond X1xxx .*ATI.*Diamond.*X1.* 3 ATI FireGL 5xxx .*ATI.*FireGL V5.* 3 diff --git a/linden/indra/newview/linux_tools/client-readme.txt b/linden/indra/newview/linux_tools/client-readme.txt index cabb034..63086c8 100644 --- a/linden/indra/newview/linux_tools/client-readme.txt +++ b/linden/indra/newview/linux_tools/client-readme.txt @@ -97,7 +97,6 @@ the Alpha release of the Linux client. implemented on the Linux client and are therefore known not to work properly at this time: * QuickTime movie playback and movie recording - * Video memory detection * Full Unicode font rendering * Auto-updater diff --git a/linden/indra/newview/linux_tools/launch_url.sh b/linden/indra/newview/linux_tools/launch_url.sh index 564e834..a1c6f5d 100755 --- a/linden/indra/newview/linux_tools/launch_url.sh +++ b/linden/indra/newview/linux_tools/launch_url.sh @@ -1,5 +1,5 @@ #!/bin/sh -# bash v1.14+ expected +# Script tested with: bash 1.14, bash 3.1.17, zsh 4.2.5, ksh 1993-12-28 # This script loads a web page in the 'default' graphical web browser. # It MUST return immediately (or soon), so the browser should be diff --git a/linden/indra/newview/linux_tools/wrapper.sh b/linden/indra/newview/linux_tools/wrapper.sh index cdc36a8..5f128e8 100755 --- a/linden/indra/newview/linux_tools/wrapper.sh +++ b/linden/indra/newview/linux_tools/wrapper.sh @@ -1,4 +1,6 @@ #!/bin/sh +# Script tested with: bash 1.14, bash 3.1.17, zsh 4.2.5, ksh 1993-12-28 + ## Here are some configuration options for Linux Client Alpha Testers. ## These options are for self-assisted troubleshooting during this alpha ## testing phase; you should not usually need to touch them. diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index ff16682..85c268b 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -7081,7 +7081,7 @@ void LLAgent::queryWearableCache() // Look up affected baked textures. // If they exist: // disallow updates for affected layersets (until dataserver responds with cache request.) - // If cache miss…turn updates back on and invalidate composite. + // If cache miss, turn updates back on and invalidate composite. // If cache hit, modify baked texture entries. // // Cache requests contain list of hashes for each baked texture entry. diff --git a/linden/indra/newview/llassetuploadresponders.cpp b/linden/indra/newview/llassetuploadresponders.cpp index 821bb2a..26c606f 100644 --- a/linden/indra/newview/llassetuploadresponders.cpp +++ b/linden/indra/newview/llassetuploadresponders.cpp @@ -21,7 +21,7 @@ #include "lluploaddialog.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" -#include "llviewermenu.h" +#include "llviewermenufile.h" #include "llviewerwindow.h" #include "viewer.h" diff --git a/linden/indra/newview/llcallingcard.cpp b/linden/indra/newview/llcallingcard.cpp index 22e7f23..3e00f40 100644 --- a/linden/indra/newview/llcallingcard.cpp +++ b/linden/indra/newview/llcallingcard.cpp @@ -269,12 +269,28 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds) for(buddy_map_t::const_iterator itr = buds.begin(); itr != buds.end(); ++itr) { agent_id = (*itr).first; - if(mBuddyInfo.find(agent_id) == mBuddyInfo.end()) + buddy_map_t::const_iterator existing_buddy = mBuddyInfo.find(agent_id); + if(existing_buddy == mBuddyInfo.end()) { ++new_buddy_count; mBuddyInfo[agent_id] = (*itr).second; gCacheName->getName(agent_id, first, last); mModifyMask |= LLFriendObserver::ADD; + lldebugs << "Added buddy " << agent_id + << ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline") + << ", TO: " << mBuddyInfo[agent_id]->getRightsGrantedTo() + << ", FROM: " << mBuddyInfo[agent_id]->getRightsGrantedFrom() + << llendl; + } + else + { + LLRelationship* e_r = (*existing_buddy).second; + LLRelationship* n_r = (*itr).second; + llwarns << "!! Add buddy for existing buddy: " << agent_id + << " [" << (e_r->isOnline() ? "Online" : "Offline") << "->" << (n_r->isOnline() ? "Online" : "Offline") + << ", " << e_r->getRightsGrantedTo() << "->" << n_r->getRightsGrantedTo() + << ", " << e_r->getRightsGrantedTo() << "->" << n_r->getRightsGrantedTo() + << "]" << llendl; } } @@ -325,6 +341,12 @@ void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online) { info->online(is_online); mModifyMask |= LLFriendObserver::ONLINE; + lldebugs << "Set buddy " << id << (is_online ? " Online" : " Offline") << llendl; + } + else + { + llwarns << "!! No buddy info found for " << id + << ", setting to " << (is_online ? "Online" : "Offline") << llendl; } } @@ -598,6 +620,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) S32 count = msg->getNumberOfBlocksFast(_PREHASH_AgentBlock); BOOL chat_notify = gSavedSettings.getBOOL("ChatOnlineNotification"); + lldebugs << "Received " << count << " online notifications **** " << llendl; if(count > 0) { LLUUID agent_id; @@ -628,6 +651,12 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) } } } + else + { + llwarns << "Received online notification for unknown buddy: " + << agent_id << " is " << (online ? "ONLINE" : "OFFLINE") << llendl; + } + if(tracking_id == agent_id) { // we were tracking someone who went offline diff --git a/linden/indra/newview/llchatbar.cpp b/linden/indra/newview/llchatbar.cpp index 02bed33..a6feac7 100644 --- a/linden/indra/newview/llchatbar.cpp +++ b/linden/indra/newview/llchatbar.cpp @@ -118,9 +118,10 @@ LLChatBar::LLChatBar(const std::string& name, const LLRect& rect) mInputEditor->setRevertOnEsc( FALSE ); mInputEditor->setIgnoreTab(TRUE); mInputEditor->setPassDelete(TRUE); + + mInputEditor->setMaxTextLength(1023); } - mInputEditor->setMaxTextLength(1023); // Build the list of gestures refreshGestures(); diff --git a/linden/indra/newview/llcontroldef.cpp b/linden/indra/newview/llcontroldef.cpp index 7989791..11b97b4 100644 --- a/linden/indra/newview/llcontroldef.cpp +++ b/linden/indra/newview/llcontroldef.cpp @@ -573,7 +573,7 @@ void declare_settings() gSavedSettings.declareBOOL("ShowAxes", FALSE, "Render coordinate frame at your position"); - gSavedSettings.declareBOOL("ShowMiniMap", FALSE, "Display mini map on login"); + gSavedSettings.declareBOOL("ShowMiniMap", TRUE, "Display mini map on login"); gSavedSettings.declareBOOL("ShowWorldMap", FALSE, "Display world map on login"); gSavedSettings.declareBOOL("ShowToolBar", TRUE, "Show toolbar at bottom of screen"); gSavedSettings.declareBOOL("ShowCameraControls", FALSE, "Display camera controls on login"); @@ -833,7 +833,7 @@ void declare_settings() // Previews - only width and height are used gSavedSettings.declareRect("PreviewTextureRect", LLRect(0, 400, 400, 0), "Rectangle for texture preview window" ); // Only width and height are used gSavedSettings.declareRect("PreviewScriptRect", LLRect(0, 550, 500, 0), "Rectangle for script preview window" ); // Only width and height are used - gSavedSettings.declareRect("LSLHelpRect", LLRect(0, 500, 600, 0), "Rectangle for LSL help window" ); // Only width and height are used + gSavedSettings.declareRect("LSLHelpRect", LLRect(0, 400, 400, 0), "Rectangle for LSL help window" ); // Only width and height are used gSavedSettings.declareRect("PreviewLandmarkRect", LLRect(0, 90, 300, 0), "Rectangle for landmark preview window" ); // Only width and height are used gSavedSettings.declareRect("PreviewSoundRect", LLRect(0, 85, 300, 0), "Rectangle for sound preview window" ); // Only width and height are used gSavedSettings.declareRect("PreviewObjectRect", LLRect(0, 85, 300, 0), "Rectangle for object preview window" ); // Only width and height are used @@ -1145,15 +1145,18 @@ void declare_settings() gSavedSettings.declareBOOL("NotifyMoneyChange", TRUE, "Pop up notifications for all financial transactions"); + gSavedSettings.declareBOOL("ShowNewInventory", TRUE, + "Automatic Previews of new notecards/textures/landmarks"); // Bitfield // 1 = by date // 2 = folders always by name + // 4 = system folders to top // This where the default first time user gets his settings. - gSavedSettings.declareU32("InventorySortOrder", 1 | 2, "Specifies sort key for inventory items (+0 = name, +1 = date, +2 = folders always by name)"); - gSavedSettings.declareU32("RecentItemsSortOrder", 1, "Specifies sort key for recent inventory items (+0 = name, +1 = date, +2 = folders always by name)"); - gSavedSettings.declareU32("TexturePickerSortOrder", 2, "Specifies sort key for textures in texture picker (+0 = name, +1 = date, +2 = folders always by name)"); - gSavedSettings.declareU32("AvatarPickerSortOrder", 2, "Specifies sort key for textures in avatar picker (+0 = name, +1 = date, +2 = folders always by name)"); + gSavedSettings.declareU32("InventorySortOrder", 1 | 2 | 4, "Specifies sort key for inventory items (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)"); + gSavedSettings.declareU32("RecentItemsSortOrder", 1, "Specifies sort key for recent inventory items (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)"); + gSavedSettings.declareU32("TexturePickerSortOrder", 2, "Specifies sort key for textures in texture picker (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)"); + gSavedSettings.declareU32("AvatarPickerSortOrder", 2, "Specifies sort key for textures in avatar picker (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)"); // Pixels away from edge that windows snap. gSavedSettings.declareS32("SnapMargin", 10, "Controls maximum distance between windows before they auto-snap together (pixels)"); diff --git a/linden/indra/newview/lldebugmessagebox.cpp b/linden/indra/newview/lldebugmessagebox.cpp index af500da..e238800 100644 --- a/linden/indra/newview/lldebugmessagebox.cpp +++ b/linden/indra/newview/lldebugmessagebox.cpp @@ -225,21 +225,21 @@ void LLDebugVarMessageBox::draw() if(mAnimate) { - F32 animated_val = clamp_rescale(fmodf((F32)LLFrameTimer::getElapsedSeconds() / 5.f, 1.f), 0.f, 1.f, 0.f, mSlider1->getMaxValue()); if (mSlider1) { + F32 animated_val = clamp_rescale(fmodf((F32)LLFrameTimer::getElapsedSeconds() / 5.f, 1.f), 0.f, 1.f, 0.f, mSlider1->getMaxValue()); mSlider1->setValue(animated_val); slider_changed(mSlider1, this); - } - if (mSlider2) - { - mSlider2->setValue(animated_val); - slider_changed(mSlider2, this); - } - if (mSlider3) - { - mSlider3->setValue(animated_val); - slider_changed(mSlider3, this); + if (mSlider2) + { + mSlider2->setValue(animated_val); + slider_changed(mSlider2, this); + } + if (mSlider3) + { + mSlider3->setValue(animated_val); + slider_changed(mSlider3, this); + } } } LLFloater::draw(); diff --git a/linden/indra/newview/lldrawpoolavatar.cpp b/linden/indra/newview/lldrawpoolavatar.cpp index debcfe2..b864449 100644 --- a/linden/indra/newview/lldrawpoolavatar.cpp +++ b/linden/indra/newview/lldrawpoolavatar.cpp @@ -102,7 +102,8 @@ BOOL gRenderAvatar = TRUE; S32 LLDrawPoolAvatar::getVertexShaderLevel() const { - return (S32) LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR); + return sShaderLevel; + //return (S32) LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR); } void LLDrawPoolAvatar::prerender() @@ -197,20 +198,22 @@ void LLDrawPoolAvatar::endFootShadow() void LLDrawPoolAvatar::beginRigid() { - sVertexProgram = &gAvatarEyeballProgram; + sVertexProgram = NULL; + sShaderLevel = 0; glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - if (sShaderLevel > 0) + /*if (sShaderLevel > 0) { //eyeballs render with the specular shader gAvatarEyeballProgram.bind(); gMaterialIndex = gAvatarEyeballProgram.mAttribute[LLShaderMgr::MATERIAL_COLOR]; gSpecularIndex = gAvatarEyeballProgram.mAttribute[LLShaderMgr::SPECULAR_COLOR]; - } + }*/ } void LLDrawPoolAvatar::endRigid() { + sShaderLevel = mVertexShaderLevel; glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } diff --git a/linden/indra/newview/lldriverparam.cpp b/linden/indra/newview/lldriverparam.cpp index ce42ad5..463888c 100644 --- a/linden/indra/newview/lldriverparam.cpp +++ b/linden/indra/newview/lldriverparam.cpp @@ -346,7 +346,7 @@ const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_ // We're already in the middle of a param's distortions, so get the next one. const LLVector3* v = driven->mParam->getNextDistortion( index, poly_mesh ); - if( !v ) + if( (!v) && (iter != mDriven.end()) ) { // This param is finished, so start the next param. It might not have any // distortions, though, so we have to loop to find the next param that does. diff --git a/linden/indra/newview/lleventpoll.cpp b/linden/indra/newview/lleventpoll.cpp index 9c5a19d..7430fc3 100644 --- a/linden/indra/newview/lleventpoll.cpp +++ b/linden/indra/newview/lleventpoll.cpp @@ -79,7 +79,7 @@ LLEventPoll::Impl& LLEventPoll::Impl::start( void LLEventPoll::Impl::stop() { - llinfos << "LLEventPoll::Impl::stop <" << mCount << "> " + lldebugs << "LLEventPoll::Impl::stop <" << mCount << "> " << mPollURL << llendl; // there should be a way to stop a LLHTTPClient request in progress mDone = true; diff --git a/linden/indra/newview/llfasttimerview.cpp b/linden/indra/newview/llfasttimerview.cpp index c469d8c..c7be3aa 100644 --- a/linden/indra/newview/llfasttimerview.cpp +++ b/linden/indra/newview/llfasttimerview.cpp @@ -1108,6 +1108,15 @@ F64 LLFastTimerView::getTime(LLFastTimer::EFastTimerType tidx) break; } } + + if (i == FTV_DISPLAY_NUM) + { + // walked off the end of ft_display_table without finding + // the desired timer type + llwarns << "Timer type " << tidx << " not known." << llendl; + return F64(0.0); + } + S32 table_idx = i; // Add child ticks to parent diff --git a/linden/indra/newview/llfeaturemanager.cpp b/linden/indra/newview/llfeaturemanager.cpp index 57fbc64..2a30680 100644 --- a/linden/indra/newview/llfeaturemanager.cpp +++ b/linden/indra/newview/llfeaturemanager.cpp @@ -60,6 +60,8 @@ extern void write_debug(const std::string& str); #if LL_DARWIN const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt"; +#elif LL_LINUX +const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt"; #else const char FEATURE_TABLE_FILENAME[] = "featuretable.txt"; #endif diff --git a/linden/indra/newview/llfilepicker.cpp b/linden/indra/newview/llfilepicker.cpp index 971743b..24d3932 100644 --- a/linden/indra/newview/llfilepicker.cpp +++ b/linden/indra/newview/llfilepicker.cpp @@ -451,8 +451,9 @@ void LLFilePicker::reset() void LLFilePicker::buildFilename( void ) { - strncpy( mFilename, mFiles, LL_MAX_PATH ); /*Flawfinder: ignore*/ - S32 len = strlen( mFilename ); /*Flawfinder: ignore*/ + strncpy( mFilename, mFiles, LL_MAX_PATH ); + mFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy + S32 len = strlen( mFilename ); strncat(mFilename,gDirUtilp->getDirDelimiter().c_str(), sizeof(mFilename)-len+1); /*Flawfinder: ignore*/ len += strlen(gDirUtilp->getDirDelimiter().c_str()); /*Flawfinder: ignore*/ @@ -858,7 +859,10 @@ void LLFilePicker::getFilePath(SInt32 index) { mFiles[0] = 0; if (mFileVector.size()) - strncpy(mFiles, mFileVector[index].c_str(), sizeof(mFiles)); /*Flawfinder: ignore*/ + { + strncpy(mFiles, mFileVector[index].c_str(), sizeof(mFiles)); + mFiles[sizeof(mFiles)-1] = '\0'; // stupid strncpy + } } void LLFilePicker::getFileName(SInt32 index) @@ -868,7 +872,10 @@ void LLFilePicker::getFileName(SInt32 index) { char *start = strrchr(mFileVector[index].c_str(), '/'); if (start && ((start + 1 - mFileVector[index].c_str()) < (mFileVector[index].size()))) - strncpy(mFilename, start + 1, sizeof(mFilename)); /*Flawfinder: ignore*/ + { + strncpy(mFilename, start + 1, sizeof(mFilename)); + mFilename[sizeof(mFilename)-1] = '\0';// stupid strncpy + } } } diff --git a/linden/indra/newview/llfloateranimpreview.cpp b/linden/indra/newview/llfloateranimpreview.cpp index 6802fb2..b1f8a53 100644 --- a/linden/indra/newview/llfloateranimpreview.cpp +++ b/linden/indra/newview/llfloateranimpreview.cpp @@ -54,7 +54,7 @@ #include "llviewercamera.h" #include "llviewerobjectlist.h" #include "llviewerwindow.h" -#include "llviewermenu.h" +#include "llviewermenufile.h" // upload_new_resource() #include "llvoavatar.h" #include "pipeline.h" #include "viewer.h" @@ -221,7 +221,7 @@ BOOL LLFloaterAnimPreview::postBuild() } apr_file_close(fp); - delete file_buffer; + delete[] file_buffer; } } @@ -247,11 +247,11 @@ BOOL LLFloaterAnimPreview::postBuild() // pass animation data through memory buffer loaderp->serialize(dp); dp.reset(); - BOOL success = motionp->deserialize(dp); + BOOL success = motionp && motionp->deserialize(dp); delete []buffer; - if (motionp && success) + if (success) { const LLBBoxLocal &pelvis_bbox = motionp->getPelvisBBox(); diff --git a/linden/indra/newview/llfloateravatarinfo.cpp b/linden/indra/newview/llfloateravatarinfo.cpp index c0351ee..2245d31 100644 --- a/linden/indra/newview/llfloateravatarinfo.cpp +++ b/linden/indra/newview/llfloateravatarinfo.cpp @@ -195,7 +195,6 @@ void LLFloaterAvatarInfo::showFromDirectory(const LLUUID &avatar_id) { // ...bring that window to front floater = gAvatarInfoInstances.getData(avatar_id); - floater->open(); /*Flawfinder: ignore*/ } else { @@ -203,7 +202,10 @@ void LLFloaterAvatarInfo::showFromDirectory(const LLUUID &avatar_id) avatar_id); floater->center(); floater->mPanelAvatarp->setAvatarID(avatar_id, "", ONLINE_STATUS_NO); - floater->open(); /*Flawfinder: ignore*/ + } + if(floater) + { + floater->open(); } } diff --git a/linden/indra/newview/llfloaterfriends.cpp b/linden/indra/newview/llfloaterfriends.cpp index 8d39890..d01a24b 100644 --- a/linden/indra/newview/llfloaterfriends.cpp +++ b/linden/indra/newview/llfloaterfriends.cpp @@ -287,6 +287,7 @@ void LLFloaterFriends::refreshRightsChangeList(U8 state) bool can_change_online_multiple = true; bool can_change_map_multiple = true; LLTextBox* processing_label = LLUICtrlFactory::getTextBoxByName(this, "process_rights_label"); + if(!mAllowRightsChange) { if(processing_label) @@ -302,9 +303,10 @@ void LLFloaterFriends::refreshRightsChangeList(U8 state) processing_label->setVisible(false); } } + if(state == 1) { - if(!friend_status->isOnline()) + if(friend_status && !friend_status->isOnline()) { childSetEnabled("offer_teleport_btn", false); } diff --git a/linden/indra/newview/llfloatergroupinfo.cpp b/linden/indra/newview/llfloatergroupinfo.cpp index 348f31f..3e8eae5 100644 --- a/linden/indra/newview/llfloatergroupinfo.cpp +++ b/linden/indra/newview/llfloatergroupinfo.cpp @@ -191,7 +191,7 @@ void LLFloaterGroupInfo::showNotice(const char* subject, // We need to clean up that inventory offer. if (inventory_offer) { - inventory_offer_callback( 1 , inventory_offer); + inventory_offer_callback( IOR_DECLINE , inventory_offer); } return; } @@ -203,7 +203,7 @@ void LLFloaterGroupInfo::showNotice(const char* subject, // We need to clean up that inventory offer. if (inventory_offer) { - inventory_offer_callback( 1 , inventory_offer); + inventory_offer_callback( IOR_DECLINE , inventory_offer); } return; } diff --git a/linden/indra/newview/llfloaterhtml.cpp b/linden/indra/newview/llfloaterhtml.cpp index 519a031..0c5bdcd 100644 --- a/linden/indra/newview/llfloaterhtml.cpp +++ b/linden/indra/newview/llfloaterhtml.cpp @@ -49,8 +49,12 @@ LLFloaterHtml* LLFloaterHtml::getInstance() //////////////////////////////////////////////////////////////////////////////// // LLFloaterHtml::LLFloaterHtml() -: LLFloater( "HTML Floater" ), +: LLFloater( "HTML Floater" ) + +#if LL_LIBXUL_ENABLED + , mWebBrowser( 0 ) +#endif // LL_LIBXUL_ENABLED { // create floater from its XML definition gUICtrlFactory->buildFloater( this, "floater_html.xml" ); @@ -60,6 +64,7 @@ LLFloaterHtml::LLFloaterHtml() reshape( rect.getWidth(), rect.getHeight(), FALSE ); setRect( rect ); +#if LL_LIBXUL_ENABLED mWebBrowser = LLViewerUICtrlFactory::getWebBrowserByName(this, "html_floater_browser" ); if ( mWebBrowser ) { @@ -72,7 +77,8 @@ LLFloaterHtml::LLFloaterHtml() // don't automatically open secondlife links since we want to catch // special ones that do other stuff (like open F1 Help) mWebBrowser->setOpenSecondLifeLinksInMap( false ); - }; + } +#endif // LL_LIBXUL_ENABLED childSetAction("close_btn", onClickClose, this); setDefaultBtn("close_btn"); @@ -82,9 +88,11 @@ LLFloaterHtml::LLFloaterHtml() // LLFloaterHtml::~LLFloaterHtml() { +#if LL_LIBXUL_ENABLED // stop observing browser events if ( mWebBrowser ) mWebBrowser->remObserver( this ); +#endif // LL_LIBXUL_ENABLED // save position of floater gSavedSettings.setRect( "HtmlFloaterRect", mRect ); @@ -103,9 +111,11 @@ void LLFloaterHtml::show( LLString content_id ) // set the title setTitle( childGetValue( title_str ).asString() ); +#if LL_LIBXUL_ENABLED // navigate to the URL if ( mWebBrowser ) mWebBrowser->navigateTo( childGetValue( url_str ).asString() ); +#endif // LL_LIBXUL_ENABLED // make floater appear setVisibleAndFrontmost(); @@ -131,6 +141,7 @@ void LLFloaterHtml::onClickClose( void* data ) // void LLFloaterHtml::onClickLinkSecondLife( const EventType& eventIn ) { +#if LL_LIBXUL_ENABLED const std::string protocol( "secondlife://app." ); // special 'app' secondlife link (using a different protocol - one that isn't registered in the browser) causes bad @@ -144,11 +155,12 @@ void LLFloaterHtml::onClickLinkSecondLife( const EventType& eventIn ) if ( LLString::compareInsensitive( cmd.c_str() , "floater.html.help" ) == 0 ) { gViewerHtmlHelp.show(); - }; + } } else // regular secondlife link - just open the map as normal { mWebBrowser->openMapAtlocation( eventIn.getStringValue() ); - }; -}; \ No newline at end of file + } +#endif // LL_LIBXUL_ENABLED +}; diff --git a/linden/indra/newview/llfloaterhtml.h b/linden/indra/newview/llfloaterhtml.h index 9a09baf..fef57d0 100644 --- a/linden/indra/newview/llfloaterhtml.h +++ b/linden/indra/newview/llfloaterhtml.h @@ -51,9 +51,11 @@ class LLFloaterHtml : private: LLFloaterHtml(); +#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* mWebBrowser; +#endif // LL_LIBXUL_ENABLED static LLFloaterHtml* sInstance; LLButton* mCloseButton; }; -#endif \ No newline at end of file +#endif diff --git a/linden/indra/newview/llfloaterimport.cpp b/linden/indra/newview/llfloaterimport.cpp index 72cf2e0..ed71c1b 100644 --- a/linden/indra/newview/llfloaterimport.cpp +++ b/linden/indra/newview/llfloaterimport.cpp @@ -44,12 +44,13 @@ #include "llface.h" #include "llinventorymodel.h" #include "lllineeditor.h" +#include "llresourcedata.h" #include "lltextbox.h" #include "lltoolmgr.h" #include "llui.h" #include "lluploaddialog.h" #include "llviewercamera.h" -#include "llviewermenu.h" +#include "llviewermenufile.h" // upload_new_resource() #include "llviewerwindow.h" #include "llvoavatar.h" #include "pipeline.h" @@ -264,9 +265,8 @@ BOOL LLFloaterImport::postBuild() FILE* fCheck = LLFile::fopen(image_path.c_str(), "rb"); /*Flawfinder: ignore*/ if (fCheck) { - LLMD5 my_md5_hash(fCheck); + LLMD5 my_md5_hash(fCheck); // this fclose()s fCheck too my_md5_hash.hex_digest(md5_hash_string); - fclose(fCheck); llinfos << "hash: " << md5_hash_string << llendl; } @@ -474,7 +474,7 @@ void LLFloaterImport::finishImport(ImportAssetInfo *info) char *buffer = new char[length]; ll_apr_file_read(fIn, buffer, length); ll_apr_file_write(fOut, buffer, length); - delete buffer; + delete[] buffer; generated_file = true; apr_file_close(fOut); } diff --git a/linden/indra/newview/llfloaterinspect.cpp b/linden/indra/newview/llfloaterinspect.cpp index 1548c0e..80da7b6 100644 --- a/linden/indra/newview/llfloaterinspect.cpp +++ b/linden/indra/newview/llfloaterinspect.cpp @@ -64,42 +64,54 @@ void LLFloaterInspect::show(void* ignored) void LLFloaterInspect::onClickCreatorProfile(void* ctrl) { if(sInstance->mObjectList->getAllSelected().size() == 0) return; - LLSelectNode* obj = sInstance->mObjectSelection->getFirstNode(); - LLUUID obj_id, creator_id; - obj_id = sInstance->mObjectList->getFirstSelected()->getUUID(); - while(obj) + LLScrollListItem* first_selected = + sInstance->mObjectList->getFirstSelected(); + + if (first_selected) { - if(obj_id == obj->getObject()->getID()) + LLSelectNode* obj= sInstance->mObjectSelection->getFirstNode(); + LLUUID obj_id, creator_id; + obj_id = first_selected->getUUID(); + while(obj) { - creator_id = obj->mPermissions->getCreator(); - break; + if(obj_id == obj->getObject()->getID()) + { + creator_id = obj->mPermissions->getCreator(); + break; + } + obj = sInstance->mObjectSelection->getNextNode(); + } + if(obj) + { + LLFloaterAvatarInfo::showFromDirectory(creator_id); } - obj = sInstance->mObjectSelection->getNextNode(); - } - if(obj) - { - LLFloaterAvatarInfo::showFromDirectory(creator_id); } } void LLFloaterInspect::onClickOwnerProfile(void* ctrl) { if(sInstance->mObjectList->getAllSelected().size() == 0) return; - LLSelectNode* obj = sInstance->mObjectSelection->getFirstNode(); - LLUUID obj_id, owner_id; - obj_id = sInstance->mObjectList->getFirstSelected()->getUUID(); - while(obj) + LLScrollListItem* first_selected = + sInstance->mObjectList->getFirstSelected(); + + if (first_selected) { - if(obj_id == obj->getObject()->getID()) + LLSelectNode* obj= sInstance->mObjectSelection->getFirstNode(); + LLUUID obj_id, owner_id; + obj_id = first_selected->getUUID(); + while(obj) { - owner_id = obj->mPermissions->getOwner(); - break; + if(obj_id == obj->getObject()->getID()) + { + owner_id = obj->mPermissions->getOwner(); + break; + } + obj = sInstance->mObjectSelection->getNextNode(); + } + if(obj) + { + LLFloaterAvatarInfo::showFromDirectory(owner_id); } - obj = sInstance->mObjectSelection->getNextNode(); - } - if(obj) - { - LLFloaterAvatarInfo::showFromDirectory(owner_id); } } @@ -125,7 +137,15 @@ LLUUID LLFloaterInspect::getSelectedUUID() { if(sInstance) { - if(sInstance->mObjectList->getAllSelected().size() > 0) return sInstance->mObjectList->getFirstSelected()->getUUID(); + if(sInstance->mObjectList->getAllSelected().size() > 0) + { + LLScrollListItem* first_selected = + sInstance->mObjectList->getFirstSelected(); + if (first_selected) + { + return first_selected->getUUID(); + } + } } return LLUUID::null; } @@ -139,7 +159,15 @@ void LLFloaterInspect::refresh() childSetEnabled("button creator", false); LLUUID selected_uuid; S32 selected_index = mObjectList->getFirstSelectedIndex(); - if(selected_index > -1) selected_uuid = mObjectList->getFirstSelected()->getUUID(); + if(selected_index > -1) + { + LLScrollListItem* first_selected = + mObjectList->getFirstSelected(); + if (first_selected) + { + selected_uuid = first_selected->getUUID(); + } + } mObjectList->operateOnAll(LLScrollListCtrl::OP_DELETE); //List all transient objects, then all linked objects LLSelectNode* obj = mObjectSelection->getFirstNode(); diff --git a/linden/indra/newview/llfloaterland.cpp b/linden/indra/newview/llfloaterland.cpp index 9ff44f4..82b50ec 100644 --- a/linden/indra/newview/llfloaterland.cpp +++ b/linden/indra/newview/llfloaterland.cpp @@ -1996,12 +1996,18 @@ BOOL LLPanelLandOptions::postBuild() mSnapshotCtrl = LLUICtrlFactory::getTexturePickerByName(this, "snapshot_ctrl"); - mSnapshotCtrl->setCommitCallback( onCommitAny ); - mSnapshotCtrl->setCallbackUserData( this ); - mSnapshotCtrl->setAllowNoTexture ( TRUE ); - mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - + if (mSnapshotCtrl) + { + mSnapshotCtrl->setCommitCallback( onCommitAny ); + mSnapshotCtrl->setCallbackUserData( this ); + mSnapshotCtrl->setAllowNoTexture ( TRUE ); + mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + else + { + llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'snapshot_ctrl'" << llendl; + } mLocationText = LLUICtrlFactory::getTextBoxByName(this, "Landing Point: (none)"); @@ -2333,12 +2339,19 @@ BOOL LLPanelLandMedia::postBuild() mMediaTextureCtrl = LLUICtrlFactory::getTexturePickerByName(this, "media texture"); - mMediaTextureCtrl->setCommitCallback( onCommitAny ); - mMediaTextureCtrl->setCallbackUserData( this ); - mMediaTextureCtrl->setAllowNoTexture ( TRUE ); - mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - + if (mMediaTextureCtrl) + { + mMediaTextureCtrl->setCommitCallback( onCommitAny ); + mMediaTextureCtrl->setCallbackUserData( this ); + mMediaTextureCtrl->setAllowNoTexture ( TRUE ); + mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + else + { + llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'media texure'" << llendl; + } + mMediaAutoScaleCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_auto_scale"); childSetCommitCallback("media_auto_scale", onCommitAny, this); diff --git a/linden/indra/newview/llfloaternamedesc.cpp b/linden/indra/newview/llfloaternamedesc.cpp index f5ef7dc..5f41b13 100644 --- a/linden/indra/newview/llfloaternamedesc.cpp +++ b/linden/indra/newview/llfloaternamedesc.cpp @@ -29,6 +29,8 @@ #include "llviewerprecompiledheaders.h" #include "llfloaternamedesc.h" + +// project includes #include "lllineeditor.h" #include "llresmgr.h" #include "lltextbox.h" @@ -36,13 +38,16 @@ #include "llviewerwindow.h" #include "llfocusmgr.h" #include "llradiogroup.h" -#include "llassetstorage.h" #include "lldbstrings.h" #include "lldir.h" #include "llviewercontrol.h" -#include "llviewermenu.h" +#include "llviewermenufile.h" // upload_new_resource() #include "llvieweruictrlfactory.h" +// linden includes +#include "llassetstorage.h" +#include "llinventorytype.h" + const S32 PREVIEW_LINE_HEIGHT = 19; const S32 PREVIEW_CLOSE_BOX_SIZE = 16; const S32 PREVIEW_BORDER_WIDTH = 2; diff --git a/linden/indra/newview/llfloaternewim.cpp b/linden/indra/newview/llfloaternewim.cpp index 2fa2b51..1adb37c 100644 --- a/linden/indra/newview/llfloaternewim.cpp +++ b/linden/indra/newview/llfloaternewim.cpp @@ -74,8 +74,15 @@ BOOL LLFloaterNewIM::postBuild() childSetAction("start_btn", &LLFloaterNewIM::onStart, this); childSetAction("close_btn", &LLFloaterNewIM::onClickClose, this); mSelectionList = LLViewerUICtrlFactory::getNameListByName(this, "user_list"); - mSelectionList->setDoubleClickCallback(&LLFloaterNewIM::onStart); - mSelectionList->setCallbackUserData(this); + if (mSelectionList) + { + mSelectionList->setDoubleClickCallback(&LLFloaterNewIM::onStart); + mSelectionList->setCallbackUserData(this); + } + else + { + llwarns << "LLViewerUICtrlFactory::getNameListByName() returned NULL for 'user_list'" << llendl; + } sOnlineDescriptor = childGetValue("online_descriptor").asString(); sNameFormat = childGetValue("name_format").asString(); setDefaultBtn("start_btn"); diff --git a/linden/indra/newview/llfloaterpreference.cpp b/linden/indra/newview/llfloaterpreference.cpp index dceadf9..963c268 100644 --- a/linden/indra/newview/llfloaterpreference.cpp +++ b/linden/indra/newview/llfloaterpreference.cpp @@ -156,6 +156,66 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton // addTabPanel(mWebPanel, "Web", FALSE, onTabChanged, this); } +LLPreferenceCore::~LLPreferenceCore() +{ + if (mGeneralPanel) + { + delete mGeneralPanel; + mGeneralPanel = NULL; + } + if (mInputPanel) + { + delete mInputPanel; + mInputPanel = NULL; + } + if (mNetworkPanel) + { + delete mNetworkPanel; + mNetworkPanel = NULL; + } + if (mDisplayPanel) + { + delete mDisplayPanel; + mDisplayPanel = NULL; + } + if (mDisplayPanel2) + { + delete mDisplayPanel2; + mDisplayPanel2 = NULL; + } + if (mDisplayPanel3) + { + delete mDisplayPanel3; + mDisplayPanel3 = NULL; + } + if (mAudioPanel) + { + delete mAudioPanel; + mAudioPanel = NULL; + } + if (mPrefsChat) + { + delete mPrefsChat; + mPrefsChat = NULL; + } + if (mPrefsIM) + { + delete mPrefsIM; + mPrefsIM = NULL; + } + if (mMsgPanel) + { + delete mMsgPanel; + mMsgPanel = NULL; + } + //if (mWebPanel) + //{ + // delete mWebPanel; + // mWebPanel = NULL; + //} +} + + void LLPreferenceCore::apply() { mGeneralPanel->apply(); diff --git a/linden/indra/newview/llfloaterpreference.h b/linden/indra/newview/llfloaterpreference.h index dcef6a0..7a6789f 100644 --- a/linden/indra/newview/llfloaterpreference.h +++ b/linden/indra/newview/llfloaterpreference.h @@ -58,6 +58,7 @@ class LLPreferenceCore public: LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton * default_btn); + ~LLPreferenceCore(); void apply(); void cancel(); diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index 7fa5f6a..682fda8 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -74,7 +74,6 @@ const S32 TERRAIN_TEXTURE_COUNT = 4; const S32 CORNER_COUNT = 4; -#define LL_ENABLE_MAINLAND_VISIBLE_CONTROL 0 ///---------------------------------------------------------------------------- /// Local class declaration @@ -1920,9 +1919,6 @@ BOOL LLPanelEstateInfo::postBuild() { // set up the callbacks for the generic controls initCtrl("externally_visible_check"); -#if LL_ENABLE_MAINLAND_VISIBLE_CONTROL - initCtrl("mainland_visible_check"); -#endif initCtrl("use_global_time_check"); initCtrl("fixed_sun_check"); initCtrl("allow_direct_teleport"); @@ -1934,9 +1930,6 @@ BOOL LLPanelEstateInfo::postBuild() initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime"); initHelpBtn("fixed_sun_help", "HelpEstateFixedSun"); initHelpBtn("externally_visible_help", "HelpEstateExternallyVisible"); -#if LL_ENABLE_MAINLAND_VISIBLE_CONTROL - initHelpBtn("mainland_visible_help", "HelpEstateMainlandVisible"); -#endif initHelpBtn("allow_direct_teleport_help", "HelpEstateAllowDirectTeleport"); initHelpBtn("allow_resident_help", "HelpEstateAllowResident"); initHelpBtn("allow_group_help", "HelpEstateAllowGroup"); @@ -2105,9 +2098,6 @@ void LLPanelEstateInfo::commitEstateInfo() void LLPanelEstateInfo::setEstateFlags(U32 flags) { childSetValue("externally_visible_check", LLSD(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE) ); -#if LL_ENABLE_MAINLAND_VISIBLE_CONTROL - childSetValue("mainland_visible_check", LLSD(flags & REGION_FLAGS_MAINLAND_VISIBLE ? TRUE : FALSE) ); -#endif childSetValue("fixed_sun_check", LLSD(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE) ); childSetValue("allow_direct_teleport", LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) ); childSetValue("deny_anonymous", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) ); @@ -2124,15 +2114,6 @@ U32 LLPanelEstateInfo::computeEstateFlags() { flags |= REGION_FLAGS_EXTERNALLY_VISIBLE; } -#if LL_ENABLE_MAINLAND_VISIBLE_CONTROL - // This flag is ignored by everything. 2006-11-17 Phoenix. - if (childGetValue("mainland_visible_check").asBoolean()) - { - flags |= REGION_FLAGS_MAINLAND_VISIBLE; - } -#else - flags |= REGION_FLAGS_MAINLAND_VISIBLE; -#endif if (childGetValue("allow_direct_teleport").asBoolean()) { diff --git a/linden/indra/newview/llfloaterreporter.cpp b/linden/indra/newview/llfloaterreporter.cpp index 2e44191..bcbab5b 100644 --- a/linden/indra/newview/llfloaterreporter.cpp +++ b/linden/indra/newview/llfloaterreporter.cpp @@ -66,10 +66,9 @@ #include "lluploaddialog.h" #include "llcallingcard.h" #include "llviewerobjectlist.h" -#include "llagent.h" #include "lltoolobjpicker.h" #include "lltoolmgr.h" -#include "llviewermenu.h" // for LLResourceData +#include "llresourcedata.h" // for LLResourceData #include "llviewerwindow.h" #include "llviewerimagelist.h" #include "llworldmap.h" @@ -965,8 +964,8 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, self->mScreenID = uuid; llinfos << "Got screen shot " << uuid << llendl; self->sendReportViaLegacy(self->gatherReport()); + self->close(); } - self->close(); } diff --git a/linden/indra/newview/llfloatersellland.cpp b/linden/indra/newview/llfloatersellland.cpp old mode 100755 new mode 100644 diff --git a/linden/indra/newview/llfloatersellland.h b/linden/indra/newview/llfloatersellland.h old mode 100755 new mode 100644 diff --git a/linden/indra/newview/llfloatersnapshot.cpp b/linden/indra/newview/llfloatersnapshot.cpp index af58cd9..5008509 100644 --- a/linden/indra/newview/llfloatersnapshot.cpp +++ b/linden/indra/newview/llfloatersnapshot.cpp @@ -53,7 +53,7 @@ #include "llviewerstats.h" #include "llviewercamera.h" #include "llviewerwindow.h" -#include "llviewermenu.h" +#include "llviewermenufile.h" // upload_new_resource() #include "llfloaterpostcard.h" #include "llcheckboxctrl.h" #include "llradiogroup.h" diff --git a/linden/indra/newview/llfloatertest.cpp b/linden/indra/newview/llfloatertest.cpp index 510072d..c5e353a 100644 --- a/linden/indra/newview/llfloatertest.cpp +++ b/linden/indra/newview/llfloatertest.cpp @@ -227,8 +227,7 @@ LLFloaterTestImpl::LLFloaterTestImpl() combo = new LLComboBox("combo", LLRect(LEFT, y, LEFT+100, y-LLCOMBOBOX_HEIGHT), "Combobox Label", - onCommitCombo, this, - 150); // list_width + onCommitCombo, this); combo->add("first item"); combo->add("second item"); combo->add("should go to the top", ADD_TOP); diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index 0480628..3931acb 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -314,8 +314,8 @@ BOOL LLFloaterTools::postBuild() mTab->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); mTab->setVisible( gSavedSettings.getBOOL("ToolboxShowMore") ); mTab->setBorderVisible(FALSE); + mTab->selectFirstTab(); } - mTab->selectFirstTab(); return TRUE; } diff --git a/linden/indra/newview/llfloatertos.cpp b/linden/indra/newview/llfloatertos.cpp index 6b38ca8..3ea8c49 100644 --- a/linden/indra/newview/llfloatertos.cpp +++ b/linden/indra/newview/llfloatertos.cpp @@ -182,7 +182,6 @@ BOOL LLFloaterTOS::postBuild() childSetValue("tos_text", LLSD(mMessage)); #endif - return TRUE; } diff --git a/linden/indra/newview/llfolderview.cpp b/linden/indra/newview/llfolderview.cpp index 7bc9cd8..ff0ad3f 100644 --- a/linden/indra/newview/llfolderview.cpp +++ b/linden/indra/newview/llfolderview.cpp @@ -229,6 +229,16 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children) return itemp; } +// is this item something we think we should be showing? +// for example, if we haven't gotten around to filtering it yet, then the answer is yes +// until we find out otherwise +BOOL LLFolderViewItem::potentiallyVisible() +{ + // we haven't been checked against min required filter + // or we have and we passed + return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered(); +} + BOOL LLFolderViewItem::getFiltered() { return mFiltered && mLastFilterGeneration >= mRoot->getFilter()->getMinRequiredGeneration(); @@ -335,8 +345,7 @@ void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection, } // helper function to change the selection from the root. -void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, - BOOL selected) +void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected) { getRoot()->changeSelection(selection, selected); } @@ -358,6 +367,11 @@ LLString LLFolderViewItem::getWidgetTag() const return LL_FOLDER_VIEW_ITEM_TAG; } +EInventorySortGroup LLFolderViewItem::getSortGroup() +{ + return SG_ITEM; +} + // addToFolder() returns TRUE if it succeeds. FALSE otherwise BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root) { @@ -427,8 +441,7 @@ void LLFolderViewItem::dirtyFilter() // means 'deselect' for a leaf item. Do this optimization after // multiple selection is implemented to make sure it all plays nice // together. -BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL open, - BOOL take_keyboard_focus) +BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL open, BOOL take_keyboard_focus) { if( selection == this ) { @@ -445,8 +458,7 @@ BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL open, return mIsSelected; } -BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, - BOOL selected) +BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected) { if(selection == this && mIsSelected != selected) { @@ -788,182 +800,174 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, void LLFolderViewItem::draw() { - if( getVisible() ) + bool possibly_has_children = false; + bool up_to_date = mListener && mListener->isUpToDate(); + if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter... + (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter) { - bool possibly_has_children = false; - bool up_to_date = mListener && mListener->isUpToDate(); - if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter... - (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter) - { - possibly_has_children = true; - } - if(/*mControlLabel[0] != '\0' && */possibly_has_children) + possibly_has_children = true; + } + if(/*mControlLabel[0] != '\0' && */possibly_has_children) + { + LLGLSTexture gls_texture; + if (mArrowImage) { - LLGLSTexture gls_texture; - if (mArrowImage) - { - gl_draw_scaled_rotated_image(mIndentation, mRect.getHeight() - ARROW_SIZE - TEXT_PAD, - ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, mArrowImage, sFgColor); - } + gl_draw_scaled_rotated_image(mIndentation, mRect.getHeight() - ARROW_SIZE - TEXT_PAD, + ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, mArrowImage, sFgColor); } + } - F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); + F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); - // If we have keyboard focus, draw selection filled - BOOL show_context = getRoot()->getShowSelectionContext(); - BOOL filled = show_context || (gFocusMgr.getKeyboardFocus() == getRoot()); + // If we have keyboard focus, draw selection filled + BOOL show_context = getRoot()->getShowSelectionContext(); + BOOL filled = show_context || (gFocusMgr.getKeyboardFocus() == getRoot()); - // always render "current" item, only render other selected items if - // mShowSingleSelection is FALSE - if( mIsSelected ) + // always render "current" item, only render other selected items if + // mShowSingleSelection is FALSE + if( mIsSelected ) + { + LLGLSNoTexture gls_no_texture; + LLColor4 bg_color = sHighlightBgColor; + //const S32 TRAILING_PAD = 5; // It just looks better with this. + if (!mIsCurSelection) { - LLGLSNoTexture gls_no_texture; - LLColor4 bg_color = sHighlightBgColor; - //const S32 TRAILING_PAD = 5; // It just looks better with this. - if (!mIsCurSelection) + // do time-based fade of extra objects + F32 fade_time = getRoot()->getSelectionFadeElapsedTime(); + if (getRoot()->getShowSingleSelection()) { - // do time-based fade of extra objects - F32 fade_time = getRoot()->getSelectionFadeElapsedTime(); - if (getRoot()->getShowSingleSelection()) - { - // fading out - bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f); - } - else - { - // fading in - bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]); - } + // fading out + bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f); } + else + { + // fading in + bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]); + } + } + gl_rect_2d( + 0, + mRect.getHeight(), + mRect.getWidth() - 2, + llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD), + bg_color, filled); + if (mIsCurSelection) + { gl_rect_2d( 0, mRect.getHeight(), mRect.getWidth() - 2, llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD), - bg_color, filled); - if (mIsCurSelection) - { - gl_rect_2d( - 0, - mRect.getHeight(), - mRect.getWidth() - 2, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD), - sHighlightFgColor, FALSE); - } - if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) - { - gl_rect_2d( - 0, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - mRect.getWidth() - 2, - 2, - sHighlightFgColor, FALSE); - if (show_context) - { - gl_rect_2d( - 0, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - mRect.getWidth() - 2, - 2, - sHighlightBgColor, TRUE); - } - } + sHighlightFgColor, FALSE); } - if (mDragAndDropTarget) + if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) { - LLGLSNoTexture gls_no_texture; gl_rect_2d( 0, - mRect.getHeight(), + llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, mRect.getWidth() - 2, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD), - sHighlightBgColor, FALSE); - - if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) + 2, + sHighlightFgColor, FALSE); + if (show_context) { gl_rect_2d( 0, llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, mRect.getWidth() - 2, 2, - sHighlightBgColor, FALSE); + sHighlightBgColor, TRUE); } - mDragAndDropTarget = FALSE; } + } + if (mDragAndDropTarget) + { + LLGLSNoTexture gls_no_texture; + gl_rect_2d( + 0, + mRect.getHeight(), + mRect.getWidth() - 2, + llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD), + sHighlightBgColor, FALSE); - - if(mIcon) + if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) { - gl_draw_image(mIndentation + ARROW_SIZE + TEXT_PAD, mRect.getHeight() - mIcon->getHeight(), mIcon); - mIcon->addTextureStats( (F32)(mIcon->getWidth() * mIcon->getHeight())); + gl_rect_2d( + 0, + llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + mRect.getWidth() - 2, + 2, + sHighlightBgColor, FALSE); } + mDragAndDropTarget = FALSE; + } - if (!mLabel.empty()) - { - // highlight filtered text - BOOL debug_filters = getRoot()->getDebugFilters(); - LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor ); - F32 right_x; - F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; - if (debug_filters) - { - if (!getFiltered() && !possibly_has_children) - { - color.mV[VALPHA] *= 0.5f; - } - - LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f); - sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color, - LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, - S32_MAX, S32_MAX, &right_x, FALSE ); - text_left = right_x; - } + if(mIcon) + { + gl_draw_image(mIndentation + ARROW_SIZE + TEXT_PAD, mRect.getHeight() - mIcon->getHeight(), mIcon); + mIcon->addTextureStats( (F32)(mIcon->getWidth() * mIcon->getHeight())); + } - sFont->renderUTF8( mLabel, 0, text_left, y, color, - LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, - S32_MAX, S32_MAX, &right_x, FALSE ); - if (!mLabelSuffix.empty()) - { - sFont->renderUTF8( mLabelSuffix, 0, right_x, y, LLColor4(0.75f, 0.85f, 0.85f, 1.f), - LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, - S32_MAX, S32_MAX, &right_x, FALSE ); - } + if (!mLabel.empty()) + { + // highlight filtered text + BOOL debug_filters = getRoot()->getDebugFilters(); + LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor ); + F32 right_x; + F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; - if (mBoxImage.notNull() && mStringMatchOffset != LLString::npos) + if (debug_filters) + { + if (!getFiltered() && !possibly_has_children) { - // don't draw backgrounds for zero-length strings - S32 filter_string_length = mRoot->getFilterSubString().size(); - if (filter_string_length > 0) - { - LLString combined_string = mLabel + mLabelSuffix; - S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1; - S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; - S32 bottom = llfloor(mRect.getHeight() - sFont->getLineHeight() - 3); - S32 top = mRect.getHeight(); - - LLViewerImage::bindTexture(mBoxImage); - glColor4fv(sFilterBGColor.mV); - gl_segmented_rect_2d_tex(left, top, right, bottom, mBoxImage->getWidth(), mBoxImage->getHeight(), 16); - F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset); - F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; - sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y, - sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, - filter_string_length, S32_MAX, &right_x, FALSE ); - } + color.mV[VALPHA] *= 0.5f; } + + LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f); + sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color, + LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, + S32_MAX, S32_MAX, &right_x, FALSE ); + text_left = right_x; } - if( sDebugRects ) + sFont->renderUTF8( mLabel, 0, text_left, y, color, + LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, + S32_MAX, S32_MAX, &right_x, FALSE ); + if (!mLabelSuffix.empty()) { - drawDebugRect(); + sFont->renderUTF8( mLabelSuffix, 0, right_x, y, LLColor4(0.75f, 0.85f, 0.85f, 1.f), + LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, + S32_MAX, S32_MAX, &right_x, FALSE ); + } + + if (mBoxImage.notNull() && mStringMatchOffset != LLString::npos) + { + // don't draw backgrounds for zero-length strings + S32 filter_string_length = mRoot->getFilterSubString().size(); + if (filter_string_length > 0) + { + LLString combined_string = mLabel + mLabelSuffix; + S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1; + S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; + S32 bottom = llfloor(mRect.getHeight() - sFont->getLineHeight() - 3); + S32 top = mRect.getHeight(); + + LLViewerImage::bindTexture(mBoxImage); + glColor4fv(sFilterBGColor.mV); + gl_segmented_rect_2d_tex(left, top, right, bottom, mBoxImage->getWidth(), mBoxImage->getHeight(), 16); + F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset); + F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; + sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y, + sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, + filter_string_length, S32_MAX, &right_x, FALSE ); + } } } - else if (mStatusText.size()) + + if( sDebugRects ) { - // just draw status text - sFont->renderUTF8( mStatusText, 0, 0, 1, sFgColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, S32_MAX, S32_MAX, NULL, FALSE ); + drawDebugRect(); } } @@ -977,7 +981,6 @@ LLFolderViewFolder::LLFolderViewFolder( const LLString& name, LLViewerImage* ico LLFolderView* root, LLFolderViewEventListener* listener ): LLFolderViewItem( name, icon, 0, root, listener ), // 0 = no create time - mSortFunction(sort_item_name), mIsOpen(FALSE), mExpanderHighlighted(FALSE), mCurHeight(0.f), @@ -1246,7 +1249,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter) } // when applying a filter, matching folders get their contents downloaded first - if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && !gInventory.isCategoryComplete(mListener->getUUID())) + if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID()))) { gInventory.startBackgroundFetch(mListener->getUUID()); } @@ -1667,7 +1670,8 @@ BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item) { if(item->remove()) { - removeView(item); + //RN: this seem unneccessary as remove() moves to trash + //removeView(item); return TRUE; } return FALSE; @@ -1677,7 +1681,7 @@ BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item) // listeners. void LLFolderViewFolder::removeView(LLFolderViewItem* item) { - if (!item) + if (!item || item->getParentFolder() != this) { return; } @@ -1722,23 +1726,8 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) // This is only called for renaming an object because it won't work for date void LLFolderViewFolder::resort(LLFolderViewItem* item) { - std::sort(mItems.begin(), mItems.end(), *mSortFunction); - std::sort(mFolders.begin(), mFolders.end(), *mSortFunction); - //if(mItems.removeData(item)) - //{ - // mItems.addDataSorted(item); - //} - //else - //{ - // // This is an evil downcast. However, it's only doing - // // pointer comparison to find if (which it should be ) the - // // item is in the container, so it's pretty safe. - // LLFolderViewFolder* f = reinterpret_cast(item); - // if(mFolders.removeData(f)) - // { - // mFolders.addDataSorted(f); - // } - //} + std::sort(mItems.begin(), mItems.end(), mSortFunction); + std::sort(mFolders.begin(), mFolders.end(), mSortFunction); } bool LLFolderViewFolder::isTrash() @@ -1752,65 +1741,22 @@ bool LLFolderViewFolder::isTrash() void LLFolderViewFolder::sortBy(U32 order) { - BOOL sort_order_changed = FALSE; - if (!(order & LLInventoryFilter::SO_DATE)) - { - if (mSortFunction != sort_item_name) - { - mSortFunction = sort_item_name; - sort_order_changed = TRUE; - } - } - else + if (!mSortFunction.updateSort(order)) { - if (mSortFunction != sort_item_date) - { - mSortFunction = sort_item_date; - sort_order_changed = TRUE; - } + // No changes. + return; } + // Propegate this change to sub folders for (folders_t::iterator iter = mFolders.begin(); iter != mFolders.end();) { folders_t::iterator fit = iter++; (*fit)->sortBy(order); } - if (order & LLInventoryFilter::SO_FOLDERS_BY_NAME) - { - // sort folders by name if always by name - std::sort(mFolders.begin(), mFolders.end(), sort_item_name); - } - else - { - // sort folders by the default sort ordering - std::sort(mFolders.begin(), mFolders.end(), *mSortFunction); - // however, if we are at the root of the inventory and we are sorting by date - if (mListener->getUUID() == gAgent.getInventoryRootID() && order & LLInventoryFilter::SO_DATE) - { - // pull the trash folder and stick it on the end of the list - LLFolderViewFolder *t = NULL; - for (folders_t::iterator fit = mFolders.begin(); - fit != mFolders.end(); ++fit) - { - if ((*fit)->isTrash()) - { - t = *fit; - mFolders.erase(fit); - break; - } - } - if (t) - { - mFolders.push_back(t); - } - } - } - if (sort_order_changed) - { - std::sort(mItems.begin(), mItems.end(), *mSortFunction); - } + std::sort(mFolders.begin(), mFolders.end(), mSortFunction); + std::sort(mItems.begin(), mItems.end(), mSortFunction); if (order & LLInventoryFilter::SO_DATE) { @@ -1834,19 +1780,39 @@ void LLFolderViewFolder::sortBy(U32 order) } } -void LLFolderViewFolder::setItemSortFunction(sort_order_f ordering) +void LLFolderViewFolder::setItemSortOrder(U32 ordering) { - mSortFunction = ordering; + if (mSortFunction.updateSort(ordering)) + { + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end();) + { + folders_t::iterator fit = iter++; + (*fit)->setItemSortOrder(ordering); + } - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) + std::sort(mFolders.begin(), mFolders.end(), mSortFunction); + std::sort(mItems.begin(), mItems.end(), mSortFunction); + } +} + +EInventorySortGroup LLFolderViewFolder::getSortGroup() +{ + if (isTrash()) { - folders_t::iterator fit = iter++; - (*fit)->setItemSortFunction(ordering); + return SG_TRASH_FOLDER; } - std::sort(mFolders.begin(), mFolders.end(), *mSortFunction); - std::sort(mItems.begin(), mItems.end(), *mSortFunction); + // Folders that can't be moved are 'system' folders. + if( mListener ) + { + if( !(mListener->isItemMovable()) ) + { + return SG_SYSTEM_FOLDER; + } + } + + return SG_NORMAL_FOLDER; } BOOL LLFolderViewFolder::isMovable() @@ -1917,6 +1883,7 @@ BOOL LLFolderViewFolder::isRemovable() // this is an internal method used for adding items to folders. BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) { + items_t::iterator it = std::lower_bound( mItems.begin(), mItems.end(), @@ -1945,18 +1912,29 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder) folder->setVisible(FALSE); addChild( folder ); folder->dirtyFilter(); - requestArrange(); + // rearrange all descendants too, as our indentation level might have changed + folder->requestArrange(TRUE); return TRUE; } -void LLFolderViewFolder::requestArrange() +void LLFolderViewFolder::requestArrange(BOOL include_descendants) { mLastArrangeGeneration = -1; // flag all items up to root - if (mParentFolder) + if (mParentFolder && !mParentFolder->needsArrange()) { mParentFolder->requestArrange(); } + + if (include_descendants) + { + for (folders_t::iterator iter = mFolders.begin(); + iter != mFolders.end(); + ++iter) + { + (*iter)->requestArrange(TRUE); + } + } } void LLFolderViewFolder::toggleOpen() @@ -2002,11 +1980,11 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL open, ERecurseType recur } BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask, - BOOL drop, - EDragAndDropType c_type, - void* cargo_data, - EAcceptance* accept, - LLString& tooltip_msg) + BOOL drop, + EDragAndDropType c_type, + void* cargo_data, + EAcceptance* accept, + LLString& tooltip_msg) { BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data); if (accepted) @@ -2218,16 +2196,13 @@ void LLFolderViewFolder::draw() } LLFolderViewItem::draw(); - if( mIsOpen ) + + // draw children if root folder, or any other folder that is open or animating to closed state + if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight )) { LLView::draw(); } -// if (mExpanderHighlighted) -// { -// gl_rect_2d(mIndentation - TEXT_PAD, llfloor(mRect.getHeight() - TEXT_PAD), mIndentation + sFont->getWidth(mControlLabel) + TEXT_PAD, llfloor(mRect.getHeight() - sFont->getLineHeight() - TEXT_PAD), sFgColor, FALSE); -// //sFont->renderUTF8( mControlLabel, 0, mIndentation, llfloor(mRect.getHeight() - sFont->getLineHeight() - TEXT_PAD), sFgColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, S32_MAX, S32_MAX, NULL, FALSE ); -// } mExpanderHighlighted = FALSE; } @@ -2237,6 +2212,16 @@ U32 LLFolderViewFolder::getCreationDate() const } +BOOL LLFolderViewFolder::potentiallyVisible() +{ + // folder should be visible by it's own filter status + return LLFolderViewItem::potentiallyVisible() + // or one or more of its descendants have passed the minimum filter requirement + || hasFilteredDescendants(mRoot->getFilter()->getMinRequiredGeneration()) + // or not all of its descendants have been checked against minimum filter requirement + || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration(); +} + // this does prefix traversal, as folders are listed above their contents LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children ) { @@ -2456,20 +2441,20 @@ LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* it class LLSetItemSortFunction : public LLFolderViewFunctor { public: - LLSetItemSortFunction(sort_order_f ordering) - : mSortFunction(ordering) {} + LLSetItemSortFunction(U32 ordering) + : mSortOrder(ordering) {} virtual ~LLSetItemSortFunction() {} virtual void doFolder(LLFolderViewFolder* folder); virtual void doItem(LLFolderViewItem* item); - sort_order_f mSortFunction; + U32 mSortOrder; }; // Set the sort order. void LLSetItemSortFunction::doFolder(LLFolderViewFolder* folder) { - folder->setItemSortFunction(mSortFunction); + folder->setItemSortOrder(mSortOrder); } // Do nothing. @@ -2696,6 +2681,7 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder) folder->setVisible(FALSE); addChild( folder ); folder->dirtyFilter(); + folder->requestArrange(); return TRUE; } @@ -2916,8 +2902,8 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL open, /* Flaw addToSelectionList(selection); } - BOOL rv = LLFolderViewFolder::setSelection(selection, open, take_keyboard_focus); /* Flawfinder: ignore */ - if(open) /* Flawfinder: ignore */ + BOOL rv = LLFolderViewFolder::setSelection(selection, open, take_keyboard_focus); + if(open && selection) { selection->getParentFolder()->requestArrange(); } @@ -2954,11 +2940,6 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected) } BOOL on_list = (item_iter != mSelectedItems.end()); - if (on_list && mSelectedItems.size() == 1) - { - // we are trying to select/deselect the only selected item - return FALSE; - } if(selected && !on_list) { @@ -3005,48 +2986,46 @@ S32 LLFolderView::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* void LLFolderView::sanitizeSelection() { + // store off current item in case it is automatically deselected + // and we want to preserve context + LLFolderViewItem* original_selected_item = getCurSelectedItem(); + std::vector items_to_remove; selected_items_t::iterator item_iter; for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter) { LLFolderViewItem* item = *item_iter; - BOOL visible = item->getVisible(); + // ensure that each ancestor is open and potentially passes filtering + BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item + // modify with parent open and filters states LLFolderViewFolder* parent_folder = item->getParentFolder(); - while(visible && parent_folder) + while(parent_folder) { - visible = visible && parent_folder->isOpen() && parent_folder->getVisible(); + visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible(); parent_folder = parent_folder->getParentFolder(); } - if (!visible || item->getNumSelectedDescendants() > 0) + + // deselect item if any ancestor is closed or didn't pass filter requirements. + if (!visible) { - // only deselect self if not visible - // check to see if item failed the filter but was checked against most recent generation - if ((!item->getFiltered() && item->getLastFilterGeneration() >= getFilter()->getMinRequiredGeneration()) - || (item->getParentFolder() && !item->getParentFolder()->isOpen())) - { - item->recursiveDeselect(TRUE); - items_to_remove.push_back(item); - } - else - { - item->recursiveDeselect(FALSE); - } + items_to_remove.push_back(item); + } - selected_items_t::iterator other_item_iter; - for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter) + // disallow nested selections (i.e. folder items plus one or more ancestors) + // could check cached mum selections count and only iterate if there are any + // but that may be a premature optimization. + selected_items_t::iterator other_item_iter; + for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter) + { + LLFolderViewItem* other_item = *other_item_iter; + for(LLFolderViewFolder* parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder()) { - LLFolderViewItem* other_item = *other_item_iter; - LLFolderViewFolder* parent_folder = other_item->getParentFolder(); - while (parent_folder) + if (parent_folder == item) { - if (parent_folder == item) - { - // this is a descendent of the current folder, remove from list - items_to_remove.push_back(other_item); - break; - } - parent_folder = parent_folder->getParentFolder(); + // this is a descendent of the current folder, remove from list + items_to_remove.push_back(other_item); + break; } } } @@ -3055,7 +3034,47 @@ void LLFolderView::sanitizeSelection() std::vector::iterator item_it; for (item_it = items_to_remove.begin(); item_it != items_to_remove.end(); ++item_it ) { - removeFromSelectionList(*item_it); + changeSelection(*item_it, FALSE); // toggle selection (also removes from list) + } + + // if nothing selected after prior constraints... + if (mSelectedItems.empty()) + { + // ...select first available parent of original selection, or "My Inventory" otherwise + LLFolderViewItem* new_selection = NULL; + if (original_selected_item) + { + for(LLFolderViewFolder* parent_folder = original_selected_item->getParentFolder(); + parent_folder; + parent_folder = parent_folder->getParentFolder()) + { + if (parent_folder->potentiallyVisible()) + { + // give initial selection to first ancestor folder that potentially passes the filter + if (!new_selection) + { + new_selection = parent_folder; + } + + // if any ancestor folder of original item is closed, move the selection up + // to the highest closed + if (!parent_folder->isOpen()) + { + new_selection = parent_folder; + } + } + } + } + else + { + // nothing selected to start with, so pick "My Inventory" as best guess + new_selection = getItemByID(gAgent.getInventoryRootID()); + } + + if (new_selection) + { + setSelection(new_selection, FALSE, FALSE); + } } } @@ -3232,7 +3251,7 @@ void LLFolderView::removeSelectedItems( void ) // create a temporary structure which we will use to remove // items, since the removal will futz with internal data // structures. - LLDynamicArray items; + std::vector items; S32 count = mSelectedItems.size(); if(count == 0) return; LLFolderViewItem* item = NULL; @@ -3242,7 +3261,7 @@ void LLFolderView::removeSelectedItems( void ) item = *item_it; if(item->isRemovable()) { - items.put(item); + items.push_back(item); } else { @@ -3252,11 +3271,11 @@ void LLFolderView::removeSelectedItems( void ) } // iterate through the new container. - count = items.count(); + count = items.size(); LLUUID new_selection_id; if(count == 1) { - LLFolderViewItem* item_to_delete = items.get(0); + LLFolderViewItem* item_to_delete = items[0]; LLFolderViewFolder* parent = item_to_delete->getParentFolder(); LLFolderViewItem* new_selection = item_to_delete->getNextOpenNode(FALSE); if (!new_selection) @@ -3284,7 +3303,7 @@ void LLFolderView::removeSelectedItems( void ) { LLDynamicArray listeners; LLFolderViewEventListener* listener; - LLFolderViewItem* last_item = items.get(count - 1); + LLFolderViewItem* last_item = items[count - 1]; LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE); while(new_selection && new_selection->isSelected()) { @@ -3309,7 +3328,7 @@ void LLFolderView::removeSelectedItems( void ) for(S32 i = 0; i < count; ++i) { - listener = items.get(i)->getListener(); + listener = items[i]->getListener(); if(listener && (listeners.find(listener) == LLDynamicArray::FAIL)) { listeners.put(listener); @@ -3620,21 +3639,6 @@ void LLFolderView::setFocus(BOOL focus) { if (focus) { - // select "My Inventory" if nothing selected - if (!getCurSelectedItem()) - { - LLFolderViewItem* itemp = getItemByID(gAgent.getInventoryRootID()); - if (itemp) - { - setSelection(itemp, FALSE, FALSE); - } - } - - if (mRenamer->getVisible()) - { - //RN: commit rename changes when focus is moved, only revert on ESC - finishRenamingItem(); - } if(!hasFocus()) { gEditMenuHandler = this; @@ -3954,10 +3958,10 @@ BOOL LLFolderView::search(LLFolderViewItem* first_item, const LLString &search_s LLString::toUpper(upper_case_string); // if nothing selected, select first item in folder - if (!first_item) + if (!search_item) { // start from first item - first_item = getNextFromChild(NULL); + search_item = getNextFromChild(NULL); } // search over all open nodes for first substring match (with wrapping) @@ -4248,8 +4252,6 @@ void LLFolderView::idle(void* user_data) // filter to determine visiblity before arranging self->filterFromRoot(); - self->sanitizeSelection(); - // automatically show matching items, and select first one // do this every frame until user puts keyboard focus into the inventory window // signaling the end of the automatic update @@ -4269,6 +4271,8 @@ void LLFolderView::idle(void* user_data) self->scrollToShowSelection(); } + self->sanitizeSelection(); + if( self->needsArrange() && self->isInVisibleChain()) { self->arrangeFromRoot(); @@ -4307,33 +4311,71 @@ void LLFolderView::dumpSelectionInformation() ///---------------------------------------------------------------------------- /// Local function definitions ///---------------------------------------------------------------------------- - -bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b) +bool LLInventorySort::updateSort(U32 order) { - S32 compare = LLString::compareDict(a->getLabel(), b->getLabel()); - if (0 == compare) - { - return (a->getCreationDate() > b->getCreationDate()); - } - else + if (order != mSortOrder) { - return (compare < 0); + mSortOrder = order; + mByDate = (order & LLInventoryFilter::SO_DATE); + mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); + mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); + return true; } + return false; } -// BUG: This is very very slow. The getCreationDate() is log n in number -// of inventory items. -bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b) +bool LLInventorySort::operator()(LLFolderViewItem* a, LLFolderViewItem* b) { - U32 first_create = a->getCreationDate(); - U32 second_create = b->getCreationDate(); - if (first_create == second_create) + // We sort by name if we aren't sorting by date + // OR if these are folders and we are sorting folders by name. + bool by_name = (!mByDate + || (mFoldersByName + && (a->getSortGroup() != SG_ITEM))); + + if (a->getSortGroup() != b->getSortGroup()) + { + if (mSystemToTop) + { + // Group order is System Folders, Trash, Normal Folders, Items + return (a->getSortGroup() < b->getSortGroup()); + } + else if (mByDate) + { + // Trash needs to go to the bottom if we are sorting by date + if ( (a->getSortGroup() == SG_TRASH_FOLDER) + || (b->getSortGroup() == SG_TRASH_FOLDER)) + { + return (b->getSortGroup() == SG_TRASH_FOLDER); + } + } + } + + if (by_name) { - return (LLString::compareDict(a->getLabel(), b->getLabel()) < 0); + S32 compare = LLString::compareDict(a->getLabel(), b->getLabel()); + if (0 == compare) + { + return (a->getCreationDate() > b->getCreationDate()); + } + else + { + return (compare < 0); + } } else { - return (first_create > second_create); + // BUG: This is very very slow. The getCreationDate() is log n in number + // of inventory items. + U32 first_create = a->getCreationDate(); + U32 second_create = b->getCreationDate(); + if (first_create == second_create) + { + return (LLString::compareDict(a->getLabel(), b->getLabel()) < 0); + } + else + { + return (first_create > second_create); + } } } diff --git a/linden/indra/newview/llfolderview.h b/linden/indra/newview/llfolderview.h index 8acbc8f..ec70b90 100644 --- a/linden/indra/newview/llfolderview.h +++ b/linden/indra/newview/llfolderview.h @@ -181,6 +181,7 @@ public: static const U32 SO_DATE = 1; static const U32 SO_FOLDERS_BY_NAME = 2; + static const U32 SO_SYSTEM_FOLDERS_TO_TOP = 4; LLInventoryFilter(const LLString& name); virtual ~LLInventoryFilter(); @@ -265,6 +266,34 @@ private: LLString mFilterText; }; +// These are grouping of inventory types. +// Order matters when sorting system folders to the top. +enum EInventorySortGroup +{ + SG_SYSTEM_FOLDER, + SG_TRASH_FOLDER, + SG_NORMAL_FOLDER, + SG_ITEM +}; + +class LLInventorySort +{ +public: + LLInventorySort() + : mSortOrder(0) { } + + // Returns true if order has changed + bool updateSort(U32 order); + U32 getSort() { return mSortOrder; } + + bool operator()(LLFolderViewItem* a, LLFolderViewItem* b); +private: + U32 mSortOrder; + bool mByDate; + bool mSystemToTop; + bool mFoldersByName; +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFolderViewItem // @@ -351,6 +380,8 @@ public: enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE }; virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root); + virtual EInventorySortGroup getSortGroup(); + // Finds width and height of this object and it's children. Also // makes sure that this view and it's children are the right size. virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); @@ -449,8 +480,10 @@ public: virtual void setStatusText(const LLString& text) { mStatusText = text; } - BOOL getFiltered(); - BOOL getFiltered(S32 filter_generation); + virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out? + + virtual BOOL getFiltered(); + virtual BOOL getFiltered(S32 filter_generation); virtual void setFiltered(BOOL filtered, S32 filter_generation); // change the icon @@ -504,7 +537,7 @@ protected: typedef std::vector folders_t; items_t mItems; folders_t mFolders; - sort_order_f mSortFunction; + LLInventorySort mSortFunction; BOOL mIsOpen; BOOL mExpanderHighlighted; @@ -534,6 +567,8 @@ public: virtual EWidgetType getWidgetType() const; virtual LLString getWidgetTag() const; + virtual BOOL potentiallyVisible(); + LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE ); @@ -546,6 +581,9 @@ public: BOOL needsArrange(); + // Returns the sort group (system, trash, folder) for this folder. + virtual EInventorySortGroup getSortGroup(); + virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up); virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; } @@ -603,7 +641,7 @@ public: // This function is called by a child that needs to be resorted. void resort(LLFolderViewItem* item); - void setItemSortFunction(sort_order_f ordering); + void setItemSortOrder(U32 ordering); void sortBy(U32); //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b)); @@ -617,7 +655,8 @@ public: virtual void setOpen(BOOL open = TRUE); /* Flawfinder: ignore */ // Called when a child is refreshed. - virtual void requestArrange(); + // don't rearrange child folder contents unless explicitly requested + virtual void requestArrange(BOOL include_descendants = FALSE); // internal method which doesn't update the entire view. This // method was written because the list iterators destroy the state diff --git a/linden/indra/newview/llgenepool.cpp b/linden/indra/newview/llgenepool.cpp index 95b15f3..3cc57e9 100644 --- a/linden/indra/newview/llgenepool.cpp +++ b/linden/indra/newview/llgenepool.cpp @@ -223,6 +223,14 @@ void LLGenePool::spawn( EWearableType type ) // Only consider archetypes that have the same sex as you have already. LLVisualParam* male_param = avatar->getVisualParam( "male" ); + + if (!male_param) + { + llwarns << "The hard coded \'male\' parameter passed to avatar->getVisualParam() in LLGenePool::spawn() is no longer valid." + << llendl; + return; + } + S32 male_param_id = male_param->getID(); F32 sex_weight = male_param->getWeight(); diff --git a/linden/indra/newview/llgivemoney.cpp b/linden/indra/newview/llgivemoney.cpp index 3722682..e89ab3d 100644 --- a/linden/indra/newview/llgivemoney.cpp +++ b/linden/indra/newview/llgivemoney.cpp @@ -155,7 +155,7 @@ LLFloaterPay::LLFloaterPay(const std::string& name, childSetKeystrokeCallback("amount", &LLFloaterPay::onKeystroke, this); childSetText("amount", last_amount); - childSetPrevalidate("amount", LLLineEditor::prevalidatePositiveS32); + childSetPrevalidate("amount", LLLineEditor::prevalidateNonNegativeS32); info = new LLGiveMoneyInfo(this, 0); mCallbackData.push_back(info); @@ -422,14 +422,9 @@ void LLFloaterPay::onKeystroke(LLLineEditor*, void* data) LLFloaterPay* self = reinterpret_cast(data); if(self) { - if (!self->childGetText("amount").empty()) - { - self->childSetEnabled("pay btn", TRUE); - } - else - { - self->childSetEnabled("pay btn", FALSE); - } + // enable the Pay button when amount is non-empty and positive, disable otherwise + LLString amtstr = self->childGetText("amount"); + self->childSetEnabled("pay btn", !amtstr.empty() && atoi(amtstr.c_str()) > 0); } } diff --git a/linden/indra/newview/llglsandbox.cpp b/linden/indra/newview/llglsandbox.cpp index e14cebe..81806dc 100644 --- a/linden/indra/newview/llglsandbox.cpp +++ b/linden/indra/newview/llglsandbox.cpp @@ -1134,5 +1134,5 @@ void post_show_depth_buffer() } glDrawPixels(xsize,ysize,GL_RED,GL_UNSIGNED_BYTE,buf); - delete buf; + delete [] buf; } diff --git a/linden/indra/newview/llglslshader.cpp b/linden/indra/newview/llglslshader.cpp index 3f23a66..9c3d707 100644 --- a/linden/indra/newview/llglslshader.cpp +++ b/linden/indra/newview/llglslshader.cpp @@ -847,7 +847,7 @@ BOOL LLShaderMgr::loadShadersAvatar() return FALSE; } - if (success) + /*if (success) { //load specular (eyeball) vertex program std::string eyeballvertex = "avatar/eyeballV.glsl"; @@ -865,7 +865,7 @@ BOOL LLShaderMgr::loadShadersAvatar() { llwarns << "Failed to load " << eyeballvertex << llendl; } - } + }*/ if (success) { diff --git a/linden/indra/newview/llgroupnotify.cpp b/linden/indra/newview/llgroupnotify.cpp index de9b571..ef20138 100644 --- a/linden/indra/newview/llgroupnotify.cpp +++ b/linden/indra/newview/llgroupnotify.cpp @@ -162,7 +162,7 @@ LLGroupNotifyBox::LLGroupNotifyBox(const char* subject, line = new LLTextBox("title",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),"Group Notice",LLFontGL::sSansSerifHuge); line->setHAlign(LLFontGL::RIGHT); - line->setDropshadowVisible(true); + line->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); line->setBorderVisible(FALSE); line->setColor(LLColor4::white); line->setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") ); @@ -177,7 +177,7 @@ LLGroupNotifyBox::LLGroupNotifyBox(const char* subject, from << "Sent by " << from_name << ", " << group_name; line = new LLTextBox("group",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),from.str().c_str(),LLFontGL::sSansSerif); - line->setDropshadowVisible(true); + line->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); line->setHAlign(LLFontGL::RIGHT); line->setBorderVisible(FALSE); line->setColor(LLColor4::white); @@ -244,7 +244,7 @@ LLGroupNotifyBox::LLGroupNotifyBox(const char* subject, line = new LLTextBox("subjecttitle",LLRect(x,y,x + LABEL_WIDTH,y - LINE_HEIGHT),"Attached: ",LLFontGL::sSansSerif); line->setBorderVisible(FALSE); line->setColor(LLColor4::white); - line->setDropshadowVisible(TRUE); + line->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); line->setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") ); addChild(line); @@ -261,7 +261,7 @@ LLGroupNotifyBox::LLGroupNotifyBox(const char* subject, line->setEnabled(FALSE); line->setBorderVisible(TRUE); line->setDisabledColor(LLColor4::blue4); - line->setDropshadowVisible(FALSE); + line->setFontStyle(LLFontGL::NORMAL); line->setBackgroundVisible(true); line->setBackgroundColor( semi_transparent ); addChild(line); @@ -399,7 +399,7 @@ void LLGroupNotifyBox::close() // Then we need to send the inventory declined message if(mHasInventory) { - inventory_offer_callback( 1 , mInventoryOffer); + inventory_offer_callback(IOR_DECLINE , mInventoryOffer); } gNotifyBoxView->removeChild(this); @@ -461,7 +461,7 @@ void LLGroupNotifyBox::onClickSaveInventory(void* data) { LLGroupNotifyBox* self = (LLGroupNotifyBox*)data; - inventory_offer_callback( 0 , self->mInventoryOffer); + inventory_offer_callback( IOR_ACCEPT , self->mInventoryOffer); // inventory_offer_callback will delete the offer, so make sure we aren't still pointing to it. self->mInventoryOffer = NULL; diff --git a/linden/indra/newview/llhoverview.cpp b/linden/indra/newview/llhoverview.cpp index 6807b42..8296e14 100644 --- a/linden/indra/newview/llhoverview.cpp +++ b/linden/indra/newview/llhoverview.cpp @@ -539,7 +539,6 @@ void LLHoverView::updateText() // on the land info panel if ( !hover_parcel->getAllowModify() ) { - if (words) line->append(", "); if ( hover_parcel->getAllowGroupModify() ) { line->append("Group Build"); diff --git a/linden/indra/newview/llhudeffecttrail.cpp b/linden/indra/newview/llhudeffecttrail.cpp index fed3a9e..79c05d7 100644 --- a/linden/indra/newview/llhudeffecttrail.cpp +++ b/linden/indra/newview/llhudeffecttrail.cpp @@ -112,17 +112,19 @@ void LLHUDEffectSpiral::packData(LLMessageSystem *mesgsys) void LLHUDEffectSpiral::unpackData(LLMessageSystem *mesgsys, S32 blocknum) { - U8 packed_data[56]; + const size_t EFFECT_SIZE = 56; + U8 packed_data[EFFECT_SIZE]; LLHUDEffect::unpackData(mesgsys, blocknum); LLUUID object_id, target_object_id; S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData); - if (size != 56) + if (size != EFFECT_SIZE) { llwarns << "Spiral effect with bad size " << size << llendl; return; } - mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 56, blocknum); + mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, + packed_data, EFFECT_SIZE, blocknum, EFFECT_SIZE); htonmemcpy(object_id.mData, packed_data, MVT_LLUUID, 16); htonmemcpy(target_object_id.mData, packed_data + 16, MVT_LLUUID, 16); diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp index 38471ad..02578d2 100644 --- a/linden/indra/newview/llimview.cpp +++ b/linden/indra/newview/llimview.cpp @@ -374,11 +374,21 @@ void LLIMView::addMessage( } else { + //if we have recently requsted to be dropped from a session + //but are still receiving messages from the session, don't make + //a new floater +// if ( mSessionsDropRequested.has(session_id.asString()) ) +// { +// return ; +// } + const char* name = from; if(session_name && (strlen(session_name)>1)) { name = session_name; } + + floater = createFloater(new_session_id, other_participant_id, name, dialog, FALSE); // When we get a new IM, and if you are a god, display a bit @@ -502,13 +512,17 @@ LLUUID LLIMView::addSession(const std::string& name, LLFloaterIMPanel* floater = findFloaterBySession(session_id); if(!floater) { - // On creation, use the first element of ids as the "other_participant_id" + // On creation, use the first element of ids as the + // "other_participant_id" floater = createFloater(session_id, other_participant_id, name, ids, dialog, TRUE); + + if ( !floater ) return LLUUID::null; + noteOfflineUsers(floater, ids); } mTalkFloater->showFloater(floater); @@ -528,6 +542,11 @@ void LLIMView::removeSession(const LLUUID& session_id) mTalkFloater->removeFloater(floater); //mTabContainer->removeTabPanel(floater); } + +// if ( session_id.notNull() ) +// { +// mSessionsDropRequested[session_id.asString()] = LLSD(); +// } } void LLIMView::refresh() @@ -705,6 +724,7 @@ LLFloaterIMPanel* LLIMView::createFloater( { llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl; } + llinfos << "LLIMView::createFloater: from " << other_participant_id << " in session " << session_id << llendl; LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label, @@ -731,6 +751,7 @@ LLFloaterIMPanel* LLIMView::createFloater( { llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl; } + llinfos << "LLIMView::createFloater: from " << other_participant_id << " in session " << session_id << llendl; LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label, @@ -805,6 +826,11 @@ void LLIMView::updateFloaterSessionID(const LLUUID& old_session_id, } } +void LLIMView::onDropRequestReplyReceived(const LLUUID& session_id) +{ + mSessionsDropRequested.erase(session_id.asString()); +} + void onConfirmForceCloseError(S32 option, void* data) { //only 1 option really @@ -869,7 +895,7 @@ public: class LLViewerIMSessionEventReply : public LLHTTPNode { - public: +public: virtual void describe(Description& desc) const { desc.shortInfo("Used for receiving a reply to a IM session event"); @@ -913,7 +939,7 @@ class LLViewerIMSessionEventReply : public LLHTTPNode class LLViewerForceCloseIMSession: public LLHTTPNode { - +public: virtual void post(ResponsePtr response, const LLSD& context, const LLSD& input) const @@ -942,11 +968,40 @@ class LLViewerForceCloseIMSession: public LLHTTPNode } }; +class LLViewerIMSessionDropReply : public LLHTTPNode +{ +public: + virtual void post(ResponsePtr response, + const LLSD& context, + const LLSD& input) const + { + LLUUID session_id; + bool success; + + success = input["body"]["success"].asBoolean(); + session_id = input["body"]["session_id"].asUUID(); + + if ( !success ) + { + //throw an error alert? + } + + gIMView->onDropRequestReplyReceived(session_id); + } +}; + LLHTTPRegistration - gHTTPRegistrationMessageImsessionstartreply("/message/IMSessionStartReply"); + gHTTPRegistrationMessageImsessionstartreply( + "/message/IMSessionStartReply"); LLHTTPRegistration - gHTTPRegistrationMessageImsessioneventreply("/message/IMSessionEventReply"); + gHTTPRegistrationMessageImsessioneventreply( + "/message/IMSessionEventReply"); LLHTTPRegistration - gHTTPRegistrationMessageForceCloseImSession("/message/ForceCloseIMSession"); + gHTTPRegistrationMessageForceCloseImSession( + "/message/ForceCloseIMSession"); + +LLHTTPRegistration + gHTTPRegistrationMessageImSessionDropReply( + "/message/IMSessionDropReply"); diff --git a/linden/indra/newview/llimview.h b/linden/indra/newview/llimview.h index 74ea880..c0b0f79 100644 --- a/linden/indra/newview/llimview.h +++ b/linden/indra/newview/llimview.h @@ -131,6 +131,8 @@ public: // is no matching panel. LLFloaterIMPanel* findFloaterBySession(const LLUUID& session_id); + void onDropRequestReplyReceived(const LLUUID& session_id); + private: // create a panel and update internal representation for // consistency. Returns the pointer, caller (the class instance @@ -167,6 +169,8 @@ private: // An IM has been received that you haven't seen yet. BOOL mIMReceived; + + LLSD mSessionsDropRequested; }; diff --git a/linden/indra/newview/llinventoryactions.cpp b/linden/indra/newview/llinventoryactions.cpp index 6452c87..900a729 100644 --- a/linden/indra/newview/llinventoryactions.cpp +++ b/linden/indra/newview/llinventoryactions.cpp @@ -491,6 +491,23 @@ class LLSetSortBy : public inventory_listener_t } mPtr->getActivePanel()->setSortOrder( order ); } + else if (sort_field == "systemfolderstotop") + { + U32 order = mPtr->getActivePanel()->getSortOrder(); + if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ) + { + order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + + mPtr->getControl("Inventory.SystemFoldersToTop")->setValue( FALSE ); + } + else + { + order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + + mPtr->getControl("Inventory.SystemFoldersToTop")->setValue( TRUE ); + } + mPtr->getActivePanel()->setSortOrder( order ); + } return true; } diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp index 05334d7..a7b80ae 100644 --- a/linden/indra/newview/llinventorybridge.cpp +++ b/linden/indra/newview/llinventorybridge.cpp @@ -569,10 +569,10 @@ const char* safe_inv_type_lookup(LLInventoryType::EType inv_type) } LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, - LLInventoryType::EType inv_type, - LLInventoryPanel* inventory, - const LLUUID& uuid, - U32 flags) + LLInventoryType::EType inv_type, + LLInventoryPanel* inventory, + const LLUUID& uuid, + U32 flags) { LLInvFVBridge* new_listener = NULL; switch(asset_type) @@ -677,7 +677,11 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, break; } - new_listener->mInvType = inv_type; + if (new_listener) + { + new_listener->mInvType = inv_type; + } + return new_listener; } @@ -907,16 +911,20 @@ BOOL LLItemBridge::removeItem() if(!model) return FALSE; LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); LLViewerInventoryItem* item = getItem(); - if(item) + + // if item is not already in trash + if(item && !model->isObjectDescendentOf(mUUID, trash_id)) { - // restamp on move to trash. + // move to trash, and restamp LLInvFVBridge::changeItemParent(model, item, trash_id, TRUE); + // delete was successful + return TRUE; + } + else + { + // tried to delete already item in trash (should purge?) + return FALSE; } - - // return false anyway, so that if it's called from the folder - // view, it doesn't remove the view - it's just being moved to the - // trash. - return FALSE; } BOOL LLItemBridge::isItemCopyable() const @@ -1462,11 +1470,20 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask) { LLViewerInventoryCategory* category = gInventory.getCategory(mCatID); - if (category->getDescendentCount() == mContentsCount) + if (NULL == category) { - gInventory.removeObserver(this); - wear_inventory_category(category, FALSE, TRUE); - delete this; + llwarns << "gInventory.getCategory(" << mCatID + << ") was NULL" << llendl; + } + else + { + if (category->getDescendentCount() == + mContentsCount) + { + gInventory.removeObserver(this); + wear_inventory_category(category, FALSE, TRUE); + delete this; + } } } @@ -1682,11 +1699,7 @@ BOOL LLFolderBridge::removeItem() LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE); } - // return false anyway, so that if it's called from the folder - // view, it doesn't remove the view - it's just being moved to the - // trash. - return FALSE; - + return TRUE; } BOOL LLFolderBridge::isClipboardPasteable() const @@ -2178,10 +2191,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // everything in the active window so that we don't follow // the selection to its new location (which is very // annoying). - LLInventoryPanel* active_panel = LLInventoryView::getActiveInventory()->getPanel(); - if (mInventoryPanel != active_panel) + if (LLInventoryView::getActiveInventory()) { - active_panel->unSelectAll(); + LLInventoryPanel* active_panel = LLInventoryView::getActiveInventory()->getPanel(); + if (active_panel && (mInventoryPanel != active_panel)) + { + active_panel->unSelectAll(); + } } // restamp if the move is into the trash. @@ -3117,7 +3133,16 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model gMessageSystem->sendReliable( gAgent.getRegion()->getHost() ); } // this object might have been selected, so let the selection manager know it's gone now - gSelectMgr->remove(gObjectList.findObject(item->getUUID())); + LLViewerObject *found_obj = + gObjectList.findObject(item->getUUID()); + if (found_obj) + { + gSelectMgr->remove(found_obj); + } + else + { + llwarns << "object not found - ignoring" << llendl; + } } else LLItemBridge::performAction(folder, model, action); } @@ -4027,7 +4052,15 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata) gMessageSystem->sendReliable( gAgent.getRegion()->getHost() ); // this object might have been selected, so let the selection manager know it's gone now - gSelectMgr->remove(gObjectList.findObject( obj_item_array.get(i)->getUUID()) ); + LLViewerObject *found_obj = gObjectList.findObject( obj_item_array.get(i)->getUUID()); + if (found_obj) + { + gSelectMgr->remove(found_obj); + } + else + { + llwarns << "object not found, ignoring" << llendl; + } } } diff --git a/linden/indra/newview/llinventorybridge.h b/linden/indra/newview/llinventorybridge.h old mode 100755 new mode 100644 diff --git a/linden/indra/newview/llinventorymodel.cpp b/linden/indra/newview/llinventorymodel.cpp index ddd229b..8e95156 100644 --- a/linden/indra/newview/llinventorymodel.cpp +++ b/linden/indra/newview/llinventorymodel.cpp @@ -27,6 +27,7 @@ */ #include "llviewerprecompiledheaders.h" + #include "llinventorymodel.h" #include "llassetstorage.h" @@ -41,6 +42,7 @@ #include "llfocusmgr.h" #include "llinventoryview.h" #include "llviewerinventory.h" +#include "llviewermessage.h" #include "llviewerwindow.h" #include "viewer.h" #include "lldbstrings.h" @@ -2282,7 +2284,7 @@ void LLInventoryModel::processUseCachedInventory(LLMessageSystem* msg, void**) void LLInventoryModel::processUpdateCreateInventoryItem(LLMessageSystem* msg, void**) { // do accounting and highlight new items if they arrive - if (gInventory.messageUpdateCore(msg, true, true)) + if (gInventory.messageUpdateCore(msg, true)) { U32 callback_id; LLUUID item_id; @@ -2298,12 +2300,15 @@ void LLInventoryModel::processUpdateCreateInventoryItem(LLMessageSystem* msg, vo void LLInventoryModel::processFetchInventoryReply(LLMessageSystem* msg, void**) { // no accounting - gInventory.messageUpdateCore(msg, false, false); + gInventory.messageUpdateCore(msg, false); } -bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, bool highlight_new) +bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account) { + //make sure our added inventory observer is active -Gigs + start_new_inventory_observer(); + LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); if(agent_id != gAgent.getID()) @@ -2312,16 +2317,15 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, boo << llendl; return false; } - LLPointer lastitem; // hack item_array_t items; update_map_t update; S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData); bool all_one_folder = true; LLUUID folder_id; + // Does this loop ever execute more than once? -Gigs for(S32 i = 0; i < count; ++i) { LLPointer titem = new LLViewerInventoryItem; - lastitem = titem; titem->unpackMessage(msg, _PREHASH_InventoryData, i); lldebugs << "LLInventoryModel::messageUpdateCore() item id:" << titem->getUUID() << llendl; @@ -2359,6 +2363,7 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, boo } U32 changes = 0x0; + //as above, this loop never seems to loop more than once per call for (item_array_t::iterator it = items.begin(); it != items.end(); ++it) { changes |= gInventory.updateItem(*it); @@ -2366,88 +2371,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, boo gInventory.notifyObservers(); gViewerWindow->getWindow()->decBusyCount(); - // *HACK: Do the 'show' logic for a new item in the inventory if - // it is a newly created item. - if (highlight_new - && (changes & LLInventoryObserver::ADD) == LLInventoryObserver::ADD) - { - LLUUID trash_id; - trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH); - if(!gInventory.isObjectDescendentOf(lastitem->getUUID(), trash_id)) - { - LLMultiPreview* multi_previewp = LLMultiPreview::getAutoOpenInstance(folder_id); - if (!multi_previewp && all_one_folder && count > 1) - { - S32 left, top; - gFloaterView->getNewFloaterPosition(&left, &top); - - multi_previewp = new LLMultiPreview(LLRect(left, top, left + 300, top - 100)); - LLMultiPreview::setAutoOpenInstance(multi_previewp, folder_id); - } - - LLFloater::setFloaterHost(multi_previewp); - - bool show_keep_discard = lastitem->getPermissions().getCreator() != gAgent.getID(); - switch(lastitem->getType()) - { - case LLAssetType::AT_NOTECARD: - open_notecard( - lastitem->getUUID(), - LLString("Note: ") + lastitem->getName(), - show_keep_discard, - LLUUID::null, - FALSE); - break; - case LLAssetType::AT_LANDMARK: - open_landmark( - lastitem->getUUID(), - LLString(" ") + lastitem->getName(), - show_keep_discard, - LLUUID::null, - FALSE); - break; - case LLAssetType::AT_TEXTURE: - open_texture( - lastitem->getUUID(), - LLString("Texture: ") + lastitem->getName(), - show_keep_discard, - LLUUID::null, - FALSE); - break; - default: - break; - } - - LLFloater::setFloaterHost(NULL); - if (multi_previewp) - { - multi_previewp->open(); - } - - LLInventoryView* view = LLInventoryView::getActiveInventory(); - if(view) - { - LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); - BOOL inventory_has_focus = gFocusMgr.childHasKeyboardFocus(view); - BOOL user_is_away = gAwayTimer.getStarted(); - - // don't select lost and found items if an active user is working in the inventory - if (!gInventory.isObjectDescendentOf(lastitem->getUUID(), lost_and_found_id) || - !inventory_has_focus || - user_is_away) - { - LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); - LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback(); - view->getPanel()->setSelection(lastitem->getUUID(), TAKE_FOCUS_NO); - // HACK to open inventory offers that are - // accepted. This information really needs to - // flow through the instant messages and - // inventory restore keyboard focus - gFocusMgr.setKeyboardFocus(focus_ctrl, callback); - } - } - } - } return true; } @@ -3452,6 +3375,43 @@ void LLInventoryExistenceObserver::changed(U32 mask) } } +void LLInventoryAddedObserver::changed(U32 mask) +{ + if(!(mask & LLInventoryObserver::ADD)) + { + return; + } + + // *HACK: If this was in response to a packet off + // the network, figure out which item was updated. + // Code from Gigs Taggert, sin allowed by JC. + LLMessageSystem* msg = gMessageSystem; + const char* msg_name = msg->getMessageName(); + if (!msg_name) return; + + // We only want newly created inventory items. JC + if ( strcmp(msg_name, "UpdateCreateInventoryItem") ) + { + return; + } + + LLPointer titem = new LLViewerInventoryItem; + S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_InventoryData); + for(S32 i = 0; i < num_blocks; ++i) + { + titem->unpackMessage(msg, _PREHASH_InventoryData, i); + if (!(titem->getUUID().isNull())) + { + //we don't do anything with null keys + mAdded.push_back(titem->getUUID()); + } + } + if (!mAdded.empty()) + { + done(); + } +} + LLInventoryTransactionObserver::LLInventoryTransactionObserver( const LLTransactionID& transaction_id) : mTransactionID(transaction_id) diff --git a/linden/indra/newview/llinventorymodel.h b/linden/indra/newview/llinventorymodel.h index 9867842..78ab0e3 100644 --- a/linden/indra/newview/llinventorymodel.h +++ b/linden/indra/newview/llinventorymodel.h @@ -29,10 +29,8 @@ #ifndef LL_LLINVENTORYMODEL_H #define LL_LLINVENTORYMODEL_H -#include "llassetstorage.h" +#include "llassettype.h" #include "lldarray.h" -//#include "llskiplist.h" -//#include "llptrskipmap.h" #include "lluuid.h" #include "llpermissionsflags.h" #include "llstring.h" @@ -387,7 +385,7 @@ protected: static void processMoveInventoryItem(LLMessageSystem* msg, void**); static void processFetchInventoryReply(LLMessageSystem* msg, void**); - bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting, bool highlight_new); + bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting); protected: // Varaibles used to track what has changed since the last notify. @@ -751,6 +749,29 @@ protected: }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLInventoryAddedObserver +// +// This class is used as a base class for doing something when +// a new item arrives in inventory. +// It does not watch for a certain UUID, rather it acts when anything is added +// Derive a class from this class and implement the done() method to do +// something useful. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLInventoryAddedObserver : public LLInventoryObserver +{ +public: + LLInventoryAddedObserver() : mAdded() {} + virtual void changed(U32 mask); + +protected: + virtual void done() = 0; + + typedef std::vector item_ref_t; + item_ref_t mAdded; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInventoryTransactionObserver // // Class which can be used as a base class for doing something when an diff --git a/linden/indra/newview/llinventoryview.cpp b/linden/indra/newview/llinventoryview.cpp index 900b145..bb70ea4 100644 --- a/linden/indra/newview/llinventoryview.cpp +++ b/linden/indra/newview/llinventoryview.cpp @@ -451,11 +451,13 @@ void LLInventoryView::init(LLInventoryModel* inventory) U32 sort_order = gSavedSettings.getU32("InventorySortOrder"); BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE ); BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME ); + BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ); addBoolControl("Inventory.ShowFilters", FALSE); addBoolControl("Inventory.SortByName", sort_by_name ); addBoolControl("Inventory.SortByDate", ! sort_by_name ); addBoolControl("Inventory.FoldersAlwaysByName", sort_folders_by_name ); + addBoolControl("Inventory.SystemFoldersToTop", sort_system_folders_to_top ); mSavedFolderState = new LLSaveFolderState(); mSavedFolderState->setApply(FALSE); @@ -637,20 +639,24 @@ void LLInventoryView::onClose(bool app_quitting) BOOL LLInventoryView::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) { LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL; - // first check for user accepting current search results - if (!called_from_parent && root_folder&& - mSearchEditor && mSearchEditor->hasFocus() && - (key == KEY_RETURN || key == KEY_DOWN) && mask == MASK_NONE) - { - // move focus to inventory proper - root_folder->setFocus(TRUE); - root_folder->scrollToShowSelection(); - return TRUE; - } - - if (root_folder->hasFocus() && key == KEY_UP) + if (root_folder) { - startSearch(); + // first check for user accepting current search results + if (!called_from_parent + && mSearchEditor && mSearchEditor->hasFocus() + && (key == KEY_RETURN || key == KEY_DOWN) + && mask == MASK_NONE) + { + // move focus to inventory proper + root_folder->setFocus(TRUE); + root_folder->scrollToShowSelection(); + return TRUE; + } + + if (root_folder->hasFocus() && key == KEY_UP) + { + startSearch(); + } } return LLFloater::handleKeyHere(key, mask, called_from_parent); @@ -1364,11 +1370,13 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) S32 count; if (objectp) - { - if (objectp->getType() == LLAssetType::AT_NONE) + { + if (objectp->getType() <= LLAssetType::AT_NONE || + objectp->getType() >= LLAssetType::AT_COUNT) { - llwarns << "LLInventoryPanel::buildNewViews called with objectp->mType == AT_NONE (shouldn't happen)" << llendl; - itemp = NULL; + llwarns << "LLInventoryPanel::buildNewViews called with objectp->mType == " + << ((S32) objectp->getType()) + << " (shouldn't happen)" << llendl; } else if (objectp->getType() == LLAssetType::AT_CATEGORY) // build new view for category { @@ -1377,19 +1385,16 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) this, objectp->getUUID()); - LLFolderViewFolder* folderp = new LLFolderViewFolder(new_listener->getDisplayName(), - new_listener->getIcon(), - mFolders, - new_listener); - if (!(mFolders->getSortOrder() & LLInventoryFilter::SO_DATE)) - { - folderp->setItemSortFunction(sort_item_name); - } - else + if (new_listener) { - folderp->setItemSortFunction(sort_item_date); + LLFolderViewFolder* folderp = new LLFolderViewFolder(new_listener->getDisplayName(), + new_listener->getIcon(), + mFolders, + new_listener); + + folderp->setItemSortOrder(mFolders->getSortOrder()); + itemp = folderp; } - itemp = folderp; } else // build new view for item { @@ -1400,11 +1405,14 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) this, item->getUUID(), item->getFlags()); - itemp = new LLFolderViewItem(new_listener->getDisplayName(), - new_listener->getIcon(), - new_listener->getCreationDate(), - mFolders, - new_listener); + if (new_listener) + { + itemp = new LLFolderViewItem(new_listener->getDisplayName(), + new_listener->getIcon(), + new_listener->getCreationDate(), + mFolders, + new_listener); + } } LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(objectp->getParentUUID()); diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp index 35774cb..2105521 100644 --- a/linden/indra/newview/llnetmap.cpp +++ b/linden/indra/newview/llnetmap.cpp @@ -103,7 +103,7 @@ LLNetMap::LLNetMap( LLRect major_dir_rect( 0, DIR_HEIGHT, DIR_WIDTH, 0 ); mTextBoxNorth = new LLTextBox( "N", major_dir_rect ); - mTextBoxNorth->setDropshadowVisible( TRUE ); + mTextBoxNorth->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); addChild( mTextBoxNorth ); LLColor4 minor_color( 1.f, 1.f, 1.f, .7f ); diff --git a/linden/indra/newview/llpanelavatar.cpp b/linden/indra/newview/llpanelavatar.cpp index fd25775..9c73dad 100644 --- a/linden/indra/newview/llpanelavatar.cpp +++ b/linden/indra/newview/llpanelavatar.cpp @@ -1522,40 +1522,43 @@ void LLPanelAvatar::resetGroupList() { return; } - LLScrollListCtrl* group_list = LLUICtrlFactory::getScrollListByName(mPanelSecondLife,"groups"); - if (mPanelSecondLife && group_list) + if (mPanelSecondLife) { - group_list->deleteAllItems(); - - S32 count = gAgent.mGroups.count(); - LLUUID id; - - for(S32 i = 0; i < count; ++i) + LLScrollListCtrl* group_list = LLUICtrlFactory::getScrollListByName(mPanelSecondLife,"groups"); + if (group_list) { - LLGroupData group_data = gAgent.mGroups.get(i); - id = group_data.mID; - std::string group_string; - /* Show group title? DUMMY_POWER for Don Grep - if(group_data.mOfficer) - { - group_string = "Officer of "; - } - else + group_list->deleteAllItems(); + + S32 count = gAgent.mGroups.count(); + LLUUID id; + + for(S32 i = 0; i < count; ++i) { - group_string = "Member of "; - } - */ + LLGroupData group_data = gAgent.mGroups.get(i); + id = group_data.mID; + std::string group_string; + /* Show group title? DUMMY_POWER for Don Grep + if(group_data.mOfficer) + { + group_string = "Officer of "; + } + else + { + group_string = "Member of "; + } + */ + + group_string += group_data.mName; - group_string += group_data.mName; - - LLSD row; - row["columns"][0]["value"] = group_string; - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - row["columns"][0]["width"] = 0; - group_list->addElement(row); + LLSD row; + row["columns"][0]["value"] = group_string; + row["columns"][0]["font"] = "SANSSERIF_SMALL"; + row["columns"][0]["width"] = 0; + group_list->addElement(row); + } + group_list->sortByColumn(0, TRUE); } - group_list->sortByColumn(0, TRUE); } } diff --git a/linden/indra/newview/llpanelcontents.cpp b/linden/indra/newview/llpanelcontents.cpp index 2265ed5..4d138d4 100644 --- a/linden/indra/newview/llpanelcontents.cpp +++ b/linden/indra/newview/llpanelcontents.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llpanelcontents.cpp * @brief Object contents panel in the tools floater. * @@ -101,21 +101,25 @@ LLPanelContents::~LLPanelContents() void LLPanelContents::getState(LLViewerObject *objectp ) { if( !objectp ) - { + { childSetEnabled("button new script",FALSE); //mBtnNewScript->setEnabled( FALSE ); return; } + LLUUID group_id; // used for SL-23488 + gSelectMgr->selectGetGroup(group_id); // sets group_id as a side effect SL-23488 + // BUG? Check for all objects being editable? - BOOL editable = gAgent.isGodlike() - || (objectp->permModify() && objectp->permYouOwner()); + BOOL editable = gAgent.isGodlike() + || (objectp->permModify() + && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488 BOOL all_volume = gSelectMgr->selectionAllPCode( LL_PCODE_VOLUME ); // Edit script button - ok if object is editable and there's an // unambiguous destination for the object. - if( editable && - all_volume && + if( editable && + all_volume && ((gSelectMgr->getSelection()->getRootObjectCount() == 1) || (gSelectMgr->getSelection()->getObjectCount() == 1))) { diff --git a/linden/indra/newview/llpaneldisplay.cpp b/linden/indra/newview/llpaneldisplay.cpp index d22d1c2..d79dcb4 100644 --- a/linden/indra/newview/llpaneldisplay.cpp +++ b/linden/indra/newview/llpaneldisplay.cpp @@ -448,7 +448,6 @@ LLPanelDisplay2::LLPanelDisplay2() BOOL LLPanelDisplay2::postBuild() { - requires("ani", WIDGET_TYPE_CHECKBOX); requires("gamma", WIDGET_TYPE_SPINNER); requires("vbo", WIDGET_TYPE_CHECKBOX); @@ -466,6 +465,14 @@ BOOL LLPanelDisplay2::postBuild() // Graphics Card Memory mRadioVideoCardMem = LLUICtrlFactory::getRadioGroupByName(this, "video card memory radio"); +#if !LL_WINDOWS + // The probe_hardware_checkbox setting is only used in the Windows build + // (It apparently controls a time-consuming DX9 hardware probe.) + // Disable the checkbox everywhere else + gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE ); + childSetEnabled("probe_hardware_checkbox", false); +#endif // !LL_WINDOWS + refresh(); return TRUE; @@ -490,7 +497,8 @@ void LLPanelDisplay2::refresh() mParticleCount = gSavedSettings.getS32("RenderMaxPartCount"); mCompositeLimit = gSavedSettings.getS32("AvatarCompositeLimit"); mDebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth"); - + mProbeHardwareOnStartup = gSavedSettings.getBOOL("ProbeHardwareOnStartup"); + refreshEnabledState(); } @@ -521,7 +529,6 @@ void LLPanelDisplay2::apply() gViewerWindow->restartDisplay(logged_in); } - refresh(); } @@ -537,6 +544,7 @@ void LLPanelDisplay2::cancel() gSavedSettings.setS32("RenderMaxPartCount", mParticleCount); gSavedSettings.setS32("AvatarCompositeLimit", mCompositeLimit); gSavedSettings.setS32("DebugBeaconLineWidth", mDebugBeaconLineWidth); + gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup ); } //============================================================================ diff --git a/linden/indra/newview/llpaneldisplay.h b/linden/indra/newview/llpaneldisplay.h index b4db723..80aae66 100644 --- a/linden/indra/newview/llpaneldisplay.h +++ b/linden/indra/newview/llpaneldisplay.h @@ -102,7 +102,7 @@ protected: S32 mParticleCount; S32 mCompositeLimit; S32 mDebugBeaconLineWidth; - + BOOL mProbeHardwareOnStartup; }; class LLPanelDisplay3 : public LLPanel @@ -147,7 +147,6 @@ protected: F32 mFlexLOD; F32 mTreeLOD; F32 mAvatarLOD; - }; const S32 LL_MAX_VRAM_INDEX = 6; diff --git a/linden/indra/newview/llpanelface.cpp b/linden/indra/newview/llpanelface.cpp index 8f24c55..9cbfdc2 100644 --- a/linden/indra/newview/llpanelface.cpp +++ b/linden/indra/newview/llpanelface.cpp @@ -505,7 +505,16 @@ void LLPanelFace::getState() { F32 shinyf = 0.f; identical = allFacesSameValue( &LLPanelFace::valueShiny, &shinyf ); - childGetSelectionInterface("combobox shininess")->selectNthItem((S32)shinyf); + LLCtrlSelectionInterface* combobox_shininess = + childGetSelectionInterface("combobox shininess"); + if (combobox_shininess) + { + combobox_shininess->selectNthItem((S32)shinyf); + } + else + { + llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl; + } childSetEnabled("combobox shininess",editable); childSetTentative("combobox shininess",!identical); childSetEnabled("label shininess",editable); @@ -514,7 +523,16 @@ void LLPanelFace::getState() { F32 bumpf = 0.f; identical = allFacesSameValue( &LLPanelFace::valueBump, &bumpf ); - childGetSelectionInterface("combobox bumpiness")->selectNthItem((S32)bumpf); + LLCtrlSelectionInterface* combobox_bumpiness = + childGetSelectionInterface("combobox bumpiness"); + if (combobox_bumpiness) + { + combobox_bumpiness->selectNthItem((S32)bumpf); + } + else + { + llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl; + } childSetEnabled("combobox bumpiness",editable); childSetTentative("combobox bumpiness",!identical); childSetEnabled("label bumpiness",editable); @@ -523,8 +541,17 @@ void LLPanelFace::getState() { F32 genf = 0.f; identical = allFacesSameValue( &LLPanelFace::valueTexGen, &genf); - S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT; - childGetSelectionInterface("combobox texgen")->selectNthItem(selected_texgen); + S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT; + LLCtrlSelectionInterface* combobox_texgen = + childGetSelectionInterface("combobox texgen"); + if (combobox_texgen) + { + combobox_texgen->selectNthItem(selected_texgen); + } + else + { + llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl; + } childSetEnabled("combobox texgen",editable); childSetTentative("combobox texgen",!identical); childSetEnabled("tex gen",editable); diff --git a/linden/indra/newview/llpanelgeneral.cpp b/linden/indra/newview/llpanelgeneral.cpp index 900598a..d60471d 100644 --- a/linden/indra/newview/llpanelgeneral.cpp +++ b/linden/indra/newview/llpanelgeneral.cpp @@ -105,7 +105,6 @@ BOOL LLPanelGeneral::postBuild() requires("rotate_mini_map_checkbox", WIDGET_TYPE_CHECKBOX); requires("friends_online_notify_checkbox", WIDGET_TYPE_CHECKBOX); requires("notify_money_change_checkbox", WIDGET_TYPE_CHECKBOX); - requires("probe_hardware_checkbox", WIDGET_TYPE_CHECKBOX); requires("use_system_color_picker_checkbox", WIDGET_TYPE_CHECKBOX); requires("crash_behavior_combobox", WIDGET_TYPE_COMBO_BOX); @@ -152,14 +151,6 @@ BOOL LLPanelGeneral::postBuild() childSetCommitCallback("language_combobox", set_language ); childSetValue("language_combobox", gSavedSettings.getString("Language")); - -#if !LL_WINDOWS - // The probe_hardware_checkbox setting is only used in the Windows build - // (It apparently controls a time-consuming DX9 hardware probe.) - // Disable the checkbox everywhere else - gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE ); - childSetEnabled("probe_hardware_checkbox", false); -#endif // !LL_WINDOWS refresh(); @@ -205,7 +196,7 @@ void LLPanelGeneral::refresh() mAFKTimeout = gSavedSettings.getF32("AFKTimeout"); mMiniMapRotate = gSavedSettings.getBOOL("MiniMapRotate"); mNotifyMoney = gSavedSettings.getBOOL("NotifyMoneyChange"); - mProbeHardwareOnStartup = gSavedSettings.getBOOL("ProbeHardwareOnStartup"); + mShowNewInventory = gSavedSettings.getBOOL("ShowNewInventory"); mUseDefaultColor = gSavedSettings.getBOOL("UseDefaultColorPicker"); mEffectColor = gSavedSettings.getColor4("EffectColor"); @@ -226,7 +217,7 @@ void LLPanelGeneral::cancel() gSavedSettings.setF32("AFKTimeout", mAFKTimeout ); gSavedSettings.setBOOL("MiniMapRotate", mMiniMapRotate ); gSavedSettings.setBOOL("NotifyMoneyChange", mNotifyMoney ); - gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup ); + gSavedSettings.setBOOL("ShowNewInventory", mShowNewInventory); gSavedSettings.setBOOL("UseDefaultColorPicker", mUseDefaultColor ); gSavedSettings.setColor4("EffectColor", mEffectColor ); gSavedSettings.setString("Language", mLanguage); diff --git a/linden/indra/newview/llpanelgeneral.h b/linden/indra/newview/llpanelgeneral.h index 9f70560..fe4ff4e 100644 --- a/linden/indra/newview/llpanelgeneral.h +++ b/linden/indra/newview/llpanelgeneral.h @@ -61,7 +61,7 @@ protected: BOOL mChatOnlineNotification; F32 mAFKTimeout; BOOL mNotifyMoney; - BOOL mProbeHardwareOnStartup; + BOOL mShowNewInventory; BOOL mUseDefaultColor; LLColor4 mEffectColor; BOOL mMiniMapRotate; diff --git a/linden/indra/newview/llpanelgroup.cpp b/linden/indra/newview/llpanelgroup.cpp index 6710c43..47dacf3 100644 --- a/linden/indra/newview/llpanelgroup.cpp +++ b/linden/indra/newview/llpanelgroup.cpp @@ -660,7 +660,7 @@ void LLPanelGroup::showNotice(const char* subject, // We need to clean up that inventory offer. if (inventory_offer) { - inventory_offer_callback( 1 , inventory_offer); + inventory_offer_callback( IOR_DECLINE , inventory_offer); } return; } diff --git a/linden/indra/newview/llpanelgroupgeneral.cpp b/linden/indra/newview/llpanelgroupgeneral.cpp index 67a0c31..5ec9651 100644 --- a/linden/indra/newview/llpanelgroupgeneral.cpp +++ b/linden/indra/newview/llpanelgroupgeneral.cpp @@ -45,10 +45,10 @@ #include "llnamebox.h" #include "llnamelistctrl.h" #include "llspinctrl.h" +#include "llstatusbar.h" // can_afford_transaction() #include "lltextbox.h" #include "lltexteditor.h" #include "lltexturectrl.h" -#include "llviewermessage.h" #include "llviewerwindow.h" // static @@ -322,19 +322,27 @@ void LLPanelGroupGeneral::onClickJoin(void *userdata) LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(self->mGroupID); - S32 cost = gdatap->mMembershipFee; - LLString::format_map_t args; - args["[COST]"] = llformat("%d", cost); - - if (can_afford_transaction(cost)) + if (gdatap) { - gViewerWindow->alertXml("JoinGroupCanAfford", args, - LLPanelGroupGeneral::joinDlgCB, - self); + S32 cost = gdatap->mMembershipFee; + LLString::format_map_t args; + args["[COST]"] = llformat("%d", cost); + + if (can_afford_transaction(cost)) + { + gViewerWindow->alertXml("JoinGroupCanAfford", args, + LLPanelGroupGeneral::joinDlgCB, + self); + } + else + { + gViewerWindow->alertXml("JoinGroupCannotAfford", args); + } } else { - gViewerWindow->alertXml("JoinGroupCannotAfford", args); + llwarns << "gGroupMgr->getGroupData(" << self->mGroupID + << ") was NULL" << llendl; } } diff --git a/linden/indra/newview/llpanelgroupnotices.cpp b/linden/indra/newview/llpanelgroupnotices.cpp index 373f3f2..a001455 100644 --- a/linden/indra/newview/llpanelgroupnotices.cpp +++ b/linden/indra/newview/llpanelgroupnotices.cpp @@ -204,7 +204,7 @@ LLPanelGroupNotices::~LLPanelGroupNotices() if (mInventoryOffer) { // Cancel the inventory offer. - inventory_offer_callback( 1 , mInventoryOffer); + inventory_offer_callback( IOR_DECLINE , mInventoryOffer); mInventoryOffer = NULL; } } @@ -359,7 +359,7 @@ void LLPanelGroupNotices::onClickOpenAttachment(void* data) { LLPanelGroupNotices* self = (LLPanelGroupNotices*)data; - inventory_offer_callback( 0 , self->mInventoryOffer); + inventory_offer_callback( IOR_ACCEPT , self->mInventoryOffer); self->mInventoryOffer = NULL; self->mBtnOpenAttachment->setEnabled(FALSE); } @@ -398,7 +398,7 @@ void LLPanelGroupNotices::onClickNewMessage(void* data) if (self->mInventoryOffer) { - inventory_offer_callback( 1 , self->mInventoryOffer); + inventory_offer_callback( IOR_DECLINE , self->mInventoryOffer); self->mInventoryOffer = NULL; } @@ -548,7 +548,7 @@ void LLPanelGroupNotices::showNotice(const char* subject, if (mInventoryOffer) { // Cancel the inventory offer for the previously viewed notice - inventory_offer_callback( 1 , mInventoryOffer); + inventory_offer_callback( IOR_DECLINE , mInventoryOffer); mInventoryOffer = NULL; } diff --git a/linden/indra/newview/llpanelgrouproles.cpp b/linden/indra/newview/llpanelgrouproles.cpp index 266ff12..5765a12 100644 --- a/linden/indra/newview/llpanelgrouproles.cpp +++ b/linden/indra/newview/llpanelgrouproles.cpp @@ -1323,13 +1323,17 @@ void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data) LLCheckBoxCtrl* check_box = static_cast(ctrl); if (!check_box || !self) return; - - LLUUID role_id = self->mAssignedRolesList->getFirstSelected()->getUUID(); - LLRoleMemberChangeType change_type = (check_box->get() ? - RMC_ADD : - RMC_REMOVE); - - self->handleRoleCheck(role_id, change_type); + LLScrollListItem* first_selected = + self->mAssignedRolesList->getFirstSelected(); + if (first_selected) + { + LLUUID role_id = first_selected->getUUID(); + LLRoleMemberChangeType change_type = (check_box->get() ? + RMC_ADD : + RMC_REMOVE); + + self->handleRoleCheck(role_id, change_type); + } } void LLPanelGroupMembersSubTab::handleMemberDoubleClick() @@ -2056,8 +2060,9 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) } if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc) - && gdatap->isMemberDataComplete() - && gdatap->isRoleMemberDataComplete()) + && gdatap + && gdatap->isMemberDataComplete() + && gdatap->isRoleMemberDataComplete()) { buildMembersList(); } diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp index 2089a6c..13cee05 100644 --- a/linden/indra/newview/llpanelinventory.cpp +++ b/linden/indra/newview/llpanelinventory.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llpanelinventory.cpp * @brief LLPanelInventory class implementation * @@ -72,7 +72,7 @@ #include "llviewerregion.h" #include "llviewerimagelist.h" #include "llviewerinventory.h" -#include "llviewermessage.h" +#include "llviewermessage.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerwindow.h" @@ -197,7 +197,7 @@ struct LLBuyInvItemData LLUUID mTaskID; LLUUID mItemID; LLAssetType::EType mType; - + LLBuyInvItemData(const LLUUID& task, const LLUUID& item, LLAssetType::EType type) : @@ -217,34 +217,45 @@ void LLTaskInvFVBridge::buyItem() const LLSaleInfo& sale_info = item->getSaleInfo(); const LLPermissions& perm = item->getPermissions(); const LLString owner_name; // no owner name currently... FIXME? - - LLString::format_map_t args; - args["[PRICE]"] = llformat("%d",sale_info.getSalePrice()); - args["[OWNER]"] = owner_name; - if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS) - { - U32 next_owner_mask = perm.getMaskNextOwner(); - args["[MODIFYPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo"); - args["[COPYPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo"); - args["[RESELLPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo"); - } - LLString alertdesc; - switch(sale_info.getSaleType()) + LLViewerObject* obj; + if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() ) { - case LLSaleInfo::FS_ORIGINAL: - alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal"; - break; - case LLSaleInfo::FS_COPY: - default: - alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy"; - break; - case LLSaleInfo::FS_CONTENTS: - alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents"; - break; + gViewerWindow->alertXml("Cannot_Purchase_an_Attachment"); + llinfos << "Attempt to purchase an attachment" << llendl; } - - gViewerWindow->alertXml(alertdesc, args, LLTaskInvFVBridge::commitBuyItem, (void*)inv); + else + { + + + LLString::format_map_t args; + args["[PRICE]"] = llformat("%d",sale_info.getSalePrice()); + args["[OWNER]"] = owner_name; + if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS) + { + U32 next_owner_mask = perm.getMaskNextOwner(); + args["[MODIFYPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo"); + args["[COPYPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo"); + args["[RESELLPERM]"] = LLAlertDialog::getTemplateMessage((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo"); + } + + LLString alertdesc; + switch(sale_info.getSaleType()) + { + case LLSaleInfo::FS_ORIGINAL: + alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal"; + break; + case LLSaleInfo::FS_COPY: + default: + alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy"; + break; + case LLSaleInfo::FS_CONTENTS: + alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents"; + break; + } + + gViewerWindow->alertXml(alertdesc, args, LLTaskInvFVBridge::commitBuyItem, (void*)inv); + } } S32 LLTaskInvFVBridge::getPrice() @@ -269,7 +280,7 @@ void LLTaskInvFVBridge::commitBuyItem(S32 option, void* data) { LLViewerObject* object = gObjectList.findObject(inv->mTaskID); if(!object || !object->getRegion()) return; - + LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_BuyObjectInventory); @@ -289,12 +300,12 @@ void LLTaskInvFVBridge::commitBuyItem(S32 option, void* data) const LLString& LLTaskInvFVBridge::getName() const { return mName; -} +} const LLString& LLTaskInvFVBridge::getDisplayName() const { LLInventoryItem* item = findItem(); - if(item) + if(item) { mDisplayName.assign(item->getName()); @@ -316,9 +327,9 @@ const LLString& LLTaskInvFVBridge::getDisplayName() const mDisplayName.append(" (no transfer)"); } } - + return mDisplayName; -} +} // BUG: No creation dates for task inventory U32 LLTaskInvFVBridge::getCreationDate() const @@ -444,7 +455,7 @@ BOOL LLTaskInvFVBridge::removeItem() { // just do it. object->removeInventory(mUUID); - return TRUE; + return TRUE; } else { @@ -542,20 +553,20 @@ BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID))) { const LLPermissions& perm = inv->getPermissions(); - bool can_copy = gAgent.allowOperation(PERM_COPY, perm, + bool can_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); if (object->isAttachment() && !can_copy) - { + { //RN: no copy contents of attachments cannot be dragged out // due to a race condition and possible exploit where // attached objects do not update their inventory items - // when their contents are manipulated - return FALSE; - } + // when their contents are manipulated + return FALSE; + } if((can_copy && perm.allowTransferTo(gAgent.getID())) || object->permYouOwner()) // || gAgent.isGodlike()) - + { *type = LLAssetType::lookupDragAndDropType(inv->getType()); @@ -621,7 +632,7 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) std::vector items; std::vector disabled_items; - if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(), + if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(), GP_OBJECT_MANIPULATE) && item->getSaleInfo().isForSale()) { @@ -755,12 +766,12 @@ BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID))) { const LLPermissions& perm = inv->getPermissions(); - bool can_copy = gAgent.allowOperation(PERM_COPY, perm, + bool can_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); if((can_copy && perm.allowTransferTo(gAgent.getID())) || object->permYouOwner()) // || gAgent.isGodlike()) - + { *type = LLAssetType::lookupDragAndDropType(inv->getType()); @@ -776,7 +787,7 @@ BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data) -{ +{ //llinfos << "LLTaskCategoryBridge::dragOrDrop()" << llendl; BOOL accept = FALSE; LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); @@ -1060,7 +1071,7 @@ LLTaskLandmarkBridge::LLTaskLandmarkBridge( LLTaskInvFVBridge(panel, uuid, name) { } - + LLViewerImage* LLTaskLandmarkBridge::getIcon() const { return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, 0, FALSE); @@ -1091,7 +1102,7 @@ LLTaskCallingCardBridge::LLTaskCallingCardBridge( LLTaskInvFVBridge(panel, uuid, name) { } - + LLViewerImage* LLTaskCallingCardBridge::getIcon() const { return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, 0, FALSE); @@ -1476,7 +1487,7 @@ LLTaskWearableBridge::LLTaskWearableBridge( mAssetType( asset_type ) { } - + LLViewerImage* LLTaskWearableBridge::getIcon() const { return get_item_icon(mAssetType, LLInventoryType::IT_WEARABLE, mFlags, FALSE ); @@ -1648,7 +1659,7 @@ void LLPanelInventory::inventoryChanged(LLViewerObject* object, { if(!object) return; - //llinfos << "invetnory arrived: \n" + //llinfos << "invetnory arrived: \n" // << " panel UUID: " << panel->mTaskUUID << "\n" // << " task UUID: " << object->mID << llendl; if(mTaskUUID == object->mID) @@ -1686,7 +1697,7 @@ void LLPanelInventory::inventoryChanged(LLViewerObject* object, void LLPanelInventory::updateInventory() { - //llinfos << "inventory arrived: \n" + //llinfos << "inventory arrived: \n" // << " panel UUID: " << panel->mTaskUUID << "\n" // << " task UUID: " << object->mID << llendl; // We're still interested in this task's inventory. @@ -1865,7 +1876,7 @@ void LLPanelInventory::refresh() // Otherwise we show the old stuff until the update comes in clearContents(); - // Register for updates from this object, + // Register for updates from this object, registerVOInventoryListener(object,NULL); } @@ -1978,7 +1989,7 @@ BOOL LLPanelInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDr } } -//static +//static void LLPanelInventory::idle(void* user_data) { LLPanelInventory* self = (LLPanelInventory*)user_data; diff --git a/linden/indra/newview/llpanelmsgs.cpp b/linden/indra/newview/llpanelmsgs.cpp index f25d477..3f5314c 100644 --- a/linden/indra/newview/llpanelmsgs.cpp +++ b/linden/indra/newview/llpanelmsgs.cpp @@ -88,14 +88,33 @@ void LLPanelMsgs::buildLists() row["columns"][1]["font"] = "SANSSERIF_SMALL"; row["columns"][1]["width"] = 160; } - item = mDisabledPopups->addElement(row, ADD_SORTED); + if (mDisabledPopups) + { + item = mDisabledPopups->addElement(row, + ADD_SORTED); + } + else + { + llwarns << "(ignore) but also (!mDisabledPopups)" << llendl; + } } else { - item = mEnabledPopups->addElement(row, ADD_SORTED); + if (mEnabledPopups) + { + item = mEnabledPopups->addElement(row, + ADD_SORTED); + } + else + { + llwarns << "(!ignore) but also (!mEnabledPopups)" << llendl; + } } - item->setUserdata((void*)&iter->first); + if (item) + { + item->setUserdata((void*)&iter->first); + } } } diff --git a/linden/indra/newview/llpanelpermissions.cpp b/linden/indra/newview/llpanelpermissions.cpp index 18ec28e..6e8a4ff 100644 --- a/linden/indra/newview/llpanelpermissions.cpp +++ b/linden/indra/newview/llpanelpermissions.cpp @@ -726,14 +726,17 @@ void LLPanelPermissions::refresh() LLSaleInfo::EForSale sale_type = sale_info.getSaleType(); LLRadioGroup* RadioSaleType = gUICtrlFactory->getRadioGroupByName(this,"sale type"); - if(RadioSaleType && valid_sale_info) + if(RadioSaleType) { - RadioSaleType->setSelectedIndex((S32)sale_type - 1); - } - else - { - // default option is sell copy, determined to be safest - RadioSaleType->setSelectedIndex((S32)LLSaleInfo::FS_COPY - 1); + if (valid_sale_info) + { + RadioSaleType->setSelectedIndex((S32)sale_type - 1); + } + else + { + // default option is sell copy, determined to be safest + RadioSaleType->setSelectedIndex((S32)LLSaleInfo::FS_COPY - 1); + } } if (is_for_sale) diff --git a/linden/indra/newview/llpatchvertexarray.cpp b/linden/indra/newview/llpatchvertexarray.cpp index bfd4ff4..611ff97 100644 --- a/linden/indra/newview/llpatchvertexarray.cpp +++ b/linden/indra/newview/llpatchvertexarray.cpp @@ -126,8 +126,16 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p mRenderStridep = new U32 [mPatchOrder + 1]; } + if (NULL == mRenderLevelp || NULL == mRenderStridep) + { + // init() and some other things all want to deref these + // pointers, so this is serious. + llerrs << "mRenderLevelp or mRenderStridep was NULL; we'd crash soon." << llendl; + return; + } - // Now that we've allocated memory, we can initialize the arrays... + // Now that we've allocated memory, we can initialize + // the arrays... init(); } diff --git a/linden/indra/newview/llpolymesh.cpp b/linden/indra/newview/llpolymesh.cpp index cf94142..1edb8f5 100644 --- a/linden/indra/newview/llpolymesh.cpp +++ b/linden/indra/newview/llpolymesh.cpp @@ -301,6 +301,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 1) { llerrs << "can't read HasWeights flag from " << fileName << llendl; + return FALSE; } if (!isLOD()) { @@ -315,6 +316,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 1) { llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl; + return FALSE; } //---------------------------------------------------------------- @@ -326,6 +328,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 3) { llerrs << "can't read Position from " << fileName << llendl; + return FALSE; } setPosition( position ); @@ -338,6 +341,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 3) { llerrs << "can't read RotationAngles from " << fileName << llendl; + return FALSE; } U8 rotationOrder; @@ -346,6 +350,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 1) { llerrs << "can't read RotationOrder from " << fileName << llendl; + return FALSE; } rotationOrder = 0; @@ -364,6 +369,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 3) { llerrs << "can't read Scale from " << fileName << llendl; + return FALSE; } setScale( scale ); @@ -384,6 +390,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 1) { llerrs << "can't read NumVertices from " << fileName << llendl; + return FALSE; } allocateVertexData( numVertices ); @@ -396,6 +403,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != numVertices) { llerrs << "can't read Coordinates from " << fileName << llendl; + return FALSE; } //---------------------------------------------------------------- @@ -406,6 +414,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != numVertices) { llerrs << " can't read Normals from " << fileName << llendl; + return FALSE; } //---------------------------------------------------------------- @@ -416,6 +425,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != numVertices) { llerrs << " can't read Binormals from " << fileName << llendl; + return FALSE; } @@ -427,6 +437,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != numVertices) { llerrs << "can't read TexCoords from " << fileName << llendl; + return FALSE; } //---------------------------------------------------------------- @@ -439,6 +450,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != numVertices) { llerrs << "can't read DetailTexCoords from " << fileName << llendl; + return FALSE; } } @@ -452,6 +464,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != numVertices) { llerrs << "can't read Weights from " << fileName << llendl; + return FALSE; } } } @@ -465,6 +478,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 1) { llerrs << "can't read NumFaces from " << fileName << llendl; + return FALSE; } allocateFaceData( numFaces ); @@ -482,6 +496,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 3) { llerrs << "can't read Face[" << i << "] from " << fileName << llendl; + return FALSE; } if (mReferenceData) { @@ -538,6 +553,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) if (numRead != 1) { llerrs << "can't read NumSkinJoints from " << fileName << llendl; + return FALSE; } allocateJointNames( numSkinJoints ); } @@ -547,11 +563,13 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) //---------------------------------------------------------------- for (i=0; i < numSkinJoints; i++) { - char jointName[64]; /*Flawfinder: ignore*/ - numRead = fread(jointName, sizeof(jointName), 1, fp); + char jointName[64+1]; + numRead = fread(jointName, sizeof(jointName)-1, 1, fp); + jointName[sizeof(jointName)-1] = '\0'; // ensure nul-termination if (numRead != 1) { llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl; + return FALSE; } std::string *jn = &mJointNames[i]; @@ -561,7 +579,8 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) //------------------------------------------------------------------------- // look for morph section //------------------------------------------------------------------------- - char morphName[64]; /*Flawfinder: ignore*/ + char morphName[64+1]; + morphName[sizeof(morphName)-1] = '\0'; // ensure nul-termination while(fread(&morphName, sizeof(char), 64, fp) == 64) { if (!strcmp(morphName, "End Morphs")) @@ -991,6 +1010,13 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node) LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton"); + if (NULL == skeletalParam) + { + llwarns << "Failed to getChildByName(\"param_skeleton\")" + << llendl; + return FALSE; + } + for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() ) { if (bone->hasName("bone")) diff --git a/linden/indra/newview/llpolymorph.cpp b/linden/indra/newview/llpolymorph.cpp index 2d1375d..b36f0e2 100644 --- a/linden/indra/newview/llpolymorph.cpp +++ b/linden/indra/newview/llpolymorph.cpp @@ -214,6 +214,13 @@ BOOL LLPolyMorphTargetInfo::parseXml(LLXmlTreeNode* node) LLXmlTreeNode *paramNode = node->getChildByName("param_morph"); + if (NULL == paramNode) + { + llwarns << "Failed to getChildByName(\"param_morph\")" + << llendl; + return FALSE; + } + for (LLXmlTreeNode* child_node = paramNode->getFirstChild(); child_node; child_node = paramNode->getNextChild()) @@ -256,7 +263,10 @@ LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh) //----------------------------------------------------------------------------- LLPolyMorphTarget::~LLPolyMorphTarget() { - delete mVertMask; + if (mVertMask) + { + delete mVertMask; + } } //----------------------------------------------------------------------------- diff --git a/linden/indra/newview/llpreview.cpp b/linden/indra/newview/llpreview.cpp index 347c6d5..23f31aa 100644 --- a/linden/indra/newview/llpreview.cpp +++ b/linden/indra/newview/llpreview.cpp @@ -60,6 +60,7 @@ LLPreview::LLPreview(const std::string& name) : LLFloater(name), mCopyToInvBtn(NULL), mForceClose(FALSE), + mUserResized(FALSE), mCloseAfterSave(FALSE), mAssetStatus(PREVIEW_ASSET_UNLOADED) { @@ -76,6 +77,7 @@ LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::str mObjectUUID(object_uuid), mCopyToInvBtn( NULL ), mForceClose( FALSE ), + mUserResized(FALSE), mCloseAfterSave(FALSE), mAssetStatus(PREVIEW_ASSET_UNLOADED) { @@ -189,8 +191,6 @@ void LLPreview::onCommit() } LLPointer new_item = new LLViewerInventoryItem(item); - BOOL has_sale_info = FALSE; - LLSaleInfo sale_info; new_item->setDescription(childGetText("desc")); if(mObjectUUID.notNull()) { @@ -222,11 +222,6 @@ void LLPreview::onCommit() gSelectMgr->deselectAll(); gSelectMgr->addAsIndividual( obj, SELECT_ALL_TES, FALSE ); gSelectMgr->selectionSetObjectDescription( childGetText("desc") ); - - if( has_sale_info ) - { - gSelectMgr->selectionSetObjectSaleInfo( sale_info ); - } gSelectMgr->deselectAll(); } @@ -487,6 +482,12 @@ LLPreview* LLPreview::getFirstPreviewForSource(const LLUUID& source_id) return NULL; } +void LLPreview::userSetShape(const LLRect& new_rect) +{ + userResized(); + LLView::userSetShape(new_rect); +} + // // LLMultiPreview // @@ -506,6 +507,15 @@ void LLMultiPreview::open() /*Flawfinder: ignore*/ } } + +void LLMultiPreview::userSetShape(const LLRect& new_rect) +{ + LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel(); + if (frontmost_preview) frontmost_preview->userResized(); + LLView::userSetShape(new_rect); +} + + void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click) { LLPreview* opened_preview = (LLPreview*)opened_floater; diff --git a/linden/indra/newview/llpreview.h b/linden/indra/newview/llpreview.h index 266bdd1..c8c0355 100644 --- a/linden/indra/newview/llpreview.h +++ b/linden/indra/newview/llpreview.h @@ -48,6 +48,7 @@ public: /*virtual*/void open(); /*Flawfinder: ignore*/ /*virtual*/void tabOpen(LLFloater* opened_floater, bool from_click); + /*virtual*/ void userSetShape(const LLRect& new_rect); static LLMultiPreview* getAutoOpenInstance(const LLUUID& id); static void setAutoOpenInstance(LLMultiPreview* previewp, const LLUUID& id); @@ -101,6 +102,9 @@ public: void addKeepDiscardButtons(); static void onKeepBtn(void* data); static void onDiscardBtn(void* data); + /*virtual*/ void userSetShape(const LLRect& new_rect); + + void userResized() { mUserResized = TRUE; }; virtual void loadAsset() { mAssetStatus = PREVIEW_ASSET_LOADED; } virtual EAssetStatus getAssetStatus() { return mAssetStatus;} @@ -135,6 +139,8 @@ protected: // Close without saving changes BOOL mForceClose; + BOOL mUserResized; + // When closing springs a "Want to save?" dialog, we want // to keep the preview open until the save completes. BOOL mCloseAfterSave; diff --git a/linden/indra/newview/llpreviewgesture.cpp b/linden/indra/newview/llpreviewgesture.cpp index 5f657d3..2bb0108 100644 --- a/linden/indra/newview/llpreviewgesture.cpp +++ b/linden/indra/newview/llpreviewgesture.cpp @@ -1590,6 +1590,11 @@ LLScrollListItem* LLPreviewGesture::addStep(const std::string& library_text) { step = new LLGestureStepWait(); } + else + { + llerrs << "Unknown step type: " << library_text << llendl;; + return NULL; + } // Create an enabled item with this step LLSD row; @@ -1645,7 +1650,7 @@ void LLPreviewGesture::onClickDelete(void* data) LLScrollListItem* item = self->mStepList->getFirstSelected(); S32 selected_index = self->mStepList->getFirstSelectedIndex(); - if (selected_index >= 0) + if (item && selected_index >= 0) { LLGestureStep* step = (LLGestureStep*)item->getUserdata(); delete step; diff --git a/linden/indra/newview/llpreviewnotecard.cpp b/linden/indra/newview/llpreviewnotecard.cpp index 1c59bb4..471fe8a 100644 --- a/linden/indra/newview/llpreviewnotecard.cpp +++ b/linden/indra/newview/llpreviewnotecard.cpp @@ -296,11 +296,12 @@ void LLPreviewNotecard::loadAsset() { // The object that we're trying to look at disappeared, bail. llwarns << "Can't find object " << mObjectUUID << " associated with notecard." << llendl; - mAssetID.setNull(); - editor->setText("Unable to find object containing this note."); - editor->makePristine(); - editor->setEnabled(FALSE); - mAssetStatus = PREVIEW_ASSET_LOADED; + mAssetID.setNull(); + editor->setText("Unable to find object containing this note."); + editor->makePristine(); + editor->setEnabled(FALSE); + mAssetStatus = PREVIEW_ASSET_LOADED; + delete new_uuid; return; } } diff --git a/linden/indra/newview/llpreviewscript.cpp b/linden/indra/newview/llpreviewscript.cpp index 39938d4..86c78a5 100644 --- a/linden/indra/newview/llpreviewscript.cpp +++ b/linden/indra/newview/llpreviewscript.cpp @@ -470,12 +470,14 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) LLFloater* help_floater = LLFloater::getFloaterByHandle(mLiveHelpHandle); if (!help_floater) return; +#if LL_LIBXUL_ENABLED // update back and forward buttons LLButton* fwd_button = LLUICtrlFactory::getButtonByName(help_floater, "fwd_btn"); LLButton* back_button = LLUICtrlFactory::getButtonByName(help_floater, "back_btn"); LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(help_floater, "lsl_guide_html"); back_button->setEnabled(browser->canNavigateBack()); fwd_button->setEnabled(browser->canNavigateForward()); +#endif // LL_LIBXUL_ENABLED if (!immediate && !gSavedSettings.getBOOL("ScriptHelpFollowsCursor")) { @@ -521,7 +523,7 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) mLiveHelpTimer.stop(); } } - else + else if (immediate) { setHelpPage(""); } @@ -543,7 +545,9 @@ void LLScriptEdCore::setHelpPage(const LLString& help_string) url_string.setArg("[LSL_STRING]", help_string); addHelpItemToHistory(help_string); +#if LL_LIBXUL_ENABLED web_browser->navigateTo(url_string); +#endif // LL_LIBXUL_ENABLED } void LLScriptEdCore::addHelpItemToHistory(const LLString& help_string) @@ -675,8 +679,10 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) live_help_floater->childSetAction("back_btn", onClickBack, userdata); live_help_floater->childSetAction("fwd_btn", onClickForward, userdata); +#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); browser->setAlwaysRefresh(TRUE); +#endif // LL_LIBXUL_ENABLED LLComboBox* help_combo = LLUICtrlFactory::getComboBoxByName(live_help_floater, "history_combo"); LLKeywordToken *token; @@ -700,6 +706,7 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) //static void LLScriptEdCore::onClickBack(void* userdata) { +#if LL_LIBXUL_ENABLED LLScriptEdCore* corep = (LLScriptEdCore*)userdata; LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); if (live_help_floater) @@ -710,11 +717,13 @@ void LLScriptEdCore::onClickBack(void* userdata) browserp->navigateBack(); } } +#endif // LL_LIBXUL_ENABLED } //static void LLScriptEdCore::onClickForward(void* userdata) { +#if LL_LIBXUL_ENABLED LLScriptEdCore* corep = (LLScriptEdCore*)userdata; LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); if (live_help_floater) @@ -725,6 +734,7 @@ void LLScriptEdCore::onClickForward(void* userdata) browserp->navigateForward(); } } +#endif // LL_LIBXUL_ENABLED } // static @@ -757,16 +767,17 @@ void LLScriptEdCore::onHelpComboCommit(LLUICtrl* ctrl, void* userdata) LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); if (live_help_floater) { - LLWebBrowserCtrl* web_browser = gUICtrlFactory->getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); - LLString help_string = ctrl->getValue().asString(); corep->addHelpItemToHistory(help_string); +#if LL_LIBXUL_ENABLED + LLWebBrowserCtrl* web_browser = gUICtrlFactory->getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); LLUIString url_string = gSavedSettings.getString("LSLHelpURL"); url_string.setArg("[APP_DIRECTORY]", gDirUtilp->getWorkingDir()); url_string.setArg("[LSL_STRING]", help_string); web_browser->navigateTo(url_string); +#endif // LL_LIBXUL_ENABLED } } @@ -1336,10 +1347,6 @@ void LLPreviewLSL::uploadAssetLegacy(const std::string& filename, { break; } - else if(!buffer) - { - continue; - } else { line.assign(buffer); @@ -1709,7 +1716,7 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) mScriptEd->mEditor->setEnabled(FALSE); mAssetStatus = PREVIEW_ASSET_LOADED; } - else if(mItem.notNull()) + else if(item && mItem.notNull()) { // request the text from the object LLUUID* user_data = new LLUUID(mItemID ^ mObjectID); @@ -1835,6 +1842,7 @@ void LLLiveLSLEditor::loadScriptText(const char* filename) if(!filename) { llerrs << "Filename is Empty!" << llendl; + return; } FILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ if(file) @@ -2115,10 +2123,6 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, { break; } - else if(!buffer) - { - continue; - } else { line.assign(buffer); diff --git a/linden/indra/newview/llpreviewtexture.cpp b/linden/indra/newview/llpreviewtexture.cpp index 27a9b52..b59846d 100644 --- a/linden/indra/newview/llpreviewtexture.cpp +++ b/linden/indra/newview/llpreviewtexture.cpp @@ -388,29 +388,23 @@ void LLPreviewTexture::updateAspectRatio() // If that fails, cut width by half. S32 client_width = image_width; S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE; + S32 vert_pad = PREVIEW_HEADER_SIZE + 2 * CLIENT_RECT_VPAD + LLPANEL_BORDER_WIDTH; S32 screen_width = gViewerWindow->getWindowWidth(); S32 max_client_width = screen_width - horiz_pad; + S32 max_client_height = gViewerWindow->getWindowHeight() - vert_pad; + F32 inv_aspect_ratio = (F32) image_height / (F32) image_width; - while (client_width > max_client_width) + while ((client_width > max_client_width) || ( llround(client_width * inv_aspect_ratio) > max_client_height ) ) { client_width /= 2; } - // Demand width at least 128 - if (client_width < 128) - { - client_width = 128; - } - S32 view_width = client_width + horiz_pad; // Adjust the height based on the width computed above. - F32 inv_aspect_ratio = (F32) image_height / (F32) image_width; S32 client_height = llround(client_width * inv_aspect_ratio); - S32 view_height = - PREVIEW_HEADER_SIZE + // header (includes top border) - client_height + 2 * CLIENT_RECT_VPAD + // texture plus uniform spacing (which leaves room for resize handle) - LLPANEL_BORDER_WIDTH; // bottom border + S32 view_height = client_height + vert_pad; + // set text on dimensions display (should be moved out of here and into a callback of some sort) childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->mFullWidth)); @@ -453,28 +447,43 @@ void LLPreviewTexture::updateAspectRatio() } } - // clamp texture size to fit within actual size of floater after attempting resize - client_width = llmin(client_width, mRect.getWidth() - horiz_pad); - client_height = llmin(client_height, mRect.getHeight() - PREVIEW_HEADER_SIZE - (2 * CLIENT_RECT_VPAD) - LLPANEL_BORDER_WIDTH - info_height); - - LLRect window_rect(0, mRect.getHeight(), mRect.getWidth(), 0); - window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD); - window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD; - - if (getHost()) + + if (!mUserResized) { - // try to keep aspect ratio when hosted, as hosting view can resize without user input - mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height); + // clamp texture size to fit within actual size of floater after attempting resize + client_width = llmin(client_width, mRect.getWidth() - horiz_pad); + client_height = llmin(client_height, mRect.getHeight() - PREVIEW_HEADER_SIZE + - (2 * CLIENT_RECT_VPAD) - LLPANEL_BORDER_WIDTH - info_height); + + } else { - mClientRect.setLeftTopAndSize(LLPANEL_BORDER_WIDTH + PREVIEW_PAD + 6, - mRect.getHeight() - (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD), - mRect.getWidth() - horiz_pad, - client_height); + client_width = mRect.getWidth() - horiz_pad; + client_height = llround(client_width * inv_aspect_ratio); + } + + + S32 max_height = mRect.getHeight() - PREVIEW_BORDER - button_height + - CLIENT_RECT_VPAD - info_height - CLIENT_RECT_VPAD - PREVIEW_HEADER_SIZE; + max_height = llmax(max_height, 1); + + if (client_height > max_height) + { + F32 aspect_ratio = (F32) image_width / (F32) image_height; + client_height = max_height; + client_width = llround(client_height * aspect_ratio); } + + LLRect window_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD); + window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD; + + // try to keep aspect ratio when hosted, as hosting view can resize without user input + mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height); } + void LLPreviewTexture::loadAsset() { mImage = gImageList.getImage(mImageID, MIPMAP_TRUE, FALSE); diff --git a/linden/indra/newview/llresourcedata.h b/linden/indra/newview/llresourcedata.h new file mode 100644 index 0000000..9f5d329 --- /dev/null +++ b/linden/indra/newview/llresourcedata.h @@ -0,0 +1,44 @@ +/** + * @file llresourcedata.h + * @brief Tracking object for uploads. + * + * Copyright (c) 2006-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + */ + +#ifndef LLRESOURCEDATA_H +#define LLRESOURCEDATA_H + +#include "llassetstorage.h" +#include "llinventorytype.h" + +struct LLResourceData +{ + LLAssetInfo mAssetInfo; + LLAssetType::EType mPreferredLocation; + LLInventoryType::EType mInventoryType; + U32 mNextOwnerPerm; + void *mUserData; +}; + +#endif diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index 598ded9..ec7ba78 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -91,7 +91,6 @@ const S32 MAX_ACTION_QUEUE_SIZE = 20; const S32 MAX_SILS_PER_FRAME = 50; const S32 MAX_OBJECTS_PER_PACKET = 254; -extern LLGlobalEconomy *gGlobalEconomy; extern LLUUID gLastHitObjectID; extern LLVector3d gLastHitObjectOffset; @@ -208,6 +207,20 @@ LLSelectMgr::~LLSelectMgr() void LLSelectMgr::updateEffects() { + + //keep reference grid objects active + for (LLSelectNode* grid_nodep = mGridObjects.getFirstNode(); + grid_nodep; + grid_nodep = mGridObjects.getNextNode()) + { + LLViewerObject* grid_object = grid_nodep->getObject(); + LLDrawable* drawable = grid_object->mDrawable; + if (drawable) + { + gPipeline.markMoved(drawable); + } + } + if (mEffectsTimer.getElapsedTimeF32() > 1.f) { mSelectedObjects->updateEffects(); @@ -993,7 +1006,7 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & LLVector3 first_grid_obj_pos = grid_object->getRenderPosition(); LLVector3 min_extents(F32_MAX, F32_MAX, F32_MAX); - LLVector3 max_extents(F32_MIN, F32_MIN, F32_MIN); + LLVector3 max_extents(-min_extents); BOOL grid_changed = FALSE; LLSelectNode* grid_nodep; for (grid_nodep = mGridObjects.getFirstNode(); @@ -1001,34 +1014,23 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & grid_nodep = mGridObjects.getNextNode()) { grid_object = grid_nodep->getObject(); - - LLVector3 local_min_extents(F32_MAX, F32_MAX, F32_MAX); - LLVector3 local_max_extents(F32_MIN, F32_MIN, F32_MIN); - - // *FIX: silhouette flag is insufficient as it gets - // cleared by view update. - if (!mGridValid || - grid_object->isChanged(LLXform::SILHOUETTE) - || (grid_object->getParent() && grid_object->getParent()->isChanged(LLXform::SILHOUETTE))) + LLDrawable* drawable = grid_object->mDrawable; + if (drawable) { - getSilhouetteExtents(grid_nodep, mGridRotation, local_min_extents, local_max_extents); + const LLVector3* ext = drawable->getSpatialExtents(); + update_min_max(min_extents, max_extents, ext[0]); + update_min_max(min_extents, max_extents, ext[1]); grid_changed = TRUE; - LLVector3 object_offset = (grid_object->getRenderPosition() - first_grid_obj_pos) * ~mGridRotation; - local_min_extents += object_offset; - local_max_extents += object_offset; } - min_extents.mV[VX] = llmin(min_extents.mV[VX], local_min_extents.mV[VX]); - min_extents.mV[VY] = llmin(min_extents.mV[VY], local_min_extents.mV[VY]); - min_extents.mV[VZ] = llmin(min_extents.mV[VZ], local_min_extents.mV[VZ]); - max_extents.mV[VX] = llmax(max_extents.mV[VX], local_max_extents.mV[VX]); - max_extents.mV[VY] = llmax(max_extents.mV[VY], local_max_extents.mV[VY]); - max_extents.mV[VZ] = llmax(max_extents.mV[VZ], local_max_extents.mV[VZ]); } if (grid_changed) { mGridOrigin = lerp(min_extents, max_extents, 0.5f); - mGridOrigin = mGridOrigin * ~mGridRotation; - mGridOrigin += first_grid_obj_pos; + LLDrawable* drawable = grid_object->mDrawable; + if (drawable && drawable->isActive()) + { + mGridOrigin = mGridOrigin * grid_object->getRenderMatrix(); + } mGridScale = (max_extents - min_extents) * 0.5f; } } @@ -4939,66 +4941,6 @@ void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_ } } -void LLSelectMgr::getSilhouetteExtents(LLSelectNode* nodep, const LLQuaternion& orientation, LLVector3& min_extents, LLVector3& max_extents) -{ - LLViewerObject* objectp = nodep->getObject(); - - if (objectp->mDrawable.isNull()) - { - return; - } - - LLQuaternion test_rot = orientation * ~objectp->getRenderRotation(); - LLVector3 x_axis_rot = LLVector3::x_axis * test_rot; - LLVector3 y_axis_rot = LLVector3::y_axis * test_rot; - LLVector3 z_axis_rot = LLVector3::z_axis * test_rot; - - x_axis_rot.scaleVec(objectp->mDrawable->getScale()); - y_axis_rot.scaleVec(objectp->mDrawable->getScale()); - z_axis_rot.scaleVec(objectp->mDrawable->getScale()); - - generateSilhouette(nodep, objectp->mDrawable->getPositionAgent() + x_axis_rot * 100.f); - - S32 num_vertices = nodep->mSilhouetteVertices.size(); - if (num_vertices) - { - min_extents.mV[VY] = llmin(min_extents.mV[VY], nodep->mSilhouetteVertices[0] * y_axis_rot); - max_extents.mV[VY] = llmax(max_extents.mV[VY], nodep->mSilhouetteVertices[0] * y_axis_rot); - - min_extents.mV[VZ] = llmin(min_extents.mV[VZ], nodep->mSilhouetteVertices[0] * z_axis_rot); - max_extents.mV[VZ] = llmax(min_extents.mV[VZ], nodep->mSilhouetteVertices[0] * z_axis_rot); - - for (S32 vert = 1; vert < num_vertices; vert++) - { - F32 y_pos = nodep->mSilhouetteVertices[vert] * y_axis_rot; - F32 z_pos = nodep->mSilhouetteVertices[vert] * z_axis_rot; - min_extents.mV[VY] = llmin(y_pos, min_extents.mV[VY]); - max_extents.mV[VY] = llmax(y_pos, max_extents.mV[VY]); - min_extents.mV[VZ] = llmin(z_pos, min_extents.mV[VZ]); - max_extents.mV[VZ] = llmax(z_pos, max_extents.mV[VZ]); - } - } - - generateSilhouette(nodep, objectp->mDrawable->getPositionAgent() + y_axis_rot * 100.f); - - num_vertices = nodep->mSilhouetteVertices.size(); - if (num_vertices) - { - min_extents.mV[VX] = llmin(min_extents.mV[VX], nodep->mSilhouetteVertices[0] * x_axis_rot); - max_extents.mV[VX] = llmax(max_extents.mV[VX], nodep->mSilhouetteVertices[0] * x_axis_rot); - - for (S32 vert = 1; vert < num_vertices; vert++) - { - F32 x_pos = nodep->mSilhouetteVertices[vert] * x_axis_rot; - min_extents.mV[VX] = llmin(x_pos, min_extents.mV[VX]); - max_extents.mV[VX] = llmax(x_pos, max_extents.mV[VX]); - } - } - - generateSilhouette(nodep, gCamera->getOrigin()); -} - - // // Utility classes // @@ -6479,6 +6421,8 @@ LLViewerObject* LLObjectSelection::getFirstDeleteableObject(BOOL get_root) } else { + // We've avoided this path for a while. It may not work. + llwarns << "!get_root code path may have bitrotted." << llendl; for(LLViewerObject* current = getFirstObject(); current != NULL; current = getNextObject()) diff --git a/linden/indra/newview/llselectmgr.h b/linden/indra/newview/llselectmgr.h index 98c0a7b..96db8e5 100644 --- a/linden/indra/newview/llselectmgr.h +++ b/linden/indra/newview/llselectmgr.h @@ -492,7 +492,6 @@ private: ESelectType getSelectTypeForObject(LLViewerObject* object); void addAsFamily(LLDynamicArray& objects, BOOL add_to_end = FALSE); void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point); - void getSilhouetteExtents(LLSelectNode* nodep, const LLQuaternion& orientation, LLVector3& min_extents, LLVector3& max_extents); // Send one message to each region containing an object on selection list. void sendListToRegions( const LLString& message_name, void (*pack_header)(void *user_data), diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp index 46b9df9..d62a93e 100644 --- a/linden/indra/newview/llspatialpartition.cpp +++ b/linden/indra/newview/llspatialpartition.cpp @@ -1180,6 +1180,13 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); + + // sanity check submitted by open source user bushing Spatula + // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne) + if (!drawablep) { + OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << llendl; + return; + } BOOL was_visible = curp ? curp->isVisible() : FALSE; diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 585f769..e83aa0d 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -203,6 +203,7 @@ LLPointer gStartImageGL; static LLHost gAgentSimHost; static BOOL gSkipOptionalUpdate = FALSE; +bool gUseQuickTime = true; bool gQuickTimeInitialized = false; static bool gGotUseCircuitCodeAck = false; LLString gInitialOutfit; @@ -1867,7 +1868,8 @@ BOOL idle_startup() } #if LL_QUICKTIME_ENABLED // windows only right now but will be ported to mac - if (!gQuickTimeInitialized) + if (gUseQuickTime + && !gQuickTimeInitialized) { // initialize quicktime libraries (fails gracefully if quicktime not installed ($QUICKTIME) llinfos << "Initializing QuickTime...." << llendl; diff --git a/linden/indra/newview/llstartup.h b/linden/indra/newview/llstartup.h index 59a433e..7c54b8c 100644 --- a/linden/indra/newview/llstartup.h +++ b/linden/indra/newview/llstartup.h @@ -82,6 +82,7 @@ enum EStartupState{ // exorted symbol extern S32 gStartupState; extern BOOL gAgentMovementCompleted; +extern bool gUseQuickTime; extern bool gQuickTimeInitialized; extern LLPointer gStartImageGL; diff --git a/linden/indra/newview/llstatusbar.cpp b/linden/indra/newview/llstatusbar.cpp index 58ac8c2..784765b 100644 --- a/linden/indra/newview/llstatusbar.cpp +++ b/linden/indra/newview/llstatusbar.cpp @@ -643,3 +643,8 @@ void LLStatusBar::onClickBuyLand(void*) gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); gParcelMgr->startBuyLand(); } + +BOOL can_afford_transaction(S32 cost) +{ + return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost))); +} diff --git a/linden/indra/newview/llstatusbar.h b/linden/indra/newview/llstatusbar.h index 52cc236..a072cd9 100644 --- a/linden/indra/newview/llstatusbar.h +++ b/linden/indra/newview/llstatusbar.h @@ -123,6 +123,9 @@ protected: LLFrameTimer* mHealthTimer; }; +// *HACK: Status bar owns your cached money balance. JC +BOOL can_afford_transaction(S32 cost); + extern LLStatusBar *gStatusBar; #endif diff --git a/linden/indra/newview/lltexlayer.cpp b/linden/indra/newview/lltexlayer.cpp index 237d563..2005e39 100644 --- a/linden/indra/newview/lltexlayer.cpp +++ b/linden/indra/newview/lltexlayer.cpp @@ -277,7 +277,7 @@ BOOL LLTexLayerSetBuffer::render() { if (!success) { - delete baked_bump_data; + delete [] baked_bump_data; llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegion() << llendl; mUploadPending = FALSE; } diff --git a/linden/indra/newview/lltexturectrl.cpp b/linden/indra/newview/lltexturectrl.cpp index 1436b62..b5c1ace 100644 --- a/linden/indra/newview/lltexturectrl.cpp +++ b/linden/indra/newview/lltexturectrl.cpp @@ -410,32 +410,35 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask, BOOL called_from_ { LLFolderView* root_folder = mInventoryPanel->getRootFolder(); - if (!called_from_parent && root_folder && - mSearchEdit && mSearchEdit->hasFocus() && - (key == KEY_RETURN || key == KEY_DOWN) && mask == MASK_NONE) + if (root_folder && mSearchEdit) { - if (!root_folder->getCurSelectedItem()) + if (!called_from_parent && mSearchEdit->hasFocus() && + (key == KEY_RETURN || key == KEY_DOWN) && + mask == MASK_NONE) { - LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID()); - if (itemp) + if (!root_folder->getCurSelectedItem()) { - root_folder->setSelection(itemp, FALSE, FALSE); + LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID()); + if (itemp) + { + root_folder->setSelection(itemp, FALSE, FALSE); + } } + root_folder->scrollToShowSelection(); + + // move focus to inventory proper + root_folder->setFocus(TRUE); + + // treat this as a user selection of the first filtered result + commitIfImmediateSet(); + + return TRUE; } - root_folder->scrollToShowSelection(); - - // move focus to inventory proper - root_folder->setFocus(TRUE); - // treat this as a user selection of the first filtered result - commitIfImmediateSet(); - - return TRUE; - } - - if (root_folder->hasFocus() && key == KEY_UP) - { - mSearchEdit->focusFirstItem(TRUE); + if (root_folder->hasFocus() && key == KEY_UP) + { + mSearchEdit->focusFirstItem(TRUE); + } } return LLFloater::handleKeyHere(key, mask, called_from_parent); diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp index 3956402..6196927 100644 --- a/linden/indra/newview/lltooldraganddrop.cpp +++ b/linden/indra/newview/lltooldraganddrop.cpp @@ -2575,7 +2575,13 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory( LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { lldebugs << "LLToolDragAndDrop::dad3dUpdateInventoryCategory()" << llendl; - if(mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY) + if (NULL==obj) + { + llwarns << "obj is NULL; aborting func with ACCEPT_NO" << llendl; + return ACCEPT_NO; + } + + if (mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY) { return ACCEPT_NO; } @@ -2591,17 +2597,17 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory( LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; gInventory.collectDescendentsIf(cat->getUUID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - droppable); + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + droppable); cats.put(cat); if(droppable.countNoCopy() > 0) { llwarns << "*** Need to confirm this step" << llendl; } LLViewerObject* root_object = obj; - if (obj && obj->getParent()) + if (obj->getParent()) { LLViewerObject* parent_obj = (LLViewerObject*)obj->getParent(); if (!parent_obj->isAvatar()) diff --git a/linden/indra/newview/lltoolgrab.cpp b/linden/indra/newview/lltoolgrab.cpp index 502e2be..b56e762 100644 --- a/linden/indra/newview/lltoolgrab.cpp +++ b/linden/indra/newview/lltoolgrab.cpp @@ -180,6 +180,12 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas llinfos << "LLToolGrab handleObjectHit " << mMouseDownX << "," << mMouseDownY << llendl; } + if (NULL == objectp) // unexpected + { + llwarns << "objectp was NULL; returning FALSE" << llendl; + return FALSE; + } + if (objectp->isAvatar()) { if (gGrabTransientTool) @@ -198,7 +204,7 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas // objectp = (LLViewerObject *)objectp->getRoot(); LLViewerObject* parent = objectp->getRootEdit(); - BOOL script_touch = (objectp && objectp->flagHandleTouch()) || (parent && parent->flagHandleTouch()); + BOOL script_touch = (objectp->flagHandleTouch()) || (parent && parent->flagHandleTouch()); // Clicks on scripted or physical objects are temporary grabs, so // not "Build mode" diff --git a/linden/indra/newview/lltoolpie.cpp b/linden/indra/newview/lltoolpie.cpp index adc46e2..7231286 100644 --- a/linden/indra/newview/lltoolpie.cpp +++ b/linden/indra/newview/lltoolpie.cpp @@ -390,11 +390,11 @@ U8 final_click_action(LLViewerObject* obj) if (obj->isAttachment()) return CLICK_ACTION_NONE; U8 click_action = CLICK_ACTION_TOUCH; - LLViewerObject* parent = (obj ? obj->getRootEdit() : NULL); - if ((obj && obj->getClickAction()) - || (parent && parent->getClickAction())) + LLViewerObject* parent = obj->getRootEdit(); + if (obj->getClickAction() + || (parent && parent->getClickAction())) { - if (obj && obj->getClickAction()) + if (obj->getClickAction()) { click_action = obj->getClickAction(); } diff --git a/linden/indra/newview/lltoolpipette.cpp b/linden/indra/newview/lltoolpipette.cpp old mode 100755 new mode 100644 diff --git a/linden/indra/newview/lltoolpipette.h b/linden/indra/newview/lltoolpipette.h old mode 100755 new mode 100644 diff --git a/linden/indra/newview/llviewerassetstorage.cpp b/linden/indra/newview/llviewerassetstorage.cpp index c7e9c97..95ef983 100644 --- a/linden/indra/newview/llviewerassetstorage.cpp +++ b/linden/indra/newview/llviewerassetstorage.cpp @@ -166,21 +166,22 @@ void LLViewerAssetStorage::storeAssetData( if(!filename) { llerrs << "No filename specified" << llendl; + return; } LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); llinfos << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl; - LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; - llinfos << "ASSET_ID: " << asset_id << llendl; - legacy->mUpCallback = callback; - legacy->mUserData = user_data; - - FILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ + FILE* fp = LLFile::fopen(filename, "rb"); if (fp) { + LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; + + legacy->mUpCallback = callback; + legacy->mUserData = user_data; + LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE); fseek(fp, 0, SEEK_END); diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 61285d5..08abd2d 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp @@ -240,6 +240,14 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) LLSpinCtrl* spinner3 = LLUICtrlFactory::getSpinnerByName(this, "val_spinner_3"); LLSpinCtrl* spinner4 = LLUICtrlFactory::getSpinnerByName(this, "val_spinner_4"); LLColorSwatchCtrl* color_swatch = LLUICtrlFactory::getColorSwatchByName(this, "color_swatch"); + + if (!spinner1 || !spinner2 || !spinner3 || !spinner4 || !color_swatch) + { + llwarns << "Could not find all desired controls by name" + << llendl; + return; + } + spinner1->setVisible(FALSE); spinner2->setVisible(FALSE); spinner3->setVisible(FALSE); diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index c2ef30a..fc288c0 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp @@ -564,6 +564,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); + if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices(FALSE)) { LLCamera hud_cam = *gCamera; @@ -598,7 +599,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) LLFastTimer ftm(LLFastTimer::FTM_REBUILD); gPipeline.stateSort(hud_cam); } - + gPipeline.renderGeom(hud_cam); //restore type mask @@ -657,6 +658,7 @@ BOOL setup_hud_matrices(BOOL for_select) } LLBBox hud_bbox = my_avatarp->getHUDBBox(); + // set up transform to encompass bounding box of HUD glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -685,7 +687,7 @@ BOOL setup_hud_matrices(BOOL for_select) glLoadMatrixf(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f); glScalef(zoom_level, zoom_level, zoom_level); - + return TRUE; } else diff --git a/linden/indra/newview/llviewergenericmessage.cpp b/linden/indra/newview/llviewergenericmessage.cpp index 56b168b..0e1ce49 100644 --- a/linden/indra/newview/llviewergenericmessage.cpp +++ b/linden/indra/newview/llviewergenericmessage.cpp @@ -1,9 +1,9 @@ -/** - * @file llviewergenericmessage.cpp - * @brief Handle processing of "generic messages" which contain short lists of strings. - * @author James Cook - * - * Copyright (c) 2007-2007, Linden Research, Inc. +/** + * @file llviewergenericmessage.cpp + * @brief Handle processing of "generic messages" which contain short lists of strings. + * @author James Cook + * + * Copyright (c) 2007-2007, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -24,74 +24,74 @@ * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#include "llviewerprecompiledheaders.h" - -#include "llviewergenericmessage.h" - -#include "lldispatcher.h" -#include "lluuid.h" -#include "message.h" - -#include "llagent.h" - - -LLDispatcher gGenericDispatcher; - - -void send_generic_message(const char* method, - const std::vector& strings, - const LLUUID& invoice) -{ - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("GenericMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - msg->nextBlock("MethodData"); - msg->addString("Method", method); - msg->addUUID("Invoice", invoice); - if(strings.empty()) - { - msg->nextBlock("ParamList"); - msg->addString("Parameter", NULL); - } - else - { - std::vector::const_iterator it = strings.begin(); - std::vector::const_iterator end = strings.end(); - for(; it != end; ++it) - { - msg->nextBlock("ParamList"); - msg->addString("Parameter", (*it).c_str()); - } - } - gAgent.sendReliableMessage(); -} - - - -void process_generic_message(LLMessageSystem* msg, void**) -{ - LLUUID agent_id; - msg->getUUID("AgentData", "AgentID", agent_id); - if (agent_id != gAgent.getID()) - { - llwarns << "GenericMessage for wrong agent" << llendl; - return; - } - - std::string request; - LLUUID invoice; - LLDispatcher::sparam_t strings; - LLDispatcher::unpackMessage(msg, request, invoice, strings); - - if(!gGenericDispatcher.dispatch(request, invoice, strings)) - { - llwarns << "GenericMessage " << request << " failed to dispatch" - << llendl; - } -} + * COMPLETENESS OR PERFORMANCE. + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewergenericmessage.h" + +#include "lldispatcher.h" +#include "lluuid.h" +#include "message.h" + +#include "llagent.h" + + +LLDispatcher gGenericDispatcher; + + +void send_generic_message(const char* method, + const std::vector& strings, + const LLUUID& invoice) +{ + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("GenericMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + msg->nextBlock("MethodData"); + msg->addString("Method", method); + msg->addUUID("Invoice", invoice); + if(strings.empty()) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", NULL); + } + else + { + std::vector::const_iterator it = strings.begin(); + std::vector::const_iterator end = strings.end(); + for(; it != end; ++it) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", (*it).c_str()); + } + } + gAgent.sendReliableMessage(); +} + + + +void process_generic_message(LLMessageSystem* msg, void**) +{ + LLUUID agent_id; + msg->getUUID("AgentData", "AgentID", agent_id); + if (agent_id != gAgent.getID()) + { + llwarns << "GenericMessage for wrong agent" << llendl; + return; + } + + std::string request; + LLUUID invoice; + LLDispatcher::sparam_t strings; + LLDispatcher::unpackMessage(msg, request, invoice, strings); + + if(!gGenericDispatcher.dispatch(request, invoice, strings)) + { + llwarns << "GenericMessage " << request << " failed to dispatch" + << llendl; + } +} diff --git a/linden/indra/newview/llviewergenericmessage.h b/linden/indra/newview/llviewergenericmessage.h index cf94d86..b0d02a2 100644 --- a/linden/indra/newview/llviewergenericmessage.h +++ b/linden/indra/newview/llviewergenericmessage.h @@ -1,9 +1,9 @@ -/** - * @file llviewergenericmessage.h - * @brief Handle processing of "generic messages" which contain short lists of strings. - * @author James Cook - * - * Copyright (c) 2007-2007, Linden Research, Inc. +/** + * @file llviewergenericmessage.h + * @brief Handle processing of "generic messages" which contain short lists of strings. + * @author James Cook + * + * Copyright (c) 2007-2007, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -24,23 +24,23 @@ * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - */ - -#ifndef LLVIEWERGENERICMESSAGE_H -#define LLVIEWERGENERICMESSAGE_H - -class LLUUID; -class LLDispatcher; - - -void send_generic_message(const char* method, - const std::vector& strings, - const LLUUID& invoice = LLUUID::null); - -void process_generic_message(LLMessageSystem* msg, void**); - - -extern LLDispatcher gGenericDispatcher; - -#endif + * COMPLETENESS OR PERFORMANCE. + */ + +#ifndef LLVIEWERGENERICMESSAGE_H +#define LLVIEWERGENERICMESSAGE_H + +class LLUUID; +class LLDispatcher; + + +void send_generic_message(const char* method, + const std::vector& strings, + const LLUUID& invoice = LLUUID::null); + +void process_generic_message(LLMessageSystem* msg, void**); + + +extern LLDispatcher gGenericDispatcher; + +#endif diff --git a/linden/indra/newview/llviewerimagelist.cpp b/linden/indra/newview/llviewerimagelist.cpp index 9da84fa..4e87905 100644 --- a/linden/indra/newview/llviewerimagelist.cpp +++ b/linden/indra/newview/llviewerimagelist.cpp @@ -125,6 +125,9 @@ void LLViewerImageList::doPreloadImages() // Set the "white" image LLViewerImage::sWhiteImagep = preloadImage("white.tga", LLUUID::null, TRUE);; + // Speeds up startup by 4-5 seconds. JC + if (!gPreloadImages) return; + // Preload some images preloadImage("button_anim_pause.tga", LLUUID::null, FALSE); preloadImage("button_anim_pause_selected.tga", LLUUID::null, FALSE); @@ -1116,6 +1119,7 @@ LLPointer LLViewerImageList::convertToUploadFile(LLPointergetU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets); msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes); - U16 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); + S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); if (!data_size) { return; } - + if (data_size < 0) + { + // msg->getSizeFast() is probably trying to tell us there + // was an error. + llerrs << "image header chunk size was negative: " + << data_size << llendl; + return; + } + // this buffer gets saved off in the packet list U8 *data = new U8[data_size]; msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); @@ -1246,6 +1265,7 @@ void LLViewerImageList::receiveImageHeader(LLMessageSystem *msg, void **user_dat LLViewerImage *image = gImageList.getImage(id); if (!image) { + delete [] data; return; } image->mLastPacketTimer.reset(); @@ -1284,15 +1304,24 @@ void LLViewerImageList::receiveImagePacket(LLMessageSystem *msg, void **user_dat //llprintline("Start decode, image header..."); msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num); - U16 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); + S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); if (!data_size) { return; } + if (data_size < 0) + { + // msg->getSizeFast() is probably trying to tell us there + // was an error. + llerrs << "image data chunk size was negative: " + << data_size << llendl; + return; + } if (data_size > MTUBYTES) { llerrs << "image data chunk too large: " << data_size << " bytes" << llendl; + return; } U8 *data = new U8[data_size]; msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); @@ -1300,6 +1329,7 @@ void LLViewerImageList::receiveImagePacket(LLMessageSystem *msg, void **user_dat LLViewerImage *image = gImageList.getImage(id); if (!image) { + delete [] data; return; } image->mLastPacketTimer.reset(); diff --git a/linden/indra/newview/llviewerinventory.cpp b/linden/indra/newview/llviewerinventory.cpp index 8f23346..d271af5 100644 --- a/linden/indra/newview/llviewerinventory.cpp +++ b/linden/indra/newview/llviewerinventory.cpp @@ -462,10 +462,6 @@ bool LLViewerInventoryCategory::importFileLocal(FILE* fp) fgets(buffer, MAX_STRING, fp); sscanf( /* Flawfinder: ignore */ buffer, " %254s %254s", keyword, valuestr); - if(!keyword) - { - continue; - } if(0 == strcmp("{",keyword)) { continue; diff --git a/linden/indra/newview/llviewerjointmesh.cpp b/linden/indra/newview/llviewerjointmesh.cpp index 216e29f..c76990c 100644 --- a/linden/indra/newview/llviewerjointmesh.cpp +++ b/linden/indra/newview/llviewerjointmesh.cpp @@ -216,11 +216,11 @@ S32 LLViewerJointMesh::getBoundJointsByIndex(S32 index, S32 &joint_a, S32& joint if (render_datap->mSkinJoint) { joint_b = render_datap->mSkinJoint->mJoint->mJointNum; - } - if (joint_a == -1) - { - joint_a = render_datap->mSkinJoint->mJoint->getParent()->mJointNum; + if (joint_a == -1) + { + joint_a = render_datap->mSkinJoint->mJoint->getParent()->mJointNum; + } } num_joints++; } diff --git a/linden/indra/newview/llviewerkeyboard.cpp b/linden/indra/newview/llviewerkeyboard.cpp index f514b2e..fcb1550 100644 --- a/linden/indra/newview/llviewerkeyboard.cpp +++ b/linden/indra/newview/llviewerkeyboard.cpp @@ -717,15 +717,16 @@ S32 LLViewerKeyboard::loadBindings(const char *filename) S32 binding_count = 0; S32 line_count = 0; - fp = LLFile::fopen(filename, "r"); /* Flawfinder: ignore */ + if(!filename) + { + llerrs << " No filename specified" << llendl; + return 0; + } + + fp = LLFile::fopen(filename, "r"); if (!fp) { - if(!filename) - { - llerrs << " No filename specified" << llendl; - return 0; - } return 0; } diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 64f1af8..1ff995e 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -34,15 +34,12 @@ #include #include #include -#include // linden library includes #include "audioengine.h" #include "indra_constants.h" -#include "llassetuploadresponders.h" #include "llassetstorage.h" #include "llchat.h" -#include "lleconomy.h" #include "llfocusmgr.h" #include "llfontgl.h" #include "llinstantmessage.h" @@ -57,7 +54,6 @@ #include "raytrace.h" #include "llsdserialize.h" #include "lltimer.h" -#include "vorbisencode.h" #include "llvfile.h" #include "llvolumemgr.h" #include "llwindow.h" // for shell_open() @@ -83,7 +79,6 @@ #include "llfloater.h" #include "llfloaterabout.h" #include "llfloaterbuycurrency.h" -#include "llfloateranimpreview.h" #include "llfloateravatarinfo.h" #include "llfloateravatartextures.h" #include "llfloaterbuildoptions.h" @@ -104,21 +99,17 @@ #include "llfloaterhtml.h" #include "llfloaterhtmlhelp.h" #include "llfloaterhtmlfind.h" -#include "llfloaterimport.h" #include "llfloaterinspect.h" #include "llfloaterland.h" #include "llfloaterlandholdings.h" #include "llfloatermap.h" -#include "llfloaterimagepreview.h" #include "llfloatermute.h" -#include "llfloaternamedesc.h" #include "llfloateropenobject.h" #include "llfloaterpermissionsmgr.h" #include "llfloaterpreference.h" #include "llfloaterregioninfo.h" #include "llfloaterreporter.h" #include "llfloaterscriptdebug.h" -#include "llfloatersnapshot.h" #include "llfloatertest.h" #include "llfloatertools.h" #include "llfloaterworldmap.h" @@ -147,8 +138,6 @@ #include "llnotify.h" #include "llpanelobject.h" #include "llparcel.h" -#include "llpreviewscript.h" -#include "llpreviewtexture.h" #include "llprimitive.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -176,8 +165,8 @@ #include "llviewercamera.h" #include "llviewergenericmessage.h" #include "llviewergesture.h" -#include "llviewerimagelist.h" #include "llviewerinventory.h" +#include "llviewermenufile.h" // init_menu_file() #include "llviewermessage.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" @@ -402,7 +391,6 @@ void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new void reload_personal_settings_overrides(void *); void force_breakpoint(void *); void reload_vertex_shader(void *); -void flush_animations(void *); void slow_mo_animations(void *); void handle_disconnect_viewer(void *); @@ -467,6 +455,7 @@ void handle_dump_avatar_local_textures(void*); void handle_debug_avatar_textures(void*); void handle_grab_texture(void*); BOOL enable_grab_texture(void*); +void handle_dump_region_object_cache(void*); BOOL menu_ui_enabled(void *user_data); void check_toggle_control( LLUICtrl *, void* user_data ); @@ -537,7 +526,7 @@ void pre_init_menus() LLMenuItemGL::setHighlightFGColor( color ); } -void initialize_menu_actions(); +void initialize_menus(); //----------------------------------------------------------------------------- // Initialize main menus @@ -565,7 +554,7 @@ void init_menus() LLMenuGL::sMenuContainer = gMenuHolder; // Initialize actions - initialize_menu_actions(); + initialize_menus(); /// /// Popup menu @@ -965,6 +954,8 @@ void init_debug_world_menu(LLMenuGL* menu) NULL, &menu_check_control, (void*)"FixedWeather")); + menu->append(new LLMenuItemCallGL("Dump Region Object Cache", + &handle_dump_region_object_cache, NULL, NULL)); menu->createJumpKeys(); } @@ -1293,7 +1284,6 @@ void init_debug_avatar_menu(LLMenuGL* menu) menu->append(new LLMenuItemCallGL("Force Params to Default", &LLAgent::clearVisualParams, NULL)); menu->append(new LLMenuItemCallGL("Reload Vertex Shader", &reload_vertex_shader, NULL)); menu->append(new LLMenuItemToggleGL("Animation Info", &LLVOAvatar::sShowAnimationDebug)); - menu->append(new LLMenuItemCallGL("Flush Animations", &flush_animations, NULL)); menu->append(new LLMenuItemCallGL("Slow Motion Animations", &slow_mo_animations, NULL)); menu->append(new LLMenuItemToggleGL("Show Look At", &LLHUDEffectLookAt::sDebugLookAt)); menu->append(new LLMenuItemToggleGL("Show Point At", &LLHUDEffectPointAt::sDebugPointAt)); @@ -2041,13 +2031,13 @@ class LLAvatarDebug : public view_listener_t if( avatar ) { avatar->dumpLocalTextures(); + llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl; + std::vector strings; + strings.push_back(avatar->getID().asString()); + LLUUID invoice; + send_generic_message("dumptempassetdata", strings, invoice); + LLFloaterAvatarTextures::show( avatar->getID() ); } - llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl; - std::vector strings; - strings.push_back(avatar->getID().asString()); - LLUUID invoice; - send_generic_message("dumptempassetdata", strings, invoice); - LLFloaterAvatarTextures::show( avatar->getID() ); return true; } }; @@ -2337,16 +2327,6 @@ void handle_buy_contents(LLSaleInfo sale_info) LLFloaterBuyContents::show(sale_info); } -class LLFileEnableSaveAs : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs(); - gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); - return true; - } -}; - void handle_region_dump_temp_asset_data(void*) { llinfos << "Dumping temporary asset data to simulator logs" << llendl; @@ -2397,6 +2377,15 @@ void handle_dump_capabilities_info(void *) } } +void handle_dump_region_object_cache(void*) +{ + LLViewerRegion* regionp = gAgent.getRegion(); + if (regionp) + { + regionp->dumpCache(); + } +} + void handle_dump_focus(void *) { LLView *view = gFocusMgr.getKeyboardFocus(); @@ -4279,7 +4268,10 @@ void show_buy_currency(const char* extra) mesg << "Go to " << BUY_CURRENCY_URL << "\nfor information on purchasing currency?"; LLString::format_map_t args; - args["[EXTRA]"] = extra; + if (extra != NULL) + { + args["[EXTRA]"] = extra; + } args["[URL]"] = BUY_CURRENCY_URL; gViewerWindow->alertXml("PromptGoToCurrencyPage", args, callback_show_buy_currency); @@ -4876,906 +4868,6 @@ void toggle_map( void* user_data ) } } -/** - char* upload_pick(void* data) - - If applicable, brings up a file chooser in which the user selects a file - to upload for a particular task. If the file is valid for the given action, - returns the string to the full path filename, else returns NULL. - Data is the load filter for the type of file as defined in LLFilePicker. -**/ -const char* upload_pick(void* data) -{ - if( gAgent.cameraMouselook() ) - { - gAgent.changeCameraToDefault(); - // This doesn't seem necessary. JC - // display(); - } - - LLFilePicker::ELoadFilter type; - if(data) - { - type = (LLFilePicker::ELoadFilter)((intptr_t)data); - } - else - { - type = LLFilePicker::FFLOAD_ALL; - } - - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getOpenFile(type)) - { - llinfos << "Couldn't import objects from file" << llendl; - return NULL; - } - - const char* filename = picker.getFirstFile(); - const char* ext = strrchr(filename, '.'); - - //strincmp doesn't like NULL pointers - if (ext == NULL) - { - const char* short_name = strrchr(filename, - *gDirUtilp->getDirDelimiter().c_str()); - - // No extension - LLStringBase::format_map_t args; - args["[FILE]"] = LLString(short_name + 1); - gViewerWindow->alertXml("NoFileExtension", args); - return NULL; - } - else - { - //so there is an extension - //loop over the valid extensions and compare to see - //if the extension is valid - - //now grab the set of valid file extensions - const char* valids = build_extensions_string(type); - std::string valid_extensions = std::string(valids); - - BOOL ext_valid = FALSE; - - typedef boost::tokenizer > tokenizer; - boost::char_separator sep(" "); - tokenizer tokens(valid_extensions, sep); - tokenizer::iterator token_iter; - - //now loop over all valid file extensions - //and compare them to the extension of the file - //to be uploaded - for( token_iter = tokens.begin(); - token_iter != tokens.end() && ext_valid != TRUE; - ++token_iter) - { - const char* cur_token = token_iter->c_str(); - - if (0 == strnicmp(cur_token, ext, strlen(cur_token)) || /* Flawfinder: ignore */ - 0 == strnicmp(cur_token, "*.*", strlen(cur_token))) /* Flawfinder: ignore */ - { - //valid extension - //or the acceptable extension is any - ext_valid = TRUE; - } - }//end for (loop over all tokens) - - if (ext_valid == FALSE) - { - //should only get here if the extension exists - //but is invalid - LLStringBase::format_map_t args; - args["[EXTENSION]"] = ext; - args["[VALIDS]"] = valids; - gViewerWindow->alertXml("InvalidFileExtension", args); - return NULL; - } - }//end else (non-null extension) - - //valid file extension - - //now we check to see - //if the file is actually a valid image/sound/etc. - if (type == LLFilePicker::FFLOAD_WAV) - { - // pre-qualify wavs to make sure the format is acceptable - char error_msg[MAX_STRING]; /* Flawfinder: ignore */ - if (check_for_invalid_wav_formats(filename,error_msg)) - { - llinfos << error_msg << ": " << filename << llendl; - LLStringBase::format_map_t args; - args["[FILE]"] = filename; - gViewerWindow->alertXml( error_msg, args ); - return NULL; - } - }//end if a wave/sound file - - - return filename; -} - -void handle_upload_object(void* data) -{ - const char* filename = upload_pick(data); - if (filename) - { - // start the import - LLFloaterImport* floaterp = new LLFloaterImport(filename); - gUICtrlFactory->buildFloater(floaterp, "floater_import.xml"); - } -} - -class LLFileUploadImage : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - const char* filename = upload_pick((void *)(S32)LLFilePicker::FFLOAD_IMAGE); - if (filename) - { - LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename); - gUICtrlFactory->buildFloater(floaterp, "floater_image_preview.xml"); - } - return TRUE; - } -}; - -class LLFileUploadSound : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_WAV)); - if (filename) - { - LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename); - gUICtrlFactory->buildFloater(floaterp, "floater_sound_preview.xml"); - } - return true; - } -}; - -class LLFileUploadAnim : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_ANIM)); - if (filename) - { - LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename); - gUICtrlFactory->buildFloater(floaterp, "floater_animation_preview.xml"); - } - return true; - } -}; - -class LLFileUploadBulk : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - if( gAgent.cameraMouselook() ) - { - gAgent.changeCameraToDefault(); - } - - // TODO: - // Iterate over all files - // Check extensions for uploadability, cost - // Check user balance for entire cost - // Charge user entire cost - // Loop, uploading - // If an upload fails, refund the user for that one - // - // Also fix single upload to charge first, then refund - - LLFilePicker& picker = LLFilePicker::instance(); - if (picker.getMultipleOpenFiles()) - { - const char* filename = picker.getFirstFile(); - const char* name = picker.getDirname(); - - LLString asset_name = name; - LLString::replaceNonstandardASCII( asset_name, '?' ); - LLString::replaceChar(asset_name, '|', '?'); - LLString::stripNonprintable(asset_name); - LLString::trim(asset_name); - - char* asset_name_str = (char*)asset_name.c_str(); - char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists - if( !end_p ) - { - end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */ - } - - S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); - - asset_name = asset_name.substr( 0, len ); - - upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file - } - else - { - llinfos << "Couldn't import objects from file" << llendl; - } - return true; - } -}; - -void upload_error(const char* error_message, const char* label, const std::string filename, const LLStringBase::format_map_t args) -{ - llwarns << error_message << llendl; - gViewerWindow->alertXml(label, args); - if(remove(filename.c_str()) == -1) - { - lldebugs << "unable to remove temp file" << llendl; - } - LLFilePicker::instance().reset(); -} - -class LLFileEnableCloseWindow : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - bool new_value = gFloaterView->getFocusedFloater() != NULL || gSnapshotFloaterView->getFocusedFloater() != NULL; - // horrendously opaque, this code - gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); - return true; - } -}; - -class LLFileCloseWindow : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloater::closeFocusedFloater(); - - return true; - } -}; - -class LLFileSaveTexture : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloater* top = gFloaterView->getFrontmost(); - if (top) - { - top->saveAs(); - } - return true; - } -}; - -class LLFileTakeSnapshot : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLFloaterSnapshot::show(NULL); - return true; - } -}; - -class LLFileTakeSnapshotToDisk : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLPointer raw = new LLImageRaw; - - S32 width = gViewerWindow->getWindowDisplayWidth(); - S32 height = gViewerWindow->getWindowDisplayHeight(); - - if (gSavedSettings.getBOOL("HighResSnapshot")) - { - width *= 2; - height *= 2; - } - - if (gViewerWindow->rawSnapshot(raw, - width, - height, - TRUE, - gSavedSettings.getBOOL("RenderUIInSnapshot"), - FALSE)) - { - if (!gQuietSnapshot) - { - gViewerWindow->playSnapshotAnimAndSound(); - } - LLImageBase::setSizeOverride(TRUE); - gViewerWindow->saveImageNumbered(raw); - LLImageBase::setSizeOverride(FALSE); - } - return true; - } -}; - -class LLFileSaveMovie : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLViewerWindow::saveMovieNumbered(NULL); - return true; - } -}; - -class LLFileSetWindowSize : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLString size = userdata.asString(); - S32 width, height; - sscanf(size.c_str(), "%d,%d", &width, &height); - LLViewerWindow::movieSize(width, height); - return true; - } -}; - -class LLFileQuit : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - app_request_quit(); - return true; - } -}; - -void handle_upload(void* data) -{ - const char* filename = upload_pick(data); - if (filename) - { - LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename); - gUICtrlFactory->buildFloater(floaterp, "floater_name_description.xml"); - } -} - -void handle_compress_image(void*) -{ - LLFilePicker& picker = LLFilePicker::instance(); - if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE)) - { - std::string infile(picker.getFirstFile()); - std::string outfile = infile + ".j2c"; - - llinfos << "Input: " << infile << llendl; - llinfos << "Output: " << outfile << llendl; - - BOOL success; - - success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA); - - if (success) - { - llinfos << "Compression complete" << llendl; - } - else - { - llinfos << "Compression failed: " << LLImageBase::getLastError() << llendl; - } - } -} - -void upload_new_resource(const LLString& src_filename, std::string name, - std::string desc, S32 compression_info, - LLAssetType::EType destination_folder_type, - LLInventoryType::EType inv_type, - U32 next_owner_perm, - const LLString& display_name, - LLAssetStorage::LLStoreAssetCallback callback, - void *userdata) -{ - // Generate the temporary UUID. - LLString filename = gDirUtilp->getTempFilename(); - LLTransactionID tid; - LLAssetID uuid; - - LLStringBase::format_map_t args; - - LLString ext = src_filename.substr(src_filename.find_last_of('.')); - LLAssetType::EType asset_type = LLAssetType::AT_NONE; - char error_message[MAX_STRING]; /* Flawfinder: ignore */ - error_message[0] = '\0'; - LLString temp_str; - - BOOL error = FALSE; - - if (ext.empty()) - { - LLString::size_type offset = filename.find_last_of(gDirUtilp->getDirDelimiter()); - if (offset != LLString::npos) - offset++; - LLString short_name = filename.substr(offset); - - // No extension - snprintf(error_message, /* Flawfinder: ignore */ - MAX_STRING, - "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension", - short_name.c_str()); - args["[FILE]"] = short_name; - upload_error(error_message, "NofileExtension", filename, args); - return; - } - else if( LLString::compareInsensitive(ext.c_str(),".bmp") == 0 ) - { - asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, - filename, - IMG_CODEC_BMP )) - { - snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */ - src_filename.c_str(), LLImageBase::getLastError().c_str()); - args["[FILE]"] = src_filename; - args["[ERROR]"] = LLImageBase::getLastError(); - upload_error(error_message, "ProblemWithFile", filename, args); - return; - } - } - else if( LLString::compareInsensitive(ext.c_str(),".tga") == 0 ) - { - asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, - filename, - IMG_CODEC_TGA )) - { - snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */ - src_filename.c_str(), LLImageBase::getLastError().c_str()); - args["[FILE]"] = src_filename; - args["[ERROR]"] = LLImageBase::getLastError(); - upload_error(error_message, "ProblemWithFile", filename, args); - return; - } - } - else if( LLString::compareInsensitive(ext.c_str(),".jpg") == 0 || LLString::compareInsensitive(ext.c_str(),".jpeg") == 0) - { - asset_type = LLAssetType::AT_TEXTURE; - if (!LLViewerImageList::createUploadFile(src_filename, - filename, - IMG_CODEC_JPEG )) - { - snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */ - src_filename.c_str(), LLImageBase::getLastError().c_str()); - args["[FILE]"] = src_filename; - args["[ERROR]"] = LLImageBase::getLastError(); - upload_error(error_message, "ProblemWithFile", filename, args); - return; - } - } - else if(LLString::compareInsensitive(ext.c_str(),".wav") == 0) - { - asset_type = LLAssetType::AT_SOUND; // tag it as audio - S32 encode_result = 0; - - S32 bitrate = 128; - - if (compression_info) - { - bitrate = compression_info; - } - llinfos << "Attempting to encode wav as an ogg file at " << bitrate << "kbps" << llendl; - - encode_result = encode_vorbis_file_at(src_filename.c_str(), filename.c_str(), bitrate*1000); - - if (LLVORBISENC_NOERR != encode_result) - { - switch(encode_result) - { - case LLVORBISENC_DEST_OPEN_ERR: - snprintf(error_message, MAX_STRING, "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str()); /* Flawfinder: ignore */ - args["[FILE]"] = filename; - upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args); - break; - - default: - snprintf(error_message, MAX_STRING, "Unknown vorbis encode failure on: %s\n", src_filename.c_str()); /* Flawfinder: ignore */ - args["[FILE]"] = src_filename; - upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args); - break; - } - return; - } - } - else if(LLString::compareInsensitive(ext.c_str(),".tmp") == 0) - { - // This is a generic .lin resource file - asset_type = LLAssetType::AT_OBJECT; - FILE* in = LLFile::fopen(src_filename.c_str(), "rb"); /* Flawfinder: ignore */ - if (in) - { - // read in the file header - char buf[16384]; /* Flawfinder: ignore */ - S32 read; /* Flawfinder: ignore */ - S32 version; - if (fscanf(in, "LindenResource\nversion %d\n", &version)) - { - if (2 == version) - { - // *NOTE: This buffer size is hard coded into scanf() below. - char label[MAX_STRING]; /* Flawfinder: ignore */ - char value[MAX_STRING]; /* Flawfinder: ignore */ - S32 tokens_read; - while (fgets(buf, 1024, in)) - { - label[0] = '\0'; - value[0] = '\0'; - tokens_read = sscanf( /* Flawfinder: ignore */ - buf, - "%254s %254s\n", - label, value); - - llinfos << "got: " << label << " = " << value - << llendl; - - if (EOF == tokens_read) - { - fclose(in); - snprintf(error_message, MAX_STRING, "corrupt resource file: %s", src_filename.c_str()); /* Flawfinder: ignore */ - args["[FILE]"] = src_filename; - upload_error(error_message, "CorruptResourceFile", filename, args); - return; - } - - if (2 == tokens_read) - { - if (! strcmp("type", label)) - { - asset_type = (LLAssetType::EType)(atoi(value)); - } - } - else - { - if (! strcmp("_DATA_", label)) - { - // below is the data section - break; - } - } - // other values are currently discarded - } - - } - else - { - fclose(in); - snprintf(error_message, MAX_STRING, "unknown linden resource file version in file: %s", src_filename.c_str()); /* Flawfinder: ignore */ - args["[FILE]"] = src_filename; - upload_error(error_message, "UnknownResourceFileVersion", filename, args); - return; - } - } - else - { - // this is an original binary formatted .lin file - // start over at the beginning of the file - fseek(in, 0, SEEK_SET); - - const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256; - const S32 MAX_ASSET_NAME_LENGTH = 64; - S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH; - S16 type_num; - - // read in and throw out most of the header except for the type - fread(buf, header_size, 1, in); - memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */ - asset_type = (LLAssetType::EType)type_num; - } - - // copy the file's data segment into another file for uploading - FILE* out = LLFile::fopen(filename.c_str(), "wb"); /* Flawfinder: ignore */ - if (out) - { - while((read = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */ - { - fwrite(buf, 1, read, out); /* Flawfinder: ignore */ - } - fclose(out); - } - else - { - fclose(in); - snprintf(error_message, MAX_STRING, "Unable to create output file: %s", filename.c_str()); /* Flawfinder: ignore */ - args["[FILE]"] = filename; - upload_error(error_message, "UnableToCreateOutputFile", filename, args); - return; - } - - fclose(in); - } - else - { - llinfos << "Couldn't open .lin file " << src_filename << llendl; - } - } - else if (LLString::compareInsensitive(ext.c_str(),".bvh") == 0) - { - snprintf(error_message, MAX_STRING, "We do not currently support bulk upload of animation files\n"); /* Flawfinder: ignore */ - upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args); - return; - } - else - { - // Unknown extension - snprintf(error_message, MAX_STRING, "Unknown file extension %s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", ext.c_str()); /* Flawfinder: ignore */ - error = TRUE;; - } - - // gen a new transaction ID for this asset - tid.generate(); - - if (!error) - { - uuid = tid.makeAssetID(gAgent.getSecureSessionID()); - // copy this file into the vfs for upload - S32 file_size; - apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size); - if (fp) - { - LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE); - - file.setMaxSize(file_size); - - const S32 buf_size = 65536; - U8 copy_buf[buf_size]; - while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size))) - { - file.write(copy_buf, file_size); - } - apr_file_close(fp); - } - else - { - snprintf(error_message, MAX_STRING, "Unable to access output file: %s", filename.c_str()); /* Flawfinder: ignore */ - error = TRUE; - } - } - - if (!error) - { - LLString t_disp_name = display_name; - if (t_disp_name.empty()) - { - t_disp_name = src_filename; - } - upload_new_resource(tid, asset_type, name, desc, compression_info, // tid - destination_folder_type, inv_type, next_owner_perm, - display_name, callback, userdata); - } - else - { - llwarns << error_message << llendl; - LLStringBase::format_map_t args; - args["[ERROR_MESSAGE]"] = error_message; - gViewerWindow->alertXml("ErrorMessage", args); - if(LLFile::remove(filename.c_str()) == -1) - { - lldebugs << "unable to remove temp file" << llendl; - } - LLFilePicker::instance().reset(); - } -} - -void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, - std::string name, - std::string desc, S32 compression_info, - LLAssetType::EType destination_folder_type, - LLInventoryType::EType inv_type, - U32 next_owner_perm, - const LLString& display_name, - LLAssetStorage::LLStoreAssetCallback callback, - void *userdata) -{ - LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); - - if( LLAssetType::AT_SOUND == asset_type ) - { - gViewerStats->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT ); - } - else - if( LLAssetType::AT_TEXTURE == asset_type ) - { - gViewerStats->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); - } - else - if( LLAssetType::AT_ANIMATION == asset_type) - { - gViewerStats->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT ); - } - - if(LLInventoryType::IT_NONE == inv_type) - { - inv_type = LLInventoryType::defaultForAssetType(asset_type); - } - LLString::stripNonprintable(name); - LLString::stripNonprintable(desc); - if(name.empty()) - { - name = "(No Name)"; - } - if(desc.empty()) - { - desc = "(No Description)"; - } - - // At this point, we're ready for the upload. - LLString upload_message = "Uploading...\n\n"; - upload_message.append(display_name); - LLUploadDialog::modalUploadDialog(upload_message); - - llinfos << "*** Uploading: " << llendl; - llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl; - llinfos << "UUID: " << uuid << llendl; - llinfos << "Name: " << name << llendl; - llinfos << "Desc: " << desc << llendl; - lldebugs << "Folder: " << gInventory.findCategoryUUIDForType(destination_folder_type) << llendl; - lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; - std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); - if (!url.empty()) - { - llinfos << "New Agent Inventory via capability" << llendl; - LLSD body; - body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type); - body["asset_type"] = LLAssetType::lookup(asset_type); - body["inventory_type"] = LLInventoryType::lookup(inv_type); - body["name"] = name; - body["description"] = desc; - - std::ostringstream llsdxml; - LLSDSerialize::toXML(body, llsdxml); - lldebugs << "posting body to capability: " << llsdxml.str() << llendl; - LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); - } - else - { - llinfos << "NewAgentInventory capability not found, new agent inventory via asset system." << llendl; - // check for adequate funds - // TODO: do this check on the sim - if (LLAssetType::AT_SOUND == asset_type || - LLAssetType::AT_TEXTURE == asset_type || - LLAssetType::AT_ANIMATION == asset_type) - { - S32 upload_cost = gGlobalEconomy->getPriceUpload(); - S32 balance = gStatusBar->getBalance(); - if (balance < upload_cost) - { - // insufficient funds, bail on this upload - LLFloaterBuyCurrency::buyCurrency("Uploading costs", upload_cost); - return; - } - } - - LLResourceData* data = new LLResourceData; - data->mAssetInfo.mTransactionID = tid; - data->mAssetInfo.mUuid = uuid; - data->mAssetInfo.mType = asset_type; - data->mAssetInfo.mCreatorID = gAgentID; - data->mInventoryType = inv_type; - data->mNextOwnerPerm = next_owner_perm; - data->mUserData = userdata; - data->mAssetInfo.setName(name); - data->mAssetInfo.setDescription(desc); - data->mPreferredLocation = destination_folder_type; - - LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback; - if (callback) - { - asset_callback = callback; - } - gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType, - asset_callback, - (void*)data, - FALSE); - } -} - -void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result) // StoreAssetData callback (fixed) -{ - LLResourceData* data = (LLResourceData*)user_data; - //LLAssetType::EType pref_loc = data->mPreferredLocation; - BOOL is_balance_sufficient = TRUE; - if(result >= 0) - { - LLAssetType::EType dest_loc = (data->mPreferredLocation == LLAssetType::AT_NONE) ? data->mAssetInfo.mType : data->mPreferredLocation; - - if (LLAssetType::AT_SOUND == data->mAssetInfo.mType || - LLAssetType::AT_TEXTURE == data->mAssetInfo.mType || - LLAssetType::AT_ANIMATION == data->mAssetInfo.mType) - { - // Charge the user for the upload. - LLViewerRegion* region = gAgent.getRegion(); - S32 upload_cost = gGlobalEconomy->getPriceUpload(); - - if(!(can_afford_transaction(upload_cost))) - { - LLFloaterBuyCurrency::buyCurrency( - llformat("Uploading %s costs", - data->mAssetInfo.getName().c_str()), - upload_cost); - is_balance_sufficient = FALSE; - } - else if(region) - { - // Charge user for upload - gStatusBar->debitBalance(upload_cost); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_MoneyTransferRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_MoneyData); - msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_DestID, LLUUID::null); - msg->addU8("Flags", 0); - msg->addS32Fast(_PREHASH_Amount, upload_cost); - msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY); - msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY); - msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE); - msg->addStringFast(_PREHASH_Description, NULL); - msg->sendReliable(region->getHost()); - } - } - - if(is_balance_sufficient) - { - // Actually add the upload to inventory - llinfos << "Adding " << uuid << " to inventory." << llendl; - LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc)); - if(folder_id.notNull()) - { - U32 next_owner_perm = data->mNextOwnerPerm; - if(PERM_NONE == next_owner_perm) - { - next_owner_perm = PERM_MOVE | PERM_TRANSFER; - } - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), - data->mAssetInfo.getDescription(), data->mAssetInfo.mType, - data->mInventoryType, NOT_WEARABLE, next_owner_perm, - LLPointer(NULL)); - } - else - { - llwarns << "Can't find a folder to put it in" << llendl; - } - } - } - else // if(result >= 0) - { - LLStringBase::format_map_t args; - args["[FILE]"] = LLInventoryType::lookupHumanReadable(data->mInventoryType); - args["[REASON]"] = LLString(LLAssetStorage::getErrorString(result)); - gViewerWindow->alertXml("CannotUploadReason", args); - } - - LLUploadDialog::modalUploadFinished(); - delete data; - - // *NOTE: This is a pretty big hack. What this does is check the - // file picker if there are any more pending uploads. If so, - // upload that file. - const char* next_file = LLFilePicker::instance().getNextFile(); - if(is_balance_sufficient && next_file) - { - const char* name = LLFilePicker::instance().getDirname(); - - LLString asset_name = name; - LLString::replaceNonstandardASCII( asset_name, '?' ); - LLString::replaceChar(asset_name, '|', '?'); - LLString::stripNonprintable(asset_name); - LLString::trim(asset_name); - - char* asset_name_str = (char*)asset_name.c_str(); - char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists - if( !end_p ) - { - end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */ - } - - S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); - - asset_name = asset_name.substr( 0, len ); - - upload_new_resource(next_file, asset_name, asset_name, // file - 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); - } -} LLUUID gExporterRequestID; LLString gExportDirectory; @@ -7634,15 +6726,6 @@ BOOL enable_not_thirdperson(void*) return !gAgent.cameraThirdPerson(); } -class LLFileEnableUpload : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - bool new_value = gStatusBar && gGlobalEconomy && (gStatusBar->getBalance() >= gGlobalEconomy->getPriceUpload()); - gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); - return true; - } -}; BOOL enable_export_selected(void *) { @@ -7857,14 +6940,6 @@ void reload_vertex_shader(void *) //THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP } -void flush_animations(void *) -{ - if (gAgent.getAvatarObject()) - { - gAgent.getAvatarObject()->resetAnimations(); - } -} - void slow_mo_animations(void*) { static BOOL slow_mo = FALSE; @@ -8450,24 +7525,10 @@ class LLToolsSelectTool : public view_listener_t } }; -void initialize_menu_actions() +void initialize_menus() { // File menu - (new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage"); - (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound"); - (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim"); - (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk"); - (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow"); - (new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow"); - (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture"); - (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot"); - (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk"); - (new LLFileSaveMovie())->registerListener(gMenuHolder, "File.SaveMovie"); - (new LLFileSetWindowSize())->registerListener(gMenuHolder, "File.SetWindowSize"); - (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit"); - - (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload"); - (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs"); + init_menu_file(); // Edit menu (new LLEditUndo())->registerListener(gMenuHolder, "Edit.Undo"); diff --git a/linden/indra/newview/llviewermenu.h b/linden/indra/newview/llviewermenu.h index ac2a57a..c223a3a 100644 --- a/linden/indra/newview/llviewermenu.h +++ b/linden/indra/newview/llviewermenu.h @@ -29,8 +29,6 @@ #ifndef LL_LLVIEWERMENU_H #define LL_LLVIEWERMENU_H -#include "llassetstorage.h" -#include "llinventory.h" #include "llmenugl.h" //newview includes @@ -41,14 +39,6 @@ class LLView; class LLParcelSelection; class LLObjectSelection; -struct LLResourceData -{ - LLAssetInfo mAssetInfo; - LLAssetType::EType mPreferredLocation; - LLInventoryType::EType mInventoryType; - U32 mNextOwnerPerm; - void *mUserData; -}; void pre_init_menus(); void init_menus(); @@ -114,25 +104,6 @@ bool handle_give_money_dialog(); bool handle_object_open(); bool handle_go_to(); -void upload_new_resource(const LLString& src_filename, std::string name, - std::string desc, S32 compression_info, - LLAssetType::EType destination_folder_type, - LLInventoryType::EType inv_type, - U32 next_owner_perm = PERM_NONE, - const LLString& display_name = LLString::null, - LLAssetStorage::LLStoreAssetCallback callback = NULL, - void *userdata = NULL); - -void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType type, - std::string name, - std::string desc, S32 compression_info, - LLAssetType::EType destination_folder_type, - LLInventoryType::EType inv_type, - U32 next_owner_perm = PERM_NONE, - const LLString& display_name = LLString::null, - LLAssetStorage::LLStoreAssetCallback callback = NULL, - void *userdata = NULL); - // Export to XML or Collada void handle_export_selected( void * ); diff --git a/linden/indra/newview/llviewermenufile.cpp b/linden/indra/newview/llviewermenufile.cpp new file mode 100644 index 0000000..6954b1c --- /dev/null +++ b/linden/indra/newview/llviewermenufile.cpp @@ -0,0 +1,1022 @@ +/** + * @file llviewermenufile.cpp + * @brief "File" menu in the main menu bar. + * + * Copyright (c) 2002-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewermenufile.h" + +// project includes +#include "llagent.h" +#include "llfilepicker.h" +#include "llfloateranimpreview.h" +#include "llfloaterbuycurrency.h" +#include "llfloaterimagepreview.h" +#include "llfloaterimport.h" +#include "llfloaternamedesc.h" +#include "llfloatersnapshot.h" +#include "llinventorymodel.h" // gInventory +#include "llresourcedata.h" +#include "llstatusbar.h" +#include "llviewercontrol.h" // gSavedSettings +#include "llviewerimagelist.h" +#include "llvieweruictrlfactory.h" +#include "llviewermenu.h" // gMenuHolder +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "llviewerwindow.h" +#include "viewer.h" // app_request_quit() + +// linden libraries +#include "llassetuploadresponders.h" +#include "lleconomy.h" +#include "llhttpclient.h" +#include "llmemberlistener.h" +#include "llsdserialize.h" +#include "llstring.h" +#include "lltransactiontypes.h" +#include "lluuid.h" +#include "vorbisencode.h" + +// system libraries +#include + +typedef LLMemberListener view_listener_t; + + +class LLFileEnableSaveAs : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLFileEnableUpload : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool new_value = gStatusBar && gGlobalEconomy && (gStatusBar->getBalance() >= gGlobalEconomy->getPriceUpload()); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +/** + char* upload_pick(void* data) + + If applicable, brings up a file chooser in which the user selects a file + to upload for a particular task. If the file is valid for the given action, + returns the string to the full path filename, else returns NULL. + Data is the load filter for the type of file as defined in LLFilePicker. +**/ +const char* upload_pick(void* data) +{ + if( gAgent.cameraMouselook() ) + { + gAgent.changeCameraToDefault(); + // This doesn't seem necessary. JC + // display(); + } + + LLFilePicker::ELoadFilter type; + if(data) + { + type = (LLFilePicker::ELoadFilter)((intptr_t)data); + } + else + { + type = LLFilePicker::FFLOAD_ALL; + } + + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getOpenFile(type)) + { + llinfos << "Couldn't import objects from file" << llendl; + return NULL; + } + + const char* filename = picker.getFirstFile(); + const char* ext = strrchr(filename, '.'); + + //strincmp doesn't like NULL pointers + if (ext == NULL) + { + const char* short_name = strrchr(filename, + *gDirUtilp->getDirDelimiter().c_str()); + + // No extension + LLStringBase::format_map_t args; + args["[FILE]"] = LLString(short_name + 1); + gViewerWindow->alertXml("NoFileExtension", args); + return NULL; + } + else + { + //so there is an extension + //loop over the valid extensions and compare to see + //if the extension is valid + + //now grab the set of valid file extensions + const char* valids = build_extensions_string(type); + std::string valid_extensions = std::string(valids); + + BOOL ext_valid = FALSE; + + typedef boost::tokenizer > tokenizer; + boost::char_separator sep(" "); + tokenizer tokens(valid_extensions, sep); + tokenizer::iterator token_iter; + + //now loop over all valid file extensions + //and compare them to the extension of the file + //to be uploaded + for( token_iter = tokens.begin(); + token_iter != tokens.end() && ext_valid != TRUE; + ++token_iter) + { + const char* cur_token = token_iter->c_str(); + + if (0 == strnicmp(cur_token, ext, strlen(cur_token)) || /* Flawfinder: ignore */ + 0 == strnicmp(cur_token, "*.*", strlen(cur_token))) /* Flawfinder: ignore */ + { + //valid extension + //or the acceptable extension is any + ext_valid = TRUE; + } + }//end for (loop over all tokens) + + if (ext_valid == FALSE) + { + //should only get here if the extension exists + //but is invalid + LLStringBase::format_map_t args; + args["[EXTENSION]"] = ext; + args["[VALIDS]"] = valids; + gViewerWindow->alertXml("InvalidFileExtension", args); + return NULL; + } + }//end else (non-null extension) + + //valid file extension + + //now we check to see + //if the file is actually a valid image/sound/etc. + if (type == LLFilePicker::FFLOAD_WAV) + { + // pre-qualify wavs to make sure the format is acceptable + char error_msg[MAX_STRING]; /* Flawfinder: ignore */ + if (check_for_invalid_wav_formats(filename,error_msg)) + { + llinfos << error_msg << ": " << filename << llendl; + LLStringBase::format_map_t args; + args["[FILE]"] = filename; + gViewerWindow->alertXml( error_msg, args ); + return NULL; + } + }//end if a wave/sound file + + + return filename; +} + +void handle_upload_object(void* data) +{ + const char* filename = upload_pick(data); + if (filename) + { + // start the import + LLFloaterImport* floaterp = new LLFloaterImport(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_import.xml"); + } +} + +class LLFileUploadImage : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + const char* filename = upload_pick((void *)(S32)LLFilePicker::FFLOAD_IMAGE); + if (filename) + { + LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_image_preview.xml"); + } + return TRUE; + } +}; + +class LLFileUploadSound : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_WAV)); + if (filename) + { + LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_sound_preview.xml"); + } + return true; + } +}; + +class LLFileUploadAnim : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_ANIM)); + if (filename) + { + LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_animation_preview.xml"); + } + return true; + } +}; + +class LLFileUploadBulk : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + if( gAgent.cameraMouselook() ) + { + gAgent.changeCameraToDefault(); + } + + // TODO: + // Iterate over all files + // Check extensions for uploadability, cost + // Check user balance for entire cost + // Charge user entire cost + // Loop, uploading + // If an upload fails, refund the user for that one + // + // Also fix single upload to charge first, then refund + + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getMultipleOpenFiles()) + { + const char* filename = picker.getFirstFile(); + const char* name = picker.getDirname(); + + LLString asset_name = name; + LLString::replaceNonstandardASCII( asset_name, '?' ); + LLString::replaceChar(asset_name, '|', '?'); + LLString::stripNonprintable(asset_name); + LLString::trim(asset_name); + + char* asset_name_str = (char*)asset_name.c_str(); + char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists + if( !end_p ) + { + end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */ + } + + S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); + + asset_name = asset_name.substr( 0, len ); + + upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file + } + else + { + llinfos << "Couldn't import objects from file" << llendl; + } + return true; + } +}; + +void upload_error(const char* error_message, const char* label, const std::string filename, const LLStringBase::format_map_t args) +{ + llwarns << error_message << llendl; + gViewerWindow->alertXml(label, args); + if(remove(filename.c_str()) == -1) + { + lldebugs << "unable to remove temp file" << llendl; + } + LLFilePicker::instance().reset(); +} + +class LLFileEnableCloseWindow : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool new_value = gFloaterView->getFocusedFloater() != NULL || gSnapshotFloaterView->getFocusedFloater() != NULL; + // horrendously opaque, this code + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLFileCloseWindow : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloater::closeFocusedFloater(); + + return true; + } +}; + +class LLFileCloseAllWindows : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool app_quitting = false; + gFloaterView->closeAllChildren(app_quitting); + + return true; + } +}; + +class LLFileSaveTexture : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloater* top = gFloaterView->getFrontmost(); + if (top) + { + top->saveAs(); + } + return true; + } +}; + +class LLFileTakeSnapshot : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterSnapshot::show(NULL); + return true; + } +}; + +class LLFileTakeSnapshotToDisk : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLPointer raw = new LLImageRaw; + + S32 width = gViewerWindow->getWindowDisplayWidth(); + S32 height = gViewerWindow->getWindowDisplayHeight(); + + if (gSavedSettings.getBOOL("HighResSnapshot")) + { + width *= 2; + height *= 2; + } + + if (gViewerWindow->rawSnapshot(raw, + width, + height, + TRUE, + gSavedSettings.getBOOL("RenderUIInSnapshot"), + FALSE)) + { + if (!gQuietSnapshot) + { + gViewerWindow->playSnapshotAnimAndSound(); + } + LLImageBase::setSizeOverride(TRUE); + gViewerWindow->saveImageNumbered(raw); + LLImageBase::setSizeOverride(FALSE); + } + return true; + } +}; + +class LLFileSaveMovie : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLViewerWindow::saveMovieNumbered(NULL); + return true; + } +}; + +class LLFileSetWindowSize : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLString size = userdata.asString(); + S32 width, height; + sscanf(size.c_str(), "%d,%d", &width, &height); + LLViewerWindow::movieSize(width, height); + return true; + } +}; + +class LLFileQuit : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + app_request_quit(); + return true; + } +}; + +void handle_upload(void* data) +{ + const char* filename = upload_pick(data); + if (filename) + { + LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_name_description.xml"); + } +} + +void handle_compress_image(void*) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE)) + { + std::string infile(picker.getFirstFile()); + std::string outfile = infile + ".j2c"; + + llinfos << "Input: " << infile << llendl; + llinfos << "Output: " << outfile << llendl; + + BOOL success; + + success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA); + + if (success) + { + llinfos << "Compression complete" << llendl; + } + else + { + llinfos << "Compression failed: " << LLImageBase::getLastError() << llendl; + } + } +} + +void upload_new_resource(const LLString& src_filename, std::string name, + std::string desc, S32 compression_info, + LLAssetType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perm, + const LLString& display_name, + LLAssetStorage::LLStoreAssetCallback callback, + void *userdata) +{ + // Generate the temporary UUID. + LLString filename = gDirUtilp->getTempFilename(); + LLTransactionID tid; + LLAssetID uuid; + + LLStringBase::format_map_t args; + + LLString ext = src_filename.substr(src_filename.find_last_of('.')); + LLAssetType::EType asset_type = LLAssetType::AT_NONE; + char error_message[MAX_STRING]; /* Flawfinder: ignore */ + error_message[0] = '\0'; + LLString temp_str; + + BOOL error = FALSE; + + if (ext.empty()) + { + LLString::size_type offset = filename.find_last_of(gDirUtilp->getDirDelimiter()); + if (offset != LLString::npos) + offset++; + LLString short_name = filename.substr(offset); + + // No extension + snprintf(error_message, /* Flawfinder: ignore */ + MAX_STRING, + "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension", + short_name.c_str()); + args["[FILE]"] = short_name; + upload_error(error_message, "NofileExtension", filename, args); + return; + } + else if( LLString::compareInsensitive(ext.c_str(),".bmp") == 0 ) + { + asset_type = LLAssetType::AT_TEXTURE; + if (!LLViewerImageList::createUploadFile(src_filename, + filename, + IMG_CODEC_BMP )) + { + snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */ + src_filename.c_str(), LLImageBase::getLastError().c_str()); + args["[FILE]"] = src_filename; + args["[ERROR]"] = LLImageBase::getLastError(); + upload_error(error_message, "ProblemWithFile", filename, args); + return; + } + } + else if( LLString::compareInsensitive(ext.c_str(),".tga") == 0 ) + { + asset_type = LLAssetType::AT_TEXTURE; + if (!LLViewerImageList::createUploadFile(src_filename, + filename, + IMG_CODEC_TGA )) + { + snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */ + src_filename.c_str(), LLImageBase::getLastError().c_str()); + args["[FILE]"] = src_filename; + args["[ERROR]"] = LLImageBase::getLastError(); + upload_error(error_message, "ProblemWithFile", filename, args); + return; + } + } + else if( LLString::compareInsensitive(ext.c_str(),".jpg") == 0 || LLString::compareInsensitive(ext.c_str(),".jpeg") == 0) + { + asset_type = LLAssetType::AT_TEXTURE; + if (!LLViewerImageList::createUploadFile(src_filename, + filename, + IMG_CODEC_JPEG )) + { + snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */ + src_filename.c_str(), LLImageBase::getLastError().c_str()); + args["[FILE]"] = src_filename; + args["[ERROR]"] = LLImageBase::getLastError(); + upload_error(error_message, "ProblemWithFile", filename, args); + return; + } + } + else if(LLString::compareInsensitive(ext.c_str(),".wav") == 0) + { + asset_type = LLAssetType::AT_SOUND; // tag it as audio + S32 encode_result = 0; + + S32 bitrate = 128; + + if (compression_info) + { + bitrate = compression_info; + } + llinfos << "Attempting to encode wav as an ogg file at " << bitrate << "kbps" << llendl; + + encode_result = encode_vorbis_file_at(src_filename.c_str(), filename.c_str(), bitrate*1000); + + if (LLVORBISENC_NOERR != encode_result) + { + switch(encode_result) + { + case LLVORBISENC_DEST_OPEN_ERR: + snprintf(error_message, MAX_STRING, "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str()); /* Flawfinder: ignore */ + args["[FILE]"] = filename; + upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args); + break; + + default: + snprintf(error_message, MAX_STRING, "Unknown vorbis encode failure on: %s\n", src_filename.c_str()); /* Flawfinder: ignore */ + args["[FILE]"] = src_filename; + upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args); + break; + } + return; + } + } + else if(LLString::compareInsensitive(ext.c_str(),".tmp") == 0) + { + // This is a generic .lin resource file + asset_type = LLAssetType::AT_OBJECT; + FILE* in = LLFile::fopen(src_filename.c_str(), "rb"); /* Flawfinder: ignore */ + if (in) + { + // read in the file header + char buf[16384]; /* Flawfinder: ignore */ + S32 read; /* Flawfinder: ignore */ + S32 version; + if (fscanf(in, "LindenResource\nversion %d\n", &version)) + { + if (2 == version) + { + // *NOTE: This buffer size is hard coded into scanf() below. + char label[MAX_STRING]; /* Flawfinder: ignore */ + char value[MAX_STRING]; /* Flawfinder: ignore */ + S32 tokens_read; + while (fgets(buf, 1024, in)) + { + label[0] = '\0'; + value[0] = '\0'; + tokens_read = sscanf( /* Flawfinder: ignore */ + buf, + "%254s %254s\n", + label, value); + + llinfos << "got: " << label << " = " << value + << llendl; + + if (EOF == tokens_read) + { + fclose(in); + snprintf(error_message, MAX_STRING, "corrupt resource file: %s", src_filename.c_str()); /* Flawfinder: ignore */ + args["[FILE]"] = src_filename; + upload_error(error_message, "CorruptResourceFile", filename, args); + return; + } + + if (2 == tokens_read) + { + if (! strcmp("type", label)) + { + asset_type = (LLAssetType::EType)(atoi(value)); + } + } + else + { + if (! strcmp("_DATA_", label)) + { + // below is the data section + break; + } + } + // other values are currently discarded + } + + } + else + { + fclose(in); + snprintf(error_message, MAX_STRING, "unknown linden resource file version in file: %s", src_filename.c_str()); /* Flawfinder: ignore */ + args["[FILE]"] = src_filename; + upload_error(error_message, "UnknownResourceFileVersion", filename, args); + return; + } + } + else + { + // this is an original binary formatted .lin file + // start over at the beginning of the file + fseek(in, 0, SEEK_SET); + + const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256; + const S32 MAX_ASSET_NAME_LENGTH = 64; + S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH; + S16 type_num; + + // read in and throw out most of the header except for the type + fread(buf, header_size, 1, in); + memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */ + asset_type = (LLAssetType::EType)type_num; + } + + // copy the file's data segment into another file for uploading + FILE* out = LLFile::fopen(filename.c_str(), "wb"); /* Flawfinder: ignore */ + if (out) + { + while((read = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */ + { + fwrite(buf, 1, read, out); /* Flawfinder: ignore */ + } + fclose(out); + } + else + { + fclose(in); + snprintf(error_message, MAX_STRING, "Unable to create output file: %s", filename.c_str()); /* Flawfinder: ignore */ + args["[FILE]"] = filename; + upload_error(error_message, "UnableToCreateOutputFile", filename, args); + return; + } + + fclose(in); + } + else + { + llinfos << "Couldn't open .lin file " << src_filename << llendl; + } + } + else if (LLString::compareInsensitive(ext.c_str(),".bvh") == 0) + { + snprintf(error_message, MAX_STRING, "We do not currently support bulk upload of animation files\n"); /* Flawfinder: ignore */ + upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args); + return; + } + else + { + // Unknown extension + snprintf(error_message, MAX_STRING, "Unknown file extension %s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", ext.c_str()); /* Flawfinder: ignore */ + error = TRUE;; + } + + // gen a new transaction ID for this asset + tid.generate(); + + if (!error) + { + uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + // copy this file into the vfs for upload + S32 file_size; + apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size); + if (fp) + { + LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE); + + file.setMaxSize(file_size); + + const S32 buf_size = 65536; + U8 copy_buf[buf_size]; + while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size))) + { + file.write(copy_buf, file_size); + } + apr_file_close(fp); + } + else + { + snprintf(error_message, MAX_STRING, "Unable to access output file: %s", filename.c_str()); /* Flawfinder: ignore */ + error = TRUE; + } + } + + if (!error) + { + LLString t_disp_name = display_name; + if (t_disp_name.empty()) + { + t_disp_name = src_filename; + } + upload_new_resource(tid, asset_type, name, desc, compression_info, // tid + destination_folder_type, inv_type, next_owner_perm, + display_name, callback, userdata); + } + else + { + llwarns << error_message << llendl; + LLStringBase::format_map_t args; + args["[ERROR_MESSAGE]"] = error_message; + gViewerWindow->alertXml("ErrorMessage", args); + if(LLFile::remove(filename.c_str()) == -1) + { + lldebugs << "unable to remove temp file" << llendl; + } + LLFilePicker::instance().reset(); + } +} + +void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result) // StoreAssetData callback (fixed) +{ + LLResourceData* data = (LLResourceData*)user_data; + //LLAssetType::EType pref_loc = data->mPreferredLocation; + BOOL is_balance_sufficient = TRUE; + if(result >= 0) + { + LLAssetType::EType dest_loc = (data->mPreferredLocation == LLAssetType::AT_NONE) ? data->mAssetInfo.mType : data->mPreferredLocation; + + if (LLAssetType::AT_SOUND == data->mAssetInfo.mType || + LLAssetType::AT_TEXTURE == data->mAssetInfo.mType || + LLAssetType::AT_ANIMATION == data->mAssetInfo.mType) + { + // Charge the user for the upload. + LLViewerRegion* region = gAgent.getRegion(); + S32 upload_cost = gGlobalEconomy->getPriceUpload(); + + if(!(can_afford_transaction(upload_cost))) + { + LLFloaterBuyCurrency::buyCurrency( + llformat("Uploading %s costs", + data->mAssetInfo.getName().c_str()), + upload_cost); + is_balance_sufficient = FALSE; + } + else if(region) + { + // Charge user for upload + gStatusBar->debitBalance(upload_cost); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MoneyTransferRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_MoneyData); + msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_DestID, LLUUID::null); + msg->addU8("Flags", 0); + msg->addS32Fast(_PREHASH_Amount, upload_cost); + msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY); + msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY); + msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE); + msg->addStringFast(_PREHASH_Description, NULL); + msg->sendReliable(region->getHost()); + } + } + + if(is_balance_sufficient) + { + // Actually add the upload to inventory + llinfos << "Adding " << uuid << " to inventory." << llendl; + LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc)); + if(folder_id.notNull()) + { + U32 next_owner_perm = data->mNextOwnerPerm; + if(PERM_NONE == next_owner_perm) + { + next_owner_perm = PERM_MOVE | PERM_TRANSFER; + } + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), + data->mAssetInfo.getDescription(), data->mAssetInfo.mType, + data->mInventoryType, NOT_WEARABLE, next_owner_perm, + LLPointer(NULL)); + } + else + { + llwarns << "Can't find a folder to put it in" << llendl; + } + } + } + else // if(result >= 0) + { + LLStringBase::format_map_t args; + args["[FILE]"] = LLInventoryType::lookupHumanReadable(data->mInventoryType); + args["[REASON]"] = LLString(LLAssetStorage::getErrorString(result)); + gViewerWindow->alertXml("CannotUploadReason", args); + } + + LLUploadDialog::modalUploadFinished(); + delete data; + + // *NOTE: This is a pretty big hack. What this does is check the + // file picker if there are any more pending uploads. If so, + // upload that file. + const char* next_file = LLFilePicker::instance().getNextFile(); + if(is_balance_sufficient && next_file) + { + const char* name = LLFilePicker::instance().getDirname(); + + LLString asset_name = name; + LLString::replaceNonstandardASCII( asset_name, '?' ); + LLString::replaceChar(asset_name, '|', '?'); + LLString::stripNonprintable(asset_name); + LLString::trim(asset_name); + + char* asset_name_str = (char*)asset_name.c_str(); + char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists + if( !end_p ) + { + end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */ + } + + S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); + + asset_name = asset_name.substr( 0, len ); + + upload_new_resource(next_file, asset_name, asset_name, // file + 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); + } +} + +void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, + std::string name, + std::string desc, S32 compression_info, + LLAssetType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perm, + const LLString& display_name, + LLAssetStorage::LLStoreAssetCallback callback, + void *userdata) +{ + LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + + if( LLAssetType::AT_SOUND == asset_type ) + { + gViewerStats->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT ); + } + else + if( LLAssetType::AT_TEXTURE == asset_type ) + { + gViewerStats->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); + } + else + if( LLAssetType::AT_ANIMATION == asset_type) + { + gViewerStats->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT ); + } + + if(LLInventoryType::IT_NONE == inv_type) + { + inv_type = LLInventoryType::defaultForAssetType(asset_type); + } + LLString::stripNonprintable(name); + LLString::stripNonprintable(desc); + if(name.empty()) + { + name = "(No Name)"; + } + if(desc.empty()) + { + desc = "(No Description)"; + } + + // At this point, we're ready for the upload. + LLString upload_message = "Uploading...\n\n"; + upload_message.append(display_name); + LLUploadDialog::modalUploadDialog(upload_message); + + llinfos << "*** Uploading: " << llendl; + llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl; + llinfos << "UUID: " << uuid << llendl; + llinfos << "Name: " << name << llendl; + llinfos << "Desc: " << desc << llendl; + lldebugs << "Folder: " << gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type) << llendl; + lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; + std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); + if (!url.empty()) + { + llinfos << "New Agent Inventory via capability" << llendl; + LLSD body; + body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type); + body["asset_type"] = LLAssetType::lookup(asset_type); + body["inventory_type"] = LLInventoryType::lookup(inv_type); + body["name"] = name; + body["description"] = desc; + + std::ostringstream llsdxml; + LLSDSerialize::toXML(body, llsdxml); + lldebugs << "posting body to capability: " << llsdxml.str() << llendl; + LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); + } + else + { + llinfos << "NewAgentInventory capability not found, new agent inventory via asset system." << llendl; + // check for adequate funds + // TODO: do this check on the sim + if (LLAssetType::AT_SOUND == asset_type || + LLAssetType::AT_TEXTURE == asset_type || + LLAssetType::AT_ANIMATION == asset_type) + { + S32 upload_cost = gGlobalEconomy->getPriceUpload(); + S32 balance = gStatusBar->getBalance(); + if (balance < upload_cost) + { + // insufficient funds, bail on this upload + LLFloaterBuyCurrency::buyCurrency("Uploading costs", upload_cost); + return; + } + } + + LLResourceData* data = new LLResourceData; + data->mAssetInfo.mTransactionID = tid; + data->mAssetInfo.mUuid = uuid; + data->mAssetInfo.mType = asset_type; + data->mAssetInfo.mCreatorID = gAgentID; + data->mInventoryType = inv_type; + data->mNextOwnerPerm = next_owner_perm; + data->mUserData = userdata; + data->mAssetInfo.setName(name); + data->mAssetInfo.setDescription(desc); + data->mPreferredLocation = destination_folder_type; + + LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback; + if (callback) + { + asset_callback = callback; + } + gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType, + asset_callback, + (void*)data, + FALSE); + } +} + + +void init_menu_file() +{ + (new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage"); + (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound"); + (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim"); + (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk"); + (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow"); + (new LLFileCloseAllWindows())->registerListener(gMenuHolder, "File.CloseAllWindows"); + (new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow"); + (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture"); + (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot"); + (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk"); + (new LLFileSaveMovie())->registerListener(gMenuHolder, "File.SaveMovie"); + (new LLFileSetWindowSize())->registerListener(gMenuHolder, "File.SetWindowSize"); + (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit"); + + (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload"); + (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs"); +} diff --git a/linden/indra/newview/llviewermenufile.h b/linden/indra/newview/llviewermenufile.h new file mode 100644 index 0000000..32806fb --- /dev/null +++ b/linden/indra/newview/llviewermenufile.h @@ -0,0 +1,59 @@ +/** + * @file llviewermenufile.h + * @brief "File" menu in the main menu bar. + * + * Copyright (c) 2002-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + */ + +#ifndef LLVIEWERMENUFILE_H +#define LLVIEWERMENUFILE_H + +#include "llassettype.h" +#include "llinventorytype.h" + +class LLTransactionID; + + +void init_menu_file(); + +void upload_new_resource(const LLString& src_filename, std::string name, + std::string desc, S32 compression_info, + LLAssetType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perm = 0x0, // PERM_NONE + const LLString& display_name = LLString::null, + LLAssetStorage::LLStoreAssetCallback callback = NULL, + void *userdata = NULL); + +void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType type, + std::string name, + std::string desc, S32 compression_info, + LLAssetType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perm = 0x0, // PERM_NONE + const LLString& display_name = LLString::null, + LLAssetStorage::LLStoreAssetCallback callback = NULL, + void *userdata = NULL); + +#endif diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index 5dab363..5eafd9d 100644 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -145,8 +145,14 @@ extern BOOL gDebugClicks; extern void bad_network_handler(); // function prototypes -void open_offer(const std::vector& items); +void open_offer(const std::vector& items, const std::string& from_name); void friendship_offer_callback(S32 option, void* user_data); +bool check_offer_throttle(const std::string& from_name, bool check_only); + +//inventory offer throttle globals +LLFrameTimer gThrottleTimer; +const U32 OFFER_THROTTLE_MAX_COUNT=5; //number of items per time period +const F32 OFFER_THROTTLE_TIME=10.f; //time period in seconds struct LLFriendshipOffer { @@ -195,11 +201,6 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_ } } -BOOL can_afford_transaction(S32 cost) -{ - return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost))); -} - void send_complete_agent_movement(const LLHost& sim_host) { LLMessageSystem* msg = gMessageSystem; @@ -275,11 +276,19 @@ void process_layer_data(LLMessageSystem *mesgsys, void **user_data) mesgsys->getS8Fast(_PREHASH_LayerID, _PREHASH_Type, type); size = mesgsys->getSizeFast(_PREHASH_LayerData, _PREHASH_Data); - if(!size) + if (0 == size) { llwarns << "Layer data has zero size." << llendl; return; } + if (size < 0) + { + // getSizeFast() is probably trying to tell us about an error + llwarns << "getSizeFast() returned negative result: " + << size + << llendl; + return; + } U8 *datap = new U8[size]; mesgsys->getBinaryDataFast(_PREHASH_LayerData, _PREHASH_Data, datap, size); LLVLData *vl_datap = new LLVLData(regionp, type, datap, size); @@ -326,25 +335,29 @@ void export_complete() while ((pos = strstr(pos+1, ""); - if (pos_check && pos_uuid) + if (pos_check) { - char image_uuid_str[UUID_STR_SIZE]; /* Flawfinder: ignore */ - memcpy(image_uuid_str, pos_uuid+2, UUID_STR_SIZE-1); /* Flawfinder: ignore */ - image_uuid_str[UUID_STR_SIZE-1] = 0; + char *pos_uuid = strstr(pos_check, "\">"); - LLUUID image_uuid(image_uuid_str); + if (pos_uuid) + { + char image_uuid_str[UUID_STR_SIZE]; /* Flawfinder: ignore */ + memcpy(image_uuid_str, pos_uuid+2, UUID_STR_SIZE-1); /* Flawfinder: ignore */ + image_uuid_str[UUID_STR_SIZE-1] = 0; + + LLUUID image_uuid(image_uuid_str); - llinfos << "Found UUID: " << image_uuid << llendl; + llinfos << "Found UUID: " << image_uuid << llendl; - std::map::iterator itor = gImageChecksums.find(image_uuid); - if (itor != gImageChecksums.end()) - { - llinfos << "Replacing with checksum: " << itor->second << llendl; - if (itor->second.c_str() != NULL) + std::map::iterator itor = gImageChecksums.find(image_uuid); + if (itor != gImageChecksums.end()) { - memcpy(&pos_check[10], itor->second.c_str(), 32); /* Flawfinder: ignore */ + llinfos << "Replacing with checksum: " << itor->second << llendl; + if (itor->second.c_str() != NULL) + { + memcpy(&pos_check[10], itor->second.c_str(), 32); /* Flawfinder: ignore */ + } } } } @@ -354,7 +367,7 @@ void export_complete() fwrite(buffer, 1, length, fXMLOut); fclose(fXMLOut); - delete buffer; + delete [] buffer; } @@ -432,7 +445,7 @@ void exported_j2c_complete(const LLTSCode status, void *user_data) char *end = strrchr(file_path, gDirUtilp->getDirDelimiter()[0]); end[0] = 0; LLString output_file = llformat("%s/image-%03d.tga", file_path, image_num);//filename; - delete file_path; + delete [] file_path; //S32 name_len = output_file.length(); //strcpy(&output_file[name_len-3], "tga"); FILE* fOut = LLFile::fopen(output_file.c_str(), "wb"); /* Flawfinder: ignore */ @@ -599,31 +612,44 @@ void join_group_callback(S32 option, void* user_data) class LLOpenAgentOffer : public LLInventoryFetchObserver { public: - LLOpenAgentOffer() {} - virtual ~LLOpenAgentOffer() {} - - virtual void done() + LLOpenAgentOffer(const std::string& from_name) : mFromName(from_name) {} + /*virtual*/ void done() { - open_offer(mComplete); + open_offer(mComplete, mFromName); gInventory.removeObserver(this); delete this; } +private: + std::string mFromName; }; -class LLOpenTaskOffer : public LLInventoryExistenceObserver +//unlike the FetchObserver for AgentOffer, we only make one +//instance of the AddedObserver for TaskOffers +//and it never dies. We do this because we don't know the UUID of +//task offers until they are accepted, so we don't wouldn't +//know what to watch for, so instead we just watch for all additions. -Gigs +class LLOpenTaskOffer : public LLInventoryAddedObserver { -public: - LLOpenTaskOffer() {} - virtual ~LLOpenTaskOffer() {} - protected: - virtual void done() + /*virtual*/ void done() { - open_offer(mExist); - gInventory.removeObserver(this); - delete this; + open_offer(mAdded, ""); + mAdded.clear(); } -}; + }; + +//one global instance to bind them +LLOpenTaskOffer* gNewInventoryObserver=NULL; + +void start_new_inventory_observer() +{ + if (!gNewInventoryObserver) //task offer observer + { + // Observer is deleted by gInventory + gNewInventoryObserver = new LLOpenTaskOffer; + gInventory.addObserver(gNewInventoryObserver); + } +} class LLDiscardAgentOffer : public LLInventoryFetchComboObserver { @@ -675,7 +701,71 @@ protected: }; -void open_offer(const std::vector& items) +//Returns TRUE if we are OK, FALSE if we are throttled +//Set check_only true if you want to know the throttle status +//without registering a hit -Gigs +bool check_offer_throttle(const std::string& from_name, bool check_only) +{ + static U32 throttle_count; + static bool throttle_logged; + LLChat chat; + LLString log_message; + + if (!gSavedSettings.getBOOL("ShowNewInventory")) + return false; + + if (check_only) + { + return gThrottleTimer.hasExpired(); + } + + if(gThrottleTimer.checkExpirationAndReset(OFFER_THROTTLE_TIME)) + { + //llinfos << "Throttle Expired" << llendl; + throttle_count=1; + throttle_logged=false; + return true; + } + else //has not expired + { + //llinfos << "Throttle Not Expired, Count: " << throttle_count << llendl; + // When downloading the initial inventory we get a lot of new items + // coming in and can't tell that from spam. JC + if (gStartupState >= STATE_STARTED + && throttle_count >= OFFER_THROTTLE_MAX_COUNT) + { + if (!throttle_logged) + { + // Use the name of the last item giver, who is probably the person + // spamming you. JC + std::ostringstream message; + message << gSecondLife; + if (!from_name.empty()) + { + message << ": Items coming in too fast from " << from_name; + } + else + { + message << ": Items coming in too fast"; + } + message << ", automatic preview disabled for " + << OFFER_THROTTLE_TIME << " seconds."; + chat.mText = message.str(); + //this is kinda important, so actually put it on screen + LLFloaterChat::addChat(chat, FALSE, FALSE); + throttle_logged=true; + } + return false; + } + else + { + throttle_count++; + return true; + } + } +} + +void open_offer(const std::vector& items, const std::string& from_name) { std::vector::const_iterator it = items.begin(); std::vector::const_iterator end = items.end(); @@ -693,33 +783,66 @@ void open_offer(const std::vector& items) { continue; } - switch(item->getType()) + //if we are throttled, don't display them - Gigs + if (check_offer_throttle(from_name, false)) { - case LLAssetType::AT_NOTECARD: - open_notecard(*it, LLString("Note: ") + item->getName(), TRUE, LLUUID::null, FALSE); - break; - case LLAssetType::AT_LANDMARK: - open_landmark(*it, LLString("Landmark: ") + item->getName(), TRUE, LLUUID::null, FALSE); - break; - case LLAssetType::AT_TEXTURE: - open_texture(*it, LLString("Texture: ") + item->getName(), TRUE, LLUUID::null, FALSE); - break; - default: - { - // Don't auto-open the inventory - just select it if we - // already have an active inventory. - LLInventoryView* view = LLInventoryView::getActiveInventory(); - if(view) + // I'm not sure this is a good idea. JC + // bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID(); + bool show_keep_discard = true; + switch(item->getType()) { - LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); - LLFocusMgr::FocusLostCallback callback; - callback = gFocusMgr.getFocusCallback(); - view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO); - gFocusMgr.setKeyboardFocus(focus_ctrl, callback); + case LLAssetType::AT_NOTECARD: + open_notecard(*it, LLString("Note: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); + break; + case LLAssetType::AT_LANDMARK: + open_landmark(*it, LLString("Landmark: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); + break; + case LLAssetType::AT_TEXTURE: + open_texture(*it, LLString("Texture: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE); + break; + default: break; } } + //highlight item, if it's not in the trash or lost+found + + // Don't auto-open the inventory floater + LLInventoryView* view = LLInventoryView::getActiveInventory(); + if(!view) + { + return; + } + + //Trash Check + LLUUID trash_id; + trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH); + if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) + { + return; } + LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); + //BOOL inventory_has_focus = gFocusMgr.childHasKeyboardFocus(view); + BOOL user_is_away = gAwayTimer.getStarted(); + + // don't select lost and found items if the user is active + if (gInventory.isObjectDescendentOf(item->getUUID(), lost_and_found_id) + && !user_is_away) + { + return; + } + + //Not sure about this check. Could make it easy to miss incoming items. -Gigs + //don't dick with highlight while the user is working + //if(inventory_has_focus && !user_is_away) + // break; + //llinfos << "Highlighting" << item->getUUID() << llendl; + //highlight item + + LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); + LLFocusMgr::FocusLostCallback callback; + callback = gFocusMgr.getFocusCallback(); + view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO); + gFocusMgr.setKeyboardFocus(focus_ctrl, callback); } } @@ -807,11 +930,11 @@ void inventory_offer_callback(S32 option, void* user_data) char group_name[MAX_STRING]; /* Flawfinder: ignore */ if (gCacheName->getGroupName(info->mFromID, group_name)) { - from_string = LLString("An object named ") + info->mFromName + " owned by the group '" + group_name + "'"; + from_string = LLString("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'"; } else { - from_string = LLString("An object named ") + info->mFromName + " owned by an unknown group"; + from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown group"; } } else @@ -820,11 +943,11 @@ void inventory_offer_callback(S32 option, void* user_data) char last_name[MAX_STRING]; /* Flawfinder: ignore */ if (gCacheName->getName(info->mFromID, first_name, last_name)) { - from_string = LLString("An object named ") + info->mFromName + " owned by " + first_name + " " + last_name; + from_string = LLString("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name; } else { - from_string = LLString("An object named ") + info->mFromName + " owned by an unknown user"; + from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown user"; } } } @@ -833,9 +956,11 @@ void inventory_offer_callback(S32 option, void* user_data) from_string = info->mFromName; } + bool busy=FALSE; + switch(option) { - case 0: + case IOR_ACCEPT: // ACCEPT. The math for the dialog works, because the accept // for inventory_offered, task_inventory_offer or // group_notice_inventory is 1 greater than the offer integer value. @@ -846,9 +971,15 @@ void inventory_offer_callback(S32 option, void* user_data) sizeof(info->mFolderID.mData)); // send the message msg->sendReliable(info->mHost); - log_message = info->mFromName + " gave you " + info->mDesc + "."; - chat.mText = log_message; - LLFloaterChat::addChatHistory(chat); + + //don't spam them if they are getting flooded + if (check_offer_throttle(info->mFromName, true)) + { + log_message = info->mFromName + " gave you " + info->mDesc + "."; + chat.mText = log_message; + LLFloaterChat::addChatHistory(chat); + } + // we will want to open this item when it comes back. lldebugs << "Initializing an opener for tid: " << info->mTransactionID << llendl; @@ -861,7 +992,7 @@ void inventory_offer_callback(S32 option, void* user_data) // so we can fetch it out of our inventory. LLInventoryFetchObserver::item_ref_t items; items.push_back(info->mObjectID); - LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer; + LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string); open_agent_offer->fetchItems(items); if(catp || (itemp && itemp->isComplete())) { @@ -877,22 +1008,10 @@ void inventory_offer_callback(S32 option, void* user_data) case IM_GROUP_NOTICE: case IM_GROUP_NOTICE_REQUESTED: { - // This is an offer from a task or group. - // Because it would be easy - // to write a task which would overload your inventory, we - // force the offer to stay in an instant message until - // accepted. Thus, we have to respond, and then wait for - // the update to come back before we open the item. - LLOpenTaskOffer* open_task_offer = new LLOpenTaskOffer; - open_task_offer->watchItem(info->mObjectID); - if(itemp && itemp->isComplete()) - { - opener->changed(0x0); - } - else - { - opener = open_task_offer; - } + // This is an offer from a task or group. + // We don't use a new instance of an opener + // We instead use the singular observer gOpenTaskOffer + // Since it already exists, we don't need to actually do anything } break; default: @@ -901,9 +1020,12 @@ void inventory_offer_callback(S32 option, void* user_data) } break; - case 2: + case IOR_BUSY: + //Busy falls through to decline. Says to make busy message. + busy=TRUE; + case IOR_MUTE: // MUTE falls through to decline - case 1: + case IOR_DECLINE: // DECLINE. The math for the dialog works, because the decline // for inventory_offered, task_inventory_offer or // group_notice_inventory is 2 greater than the offer integer value. @@ -941,7 +1063,7 @@ void inventory_offer_callback(S32 option, void* user_data) } } - if (!info->mFromGroup && !info->mFromObject) + if (busy || (!info->mFromGroup && !info->mFromObject)) { busy_message(msg,info->mFromID); } @@ -964,88 +1086,73 @@ void inventory_offer_callback(S32 option, void* user_data) void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) { - switch(info->mType) + + //Until throttling is implmented, busy mode should reject inventory instead of silently + //accepting it. SEE SL-39554 + if (gAgent.getBusy()) + { + inventory_offer_callback(IOR_BUSY, info); + return; + } + + //If muted, don't even go through the messaging stuff. Just curtail the offer here. + if (gMuteListp->isMuted(info->mFromID, info->mFromName)) + { + inventory_offer_callback(IOR_MUTE, info); + return; + } + + if (gSavedSettings.getBOOL("ShowNewInventory") + && (info->mType == LLAssetType::AT_NOTECARD + || info->mType == LLAssetType::AT_LANDMARK + || info->mType == LLAssetType::AT_TEXTURE)) { // For certain types, just accept the items into the inventory, // and we'll automatically open them on receipt. - case LLAssetType::AT_NOTECARD: - case LLAssetType::AT_LANDMARK: - case LLAssetType::AT_TEXTURE: - { - // 0 = accept button - inventory_offer_callback(0, info); - //LLInventoryView::sOpenNextNewItem = TRUE; - } - break; - - case LLAssetType::AT_SOUND: - case LLAssetType::AT_CALLINGCARD: - case LLAssetType::AT_SCRIPT: - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_OBJECT: - case LLAssetType::AT_CATEGORY: - case LLAssetType::AT_ROOT_CATEGORY: - case LLAssetType::AT_LSL_TEXT: - case LLAssetType::AT_LSL_BYTECODE: - case LLAssetType::AT_TEXTURE_TGA: - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_TRASH: - case LLAssetType::AT_SNAPSHOT_CATEGORY: - case LLAssetType::AT_LOST_AND_FOUND: - case LLAssetType::AT_ANIMATION: - case LLAssetType::AT_GESTURE: - default: - { - LLString::format_map_t args; - args["[OBJECTNAME]"] = info->mDesc; - args["[OBJECTTYPE]"] = LLAssetType::lookupHumanReadable(info->mType); - - // Name cache callbacks don't store userdata, so can't save - // off the LLOfferInfo. Argh. JC - BOOL name_found = FALSE; - char first_name[MAX_STRING]; /* Flawfinder: ignore */ - char last_name[MAX_STRING]; /* Flawfinder: ignore */ - if (info->mFromGroup) - { - if (gCacheName->getGroupName(info->mFromID, first_name)) - { - args["[FIRST]"] = first_name; - args["[LAST]"] = ""; - name_found = TRUE; - } - } - else - { - if (gCacheName->getName(info->mFromID, first_name, last_name)) - { - args["[FIRST]"] = first_name; - args["[LAST]"] = last_name; - name_found = TRUE; - } - } - if (from_task) - { - args["[OBJECTFROMNAME]"] = info->mFromName; - if (name_found) - { - LLNotifyBox::showXml("ObjectGiveItem", args, - &inventory_offer_callback, (void*)info); - } - else - { - LLNotifyBox::showXml("ObjectGiveItemUnknownUser", args, - &inventory_offer_callback, (void*)info); - } - } - else - { - // XUI:translate -> [FIRST] [LAST] - args["[NAME]"] = info->mFromName; - LLNotifyBox::showXml("UserGiveItem", args, - &inventory_offer_callback, (void*)info); - } - break; - } + // 0 = accept button + inventory_offer_callback(IOR_ACCEPT, info); + return; + } + + LLString::format_map_t args; + args["[OBJECTNAME]"] = info->mDesc; + args["[OBJECTTYPE]"] = LLAssetType::lookupHumanReadable(info->mType); + + // Name cache callbacks don't store userdata, so can't save + // off the LLOfferInfo. Argh. JC + BOOL name_found = FALSE; + char first_name[MAX_STRING]; /* Flawfinder: ignore */ + char last_name[MAX_STRING]; /* Flawfinder: ignore */ + if (info->mFromGroup) + { + if (gCacheName->getGroupName(info->mFromID, first_name)) + { + args["[FIRST]"] = first_name; + args["[LAST]"] = ""; + name_found = TRUE; + } + } + else + { + if (gCacheName->getName(info->mFromID, first_name, last_name)) + { + args["[FIRST]"] = first_name; + args["[LAST]"] = last_name; + name_found = TRUE; + } + } + if (from_task) + { + args["[OBJECTFROMNAME]"] = info->mFromName; + LLNotifyBox::showXml(name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser", + args, &inventory_offer_callback, (void*)info); + } + else + { + // XUI:translate -> [FIRST] [LAST] + args["[NAME]"] = info->mFromName; + LLNotifyBox::showXml("UserGiveItem", args, + &inventory_offer_callback, (void*)info); } } @@ -1538,10 +1645,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else { - if (dialog == IM_TASK_INVENTORY_OFFERED) - inventory_offer_handler(info, TRUE); - else - inventory_offer_handler(info, FALSE); + inventory_offer_handler(info, dialog == IM_TASK_INVENTORY_OFFERED); } } break; @@ -1760,6 +1864,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_GOTO_URL: { + if (binary_bucket_size <= 0) + { + llwarns << "bad binary_bucket_size: " + << binary_bucket_size + << " - aborting function." << llendl; + return; + } + char* url = new char[binary_bucket_size]; if (url == NULL) { @@ -1985,16 +2097,22 @@ void process_offer_callingcard(LLMessageSystem* msg, void**) { // automatically decline offer callingcard_offer_callback(1, (void*)offerdata); - return; + offerdata = NULL; // pointer was freed by callback + } + else + { + LLNotifyBox::showXml("OfferCallingCard", args, + &callingcard_offer_callback, (void*)offerdata); + offerdata = NULL; // pointer ownership transferred } - - LLNotifyBox::showXml("OfferCallingCard", args, - &callingcard_offer_callback, (void*)offerdata); } else { llwarns << "Calling card offer from an unknown source." << llendl; } + + delete offerdata; // !=NULL if we didn't give ownership away + offerdata = NULL; } void process_accept_callingcard(LLMessageSystem* msg, void**) @@ -3609,7 +3727,7 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data) if (object) { LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation()); - if (!use_autopilot || (avatar->mIsSitting && avatar->getRoot() == object->getRoot())) + if (!use_autopilot || (avatar && avatar->mIsSitting && avatar->getRoot() == object->getRoot())) { //we're already sitting on this object, so don't autopilot } @@ -5002,9 +5120,10 @@ void onCovenantLoadComplete(LLVFS *vfs, if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) ) { - LLViewerTextEditor* editor = new LLViewerTextEditor("temp", - LLRect(0,0,0,0), - file_length+1); + LLViewerTextEditor* editor = + new LLViewerTextEditor("temp", + LLRect(0,0,0,0), + file_length+1); if( !editor->importBuffer( buffer ) ) { llwarns << "Problem importing estate covenant." << llendl; @@ -5020,27 +5139,32 @@ void onCovenantLoadComplete(LLVFS *vfs, } else { - if( gViewerStats ) - { - gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - } - - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || - LL_ERR_FILE_EMPTY == status) - { - covenant_text = "Estate covenant notecard is missing from database."; - } - else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) - { - covenant_text = "Insufficient permissions to view estate covenant."; - } - else - { - covenant_text = "Unable to load estate covenant at this time."; - } - - llwarns << "Problem loading notecard: " << status << llendl; + llwarns << "Problem importing estate covenant: Covenant file format error." << llendl; + covenant_text = "Problem importing estate covenant: Covenant file format error."; + } + } + else + { + if( gViewerStats ) + { + gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); } + + if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || + LL_ERR_FILE_EMPTY == status) + { + covenant_text = "Estate covenant notecard is missing from database."; + } + else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) + { + covenant_text = "Insufficient permissions to view estate covenant."; + } + else + { + covenant_text = "Unable to load estate covenant at this time."; + } + + llwarns << "Problem loading notecard: " << status << llendl; } LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid); LLPanelLandCovenant::updateCovenantText(covenant_text); diff --git a/linden/indra/newview/llviewermessage.h b/linden/indra/newview/llviewermessage.h index ce8f6a7..14f2cda 100644 --- a/linden/indra/newview/llviewermessage.h +++ b/linden/indra/newview/llviewermessage.h @@ -48,6 +48,14 @@ class LLViewerRegion; // Prototypes // +enum InventoryOfferResponse +{ + IOR_ACCEPT, + IOR_DECLINE, + IOR_MUTE, + IOR_BUSY +}; + BOOL can_afford_transaction(S32 cost); void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE, S32 trx_type = TRANS_GIFT, const LLString& desc = LLString::null); @@ -190,6 +198,7 @@ void invalid_message_callback(LLMessageSystem*, void*, EMessageException); void process_initiate_download(LLMessageSystem* msg, void**); void inventory_offer_callback(S32 option, void* user_data); +void start_new_inventory_observer(); struct LLOfferInfo { diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp index 5cb65b6..58d57b5 100644 --- a/linden/indra/newview/llviewerobject.cpp +++ b/linden/indra/newview/llviewerobject.cpp @@ -639,10 +639,10 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) } U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, - const EObjectUpdateType update_type, - LLDataPacker *dp) + void **user_data, + U32 block_num, + const EObjectUpdateType update_type, + LLDataPacker *dp) { LLMemType mt(LLMemType::MTYPE_OBJECT); @@ -658,6 +658,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, from_region_handle(region_handle, &x, &y); llerrs << "Object has invalid region " << x << ":" << y << "!" << llendl; + return retval; } U16 time_dilation16; @@ -934,7 +935,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // Check for appended generic data S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data); - if (data_size == 0) + if (data_size <= 0) { mData = NULL; } @@ -1757,9 +1758,16 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, if (gPingInterpolate) { LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender()); - F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped); - LLVector3 diff = getVelocity() * (0.5f*mTimeDilation*(gFrameDTClamped + ((F32)ping_delay)*0.001f)); - new_pos_parent += diff; + if (cdp) + { + F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped); + LLVector3 diff = getVelocity() * (0.5f*mTimeDilation*(gFrameDTClamped + ((F32)ping_delay)*0.001f)); + new_pos_parent += diff; + } + else + { + llwarns << "findCircuit() returned NULL; skipping interpolation" << llendl; + } } ////////////////////////// @@ -4134,7 +4142,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow { return; } - + if (audio_uuid.isNull()) { if (mAudioSourcep && mAudioSourcep->isLoop() && !mAudioSourcep->hasPendingPreloads()) @@ -4169,7 +4177,8 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow } } - if ( mAudioSourcep ) + // don't clean up before previous sound is done. Solves: SL-33486 + if ( mAudioSourcep && mAudioSourcep->isDone() ) { gAudiop->cleanupAudioSource(mAudioSourcep); mAudioSourcep = NULL; diff --git a/linden/indra/newview/llviewerparceloverlay.cpp b/linden/indra/newview/llviewerparceloverlay.cpp index d5ad910..e31b714 100644 --- a/linden/indra/newview/llviewerparceloverlay.cpp +++ b/linden/indra/newview/llviewerparceloverlay.cpp @@ -485,20 +485,21 @@ void LLViewerParcelOverlay::updatePropertyLines() // shuffling. S32 new_vertex_count = new_vertex_array.count(); - // NOTE: If the new_vertex_count is 0 and wasn't 0 previously - // the arrays are still allocated as the arrays aren't set to NULL, etc. - // This won't cause any problems, but might waste a few cycles copying over - // old data. - jwolk - if ( !(mVertexArray && mColorArray && new_vertex_count == mVertexCount) && new_vertex_count > 0 ) + if (!(mVertexArray && mColorArray && new_vertex_count == mVertexCount)) { // ...need new arrays delete[] mVertexArray; + mVertexArray = NULL; delete[] mColorArray; + mColorArray = NULL; mVertexCount = new_vertex_count; - mVertexArray = new F32[3 * mVertexCount]; - mColorArray = new U8 [4 * mVertexCount]; + if (new_vertex_count > 0) + { + mVertexArray = new F32[3 * mVertexCount]; + mColorArray = new U8 [4 * mVertexCount]; + } } // Copy the new data into the arrays diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index 9498dbd..c57c84a 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp @@ -1504,27 +1504,8 @@ LLViewerWindow::LLViewerWindow( // stuff like AGP if we think that it'll crash the viewer. // gFeatureManagerp->initGraphicsFeatureMasks(); - - // The ATI Mobility Radeon with 1.15.0 causes crashes in FMOD on startup for - // unknown reasons, but only if you have an old settings.ini file. - // In this case, force the graphics settings back to recommended, but only - // do it once. JC - std::string gpu_string = gFeatureManagerp->getGPUString(); - LLString::toLower(gpu_string); - bool upgrade_to_1_15 = (gSavedSettings.getString("LastRunVersion") != "1.15.0"); - bool mobility_radeon = (gpu_string.find("mobility radeon") != std::string::npos); - bool mobility_radeon_upgrade_hack = upgrade_to_1_15 && mobility_radeon; - if (mobility_radeon_upgrade_hack) - { - llinfos << "1.15.0 update on Mobility Radeon" << llendl; - llinfos << "Forcing recommended graphics settings" << llendl; - llinfos << "Forcing audio off" << llendl; - gUseAudio = FALSE; - } - if (gFeatureManagerp->isSafe() - || (gSavedSettings.getS32("LastFeatureVersion") != gFeatureManagerp->getVersion()) - || mobility_radeon_upgrade_hack) + || (gSavedSettings.getS32("LastFeatureVersion") != gFeatureManagerp->getVersion())) { gFeatureManagerp->applyRecommendedFeatures(); } @@ -1747,7 +1728,7 @@ void LLViewerWindow::initBase() mToolTip->setBorderVisible( FALSE ); mToolTip->setBackgroundColor( gColors.getColor( "ToolTipBgColor" ) ); mToolTip->setBackgroundVisible( TRUE ); - mToolTip->setDropshadowVisible( FALSE ); + mToolTip->setFontStyle(LLFontGL::NORMAL); mToolTip->setBorderDropshadowVisible( TRUE ); mToolTip->setVisible( FALSE ); diff --git a/linden/indra/newview/llvlcomposition.cpp b/linden/indra/newview/llvlcomposition.cpp index af0fe96..370bf24 100644 --- a/linden/indra/newview/llvlcomposition.cpp +++ b/linden/indra/newview/llvlcomposition.cpp @@ -126,6 +126,13 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, } llassert(mSurfacep); + + if (!mSurfacep || !mSurfacep->getRegion()) + { + // We don't always have the region yet here.... + return FALSE; + } + S32 x_begin, y_begin, x_end, y_end; x_begin = llround( x * mScaleInv ); diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 25c6eb6..37380a4 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -1486,6 +1486,7 @@ void LLVOAvatar::initClass() if (!root) { llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl; + return; } //------------------------------------------------------------------------- @@ -1893,6 +1894,7 @@ void LLVOAvatar::buildCharacter() mEyeRightp)) { llerrs << "Failed to create avatar." << llendl; + return; } //------------------------------------------------------------------------- @@ -2461,7 +2463,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) if (LLVOAvatar::sJointDebug) { - llinfos << getNVPair("FirstName")->getString() << getNVPair("LastName")->getString() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << llendl; + llinfos << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << llendl; } LLJoint::sNumUpdates = 0; @@ -4809,7 +4811,7 @@ BOOL LLVOAvatar::allocateCollisionVolumes( U32 num ) LLJoint *LLVOAvatar::getCharacterJoint( U32 num ) { if ((S32)num >= mNumJoints - || num < 0) + || (S32)num < 0) { return NULL; } diff --git a/linden/indra/newview/llvoclouds.cpp b/linden/indra/newview/llvoclouds.cpp index 24084cf..be7c1b1 100644 --- a/linden/indra/newview/llvoclouds.cpp +++ b/linden/indra/newview/llvoclouds.cpp @@ -126,6 +126,12 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) for ( ; face_indx < num_faces; face_indx++) { facep = drawable->getFace(face_indx); + if (!facep) + { + llwarns << "No facep for index " << face_indx << llendl; + continue; + } + if (isParticle()) { facep->setSize(1,1); @@ -143,6 +149,12 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) for ( ; face_indx < drawable->getNumFaces(); face_indx++) { facep = drawable->getFace(face_indx); + if (!facep) + { + llwarns << "No facep for index " << face_indx << llendl; + continue; + } + facep->setTEOffset(face_indx); facep->setSize(0,0); } diff --git a/linden/indra/newview/llvopartgroup.cpp b/linden/indra/newview/llvopartgroup.cpp index 28aeb29..fbf753a 100644 --- a/linden/indra/newview/llvopartgroup.cpp +++ b/linden/indra/newview/llvopartgroup.cpp @@ -151,7 +151,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) if (!num_parts) { - if (drawable->getNumFaces()) + if (group && drawable->getNumFaces()) { group->dirtyGeom(); } @@ -206,6 +206,12 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) count++; facep = drawable->getFace(i); + if (!facep) + { + llwarns << "No face found for index " << i << "!" << llendl; + continue; + } + facep->setTEOffset(i); const F32 NEAR_PART_DIST_SQ = 5.f*5.f; // Only discard particles > 5 m from the camera const F32 MIN_PART_AREA = .005f*.005f; // only less than 5 mm x 5 mm at 1 m from camera @@ -259,6 +265,11 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) for (i = count; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); + if (!facep) + { + llwarns << "No face found for index " << i << "!" << llendl; + continue; + } facep->setTEOffset(i); facep->setSize(0,0); } diff --git a/linden/indra/newview/llwindebug.cpp b/linden/indra/newview/llwindebug.cpp index 6221b85..7433984 100644 --- a/linden/indra/newview/llwindebug.cpp +++ b/linden/indra/newview/llwindebug.cpp @@ -131,6 +131,8 @@ BOOL LLWinDebug::setupExceptionHandler() if (!f_mdwp) { write_debug("No MiniDumpWriteDump!\n"); + FreeLibrary(hDll); + hDll = NULL; ok = FALSE; } } diff --git a/linden/indra/newview/llworldmap.cpp b/linden/indra/newview/llworldmap.cpp index f2a2c90..db7ac19 100644 --- a/linden/indra/newview/llworldmap.cpp +++ b/linden/indra/newview/llworldmap.cpp @@ -491,7 +491,7 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) U32 agent_flags; msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); - if (agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES) + if ((S32)agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES) { llwarns << "Invalid map image type returned! " << agent_flags << llendl; return; diff --git a/linden/indra/newview/llworldmapview.cpp b/linden/indra/newview/llworldmapview.cpp index 01dd1b8..328af72 100644 --- a/linden/indra/newview/llworldmapview.cpp +++ b/linden/indra/newview/llworldmapview.cpp @@ -178,7 +178,6 @@ LLWorldMapView::LLWorldMapView(const std::string& name, const LLRect& rect ) LLRect major_dir_rect( 0, DIR_HEIGHT, DIR_WIDTH, 0 ); mTextBoxNorth = new LLTextBox( "N", major_dir_rect ); - mTextBoxNorth->setDropshadowVisible( TRUE ); addChild( mTextBoxNorth ); LLColor4 minor_color( 1.f, 1.f, 1.f, .7f ); diff --git a/linden/indra/newview/macview.xcodeproj/project.pbxproj b/linden/indra/newview/macview.xcodeproj/project.pbxproj index 9534878..8bc52b1 100644 --- a/linden/indra/newview/macview.xcodeproj/project.pbxproj +++ b/linden/indra/newview/macview.xcodeproj/project.pbxproj @@ -40,6 +40,8 @@ 1A758C940A436FD800589675 /* llpanellandobjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A758C930A436FD800589675 /* llpanellandobjects.cpp */; }; 1A758C960A436FDE00589675 /* llpanellandoptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A758C950A436FDE00589675 /* llpanellandoptions.cpp */; }; 1A83767E0BA2169600F28979 /* llviewergenericmessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A83767D0BA2169600F28979 /* llviewergenericmessage.cpp */; }; + 1A8870D50BCC5A6300E89AA6 /* llinventorytype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8870D40BCC5A6300E89AA6 /* llinventorytype.cpp */; }; + 1A8870E50BCC5A9500E89AA6 /* llviewermenufile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8870E40BCC5A9500E89AA6 /* llviewermenufile.cpp */; }; 1A89230508B12D1000A04AA9 /* llurlwhitelist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A89230308B12D1000A04AA9 /* llurlwhitelist.cpp */; }; 1A89230808B12D2E00A04AA9 /* llfloateropenobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A89230608B12D2E00A04AA9 /* llfloateropenobject.cpp */; }; 1A89230A08B12D9900A04AA9 /* llmediabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A89230908B12D9800A04AA9 /* llmediabase.cpp */; }; @@ -850,6 +852,11 @@ 1A758C990A43700400589675 /* llagentdata.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llagentdata.h; sourceTree = ""; }; 1A83767C0BA2169600F28979 /* llviewergenericmessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llviewergenericmessage.h; sourceTree = ""; }; 1A83767D0BA2169600F28979 /* llviewergenericmessage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llviewergenericmessage.cpp; sourceTree = ""; }; + 1A8870D30BCC5A6300E89AA6 /* llinventorytype.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llinventorytype.h; sourceTree = ""; }; + 1A8870D40BCC5A6300E89AA6 /* llinventorytype.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llinventorytype.cpp; sourceTree = ""; }; + 1A8870E30BCC5A9500E89AA6 /* llviewermenufile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llviewermenufile.h; sourceTree = ""; }; + 1A8870E40BCC5A9500E89AA6 /* llviewermenufile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llviewermenufile.cpp; sourceTree = ""; }; + 1A8870E60BCC5AAD00E89AA6 /* llresourcedata.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llresourcedata.h; sourceTree = ""; }; 1A89230308B12D1000A04AA9 /* llurlwhitelist.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llurlwhitelist.cpp; sourceTree = ""; }; 1A89230408B12D1000A04AA9 /* llurlwhitelist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = llurlwhitelist.h; sourceTree = ""; }; 1A89230608B12D2E00A04AA9 /* llfloateropenobject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = llfloateropenobject.cpp; sourceTree = ""; }; @@ -2334,6 +2341,8 @@ 1A83767C0BA2169600F28979 /* llviewergenericmessage.h */, 1A83767D0BA2169600F28979 /* llviewergenericmessage.cpp */, 9C18425A0B9F951500208356 /* llcaphttpsender.cpp */, + 1A8870E30BCC5A9500E89AA6 /* llviewermenufile.h */, + 1A8870E40BCC5A9500E89AA6 /* llviewermenufile.cpp */, A3C20E4B0BB0BD12007E872B /* llviewerjoystick.cpp */, A3C20E490BB0BCDF007E872B /* llglslshader.cpp */, AAF5FFD00B13F71900D28A84 /* lltexturecache.cpp */, @@ -2863,6 +2872,8 @@ 6192217F074A9B58005E1F34 /* llinventory */ = { isa = PBXGroup; children = ( + 1A8870D30BCC5A6300E89AA6 /* llinventorytype.h */, + 1A8870D40BCC5A6300E89AA6 /* llinventorytype.cpp */, 913B26970B4DDCDA0030C3EC /* lllandmark.cpp */, 913B26980B4DDCDA0030C3EC /* lllandmark.h */, C1F5D0A30B138AEB00827F1D /* lluserrelations.cpp */, @@ -3499,6 +3510,7 @@ isa = PBXGroup; children = ( 9C1842500B9F94F200208356 /* llcaphttpsender.h */, + 1A8870E60BCC5AAD00E89AA6 /* llresourcedata.h */, A3C20E4E0BB0BD49007E872B /* llviewerjoystick.h */, A3C20E4D0BB0BD37007E872B /* llglslshader.h */, 1AF7C1F20AF6C45000C4BF4A /* llweb.h */, @@ -4538,6 +4550,8 @@ 9C659A870BAB0B6E00D2EB60 /* llmessageconfig.cpp in Sources */, A3C20E4A0BB0BCDF007E872B /* llglslshader.cpp in Sources */, A3C20E4C0BB0BD12007E872B /* llviewerjoystick.cpp in Sources */, + 1A8870D50BCC5A6300E89AA6 /* llinventorytype.cpp in Sources */, + 1A8870E50BCC5A9500E89AA6 /* llviewermenufile.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/linden/indra/newview/newview.vcproj b/linden/indra/newview/newview.vcproj index 33c2d90..699a2bc 100644 --- a/linden/indra/newview/newview.vcproj +++ b/linden/indra/newview/newview.vcproj @@ -1121,6 +1121,9 @@ RelativePath=".\llviewermenu.cpp"> + + + + + + + + diff --git a/linden/indra/newview/newview_vc8.vcproj b/linden/indra/newview/newview_vc8.vcproj index e98c4ed..4cb359b 100644 --- a/linden/indra/newview/newview_vc8.vcproj +++ b/linden/indra/newview/newview_vc8.vcproj @@ -41,13 +41,12 @@ + + @@ -1175,6 +1173,10 @@ > + + @@ -1753,10 +1755,6 @@ > - - @@ -1893,18 +1891,10 @@ > - - - - @@ -1925,10 +1915,6 @@ > - - @@ -2337,6 +2323,10 @@ > + + @@ -2537,6 +2527,10 @@ > + + @@ -3041,10 +3035,6 @@ > - - @@ -3487,6 +3477,10 @@ > + + @@ -3507,6 +3501,10 @@ > + + @@ -3751,6 +3749,10 @@ > + + diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index 5d4618e..d030ac2 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp @@ -768,6 +768,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) if (!drawablep) { llerrs << "updateMove called with NULL drawablep" << llendl; + return; } if (drawablep->isState(LLDrawable::EARLY_MOVE)) { @@ -1124,7 +1125,7 @@ void LLPipeline::updateGeom(F32 max_dtime) last_bridge = bridge; BOOL update_complete = TRUE; - if (drawablep && !drawablep->isDead()) + if (!drawablep->isDead()) { update_complete = updateDrawableGeom(drawablep, FALSE); count++; @@ -1398,7 +1399,9 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) LLMemType mt(LLMemType::MTYPE_PIPELINE); LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE); - if (drawablep->isDead() || !hasRenderType(drawablep->getRenderType())) + if (!drawablep + || drawablep->isDead() + || !hasRenderType(drawablep->getRenderType())) { return; } @@ -1412,7 +1415,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } - if (drawablep && (hasRenderType(drawablep->mRenderType))) + if (hasRenderType(drawablep->mRenderType)) { if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) { @@ -1835,6 +1838,7 @@ void LLPipeline::renderHighlights() if (!facep || facep->getDrawable()->isDead()) { llerrs << "Bad face on selection" << llendl; + return; } facep->renderSelected(mFaceSelectImagep, color); @@ -4045,4 +4049,4 @@ void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res, glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); -} \ No newline at end of file +} diff --git a/linden/indra/newview/releasenotes.txt b/linden/indra/newview/releasenotes.txt index 2fc26c7..c6c57f0 100644 --- a/linden/indra/newview/releasenotes.txt +++ b/linden/indra/newview/releasenotes.txt @@ -1,6 +1,54 @@ +Release Notes for Second Life 1.15.1(3) May 14, 2007 +===================================== +Changes: +* Soft shadow for text is now an option available via the text style flag +* Expanded Tools->Report Bug to include additional information and links +* Alt-Left and Alt-Right switch between tabs in IM +* Ctrl-W closes one tab in IM window (Ctrl-T closes IM window) +* Ctrl-Shift-W closes all windows +* Inventory system folders may be sorted to top +* Busy mode declines notecards and textures and silently sends all other transfers to Inventory +* L$ balance displays "Loading..." (instead of a blank) when first checking your balance +* Minimap is enabled when Second Life runs for the first time +* Texture transfers are limited to 5 items per 10 seconds + +Bug fixes: +* Fixed windows maximizing when opening other windows +* Fixed floating text inworld (original hard shadow restored) +* Fixed LSL Help window restoring when clicking on script editor +* Fixed LSL Wiki Help window forgetting its size +* Fixed Ctrl-W closing the floater instead of one IM panel +* Fixed a client crash when deleting an object from inventory +* Fixed avatar eyeball shader +* Fixed closing an inventory folder while selection is inside moves selection to 'My Inventory' +* Fixed nametag text leaving background box while moving +* Fixed graphics cards with unlisted memory sizes defaulting to 16MB +* Fixed right-clicking on self failing if you are wearing a HUD +* Fixed llSetText appearance on HUD attachments +* Fixed Alt-WASD behavior when sitting +* Fixed first digit in Pay dialog cannot be erased +* Fixed reference ruler measuring to region edge instead of reference object +* Fixed permissions on group-owned object's script when group member clicks New Script +* Improved detection of Linux video memory +* VWR-38: Magic Opening Folders +* VWR-42: llSetSoundQueueing() is broken +* VWR-71: Tabulating and moving by word (Ctrl-left, ctrl-right) off-by-one errors in scripting editor. +* VWR-136: Seg fault in llpolymorph.cpp +* VWR-148: llListStatistics tooltip wrong +* VWR-154: typo in en-US/floater_mute.xml 'Resident' not 'resident' +* VWR-155: typo in en-US/floater_mute.xml 'Resident' not 'Person' +* VWR-165: First Digit in the 'Pay' dialog does not erase without entering more digits +* VWR-166: moving of open folders in the inventory to an other indentation level leaves the contents on the previous level +* VWR-192: textures in windows only stretches horizontally +* VWR-326: Allow a 'limit texture recieving' in the client +* VWR-346: Selecting Client>Character>Flush Animations immediately crashes 1.14.0.x +* VWR-379: Fix shell scripts to use bash and not sh when appropriate. +* VWR-414: 8-bit character in llagent.cpp comment confuses Japanese text editors +* VWR-415: Definitions of WM_MOUSEWHEEL and WHEEL_DELTA need conditionals (on Windows) +* VWR-429: add scons option making FMOD optional + Release Notes for Second Life 1.15.0(2) April 25, 2007 ===================================== - Changes: * Improved Help menu with links to additional resources * 'Add as Friend' button added to Profile diff --git a/linden/indra/newview/res/newViewRes.rc b/linden/indra/newview/res/newViewRes.rc index e544a39..e9ac143 100644 --- a/linden/indra/newview/res/newViewRes.rc +++ b/linden/indra/newview/res/newViewRes.rc @@ -227,8 +227,8 @@ TOOLPIPETTE CURSOR "toolpipette.cur" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,15,0,2 - PRODUCTVERSION 1,15,0,2 + FILEVERSION 1,15,1,3 + PRODUCTVERSION 1,15,1,3 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -245,12 +245,12 @@ BEGIN BEGIN VALUE "CompanyName", "Linden Lab" VALUE "FileDescription", "Second Life" - VALUE "FileVersion", "1.15.0.2" + VALUE "FileVersion", "1.15.1.3" VALUE "InternalName", "Second Life" VALUE "LegalCopyright", "Copyright © 2001-2007, Linden Research, Inc." VALUE "OriginalFilename", "SecondLife.exe" VALUE "ProductName", "Second Life" - VALUE "ProductVersion", "1.15.0.2" + VALUE "ProductVersion", "1.15.1.3" END END BLOCK "VarFileInfo" diff --git a/linden/indra/newview/secondlife setup build uma.bat b/linden/indra/newview/secondlife setup build uma.bat index 72c27fb..ad2d849 100644 --- a/linden/indra/newview/secondlife setup build uma.bat +++ b/linden/indra/newview/secondlife setup build uma.bat @@ -1,4 +1,4 @@ -@rem Invoke the script which preps then runs the installer. -@rem This batch file is customized per grid. - -@"secondlife setup build.bat" --grid=uma +@rem Invoke the script which preps then runs the installer. +@rem This batch file is customized per grid. + +@"secondlife setup build.bat" --grid=uma diff --git a/linden/indra/newview/secondlife setup build vaak.bat b/linden/indra/newview/secondlife setup build vaak.bat index 2036c33..f957918 100644 --- a/linden/indra/newview/secondlife setup build vaak.bat +++ b/linden/indra/newview/secondlife setup build vaak.bat @@ -1,4 +1,4 @@ -@rem Invoke the script which preps then runs the installer. -@rem This batch file is customized per grid. - -@"secondlife setup build.bat" --grid=vaak +@rem Invoke the script which preps then runs the installer. +@rem This batch file is customized per grid. + +@"secondlife setup build.bat" --grid=vaak diff --git a/linden/indra/newview/secondlife setup build yami.bat b/linden/indra/newview/secondlife setup build yami.bat index ffc8568..4f88805 100644 --- a/linden/indra/newview/secondlife setup build yami.bat +++ b/linden/indra/newview/secondlife setup build yami.bat @@ -1,4 +1,4 @@ -@rem Invoke the script which preps then runs the installer. -@rem This batch file is customized per grid. - -@"secondlife setup build.bat" --grid=yami +@rem Invoke the script which preps then runs the installer. +@rem This batch file is customized per grid. + +@"secondlife setup build.bat" --grid=yami diff --git a/linden/indra/newview/skins/xui/en-us/alerts.xml b/linden/indra/newview/skins/xui/en-us/alerts.xml index 265fca8..a783d00 100644 --- a/linden/indra/newview/skins/xui/en-us/alerts.xml +++ b/linden/indra/newview/skins/xui/en-us/alerts.xml @@ -11,7 +11,7 @@ Floater error: Could not find the following controls: - + [CONTROLS] - Granting modify rights to another resident allows them to change -ANY objects you may have in-world. Be VERY careful when handing + Granting modify rights to another resident allows them to change +ANY objects you may have in-world. Be VERY careful when handing out this permission. Do you want to grant modify rights for [FIRST_NAME] [LAST_NAME]? @@ -212,10 +212,10 @@ Do you want to grant modify rights for [FIRST_NAME] [LAST_NAME]? Creating a group costs L$[COST]. - + To maintain the group for more than three days, you must reach a total of three or more members. - + Create group? - You are about to add the Ability '[ACTION_NAME]' to the + You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. - + *WARNING* Any Member in a Role with this Ability can assign themselves-- and any other member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability. - + Add this Ability to '[ROLE_NAME]'? - You are about to add the Ability '[ACTION_NAME]' to the + You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. - + *WARNING* Any Member in a Role with this Ability can assign themselves-- and any other member--all Abilities, elevating themselves to near-Owner power. - + Add this Ability to '[ROLE_NAME]'? Sets whether or not parcels not owned by the estate owner -can be joined or subdivided. +can be joined or subdivided. If this option is unchecked: - * Only estate owners or managers can join or subdivide parcels. - * They may only join or subdivide parcels belonging to the owner, + * Only estate owners or managers can join or subdivide parcels. + * They may only join or subdivide parcels belonging to the owner, or to a group where they have the appropriate group powers. If this option is checked: - * All parcel owners can join or subdivide the parcels they own. + * All parcel owners can join or subdivide the parcels they own. * For group owned parcels, those with appropriate group powers may join or subdivide parcels. - + Default: Checked - The maturity rating for this region has been updated. - -The world map, however, will take approximately 5 minutes -to update, because the system only updates map information + The maturity rating for this region has been updated. + +The world map, however, will take approximately 5 minutes +to update, because the system only updates map information periodically. - Estate owners and managers can sell any land owned by the estate owner. -If this option is left unchecked, buyers cannot resell their land in this region. -If this option is checked, buyers can resell their land in this region. - + Estate owners and managers can sell any land owned by the estate owner. +If this option is left unchecked, buyers cannot resell their land in this region. +If this option is checked, buyers can resell their land in this region. + Default: Disallow Sets the notecard asset ID for the Estate Covenant belonging to this -estate. - +estate. + Default: 00000000-0000-0000-0000-000000000000 or none @@ -3546,200 +3593,200 @@ Default: 00000000-0000-0000-0000-000000000000 or none When sim performance is poor, a script may be to blame. Open the Statistics Bar (Ctrl-Shift-1). Look at the Simulator Physics FPS. -If it is lower than 45 then open the 'Time' panel located at the -bottom of the Stats Bar. If Script Time reads 25 ms or higher, click -the 'Get Top Scripts' button. You will be given the name and location +If it is lower than 45 then open the 'Time' panel located at the +bottom of the Stats Bar. If Script Time reads 25 ms or higher, click +the 'Get Top Scripts' button. You will be given the name and location of scripts that may be causing poor performance. - -Checking the 'Disable Scripts' box and then pressing the 'Apply' -button will temporarily disable all scripts in this region. You may -need to do this in order to travel to the location of a noted -'top script'. Once you have arrived at the location, investigate the -script to determine if it is causing the problem. You may want to -contact the owner of the script or delete or return the object. -Uncheck the 'Disable Script' box and then 'Apply' to reactivate + +Checking the 'Disable Scripts' box and then pressing the 'Apply' +button will temporarily disable all scripts in this region. You may +need to do this in order to travel to the location of a noted +'top script'. Once you have arrived at the location, investigate the +script to determine if it is causing the problem. You may want to +contact the owner of the script or delete or return the object. +Uncheck the 'Disable Script' box and then 'Apply' to reactivate the scripts in the region. - + Default: off - When sim performance is poor, physical objects may be to blame. -Open the Statistics Bar (Ctrl-Shift-1). Look at the Simulator -Physics FPS. If it is lower than 45 then open the 'Time' panel -located at the bottom of the Stats Bar. If Sim Time (Physics) -reads 20 ms or higher, click the 'Get Top Colliders' button. -You will be given the name and location of physical objects + When sim performance is poor, physical objects may be to blame. +Open the Statistics Bar (Ctrl-Shift-1). Look at the Simulator +Physics FPS. If it is lower than 45 then open the 'Time' panel +located at the bottom of the Stats Bar. If Sim Time (Physics) +reads 20 ms or higher, click the 'Get Top Colliders' button. +You will be given the name and location of physical objects that may be causing poor performance. - -Checking the 'Disable Collisions' box and then pressing the 'Apply' -button will temporarily disable object-object collisions. You may -need to do this in order to travel to the location of a noted -'top collider'. Once you have arrived at the location, investigate the -object - is it constantly colliding with other objects? You may want to -contact the owner of the object or delete or return the object. -Uncheck the 'Disable Collisions' box and then 'Apply' to reactivate + +Checking the 'Disable Collisions' box and then pressing the 'Apply' +button will temporarily disable object-object collisions. You may +need to do this in order to travel to the location of a noted +'top collider'. Once you have arrived at the location, investigate the +object - is it constantly colliding with other objects? You may want to +contact the owner of the object or delete or return the object. +Uncheck the 'Disable Collisions' box and then 'Apply' to reactivate collisions in the region. - + Default: off - Disable Physics is similar to Disable Collisions, except all -physics simulation is disabled. This means that not only will -objects stop colliding, but avatars will be unable to move. - -This should only be used when Disable Collisions does not -give back enough performance to the region to investigate + Disable Physics is similar to Disable Collisions, except all +physics simulation is disabled. This means that not only will +objects stop colliding, but avatars will be unable to move. + +This should only be used when Disable Collisions does not +give back enough performance to the region to investigate a physics problem or 'Top Collider'. - -Be sure to re-enable physics when you are done, or avatars -will continue to be unable to move. - + +Be sure to re-enable physics when you are done, or avatars +will continue to be unable to move. + Default: off - Show a list of objects experiencing the greatest number -of potential object-object collisions. These objects can -slow sim performance. Select View > Statistics Bar and -look under Simulator > Time > Sim Time (Physics) to see + Show a list of objects experiencing the greatest number +of potential object-object collisions. These objects can +slow sim performance. Select View > Statistics Bar and +look under Simulator > Time > Sim Time (Physics) to see if more than 20 ms is being spent in physics. - Show a list of objects spending the most time running -LSL scripts. These objects can slow sim performance. -Select View > Statistics Bar and look under -Simulator > Time > Script Time to see if more than + Show a list of objects spending the most time running +LSL scripts. These objects can slow sim performance. +Select View > Statistics Bar and look under +Simulator > Time > Script Time to see if more than 25 ms is being spent in scripts. - Restart the server process running this region after a -two minute warning. All residents in the region will be -disconnected. The region will save its data, and should -come back up within 90 seconds. - -Restarting the region will not fix most performance + Restart the server process running this region after a +two minute warning. All residents in the region will be +disconnected. The region will save its data, and should +come back up within 90 seconds. + +Restarting the region will not fix most performance problems, and should usually be used only when directed. - This is the height in meters where water appears. If -this setting is anything other than 20 and you have -water that is adjacent to the edge of world or 'void' -water, there will be a visible gap. - + This is the height in meters where water appears. If +this setting is anything other than 20 and you have +water that is adjacent to the edge of world or 'void' +water, there will be a visible gap. + Default: 20 - This is the distance that parcel owners can raise -their terrain above the 'baked' terrain default -height. - + This is the distance that parcel owners can raise +their terrain above the 'baked' terrain default +height. + Default: 4 - This is the distance that parcel owners can lower -their terrain below the 'baked' terrain default -height. - + This is the distance that parcel owners can lower +their terrain below the 'baked' terrain default +height. + Default: -4 - This button uploads a .RAW file to the region you are in. -The file must have the correct dimensions/number of channels: -RGB, 256x256 and 13 channels. The best way to create a -terrain file is to download the existing RAW file. A good -first step is to modify the first channel (land height), -and upload it. - -The upload can take up to 45 seconds. Note that uploading a -terrain file *will not* move the objects that are on the land, -only the terrain itself and the permissions associated with the -parcels. This can result in objects going underground. - -For more information on editing region height fields, go to: + This button uploads a .RAW file to the region you are in. +The file must have the correct dimensions/number of channels: +RGB, 256x256 and 13 channels. The best way to create a +terrain file is to download the existing RAW file. A good +first step is to modify the first channel (land height), +and upload it. + +The upload can take up to 45 seconds. Note that uploading a +terrain file *will not* move the objects that are on the land, +only the terrain itself and the permissions associated with the +parcels. This can result in objects going underground. + +For more information on editing region height fields, go to: http://secondlife.com/tiki/tiki-index.php?page=RawTerrainFile - This button downloads a file containing the height field data, -parcel dimensions, parcel for sale status and some parcel permissions -for this region. When opening the file in a program such as -Photoshop you must specify the document's dimensions which -are: RGB, 256x256 with 13 channels. This terrain file cannot -be opened in any other way. - -For more information on editing region height fields, go to: + This button downloads a file containing the height field data, +parcel dimensions, parcel for sale status and some parcel permissions +for this region. When opening the file in a program such as +Photoshop you must specify the document's dimensions which +are: RGB, 256x256 with 13 channels. This terrain file cannot +be opened in any other way. + +For more information on editing region height fields, go to: http://secondlife.com/tiki/tiki-index.php?page=RawTerrainFile - This checkbox makes the sun position in this region the -same as the sun position in the rest of the estate. - + This checkbox makes the sun position in this region the +same as the sun position in the rest of the estate. + Default: on - This checkbox sets the sun position to the position -in the Phase slider and stops the sun from moving. - + This checkbox sets the sun position to the position +in the Phase slider and stops the sun from moving. + Default: off - This button saves the current shape of the terrain as the -new default for the region. Once baked, the land can revert + This button saves the current shape of the terrain as the +new default for the region. Once baked, the land can revert to the saved shape whenever you or others use the Edit Terrain -'Revert' option/tool. The baked terrain is also the middle +'Revert' option/tool. The baked terrain is also the middle point for the terrain raise and lower limits. - An estate manager is a resident to whom you have delegated -control of region and estate settings. An estate manager -can change any setting in these panels, except for uploading, -downloading, and baking terrain. In particular, they can -allow or ban residents from your estate. - -Estate managers can only be added or removed by the owner -of the estate, not by each other. Please only choose -residents you trust as estate managers, as you will be + An estate manager is a resident to whom you have delegated +control of region and estate settings. An estate manager +can change any setting in these panels, except for uploading, +downloading, and baking terrain. In particular, they can +allow or ban residents from your estate. + +Estate managers can only be added or removed by the owner +of the estate, not by each other. Please only choose +residents you trust as estate managers, as you will be ultimately responsible for their actions. - This checkbox makes the sun in your estate follow -the same position as on the Linden-owned 'mainland' -estates. - + This checkbox makes the sun in your estate follow +the same position as on the Linden-owned 'mainland' +estates. + Default: on - This checkbox sets the sun position to the position + This checkbox sets the sun position to the position in the Phase slider and stops the sun from moving. @@ -3747,91 +3794,91 @@ in the Phase slider and stops the sun from moving. Sets whether residents who are on other estates can enter this estate without being on an access list. - + Default: on - When checked, allows residents to directly teleport to any -point in your estate. When unchecked, residents teleport -to the nearest telehub. - + When checked, allows residents to directly teleport to any +point in your estate. When unchecked, residents teleport +to the nearest telehub. + Default: off - If any resident is listed here, access to the estate will be -limited to residents on this list and groups listed below. - -(If the estate is visible from the mainland, access cannot be -limited to a resident or group list, and these controls will be + If any resident is listed here, access to the estate will be +limited to residents on this list and groups listed below. + +(If the estate is visible from the mainland, access cannot be +limited to a resident or group list, and these controls will be disabled. Only the 'access denied' list will be used.) - If any group is listed here, access to the estate will be -limited to the groups on this list and residents specifically -allowed above. - -(If the estate is visible from the mainland, access cannot be -limited to a resident or group list, and these controls will be + If any group is listed here, access to the estate will be +limited to the groups on this list and residents specifically +allowed above. + +(If the estate is visible from the mainland, access cannot be +limited to a resident or group list, and these controls will be disabled. Only the 'access denied' list will be used.) - Residents on this list are denied access to your estate, -regardless of the allow and group settings above. - -Adding a resident to this list will remove them from + Residents on this list are denied access to your estate, +regardless of the allow and group settings above. + +Adding a resident to this list will remove them from the allow list. - Setting an estate covenant enables you to sell parcels -within that estate. If a covenant is not set, you cannot -sell the land. The notecard for your covenant can be empty -if you do not wish to apply any rules or advise buyers of -anything in relation to the land before they buy it. - -A covenant can be used to communicate rules, guidelines, -cultural information or simply your own expectations to the -prospective buyer. This can include zoning, building regulations, -payment options or any other information you feel it is -important for the new owner to have seen and to have agreed -to before they purchase. - -The buyer must agree to the covenant by ticking the check box -before they will be able to finish the purchase. Estate -covenants are always visible in the About Land dialog for + Setting an estate covenant enables you to sell parcels +within that estate. If a covenant is not set, you cannot +sell the land. The notecard for your covenant can be empty +if you do not wish to apply any rules or advise buyers of +anything in relation to the land before they buy it. + +A covenant can be used to communicate rules, guidelines, +cultural information or simply your own expectations to the +prospective buyer. This can include zoning, building regulations, +payment options or any other information you feel it is +important for the new owner to have seen and to have agreed +to before they purchase. + +The buyer must agree to the covenant by ticking the check box +before they will be able to finish the purchase. Estate +covenants are always visible in the About Land dialog for any parcels that have one set. - Unable to buy more than one object at a time. + Unable to buy more than one object at a time. Please select only one object and try again. - Cannot buy objects from different owners at the same time. + Cannot buy objects from different owners at the same time. Please select only one object and try again. - Unable to buy the contents of more than one object at a time. + Unable to buy the contents of more than one object at a time. Please select only one object and try again. - Cannot buy objects from different owners at the same time. + Cannot buy objects from different owners at the same time. Please select only one object and try again. @@ -3936,9 +3983,9 @@ They will be copied to your inventory. This transaction will: - + [ACTION] - + Are you sure you want to proceed with this purchase? Dear Resident, - + Reports about copyright infringement can only be submitted as described at http://secondlife.com/corporate/dmca.php. - + Reports concerning copyright infringement will automatically be discarded if they are submitted through the 'Abuse Report' feature. If your report does not relate to copyright infringement, you may close this window and finish submitting your report. - + Thank you, - + Linden Lab @@ -4195,7 +4242,7 @@ Do you want to replace it with the selected object? You are in Busy Mode, which means you will not receive any items offered in exchange for this payment. - + Would you like to leave Busy Mode before completing this transaction? @@ -4242,9 +4289,9 @@ the contents of your Lost And Found folder? The following SLURL has been copied to your clipboard: - - [SLURL] - + + [SLURL] + Put it in a web page to give others easy access to this location or try it out yourself by pasting it into the address bar of your web browser. @@ -4288,4 +4335,11 @@ the contents of your Lost And Found folder? OK + + + Items may not be purchased while + they are part of an attachment. + + + diff --git a/linden/indra/newview/skins/xui/en-us/floater_avatar_picker.xml b/linden/indra/newview/skins/xui/en-us/floater_avatar_picker.xml index a0e6a91..71a3bd4 100644 --- a/linden/indra/newview/skins/xui/en-us/floater_avatar_picker.xml +++ b/linden/indra/newview/skins/xui/en-us/floater_avatar_picker.xml @@ -6,7 +6,7 @@ @@ -24,7 +24,7 @@ diff --git a/linden/indra/newview/skins/xui/en-us/floater_inventory.xml b/linden/indra/newview/skins/xui/en-us/floater_inventory.xml old mode 100755 new mode 100644 index 52af7a3..d9d8eb8 --- a/linden/indra/newview/skins/xui/en-us/floater_inventory.xml +++ b/linden/indra/newview/skins/xui/en-us/floater_inventory.xml @@ -149,6 +149,11 @@ name="Folders Always By Name" width="118"> +