Merge Firestorm LGPL

master
Ansariel 2016-08-11 00:17:47 +02:00
commit 0054c93c3f
198 changed files with 5603 additions and 1204 deletions

View File

@ -31,6 +31,7 @@ fdf1fd7884cf642ad3d41c3f5bc2521e4a7ab3aa Firestorm_4.6.9_Release
76c9998c37a52d58792e7a22cc5055e831c95023 Firestorm_4.7.3_Release
a27ad24ed75000d96d056aa20495637386e4a53e Firestorm_4.7.5_Release
31f9b0f8e9365a87975af3aa73e3f782db17f994 Firestorm_4.7.7_Release
6ef63161a501b12536b1a94b74d0084a4b014572 Firestorm_4.7.9_Release
bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2.1.1-release
003dd9461bfa479049afcc34545ab3431b147c7c v2start
52d96ad3d39be29147c5b2181b3bb46af6164f0e alpha-3

View File

@ -1,4 +1,4 @@
First, make sure gcc-4.6 and g++-4.6 are installed.
First, make sure gcc-4.7 and g++-4.7 are installed.
32bit build platforms are better tested at this point and strongly recommended.
@ -44,3 +44,4 @@ Logs:
Output:
Look for output in build-linux-i686/newview/Release

View File

@ -5,7 +5,7 @@ This is WIP. Please change/expand when seeing fit.
2. autobuild from https://bitbucket.org/NickyD/autobuild-1.0
3. FMOD, if you want sound, please see https://bitbucket.org/NickyD/3p-fmodex
You will find the urls to all 64 bit prebuild packages in <viewer_source_dir>/package_override.ini
You will find the urls to all 64 bit prebuild packages in <viewer_source_dir>/package_override_vc12.ini
Make sure you're not building from a Visual Studio command prompt, or parts of the build
chain might accidentally pick up a 32 bit compiler, resulting in x86<>x64 mismatch.

View File

@ -27,9 +27,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>e54568cfa7bced82cb6eae26471b7fa5</string>
<string>68bf8ef0e36e52a995fbe5a4889d5065</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/slplugin_x86-4.7.8.50261-darwin-201606211711-r3.tar.bz2</string>
<string>http://downloads.phoenixviewer.com/slplugin_x86-4.7.8.50451-darwin-201607130911-r5.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1146,6 +1146,46 @@
<key>version</key>
<string>0.10.6.294903</string>
</map>
<key>gstreamer10</key>
<map>
<key>copyright</key>
<string>Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</string>
<key>license</key>
<string>LGPL</string>
<key>license_file</key>
<string>LICENSES/gstreamer.txt</string>
<key>name</key>
<string>gstreamer10</string>
<key>platforms</key>
<map>
<key>linux</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>01f39ecf80dae64e30402ac384035b3e</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/gstreamer10-1.6.3.201605191852-linux-201605191852.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>437b1dfd7e20cd0b688e2c1393cdbfc3</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/gstreamer10-1.6.3.201605192127-r9-windows-201605192127-r9.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>version</key>
<string>0.10.6.294903</string>
</map>
<key>gtk-atk-pango-glib</key>
<map>
<key>copyright</key>
@ -1163,9 +1203,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>15af375116f5c943ea6f4190bc764224</string>
<string>8cd64b4c5d7f02c5ad87051861108749</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/gtk_3p-gtk-atk-pango-glib/rev/294804/arch/Linux/installer/gtk_atk_pango_glib-0.1-linux-294804.tar.bz2</string>
<string>http://downloads.phoenixviewer.com/gtk_atk_pango_glib-2.0-linux-201608031222.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1687,11 +1727,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>7d12fe9dff388d237615f7158315d1cb</string>
<string>d382fe4c4d80c4ee778166bf97e82e19</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/llceflib-1.0-windows-201602081454-r54.tar.bz2</string>
<string>http://downloads.phoenixviewer.com/llceflib-1.0-windows-201608011747-r69.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1701,18 +1741,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>57bbb4defb7986aa241b10558c6abfea</string>
<string>98c702cb445a3afda0d1ee0eb23069c3</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/llceflib-1.0-linux-201603010220-r58.tar.bz2</string>
<string>http://downloads.phoenixviewer.com/llceflib-1.0-linux-201608022058-r69.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
</map>
</map>
<key>version</key>
<string>1.5.3.311349</string>
<string>1.5.3.317959</string>
</map>
<key>llphysicsextensions_source</key>
<map>
@ -2231,9 +2271,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>06c3a9b1005249f0c94a8b9f3775f3d3</string>
<string>6e7b0961d6489a1b3c3090eccfd6e80e</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/vivox_3p-slvoice/rev/302004/arch/Linux/installer/slvoice-3.2.0002.10426.302004-linux-302004.tar.bz2</string>
<string>http://downloads.phoenixviewer.com/slvoice-3.2.0002.10426.298329-linux-20160717.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>

View File

@ -194,7 +194,7 @@ if (LINUX)
OUTPUT_STRIP_TRAILING_WHITESPACE)
#<FS:ND> Gentoo defines _FORTIFY_SOURCE by default
if (NOT ( ${GXX_VERSION} MATCHES "Gentoo 4.[789].*" OR ${GXX_VERSION} MATCHES "Gentoo 5.3.*" ) )
if (NOT ND_SYSTEM_DEFINES_FORTIFY_SOURCE)
#</FS:ND>
if (${GXX_VERSION} STREQUAL ${CXX_VERSION})
@ -206,7 +206,7 @@ if (LINUX)
endif (${GXX_VERSION} STREQUAL ${CXX_VERSION})
#<FS:ND> Gentoo defines _FORTIFY_SOURCE by default
endif (NOT ( ${GXX_VERSION} MATCHES "Gentoo 4.[789].*" OR ${GXX_VERSION} MATCHES "Gentoo 5.3.*" ) )
endif (NOT ND_SYSTEM_DEFINES_FORTIFY_SOURCE)
#</FS:ND>
# Let's actually get a numerical version of gxx's version

View File

@ -0,0 +1,31 @@
# -*- cmake -*-
include(Prebuilt)
if (USESYSTEMLIBS)
include(FindPkgConfig)
pkg_check_modules(GSTREAMER10 REQUIRED gstreamer-1.0)
pkg_check_modules(GSTREAMER10_PLUGINS_BASE REQUIRED gstreamer-plugins-base-1.0)
elseif (LINUX OR WINDOWS)
use_prebuilt_binary(gstreamer10)
use_prebuilt_binary(libxml2)
set(GSTREAMER10_FOUND ON FORCE BOOL)
set(GSTREAMER10_PLUGINS_BASE_FOUND ON FORCE BOOL)
set(GSTREAMER10_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/gstreamer-1.0
${LIBS_PREBUILT_DIR}/include/glib-2.0
${LIBS_PREBUILT_DIR}/include/libxml2
)
# We don't need to explicitly link against gstreamer itself, because
# LLMediaImplGStreamer probes for the system's copy at runtime.
set(GSTREAMER10_LIBRARIES)
endif (USESYSTEMLIBS)
if (GSTREAMER10_FOUND AND GSTREAMER10_PLUGINS_BASE_FOUND)
set(GSTREAMER10 ON CACHE BOOL "Build with GStreamer-1.0 streaming media support.")
endif (GSTREAMER10_FOUND AND GSTREAMER10_PLUGINS_BASE_FOUND)
if (GSTREAMER10)
add_definitions(-DLL_GSTREAMER10_ENABLED=1)
endif (GSTREAMER10)

View File

@ -50,17 +50,12 @@ else (USESYSTEMLIBS)
pango-1.0
pangoft2-1.0
pangox-1.0
pangoxft-1.0
#pangoxft-1.0
gio-2.0
pangocairo-1.0
ffi
)
if (ND_BUILD64BIT_ARCH)
set(UI_LIB_NAMES ${UI_LIB_NAMES}
gio-2.0
pangocairo-1.0
ffi
)
endif(ND_BUILD64BIT_ARCH)
foreach(libname ${UI_LIB_NAMES})
find_library(UI_LIB_${libname}
NAMES ${libname}

View File

@ -39,11 +39,11 @@ set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (en
# <FS:ND> When building for Linux x64 we enable building the media plugins, in all other cases we use the prebuild 32 bit packages
# set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
if (ND_BUILD64BIT_ARCH AND (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") )
if (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
set( ENABLE_MEDIA_PLUGINS OFF CACHE FORCE "Build with media plugins" )
else (ND_BUILD64BIT_ARCH AND (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") )
else (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
endif (ND_BUILD64BIT_ARCH AND (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") )
endif (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
# </FS:ND>
if(LIBS_CLOSED_DIR)

View File

@ -12,7 +12,6 @@ if (NOT USESYSTEMLIBS)
if( ND_BUILD64BIT_ARCH )
if( WINDOWS )
# use_prebuilt_binary( slplugin_x86 )
use_prebuilt_binary( wix )
elseif( DARWIN )
use_prebuilt_binary( slplugin_x86 )

View File

@ -507,40 +507,6 @@ LLProcessPtr LLProcess::create(const LLSDOrParams& params)
}
}
// <FS:ND> Annoying preload hack to make tcmalloc in libcef.so play nicely.
std::string installPreloadHack( std::string const &preload )
{
std::string strOldPreload;
#ifdef LL_LINUX
if( preload.size() )
{
std::string strPreload = preload;
if( getenv( "LD_PRELOAD" ) )
{
strOldPreload = getenv( "LD_PRELOAD" );
strPreload = ":" + strOldPreload;
}
setenv( "LD_PRELOAD", strPreload.c_str(), 1 );
}
#endif
return strOldPreload;
}
void uninstallPreloadHack( std::string const &preload, std::string const &strOldPreload )
{
#ifdef LL_LINUX
if( preload.empty() )
return;
if( strOldPreload.size() )
setenv( "LD_PRELOAD", strOldPreload.c_str(), 1 );
else
unsetenv( "LD_PRELOAD" );
#endif
}
// </FS:ND>
/// Call an apr function returning apr_status_t. On failure, log warning and
/// throw LLProcessError mentioning the function call that produced that
/// result.
@ -706,20 +672,15 @@ LLProcess::LLProcess(const LLSDOrParams& params):
// terminate with a null pointer
argv.push_back(NULL);
std::string strOldPreload = installPreloadHack( params.preload ); // FS:ND/> Install preload hack (if needed)
// Launch! The NULL would be the environment block, if we were passing
// one. Hand-expand chkapr() macro so we can fill in the actual command
// string instead of the variable names.
if (ll_apr_warn_status(apr_proc_create(&mProcess, argv[0], &argv[0], NULL, procattr,
gAPRPoolp)))
{
uninstallPreloadHack( params.preload, strOldPreload ); // <FS:ND/> Remove preload hack
throw LLProcessError(STRINGIZE(params << " failed"));
}
uninstallPreloadHack( params.preload, strOldPreload ); // <FS:ND/> Remove preload hack
// arrange to call status_callback()
apr_proc_other_child_register(&mProcess, &LLProcess::status_callback, this, mProcess.in,
gAPRPoolp);

View File

@ -32,6 +32,7 @@ include_directories(
)
set(llmessage_SOURCE_FILES
fscorehttputil.cpp
llassetstorage.cpp
llavatarname.cpp
llavatarnamecache.cpp
@ -111,6 +112,7 @@ set(llmessage_SOURCE_FILES
set(llmessage_HEADER_FILES
CMakeLists.txt
fscorehttputil.h
llassetstorage.h
llavatarname.h
llavatarnamecache.h

View File

@ -1,3 +1,32 @@
/**
* @file fscorehttputil.h
* @brief Core HTTP utility classes.
*
* $LicenseInfo:firstyear=2015&license=viewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (c) 2015 Nicky Dasmijn
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
* http://www.firestormviewer.org
* $/LicenseInfo$
*/
#include "fscorehttputil.h"
namespace FSCoreHttpUtil
{
void trivialPostCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::BufferArray::ptr_t postData, LLCore::HttpHeaders::ptr_t aHeader, completionCallback_t success, completionCallback_t failure)

View File

@ -1,3 +1,34 @@
/**
* @file fscorehttputil.h
* @brief Core HTTP utility classes.
*
* $LicenseInfo:firstyear=2015&license=viewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (c) 2015 Nicky Dasmijn
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
* http://www.firestormviewer.org
* $/LicenseInfo$
*/
#ifndef FS_COREHTTPUTIL_H
#define FS_COREHTTPUTIL_H
#include "llcorehttputil.h"
namespace FSCoreHttpUtil
{
@ -13,3 +44,4 @@ namespace FSCoreHttpUtil
completionCallback_t success, completionCallback_t failure);
}
#endif // FS_COREHTTPUTIL_H

View File

@ -1345,5 +1345,3 @@ void HttpCoroutineAdapter::trivialPostCoro(std::string url, LLCore::HttpRequest:
} // end namespace LLCoreHttpUtil
#include "fscorehttputil.cpp"

View File

@ -684,6 +684,4 @@ private:
} // end namespace LLCoreHttpUtil
#include "fscorehttputil.h"
#endif // LL_LLCOREHTTPUTIL_H

View File

@ -4017,7 +4017,10 @@ void LLMessageSystem::sendUntrustedSimulatorMessageCoro(std::string url, std::st
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
// <FS:Ansariel> Fix adapter naming
//httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("untrustedSimulatorMessage", httpPolicy));
// </FS:Ansariel>
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);

View File

@ -70,11 +70,7 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
add_library (llplugin ${llplugin_SOURCE_FILES})
if( ND_BUILD64BIT_ARCH AND WINDOWS )
use_prebuilt_binary( slplugin_x86 )
else()
add_subdirectory(slplugin)
endif( ND_BUILD64BIT_ARCH AND WINDOWS )
add_subdirectory(slplugin)
# Add tests
if (LL_TESTS)

View File

@ -1488,10 +1488,3 @@ void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history)
LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL;
}
void LLPluginClassMedia::setFlipY( bool enabled )
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cef_flipy");
message.setValueBoolean("enable", enabled);
sendMessage(message);
}

View File

@ -1124,7 +1124,10 @@ bool LLDAELoader::OpenFile(const std::string& filename)
std::string LLDAELoader::preprocessDAE(std::string filename)
{
// Open a DAE file for some preprocessing (like removing space characters in IDs), see MAINT-5678
std::ifstream inFile;
// <FS:Ansariel> FIRE-19806: Mesh upload from a folder with Unicode characters in the name fails
//std::ifstream inFile;
llifstream inFile;
// </FS:Ansariel>
inFile.open(filename.c_str(), std::ios_base::in);
std::stringstream strStream;
strStream << inFile.rdbuf();

View File

@ -690,17 +690,26 @@ bool LLGLManager::initGL()
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
mVRAM = meminfo[0]/1024;
// <FS:Ansariel> VRAM detection logging
LL_INFOS("RenderInit") << "VRAM detected via ATI MemInfo OpenGL extension: " << mVRAM << " MB" << LL_ENDL;
}
else if (mHasNVXMemInfo)
{
S32 dedicated_memory;
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory);
mVRAM = dedicated_memory/1024;
// <FS:Ansariel> VRAM detection logging
LL_INFOS("RenderInit") << "VRAM detected via nVidia MemInfo OpenGL extension: " << mVRAM << " MB" << LL_ENDL;
}
if (mVRAM < 256)
{ //something likely went wrong using the above extensions, fall back to old method
mVRAM = old_vram;
// <FS:Ansariel> VRAM detection logging
LL_WARNS("RenderInit") << "VRAM detected via MemInfo OpenGL extension most likely broken. Reverting to " << mVRAM << " MB" << LL_ENDL;
}
stop_glerror();

View File

@ -480,6 +480,9 @@ public:
// *WORKAROUND: two methods to overload appropriate Params due to localization issue:
// no_items_msg & no_filtered_items_msg attributes are not defined as translatable in VLT. See EXT-5931
// [RLVa:KB] - Checked: RLVa-2.0.3
const std::string& getNoItemsMsg() const { return mNoItemsMsg; }
// [/RLVa:KB]
void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; }
void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; }

View File

@ -534,6 +534,7 @@ BOOL LLDXHardware::getInfo(BOOL vram_only, bool disable_wmi)
// </FS:Ansariel>
{
mVRAM = vram/(1024*1024);
LL_INFOS("AppInit") << "VRAM Detected via WMI: " << mVRAM << LL_ENDL;
}
else
{ // Get the English VRAM string
@ -545,7 +546,7 @@ BOOL LLDXHardware::getInfo(BOOL vram_only, bool disable_wmi)
// Dump the string as an int into the structure
char *stopstring;
mVRAM = strtol(ram_str.c_str(), &stopstring, 10);
LL_INFOS("AppInit") << "VRAM Detected: " << mVRAM << " DX9 string: " << ram_str << LL_ENDL;
LL_INFOS("AppInit") << "VRAM Detected via DirectX: " << mVRAM << " DX9 string: " << ram_str << LL_ENDL;
}
if (vram_only)

View File

@ -6,13 +6,23 @@ if (LINUX)
add_subdirectory(cef)
endif (LINUX)
if (WINDOWS OR DARWIN)
if (DARWIN)
add_subdirectory(quicktime)
add_subdirectory(cef)
endif (WINDOWS OR DARWIN)
endif (DARWIN)
if (WINDOWS)
if( WORD_SIZE EQUAL 32 )
add_subdirectory(quicktime)
endif()
add_subdirectory(cef)
add_subdirectory(winmmshim)
endif (WINDOWS)
### add_subdirectory(example)
if (WINDOWS OR LINUX)
add_subdirectory(gstreamer10)
endif (WINDOWS OR LINUX)

View File

@ -29,11 +29,9 @@ include_directories(SYSTEM
### media_plugin_base
if(NOT WORD_SIZE EQUAL 32)
if(WINDOWS)
add_definitions(/FIXED:NO)
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
if( NOT WINDOWS)
add_definitions(-fPIC)
endif(WINDOWS)
endif(NOT WINDOWS)
endif(NOT WORD_SIZE EQUAL 32)
set(media_plugin_base_SOURCE_FILES

View File

@ -40,11 +40,9 @@ include_directories(SYSTEM
### media_plugin_cef
if(NOT WORD_SIZE EQUAL 32)
if(WINDOWS)
add_definitions(/FIXED:NO)
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
if( NOT WINDOWS) # not windows therefore gcc LINUX and DARWIN
add_definitions(-fPIC)
endif(WINDOWS)
endif(NOT WINDOWS)
endif(NOT WORD_SIZE EQUAL 32)
set(media_plugin_cef_SOURCE_FILES

View File

@ -108,17 +108,11 @@ private:
VolumeCatcher mVolumeCatcher;
// <FS:ND> FS specific CEF settings
bool mFlipY;
// </FS:ND>
// <FS:ND> Buffer for a popup image to be rendered as an overlay
U8 *mPopupBuffer;
U32 mPopupW;
U32 mPopupH;
U32 mPopupX;
U32 mPopupY;
// </FS:ND>
};
////////////////////////////////////////////////////////////////////////////////
@ -147,18 +141,11 @@ MediaPluginBase(host_send_func, host_user_data)
mPickedFile = "";
mLLCEFLib = new LLCEFLib();
// <FS:ND> FS specific CEF settings
mFlipY = false;
// </FS:ND>
// <FS:ND> Buffer for a popup image to be rendered as an overlay
mPopupBuffer = NULL;
mPopupW = 0;
mPopupH = 0;
mPopupX = 0;
mPopupY = 0;
// </FS:ND>
}
////////////////////////////////////////////////////////////////////////////////
@ -188,10 +175,7 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg)
//
void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup)
{
// <FS:ND> in case this is a popup, delete our old popup buffer and create a new one if needed.
// Put this here as the media_plugin_cef will send a message with all but is_popup set to 0 in case the popup gets destroyed.
#if FS_CEFLIB_VERSION >= 3
if (is_popup)
if( is_popup )
{
delete mPopupBuffer;
mPopupBuffer = NULL;
@ -200,17 +184,11 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y,
mPopupX = 0;
mPopupY = 0;
}
#endif
// </FS:ND>
if (mPixels && pixels)
if( mPixels && pixels )
{
if (is_popup)
{
// <FS:ND> This is a valid popup, copy the texture into our overlay buffer.
// Can a texture ever have an alpha other than 255/1.0 to make an alpha blended popup/dropdown?
// (According to Mobius not w/o hacks, so we assume opague)
#if FS_CEFLIB_VERSION >= 3
if( width > 0 && height> 0 )
{
mPopupBuffer = new U8[ width * height * mDepth ];
@ -218,25 +196,8 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y,
mPopupH = height;
mPopupW = width;
mPopupX = x;
mPopupY = y;
mPopupY = mHeight - y - height;
}
#endif
// </FS:ND>
#if FS_CEFLIB_VERSION < 3
// <FS:ND/> You are outdated and will be buggy
for (int line = 0; line < height; ++line)
{
int inverted_y = mHeight - y - height;
int src = line * width * mDepth;
int dst = (inverted_y + line) * mWidth * mDepth + x * mDepth;
if (dst + width * mDepth < mWidth * mHeight * mDepth)
{
memcpy(mPixels + dst, pixels + src, width * mDepth);
}
}
#endif
}
else
{
@ -251,14 +212,12 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y,
U32 bufferSize = mWidth * mHeight * mDepth;
U32 popupStride = mPopupW * mDepth;
U32 bufferStride = mWidth * mDepth;
int dstY = mHeight - mPopupY - mPopupH;
if( !mFlipY )
dstY = mPopupY;
int dstY = mPopupY;
int src = 0;
int dst = dstY * mWidth * mDepth + mPopupX * mDepth;
for (int line = 0; dst + popupStride < bufferSize && line < mPopupH; ++line)
for( int line = 0; dst + popupStride < bufferSize && line < mPopupH; ++line )
{
memcpy( mPixels + dst, mPopupBuffer + src, popupStride );
src += popupStride;
@ -532,12 +491,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
if (message_name == "init")
{
// <FS:ND> FS specific CEF settings
#if defined( LL_WINDOWS ) || defined( LL_LINUX )
mLLCEFLib->setFlipY( mFlipY );
#endif
// </FS:ND>
// event callbacks from LLCefLib
mLLCEFLib->setOnPageChangedCallback(boost::bind(&MediaPluginCEF::onPageChangedCallback, this, _1, _2, _3, _4, _5, _6));
mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1));
@ -582,13 +535,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
message.setValueU32("internalformat", GL_RGB);
message.setValueU32("format", GL_BGRA);
message.setValueU32("type", GL_UNSIGNED_BYTE);
// <FS:ND> if mFlipY is true, teh CEF plugin will flip the texture and it will be in correct opengl format.
// If false, it needs to be flipped by the viewer.
// message.setValueBoolean("coords_opengl", true);
message.setValueBoolean("coords_opengl", mFlipY );
// </FS:ND>
message.setValueBoolean("coords_opengl", true);
sendMessage(message);
}
else if (message_name == "set_user_data_path")
@ -659,6 +606,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
S32 x = message_in.getValueS32("x");
S32 y = message_in.getValueS32("y");
y = mHeight - y;
// only even send left mouse button events to LLCEFLib
// (partially prompted by crash in OS X CEF when sending right button events)
// we catch the right click in viewer and display our own context menu anyway
@ -832,10 +781,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
mJavascriptEnabled = message_in.getValueBoolean("enable");
}
else if( message_name == "cef_flipy" )
{
mFlipY = message_in.getValueBoolean("enable");
}
}
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
{

View File

@ -0,0 +1,77 @@
# -*- cmake -*-
project(media_plugin_gstreamer10)
include(00-Common)
include(LLCommon)
include(LLImage)
include(LLPlugin)
include(LLMath)
include(LLRender)
include(LLWindow)
include(Linking)
include(PluginAPI)
include(MediaPluginBase)
include(OpenGL)
include(GStreamer10Plugin)
include_directories(
${LLPLUGIN_INCLUDE_DIRS}
${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${GSTREAMER10_INCLUDE_DIRS}
${GSTREAMER10_PLUGINS_BASE_INCLUDE_DIRS}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
)
### media_plugin_gstreamer10
if(NOT WORD_SIZE EQUAL 32)
if(NOT WINDOWS) # not windows therefore gcc LINUX and DARWIN
add_definitions(-fPIC)
endif()
endif(NOT WORD_SIZE EQUAL 32)
set(media_plugin_gstreamer10_SOURCE_FILES
media_plugin_gstreamer10.cpp
llmediaimplgstreamer_syms.cpp
)
set(media_plugin_gstreamer10_HEADER_FILES
llmediaimplgstreamer_syms.h
llmediaimplgstreamertriviallogging.h
)
add_library(media_plugin_gstreamer10
SHARED
${media_plugin_gstreamer10_SOURCE_FILES}
)
target_link_libraries(media_plugin_gstreamer10
${LLPLUGIN_LIBRARIES}
${MEDIA_PLUGIN_BASE_LIBRARIES}
${LLCOMMON_LIBRARIES}
${PLUGIN_API_WINDOWS_LIBRARIES}
${GSTREAMER10_LIBRARIES}
)
add_dependencies(media_plugin_gstreamer10
${LLPLUGIN_LIBRARIES}
${MEDIA_PLUGIN_BASE_LIBRARIES}
${LLCOMMON_LIBRARIES}
)
if (WINDOWS)
set_target_properties(
media_plugin_gstreamer10
PROPERTIES
LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT"
)
endif (WINDOWS)

View File

@ -0,0 +1,53 @@
/**
* @file llmediaimplgstreamer.h
* @author Tofu Linden
* @brief implementation that supports media playback via GStreamer.
*
* @cond
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
* @endcond
*/
// header guard
#ifndef llmediaimplgstreamer_h
#define llmediaimplgstreamer_h
#if LL_GSTREAMER010_ENABLED
extern "C" {
#include <stdio.h>
#include <gst/gst.h>
#include "apr_pools.h"
#include "apr_dso.h"
}
extern "C" {
gboolean llmediaimplgstreamer_bus_callback (GstBus *bus,
GstMessage *message,
gpointer data);
}
#endif // LL_GSTREAMER010_ENABLED
#endif // llmediaimplgstreamer_h

View File

@ -0,0 +1,197 @@
/**
* @file llmediaimplgstreamer_syms.cpp
* @brief dynamic GStreamer symbol-grabbing code
*
* @cond
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
* @endcond
*/
#include <string>
#include <iostream>
#include <vector>
#ifdef LL_WINDOWS
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0502
#include <Windows.h>
#endif
#include "linden_common.h"
extern "C" {
#include <gst/gst.h>
#include <gst/app/gstappsink.h>
}
#include "apr_pools.h"
#include "apr_dso.h"
#ifdef LL_WINDOWS
#ifndef _M_AMD64
#define GSTREAMER_REG_KEY "Software\\GStreamer1.0\\x86"
#define GSTREAMER_DIR_SUFFIX "1.0\\x86\\bin\\"
#else
#define GSTREAMER_REG_KEY "Software\\GStreamer1.0\\x86_64"
#define GSTREAMER_DIR_SUFFIX "1.0\\x86_64\\bin\\"
#endif
bool openRegKey( HKEY &aKey )
{
// Try native (32 bit view/64 bit view) of registry first.
if( ERROR_SUCCESS == ::RegOpenKeyExA( HKEY_LOCAL_MACHINE, GSTREAMER_REG_KEY, 0, KEY_QUERY_VALUE, &aKey ) )
return true;
// If native view fails, use 32 bit view or registry.
if( ERROR_SUCCESS == ::RegOpenKeyExA( HKEY_LOCAL_MACHINE, GSTREAMER_REG_KEY, 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &aKey ) )
return true;
return false;
}
std::string getGStreamerDir()
{
std::string ret;
HKEY hKey;
if( openRegKey( hKey ) )
{
DWORD dwLen(0);
::RegQueryValueExA( hKey, "InstallDir", nullptr, nullptr, nullptr, &dwLen );
if( dwLen > 0 )
{
std::vector< char > vctBuffer;
vctBuffer.resize( dwLen );
::RegQueryValueExA( hKey, "InstallDir", nullptr, nullptr, reinterpret_cast< LPBYTE>(&vctBuffer[ 0 ]), &dwLen );
ret = &vctBuffer[0];
if( ret[ dwLen-1 ] != '\\' )
ret += "\\";
ret += GSTREAMER_DIR_SUFFIX;
SetDllDirectoryA( ret.c_str() );
}
::RegCloseKey( hKey );
}
return ret;
}
#else
std::string getGStreamerDir() { return ""; }
#endif
#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL;
#include "llmediaimplgstreamer_syms_raw.inc"
#undef LL_GST_SYM
struct Symloader
{
bool mRequired;
char const *mName;
apr_dso_handle_sym_t *mPPFunc;
};
#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) { REQ, #GSTSYM , (apr_dso_handle_sym_t*)&ll##GSTSYM},
Symloader sSyms[] = {
#include "llmediaimplgstreamer_syms_raw.inc"
{ false, 0, 0 } };
#undef LL_GST_SYM
// a couple of stubs for disgusting reasons
GstDebugCategory*
ll_gst_debug_category_new(gchar *name, guint color, gchar *description)
{
static GstDebugCategory dummy;
return &dummy;
}
void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname)
{
}
static bool sSymsGrabbed = false;
static apr_pool_t *sSymGSTDSOMemoryPool = NULL;
std::vector< apr_dso_handle_t* > sLoadedLibraries;
bool grab_gst_syms( std::vector< std::string > const &aDSONames )
{
if (sSymsGrabbed)
return true;
//attempt to load the shared libraries
apr_pool_create(&sSymGSTDSOMemoryPool, NULL);
for( std::vector< std::string >::const_iterator itr = aDSONames.begin(); itr != aDSONames.end(); ++itr )
{
apr_dso_handle_t *pDSO(NULL);
std::string strDSO = getGStreamerDir() + *itr;
if( APR_SUCCESS == apr_dso_load( &pDSO, strDSO.c_str(), sSymGSTDSOMemoryPool ))
sLoadedLibraries.push_back( pDSO );
for( int i = 0; sSyms[ i ].mName; ++i )
{
if( !*sSyms[ i ].mPPFunc )
{
apr_dso_sym( sSyms[ i ].mPPFunc, pDSO, sSyms[ i ].mName );
}
}
}
std::stringstream strm;
bool sym_error = false;
for( int i = 0; sSyms[ i ].mName; ++i )
{
if( sSyms[ i ].mRequired && ! *sSyms[ i ].mPPFunc )
{
sym_error = true;
strm << sSyms[ i ].mName << std::endl;
}
}
sSymsGrabbed = !sym_error;
return sSymsGrabbed;
}
void ungrab_gst_syms()
{
// should be safe to call regardless of whether we've
// actually grabbed syms.
for( std::vector< apr_dso_handle_t* >::iterator itr = sLoadedLibraries.begin(); itr != sLoadedLibraries.end(); ++itr )
apr_dso_unload( *itr );
sLoadedLibraries.clear();
if ( sSymGSTDSOMemoryPool )
{
apr_pool_destroy(sSymGSTDSOMemoryPool);
sSymGSTDSOMemoryPool = NULL;
}
for( int i = 0; sSyms[ i ].mName; ++i )
*sSyms[ i ].mPPFunc = NULL;
sSymsGrabbed = false;
}

View File

@ -0,0 +1,68 @@
/**
* @file llmediaimplgstreamer_syms.h
* @brief dynamic GStreamer symbol-grabbing code
*
* @cond
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
* @endcond
*/
#include "linden_common.h"
#include <vector>
extern "C" {
#include <gst/gst.h>
}
bool grab_gst_syms( std::vector< std::string > const&);
void ungrab_gst_syms();
#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__);
#include "llmediaimplgstreamer_syms_raw.inc"
#undef LL_GST_SYM
// regrettable hacks to give us better runtime compatibility with older systems
#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0)
#define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0)
// regrettable hacks because GStreamer was not designed for runtime loading
#undef GST_TYPE_MESSAGE
#define GST_TYPE_MESSAGE (llgst_message_get_type())
#undef GST_TYPE_OBJECT
#define GST_TYPE_OBJECT (llgst_object_get_type())
#undef GST_TYPE_PIPELINE
#define GST_TYPE_PIPELINE (llgst_pipeline_get_type())
#undef GST_TYPE_ELEMENT
#define GST_TYPE_ELEMENT (llgst_element_get_type())
#undef GST_TYPE_VIDEO_SINK
#define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type())
// more regrettable hacks to stub-out these .h-exposed GStreamer internals
void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname);
#undef _gst_debug_register_funcptr
#define _gst_debug_register_funcptr ll_gst_debug_register_funcptr
GstDebugCategory* ll_gst_debug_category_new(gchar *name, guint color, gchar *description);
#undef _gst_debug_category_new
#define _gst_debug_category_new ll_gst_debug_category_new
#undef __gst_debug_enabled
#define __gst_debug_enabled (0)
// more hacks
#define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M)))

View File

@ -0,0 +1,68 @@
LL_GST_SYM(true, gst_buffer_new, GstBuffer*, void)
LL_GST_SYM(true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*)
LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err)
LL_GST_SYM(true, gst_message_get_type, GType, void)
LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type)
LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug)
LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug)
LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending)
LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state)
LL_GST_SYM(true, gst_object_unref, void, gpointer object)
LL_GST_SYM(true, gst_object_get_type, GType, void)
LL_GST_SYM(true, gst_pipeline_get_type, GType, void)
LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline)
LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data)
LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name)
LL_GST_SYM(true, gst_element_get_type, GType, void)
LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template)
LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp)
LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string)
LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index)
LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type)
LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value)
LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname)
LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value)
LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value)
LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure)
LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64)
LL_GST_SYM(false, gst_registry_fork_set_enabled, void, gboolean enabled)
LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled)
LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent)
LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug)
LL_GST_SYM(false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur)
LL_GST_SYM(false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano)
LL_GST_SYM( true, gst_message_parse_tag, void, GstMessage *, GstTagList **)
LL_GST_SYM( true, gst_tag_list_foreach, void, const GstTagList *, GstTagForeachFunc, gpointer)
LL_GST_SYM( true, gst_tag_list_get_tag_size, guint, const GstTagList *, const gchar *)
LL_GST_SYM( true, gst_tag_list_get_value_index, const GValue *, const GstTagList *, const gchar *, guint)
LL_GST_SYM( true, gst_caps_new_simple, GstCaps*, const char *, const char*, ... )
LL_GST_SYM( true, gst_sample_get_caps, GstCaps*, GstSample* )
LL_GST_SYM( true, gst_sample_get_buffer, GstBuffer*, GstSample* )
LL_GST_SYM( true, gst_buffer_map, gboolean, GstBuffer*, GstMapInfo*, GstMapFlags )
LL_GST_SYM( true, gst_buffer_unmap, void, GstBuffer*, GstMapInfo* )
LL_GST_SYM( true, gst_app_sink_set_caps, void, GstAppSink*, GstCaps const* )
LL_GST_SYM( true, gst_app_sink_pull_sample, GstSample*, GstAppSink* )
LL_GST_SYM( true, g_free, void, gpointer )
LL_GST_SYM( true, g_error_free, void, GError* )
LL_GST_SYM( true, g_main_context_pending, gboolean, GMainContext* )
LL_GST_SYM( true, g_main_loop_get_context, GMainContext*, GMainLoop* )
LL_GST_SYM( true, g_main_context_iteration, gboolean, GMainContext*, gboolean )
LL_GST_SYM( true, g_main_loop_new, GMainLoop*, GMainContext*, gboolean )
LL_GST_SYM( true, g_main_loop_quit, void, GMainLoop* )
LL_GST_SYM( true, gst_mini_object_unref, void, GstMiniObject* )
LL_GST_SYM( true, g_object_set, void, gpointer, gchar const*, ... )
LL_GST_SYM( true, g_source_remove, gboolean, guint )
LL_GST_SYM( true, g_value_get_string, gchar const*, GValue const* )
LL_GST_SYM( true, gst_debug_set_active, void, gboolean )
LL_GST_SYM( true, gst_debug_add_log_function, void, GstLogFunction, gpointer, GDestroyNotify )
LL_GST_SYM( true, gst_debug_set_default_threshold, void, GstDebugLevel )
LL_GST_SYM( true, gst_debug_message_get , gchar const*, GstDebugMessage * )

