Ansariel 2022-02-02 09:39:17 +01:00
commit f669e46308
44 changed files with 671 additions and 722 deletions

2
.gitignore vendored
View File

@ -112,3 +112,5 @@ compile_commands.json
# ignore tracy for now
indra/tracy
firestorm.code-workspace
.cache/clangd/index/

View File

@ -877,48 +877,6 @@
<key>version</key>
<string>5.1.25</string>
</map>
<key>dbus_glib</key>
<map>
<key>copyright</key>
<string>Copyright (C) Red Hat Inc.</string>
<key>description</key>
<string>D-Bus bindings for glib</string>
<key>license</key>
<string>Academic Free License v. 2.1</string>
<key>license_file</key>
<string>LICENSES/dbus-glib.txt</string>
<key>name</key>
<string>dbus_glib</string>
<key>platforms</key>
<map>
<key>linux</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>9591dcb7efce2a770d77e907705e1492</string>
<key>url</key>
<string>http://3p.firestormviewer.org/dbus_glib-0.76-linux-180871236.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
</map>
<key>linux64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>5a685a65a7066937ef580dcd5a90f9dc</string>
<key>url</key>
<string>http://3p.firestormviewer.org/dbus_glib-0.76-linux64-180841549.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
</map>
</map>
<key>version</key>
<string>0.76</string>
</map>
<key>dictionaries</key>
<map>
<key>copyright</key>

View File

@ -20,7 +20,7 @@ set(cmake_SOURCE_FILES
ConfigurePkgConfig.cmake
CURL.cmake
Copy3rdPartyLibs.cmake
DBusGlib.cmake
GLIB.cmake
DeploySharedLibs.cmake
Discord.cmake # <FS:LO> Discord rich presence
DragDrop.cmake

View File

@ -1,27 +0,0 @@
# -*- cmake -*-
include(Prebuilt)
include(GLIB)
if( GLIB_FOUND )
if (USESYSTEMLIBS)
include(FindPkgConfig)
pkg_check_modules(DBUSGLIB REQUIRED dbus-glib-1)
elseif (LINUX)
use_prebuilt_binary(dbus_glib)
set(DBUSGLIB_FOUND ON FORCE BOOL)
set(DBUSGLIB_INCLUDE_DIRS
${GLIB_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/dbus
)
endif (USESYSTEMLIBS)
if (DBUSGLIB_FOUND)
set(DBUSGLIB ON CACHE BOOL "Build with dbus-glib message bus support.")
endif (DBUSGLIB_FOUND)
if (DBUSGLIB)
add_definitions(-DLL_DBUS_ENABLED=1)
endif (DBUSGLIB)
endif()

View File

@ -9,7 +9,11 @@ else (USESYSTEMLIBS)
use_prebuilt_binary(freetype)
set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/freetype2) #<FS:ND/> Also add freetype2 to search dir, or some includes will fail.
set(FREETYPE_LIBRARIES freetype)
# <FS:ND> Linux links this via UI.cmake
if( NOT LINUX )
set(FREETYPE_LIBRARIES freetype)
endif()
# </FS:ND>
endif (USESYSTEMLIBS)
link_directories(${FREETYPE_LIBRARY_DIRS})

View File

@ -6,6 +6,6 @@ if( LINUX )
set(GLIB_FOUND ON CACHE BOOL "Build against glib 2")
set(GLIB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/glib-2.0 ${LIBS_PREBUILT_DIR}/lib/release/glib-2.0/include )
set(GLIB_LIBRARIES libgobject-2.0.a libglib-2.0.a libffi.a libpcre.a)
set(GIO_LIBRARIES libgio-2.0.a libgmodule-2.0.a -lresolv)
add_definitions(-DLL_GLIB=1)
endif()

View File

@ -13,7 +13,7 @@ else (USESYSTEMLIBS)
elseif(DARWIN)
set(HUNSPELL_LIBRARY hunspell-1.3)
elseif(LINUX)
set(HUNSPELL_LIBRARY hunspell-1.3)
set(HUNSPELL_LIBRARY libhunspell-1.3.a)
else()
message(FATAL_ERROR "Invalid platform")
endif()

View File

@ -1,5 +1,32 @@
# -*- cmake -*-
# <FS:ND> Try to find pulse header, if we got them we can use the linux volume catcher
if (LINUX)
include(GLIB)
include_directories( ${GLIB_INCLUDE_DIRS} )
set( PULSE_AUDIO True )
foreach( PULSE_FILE pulse/introspect.h pulse/context.h pulse/subscribe.h pulse/glib-mainloop.h )
find_path( PULSE_FILE_FOUND ${PULSE_FILE} NO_CACHE)
if( NOT PULSE_FILE_FOUND )
message( "Looking for ${PULSE_FILE} ... not found")
set( PULSE_AUDIO False )
else()
message( "Looking for ${PULSE_FILE} ... found")
endif()
endforeach()
if( NOT PULSE_AUDIO )
message( "Building without linux volume catcher" )
set(LINUX_VOLUME_CATCHER dummy_volume_catcher.cpp)
else()
message( "Building with linux volume catcher" )
set(LINUX_VOLUME_CATCHER linux_volume_catcher.cpp)
endif()
endif()
set(MEDIA_PLUGIN_BASE_INCLUDE_DIRS
${LIBS_OPEN_DIR}/media_plugins/base/

View File

@ -1,6 +1,7 @@
# -*- cmake -*-
include(Prebuilt)
include(FreeType)
include(GLIB)
if (USESYSTEMLIBS)
include(FindPkgConfig)
@ -46,7 +47,7 @@ else (USESYSTEMLIBS)
if (LINUX)
set(UI_LIB_NAMES
libfltk.a
freetype
libfreetype.a
)
foreach(libname ${UI_LIB_NAMES})
@ -61,6 +62,7 @@ else (USESYSTEMLIBS)
endforeach(libname)
set(UI_LIBRARIES ${UI_LIBRARIES} Xinerama)
include_directories ( ${GLIB_INCLUDE_DIRS} )
endif (LINUX)
include_directories (

View File

@ -77,7 +77,8 @@ if (LINUX)
${LLXML_LIBRARIES}
${UI_LIBRARIES} # for GTK
${SDL_LIBRARY}
fontconfig # For FCInit and other FC* functions.
libfontconfig.a # For FCInit and other FC* functions.
libfreetype.a
)
list(APPEND viewer_SOURCE_FILES

View File

@ -48,6 +48,10 @@ extern "C" {
#include <locale.h>
#endif // LL_GTK
#ifdef LL_GLIB
#include <glib.h>
#endif
extern "C" {
# include "fontconfig/fontconfig.h"
}
@ -1992,7 +1996,18 @@ void LLWindowSDL::processMiscNativeEvents()
setlocale(LC_ALL, saved_locale.c_str() );
}
#endif // LL_GTK
#if LL_GLIB
// Pump until we've nothing left to do or passed 1/15th of a
// second pumping for this frame.
static LLTimer pump_timer;
pump_timer.reset();
pump_timer.setTimerExpirySec(1.0f / 15.0f);
do
{
g_main_context_iteration(g_main_context_default(), FALSE);
} while( g_main_context_pending(g_main_context_default()) && !pump_timer.hasExpired());
#endif
// hack - doesn't belong here - but this is just for debugging
if (getenv("LL_DEBUG_BLOAT"))
{

View File

@ -49,4 +49,3 @@ set(media_plugin_base_HEADER_FILES
add_library(media_plugin_base
${media_plugin_base_SOURCE_FILES}
)

View File

@ -58,7 +58,8 @@ set (media_plugin_cef_LINK_LIBRARIES
if (LINUX)
# message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n"
# " Please create a volume_catcher implementation for this platform.")
list(APPEND media_plugin_cef_SOURCE_FILES dummy_volume_catcher.cpp)
list(APPEND media_plugin_cef_SOURCE_FILES ${LINUX_VOLUME_CATCHER})
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--build-id -Wl,-rpath,'$ORIGIN:$ORIGIN/../../lib'")
elseif (DARWIN)
list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher_null.cpp)

View File

@ -53,6 +53,7 @@ extern "C" {
#include "apr_dso.h"
}
////////////////////////////////////////////////////
#define DEBUGMSG(...) do {} while(0)
@ -81,7 +82,7 @@ bool grab_pa_syms(std::string pulse_dso_name)
apr_status_t rv;
apr_dso_handle_t *sSymPADSOHandle = NULL;
#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0)
#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) { if (REQUIRED) sym_error = true;} } while(0);
//attempt to load the shared library
apr_pool_create(&sSymPADSOMemoryPool, NULL);
@ -216,17 +217,16 @@ void VolumeCatcherImpl::init()
mGotSyms = loadsyms("libpulse-mainloop-glib.so.0");
if (!mGotSyms) return;
// better make double-sure glib itself is initialized properly.
if (!g_thread_supported ()) g_thread_init (NULL);
g_type_init();
mMainloop = llpa_glib_mainloop_new(g_main_context_default());
if (mMainloop)
{
pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop);
if (api)
{
pa_proplist *proplist = llpa_proplist_new();
if (proplist)
{
llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player");
@ -236,6 +236,7 @@ void VolumeCatcherImpl::init()
// plain old pa_context_new() is broken!
mPAContext = llpa_context_new_with_proplist(api, NULL, proplist);
llpa_proplist_free(proplist);
}
}
@ -350,6 +351,51 @@ void VolumeCatcherImpl::update_index_volume(U32 index, F32 volume)
}
}
pid_t getParentPid( pid_t aPid )
{
std::stringstream strm;
strm << "/proc/" << aPid << "/status";
std::ifstream in{ strm.str() };
if( !in.is_open() )
return 0;
pid_t res {0};
while( !in.eof() && res == 0 )
{
std::string line;
line.resize( 1024, 0 );
in.getline( &line[0], line.length() );
auto i = line.find( "PPid:" );
if( i == std::string::npos )
continue;
char const *pIn = line.c_str() + 5; // Skip over pid;
while( *pIn != 0 && isspace( *pIn ) )
++pIn;
if( *pIn )
res = atoll( pIn );
}
return res;
}
bool isPluginPid( pid_t aPid )
{
auto myPid = getpid();
do
{
if( aPid == myPid )
return true;
aPid = getParentPid( aPid );
} while( aPid > 1 );
return false;
}
void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata)
{
@ -360,11 +406,10 @@ void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info
{
pa_proplist *proplist = sii->proplist;
pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID));
if (sinkpid == getpid()) // does the discovered sinkinput belong to this process?
if (isPluginPid( sinkpid )) // does the discovered sinkinput belong to this process?
{
bool is_new = (impl->mSinkInputIndices.find(sii->index) ==
impl->mSinkInputIndices.end());
bool is_new = (impl->mSinkInputIndices.find(sii->index) == impl->mSinkInputIndices.end());
impl->mSinkInputIndices.insert(sii->index);
impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels;
@ -387,32 +432,31 @@ void callback_subscription_alert(pa_context *context, pa_subscription_event_type
VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
llassert(impl);
switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)
{
case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) ==
PA_SUBSCRIPTION_EVENT_REMOVE)
{
// forget this sinkinput, if we were caring about it
impl->mSinkInputIndices.erase(index);
impl->mSinkInputNumChannels.erase(index);
}
else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) ==
PA_SUBSCRIPTION_EVENT_NEW)
{
// ask for more info about this new sinkinput
pa_operation *op;
if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl)))
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
{
llpa_operation_unref(op);
// forget this sinkinput, if we were caring about it
impl->mSinkInputIndices.erase(index);
impl->mSinkInputNumChannels.erase(index);
}
}
else
{
// property change on this sinkinput - we don't care.
}
break;
else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
{
// ask for more info about this new sinkinput
pa_operation *op;
if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl)))
{
llpa_operation_unref(op);
}
}
else
{
// property change on this sinkinput - we don't care.
}
break;
default:;
default:;
}
}

