summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/CMakeLists.txt7
-rw-r--r--indra/cmake/CMakeLists.txt4
-rw-r--r--indra/cmake/FindZLIB.cmake46
-rw-r--r--indra/cmake/FindZLIBNG.cmake46
-rw-r--r--indra/cmake/LLCommon.cmake2
-rw-r--r--indra/cmake/LLPrimitive.cmake5
-rw-r--r--indra/cmake/ZLIBNG.cmake (renamed from indra/cmake/ZLIB.cmake)20
-rw-r--r--indra/llcommon/CMakeLists.txt14
-rw-r--r--indra/llcommon/classic_callback.cpp16
-rw-r--r--indra/llcommon/classic_callback.h292
-rw-r--r--indra/llcommon/llsdserialize.cpp2
-rw-r--r--indra/llcommon/llsys.cpp28
-rw-r--r--indra/llcommon/llsys.h4
-rw-r--r--indra/llcommon/tests/classic_callback_test.cpp144
-rw-r--r--indra/llcorehttp/CMakeLists.txt2
-rw-r--r--indra/llimage/CMakeLists.txt6
-rw-r--r--indra/llprimitive/llmodel.cpp2
-rw-r--r--indra/llui/llmenugl.cpp18
-rw-r--r--indra/llui/lltextbase.h2
-rw-r--r--indra/llwindow/lldxhardware.cpp78
-rw-r--r--indra/llwindow/lldxhardware.h10
-rw-r--r--indra/mac_crash_logger/README.txt3
-rw-r--r--indra/newview/CMakeLists.txt10
-rw-r--r--indra/newview/llagent.cpp27
-rw-r--r--indra/newview/llagentcamera.cpp6
-rw-r--r--indra/newview/llagentwearables.cpp21
-rw-r--r--indra/newview/llappviewer.cpp32
-rw-r--r--indra/newview/llaudiosourcevo.cpp36
-rw-r--r--indra/newview/llchathistory.cpp12
-rw-r--r--indra/newview/llfavoritesbar.cpp32
-rw-r--r--indra/newview/llfavoritesbar.h6
-rw-r--r--indra/newview/llflexibleobject.cpp9
-rw-r--r--indra/newview/llfloaterland.cpp4
-rw-r--r--indra/newview/llfloaterregioninfo.cpp2
-rw-r--r--indra/newview/llinspectobject.cpp29
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp4
-rw-r--r--indra/newview/llpanellogin.cpp71
-rw-r--r--indra/newview/llpanelobject.cpp15
-rw-r--r--indra/newview/llpreviewgesture.cpp6
-rw-r--r--indra/newview/llsettingsvo.cpp27
-rw-r--r--indra/newview/llstartup.cpp38
-rw-r--r--indra/newview/llviewermenu.cpp98
-rw-r--r--indra/newview/llviewermenu.h1
-rw-r--r--indra/newview/llviewermenufile.cpp88
-rw-r--r--indra/newview/llviewermessage.cpp15
-rw-r--r--indra/newview/llviewerobjectlist.cpp2
-rw-r--r--indra/newview/llviewerstats.cpp1
-rw-r--r--indra/newview/llviewerwindow.cpp6
-rw-r--r--indra/newview/skins/default/textures/textures.xml3
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image.jpgbin0 -> 104529 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image_left.pngbin271413 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image_right.pngbin366068 -> 0 bytes
-rw-r--r--indra/newview/skins/default/xui/da/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml1
-rw-r--r--indra/newview/skins/default/xui/en/main_view.xml15
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml8
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_login_first.xml15
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml12
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml2
72 files changed, 1175 insertions, 263 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index dc1c28ce5b..1ab5888914 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -13,7 +13,6 @@ project(${ROOT_PROJECT_NAME})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(Variables)
-include(bugsplat)
include(BuildVersion)
set(LEGACY_STDIO_LIBS)
@@ -72,6 +71,12 @@ if (LINUX)
include(LLAppearanceUtility)
add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
endif (INSTALL_PROPRIETARY)
+ add_dependencies(viewer linux-crash-logger-strip-target)
+elseif (WINDOWS)
+ # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
+ if (EXISTS ${VIEWER_DIR}win_setup)
+ add_subdirectory(${VIEWER_DIR}win_setup)
+ endif (EXISTS ${VIEWER_DIR}win_setup)
endif (LINUX)
if (WINDOWS)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index d7725670a2..1407c1a26b 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -35,7 +35,7 @@ set(cmake_SOURCE_FILES
FindSCP.cmake
FindURIPARSER.cmake
FindXmlRpcEpi.cmake
- FindZLIB.cmake
+ FindZLIBNG.cmake
FMODSTUDIO.cmake
FreeType.cmake
GLEXT.cmake
@@ -92,7 +92,7 @@ set(cmake_SOURCE_FILES
VisualLeakDetector.cmake
LibVLCPlugin.cmake
XmlRpcEpi.cmake
- ZLIB.cmake
+ ZLIBNG.cmake
)
source_group("Shared Rules" FILES ${cmake_SOURCE_FILES})
diff --git a/indra/cmake/FindZLIB.cmake b/indra/cmake/FindZLIB.cmake
deleted file mode 100644
index 03a7db9d6f..0000000000
--- a/indra/cmake/FindZLIB.cmake
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- cmake -*-
-
-# - Find zlib
-# Find the ZLIB includes and library
-# This module defines
-# ZLIB_INCLUDE_DIRS, where to find zlib.h, etc.
-# ZLIB_LIBRARIES, the libraries needed to use zlib.
-# ZLIB_FOUND, If false, do not try to use zlib.
-#
-# This FindZLIB is about 43 times as fast the one provided with cmake (2.8.x),
-# because it doesn't look up the version of zlib, resulting in a dramatic
-# speed up for configure (from 4 minutes 22 seconds to 6 seconds).
-#
-# Note: Since this file is only used for standalone, the windows
-# specific parts were left out.
-
-FIND_PATH(ZLIB_INCLUDE_DIR zlib.h
- NO_SYSTEM_ENVIRONMENT_PATH
- )
-
-FIND_LIBRARY(ZLIB_LIBRARY z)
-
-if (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
- SET(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
- SET(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
- SET(ZLIB_FOUND "YES")
-else (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
- SET(ZLIB_FOUND "NO")
-endif (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
-
-if (ZLIB_FOUND)
- if (NOT ZLIB_FIND_QUIETLY)
- message(STATUS "Found ZLIB: ${ZLIB_LIBRARIES}")
- SET(ZLIB_FIND_QUIETLY TRUE)
- endif (NOT ZLIB_FIND_QUIETLY)
-else (ZLIB_FOUND)
- if (ZLIB_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find ZLIB library")
- endif (ZLIB_FIND_REQUIRED)
-endif (ZLIB_FOUND)
-
-mark_as_advanced(
- ZLIB_LIBRARY
- ZLIB_INCLUDE_DIR
- )
-
diff --git a/indra/cmake/FindZLIBNG.cmake b/indra/cmake/FindZLIBNG.cmake
new file mode 100644
index 0000000000..6e3c8cdddb
--- /dev/null
+++ b/indra/cmake/FindZLIBNG.cmake
@@ -0,0 +1,46 @@
+# -*- cmake -*-
+
+# - Find zlib-ng
+# Find the ZLIB includes and library
+# This module defines
+# ZLIBNG_INCLUDE_DIRS, where to find zlib.h, etc.
+# ZLIBNG_LIBRARIES, the libraries needed to use zlib.
+# ZLIBNG_FOUND, If false, do not try to use zlib.
+#
+# This FindZLIBNG is about 43 times as fast the one provided with cmake (2.8.x),
+# because it doesn't look up the version of zlib, resulting in a dramatic
+# speed up for configure (from 4 minutes 22 seconds to 6 seconds).
+#
+# Note: Since this file is only used for standalone, the windows
+# specific parts were left out.
+
+FIND_PATH(ZLIBNG_INCLUDE_DIR zlib.h
+ NO_SYSTEM_ENVIRONMENT_PATH
+ )
+
+FIND_LIBRARY(ZLIBNG_LIBRARY z)
+
+if (ZLIBNG_LIBRARY AND ZLIBNG_INCLUDE_DIR)
+ SET(ZLIBNG_INCLUDE_DIRS ${ZLIBNG_INCLUDE_DIR})
+ SET(ZLIBNG_LIBRARIES ${ZLIBNG_LIBRARY})
+ SET(ZLIBNG_FOUND "YES")
+else (ZLIBNG_LIBRARY AND ZLIBNG_INCLUDE_DIR)
+ SET(ZLIBNG_FOUND "NO")
+endif (ZLINGB_LIBRARY AND ZLIBNG_INCLUDE_DIR)
+
+if (ZLIBNG_FOUND)
+ if (NOT ZLIBNG_FIND_QUIETLY)
+ message(STATUS "Found ZLIBNG: ${ZLIBNG_LIBRARIES}")
+ SET(ZLIBNG_FIND_QUIETLY TRUE)
+ endif (NOT ZLIBNG_FIND_QUIETLY)
+else (ZLIBNG_FOUND)
+ if (ZLIBNG_FIND_REQUIRED)
+ message(FATAL_ERROR "Could not find ZLIBNG library")
+ endif (ZLIBNG_FIND_REQUIRED)
+endif (ZLIBNG_FOUND)
+
+mark_as_advanced(
+ ZLIBNG_LIBRARY
+ ZLIBNG_INCLUDE_DIR
+ )
+
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index 8900419f9b..9c8740793a 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -3,7 +3,7 @@
include(APR)
include(Boost)
include(EXPAT)
-include(ZLIB)
+include(ZLIBNG)
set(LLCOMMON_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llcommon
diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake
index 93626f689f..4e34951215 100644
--- a/indra/cmake/LLPrimitive.cmake
+++ b/indra/cmake/LLPrimitive.cmake
@@ -5,6 +5,7 @@ include(Prebuilt)
include(Boost)
use_prebuilt_binary(colladadom)
+use_prebuilt_binary(minizip-ng) # needed for colladadom
use_prebuilt_binary(pcre)
use_prebuilt_binary(libxml2)
@@ -22,6 +23,8 @@ if (WINDOWS)
optimized pcrecpp
debug pcred
optimized pcre
+ debug libminizip
+ optimized libminizip
${BOOST_SYSTEM_LIBRARIES}
)
elseif (DARWIN)
@@ -29,7 +32,7 @@ elseif (DARWIN)
llprimitive
debug collada14dom-d
optimized collada14dom
- minizip
+ minizip # for collada libminizip.a
xml2
pcrecpp
pcre
diff --git a/indra/cmake/ZLIB.cmake b/indra/cmake/ZLIBNG.cmake
index 6cff0753b2..1f46a23d92 100644
--- a/indra/cmake/ZLIB.cmake
+++ b/indra/cmake/ZLIBNG.cmake
@@ -1,17 +1,17 @@
# -*- cmake -*-
-set(ZLIB_FIND_QUIETLY ON)
-set(ZLIB_FIND_REQUIRED ON)
+set(ZLIBNG_FIND_QUIETLY ON)
+set(ZLIBNG_FIND_REQUIRED ON)
include(Prebuilt)
if (USESYSTEMLIBS)
- include(FindZLIB)
+ include(FindZLIBNG)
else (USESYSTEMLIBS)
- use_prebuilt_binary(zlib)
+ use_prebuilt_binary(zlib-ng)
if (WINDOWS)
- set(ZLIB_LIBRARIES
- debug zlibd
+ set(ZLIBNG_LIBRARIES
+ debug zlib
optimized zlib)
elseif (LINUX)
#
@@ -26,10 +26,10 @@ else (USESYSTEMLIBS)
# second whole-archive load of the archive. See viewer's
# CMakeLists.txt for more information.
#
- set(ZLIB_PRELOAD_ARCHIVES -Wl,--whole-archive z -Wl,--no-whole-archive)
- set(ZLIB_LIBRARIES z)
+ set(ZLIBNG_PRELOAD_ARCHIVES -Wl,--whole-archive z -Wl,--no-whole-archive)
+ set(ZLIBNG_LIBRARIES z)
elseif (DARWIN)
- set(ZLIB_LIBRARIES z)
+ set(ZLIBNG_LIBRARIES z)
endif (WINDOWS)
- set(ZLIB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib)
+ set(ZLIBNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib-ng)
endif (USESYSTEMLIBS)
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 766a1849f9..68378222d9 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -10,14 +10,14 @@ include(Boost)
include(LLSharedLibs)
include(JsonCpp)
include(Copy3rdPartyLibs)
-include(ZLIB)
+include(ZLIBNG)
include(URIPARSER)
include_directories(
${EXPAT_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
${JSONCPP_INCLUDE_DIR}
- ${ZLIB_INCLUDE_DIRS}
+ ${ZLIBNG_INCLUDE_DIRS}
${URIPARSER_INCLUDE_DIRS}
)
@@ -125,6 +125,7 @@ set(llcommon_SOURCE_FILES
set(llcommon_HEADER_FILES
CMakeLists.txt
+ classic_callback.h
ctype_workaround.h
fix_macros.h
indra_constants.h
@@ -290,7 +291,7 @@ target_link_libraries(
${APR_LIBRARIES}
${EXPAT_LIBRARIES}
${JSONCPP_LIBRARIES}
- ${ZLIB_LIBRARIES}
+ ${ZLIBNG_LIBRARIES}
${WINDOWS_LIBRARIES}
${BOOST_FIBER_LIBRARY}
${BOOST_CONTEXT_LIBRARY}
@@ -325,16 +326,17 @@ if (LL_TESTS)
${BOOST_CONTEXT_LIBRARY}
${BOOST_THREAD_LIBRARY}
${BOOST_SYSTEM_LIBRARY})
- LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(bitpack "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(classic_callback "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llbase64 "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llcond "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldate "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldeadmantimer "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lldependencies "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventfilter "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llheteromap "" "${test_libs}")
@@ -352,8 +354,8 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltrace "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
## llexception_test.cpp isn't a regression test, and doesn't need to be run
diff --git a/indra/llcommon/classic_callback.cpp b/indra/llcommon/classic_callback.cpp
new file mode 100644
index 0000000000..5674e0a44d
--- /dev/null
+++ b/indra/llcommon/classic_callback.cpp
@@ -0,0 +1,16 @@
+/**
+ * @file classic_callback.cpp
+ * @author Nat Goodspeed
+ * @date 2021-09-23
+ * @brief Implementation for classic_callback.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+namespace {
+
+const char dummy[] = "cpp file required to build test program";
+
+} // anonymous namespace
diff --git a/indra/llcommon/classic_callback.h b/indra/llcommon/classic_callback.h
new file mode 100644
index 0000000000..1ad6dbc58f
--- /dev/null
+++ b/indra/llcommon/classic_callback.h
@@ -0,0 +1,292 @@
+/**
+ * @file classic_callback.h
+ * @author Nat Goodspeed
+ * @date 2016-06-21
+ * @brief ClassicCallback and HeapClassicCallback
+ *
+ * This header file addresses the problem of passing a method on a C++ object
+ * to an API that requires a classic-C function pointer. Typically such a
+ * callback API accepts a void* pointer along with the function pointer, and
+ * the function pointer signature accepts a void* parameter. The API passes
+ * the caller's pointer value into the callback function so it can find its
+ * data. In C++, there are a few ways to deal with this case:
+ *
+ * - Use a static method with correct signature. If you don't need access to a
+ * specific instance, that works fine.
+ * - Store the object statically (or store a static pointer to a non-static
+ * instance). As long as you only care about one instance, that works, but
+ * starts to get a little icky. As soon as there's more than one pertinent
+ * instance, fight valiantly against the temptation to stuff the instance
+ * pointer into a static pointer variable "just for a moment."
+ * - Code a static trampoline callback function that accepts the void* user
+ * data pointer, casts it to the appropriate class type and calls the actual
+ * method on that class.
+ *
+ * ClassicCallback encapsulates the last. You need only construct a
+ * ClassicCallback instance somewhere that will survive until the callback is
+ * called, binding the target C++ callable. You then call its get_callback()
+ * and get_userdata() methods to pass an appropriate classic-C function
+ * pointer and void* user data pointer, respectively, to the old-style
+ * callback API. get_callback() synthesizes a static trampoline function
+ * that casts the user data pointer and calls the bound C++ callable.
+ *
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Copyright (c) 2016, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_CLASSIC_CALLBACK_H)
+#define LL_CLASSIC_CALLBACK_H
+
+#include <tuple>
+#include <type_traits> // std::is_same
+
+/*****************************************************************************
+* Helpers
+*****************************************************************************/
+
+// find a type in a parameter pack: http://stackoverflow.com/q/17844867/5533635
+// usage: index_of<0, sought_t, PackName...>::value
+template <int idx, typename sought, typename candidate, typename ...rest>
+struct index_of
+{
+ static constexpr int const value =
+ std::is_same<sought, candidate>::value ?
+ idx : index_of<idx + 1, sought, rest...>::value;
+};
+
+// recursion tail
+template <int idx, typename sought, typename candidate>
+struct index_of<idx, sought, candidate>
+{
+ static constexpr int const value =
+ std::is_same<sought, candidate>::value ? idx : -1;
+};
+
+/*****************************************************************************
+* ClassicCallback
+*****************************************************************************/
+/**
+ * Instantiate ClassicCallback in whatever storage will persist long enough
+ * for the callback to be called. It holds a modern C++ callable, providing a
+ * static function pointer and a USERDATA (default void*) capable of being
+ * passed through a classic-C callback API. When the static function is called
+ * with that USERDATA pointer, ClassicCallback forwards the call to the bound
+ * C++ callable.
+ *
+ * Usage:
+ * @code
+ * // callback signature required by the API of interest
+ * typedef void (*callback_t)(int, const char*, void*, double);
+ * // old-style API that accepts a classic-C callback function pointer
+ * void oldAPI(callback_t callback, void* userdata);
+ * // but I want to pass a lambda that references data local to my function!
+ * // (We don't need to name the void* parameter in the C++ callable;
+ * // ClassicCallback already used it to locate the lambda instance.)
+ * auto ccb{
+ * makeClassicCallback<callback_t>(
+ * [=](int n, const char* s, void*, double f){ ... }) };
+ * oldAPI(ccb.get_callback(), ccb.get_userdata());
+ * // If the passed callback is called before oldAPI() returns, we can now
+ * // safely destroy ccb. If the callback might be called later, consider
+ * // HeapClassicCallback instead.
+ * @endcode
+ *
+ * If you have a callable object in hand, and you want to pass that to
+ * ClassicCallback, you may either consume it by passing std::move(object), or
+ * explicitly specify a reference to that object type as the CALLABLE template
+ * parameter:
+ * @code
+ * CallableObject obj;
+ * ClassicCallback<callback_t, void*, CallableObject&> ccb{obj};
+ * @endcode
+ */
+// CALLABLE should either be deduced, e.g. by makeClassicCallback(), or
+// specified explicitly. Its default type is meaningless, coded only so we can
+// provide a useful default for USERDATA.
+template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()>
+class ClassicCallback
+{
+ typedef ClassicCallback<SIGNATURE, USERDATA, CALLABLE> self_t;
+
+public:
+ /// ClassicCallback binds any modern C++ callable.
+ ClassicCallback(CALLABLE&& callable):
+ mCallable(std::forward<CALLABLE>(callable))
+ {}
+
+ /**
+ * ClassicCallback must not itself be copied or moved! Once you've passed
+ * get_userdata() to some API, this object MUST remain at that address.
+ */
+ // However, we can't yet count on C++17 Class Template Argument Deduction,
+ // which means makeClassicCallback() is still useful, which means we MUST
+ // be able to return one to construct into caller's instance (move ctor).
+ // Possible defense: bool 'referenced' data member set by get_userdata(),
+ // with an llassert_always(! referenced) check in the move constructor.
+ ClassicCallback(ClassicCallback const&) = delete;
+ ClassicCallback(ClassicCallback&&) = default; // delete;
+ ClassicCallback& operator=(ClassicCallback const&) = delete;
+ ClassicCallback& operator=(ClassicCallback&&) = delete;
+
+ /// Call get_callback() to get the necessary function pointer.
+ SIGNATURE get_callback() const
+ {
+ // This declaration is where the compiler instantiates the correct
+ // signature for the call() function template.
+ SIGNATURE callback = call;
+ return callback;
+ }
+
+ /// Call get_userdata() to get the opaque USERDATA pointer to pass
+ /// through the classic-C callback API.
+ USERDATA get_userdata() const
+ {
+ // The USERDATA userdata is of course a pointer to this object.
+ return static_cast<USERDATA>(const_cast<self_t*>(this));
+ }
+
+protected:
+ /**
+ * This call() method accepts one or more callback arguments. It assumes
+ * the first USERDATA parameter is the userdata.
+ */
+ // Note that we're not literally using C++ perfect forwarding here -- it
+ // doesn't work to specify (Args&&... args). But that's okay because we're
+ // dealing with a classic-C callback! It's not going to pass any move-only
+ // types.
+ template <typename... Args>
+ static auto call(Args... args)
+ {
+ auto userdata = extract_userdata(std::forward<Args>(args)...);
+ // cast the userdata param to 'this' and call mCallable
+ return static_cast<self_t*>(userdata)->
+ mCallable(std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static USERDATA extract_userdata(Args... args)
+ {
+ // Search for the first USERDATA parameter type, then extract that pointer.
+ // extract value from parameter pack: http://stackoverflow.com/a/24710433/5533635
+ return std::get<index_of<0, USERDATA, Args...>::value>(std::forward_as_tuple(args...));
+ }
+
+ CALLABLE mCallable;
+};
+
+/**
+ * Usage:
+ * @code
+ * auto ccb{ makeClassicCallback<classic_callback_signature>(actual_callback) };
+ * @endcode
+ */
+template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()>
+auto makeClassicCallback(CALLABLE&& callable)
+{
+ return std::move(ClassicCallback<SIGNATURE, USERDATA, CALLABLE>
+ (std::forward<CALLABLE>(callable)));
+}
+
+/*****************************************************************************
+* HeapClassicCallback
+*****************************************************************************/
+/**
+ * HeapClassicCallback is like ClassicCallback, with this exception: it MUST
+ * be allocated on the heap because, once the callback has been called, it
+ * deletes itself. This addresses the problem of a callback whose lifespan
+ * must persist beyond the scope in which the callback API is engaged -- but
+ * naturally this callback must be called exactly ONCE.
+ *
+ * Usage:
+ * @code
+ * // callback signature required by the API of interest
+ * typedef void (*callback_t)(int, const char*, void*, double);
+ * // here's the old-style API
+ * void oldAPI(callback_t callback, void* userdata);
+ * // want to call someObjPtr->method() when oldAPI() fires the callback,
+ * // sometime in the future after the enclosing function has returned
+ * auto ccb{
+ * makeHeapClassicCallback<callback_t>(
+ * [someObjPtr](int n, const char* s, void*, double f)
+ * { someObjPtr->method(); }) };
+ * oldAPI(ccb.get_callback(), ccb.get_userdata());
+ * // We don't need a smart pointer for ccb, because it will be deleted once
+ * // oldAPI() calls the bound lambda. HeapClassicCallback is for when the
+ * // callback will be called exactly once. If the classic API might call the
+ * // passed callback more than once -- or might never call it at all --
+ * // manually construct a ClassicCallback on the heap and manage its lifespan
+ * // explicitly.
+ * @endcode
+ */
+template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()>
+class HeapClassicCallback: public ClassicCallback<SIGNATURE, USERDATA, CALLABLE>
+{
+ typedef ClassicCallback<SIGNATURE, USERDATA, CALLABLE> super;
+ typedef HeapClassicCallback<SIGNATURE, USERDATA, CALLABLE> self_t;
+
+ // This destructor is intentionally private to prevent allocation anywhere
+ // but the heap. (The Design and Evolution of C++, section 11.4.2: Control
+ // of Allocation)
+ ~HeapClassicCallback() {}
+
+public:
+ HeapClassicCallback(CALLABLE&& callable):
+ super(std::forward<CALLABLE>(callable))
+ {}
+
+ // makeHeapClassicCallback() only needs to return a pointer -- not an
+ // instance -- so we can lock down our move constructor too.
+ HeapClassicCallback(HeapClassicCallback&&) = delete;
+
+ /// Replicate get_callback() from the base class because we must
+ /// instantiate OUR call() function template.
+ SIGNATURE get_callback() const
+ {
+ // This declaration is where the compiler instantiates the correct
+ // signature for the call() function template.
+ SIGNATURE callback = call;
+ return callback;
+ }
+
+ /// Replicate get_userdata() from the base class because our call()
+ /// method must be able to reconstitute a pointer to this subclass.
+ USERDATA get_userdata() const
+ {
+ // The USERDATA userdata is of course a pointer to this object.
+ return static_cast<const USERDATA>(const_cast<self_t*>(this));
+ }
+
+private:
+ // call() uses a helper class to delete the HeapClassicCallback when done,
+ // for two reasons. Most importantly, this deletes even if the callback
+ // throws an exception. But also, call() must directly return the callback
+ // result for return-type deduction.
+ struct Destroyer
+ {
+ Destroyer(self_t* p): mPtr(p) {}
+ ~Destroyer() { delete mPtr; }
+
+ self_t* mPtr;
+ };
+
+ template <typename... Args>
+ static auto call(Args... args)
+ {
+ // extract userdata at this level too
+ USERDATA userdata = super::extract_userdata(std::forward<Args>(args)...);
+ // arrange to delete it when we leave by whatever means
+ Destroyer destroy(static_cast<self_t*>(userdata));
+
+ return super::call(std::forward<Args>(args)...);
+ }
+};
+
+template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()>
+auto makeHeapClassicCallback(CALLABLE&& callable)
+{
+ return new HeapClassicCallback<SIGNATURE, USERDATA, CALLABLE>
+ (std::forward<CALLABLE>(callable));
+}
+
+#endif /* ! defined(LL_CLASSIC_CALLBACK_H) */
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 022a5d4659..8b4a0ee6d8 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -37,7 +37,7 @@
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
#else
-# include "zlib/zlib.h" // for davep's dirty little zip functions
+# include "zlib-ng/zlib.h" // for davep's dirty little zip functions
#endif
#if !LL_WINDOWS
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 2ca15a31c6..bede5beb8d 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -36,7 +36,7 @@
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
#else
-# include "zlib/zlib.h"
+# include "zlib-ng/zlib.h"
#endif
#include "llprocessor.h"
@@ -441,6 +441,8 @@ LLOSInfo::LLOSInfo() :
dotted_version_string << mMajorVer << "." << mMinorVer << "." << mBuild;
mOSVersionString.append(dotted_version_string.str());
+ mOSBitness = is64Bit() ? 64 : 32;
+ LL_INFOS("LLOSInfo") << "OS bitness: " << mOSBitness << LL_ENDL;
}
#ifndef LL_WINDOWS
@@ -496,6 +498,11 @@ const std::string& LLOSInfo::getOSVersionString() const
return mOSVersionString;
}
+const S32 LLOSInfo::getOSBitness() const
+{
+ return mOSBitness;
+}
+
//static
U32 LLOSInfo::getProcessVirtualSizeKB()
{
@@ -549,6 +556,25 @@ U32 LLOSInfo::getProcessResidentSizeKB()
return resident_size;
}
+//static
+bool LLOSInfo::is64Bit()
+{
+#if LL_WINDOWS
+#if defined(_WIN64)
+ return true;
+#elif defined(_WIN32)
+ // 32-bit viewer may be run on both 32-bit and 64-bit Windows, need to elaborate
+ BOOL f64 = FALSE;
+ return IsWow64Process(GetCurrentProcess(), &f64) && f64;
+#else
+ return false;
+#endif
+#else // ! LL_WINDOWS
+ // we only build a 64-bit mac viewer and currently we don't build for linux at all
+ return true;
+#endif
+}
+
LLCPUInfo::LLCPUInfo()
{
std::ostringstream out;
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 5ab97939b9..cb92cb0ac6 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -51,6 +51,8 @@ public:
const std::string& getOSStringSimple() const;
const std::string& getOSVersionString() const;
+
+ const S32 getOSBitness() const;
S32 mMajorVer;
S32 mMinorVer;
@@ -59,6 +61,7 @@ public:
#ifndef LL_WINDOWS
static S32 getMaxOpenFiles();
#endif
+ static bool is64Bit();
static U32 getProcessVirtualSizeKB();
static U32 getProcessResidentSizeKB();
@@ -66,6 +69,7 @@ private:
std::string mOSString;
std::string mOSStringSimple;
std::string mOSVersionString;
+ S32 mOSBitness;
};
diff --git a/indra/llcommon/tests/classic_callback_test.cpp b/indra/llcommon/tests/classic_callback_test.cpp
new file mode 100644
index 0000000000..c060775c24
--- /dev/null
+++ b/indra/llcommon/tests/classic_callback_test.cpp
@@ -0,0 +1,144 @@
+/**
+ * @file classic_callback_test.cpp
+ * @author Nat Goodspeed
+ * @date 2021-09-22
+ * @brief Test ClassicCallback and HeapClassicCallback.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "classic_callback.h"
+// STL headers
+#include <iostream>
+#include <string>
+// std headers
+// external library headers
+// other Linden headers
+#include "../test/lltut.h"
+
+/*****************************************************************************
+* example callback
+*****************************************************************************/
+// callback_t is part of the specification of someAPI()
+typedef void (*callback_t)(const char*, void*);
+void someAPI(callback_t callback, void* userdata)
+{
+ callback("called", userdata);
+}
+
+// C++ callable I want as the actual callback
+struct MyCallback
+{
+ void operator()(const char* msg, void*)
+ {
+ mMsg = msg;
+ }
+
+ void callback_with_extra(const std::string& extra, const char* msg)
+ {
+ mMsg = extra + ' ' + msg;
+ }
+
+ std::string mMsg;
+};
+
+/*****************************************************************************
+* example callback accepting several params, and void* userdata isn't first
+*****************************************************************************/
+typedef std::string (*complex_callback)(int, const char*, void*, double);
+std::string otherAPI(complex_callback callback, void* userdata)
+{
+ return callback(17, "hello world", userdata, 3.0);
+}
+
+// struct into which we can capture complex_callback params
+static struct Data
+{
+ void set(int i, const char* s, double f)
+ {
+ mi = i;
+ ms = s;
+ mf = f;
+ }
+
+ void clear() { set(0, "", 0.0); }
+
+ int mi;
+ std::string ms;
+ double mf;
+} sData;
+
+// C++ callable I want to pass
+struct OtherCallback
+{
+ std::string operator()(int num, const char* str, void*, double approx)
+ {
+ sData.set(num, str, approx);
+ return "hello back!";
+ }
+};
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct classic_callback_data
+ {
+ };
+ typedef test_group<classic_callback_data> classic_callback_group;
+ typedef classic_callback_group::object object;
+ classic_callback_group classic_callbackgrp("classic_callback");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("ClassicCallback");
+ // engage someAPI(MyCallback())
+ auto ccb{ makeClassicCallback<callback_t>(MyCallback()) };
+ someAPI(ccb.get_callback(), ccb.get_userdata());
+ // Unfortunately, with the side effect confined to the bound
+ // MyCallback instance, that call was invisible. Bind a reference to a
+ // named instance by specifying a ref type.
+ MyCallback mcb;
+ ClassicCallback<callback_t, void*, MyCallback&> ccb2(mcb);
+ someAPI(ccb2.get_callback(), ccb2.get_userdata());
+ ensure_equals("failed to call through ClassicCallback", mcb.mMsg, "called");
+
+ // try with HeapClassicCallback
+ mcb.mMsg.clear();
+ auto hcbp{ makeHeapClassicCallback<callback_t>(mcb) };
+ someAPI(hcbp->get_callback(), hcbp->get_userdata());
+ ensure_equals("failed to call through HeapClassicCallback", mcb.mMsg, "called");
+
+ // lambda
+ // The tricky thing here is that a lambda is an unspecified type, so
+ // you can't declare a ClassicCallback<signature, void*, that type>.
+ mcb.mMsg.clear();
+ auto xcb(
+ makeClassicCallback<callback_t>(
+ [&mcb](const char* msg, void*)
+ { mcb.callback_with_extra("extra", msg); }));
+ someAPI(xcb.get_callback(), xcb.get_userdata());
+ ensure_equals("failed to call lambda", mcb.mMsg, "extra called");
+
+ // engage otherAPI(OtherCallback())
+ OtherCallback ocb;
+ // Instead of specifying a reference type for the bound CALLBACK, as
+ // with ccb2 above, you can alternatively move the callable object
+ // into the ClassicCallback (of course AFTER any other reference).
+ // That's why OtherCallback uses external data for its observable side
+ // effect.
+ auto occb{ makeClassicCallback<complex_callback>(std::move(ocb)) };
+ std::string result{ otherAPI(occb.get_callback(), occb.get_userdata()) };
+ ensure_equals("failed to return callback result", result, "hello back!");
+ ensure_equals("failed to set int", sData.mi, 17);
+ ensure_equals("failed to set string", sData.ms, "hello world");
+ ensure_equals("failed to set double", sData.mf, 3.0);
+ }
+} // namespace tut
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 6a301ad50d..c591680250 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -7,7 +7,7 @@ include(GoogleMock)
include(CURL)
include(OpenSSL)
include(NGHTTP2)
-include(ZLIB)
+include(ZLIBNG)
include(LLCoreHttp)
include(LLAddBuildTest)
include(LLMessage)
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index 8883317751..436b8dd1a2 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -9,7 +9,7 @@ include(LLMath)
include(LLFileSystem)
include(LLKDU)
include(LLImageJ2COJ)
-include(ZLIB)
+include(ZLIBNG)
include(LLAddBuildTest)
include(bugsplat)
include(Tut)
@@ -20,7 +20,7 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${PNG_INCLUDE_DIRS}
- ${ZLIB_INCLUDE_DIRS}
+ ${ZLIBNG_INCLUDE_DIRS}
)
set(llimage_SOURCE_FILES
@@ -74,7 +74,7 @@ target_link_libraries(llimage
${LLCOMMON_LIBRARIES}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
- ${ZLIB_LIBRARIES}
+ ${ZLIBNG_LIBRARIES}
)
# Add tests
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 702a1b5238..239b2aa878 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -35,7 +35,7 @@
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
#else
-# include "zlib/zlib.h"
+# include "zlib-ng/zlib.h"
#endif
std::string model_names[] =
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index cdaf03ebde..6b9bf425d2 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1363,6 +1363,9 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
+
+ virtual void onFocusLost();
+ virtual void setFocus(BOOL b);
};
LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const Params& p) :
@@ -1517,6 +1520,21 @@ BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask)
return handled;
}
+void LLMenuItemBranchDownGL::onFocusLost()
+{
+ // needed for tab-based selection
+ LLMenuItemBranchGL::onFocusLost();
+ LLMenuGL::setKeyboardMode(FALSE);
+ setHighlight(FALSE);
+}
+
+void LLMenuItemBranchDownGL::setFocus(BOOL b)
+{
+ // needed for tab-based selection
+ LLMenuItemBranchGL::setFocus(b);
+ LLMenuGL::setKeyboardMode(b);
+ setHighlight(b);
+}
BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask)
{
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 2e2e1b9833..a4e83b42b4 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -457,6 +457,8 @@ public:
void setSkipLinkUnderline(bool skip_link_underline) { mSkipLinkUnderline = skip_link_underline; }
bool getSkipLinkUnderline() { return mSkipLinkUnderline; }
+ void setParseURLs(bool parse_urls) { mParseHTML = parse_urls; }
+
void setPlainText(bool value) { mPlainText = value;}
bool getPlainText() const { return mPlainText; }
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index 12a6baa3e6..81e938edbe 100644
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -229,7 +229,7 @@ S32 LLDXHardware::getMBVideoMemoryViaWMI()
}
//Getting the version of graphics controller driver via WMI
-std::string LLDXHardware::getDriverVersionWMI()
+std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
{
std::string mDriverVersion;
HRESULT hrCoInitialize = S_OK;
@@ -325,15 +325,68 @@ std::string LLDXHardware::getDriverVersionWMI()
{
break; // If quantity less then 1.
}
+
+ if (vendor != GPU_ANY)
+ {
+ VARIANT vtCaptionProp;
+ // Might be preferable to check "AdapterCompatibility" here instead of caption.
+ hr = pclsObj->Get(L"Caption", 0, &vtCaptionProp, 0, 0);
+
+ if (FAILED(hr))
+ {
+ LL_WARNS("AppInit") << "Query for Caption property failed." << " Error code = 0x" << hr << LL_ENDL;
+ pSvc->Release();
+ pLoc->Release();
+ CoUninitialize();
+ return std::string(); // Program has failed.
+ }
+
+ // use characters in the returned driver version
+ BSTR caption(vtCaptionProp.bstrVal);
+
+ //convert BSTR to std::string
+ std::wstring ws(caption, SysStringLen(caption));
+ std::string caption_str(ws.begin(), ws.end());
+ LLStringUtil::toLower(caption_str);
+
+ bool found = false;
+ switch (vendor)
+ {
+ case GPU_INTEL:
+ found = caption_str.find("intel") != std::string::npos;
+ break;
+ case GPU_NVIDIA:
+ found = caption_str.find("nvidia") != std::string::npos;
+ break;
+ case GPU_AMD:
+ found = caption_str.find("amd") != std::string::npos
+ || caption_str.find("ati ") != std::string::npos
+ || caption_str.find("radeon") != std::string::npos;
+ break;
+ default:
+ break;
+ }
- VARIANT vtProp;
+ if (found)
+ {
+ VariantClear(&vtCaptionProp);
+ }
+ else
+ {
+ VariantClear(&vtCaptionProp);
+ pclsObj->Release();
+ continue;
+ }
+ }
- // Get the value of the Name property
- hr = pclsObj->Get(L"DriverVersion", 0, &vtProp, 0, 0);
+ VARIANT vtVersionProp;
+
+ // Get the value of the DriverVersion property
+ hr = pclsObj->Get(L"DriverVersion", 0, &vtVersionProp, 0, 0);
if (FAILED(hr))
{
- LL_WARNS("AppInit") << "Query for name property failed." << " Error code = 0x" << hr << LL_ENDL;
+ LL_WARNS("AppInit") << "Query for DriverVersion property failed." << " Error code = 0x" << hr << LL_ENDL;
pSvc->Release();
pLoc->Release();
CoUninitialize();
@@ -341,7 +394,7 @@ std::string LLDXHardware::getDriverVersionWMI()
}
// use characters in the returned driver version
- BSTR driverVersion(vtProp.bstrVal);
+ BSTR driverVersion(vtVersionProp.bstrVal);
//convert BSTR to std::string
std::wstring ws(driverVersion, SysStringLen(driverVersion));
@@ -354,10 +407,19 @@ std::string LLDXHardware::getDriverVersionWMI()
}
else if (mDriverVersion != str)
{
- LL_WARNS("DriverVersion") << "Different versions of drivers. Version of second driver : " << str << LL_ENDL;
+ if (vendor == GPU_ANY)
+ {
+ // Expected from systems with gpus from different vendors
+ LL_INFOS("DriverVersion") << "Multiple video drivers detected. Version of second driver: " << str << LL_ENDL;
+ }
+ else
+ {
+ // Not Expected!
+ LL_WARNS("DriverVersion") << "Multiple video drivers detected from same vendor. Version of second driver : " << str << LL_ENDL;
+ }
}
- VariantClear(&vtProp);
+ VariantClear(&vtVersionProp);
pclsObj->Release();
}
diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h
index 1cb687e3b6..9cec3e2f1b 100644
--- a/indra/llwindow/lldxhardware.h
+++ b/indra/llwindow/lldxhardware.h
@@ -88,7 +88,15 @@ public:
// vram_only TRUE does a "light" probe.
BOOL getInfo(BOOL vram_only);
- std::string getDriverVersionWMI();
+ // WMI can return multiple GPU drivers
+ // specify which one to output
+ typedef enum {
+ GPU_INTEL,
+ GPU_NVIDIA,
+ GPU_AMD,
+ GPU_ANY
+ } EGPUVendor;
+ std::string getDriverVersionWMI(EGPUVendor vendor);
S32 getVRAM() const { return mVRAM; }
diff --git a/indra/mac_crash_logger/README.txt b/indra/mac_crash_logger/README.txt
deleted file mode 100644
index 6932a8d9c3..0000000000
--- a/indra/mac_crash_logger/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-This component is no longer used in Linden Lab builds.
-Change requests to support continued use by open source
-builds are welcome.
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 5a06106de3..88808bede2 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -55,7 +55,7 @@ include(UnixInstall)
include(ViewerMiscLibs)
include(ViewerManager)
include(VisualLeakDetector)
-include(ZLIB)
+include(ZLIBNG)
include(URIPARSER)
if (NOT HAVOK_TPV)
@@ -1848,10 +1848,6 @@ if (WINDOWS)
winmm_shim
)
- if (NOT USE_BUGSPLAT)
- LIST(APPEND COPY_INPUT_DEPENDENCIES windows-crash-logger)
- endif (NOT USE_BUGSPLAT)
-
if (ADDRESS_SIZE EQUAL 64)
list(APPEND COPY_INPUT_DEPENDENCIES
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll
@@ -2018,14 +2014,14 @@ endif (WINDOWS)
#
# We generally want the newest version of the library to provide all symbol
# resolution. To that end, when using static archives, the *_PRELOAD_ARCHIVES
-# variables, PNG_PRELOAD_ARCHIVES and ZLIB_PRELOAD_ARCHIVES, get the archives
+# variables, PNG_PRELOAD_ARCHIVES and ZLIBNG_PRELOAD_ARCHIVES, get the archives
# dumped into the target binary and runtime lookup will find the most
# modern version.
target_link_libraries(${VIEWER_BINARY_NAME}
${LEGACY_STDIO_LIBS}
${PNG_PRELOAD_ARCHIVES}
- ${ZLIB_PRELOAD_ARCHIVES}
+ ${ZLIBNG_PRELOAD_ARCHIVES}
${URIPARSER_PRELOAD_ARCHIVES}
${GOOGLE_PERFTOOLS_LIBRARIES}
${LLAUDIO_LIBRARIES}
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 50e0d1d935..daab725ce6 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -713,6 +713,12 @@ void LLAgent::moveYaw(F32 mag, bool reset_view)
setControlFlags(AGENT_CONTROL_YAW_NEG);
}
+ U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
+ if ((getControlFlags() & mask) == mask)
+ {
+ gAgentCamera.setYawKey(0);
+ }
+
if (reset_view)
{
gAgentCamera.resetView();
@@ -2004,6 +2010,27 @@ void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32
//
gAgentCamera.updateLookAt(mouse_x, mouse_y);
+
+ // When agent has no parents, position updates come from setPositionAgent()
+ // But when agent has a parent (ex: is seated), position remains unchanged
+ // relative to parent and no parent's position update trigger
+ // setPositionAgent().
+ // But EEP's sky track selection still needs an update if agent has a parent
+ // and parent moves (ex: vehicles).
+ if (isAgentAvatarValid()
+ && gAgentAvatarp->getParent()
+ && !mOnPositionChanged.empty()
+ )
+ {
+ LLVector3d new_position = getPositionGlobal();
+ if ((mLastTestGlobal - new_position).lengthSquared() > 1.0)
+ {
+ // If the position has changed by more than 1 meter since the last time we triggered.
+ // filters out some noise.
+ mLastTestGlobal = new_position;
+ mOnPositionChanged(mFrameAgent.getOrigin(), new_position);
+ }
+ }
}
// friends and operators
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index ed6c3c307f..7348b4f496 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -404,10 +404,9 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
LLQuaternion obj_rot = object->getRenderRotation();
LLVector3 obj_pos = object->getRenderPosition();
- BOOL is_avatar = object->isAvatar();
// if is avatar - don't do any funk heuristics to position the focal point
// see DEV-30589
- if (is_avatar)
+ if (object->isAvatar() || (object->isAnimatedObject() && object->getControlAvatar()))
{
return original_focus_point - obj_pos;
}
@@ -532,7 +531,6 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
// or keep the focus point in the object middle when (relatively) far
// NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars
// is almost always "tumble about middle" and not "spin around surface point"
- if (!is_avatar)
{
LLVector3 obj_rel = original_focus_point - object->getRenderPosition();
@@ -1420,7 +1418,7 @@ void LLAgentCamera::updateCamera()
F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
- if (!mFocusObject) // we differentiate on avatar mode
+ if (mFocusOnAvatar && !mFocusObject) // we differentiate on avatar mode
{
// for avatar-relative focus, we smooth in avatar space -
// the avatar moves too jerkily w/r/t global space to smooth there.
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index be168ff5dd..2e769dc737 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -37,6 +37,7 @@
#include "llgesturemgr.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "lllocaltextureobject.h"
@@ -1582,6 +1583,14 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
return;
}
+ if (!item->isFinished())
+ {
+ LL_WARNS() << "Tried to edit wearable that isn't loaded" << LL_ENDL;
+ // Restart fetch or put item to the front
+ LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false);
+ return;
+ }
+
LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
if (!wearable)
{
@@ -1595,6 +1604,18 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
return;
}
+ S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE);
+ S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR);
+ S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES);
+ S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN);
+ if (!shape_count || !hair_count || !eye_count || !skin_count)
+ {
+ // Don't let user edit wearables if avatar is cloud due to missing parts.
+ // Let user edit wearables if avatar is cloud due to missing textures.
+ LL_WARNS() << "Cannot modify wearable. Avatar is cloud and missing parts." << LL_ENDL;
+ return;
+ }
+
const BOOL disable_camera_switch = LLWearableType::getInstance()->getDisableCameraSwitch(wearable->getType());
LLPanel* panel = LLFloaterSidePanelContainer::getPanel("appearance");
LLSidepanelAppearance::editWearable(wearable, panel, disable_camera_switch);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c9d852686e..7af574dab8 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3164,7 +3164,28 @@ LLSD LLAppViewer::getViewerInfo() const
info["GRAPHICS_CARD"] = ll_safe_string((const char*)(glGetString(GL_RENDERER)));
#if LL_WINDOWS
- std::string drvinfo = gDXHardware.getDriverVersionWMI();
+ std::string drvinfo;
+
+ if (gGLManager.mIsIntel)
+ {
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_INTEL);
+ }
+ else if (gGLManager.mIsNVIDIA)
+ {
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_NVIDIA);
+ }
+ else if (gGLManager.mIsATI)
+ {
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_AMD);
+ }
+
+ if (drvinfo.empty())
+ {
+ // Generic/substitute windows driver? Unknown vendor?
+ LL_WARNS("DriverVersion") << "Vendor based driver search failed, searching for any driver" << LL_ENDL;
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_ANY);
+ }
+
if (!drvinfo.empty())
{
info["GRAPHICS_DRIVER_VERSION"] = drvinfo;
@@ -4875,13 +4896,18 @@ void LLAppViewer::idle()
}
}
+
+ // Update layonts, handle mouse events, tooltips, e t c
+ // updateUI() needs to be called even in case viewer disconected
+ // since related notification still needs handling and allows
+ // opening chat.
+ gViewerWindow->updateUI();
+
if (gDisconnected)
{
return;
}
- gViewerWindow->updateUI();
-
if (gTeleportDisplay)
{
return;
diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp
index 4b6c855bde..1846238d93 100644
--- a/indra/newview/llaudiosourcevo.cpp
+++ b/indra/newview/llaudiosourcevo.cpp
@@ -34,6 +34,7 @@
#include "llmutelist.h"
#include "llviewercontrol.h"
#include "llviewerparcelmgr.h"
+#include "llvoavatarself.h"
LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp)
: LLAudioSource(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX),
@@ -141,11 +142,36 @@ void LLAudioSourceVO::updateMute()
LLVector3d pos_global = getPosGlobal();
F32 cutoff = mObjectp->getSoundCutOffRadius();
- if ((cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff)) // consider cutoff below 0.1m as off
- || !LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
- {
- mute = true;
- }
+ // Object can specify radius at which it turns off
+ // consider cutoff below 0.1m as 'cutoff off'
+ if (cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff))
+ {
+ mute = true;
+ }
+ // check if parcel allows sounds to pass border
+ else if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
+ {
+ if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ {
+ // Check if agent is riding this object
+ // Agent can ride something out of region border and canHearSound
+ // will treat object as not being part of agent's parcel.
+ LLViewerObject *sound_root = (LLViewerObject*)mObjectp->getRoot();
+ LLViewerObject *agent_root = (LLViewerObject*)gAgentAvatarp->getRoot();
+ if (sound_root != agent_root)
+ {
+ mute = true;
+ }
+ else
+ {
+ LL_INFOS() << "roots identical" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mute = true;
+ }
+ }
if (!mute)
{
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index c110e0d815..64d3f805a0 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -558,9 +558,15 @@ public:
mTimeBoxTextBox = getChild<LLTextBox>("time_box");
mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance());
- llassert(mInfoCtrl != NULL);
- mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl));
- mInfoCtrl->setVisible(FALSE);
+ if (mInfoCtrl)
+ {
+ mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl));
+ mInfoCtrl->setVisible(FALSE);
+ }
+ else
+ {
+ LL_ERRS() << "Failed to create an interface element due to missing or corrupted file inspector_info_ctrl.xml" << LL_ENDL;
+ }
return LLPanel::postBuild();
}
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index cca6b9ce32..4c88e5383f 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -772,6 +772,14 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
}
LLFavoritesOrderStorage::instance().mPrevFavorites = mItems;
mGetPrevItems = false;
+
+ if (LLFavoritesOrderStorage::instance().isStorageUpdateNeeded())
+ {
+ if (!mItemsChangedTimer.getStarted())
+ {
+ mItemsChangedTimer.start();
+ }
+ }
}
const LLButton::Params& button_params = getButtonParams();
@@ -1650,7 +1658,6 @@ void LLFavoritesOrderStorage::load()
llifstream in_file;
in_file.open(filename.c_str());
LLSD fav_llsd;
- LLSD user_llsd;
if (in_file.is_open())
{
LLSDSerialize::fromXML(fav_llsd, in_file);
@@ -1660,12 +1667,12 @@ void LLFavoritesOrderStorage::load()
in_file.close();
if (fav_llsd.isMap() && fav_llsd.has(gAgentUsername))
{
- user_llsd = fav_llsd[gAgentUsername];
+ mStorageFavorites = fav_llsd[gAgentUsername];
S32 index = 0;
bool needs_validation = gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin");
- for (LLSD::array_iterator iter = user_llsd.beginArray();
- iter != user_llsd.endArray(); ++iter)
+ for (LLSD::array_iterator iter = mStorageFavorites.beginArray();
+ iter != mStorageFavorites.endArray(); ++iter)
{
// Validation
LLUUID fv_id = iter->get("id").asUUID();
@@ -2050,6 +2057,23 @@ void LLFavoritesOrderStorage::showFavoritesOnLoginChanged(BOOL show)
}
}
+bool LLFavoritesOrderStorage::isStorageUpdateNeeded()
+{
+ if (!mRecreateFavoriteStorage)
+ {
+ for (LLSD::array_iterator iter = mStorageFavorites.beginArray();
+ iter != mStorageFavorites.endArray(); ++iter)
+ {
+ if (mFavoriteNames[iter->get("id").asUUID()] != iter->get("name").asString())
+ {
+ mRecreateFavoriteStorage = true;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
{
if (mTargetLandmarkId.isNull()) return;
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2d7ba9df67..3b439b31fd 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -226,8 +226,11 @@ public:
BOOL saveFavoritesRecord(bool pref_changed = false);
void showFavoritesOnLoginChanged(BOOL show);
- LLInventoryModel::item_array_t mPrevFavorites;
+ bool isStorageUpdateNeeded();
+ LLInventoryModel::item_array_t mPrevFavorites;
+ LLSD mStorageFavorites;
+ bool mRecreateFavoriteStorage;
const static S32 NO_INDEX;
static bool mSaveOnExit;
@@ -254,7 +257,6 @@ private:
slurls_map_t mSLURLs;
std::set<LLUUID> mMissingSLURLs;
bool mIsDirty;
- bool mRecreateFavoriteStorage;
struct IsNotInFavorites
{
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index e075a311c2..2e9c804b21 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -389,7 +389,8 @@ void LLVolumeImplFlexible::doIdleUpdate()
U64 throttling_delay = (virtual_frame_num + id) % update_period;
if ((throttling_delay == 0 && mLastFrameNum < virtual_frame_num) //one or more virtual frames per frame
- || (mLastFrameNum + update_period < virtual_frame_num)) // missed virtual frame
+ || (mLastFrameNum + update_period < virtual_frame_num) // missed virtual frame
+ || mLastFrameNum > virtual_frame_num) // overflow
{
// We need mLastFrameNum to compensate for 'unreliable time' and to filter 'duplicate' frames
// If happened too late, subtract throttling_delay (it is zero otherwise)
@@ -787,11 +788,7 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
volume->updateRelativeXform();
- if (mRenderRes > -1)
- {
- LL_RECORD_BLOCK_TIME(FTM_DO_FLEXIBLE_UPDATE);
- doFlexibleUpdate();
- }
+ doFlexibleUpdate();
// Object may have been rotated, which means it needs a rebuild. See SL-47220
BOOL rotated = FALSE;
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index af0e56e448..925eaf44fa 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -452,7 +452,8 @@ BOOL LLPanelLandGeneral::postBuild()
mEditDesc = getChild<LLTextEditor>("Description");
mEditDesc->setCommitOnFocusLost(TRUE);
- mEditDesc->setCommitCallback(onCommitAny, this);
+ mEditDesc->setCommitCallback(onCommitAny, this);
+ mEditDesc->setContentTrusted(false);
// No prevalidate function - historically the prevalidate function was broken,
// allowing residents to put in characters like U+2661 WHITE HEART SUIT, so
// preserve that ability.
@@ -749,6 +750,7 @@ void LLPanelLandGeneral::refresh()
BOOL can_edit_identity = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_IDENTITY);
mEditName->setEnabled(can_edit_identity);
mEditDesc->setEnabled(can_edit_identity);
+ mEditDesc->setParseURLs(!can_edit_identity);
BOOL can_edit_agent_only = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_NO_POWERS);
mBtnSetGroup->setEnabled(can_edit_agent_only && !parcel->getIsGroupOwned());
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 19080f05c0..296e155d28 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -2108,6 +2108,8 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
LLTextBox* region_landtype = getChild<LLTextBox>("region_landtype_text");
region_landtype->setText(region->getLocalizedSimProductName());
+
+ getChild<LLButton>("reset_covenant")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate()));
// let the parent class handle the general data collection.
bool rv = LLPanelRegionInfo::refreshFromRegion(region);
diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index f78a5cc64e..cb7031971b 100644
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -28,16 +28,17 @@
#include "llinspectobject.h"
// Viewer
+#include "llagent.h" // To standup
#include "llfloatersidepanelcontainer.h"
#include "llinspect.h"
#include "llmediaentry.h"
-#include "llnotificationsutil.h" // *TODO: Eliminate, add LLNotificationsUtil wrapper
#include "llselectmgr.h"
#include "llslurl.h"
#include "llviewermenu.h" // handle_object_touch(), handle_buy()
#include "llviewermedia.h"
#include "llviewermediafocus.h"
#include "llviewerobjectlist.h" // to select the requested object
+#include "llvoavatarself.h"
// Linden libraries
#include "llbutton.h" // setLabel(), not virtual!
@@ -635,7 +636,31 @@ void LLInspectObject::onClickTouch()
void LLInspectObject::onClickSit()
{
- handle_object_sit_or_stand();
+ bool is_sitting = false;
+ if (mObjectSelection)
+ {
+ LLSelectNode* node = mObjectSelection->getFirstRootNode();
+ if (node && node->mValid)
+ {
+ LLViewerObject* root_object = node->getObject();
+ if (root_object
+ && isAgentAvatarValid()
+ && gAgentAvatarp->isSitting()
+ && gAgentAvatarp->getRoot() == root_object)
+ {
+ is_sitting = true;
+ }
+ }
+ }
+
+ if (is_sitting)
+ {
+ gAgent.standUp();
+ }
+ else
+ {
+ handle_object_sit(mObjectID);
+ }
closeFloater();
}
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 375daf60f8..04d3236bf1 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -97,6 +97,7 @@ BOOL LLPanelGroupGeneral::postBuild()
mEditCharter->setCommitCallback(onCommitAny, this);
mEditCharter->setFocusReceivedCallback(boost::bind(onFocusEdit, _1, this));
mEditCharter->setFocusChangedCallback(boost::bind(onFocusEdit, _1, this));
+ mEditCharter->setContentTrusted(false);
}
// Options
@@ -575,7 +576,8 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
if (mEditCharter)
{
- mEditCharter->setText(gdatap->mCharter);
+ mEditCharter->setParseURLs(!mAllowEdit || !can_change_ident);
+ mEditCharter->setText(gdatap->mCharter);
}
resetDirty();
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 381b80fb66..deb1a963a0 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -92,44 +92,6 @@ LLPointer<LLCredential> load_user_credentials(std::string &user_key)
}
}
-// keys are lower case to be case insensitive so they are not always
-// identical to names which retain user input, like:
-// "AwEsOmE Resident" -> "awesome_resident"
-std::string get_user_key_from_name(const std::string &username)
-{
- std::string key = username;
- LLStringUtil::trim(key);
- LLStringUtil::toLower(key);
- if (!LLGridManager::getInstance()->isSystemGrid())
- {
- size_t separator_index = username.find_first_of(" ");
- if (separator_index == username.npos)
- {
- // CRED_IDENTIFIER_TYPE_ACCOUNT
- return key;
- }
- }
- // CRED_IDENTIFIER_TYPE_AGENT
- size_t separator_index = username.find_first_of(" ._");
- std::string first = username.substr(0, separator_index);
- std::string last;
- if (separator_index != username.npos)
- {
- last = username.substr(separator_index + 1, username.npos);
- LLStringUtil::trim(last);
- }
- else
- {
- // ...on Linden grids, single username users as considered to have
- // last name "Resident"
- // *TODO: Make login.cgi support "account_name" like above
- last = "resident";
- }
-
- key = first + "_" + last;
- return key;
-}
-
class LLLoginLocationAutoHandler : public LLCommandHandler
{
public:
@@ -690,39 +652,6 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
LL_INFOS("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
// determine if the username is a first/last form or not.
size_t separator_index = username.find_first_of(' ');
- if (separator_index == username.npos
- && !LLGridManager::getInstance()->isSystemGrid())
- {
- LL_INFOS("Credentials", "Authentication") << "account: " << username << LL_ENDL;
- // single username, so this is a 'clear' identifier
- identifier["type"] = CRED_IDENTIFIER_TYPE_ACCOUNT;
- identifier["account_name"] = username;
-
- if (LLPanelLogin::sInstance->mPasswordModified)
- {
- // password is plaintext
- authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
- authenticator["secret"] = password;
- }
- else
- {
- credential = load_user_credentials(username);
- if (credential.notNull())
- {
- authenticator = credential->getAuthenticator();
- if (authenticator.emptyMap())
- {
- // Likely caused by user trying to log in to non-system grid
- // with unsupported name format, just retry
- LL_WARNS() << "Authenticator failed to load for: " << username << LL_ENDL;
- // password is plaintext
- authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
- authenticator["secret"] = password;
- }
- }
- }
- }
- else
{
// Be lenient in terms of what separators we allow for two-word names
// and allow legacy users to login with firstname.lastname
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 831c89b005..64f1fc9b90 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -1672,8 +1672,19 @@ void LLPanelObject::sendPosition(BOOL btn_down)
// Make sure new position is in a valid region, so the object
// won't get dumped by the simulator.
LLVector3d new_pos_global = regionp->getPosGlobalFromRegion(newpos);
-
- if ( LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global) )
+ bool is_valid_pos = true;
+ if (mObject->isAttachment())
+ {
+ LLVector3 delta_pos = mObject->getPositionEdit() - newpos;
+ LLVector3d attachment_pos = regionp->getPosGlobalFromRegion(mObject->getPositionRegion() + delta_pos);
+ is_valid_pos = LLWorld::getInstance()->positionRegionValidGlobal(attachment_pos);
+ }
+ else
+ {
+ is_valid_pos = LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global);
+ }
+
+ if (is_valid_pos)
{
// send only if the position is changed, that is, the delta vector is not zero
LLVector3d old_pos_global = mObject->getPositionGlobal();
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 061ecad099..33b7b03654 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -347,9 +347,6 @@ BOOL LLPreviewGesture::postBuild()
LLTextBox* text;
LLCheckBoxCtrl* check;
- edit = getChild<LLLineEditor>("name");
- edit->setKeystrokeCallback(onKeystrokeCommit, this);
-
edit = getChild<LLLineEditor>("desc");
edit->setKeystrokeCallback(onKeystrokeCommit, this);
@@ -482,9 +479,6 @@ BOOL LLPreviewGesture::postBuild()
{
getChild<LLUICtrl>("desc")->setValue(item->getDescription());
getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
-
- getChild<LLUICtrl>("name")->setValue(item->getName());
- getChild<LLLineEditor>("name")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
}
return LLPreview::postBuild();
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 58cbe0e20a..255ce1859a 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -1021,12 +1021,39 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n
std::set<std::string> framenames;
std::set<std::string> notfound;
+ // expected and correct folder sctructure is to have
+ // three folders in widnlight's root: days, water, skies
std::string base_path(gDirUtilp->getDirName(path));
std::string water_path(base_path);
std::string sky_path(base_path);
+ std::string day_path(base_path);
gDirUtilp->append(water_path, "water");
gDirUtilp->append(sky_path, "skies");
+ gDirUtilp->append(day_path, "days");
+
+ if (!gDirUtilp->fileExists(day_path))
+ {
+ LL_WARNS("SETTINGS") << "File " << name << ".xml is not in \"days\" folder." << LL_ENDL;
+ }
+
+ if (!gDirUtilp->fileExists(water_path))
+ {
+ LL_WARNS("SETTINGS") << "Failed to find accompaniying water folder for file " << name
+ << ".xml. Falling back to using default folder" << LL_ENDL;
+
+ water_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight");
+ gDirUtilp->append(water_path, "water");
+ }
+
+ if (!gDirUtilp->fileExists(sky_path))
+ {
+ LL_WARNS("SETTINGS") << "Failed to find accompaniying skies folder for file " << name
+ << ".xml. Falling back to using default folder" << LL_ENDL;
+
+ sky_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight");
+ gDirUtilp->append(sky_path, "skies");
+ }
newsettings[SETTING_NAME] = name;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 54f3e6305c..d9dc93aad6 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1054,7 +1054,7 @@ bool idle_startup()
{
// Generic failure message
std::ostringstream emsg;
- emsg << LLTrans::getString("LoginFailed") << "\n";
+ emsg << LLTrans::getString("LoginFailedHeader") << "\n";
if(LLLoginInstance::getInstance()->authFailure())
{
LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): "
@@ -1067,11 +1067,37 @@ bool idle_startup()
std::string message_id = response["message_id"];
std::string message; // actual string to show the user
- if(!message_id.empty() && LLTrans::findString(message, message_id, response["message_args"]))
- {
- // message will be filled in with the template and arguments
- }
- else if(!message_response.empty())
+ bool localized_by_id = false;
+ if(!message_id.empty())
+ {
+ LLSD message_args = response["message_args"];
+ if (message_args.has("TIME")
+ && (message_id == "LoginFailedAcountSuspended"
+ || message_id == "LoginFailedAccountMaintenance"))
+ {
+ LLDate date;
+ std::string time_string;
+ if (date.fromString(message_args["TIME"].asString()))
+ {
+ LLSD args;
+ args["datetime"] = (S32)date.secondsSinceEpoch();
+ LLTrans::findString(time_string, "LocalTime", args);
+ }
+ else
+ {
+ time_string = message_args["TIME"].asString() + " " + LLTrans::getString("PacificTime");
+ }
+
+ message_args["TIME"] = time_string;
+ }
+ // message will be filled in with the template and arguments
+ if (LLTrans::findString(message, message_id, message_args))
+ {
+ localized_by_id = true;
+ }
+ }
+
+ if(!localized_by_id && !message_response.empty())
{
// *HACK: "no_inventory_host" sent as the message itself.
// Remove this clause when server is sending message_id as well.
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 01a4bd587d..8d4a5fe7a0 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -202,6 +202,7 @@ LLContextMenu* gDetachBodyPartPieMenus[9];
// File Menu
void handle_compress_image(void*);
+void handle_compress_file_test(void*);
// Edit menu
@@ -397,7 +398,19 @@ void set_merchant_SLM_menu()
// All other cases (new merchant, not merchant, migrated merchant): show the new Marketplace Listings menu and enable the tool
gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(TRUE);
LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
- gToolBarView->enableCommand(command->id(), true);
+ gToolBarView->enableCommand(command->id(), true);
+
+ const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ if (marketplacelistings_id.isNull())
+ {
+ U32 mkt_status = LLMarketplaceData::instance().getSLMStatus();
+ bool is_merchant = (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT) || (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MIGRATED_MERCHANT);
+ if (is_merchant)
+ {
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, true);
+ LL_WARNS("SLM") << "Creating the marketplace listings folder for a merchant" << LL_ENDL;
+ }
+ }
}
void check_merchant_status(bool force)
@@ -2224,6 +2237,21 @@ class LLAdvancedCompressImage : public view_listener_t
};
+
+////////////////////////
+// COMPRESS FILE TEST //
+////////////////////////
+
+class LLAdvancedCompressFileTest : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_compress_file_test(NULL);
+ return true;
+ }
+};
+
+
/////////////////////////
// SHOW DEBUG SETTINGS //
/////////////////////////
@@ -4161,23 +4189,9 @@ bool is_object_sittable()
}
}
-
// only works on pie menu
-void handle_object_sit_or_stand()
+void handle_object_sit(LLViewerObject *object, const LLVector3 &offset)
{
- LLPickInfo pick = LLToolPie::getInstance()->getPick();
- LLViewerObject *object = pick.getObject();;
- if (!object || pick.mPickType == LLPickInfo::PICK_FLORA)
- {
- return;
- }
-
- if (sitting_on_selection())
- {
- gAgent.standUp();
- return;
- }
-
// get object selection offset
if (object && object->getPCode() == LL_PCODE_VOLUME)
@@ -4189,12 +4203,42 @@ void handle_object_sit_or_stand()
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID);
- gMessageSystem->addVector3Fast(_PREHASH_Offset, pick.mObjectOffset);
+ gMessageSystem->addVector3Fast(_PREHASH_Offset, offset);
object->getRegion()->sendReliableMessage();
}
}
+void handle_object_sit_or_stand()
+{
+ LLPickInfo pick = LLToolPie::getInstance()->getPick();
+ LLViewerObject *object = pick.getObject();
+ if (!object || pick.mPickType == LLPickInfo::PICK_FLORA)
+ {
+ return;
+ }
+
+ if (sitting_on_selection())
+ {
+ gAgent.standUp();
+ return;
+ }
+
+ handle_object_sit(object, pick.mObjectOffset);
+}
+
+void handle_object_sit(const LLUUID& object_id)
+{
+ LLViewerObject* obj = gObjectList.findObject(object_id);
+ if (!obj)
+ {
+ return;
+ }
+
+ LLVector3 offset(0, 0, 0);
+ handle_object_sit(obj, offset);
+}
+
void near_sit_down_point(BOOL success, void *)
{
if (success)
@@ -6303,6 +6347,24 @@ class LLAvatarResetSkeletonAndAnimations : public view_listener_t
}
};
+class LLAvatarResetSelfSkeletonAndAnimations : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ if (avatar)
+ {
+ avatar->resetSkeleton(true);
+ }
+ else
+ {
+ gAgentAvatarp->resetSkeleton(true);
+ }
+ return true;
+ }
+};
+
+
class LLAvatarAddContact : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -9341,6 +9403,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates");
view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates");
view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");
+ view_listener_t::addMenu(new LLAdvancedCompressFileTest(), "Advanced.CompressFileTest");
view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");
view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions");
view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions");
@@ -9408,6 +9471,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
+ view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");
enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL")));
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 36b6971c81..a90b32c984 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -135,6 +135,7 @@ void handle_save_snapshot(void *);
void handle_toggle_flycam();
void handle_object_sit_or_stand();
+void handle_object_sit(const LLUUID& object_id);
void handle_give_money_dialog();
bool enable_pay_object();
bool enable_buy_object();
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 4efc3d1cb3..f5b41d3179 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -773,6 +773,94 @@ void handle_compress_image(void*)
}
}
+// No convinient check in LLFile, and correct way would be something
+// like GetFileSizeEx, which is too OS specific for current purpose
+// so doing dirty, but OS independent fopen and fseek
+size_t get_file_size(std::string &filename)
+{
+ LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ if (!file)
+ {
+ LL_WARNS() << "Error opening " << filename << LL_ENDL;
+ return 0;
+ }
+
+ // read in the whole file
+ fseek(file, 0L, SEEK_END);
+ size_t file_length = (size_t)ftell(file);
+ fclose(file);
+ return file_length;
+}
+
+void handle_compress_file_test(void*)
+{
+ LLFilePicker& picker = LLFilePicker::instance();
+ if (picker.getOpenFile())
+ {
+ std::string infile = picker.getFirstFile();
+ if (!infile.empty())
+ {
+ std::string packfile = infile + ".pack_test";
+ std::string unpackfile = infile + ".unpack_test";
+
+ S64Bytes initial_size = S64Bytes(get_file_size(infile));
+
+ BOOL success;
+
+ F64 total_seconds = LLTimer::getTotalSeconds();
+ success = gzip_file(infile, packfile);
+ F64 result_pack_seconds = LLTimer::getTotalSeconds() - total_seconds;
+
+ if (success)
+ {
+ S64Bytes packed_size = S64Bytes(get_file_size(packfile));
+
+ LL_INFOS() << "Packing complete, time: " << result_pack_seconds << " size: " << packed_size << LL_ENDL;
+ total_seconds = LLTimer::getTotalSeconds();
+ success = gunzip_file(packfile, unpackfile);
+ F64 result_unpack_seconds = LLTimer::getTotalSeconds() - total_seconds;
+
+ if (success)
+ {
+ S64Bytes unpacked_size = S64Bytes(get_file_size(unpackfile));
+
+ LL_INFOS() << "Unpacking complete, time: " << result_unpack_seconds << " size: " << unpacked_size << LL_ENDL;
+
+ LLSD args;
+ args["FILE"] = infile;
+ args["PACK_TIME"] = result_pack_seconds;
+ args["UNPACK_TIME"] = result_unpack_seconds;
+ args["SIZE"] = LLSD::Integer(initial_size.valueInUnits<LLUnits::Kilobytes>());
+ args["PSIZE"] = LLSD::Integer(packed_size.valueInUnits<LLUnits::Kilobytes>());
+ args["USIZE"] = LLSD::Integer(unpacked_size.valueInUnits<LLUnits::Kilobytes>());
+ LLNotificationsUtil::add("CompressionTestResults", args);
+
+ LLFile::remove(packfile);
+ LLFile::remove(unpackfile);
+ }
+ else
+ {
+ LL_INFOS() << "Failed to uncompress file: " << packfile << LL_ENDL;
+ LLFile::remove(packfile);
+ }
+
+ }
+ else
+ {
+ LL_INFOS() << "Failed to compres file: " << infile << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS() << "Failed to open file" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS() << "Failed to open file" << LL_ENDL;
+ }
+}
+
LLUUID upload_new_resource(
const std::string& src_filename,
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 14442c9705..68cb67fb12 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3333,6 +3333,13 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
// trigger a control event.
U32 control_flags = gAgent.getControlFlags();
+ // Rotation into both directions should cancel out
+ U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
+ if ((control_flags & mask) == mask)
+ {
+ control_flags &= ~mask;
+ }
+
MASK key_mask = gKeyboard->currentMask(TRUE);
if (key_mask & MASK_ALT || key_mask & MASK_CONTROL)
@@ -5802,15 +5809,15 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit)
continue;
- if (script_perm.question == "JoinAnExperience")
- { // Some experience only permissions do not have an explicit permission bit. Add them here.
- script_question += " " + LLTrans::getString("ForceSitAvatar") + "\n";
+ if (LLTrans::getString(script_perm.question).empty())
+ {
+ continue;
}
script_question += " " + LLTrans::getString(script_perm.question) + "\n";
}
}
-
+
args["QUESTIONS"] = script_question;
if (known_questions != questions)
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 63e48d1dd0..ea8b74d2c0 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -72,7 +72,7 @@
#ifdef LL_USESYSTEMLIBS
#include <zlib.h>
#else
-#include "zlib/zlib.h"
+#include "zlib-ng/zlib.h"
#endif
#include "object_flags.h"
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 6471e89233..6c5b5d3c9e 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -493,6 +493,7 @@ void send_viewer_stats(bool include_preferences)
system["os"] = LLOSInfo::instance().getOSStringSimple();
system["cpu"] = gSysCPU.getCPUString();
system["address_size"] = ADDRESS_SIZE;
+ system["os_bitness"] = LLOSInfo::instance().getOSBitness();
unsigned char MACAddress[MAC_ADDRESS_BYTES];
LLUUID::getNodeID(MACAddress);
std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x",
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 92e8f8026d..ca20832a39 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2241,6 +2241,7 @@ void LLViewerWindow::initWorldUI()
gStatusBar->setShape(status_bar_container->getLocalRect());
// sync bg color with menu bar
gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
+ // add InBack so that gStatusBar won't be drawn over menu
status_bar_container->addChildInBack(gStatusBar);
status_bar_container->setVisible(TRUE);
@@ -3221,6 +3222,11 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
void LLViewerWindow::handleScrollHWheel(S32 clicks)
{
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return;
+ }
+
LLUI::getInstance()->resetMouseIdleTimer();
LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a36b859b6c..03e23b5ba3 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -612,8 +612,7 @@ with the same filename but different name
<texture name="login_sl_logo" file_name="windows/login_sl_logo.png" preload="true" />
<texture name="login_sl_logo_small" file_name="windows/login_sl_logo_small.png" preload="true" />
- <texture name="first_login_image_left" file_name="windows/first_login_image_left.png" preload="true" />
- <texture name="first_login_image_right" file_name="windows/first_login_image_right.png" preload="true" />
+ <texture name="first_login_image" file_name="windows/first_login_image.jpg" preload="true" />
<texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" />
<texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="false" />
diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpg
new file mode 100644
index 0000000000..30f31341ed
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/first_login_image.jpg
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/first_login_image_left.png b/indra/newview/skins/default/textures/windows/first_login_image_left.png
deleted file mode 100644
index 77904d7d12..0000000000
--- a/indra/newview/skins/default/textures/windows/first_login_image_left.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/first_login_image_right.png b/indra/newview/skins/default/textures/windows/first_login_image_right.png
deleted file mode 100644
index 35ecce9c07..0000000000
--- a/indra/newview/skins/default/textures/windows/first_login_image_right.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 814305c1bc..5f1bf73f26 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -106,7 +106,7 @@
<string name="LoginFailedNoNetwork">
Netværksfejl: Kunne ikke etablere forbindelse, check venligst din netværksforbindelse.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Login fejlede.
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index f021e03dc7..d5204a8435 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -186,7 +186,7 @@ Voice-Server-Version: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Netzwerkfehler: Verbindung konnte nicht hergestellt werden. Bitte überprüfen Sie Ihre Netzwerkverbindung.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Anmeldung fehlgeschlagen
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index b2d9e53039..dee5e29a3c 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -164,6 +164,7 @@
left_pad="2"
name="Description"
spellcheck="true"
+ parse_urls="true"
top_delta="0"
width="365"
word_wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index 9885e37cea..842184de88 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -8,6 +8,16 @@
tab_stop="false"
name="main_view"
width="1024">
+
+ <!-- At the moment layout_stack is not an LLUICtrl,
+ but Tab requires focus_root to function and focus_root
+ functionality is implemented in LLUICtrl -->
+ <panel follows="all"
+ height="768"
+ name="menu_tab_wrapper"
+ mouse_opaque="false"
+ focus_root="true"
+ top="0">
<layout_stack border_size="0"
follows="all"
mouse_opaque="false"
@@ -18,12 +28,12 @@
<layout_panel mouse_opaque="true"
follows="left|right|top"
name="status_bar_container"
- tab_stop="false"
height="19"
left="0"
top="0"
width="1024"
auto_resize="false"
+ default_tab_group="1"
visible="true">
<view mouse_opaque="false"
follows="all"
@@ -31,13 +41,13 @@
left="0"
top="0"
width="1024"
+ tab_group="1"
height="19"/>
</layout_panel>
<layout_panel auto_resize="false"
height="34"
mouse_opaque="false"
name="nav_bar_container"
- tab_stop="false"
width="1024"
visible="false"/>
<layout_panel auto_resize="true"
@@ -99,6 +109,7 @@
tab_stop="false"/>
</layout_panel>
</layout_stack>
+ </panel> <!--menu_tab_wrapper-->
<panel top="0"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 24d06722b9..c9fa4324ac 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -471,7 +471,7 @@
layout="topleft"
name="Reset Skeleton And Animations">
<menu_item_call.on_click
- function="Avatar.ResetSkeletonAndAnimations" />
+ function="Avatar.ResetSelfSkeletonAndAnimations" />
</menu_item_call>
<menu_item_call
label="Attachment scripts..."
@@ -3900,6 +3900,12 @@ function="World.EnvPreset"
<menu_item_call.on_click
function="Advanced.CompressImage" />
</menu_item_call>
+ <menu_item_call
+ label="Compress File Test"
+ name="Compress File Test">
+ <menu_item_call.on_click
+ function="Advanced.CompressFileTest" />
+ </menu_item_call>
<menu_item_call
label="Enable Visual Leak Detector"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index d4f71fb370..95eedf0cf8 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11777,5 +11777,15 @@ Unable to load the track into [TRACK].
Unable to load the track from [TRACK1] into [TRACK2].
<tag>fail</tag>
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CompressionTestResults"
+ type="alertmodal">
+Test result for gzip level 6 file compression with [FILE] of size [SIZE] KB:
+Packing: [PACK_TIME]s [PSIZE]KB
+Unpacking: [UNPACK_TIME]s [USIZE]KB
+ <tag>fail</tag>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index e34335a2af..5eafb5cdf1 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -95,6 +95,7 @@ Hover your mouse over the options for more help.
layout="topleft"
max_length="511"
name="charter"
+ parse_urls="true"
top="105"
right="-4"
bg_readonly_color="DkGray2"
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 5568ccb792..cdf07c8aef 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -216,24 +216,17 @@
auto_resize="false"
follows="left|right|top"
name="images_container"
- width="832"
+ width="675"
left="0"
top="0"
height="500">
<icon
- height="400"
- width="400"
- image_name="first_login_image_left"
+ height="450"
+ width="675"
+ image_name="first_login_image"
left="0"
name="image_left"
top="0" />
- <icon
- height="400"
- width="400"
- image_name="first_login_image_right"
- left_pad="32"
- name="image_right"
- top="0" />
</layout_panel>
<layout_panel
height="100"
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 1c9aa1eb83..b44c19810b 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -4,7 +4,6 @@
background_visible="true"
bg_opaque_color="MouseGray"
follows="left|top|right"
- focus_root="true"
height="34"
layout="topleft"
name="navigation_bar"
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 9023d68ea9..b711ed0e1c 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -11,7 +11,6 @@
mouse_opaque="false"
name="status"
top="19"
- tab_stop="false"
width="1000">
<panel.string
name="packet_loss_tooltip">
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f26ee06e6b..eff380ef6e 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -69,6 +69,7 @@ Voice Server Version: [VOICE_VERSION]
</string>
<string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string>
<string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string>
+ <string name="LocalTime">[month, datetime, local] [day, datetime, local] [year, datetime, local] [hour, datetime, local]:[min, datetime, local]:[second,datetime, local]</string>
<string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string>
<string name="BuildConfiguration">Build Configuration</string>
@@ -111,7 +112,7 @@ Voice Server Version: [VOICE_VERSION]
<string name="CertAllocationFailure">Failed to allocate openssl memory for certificate.</string>
<string name="LoginFailedNoNetwork">Network error: Could not establish connection, please check your network connection.</string>
- <string name="LoginFailed">Login failed.</string>
+ <string name="LoginFailedHeader">Login failed.</string>
<string name="Quit">Quit</string>
<string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string>
@@ -125,6 +126,8 @@ http://secondlife.com/download
For more information, see our FAQ below:
http://secondlife.com/viewer-access-faq</string>
+ <string name="LoginFailed">Grid emergency login failure.
+If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginIntermediateOptionalUpdateAvailable">Optional viewer update available: [VERSION]</string>
<string name="LoginFailedRequiredUpdate">Required viewer update: [VERSION]</string>
<string name="LoginFailedAlreadyLoggedIn">This agent is already logged in.
@@ -151,15 +154,18 @@ People with free accounts will not be able to access Second Life during this tim
<string name="LoginFailedComputerProhibited">Second Life cannot be accessed from this computer.
If you feel this is an error, please contact
support@secondlife.com.</string>
+ <!--'Pacific time' placeholder for [TIME] in case time from server can't be decoded-->
+ <string name="PacificTime">Pacific Time</string>
<string name="LoginFailedAcountSuspended">Your account is not accessible until
-[TIME] Pacific Time.</string>
+[TIME].
+If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginFailedAccountDisabled">We are unable to complete your request at this time.
Please contact Second Life support for assistance at http://support.secondlife.com.</string>
<string name="LoginFailedTransformError">Data inconsistency found during login.
Please contact support@secondlife.com.</string>
<string name="LoginFailedAccountMaintenance">Your account is undergoing minor maintenance.
Your account is not accessible until
-[TIME] Pacific Time.
+[TIME].
If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginFailedPendingLogoutFault">Request for logout responded with a fault from simulator.</string>
<string name="LoginFailedPendingLogout">The system is logging you out right now.
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index ebb4ceaa7e..204fbb1002 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -178,7 +178,7 @@ Versión del servidor de voz: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Error de red: no se ha podido conectar; por favor, revisa tu conexión a internet.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Error en el inicio de sesión.
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 9fde703d6c..be9d916a5d 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -187,7 +187,7 @@ Voice Server Version: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Erreur réseau : impossible d&apos;établir la connexion. Veuillez vérifier votre connexion réseau.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Échec de la connexion.
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 3049828f46..fb49b87ef7 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -183,7 +183,7 @@ Versione server voce: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Errore di rete: Non è stato possibile stabilire un collegamento, controlla la tua connessione.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Accesso non riuscito.
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index dcd6e65d34..fffc49cc76 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -186,7 +186,7 @@ LOD 係数: [LOD_FACTOR]
<string name="LoginFailedNoNetwork">
ネットワークエラー:接続を確立できませんでした。お使いのネットワーク接続をご確認ください。
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
ログインに失敗しました。
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index cf033df3c9..2b182dc3cc 100644
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -143,7 +143,7 @@ Wersja serwera głosu (Voice Server): [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Błąd sieci: Brak połączenia z siecią, sprawdź status swojego połączenia internetowego.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Logowanie nie powiodło się.
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index c72a41fd3a..7c593ab3be 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -178,7 +178,7 @@ Versão do servidor de voz: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Erro de rede: Falha de conexão: verifique sua conexão à internet.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Falha do login.
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 43a87b2b18..b3edd4931c 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -187,7 +187,7 @@ SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
<string name="LoginFailedNoNetwork">
Ошибка сети: не удалось установить соединение. Проверьте подключение к сети.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Ошибка входа.
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index 982de76a5b..74a6b3cac3 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -187,7 +187,7 @@ Ses Sunucusu Sürümü: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Ağ hatası: Bağlantı kurulamadı, lütfen ağ bağlantınızı kontrol edin.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Oturum açılamadı.
</string>
<string name="Quit">
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index 3221cde3b7..a8d5fd90bb 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -187,7 +187,7 @@ LibVLC版本:[LIBVLC_VERSION]N]
<string name="LoginFailedNoNetwork">
網路錯誤:無法建立連線,請檢查網路連線是否正常。
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
登入失敗。
</string>
<string name="Quit">