View File

@ -0,0 +1,980 @@
/**
* @file media_plugin_gstreamer10.cpp
* @brief GStreamer-1.0 plugin for LLMedia API plugin system
*
* @cond
* $LicenseInfo:firstyear=2016&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2016, Linden Research, Inc. / Nicky Dasmijn
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
* @endcond
*/
#define FLIP_Y
#include "linden_common.h"
#include "llgl.h"
#include "llplugininstance.h"
#include "llpluginmessage.h"
#include "llpluginmessageclasses.h"
#include "media_plugin_base.h"
#define G_DISABLE_CAST_CHECKS
extern "C" {
#include <gst/gst.h>
#include <gst/app/gstappsink.h>
}
#include "llmediaimplgstreamer.h"
#include "llmediaimplgstreamer_syms.h"
static inline void llgst_caps_unref( GstCaps * caps )
{
llgst_mini_object_unref( GST_MINI_OBJECT_CAST( caps ) );
}
static inline void llgst_sample_unref( GstSample *aSample )
{
llgst_mini_object_unref( GST_MINI_OBJECT_CAST( aSample ) );
}
//////////////////////////////////////////////////////////////////////////////
//
class MediaPluginGStreamer10 : public MediaPluginBase
{
public:
MediaPluginGStreamer10(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
~MediaPluginGStreamer10();
/* virtual */ void receiveMessage(const char *message_string);
static bool startup();
static bool closedown();
gboolean processGSTEvents(GstBus *bus, GstMessage *message);
private:
std::string getVersion();
bool navigateTo( const std::string urlIn );
bool seek( double time_sec );
bool setVolume( float volume );
// misc
bool pause();
bool stop();
bool play(double rate);
bool getTimePos(double &sec_out);
double MIN_LOOP_SEC = 1.0F;
U32 INTERNAL_TEXTURE_SIZE = 1024;
bool mIsLooping;
enum ECommand {
COMMAND_NONE,
COMMAND_STOP,
COMMAND_PLAY,
COMMAND_FAST_FORWARD,
COMMAND_FAST_REWIND,
COMMAND_PAUSE,
COMMAND_SEEK,
};
ECommand mCommand;
private:
bool unload();
bool load();
bool update(int milliseconds);
void mouseDown( int x, int y );
void mouseUp( int x, int y );
void mouseMove( int x, int y );
static bool mDoneInit;
guint mBusWatchID;
float mVolume;
int mDepth;
// padded texture size we need to write into
int mTextureWidth;
int mTextureHeight;
bool mSeekWanted;
double mSeekDestination;
// Very GStreamer-specific
GMainLoop *mPump; // event pump for this media
GstElement *mPlaybin;
GstAppSink *mAppSink;
};
//static
bool MediaPluginGStreamer10::mDoneInit = false;
MediaPluginGStreamer10::MediaPluginGStreamer10( LLPluginInstance::sendMessageFunction host_send_func,
void *host_user_data )
: MediaPluginBase(host_send_func, host_user_data)
, mBusWatchID ( 0 )
, mSeekWanted(false)
, mSeekDestination(0.0)
, mPump ( NULL )
, mPlaybin ( NULL )
, mAppSink ( NULL )
, mCommand ( COMMAND_NONE )
{
}
gboolean MediaPluginGStreamer10::processGSTEvents(GstBus *bus, GstMessage *message)
{
if (!message)
return TRUE; // shield against GStreamer bug
switch (GST_MESSAGE_TYPE (message))
{
case GST_MESSAGE_BUFFERING:
{
// NEEDS GST 0.10.11+
if (llgst_message_parse_buffering)
{
gint percent = 0;
llgst_message_parse_buffering(message, &percent);
}
break;
}
case GST_MESSAGE_STATE_CHANGED:
{
GstState old_state;
GstState new_state;
GstState pending_state;
llgst_message_parse_state_changed(message,
&old_state,
&new_state,
&pending_state);
switch (new_state)
{
case GST_STATE_VOID_PENDING:
break;
case GST_STATE_NULL:
break;
case GST_STATE_READY:
setStatus(STATUS_LOADED);
break;
case GST_STATE_PAUSED:
setStatus(STATUS_PAUSED);
break;
case GST_STATE_PLAYING:
setStatus(STATUS_PLAYING);
break;
}
break;
}
case GST_MESSAGE_ERROR:
{
GError *err = NULL;
gchar *debug = NULL;
llgst_message_parse_error (message, &err, &debug);
if (err)
llg_error_free (err);
llg_free (debug);
mCommand = COMMAND_STOP;
setStatus(STATUS_ERROR);
break;
}
case GST_MESSAGE_INFO:
{
if (llgst_message_parse_info)
{
GError *err = NULL;
gchar *debug = NULL;
llgst_message_parse_info (message, &err, &debug);
if (err)
llg_error_free (err);
llg_free (debug);
}
break;
}
case GST_MESSAGE_WARNING:
{
GError *err = NULL;
gchar *debug = NULL;
llgst_message_parse_warning (message, &err, &debug);
if (err)
llg_error_free (err);
llg_free (debug);
break;
}
case GST_MESSAGE_EOS:
/* end-of-stream */
if (mIsLooping)
{
double eos_pos_sec = 0.0F;
bool got_eos_position = getTimePos(eos_pos_sec);
if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC)
{
// if we know that the movie is really short, don't
// loop it else it can easily become a time-hog
// because of GStreamer spin-up overhead
// inject a COMMAND_PAUSE
mCommand = COMMAND_PAUSE;
}
else
{
stop();
play(1.0);
}
}
else // not a looping media
{
// inject a COMMAND_STOP
mCommand = COMMAND_STOP;
}
break;
default:
/* unhandled message */
break;
}
/* we want to be notified again the next time there is a message
* on the bus, so return true (false means we want to stop watching
* for messages on the bus and our callback should not be called again)
*/
return TRUE;
}
extern "C" {
gboolean llmediaimplgstreamer_bus_callback (GstBus *bus,
GstMessage *message,
gpointer data)
{
MediaPluginGStreamer10 *impl = (MediaPluginGStreamer10*)data;
return impl->processGSTEvents(bus, message);
}
} // extern "C"
bool MediaPluginGStreamer10::navigateTo ( const std::string urlIn )
{
if (!mDoneInit)
return false; // error
setStatus(STATUS_LOADING);
mSeekWanted = false;
if (NULL == mPump || NULL == mPlaybin)
{
setStatus(STATUS_ERROR);
return false; // error
}
llg_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL);
// navigateTo implicitly plays, too.
play(1.0);
return true;
}
class GstSampleUnref
{
GstSample *mT;
public:
GstSampleUnref( GstSample *aT )
: mT( aT )
{ llassert_always( mT ); }
~GstSampleUnref( )
{ llgst_sample_unref( mT ); }
};
bool MediaPluginGStreamer10::update(int milliseconds)
{
if (!mDoneInit)
return false; // error
// DEBUGMSG("updating media...");
// sanity check
if (NULL == mPump || NULL == mPlaybin)
{
return false;
}
// see if there's an outstanding seek wanted
if (mSeekWanted &&
// bleh, GST has to be happy that the movie is really truly playing
// or it may quietly ignore the seek (with rtsp:// at least).
(GST_STATE(mPlaybin) == GST_STATE_PLAYING))
{
seek(mSeekDestination);
mSeekWanted = false;
}
// *TODO: time-limit - but there isn't a lot we can do here, most
// time is spent in gstreamer's own opaque worker-threads. maybe
// we can do something sneaky like only unlock the video object
// for 'milliseconds' and otherwise hold the lock.
while (llg_main_context_pending(llg_main_loop_get_context(mPump)))
{
llg_main_context_iteration(llg_main_loop_get_context(mPump), FALSE);
}
// check for availability of a new frame
if( !mAppSink )
return true;
if( GST_STATE(mPlaybin) != GST_STATE_PLAYING) // Do not try to pull a sample if not in playing state
return true;
GstSample *pSample = llgst_app_sink_pull_sample( mAppSink );
if(!pSample)
return false; // Done playing
GstSampleUnref oSampleUnref( pSample );
GstCaps *pCaps = llgst_sample_get_caps ( pSample );
if (!pCaps)
return false;
gint width, height;
GstStructure *pStruct = llgst_caps_get_structure ( pCaps, 0);
int res = llgst_structure_get_int ( pStruct, "width", &width);
res |= llgst_structure_get_int ( pStruct, "height", &height);
if( !mPixels )
return true;
GstBuffer *pBuffer = llgst_sample_get_buffer ( pSample );
GstMapInfo map;
llgst_buffer_map ( pBuffer, &map, GST_MAP_READ);
// Our render buffer is always 1kx1k
U32 rowSkip = INTERNAL_TEXTURE_SIZE / mTextureHeight;
U32 colSkip = INTERNAL_TEXTURE_SIZE / mTextureWidth;
for (int row = 0; row < mTextureHeight; ++row)
{
U8 const *pTexelIn = map.data + (row*rowSkip * width *3);
#ifndef FLIP_Y
U8 *pTexelOut = mPixels + (row * mTextureWidth * mDepth );
#else
U8 *pTexelOut = mPixels + ((mTextureHeight-row-1) * mTextureWidth * mDepth );
#endif
for( int col = 0; col < mTextureWidth; ++col )
{
pTexelOut[ 0 ] = pTexelIn[0];
pTexelOut[ 1 ] = pTexelIn[1];
pTexelOut[ 2 ] = pTexelIn[2];
pTexelOut += mDepth;
pTexelIn += colSkip*3;
}
}
llgst_buffer_unmap( pBuffer, &map );
setDirty(0,0,mTextureWidth,mTextureHeight);
return true;
}
void MediaPluginGStreamer10::mouseDown( int x, int y )
{
// do nothing
}
void MediaPluginGStreamer10::mouseUp( int x, int y )
{
// do nothing
}
void MediaPluginGStreamer10::mouseMove( int x, int y )
{
// do nothing
}
bool MediaPluginGStreamer10::pause()
{
// todo: error-check this?
if (mDoneInit && mPlaybin)
{
llgst_element_set_state(mPlaybin, GST_STATE_PAUSED);
return true;
}
return false;
}
bool MediaPluginGStreamer10::stop()
{
// todo: error-check this?
if (mDoneInit && mPlaybin)
{
llgst_element_set_state(mPlaybin, GST_STATE_READY);
return true;
}
return false;
}
bool MediaPluginGStreamer10::play(double rate)
{
// NOTE: we don't actually support non-natural rate.
// todo: error-check this?
if (mDoneInit && mPlaybin)
{
llgst_element_set_state(mPlaybin, GST_STATE_PLAYING);
return true;
}
return false;
}
bool MediaPluginGStreamer10::setVolume( float volume )
{
// we try to only update volume as conservatively as
// possible, as many gst-plugins-base versions up to at least
// November 2008 have critical race-conditions in setting volume - sigh
if (mVolume == volume)
return true; // nothing to do, everything's fine
mVolume = volume;
if (mDoneInit && mPlaybin)
{
llg_object_set(mPlaybin, "volume", mVolume, NULL);
return true;
}
return false;
}
bool MediaPluginGStreamer10::seek(double time_sec)
{
bool success = false;
if (mDoneInit && mPlaybin)
{
success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME,
GstSeekFlags(GST_SEEK_FLAG_FLUSH |
GST_SEEK_FLAG_KEY_UNIT),
GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND),
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
}
return success;
}
bool MediaPluginGStreamer10::getTimePos(double &sec_out)
{
bool got_position = false;
if (mDoneInit && mPlaybin)
{
gint64 pos(0);
GstFormat timefmt = GST_FORMAT_TIME;
got_position =
llgst_element_query_position &&
llgst_element_query_position(mPlaybin,
&timefmt,
&pos);
got_position = got_position
&& (timefmt == GST_FORMAT_TIME);
// GStreamer may have other ideas, but we consider the current position
// undefined if not PLAYING or PAUSED
got_position = got_position &&
(GST_STATE(mPlaybin) == GST_STATE_PLAYING ||
GST_STATE(mPlaybin) == GST_STATE_PAUSED);
if (got_position && !GST_CLOCK_TIME_IS_VALID(pos))
{
if (GST_STATE(mPlaybin) == GST_STATE_PLAYING)
{
// if we're playing then we treat an invalid clock time
// as 0, for complicated reasons (insert reason here)
pos = 0;
}
else
{
got_position = false;
}
}
// If all the preconditions succeeded... we can trust the result.
if (got_position)
{
sec_out = double(pos) / double(GST_SECOND); // gst to sec
}
}
return got_position;
}
bool MediaPluginGStreamer10::load()
{
if (!mDoneInit)
return false; // error
setStatus(STATUS_LOADING);
mIsLooping = false;
mVolume = 0.1234567f; // minor hack to force an initial volume update
// Create a pumpable main-loop for this media
mPump = llg_main_loop_new (NULL, FALSE);
if (!mPump)
{
setStatus(STATUS_ERROR);
return false; // error
}
// instantiate a playbin element to do the hard work
mPlaybin = llgst_element_factory_make ("playbin", "");
if (!mPlaybin)
{
setStatus(STATUS_ERROR);
return false; // error
}
// get playbin's bus
GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin));
if (!bus)
{
setStatus(STATUS_ERROR);
return false; // error
}
mBusWatchID = llgst_bus_add_watch (bus,
llmediaimplgstreamer_bus_callback,
this);
llgst_object_unref (bus);
mAppSink = (GstAppSink*)(llgst_element_factory_make ("appsink", ""));
GstCaps* pCaps = llgst_caps_new_simple( "video/x-raw",
"format", G_TYPE_STRING, "RGB",
"width", G_TYPE_INT, INTERNAL_TEXTURE_SIZE,
"height", G_TYPE_INT, INTERNAL_TEXTURE_SIZE,
NULL );
llgst_app_sink_set_caps( mAppSink, pCaps );
llgst_caps_unref( pCaps );
if (!mAppSink)
{
setStatus(STATUS_ERROR);
return false;
}
llg_object_set(mPlaybin, "video-sink", mAppSink, NULL);
return true;
}
bool MediaPluginGStreamer10::unload ()
{
if (!mDoneInit)
return false; // error
// stop getting callbacks for this bus
llg_source_remove(mBusWatchID);
mBusWatchID = 0;
if (mPlaybin)
{
llgst_element_set_state (mPlaybin, GST_STATE_NULL);
llgst_object_unref (GST_OBJECT (mPlaybin));
mPlaybin = NULL;
}
if (mPump)
{
llg_main_loop_quit(mPump);
mPump = NULL;
}
mAppSink = NULL;
setStatus(STATUS_NONE);
return true;
}
void LogFunction(GstDebugCategory *category, GstDebugLevel level, const gchar *file, const gchar *function, gint line, GObject *object, GstDebugMessage *message, gpointer user_data )
#ifndef LL_LINUX // Docu says we need G_GNUC_NO_INSTRUMENT, but GCC says 'error'
G_GNUC_NO_INSTRUMENT
#endif
{
#ifdef LL_LINUX
std::cerr << file << ":" << line << "(" << function << "): " << llgst_debug_message_get( message ) << std::endl;
#endif
}
//static
bool MediaPluginGStreamer10::startup()
{
// first - check if GStreamer is explicitly disabled
if (NULL != getenv("LL_DISABLE_GSTREAMER"))
return false;
// only do global GStreamer initialization once.
if (!mDoneInit)
{
ll_init_apr();
// Get symbols!
std::vector< std::string > vctDSONames;
#if LL_DARWIN
#elif LL_WINDOWS
vctDSONames.push_back( "libgstreamer-1.0-0.dll" );
vctDSONames.push_back( "libgstapp-1.0-0.dll" );
vctDSONames.push_back( "libglib-2.0-0.dll" );
vctDSONames.push_back( "libgobject-2.0-0.dll" );
#else // linux or other ELFy unixoid
vctDSONames.push_back( "libgstreamer-1.0.so.0" );
vctDSONames.push_back( "libgstapp-1.0.so.0" );
vctDSONames.push_back( "libglib-2.0.so.0" );
vctDSONames.push_back( "libgobject-2.0.so" );
#endif
if( !grab_gst_syms( vctDSONames ) )
{
return false;
}
if (llgst_segtrap_set_enabled)
{
llgst_segtrap_set_enabled(FALSE);
}
#if LL_LINUX
// Gstreamer tries a fork during init, waitpid-ing on it,
// which conflicts with any installed SIGCHLD handler...
struct sigaction tmpact, oldact;
if (llgst_registry_fork_set_enabled ) {
// if we can disable SIGCHLD-using forking behaviour,
// do it.
llgst_registry_fork_set_enabled(false);
}
else {
// else temporarily install default SIGCHLD handler
// while GStreamer initialises
tmpact.sa_handler = SIG_DFL;
sigemptyset( &tmpact.sa_mask );
tmpact.sa_flags = SA_SIGINFO;
sigaction(SIGCHLD, &tmpact, &oldact);
}
#endif // LL_LINUX
// Protect against GStreamer resetting the locale, yuck.
static std::string saved_locale;
saved_locale = setlocale(LC_ALL, NULL);
// _putenv_s( "GST_PLUGIN_PATH", "E:\\gstreamer\\1.0\\x86\\lib\\gstreamer-1.0" );
llgst_debug_set_default_threshold( GST_LEVEL_WARNING );
llgst_debug_add_log_function( LogFunction, NULL, NULL );
llgst_debug_set_active( false );
// finally, try to initialize GStreamer!
GError *err = NULL;
gboolean init_gst_success = llgst_init_check(NULL, NULL, &err);
// restore old locale
setlocale(LC_ALL, saved_locale.c_str() );
#if LL_LINUX
// restore old SIGCHLD handler
if (!llgst_registry_fork_set_enabled)
sigaction(SIGCHLD, &oldact, NULL);
#endif // LL_LINUX
if (!init_gst_success) // fail
{
if (err)
{
llg_error_free(err);
}
return false;
}
mDoneInit = true;
}
return true;
}
//static
bool MediaPluginGStreamer10::closedown()
{
if (!mDoneInit)
return false; // error
ungrab_gst_syms();
mDoneInit = false;
return true;
}
MediaPluginGStreamer10::~MediaPluginGStreamer10()
{
closedown();
}
std::string MediaPluginGStreamer10::getVersion()
{
std::string plugin_version = "GStreamer10 media plugin, GStreamer version ";
if (mDoneInit &&
llgst_version)
{
guint major, minor, micro, nano;
llgst_version(&major, &minor, &micro, &nano);
plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor,
(unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR,
(unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO);
}
else
{
plugin_version += "(unknown)";
}
return plugin_version;
}
void MediaPluginGStreamer10::receiveMessage(const char *message_string)
{
LLPluginMessage message_in;
if(message_in.parse(message_string) >= 0)
{
std::string message_class = message_in.getClass();
std::string message_name = message_in.getName();
if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
{
if(message_name == "init")
{
LLPluginMessage message("base", "init_response");
LLSD versions = LLSD::emptyMap();
versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION;
message.setValueLLSD("versions", versions);
load();
message.setValue("plugin_version", getVersion());
sendMessage(message);
}
else if(message_name == "idle")
{
// no response is necessary here.
double time = message_in.getValueReal("time");
// Convert time to milliseconds for update()
update((int)(time * 1000.0f));
}
else if(message_name == "cleanup")
{
unload();
closedown();
}
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");
mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
}
else if(message_name == "shm_remove")
{
std::string name = message_in.getValue("name");
SharedSegmentMap::iterator iter = mSharedSegments.find(name);
if(iter != mSharedSegments.end())
{
if(mPixels == iter->second.mAddress)
{
// This is the currently active pixel buffer. Make sure we stop drawing to it.
mPixels = NULL;
mTextureSegmentName.clear();
}
mSharedSegments.erase(iter);
}
// Send the response so it can be cleaned up.
LLPluginMessage message("base", "shm_remove_response");
message.setValue("name", name);
sendMessage(message);
}
}
else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
{
if(message_name == "init")
{
// Plugin gets to decide the texture parameters to use.
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
// lame to have to decide this now, it depends on the movie. Oh well.
mDepth = 4;
mTextureWidth = 1;
mTextureHeight = 1;
message.setValueU32("format", GL_RGBA);
message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV);
message.setValueS32("depth", mDepth);
message.setValueS32("default_width", INTERNAL_TEXTURE_SIZE );
message.setValueS32("default_height", INTERNAL_TEXTURE_SIZE );
message.setValueU32("internalformat", GL_RGBA8);
message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left.
message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale
sendMessage(message);
}
else if(message_name == "size_change")
{
std::string name = message_in.getValue("name");
S32 width = message_in.getValueS32("width");
S32 height = message_in.getValueS32("height");
S32 texture_width = message_in.getValueS32("texture_width");
S32 texture_height = message_in.getValueS32("texture_height");
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
message.setValue("name", name);
message.setValueS32("width", width);
message.setValueS32("height", height);
message.setValueS32("texture_width", texture_width);
message.setValueS32("texture_height", texture_height);
sendMessage(message);
if(!name.empty())
{
// Find the shared memory region with this name
SharedSegmentMap::iterator iter = mSharedSegments.find(name);
if(iter != mSharedSegments.end())
{
mPixels = (unsigned char*)iter->second.mAddress;
mTextureSegmentName = name;
mTextureWidth = texture_width;
mTextureHeight = texture_height;
memset( mPixels, 0, mTextureWidth*mTextureHeight*mDepth );
}
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request");
message.setValue("name", mTextureSegmentName);
message.setValueS32("width", INTERNAL_TEXTURE_SIZE );
message.setValueS32("height", INTERNAL_TEXTURE_SIZE );
sendMessage(message);
}
}
else if(message_name == "load_uri")
{
std::string uri = message_in.getValue("uri");
navigateTo( uri );
sendStatus();
}
else if(message_name == "mouse_event")
{
std::string event = message_in.getValue("event");
S32 x = message_in.getValueS32("x");
S32 y = message_in.getValueS32("y");
if(event == "down")
{
mouseDown(x, y);
}
else if(event == "up")
{
mouseUp(x, y);
}
else if(event == "move")
{
mouseMove(x, y);
};
};
}
else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
{
if(message_name == "stop")
{
stop();
}
else if(message_name == "start")
{
double rate = 0.0;
if(message_in.hasValue("rate"))
{
rate = message_in.getValueReal("rate");
}
// NOTE: we don't actually support rate.
play(rate);
}
else if(message_name == "pause")
{
pause();
}
else if(message_name == "seek")
{
double time = message_in.getValueReal("time");
// defer the actual seek in case we haven't
// really truly started yet in which case there
// is nothing to seek upon
mSeekWanted = true;
mSeekDestination = time;
}
else if(message_name == "set_loop")
{
bool loop = message_in.getValueBoolean("loop");
mIsLooping = loop;
}
else if(message_name == "set_volume")
{
double volume = message_in.getValueReal("volume");
setVolume(volume);
}
}
}
}
int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
{
if( MediaPluginGStreamer10::startup() )
{
MediaPluginGStreamer10 *self = new MediaPluginGStreamer10(host_send_func, host_user_data);
*plugin_send_func = MediaPluginGStreamer10::staticReceiveMessage;
*plugin_user_data = (void*)self;
return 0; // okay
}
else
{
return -1; // failed to init
}
}

