diff options
Diffstat (limited to 'indra/newview')
73 files changed, 1138 insertions, 1495 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1821e12e09..226c905463 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1473,7 +1473,6 @@ if (USESYSTEMLIBS AND NOT DARWIN)        PROPERTIES        COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"        ) -    #LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)      if (NOT (CMAKE_CXX_COMPILER_ID MATCHES "AppleClang"))      SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")      endif () @@ -2495,4 +2494,3 @@ if (LL_TESTS)  endif (LL_TESTS)  check_message_template(${VIEWER_BINARY_NAME}) - diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 2fe040f424..5978ab1324 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -7.1.8 +7.1.9 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index bf0abee385..ad8299d785 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4920,6 +4920,17 @@      <key>Value</key>      <integer>0</integer>    </map> +  <key>MediaPluginPipeWireVolumeCatcher</key> +  <map> +    <key>Comment</key> +    <string>Use PipeWire instead of PulseAudio for controlling web media volume.</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map>    <key>MediaControlFadeTime</key>    <map>      <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl index 178510f483..a33c4cc58b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl @@ -25,13 +25,13 @@  // debug stub -float random (vec2 uv) +float random (vec2 uv)   { -    return 0.0; +    return 0.;  }  float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness)  {      collectedColor = vec4(0); -    return 0.0; +    return 0.;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 210ecce8db..e9f849a8c0 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -79,7 +79,7 @@ float getAmbientClamp();  void mirrorClip(vec3 pos); -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);  vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance) diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl index d178bf22b6..35848ff4cd 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl @@ -37,7 +37,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear)  {      ambenv = vec3(reflection_probe_ambiance * 0.25); - +          vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));      vec3 env_vec = env_mat * refnormpersp;      glossenv = srgb_to_linear(texture(environmentMap, env_vec).rgb); @@ -55,11 +55,11 @@ vec4 sampleReflectionProbesDebug(vec3 pos)      return vec4(0, 0, 0, 0);  } -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear)  {      ambenv = vec3(reflection_probe_ambiance * 0.25); - +          vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));      vec3 env_vec = env_mat * refnormpersp; @@ -70,7 +70,7 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout  void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)  { - +      }  void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity) diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl index 03dc3d7113..5e38864d38 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl @@ -48,7 +48,7 @@ vec3 linear_to_srgb(vec3 c);  vec3 srgb_to_linear(vec3 c);  // reflection probe interface -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);  void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index d3e19cf4a8..28b1b5f5e6 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -60,7 +60,7 @@ out vec4 frag_color;  float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);  #endif -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);  void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);  void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); @@ -281,10 +281,10 @@ float getShadow(vec3 pos, vec3 norm)      #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)          return sampleDirectionalShadow(pos, norm, vary_texcoord0.xy);      #else -        return 1; +        return 1.;      #endif  #else -    return 1; +    return 1.;  #endif  } diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 90c84cc428..47ec8fba55 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -453,7 +453,7 @@ void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)  void boxIntersectDebug(vec3 origin, vec3 pos, mat4 i, inout vec4 col)  {      mat4 clipToLocal = i; -     +      // transform into unit cube space      origin = (clipToLocal * vec4(origin, 1.0)).xyz;      pos = (clipToLocal * vec4(pos, 1.0)).xyz; @@ -837,7 +837,7 @@ vec4 sampleReflectionProbesDebug(vec3 pos)      return col;  } -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit)  {      float reflection_lods = max_probe_lod; diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 96c32734e4..494a69efd0 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -71,7 +71,7 @@ vec3  scaleSoftClipFragLinear(vec3 l);  // reflection probe interface  void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,      vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear); -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);  void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);  void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); @@ -169,7 +169,7 @@ void main()      if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))      { -        vec3 orm = spec.rgb;  +        vec3 orm = spec.rgb;          float perceptualRoughness = orm.g;          float metallic = orm.b;          float ao = orm.r; diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index eb3ead433b..a027aaf6d1 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -58,21 +58,14 @@ fi  ## - Avoids an often-buggy X feature that doesn't really benefit us anyway.  export SDL_VIDEO_X11_DGAMOUSE=0 -## - Works around a problem with misconfigured 64-bit systems not finding GL -I386_MULTIARCH="$(dpkg-architecture -ai386 -qDEB_HOST_MULTIARCH 2>/dev/null)" -MULTIARCH_ERR=$? -if [ $MULTIARCH_ERR -eq 0 ]; then -    echo 'Multi-arch support detected.' -    MULTIARCH_GL_DRIVERS="/usr/lib/${I386_MULTIARCH}/dri" -    export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:${MULTIARCH_GL_DRIVERS}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri" -else -    export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri" -fi -  ## - The 'scim' GTK IM module widely crashes the viewer.  Avoid it.  if [ "$GTK_IM_MODULE" = "scim" ]; then      export GTK_IM_MODULE=xim  fi +if [ "$XMODIFIERS" = "" ]; then +    ## IME is valid only for fcitx, not when using ibus +    export XMODIFIERS="@im=fcitx" +fi  ## - Automatically work around the ATI mouse cursor crash bug:  ## (this workaround is disabled as most fglrx users do not see the bug) @@ -98,25 +91,6 @@ cd "${RUN_PATH}"  ## Before we mess with LD_LIBRARY_PATH, save the old one to restore for  ##  subprocesses that care.  export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" - -# if [ -n "$LL_TCMALLOC" ]; then -#    tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0' -#    all=1 -#    for f in $tcmalloc_libs; do -#        if [ ! -f $f ]; then -#	    all=0 -#	fi -#    done -#    if [ $all != 1 ]; then -#        echo 'Cannot use tcmalloc libraries: components missing' 1>&2 -#    else -#	export LD_PRELOAD=$(echo $tcmalloc_libs | tr ' ' :) -#	if [ -z "$HEAPCHECK" -a -z "$HEAPPROFILE" ]; then -#	    export HEAPCHECK=${HEAPCHECK:-normal} -#	fi -#    fi -#fi -  export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"  # Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch. @@ -140,18 +114,6 @@ LL_RUN_ERR=$?  if [ $LL_RUN_ERR -ne 0 ]; then  	# generic error running the binary  	echo '*** Bad shutdown ($LL_RUN_ERR). ***' -	if [ "$(uname -m)" = "x86_64" ]; then -		echo -		cat << EOFMARKER -You are running the Second Life Viewer on a x86_64 platform.  The -most common problems when launching the Viewer (particularly -'bin/do-not-directly-run-secondlife-bin: not found' and 'error while -loading shared libraries') may be solved by installing your Linux -distribution's 32-bit compatibility packages. -For example, on Ubuntu and other Debian-based Linuxes you might run: -$ sudo apt-get install ia32-libs ia32-libs-gtk ia32-libs-kde ia32-libs-sdl -EOFMARKER -	fi  fi  echo diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 76271571cd..b2ce4d56dd 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -1385,8 +1385,6 @@ void AISUpdate::parseCategory(const LLSD& category_map, S32 depth)                       && curr_cat->getVersion() > LLViewerInventoryCategory::VERSION_UNKNOWN                       && version > curr_cat->getVersion())              { -                // Potentially should new_cat->setVersion(unknown) here, -                // but might be waiting for a callback that would increment                  LL_DEBUGS("Inventory") << "Category " << category_id                      << " is stale. Known version: " << curr_cat->getVersion()                      << " server version: " << version << LL_ENDL; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 86da40fcf5..975935ee6f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -272,10 +272,6 @@ using namespace LL;  // define a self-registering event API object  #include "llappviewerlistener.h" -#if (LL_LINUX || __FreeBSD__) && LL_GTK -#include "glib.h" -#endif // (LL_LINUX) && LL_GTK -  #if LL_MSVC  // disable boost::lexical_cast warning  #pragma warning (disable:4702) @@ -1142,7 +1138,7 @@ bool LLAppViewer::init()      gGLActive = FALSE; -#if 0 // LL_RELEASE_FOR_DOWNLOAD +#if 0 // LL_RELEASE_FOR_DOWNLOAD && !LL_LINUX      // Skip updater if this is a non-interactive instance      if (!gSavedSettings.getBOOL("CmdLineSkipUpdater") && !gNonInteractive)      { @@ -2395,6 +2391,14 @@ void LLAppViewer::initLoggingAndGetLastDuration()          {              LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;          } + +        std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.log"); +        if (gDirUtilp->fileExists(user_data_path_cef_log)) +        { +            std::string user_data_path_cef_old = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.old"); +            LLFile::remove(user_data_path_cef_old, ENOENT); +            LLFile::rename(user_data_path_cef_log, user_data_path_cef_old); +        }      }  } @@ -3035,9 +3039,10 @@ void LLAppViewer::initStrings()      std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);      if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))      { +        std::string crash_reason;          if (strings_path_full.empty())          { -            LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL; +            crash_reason = "The file '" + strings_file + "' is not found";          }          else          { @@ -3045,24 +3050,23 @@ void LLAppViewer::initStrings()              int rc = LLFile::stat(strings_path_full, &st);              if (rc != 0)              { -                LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL; +                crash_reason = "The file '" + strings_path_full + "' failed to get status. Error code: " + std::to_string(rc);              }              else if (S_ISDIR(st.st_mode))              { -                LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL; +                crash_reason = "The filename '" + strings_path_full + "' is a directory name";              }              else              { -                LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL; +                crash_reason = "The filename '" + strings_path_full + "' doesn't seem to be a regular file name";              }          }          // initial check to make sure files are there failed          gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);          LLError::LLUserWarningMsg::showMissingFiles(); -        LL_ERRS() << "Viewer failed to find localization and UI files." -            << " Please reinstall viewer from https://secondlife.com/support/downloads" -            << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; +        LL_ERRS() << "Viewer failed to open some of localization and UI files." +            << " " << crash_reason << "." << LL_ENDL;      }      LLTransUtil::parseStrings(strings_file, default_trans_args);      LLTransUtil::parseLanguageStrings("language_settings.xml"); @@ -5736,4 +5740,3 @@ void LLAppViewer::metricsSend(bool enable_reporting)      // resolution in time.      gViewerAssetStats->restart();  } - diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index a0aa567742..c1e8f38c51 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -40,15 +40,60 @@  #include <exception> -#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" +#if LL_GLIB +#include <gio/gio.h> +#endif +#include <netinet/in.h> +#include <resolv.h> + +#if (__GLIBC__*1000 + __GLIBC_MINOR__) >= 2034 +extern "C" +{ +  int __res_nquery(res_state statep, +                   const char *dname, int qclass, int type, +                   unsigned char *answer, int anslen) +  { +    return res_nquery( statep, dname, qclass, type, answer, anslen ); +  } + +  int __dn_expand(const unsigned char *msg, +                  const unsigned char *eomorig, +                  const unsigned char *comp_dn, char *exp_dn, +                  int length) +  { +    return dn_expand( msg,eomorig,comp_dn,exp_dn,length); +  } +} +#endif + +#if LL_SEND_CRASH_REPORTS +#include "breakpad/client/linux/handler/exception_handler.h" +#include "breakpad/common/linux/http_upload.h" +#include "lldir.h" +#include "../llcrashlogger/llcrashlogger.h" +#include "jsoncpp/reader.h" // JSON + +#endif + +#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService" +#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI" +#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI" + +#if LL_GLIB +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;  #endif  namespace @@ -81,6 +126,8 @@ int main( int argc, char **argv )      // install unexpected exception handler      gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); +    unsetenv( "LD_PRELOAD" ); // <FS:ND/> Get rid of any preloading, we do not want this to happen during startup of plugins. +      bool ok = viewer_app_ptr->init();      if(!ok)      { @@ -114,23 +161,74 @@ LLAppViewerLinux::~LLAppViewerLinux()  {  } -bool LLAppViewerLinux::init() +#if LL_SEND_CRASH_REPORTS +std::string gCrashLogger; +std::string gVersion; +std::string gBugsplatDB; +std::string gCrashBehavior; + +static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) +{ +    if( fork() == 0 ) +        execl( gCrashLogger.c_str(), gCrashLogger.c_str(), descriptor.path(), gVersion.c_str(), gBugsplatDB.c_str(),  gCrashBehavior.c_str(), nullptr ); +    return succeeded; +} + +void setupBreadpad()  { -    // g_thread_init() must be called before *any* use of glib, *and* -    // before any mutexes are held, *and* some of our third-party -    // libraries likes to use glib functions; in short, do this here -    // really early in app startup! -#ifndef LL_USESYSTEMLIBS -    if (!g_thread_supported ()) g_thread_init (NULL); +    std::string build_data_fname(gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json")); +    gCrashLogger =  gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "linux-crash-logger.bin"); + +    llifstream inf(build_data_fname.c_str()); +    if(!inf.is_open()) +    { +        LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname << "'" << LL_ENDL; +        return; +    } + +    Json::Reader reader; +    Json::Value build_data; +    if(!reader.parse(inf, build_data, false)) +    { +        LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname << "': " +                             << reader.getFormatedErrorMessages() << LL_ENDL; +        return; +    } + +    Json::Value BugSplat_DB = build_data["BugSplat DB"]; +    if(!BugSplat_DB) +    { +        LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '" << build_data_fname +                             << "'" << LL_ENDL; +        return; +    } +    gVersion = STRINGIZE( +            LL_VIEWER_VERSION_MAJOR << '.' << LL_VIEWER_VERSION_MINOR << '.' << LL_VIEWER_VERSION_PATCH +                                    << '.' << LL_VIEWER_VERSION_BUILD); +    gBugsplatDB = BugSplat_DB.asString(); + +    LL_INFOS("BUGSPLAT") << "Initializing with crash logger: " << gCrashLogger << " database: " << gBugsplatDB << " version: " << gVersion << LL_ENDL; + +    google_breakpad::MinidumpDescriptor *descriptor = new google_breakpad::MinidumpDescriptor(gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "")); +    google_breakpad::ExceptionHandler *eh = new google_breakpad::ExceptionHandler(*descriptor, NULL, dumpCallback, NULL, true, -1); +}  #endif +bool LLAppViewerLinux::init() +{      bool success = LLAppViewer::init();  #if LL_SEND_CRASH_REPORTS -    if (success) +    S32 nCrashSubmitBehavior = gCrashSettings.getS32("CrashSubmitBehavior"); + +    // For the first version we just consider always send and create a nice dialog for CRASH_BEHAVIOR_ASK later. +    if (success && nCrashSubmitBehavior != CRASH_BEHAVIOR_NEVER_SEND )      { -        LLAppViewer* pApp = LLAppViewer::instance(); -        pApp->initCrashReporting(); +        if( nCrashSubmitBehavior == CRASH_BEHAVIOR_ASK ) +            gCrashBehavior = "ask"; +        else +            gCrashBehavior = "send"; +        setupBreadpad();      }  #endif @@ -145,7 +243,7 @@ bool LLAppViewerLinux::restoreErrorTrap()  }  ///////////////////////////////////////// -#if LL_DBUS_ENABLED +#if LL_GLIB  typedef struct  { @@ -155,101 +253,77 @@ typedef struct  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) -  G_DEFINE_TYPE(ViewerAppAPI, viewerappapi, G_TYPE_OBJECT);  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. - -    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); +    LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL; -            lldbus_g_connection_register_g_object(server->connection, VIEWERAPI_PATH, G_OBJECT(server)); +    std::string url = slurl; +    LLMediaCtrl* web = NULL; +    const bool trusted_browser = false; +    LLURLDispatcher::dispatch(url, "", web, trusted_browser); +} -            DBusGProxy *serverproxy = lldbus_g_proxy_new_for_name(server->connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); +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) +{ +    LL_INFOS() << "DBUS message " << method_name << "  from: " << sender << " interface: " << interface_name << LL_ENDL; +    const gchar *slurl; -            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_variant_get (parameters, "(&s)", &slurl); +    dispatchSLURL(slurl); +} -            g_object_unref(serverproxy); -        } -        else +GDBusNodeInfo *gBusNodeInfo = nullptr; +static const GDBusInterfaceVTable interface_vtable =          { -            g_warning("Unable to connect to dbus: %s", error->message); -        } - -        if (error) -            g_error_free(error); -    } +                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);  } -gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error) +static void nameAcquired(GDBusConnection *connection, const gchar *name, gpointer user_data)  { -    bool success = false; - -    LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL; +} -    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; -    } +static void nameLost(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ -    *success_rtn = g_new (gboolean, 1); -    (*success_rtn)[0] = (gboolean)success; +} +void viewerappapi_init(ViewerAppAPI *server) +{ +    gBusNodeInfo = g_dbus_node_info_new_for_xml (DBUS_SERVER, NULL); +    g_assert (gBusNodeInfo != NULL); + +    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.  }  /// @@ -257,13 +331,6 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ  //virtual  bool LLAppViewerLinux::initSLURLHandler()  { -    if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME)) -    { -        return false; // failed -    } - -    g_type_init(); -      //ViewerAppAPI *api_server = (ViewerAppAPI*)      g_object_new(viewerappapi_get_type(), NULL); @@ -273,49 +340,49 @@ bool LLAppViewerLinux::initSLURLHandler()  //virtual  bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url)  { -    if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME)) +    auto *pBus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, nullptr); + +    if( !pBus )      { -        return false; // failed +        LL_WARNS() << "Getting dbus failed." << LL_ENDL; +        return false;      } -    bool success = false; -    DBusGConnection *bus; -    GError *error = NULL; - -    g_type_init(); +    auto pProxy = g_dbus_proxy_new_sync(pBus, G_DBUS_PROXY_FLAGS_NONE, nullptr, +                                        VIEWERAPI_SERVICE, VIEWERAPI_PATH, +                                        VIEWERAPI_INTERFACE, nullptr, nullptr); -    bus = lldbus_g_bus_get (DBUS_BUS_SESSION, &error); -    if (bus) +    if( !pProxy )      { -        gboolean rtn = FALSE; -        DBusGProxy *remote_object = -            lldbus_g_proxy_new_for_name(bus, VIEWERAPI_SERVICE, VIEWERAPI_PATH, VIEWERAPI_INTERFACE); - -        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; -        } - -        g_object_unref(G_OBJECT(remote_object)); +        LL_WARNS() << "Cannot create new dbus proxy." << LL_ENDL; +        g_object_unref( pBus ); +        return false;      } -    else + +    auto *pArgs = g_variant_new( "(s)", url.c_str() ); +    if( !pArgs )      { -        LL_WARNS() << "Couldn't connect to session bus: " << error->message << LL_ENDL; +        LL_WARNS() << "Cannot create new variant." << LL_ENDL; +        g_object_unref( pBus ); +        return false;      } -    if (error) -        g_error_free(error); +    auto pRes  = g_dbus_proxy_call_sync(pProxy, +                                        "GoSLURL", +                                        pArgs, +                                        G_DBUS_CALL_FLAGS_NONE, +                                        -1, nullptr, nullptr); -    return success; + + +    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 @@ -324,7 +391,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)  { @@ -342,15 +409,18 @@ void LLAppViewerLinux::initCrashReporting(bool reportFreeze)      pid_str <<  LLApp::getPid();      std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");      std::string appname = gDirUtilp->getExecutableFilename(); +    std::string grid{ LLGridManager::getInstance()->getGridId() }; +    std::string title{ LLAppViewer::instance()->getSecondLifeTitle() }; +    std::string pidstr{ pid_str.str() };      // launch the actual crash logger      const char * cmdargv[] =          {cmd.c_str(),           "-user", -         (char*)LLGridManager::getInstance()->getGridId().c_str(), +         grid.c_str(),           "-name", -         LLAppViewer::instance()->getSecondLifeTitle().c_str(), +         title.c_str(),           "-pid", -         pid_str.str().c_str(), +         pidstr.c_str(),           "-dumpdir",           logdir.c_str(),           "-procname", diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index 9524432b26..460ca721f1 100644 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -27,19 +27,6 @@  #ifndef LL_LLAPPVIEWERLINUX_H  #define LL_LLAPPVIEWERLINUX_H -#if LL_GTK -extern "C" { -# include <glib.h> -} -#endif - -#if LL_DBUS_ENABLED -extern "C" { -# include <glib-object.h> -# include <dbus/dbus-glib.h> -} -#endif -  #ifndef LL_LLAPPVIEWER_H  #include "llappviewer.h"  #endif @@ -72,21 +59,4 @@ protected:      virtual bool sendURLToOtherInstance(const std::string& url);  }; -#if LL_DBUS_ENABLED -typedef struct -{ -        GObject parent; -        DBusGConnection *connection; -} ViewerAppAPI; - -extern "C" { -    gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error); -} - -#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 diff --git a/indra/newview/llappviewerlinux_api.h b/indra/newview/llappviewerlinux_api.h deleted file mode 100644 index 3d1324dd19..0000000000 --- a/indra/newview/llappviewerlinux_api.h +++ /dev/null @@ -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" -}; - diff --git a/indra/newview/llappviewerlinux_api.xml b/indra/newview/llappviewerlinux_api.xml deleted file mode 100644 index fac35b7adc..0000000000 --- a/indra/newview/llappviewerlinux_api.xml +++ /dev/null @@ -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> diff --git a/indra/newview/llappviewerlinux_api_dbus.cpp b/indra/newview/llappviewerlinux_api_dbus.cpp deleted file mode 100644 index be769356c3..0000000000 --- a/indra/newview/llappviewerlinux_api_dbus.cpp +++ /dev/null @@ -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 diff --git a/indra/newview/llappviewerlinux_api_dbus.h b/indra/newview/llappviewerlinux_api_dbus.h deleted file mode 100644 index 2f4492bd7a..0000000000 --- a/indra/newview/llappviewerlinux_api_dbus.h +++ /dev/null @@ -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 diff --git a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc b/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc deleted file mode 100644 index c0548e2fba..0000000000 --- a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc +++ /dev/null @@ -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 diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 4c90a82fcb..a13e4de308 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -400,17 +400,10 @@ void ll_nvapi_init(NvDRSSessionHandle hSession)      }  } -//#define DEBUGGING_SEH_FILTER 1 -#if DEBUGGING_SEH_FILTER -#   define WINMAIN DebuggingWinMain -#else -#   define WINMAIN wWinMain -#endif - -int APIENTRY WINMAIN(HINSTANCE hInstance, -                     HINSTANCE hPrevInstance, -                     PWSTR     pCmdLine, -                     int       nCmdShow) +int APIENTRY wWinMain(HINSTANCE hInstance, +                      HINSTANCE hPrevInstance, +                      PWSTR     pCmdLine, +                      int       nCmdShow)  {      // Call Tracy first thing to have it allocate memory      // https://github.com/wolfpld/tracy/issues/196 @@ -559,27 +552,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,      return 0;  } -#if DEBUGGING_SEH_FILTER -// The compiler doesn't like it when you use __try/__except blocks -// in a method that uses object destructors. Go figure. -// This winmain just calls the real winmain inside __try. -// The __except calls our exception filter function. For debugging purposes. -int APIENTRY wWinMain(HINSTANCE hInstance, -                     HINSTANCE hPrevInstance, -                     PWSTR     lpCmdLine, -                     int       nCmdShow) -{ -    __try -    { -        WINMAIN(hInstance, hPrevInstance, lpCmdLine, nCmdShow); -    } -    __except( viewer_windows_exception_handler( GetExceptionInformation() ) ) -    { -        _tprintf( _T("Exception handled.\n") ); -    } -} -#endif -  void LLAppViewerWin32::disableWinErrorReporting()  {      std::string executable_name = gDirUtilp->getExecutableFilename(); diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp index 70827ae723..838062795b 100644 --- a/indra/newview/llconversationloglist.cpp +++ b/indra/newview/llconversationloglist.cpp @@ -95,6 +95,7 @@ BOOL LLConversationLogList::handleRightMouseDown(S32 x, S32 y, MASK mask)          context_menu->buildDrawLabels();          if (context_menu && size())              context_menu->updateParent(LLMenuGL::sMenuContainer); +          LLMenuGL::showPopup(this, context_menu, x, y);      } diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index 8c2181292f..a228cd7159 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -41,6 +41,10 @@  # include "llfilepicker.h"  #endif +#ifdef LL_FLTK +  #include "FL/Fl.H" +  #include "FL/Fl_Native_File_Chooser.H" +#endif  //  // Globals  // @@ -193,20 +197,28 @@ LLDirPicker::LLDirPicker() :      mFileName(NULL),      mLocked(false)  { +#ifndef LL_FLTK      mFilePicker = new LLFilePicker(); +#endif      reset();  }  LLDirPicker::~LLDirPicker()  { +#ifndef LL_FLTK      delete mFilePicker; +#endif  }  void LLDirPicker::reset()  { +#ifndef LL_FLTK      if (mFilePicker)          mFilePicker->reset(); +#else +    mDir = ""; +#endif  }  BOOL LLDirPicker::getDir(std::string* filename, bool blocking) @@ -219,33 +231,38 @@ BOOL LLDirPicker::getDir(std::string* filename, bool blocking)          return FALSE;      } -#if !LL_MESA_HEADLESS - -    if (mFilePicker) +#ifdef LL_FLTK +    gViewerWindow->getWindow()->beforeDialog(); +    Fl_Native_File_Chooser flDlg; +    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 )      { -        GtkWindow* picker = mFilePicker->buildFilePicker(false, true, -                                 "dirpicker"); - -        if (picker) -        { -           gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("choose_the_directory").c_str()); -           gtk_widget_show_all(GTK_WIDGET(picker)); -           gtk_main(); -           return (!mFilePicker->getFirstFile().empty()); -        } +        char const *pDir = flDlg.filename(0); +        if( pDir ) +            mDir = pDir;      } -#endif // !LL_MESA_HEADLESS - -    return FALSE; +    else if( res == -1 ) +    { +        LL_WARNS() << "FLTK failed: " <<  flDlg.errmsg() << LL_ENDL; +    } +    return !mDir.empty(); +#endif  }  std::string LLDirPicker::getDirName()  { +#ifndef LL_FLTK      if (mFilePicker)      {          return mFilePicker->getFirstFile();      }      return ""; +#else +    return mDir; +#endif  }  #else // not implemented diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index 82adbcce11..fd56f37310 100644 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -80,8 +80,10 @@ private:  #if LL_LINUX || LL_DARWIN || __FreeBSD__      // On Linux we just implement LLDirPicker on top of LLFilePicker +#ifndef LL_FLTK      LLFilePicker *mFilePicker;  #endif +#endif      std::string* mFileName; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 849dbb28f4..e46043b77e 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -57,12 +57,6 @@  #include "llsculptidsize.h"  #include "llmeshrepository.h" -#if LL_LINUX -// Work-around spurious used before init warning on Vector4a -// -#pragma GCC diagnostic ignored "-Wuninitialized" -#endif -  #define LL_MAX_INDICES_COUNT 1000000  static LLStaticHashedString sTextureIndexIn("texture_index_in"); @@ -849,7 +843,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,          //VECTORIZE THIS          LLMatrix4a mat_vert;          mat_vert.loadu(mat_vert_in); -        //LLVector4a new_extents[2];          llassert(less_than_max_mag(face.mExtents[0]));          llassert(less_than_max_mag(face.mExtents[1])); diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 4bece9d4b4..5be48a3630 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -40,6 +40,7 @@  #include "llappviewer.h"  #include "llbufferstream.h" +#include "llexception.h"  #include "llnotificationsutil.h"  #include "llviewercontrol.h"  #include "llworld.h" @@ -377,33 +378,6 @@ bool LLFeatureManager::parseFeatureTable(std::string filename)  F32 gpu_benchmark(); -#if LL_WINDOWS - -F32 logExceptionBenchmark() -{ -    // FIXME: gpu_benchmark uses many C++ classes on the stack to control state. -    //  SEH exceptions with our current exception handling options do not call -    //  destructors for these classes, resulting in an undefined state should -    //  this handler be invoked. -    F32 gbps = -1; -    __try -    { -        gbps = gpu_benchmark(); -    } -    __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) -    { -        // HACK - ensure that profiling is disabled -        LLGLSLShader::finishProfile(false); - -        // convert to C++ styled exception -        char integer_string[32]; -        sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); -        throw std::exception(integer_string); -    } -    return gbps; -} -#endif -  bool LLFeatureManager::loadGPUClass()  {      if (!gSavedSettings.getBOOL("SkipBenchmark")) @@ -413,14 +387,12 @@ bool LLFeatureManager::loadGPUClass()          F32 gbps;          try          { -#if LL_WINDOWS -            gbps = logExceptionBenchmark(); -#else -            gbps = gpu_benchmark(); -#endif +            gbps = LL::seh::catcher(gpu_benchmark);          }          catch (const std::exception& e)          { +            // HACK - ensure that profiling is disabled +            LLGLSLShader::finishProfile(false);              gbps = -1.f;              LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL;          } diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index c871b4723a..7f0a8d3787 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -40,6 +40,11 @@  #include "llwindowsdl.h" // for some X/GTK utils to help with filepickers  #endif // LL_SDL +#ifdef LL_FLTK +  #include "FL/Fl.H" +  #include "FL/Fl_Native_File_Chooser.H" +#endif +  #if LL_LINUX || __FreeBSD__  #include "llhttpconstants.h"    // file picker uses some of thes constants on Linux  #endif @@ -670,6 +675,7 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF              break;          case FFLOAD_HDRI:              allowedv->push_back("exr"); +        case FFLOAD_MODEL:          case FFLOAD_COLLADA:              allowedv->push_back("dae");              break; @@ -1102,513 +1108,231 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,  #elif LL_LINUX || __FreeBSD__ -# if LL_GTK - -// static -void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data) -{ -    // We need to run g_filename_to_utf8 in the user's locale -    std::string saved_locale(setlocale(LC_ALL, NULL)); -    setlocale(LC_ALL, ""); - -    LLFilePicker* picker = (LLFilePicker*) user_data; -    GError *error = NULL; -    gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, -                          -1, NULL, NULL, &error); -    if (error) -    { -        // *FIXME. -        // This condition should really be notified to the user, e.g. -        // through a message box.  Just logging it is inappropriate. - -        // g_filename_display_name is ideal, but >= glib 2.6, so: -        // a hand-rolled hacky makeASCII which disallows control chars -        std::string display_name; -        for (const gchar *str = (const gchar *)data; *str; str++) -        { -            display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?'); -        } -        LL_WARNS() << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << LL_ENDL; -    } - -    if (filename_utf8) -    { -        picker->mFiles.push_back(std::string(filename_utf8)); -        LL_DEBUGS() << "ADDED FILE " << filename_utf8 << LL_ENDL; -        g_free(filename_utf8); -    } - -    setlocale(LC_ALL, saved_locale.c_str()); -} - -// static -void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer user_data) -{ -    LLFilePicker* picker = (LLFilePicker*)user_data; - -    LL_DEBUGS() << "GTK DIALOG RESPONSE " << response << LL_ENDL; - -    if (response == GTK_RESPONSE_ACCEPT) -    { -        GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget)); -        g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data); -        g_slist_foreach(file_list, (GFunc)g_free, NULL); -        g_slist_free (file_list); -    } - -    // let's save the extension of the last added file(considering current filter) -    GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget)); -    if(gfilter) -    { -        std::string filter = gtk_file_filter_get_name(gfilter); - -        if(filter == LLTrans::getString("png_image_files")) -        { -            picker->mCurrentExtension = ".png"; -        } -        else if(filter == LLTrans::getString("targa_image_files")) -        { -            picker->mCurrentExtension = ".tga"; -        } -    } - -    // set the default path for this usage context. -    const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); -    if (cur_folder != NULL) -    { -        picker->mContextToPathMap[picker->mCurContextName] = cur_folder; -    } - -    gtk_widget_destroy(widget); -    gtk_main_quit(); -} - - -GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context) -{ -#ifndef LL_MESA_HEADLESS -    if (LLWindowSDL::ll_try_gtk_init()) -    { -        GtkWidget *win = NULL; -        GtkFileChooserAction pickertype = -            is_save? -            (is_folder? -             GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER : -             GTK_FILE_CHOOSER_ACTION_SAVE) : -            (is_folder? -             GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : -             GTK_FILE_CHOOSER_ACTION_OPEN); - -        win = gtk_file_chooser_dialog_new(NULL, NULL, -                          pickertype, -                          GTK_STOCK_CANCEL, -                           GTK_RESPONSE_CANCEL, -                          is_folder ? -                          GTK_STOCK_APPLY : -                          (is_save ? -                           GTK_STOCK_SAVE : -                           GTK_STOCK_OPEN), -                           GTK_RESPONSE_ACCEPT, -                          (gchar *)NULL); -        mCurContextName = context; - -        // get the default path for this usage context if it's been -        // seen before. -        std::map<std::string,std::string>::iterator -            this_path = mContextToPathMap.find(context); -        if (this_path != mContextToPathMap.end()) -        { -            gtk_file_chooser_set_current_folder -                (GTK_FILE_CHOOSER(win), -                 this_path->second.c_str()); -        } - -#  if LL_X11 -        // Make GTK tell the window manager to associate this -        // dialog with our non-GTK raw X11 window, which should try -        // to keep it on top etc. -        Window XWindowID = LLWindowSDL::get_SDL_XWindowID(); -        if (None != XWindowID) -        { -            gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin -            GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID); -            gdk_window_set_transient_for(GTK_WIDGET(win)->window, -                             gdkwin); -        } -        else -        { -            LL_WARNS() << "Hmm, couldn't get xwid to use for transient." << LL_ENDL; -        } -#  endif //LL_X11 - -        g_signal_connect (GTK_FILE_CHOOSER(win), -                  "response", -                  G_CALLBACK(LLFilePicker::chooser_responder), -                  this); - -        gtk_window_set_modal(GTK_WINDOW(win), TRUE); - -        /* GTK 2.6: if (is_folder) -            gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win), -            TRUE); */ - -        return GTK_WINDOW(win); -    } -    else -    { -        return NULL; -    } -#else -    return NULL; -#endif //LL_MESA_HEADLESS -} +#if LL_FLTK -static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter, -                         GtkWindow *picker, -                         std::string filtername) -{ -    gtk_file_filter_set_name(gfilter, filtername.c_str()); -    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), -                    gfilter); -    GtkFileFilter *allfilter = gtk_file_filter_new(); -    gtk_file_filter_add_pattern(allfilter, "*"); -    gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str()); -    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter); -    gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter); -} - -static std::string add_simple_pattern_filter_to_gtkchooser(GtkWindow *picker, -                               std::string pattern, -                               std::string filtername) -{ -    GtkFileFilter *gfilter = gtk_file_filter_new(); -    gtk_file_filter_add_pattern(gfilter, pattern.c_str()); -    add_common_filters_to_gtkchooser(gfilter, picker, filtername); -    return filtername; -} - -static std::string add_simple_mime_filter_to_gtkchooser(GtkWindow *picker, -                            std::string mime, -                            std::string filtername) -{ -    GtkFileFilter *gfilter = gtk_file_filter_new(); -    gtk_file_filter_add_mime_type(gfilter, mime.c_str()); -    add_common_filters_to_gtkchooser(gfilter, picker, filtername); -    return filtername; -} - -static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker) -{ -    return add_simple_mime_filter_to_gtkchooser(picker,  "audio/x-wav", -                            LLTrans::getString("sound_files") + " (*.wav)"); -} - -static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker) +BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, +                                       const std::string& filename, +                                       void (*callback)(bool, std::string&, void*), +                                       void *userdata)  { -    GtkFileFilter *gfilter = gtk_file_filter_new(); -    gtk_file_filter_add_pattern(gfilter, "*.bvh"); -    gtk_file_filter_add_pattern(gfilter, "*.anim"); -    std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)"; -    add_common_filters_to_gtkchooser(gfilter, picker, filtername); -    return filtername; +    LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; +    return FALSE;  } -static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker) +BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter, +                                       void (*callback)(bool, std::vector<std::string> &, void*), +                                       void *userdata)  { -    return add_simple_pattern_filter_to_gtkchooser(picker,  "*.xml", -                                                   LLTrans::getString("xml_files") + " (*.xml)"); +    LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; +    return FALSE;  } -static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker) +BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, +                                                void (*callback)(bool, std::vector<std::string> &, void*), +                                                void *userdata )  { -    return add_simple_pattern_filter_to_gtkchooser(picker,  "*.dae", -                               LLTrans::getString("scene_files") + " (*.dae)"); +    LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; +    return FALSE;  } -static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker) -{ -    GtkFileFilter *gfilter = gtk_file_filter_new(); -    gtk_file_filter_add_pattern(gfilter, "*.tga"); -    gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str()); -    gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str()); -    gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str()); -    std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)"; -    add_common_filters_to_gtkchooser(gfilter, picker, filtername); -    return filtername; -} -static std::string add_script_filter_to_gtkchooser(GtkWindow *picker) -{ -    return add_simple_mime_filter_to_gtkchooser(picker,  HTTP_CONTENT_TEXT_PLAIN, -                            LLTrans::getString("script_files") + " (*.lsl)"); -} -static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker) +BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking )  { -    return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, -                            LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)"); +    return openFileDialog( filter, blocking, eSaveFile );  } -static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker) +BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )  { -    GtkFileFilter *gfilter_tga = gtk_file_filter_new(); -    GtkFileFilter *gfilter_png = gtk_file_filter_new(); - -    gtk_file_filter_add_pattern(gfilter_tga, "*.tga"); -    gtk_file_filter_add_mime_type(gfilter_png, "image/png"); -    std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)"; -    gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str()); -    gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str()); - -    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), -                    gfilter_png); -    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), -                    gfilter_tga); -    return caption; +    return openFileDialog( filter, blocking, eOpenFile );  } -BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, -                                                void (*callback)(bool, std::vector<std::string> &, void*), -                                                void *userdata ) +BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)  { -    LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; -    return FALSE; +    return openFileDialog( filter, blocking, eOpenMultiple );  } -BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) +bool LLFilePicker::openFileDialog( int32_t filter, bool blocking, EType aType )  { -    BOOL rtn = FALSE; - -    // if local file browsing is turned off, return without opening dialog      if ( check_local_file_access_enabled() == false ) -    { -        return FALSE; -    } - +        return false;      gViewerWindow->getWindow()->beforeDialog(); -      reset(); - -    GtkWindow* picker = buildFilePicker(true, false, "savefile"); - -    if (picker) -    { -        std::string suggest_name = "untitled"; -        std::string suggest_ext = ""; -        std::string caption = LLTrans::getString("save_file_verb") + " "; -        switch (filter) +    Fl_Native_File_Chooser::Type flType = Fl_Native_File_Chooser::BROWSE_FILE; +    if( aType == eOpenMultiple ) +        flType = Fl_Native_File_Chooser::BROWSE_MULTI_FILE; +    else if( aType == eSaveFile ) +        flType = Fl_Native_File_Chooser::BROWSE_SAVE_FILE; +    Fl_Native_File_Chooser flDlg; +    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_WAV: -            caption += add_wav_filter_to_gtkchooser(picker); -            suggest_ext = ".wav"; -            break; -        case FFSAVE_TGA: -            caption += add_simple_pattern_filter_to_gtkchooser -                (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)"); -            suggest_ext = ".tga"; -            break; -        case FFSAVE_BMP: -            caption += add_simple_mime_filter_to_gtkchooser -                (picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)"); -            suggest_ext = ".bmp"; -            break; -        case FFSAVE_PNG: -            caption += add_simple_mime_filter_to_gtkchooser -                (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)"); -            suggest_ext = ".png"; -            break; -        case FFSAVE_TGAPNG: -            caption += add_save_texture_filter_to_gtkchooser(picker); -            suggest_ext = ".png"; -            break; -        case FFSAVE_AVI: -            caption += add_simple_mime_filter_to_gtkchooser -                (picker, "video/x-msvideo", -                 LLTrans::getString("avi_movie_file") + " (*.avi)"); -            suggest_ext = ".avi"; -            break; -        case FFSAVE_ANIM: -            caption += add_simple_pattern_filter_to_gtkchooser -                (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)"); -            suggest_ext = ".xaf"; -            break; -        case FFSAVE_XML: -            caption += add_simple_pattern_filter_to_gtkchooser -                (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)"); -            suggest_ext = ".xml"; -            break; -        case FFSAVE_RAW: -            caption += add_simple_pattern_filter_to_gtkchooser -                (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)"); -            suggest_ext = ".raw"; -            break; -        case FFSAVE_J2C: -            // *TODO: Should this be 'image/j2c' ? -            caption += add_simple_mime_filter_to_gtkchooser -                (picker, "images/jp2", -                 LLTrans::getString("compressed_image_files") + " (*.j2c)"); -            suggest_ext = ".j2c"; -            break; -        case FFSAVE_SCRIPT: -            caption += add_script_filter_to_gtkchooser(picker); -            suggest_ext = ".lsl"; -            break; -        default:; -            break; +            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; +            case FFSAVE_GLTF: +                file_type = "gltf_asset_file"; +                file_dialog_filter = "*.{gltf,glb}"; +                break;          } - -        gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - -        if (filename.empty()) +        file_dialog_title = LLTrans::getString("save_file_verb") + " " + LLTrans::getString(file_type); +        file_dialog_filter = LLTrans::getString(file_type) + " \t" + file_dialog_filter; +    } +    else +    { +        std::string file_type("all_files"); +        switch ((ELoadFilter) filter)          { -            suggest_name += suggest_ext; +            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; +            case FFLOAD_GLTF: +            case FFLOAD_MATERIAL: +                file_type = "gltf_asset_file"; +                file_dialog_filter = "*.{gltg,glb}"; +                break; +            case FFLOAD_MATERIAL_TEXTURE: +                file_dialog_filter = "*.{gltf,glb,tga,bmp,jpg,jpeg,png}"; +                file_type = "image_files"; +                break; +            case FFLOAD_HDRI: +                file_dialog_filter = "*.exr"; -            gtk_file_chooser_set_current_name -                (GTK_FILE_CHOOSER(picker), -                 suggest_name.c_str());          } -        else +        if (aType == EType::eOpenMultiple)          { -            gtk_file_chooser_set_current_name -                (GTK_FILE_CHOOSER(picker), filename.c_str()); +            file_dialog_title = LLTrans::getString("load_files");          } - -        gtk_widget_show_all(GTK_WIDGET(picker)); - -        gtk_main(); - -        rtn = (getFileCount() == 1); - -        if(rtn && filter == FFSAVE_TGAPNG) +        else          { -            std::string selected_file = mFiles.back(); -            mFiles.pop_back(); -            mFiles.push_back(selected_file + mCurrentExtension); +            file_dialog_title = LLTrans::getString("load_file_verb") + " " + LLTrans::getString(file_type); +            file_dialog_filter = LLTrans::getString(file_type) + " \t" + file_dialog_filter;          }      } - -    gViewerWindow->getWindow()->afterDialog(); - -    return rtn; -} - -BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, -                                       const std::string& filename, -                                       void (*callback)(bool, std::string&, void*), -                                       void *userdata) -{ -    LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; -    return FALSE; -} - -BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) -{ -    BOOL rtn = FALSE; - -    // if local file browsing is turned off, return without opening dialog -    if ( check_local_file_access_enabled() == false ) +    flDlg.title(file_dialog_title.c_str()); +    flDlg.type(flType); +    if (!file_dialog_filter.empty())      { -        return FALSE; +        flDlg.filter(file_dialog_filter.c_str());      } - -    gViewerWindow->getWindow()->beforeDialog(); - -    reset(); - -    GtkWindow* picker = buildFilePicker(false, false, "openfile"); - -    if (picker) +    int res = flDlg.show(); +    gViewerWindow->getWindow()->afterDialog(); +    if( res == 0 )      { -        std::string caption = LLTrans::getString("load_file_verb") + " "; -        std::string filtername = ""; -        switch (filter) +        int32_t count = flDlg.count(); +        if( count < 0 ) +            count = 0; +        for( int32_t i = 0; i < count; ++i )          { -        case FFLOAD_WAV: -            filtername = add_wav_filter_to_gtkchooser(picker); -            break; -        case FFLOAD_ANIM: -            filtername = add_anim_filter_to_gtkchooser(picker); -            break; -        case FFLOAD_XML: -            filtername = add_xml_filter_to_gtkchooser(picker); -            break; -        case FFLOAD_GLTF: -            //filtername = dead_code_should_blow_up_here(picker); -            break; -        case FFLOAD_COLLADA: -            filtername = add_collada_filter_to_gtkchooser(picker); -            break; -        case FFLOAD_IMAGE: -            filtername = add_imageload_filter_to_gtkchooser(picker); -            break; -        case FFLOAD_SCRIPT: -            filtername = add_script_filter_to_gtkchooser(picker); -            break; -        case FFLOAD_DICTIONARY: -            filtername = add_dictionary_filter_to_gtkchooser(picker); -            break; -        default:; -            break; +            char const *pFile = flDlg.filename(i); +            if( pFile && strlen(pFile) > 0 ) +                mFiles.push_back( pFile  );          } - -        caption += filtername; - -        gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - -        gtk_widget_show_all(GTK_WIDGET(picker)); -        gtk_main(); - -        rtn = (getFileCount() == 1);      } - -    gViewerWindow->getWindow()->afterDialog(); - -    return rtn; -} - -BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter, -                                       void (*callback)(bool, std::vector<std::string> &, void*), -                                       void *userdata) -{ -    LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; -    return FALSE; -} - -BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) -{ -    BOOL rtn = FALSE; - -    // if local file browsing is turned off, return without opening dialog -    if ( check_local_file_access_enabled() == false ) -    { -        return FALSE; -    } - -    gViewerWindow->getWindow()->beforeDialog(); - -    reset(); - -    GtkWindow* picker = buildFilePicker(false, false, "openfile"); - -    if (picker) +    else if( res == -1 )      { -        gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker), -                              TRUE); - -        gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str()); - -        gtk_widget_show_all(GTK_WIDGET(picker)); -        gtk_main(); -        rtn = !mFiles.empty(); +        LL_WARNS() << "FLTK failed: " <<  flDlg.errmsg() << LL_ENDL;      } - -    gViewerWindow->getWindow()->afterDialog(); - -    return rtn; +    return mFiles.empty()?FALSE:TRUE;  } - -# else // LL_GTK - +#else  // Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with  // static results, when we don't have a real filepicker. @@ -1696,7 +1420,7 @@ BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,      return FALSE;  } -#endif // LL_GTK +#endif // LL_FLTK  #else // not implemented diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 994e7458d3..faffee7aba 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -54,19 +54,8 @@  #include <commdlg.h>  #endif -extern "C" { -// mostly for Linux, possible on others -#if LL_GTK -# include "gtk/gtk.h" -#endif // LL_GTK -} -  class LLFilePicker  { -#ifdef LL_GTK -    friend class LLDirPicker; -    friend void chooser_responder(GtkWidget *, gint, gpointer); -#endif // LL_GTK  public:      // calling this before main() is undefined      static LLFilePicker& instance( void ) { return sInstance; } @@ -184,14 +173,12 @@ private:                                   void *userdata);  #endif -#if LL_GTK -    static void add_to_selectedfiles(gpointer data, gpointer user_data); -    static void chooser_responder(GtkWidget *widget, gint response, gpointer user_data); -    // we remember the last path that was accessed for a particular usage -    std::map <std::string, std::string> mContextToPathMap; -    std::string mCurContextName; -    // we also remember the extension of the last added file. -    std::string mCurrentExtension; +#if LL_FLTK +    enum EType +    { +     eSaveFile, eOpenFile, eOpenMultiple +    }; +    bool openFileDialog( int32_t filter, bool blocking, EType aType );  #endif      std::vector<std::string> mFiles; @@ -200,12 +187,6 @@ private:      static LLFilePicker sInstance; -protected: -#if LL_GTK -        GtkWindow* buildFilePicker(bool is_save, bool is_folder, -                   std::string context = "generic"); -#endif -  public:      // don't call these directly please.      LLFilePicker(); diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index d2ca0aaf69..f810f3afe7 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -31,6 +31,7 @@  #include "llagent.h"  #include "llagentui.h"  #include "llcombobox.h" +#include "llfloaterreg.h"  #include "llinventoryfunctions.h"  #include "llinventoryobserver.h"  #include "lllandmarkactions.h" @@ -286,8 +287,7 @@ void LLFloaterCreateLandmark::onCreateFolderClicked()              std::string folder_name = resp["message"].asString();              if (!folder_name.empty())              { -                inventory_func_type func = boost::bind(&LLFloaterCreateLandmark::folderCreatedCallback, this, _1); -                gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, func); +                gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, folderCreatedCallback);                  gInventory.notifyObservers();              }          } @@ -296,7 +296,11 @@ void LLFloaterCreateLandmark::onCreateFolderClicked()  void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id)  { -    populateFoldersList(folder_id); +    LLFloaterCreateLandmark* floater = LLFloaterReg::findTypedInstance<LLFloaterCreateLandmark>("add_landmark"); +    if (floater && !floater->isDead()) +    { +        floater->populateFoldersList(folder_id); +    }  }  void LLFloaterCreateLandmark::onSaveClicked() @@ -389,6 +393,7 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)              {                  mItem = item;                  mAssetID = mItem->getAssetUUID(); +                mParentID = mItem->getParentUUID();                  setVisibleAndFrontmost(true);                  break;              } @@ -418,8 +423,7 @@ void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask)                  closeFloater();              } -            LLUUID folder_id = mFolderCombo->getValue().asUUID(); -            if (folder_id != mItem->getParentUUID()) +            if (mParentID != mItem->getParentUUID())              {                  // user moved landmark in inventory,                  // assume that we are done all other changes should already be commited diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h index dc121677a4..89e0a0bb6a 100644 --- a/indra/newview/llfloatercreatelandmark.h +++ b/indra/newview/llfloatercreatelandmark.h @@ -62,13 +62,14 @@ private:      void onSaveClicked();      void onCancelClicked(); -    void folderCreatedCallback(LLUUID folder_id); +    static void folderCreatedCallback(LLUUID folder_id);      LLComboBox*     mFolderCombo;      LLLineEditor*   mLandmarkTitleEditor;      LLTextEditor*   mNotesEditor;      LLUUID          mLandmarksID;      LLUUID          mAssetID; +    LLUUID          mParentID;      LLLandmarksInventoryObserver*   mInventoryObserver;      LLPointer<LLInventoryItem>      mItem; diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp index 78b94d1b0c..c9d14c45f8 100644 --- a/indra/newview/llfloateremojipicker.cpp +++ b/indra/newview/llfloateremojipicker.cpp @@ -57,8 +57,7 @@ static const S32 USED_EMOJIS_IMAGE_INDEX = 0x23F2;  // https://www.compart.com/en/unicode/U+1F6D1  static const S32 EMPTY_LIST_IMAGE_INDEX = 0x1F6D1;  // The following categories should follow the required alphabetic order -static const std::string RECENTLY_USED_CATEGORY = "1 recently used"; -static const std::string FREQUENTLY_USED_CATEGORY = "2 frequently used"; +static const std::string FREQUENTLY_USED_CATEGORY = "frequently used";  // Floater state related variables  static std::list<llwchar> sRecentlyUsed; @@ -436,6 +435,7 @@ void LLFloaterEmojiPicker::fillGroups()      LLButton::Params params;      params.font = LLFontGL::getFontEmojiLarge(); +    params.name = "all_categories";      LLRect rect;      rect.mTop = mGroups->getRect().getHeight(); @@ -444,11 +444,10 @@ void LLFloaterEmojiPicker::fillGroups()      // Create button for "All categories"      createGroupButton(params, rect, ALL_EMOJIS_IMAGE_INDEX); -    // Create group and button for "Recently used" and/or "Frequently used" -    if (!sRecentlyUsed.empty() || !sFrequentlyUsed.empty()) +    // Create group and button for "Frequently used" +    if (!sFrequentlyUsed.empty())      {          std::map<std::string, std::vector<LLEmojiSearchResult>> cats; -        fillCategoryRecentlyUsed(cats);          fillCategoryFrequentlyUsed(cats);          if (!cats.empty()) @@ -479,40 +478,6 @@ void LLFloaterEmojiPicker::fillGroups()      resizeGroupButtons();  } -void LLFloaterEmojiPicker::fillCategoryRecentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats) -{ -    if (sRecentlyUsed.empty()) -        return; - -    std::vector<LLEmojiSearchResult> emojis; - -    // In case of empty mFilterPattern we'd use sRecentlyUsed directly -    if (!mFilterPattern.empty()) -    { -        // List all emojis in "Recently used" -        const LLEmojiDictionary::emoji2descr_map_t& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr(); -        std::size_t begin, end; -        for (llwchar emoji : sRecentlyUsed) -        { -            auto e2d = emoji2descr.find(emoji); -            if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty()) -            { -                for (const std::string& shortcode : e2d->second->ShortCodes) -                { -                    if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) -                    { -                        emojis.emplace_back(emoji, shortcode, begin, end); -                    } -                } -            } -        } -        if (emojis.empty()) -            return; -    } - -    cats.emplace(std::make_pair(RECENTLY_USED_CATEGORY, emojis)); -} -  void LLFloaterEmojiPicker::fillCategoryFrequentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats)  {      if (sFrequentlyUsed.empty()) @@ -533,13 +498,13 @@ void LLFloaterEmojiPicker::fillCategoryFrequentlyUsed(std::map<std::string, std:              {                  for (const std::string& shortcode : e2d->second->ShortCodes)                  { -                    if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) -                    { -                        emojis.emplace_back(emoji.first, shortcode, begin, end); -                    } +                if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) +                { +                    emojis.emplace_back(emoji.first, shortcode, begin, end);                  }              }          } +        }          if (emojis.empty())              return;      } @@ -571,13 +536,13 @@ void LLFloaterEmojiPicker::fillGroupEmojis(std::map<std::string, std::vector<LLE                  {                      for (const std::string& shortcode : descr->ShortCodes)                      { -                        if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) -                        { -                            emojis.emplace_back(descr->Character, shortcode, begin, end); -                        } +                    if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) +                    { +                        emojis.emplace_back(descr->Character, shortcode, begin, end);                      }                  }              } +            }              if (emojis.empty())                  continue;          } @@ -754,7 +719,6 @@ void LLFloaterEmojiPicker::fillEmojisCategory(const std::vector<LLEmojiSearchRes  {      // Place the category title      std::string title = -        category == RECENTLY_USED_CATEGORY ? getString("title_for_recently_used") :          category == FREQUENTLY_USED_CATEGORY ? getString("title_for_frequently_used") :          isupper(category.front()) ? category : LLStringUtil::capitalize(category);      LLEmojiGridDivider* div = new LLEmojiGridDivider(row_panel_params, title); @@ -767,21 +731,7 @@ void LLFloaterEmojiPicker::fillEmojisCategory(const std::vector<LLEmojiSearchRes      {          const LLEmojiDictionary::emoji2descr_map_t& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr();          LLEmojiSearchResult emoji { 0, "", 0, 0 }; -        if (category == RECENTLY_USED_CATEGORY) -        { -            for (llwchar code : sRecentlyUsed) -            { -                const LLEmojiDictionary::emoji2descr_map_t::const_iterator& e2d = emoji2descr.find(code); -                if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty()) -                { -                    emoji.Character = code; -                    emoji.String = e2d->second->ShortCodes.front(); -                    createEmojiIcon(emoji, category, row_panel_params, row_list_params, icon_params, -                        icon_rect, max_icons, bg, row, icon_index); -                } -            } -        } -        else if (category == FREQUENTLY_USED_CATEGORY) +        if (category == FREQUENTLY_USED_CATEGORY)          {              for (const auto& code : sFrequentlyUsed)              { diff --git a/indra/newview/llfloateremojipicker.h b/indra/newview/llfloateremojipicker.h index 05b4826e37..bc64cb1f35 100644 --- a/indra/newview/llfloateremojipicker.h +++ b/indra/newview/llfloateremojipicker.h @@ -60,7 +60,6 @@ public:  private:      void initialize();      void fillGroups(); -    void fillCategoryRecentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats);      void fillCategoryFrequentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats);      void fillGroupEmojis(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats, U32 index);      void createGroupButton(LLButton::Params& params, const LLRect& rect, llwchar emoji); diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp index 97ae97dafc..ba655ab760 100644 --- a/indra/newview/llfloaterperformance.cpp +++ b/indra/newview/llfloaterperformance.cpp @@ -115,12 +115,12 @@ BOOL LLFloaterPerformance::postBuild()      mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");      mHUDList->setNameListType(LLNameListCtrl::SPECIAL);      mHUDList->setHoverIconName("StopReload_Off"); -    mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); +    mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachObject, this, _1));      mObjectList = mComplexityPanel->getChild<LLNameListCtrl>("obj_list");      mObjectList->setNameListType(LLNameListCtrl::SPECIAL);      mObjectList->setHoverIconName("StopReload_Off"); -    mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); +    mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachObject, this, _1));      mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));      mSettingsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this)); @@ -524,9 +524,13 @@ void LLFloaterPerformance::setFPSText()      getChild<LLTextBox>("fps_lbl")->setValue(fps_text);  } -void LLFloaterPerformance::detachItem(const LLUUID& item_id) +void LLFloaterPerformance::detachObject(const LLUUID& obj_id)  { -    LLAppearanceMgr::instance().removeItemFromAvatar(item_id); +    LLViewerObject* obj = gObjectList.findObject(obj_id); +    if (obj) +    { +        LLAppearanceMgr::instance().removeItemFromAvatar(obj->getAttachmentItemID()); +    }  }  void LLFloaterPerformance::onClickAdvanced() diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h index d2f45a9e2e..03fa9e8184 100644 --- a/indra/newview/llfloaterperformance.h +++ b/indra/newview/llfloaterperformance.h @@ -46,7 +46,7 @@ public:      void hidePanels();      void showAutoadjustmentsPanel(); -    void detachItem(const LLUUID& item_id); +    void detachObject(const LLUUID& obj_id);      void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index d731f1c592..23ddd087eb 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -329,6 +329,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)      mCommitCallbackRegistrar.add("Pref.AutoAdjustments",         boost::bind(&LLFloaterPreference::onClickAutoAdjustments, this));      mCommitCallbackRegistrar.add("Pref.HardwareDefaults",       boost::bind(&LLFloaterPreference::setHardwareDefaults, this));      mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable",  boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this)); +    mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreference::updateMaxNonImpostors, this));      mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",    boost::bind(&LLFloaterPreference::updateMaxComplexity, this));      mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate",     boost::bind(&LLFloaterPreference::onRenderOptionEnable, this));      mCommitCallbackRegistrar.add("Pref.WindowedMod",            boost::bind(&LLFloaterPreference::onCommitWindowedMode, this)); @@ -360,6 +361,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)      LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );      mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateComplexityText, this)); +    mImpostorsChangedSignal = gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreference::updateIndirectMaxNonImpostors, this, _2));      mCommitCallbackRegistrar.add("Pref.ClearLog",               boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));      mCommitCallbackRegistrar.add("Pref.DeleteTranscripts",      boost::bind(&LLFloaterPreference::onDeleteTranscripts, this)); @@ -527,6 +529,7 @@ LLFloaterPreference::~LLFloaterPreference()  {      LLConversationLog::instance().removeObserver(this);      mComplexityChangedSignal.disconnect(); +    mImpostorsChangedSignal.disconnect();  }  void LLFloaterPreference::draw() @@ -1280,6 +1283,9 @@ void LLAvatarComplexityControls::setIndirectMaxArc()  void LLFloaterPreference::refresh()  {      LLPanel::refresh(); +    setMaxNonImpostorsText( +        gSavedSettings.getU32("RenderAvatarMaxNonImpostors"), +        getChild<LLTextBox>("IndirectMaxNonImpostorsText", true));      LLAvatarComplexityControls::setText(          gSavedSettings.getU32("RenderAvatarMaxComplexity"),          getChild<LLTextBox>("IndirectMaxComplexityText", true)); @@ -1558,6 +1564,44 @@ void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_bo      }  } +void LLFloaterPreference::updateMaxNonImpostors() +{ +    // Called when the IndirectMaxNonImpostors control changes +    // Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors +    LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors", true); +    U32 value = ctrl->getValue().asInteger(); + +    if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value) +    { +        value = 0; +    } +    gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value); +    LLVOAvatar::updateImpostorRendering(value); // make it effective immediately +    setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText")); +} + +void LLFloaterPreference::updateIndirectMaxNonImpostors(const LLSD& newvalue) +{ +    U32 value = newvalue.asInteger(); +    if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors"))) +    { +        gSavedSettings.setU32("IndirectMaxNonImpostors", value); +    } +    setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText")); +} + +void LLFloaterPreference::setMaxNonImpostorsText(U32 value, LLTextBox* text_box) +{ +    if (0 == value) +    { +        text_box->setText(LLTrans::getString("no_limit")); +    } +    else +    { +        text_box->setText(llformat("%d", value)); +    } +} +  void LLFloaterPreference::updateMaxComplexity()  {      // Called when the IndirectMaxComplexity control changes diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index fe684cf88c..bb7892362c 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -210,6 +210,9 @@ private:      void onDeleteTranscripts();      void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);      void updateDeleteTranscriptsButton(); +    void updateMaxNonImpostors(); +    void updateIndirectMaxNonImpostors(const LLSD& newvalue); +    void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);      void updateMaxComplexity();      void updateComplexityText();      static bool loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map); @@ -233,6 +236,7 @@ private:      std::unique_ptr< ll::prefs::SearchData > mSearchData;      bool mSearchDataDirty; +    boost::signals2::connection mImpostorsChangedSignal;      boost::signals2::connection mComplexityChangedSignal;      void onUpdateFilterTerm( bool force = false ); diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp index 709963b924..ae1c5cf6c9 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp @@ -52,13 +52,14 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L      mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));      mCommitCallbackRegistrar.add("Pref.OK",     boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2)); -    gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors, this, _2)); +    mImpostorsChangedSignal = gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors, this, _2));  }  LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()  {      mComplexityChangedSignal.disconnect();      mLODFactorChangedSignal.disconnect(); +    mImpostorsChangedSignal.disconnect();  }  BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild() @@ -221,8 +222,8 @@ void LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors(const LL      if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors")))      {          gSavedSettings.setU32("IndirectMaxNonImpostors", value); -        setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));      } +    setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));  }  void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box) diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h index 114a79a936..bab51b712b 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.h +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h @@ -60,6 +60,7 @@ protected:      void        onBtnOK(const LLSD& userdata);      void        onBtnCancel(const LLSD& userdata); +    boost::signals2::connection mImpostorsChangedSignal;      boost::signals2::connection mComplexityChangedSignal;      boost::signals2::connection mLODFactorChangedSignal;  }; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 8d2efc79db..0a66b7d037 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -4159,7 +4159,6 @@ void LLPanelRegionEnvironment::onChkAllowOverride(bool value)      mAllowOverrideRestore = mAllowOverride;      mAllowOverride = value; -      std::string notification("EstateParcelEnvironmentOverride");      if (LLPanelEstateInfo::isLindenEstate())          notification = "ChangeLindenEstate"; diff --git a/indra/newview/llhttpretrypolicy.cpp b/indra/newview/llhttpretrypolicy.cpp index 44d33eec93..de82952b9d 100644 --- a/indra/newview/llhttpretrypolicy.cpp +++ b/indra/newview/llhttpretrypolicy.cpp @@ -91,14 +91,14 @@ void LLAdaptiveRetryPolicy::onSuccess()  void LLAdaptiveRetryPolicy::onFailure(S32 status, const LLSD& headers)  { -    F32 retry_header_time; +    F32 retry_header_time{};      bool has_retry_header_time = getRetryAfter(headers,retry_header_time);      onFailureCommon(status, has_retry_header_time, retry_header_time);  }  void LLAdaptiveRetryPolicy::onFailure(const LLCore::HttpResponse *response)  { -    F32 retry_header_time; +    F32 retry_header_time{};      const LLCore::HttpHeaders::ptr_t headers = response->getHeaders();      bool has_retry_header_time = getRetryAfter(headers,retry_header_time);      onFailureCommon(response->getStatus().getType(), has_retry_header_time, retry_header_time); @@ -184,4 +184,3 @@ bool LLAdaptiveRetryPolicy::getSecondsUntilRetryAfter(const std::string& retry_a      return true;  } - diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index fbb4ac8801..bbd8e20c68 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -850,7 +850,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,              disabled_items.push_back(std::string("Copy"));          } -        if (isAgentInventory() && !single_folder_root) +        if (isAgentInventory() && !single_folder_root && !isMarketplaceListingsFolder())          {              items.push_back(std::string("New folder from selected"));              items.push_back(std::string("Subfolder Separator")); @@ -5309,7 +5309,7 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI      // Note: creation will take time, so passing folder id to callback is slightly unreliable,      // but so is collecting and passing descendants' ids -    inventory_func_type func = boost::bind(&LLFolderBridge::outfitFolderCreatedCallback, this, inv_cat->getUUID(), _1, cb); +    inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel);      gInventory.createNewCategory(dest_id,                                   LLFolderType::FT_OUTFIT,                                   inv_cat->getName(), @@ -5317,11 +5317,25 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI                                   inv_cat->getThumbnailUUID());  } -void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id, LLPointer<LLInventoryCallback> cb) +void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id, +                                                 LLUUID cat_dest_id, +                                                 LLPointer<LLInventoryCallback> cb, +                                                 LLHandle<LLInventoryPanel> inventory_panel)  {      LLInventoryModel::cat_array_t* categories;      LLInventoryModel::item_array_t* items; -    getInventoryModel()->getDirectDescendentsOf(cat_source_id, categories, items); + +    LLInventoryPanel* panel = inventory_panel.get(); +    if (!panel) +    { +        return; +    } +    LLInventoryModel*  model = panel->getModel(); +    if (!model) +    { +        return; +    } +    model->getDirectDescendentsOf(cat_source_id, categories, items);      LLInventoryObject::const_object_list_t link_array; diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index b0139e225e..70a457f98c 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -378,7 +378,10 @@ public:      static void staticFolderOptionsMenu();  protected: -    void outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id, LLPointer<LLInventoryCallback> cb); +    static void outfitFolderCreatedCallback(LLUUID cat_source_id, +                                            LLUUID cat_dest_id, +                                            LLPointer<LLInventoryCallback> cb, +                                            LLHandle<LLInventoryPanel> inventory_panel);      void callback_pasteFromClipboard(const LLSD& notification, const LLSD& response);      void perform_pasteFromClipboard();      void gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 65b8bc9e2c..c6192ddf1a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1744,7 +1744,7 @@ void LLInventoryModel::changeItemParent(LLViewerInventoryItem* item,              << " from " << make_inventory_info(item->getParentUUID())              << " to " << make_inventory_info(new_parent_id) << LL_ENDL; -        LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(), -1); +        LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);          accountForUpdate(old_folder);          LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1, false);          accountForUpdate(new_folder); @@ -2046,8 +2046,8 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo          {              LL_WARNS(LOG_INV) << "Deleting cat " << id << " while it still has child cats" << LL_ENDL;          } -        delete cat_list;          mParentChildCategoryTree.erase(id); +        delete cat_list;      }      addChangedMask(LLInventoryObserver::REMOVE, id); @@ -2540,7 +2540,7 @@ void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) const                  cat->setDescendentCount(descendents_actual);                  if (update.mChangeVersion)                  { -                    cat->setVersion(++version); +                cat->setVersion(++version);                  }                  LL_DEBUGS(LOG_INV) << "accounted: '" << cat->getName() << "' "                                     << version << " with " << descendents_actual @@ -5056,4 +5056,3 @@ void LLInventoryModel::FetchItemHttpHandler::processFailure(const char * const r                        << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL;      gInventory.notifyObservers();  } - diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index b664bfe6b9..77cf5bdcf2 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -30,6 +30,7 @@  #include "llaisapi.h"  #include "llagent.h"  #include "llappviewer.h" +#include "llappearancemgr.h"  #include "llcallbacklist.h"  #include "llinventorymodel.h"  #include "llinventorypanel.h" @@ -470,6 +471,22 @@ void LLInventoryModelBackgroundFetch::fetchCOF(nullary_func_t callback)                           callback();                           LLUUID cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);                           LLInventoryModelBackgroundFetch::getInstance()->onAISFolderCalback(cat_id, id, FT_DEFAULT); + +                         if (id.notNull()) +                         { +                             // COF might have fetched base outfit folder through a link, but it hasn't +                             // fetched base outfit's content, which doesn't nessesary match COF, +                             // so make sure it's up to date +                             LLUUID baseoutfit_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID(); +                             if (baseoutfit_id.notNull()) +                             { +                                 LLViewerInventoryCategory* cat = gInventory.getCategory(baseoutfit_id); +                                 if (!cat || cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) +                                 { +                                     LLInventoryModelBackgroundFetch::getInstance()->fetchFolderAndLinks(baseoutfit_id, no_op); +                                 } +                             } +                         }                       });      // start idle loop to track completion diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 09f1e703d1..b852ba0e3c 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -574,11 +574,6 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string              gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);          } -        /* -        LLColor4 shadow_color = LLColor4::black; -        shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; -        */ -          if (fractional_portion != 0)          {              fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str()); diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 092861a240..26f1206c85 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -132,25 +132,17 @@ std::string getLodSuffix(S32 lod)  void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LLModel*& baseModelOut, LLMatrix4& matOut)  { -    LLModelLoader::scene::iterator base_iter = scene.begin(); -    bool found = false; -    while (!found && (base_iter != scene.end())) +    for (auto scene_iter = scene.begin(); scene_iter != scene.end(); scene_iter++)      { -        matOut = base_iter->first; - -        LLModelLoader::model_instance_list::iterator base_instance_iter = base_iter->second.begin(); -        while (!found && (base_instance_iter != base_iter->second.end())) +        for (auto model_iter = scene_iter->second.begin(); model_iter != scene_iter->second.end(); model_iter++)          { -            LLModelInstance& base_instance = *base_instance_iter++; -            LLModel* base_model = base_instance.mModel; - -            if (base_model && (base_model->mLabel == name_to_match)) +            if (model_iter->mModel && (model_iter->mModel->mLabel == name_to_match))              { -                baseModelOut = base_model; +                baseModelOut = model_iter->mModel; +                matOut = scene_iter->first;                  return;              }          } -        base_iter++;      }  } @@ -210,9 +202,12 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)  LLModelPreview::~LLModelPreview()  { +    LLMutexLock lock(this); +      if (mModelLoader)      {          mModelLoader->shutdown(); +        mModelLoader = NULL;      }      if (mPreviewAvatar) @@ -260,7 +255,7 @@ void LLModelPreview::updateDimentionsAndOffsets()              accounted.insert(instance.mModel);              // update instance skin info for each lods pelvisZoffset -            for (int j = 0; j<LLModel::NUM_LODS; ++j) +            for (int j = 0; j < LLModel::NUM_LODS; ++j)              {                  if (instance.mLOD[j])                  { @@ -301,7 +296,7 @@ void LLModelPreview::rebuildUploadData()      BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");      U32 load_state = 0; -    for (LLModelLoader::scene::iterator iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter) +    for (auto iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter)      { //for each transform in scene          LLMatrix4 mat = iter->first; @@ -320,9 +315,9 @@ void LLModelPreview::rebuildUploadData()          mat *= scale_mat; -        for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end();) +        for (auto model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)          { // for each instance with said transform applied -            LLModelInstance instance = *model_iter++; +            LLModelInstance instance = *model_iter;              LLModel* base_model = instance.mModel; @@ -882,7 +877,7 @@ void LLModelPreview::clearIncompatible(S32 lod)                  {                      mBaseModel = mModel[lod];                      mBaseScene = mScene[lod]; -                    mVertexBuffer[5].clear(); +                    mVertexBuffer[LLModel::NUM_LODS].clear();                      replaced_base_model = true;                  }              } @@ -1081,7 +1076,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)              mBaseModel = mModel[loaded_lod];              mBaseScene = mScene[loaded_lod]; -            mVertexBuffer[5].clear(); +            mVertexBuffer[LLModel::NUM_LODS].clear();          }          else          { @@ -1186,7 +1181,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)      {          if (!mBaseModel.empty())          { -            const std::string& model_name = mBaseModel[0]->getName(); +            std::string model_name = mBaseModel.front()->getName();              LLLineEditor* description_form = mFMP->getChild<LLLineEditor>("description_form");              if (description_form->getText().empty())              { @@ -1207,6 +1202,8 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)  void LLModelPreview::resetPreviewTarget()  { +    LLMutexLock lock(this); +      if (mModelLoader)      {          mPreviewTarget = (mModelLoader->mExtents[0] + mModelLoader->mExtents[1]) * 0.5f; @@ -1252,7 +1249,7 @@ void LLModelPreview::generateNormals()              (*it)->generateNormals(angle_cutoff);          } -        mVertexBuffer[5].clear(); +        mVertexBuffer[LLModel::NUM_LODS].clear();      }      bool perform_copy = mModelFacesCopy[which_lod].empty(); @@ -2094,7 +2091,7 @@ void LLModelPreview::updateStatusMessages()      S32 total_verts[LLModel::NUM_LODS];      S32 total_submeshes[LLModel::NUM_LODS]; -    for (U32 i = 0; i < LLModel::NUM_LODS - 1; i++) +    for (U32 i = 0; i < LLModel::NUM_LODS; i++)      {          total_tris[i] = 0;          total_verts[i] = 0; @@ -2398,12 +2395,16 @@ void LLModelPreview::updateStatusMessages()          }      } -    if (mModelNoErrors && mModelLoader) +    if (mModelNoErrors)      { -        if (!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean()) +        LLMutexLock lock(this); +        if (mModelLoader)          { -            // Some textures are still loading, prevent upload until they are done -            mModelNoErrors = false; +            if (!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean()) +            { +                // Some textures are still loading, prevent upload until they are done +                mModelNoErrors = false; +            }          }      } @@ -2732,10 +2733,10 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  {      LLModelLoader::model_list* model = NULL; -    if (lod < 0 || lod > 4) +    if (lod < 0 || lod >= LLModel::NUM_LODS)      {          model = &mBaseModel; -        lod = 5; +        lod = LLModel::NUM_LODS;      }      else      { @@ -2972,8 +2973,9 @@ void LLModelPreview::loadedCallback(      S32 lod,      void* opaque)  { -    LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque); -    if (pPreview && !LLModelPreview::sIgnoreLoadedCallback) +    LLModelPreview* pPreview = static_cast<LLModelPreview*>(opaque); +    LLMutexLock lock(pPreview); +    if (pPreview && pPreview->mModelLoader && !LLModelPreview::sIgnoreLoadedCallback)      {          // Load loader's warnings into floater's log tab          const LLSD out = pPreview->mModelLoader->logOut(); @@ -2994,7 +2996,9 @@ void LLModelPreview::loadedCallback(          }          const LLVOAvatar* avatarp = pPreview->getPreviewAvatar(); -        if (avatarp) { // set up ground plane for possible rendering +        if (avatarp && avatarp->mRoot && avatarp->mDrawable) +        { +            // set up ground plane for possible rendering              const LLVector3 root_pos = avatarp->mRoot->getPosition();              const LLVector4a* ext = avatarp->mDrawable->getSpatialExtents();              const LLVector4a min = ext[0], max = ext[1]; @@ -3131,12 +3135,12 @@ BOOL LLModelPreview::render()      LLMutexLock lock(this);      mNeedsUpdate = FALSE; -    bool edges = mViewOption["show_edges"]; -    bool joint_overrides = mViewOption["show_joint_overrides"]; -    bool joint_positions = mViewOption["show_joint_positions"]; -    bool skin_weight = mViewOption["show_skin_weight"]; -    bool textures = mViewOption["show_textures"]; -    bool physics = mViewOption["show_physics"]; +    bool show_edges = mViewOption["show_edges"]; +    bool show_joint_overrides = mViewOption["show_joint_overrides"]; +    bool show_joint_positions = mViewOption["show_joint_positions"]; +    bool show_skin_weight = mViewOption["show_skin_weight"]; +    bool show_textures = mViewOption["show_textures"]; +    bool show_physics = mViewOption["show_physics"];      S32 width = getWidth();      S32 height = getHeight(); @@ -3213,15 +3217,15 @@ BOOL LLModelPreview::render()                      fmp->childSetValue("upload_skin", true);                      mFirstSkinUpdate = false;                      upload_skin = true; -                    skin_weight = true; +                    show_skin_weight = true;                      mViewOption["show_skin_weight"] = true;                  }                  fmp->enableViewOption("show_skin_weight"); -                fmp->setViewOptionEnabled("show_joint_overrides", skin_weight); -                fmp->setViewOptionEnabled("show_joint_positions", skin_weight); +                fmp->setViewOptionEnabled("show_joint_overrides", show_skin_weight); +                fmp->setViewOptionEnabled("show_joint_positions", show_skin_weight);                  mFMP->childEnable("upload_skin"); -                mFMP->childSetValue("show_skin_weight", skin_weight); +                mFMP->childSetValue("show_skin_weight", show_skin_weight);              }              else if ((flags & LEGACY_RIG_FLAG_TOO_MANY_JOINTS) > 0) @@ -3244,11 +3248,12 @@ BOOL LLModelPreview::render()              fmp->disableViewOption("show_joint_overrides");              fmp->disableViewOption("show_joint_positions"); -            skin_weight = false; +            show_skin_weight = false;              mFMP->childSetValue("show_skin_weight", false); -            fmp->setViewOptionEnabled("show_skin_weight", skin_weight); +            fmp->setViewOptionEnabled("show_skin_weight", show_skin_weight);          }      } +    //if (this) return TRUE;      if (upload_skin && !has_skin_weights)      { //can't upload skin weights if model has no skin weights @@ -3291,7 +3296,7 @@ BOOL LLModelPreview::render()          mFMP->childSetEnabled("upload_joints", upload_skin);      } -    F32 explode = mFMP->childGetValue("physics_explode").asReal(); +    F32 physics_explode = mFMP->childGetValue("physics_explode").asReal();      LLGLDepthTest gls_depth(GL_TRUE); // SL-12781 re-enable z-buffer for 3D model preview @@ -3311,7 +3316,7 @@ BOOL LLModelPreview::render()      F32 z_near = 0.001f;      F32 z_far = mCameraDistance*10.0f + mPreviewScale.magVec() + mCameraOffset.magVec(); -    if (skin_weight) +    if (show_skin_weight)      {          target_pos = getPreviewAvatar()->getPositionAgent() + offset;          z_near = 0.01f; @@ -3321,7 +3326,7 @@ BOOL LLModelPreview::render()          refresh();      } -    gObjectPreviewProgram.bind(skin_weight); +    gObjectPreviewProgram.bind(show_skin_weight);      gGL.loadIdentity();      gPipeline.enableLightsPreview(); @@ -3330,7 +3335,7 @@ BOOL LLModelPreview::render()          LLQuaternion(mCameraYaw, LLVector3::z_axis);      LLQuaternion av_rot = camera_rot; -    F32 camera_distance = skin_weight ? SKIN_WEIGHT_CAMERA_DISTANCE : mCameraDistance; +    F32 camera_distance = show_skin_weight ? SKIN_WEIGHT_CAMERA_DISTANCE : mCameraDistance;      LLViewerCamera::getInstance()->setOriginAndLookAt(          target_pos + ((LLVector3(camera_distance, 0.f, 0.f) + offset) * av_rot),        // camera          LLVector3::z_axis,                                                                  // up @@ -3346,9 +3351,9 @@ BOOL LLModelPreview::render()      gGL.pushMatrix();      gGL.color4fv(PREVIEW_EDGE_COL.mV); -    if (!mBaseModel.empty() && mVertexBuffer[5].empty()) +    if (!mBaseModel.empty() && mVertexBuffer[LLModel::NUM_LODS].empty())      { -        genBuffers(-1, skin_weight); +        genBuffers(-1, show_skin_weight);          //genBuffers(3);      } @@ -3363,7 +3368,7 @@ BOOL LLModelPreview::render()              if (!vb_vec.empty())              {                  const LLVertexBuffer* buff = vb_vec[0]; -                regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != skin_weight; +                regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != show_skin_weight;              }              else              { @@ -3374,15 +3379,15 @@ BOOL LLModelPreview::render()          if (regen)          { -            genBuffers(mPreviewLOD, skin_weight); +            genBuffers(mPreviewLOD, show_skin_weight);          } -        if (physics && mVertexBuffer[LLModel::LOD_PHYSICS].empty()) +        if (show_physics && mVertexBuffer[LLModel::LOD_PHYSICS].empty())          {              genBuffers(LLModel::LOD_PHYSICS, false);          } -        if (!skin_weight) +        if (!show_skin_weight)          {              for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)              { @@ -3404,11 +3409,7 @@ BOOL LLModelPreview::render()                  U32 num_models = mVertexBuffer[mPreviewLOD][model].size();                  for (U32 i = 0; i < num_models; ++i)                  { -                    LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; - -                    buffer->setBuffer(); - -                    if (textures) +                    if (show_textures)                      {                          int materialCnt = instance.mModel->mMaterialList.size();                          if (i < materialCnt) @@ -3432,10 +3433,16 @@ BOOL LLModelPreview::render()                          gGL.diffuseColor4fv(PREVIEW_BASE_COL.mV);                      } +                    // Zero this variable for an obligatory buffer initialization +                    // See https://github.com/secondlife/viewer/issues/912 +                    LLVertexBuffer::sGLRenderBuffer = 0; +                    LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; +                    buffer->setBuffer();                      buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0); +                      gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);                      gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV); -                    if (edges) +                    if (show_edges)                      {                          glLineWidth(PREVIEW_EDGE_WIDTH);  #if GL_VERSION_1_1 @@ -3452,7 +3459,7 @@ BOOL LLModelPreview::render()                  gGL.popMatrix();              } -            if (physics) +            if (show_physics)              {                  glClear(GL_DEPTH_BUFFER_BIT); @@ -3518,12 +3525,12 @@ BOOL LLModelPreview::render()                                      for (U32 i = 0; i < physics.mMesh.size(); ++i)                                      { -                                        if (explode > 0.f) +                                        if (physics_explode > 0.f)                                          {                                              gGL.pushMatrix();                                              LLVector3 offset = model->mHullCenter[i] - model->mCenterOfHullCenters; -                                            offset *= explode; +                                            offset *= physics_explode;                                              gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);                                          } @@ -3538,7 +3545,7 @@ BOOL LLModelPreview::render()                                          gGL.diffuseColor4ubv(hull_colors[i].mV);                                          LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions); -                                        if (explode > 0.f) +                                        if (physics_explode > 0.f)                                          {                                              gGL.popMatrix();                                          } @@ -3553,14 +3560,17 @@ BOOL LLModelPreview::render()                          if (render_mesh)                          {                              U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); -                            if (pass > 0){ +                            if (pass > 0) +                            {                                  for (U32 i = 0; i < num_models; ++i)                                  { -                                    LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; -                                      gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);                                      gGL.diffuseColor4fv(PREVIEW_PSYH_FILL_COL.mV); +                                    // Zero this variable for an obligatory buffer initialization +                                    // See https://github.com/secondlife/viewer/issues/912 +                                    LLVertexBuffer::sGLRenderBuffer = 0; +                                    LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];                                      buffer->setBuffer();                                      buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0); @@ -3626,10 +3636,11 @@ BOOL LLModelPreview::render()                                      U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();                                      for (U32 v = 0; v < num_models; ++v)                                      { +                                        // Zero this variable for an obligatory buffer initialization +                                        // See https://github.com/secondlife/viewer/issues/912 +                                        LLVertexBuffer::sGLRenderBuffer = 0;                                          LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v]; -                                          buffer->setBuffer(); -                                          LLStrider<LLVector3> pos_strider;                                          buffer->getVertexStrider(pos_strider, 0);                                          LLVector4a* pos = (LLVector4a*)pos_strider.get(); @@ -3695,7 +3706,7 @@ BOOL LLModelPreview::render()                          U32 joint_count = LLSkinningUtil::getMeshJointCount(skin);                          U32 bind_count = skin->mAlternateBindMatrix.size(); -                        if (joint_overrides +                        if (show_joint_overrides                              && bind_count > 0                              && joint_count == bind_count)                          { @@ -3738,16 +3749,15 @@ BOOL LLModelPreview::render()                              }                          } -                        for (U32 i = 0, e = mVertexBuffer[mPreviewLOD][model].size(); i < e; ++i) +                        std::size_t size = mVertexBuffer[mPreviewLOD][model].size(); +                        for (U32 i = 0; i < size; ++i)                          { -                            LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; -                              model->mSkinInfo.updateHash();                              LLRenderPass::uploadMatrixPalette(mPreviewAvatar, &model->mSkinInfo);                              gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -                            if (textures) +                            if (show_textures)                              {                                  int materialCnt = instance.mModel->mMaterialList.size();                                  if (i < materialCnt) @@ -3771,10 +3781,14 @@ BOOL LLModelPreview::render()                                  gGL.diffuseColor4fv(PREVIEW_BASE_COL.mV);                              } +                            // Zero this variable for an obligatory buffer initialization +                            // See https://github.com/secondlife/viewer/issues/912 +                            LLVertexBuffer::sGLRenderBuffer = 0; +                            LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];                              buffer->setBuffer();                              buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); -                            if (edges) +                            if (show_edges)                              {                                  gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);                                  gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV); @@ -3793,7 +3807,7 @@ BOOL LLModelPreview::render()                  }              } -            if (joint_positions) +            if (show_joint_positions)              {                  LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;                  if (shader) diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 0870211a8e..84e646a93a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -925,12 +925,12 @@ void LLOutfitListBase::onIdleRefreshList()          {              std::string name = cat->getName();              updateChangedCategoryName(cat, name); -        }          curent_time = LLTimer::getTotalSeconds();          if (curent_time >= end_time)              return;      } +    }      sortOutfits();      highlightBaseOutfit(); diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp index e6e3a10e13..c7c0627009 100644 --- a/indra/newview/llpanelemojicomplete.cpp +++ b/indra/newview/llpanelemojicomplete.cpp @@ -68,6 +68,9 @@ LLPanelEmojiComplete::LLPanelEmojiComplete(const LLPanelEmojiComplete::Params& p      {          LLScrollbar::Params sbparams;          sbparams.orientation(LLScrollbar::VERTICAL); +        sbparams.doc_size(mTotalEmojis); +        sbparams.doc_pos(0); +        sbparams.page_size(mVisibleEmojis);          sbparams.change_callback([this](S32 index, LLScrollbar*) { onScrollbarChange(index); });          mScrollbar = LLUICtrlFactory::create<LLScrollbar>(sbparams);          addChild(mScrollbar); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 38af68bfff..5e5d5f42d4 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -5230,7 +5230,7 @@ void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical  void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face)  { -    LLGLenum image_format; +    LLGLenum image_format{};      struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor<LLGLenum>      {          LLGLenum get(LLViewerObject* object, S32 te_index) @@ -5496,4 +5496,3 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic      } max_diff_repeats_func;      identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );  } - diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index da53b4a14c..318c7ccd24 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -396,7 +396,7 @@ private:          ReturnType (LLMaterial::* const MaterialGetFunc)() const  >      static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())      { -        DataType data_value; +        DataType data_value{};          struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType>          {              GetTEMaterialVal(DataType default_value) : _default(default_value) {} @@ -429,7 +429,7 @@ private:          ReturnType (LLTextureEntry::* const TEGetFunc)() const >      static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())      { -        DataType data_value; +        DataType data_value {};          struct GetTEVal : public LLSelectedTEGetFunctor<DataType>          {              GetTEVal(DataType default_value) : _default(default_value) {} @@ -622,4 +622,3 @@ public:  };  #endif - diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp index 37534feadc..eb0df1194e 100644 --- a/indra/newview/llphysicsshapebuilderutil.cpp +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -28,6 +28,26 @@  #include "llphysicsshapebuilderutil.h" +#include "llmeshrepository.h" + +bool LLPhysicsVolumeParams::hasDecomposition() const + { +    if (!isMeshSculpt()) +    { +        return false; +    } + +    LLUUID mesh_id = getSculptID(); +    if (mesh_id.isNull()) +    { +        return false; +    } + +    LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id); + +    return decomp != NULL; +} +  /* static */  void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut)  { @@ -200,19 +220,32 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara      {          specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;      } -    else if (volume_params.isMeshSculpt() && -             // Check overall dimensions, not individual triangles. -             (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || -              scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || -              scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE -              ) ) +    else if (volume_params.isMeshSculpt())      { -        // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. -        specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; +        // Check overall dimensions, not individual triangles. +        if (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE +            || scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE +            || scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE +            ) +        { +            if (volume_params.hasDecomposition()) +            { +                specOut.mType = PhysicsShapeSpecification::USER_MESH; +            } +            else +            { +                // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. +                specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; +            } +        } +        else +        { +            specOut.mType = PhysicsShapeSpecification::USER_MESH; +        }      } -    else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy) +    else if ( volume_params.isSculpt() )      { -        specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT; +        specOut.mType = PhysicsShapeSpecification::SCULPT;      }      else // Resort to mesh      { diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h index 0f3baa2c7f..25b44bbbb5 100644 --- a/indra/newview/llphysicsshapebuilderutil.h +++ b/indra/newview/llphysicsshapebuilderutil.h @@ -78,6 +78,8 @@ public:      bool shouldForceConvex() const { return mForceConvex; } +    bool hasDecomposition() const; +  private:      bool mForceConvex;  }; diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h index 71624d1156..9721a4b1b6 100644 --- a/indra/newview/lltoastalertpanel.h +++ b/indra/newview/lltoastalertpanel.h @@ -82,14 +82,10 @@ private:      struct ButtonData      { -        ButtonData() -        : mWidth(0) -        {} -          LLButton* mButton = nullptr;          std::string mURL; -        U32 mURLExternal; -        S32 mWidth; +        U32 mURLExternal = 0; +        S32 mWidth = 0;      };      std::vector<ButtonData> mButtonData; diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index a7ce549bdf..46f994e15c 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -409,10 +409,16 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w                  F32* vw = (F32*) vertex_weightsp.get();                  F32* cw = (F32*) clothing_weightsp.get(); -                S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF; -                LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size); -                S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF; -                LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size); +                //S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF; +                //LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size); +                //S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF; +                //LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size); + +                // Both allocated in LLPolyMeshSharedData::allocateVertexData(unsigned int) + +                memcpy(tc, mMesh->getTexCoords(), num_verts*2*sizeof(F32) ); +                memcpy(vw, mMesh->getWeights(), num_verts*sizeof(F32) ); +                  LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32));              } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index c347a5a725..c8b7a9c29b 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1723,8 +1723,6 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_          std::string user_data_path_cache = gDirUtilp->getCacheDir(false);          user_data_path_cache += gDirUtilp->getDirDelimiter(); -        std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt"); -          // See if the plugin executable exists          llstat s;          if(LLFile::stat(launcher_name, &s)) @@ -1739,6 +1737,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_          {              media_source = new LLPluginClassMedia(owner);              media_source->setSize(default_width, default_height); +            std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.log");              media_source->setUserDataPath(user_data_path_cache, gDirUtilp->getUserName(), user_data_path_cef_log);              media_source->setLanguageCode(LLUI::getLanguage());              media_source->setZoomFactor(zoom_factor); @@ -1766,6 +1765,11 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_              bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");              media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled  || clean_browser); +#if LL_LINUX +            bool media_plugin_pipewire_volume_catcher = gSavedSettings.getBOOL("MediaPluginPipeWireVolumeCatcher"); +            media_source->enablePipeWireVolumeCatcher( media_plugin_pipewire_volume_catcher ); +#endif +              // need to set agent string here before instance created              media_source->setBrowserUserAgent(LLViewerMedia::getInstance()->getCurrentUserAgent()); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ac107aa15e..26c8483223 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3038,24 +3038,33 @@ void LLViewerObject::fetchInventoryFromServer()          delete mInventory;          mInventory = NULL; -        // Results in processTaskInv -        LLMessageSystem* msg = gMessageSystem; -        msg->newMessageFast(_PREHASH_RequestTaskInventory); -        msg->nextBlockFast(_PREHASH_AgentData); -        msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -        msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -        msg->nextBlockFast(_PREHASH_InventoryData); -        msg->addU32Fast(_PREHASH_LocalID, mLocalID); -        msg->sendReliable(mRegionp->getHost()); -          // This will get reset by doInventoryCallback or processTaskInv          mInvRequestState = INVENTORY_REQUEST_PENDING; + +        if (mRegionp && !mRegionp->getCapability("RequestTaskInventory").empty()) +        { +            LLCoros::instance().launch("LLViewerObject::fetchInventoryFromCapCoro()", +                                       boost::bind(&LLViewerObject::fetchInventoryFromCapCoro, mID)); +        } +        else +        { +            LL_WARNS() << "Using old task inventory path!" << LL_ENDL; +            // Results in processTaskInv +            LLMessageSystem *msg = gMessageSystem; +            msg->newMessageFast(_PREHASH_RequestTaskInventory); +            msg->nextBlockFast(_PREHASH_AgentData); +            msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +            msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +            msg->nextBlockFast(_PREHASH_InventoryData); +            msg->addU32Fast(_PREHASH_LocalID, mLocalID); +            msg->sendReliable(mRegionp->getHost()); +        }      }  }  void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds)  { -    // unless already waiting, drop previous request and shedule an update +    // unless already waiting, drop previous request and schedule an update      if (mInvRequestState != INVENTORY_REQUEST_WAIT)      {          if (mInvRequestXFerId != 0) @@ -3086,6 +3095,80 @@ void LLViewerObject::fetchInventoryDelayedCoro(const LLUUID task_inv, const F64      }  } +//static +void LLViewerObject::fetchInventoryFromCapCoro(const LLUUID task_inv) +{ +    LLViewerObject *obj = gObjectList.findObject(task_inv); +    if (obj) +    { +        LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +        LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +                                   httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TaskInventoryRequest", httpPolicy)); +        LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); +        std::string url = obj->mRegionp->getCapability("RequestTaskInventory") + "?task_id=" + obj->mID.asString(); +        // If we already have a copy of the inventory then add it so the server won't re-send something we already have. +        // We expect this case to crop up in the case of failed inventory mutations, but it might happen otherwise as well. +        if (obj->mInventorySerialNum && obj->mInventory) +            url += "&inventory_serial=" + std::to_string(obj->mInventorySerialNum); + +        obj->mInvRequestState = INVENTORY_XFER; +        LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + +        LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +        LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +        // Object may have gone away while we were suspended, double-check that it still exists +        obj = gObjectList.findObject(task_inv); +        if (!obj) +        { +            LL_WARNS() << "Object " << task_inv << " went away while fetching inventory, dropping result" << LL_ENDL; +            return; +        } + +        bool potentially_stale = false; +        if (status) +        { +            // Dealing with inventory serials is kind of funky. They're monotonically increasing and 16 bits, +            // so we expect them to overflow, but we can use inv serial < expected serial as a signal that we may +            // have mutated the task inventory since we kicked off the request, and those mutations may have not +            // been taken into account yet. Of course, those mutations may have actually failed which would result +            // in the inv serial never increasing. +            // +            // When we detect this case, set the expected inv serial to the inventory serial we actually received +            // and kick off a re-request after a slight delay. +            S16 serial = (S16)result["inventory_serial"].asInteger(); +            potentially_stale = serial < obj->mExpectedInventorySerialNum; +            LL_INFOS() << "Inventory loaded for " << task_inv << LL_ENDL; +            obj->mInventorySerialNum = serial; +            obj->mExpectedInventorySerialNum = serial; +            obj->loadTaskInvLLSD(result); +        } +        else if (status.getType() == 304) +        { +            LL_INFOS() << "Inventory wasn't changed on server!" << LL_ENDL; +            obj->mInvRequestState = INVENTORY_REQUEST_STOPPED; +            // Even though it wasn't necessary to send a response, we still may have mutated +            // the inventory since we kicked off the request, check for that case. +            potentially_stale = obj->mInventorySerialNum < obj->mExpectedInventorySerialNum; +            // Set this to what we already have so that we don't re-request a second time. +            obj->mExpectedInventorySerialNum = obj->mInventorySerialNum; +        } +        else +        { +            // Not sure that there's anything sensible we can do to recover here, retrying in a loop would be bad. +            LL_WARNS() << "Error status while requesting task inventory: " << status.toString() << LL_ENDL; +            obj->mInvRequestState = INVENTORY_REQUEST_STOPPED; +        } + +        if (potentially_stale) +        { +            // Stale? I guess we can use what we got for now, but we'll have to re-request +            LL_WARNS() << "Stale inv_serial? Re-requesting." << LL_ENDL; +            obj->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED); +        } +    } +} +  LLControlAvatar *LLViewerObject::getControlAvatar()  {      return getRootEdit()->mControlAvatar.get(); @@ -3261,6 +3344,20 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)      S16 serial = 0;      msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, serial); +    if (object->mRegionp && !object->mRegionp->getCapability("RequestTaskInventory").empty()) +    { +        // It seems that simulator may ask us to re-download the task inventory if an update to the inventory +        // happened out-of-band while we had the object selected (like if a script is saved.) +        // +        // If we're meant to use the HTTP capability, ignore the contents of the UDP message and fetch the +        // inventory via the CAP so that we don't flow down the UDP inventory request path unconditionally here. +        // We shouldn't need to wait, as any updates should already be ready to fetch by this point. +        LL_INFOS() << "Handling unsolicited ReplyTaskInventory for " << task_id << LL_ENDL; +        object->mExpectedInventorySerialNum = serial; +        object->fetchInventoryFromServer(); +        return; +    } +      if (serial == object->mInventorySerialNum          && serial < object->mExpectedInventorySerialNum)      { @@ -3468,6 +3565,47 @@ BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)      return TRUE;  } +void LLViewerObject::loadTaskInvLLSD(const LLSD& inv_result) +{ +    if (inv_result.has("contents")) +    { +        if(mInventory) +        { +            mInventory->clear(); // will deref and delete it +        } +        else +        { +            mInventory = new LLInventoryObject::object_list_t; +        } + +        // Synthesize the "Contents" category, the viewer expects it, but it isn't sent. +        LLPointer<LLInventoryObject> inv = new LLInventoryObject(mID, LLUUID::null, LLAssetType::AT_CATEGORY, "Contents"); +        mInventory->push_front(inv); + +        const LLSD& inventory = inv_result["contents"]; +        for (const auto& inv_entry : llsd::inArray(inventory)) +        { +            if (inv_entry.has("item_id")) +            { +                LLPointer<LLViewerInventoryItem> inv = new LLViewerInventoryItem; +                inv->unpackMessage(inv_entry); +                mInventory->push_front(inv); +            } +            else +            { +                LL_WARNS_ONCE() << "Unknown inventory entry while reading from inventory file. Entry: '" +                                << inv_entry << "'" << LL_ENDL; +            } +        } +    } +    else +    { +        LL_WARNS() << "unable to load task inventory: " << inv_result << LL_ENDL; +        return; +    } +    doInventoryCallback(); +} +  void LLViewerObject::doInventoryCallback()  {      for (callback_list_t::iterator iter = mInventoryCallbacks.begin(); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index a01e0b435f..ad7b3072c8 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -675,6 +675,7 @@ private:      // forms task inventory request after some time passed, marks request as pending      void fetchInventoryDelayed(const F64 &time_seconds);      static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds); +    static void fetchInventoryFromCapCoro(const LLUUID task_inv);  public:      // @@ -806,6 +807,7 @@ protected:      static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);      BOOL loadTaskInvFile(const std::string& filename); +    void loadTaskInvLLSD(const LLSD &inv_result);      void doInventoryCallback();      BOOL isOnMap(); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index d24e15a7d3..a71746f3d3 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -3190,6 +3190,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)      capabilityNames.append("FetchInventory2");      capabilityNames.append("FetchInventoryDescendents2");      capabilityNames.append("IncrementCOFVersion"); +    capabilityNames.append("RequestTaskInventory");      AISAPI::getCapNames(capabilityNames);      capabilityNames.append("InterestList"); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 62b4c390d0..b6935aa16a 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -827,6 +827,8 @@ void send_viewer_stats(bool include_preferences)      LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL; + +    // <ND> Do those lines even do anything sane in regard of debug logging?      LL_DEBUGS("LogViewerStatsPacket");      std::string filename("viewer_stats_packet.xml");      llofstream of(filename.c_str()); diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index 88edb96fbb..2e4002479d 100644 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -317,5 +317,3 @@ F32 LLViewerStatsRecorder::getTimeSinceStart()  {      return (F32) (LLFrameTimer::getTotalSeconds() - mFileOpenTime);  } - - diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index e03bd1a726..4473c8b55b 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1014,6 +1014,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()              std::string old_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SLVoice.old");              if (gDirUtilp->fileExists(new_log))              { +                LLFile::remove(old_log, ENOENT);                  LLFile::rename(new_log, old_log);              } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2459f8cd58..fe95aa80e3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5831,8 +5831,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)                      {                          type = LLDrawPool::POOL_GLTF_PBR;                      } -                    else -                    if (type != LLDrawPool::POOL_ALPHA && force_simple) +                    else if (type != LLDrawPool::POOL_ALPHA && force_simple)                      {                          type = LLDrawPool::POOL_SIMPLE;                      } diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index a0e87fd43a..71d15ebcbb 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -128,7 +128,6 @@ Chorazin Allen and Nicky Perian for involving Erik Kundiman in viewer developmen  LinneNoir for the moral support and initial testing;  Vir Linden for making it possible for the project to have a place (in every sense of the word) in SL;  nutsobvious for the early testing and video proof; -Kokua for the Dullahan fork;  Soft Linden for the security testing; and  Kyle Linden for selling TPV parcel 2 to Erik Kundiman at L$0 price.      </text_editor> diff --git a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml index e4b8f13df7..f642ca93b7 100644 --- a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml @@ -13,7 +13,6 @@      chrome="true"      height="350"      width="304"> -  <floater.string name="title_for_recently_used" value="Recently used"/>    <floater.string name="title_for_frequently_used" value="Frequently used"/>    <floater.string name="text_no_emoji_for_filter" value="No emoji found for '[FILTER]'"/>    <scroll_container diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml index f5852fdfaf..4dc9876ac8 100644 --- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml +++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml @@ -74,6 +74,8 @@          orientation="vertical"          step_size="16"          doc_size="3000" +        page_size="50" +        doc_pos="0"            />      </layout_panel>      <layout_panel name="timers_panel" diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 94c889f4e4..b9259256a6 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -170,7 +170,7 @@      height="16"      increment="1"      initial_value="12" -    label="Max. # of non-impostors:" +    label="Max. # animated avatars:"      label_width="185"      layout="topleft"      left="30" diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index 49dd55e91b..2298005d73 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -34,7 +34,8 @@     top="16"     left="0"     right="-1" -   bottom="-1"> +   bottom="-1" +   orientation="horizontal">      <layout_panel       name="map_lp"       width="385" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index f3d44cf647..ec0d4e1768 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -4107,16 +4107,6 @@ function="World.EnvPreset"          <menu_item_separator/> -        <menu_item_check -         label="HTTP Textures" -         name="HTTP Textures"> -            <menu_item_check.on_check -             function="CheckControl" -             parameter="ImagePipelineUseHTTP" /> -            <menu_item_check.on_click -             function="ToggleControl" -             parameter="ImagePipelineUseHTTP" /> -        </menu_item_check>          <menu_item_call           label="Compress Images"           name="Compress Images"> diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index f57b0d4825..0682a5d680 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -145,7 +145,6 @@      control_name="RememberPassword"      follows="left|top"      font="SansSerifMedium" -    text_color="EmphasisColor"      height="24"      left="408"      bottom_delta="0" diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml index 5e823c7b2f..0a8ae48b02 100644 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ b/indra/newview/skins/default/xui/en/panel_login_first.xml @@ -179,7 +179,6 @@              control_name="RememberPassword"              follows="left|top"              font="SansSerifLarge" -            text_color="EmphasisColor"              height="24"              left="262"              bottom_delta="0" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index adc0337edd..a19c9dd288 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -210,26 +210,60 @@      increment="8"      initial_value="160"      label="Draw distance:" -    label_width="90" +    label_width="187"      layout="topleft"      left="30"      min_val="64"      max_val="512"      name="DrawDistance"      top_delta="40" -    width="330" /> +    width="427" />    <text      type="string"      length="1"      follows="left|top"      height="12"      layout="topleft" -    left_delta="330" +    left_delta="427"      name="DrawDistanceMeterText2"      top_delta="0"      width="128">       m    </text> +  <slider +    control_name="IndirectMaxNonImpostors" +    name="IndirectMaxNonImpostors" +    decimal_digits="0" +    increment="1" +    initial_value="12" +    show_text="false" +    min_val="1" +    max_val="66" +    label="Maximum number of animated avatars:" +    follows="left|top" +    layout="topleft" +    height="16" +    label_width="240" +    left="30" +    top_delta="40" +    width="393"> +      <slider.commit_callback +        function="Pref.UpdateIndirectMaxNonImpostors" +        parameter="IndirectNonImpostorsText" /> +  </slider> +  <text +    type="string" +    length="1" +    follows="left|top" +    height="16" +    layout="topleft" +    top_delta="0" +    left_delta="397" +    text_readonly_color="LabelDisabledColor" +    name="IndirectMaxNonImpostorsText" +    width="65"> +      0 +  </text>    <button    height="23" diff --git a/indra/newview/skins/default/xui/en/panel_region_environment.xml b/indra/newview/skins/default/xui/en/panel_region_environment.xml index 6d23592948..6531233696 100644 --- a/indra/newview/skins/default/xui/en/panel_region_environment.xml +++ b/indra/newview/skins/default/xui/en/panel_region_environment.xml @@ -264,8 +264,7 @@                                  top_pad="1"                                  halign="right"                                  name="txt_alt1"> -                            Sky [INDEX] -                            [ALTITUDE]m +                            Sky [INDEX]
[ALTITUDE]m                          </text>                          <line_editor                                  follows="left|top" @@ -310,8 +309,7 @@                                  top_pad="1"                                  halign="right"                                  name="txt_alt2"> -                            Sky [INDEX] -                            [ALTITUDE]m +                            Sky [INDEX]
[ALTITUDE]m                          </text>                          <line_editor                                  follows="left|top" @@ -356,8 +354,7 @@                                  top_pad="1"                                  halign="right"                                  name="txt_alt3"> -                            Sky [INDEX] -                            [ALTITUDE]m +                            Sky [INDEX]
[ALTITUDE]m                          </text>                          <line_editor                                  follows="left|top" diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 8359fc5cf9..695a9e6634 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -59,12 +59,14 @@ class ViewerManifest(LLManifest):          # files during the build (see copy_w_viewer_manifest          # and copy_l_viewer_manifest targets)          return 'package' in self.args['actions'] -     +      def construct(self):          super(ViewerManifest, self).construct()          self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg")          self.path(src="../../etc/message.xml", dst="app_settings/message.xml") +        os.environ["XZ_DEFAULTS"] = "-T0" +          if self.is_packaging_viewer():              with self.prefix(src_dst="app_settings"):                  self.exclude("logcontrol.xml") @@ -87,7 +89,7 @@ class ViewerManifest(LLManifest):                  # ... and the entire image filters directory                  self.path("filters") -             +                  # ... and the included spell checking dictionaries                  pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')                  with self.prefix(src=pkgdir): @@ -260,14 +262,14 @@ class ViewerManifest(LLManifest):      def app_name_oneword(self):          return ''.join(self.app_name().split()) -     +      def icon_path(self):          return "icons/" + self.channel_type()      def extract_names(self,src):          """Extract contributor names from source file, returns string"""          try: -            with open(src, 'r') as contrib_file:  +            with open(src, 'r') as contrib_file:                  lines = contrib_file.readlines()          except IOError:              print("Failed to open '%s'" % src) @@ -491,7 +493,7 @@ class Windows_x86_64_Manifest(ViewerManifest):                  raise Exception("Directories are not supported by test_CRT_and_copy_action()")          else:              print("Doesn't exist:", src) -         +      def construct(self):          super().construct() @@ -543,7 +545,7 @@ class Windows_x86_64_Manifest(ViewerManifest):          self.path2basename(os.path.join(os.pardir,                                          'llplugin', 'slplugin', self.args['configuration']),                             "slplugin.exe") -         +          # Get shared libs from the shared libs staging directory          with self.prefix(src=os.path.join(self.args['build'], os.pardir,                                            'sharedlibs', self.args['buildtype'])): @@ -578,7 +580,7 @@ class Windows_x86_64_Manifest(ViewerManifest):              # Vivox libraries              self.path("vivoxsdk_x64.dll")              self.path("ortp_x64.dll") -             +              # OpenSSL              self.path("libcrypto-1_1-x64.dll")              self.path("libssl-1_1-x64.dll") @@ -705,7 +707,7 @@ class Windows_x86_64_Manifest(ViewerManifest):                  self.path("plugins/")          if not self.is_packaging_viewer(): -            self.package_file = "copied_deps"     +            self.package_file = "copied_deps"      def nsi_file_commands(self, install=True):          def INSTDIR(path): @@ -764,7 +766,7 @@ class Windows_x86_64_Manifest(ViewerManifest):          installer_file = self.installer_base_name() + '_Setup.exe'          substitution_strings['installer_file'] = installer_file -         +          version_vars = """          !define INSTEXE "SLVersionChecker.exe"          !define VERSION "%(version_short)s" @@ -773,7 +775,7 @@ class Windows_x86_64_Manifest(ViewerManifest):          !define VERSION_REGISTRY "%(version_registry)s"          !define VIEWER_EXE "%(final_exe)s"          """ % substitution_strings -         +          if self.channel_type() == 'release':              substitution_strings['caption'] = CHANNEL_VENDOR_BASE          else: @@ -904,7 +906,7 @@ class Darwin_x86_64_Manifest(ViewerManifest):                  # yields a slightly smaller binary but makes crash                  # logs mostly useless. This may be desirable for the                  # final release. Or not. -                if ("package" in self.args['actions'] or  +                if ("package" in self.args['actions'] or                      "unpacked" in self.args['actions']):                      self.run_command(                          ['strip', '-S', executable]) @@ -929,7 +931,7 @@ class Darwin_x86_64_Manifest(ViewerManifest):                  with self.prefix(src=relpkgdir, dst=""):                      self.path("libndofdev.dylib") -                    self.path("libhunspell-*.dylib")    +                    self.path("libhunspell-*.dylib")                  with self.prefix(src_dst="cursors_mac"):                      self.path("*.tif") @@ -1573,6 +1575,9 @@ class LinuxManifest(ViewerManifest):          super(LinuxManifest, self).construct()          pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') +        if "package_dir" in self.args: +            pkgdir = self.args['package_dir'] +          relpkgdir = os.path.join(pkgdir, "lib", "release")          debpkgdir = os.path.join(pkgdir, "lib", "debug") @@ -1591,49 +1596,123 @@ class LinuxManifest(ViewerManifest):          with self.prefix(dst="bin"):              self.path("secondlife-bin","do-not-directly-run-secondlife-bin") -            self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") +            #self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")              self.path2basename("../llplugin/slplugin", "SLPlugin")              #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 -            with self.prefix(src="../viewer_components/manager", dst=""): -                self.path("*.py") +            #with self.prefix(src="../viewer_components/manager", dst=""): +            #    self.path("*.py")          # recurses, packaged again          self.path("res-sdl") +        # We  copy ll_icon.BMP in CMakeLists.txt to newview/res-sdl and this will let the above self.path step take  care of copying +        # the correct branded icon          # Get the icons based on the channel type          icon_path = self.icon_path() -        print("DEBUG: icon_path '%s'" % icon_path) +        #print("DEBUG: icon_path '%s'" % icon_path)          with self.prefix(src=icon_path) :              self.path("secondlife_256.png","secondlife_icon.png")              with self.prefix(dst="res-sdl") :                  self.path("secondlife_256.BMP","ll_icon.BMP")          # plugins -        with self.prefix(src="../media_plugins", dst="bin/llplugin"): -            self.path("gstreamer010/libmedia_plugin_gstreamer010.so", -                      "libmedia_plugin_gstreamer.so") -            self.path2basename("libvlc", "libmedia_plugin_libvlc.so") - -        with self.prefix(src=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"): -            self.path( "plugins.dat" ) -            self.path( "*/*.so" ) - -        with self.prefix(src=os.path.join(pkgdir, 'lib' ), dst="lib"): -            self.path( "libvlc*.so*" ) - -        # llcommon -        if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"): -            print("Skipping llcommon.so (assuming llcommon was linked statically)") +        with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins'), dst="bin/llplugin"): +            self.path("gstreamer10/libmedia_plugin_gstreamer10.so", "libmedia_plugin_gstreamer.so") + + +        with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins'), dst="bin/llplugin"): +            self.path("cef/libmedia_plugin_cef.so", "libmedia_plugin_cef.so" ) +        with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"): +            self.path( "libcef.so" ) + +            self.path( "libEGL*" ) +            self.path( "libvulkan*" ) +            self.path( "libvk_swiftshader*" ) +            self.path( "libGLESv2*" ) +            self.path( "vk_swiftshader_icd.json") + +        with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="bin"): +            self.path( "chrome-sandbox" ) +            self.path( "dullahan_host" ) +            self.path( "snapshot_blob.bin" ) +            self.path( "v8_context_snapshot.bin" ) +        with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="lib"): +            self.path( "snapshot_blob.bin" ) +            self.path( "v8_context_snapshot.bin" ) + +        with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="lib"): +            self.path( "chrome_100_percent.pak" ) +            self.path( "chrome_200_percent.pak" ) +            self.path( "resources.pak" ) +            self.path( "icudtl.dat" ) + +        with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('lib', 'locales')): +            self.path("am.pak") +            self.path("ar.pak") +            self.path("bg.pak") +            self.path("bn.pak") +            self.path("ca.pak") +            self.path("cs.pak") +            self.path("da.pak") +            self.path("de.pak") +            self.path("el.pak") +            self.path("en-GB.pak") +            self.path("en-US.pak") +            self.path("es-419.pak") +            self.path("es.pak") +            self.path("et.pak") +            self.path("fa.pak") +            self.path("fi.pak") +            self.path("fil.pak") +            self.path("fr.pak") +            self.path("gu.pak") +            self.path("he.pak") +            self.path("hi.pak") +            self.path("hr.pak") +            self.path("hu.pak") +            self.path("id.pak") +            self.path("it.pak") +            self.path("ja.pak") +            self.path("kn.pak") +            self.path("ko.pak") +            self.path("lt.pak") +            self.path("lv.pak") +            self.path("ml.pak") +            self.path("mr.pak") +            self.path("ms.pak") +            self.path("nb.pak") +            self.path("nl.pak") +            self.path("pl.pak") +            self.path("pt-BR.pak") +            self.path("pt-PT.pak") +            self.path("ro.pak") +            self.path("ru.pak") +            self.path("sk.pak") +            self.path("sl.pak") +            self.path("sr.pak") +            self.path("sv.pak") +            self.path("sw.pak") +            self.path("ta.pak") +            self.path("te.pak") +            self.path("th.pak") +            self.path("tr.pak") +            self.path("uk.pak") +            self.path("vi.pak") +            self.path("zh-CN.pak") +            self.path("zh-TW.pak")          self.path("featuretable_linux.txt")          self.path("cube.dae") -        with self.prefix(src=pkgdir): +        with self.prefix(src=pkgdir, dst="bin"):              self.path("ca-bundle.crt")      def package_finish(self):          installer_name = self.installer_base_name() +        # When running as a GitHub Action job, RUNNER_TEMP is defined as the tmp dir +        RUNNER_TEMP = os.getenv('RUNNER_TEMP') +          self.strip_binaries()          # Fix access permissions @@ -1648,93 +1727,79 @@ class LinuxManifest(ViewerManifest):          # temporarily move directory tree so that it has the right          # name in the tarfile          realname = self.get_dst_prefix() -        tempname = self.build_path_of(installer_name) -        self.run_command(["mv", realname, tempname]) +        versionedName = self.build_path_of(installer_name) + +        tarName = versionedName + ".tar.xz" + +        # If using a github runner we divert packaging a little. Considering this wil be a VM/docker image +        # we can just pack the final installer into RUNNER_TEMP and not into the usual stop we'd pick when +        # not building a GHA release +        if RUNNER_TEMP: +            tarName = os.path.join(RUNNER_TEMP, self.package_file) + +        self.run_command(["mv", realname, versionedName]) +          try:              # only create tarball if it's a release build.              if self.args['buildtype'].lower() == 'release': -                # --numeric-owner hides the username of the builder for -                # security etc.                  self.run_command(['tar', '-C', self.get_build_prefix(),                                    '--numeric-owner', '-cJf', -                                 tempname + '.tar.xz', installer_name]) +                                 tarName, installer_name]) +                self.set_github_output_path('viewer_app', tarName)              else:                  print("Skipping %s.tar.xz for non-Release build (%s)" % \                        (installer_name, self.args['buildtype']))          finally: -            self.run_command(["mv", tempname, realname]) +            self.run_command(["mv", versionedName, realname])      def strip_binaries(self): +        doStrip = False          if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): -            print("* Going strip-crazy on the packaged binaries, since this is a RELEASE build") +            doStrip = True +        # In case of flatpak flatpak-build will call strip, disable doStrip here to get a flatpak symbol package. Increases flatpak size by about 1G +        if "FLATPAK_DEST" in os.environ: +            doStrip = True + +        if doStrip: +            print("* Going strip-crazy on the packaged binaries, since this is a Release build")              # makes some small assumptions about our packaged dir structure              self.run_command(                  ["find"] +                  [os.path.join(self.get_dst_prefix(), dir) for dir in ('bin', 'lib')] +                  ['-type', 'f', '!', '-name', '*.py', +                 '!', '-name', '*.pak', +                 '!', '-name', '*.bin', +                 '!', '-name', '*.dat', +                 '!', '-name', '*.crt', +                 '!', '-name', '*.dll', +                 '!', '-name', '*.lib',                   '!', '-name', 'update_install', '-exec', 'strip', '-S', '{}', ';']) -class Linux_i686_Manifest(LinuxManifest): -    address_size = 32 +class Linux_x86_64_Manifest(LinuxManifest): +    address_size = 64      def construct(self): -        super(Linux_i686_Manifest, self).construct() +        super(Linux_x86_64_Manifest, self).construct()          pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') +        if "package_dir" in self.args: +            pkgdir = self.args['package_dir'] +          relpkgdir = os.path.join(pkgdir, "lib", "release")          debpkgdir = os.path.join(pkgdir, "lib", "debug")          with self.prefix(src=relpkgdir, dst="lib"): -            self.path("libapr-1.so") -            self.path("libapr-1.so.0") -            self.path("libapr-1.so.0.4.5") -            self.path("libaprutil-1.so") -            self.path("libaprutil-1.so.0") -            self.path("libaprutil-1.so.0.4.1") -            self.path("libdb*.so") +            self.path("libapr-1.so*") +            self.path("libaprutil-1.so*")              self.path("libexpat.so.*") -            self.path("libuuid.so*") -            self.path("libSDL-1.2.so.*") -            self.path("libdirectfb-1.*.so.*") -            self.path("libfusion-1.*.so.*") -            self.path("libdirect-1.*.so.*") -            self.path("libopenjp2.so*") -            self.path("libdirectfb-1.4.so.5") -            self.path("libfusion-1.4.so.5") -            self.path("libdirect-1.4.so.5*") -            self.path("libhunspell-1.3.so*") -            self.path("libalut.so*") -            self.path("libopenal.so*") -            self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname -            # KLUDGE: As of 2012-04-11, the 'fontconfig' package installs -            # libfontconfig.so.1.4.4, along with symlinks libfontconfig.so.1 -            # and libfontconfig.so. Before we added support for library-file -            # wildcards, though, this self.path() call specifically named -            # libfontconfig.so.1.4.4 WITHOUT also copying the symlinks. When I -            # (nat) changed the call to self.path("libfontconfig.so.*"), we -            # ended up with the libfontconfig.so.1 symlink in the target -            # directory as well. But guess what! At least on Ubuntu 10.04, -            # certain viewer fonts look terrible with libfontconfig.so.1 -            # present in the target directory. Removing that symlink suffices -            # to improve them. I suspect that means we actually do better when -            # the viewer fails to find our packaged libfontconfig.so*, falling -            # back on the system one instead -- but diagnosing and fixing that -            # is a bit out of scope for the present project. Meanwhile, this -            # particular wildcard specification gets us exactly what the -            # previous call did, without having to explicitly state the -            # version number. -            self.path("libfontconfig.so.*.*") - -            # Include libfreetype.so. but have it work as libfontconfig does. -            self.path("libfreetype.so.*.*") +            self.path_optional("libSDL*.so.*") -            try: -                self.path("libtcmalloc.so*") #formerly called google perf tools -                pass -            except: -                print("tcmalloc files not found, skipping") -                pass +            self.path_optional("libjemalloc*.so") +            self.path("libhunspell-1.3.so*") +            self.path_optional("libalut.so*") +            self.path_optional("libopenal.so*") +            self.path_optional("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname              if self.args['fmodstudio'] == 'ON':                  try:                      self.path("libfmod.so.11.7") @@ -1755,17 +1820,6 @@ class Linux_i686_Manifest(LinuxManifest):              self.path("libvivoxsdk.so")          self.strip_binaries() - - -class Linux_x86_64_Manifest(LinuxManifest): -    address_size = 64 - -    def construct(self): -        super(Linux_x86_64_Manifest, self).construct() - -        # support file for valgrind debug tool -        self.path("secondlife-i686.supp") -  ################################################################  if __name__ == "__main__": | 