View File

@ -13,7 +13,7 @@ include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
include(CubemapToEquirectangularJS)
include(DBusGlib)
include(GLIB)
include(DragDrop)
include(EXPAT)
include(FMODSTUDIO)
@ -1792,7 +1792,6 @@ if (LINUX)
# fsversionstrings.h with the right numbers in it.
# COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
)
LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
# [FS] Growl support
LIST(APPEND viewer_HEADER_FILES desktopnotifierlinux.h growlmanager.h)
LIST(APPEND viewer_SOURCE_FILES desktopnotifierlinux.cpp growlmanager.cpp)
@ -2532,6 +2531,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLAPPEARANCE_LIBRARIES}
${TRACY_LIBRARY}
${GROWL_LIBRARY}
${GIO_LIBRARIES}
)
target_link_libraries(${VIEWER_BINARY_NAME} ${DISCORD_LIBRARY} )

View File

@ -49,11 +49,12 @@ namespace FSPerfStats
std::atomic<int64_t> tunedAvatars{0};
U32 targetFPS; // desired FPS
U64 renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features
U32 fpsTuningStrategy{0}; // linked to FSTuningFPSStrategy
U32 lastGlobalPrefChange{0};
std::mutex bufferToggleLock{};
bool autoTune{false};
Tunables tunables;
std::atomic<int> StatsRecorder::writeBuffer{0};
bool StatsRecorder::collectionEnabled{true};
LLUUID StatsRecorder::focusAv{LLUUID::null};
@ -61,6 +62,14 @@ namespace FSPerfStats
std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::max{ {} };
std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::sum{ {} };
void Tunables::applyUpdates()
{
assert_main_thread();
if( tuningFlag & NonImposters ){ gSavedSettings.setU32("IndirectMaxNonImpostors", nonImposters); };
if( tuningFlag & ReflectionDetail ){ gSavedSettings.setS32("RenderReflectionDetail", reflectionDetail); };
if( tuningFlag & FarClip ){ gSavedSettings.setF32("RenderFarClip", farClip); };
resetChanges();
}
StatsRecorder::StatsRecorder():q(1024*16),t(&StatsRecorder::run)
{
@ -175,7 +184,7 @@ namespace FSPerfStats
sum[writeBuffer][i].fill(0);
}
// and now adjust the visuals.
// and now adjust the proxy vars so that the main thread can adjust the visuals.
if(autoTune)
{
updateAvatarParams();
@ -280,6 +289,7 @@ namespace FSPerfStats
static LLCachedControl<F32> impostorDistance(gSavedSettings, "FSAutoTuneImpostorFarAwayDistance");
static LLCachedControl<bool> impostorDistanceTuning(gSavedSettings, "FSAutoTuneImpostorByDistEnabled");
static LLCachedControl<U32> maxNonImpostors (gSavedSettings, "IndirectMaxNonImpostors");
static LLCachedControl<U32> fpsTuningStrategy (gSavedSettings, "FSTuningFPSStrategy");
if(impostorDistanceTuning)
{
@ -288,7 +298,7 @@ namespace FSPerfStats
auto count = countNearbyAvatars(std::min(drawDistance, impostorDistance));
if( count != maxNonImpostors )
{
gSavedSettings.setU32("IndirectMaxNonImpostors", (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER);
tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER );
LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(drawDistance, impostorDistance) << "m of the camera" << LL_ENDL;
}
}
@ -339,13 +349,13 @@ namespace FSPerfStats
// we cannnot do this by avatar adjustment alone.
if((gFrameCount - FSPerfStats::lastGlobalPrefChange) > 10) // give changes a short time to take effect.
{
if(FSPerfStats::fpsTuningStrategy == 1)
if(fpsTuningStrategy == 1)
{
// 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit.
// the other reflection options make comparatively little change and iof this overshoots we'll be stepping back up later
if(LLPipeline::RenderReflectionDetail != -2)
{
gSavedSettings.setS32("RenderReflectionDetail", -2);
FSPerfStats::tunables.updateReflectionDetail(-2);
FSPerfStats::lastGlobalPrefChange = gFrameCount;
return;
}
@ -355,7 +365,7 @@ namespace FSPerfStats
auto new_dd = (drawDistance-10>userMinDrawDistance)?(drawDistance - 10) : userMinDrawDistance;
if(new_dd != drawDistance)
{
gSavedSettings.setF32("RenderFarClip", new_dd);
FSPerfStats::tunables.updateFarClip( new_dd );
FSPerfStats::lastGlobalPrefChange = gFrameCount;
return;
}
@ -404,15 +414,14 @@ namespace FSPerfStats
}
if( drawDistance < userTargetDrawDistance )
{
gSavedSettings.setF32("RenderFarClip", drawDistance + 10.);
FSPerfStats::tunables.updateFarClip( drawDistance + 10. );
}
if( (target_frame_time_raw * 1.5) > tot_frame_time_raw &&
FSPerfStats::tunedAvatars == 0 &&
drawDistance >= userTargetDrawDistance)
{
// if everything else is "max" and we have 50% headroom let's knock the water quality up a notch at a time.
auto water = gSavedSettings.getS32("RenderReflectionDetail");
gSavedSettings.setS32("RenderReflectionDetail", water+1);
FSPerfStats::tunables.updateReflectionDetail( gSavedSettings.getS32("RenderReflectionDetail") + 1 );
}
}
updateSettingsFromRenderCostLimit();

View File

@ -74,7 +74,6 @@ namespace FSPerfStats
extern std::atomic<int64_t> tunedAvatars;
extern U32 targetFPS; // desired FPS
extern U64 renderAvatarMaxART_ns;
extern U32 fpsTuningStrategy;
extern U32 lastGlobalPrefChange;
extern std::mutex bufferToggleLock;
extern bool autoTune;
@ -116,6 +115,28 @@ namespace FSPerfStats
bool isHUD;
};
struct Tunables
{
static constexpr U32 Nothing{0};
static constexpr U32 NonImposters{1};
static constexpr U32 ReflectionDetail{2};
static constexpr U32 FarClip{4};
U32 tuningFlag{0};
U32 nonImposters;
S32 reflectionDetail;
F32 farClip;
void updateFarClip(F32 nv){farClip=nv; tuningFlag |= FarClip;};
void updateNonImposters(U32 nv){nonImposters=nv; tuningFlag |= NonImposters;};
void updateReflectionDetail(S32 nv){reflectionDetail=nv; tuningFlag |= ReflectionDetail;};
void applyUpdates();
void resetChanges(){tuningFlag=Nothing;};
};
extern Tunables tunables;
class StatsRecorder{
using Queue = moodycamel::BlockingConcurrentQueue<StatsRecord>;
public:

View File

@ -0,0 +1,47 @@
#!/bin/bash
SCRIPT_PATH=`readlink -f $0`
SCRIPT_PATH=`dirname $SCRIPT_PATH`
# All hope is lost if there is no lsb_release command
command -v lsb_release >/dev/null 2>/dev/null || exit 0
if [ `lsb_release -is` != "Ubuntu" ]
then
echo "Distribution is not Ubuntu, skipping AppImage creation"
exit 0
fi
set -e
cd $1
pushd packaged
wget -q https://github.com/AppImage/AppImages/raw/master/functions.sh -O ./functions.sh
. ./functions.sh
rm functions.sh
cp firestorm AppRun
cp ${SCRIPT_PATH}/firestorm.desktop firestorm.desktop
copy_deps
copy_deps
copy_deps
delete_blacklisted
# Now copy everything to ./lib. The viewer binaries got build with a rpath pointing to ./lib so all so will be magically found there.
#find ./usr/lib/ -type f -print0 | xargs -0 -Ifile cp file ./lib/
#find ./lib/x86_64-linux-gnu/ -type f -print0 | xargs -0 -Ifile cp file ./lib/
#rm -rf ./usr/lib/
#rm -rf ./lib/x86_64-linux-gnu/
find . -empty -type d -delete
popd
wget "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod a+x appimagetool-x86_64.AppImage
./appimagetool-x86_64.AppImage --appimage-extract
rm appimagetool-x86_64.AppImage
ARCH=x86_64 squashfs-root/AppRun packaged

View File

@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Name=Firestorm
Exec=firestorm
Comment=Client for virtual worlds
Icon=firestorm_icon
Categories=Development;
Terminal=true

View File

@ -1602,7 +1602,14 @@ bool LLAppViewer::doFrame()
LL_RECORD_BLOCK_TIME(FTM_FRAME);
// <FS:Beq> Perfstats collection Frame boundary
{FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_FRAME);
{
// and now adjust the visuals from previous frame.
if(FSPerfStats::autoTune && FSPerfStats::tunables.tuningFlag != FSPerfStats::Tunables::Nothing)
{
FSPerfStats::tunables.applyUpdates();
}
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_FRAME);
if (!LLWorld::instanceExists())
{
@ -1680,7 +1687,7 @@ bool LLAppViewer::doFrame()
}
// Check if we need to temporarily enable rendering.
//F32 periodic_rendering = gSavedSettings.getF32("ForcePeriodicRenderingTime");
static LLCachedControl<F32> periodic_rendering(gSavedSettings, "ForcePeriodicRenderingTime");
static LLCachedControl<F32> periodic_rendering(gSavedSettings, "ForcePeriodicRenderingTime", -1.f);
if (periodic_rendering > F_APPROXIMATELY_ZERO && periodicRenderingTimer.getElapsedTimeF64() > periodic_rendering)
{
periodicRenderingTimer.reset();

View File

@ -42,16 +42,27 @@
#include "json/reader.h" // <FS:ND/> To parse manifest.json from pepperflash
#if LL_DBUS_ENABLED
# include "llappviewerlinux_api_dbus.h"
// regrettable hacks to give us better runtime compatibility with older systems inside llappviewerlinux_api.h:
#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0)
#undef g_return_if_fail
#define g_return_if_fail(COND) llg_return_if_fail(COND)
// The generated API
# include "llappviewerlinux_api.h"
#endif
#include <gio/gio.h>
#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService"
#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI"
#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI"
static const char * DBUS_SERVER = "<node name=\"/com/secondlife/ViewerAppAPI\">\n"
" <interface name=\"com.secondlife.ViewerAppAPI\">\n"
" <annotation name=\"org.freedesktop.DBus.GLib.CSymbol\" value=\"viewer_app_api\"/>\n"
" <method name=\"GoSLURL\">\n"
" <annotation name=\"org.freedesktop.DBus.GLib.CSymbol\" value=\"dispatchSLURL\"/>\n"
" <arg type=\"s\" name=\"slurl\" direction=\"in\" />\n"
" </method>\n"
" </interface>\n"
"</node>";
typedef struct
{
GObject parent;
} ViewerAppAPI;
namespace
{
@ -127,10 +138,6 @@ bool LLAppViewerLinux::init()
// libraries likes to use glib functions; in short, do this here
// really early in app startup!
#if ( !defined(GLIB_MAJOR_VERSION) && !defined(GLIB_MINOR_VERSION) ) || ( GLIB_MAJOR_VERSION < 2 ) || ( GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 32 )
if (!g_thread_supported ()) g_thread_init (NULL);
#endif
bool success = LLAppViewer::init();
#if LL_SEND_CRASH_REPORTS
@ -152,40 +159,17 @@ bool LLAppViewerLinux::restoreErrorTrap()
}
/////////////////////////////////////////
#if LL_DBUS_ENABLED
#if LL_GLIB
typedef struct
{
GObjectClass parent_class;
} ViewerAppAPIClass;
static void viewerappapi_init(ViewerAppAPI *server);
static void viewerappapi_class_init(ViewerAppAPIClass *klass);
///
// regrettable hacks to give us better runtime compatibility with older systems in general
static GType llg_type_register_static_simple_ONCE(GType parent_type,
const gchar *type_name,
guint class_size,
GClassInitFunc class_init,
guint instance_size,
GInstanceInitFunc instance_init,
GTypeFlags flags)
{
static GTypeInfo type_info;
memset(&type_info, 0, sizeof(type_info));
type_info.class_size = class_size;
type_info.class_init = class_init;
type_info.instance_size = instance_size;
type_info.instance_init = instance_init;
return g_type_register_static(parent_type, type_name, &type_info, flags);
}
#define llg_intern_static_string(S) (S)
#define g_intern_static_string(S) llg_intern_static_string(S)
#define g_type_register_static_simple(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags) llg_type_register_static_simple_ONCE(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags)
static void viewerappapi_init(ViewerAppAPI *server);
static void viewerappapi_class_init(ViewerAppAPIClass *klass);
G_DEFINE_TYPE(ViewerAppAPI, viewerappapi, G_TYPE_OBJECT);
@ -193,79 +177,71 @@ void viewerappapi_class_init(ViewerAppAPIClass *klass)
{
}
static bool dbus_server_init = false;
void viewerappapi_init(ViewerAppAPI *server)
static void dispatchSLURL(gchar const *slurl)
{
// Connect to the default DBUS, register our service/API.
LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL;
if (!dbus_server_init)
{
GError *error = NULL;
server->connection = lldbus_g_bus_get(DBUS_BUS_SESSION, &error);
if (server->connection)
{
lldbus_g_object_type_install_info(viewerappapi_get_type(), &dbus_glib_viewerapp_object_info);
lldbus_g_connection_register_g_object(server->connection, VIEWERAPI_PATH, G_OBJECT(server));
DBusGProxy *serverproxy = lldbus_g_proxy_new_for_name(server->connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
guint request_name_ret_unused;
// akin to org_freedesktop_DBus_request_name
if (lldbus_g_proxy_call(serverproxy, "RequestName", &error, G_TYPE_STRING, VIEWERAPI_SERVICE, G_TYPE_UINT, 0, G_TYPE_INVALID, G_TYPE_UINT, &request_name_ret_unused, G_TYPE_INVALID))
{
// total success.
dbus_server_init = true;
}
else
{
LL_WARNS() << "Unable to register service name: " << error->message << LL_ENDL;
}
g_object_unref(serverproxy);
}
else
{
g_warning("Unable to connect to dbus: %s", error->message);
}
if (error)
g_error_free(error);
}
std::string url = slurl;
LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
LLURLDispatcher::dispatch(url, "", web, trusted_browser);
}
// <FS:ND> FIRE-5417; The xml manifest for dbus claims success_rtn is a boolean, not a boolean array
//gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error)
gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean *success_rtn, GError **error)
// </FS:ND>
static void DoMethodeCall (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
bool success = false;
LL_INFOS() << "DBUS message " << method_name << " from: " << sender << " interface: " << interface_name << LL_ENDL;
const gchar *slurl;
LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL;
g_variant_get (parameters, "(&s)", &slurl);
dispatchSLURL(slurl);
}
std::string url = slurl;
LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
if (LLURLDispatcher::dispatch(url, "", web, trusted_browser))
{
// bring window to foreground, as it has just been "launched" from a URL
// todo: hmm, how to get there from here?
//xxx->mWindow->bringToFront();
success = true;
}
GDBusNodeInfo *gBusNodeInfo = nullptr;
static const GDBusInterfaceVTable interface_vtable =
{
DoMethodeCall
};
static void busAcquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
{
auto id = g_dbus_connection_register_object(connection,
VIEWERAPI_PATH,
gBusNodeInfo->interfaces[0],
&interface_vtable,
NULL, /* user_data */
NULL, /* user_data_free_func */
NULL); /* GError** */
g_assert (id > 0);
}
// <FS:ND> FIRE-5417; The xml manifest for dbus claims success_rtn is a boolean, not a boolean array
static void nameAcquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
{
}
// *success_rtn = g_new (gboolean, 1);
// (*success_rtn)[0] = (gboolean)success;
static void nameLost(GDBusConnection *connection, const gchar *name, gpointer user_data)
{
*success_rtn = (gboolean)success;
}
void viewerappapi_init(ViewerAppAPI *server)
{
gBusNodeInfo = g_dbus_node_info_new_for_xml (DBUS_SERVER, NULL);
g_assert (gBusNodeInfo != NULL);
// </FS:ND>
auto owner_id = g_bus_own_name(G_BUS_TYPE_SESSION,
VIEWERAPI_SERVICE,
G_BUS_NAME_OWNER_FLAGS_NONE,
busAcquired,
nameAcquired,
nameLost,
NULL,
NULL);
return TRUE; // the invokation succeeded, even if the actual dispatch didn't.
}
///
@ -273,15 +249,6 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean *succe
//virtual
bool LLAppViewerLinux::initSLURLHandler()
{
if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME))
{
return false; // failed
}
#if ( !defined(GLIB_MAJOR_VERSION) && !defined(GLIB_MINOR_VERSION) ) || ( GLIB_MAJOR_VERSION < 2 ) || ( GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 35 )
g_type_init();
#endif
//ViewerAppAPI *api_server = (ViewerAppAPI*)
g_object_new(viewerappapi_get_type(), NULL);
@ -291,51 +258,51 @@ bool LLAppViewerLinux::initSLURLHandler()
//virtual
bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url)
{
if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME))
{
return false; // failed
}
bool success = false;
bool success = false;
DBusGConnection *bus;
GError *error = NULL;
auto *pBus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, nullptr);
#if ( !defined(GLIB_MAJOR_VERSION) && !defined(GLIB_MINOR_VERSION) ) || ( GLIB_MAJOR_VERSION < 2 ) || ( GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 35 )
g_type_init();
#endif
bus = lldbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (bus)
{
gboolean rtn = FALSE;
DBusGProxy *remote_object =
lldbus_g_proxy_new_for_name(bus, VIEWERAPI_SERVICE, VIEWERAPI_PATH, VIEWERAPI_INTERFACE);
if( !pBus )
{
LL_WARNS() << "Getting dbus failed." << LL_ENDL;
return false;
}
if (lldbus_g_proxy_call(remote_object, "GoSLURL", &error,
G_TYPE_STRING, url.c_str(), G_TYPE_INVALID,
G_TYPE_BOOLEAN, &rtn, G_TYPE_INVALID))
{
success = rtn;
}
else
{
LL_INFOS() << "Call-out to other instance failed (perhaps not running): " << error->message << LL_ENDL;
}
auto pProxy = g_dbus_proxy_new_sync(pBus, G_DBUS_PROXY_FLAGS_NONE, nullptr,
VIEWERAPI_SERVICE, VIEWERAPI_PATH,
VIEWERAPI_INTERFACE, nullptr, nullptr);
g_object_unref(G_OBJECT(remote_object));
}
else
{
LL_WARNS() << "Couldn't connect to session bus: " << error->message << LL_ENDL;
}
if( !pProxy )
{
LL_WARNS() << "Cannot create new dbus proxy." << LL_ENDL;
g_object_unref( pBus );
return false;
}
if (error)
g_error_free(error);
return success;
auto *pArgs = g_variant_new( "(s)", url.c_str() );
if( !pArgs )
{
LL_WARNS() << "Cannot create new variant." << LL_ENDL;
g_object_unref( pBus );
return false;
}
auto pRes = g_dbus_proxy_call_sync(pProxy,
"GoSLURL",
pArgs,
G_DBUS_CALL_FLAGS_NONE,
-1, nullptr, nullptr);
if( pRes )
g_variant_unref( pRes );
g_object_unref( pProxy );
g_object_unref( pBus );
return true;
}
#else // LL_DBUS_ENABLED
#else // LL_GLIB
bool LLAppViewerLinux::initSLURLHandler()
{
return false; // not implemented without dbus
@ -344,7 +311,7 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url)
{
return false; // not implemented without dbus
}
#endif // LL_DBUS_ENABLED
#endif // LL_GLIB
void LLAppViewerLinux::initCrashReporting(bool reportFreeze)
{

View File

@ -27,19 +27,6 @@
#ifndef LL_LLAPPVIEWERLINUX_H
#define LL_LLAPPVIEWERLINUX_H
#ifdef LL_GLIB
extern "C" {
# include <glib.h>
#if LL_DBUS_ENABLED
# include <glib-object.h>
# include <dbus/dbus-glib.h>
#endif
}
#endif
#ifndef LL_LLAPPVIEWER_H
#include "llappviewer.h"
#endif
@ -72,26 +59,4 @@ protected:
virtual bool sendURLToOtherInstance(const std::string& url);
};
#if LL_DBUS_ENABLED && LL_GLIB
typedef struct
{
GObject parent;
DBusGConnection *connection;
} ViewerAppAPI;
extern "C" {
// <FS:ND> FIRE-5417; The xml manifest for dbus claims success_rtn is a boolean, not a boolean array
// gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error);
gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean *success_rtn, GError **error);
// <FS:ND>
}
#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService"
#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI"
#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI"
#endif // LL_DBUS_ENABLED
#endif // LL_LLAPPVIEWERLINUX_H