View File

@ -429,7 +429,7 @@ extern "C" {
return DefDriverProc_orig( dwDriverIdentifier, hdrvr, uMsg, lParam1, lParam2);
}
BOOL WINAPI DriverCallback( DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
BOOL WINAPI DriverCallback( DWORD_PTR dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
{
ll_winmm_shim_initialize();
//OutputDebugString(L"DriverCallback\n");

View File

@ -46,7 +46,7 @@ typedef HMODULE (WINAPI *GetDriverModuleHandle_type)( HDRVR hDriver);
extern GetDriverModuleHandle_type GetDriverModuleHandle_orig;
typedef LRESULT (WINAPI *DefDriverProc_type)( DWORD_PTR dwDriverIdentifier, HDRVR hdrvr, UINT uMsg, LPARAM lParam1, LPARAM lParam2);
extern DefDriverProc_type DefDriverProc_orig;
typedef BOOL (WINAPI *DriverCallback_type)(DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
typedef BOOL( WINAPI *DriverCallback_type )(DWORD_PTR dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
extern DriverCallback_type DriverCallback_orig;
typedef UINT (WINAPI *mmsystemGetVersion_type)(void);
extern mmsystemGetVersion_type mmsystemGetVersion_orig;

View File

@ -169,6 +169,8 @@ extern "C"
{
short volume_16 = (short)(sVolumeLevel * 32767.f);
// <FS:ND/> For x64 we leave out the MMX loop as it needs to be rewritten with SSE2 (_m128) instead of _m64. Needs a check if winshim is even used for x64 before invessting more time.
#ifndef _M_AMD64
// copy volume level 4 times into 64 bit MMX register
__m64 volume_64 = _mm_set_pi16(volume_16, volume_16, volume_16, volume_16);
__m64* sample_64;
@ -189,6 +191,9 @@ extern "C"
// the captain has turned off the MMX sign, you are now free to use floating point registers
_mm_empty();
#else
short *sample_64 = (short*)pwh->lpData;
#endif
// finish remaining samples that didn't fit into 64 bit register
for (short* sample_16 = (short*)sample_64;

View File

@ -139,6 +139,7 @@ set(viewer_SOURCE_FILES
fsdroptarget.cpp
fsexportperms.cpp
fsfloateraddtocontactset.cpp
fsfloateravatarrendersettings.cpp
fsfloaterblocklist.cpp
fsfloatercontacts.cpp
fsfloatercontactsetconfiguration.cpp
@ -879,6 +880,7 @@ set(viewer_HEADER_FILES
fsdroptarget.h
fsexportperms.h
fsfloateraddtocontactset.h
fsfloateravatarrendersettings.h
fsfloaterblocklist.h
fsfloatercontacts.h
fsfloatercontactsetconfiguration.h
@ -1976,6 +1978,20 @@ if (NOT USESYSTEMLIBS)
list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
endif (NOT USESYSTEMLIBS)
# <FS:Ansariel> Add Firestorm folders
file(GLOB viewer_FONT_FILES fonts/*.xml)
source_group("Fonts" FILES ${viewer_FONT_FILES})
set_source_files_properties(${viewer_FONT_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND viewer_SOURCE_FILES ${viewer_FONT_FILES})
file(GLOB viewer_FS_RESOURCES fs_resources/*)
source_group("Firestorm Resources" FILES ${viewer_FS_RESOURCES})
set_source_files_properties(${viewer_FS_RESOURCES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND viewer_SOURCE_FILES ${viewer_FS_RESOURCES})
# </FS:Ansariel>
if (WINDOWS)
file(GLOB viewer_INSTALLER_FILES installers/windows/*.nsi)
@ -2110,6 +2126,7 @@ if (WINDOWS)
SLPlugin
media_plugin_quicktime
media_plugin_cef
media_plugin_gstreamer10
winmm_shim
windows-crash-logger
)
@ -2166,14 +2183,10 @@ if (WINDOWS)
add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)
endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
if( NOT ND_BUILD64BIT_ARCH )
add_dependencies(${VIEWER_BINARY_NAME}
SLPlugin
windows-crash-logger
windows-crash-logger
)
else()
add_dependencies(${VIEWER_BINARY_NAME} windows-crash-logger )
endif( NOT ND_BUILD64BIT_ARCH )
# sets the 'working directory' for debugging from visual studio.
if (NOT UNATTENDED)
@ -2364,6 +2377,7 @@ else (NOT ENABLE_MEDIA_PLUGINS)
SLPlugin
media_plugin_cef
media_plugin_gstreamer010
media_plugin_gstreamer10
llcommon
)
endif (NOT ENABLE_MEDIA_PLUGINS)

View File

@ -1 +1 @@
4.7.8
4.7.10

View File

@ -60,7 +60,6 @@
-->
<string>import</string>
<string>export</string>
<string>fsdata</string>
<string>SLURL</string>
<string>Outfit</string>
</array>

View File

@ -1254,6 +1254,17 @@
<key>Value</key>
<string>+</string>
</map>
<key>RLVaCompatibilityModeList</key>
<map>
<key>Comment</key>
<string>Contains a list of creators or partial items names that require compatibility mode handling (see wiki for more information and syntax)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string></string>
</map>
<key>RLVaDebugDeprecateExplicitPoint</key>
<map>
<key>Comment</key>
@ -1287,6 +1298,17 @@
<key>Value</key>
<boolean>0</boolean>
</map>
<key>RLVaEnableIMQuery</key>
<map>
<key>Comment</key>
<string>Enables a limited number of configuration queries via IM (e.g. @version)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<boolean>1</boolean>
</map>
<key>RLVaEnableLegacyNaming</key>
<map>
<key>Comment</key>
@ -1309,6 +1331,17 @@
<key>Value</key>
<boolean>1</boolean>
</map>
<key>RLVaEnableTemporaryAttachments</key>
<map>
<key>Comment</key>
<string>Allows temporary attachments (regardless of origin) to issue RLV commands</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<boolean>1</boolean>
</map>
<key>RLVaExperimentalCommands</key>
<map>
<key>Comment</key>
@ -1388,17 +1421,6 @@
<key>Value</key>
<boolean>1</boolean>
</map>
<key>WarnFirstRLVGiveToRLV</key>
<map>
<key>Comment</key>
<string>Enables FirstRLVGiveToRLV warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<boolean>1</boolean>
</map>
<key>DebugSearch</key>
<map>
@ -6949,7 +6971,7 @@
<key>InventoryTrashMaxCapacity</key>
<map>
<key>Comment</key>
<string>Maximum capacity of the Trash folder. User will ve offered to clean it up when exceeded.</string>
<string>Maximum capacity of the Trash folder. User will be offered to clean it up when exceeded.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -22654,7 +22676,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>FSFlashOnMessage</key>
<map>
<key>Comment</key>
<string>Flash/Bounce the app icon when a new message is recieved and Firestorm is not in focus</string>
<string>Flash/Bounce the app icon when a new message is received and Firestorm is not in focus</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -22662,6 +22684,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>FSFlashOnObjectIM</key>
<map>
<key>Comment</key>
<string>Flash/Bounce the app icon when a new instant message from an object is received and Firestorm is not in focus.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FSDisableReturnObjectNotification</key>
<map>
<key>Comment</key>
@ -23908,17 +23941,6 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>SanityComment</key>
<string>This value needs to be greater than 0 for a fading effect.</string>
</map>
<key>FSFlipCEFY</key>
<map>
<key>Comment</key>
<string>Let CEF internally flip the generated image rather than do it on the GPU. More memory and CPU intensive if enabled. Requires restart.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FSStartupClearBrowserCache</key>
<map>
<key>Comment</key>
@ -24009,18 +24031,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>FSTagShowTooComplexARW</key>
<map>
<key>Comment</key>
<string>If enabled, the avatar complexity will be shown in the nametag for too complex avatars (Jelly Dolls)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FSTagAlwaysShowARW</key>
<key>FSTagShowARW</key>
<map>
<key>Comment</key>
<string>If enabled, the avatar complexity will be shown in the nametag for every avatar.</string>
@ -24029,8 +24040,52 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FSTagShowOwnARW</key>
<map>
<key>Comment</key>
<string>If enabled, the avatar complexity for the own avatar will be shown in the nametag.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSTagShowTooComplexOnlyARW</key>
<map>
<key>Comment</key>
<string>If enabled, the avatar complexity will be shown in the nametag only for too complex avatars (Jelly Dolls)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FSLinuxEnableWin32VoiceProxy</key>
<map>
<key>Comment</key>
<string>Use Win32 SLVoice.exe for voice. Needs wine (https://www.winehq.org/) installed, as SLVoice.exe is started inside wine.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSStatusBarMenuButtonPopupOnRollover</key>
<map>
<key>Comment</key>
<string>Enable rollover popups on top status bar menu icons: Quick Graphics Presets, Volume, and Media.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
</map>
</llsd>

View File

@ -19,6 +19,7 @@
#include "llviewerprecompiledheaders.h"
#include "fscorehttputil.h"
#include "llbufferstream.h"
#include "lluri.h"
#include "llxmltree.h"

View File

@ -19,6 +19,7 @@
#include "llviewerprecompiledheaders.h"
#include "fscorehttputil.h"
#include "llwindow.h"
#include "llviewerwindow.h"
#include "llbufferstream.h"

View File

@ -1611,7 +1611,11 @@ bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata)
{
LLUUID object_id = (*item_it)->getUUID();
LLViewerObject* objectp = gObjectList.findObject(object_id);
if (objectp)
// if (objectp)
// [RLVa:KB] - Checked: RLVa-2.0.0 | FS-specific
// Don't allow derendering of own attachments when RLVa is enabled
if ( (objectp) && (gAgentID != objectp->getID()) && ((!rlv_handler_t::isEnabled()) || (!objectp->isAttachment()) || (!objectp->permYouOwner())) )
// [/RLVa:KB]
{
std::string region_name;
LLViewerRegion* region = objectp->getRegion();

View File

@ -29,6 +29,7 @@
#include "fsavatarrenderpersistence.h"
#include "llsdserialize.h"
FSAvatarRenderPersistence::FSAvatarRenderPersistence()
{
}
@ -69,6 +70,8 @@ void FSAvatarRenderPersistence::setAvatarRenderSettings(const LLUUID& avatar_id,
{
mAvatarRenderMap[avatar_id] = render_settings;
}
mAvatarRenderSettingChangedCallback(avatar_id, render_settings);
}
void FSAvatarRenderPersistence::loadAvatarRenderSettings()

View File

@ -43,6 +43,15 @@ public:
LLVOAvatar::VisualMuteSettings getAvatarRenderSettings(const LLUUID& avatar_id);
void setAvatarRenderSettings(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_settings);
typedef std::map<LLUUID, LLVOAvatar::VisualMuteSettings> avatar_render_setting_t;
avatar_render_setting_t getAvatarRenderMap() const { return mAvatarRenderMap; }
typedef boost::signals2::signal<void(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_setting)> render_setting_changed_callback_t;
boost::signals2::connection setAvatarRenderSettingChangedCallback(const render_setting_changed_callback_t::slot_type& cb)
{
return mAvatarRenderSettingChangedCallback.connect(cb);
}
private:
FSAvatarRenderPersistence();
virtual ~FSAvatarRenderPersistence();
@ -50,8 +59,8 @@ private:
void loadAvatarRenderSettings();
void saveAvatarRenderSettings();
typedef std::map<LLUUID, LLVOAvatar::VisualMuteSettings> avatar_render_setting_t;
avatar_render_setting_t mAvatarRenderMap;
};
render_setting_changed_callback_t mAvatarRenderSettingChangedCallback;
};
#endif // FS_AVATARRENDERPERSISTENCE_H

View File

@ -325,7 +325,7 @@ bool FSCommon::checkIsActionEnabled(const LLUUID& av_id, EFSRegistrarFunctionAct
}
else if (action == FS_RGSTR_ACT_ZOOM_IN)
{
return (!isSelf && LLAvatarActions::canZoomIn(av_id));
return (!isSelf && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) && LLAvatarActions::canZoomIn(av_id));
}
else if (action == FS_RGSTR_ACT_OFFER_TELEPORT)
{

View File

@ -33,7 +33,7 @@
class LLAvatarName;
class LLViewerObject;
const F32 AVATAR_UNKNOWN_Z_OFFSET = -1.f; // Const value for avatars at unknown height
const F64 AVATAR_UNKNOWN_Z_OFFSET = -1.0; // Const value for avatars at unknown height
const F32 AVATAR_UNKNOWN_RANGE = -1.f;
void report_to_nearby_chat(const std::string& message);

View File

@ -32,6 +32,7 @@
#include "fsdata.h"
#include "fscommon.h"
#include "fscorehttputil.h"
#include "fswsassetblacklist.h"
/* boost: will not compile unless equivalent is undef'd, beware. */
@ -56,6 +57,11 @@
#include "llvfs.h"
#include "message.h"
// [RLVa:KB]
#include "rlvactions.h"
#include "rlvhelper.h"
// [/RLVa:KB]
const std::string LEGACY_CLIENT_LIST_URL = "http://phoenixviewer.com/app/client_tags/client_list_v2.xml";
const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730");
const F32 HTTP_TIMEOUT = 30.f;
@ -443,6 +449,13 @@ void FSData::processData(const LLSD& fs_data)
{
updateClientTagsLocal();
}
// [RLVa:KB]
if ( (RlvActions::isRlvEnabled()) && (fs_data.has("rlva_compat_list")) )
{
RlvSettings::initCompatibilityMode(fs_data["rlva_compat_list"].asString());
}
// [/RLVa:KB]
}
void FSData::processAssets(const LLSD& assets)

View File

@ -0,0 +1,150 @@
/**
* @file fsfloateravatarrendersettings.cpp
* @brief Floater for showing persisted avatar render settings
*
* $LicenseInfo:firstyear=2016&license=fsviewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (C) 2016, Ansariel Hiller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
* http://www.firestormviewer.org
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "fsfloateravatarrendersettings.h"
#include "llnamelistctrl.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
FSFloaterAvatarRenderSettings::FSFloaterAvatarRenderSettings(const LLSD& key)
: LLFloater(key),
mAvatarList(NULL),
mRenderSettingChangedCallbackConnection()
{
}
FSFloaterAvatarRenderSettings::~FSFloaterAvatarRenderSettings()
{
if (mRenderSettingChangedCallbackConnection.connected())
{
mRenderSettingChangedCallbackConnection.disconnect();
}
}
void FSFloaterAvatarRenderSettings::addElementToList(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_setting)
{
static const std::string av_render_never = getString("av_render_never");
static const std::string av_render_always = getString("av_render_always");
static const std::string av_name_waiting = LLTrans::getString("AvatarNameWaiting");
LLNameListCtrl::NameItem item_params;
item_params.value = avatar_id;
item_params.target = LLNameListCtrl::INDIVIDUAL;
item_params.columns.add().column("name");
item_params.name = av_name_waiting;
std::string render_value = (render_setting == LLVOAvatar::AV_DO_NOT_RENDER ? av_render_never : av_render_always);
item_params.columns.add().value(render_value).column("render_setting");
mAvatarList->addNameItemRow(item_params);
}
BOOL FSFloaterAvatarRenderSettings::postBuild()
{
mAvatarList = getChild<LLNameListCtrl>("avatar_list");
mAvatarList->setContextMenu(&FSFloaterAvatarRenderPersistenceMenu::gFSAvatarRenderPersistenceMenu);
childSetAction("close_btn", boost::bind(&FSFloaterAvatarRenderSettings::onCloseBtn, this));
mRenderSettingChangedCallbackConnection = FSAvatarRenderPersistence::instance().setAvatarRenderSettingChangedCallback(boost::bind(&FSFloaterAvatarRenderSettings::onAvatarRenderSettingChanged, this, _1, _2));
loadInitialList();
return TRUE;
}
void FSFloaterAvatarRenderSettings::onCloseBtn()
{
closeFloater();
}
void FSFloaterAvatarRenderSettings::loadInitialList()
{
FSAvatarRenderPersistence::avatar_render_setting_t avatar_render_map = FSAvatarRenderPersistence::instance().getAvatarRenderMap();
for (FSAvatarRenderPersistence::avatar_render_setting_t::iterator it = avatar_render_map.begin(); it != avatar_render_map.end(); ++it)
{
addElementToList(it->first, it->second);
}
}
void FSFloaterAvatarRenderSettings::onAvatarRenderSettingChanged(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_setting)
{
mAvatarList->removeNameItem(avatar_id);
if (render_setting != LLVOAvatar::AV_RENDER_NORMALLY)
{
addElementToList(avatar_id, render_setting);
}
}
namespace FSFloaterAvatarRenderPersistenceMenu
{
FSAvatarRenderPersistenceMenu gFSAvatarRenderPersistenceMenu;
LLContextMenu* FSAvatarRenderPersistenceMenu::createMenu()
{
// set up the callbacks for all of the avatar menu items
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("Avatar.ChangeRenderSetting", boost::bind(&FSAvatarRenderPersistenceMenu::changeRenderSetting, this, _2));
// create the context menu from the XUI
return createFromFile("menu_fs_avatar_render_setting.xml");
}
void FSAvatarRenderPersistenceMenu::changeRenderSetting(const LLSD& param)
{
LLVOAvatar::VisualMuteSettings render_setting = (LLVOAvatar::VisualMuteSettings)param.asInteger();
for (uuid_vec_t::iterator it = mUUIDs.begin(); it != mUUIDs.end(); ++it)
{
LLUUID avatar_id = *it;
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(gObjectList.findObject(avatar_id));
if (avatar)
{
// Set setting via the LLVOAvatar instance if it's available; will also call FSAvatarRenderPersistence::setAvatarRenderSettings()
avatar->setVisualMuteSettings(render_setting);
}
else
{
FSAvatarRenderPersistence::instance().setAvatarRenderSettings(avatar_id, render_setting);
}
}
LLVOAvatar::cullAvatarsByPixelArea();
}
}

View File

@ -0,0 +1,76 @@
/**
* @file fsfloateravatarrendersettings.h
* @brief Floater for showing persisted avatar render settings
*
* $LicenseInfo:firstyear=2016&license=fsviewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (C) 2016, Ansariel Hiller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
* http://www.firestormviewer.org
* $/LicenseInfo$
*/
#ifndef FS_FLOATERAVATARRENDERSETTINGS_H
#define FS_FLOATERAVATARRENDERSETTINGS_H
#include "fsavatarrenderpersistence.h"
#include "llfloater.h"
#include "lllistcontextmenu.h"
#include "llvoavatar.h"
class LLNameListCtrl;
class FSFloaterAvatarRenderSettings : public LLFloater
{
LOG_CLASS(FSFloaterAvatarRenderSettings);
public:
FSFloaterAvatarRenderSettings(const LLSD& key);
virtual ~FSFloaterAvatarRenderSettings();
/*virtual*/ BOOL postBuild();
private:
void onCloseBtn();
void onAvatarRenderSettingChanged(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_setting);
void loadInitialList();
void addElementToList(const LLUUID& avatar_id, LLVOAvatar::VisualMuteSettings render_setting);
LLNameListCtrl* mAvatarList;
boost::signals2::connection mRenderSettingChangedCallbackConnection;
};
namespace FSFloaterAvatarRenderPersistenceMenu
{
class FSAvatarRenderPersistenceMenu : public LLListContextMenu
{
public:
/*virtual*/ LLContextMenu* createMenu();
private:
void changeRenderSetting(const LLSD& param);
};
extern FSAvatarRenderPersistenceMenu gFSAvatarRenderPersistenceMenu;
} // namespace FSFloaterAvatarRenderPersistenceMenu
#endif // FS_FLOATERAVATARRENDERSETTINGS_H

View File

@ -2068,21 +2068,18 @@ void FSFloaterIM::sRemoveTypingIndicator(const LLSD& data)
floater->removeTypingIndicator();
}
void FSFloaterIM::onNewIMReceived( const LLUUID& session_id )
void FSFloaterIM::onNewIMReceived(const LLUUID& session_id)
{
if (isChatMultiTab())
{
FSFloaterIMContainer* im_box = FSFloaterIMContainer::getInstance();
if (!im_box) return;
if (FSFloaterIM::findInstance(session_id)) return;
if (FSFloaterIM::findInstance(session_id))
{
return;
}
FSFloaterIM* new_tab = FSFloaterIM::getInstance(session_id);
im_box->addFloater(new_tab, FALSE, LLTabContainer::END);
FSFloaterIMContainer::getInstance()->addNewSession(new_tab);
}
}
void FSFloaterIM::onClickCloseBtn(bool app_quitting)
@ -2362,6 +2359,9 @@ void FSFloaterIM::handleMinimized(bool minimized)
else
{
gConsole->addSession(mSessionID);
updateMessages();
if (mChatHistory)
{
updateMessages();
}
}
}

View File

@ -49,7 +49,8 @@ FSFloaterIMContainer::FSFloaterIMContainer(const LLSD& seed)
: LLMultiFloater(seed),
mActiveVoiceFloater(NULL),
mCurrentVoiceState(VOICE_STATE_NONE),
mForceVoiceStateUpdate(false)
mForceVoiceStateUpdate(false),
mIsAddingNewSession(false)
{
mAutoResize = FALSE;
LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
@ -233,31 +234,34 @@ void FSFloaterIMContainer::addFloater(LLFloater* floaterp,
{
// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-06-22 (Catznip-3.3.0)
// If we're redocking a torn off IM floater, return it back to its previous place
if ( (floaterp->isTornOff()) && (LLTabContainer::END == insertion_point) )
if (!mIsAddingNewSession && (floaterp->isTornOff()) && (LLTabContainer::END == insertion_point) )
{
LLChicletPanel* pChicletPanel = LLChicletBar::instance().getChicletPanel();
LLIMChiclet* pChiclet = pChicletPanel->findChiclet<LLIMChiclet>(floaterp->getKey());
S32 idxChiclet = pChicletPanel->getChicletIndex(pChiclet);
if ( (idxChiclet > 0) && (idxChiclet < pChicletPanel->getChicletCount()) )
if (pChiclet)
{
// Look for the first IM session to the left of this one
while (--idxChiclet >= 0)
S32 idxChiclet = pChicletPanel->getChicletIndex(pChiclet);
if ((idxChiclet > 0) && (idxChiclet < pChicletPanel->getChicletCount()))
{
if (pChiclet = dynamic_cast<LLIMChiclet*>(pChicletPanel->getChiclet(idxChiclet)))
// Look for the first IM session to the left of this one
while (--idxChiclet >= 0)
{
FSFloaterIM* pFloater = FSFloaterIM::findInstance(pChiclet->getSessionId());
if (pFloater)
if (pChiclet = dynamic_cast<LLIMChiclet*>(pChicletPanel->getChiclet(idxChiclet)))
{
insertion_point = (LLTabContainer::eInsertionPoint)(mTabContainer->getIndexForPanel(pFloater) + 1);
break;
FSFloaterIM* pFloater = FSFloaterIM::findInstance(pChiclet->getSessionId());
if (pFloater)
{
insertion_point = (LLTabContainer::eInsertionPoint)(mTabContainer->getIndexForPanel(pFloater) + 1);
break;
}
}
}
}
}
else
{
insertion_point = (0 == idxChiclet) ? LLTabContainer::START : LLTabContainer::END;
else
{
insertion_point = (0 == idxChiclet) ? LLTabContainer::START : LLTabContainer::END;
}
}
}
// [/SL:KB]
@ -270,6 +274,14 @@ void FSFloaterIMContainer::addFloater(LLFloater* floaterp,
floaterp->mCloseSignal.connect(boost::bind(&FSFloaterIMContainer::onCloseFloater, this, session_id));
}
void FSFloaterIMContainer::addNewSession(LLFloater* floaterp)
{
// Make sure we don't do some strange re-arranging if we add a new IM floater due to a new session
mIsAddingNewSession = true;
addFloater(floaterp, FALSE, LLTabContainer::END);
mIsAddingNewSession = false;
}
// [SL:KB] - Patch: Chat-NearbyChatBar | Checked: 2011-12-11 (Catznip-3.2.0d) | Added: Catznip-3.2.0d
void FSFloaterIMContainer::removeFloater(LLFloater* floaterp)
{

View File

@ -55,6 +55,8 @@ public:
// [/SL:KB]
bool hasFloater(LLFloater* floaterp);
void addNewSession(LLFloater* floaterp);
static FSFloaterIMContainer* findInstance();
static FSFloaterIMContainer* getInstance();
@ -99,6 +101,8 @@ private:
void checkFlashing();
uuid_vec_t mFlashingSessions;
bool mIsAddingNewSession;
// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3.0)
protected:
void onIMTabRearrange(S32 tab_index, LLPanel* tab_panel);

View File

@ -1968,13 +1968,13 @@ BOOL FSPanelSearchClassifieds::postBuild()
if (mClassifiedsCategory)
{
LLClassifiedInfo::cat_map::iterator iter;
mClassifiedsCategory->add(LLTrans::getString("all_categories"), LLSD("any"));
mClassifiedsCategory->add(LLTrans::getString("all_categories"), LLSD(0));
mClassifiedsCategory->addSeparator();
for (iter = LLClassifiedInfo::sCategories.begin();
iter != LLClassifiedInfo::sCategories.end();
iter++)
{
mClassifiedsCategory->add(LLTrans::getString(iter->second));
mClassifiedsCategory->add(LLTrans::getString(iter->second), LLSD((S32)iter->first));
}
}
childSetAction("classifieds_next", boost::bind(&FSPanelSearchClassifieds::onBtnNext, this));
@ -2008,7 +2008,7 @@ void FSPanelSearchClassifieds::find()
LLNotificationsUtil::add("NoContentToSearch");
return;
}
U32 category = childGetValue("classifieds_category").asInteger();
U32 category = mClassifiedsCategory->getValue().asInteger();
BOOL auto_renew = FALSE;
U32 flags = pack_classified_flags_request(auto_renew, inc_pg, inc_mature, inc_adult);

View File

@ -54,6 +54,8 @@
#include "llfirstuse.h"
#include "llsliderctrl.h"
#include "lltextbox.h"
#include "rlvcommon.h"
static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids);
void reshape_floater(FSFloaterVoiceControls* floater, S32 delta_height);
@ -112,6 +114,7 @@ FSFloaterVoiceControls::FSFloaterVoiceControls(const LLSD& key)
, mInitParticipantsVoiceState(false)
, mVolumeSlider(NULL)
, mMuteButton(NULL)
, mIsRlvShowNearbyRestricted(false)
{
static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10);
mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&FSFloaterVoiceControls::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay);
@ -158,6 +161,9 @@ BOOL FSFloaterVoiceControls::postBuild()
mVolumeSlider = findChild<LLSliderCtrl>("volume_slider");
mMuteButton = findChild<LLButton>("mute_btn");
mRlvRestrictedText = getChild<LLTextBox>("rlv_restricted");
mRlvRestrictedText->setText(RlvStrings::getString("blocked_nearby"));
if (mVolumeSlider && mMuteButton)
{
mAvatarList->setCommitCallback(boost::bind(&FSFloaterVoiceControls::onParticipantSelected, this));
@ -350,8 +356,10 @@ void FSFloaterVoiceControls::refreshParticipantList()
mNonAvatarCaller->setName(session->mName);
}
mNonAvatarCaller->setVisible(non_avatar_caller);
mAvatarList->setVisible(!non_avatar_caller);
// Ansariel: Changed for RLVa @shownearby
//mNonAvatarCaller->setVisible(non_avatar_caller);
//mAvatarList->setVisible(!non_avatar_caller);
updateListVisibility();
if (!non_avatar_caller)
{
@ -885,10 +893,45 @@ void FSFloaterVoiceControls::reset(const LLVoiceChannel::EState& new_state)
mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
}
mAvatarList->setVisible(TRUE);
mNonAvatarCaller->setVisible(FALSE);
// Ansariel: Changed for RLVa @shownearby
//mAvatarList->setVisible(TRUE);
//mNonAvatarCaller->setVisible(FALSE);
updateListVisibility();
mSpeakerManager = NULL;
}
void FSFloaterVoiceControls::toggleRlvShowNearbyRestriction(bool restricted)
{
mIsRlvShowNearbyRestricted = restricted;
updateListVisibility();
}
void FSFloaterVoiceControls::updateListVisibility()
{
if (mIsRlvShowNearbyRestricted && mVoiceType == VC_LOCAL_CHAT)
{
mAvatarList->setVisible(FALSE);
mNonAvatarCaller->setVisible(FALSE);
mRlvRestrictedText->setVisible(TRUE);
}
else
{
mRlvRestrictedText->setVisible(FALSE);
if (mParticipants)
{
// Case coming from refreshParticipantList
bool non_avatar_caller = VC_PEER_TO_PEER_AVALINE == mVoiceType;
mNonAvatarCaller->setVisible(non_avatar_caller);
mAvatarList->setVisible(!non_avatar_caller);
}
else
{
// Case coming from reset()
mAvatarList->setVisible(TRUE);
mNonAvatarCaller->setVisible(FALSE);
}
}
}
//EOF

View File

@ -43,6 +43,7 @@ class LLOutputMonitorCtrl;
class LLSpeakerMgr;
class LLSpeakersDelayActionsStorage;
class LLSliderCtrl;
class LLTextBox;
/**
* The Voice Control Panel is an ambient window summoned by clicking the flyout chevron
@ -82,6 +83,8 @@ public:
LLAvatarList* getAvatarCallerList() { return mAvatarList; }
// [/RLVa:KB]
void toggleRlvShowNearbyRestriction(bool restricted);
private:
typedef enum e_voice_controls_type
{
@ -248,6 +251,8 @@ private:
*/
void reset(const LLVoiceChannel::EState& new_state);
void updateListVisibility();
private:
speaker_state_map_t mSpeakerStateMap;
LLSpeakerMgr* mSpeakerManager;
@ -258,10 +263,12 @@ private:
LLPanel* mAgentPanel;
LLOutputMonitorCtrl* mSpeakingIndicator;
bool mIsModeratorMutedVoice;
bool mIsRlvShowNearbyRestricted;
LLUUID mSelectedParticipant;
LLSliderCtrl* mVolumeSlider;
LLButton* mMuteButton;
LLTextBox* mRlvRestrictedText;
/**
* Flag indicated that participants voice states should be initialized.

View File

@ -47,7 +47,7 @@
#endif
#include "llstartup.h"
#include "llcorehttputil.h"
#include "fscorehttputil.h"
void downloadError( LLSD const &aData, LLGridManager* mOwner, GridEntry* mData, LLGridManager::AddState mState )
{

View File

@ -42,6 +42,7 @@
#include "llpanelblockedlist.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewermenu.h" // for gMenuHolder
#include "rlvactions.h"
#include "rlvhandler.h"
@ -321,6 +322,11 @@ void FSPanelRadar::updateList(const std::vector<LLSD>& entries, const LLSD& stat
S32 lastScroll = mRadarList->getScrollPos();
// Update list
mRadarList->setCommentText(RlvActions::canShowNearbyAgents() ? LLStringUtil::null : RlvStrings::getString("blocked_nearby"));
bool needs_sort = mRadarList->isSorted();
mRadarList->setNeedsSort(false);
mRadarList->clearRows();
const std::vector<LLSD>::const_iterator it_end = entries.end();
for (std::vector<LLSD>::const_iterator it = entries.begin(); it != it_end; ++it)
@ -408,6 +414,9 @@ void FSPanelRadar::updateList(const std::vector<LLSD>& entries, const LLSD& stat
}
}
mRadarList->setNeedsSort(needs_sort);
mRadarList->updateSort();
LLStringUtil::format_map_t name_count_args;
name_count_args["[TOTAL]"] = stats["total"].asString();
name_count_args["[IN_REGION]"] = stats["region"].asString();

View File

@ -55,8 +55,9 @@
#include "llvoiceclient.h"
#include "llworld.h"
#include "llspeakers.h"
#include "rlvhandler.h"
#include "llviewerregion.h"
#include "rlvactions.h"
#include "rlvhandler.h"
using namespace boost;
@ -228,14 +229,16 @@ void FSRadar::updateRadarList()
//STEP 1: Update our basic data model: detect Avatars & Positions in our defined range
std::vector<LLVector3d> positions;
uuid_vec_t avatar_ids;
std::map<LLUUID, LLUUID> region_assignments;
if (sLimitRange)
if (RlvActions::canShowNearbyAgents())
{
world->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), sNearMeRange, &region_assignments);
}
else
{
world->getAvatars(&avatar_ids, &positions, LLVector3d(), FLT_MAX, &region_assignments);
if (sLimitRange)
{
world->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), sNearMeRange);
}
else
{
world->getAvatars(&avatar_ids, &positions);
}
}
// Determine lists of new added and removed avatars
@ -298,13 +301,7 @@ void FSRadar::updateRadarList()
// Skip modelling this avatar if its basic data is either inaccessible, or it's a dummy placeholder
FSRadarEntry* ent = getEntry(avId);
LLViewerRegion* reg = world->getRegionFromID(region_assignments[avId]);
if (!reg)
{
// Fallback in case we somehow didn't get the region via ID
LL_DEBUGS() << "Couldn't retrieve region by ID - falling back to region from global position" << LL_ENDL;
reg = world->getRegionFromPosGlobal(avPos);
}
LLViewerRegion* reg = world->getRegionFromPosGlobal(avPos);
if (!ent) // don't update this radar listing if data is inaccessible
{
continue;
@ -680,33 +677,35 @@ void FSRadar::updateRadarList()
//3b: process alerts for avatars that where here last frame, but gone this frame (ie, they left)
// as well as dispatch all earlier detected alerts for crossing range thresholds.
//
radarfields_map_t::iterator rf_it_end = mLastRadarSweep.end();
for (radarfields_map_t::iterator i = mLastRadarSweep.begin(); i != rf_it_end; ++i)
if (RlvActions::canShowNearbyAgents())
{
LLUUID prevId = i->first;
RadarFields rf = i->second;
if ((sFSRadarShowMutedAndDerendered || !rf.lastIgnore) && mEntryList.find(prevId) == mEntryList.end())
radarfields_map_t::iterator rf_it_end = mLastRadarSweep.end();
for (radarfields_map_t::iterator i = mLastRadarSweep.begin(); i != rf_it_end; ++i)
{
if (sRadarReportChatRangeLeave && (rf.lastDistance <= chat_range_say) && rf.lastDistance > AVATAR_UNKNOWN_RANGE)
LLUUID prevId = i->first;
RadarFields rf = i->second;
if ((sFSRadarShowMutedAndDerendered || !rf.lastIgnore) && mEntryList.find(prevId) == mEntryList.end())
{
make_ui_sound("UISndRadarChatLeave"); // <FS:PP> FIRE-6069: Radar alerts sounds
LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_chat_leaving));
}
if (sRadarReportDrawRangeLeave && (rf.lastDistance <= drawRadius) && rf.lastDistance > AVATAR_UNKNOWN_RANGE)
{
make_ui_sound("UISndRadarDrawLeave"); // <FS:PP> FIRE-6069: Radar alerts sounds
LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_draw_distance_leaving));
}
if (sRadarReportSimRangeLeave && (rf.lastRegion == regionSelf || rf.lastRegion.isNull()))
{
make_ui_sound("UISndRadarSimLeave"); // <FS:PP> FIRE-6069: Radar alerts sounds
LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_region_leaving));
}
if (sRadarLeaveChannelAlert)
{
mRadarLeaveAlerts.push_back(prevId);
if (sRadarReportChatRangeLeave && (rf.lastDistance <= chat_range_say) && rf.lastDistance > AVATAR_UNKNOWN_RANGE)
{
make_ui_sound("UISndRadarChatLeave"); // <FS:PP> FIRE-6069: Radar alerts sounds
LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_chat_leaving));
}
if (sRadarReportDrawRangeLeave && (rf.lastDistance <= drawRadius) && rf.lastDistance > AVATAR_UNKNOWN_RANGE)
{
make_ui_sound("UISndRadarDrawLeave"); // <FS:PP> FIRE-6069: Radar alerts sounds
LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_draw_distance_leaving));
}
if (sRadarReportSimRangeLeave && (rf.lastRegion == regionSelf || rf.lastRegion.isNull()))
{
make_ui_sound("UISndRadarSimLeave"); // <FS:PP> FIRE-6069: Radar alerts sounds
LLAvatarNameCache::get(prevId, boost::bind(&FSRadar::radarAlertMsg, this, _1, _2, str_region_leaving));
}
if (sRadarLeaveChannelAlert)
{
mRadarLeaveAlerts.push_back(prevId);
}
}
}
}
@ -789,7 +788,15 @@ void FSRadar::updateRadarList()
RadarFields rf;
rf.lastDistance = ent->mRange;
rf.lastIgnore = ent->mIgnore;
rf.lastRegion = ent->getRegion();
rf.lastRegion = LLUUID::null;
if (ent->mGlobalPos != LLVector3d(0.0, 0.0, 0.0))
{
LLViewerRegion* lastRegion = world->getRegionFromPosGlobal(ent->mGlobalPos);
if (lastRegion)
{
rf.lastRegion = lastRegion->getRegionID();
}
}
mLastRadarSweep[ent->mID] = rf;
}
@ -797,10 +804,18 @@ void FSRadar::updateRadarList()
//
//STEP 5: Final data updates and notification of subscribers
//
mAvatarStats["total"] = llformat("%d", mLastRadarSweep.size() - 1);
mAvatarStats["region"] = llformat("%d", inSameRegion);
mAvatarStats["chatrange"] = llformat("%d", inChatRange);
if (RlvActions::canShowNearbyAgents())
{
mAvatarStats["total"] = llformat("%d", mLastRadarSweep.size() - 1);
mAvatarStats["region"] = llformat("%d", inSameRegion);
mAvatarStats["chatrange"] = llformat("%d", inChatRange);
}
else
{
mAvatarStats["total"] = "-";
mAvatarStats["region"] = "-";
mAvatarStats["chatrange"] = "-";
}
checkTracking();

View File

@ -42,7 +42,7 @@ FSRadarEntry::FSRadarEntry(const LLUUID& avid)
mDisplayName(LLStringUtil::null),
mRange(0.f),
mFirstSeen(time(NULL)),
mGlobalPos(LLVector3d(0.0f,0.0f,0.0f)),
mGlobalPos(LLVector3d(0.0, 0.0, 0.0)),
mRegion(LLUUID::null),
mStatus(0),
mZOffset(0.f),

View File

@ -22,7 +22,8 @@
<File Id="llplugin_llceflib_host_exe" Source="$(var.PLUGIN_SOURCEDIR)\llplugin\llceflib_host.exe" />
<File Id="llplugin_llceflib_host_manifest" Source="$(var.PLUGIN_SOURCEDIR)\llplugin\llceflib_host.exe.manifest" />
<File Id="llplugin_media_plugin_cef_dll" Source="$(var.PLUGIN_SOURCEDIR)\llplugin\media_plugin_cef.dll" />
<File Id="llplugin_media_plugin_quicktime_dll" Source="$(var.PLUGIN_SOURCEDIR)\llplugin\media_plugin_quicktime.dll" />
<!-- <File Id="llplugin_media_plugin_quicktime_dll" Source="$(var.PLUGIN_SOURCEDIR)\llplugin\media_plugin_quicktime.dll" /> -->
<File Id="llplugin_media_plugin_gstreamer10_dll" Source="$(var.PLUGIN_SOURCEDIR)\llplugin\media_plugin_gstreamer10.dll" />
<File Id="llplugin_msvcp120_dll" Source="$(var.PLUGIN_SOURCEDIR)\llplugin\msvcp120.dll" />
<File Id="llplugin_msvcr120_dll" Source="$(var.PLUGIN_SOURCEDIR)\llplugin\msvcr120.dll" />
<File Id="llplugin_natives_blob_bin" Source="$(var.PLUGIN_SOURCEDIR)\llplugin\natives_blob.bin" />

View File

@ -2082,7 +2082,7 @@ bool LLAgentCamera::clampCameraPosition(LLVector3d& posCamGlobal, const LLVector
m_fRlvMinDist = true;
}
if (!isnan(nDistMult))
if (!llisnan(nDistMult))
{
posCamGlobal = posCamRefGlobal + nDistMult * offsetCamera;
m_posRlvRefGlobal = posCamRefGlobal;

View File

@ -62,6 +62,7 @@
#include "llavatarpropertiesprocessor.h"
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
#include "rlvactions.h"
#include "rlvhandler.h"
#include "rlvhelper.h"
#include "rlvlocks.h"
@ -1911,6 +1912,13 @@ bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id)
{
return false;
}
// [RLVa:KB] - Checked: RLVa-2.0.3
if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(outfit_cat_id, RLV_LOCK_REMOVE)) )
{
return false;
}
// [/RLVa:KB]
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false);
@ -1930,6 +1938,13 @@ bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id)
return false;
}
// [RLVa:KB] - Checked: RLVa-2.0.3
if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(outfit_cat_id, RLV_LOCK_ADD)) )
{
return false;
}
// [/RLVa:KB]
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
@ -1950,6 +1965,14 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
return false;
}
// [RLVa:KB] - Checked: RLVa-2.0.3
// Block "Replace Current Outfit" if the user can't wear the new folder
if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(outfit_cat_id, RLV_LOCK_ADD)) )
{
return false;
}
// [/RLVa:KB]
// Check whether it's the base outfit.
// if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-21 (Catznip-2.1)
@ -1959,17 +1982,20 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
return false;
}
// <FS:KC> FIRE-11920: Always allow replacing outfit
// Check whether the outfit contains any wearables we aren't wearing already (STORM-702).
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true);
gInventory.collectDescendentsIf(outfit_cat_id,
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
is_worn);
// LLInventoryModel::cat_array_t cats;
// LLInventoryModel::item_array_t items;
// LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true);
// gInventory.collectDescendentsIf(outfit_cat_id,
// cats,
// items,
// LLInventoryModel::EXCLUDE_TRASH,
// is_worn);
return items.size() > 0;
// return items.size() > 0;
return TRUE;
// </FS:KC> FIRE-11920: Always allow replacing outfit
}
// Moved from LLWearableList::ContextMenu for wider utility.
@ -2142,9 +2168,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
LLInventoryModel::item_array_t body_items;
getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART);
// getDescendentsOfAssetType(category, body_items, LLAssetType::AT_BODYPART);
// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0)
// [RLVa:KB] - Checked: RLVa-2.0.3
// Filter out any new body parts that can't be worn before adding them
if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) )
if ( (RlvActions::isRlvEnabled()) && ((gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ADD))) )
body_items_new.erase(std::remove_if(body_items_new.begin(), body_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR_REPLACE)), body_items_new.end());
body_items.insert(body_items.end(), body_items_new.begin(), body_items_new.end());
// [/RLVa:KB]
@ -2159,8 +2185,8 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
LLInventoryModel::item_array_t wear_items;
if (append)
getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING);
// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0)
else if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) )
// [RLVa:KB] - Checked: RLVa-2.0.3
else if ( (RlvActions::isRlvEnabled()) && ((gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_REMOVE))) )
{
// Make sure that all currently locked clothing layers remain in COF when replacing
getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING);
@ -2168,9 +2194,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
}
// [/RLVa:KB]
// getDescendentsOfAssetType(category, wear_items, LLAssetType::AT_CLOTHING);
// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0)
// [RLVa:KB] - Checked: RLVa-2.0.3
// Filter out any new wearables that can't be worn before adding them
if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) )
if ( (RlvActions::isRlvEnabled()) && ((gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ADD))) )
wear_items_new.erase(std::remove_if(wear_items_new.begin(), wear_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR)), wear_items_new.end());
wear_items.insert(wear_items.end(), wear_items_new.begin(), wear_items_new.end());
// [/RLVa:KB]
@ -2185,8 +2211,8 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
LLInventoryModel::item_array_t obj_items;
if (append)
getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT);
// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0z) | Modified: RLVa-1.2.0b
else if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
// [RLVa:KB] - Checked: RLVa-2.0.3
else if ( (RlvActions::isRlvEnabled()) && ((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_REMOVE))) )
{
// Make sure that all currently locked attachments remain in COF when replacing
getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT);
@ -2194,9 +2220,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
}
// [/RLVa:KB]
// getDescendentsOfAssetType(category, obj_items, LLAssetType::AT_OBJECT);
// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0)
// [RLVa:KB] - Checked: RLVa-2.0.3
// Filter out any new attachments that can't be worn before adding them
if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
if ( (RlvActions::isRlvEnabled()) && ((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ADD))) )
obj_items_new.erase(std::remove_if(obj_items_new.begin(), obj_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR)), obj_items_new.end());
obj_items.insert(obj_items.end(), obj_items_new.begin(), obj_items_new.end());
// [/RLVa:KB]

View File

@ -1162,6 +1162,7 @@ bool LLAppViewer::init()
// Early out from user choice.
return false;
}
LL_INFOS("InitInfo") << "Hardware test initialization done." << LL_ENDL ;
// Prepare for out-of-memory situations, during which we will crash on
@ -3965,13 +3966,6 @@ LLSD LLAppViewer::getViewerInfo() const
// info["LLCEFLIB_VERSION"] = "Undefined";
//#endif
#if defined( FS_CEFLIB_VERSION ) && FS_CEFLIB_VERSION >= 6
{
std::stringstream strm;
strm << LLCEFLIB_BASE_VERSION << ".FS" << FS_CEFLIB_VERSION << "-" << FS_CEF_VERSION << " (Chrome " << FS_CEF_CHROME_VERSION << ")";
info[ "LLCEFLIB_VERSION" ] = strm.str();
}
#endif
// <FS:ND> Use the total accumulated samples.
//S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN);

View File

@ -563,7 +563,7 @@ void LLAvatarActions::teleport_request_callback(const LLSD& notification, const
std::string strMessage = response["message"];
// Filter the request message if the recipients is IM-blocked
if ( (!RlvActions::isRlvEnabled()) || ((RlvActions::canStartIM(idRecipient)) && (RlvActions::canSendIM(idRecipient))) )
if ( (RlvActions::isRlvEnabled()) && ((!RlvActions::canStartIM(idRecipient)) || (!RlvActions::canSendIM(idRecipient))) )
{
strMessage = RlvStrings::getString(RLV_STRING_HIDDEN);
}
@ -1634,7 +1634,7 @@ void LLAvatarActions::getScriptInfo(const LLUUID& idAgent)
// Defined in llworld.cpp
LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin);
LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin, F32 width_scale_factor);
// static - Checked: 2010-12-03 (Catznip-2.4.0g) | Added: Catznip-2.4.0g
bool getRegionAndPosGlobalFromAgentID(const LLUUID& idAgent, const LLViewerRegion** ppRegion, LLVector3d* pPosGlobal)
@ -1663,7 +1663,7 @@ bool getRegionAndPosGlobalFromAgentID(const LLUUID& idAgent, const LLViewerRegio
if (ppRegion)
*ppRegion = pRegion;
if (pPosGlobal)
*pPosGlobal = unpackLocalToGlobalPosition(pRegion->mMapAvatars.at(idxRegionAgent), pRegion->getOriginGlobal());
*pPosGlobal = unpackLocalToGlobalPosition(pRegion->mMapAvatars.at(idxRegionAgent), pRegion->getOriginGlobal(), pRegion->getWidthScaleFactor());
return (NULL != pRegion);
}
}

View File

@ -294,6 +294,10 @@ void LLAvatarList::draw()
void LLAvatarList::clear()
{
getIDs().clear();
// [RLVa:KB] - Checked: RLVa-2.0.3
// We need to be able to call this *somehow* and it actually makes moderate sense to call this in here
updateNoItemsMessage(mNameFilter);
// [/RLVa:KB]
setDirty(true);
LLFlatListViewEx::clear();
}

View File

@ -42,21 +42,19 @@
#include "llsdutil.h" // <FS:ND/> for ll_pretty_print_sd
#include "boost/make_shared.hpp"
namespace LLEventPolling
{
namespace Details
{
class LLEventPollImpl
class LLEventPollImpl: public boost::enable_shared_from_this<LLEventPollImpl>
{
public:
LLEventPollImpl(const LLHost &sender);
// <FS:ND> FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active.
// void start(const std::string &url);
void start( const std::string &url, boost::shared_ptr< LLEventPollImpl > aThis );
// </FS:ND>
void start(const std::string &url);
void stop();
private:
@ -67,16 +65,14 @@ namespace Details
static const F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC;
static const S32 MAX_EVENT_POLL_HTTP_ERRORS;
// <FS:ND> FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active.
// void eventPollCoro(std::string url);
void eventPollCoro( std::string url, boost::shared_ptr< LLEventPollImpl > aThis );
// </FS:ND>
void eventPollCoro(std::string url);
void handleMessage(const LLSD &content);
bool mDone;
LLCore::HttpRequest::ptr_t mHttpRequest;
LLCore::HttpRequest::policy_t mHttpPolicy;
LLCore::HttpOptions::ptr_t mHttpOptions; // <FS:Ansariel> Restore pre-coro behavior (60s timeout, no retries)
std::string mSenderIp;
int mCounter;
LLCoreHttpUtil::HttpCoroutineAdapter::wptr_t mAdapter;
@ -96,6 +92,7 @@ namespace Details
mDone(false),
mHttpRequest(),
mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mHttpOptions(), // <FS:Ansariel> Restore pre-coro behavior (60s timeout, no retries)
mSenderIp(),
mCounter(sNextCounter++)
@ -104,6 +101,11 @@ namespace Details
mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest);
mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_LONG_POLL);
// <FS:Ansariel> Restore pre-coro behavior (60s timeout, no retries)
mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
mHttpOptions->setRetries(0);
mHttpOptions->setTransferTimeout(60);
// </FS:Ansariel>
mSenderIp = sender.getIPandPort();
}
@ -124,24 +126,13 @@ namespace Details
LLMessageSystem::dispatch(msg_name, message);
}
// <FS:ND> FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active.
// void LLEventPollImpl::start(const std::string &url)
void LLEventPollImpl::start( const std::string &url, boost::shared_ptr< LLEventPollImpl > aThis )
// </FS:ND>
void LLEventPollImpl::start(const std::string &url)
{
if (!url.empty())
{
// <FS:ND> FIRE-19557; Hold on LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active.
// std::string coroname =
// LLCoros::instance().launch("LLEventPollImpl::eventPollCoro",
// boost::bind(&LLEventPollImpl::eventPollCoro, this, url));
std::string coroname = LLCoros::instance().launch("LLEventPollImpl::eventPollCoro",
boost::bind( &LLEventPollImpl::eventPollCoro, this, url, aThis ) );
// </FS:ND>
std::string coroname =
LLCoros::instance().launch("LLEventPollImpl::eventPollCoro",
boost::bind(&LLEventPollImpl::eventPollCoro, this->shared_from_this(), url));
LL_INFOS("LLEventPollImpl") << coroname << " with url '" << url << LL_ENDL;
}
}
@ -163,11 +154,8 @@ namespace Details
}
}
// <FS:ND> FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active.
// void LLEventPollImpl::eventPollCoro(std::string url)
void LLEventPollImpl::eventPollCoro( std::string url, boost::shared_ptr< LLEventPollImpl > aThis )
// </FS:ND>
{
void LLEventPollImpl::eventPollCoro(std::string url)
{
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EventPoller", mHttpPolicy));
LLSD acknowledge;
int errorCount = 0;
@ -189,7 +177,10 @@ namespace Details
// << LLSDXMLStreamer(request) << LL_ENDL;
LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> posting and yielding." << LL_ENDL;
LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request);
// <FS:Ansariel> Restore pre-coro behavior (60s timeout, no retries)
//LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request);
LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request, mHttpOptions);
// </FS:Ansariel>
// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = "
// << LLSDXMLStreamer(result) << LL_ENDL;
@ -205,6 +196,15 @@ namespace Details
errorCount = 0;
continue;
}
// <FS:Ansariel> Restore pre-coro behavior (60s timeout, no retries)
else if (status == LLCore::HttpStatus(HTTP_BAD_GATEWAY))
{ // Pre-coro says this is the default answer for timeouts and it can happen
// frequently on OpenSim - assume this is normal and issue a new request immediately
LL_INFOS("LLEventPollImpl") << "Received HTTP 502 - start new request." << LL_ENDL;
errorCount = 0;
continue;
}
// </FS:Ansariel>
else if ((status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_OP_CANCELED)) ||
(status == LLCore::HttpStatus(HTTP_NOT_FOUND)))
{ // Event polling for this server has been canceled. In
@ -304,16 +304,8 @@ namespace Details
LLEventPoll::LLEventPoll(const std::string& poll_url, const LLHost& sender):
mImpl()
{
// <FS:ND> FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active.
// mImpl = boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl>
// (new LLEventPolling::Details::LLEventPollImpl(sender));
// mImpl->start(poll_url);
mImpl.reset( new LLEventPolling::Details::LLEventPollImpl(sender) );
mImpl->start( poll_url, mImpl );
// </FS:ND>
mImpl = boost::make_shared<LLEventPolling::Details::LLEventPollImpl>(sender);
mImpl->start(poll_url);
}
LLEventPoll::~LLEventPoll()

View File

@ -27,12 +27,6 @@
#ifndef LL_LLEVENTPOLL_H
#define LL_LLEVENTPOLL_H
#include "boost/move/unique_ptr.hpp"
namespace boost
{
using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace.
}
class LLHost;
@ -57,10 +51,7 @@ public:
private:
// <FS:ND> FIRE-19557; Hold on to LLEventPollImpl while the coroutine runs, otherwise the this pointer can get deleted while the coroutine is still active.
// boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl> mImpl;
boost::shared_ptr<LLEventPolling::Details::LLEventPollImpl> mImpl;
// </FS:ND>
boost::shared_ptr<LLEventPolling::Details::LLEventPollImpl> mImpl;
};

View File

@ -293,7 +293,8 @@ void LLFace::setTexture(U32 ch, LLViewerTexture* tex)
if ( (LLRender::DIFFUSE_MAP == ch) && (!mShowDiffTexture) )
{
mOrigDiffTexture = tex;
return;
if (LLViewerFetchedTexture::sDefaultDiffuseImagep.get() == mTexture[ch].get())
return;
}
// [/SL:KB]

View File

@ -110,6 +110,9 @@ public:
static void startFetchServerReleaseNotes();
static void handleServerReleaseNotes(LLSD results);
// <FS:Ansariel> FIRE-19760: In Help/About Firestorm server release notes not getting fetched
static void fetchServerReleaseNotesCoro(const std::string& cap_url);
};
@ -227,9 +230,11 @@ void LLFloaterAbout::startFetchServerReleaseNotes()
// an URL suitable for external browsers in the "Location:" HTTP header.
std::string cap_url = region->getCapability("ServerReleaseNotes");
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(cap_url,
&LLFloaterAbout::handleServerReleaseNotes, &LLFloaterAbout::handleServerReleaseNotes);
// <FS:Ansariel> FIRE-19760: In Help/About Firestorm server release notes not getting fetched
//LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(cap_url,
// &LLFloaterAbout::handleServerReleaseNotes, &LLFloaterAbout::handleServerReleaseNotes);
LLCoros::instance().launch("fetchServerReleaseNotesCoro", boost::bind(&LLFloaterAbout::fetchServerReleaseNotesCoro, cap_url));
// </FS:Ansariel>
}
/*static*/
@ -256,8 +261,45 @@ void LLFloaterAbout::handleServerReleaseNotes(LLSD results)
}
LLAppViewer::instance()->setServerReleaseNotesURL(location);
// }
// <FS:Ansariel> FIRE-19760: In Help/About Firestorm server release notes not getting fetched
LLFloaterAbout* floater_about = LLFloaterReg::findTypedInstance<LLFloaterAbout>("sl_about");
if (floater_about)
{
floater_about->setSupportText(location);
}
// </FS:Ansariel>
}
// <FS:Ansariel> FIRE-19760: In Help/About Firestorm server release notes not getting fetched
/*static*/
void LLFloaterAbout::fetchServerReleaseNotesCoro(const std::string& cap_url)
{
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("fetchServerReleaseNotesCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
LLSD result = httpAdapter->getAndSuspend(httpRequest, cap_url, httpOpts);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
{
handleServerReleaseNotes(httpResults);
}
else
{
handleServerReleaseNotes(result);
}
// </FS:Ansariel>
}
class LLFloaterAboutListener: public LLEventAPI
{
public:

View File

@ -54,6 +54,7 @@
#include <boost/regex.hpp>
#include "llspinctrl.h"
#include "llviewernetwork.h"
#include "llnotificationsutil.h"
#ifdef OPENSIM
#include "exoflickr.h"
@ -66,8 +67,12 @@ static LLPanelInjector<LLFlickrPhotoPanel> t_panel_photo("llflickrphotopanel");
static LLPanelInjector<LLFlickrAccountPanel> t_panel_account("llflickraccountpanel");
const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=flickr&utm_medium=photo&utm_campaign=slshare";
const std::string DEFAULT_TAG_TEXT = "secondlife ";
const std::string FLICKR_MACHINE_TAGS_NAMESPACE = "secondlife";
// <FS:Ansariel> Don't assume we're always in Second Life
//const std::string DEFAULT_TAG_TEXT = "secondlife ";
//const std::string FLICKR_MACHINE_TAGS_NAMESPACE = "secondlife";
const std::string DEFAULT_TAG_TEXT = "Firestorm ";
static std::string FLICKR_MACHINE_TAGS_NAMESPACE = "secondlife";
// </FS:Ansariel>
///////////////////////////
//LLFlickrPhotoPanel///////
@ -122,7 +127,10 @@ BOOL LLFlickrPhotoPanel::postBuild()
mDescriptionTextBox = getChild<LLUICtrl>("photo_description");
mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
mTagsTextBox = getChild<LLUICtrl>("photo_tags");
mTagsTextBox->setValue(DEFAULT_TAG_TEXT);
// <FS:Ansariel> Don't assume we're always in Second Life
//mTagsTextBox->setValue(DEFAULT_TAG_TEXT);
mTagsTextBox->setValue(DEFAULT_TAG_TEXT + (LLGridManager::instance().isInSecondLife() ? "secondlife" : ("\"" + LLGridManager::instance().getGridId()) + "\"") + " ");
// </FS:Ansariel>
mRatingComboBox = getChild<LLUICtrl>("rating_combobox");
mPostButton = getChild<LLUICtrl>("post_photo_btn");
mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
@ -391,7 +399,13 @@ void LLFlickrPhotoPanel::sendPhoto()
std::string slurl_string = slurl.getSLURLString();
// Add query parameters so Google Analytics can track incoming clicks!
slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
// <FS:Ansariel> Don't assume we're always in Second Life
//slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
if (LLGridManager::instance().isInSecondLife())
{
slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
}
// </FS:Ansariel>
std::string photo_link_text = "Visit this location";// at [] in Second Life";
std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName();
@ -404,7 +418,17 @@ void LLFlickrPhotoPanel::sendPhoto()
photo_link_text += " at " + parcel_name;
}
}
photo_link_text += " in Second Life";
// <FS:Ansariel> Don't assume we're always in Second Life
//photo_link_text += " in Second Life";
if (LLGridManager::instance().isInSecondLife())
{
photo_link_text += " in Second Life";
}
else
{
photo_link_text += " in \"" + LLGridManager::instance().getGridLabel() + "\"";
}
// </FS:Ansariel>
slurl_string = "<a href=\"" + slurl_string + "\">" + photo_link_text + "</a>";
@ -427,6 +451,13 @@ void LLFlickrPhotoPanel::sendPhoto()
std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName();
std::string region_name = region->getName();
// <FS:Ansariel> Don't assume we're always in Second Life
if (!LLGridManager::instance().isInSecondLife())
{
FLICKR_MACHINE_TAGS_NAMESPACE = LLGridManager::instance().getGridId();
}
// </FS:Ansariel>
if (!region_name.empty())
{
tags += llformat(" \"%s:region=%s\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), region_name.c_str());

View File

@ -768,6 +768,8 @@ BOOL LLFloaterPreference::postBuild()
// <FS:Ansariel> Properly disable avatar tag setting
gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAvatarTagSettingsChanged, this));
gSavedSettings.getControl("FSNameTagShowLegacyUsernames")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAvatarTagSettingsChanged, this));
gSavedSettings.getControl("AvatarNameTagMode")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAvatarTagSettingsChanged, this));
gSavedSettings.getControl("FSTagShowARW")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAvatarTagSettingsChanged, this));
onAvatarTagSettingsChanged();
// </FS:Ansariel>
@ -1192,15 +1194,17 @@ void LLFloaterPreference::onOpen(const LLSD& key)
// <FS:Ansariel> Fix resetting graphics preset on cancel
saveGraphicsPreset(gSavedSettings.getString("PresetGraphicActive"));
bool started = (LLStartUp::getStartupState() == STATE_STARTED);
// <FS:Ansariel> FIRE-19810: Make presets global since PresetGraphicActive setting is global as well
//bool started = (LLStartUp::getStartupState() == STATE_STARTED);
LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
LLButton* save_btn = findChild<LLButton>("PrefSaveButton");
LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
//LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
//LLButton* save_btn = findChild<LLButton>("PrefSaveButton");
//LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
load_btn->setEnabled(started);
save_btn->setEnabled(started);
delete_btn->setEnabled(started);
//load_btn->setEnabled(started);
//save_btn->setEnabled(started);
//delete_btn->setEnabled(started);
// </FS:Ansariel>
// <FS:ND> Hook up and init for filtering
collectSearchableItems();
@ -3219,7 +3223,10 @@ void LLFloaterPreference::onClickBlockList()
// </FS:Ansariel> Optional standalone blocklist floater
//LLFloaterSidePanelContainer::showPanel("people", "panel_people",
// LLSD().with("people_panel_tab_name", "blocked_panel"));
BOOL saved_setting = gSavedSettings.getBOOL("FSDisableBlockListAutoOpen");
gSavedSettings.setBOOL("FSDisableBlockListAutoOpen", FALSE);
LLPanelBlockedList::showPanelAndSelect();
gSavedSettings.setBOOL("FSDisableBlockListAutoOpen", saved_setting);
// </FS:Ansariel>
}
@ -3418,6 +3425,10 @@ void LLFloaterPreference::onAvatarTagSettingsChanged()
childSetEnabled("FSshow_legacyun", usernames_enabled);
childSetEnabled("legacy_trim_check", usernames_enabled && legacy_enabled);
bool arw_options_enabled = gSavedSettings.getBOOL("FSTagShowARW") && gSavedSettings.getS32("AvatarNameTagMode") > 0;
childSetEnabled("FSTagShowTooComplexOnlyARW", arw_options_enabled);
childSetEnabled("FSTagShowOwnARW", arw_options_enabled);
}
// </FS:Ansariel>
@ -3630,9 +3641,11 @@ BOOL LLPanelPreference::postBuild()
// <FS:Ansariel> Only enable Growl checkboxes if Growl is usable
if (hasChild("notify_growl_checkbox", TRUE))
{
BOOL growl_enabled = gSavedSettings.getBOOL("FSEnableGrowl") && GrowlManager::isUsable();
getChild<LLCheckBoxCtrl>("notify_growl_checkbox")->setCommitCallback(boost::bind(&LLPanelPreference::onEnableGrowlChanged, this));
getChild<LLCheckBoxCtrl>("notify_growl_checkbox")->setEnabled(GrowlManager::isUsable());
getChild<LLCheckBoxCtrl>("notify_growl_always_checkbox")->setEnabled(gSavedSettings.getBOOL("FSEnableGrowl") && GrowlManager::isUsable());
getChild<LLCheckBoxCtrl>("notify_growl_always_checkbox")->setEnabled(growl_enabled);
getChild<LLCheckBoxCtrl>("FSFilterGrowlKeywordDuplicateIMs")->setEnabled(growl_enabled);
}
// </FS:Ansariel>
@ -3736,7 +3749,9 @@ void LLPanelPreference::handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const
// <FS:Ansariel> Only enable Growl checkboxes if Growl is usable
void LLPanelPreference::onEnableGrowlChanged()
{
getChild<LLCheckBoxCtrl>("notify_growl_always_checkbox")->setEnabled(gSavedSettings.getBOOL("FSEnableGrowl") && GrowlManager::isUsable());
BOOL growl_enabled = gSavedSettings.getBOOL("FSEnableGrowl") && GrowlManager::isUsable();
getChild<LLCheckBoxCtrl>("notify_growl_always_checkbox")->setEnabled(growl_enabled);
getChild<LLCheckBoxCtrl>("FSFilterGrowlKeywordDuplicateIMs")->setEnabled(growl_enabled);
}
// </FS:Ansariel>
@ -4039,9 +4054,6 @@ BOOL LLPanelPreferenceGraphics::postBuild()
#endif // LL_DARWIN
// </FS:CR>
// <FS:Ansariel> Texture memory management
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue((F32)gMaxVideoRam.value());
return LLPanelPreference::postBuild();
}
void LLPanelPreferenceGraphics::draw()
@ -4918,55 +4930,10 @@ void FSPanelPreferenceBackup::onClickBackupSettings()
// and only restore selectively
std::string file = item->getColumn(2)->getValue().asString();
if (item->getValue().asString() != "presets")
{
LL_INFOS("SettingsBackup") << "copying per account file " << file << LL_ENDL;
copy_prefs_file(
gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file),
gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, file));
}
else
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR));
std::string presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR) + gDirUtilp->getDirDelimiter();
std::string graphics_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC) + gDirUtilp->getDirDelimiter();
std::string camera_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_CAMERA) + gDirUtilp->getDirDelimiter();
if (LLFile::isdir(graphics_presets_folder))
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR, PRESETS_GRAPHIC));
std::string file_name;
while (gDirUtilp->getNextFileInDir(graphics_presets_folder, "*", file_name))
{
std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, graphics_presets_folder, file_name);
if (LLFile::isfile(source.c_str()))
{
std::string target = gDirUtilp->add(gDirUtilp->add(gDirUtilp->add(backup_per_account_folder, PRESETS_DIR), PRESETS_GRAPHIC), file_name);
copy_prefs_file(source, target);
}
}
}
if (LLFile::isdir(camera_presets_folder))
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR, PRESETS_CAMERA));
std::string file_name;
while (gDirUtilp->getNextFileInDir(camera_presets_folder, "*", file_name))
{
std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, camera_presets_folder, file_name);
if (LLFile::isfile(source.c_str()))
{
std::string target = gDirUtilp->add(gDirUtilp->add(gDirUtilp->add(backup_per_account_folder, PRESETS_DIR), PRESETS_CAMERA), file_name);
copy_prefs_file(source, target);
}
}
}
}
LL_INFOS("SettingsBackup") << "copying per account file " << file << LL_ENDL;
copy_prefs_file(
gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file),
gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, file));
}
}
else
@ -4986,28 +4953,73 @@ void FSPanelPreferenceBackup::onClickBackupSettings()
LLScrollListItem* item = globalFoldersList[index];
// Don't bother with the checkbox and get the path, since we back up all folders
// and only restore selectively
std::string folder = item->getColumn(2)->getValue().asString();
std::string folder_name = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, folder) + gDirUtilp->getDirDelimiter();
std::string backup_folder_name = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, folder) + gDirUtilp->getDirDelimiter();
LL_INFOS("SettingsBackup") << "backing up global folder: " << folder_name << LL_ENDL;
// create folder if it's not there already
LLFile::mkdir(backup_folder_name.c_str());
std::string file_name;
while (gDirUtilp->getNextFileInDir(folder_name, "*", file_name))
if (item->getValue().asString() != "presets")
{
LL_INFOS("SettingsBackup") << "found entry: " << folder_name + file_name << LL_ENDL;
// only copy files, not subfolders
if (LLFile::isfile(folder_name + file_name.c_str()))
std::string folder = item->getColumn(2)->getValue().asString();
std::string folder_name = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, folder) + gDirUtilp->getDirDelimiter();
std::string backup_folder_name = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, folder) + gDirUtilp->getDirDelimiter();
LL_INFOS("SettingsBackup") << "backing up global folder: " << folder_name << LL_ENDL;
// create folder if it's not there already
LLFile::mkdir(backup_folder_name.c_str());
std::string file_name;
while (gDirUtilp->getNextFileInDir(folder_name, "*", file_name))
{
copy_prefs_file(folder_name + file_name, backup_folder_name + file_name);
LL_INFOS("SettingsBackup") << "found entry: " << folder_name + file_name << LL_ENDL;
// only copy files, not subfolders
if (LLFile::isfile(folder_name + file_name.c_str()))
{
copy_prefs_file(folder_name + file_name, backup_folder_name + file_name);
}
else
{
LL_INFOS("SettingsBackup") << "skipping subfolder " << folder_name + file_name << LL_ENDL;
}
}
else
}
else
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR));
std::string presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR) + gDirUtilp->getDirDelimiter();
std::string graphics_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_GRAPHIC) + gDirUtilp->getDirDelimiter();
std::string camera_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_CAMERA) + gDirUtilp->getDirDelimiter();
if (LLFile::isdir(graphics_presets_folder))
{
LL_INFOS("SettingsBackup") << "skipping subfolder " << folder_name + file_name << LL_ENDL;
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR, PRESETS_GRAPHIC));
std::string file_name;
while (gDirUtilp->getNextFileInDir(graphics_presets_folder, "*", file_name))
{
std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, graphics_presets_folder, file_name);
if (LLFile::isfile(source.c_str()))
{
std::string target = gDirUtilp->add(gDirUtilp->add(gDirUtilp->add(dir_name, PRESETS_DIR), PRESETS_GRAPHIC), file_name);
copy_prefs_file(source, target);
}
}
}
if (LLFile::isdir(camera_presets_folder))
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR, PRESETS_CAMERA));
std::string file_name;
while (gDirUtilp->getNextFileInDir(camera_presets_folder, "*", file_name))
{
std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, camera_presets_folder, file_name);
if (LLFile::isfile(source.c_str()))
{
std::string target = gDirUtilp->add(gDirUtilp->add(gDirUtilp->add(dir_name, PRESETS_DIR), PRESETS_CAMERA), file_name);
copy_prefs_file(source, target);
}
}
}
}
}
@ -5149,57 +5161,12 @@ void FSPanelPreferenceBackup:: doRestoreSettings(const LLSD& notification, const
// Only restore if this item is checked on
if (checkbox->getCheckBox()->getValue().asBoolean())
{
if (item->getValue().asString() != "presets")
{
// Get the path to restore for this item
std::string file = item->getColumn(2)->getValue().asString();
LL_INFOS("SettingsBackup") << "copying per account file " << file << LL_ENDL;
copy_prefs_file(
gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, file),
gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file));
}
else
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR));
std::string presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR) + gDirUtilp->getDirDelimiter();
std::string graphics_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR, PRESETS_GRAPHIC) + gDirUtilp->getDirDelimiter();
std::string camera_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, PRESETS_DIR, PRESETS_CAMERA) + gDirUtilp->getDirDelimiter();
if (LLFile::isdir(graphics_presets_folder))
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC));
std::string file_name;
while (gDirUtilp->getNextFileInDir(graphics_presets_folder, "*", file_name))
{
std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, graphics_presets_folder, file_name);
if (LLFile::isfile(source.c_str()))
{
std::string target = gDirUtilp->add(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC), file_name);
copy_prefs_file(source, target);
}
}
}
if (LLFile::isdir(camera_presets_folder))
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_CAMERA));
std::string file_name;
while (gDirUtilp->getNextFileInDir(camera_presets_folder, "*", file_name))
{
std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, camera_presets_folder, file_name);
if (LLFile::isfile(source.c_str()))
{
std::string target = gDirUtilp->add(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_CAMERA), file_name);
copy_prefs_file(source, target);
}
}
}
}
// Get the path to restore for this item
std::string file = item->getColumn(2)->getValue().asString();
LL_INFOS("SettingsBackup") << "copying per account file " << file << LL_ENDL;
copy_prefs_file(
gDirUtilp->getExpandedFilename(LL_PATH_NONE, backup_per_account_folder, file),
gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file));
}
}
@ -5237,29 +5204,74 @@ void FSPanelPreferenceBackup:: doRestoreSettings(const LLSD& notification, const
// Only restore if this item is checked on
if (checkbox->getCheckBox()->getValue().asBoolean())
{
// Get the path to restore for this item
std::string folder = item->getColumn(2)->getValue().asString();
std::string folder_name = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, folder) + gDirUtilp->getDirDelimiter();
std::string backup_folder_name = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, folder) + gDirUtilp->getDirDelimiter();
LL_INFOS("SettingsBackup") << "restoring global folder: " << folder_name << LL_ENDL;
// create folder if it's not there already
LLFile::mkdir(folder_name.c_str());
std::string file_name;
while (gDirUtilp->getNextFileInDir(backup_folder_name, "*", file_name))
if (item->getValue().asString() != "presets")
{
LL_INFOS("SettingsBackup") << "found entry: " << backup_folder_name + file_name << LL_ENDL;
// only restore files, not subfolders
if (LLFile::isfile(backup_folder_name + file_name.c_str()))
// Get the path to restore for this item
std::string folder = item->getColumn(2)->getValue().asString();
std::string folder_name = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, folder) + gDirUtilp->getDirDelimiter();
std::string backup_folder_name = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, folder) + gDirUtilp->getDirDelimiter();
LL_INFOS("SettingsBackup") << "restoring global folder: " << folder_name << LL_ENDL;
// create folder if it's not there already
LLFile::mkdir(folder_name.c_str());
std::string file_name;
while (gDirUtilp->getNextFileInDir(backup_folder_name, "*", file_name))
{
copy_prefs_file(backup_folder_name + file_name, folder_name + file_name);
LL_INFOS("SettingsBackup") << "found entry: " << backup_folder_name + file_name << LL_ENDL;
// only restore files, not subfolders
if (LLFile::isfile(backup_folder_name + file_name.c_str()))
{
copy_prefs_file(backup_folder_name + file_name, folder_name + file_name);
}
else
{
LL_INFOS("SettingsBackup") << "skipping subfolder " << backup_folder_name + file_name << LL_ENDL;
}
}
else
}
else
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR));
std::string presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR) + gDirUtilp->getDirDelimiter();
std::string graphics_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR, PRESETS_GRAPHIC) + gDirUtilp->getDirDelimiter();
std::string camera_presets_folder = gDirUtilp->getExpandedFilename(LL_PATH_NONE, dir_name, PRESETS_DIR, PRESETS_CAMERA) + gDirUtilp->getDirDelimiter();
if (LLFile::isdir(graphics_presets_folder))
{
LL_INFOS("SettingsBackup") << "skipping subfolder " << backup_folder_name + file_name << LL_ENDL;
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_GRAPHIC));
std::string file_name;
while (gDirUtilp->getNextFileInDir(graphics_presets_folder, "*", file_name))
{
std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, graphics_presets_folder, file_name);
if (LLFile::isfile(source.c_str()))
{
std::string target = gDirUtilp->add(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_GRAPHIC), file_name);
copy_prefs_file(source, target);
}
}
}
if (LLFile::isdir(camera_presets_folder))
{
LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_CAMERA));
std::string file_name;
while (gDirUtilp->getNextFileInDir(camera_presets_folder, "*", file_name))
{
std::string source = gDirUtilp->getExpandedFilename(LL_PATH_NONE, camera_presets_folder, file_name);
if (LLFile::isfile(source.c_str()))
{
std::string target = gDirUtilp->add(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_CAMERA), file_name);
copy_prefs_file(source, target);
}
}
}
}
}

View File

@ -640,7 +640,7 @@ void LLFriendCardsManager::onFriendListUpdate(U32 changed_mask)
void create_agent_calling_card_name_cb(const LLAvatarName& av_name, const LLUUID& calling_cards_folder_id)
{
create_inventory_item(gAgentID,
gAgent.getSessionID(),
gAgentSessionID,
calling_cards_folder_id,
LLTransactionID::tnull,
av_name.getUserName(),
@ -652,11 +652,8 @@ void create_agent_calling_card_name_cb(const LLAvatarName& av_name, const LLUUID
NULL);
}
// static
void LLFriendCardsManager::createAgentCallingCard()
void calling_card_folder_loaded_cb(const LLUUID& calling_cards_folder_id)
{
const LLUUID calling_cards_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindAgentCallingCard collector;
@ -668,5 +665,26 @@ void LLFriendCardsManager::createAgentCallingCard()
LLAvatarNameCache::get(gAgentID, boost::bind(&create_agent_calling_card_name_cb, _2, calling_cards_folder_id));
}
}
// static
void LLFriendCardsManager::createAgentCallingCard()
{
const LLUUID calling_cards_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
// This instance will be deleted in LLInitialFriendCardsFetch::done().
LLInitialFriendCardsFetch* fetch = new LLInitialFriendCardsFetch(calling_cards_folder_id, boost::bind(&calling_card_folder_loaded_cb, calling_cards_folder_id));
fetch->startFetch();
if (fetch->isFinished())
{
// everything is already here - call done.
fetch->done();
}
else
{
// it's all on it's way - add an observer, and the inventory
// will call done for us when everything is here.
gInventory.addObserver(fetch);
}
}
// </FS:Ansariel>
// EOF