View File

@ -1,143 +0,0 @@
/* Generated by dbus-binding-tool; do not edit! */
/**
* $LicenseInfo:firstyear=2008&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$
*/
#ifndef __dbus_glib_marshal_viewerapp_MARSHAL_H__
#define __dbus_glib_marshal_viewerapp_MARSHAL_H__
#include <glib-object.h>
G_BEGIN_DECLS
#ifdef G_ENABLE_DEBUG
#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
#define g_marshal_value_peek_char(v) g_value_get_char (v)
#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
#define g_marshal_value_peek_int(v) g_value_get_int (v)
#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
#define g_marshal_value_peek_long(v) g_value_get_long (v)
#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
#define g_marshal_value_peek_float(v) g_value_get_float (v)
#define g_marshal_value_peek_double(v) g_value_get_double (v)
#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
#define g_marshal_value_peek_param(v) g_value_get_param (v)
#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
#define g_marshal_value_peek_object(v) g_value_get_object (v)
#else /* !G_ENABLE_DEBUG */
/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
* Do not access GValues directly in your code. Instead, use the
* g_value_get_*() functions
*/
#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
#define g_marshal_value_peek_char(v) (v)->data[0].v_int
#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
#define g_marshal_value_peek_int(v) (v)->data[0].v_int
#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
#define g_marshal_value_peek_long(v) (v)->data[0].v_long
#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_float(v) (v)->data[0].v_float
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
#endif /* !G_ENABLE_DEBUG */
/* BOOLEAN:STRING,POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.5XXD8T:1) */
extern void dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data);
void
dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data)
{
typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (gpointer data1,
gpointer arg_1,
gpointer arg_2,
gpointer arg_3,
gpointer data2);
register GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 4);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
g_marshal_value_peek_string (param_values + 1),
g_marshal_value_peek_pointer (param_values + 2),
g_marshal_value_peek_pointer (param_values + 3),
data2);
g_value_set_boolean (return_value, v_return);
}
G_END_DECLS
#endif /* __dbus_glib_marshal_viewerapp_MARSHAL_H__ */
#include <dbus/dbus-glib.h>
static const DBusGMethodInfo dbus_glib_viewerapp_methods[] = {
{ (GCallback) viewer_app_api_GoSLURL, dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER, 0 },
};
const DBusGObjectInfo dbus_glib_viewerapp_object_info = {
0,
dbus_glib_viewerapp_methods,
1,
"com.secondlife.ViewerAppAPI\0GoSLURL\0S\0slurl\0I\0s\0success_ret\0O\0F\0N\0b\0\0\0",
"\0",
"\0"
};

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- dbus-binding-tool -mode=glib-server llappviewerlinux_api.xml -prefix=viewerapp -output=llappviewerlinux_api.h -->
<node name="/com/secondlife/ViewerAppAPI">
<interface name="com.secondlife.ViewerAppAPI">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="viewer_app_api"/>
<method name="GoSLURL">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="viewer_app_api_GoSLURL"/>
<arg type="s" name="slurl" direction="in" />
<arg type="b" name="success_ret" direction="out" />
</method>
</interface>
</node>