View File

@ -326,8 +326,8 @@ bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response)
void LLGroupActions::leave(const LLUUID& group_id)
{
// if (group_id.isNull())
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f
if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))) )
// [RLVa:KB] - Checked: RLVa-1.3.0
if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (!RlvActions::canChangeActiveGroup())) )
// [/RLVa:KB]
{
return;
@ -388,8 +388,8 @@ void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id)
// static
void LLGroupActions::activate(const LLUUID& group_id)
{
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)) && (gRlvHandler.getAgentGroup() != group_id) )
// [RLVa:KB] - Checked: RLVa-1.3.0
if ( (!RlvActions::canChangeActiveGroup()) && (gRlvHandler.getAgentGroup() != group_id) )
{
return;
}

View File

@ -43,8 +43,8 @@
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewermenu.h" // for gMenuHolder
#include "llvoiceclient.h"
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
#include "rlvhandler.h"
// [RLVa:KB] - Checked: RLVa-2.0.3
#include "rlvactions.h"
// [/RLVa:KB]
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
@ -360,14 +360,14 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
bool real_group_selected = selected_group_id.notNull(); // a "real" (not "none") group is selected
// each group including "none" can be activated
// [RLVa:KB] - Checked: RLVa-1.3.0
if (userdata.asString() == "activate")
return (gAgent.getGroupID() != selected_group_id) && (RlvActions::canChangeActiveGroup());
else if (userdata.asString() == "leave")
return (real_group_selected) && ((gAgent.getGroupID() != selected_group_id) || (RlvActions::canChangeActiveGroup()));
// [/RLVa:KB]
// if (userdata.asString() == "activate")
// return gAgent.getGroupID() != selected_group_id;
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f
if (userdata.asString() == "activate")
return (gAgent.getGroupID() != selected_group_id) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP));
else if (userdata.asString() == "leave")
return (real_group_selected) && ((gAgent.getGroupID() != selected_group_id) || (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)));
// [/RLVa:KB]
if (userdata.asString() == "call")
return real_group_selected && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();