View File

@ -1,126 +0,0 @@
/**
* @file llappviewerlinux_api_dbus.cpp
* @brief dynamic DBus symbol-grabbing code
*
* $LicenseInfo:firstyear=2008&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$
*/
#if LL_DBUS_ENABLED
#include "linden_common.h"
extern "C" {
#include <dbus/dbus-glib.h>
#include "apr_pools.h"
#include "apr_dso.h"
}
#define DEBUGMSG(...) do { LL_DEBUGS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0)
#define INFOMSG(...) do { LL_INFOS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0)
#define WARNMSG(...) do { LL_WARNS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0)
#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) RTN (*ll##DBUSSYM)(__VA_ARGS__) = NULL
#include "llappviewerlinux_api_dbus_syms_raw.inc"
#undef LL_DBUS_SYM
static bool sSymsGrabbed = false;
static apr_pool_t *sSymDBUSDSOMemoryPool = NULL;
static apr_dso_handle_t *sSymDBUSDSOHandleG = NULL;
bool grab_dbus_syms(std::string dbus_dso_name)
{
if (sSymsGrabbed)
{
// already have grabbed good syms
return TRUE;
}
bool sym_error = false;
bool rtn = false;
apr_status_t rv;
apr_dso_handle_t *sSymDBUSDSOHandle = NULL;
#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0)
//attempt to load the shared library
apr_pool_create(&sSymDBUSDSOMemoryPool, NULL);
if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle,
dbus_dso_name.c_str(),
sSymDBUSDSOMemoryPool) ))
{
INFOMSG("Found DSO: %s", dbus_dso_name.c_str());
#include "llappviewerlinux_api_dbus_syms_raw.inc"
if ( sSymDBUSDSOHandle )
{
sSymDBUSDSOHandleG = sSymDBUSDSOHandle;
sSymDBUSDSOHandle = NULL;
}
rtn = !sym_error;
}
else
{
INFOMSG("Couldn't load DSO: %s", dbus_dso_name.c_str());
rtn = false; // failure
}
if (sym_error)
{
WARNMSG("Failed to find necessary symbols in DBUS-GLIB libraries.");
}
#undef LL_DBUS_SYM
sSymsGrabbed = rtn;
return rtn;
}
void ungrab_dbus_syms()
{
// should be safe to call regardless of whether we've
// actually grabbed syms.
if ( sSymDBUSDSOHandleG )
{
apr_dso_unload(sSymDBUSDSOHandleG);
sSymDBUSDSOHandleG = NULL;
}
if ( sSymDBUSDSOMemoryPool )
{
apr_pool_destroy(sSymDBUSDSOMemoryPool);
sSymDBUSDSOMemoryPool = NULL;
}
// NULL-out all of the symbols we'd grabbed
#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0)
#include "llappviewerlinux_api_dbus_syms_raw.inc"
#undef LL_DBUS_SYM
sSymsGrabbed = false;
}
#endif // LL_DBUS_ENABLED