View File

@ -259,7 +259,7 @@ void LLHUDText::setString(const std::string &text_utf8)
{
mTextSegments.clear();
// addLine(text_utf8, mColor);
// [RLVa:KB] - Checked: 2010-03-02 (RLVa-1.4.0a) | Modified: RLVa-1.0.0f
// [RLVa:KB] - Checked: RLVa-2.0.3
// NOTE: setString() is called for debug and map beacons as well
if (RlvActions::isRlvEnabled())
{
@ -268,8 +268,10 @@ void LLHUDText::setString(const std::string &text_utf8)
{
if (!RlvActions::canShowLocation())
RlvUtil::filterLocation(text);
if (!RlvActions::canShowName(RlvActions::SNC_DEFAULT))
RlvUtil::filterNames(text);
bool fCanShowNearby = RlvActions::canShowNearbyAgents();
if ( (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) || (!fCanShowNearby) )
RlvUtil::filterNames(text, true, !fCanShowNearby);
}
else
{
@ -671,14 +673,16 @@ F32 LLHUDText::LLHUDTextSegment::getWidth(const LLFontGL* font)
}
}
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f
void LLHUDText::refreshAllObjectText()
// [RLVa:KB] - Checked: RLVa-2.0.3
void LLHUDText::refreshAllObjectText(EObjectTextFilter eObjFilter)
{
for (TextObjectIterator itText = sTextObjects.begin(); itText != sTextObjects.end(); ++itText)
for (LLHUDText* pText : sTextObjects)
{
LLHUDText* pText = *itText;
if ( (pText) && (!pText->mObjText.empty()) && (pText->mSourceObject) && (LL_PCODE_VOLUME == pText->mSourceObject->getPCode()) )
if ((pText) && (!pText->mObjText.empty()) && (pText->mSourceObject) && (LL_PCODE_VOLUME == pText->mSourceObject->getPCode()) &&
((OTF_NONE == eObjFilter) || ((OTF_HUD_ATTACHMENTS == eObjFilter) && (pText->mSourceObject->isHUDAttachment()))))
{
pText->setString(pText->mObjText);
}
}
}
// [/RLVa:KB]

View File

@ -124,10 +124,12 @@ public:
static void reshape();
static void setDisplayText(BOOL flag) { sDisplayText = flag ; }
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f
// [RLVa:KB] - Checked: RLVa-2.0.3
const std::string& getObjectText() const { return mObjText; }
void setObjectText(const std::string &utf8string) { mObjText = utf8string; }
static void refreshAllObjectText();
enum EObjectTextFilter { OTF_NONE, OTF_HUD_ATTACHMENTS };
static void refreshAllObjectText(EObjectTextFilter eObjFilter = OTF_NONE);
// [/RLVa:KB]
// <FS:Ansariel> FIRE-17393: Control HUD text fading by options
@ -170,7 +172,7 @@ private:
ETextAlignment mTextAlignment;
EVertAlignment mVertAlignment;
BOOL mHidden;
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f
// [RLVa:KB] - Checked: RLVa-1.0.0
std::string mObjText;
// [/RLVa:KB]

View File

@ -4309,49 +4309,51 @@ public:
// [/RLVa:KB]
// <FS> Mute group chat port from Phoenix
BOOL FSMuteAllGroups = gSavedSettings.getBOOL("FSMuteAllGroups");
BOOL FSMuteGroupWhenNoticesDisabled = gSavedSettings.getBOOL("FSMuteGroupWhenNoticesDisabled");
LLGroupData group_data;
if (gAgent.getGroupData(session_id, group_data))
if (from_id != gAgentID) // FIRE-14222: OpenSim routes agent's chat through here - don't mute it!
{
if (FSMuteAllGroups || (FSMuteGroupWhenNoticesDisabled && !group_data.mAcceptNotices))
BOOL FSMuteAllGroups = gSavedSettings.getBOOL("FSMuteAllGroups");
BOOL FSMuteGroupWhenNoticesDisabled = gSavedSettings.getBOOL("FSMuteGroupWhenNoticesDisabled");
LLGroupData group_data;
if (gAgent.getGroupData(session_id, group_data))
{
LL_INFOS() << "Firestorm: muting group chat: " << group_data.mName << LL_ENDL;
if (gSavedSettings.getBOOL("FSReportMutedGroupChat"))
if (FSMuteAllGroups || (FSMuteGroupWhenNoticesDisabled && !group_data.mAcceptNotices))
{
LLStringUtil::format_map_t args;
args["NAME"] = LLSLURL("group", session_id, "about").getSLURLString();
report_to_nearby_chat(LLTrans::getString("GroupChatMuteNotice", args));
LL_INFOS() << "Muting group chat: " << group_data.mName << LL_ENDL;
if (gSavedSettings.getBOOL("FSReportMutedGroupChat"))
{
LLStringUtil::format_map_t args;
args["NAME"] = LLSLURL("group", session_id, "about").getSLURLString();
report_to_nearby_chat(LLTrans::getString("GroupChatMuteNotice", args));
}
//KC: make sure we leave the group chat at the server end as well
std::string aname;
gAgent.buildFullname(aname);
pack_instant_message(
gMessageSystem,
gAgentID,
FALSE,
gAgentSessionID,
from_id,
aname,
LLStringUtil::null,
IM_ONLINE,
IM_SESSION_LEAVE,
session_id);
gAgent.sendReliableMessage();
gIMMgr->leaveSession(session_id);
return;
}
//KC: make sure we leave the group chat at the server end as well
std::string aname;
gAgent.buildFullname(aname);
pack_instant_message(
gMessageSystem,
gAgent.getID(),
FALSE,
gAgent.getSessionID(),
from_id,
aname,
LLStringUtil::null,
IM_ONLINE,
IM_SESSION_LEAVE,
session_id);
gAgent.sendReliableMessage();
//gIMMgr->removeSession(session_id);
gIMMgr->leaveSession(session_id);
return;
}
// <FS:Ansariel> Groupdata debug
else
{
LL_INFOS("Agent_GroupData") << "GROUPDEBUG: Group chat mute: No agent group data for group " << session_id.asString() << LL_ENDL;
}
// </FS:Ansariel>
}
// <FS:Ansariel> Groupdata debug
else
{
LL_INFOS("Agent_GroupData") << "GROUPDEBUG: Group chat mute: No agent group data for group " << session_id.asString() << LL_ENDL;
}
// </FS:Ansariel>
// </FS> Mute group chat port from Phoenix
// standard message, not from system

View File

@ -4323,6 +4323,13 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
{
disabled_items.push_back(std::string("Replace Outfit"));
}
// [RLVa:KB] - Checked: RLVa-2.0.3
// Block "Replace Current Outfit" if the user can't wear the new folder
if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(mUUID, RLV_LOCK_ADD)) )
{
disabled_items.push_back(std::string("Replace Outfit"));
}
// [/RLVa:KB]
if (!LLAppearanceMgr::instance().getCanAddToCOF(mUUID))
{
disabled_items.push_back(std::string("Add To Outfit"));
@ -6546,6 +6553,11 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
{
attachment = RlvAttachPtLookup::getAttachPoint(item);
}
if ( (RlvActions::isRlvEnabled()) && (!rlvPredCanWearItem(item, (replace) ? RLV_WEAR_REPLACE : RLV_WEAR_ADD)) )
{
return;
}
// [/RLVa:KB]
const LLUUID& item_id = item->getLinkedUUID();

View File

@ -1026,7 +1026,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
if( item_array )
{
// *FIX: bit of a hack to call update server from here...
new_item->updateServer(TRUE);
// <FS:KB> FIRE-19635 / BUG-20161: Detached object ends up in root of inventory
//new_item->updateServer(TRUE);
LLInventoryModel::LLCategoryUpdate update(category_id, 1);
gInventory.accountForUpdate(update);
new_item->updateParentOnServer(FALSE);
// </FS:KB>
item_array->push_back(new_item);
}
else
@ -1069,7 +1074,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
{
// *FIX: bit of a hack to call update server from
// here...
new_item->updateServer(TRUE);
// <FS:KB> FIRE-19635 / BUG-20161: Detached object ends up in root of inventory
//new_item->updateServer(TRUE);
LLInventoryModel::LLCategoryUpdate update(parent_id, 1);
gInventory.accountForUpdate(update);
new_item->updateParentOnServer(FALSE);
// </FS:KB>
item_array->push_back(new_item);
}
else

View File

@ -3995,10 +3995,11 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3
S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
{
if (mThread)
if (mThread && mesh_id.notNull())
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
if (iter != mThread->mMeshHeader.end())
if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0)
{
LLSD& header = iter->second;
@ -4070,9 +4071,30 @@ void LLMeshRepository::uploadError(LLSD& args)
mUploadErrorQ.push(args);
}
F32 LLMeshRepository::getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
{
if (mThread && mesh_id.notNull())
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0)
{
return getStreamingCost(iter->second, radius, bytes, bytes_visible, lod, unscaled_value);
}
}
return 0.f;
}
//static
F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
{
if (header.has("404")
|| !header.has("lowest_lod")
|| (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION))
{
return 0.f;
}
F32 max_distance = 512.f;
F32 dlowest = llmin(radius/0.03f, max_distance);
@ -4147,7 +4169,7 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32
}
}
F32 max_area = 102932.f; //area of circle that encompasses region
F32 max_area = 102944.f; //area of circle that encompasses region (see MAINT-6559)
F32 min_area = 1.f;
F32 high_area = llmin(F_PI*dmid*dmid, max_area);
@ -4841,9 +4863,14 @@ void on_new_single_inventory_upload_complete(
// and display something saying that it cost L$
LLStatusBar::sendMoneyBalanceRequest();
// <FS:Ansariel> FIRE-10628 - Option to supress upload cost notification
if (gSavedSettings.getBOOL("FSShowUploadPaymentToast"))
{
LLSD args;
args["AMOUNT"] = llformat("%d", upload_price);
LLNotificationsUtil::add("UploadPayment", args);
}
// </FS:Ansariel>
}
if (item_folder_id.notNull())

View File

@ -477,6 +477,7 @@ public:
static LLDeadmanTimer sQuiescentTimer; // Time-to-complete-mesh-downloads after significant events
F32 getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
LLMeshRepository();

View File

@ -178,13 +178,33 @@ std::string LLMIMETypes::widgetType(const std::string& mime_type)
}
}
// <FS:ND> Get the selected media impl, hardcoded for now. Can be quicktime/gstreamer/(vlc in the future) depending on OS and bitness
std::string getStreamingPlugin()
{
#if defined( LL_LINUX ) || defined( LL_WINDOWS )
return "media_plugin_gstreamer10";
#else
llassert_always( false );
#endif
}
// </FS:ND>
// static
std::string LLMIMETypes::implType(const std::string& mime_type)
{
mime_info_map_t::const_iterator it = sMap.find(mime_type);
if (it != sMap.end())
{
return it->second.mImpl;
// <FS:ND> Get the selected media impl, hardcoded for now. Can be quicktime/gstreamer/(vlc in the future) depending on OS and bitness
// return it->second.mImpl;
std::string impl = it->second.mImpl;
if( impl == "media_plugin_streaming" )
return getStreamingPlugin();
return impl;
// </FS:ND>
}
else
{

View File

@ -946,7 +946,18 @@ void LLPanelPeople::updateNearbyList()
std::vector<LLVector3d> positions;
LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
// [RLVa:KB] - Checked: RLVa-2.0.3
if (RlvActions::canShowNearbyAgents())
{
// [/RLVa:KB]
LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
// [RLVa:KB] - Checked: RLVa-2.0.3
}
else
{
mNearbyList->getIDs().clear();
}
// [/RLVa:KB]
mNearbyList->setDirty();
DISTANCE_COMPARATOR.updateAvatarsPositions(positions, mNearbyList->getIDs());
@ -1077,16 +1088,6 @@ void LLPanelPeople::updateButtons()
}
}
}
// [RLVa:KB] - Checked: RLVa-1.2.0
if ( (nearby_tab_active) && (RlvActions::isRlvEnabled()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) )
{
bool fCanShowNames = true;
std::for_each(selected_uuids.begin(), selected_uuids.end(), [&fCanShowNames](const LLUUID& idAgent) { fCanShowNames &= RlvActions::canShowName(RlvActions::SNC_DEFAULT, idAgent); });
if (!fCanShowNames)
item_selected = multiple_selected = false;
}
// [/RLBa:KB]
}
std::string LLPanelPeople::getActiveTabName() const
@ -1334,10 +1335,11 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl)
}
// [RLVa:KB] - Checked: RLVa-2.0.1
if ( (RlvActions::isRlvEnabled()) && (NEARBY_TAB_NAME == getActiveTabName()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, clicked_id)) )
{
return;
}
// <FS:Ansariel> Firestorm radar; commented out
//if ( (RlvActions::isRlvEnabled()) && (NEARBY_TAB_NAME == getActiveTabName()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, clicked_id)) )
//{
// return;
//}
// [/RLVa:KB]
#if 0 // SJB: Useful for testing, but not currently functional or to spec
@ -1457,13 +1459,14 @@ void LLPanelPeople::onImButtonClicked()
uuid_vec_t selected_uuids;
getCurrentItemIDs(selected_uuids);
// [RLVa:KB] - Checked: RLVa-2.0.1
if ( (RlvActions::isRlvEnabled()) && (NEARBY_TAB_NAME == getActiveTabName()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) )
{
bool fCanShowNames = true;
std::for_each(selected_uuids.begin(), selected_uuids.end(), [&fCanShowNames](const LLUUID& idAgent) { fCanShowNames &= RlvActions::canShowName(RlvActions::SNC_DEFAULT, idAgent); });
if (!fCanShowNames)
return;
}
// <FS:Ansariel> Firestorm radar; commented out
//if ( (RlvActions::isRlvEnabled()) && (NEARBY_TAB_NAME == getActiveTabName()) && (!RlvActions::canShowName(RlvActions::SNC_DEFAULT)) )
//{
// bool fCanShowNames = true;
// std::for_each(selected_uuids.begin(), selected_uuids.end(), [&fCanShowNames](const LLUUID& idAgent) { fCanShowNames &= RlvActions::canShowName(RlvActions::SNC_DEFAULT, idAgent); });
// if (!fCanShowNames)
// return;
//}
// [/RLVa:KB]
if ( selected_uuids.size() == 1 )
{

View File

@ -71,6 +71,7 @@ public:
// [RLVa:KB] - Checked: RLVa-1.2.0
LLAvatarList* getNearbyList() { return mNearbyList; }
void updateNearbyList();
// [/RLVa:KB]
// internals
@ -94,7 +95,7 @@ private:
void updateFriendListHelpText();
void updateFriendList();
bool updateSuggestedFriendList();
void updateNearbyList();
// void updateNearbyList();
void updateRecentList();
void updateFacebookList(bool visible);

View File

@ -62,7 +62,10 @@ void LLPresetsManager::triggerChangeSignal()
void LLPresetsManager::createMissingDefault()
{
std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml");
// <FS:Ansariel> FIRE-19810: Make presets global since PresetGraphicActive setting is global as well
//std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml");
std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml");
// </FS:Ansariel>
if (!gDirUtilp->fileExists(default_file))
{
LL_INFOS() << "No default preset found -- creating one at " << default_file << LL_ENDL;
@ -78,7 +81,10 @@ void LLPresetsManager::createMissingDefault()
std::string LLPresetsManager::getPresetsDir(const std::string& subdirectory)
{
std::string presets_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR);
// <FS:Ansariel> FIRE-19810: Make presets global since PresetGraphicActive setting is global as well
//std::string presets_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR);
std::string presets_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR);
// </FS:Ansariel>
std::string full_path;
if (!gDirUtilp->fileExists(presets_path))
@ -86,7 +92,10 @@ std::string LLPresetsManager::getPresetsDir(const std::string& subdirectory)
LLFile::mkdir(presets_path);
}
full_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, subdirectory);
// <FS:Ansariel> FIRE-19810: Make presets global since PresetGraphicActive setting is global as well
//full_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, subdirectory);
full_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, subdirectory);
// </FS:Ansariel>
if (!gDirUtilp->fileExists(full_path))
{
LLFile::mkdir(full_path);

View File

@ -220,6 +220,7 @@
#include "fsavatarrenderpersistence.h"
#include "fscommon.h"
#include "fscorehttputil.h"
#include "fsdata.h"
#include "fsfloatercontacts.h"
#include "fsfloaterimcontainer.h"
@ -320,6 +321,9 @@ void apply_udp_blacklist(const std::string& csv);
bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y);
// </FS:CR> Aurora Sim
void transition_back_to_login_panel(const std::string& emsg);
// <FS:KC> FIRE-18250: Option to disable default eye movement
void update_static_eyes();
// </FS:KC> FIRE-18250
void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group)
{
@ -1960,6 +1964,11 @@ bool idle_startup()
display_startup();
// </FS:Ansariel> [FS communication UI]
// <FS:KC> FIRE-18250: Option to disable default eye movement
gAgent.addRegionChangedCallback(boost::bind(&update_static_eyes));
update_static_eyes();
// </FS:KC>
// *Note: this is where gWorldMap used to be initialized.
// register null callbacks for audio until the audio system is initialized
@ -2898,15 +2907,6 @@ bool idle_startup()
}
// </FS:PP>
// <FS:KC> FIRE-18250: Option to disable default eye movement
if (gSavedPerAccountSettings.getBOOL("FSStaticEyes"))
{
LLUUID anim_id(gSavedSettings.getString("FSStaticEyesUUID"));
gAgentAvatarp->startMotion(anim_id);
gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_START);
}
// </FS:KC>
return TRUE;
}
@ -4494,3 +4494,13 @@ void transition_back_to_login_panel(const std::string& emsg)
gSavedSettings.setBOOL("AutoLogin", FALSE);
}
// <FS:KC> FIRE-18250: Option to disable default eye movement
//static
void update_static_eyes() {
if (gSavedPerAccountSettings.getBOOL("FSStaticEyes"))
{
LLUUID anim_id(gSavedSettings.getString("FSStaticEyesUUID"));
gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_START);
}
}
// </FS:KC>

View File