View File

@ -1,44 +0,0 @@
/**
* @file llappviewerlinux_api_dbus.h
* @brief DBus-glib symbol handling
*
* $LicenseInfo:firstyear=2008&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$
*/
#include "linden_common.h"
#if LL_DBUS_ENABLED
extern "C" {
#include <dbus/dbus-glib.h>
}
#define DBUSGLIB_DYLIB_DEFAULT_NAME "libdbus-glib-1.so.2"
bool grab_dbus_syms(std::string dbus_dso_name);
void ungrab_dbus_syms();
#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) extern RTN (*ll##DBUSSYM)(__VA_ARGS__)
#include "llappviewerlinux_api_dbus_syms_raw.inc"
#undef LL_DBUS_SYM
#endif // LL_DBUS_ENABLED

View File

@ -1,9 +0,0 @@
// required symbols to grab
LL_DBUS_SYM(true, dbus_g_bus_get, DBusGConnection*, DBusBusType, GError**);
LL_DBUS_SYM(true, dbus_g_proxy_new_for_name, DBusGProxy*, DBusGConnection*, const char *, const char*, const char*);
LL_DBUS_SYM(true, dbus_g_proxy_call, gboolean, DBusGProxy*, const char*, GError**, GType, ...);
LL_DBUS_SYM(true, dbus_g_object_type_install_info, void, GType, const DBusGObjectInfo*);
LL_DBUS_SYM(true, dbus_g_connection_register_g_object, void, DBusGConnection*, const char*, GObject*);
// optional symbols to grab

View File

@ -252,11 +252,15 @@ BOOL LLDirPicker::getDir(std::string* filename, bool blocking)
return FALSE;
#else
gViewerWindow->getWindow()->beforeDialog();
Fl_Native_File_Chooser flDlg;
flDlg.title("Pick a dir");
flDlg.title(LLTrans::getString("choose_the_directory").c_str());
flDlg.type(Fl_Native_File_Chooser::BROWSE_DIRECTORY );
int res = flDlg.show();
gViewerWindow->getWindow()->afterDialog();
if( res == 0 )
{
char const *pDir = flDlg.filename(0);

View File

@ -79,8 +79,11 @@ private:
bool check_local_file_access_enabled();
#if LL_LINUX || LL_DARWIN
// On Linux we just implement LLDirPicker on top of LLFilePicker
// LLFilePicker *mFilePicker;
// On Linux we just implement LLDirPicker on top of LLFilePicker
// <FS:ND> Seems like on OSX too ... Unless FLTK is used, then nope
#ifndef LL_FLTK
LLFilePicker *mFilePicker;
#endif
#endif

View File

@ -1588,19 +1588,12 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
return openFileDialog( filter, blocking, eOpenMultiple );
}
void setupFilter( Fl_Native_File_Chooser &chooser, LLFilePicker::ESaveFilter filter )
{
}
void setupFilter( Fl_Native_File_Chooser &chooser, LLFilePicker::ELoadFilter filter )
{
}
bool LLFilePicker::openFileDialog( int32_t filter, bool blocking, EType aType )
{
if ( check_local_file_access_enabled() == false )
return false;
gViewerWindow->getWindow()->beforeDialog();
reset();
Fl_Native_File_Chooser::Type flType = Fl_Native_File_Chooser::BROWSE_FILE;
@ -1610,15 +1603,186 @@ bool LLFilePicker::openFileDialog( int32_t filter, bool blocking, EType aType )
flType = Fl_Native_File_Chooser::BROWSE_SAVE_FILE;
Fl_Native_File_Chooser flDlg;
flDlg.title("Pick a file");
flDlg.type( flType );
if( aType == eSaveFile )
setupFilter( flDlg, (ESaveFilter) filter );
std::string file_dialog_title;
std::string file_dialog_filter;
if (aType == EType::eSaveFile)
{
std::string file_type("all_files");
switch ((ESaveFilter) filter)
{
case FFSAVE_ALL:
break;
case FFSAVE_TGA:
file_type = "targa_image_files";
file_dialog_filter = "*.tga";
break;
case FFSAVE_BMP:
file_type = "bitmap_image_files";
file_dialog_filter = "*.bmp";
break;
case FFSAVE_AVI:
file_type = "avi_movie_file";
file_dialog_filter = "*.avi";
break;
case FFSAVE_ANIM:
file_type = "xaf_animation_file";
file_dialog_filter = "*.xaf";
break;
case FFSAVE_XML:
file_type = "xml_file";
file_dialog_filter = "*.xml";
break;
case FFSAVE_COLLADA:
file_type = "collada_files";
file_dialog_filter = "*.dae";
break;
case FFSAVE_RAW:
file_type = "raw_file";
file_dialog_filter = "*.raw";
break;
case FFSAVE_J2C:
file_type = "compressed_image_files";
file_dialog_filter = "*.j2c";
break;
case FFSAVE_PNG:
file_type = "png_image_files";
file_dialog_filter = "*.png";
break;
case FFSAVE_JPEG:
file_type = "jpeg_image_files";
file_dialog_filter = "*.{jpg,jpeg}";
break;
case FFSAVE_SCRIPT:
file_type = "script_files";
file_dialog_filter = "*.lsl";
break;
case FFSAVE_TGAPNG:
file_type = "save_texture_image_files";
file_dialog_filter = "*.{tga,png}";
break;
case FFSAVE_WAV:
file_type = "sound_files";
file_dialog_filter = "*.wav";
break;
// Firestorm additions
case FFSAVE_BEAM:
file_type = "xml_file";
file_dialog_filter = "*.xml";
break;
case FFSAVE_EXPORT:
file_type = "backup_files";
file_dialog_filter = "*.oxp";
break;
case FFSAVE_CSV:
file_type = "csv_files";
file_dialog_filter = "*.csv";
break;
#ifdef _CORY_TESTING
case FFSAVE_GEOMETRY:
// no file type translation for this, so using the default "all_files" for now
file_dialog_filter = "*.slg";
break;
#endif
}
// can't say I like this combining of verb+type, it might not work too well in all languages -Zi
file_dialog_title = LLTrans::getString("save_file_verb") + " " + LLTrans::getString(file_type);
file_dialog_filter = LLTrans::getString(file_type) + " \t" + file_dialog_filter;
}
else
setupFilter( flDlg, (ELoadFilter) filter );
{
std::string file_type("all_files");
switch ((ELoadFilter) filter)
{
case FFLOAD_ALL:
break;
case FFLOAD_WAV:
file_type = "sound_files";
file_dialog_filter = "*.wav";
break;
case FFLOAD_IMAGE:
file_type = "image_files";
file_dialog_filter = "*.{tga,bmp,jpg,jpeg,png}";
break;
case FFLOAD_ANIM:
file_type = "animation_files";
file_dialog_filter = "*.{bvh,anim}";
break;
case FFLOAD_XML:
file_type = "xml_file";
file_dialog_filter = "*.xml";
break;
case FFLOAD_SLOBJECT:
file_type = "xml_file";
file_dialog_filter = "*.slobject";
break;
case FFLOAD_RAW:
file_type = "raw_file";
file_dialog_filter = "*.raw";
break;
case FFLOAD_MODEL:
case FFLOAD_COLLADA:
file_type = "collada_files";
file_dialog_filter = "*.dae";
break;
case FFLOAD_SCRIPT:
file_type = "script_files";
file_dialog_filter = "*.lsl";
break;
case FFLOAD_DICTIONARY:
file_type = "dictionary_files";
file_dialog_filter = "*.{dic,xcu}";
break;
case FFLOAD_DIRECTORY:
file_type = "choose_the_directory";
break;
case FFLOAD_EXE:
file_type = "executable_files";
break;
// Firestorm additions
case FFLOAD_IMPORT:
file_type = "backup_files";
file_dialog_filter = "*.oxp";
break;
#ifdef _CORY_TESTING
case FFLOAD_GEOMETRY:
// no file type translation for this, so using the default "all_files" for now
file_dialog_filter = "*.slg";
break;
#endif
}
if (aType == EType::eOpenMultiple)
{
file_dialog_title = LLTrans::getString("load_files");
}
else
{
// can't say I like this combining of verb+type, it might not work too well in all languages -Zi
file_dialog_title = LLTrans::getString("load_file_verb") + " " + LLTrans::getString(file_type);
file_dialog_filter = LLTrans::getString(file_type) + " \t" + file_dialog_filter;
}
}
flDlg.title(file_dialog_title.c_str());
flDlg.type(flType);
if (!file_dialog_filter.empty())
{
flDlg.filter(file_dialog_filter.c_str());
}
int res = flDlg.show();
gViewerWindow->getWindow()->afterDialog();
if( res == 0 )
{
int32_t count = flDlg.count();

View File

@ -3087,6 +3087,16 @@ void LLFloaterPreference::updateUISoundsControls()
getChild<LLComboBox>("PlayModeUISndNewIncomingGroupIMSession")->setValue((int)gSavedSettings.getU32("PlayModeUISndNewIncomingGroupIMSession")); // 0, 1, 2, 3. Shared with Chat > Notifications > "When receiving Group Instant Messages"
getChild<LLComboBox>("PlayModeUISndNewIncomingConfIMSession")->setValue((int)gSavedSettings.getU32("PlayModeUISndNewIncomingConfIMSession")); // 0, 1, 2, 3. Shared with Chat > Notifications > "When receiving AdHoc Instant Messages"
#ifdef OPENSIM
// <FS:Beq> OpenSim has option to not attenuate nearby local voice by distance
auto earPosGroup = findChild<LLRadioGroup>("ear_location");
if (earPosGroup)
{
// It seems there is no better way to do this than with magic numbers short of importing the enums in vivoxvoice (which aren't necessarily the same thing).
// Index 2 here is the opensim only option to hear nearby chat without attenuation.
constexpr int hearNearbyVoiceFullVolume{2};
earPosGroup->setIndexEnabled(hearNearbyVoiceFullVolume, LLGridManager::instance().isInOpenSim());
}
// <FS:Beq>
getChild<LLTextBox>("textFSRestartOpenSim")->setVisible(TRUE);
getChild<LLLineEditor>("UISndRestartOpenSim")->setVisible(TRUE);
getChild<LLButton>("Prev_UISndRestartOpenSim")->setVisible(TRUE);

View File

@ -1106,11 +1106,7 @@ void handleRenderAvatarMaxARTChanged(const LLSD& newValue)
{
FSPerfStats::StatsRecorder::updateRenderCostLimitFromSettings();
}
void handleFPSTuningStrategyChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getU32("FSTuningFPSStrategy");
FSPerfStats::fpsTuningStrategy = newval;
}
void handlePerformanceStatsEnabledChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getBOOL("FSPerfStatsCaptureEnabled");
@ -1377,7 +1373,6 @@ void settings_setup_listeners()
gSavedSettings.getControl("FSTargetFPS")->getSignal()->connect(boost::bind(&handleTargetFPSChanged, _2));
gSavedSettings.getControl("FSAutoTuneFPS")->getSignal()->connect(boost::bind(&handleAutoTuneFPSChanged, _2));
gSavedSettings.getControl("FSRenderAvatarMaxART")->getSignal()->connect(boost::bind(&handleRenderAvatarMaxARTChanged, _2));
gSavedSettings.getControl("FSTuningFPSStrategy")->getSignal()->connect(boost::bind(&handleFPSTuningStrategyChanged, _2));
gSavedSettings.getControl("FSPerfStatsCaptureEnabled")->getSignal()->connect(boost::bind(&handlePerformanceStatsEnabledChanged, _2));
// </FS:Beq>
}

View File