@ -195,7 +195,12 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
mNearbyIcons(FALSE), // <FS:Ansariel> Script debug
mSearchData(NULL), // <FS:ND/> Hook up and init for filtering
mFilterEdit(NULL), // <FS:ND/> Edit for filtering
mSearchPanel(NULL) // <FS:ND/> Panel for filtering
mSearchPanel(NULL), // <FS:ND/> Panel for filtering
mIconPresets(NULL),
mMediaToggle(NULL),
mMouseEnterPresetsConnection(),
mMouseEnterVolumeConnection(),
mMouseEnterNearbyMediaConnection()
{
setRect(rect);
@ -244,6 +249,22 @@ LLStatusBar::~LLStatusBar()
{
mShowCoordsCtrlConnection.disconnect();
}
// <FS:Ansariel> FIRE-19697: Add setting to disable graphics preset menu popup on mouse over
if (mMouseEnterPresetsConnection.connected())
{
mMouseEnterPresetsConnection.disconnect();
}
if (mMouseEnterVolumeConnection.connected())
{
mMouseEnterVolumeConnection.disconnect();
}
if (mMouseEnterNearbyMediaConnection.connected())
{
mMouseEnterNearbyMediaConnection.disconnect();
}
// </FS:Ansariel>
// LLView destructor cleans up children
}
@ -285,26 +306,47 @@ BOOL LLStatusBar::postBuild()
//mBtnStats = getChildView("stat_btn");
mIconPresets = getChild<LLButton>( "presets_icon" );
mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
// <FS: KC> FIRE-19697: Add setting to disable graphics preset menu popup on mouse over
// mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
if (gSavedSettings.getBOOL("FSStatusBarMenuButtonPopupOnRollover"))
{
mMouseEnterPresetsConnection = mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
}
// </FS: KC> FIRE-19697: Add setting to disable graphics preset menu popup on mouse over
mIconPresets->setClickedCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
mBtnVolume = getChild<LLButton>( "volume_btn" );
mBtnVolume->setClickedCallback( onClickVolume, this );
mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this));
// <FS: KC> FIRE-19697: Add setting to disable status bar icon menu popup on mouseover
// mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this));
if (gSavedSettings.getBOOL("FSStatusBarMenuButtonPopupOnRollover"))
{
mMouseEnterVolumeConnection = mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this));
}
// </FS: KC> FIRE-19697: Add setting to disable status bar icon menu popup on mouseover
// ## Zi: Media/Stream separation
// <FS:Zi> Media/Stream separation
mStreamToggle = getChild<LLButton>("stream_toggle_btn");
mStreamToggle->setClickedCallback( &LLStatusBar::onClickStreamToggle, this );
// ## Zi: Media/Stream separation
mStreamToggle->setClickedCallback(&LLStatusBar::onClickStreamToggle, this);
// </FS:Zi> Media/Stream separation
mMediaToggle = getChild<LLButton>("media_toggle_btn");
mMediaToggle->setClickedCallback( &LLStatusBar::onClickMediaToggle, this );
mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this));
// <FS: KC> FIRE-19697: Add setting to disable status bar icon menu popup on mouseover
// mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this));
if (gSavedSettings.getBOOL("FSStatusBarMenuButtonPopupOnRollover"))
{
mMouseEnterNearbyMediaConnection = mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this));
}
// </FS: KC> FIRE-19697: Add setting to disable status bar icon menu popup on mouseover
LLHints::registerHintTarget("linden_balance", getChild<LLView>("balance_bg")->getHandle());
gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2));
// <FS:Ansariel> FIRE-19697: Add setting to disable graphics preset menu popup on mouse over
gSavedSettings.getControl("FSStatusBarMenuButtonPopupOnRollover")->getSignal()->connect(boost::bind(&LLStatusBar::onPopupRolloverChanged, this, _2));
// Adding Net Stat Graph
S32 x = getRect().getWidth() - 2;
S32 y = 0;
@ -790,8 +832,11 @@ void LLStatusBar::onClickBuyCurrency()
void LLStatusBar::onMouseEnterPresets()
{
LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder");
LLIconCtrl* icon = getChild<LLIconCtrl>( "presets_icon" );
LLRect icon_rect = icon->getRect();
// <FS:Ansariel> Changed presets icon to LLButton
//LLIconCtrl* icon = getChild<LLIconCtrl>( "presets_icon" );
//LLRect icon_rect = icon->getRect();
LLRect icon_rect = mIconPresets->getRect();
// </FS:Ansariel>
LLRect pulldown_rect = mPanelPresetsPulldown->getRect();
pulldown_rect.setLeftTopAndSize(icon_rect.mLeft -
(pulldown_rect.getWidth() - icon_rect.getWidth()),
@ -1370,7 +1415,7 @@ void LLStatusBar::onParcelIconClick(EParcelIcon icon)
case PATHFINDING_DIRTY_ICON:
// <FS:Zi> Pathfinding rebake functions
// LLNotificationsUtil::add("PathfindingDirty");
LLNotificationsUtil::add("PathfindingDirty",LLSD(),LLSD(),boost::bind(&LLStatusBar::rebakeRegionCallback,this,_1,_2));
LLNotificationsUtil::add("PathfindingDirty", LLSD(), LLSD(), boost::bind(&LLStatusBar::rebakeRegionCallback, this, _1, _2));
// </FS:Zi>
break;
case PATHFINDING_DISABLED_ICON:
@ -1497,10 +1542,9 @@ void LLStatusBar::updateVolumeControlsVisibility(const LLSD& data)
// </FS:PP>
// <FS:Zi> Pathfinding rebake functions
BOOL LLStatusBar::rebakeRegionCallback(const LLSD& notification,const LLSD& response)
BOOL LLStatusBar::rebakeRegionCallback(const LLSD& notification, const LLSD& response)
{
std::string newSetName = response["message"].asString();
S32 option = LLNotificationsUtil::getSelectedOption(notification,response);
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
@ -1579,3 +1623,29 @@ void LLStatusBar::updateMenuSearchVisibility(const LLSD& data)
}
update();
}
// <FS:Ansariel> FIRE-19697: Add setting to disable graphics preset menu popup on mouse over
void LLStatusBar::onPopupRolloverChanged(const LLSD& newvalue)
{
bool new_value = newvalue.asBoolean();
if (mMouseEnterPresetsConnection.connected())
{
mMouseEnterPresetsConnection.disconnect();
}
if (mMouseEnterVolumeConnection.connected())
{
mMouseEnterVolumeConnection.disconnect();
}
if (mMouseEnterNearbyMediaConnection.connected())
{
mMouseEnterNearbyMediaConnection.disconnect();
}
if (new_value)
{
mMouseEnterPresetsConnection = mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
mMouseEnterVolumeConnection = mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this));
mMouseEnterNearbyMediaConnection = mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this));
}
}

View File

@ -261,6 +261,10 @@ private:
void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus);
void createNavMeshStatusListenerForCurrentRegion();
// </FS:Ansariel> Pathfinding support
// <FS:Ansariel> FIRE-19697: Add setting to disable graphics preset menu popup on mouse over
void onPopupRolloverChanged(const LLSD& newvalue);
public:
/**
@ -362,6 +366,12 @@ private:
boost::signals2::connection mShowCoordsCtrlConnection;
boost::signals2::connection mParcelMgrConnection;
// <FS:Ansariel> FIRE-19697: Add setting to disable graphics preset menu popup on mouse over
boost::signals2::connection mMouseEnterPresetsConnection;
boost::signals2::connection mMouseEnterVolumeConnection;
boost::signals2::connection mMouseEnterNearbyMediaConnection;
// </FS:Ansariel>
// <FS:Zi> Pathfinding rebake functions
BOOL rebakeRegionCallback(const LLSD& notification,const LLSD& response);

View File

@ -52,6 +52,7 @@
#include "llcoproceduremanager.h"
#include "llviewernetwork.h"
#include "llviewercontrol.h"
void dialog_refresh_all();
@ -758,9 +759,14 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
// and display something saying that it cost L$
LLStatusBar::sendMoneyBalanceRequest();
// <FS:Ansariel> FIRE-10628 - Option to supress upload cost notification
if (gSavedSettings.getBOOL("FSShowUploadPaymentToast"))
{
LLSD args;
args["AMOUNT"] = llformat("%d", uploadPrice);
LLNotificationsUtil::add("UploadPayment", args);
}
// </FS:Ansariel>
}
}
else

View File

@ -169,6 +169,7 @@
#include "floatermedialists.h"
#include "fsareasearch.h"
#include "fsfloateraddtocontactset.h"
#include "fsfloateravatarrendersettings.h"
#include "fsfloatercontacts.h"
#include "fsfloatercontactsetconfiguration.h"
#include "fsfloaterexport.h"
@ -439,6 +440,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("export_collada", "floater_export_collada.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ColladaExportFloater>);
LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteQueue>);
LLFloaterReg::add("floater_profile", "floater_profile_view.xml",&LLFloaterReg::build<FSFloaterProfile>);
LLFloaterReg::add("fs_avatar_render_settings", "floater_fs_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAvatarRenderSettings>);
LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterBlocklist>);
LLFloaterReg::add("fs_add_contact", "floater_fs_contact_add.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAddToContactSet>);
LLFloaterReg::add("fs_contact_set_config", "floater_fs_contact_set_configuration.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterContactSetConfiguration>);

View File

@ -174,10 +174,10 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
{
LL_INFOS() << "(same object re-attached)" << LL_ENDL;
// [SL:KB] - Patch: Appearance-TeleportAttachKill | Checked: Catznip-4.0
if ( (object->permYouOwner()) && (gAgentAvatarp) )
{
gAgentAvatarp->removePendingDetach(object->getID());
}
// if ( (object->permYouOwner()) && (gAgentAvatarp) )
// {
// gAgentAvatarp->removePendingDetach(object->getID());
// }
// [/SL:KB]
removeObject(object);
// Pass through anyway to let setupDrawable()

View File

@ -50,6 +50,7 @@
#include "rlvhandler.h"
// [/RLVa:KB]
#include "llfloaterwebcontent.h"
#include "fsfloatersearch.h"
//
// Constants
@ -631,7 +632,7 @@ void start_gesture( EKeystate s )
// <FS:Ansariel> FIRE-4167: Don't start gesture if a floater with web content has focus
LLFloater* focused_floater = gFloaterView->getFocusedFloater();
if (focused_floater && dynamic_cast<LLFloaterWebContent*>(focused_floater))
if (focused_floater && (dynamic_cast<LLFloaterWebContent*>(focused_floater) || dynamic_cast<FSFloaterSearch*>(focused_floater)))
{
return;
}

View File

@ -1888,8 +1888,6 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled || clean_browser);
media_source->setFlipY( gSavedSettings.getBOOL( "FSFlipCEFY" ) );
// need to set agent string here before instance created
media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent());
@ -3057,7 +3055,10 @@ void LLViewerMediaImpl::updateImagesMediaStreams()
//////////////////////////////////////////////////////////////////////////////////////////
LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
{
if(mTextureId.isNull())
// if(mTextureId.isNull())
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
if ( (mTextureId.isNull()) || ((LLViewerFetchedTexture::sDefaultDiffuseImagep.notNull()) && (LLViewerFetchedTexture::sDefaultDiffuseImagep->getID() == mTextureId)) )
// [/SL:KB]
{
// The code that created this instance will read from the plugin's bits.
return NULL;

View File

@ -7542,6 +7542,13 @@ void handle_viewer_disable_message_log(void*)
void handle_customize_avatar()
{
// <FS:Ansariel> FIRE-19614: Make CTRL-O toggle the appearance floater
if (LLFloaterReg::instanceVisible("appearance"))
{
LLFloaterReg::hideInstance("appearance");
}
else
// </FS:Ansariel>
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
}

View File

@ -2748,17 +2748,17 @@ static void teleport_region_info_cb(const std::string& slurl, LLSD args, const L
if (!can_user_access_dst_region)
{
params.name = "TeleportOffered_MaturityBlocked";
params.name = "TeleportOffered_MaturityBlocked_SLUrl";
send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
}
else if (does_user_require_maturity_increase)
{
params.name = "TeleportOffered_MaturityExceeded";
params.name = "TeleportOffered_MaturityExceeded_SLUrl";
}
else
{
params.name = "TeleportOffered";
params.name = "TeleportOffered_SLUrl";
params.functor.name = "TeleportOffered";
}
@ -2925,11 +2925,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// do nothing -- don't distract newbies in
// Prelude with global IMs
}
// [RLVa:KB] - Checked: 2011-05-28 (RLVa-1.4.0)
else if ( (rlv_handler_t::isEnabled()) && (offline == IM_ONLINE) && ("@version" == message) &&
(!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) )
// [RLVa:KB] - Checked: RLVa-2.0.3
else if ( (RlvActions::isRlvEnabled()) && (RlvSettings::getEnableIMQuery()) && (offline == IM_ONLINE) && ("@version" == message) && (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) )
{
RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(), session_id);
RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(LLUUID::null), session_id);
}
// [/RLVa:KB]
// else if (offline == IM_ONLINE
@ -3936,7 +3935,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
payload["region_maturity"] = region_access;
// <FS:Ansariel> FIRE-6786: Always show teleport location in teleport offer
if (dialog == IM_LURE_USER && (!rlv_handler_t::isEnabled() || !fRlvAutoAccept))
if (dialog == IM_LURE_USER && (!rlv_handler_t::isEnabled() || !fRlvAutoAccept) && LLGridManager::instance().isInSecondLife())
{
LLVector3d pos_global = from_region_handle(region_handle);
pos_global += LLVector3d(pos);
@ -4210,7 +4209,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// <FS:CR> Make osx dashboard icon bounce when window isn't in focus
//if (viewer_window && viewer_window->getMinimized())
static LLCachedControl<bool> sFlashIcon(gSavedSettings, "FSFlashOnMessage");
if (viewer_window && dialog != IM_TYPING_START && dialog != IM_TYPING_STOP && sFlashIcon)
static LLCachedControl<bool> sFSFlashOnObjectIM(gSavedSettings, "FSFlashOnObjectIM");
if (viewer_window && dialog != IM_TYPING_START && dialog != IM_TYPING_STOP && sFlashIcon && (sFSFlashOnObjectIM || (chat.mChatType != CHAT_TYPE_IM)))
{
viewer_window->flashIcon(5.f);
}
@ -4733,7 +4733,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
// [RLVa:KB] - Checked: 2010-02-XX (RLVa-1.2.0a) | Modified: RLVa-1.1.0f
// TODO-RLVa: [RLVa-1.2.0] consider rewriting this before a RLVa-1.2.0 release
if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) && (CHAT_TYPE_OWNER == chat.mChatType) )
if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) && (CHAT_TYPE_OWNER == chat.mChatType) &&
((!chatter) || (!chatter->isAttachment()) || (!chatter->isTempAttachment()) || (RlvSettings::getEnableTemporaryAttachments())) )
{
mesg.erase(0, 1);
LLStringUtil::toLower(mesg);
@ -5966,11 +5967,11 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
if (objectp)
{
// [SL:KB] - Patch: Appearance-TeleportAttachKill | Checked: Catznip-4.0
if ( (objectp->isAttachment()) && (gAgentAvatarp) && (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) && (objectp->permYouOwner()) )
{
gAgentAvatarp->addPendingDetach(objectp->getRootEdit()->getID());
continue;
}
// if ( (objectp->isAttachment()) && (gAgentAvatarp) && (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) && (objectp->permYouOwner()) )
// {
// gAgentAvatarp->addPendingDetach(objectp->getRootEdit()->getID());
// continue;
// }
// [/SL:KB]
// Display green bubble on kill
@ -6370,8 +6371,6 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
{
// <FS:Ansariel> Cut down logspam
//LL_WARNS() << "Unknown sim stat identifier: " << stat_id << LL_ENDL;
LL_WARNS_ONCE() << "Unknown sim stat identifier: " << stat_id << LL_ENDL;
// </FS:Ansariel>
}
}

View File

@ -551,7 +551,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mInvisibilityCheckHistory(-1),
mPaused(FALSE),
// <FS:CR> Aurora Sim
mWidth(region_width_meters)
mWidth(region_width_meters),
mWidthScaleFactor(region_width_meters / REGION_WIDTH_METERS) // <FS:Ansariel> FIRE-19563: Scaling for OpenSim VarRegions
{
// Moved this up... -> mWidth = region_width_meters;
// </FS:CR>
@ -2176,8 +2177,12 @@ public:
if(i == target_index)
{
LLVector3d global_pos(region->getOriginGlobal());
global_pos.mdV[VX] += (F64)x;
global_pos.mdV[VY] += (F64)y;
// <FS:Ansariel> FIRE-19563: Scaling for OpenSim VarRegions
//global_pos.mdV[VX] += (F64)x;
//global_pos.mdV[VY] += (F64)y;
global_pos.mdV[VX] += (F64)x * region->getWidthScaleFactor();
global_pos.mdV[VY] += (F64)y * region->getWidthScaleFactor();
// </FS:Ansariel>
global_pos.mdV[VZ] += (F64)z * 4.0;
LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
}
@ -2251,8 +2256,12 @@ void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
if(i == target_index)
{
LLVector3d global_pos(mImpl->mOriginGlobal);
global_pos.mdV[VX] += (F64)(x_pos);
global_pos.mdV[VY] += (F64)(y_pos);
// <FS:Ansariel> FIRE-19563: Scaling for OpenSim VarRegions
//global_pos.mdV[VX] += (F64)(x_pos);
//global_pos.mdV[VY] += (F64)(y_pos);
global_pos.mdV[VX] += (F64)(x_pos) * mWidthScaleFactor;
global_pos.mdV[VY] += (F64)(y_pos) * mWidthScaleFactor;
// </FS:Ansariel>
global_pos.mdV[VZ] += (F64)(z_pos) * 4.0;
LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
}
@ -2315,7 +2324,7 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
std::stringstream str;
LLSDSerialize::toPrettyXML(sim_features, str);
LL_INFOS() << str.str() << LL_ENDL;
LL_INFOS() << "Region ID " << getRegionID().asString() << ": " << str.str() << LL_ENDL;
mSimulatorFeatures = sim_features;
setSimulatorFeaturesReceived(true);

View File

@ -240,6 +240,7 @@ public:
void setCacheID(const LLUUID& id);
F32 getWidth() const { return mWidth; }
F32 getWidthScaleFactor() const { return mWidthScaleFactor; } // <FS:Ansariel> FIRE-19563: Scaling for OpenSim VarRegions
void idleUpdate(F32 max_update_time);
void lightIdleUpdate();
@ -495,6 +496,7 @@ private:
U64 mHandle;
F32 mTimeDilation; // time dilation of physics simulation on simulator
S32 mLastUpdate; //last time called idleUpdate()
F32 mWidthScaleFactor; // <FS:Ansariel> FIRE-19563: Scaling for OpenSim VarRegions
// simulator name
std::string mName;

View File

@ -68,11 +68,7 @@
const S32Megabytes gMinVideoRam(32);
// <FS:Ansariel> Texture memory management
//const S32Megabytes gMaxVideoRam(512);
#ifdef ND_BUILD64BIT_ARCH
const S32Megabytes gMaxVideoRam(1024);
#else
const S32Megabytes gMaxVideoRam(512);
#endif
S32Megabytes gMaxVideoRam(512);
// </FS:Ansariel>
@ -3781,37 +3777,6 @@ void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)
if(mIsPlaying) //old textures switch to the media texture
{
// <FS:ND> If using CEF then set a texture matrix to flip around the Y Axis.
static bool sFlipY = gSavedSettings.getBOOL( "FSFlipCEFY" );
LLViewerMediaImpl *pMedia = mMediaImplp;
if( !pMedia )
pMedia = LLViewerMedia::getMediaImplFromTextureID(mID);
std::string strMimeType;
if( pMedia )
strMimeType = pMedia->getMimeType();
std::string strImpl = LLMIMETypes::implType( strMimeType );
bool bCoordsOpenGl = sFlipY;
if( pMedia && pMedia->getMediaPlugin() )
bCoordsOpenGl = pMedia->getMediaPlugin()->getTextureCoordsOpenGL();
if( strImpl == "media_plugin_cef" && !bCoordsOpenGl )
{
if( !facep->mTextureMatrix )
{
facep->mTextureMatrix = new LLMatrix4();
facep->mTextureMatrix->mMatrix[ 1 ][ 1 ] = -1.0f;
facep->mTextureMatrix->mMatrix[ 2 ][ 1 ] = 1.0f;
}
else
{
LL_WARNS() << "Matrix for media face is already set." << LL_ENDL;
}
}
// </FS:ND>
facep->switchTexture(ch, this);
}
else //switch to old textures.

View File

@ -40,7 +40,10 @@
#include <list>
extern const S32Megabytes gMinVideoRam;
extern const S32Megabytes gMaxVideoRam;
// <FS:Ansariel> Texture memory management
//extern const S32Megabytes gMaxVideoRam;
extern S32Megabytes gMaxVideoRam;
// </FS:Ansariel>
class LLFace;
class LLImageGL ;

View File

@ -1877,6 +1877,32 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LLFeatureManager::getInstance()->setGraphicsLevel(0, false);
gSavedSettings.setU32("RenderQualityPerformance", 0);
}
// <FS:Ansariel> Texture memory management
// On 64bit builds, allow up to 1GB texture memory on cards with 2GB video
// memory and up to 2GB texture memory on cards with 4GB video memory. Check
// is performed against a lower limit as not exactly 2 or 4GB might not be
// returned.
#ifdef ND_BUILD64BIT_ARCH
LL_INFOS() << "GLManager detected " << gGLManager.mVRAM << " MB VRAM" << LL_ENDL;
if (gGLManager.mVRAM > 3584)
{
gMaxVideoRam = S32Megabytes(2048);
LL_INFOS() << "At least 4 GB video memory detected - increasing max video ram for textures to 2048 MB" << LL_ENDL;
}
else if (gGLManager.mVRAM > 1536)
{
gMaxVideoRam = S32Megabytes(1024);
LL_INFOS() << "At least 2 GB video memory detected - increasing max video ram for textures to 1024 MB" << LL_ENDL;
}
else if (gGLManager.mVRAM > 768)
{
gMaxVideoRam = S32Megabytes(768);
LL_INFOS() << "At least 1 GB video memory detected - increasing max video ram for textures to 768 MB" << LL_ENDL;
}
#endif
// </FS:Ansariel>
// Init the image list. Must happen after GL is initialized and before the images that
// LLViewerWindow needs are requested.

Some files were not shown because too many files have changed in this diff Show More