@ -6834,7 +6834,7 @@ void mean_name_callback(const LLUUID &id, const LLAvatarName& av_name)
LLMeanCollisionData *mcd = *iter;
if (mcd->mPerp == id)
{
mcd->mFullName = av_name.getUserName();
mcd->mFullName = gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) ? RlvStrings::getAnonym(av_name) : av_name.getUserName();
}
}
// <FS:Ansariel> Instant bump list floater update
@ -6881,7 +6881,14 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use
{
std::string action;
LLStringUtil::format_map_t args;
args["NAME"] = llformat("secondlife:///app/agent/%s/inspect", perp.asString().c_str());
if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
{
args["NAME"] = llformat("secondlife:///app/agent/%s/inspect", perp.asString().c_str());
}
else
{
args["NAME"] = llformat("secondlife:///app/agent/%s/rlvanonym", perp.asString().c_str());
}
switch (type)
{
@ -6915,10 +6922,10 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use
LLMessageSystem* msgs = gMessageSystem;
msgs->newMessage(_PREHASH_ScriptDialogReply);
msgs->nextBlock(_PREHASH_AgentData);
msgs->addUUID(_PREHASH_AgentID, gAgent.getID());
msgs->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
msgs->addUUID(_PREHASH_AgentID, gAgentID);
msgs->addUUID(_PREHASH_SessionID, gAgentSessionID);
msgs->nextBlock(_PREHASH_Data);
msgs->addUUID(_PREHASH_ObjectID, gAgent.getID());
msgs->addUUID(_PREHASH_ObjectID, gAgentID);
msgs->addS32(_PREHASH_ChatChannel, gSavedSettings.getS32("FSReportCollisionMessagesChannel"));
msgs->addS32(_PREHASH_ButtonIndex, 1);
msgs->addString(_PREHASH_ButtonLabel, collision_data.c_str());

View File

@ -3373,17 +3373,31 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void)
earVelocity = mAvatarVelocity;
earRot = mCameraRot;
break;
// <FS:Beq> reimplement hear voice equally
case earLocSpeaker:
// we leave EarPos/Vel/Rot as empty
LL_DEBUGS("Voice") << "EarLoc Speaker in use" << LL_ENDL;
break;
// </FS:Beq>
}
// <FS:Beq> reimplement hear voice equally
if(mEarLocation != earLocSpeaker)
{
// for all spatial sources we need to do the transform
// </FS:Beq>
l = earRot.getLeftRow();
u = earRot.getUpRow();
a = earRot.getFwdRow();
pos = earPosition;
vel = earVelocity;
oldSDKTransform(l, u, a, pos, vel);
// <FS:Beq> reimplement hear voice equally
}
// </FS:Beq>
if (mHidden)
{

View File

@ -803,6 +803,7 @@ private:
{
earLocCamera = 0, // ear at camera
earLocAvatar, // ear at avatar
earLocSpeaker, // <FS:Beq> re-add equal voice based loosely on original patch from Tigh MacFanatic
earLocMixed // ear at avatar location/camera direction
};

View File

@ -10,8 +10,8 @@
Maustaste 5
</panel.string>
<tab_container label="Firestorm Prefs" name="tabs">
<!-- Sounds -->
<panel label="Klänge" name="Media Sounds Panel">
<!-- Sounds -->
<panel label="Klänge" name="Media Sounds Panel">
<slider label="Master-Lautstärke" name="System Volume"/>
<check_box name="mute_when_minimized" label="Stummschalten, wenn minimiert"/>
<slider label="Schaltflächen" name="UI Volume"/>
@ -57,7 +57,7 @@
</panel>
</panel>
<!-- Media -->
<panel label="Medien" name="Media Media Panel">
<text width="190" name="media_autoplay_label">
@ -72,23 +72,23 @@
<check_box label="Medien, die an andere Avatare angehängt sind, wiedergeben." name="media_show_on_others_btn" tool_tip="Diese Option deaktivieren, um Medien für andere Avataren, die sich in der Nähe befinden, auszublenden."/>
<check_box name="media_filter" tool_tip="Aktiviert den Medienfilter, der abhängig der Medien-URL die Wiedergabe erlaubt oder verbietet." label="Medienfilter aktivieren (erhöhte Sicherheit)"/>
<button label="Listen bearbeiten..." name="edit_media_lists_button"/>
<text name="Media Rolloff">
Lautstärkeabfall-Distanz für Medien-Quellen:
</text>
<slider label="Wird leiser ab:" name="MediaRollOffMin" tool_tip="Minimale Distanz von der Soundquelle, ab der die Lautstärke abzufallen beginnt."/>
<text name="MinMeters">
Meter
</text>
<slider label="Wird lauter ab:" name="MediaRollOffMax" tool_tip="Maximale Distanz von der Soundquelle, ab der sie stummgeschaltet wird."/>
<text name="MaxMeters">
Meter
</text>
</panel>
<text name="Media Rolloff">
Lautstärkeabfall-Distanz für Medien-Quellen:
</text>
<slider label="Wird leiser ab:" name="MediaRollOffMin" tool_tip="Minimale Distanz von der Soundquelle, ab der die Lautstärke abzufallen beginnt."/>
<text name="MinMeters">
Meter
</text>
<slider label="Wird lauter ab:" name="MediaRollOffMax" tool_tip="Maximale Distanz von der Soundquelle, ab der sie stummgeschaltet wird."/>
<text name="MaxMeters">
Meter
</text>
</panel>
<!-- Music -->
<panel label="Musik" name="Media Music Panel">
<check_box label="Automatische Audio-Wiedergabe zulassen" name="audio_auto_play_btn" tool_tip="Hier aktivieren, um Audio-Streams automatisch wiederzugeben."/>
<check_box name="FSFadeAudioStream" tool_tip="Aktiviert Fading, wenn sich der Parzellen-Audiostream ändert" label="Parzellen-Audiostream-Fading aktivieren:"/>
<check_box name="FSFadeAudioStream" tool_tip="Aktiviert Fading, wenn sich der Parzellen-Audiostream ändert" label="Parzellen-Audiostream-Fading aktivieren:"/>
<slider label="Einblenden:" width="270" label_width="70" name="FSAudioMusicFadeIn" tool_tip="Einblenddauer für Parzellen-Audiostream."/>
<text left_delta="275" name="FSAudioMusicFadeInSeconds">
Sekunden
@ -105,8 +105,8 @@
<radio_item label="Toasts" name="radio_toasts"/>
<radio_item label="Chat in der Nähe" name="radio_chat"/>
</radio_group>
<check_box name="StreamMetadataAnnounceToChat" label="Stream-Titel an diesen Kanal senden:" width="230"/>
</panel>
<check_box name="StreamMetadataAnnounceToChat" label="Stream-Titel an diesen Kanal senden:" width="230"/>
</panel>
<!-- Voice -->
<panel label="Voice-Chat" name="Media Voice tab">
@ -116,6 +116,7 @@
<radio_group name="ear_location">
<radio_item label="Voice-Chat von Kameraposition aus hören" name="0"/>
<radio_item label="Voice-Chat von Avatarposition aus hören" name="1"/>
<radio_item label="Voice-Chat in der Nähe in gleicher Lautstärke hören (nur OpenSim)" name="2"/>
</radio_group>
<check_box label="Avatarlippen beim Sprechen bewegen" name="enable_lip_sync"/>
<check_box label="Zeige Voice-Indikator über Avataren" name="FSShowVoiceVisualizer" tool_tip="Wenn diese Option aktiviert ist, wird der Voice-Indikator (weißer Punkt) über Avataren angezeigt."/>
@ -153,7 +154,7 @@
</text>
</panel>
</panel>
<!-- UI Sounds 1 -->
<panel label="UI-Klänge 1" name="UI Sounds tab 1">
<text name="textFSExplanation_tab1">
@ -182,7 +183,7 @@ Der jeweilige Standardwert wird im Hovertip des UUID-Feldes angezeigt.
<check_box label="Abspielen" name="PlayModeUISndClick"/>
<text tool_tip="UUID des Klangs beim Loslassen eines Mausknopfs." name="textFSClickRelease">
Loslassen Mausknopf:
Loslassen Mausknopf:
</text>
<button label="V" name="Prev_UISndClickRelease" tool_tip="Vorschau zu diesem Klang."/>
<button label="S" name="Def_UISndClickRelease" tool_tip="Auf Standardwert zurücksetzen."/>
@ -217,7 +218,7 @@ Der jeweilige Standardwert wird im Hovertip des UUID-Feldes angezeigt.
<check_box label="Abspielen" name="PlayModeUISndMoneyChangeUp"/>
<text tool_tip="UUID des Klangs bei eingehenden Instant Messages. Diese Einstellung ist gekoppelt mit Chat &gt; Benachrichtigungen &gt; 'Beim Eintreffen von Instant Messages:'." name="textFSNewIncomingIMSession">
Eingeh. Instant Messages:
Eingeh. Instant Messages:
</text>
<button label="V" name="Prev_UISndNewIncomingIMSession" tool_tip="Vorschau zu diesem Klang."/>
<button label="S" name="Def_UISndNewIncomingIMSession" tool_tip="Auf Standardwert zurücksetzen."/>
@ -229,7 +230,7 @@ Der jeweilige Standardwert wird im Hovertip des UUID-Feldes angezeigt.
</combo_box>
<text tool_tip="UUID des Klangs bei eingehenden Gruppenchats. Diese Einstellung ist gekoppelt mit Chat &gt; Benachrichtigungen &gt; 'Beim Eintreffen von Gruppenchats:'." name="textFSNewGroupIncomingIMSession">
Eingeh. Gruppenchats:
Eingeh. Gruppenchats:
</text>
<button label="V" name="Prev_UISndNewIncomingGroupIMSession" tool_tip="Vorschau zu diesem Klang."/>
<button label="S" name="Def_UISndNewIncomingGroupIMSession" tool_tip="Auf Standardwert zurücksetzen."/>
@ -274,7 +275,7 @@ Der jeweilige Standardwert wird im Hovertip des UUID-Feldes angezeigt.
<check_box label="Abspielen" name="PlayModeUISndObjectDelete"/>
<text tool_tip="UUID des Klangs beim Rezzen eines Objektes." name="textFSObjectRezIn">
Objekt rezzen:
Objekt rezzen:
</text>
<button label="V" name="Prev_UISndObjectRezIn" tool_tip="Vorschau zu diesem Klang."/>
<button label="S" name="Def_UISndObjectRezIn" tool_tip="Auf Standardwert zurücksetzen."/>
@ -288,7 +289,7 @@ Der jeweilige Standardwert wird im Hovertip des UUID-Feldes angezeigt.
<check_box label="Abspielen" name="PlayModeUISndObjectRezOut"/>
<text tool_tip="UUID des Klangs beim Erzeugen eines Fotos. Diese Einstellung ist gekoppelt an die Option 'Fotos leise speichern' im 'Erweitert'-Menü." name="textFSSnapshot">
Erstellen Schnappschuß:
Erstellen Schnappschuß:
</text>
<button label="V" name="Prev_UISndSnapshot" tool_tip="Vorschau zu diesem Klang."/>
<button label="S" name="Def_UISndSnapshot" tool_tip="Auf Standardwert zurücksetzen."/>
@ -311,14 +312,14 @@ Der jeweilige Standardwert wird im Hovertip des UUID-Feldes angezeigt.
</text>
<text tool_tip="UUID des Klangs beim Öffnen des Pie-Menüs." name="textFSPieMenuAppear">
Öffnen Pie-Menü:
Öffnen Pie-Menü:
</text>
<button label="V" name="Prev_UISndPieMenuAppear" tool_tip="Vorschau zu diesem Klang."/>
<button label="S" name="Def_UISndPieMenuAppear" tool_tip="Auf Standardwert zurücksetzen."/>
<check_box label="Abspielen" name="PlayModeUISndPieMenuAppear"/>
<text tool_tip="UUID des Klangs beim Schließen des Pie-Menüs." name="textFSPieMenuHide">
Schließen Pie-Menü:
Schließen Pie-Menü:
</text>
<button label="V" name="Prev_UISndPieMenuHide" tool_tip="Vorschau zu diesem Klang."/>
<button label="S" name="Def_UISndPieMenuHide" tool_tip="Auf Standardwert zurücksetzen."/>
@ -435,7 +436,7 @@ Der jeweilige Standardwert wird im Hovertip des UUID-Feldes angezeigt.
<button label="V" name="Prev_UISndTeleportOffer" tool_tip="Vorschau zu diesem Klang."/>
<button label="S" name="Def_UISndTeleportOffer" tool_tip="Auf Standardwert zurücksetzen."/>
<check_box label="Abspielen" name="PlayModeUISndTeleportOffer"/>
</panel>
</panel>
<!-- UI Sounds 3 -->
<panel label="UI-Klänge 3" name="UI Sounds tab 3">
@ -520,7 +521,6 @@ Der jeweilige Standardwert wird im Hovertip des UUID-Feldes angezeigt.
<button label="V" name="Prev_UISndRestartOpenSim" tool_tip="Vorschau zu diesem Klang."/>
<button label="S" name="Def_UISndRestartOpenSim" tool_tip="Auf Standardwert zurücksetzen."/>
<check_box label="Abspielen" name="PlayModeUISndRestartOpenSim"/>
</panel>
</panel>
</tab_container>
</panel>

View File

@ -1448,6 +1448,12 @@ https://www.firestormviewer.org/support für Hilfe zum Lösen des Problems.
<string name="csv_files">
Komma-separierte Werte
</string>
<string name="jpeg_image_files">
JPEG-Bilder
</string>
<string name="executable_files">
Ausführbare Programmdateien
</string>
<string name="recompile_script_verb">
Rekompilieren
</string>

View File

@ -939,7 +939,7 @@
layout="topleft"
left="25"
width="400"
height="40"
height="60"
top_pad="0"
name="ear_location">
<radio_item
@ -949,7 +949,7 @@
layout="topleft"
name="0"
width="150"/>
<radio_item
<radio_item
height="19"
follows="left|top"
label="Hear Voice from Avatar position"
@ -957,6 +957,15 @@
name="1"
top_pad="-2"
width="150" />
<radio_item
enabled="false"
height="19"
follows="left|top"
label="Hear Nearby Voices at full volume (Open Sim Only)"
layout="topleft"
name="2"
top_pad="-2"
width="150" />
</radio_group>
<check_box

View File

@ -655,6 +655,10 @@ https://www.firestormviewer.org/support for help fixing this problem.
<string name="csv_files">Comma separated values</string>
<string name="recompile_script_verb">Recompile</string>
<!-- FS:Zi: add missing file picker translations -->
<string name="jpeg_image_files">JPEG Images</string>
<string name="executable_files">Executable Program Files</string>
<!-- LSL Usage Hover Tips -->
<string name="LSLTipSleepTime" translate="false">Sleeps script for [SLEEP_TIME] seconds.</string>
<!-- (FS:CR) LSL Hover Tips have been moved into scriptlibrary_*.xml so they can be dynamically updated -->

View File

@ -107,6 +107,7 @@
<radio_group name="ear_location">
<radio_item label="Odtwarzaj głos z pozycji kamery" name="0"/>
<radio_item label="Odtwarzaj głos z pozycji mojego awatara" name="1"/>
<radio_item label="Odtwarzaj głos z pełną głośnością (tylko OpenSim)" name="2" />
</radio_group>
<check_box label="Poruszaj ustami awatara podczas mówienia" name="enable_lip_sync"/>
<check_box label="Pokazuj wskaźniki dźwięku ponad awatarami" tool_tip="Pokazuj wskaźniki dźwięku (białe kropki) ponad awatarami" name="FSShowVoiceVisualizer"/>

View File

@ -1365,6 +1365,12 @@ https://www.firestormviewer.org/support aby uzyskać pomoc.
<string name="recompile_script_verb">
Rekompiluj
</string>
<string name="jpeg_image_files">
Obrazy JPEG
</string>
<string name="executable_files">
Pliki wykonywalne
</string>
<string name="shape">
Kształt
</string>

View File

@ -102,6 +102,7 @@
<radio_group name="ear_location">
<radio_item label="Слышать голос из положения камеры" name="0"/>
<radio_item label="Слышать голос из положения аватара" name="1"/>
<radio_item label="Слышать все голоса громко (только Open Sim)" name="2"/>
</radio_group>
<check_box label="Двигать губами аватара во время разговора" name="enable_lip_sync"/>
<check_box label="Показать голосовой индикатор над аватарами" tool_tip="Показывает голосовой индикатор (белую точку) над аватарами" name="FSShowVoiceVisualizer"/>

View File

@ -1421,6 +1421,12 @@ https://www.firestormviewer.org/support за помощь в решении эт
<string name="recompile_script_verb">
Перекомпиляция
</string>
<string name="jpeg_image_files">
Изображения в формате JPEG
</string>
<string name="executable_files">
Исполняемые файлы программы
</string>
<string name="LSLTipSleepTime">
Пауза скрипта на [SLEEP_TIME] секунд.
</string>

View File

@ -1797,8 +1797,15 @@ class LinuxManifest(ViewerManifest):
build_data_json_platform = 'lnx'
def construct(self):
# <FS:ND> HACK! Force parent to always copy XML/... even when not having configured with --package.
# This allows build result to be started without always having to --package and thus waiting for the length tar ball generation --package incurs
savedActions = self.args['actions']
self.args["actions"].append("package")
super(LinuxManifest, self).construct()
self.args["actions"] = savedActions # Restore old actions
pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
relpkgdir = os.path.join(pkgdir, "lib", "release")
debpkgdir = os.path.join(pkgdir, "lib", "debug")
@ -1875,11 +1882,9 @@ class LinuxManifest(ViewerManifest):
with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="bin"):
self.path( "chrome-sandbox" )
self.path( "dullahan_host" )
self.fs_try_path( "natives_blob.bin" )
self.path( "snapshot_blob.bin" )
self.path( "v8_context_snapshot.bin" )
with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="lib"):
self.fs_try_path( "natives_blob.bin" )
self.path( "snapshot_blob.bin" )
self.path( "v8_context_snapshot.bin" )
@ -1958,8 +1963,7 @@ class LinuxManifest(ViewerManifest):
with self.prefix(src=pkgdir, dst="bin"):
self.path("ca-bundle.crt")
if self.is_packaging_viewer():
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path("libapr-1.so*")
self.path("libaprutil-1.so*")
#self.path("libboost_context-mt.so*")
@ -2011,24 +2015,24 @@ class LinuxManifest(ViewerManifest):
# particular wildcard specification gets us exactly what the
# previous call did, without having to explicitly state the
# version number.
self.path("libfontconfig.so.*.*")
#self.path("libfontconfig.so.*.*")
self.fs_try_path("libjemalloc.so*")
# Vivox runtimes
# Currentelly, the 32-bit ones will work with a 64-bit client.
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="bin"):
self.path("SLVoice")
self.path("win32")
self.path("win64")
# Vivox runtimes
# Currentelly, the 32-bit ones will work with a 64-bit client.
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="bin"):
self.path("SLVoice")
self.path("win32")
self.path("win64")
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path("libortp.so")
self.path("libsndfile.so.1")
# <FS:TS> Vivox wants this library even if it's present already in the viewer
self.path("libvivoxoal.so.1")
self.path("libvivoxsdk.so")
self.path("libvivoxplatform.so")
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path("libortp.so")
self.path("libsndfile.so.1")
# <FS:TS> Vivox wants this library even if it's present already in the viewer
self.path("libvivoxoal.so.1")
self.path("libvivoxsdk.so")
self.path("libvivoxplatform.so")
def package_finish(self):
@ -2054,6 +2058,7 @@ class LinuxManifest(ViewerManifest):
# name in the tarfile
realname = self.get_dst_prefix()
tempname = self.build_path_of(installer_name)
self.run_command([self.args["source"] + "/installers/linux/appimage.sh", self.args["build"]] )
self.run_command(["mv", realname, tempname])
try:
# only create tarball if it's a release build.
@ -2179,8 +2184,7 @@ class Linux_x86_64_Manifest(LinuxManifest):
relpkgdir = os.path.join(pkgdir, "lib", "release")
debpkgdir = os.path.join(pkgdir, "lib", "debug")
if self.is_packaging_viewer():
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
#self.path("libffi*.so*")
# vivox 32-bit hack.
# one has to extract libopenal.so from the 32-bit openal package, or official LL viewer, and rename it to libopenal32.so