diff options
| author | Erik Kundiman <erik@megapahit.org> | 2025-10-25 20:04:44 +0800 |
|---|---|---|
| committer | Erik Kundiman <erik@megapahit.org> | 2025-10-26 12:45:19 +0800 |
| commit | aa76edd40883e57541dc85b14d098708d6e074ed (patch) | |
| tree | 969a5df44f31bd2f007e980bf52280b7b5037ed6 | |
| parent | 7c37297689f9e6e1b6ac77f33243c1274d5d9e82 (diff) | |
| parent | 4e2a9667bda1a1980993ae453dfe6ff38dd1835a (diff) | |
Merge tag 'Second_Life_Release#4e2a9667-2025.08' into 2025.08
45 files changed, 1651 insertions, 751 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index c68131402b..ce934f1a21 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,6 +1,7 @@ # Replace tabs with spaces 1b68f71348ecf3983b76b40d7940da8377f049b7 33418a77b716e122da9778869cdbabe97c83ff37 +6b974724826a038b0db794460b322eb4921da735 # Trim trailing whitespace a0b3021bdcf76859054fda8e30abb3ed47749e83 8444cd9562a6a7b755fcb075864e205122354192 diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000000..3e3e1df3e2 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,7 @@ +version: 2 +updates: + + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 5a5628ede2..4c948e5586 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -86,7 +86,7 @@ jobs: variants: ${{ matrix.configuration }} steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} @@ -95,14 +95,14 @@ jobs: with: python-version: "3.11" - name: Checkout build variables - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: secondlife/build-variables ref: master path: .build-variables - name: Checkout master-message-template - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: secondlife/master-message-template path: .master-message-template diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index d626eef38d..726e1cd889 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -11,8 +11,8 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/setup-python@v4 with: python-version: 3.x - - uses: pre-commit/action@v3.0.0 + - uses: pre-commit/action@v3.0.1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8baac5a81d..d1dcc93976 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,14 +7,14 @@ repos: - id: no-trigraphs - id: copyright - id: end-of-file - files: \.(cpp|c|h|py|glsl|cmake|txt)$ + files: \.(cpp|c|m|mm|h|py|glsl|cmake|txt)$ exclude: language.txt - id: indent-with-spaces - files: \.(cpp|c|h|inl|py|glsl|cmake)$ + files: \.(cpp|c|m|mm|h|inl|py|glsl|cmake)$ - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: check-xml - id: mixed-line-ending - id: trailing-whitespace - files: \.(cpp|c|h|inl|py|glsl|cmake|yaml|sh)$ + files: \.(cpp|c|m|mm|h|inl|py|glsl|cmake|yaml|sh)$ diff --git a/autobuild.xml b/autobuild.xml index fe83b6776f..a14d477234 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1468,36 +1468,6 @@ <key>name</key> <string>llphysicsextensions_source</string> </map> - <key>llphysicsextensions_stub</key> - <map> - <key>platforms</key> - <map> - <key>common</key> - <map> - <key>archive</key> - <map> - <key>hash</key> - <string>bc41438b10ac6474cf5560465a3662a64f9e65a81342e4c33f18f6694581c7ee28c9ee6f091c36e80a0b1e10c68205be71eb5f8e40fef115d2c744fc2bbfcb43</string> - <key>hash_algorithm</key> - <string>blake2b</string> - <key>url</key> - <string>https://github.com/AlchemyViewer/llphysicsextensions_stub/releases/download/v1.0-cb4900e/llphysicsextensions_stub-1.0-common-17836965684.tar.zst</string> - </map> - <key>name</key> - <string>common</string> - </map> - </map> - <key>license</key> - <string>internal</string> - <key>license_file</key> - <string>LICENSES/llphysicsextensions.txt</string> - <key>copyright</key> - <string>Copyright (c) 2010, Linden Research, Inc.</string> - <key>version</key> - <string>1.0</string> - <key>name</key> - <string>llphysicsextensions_stub</string> - </map> <key>llphysicsextensions_tpv</key> <map> <key>platforms</key> diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index ccc4b08447..6f3ec1cfff 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -61,9 +61,6 @@ add_subdirectory(cmake) add_subdirectory(${LIBS_OPEN_PREFIX}llaudio) add_subdirectory(${LIBS_OPEN_PREFIX}llappearance) add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter) -if (NOT HAVOK AND NOT HAVOK_TPV) - add_subdirectory(${LIBS_OPEN_PREFIX}llconvexdecomposition) -endif () add_subdirectory(${LIBS_OPEN_PREFIX}llcommon) add_subdirectory(${LIBS_OPEN_PREFIX}llcorehttp) add_subdirectory(${LIBS_OPEN_PREFIX}llimage) @@ -73,6 +70,7 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llinventory) add_subdirectory(${LIBS_OPEN_PREFIX}llmath) add_subdirectory(${LIBS_OPEN_PREFIX}llmeshoptimizer) add_subdirectory(${LIBS_OPEN_PREFIX}llmessage) +add_subdirectory(${LIBS_OPEN_PREFIX}llphysicsextensionsos) add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive) add_subdirectory(${LIBS_OPEN_PREFIX}llrender) add_subdirectory(${LIBS_OPEN_PREFIX}llfilesystem) diff --git a/indra/cmake/LLPhysicsExtensions.cmake b/indra/cmake/LLPhysicsExtensions.cmake index 49950be37b..84722b45a7 100644 --- a/indra/cmake/LLPhysicsExtensions.cmake +++ b/indra/cmake/LLPhysicsExtensions.cmake @@ -22,7 +22,6 @@ if (HAVOK) include(Havok) use_prebuilt_binary(llphysicsextensions_source) set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/src) - target_compile_definitions( llphysicsextensions_impl INTERFACE LL_HAVOK=1 ) if(DARWIN) set(LLPHYSICSEXTENSIONS_STUB_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/stub) # can't set these library dependencies per-arch here, need to do it using XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=*] in newview/CMakeLists.txt @@ -30,22 +29,18 @@ if (HAVOK) #target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensionsstub) else() target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions) + target_compile_definitions( llphysicsextensions_impl INTERFACE LL_HAVOK=1 ) endif() + target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions) elseif (HAVOK_TPV) use_prebuilt_binary(llphysicsextensions_tpv) - if (CMAKE_OSX_ARCHITECTURES MATCHES x86_64) - target_link_directories( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE} ) - endif () - if(WINDOWS) - target_link_libraries( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS}/llphysicsextensions_tpv.lib) - else() - target_link_libraries( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS}/libllphysicsextensions_tpv.a) + if (NOT DARWIN) + if(WINDOWS) + target_link_libraries( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS}/llphysicsextensions_tpv.lib) + elseif(LINUX) + target_link_libraries( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS}/libllphysicsextensions_tpv.a) + endif() + target_compile_definitions( llphysicsextensions_impl INTERFACE LL_HAVOK=1 ) endif() - target_compile_definitions( llphysicsextensions_impl INTERFACE LL_HAVOK=1 ) -else (HAVOK) - use_prebuilt_binary(llphysicsextensions_stub) - set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/stub) - target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensionsstub) -endif (HAVOK) - -target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions) + target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions) +endif () diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp index 719381b4fc..d5323e0b84 100644 --- a/indra/llappearance/llpolymesh.cpp +++ b/indra/llappearance/llpolymesh.cpp @@ -283,6 +283,7 @@ bool LLPolyMeshSharedData::loadMesh( const std::string& fileName ) LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/ if (!fp) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "can't open: " << fileName << LL_ENDL; return false; } diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 53659ac13f..a539e4fe28 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -35,7 +35,6 @@ #if LL_WINDOWS #include "llwin32headers.h" -#include <stdlib.h> // Windows errno #include <vector> #else #include <errno.h> @@ -49,6 +48,86 @@ static std::string empty; // variants of strerror() to report errors. #if LL_WINDOWS +// For the situations where we directly call into Windows API functions we need to translate +// the Windows error codes into errno values +namespace +{ + struct errentry + { + unsigned long oserr; // Windows OS error value + int errcode; // System V error code + }; +} + +// translation table between Windows OS error value and System V errno code +static errentry const errtable[] +{ + { ERROR_INVALID_FUNCTION, EINVAL }, // 1 + { ERROR_FILE_NOT_FOUND, ENOENT }, // 2 + { ERROR_PATH_NOT_FOUND, ENOENT }, // 3 + { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, // 4 + { ERROR_ACCESS_DENIED, EACCES }, // 5 + { ERROR_INVALID_HANDLE, EBADF }, // 6 + { ERROR_ARENA_TRASHED, ENOMEM }, // 7 + { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, // 8 + { ERROR_INVALID_BLOCK, ENOMEM }, // 9 + { ERROR_BAD_ENVIRONMENT, E2BIG }, // 10 + { ERROR_BAD_FORMAT, ENOEXEC }, // 11 + { ERROR_INVALID_ACCESS, EINVAL }, // 12 + { ERROR_INVALID_DATA, EINVAL }, // 13 + { ERROR_INVALID_DRIVE, ENOENT }, // 15 + { ERROR_CURRENT_DIRECTORY, EACCES }, // 16 + { ERROR_NOT_SAME_DEVICE, EXDEV }, // 17 + { ERROR_NO_MORE_FILES, ENOENT }, // 18 + { ERROR_LOCK_VIOLATION, EACCES }, // 33 + { ERROR_BAD_NETPATH, ENOENT }, // 53 + { ERROR_NETWORK_ACCESS_DENIED, EACCES }, // 65 + { ERROR_BAD_NET_NAME, ENOENT }, // 67 + { ERROR_FILE_EXISTS, EEXIST }, // 80 + { ERROR_CANNOT_MAKE, EACCES }, // 82 + { ERROR_FAIL_I24, EACCES }, // 83 + { ERROR_INVALID_PARAMETER, EINVAL }, // 87 + { ERROR_NO_PROC_SLOTS, EAGAIN }, // 89 + { ERROR_DRIVE_LOCKED, EACCES }, // 108 + { ERROR_BROKEN_PIPE, EPIPE }, // 109 + { ERROR_DISK_FULL, ENOSPC }, // 112 + { ERROR_INVALID_TARGET_HANDLE, EBADF }, // 114 + { ERROR_WAIT_NO_CHILDREN, ECHILD }, // 128 + { ERROR_CHILD_NOT_COMPLETE, ECHILD }, // 129 + { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, // 130 + { ERROR_NEGATIVE_SEEK, EINVAL }, // 131 + { ERROR_SEEK_ON_DEVICE, EACCES }, // 132 + { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, // 145 + { ERROR_NOT_LOCKED, EACCES }, // 158 + { ERROR_BAD_PATHNAME, ENOENT }, // 161 + { ERROR_MAX_THRDS_REACHED, EAGAIN }, // 164 + { ERROR_LOCK_FAILED, EACCES }, // 167 + { ERROR_ALREADY_EXISTS, EEXIST }, // 183 + { ERROR_FILENAME_EXCED_RANGE, ENOENT }, // 206 + { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, // 215 + { ERROR_NO_UNICODE_TRANSLATION, EILSEQ }, // 1113 + { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } // 1816 +}; + +static int set_errno_from_oserror(unsigned long oserr) +{ + if (!oserr) + return 0; + + // Check the table for the Windows OS error code + for (const struct errentry &entry : errtable) + { + if (oserr == entry.oserr) + { + _set_errno(entry.errcode); + return -1; + } + } + + _set_errno(EINVAL); + return -1; +} + // On Windows, use strerror_s(). std::string strerr(int errn) { @@ -57,7 +136,67 @@ std::string strerr(int errn) return buffer; } -typedef std::basic_ios<char,std::char_traits < char > > _Myios; +inline bool is_slash(wchar_t const c) +{ + return c == L'\\' || c == L'/'; +} + +static std::wstring utf8path_to_wstring(const std::string& utf8path) +{ + if (utf8path.size() >= MAX_PATH) + { + // By prepending "\\?\" to a path, Windows widechar file APIs will not fail on long path names + std::wstring utf16path = L"\\\\?\\" + ll_convert<std::wstring>(utf8path); + // We need to make sure that the path does not contain forward slashes as above + // prefix does bypass the path normalization that replaces slashes with backslashes + // before passing the path to kernel mode APIs + std::replace(utf16path.begin(), utf16path.end(), L'/', L'\\'); + return utf16path; + } + return ll_convert<std::wstring>(utf8path); +} + +static unsigned short get_fileattr(const std::wstring& utf16path, bool dontFollowSymLink = false) +{ + unsigned long flags = FILE_FLAG_BACKUP_SEMANTICS; + if (dontFollowSymLink) + { + flags |= FILE_FLAG_OPEN_REPARSE_POINT; + } + HANDLE file_handle = CreateFileW(utf16path.c_str(), FILE_READ_ATTRIBUTES, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + nullptr, OPEN_EXISTING, flags, nullptr); + if (file_handle != INVALID_HANDLE_VALUE) + { + FILE_ATTRIBUTE_TAG_INFO attribute_info; + if (GetFileInformationByHandleEx(file_handle, FileAttributeTagInfo, &attribute_info, sizeof(attribute_info))) + { + // A volume path alone (only drive letter) is not recognized as directory while it technically is + bool is_directory = (attribute_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) || + (iswalpha(utf16path[0]) && utf16path[1] == ':' && + (!utf16path[2] || (is_slash(utf16path[2]) && !utf16path[3]))); + unsigned short st_mode = is_directory ? S_IFDIR : + (attribute_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ? S_IFLNK : S_IFREG); + st_mode |= (attribute_info.FileAttributes & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE; + // we do not try to guess executable flag + + // propagate user bits to group/other fields: + st_mode |= (st_mode & 0700) >> 3; + st_mode |= (st_mode & 0700) >> 6; + + CloseHandle(file_handle); + return st_mode; + } + } + // Retrieve last error and set errno before calling CloseHandle() + set_errno_from_oserror(GetLastError()); + + if (file_handle != INVALID_HANDLE_VALUE) + { + CloseHandle(file_handle); + } + return 0; +} #else // On Posix we want to call strerror_r(), but alarmingly, there are two @@ -108,18 +247,13 @@ std::string strerr(int errn) } #endif // ! LL_WINDOWS -// On either system, shorthand call just infers global 'errno'. -std::string strerr() -{ - return strerr(errno); -} - -int warnif(const std::string& desc, const std::string& filename, int rc, int accept=0) +static int warnif(const std::string& desc, const std::string& filename, int rc, int accept = 0) { if (rc < 0) { // Capture errno before we start emitting output int errn = errno; + // For certain operations, a particular errno value might be // acceptable -- e.g. stat() could permit ENOENT, mkdir() could permit // EEXIST. Don't warn if caller explicitly says this errno is okay. @@ -176,62 +310,59 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc // static int LLFile::mkdir(const std::string& dirname, int perms) { + // We often use mkdir() to ensure the existence of a directory that might + // already exist. There is no known case in which we want to call out as + // an error the requested directory already existing. #if LL_WINDOWS // permissions are ignored on Windows - std::wstring utf16dirname = ll_convert<std::wstring>(dirname); - int rc = _wmkdir(utf16dirname.c_str()); + int rc = 0; + std::wstring utf16dirname = utf8path_to_wstring(dirname); + if (!CreateDirectoryW(utf16dirname.c_str(), nullptr)) + { + // Only treat other errors than an already existing file as a real error + unsigned long oserr = GetLastError(); + if (oserr != ERROR_ALREADY_EXISTS) + { + rc = set_errno_from_oserror(oserr); + } + } #else int rc = ::mkdir(dirname.c_str(), (mode_t)perms); -#endif - // We often use mkdir() to ensure the existence of a directory that might - // already exist. There is no known case in which we want to call out as - // an error the requested directory already existing. if (rc < 0 && errno == EEXIST) { // this is not the error you want, move along return 0; } +#endif // anything else might be a problem - return warnif("mkdir", dirname, rc, EEXIST); + return warnif("mkdir", dirname, rc); } // static -int LLFile::rmdir(const std::string& dirname) +int LLFile::rmdir(const std::string& dirname, int suppress_error) { #if LL_WINDOWS - // permissions are ignored on Windows - std::wstring utf16dirname = ll_convert<std::wstring>(dirname); + std::wstring utf16dirname = utf8path_to_wstring(dirname); int rc = _wrmdir(utf16dirname.c_str()); #else int rc = ::rmdir(dirname.c_str()); #endif - return warnif("rmdir", dirname, rc); + return warnif("rmdir", dirname, rc, suppress_error); } // static -LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawfinder: ignore */ -{ -#if LL_WINDOWS - std::wstring utf16filename = ll_convert<std::wstring>(filename); - std::wstring utf16mode = ll_convert<std::wstring>(std::string(mode)); - return _wfopen(utf16filename.c_str(),utf16mode.c_str()); -#else - return ::fopen(filename.c_str(),mode); /* Flawfinder: ignore */ -#endif -} - -LLFILE* LLFile::_fsopen(const std::string& filename, const char* mode, int sharingFlag) +LLFILE* LLFile::fopen(const std::string& filename, const char* mode) { #if LL_WINDOWS - std::wstring utf16filename = ll_convert<std::wstring>(filename); + std::wstring utf16filename = utf8path_to_wstring(filename); std::wstring utf16mode = ll_convert<std::wstring>(std::string(mode)); - return _wfsopen(utf16filename.c_str(),utf16mode.c_str(),sharingFlag); + return _wfopen(utf16filename.c_str(), utf16mode.c_str()); #else - llassert(0);//No corresponding function on non-windows - return NULL; + return ::fopen(filename.c_str(),mode); #endif } +// static int LLFile::close(LLFILE * file) { int ret_value = 0; @@ -242,9 +373,10 @@ int LLFile::close(LLFILE * file) return ret_value; } +// static std::string LLFile::getContents(const std::string& filename) { - LLFILE* fp = fopen(filename, "rb"); /* Flawfinder: ignore */ + LLFILE* fp = LLFile::fopen(filename, "rb"); if (fp) { fseek(fp, 0, SEEK_END); @@ -261,42 +393,80 @@ std::string LLFile::getContents(const std::string& filename) return LLStringUtil::null; } -int LLFile::remove(const std::string& filename, int supress_error) +// static +int LLFile::remove(const std::string& filename, int suppress_error) { #if LL_WINDOWS - std::wstring utf16filename = ll_convert<std::wstring>(filename); - int rc = _wremove(utf16filename.c_str()); + // Posix remove() works on both files and directories although on Windows + // remove() and its wide char variant _wremove() only removes files just + // as its siblings unlink() and _wunlink(). + // If we really only want to support files we should instead use + // unlink() in the non-Windows part below too + int rc = -1; + std::wstring utf16filename = utf8path_to_wstring(filename); + unsigned short st_mode = get_fileattr(utf16filename); + if (S_ISDIR(st_mode)) + { + rc = _wrmdir(utf16filename.c_str()); + } + else if (S_ISREG(st_mode)) + { + rc = _wunlink(utf16filename.c_str()); + } + else if (st_mode) + { + // it is something else than a file or directory + // this should not really happen as long as we do not allow for symlink + // detection in the optional parameter to get_fileattr() + rc = set_errno_from_oserror(ERROR_INVALID_PARAMETER); + } + else + { + // get_fileattr() failed and already set errno, preserve it for correct error reporting + } #else int rc = ::remove(filename.c_str()); #endif - return warnif("remove", filename, rc, supress_error); + return warnif("remove", filename, rc, suppress_error); } -int LLFile::rename(const std::string& filename, const std::string& newname, int supress_error) +// static +int LLFile::rename(const std::string& filename, const std::string& newname, int suppress_error) { #if LL_WINDOWS - std::wstring utf16filename = ll_convert<std::wstring>(filename); - std::wstring utf16newname = ll_convert<std::wstring>(newname); - int rc = _wrename(utf16filename.c_str(),utf16newname.c_str()); + // Posix rename() will gladly overwrite a file at newname if it exists, the Windows + // rename(), respectively _wrename(), will bark on that. Instead call directly the Windows + // API MoveFileEx() and use its flags to specify that overwrite is allowed. + std::wstring utf16filename = utf8path_to_wstring(filename); + std::wstring utf16newname = utf8path_to_wstring(newname); + int rc = 0; + if (!MoveFileExW(utf16filename.c_str(), utf16newname.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED)) + { + rc = set_errno_from_oserror(GetLastError()); + } #else int rc = ::rename(filename.c_str(),newname.c_str()); #endif - return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error); + return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, suppress_error); } +// Make this a define rather than using magic numbers multiple times in the code +#define LLFILE_COPY_BUFFER_SIZE 16384 + +// static bool LLFile::copy(const std::string& from, const std::string& to) { bool copied = false; - LLFILE* in = LLFile::fopen(from, "rb"); /* Flawfinder: ignore */ + LLFILE* in = LLFile::fopen(from, "rb"); if (in) { - LLFILE* out = LLFile::fopen(to, "wb"); /* Flawfinder: ignore */ + LLFILE* out = LLFile::fopen(to, "wb"); if (out) { - char buf[16384]; /* Flawfinder: ignore */ + char buf[LLFILE_COPY_BUFFER_SIZE]; size_t readbytes; bool write_ok = true; - while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */ + while (write_ok && (readbytes = fread(buf, 1, LLFILE_COPY_BUFFER_SIZE, in))) { if (fwrite(buf, 1, readbytes, out) != readbytes) { @@ -315,33 +485,62 @@ bool LLFile::copy(const std::string& from, const std::string& to) return copied; } -int LLFile::stat(const std::string& filename, llstat* filestatus) +// static +int LLFile::stat(const std::string& filename, llstat* filestatus, int suppress_error) { #if LL_WINDOWS - std::wstring utf16filename = ll_convert<std::wstring>(filename); - int rc = _wstat(utf16filename.c_str(),filestatus); + std::wstring utf16filename = utf8path_to_wstring(filename); + int rc = _wstat64(utf16filename.c_str(), filestatus); #else - int rc = ::stat(filename.c_str(),filestatus); + int rc = ::stat(filename.c_str(), filestatus); #endif - // We use stat() to determine existence (see isfile(), isdir()). - // Don't spam the log if the subject pathname doesn't exist. - return warnif("stat", filename, rc, ENOENT); + return warnif("stat", filename, rc, suppress_error); } -bool LLFile::isdir(const std::string& filename) +// static +unsigned short LLFile::getattr(const std::string& filename, bool dontFollowSymLink, int suppress_error) { - llstat st; +#if LL_WINDOWS + // _wstat64() is a bit heavyweight on Windows, use a more lightweight API + // to just get the attributes + int rc = -1; + std::wstring utf16filename = utf8path_to_wstring(filename); + unsigned short st_mode = get_fileattr(utf16filename, dontFollowSymLink); + if (st_mode) + { + return st_mode; + } +#else + llstat filestatus; + int rc = dontFollowSymLink ? ::lstat(filename.c_str(), &filestatus) : ::stat(filename.c_str(), &filestatus); + if (rc == 0) + { + return filestatus.st_mode; + } +#endif + warnif("getattr", filename, rc, suppress_error); + return 0; +} - return stat(filename, &st) == 0 && S_ISDIR(st.st_mode); +// static +bool LLFile::isdir(const std::string& filename) +{ + return S_ISDIR(getattr(filename)); } +// static bool LLFile::isfile(const std::string& filename) { - llstat st; + return S_ISREG(getattr(filename)); +} - return stat(filename, &st) == 0 && S_ISREG(st.st_mode); +// static +bool LLFile::islink(const std::string& filename) +{ + return S_ISLNK(getattr(filename, true)); } +// static const char *LLFile::tmpdir() { static std::string utf8path; @@ -368,75 +567,8 @@ const char *LLFile::tmpdir() return utf8path.c_str(); } - -/***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/ - #if LL_WINDOWS -LLFILE * LLFile::_Fiopen(const std::string& filename, - std::ios::openmode mode) -{ // open a file - static const char *mods[] = - { // fopen mode strings corresponding to valid[i] - "r", "w", "w", "a", "rb", "wb", "wb", "ab", - "r+", "w+", "a+", "r+b", "w+b", "a+b", - 0}; - static const int valid[] = - { // valid combinations of open flags - ios_base::in, - ios_base::out, - ios_base::out | ios_base::trunc, - ios_base::out | ios_base::app, - ios_base::in | ios_base::binary, - ios_base::out | ios_base::binary, - ios_base::out | ios_base::trunc | ios_base::binary, - ios_base::out | ios_base::app | ios_base::binary, - ios_base::in | ios_base::out, - ios_base::in | ios_base::out | ios_base::trunc, - ios_base::in | ios_base::out | ios_base::app, - ios_base::in | ios_base::out | ios_base::binary, - ios_base::in | ios_base::out | ios_base::trunc - | ios_base::binary, - ios_base::in | ios_base::out | ios_base::app - | ios_base::binary, - 0}; - - LLFILE *fp = 0; - int n; - ios_base::openmode atendflag = mode & ios_base::ate; - ios_base::openmode norepflag = mode & ios_base::_Noreplace; - - if (mode & ios_base::_Nocreate) - mode |= ios_base::in; // file must exist - mode &= ~(ios_base::ate | ios_base::_Nocreate | ios_base::_Noreplace); - for (n = 0; valid[n] != 0 && valid[n] != mode; ++n) - ; // look for a valid mode - - if (valid[n] == 0) - return (0); // no valid mode - else if (norepflag && mode & (ios_base::out | ios_base::app) - && (fp = LLFile::fopen(filename, "r")) != 0) /* Flawfinder: ignore */ - { // file must not exist, close and fail - fclose(fp); - return (0); - } - else if (fp != 0 && fclose(fp) != 0) - return (0); // can't close after test open -// should open with protection here, if other than default - else if ((fp = LLFile::fopen(filename, mods[n])) == 0) /* Flawfinder: ignore */ - return (0); // open failed - - if (!atendflag || fseek(fp, 0, SEEK_END) == 0) - return (fp); // no need to seek to end, or seek succeeded - - fclose(fp); // can't position at end - return (0); -} - -#endif /* LL_WINDOWS */ - - -#if LL_WINDOWS /************** input file stream ********************************/ llifstream::llifstream() {} diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 1661cbeb55..04a2946ac4 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -41,8 +41,9 @@ typedef FILE LLFILE; #include <sys/stat.h> #if LL_WINDOWS -// windows version of stat function and stat data structure are called _stat -typedef struct _stat llstat; +// The Windows version of stat function and stat data structure are called _stat64 +// We use _stat64 here to support 64-bit st_size and time_t values +typedef struct _stat64 llstat; #else typedef struct stat llstat; #include <sys/types.h> @@ -56,35 +57,110 @@ typedef struct stat llstat; # define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) #endif +// Windows C runtime library does not define this and does not support symlink detection in the +// stat functions but we do in our getattr() function +#ifndef S_IFLNK +#define S_IFLNK 0xA000 /* symlink */ +#endif + +#ifndef S_ISLNK +#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) +#endif + #include "llstring.h" // safe char* -> std::string conversion +/// LLFile is a class of static functions operating on paths +/// All the functions with a path string input take UTF8 path/filenames class LL_COMMON_API LLFile { public: - // All these functions take UTF8 path/filenames. - static LLFILE* fopen(const std::string& filename,const char* accessmode); /* Flawfinder: ignore */ - static LLFILE* _fsopen(const std::string& filename,const char* accessmode,int sharingFlag); + /// open a file with the specified access mode + static LLFILE* fopen(const std::string& filename, const char* accessmode); /* Flawfinder: ignore */ + ///< 'accessmode' follows the rules of the Posix fopen() mode parameter + /// "r" open the file for reading only and positions the stream at the beginning + /// "r+" open the file for reading and writing and positions the stream at the beginning + /// "w" open the file for reading and writing and truncate it to zero length + /// "w+" open or create the file for reading and writing and truncate to zero length if it existed + /// "a" open the file for reading and writing and position the stream at the end of the file + /// "a+" open or create the file for reading and writing and position the stream at the end of the file + /// + /// in addition to these values, "b" can be appended to indicate binary stream access, but on Linux and Mac + /// this is strictly for compatibility and has no effect. On Windows this makes the file functions not + /// try to translate line endings. Windows also allows to append "t" to indicate text mode. If neither + /// "b" or "t" is defined, Windows uses the value set by _fmode which by default is _O_TEXT. + /// This means that it is always a good idea to append "b" specifically for binary file access to + /// avoid corruption of the binary consistency of the data stream when reading or writing + /// Other characters in 'accessmode' will usually cause an error as fopen will verify this parameter + /// @returns a valid LLFILE* pointer on success or NULL on failure static int close(LLFILE * file); + /// retrieve the content of a file into a string static std::string getContents(const std::string& filename); + ///< @returns the content of the file or an empty string on failure - // perms is a permissions mask like 0777 or 0700. In most cases it will - // be overridden by the user's umask. It is ignored on Windows. - // mkdir() considers "directory already exists" to be SUCCESS. + /// create a directory static int mkdir(const std::string& filename, int perms = 0700); - - static int rmdir(const std::string& filename); - static int remove(const std::string& filename, int supress_error = 0); - static int rename(const std::string& filename,const std::string& newname, int supress_error = 0); + ///< perms is a permissions mask like 0777 or 0700. In most cases it will be + /// overridden by the user's umask. It is ignored on Windows. + /// mkdir() considers "directory already exists" to be not an error. + /// @returns 0 on success and -1 on failure. + + //// remove a directory + static int rmdir(const std::string& filename, int suppress_error = 0); + ///< pass ENOENT in the optional 'suppress_error' parameter + /// if you don't want a warning in the log when the directory does not exist + /// @returns 0 on success and -1 on failure. + + /// remove a file or directory + static int remove(const std::string& filename, int suppress_error = 0); + ///< pass ENOENT in the optional 'suppress_error' parameter + /// if you don't want a warning in the log when the directory does not exist + /// @returns 0 on success and -1 on failure. + + /// rename a file + static int rename(const std::string& filename, const std::string& newname, int suppress_error = 0); + ///< it will silently overwrite newname if it exists without returning an error + /// Posix guarantees that if newname already exists, then there will be no moment + /// in which for other processes newname does not exist. There is no such guarantee + /// under Windows at this time. It may do it in the same way but the used Windows API + /// does not make such guarantees. + /// @returns 0 on success and -1 on failure. + + + /// copy the contents of file from 'from' to 'to' filename static bool copy(const std::string& from, const std::string& to); - - static int stat(const std::string& filename,llstat* file_status); - static bool isdir(const std::string& filename); - static bool isfile(const std::string& filename); - static LLFILE * _Fiopen(const std::string& filename, - std::ios::openmode mode); - + ///< @returns true on success and false on failure. + + /// return the file stat structure for filename + static int stat(const std::string& filename, llstat* file_status, int suppress_error = ENOENT); + ///< for compatibility with existing uses of LL_File::stat() we use ENOENT as default in the + /// optional 'suppress_error' parameter to avoid spamming the log with warnings when the API + /// is used to detect if a file exists + /// @returns 0 on success and -1 on failure. + + /// get the file or directory attributes for filename + static unsigned short getattr(const std::string& filename, bool dontFollowSymLink = false, int suppress_error = ENOENT); + ///< a more lightweight function on Windows to stat, that just returns the file attribute flags + /// dontFollowSymLinks set to true returns the attributes of the symlink if it is one, rather than resolving it + /// we pass by default ENOENT in the optional 'suppress_error' parameter to not spam the log with + /// warnings when the file or directory does not exist + /// @returns 0 on failure and a st_mode value with either S_IFDIR or S_IFREG set otherwise + /// together with the three access bits which under Windows only the write bit is relevant. + + /// check if filename is an existing directory + static bool isdir(const std::string& filename); + ///< @returns true if the path is for an existing directory + + /// check if filename is an existing file + static bool isfile(const std::string& filename); + ///< @returns true if the path is for an existing file + + /// check if filename is a symlink + static bool islink(const std::string& filename); + ///< @returns true if the path is pointing at a symlink + + /// return a path to the temporary directory on the system static const char * tmpdir(); }; diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 2c46c59aa5..edc891f5ec 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -1357,10 +1357,6 @@ bool gunzip_file(const std::string& srcfile, const std::string& dstfile) } while(gzeof(src) == 0); fclose(dst); dst = NULL; -#if LL_WINDOWS - // Rename in windows needs the dstfile to not exist. - LLFile::remove(dstfile, ENOENT); -#endif if (LLFile::rename(tmpfile, dstfile) == -1) goto err; /* Flawfinder: ignore */ retval = true; err: @@ -1408,10 +1404,6 @@ bool gzip_file(const std::string& srcfile, const std::string& dstfile) gzclose(dst); dst = NULL; -#if LL_WINDOWS - // Rename in windows needs the dstfile to not exist. - LLFile::remove(dstfile); -#endif if (LLFile::rename(tmpfile, dstfile) == -1) goto err; /* Flawfinder: ignore */ retval = true; err: diff --git a/indra/llconvexdecomposition/CMakeLists.txt b/indra/llconvexdecomposition/CMakeLists.txt deleted file mode 100644 index 7dae884db8..0000000000 --- a/indra/llconvexdecomposition/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -# -*- cmake -*- - -project(llconvexdecomposition) - -include(00-Common) -include(LLCommon) -include(LLMath) -include(VHACD) - -set(llconvexdecomposition_SOURCE_FILES - llconvexdecomposition.cpp - llconvexdecompositionvhacd.cpp - ) - -set(llconvexdecomposition_HEADER_FILES - CMakeLists.txt - llconvexdecomposition.h - llconvexdecompositionvhacd.h - ) - -set_source_files_properties(${llconvexdecomposition_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND llconvexdecomposition_SOURCE_FILES ${llconvexdecomposition_HEADER_FILES}) - -add_library (llconvexdecomposition ${llconvexdecomposition_SOURCE_FILES}) -target_include_directories(llconvexdecomposition INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) - -target_link_libraries(llconvexdecomposition - llcommon - llmath - ll::vhacd) - -if(WINDOWS) - target_compile_options(llconvexdecomposition PRIVATE /bigobj) -endif() - -# Add tests - diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index b1b698375a..d5c585b45e 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -576,10 +576,6 @@ bool LLCrashLogger::init() std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log.old"); std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log"); -#if LL_WINDOWS - LLAPRFile::remove(old_log_file); -#endif - LLFile::rename(log_file.c_str(), old_log_file.c_str()); // Set the log file to crashreport.log diff --git a/indra/llfilesystem/lldir_utils_objc.mm b/indra/llfilesystem/lldir_utils_objc.mm index 01fe9e1f2c..35513d5647 100644 --- a/indra/llfilesystem/lldir_utils_objc.mm +++ b/indra/llfilesystem/lldir_utils_objc.mm @@ -1,28 +1,28 @@ -/** +/** * @file lldir_utils_objc.mm * @brief Cocoa implementation of directory utilities for macOS * * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2020, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ - */ + */ #if LL_DARWIN //WARNING: This file CANNOT use standard linden includes due to conflicts between definitions of BOOL @@ -39,18 +39,18 @@ std::string getSystemTempFolder() tempDir = @"/tmp"; result = std::string([tempDir UTF8String]); } - + return result; } -//findSystemDirectory scoped exclusively to this file. +//findSystemDirectory scoped exclusively to this file. std::string findSystemDirectory(NSSearchPathDirectory searchPathDirectory, NSSearchPathDomainMask domainMask) { std::string result; @autoreleasepool { NSString *path = nil; - + // Search for the path NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory, domainMask, @@ -60,10 +60,10 @@ std::string findSystemDirectory(NSSearchPathDirectory searchPathDirectory, path = [paths objectAtIndex:0]; //HACK: Always attempt to create directory, ignore errors. NSError *error = nil; - + [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; - - + + result = std::string([path UTF8String]); } } @@ -88,7 +88,7 @@ std::string getSystemResourceFolder() NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; result = std::string([bundlePath UTF8String]); } - + return result; } @@ -102,7 +102,7 @@ std::string getSystemApplicationSupportFolder() { return findSystemDirectory (NSApplicationSupportDirectory, NSUserDomainMask); - + } #endif // LL_DARWIN diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index 5ce5244107..541266af4f 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -103,9 +103,6 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp const std::string old_filename = LLDiskCache::metaDataToFilepath(old_file_id, old_file_type); const std::string new_filename = LLDiskCache::metaDataToFilepath(new_file_id, new_file_type); - // Rename needs the new file to not exist. - LLFileSystem::removeFile(new_file_id, new_file_type, ENOENT); - if (LLFile::rename(old_filename, new_filename) != 0) { // We would like to return false here indicating the operation diff --git a/indra/llphysicsextensionsos/CMakeLists.txt b/indra/llphysicsextensionsos/CMakeLists.txt new file mode 100644 index 0000000000..c04115ef26 --- /dev/null +++ b/indra/llphysicsextensionsos/CMakeLists.txt @@ -0,0 +1,47 @@ +# -*- cmake -*- + +project(llphysicsextensionsos) + +include(00-Common) +include(LLCommon) +include(LLMath) +include(VHACD) + +set(llphysicsextensionsos_SOURCE_FILES + llconvexdecomposition.cpp + llconvexdecompositionvhacd.cpp + llpathinglib.cpp + LLPathingLibStubImpl.cpp + llphysicsextensions.cpp + LLPhysicsExtensionsStubImpl.cpp + ) + +set(llphysicsextensionsos_HEADER_FILES + CMakeLists.txt + llconvexdecomposition.h + llconvexdecompositionvhacd.h + llpathinglib.h + LLPathingLibStubImpl.h + llphysicsextensions.h + LLPhysicsExtensionsStubImpl.h + ) + +set_source_files_properties(${llphysicsextensionsos_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llphysicsextensionsos_SOURCE_FILES ${llphysicsextensionsos_HEADER_FILES}) + +add_library (llphysicsextensionsos ${llphysicsextensionsos_SOURCE_FILES}) +target_include_directories(llphysicsextensionsos INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(llphysicsextensionsos + llcommon + llmath + ll::vhacd) + +if(WINDOWS) + target_compile_options(llphysicsextensionsos PRIVATE /bigobj) +endif() + +# Add tests + diff --git a/indra/llphysicsextensionsos/LLPathingLibStubImpl.cpp b/indra/llphysicsextensionsos/LLPathingLibStubImpl.cpp new file mode 100644 index 0000000000..9830fd1ad0 --- /dev/null +++ b/indra/llphysicsextensionsos/LLPathingLibStubImpl.cpp @@ -0,0 +1,109 @@ +/** +* @file LLPathingLibStubImpl.cpp +* @author prep@lindenlab.com +* @brief A stubbed implementation of LLPathingLib +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 20112010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "linden_common.h" + +#include "llpathinglib.h" +#include "LLPathingLibStubImpl.h" + +#include "llsd.h" + +//============================================================================= +LLPathingLibImpl::LLPathingLibImpl() +{ +} + +LLPathingLibImpl::~LLPathingLibImpl() +{ + +} + +LLPathingLib* LLPathingLibImpl::getInstance() +{ + return NULL; +} + + +LLPathingLib::LLPLResult LLPathingLibImpl::initSystem() +{ + return LLPL_NOT_IMPLEMENTED; +} + +LLPathingLib::LLPLResult LLPathingLibImpl::quitSystem() +{ + return LLPL_NOT_IMPLEMENTED; +} + +LLPathingLib::LLPLResult LLPathingLibImpl::extractNavMeshSrcFromLLSD( const LLSD::Binary& dataBlock, int dir ) +{ + return LLPL_NOT_IMPLEMENTED; +} + +void LLPathingLibImpl::processNavMeshData() +{ +} + +LLPathingLibImpl::LLPLResult LLPathingLibImpl::generatePath( const PathingPacket& pathingPacket ) +{ + return LLPL_NOT_IMPLEMENTED; +} + +void LLPathingLibImpl::setNavMeshMaterialType( LLPLCharacterType materialType ) +{ +} + +void LLPathingLibImpl::setNavMeshColors( const NavMeshColors& color ) +{ +} + +void LLPathingLibImpl::renderNavMesh() +{ +} + +void LLPathingLibImpl::renderNavMeshEdges() +{ +} + +void LLPathingLibImpl::renderNavMeshShapesVBO( U32 shapeRenderFlags ) +{ +} + +void LLPathingLibImpl::renderPath() +{ +} + +void LLPathingLibImpl::renderPathBookend( LLRender& gl, LLPathingLib::LLPLPathBookEnd type ) +{ +} + +void LLPathingLibImpl::cleanupVBOManager() +{ +} + +void LLPathingLibImpl::cleanupResidual() +{ +} diff --git a/indra/llphysicsextensionsos/LLPathingLibStubImpl.h b/indra/llphysicsextensionsos/LLPathingLibStubImpl.h new file mode 100644 index 0000000000..8a97566e8c --- /dev/null +++ b/indra/llphysicsextensionsos/LLPathingLibStubImpl.h @@ -0,0 +1,78 @@ +/** +* @file LLPathingLibSubImpl.h +* @author prep@lindenlab.com +* @brief A stubbed implementation of LLPathingLib +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_PATHING_LIB_H +#define LL_PATHING_LIB_H + +#include "llpathinglib.h" + +class LLSD; + +//============================================================================= +class LLPathingLibImpl : public LLPathingLib +{ +public: + LLPathingLibImpl(); + virtual ~LLPathingLibImpl(); + + // Obtain a pointer to the actual implementation + static LLPathingLib* getInstance(); + static LLPathingLib::LLPLResult initSystem(); + static LLPathingLib::LLPLResult quitSystem(); + + //Extract and store navmesh data from the llsd datablock sent down by the server + virtual LLPLResult extractNavMeshSrcFromLLSD( const LLSD::Binary& dataBlock, int dir ); + //Stitch any stored navmeshes together + virtual void processNavMeshData(); + + //Method used to generate and visualize a path on the viewers navmesh + virtual LLPLResult generatePath( const PathingPacket& pathingPacket ); + + //Set the material type for the heatmap type + virtual void setNavMeshMaterialType( LLPLCharacterType materialType ); + //Set the various navmesh colors + virtual void setNavMeshColors( const NavMeshColors& color ); + + //The entry method to rendering the client side navmesh + virtual void renderNavMesh(); + //The entry method to rendering the client side navmesh edges + virtual void renderNavMeshEdges(); + //The entry method to render the client navmesh shapes VBO + virtual void renderNavMeshShapesVBO( U32 shapeRenderFlags ); + //The entry method to render the clients designated path + virtual void renderPath(); + //The entry method to render the capsule bookends for the clients designated path + virtual void renderPathBookend( LLRender& gl, LLPathingLib::LLPLPathBookEnd type ); + + //Method to delete any vbo's that are currently being managed by the pathing library + virtual void cleanupVBOManager(); + //Method to cleanup any allocations within the implementation + virtual void cleanupResidual(); +}; + +#endif //LL_PATHING_LIB_H + diff --git a/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.cpp b/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.cpp new file mode 100644 index 0000000000..8401e16e9c --- /dev/null +++ b/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.cpp @@ -0,0 +1,51 @@ +/** +* @file LLPhysicsExtensionsStubImpl.cpp +* @author prep@lindenlab.com +* @brief A stubbed implementation of LLPhysicsExtensions +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "linden_common.h" + +#include "llphysicsextensions.h" +#include "LLPhysicsExtensionsStubImpl.h" + +//============================================================================= +LLPhysicsExtensionsImpl::LLPhysicsExtensionsImpl() +{ +} + +LLPhysicsExtensionsImpl::~LLPhysicsExtensionsImpl() +{ +} + +bool LLPhysicsExtensionsImpl::initSystem() +{ + return false; +} + +bool LLPhysicsExtensionsImpl::quitSystem() +{ + return false; +} + diff --git a/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.h b/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.h new file mode 100644 index 0000000000..135f92bb88 --- /dev/null +++ b/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.h @@ -0,0 +1,46 @@ +/** +* @file LLPhysicsExtensionsSubImpl.h +* @author prep@lindenlab.com +* @brief A stubbed implementation of LLPhysicsExtensions +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_PHYSICS_EXTENSIONS_STUB_IMPL_H +#define LL_PHYSICS_EXTENSIONS_STUB_IMPL_H + +#include "llphysicsextensions.h" + +//============================================================================= +class LLPhysicsExtensionsImpl : public LLPhysicsExtensions +{ + public: + + LLPhysicsExtensionsImpl(); + virtual ~LLPhysicsExtensionsImpl(); + + static bool initSystem(); + static bool quitSystem(); +}; + +#endif //LL_PHYSICS_EXTENSIONS_STUB_IMPL_H + diff --git a/indra/llconvexdecomposition/llconvexdecomposition.cpp b/indra/llphysicsextensionsos/llconvexdecomposition.cpp index 7b9d775c53..d58c0fec54 100644 --- a/indra/llconvexdecomposition/llconvexdecomposition.cpp +++ b/indra/llphysicsextensionsos/llconvexdecomposition.cpp @@ -25,6 +25,7 @@ * $/LicenseInfo$ */ +#include <unordered_map> #include "linden_common.h" #include "llconvexdecompositionvhacd.h" diff --git a/indra/llconvexdecomposition/llconvexdecomposition.h b/indra/llphysicsextensionsos/llconvexdecomposition.h index 8008bc6e12..8008bc6e12 100644 --- a/indra/llconvexdecomposition/llconvexdecomposition.h +++ b/indra/llphysicsextensionsos/llconvexdecomposition.h diff --git a/indra/llconvexdecomposition/llconvexdecompositionvhacd.cpp b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp index 78876f9f36..78876f9f36 100644 --- a/indra/llconvexdecomposition/llconvexdecompositionvhacd.cpp +++ b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp diff --git a/indra/llconvexdecomposition/llconvexdecompositionvhacd.h b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.h index 675356629c..675356629c 100644 --- a/indra/llconvexdecomposition/llconvexdecompositionvhacd.h +++ b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.h diff --git a/indra/llphysicsextensionsos/llpathinglib.cpp b/indra/llphysicsextensionsos/llpathinglib.cpp new file mode 100644 index 0000000000..f41cb9c45f --- /dev/null +++ b/indra/llphysicsextensionsos/llpathinglib.cpp @@ -0,0 +1,83 @@ +/** +* @file llpathinglib.cpp +* @author prep@lindenlab.com +* @brief LLPathingLib core creation methods +* +* $LicenseInfo:firstyear=2012&license=lgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2011, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "linden_common.h" + +#include "LLPathingLibStubImpl.h" + +#include "llpathinglib.h" + +//============================================================================= + +/*static */bool LLPathingLib::s_isInitialized = false; + +//============================================================================= + + +/*static*/bool LLPathingLib::isFunctional() +{ + return false; +} + +/*static*/LLPathingLib* LLPathingLib::getInstance() +{ + if ( !s_isInitialized ) + { + return NULL; + } + else + { + return LLPathingLibImpl::getInstance(); + } +} + +//============================================================================= + +/*static */LLPathingLib::LLPLResult LLPathingLib::initSystem() +{ + if ( LLPathingLibImpl::initSystem() == LLPL_OK ) + { + s_isInitialized = true; + return LLPL_OK; + } + return LLPL_UNKOWN_ERROR; +} +//============================================================================= +/*static */LLPathingLib::LLPLResult LLPathingLib::quitSystem() +{ + LLPLResult quitResult = LLPL_UNKOWN_ERROR; + + if (s_isInitialized) + { + quitResult = LLPathingLibImpl::quitSystem(); + s_isInitialized = false; + } + + return quitResult; +} +//============================================================================= + diff --git a/indra/llphysicsextensionsos/llpathinglib.h b/indra/llphysicsextensionsos/llpathinglib.h new file mode 100644 index 0000000000..41583f1fd1 --- /dev/null +++ b/indra/llphysicsextensionsos/llpathinglib.h @@ -0,0 +1,187 @@ +/** + * @file llpathinglib.cpp + * @author prep@lindenlab.com + * @brief LLPathingLib interface definition + * + * $LicenseInfo:firstyear=2012&license=lgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_PATHING_LIBRARY +#define LL_PATHING_LIBRARY + +#include "llpreprocessor.h" +#include "llsd.h" +#include "v3dmath.h" +#include "v4math.h" + +#include "v4color.h" +#include "v4coloru.h" +#include "llphysicsextensions.h" + +typedef int bool32; + +#if defined(_WIN32) || defined(_WIN64) +#define LLCD_CALL __cdecl +#else +#define LLCD_CALL +#endif + +class LLRender; + +//============================================================================= +class LLPathingLib +{ + +public: + enum LLShapeType + { + LLST_WalkableObjects = 0, + LLST_ObstacleObjects, + LLST_MaterialPhantoms, + LLST_ExclusionPhantoms, + LLST_MaxShapeTypes = LLST_ExclusionPhantoms+1, + LLST_None = LLST_MaxShapeTypes+2, + LLST_SimpleBox = LLST_None+1, + LLST_SimpleCapsule = LLST_SimpleBox+1, + }; + + enum LLShapeTypeFlag + { + LLSTB_WalkableObjects = 0x1 << 1, + LLSTB_ObstacleObjects = 0x1 << 2, + LLSTB_MaterialPhantoms = 0x1 << 3, + LLSTB_ExclusionPhantoms = 0x1 << 4, + LLSTB_None = 0x1 << 5 + }; + + enum LLPLPathBookEnd + { + LLPL_START = 0, + LLPL_END, + }; + + enum LLPLResult + { + LLPL_OK = 0, + LLPL_NOTSET, + LLPL_ERROR, + LLPL_NO_NAVMESH, + LLPL_UNKOWN_ERROR, + LLPL_NO_PATH, + LLPL_PATH_GENERATED_OK, + LLPL_NOT_IMPLEMENTED, + }; + + enum LLPLCharacterType + { + LLPL_CHARACTER_TYPE_A = 4, + LLPL_CHARACTER_TYPE_B = 3, + LLPL_CHARACTER_TYPE_C = 2, + LLPL_CHARACTER_TYPE_D = 1, + LLPL_CHARACTER_TYPE_NONE = 0 + }; + + struct PathingPacket + { + PathingPacket() : mHasPointA(false), mHasPointB(false), mCharacterWidth(0.0f), mCharacterType(LLPL_CHARACTER_TYPE_NONE) {} + bool mHasPointA; + LLVector3 mStartPointA; + LLVector3 mEndPointA; + bool mHasPointB; + LLVector3 mStartPointB; + LLVector3 mEndPointB; + F32 mCharacterWidth; + LLPLCharacterType mCharacterType; + }; + + struct NavMeshColors + { + LLColor4U mWalkable; + LLColor4U mObstacle; + LLColor4U mMaterial; + LLColor4U mExclusion; + LLColor4U mConnectedEdge; + LLColor4U mBoundaryEdge; + LLColor4 mHeatColorBase; + LLColor4 mHeatColorMax; + LLColor4U mFaceColor; + LLColor4U mStarValid; + LLColor4U mStarInvalid; + LLColor4U mTestPath; + LLColor4U mWaterColor; + }; + +public: + //Ctor + LLPathingLib() {} + virtual ~LLPathingLib() {} + + /// @returns false if this is the stub + static bool isFunctional(); + + // Obtain a pointer to the actual implementation + static LLPathingLib* getInstance(); + static LLPathingLib::LLPLResult initSystem(); + static LLPathingLib::LLPLResult quitSystem(); + + //Extract and store navmesh data from the llsd datablock sent down by the server + virtual LLPLResult extractNavMeshSrcFromLLSD( const LLSD::Binary& dataBlock, int dir ) = 0; + //Stitch any stored navmeshes together + virtual void processNavMeshData( ) = 0; + + //Method used to generate and visualize a path on the viewers navmesh + virtual LLPLResult generatePath( const PathingPacket& pathingPacket ) = 0; + + //Set the material type for the heatmap type + virtual void setNavMeshMaterialType( LLPLCharacterType materialType ) = 0; + //Set the various navmesh colors + virtual void setNavMeshColors( const NavMeshColors& color ) = 0; + + //The entry method to rendering the client side navmesh + virtual void renderNavMesh() = 0; + //The entry method to rendering the client side navmesh edges + virtual void renderNavMeshEdges() = 0; + //The entry method to render the client navmesh shapes VBO + virtual void renderNavMeshShapesVBO( U32 shapeRenderFlags ) = 0; + //The entry method to render the clients designated path + virtual void renderPath() = 0; + //The entry method to render the capsule bookends for the clients designated path + virtual void renderPathBookend( LLRender& gl, LLPathingLib::LLPLPathBookEnd type ) = 0; + //Renders all of the generated simple shapes (using their default transforms) + virtual void renderSimpleShapes( LLRender& gl, F32 regionsWaterHeight ) = 0; + + //Method called from second life to create a capsule from properties of a character + virtual void createPhysicsCapsuleRep( F32 length, F32 radius, BOOL horizontal, const LLUUID& id ) = 0; + //Removes any cached physics capsule using a list of cached uuids + virtual void cleanupPhysicsCapsuleRepResiduals() = 0; + //Renders a selected uuids physics rep + virtual void renderSimpleShapeCapsuleID( LLRender& gl, const LLUUID& id, const LLVector3& pos, const LLQuaternion& rot ) = 0; + + //Method to delete any vbo's that are currently being managed by the pathing library + virtual void cleanupVBOManager( ) = 0; + //Method to cleanup any allocations within the implementation + virtual void cleanupResidual( ) = 0; +private: + static bool s_isInitialized; +}; + +#endif //LL_PATHING_LIBRARY diff --git a/indra/llphysicsextensionsos/llphysicsextensions.cpp b/indra/llphysicsextensionsos/llphysicsextensions.cpp new file mode 100644 index 0000000000..3bb8ffbf1a --- /dev/null +++ b/indra/llphysicsextensionsos/llphysicsextensions.cpp @@ -0,0 +1,78 @@ +/** +* @file llphysicsextensions.cpp +* @author nyx@lindenlab.com +* @brief LLPhysicsExtensions core initialization methods +* +* $LicenseInfo:firstyear=2012&license=lgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2011, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "linden_common.h" + +#include "llphysicsextensions.h" +#include "LLPhysicsExtensionsStubImpl.h" + + +//disable the undefined symbol optimization +//#pragma warning (disable : 4221) + +//============================================================================= + +/*static */bool LLPhysicsExtensions::s_isInitialized = false; + + +/*static*/bool LLPhysicsExtensions::isFunctional() +{ + return false; +} + +//============================================================================= + +/*static*/LLPhysicsExtensions* LLPhysicsExtensions::getInstance() +{ + if ( !s_isInitialized ) + { + return NULL; + } + else + { + return LLPhysicsExtensionsImpl::getInstance(); + } +} + +//============================================================================= + +/*static */bool LLPhysicsExtensions::initSystem() +{ + bool result = LLPhysicsExtensionsImpl::initSystem(); + if ( result ) + { + s_isInitialized = true; + } + return result; +} +//============================================================================= +/*static */bool LLPhysicsExtensions::quitSystem() +{ + return LLPhysicsExtensionsImpl::quitSystem(); +} +//============================================================================= + diff --git a/indra/llphysicsextensionsos/llphysicsextensions.h b/indra/llphysicsextensionsos/llphysicsextensions.h new file mode 100644 index 0000000000..fa23ebd725 --- /dev/null +++ b/indra/llphysicsextensionsos/llphysicsextensions.h @@ -0,0 +1,59 @@ +/** +* @file llphysicsextensions.h +* @author nyx@lindenlab.com +* @brief LLPhysicsExtensions core shared initialization +* routines +* +* $LicenseInfo:firstyear=2012&license=lgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2011, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_PHYSICS_EXTENSIONS +#define LL_PHYSICS_EXTENSIONS + +#include "llpreprocessor.h" +#include "llsd.h" +#include "v3dmath.h" + +#define LLPHYSICSEXTENSIONS_VERSION "1.0" + +typedef int bool32; + +class LLPhysicsExtensions +{ + +public: + // Obtain a pointer to the actual implementation + static LLPhysicsExtensions* getInstance(); + + /// @returns false if this is the stub + static bool isFunctional(); + + static bool initSystem(); + static bool quitSystem(); + +private: + static bool s_isInitialized; +}; + +#endif //LL_PATHING_LIBRARY + + diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 63f1de8d6a..d6ab52a17a 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -986,6 +986,7 @@ void LLPluginProcessParent::poll(F64 timeout) } // Remove instances in the done state from the sInstances map. + LLCoros::LockType lock(*sInstancesMutex); mapInstances_t::iterator itClean = sInstances.begin(); while (itClean != sInstances.end()) { diff --git a/indra/llplugin/slplugin/slplugin-objc.mm b/indra/llplugin/slplugin/slplugin-objc.mm index 68ff196eaf..adde594b59 100644 --- a/indra/llplugin/slplugin/slplugin-objc.mm +++ b/indra/llplugin/slplugin/slplugin-objc.mm @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ * @@ -38,51 +38,51 @@ void LLCocoaPlugin::setupCocoa() { - static bool inited = false; - - if(!inited) - { - createAutoReleasePool(); - - // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. - // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' - // when init'ing the Cocoa App window. - [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; - - // This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor": - // http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html - - // Needed for Carbon based applications which call into Cocoa - NSApplicationLoad(); - - // Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image - [[[NSWindow alloc] init] release]; - + static bool inited = false; + + if(!inited) + { + createAutoReleasePool(); + + // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. + // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' + // when init'ing the Cocoa App window. + [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; + + // This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor": + // http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html + + // Needed for Carbon based applications which call into Cocoa + NSApplicationLoad(); + + // Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image + [[[NSWindow alloc] init] release]; + mPluginWindow = [NSApp mainWindow]; - - deleteAutoReleasePool(); - - inited = true; - } + + deleteAutoReleasePool(); + + inited = true; + } } static NSAutoreleasePool *sPool = NULL; void LLCocoaPlugin::createAutoReleasePool() { - if(!sPool) - { - sPool = [[NSAutoreleasePool alloc] init]; - } + if(!sPool) + { + sPool = [[NSAutoreleasePool alloc] init]; + } } void LLCocoaPlugin::deleteAutoReleasePool() { - if(sPool) - { - [sPool release]; - sPool = NULL; - } + if(sPool) + { + [sPool release]; + sPool = NULL; + } } LLCocoaPlugin::LLCocoaPlugin():mHackState(0) @@ -110,12 +110,12 @@ void LLCocoaPlugin::setupGroup() // { // // Start out with a window layer that's way out in front (fixes the problem with the menubar not getting hidden on first switch to fullscreen youtube) // SetWindowGroupName(layer_group, CFSTR("SLPlugin Layer")); - // SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel); + // SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel); // } - + } -void LLCocoaPlugin::updateWindows() +void LLCocoaPlugin::updateWindows() { // NSArray* window_list = [NSApp orderedWindows]; // NSWindow* current_window = [window_list objectAtIndex:0]; @@ -123,38 +123,38 @@ void LLCocoaPlugin::updateWindows() // bool this_is_front_process = false; // bool parent_is_front_process = false; // -// +// // // Check for a change in this process's frontmost window. // if ( current_window != mFrontWindow ) // { // // and figure out whether this process or its parent are currently frontmost // if ( current_window == parent_window ) parent_is_front_process = true; // if ( current_window == mPluginWindow ) this_is_front_process = true; -// +// // if (current_window != NULL && mFrontWindow == NULL) // { // // Opening the first window -// +// // if(mHackState == 0) // { // // Next time through the event loop, lower the window group layer // mHackState = 1; // } -// +// // if(parent_is_front_process) // { // // Bring this process's windows to the front. // [mPluginWindow makeKeyAndOrderFront:NSApp]; // [mPluginWindow setOrderedIndex:0]; // } -// +// // [NSApp activateIgnoringOtherApps:YES]; // } -// +// // else if (( current_window == NULL) && (mFrontWindow != NULL)) // { // // Closing the last window -// +// // if(this_is_front_process) // { // // Try to bring this process's parent to the front @@ -171,7 +171,7 @@ void LLCocoaPlugin::updateWindows() //// } // mHackState = 2; // } -// +// // mFrontWindow = [window_list objectAtIndex:0]; // } } diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 0e8f591800..d93a75b05d 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -87,15 +87,18 @@ target_link_libraries(llprimitive llxml llcharacter llrender - llphysicsextensions_impl ll::colladadom ll::glm ) -if (TARGET llconvexdecomposition) +if (HAVOK OR HAVOK_TPV) target_link_libraries(llprimitive - llconvexdecomposition - ) + llphysicsextensions_impl + ) +else() + target_link_libraries(llprimitive + llphysicsextensionsos + ) endif () include(LibraryInstall) diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp index 6d907d7e45..9eefba1390 100644 --- a/indra/llui/llviewereventrecorder.cpp +++ b/indra/llui/llviewereventrecorder.cpp @@ -34,8 +34,6 @@ LLViewerEventRecorder::LLViewerEventRecorder() { logEvents = false; // Remove any previous event log file std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old"); - LLFile::remove(old_log_ui_events_to_llsd_file, ENOENT); - mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd"); LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file, ENOENT); diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 268afe843d..bdb5d8def0 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -125,7 +125,7 @@ attributedStringInfo getSegments(NSAttributedString *str) - (unsigned long)getVramSize { CGLRendererInfoObj info = 0; - GLint vram_megabytes = 0; + GLint vram_megabytes = 0; int num_renderers = 0; CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers); if(0 == the_err) @@ -143,7 +143,7 @@ attributedStringInfo getSegments(NSAttributedString *str) vram_megabytes = 256; } - return (unsigned long)vram_megabytes; // return value is in megabytes. + return (unsigned long)vram_megabytes; // return value is in megabytes. } - (void)viewWillMoveToWindow:(nullable NSWindow *)newWindow @@ -164,24 +164,24 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void)viewDidMoveToWindow { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(windowResized:) name:NSWindowDidResizeNotification - object:[self window]]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowResized:) name:NSWindowDidResizeNotification + object:[self window]]; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification - object:[self window]]; + selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification + object:[self window]]; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification - object:[self window]]; + selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification + object:[self window]]; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification - object:[self window]]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(windowDidChangeScreen:) name:NSWindowDidChangeScreenNotification - object:[self window]]; + selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification + object:[self window]]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowDidChangeScreen:) name:NSWindowDidChangeScreenNotification + object:[self window]]; NSRect wnd_rect = [[self window] frame]; @@ -215,28 +215,28 @@ attributedStringInfo getSegments(NSAttributedString *str) -(void)windowDidChangeScreen:(NSNotification *)notification; { - callWindowDidChangeScreen(); + callWindowDidChangeScreen(); } - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; } - (id) init { - return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE]; + return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE]; } - (id) initWithSamples:(NSUInteger)samples { - return [self initWithFrame:[self bounds] withSamples:samples andVsync:TRUE]; + return [self initWithFrame:[self bounds] withSamples:samples andVsync:TRUE]; } - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync { - return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync]; + return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync]; } #if LL_DARWIN @@ -248,21 +248,21 @@ attributedStringInfo getSegments(NSAttributedString *str) - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync { [self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeURL]]; - [self initWithFrame:frame]; + [self initWithFrame:frame]; - // Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6. - // Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat. - // 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons). + // Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6. + // Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat. + // 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons). - NSOpenGLPixelFormatAttribute SDRAttrs[] = { + NSOpenGLPixelFormatAttribute SDRAttrs[] = { NSOpenGLPFANoRecovery, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAClosestPolicy, - NSOpenGLPFAAccelerated, - NSOpenGLPFADepthSize, 24, - NSOpenGLPFAColorSize, 32, - NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core, - 0 + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAClosestPolicy, + NSOpenGLPFAAccelerated, + NSOpenGLPFADepthSize, 24, + NSOpenGLPFAColorSize, 32, + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core, + 0 }; NSOpenGLPixelFormatAttribute HDRAttrs[] = { @@ -298,21 +298,21 @@ attributedStringInfo getSegments(NSAttributedString *str) pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:SDRAttrs] autorelease]; } - if (pixelFormat == nil) - { - NSLog(@"Failed to create pixel format!", nil); - return nil; - } + if (pixelFormat == nil) + { + NSLog(@"Failed to create pixel format!", nil); + return nil; + } - glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; + glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - if (glContext == nil) - { - NSLog(@"Failed to create OpenGL context!", nil); - return nil; - } + if (glContext == nil) + { + NSLog(@"Failed to create OpenGL context!", nil); + return nil; + } - [self setPixelFormat:pixelFormat]; + [self setPixelFormat:pixelFormat]; if(mHDRDisplay) { @@ -327,55 +327,55 @@ attributedStringInfo getSegments(NSAttributedString *str) NSLog(@"Extended color space applied for HDR Display", nil); } - //for retina support - [self setWantsBestResolutionOpenGLSurface:gHiDPISupport]; + //for retina support + [self setWantsBestResolutionOpenGLSurface:gHiDPISupport]; - [self setOpenGLContext:glContext]; + [self setOpenGLContext:glContext]; - [glContext setView:self]; + [glContext setView:self]; - [glContext makeCurrentContext]; + [glContext makeCurrentContext]; - if (vsync) - { - GLint value = 1; + if (vsync) + { + GLint value = 1; [glContext setValues:&value forParameter:NSOpenGLContextParameterSwapInterval]; - } else { - // supress this error after move to Xcode 7: - // error: null passed to a callee that requires a non-null argument [-Werror,-Wnonnull] - // Tried using ObjC 'nonnull' keyword as per SO article but didn't build - GLint swapInterval=0; + } else { + // supress this error after move to Xcode 7: + // error: null passed to a callee that requires a non-null argument [-Werror,-Wnonnull] + // Tried using ObjC 'nonnull' keyword as per SO article but didn't build + GLint swapInterval=0; [glContext setValues:&swapInterval forParameter:NSOpenGLContextParameterSwapInterval]; - } + } GLint opacity = 1; [glContext setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; - return self; + return self; } - (BOOL) rebuildContext { - return [self rebuildContextWithFormat:[self pixelFormat]]; + return [self rebuildContextWithFormat:[self pixelFormat]]; } - (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format { - NSOpenGLContext *ctx = [self openGLContext]; + NSOpenGLContext *ctx = [self openGLContext]; - [ctx clearDrawable]; - [ctx initWithFormat:format shareContext:nil]; + [ctx clearDrawable]; + [ctx initWithFormat:format shareContext:nil]; - if (ctx == nil) - { - NSLog(@"Failed to create OpenGL context!", nil); - return false; - } + if (ctx == nil) + { + NSLog(@"Failed to create OpenGL context!", nil); + return false; + } - [self setOpenGLContext:ctx]; - [ctx setView:self]; - [ctx makeCurrentContext]; - return true; + [self setOpenGLContext:ctx]; + [ctx setView:self]; + [ctx makeCurrentContext]; + return true; } #if LL_DARWIN @@ -384,14 +384,14 @@ attributedStringInfo getSegments(NSAttributedString *str) - (CGLContextObj)getCGLContextObj { - NSOpenGLContext *ctx = [self openGLContext]; - return (CGLContextObj)[ctx CGLContextObj]; + NSOpenGLContext *ctx = [self openGLContext]; + return (CGLContextObj)[ctx CGLContextObj]; } - (CGLPixelFormatObj*)getCGLPixelFormatObj { - NSOpenGLPixelFormat *fmt = [self pixelFormat]; - return (CGLPixelFormatObj*)[fmt CGLPixelFormatObj]; + NSOpenGLPixelFormat *fmt = [self pixelFormat]; + return (CGLPixelFormatObj*)[fmt CGLPixelFormatObj]; } // Various events can be intercepted by our view, thus not reaching our window. @@ -436,29 +436,29 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) rightMouseDown:(NSEvent *)theEvent { - callRightMouseDown(mMousePos, [theEvent modifierFlags]); + callRightMouseDown(mMousePos, [theEvent modifierFlags]); } - (void) rightMouseUp:(NSEvent *)theEvent { - callRightMouseUp(mMousePos, [theEvent modifierFlags]); + callRightMouseUp(mMousePos, [theEvent modifierFlags]); } - (void)mouseMoved:(NSEvent *)theEvent { NSPoint dev_delta = [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])]; - float mouseDeltas[] = { - float(dev_delta.x), - float(dev_delta.y) - }; + float mouseDeltas[] = { + float(dev_delta.x), + float(dev_delta.y) + }; - callDeltaUpdate(mouseDeltas, 0); + callDeltaUpdate(mouseDeltas, 0); NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]]; - mMousePos[0] = mPoint.x; - mMousePos[1] = mPoint.y; - callMouseMoved(mMousePos, 0); + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; + callMouseMoved(mMousePos, 0); } // NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged. @@ -466,23 +466,23 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) mouseDragged:(NSEvent *)theEvent { - // Trust the deltas supplied by NSEvent. - // The old CoreGraphics APIs we previously relied on are now flagged as obsolete. - // NSEvent isn't obsolete, and provides us with the correct deltas. + // Trust the deltas supplied by NSEvent. + // The old CoreGraphics APIs we previously relied on are now flagged as obsolete. + // NSEvent isn't obsolete, and provides us with the correct deltas. NSPoint dev_delta = [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])]; - float mouseDeltas[] = { - float(dev_delta.x), - float(dev_delta.y) - }; + float mouseDeltas[] = { + float(dev_delta.x), + float(dev_delta.y) + }; - callDeltaUpdate(mouseDeltas, 0); + callDeltaUpdate(mouseDeltas, 0); - NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]]; - mMousePos[0] = mPoint.x; - mMousePos[1] = mPoint.y; - callMouseDragged(mMousePos, 0); + NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]]; + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; + callMouseDragged(mMousePos, 0); } - (void) otherMouseDown:(NSEvent *)theEvent @@ -497,29 +497,29 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) rightMouseDragged:(NSEvent *)theEvent { - [self mouseDragged:theEvent]; + [self mouseDragged:theEvent]; } - (void) otherMouseDragged:(NSEvent *)theEvent { - [self mouseDragged:theEvent]; + [self mouseDragged:theEvent]; } - (void) scrollWheel:(NSEvent *)theEvent { - callScrollMoved(-[theEvent deltaX], -[theEvent deltaY]); + callScrollMoved(-[theEvent deltaX], -[theEvent deltaY]); } - (void) mouseExited:(NSEvent *)theEvent { - callMouseExit(); + callMouseExit(); } - (void) keyUp:(NSEvent *)theEvent { NativeKeyEventData eventData = extractKeyDataFromKeyEvent(theEvent); eventData.mKeyEvent = NativeKeyEventData::KEYUP; - callKeyUp(&eventData, [theEvent keyCode], [theEvent modifierFlags]); + callKeyUp(&eventData, [theEvent keyCode], [theEvent modifierFlags]); } - (void) keyDown:(NSEvent *)theEvent @@ -533,7 +533,7 @@ attributedStringInfo getSegments(NSAttributedString *str) // Because flagsChange event handler misses event when other window is activated, // e.g. OS Window for upload something or Input Window... // mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit) - mModifiers = [theEvent modifierFlags]; + mModifiers = [theEvent modifierFlags]; NSString *str_no_modifiers = [theEvent charactersIgnoringModifiers]; unichar ch = 0; if (str_no_modifiers.length) @@ -561,8 +561,8 @@ attributedStringInfo getSegments(NSAttributedString *str) { NativeKeyEventData eventData = extractKeyDataFromModifierEvent(theEvent); - mModifiers = [theEvent modifierFlags]; - callModifier([theEvent modifierFlags]); + mModifiers = [theEvent modifierFlags]; + callModifier([theEvent modifierFlags]); NSInteger mask = 0; switch([theEvent keyCode]) @@ -603,69 +603,69 @@ attributedStringInfo getSegments(NSAttributedString *str) - (BOOL) acceptsFirstResponder { - return YES; + return YES; } - (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender { - NSPasteboard *pboard; + NSPasteboard *pboard; NSDragOperation sourceDragMask; - sourceDragMask = [sender draggingSourceOperationMask]; + sourceDragMask = [sender draggingSourceOperationMask]; - pboard = [sender draggingPasteboard]; + pboard = [sender draggingPasteboard]; if ([[pboard types] containsObject:NSPasteboardTypeURL]) - { - if (sourceDragMask & NSDragOperationLink) { - NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0]; - mLastDraggedUrl = [[fileUrl absoluteString] UTF8String]; + { + if (sourceDragMask & NSDragOperationLink) { + NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0]; + mLastDraggedUrl = [[fileUrl absoluteString] UTF8String]; return NSDragOperationLink; } - } - return NSDragOperationNone; + } + return NSDragOperationNone; } - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender { - callHandleDragUpdated(mLastDraggedUrl); + callHandleDragUpdated(mLastDraggedUrl); - return NSDragOperationLink; + return NSDragOperationLink; } - (void) draggingExited:(id<NSDraggingInfo>)sender { - callHandleDragExited(mLastDraggedUrl); + callHandleDragExited(mLastDraggedUrl); } - (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender { - return YES; + return YES; } - (BOOL) performDragOperation:(id<NSDraggingInfo>)sender { - callHandleDragDropped(mLastDraggedUrl); - return true; + callHandleDragDropped(mLastDraggedUrl); + return true; } - (BOOL)hasMarkedText { - return mHasMarkedText; + return mHasMarkedText; } - (NSRange)markedRange { - int range[2]; - getPreeditMarkedRange(&range[0], &range[1]); - return NSMakeRange(range[0], range[1]); + int range[2]; + getPreeditMarkedRange(&range[0], &range[1]); + return NSMakeRange(range[0], range[1]); } - (NSRange)selectedRange { - int range[2]; - getPreeditSelectionRange(&range[0], &range[1]); - return NSMakeRange(range[0], range[1]); + int range[2]; + getPreeditSelectionRange(&range[0], &range[1]); + return NSMakeRange(range[0], range[1]); } - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange @@ -751,21 +751,21 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void)unmarkText { - [[self inputContext] discardMarkedText]; - resetPreedit(); - mHasMarkedText = FALSE; + [[self inputContext] discardMarkedText]; + resetPreedit(); + mHasMarkedText = FALSE; } // We don't support attributed strings. - (NSArray *)validAttributesForMarkedText { - return [NSArray array]; + return [NSArray array]; } // See above. - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { - return nil; + return nil; } - (void)insertText:(id)insertString @@ -778,9 +778,9 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { - // SL-19801 Special workaround for system emoji picker - if ([aString length] == 2) - { + // SL-19801 Special workaround for system emoji picker + if ([aString length] == 2) + { @try { uint32_t b0 = [aString characterAtIndex:0]; @@ -798,7 +798,7 @@ attributedStringInfo getSegments(NSAttributedString *str) NSLog(@"Encountered an unsupported attributed character. Exception: %@ String: %@", e.name, aString); return; } - } + } @try { @@ -831,36 +831,36 @@ attributedStringInfo getSegments(NSAttributedString *str) if (!(mModifiers & NSEventModifierFlagCommand) && !(mModifiers & NSEventModifierFlagShift) && !(mModifiers & NSEventModifierFlagOption)) - { - callUnicodeCallback(13, 0); - } else { - callUnicodeCallback(13, mModifiers); - } + { + callUnicodeCallback(13, 0); + } else { + callUnicodeCallback(13, mModifiers); + } } - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { - return NSNotFound; + return NSNotFound; } - (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { - float pos[4] = {0, 0, 0, 0}; - getPreeditLocation(pos, mMarkedTextLength); - return NSMakeRect(pos[0], pos[1], pos[2], pos[3]); + float pos[4] = {0, 0, 0, 0}; + getPreeditLocation(pos, mMarkedTextLength); + return NSMakeRect(pos[0], pos[1], pos[2], pos[3]); } - (void)doCommandBySelector:(SEL)aSelector { - if (aSelector == @selector(insertNewline:)) - { - [self insertNewline:self]; - } + if (aSelector == @selector(insertNewline:)) + { + [self insertNewline:self]; + } } - (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex { - return NO; + return NO; } - (void) allowMarkedTextInput:(bool)allowed @@ -895,7 +895,7 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) setGLView:(LLOpenGLView *)view { - glview = view; + glview = view; } - (void)keyDown:(NSEvent *)theEvent @@ -946,24 +946,24 @@ attributedStringInfo getSegments(NSAttributedString *str) - (id) init { - return self; + return self; } - (BOOL) becomeFirstResponder { - callFocus(); - return true; + callFocus(); + return true; } - (BOOL) resignFirstResponder { - callFocusLost(); - return true; + callFocusLost(); + return true; } - (void) close { - callQuitHandler(); + callQuitHandler(); } @end diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 42cd95be5d..d902a82a3c 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -41,15 +41,15 @@ int createNSApp(int argc, const char *argv[]) { - return NSApplicationMain(argc, argv); + return NSApplicationMain(argc, argv); } void setupCocoa() { - static bool inited = false; - - if(!inited) - { + static bool inited = false; + + if(!inited) + { @autoreleasepool { // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' @@ -57,8 +57,8 @@ void setupCocoa() [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; } - inited = true; - } + inited = true; + } } bool copyToPBoard(const unsigned short *str, unsigned int len) @@ -66,7 +66,7 @@ bool copyToPBoard(const unsigned short *str, unsigned int len) @autoreleasepool { NSPasteboard *pboard = [NSPasteboard generalPasteboard]; [pboard clearContents]; - + NSArray *contentsToPaste = [[[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil] autorelease]; return [pboard writeObjects:contentsToPaste]; } @@ -74,8 +74,8 @@ bool copyToPBoard(const unsigned short *str, unsigned int len) bool pasteBoardAvailable() { - NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; - return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; + NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; + return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; } unsigned short *copyFromPBoard() @@ -111,55 +111,55 @@ CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) hotSpot:NSMakePoint(hotspotX, hotspotY) ] retain]; } - - return (CursorRef)cursor; + + return (CursorRef)cursor; } void setArrowCursor() { - NSCursor *cursor = [NSCursor arrowCursor]; - [NSCursor unhide]; - [cursor set]; + NSCursor *cursor = [NSCursor arrowCursor]; + [NSCursor unhide]; + [cursor set]; } void setIBeamCursor() { - NSCursor *cursor = [NSCursor IBeamCursor]; - [cursor set]; + NSCursor *cursor = [NSCursor IBeamCursor]; + [cursor set]; } void setPointingHandCursor() { - NSCursor *cursor = [NSCursor pointingHandCursor]; - [cursor set]; + NSCursor *cursor = [NSCursor pointingHandCursor]; + [cursor set]; } void setCopyCursor() { - NSCursor *cursor = [NSCursor dragCopyCursor]; - [cursor set]; + NSCursor *cursor = [NSCursor dragCopyCursor]; + [cursor set]; } void setCrossCursor() { - NSCursor *cursor = [NSCursor crosshairCursor]; - [cursor set]; + NSCursor *cursor = [NSCursor crosshairCursor]; + [cursor set]; } void setNotAllowedCursor() { - NSCursor *cursor = [NSCursor operationNotAllowedCursor]; - [cursor set]; + NSCursor *cursor = [NSCursor operationNotAllowedCursor]; + [cursor set]; } void hideNSCursor() { - [NSCursor hide]; + [NSCursor hide]; } void showNSCursor() { - [NSCursor unhide]; + [NSCursor unhide]; } #if LL_DARWIN @@ -179,42 +179,42 @@ bool isCGCursorVisible() void hideNSCursorTillMove(bool hide) { - [NSCursor setHiddenUntilMouseMoves:hide]; + [NSCursor setHiddenUntilMouseMoves:hide]; } // This is currently unused, since we want all our cursors to persist for the life of the app, but I've included it for completeness. OSErr releaseImageCursor(CursorRef ref) { - if( ref != NULL ) - { + if( ref != NULL ) + { @autoreleasepool { NSCursor *cursor = (NSCursor*)ref; [cursor autorelease]; } - } - else - { - return paramErr; - } - - return noErr; + } + else + { + return paramErr; + } + + return noErr; } OSErr setImageCursor(CursorRef ref) { - if( ref != NULL ) - { + if( ref != NULL ) + { @autoreleasepool { NSCursor *cursor = (NSCursor*)ref; [cursor set]; } - } - else - { - return paramErr; - } - - return noErr; + } + else + { + return paramErr; + } + + return noErr; } // Now for some unholy juggling between generic pointers and casting them to Obj-C objects! @@ -222,46 +222,46 @@ OSErr setImageCursor(CursorRef ref) NSWindowRef createNSWindow(int x, int y, int width, int height) { - LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height) + LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable backing:NSBackingStoreBuffered defer:NO]; - [window makeKeyAndOrderFront:nil]; - [window setAcceptsMouseMovedEvents:TRUE]; + [window makeKeyAndOrderFront:nil]; + [window setAcceptsMouseMovedEvents:TRUE]; [window setRestorable:FALSE]; // Viewer manages state from own settings - return window; + return window; } GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync) { - LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:samples andVsync:vsync]; - [(LLNSWindow*)window setContentView:glview]; - return glview; + LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:samples andVsync:vsync]; + [(LLNSWindow*)window setContentView:glview]; + return glview; } void glSwapBuffers(void* context) { - [(NSOpenGLContext*)context flushBuffer]; + [(NSOpenGLContext*)context flushBuffer]; } CGLContextObj getCGLContextObj(GLViewRef view) { - return [(LLOpenGLView *)view getCGLContextObj]; + return [(LLOpenGLView *)view getCGLContextObj]; } CGLPixelFormatObj* getCGLPixelFormatObj(NSWindowRef window) { - LLOpenGLView *glview = [(LLNSWindow*)window contentView]; - return [glview getCGLPixelFormatObj]; + LLOpenGLView *glview = [(LLNSWindow*)window contentView]; + return [glview getCGLPixelFormatObj]; } unsigned long getVramSize(GLViewRef view) { - return [(LLOpenGLView *)view getVramSize]; + return [(LLOpenGLView *)view getVramSize]; } float getDeviceUnitSize(GLViewRef view) { - return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width; + return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width; } CGRect getContentViewRect(NSWindowRef window) @@ -276,48 +276,48 @@ CGRect getBackingViewRect(NSWindowRef window, GLViewRef view) void getWindowSize(NSWindowRef window, float* size) { - NSRect frame = [(LLNSWindow*)window frame]; - size[0] = frame.origin.x; - size[1] = frame.origin.y; - size[2] = frame.size.width; - size[3] = frame.size.height; + NSRect frame = [(LLNSWindow*)window frame]; + size[0] = frame.origin.x; + size[1] = frame.origin.y; + size[2] = frame.size.width; + size[3] = frame.size.height; } void setWindowSize(NSWindowRef window, int width, int height) { - NSRect frame = [(LLNSWindow*)window frame]; - frame.size.width = width; - frame.size.height = height; - [(LLNSWindow*)window setFrame:frame display:TRUE]; + NSRect frame = [(LLNSWindow*)window frame]; + frame.size.width = width; + frame.size.height = height; + [(LLNSWindow*)window setFrame:frame display:TRUE]; } void setWindowPos(NSWindowRef window, float* pos) { - NSPoint point; - point.x = pos[0]; - point.y = pos[1]; - [(LLNSWindow*)window setFrameOrigin:point]; + NSPoint point; + point.x = pos[0]; + point.y = pos[1]; + [(LLNSWindow*)window setFrameOrigin:point]; } void getCursorPos(NSWindowRef window, float* pos) { - NSPoint mLoc; - mLoc = [(LLNSWindow*)window mouseLocationOutsideOfEventStream]; - pos[0] = mLoc.x; - pos[1] = mLoc.y; + NSPoint mLoc; + mLoc = [(LLNSWindow*)window mouseLocationOutsideOfEventStream]; + pos[0] = mLoc.x; + pos[1] = mLoc.y; } void makeWindowOrderFront(NSWindowRef window) { - [(LLNSWindow*)window makeKeyAndOrderFront:nil]; + [(LLNSWindow*)window makeKeyAndOrderFront:nil]; } void convertScreenToWindow(NSWindowRef window, float *coord) { NSRect point = NSMakeRect(coord[0], coord[1], 0,0); - point = [(LLNSWindow*)window convertRectFromScreen:point]; - coord[0] = point.origin.x; - coord[1] = point.origin.y; + point = [(LLNSWindow*)window convertRectFromScreen:point]; + coord[0] = point.origin.x; + coord[1] = point.origin.y; } void convertRectToScreen(NSWindowRef window, float *coord) @@ -325,21 +325,21 @@ void convertRectToScreen(NSWindowRef window, float *coord) NSRect rect = NSMakeRect(coord[0], coord[1], coord[2], coord[3]);; rect = [(LLNSWindow*)window convertRectToScreen:rect]; - coord[0] = rect.origin.x; - coord[1] = rect.origin.y; - coord[2] = rect.size.width; - coord[3] = rect.size.height; + coord[0] = rect.origin.x; + coord[1] = rect.origin.y; + coord[2] = rect.size.width; + coord[3] = rect.size.height; } void convertRectFromScreen(NSWindowRef window, float *coord) { - NSRect point = NSMakeRect(coord[0], coord[1], coord[2], coord[3]); - point = [(LLNSWindow*)window convertRectFromScreen:point]; - - coord[0] = point.origin.x; - coord[1] = point.origin.y; - coord[2] = point.size.width; - coord[3] = point.size.height; + NSRect point = NSMakeRect(coord[0], coord[1], coord[2], coord[3]); + point = [(LLNSWindow*)window convertRectFromScreen:point]; + + coord[0] = point.origin.x; + coord[1] = point.origin.y; + coord[2] = point.size.width; + coord[3] = point.size.height; } void convertWindowToScreen(NSWindowRef window, float *coord) @@ -353,24 +353,24 @@ void convertWindowToScreen(NSWindowRef window, float *coord) void closeWindow(NSWindowRef window) { - [(LLNSWindow*)window close]; - [(LLNSWindow*)window release]; + [(LLNSWindow*)window close]; + [(LLNSWindow*)window release]; } void removeGLView(GLViewRef view) { - [(LLOpenGLView*)view clearGLContext]; - [(LLOpenGLView*)view removeFromSuperview]; + [(LLOpenGLView*)view clearGLContext]; + [(LLOpenGLView*)view removeFromSuperview]; } void setupInputWindow(NSWindowRef window, GLViewRef glview) { - [[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview]; + [[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview]; } void commitCurrentPreedit(GLViewRef glView) { - [(LLOpenGLView*)glView commitCurrentPreedit]; + [(LLOpenGLView*)glView commitCurrentPreedit]; } void allowDirectMarkedTextInput(bool allow, GLViewRef glView) @@ -380,20 +380,20 @@ void allowDirectMarkedTextInput(bool allow, GLViewRef glView) NSWindowRef getMainAppWindow() { - LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window]; - - [winRef setAcceptsMouseMovedEvents:TRUE]; - return winRef; + LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window]; + + [winRef setAcceptsMouseMovedEvents:TRUE]; + return winRef; } void makeFirstResponder(NSWindowRef window, GLViewRef view) { - [(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view]; + [(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view]; } void requestUserAttention() { - [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest]; + [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest]; } long showAlert(std::string text, std::string title, int type) @@ -401,7 +401,7 @@ long showAlert(std::string text, std::string title, int type) long ret = 0; @autoreleasepool { NSAlert *alert = [[[NSAlert alloc] init] autorelease]; - + [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]]; [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]]; if (type == 0) @@ -418,7 +418,7 @@ long showAlert(std::string text, std::string title, int type) } ret = [alert runModal]; } - + if (ret == NSAlertFirstButtonReturn) { if (type == 1) @@ -438,7 +438,7 @@ long showAlert(std::string text, std::string title, int type) ret = 1; } } - + return ret; } @@ -451,5 +451,5 @@ long showAlert(std::string text, std::string title, int type) unsigned int getModifiers() { - return [NSEvent modifierFlags]; + return [NSEvent modifierFlags]; } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d1ea2773fe..88e12e07cf 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -58,7 +58,7 @@ if (ENABLE_MEDIA_PLUGINS) include(CEFPlugin) endif () -if (NOT HAVOK_TPV) +if (HAVOK) # When using HAVOK_TPV, the library is precompiled, so no need for this # Stub and probably havok lib itself is a hack, autobuild loads a 3p that really is a source tarball @@ -84,7 +84,7 @@ if (NOT HAVOK_TPV) target_compile_options( llphysicsextensions PRIVATE -Wno-unused-local-typedef) endif (DARWIN) endif() -endif (NOT HAVOK_TPV) +endif () set(viewer_SOURCE_FILES gltfscenemanager.cpp @@ -2089,13 +2089,30 @@ elseif (DARWIN) PROPERTIES RESOURCE SecondLife.xib LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip" - # arch specific flags for universal builds: https://stackoverflow.com/a/77942065 - XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=x86_64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_FULL" - XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=arm64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_STUB" - # only generate the .MAP file for llphysicsextensions_tpv on x86_64 - XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=x86_64] "$(inherited) -L${CMAKE_CURRENT_BINARY_DIR}/llphysicsextensions/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensions -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP" - XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=arm64] "$(inherited) -L${CMAKE_CURRENT_BINARY_DIR}/llphysicsextensionsstub/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensionsstub" ) + if(HAVOK) + set_target_properties(${VIEWER_BINARY_NAME} + PROPERTIES + # arch specific flags for universal builds: https://stackoverflow.com/a/77942065 + XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=x86_64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_FULL -DLL_HAVOK=1" + XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=arm64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_STUB" + # only generate the .MAP file for llphysicsextensions_tpv on x86_64 + XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=x86_64] "$(inherited) -L${CMAKE_CURRENT_BINARY_DIR}/llphysicsextensions/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensions -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP" + XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=arm64] "$(inherited) -L${CMAKE_BINARY_DIR}/llphysicsextensionsos/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensionsos" + ) + elseif(HAVOK_TPV) + set_target_properties(${VIEWER_BINARY_NAME} + PROPERTIES + # arch specific flags for universal builds: https://stackoverflow.com/a/77942065 + XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=x86_64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_FULL -DLL_HAVOK=1" + XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=arm64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_STUB" + # only generate the .MAP file for llphysicsextensions_tpv on x86_64 + XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=x86_64] "$(inherited) -L${ARCH_PREBUILT_DIRS}/ -lllphysicsextensions_tpv" + XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=arm64] "$(inherited) -L${CMAKE_BINARY_DIR}/llphysicsextensionsos/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensionsos" + ) + else() + target_link_libraries(${VIEWER_BINARY_NAME} llphysicsextensionsos) + endif() else (WINDOWS) # Linux set_target_properties(${VIEWER_BINARY_NAME} diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index b8fd3dc189..af18dca185 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -57,42 +57,42 @@ - (void) applicationDidFinishLaunching:(NSNotification *)notification { - // Call constructViewer() first so our logging subsystem is in place. This - // risks missing crashes in the LLAppViewerMacOSX constructor, but for - // present purposes it's more important to get the startup sequence - // properly logged. - // Someday I would like to modify the logging system so that calls before - // it's initialized are cached in a std::ostringstream and then, once it's - // initialized, "played back" into whatever handlers have been set up. - constructViewer(); + // Call constructViewer() first so our logging subsystem is in place. This + // risks missing crashes in the LLAppViewerMacOSX constructor, but for + // present purposes it's more important to get the startup sequence + // properly logged. + // Someday I would like to modify the logging system so that calls before + // it's initialized are cached in a std::ostringstream and then, once it's + // initialized, "played back" into whatever handlers have been set up. + constructViewer(); #if defined(LL_BUGSPLAT) infos("bugsplat setup"); - // Engage BugsplatStartupManager *before* calling initViewer() to handle - // any crashes during initialization. - // https://www.bugsplat.com/docs/platforms/os-x#initialization - [BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES; - [BugsplatStartupManager sharedManager].askUserDetails = NO; - [BugsplatStartupManager sharedManager].delegate = self; - [[BugsplatStartupManager sharedManager] start]; + // Engage BugsplatStartupManager *before* calling initViewer() to handle + // any crashes during initialization. + // https://www.bugsplat.com/docs/platforms/os-x#initialization + [BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES; + [BugsplatStartupManager sharedManager].askUserDetails = NO; + [BugsplatStartupManager sharedManager].delegate = self; + [[BugsplatStartupManager sharedManager] start]; #endif infos("post-bugsplat setup"); - frameTimer = nil; + frameTimer = nil; - [self languageUpdated]; + [self languageUpdated]; - if (initViewer()) - { - // Set up recurring calls to oneFrame (repeating timer with timeout 0) - // until applicationShouldTerminate. - frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self - selector:@selector(oneFrame) userInfo:nil repeats:YES]; - } else { - exit(0); - } + if (initViewer()) + { + // Set up recurring calls to oneFrame (repeating timer with timeout 0) + // until applicationShouldTerminate. + frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self + selector:@selector(oneFrame) userInfo:nil repeats:YES]; + } else { + exit(0); + } - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil]; // [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; } @@ -110,74 +110,74 @@ - (void) applicationDidBecomeActive:(NSNotification *)notification { - callWindowFocus(); + callWindowFocus(); } - (void) applicationDidResignActive:(NSNotification *)notification { - callWindowUnfocus(); + callWindowUnfocus(); } - (void) applicationDidHide:(NSNotification *)notification { - callWindowHide(); + callWindowHide(); } - (void) applicationDidUnhide:(NSNotification *)notification { - callWindowUnhide(); + callWindowUnhide(); } - (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender { - // run one frame to assess state - if (!pumpMainLoop()) - { - // pumpMainLoop() returns true when done, false if it wants to be - // called again. Since it returned false, do not yet cancel - // frameTimer. - handleQuit(); - [[NSApplication sharedApplication] stopModal]; - return NSTerminateCancel; - } else { - // pumpMainLoop() returned true: it's done. Okay, done with frameTimer. - [frameTimer release]; - cleanupViewer(); - return NSTerminateNow; - } + // run one frame to assess state + if (!pumpMainLoop()) + { + // pumpMainLoop() returns true when done, false if it wants to be + // called again. Since it returned false, do not yet cancel + // frameTimer. + handleQuit(); + [[NSApplication sharedApplication] stopModal]; + return NSTerminateCancel; + } else { + // pumpMainLoop() returned true: it's done. Okay, done with frameTimer. + [frameTimer release]; + cleanupViewer(); + return NSTerminateNow; + } } - (void) oneFrame { - bool appExiting = pumpMainLoop(); - if (appExiting) - { - // Once pumpMainLoop() reports that we're done, cancel frameTimer: - // stop the repetitive calls. - [frameTimer release]; - [[NSApplication sharedApplication] terminate:self]; - } + bool appExiting = pumpMainLoop(); + if (appExiting) + { + // Once pumpMainLoop() reports that we're done, cancel frameTimer: + // stop the repetitive calls. + [frameTimer release]; + [[NSApplication sharedApplication] terminate:self]; + } } - (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent { - if (![self romanScript]) - { - if (show) - { - NSLog(@"Showing input window."); - [inputWindow makeKeyAndOrderFront:inputWindow]; + if (![self romanScript]) + { + if (show) + { + NSLog(@"Showing input window."); + [inputWindow makeKeyAndOrderFront:inputWindow]; if (textEvent != nil) { [[inputView inputContext] discardMarkedText]; [[inputView inputContext] handleEvent:textEvent]; } - } else { - NSLog(@"Hiding input window."); - [inputWindow orderOut:inputWindow]; - [window makeKeyAndOrderFront:window]; - } - } + } else { + NSLog(@"Hiding input window."); + [inputWindow orderOut:inputWindow]; + [window makeKeyAndOrderFront:window]; + } + } } // This will get called multiple times by NSNotificationCenter. @@ -187,15 +187,15 @@ - (void) languageUpdated { - TISInputSourceRef currentInput = TISCopyCurrentKeyboardInputSource(); - CFArrayRef languages = (CFArrayRef)TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages); - + TISInputSourceRef currentInput = TISCopyCurrentKeyboardInputSource(); + CFArrayRef languages = (CFArrayRef)TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages); + #if 0 // In the event of ever needing to add new language sources, change this to 1 and watch the terminal for "languages:" - NSLog(@"languages: %@", TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages)); + NSLog(@"languages: %@", TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages)); #endif - - // Typically the language we want is going to be the very first result in the array. - currentInputLanguage = (NSString*)CFArrayGetValueAtIndex(languages, 0); + + // Typically the language we want is going to be the very first result in the array. + currentInputLanguage = (NSString*)CFArrayGetValueAtIndex(languages, 0); } - (bool) romanScript @@ -209,7 +209,7 @@ return false; } } - + return true; } @@ -313,11 +313,11 @@ struct AttachmentInfo // We "happen to know" that info[0].basename is "SecondLife.old" -- due to // the fact that BugsplatMac only notices a crash during the viewer run - // following the crash. + // following the crash. // The Bugsplat service doesn't respect the MIME type above when returning // the log data to a browser, so take this opportunity to rename the file // from <base>.old to <base>_log.txt - info[0].basename = + info[0].basename = boost::filesystem::path(info[0].pathname).stem().string() + "_log.txt"; infos("attachmentsForBugsplatStartupManager attaching log " + info[0].basename); @@ -373,7 +373,7 @@ struct AttachmentInfo { [super sendEvent:event]; if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) - { + { [[self keyWindow] sendEvent:event]; } } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f7dc7f0895..c34441932d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2459,7 +2459,6 @@ void LLAppViewer::initLoggingAndGetLastDuration() if (gDirUtilp->fileExists(user_data_path_cef_log)) { std::string user_data_path_cef_old = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.old"); - LLFile::remove(user_data_path_cef_old, ENOENT); LLFile::rename(user_data_path_cef_log, user_data_path_cef_old); } } diff --git a/indra/newview/llappviewermacosx-objc.mm b/indra/newview/llappviewermacosx-objc.mm index 2ea3f2f171..96a6bc6edc 100644 --- a/indra/newview/llappviewermacosx-objc.mm +++ b/indra/newview/llappviewermacosx-objc.mm @@ -5,27 +5,27 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ - */ + */ #if !defined LL_DARWIN - #error "Use only with macOS" + #error "Use only with macOS" #endif #import <Cocoa/Cocoa.h> diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm index 978069457c..6cb7c4ad51 100644 --- a/indra/newview/llfilepicker_mac.mm +++ b/indra/newview/llfilepicker_mac.mm @@ -1,25 +1,25 @@ -/** +/** * @file llfilepicker_mac.cpp * @brief OS-specific file picker * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,15 +32,15 @@ NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned int flags) { int i; - + NSOpenPanel *panel = [NSOpenPanel openPanel]; NSMutableArray *fileTypes = nil; - - + + if ( allowed_types && !allowed_types->empty()) { fileTypes = [[NSMutableArray alloc] init]; - + for (i=0;i<allowed_types->size();++i) { [fileTypes addObject: @@ -48,7 +48,7 @@ NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned encoding:[NSString defaultCStringEncoding]]]; } } - + //[panel setMessage:@"Import one or more files or directories."]; [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ]; [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ]; @@ -56,7 +56,7 @@ NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned [panel setResolvesAliases: true]; [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )]; [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; - + if (fileTypes) { [panel setAllowedFileTypes:fileTypes]; @@ -77,7 +77,7 @@ std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::st std::unique_ptr<std::vector<std::string>> outfiles; @autoreleasepool - { + { int result; //Aura TODO: We could init a small window and release it at the end of this routine //for a modeless interface. @@ -85,17 +85,17 @@ std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::st NSOpenPanel *panel = init_panel(allowed_types,flags); result = [panel runModal]; - + if (result == NSModalResponseOK) { NSArray *filesToOpen = [panel URLs]; int i, count = [filesToOpen count]; - + if (count > 0) { outfiles.reset(new std::vector<std::string>); } - + for (i=0; i<count; i++) { NSString *aFile = [[filesToOpen objectAtIndex:i] path]; std::string afilestr = std::string([aFile UTF8String]); @@ -113,11 +113,11 @@ void doLoadDialogModeless(const std::vector<std::string>* allowed_types, { @autoreleasepool - { + { // Note: might need to return and save this panel // so that it does not close immediately NSOpenPanel *panel = init_panel(allowed_types,flags); - + [panel beginWithCompletionHandler:^(NSModalResponse result) { std::vector<std::string> outfiles; @@ -125,10 +125,10 @@ void doLoadDialogModeless(const std::vector<std::string>* allowed_types, { NSArray *filesToOpen = [panel URLs]; int i, count = [filesToOpen count]; - + if (count > 0) { - + for (i=0; i<count; i++) { NSString *aFile = [[filesToOpen objectAtIndex:i] path]; std::string *afilestr = new std::string([aFile UTF8String]); @@ -149,7 +149,7 @@ void doLoadDialogModeless(const std::vector<std::string>* allowed_types, } } -std::unique_ptr<std::string> doSaveDialog(const std::string* file, +std::unique_ptr<std::string> doSaveDialog(const std::string* file, const std::string* type, const std::string* creator, const std::string* extension, @@ -157,18 +157,18 @@ std::unique_ptr<std::string> doSaveDialog(const std::string* file, { std::unique_ptr<std::string> outfile; @autoreleasepool - { + { NSSavePanel *panel = [NSSavePanel savePanel]; - + NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; NSArray *fileType = [extensionns componentsSeparatedByString:@","]; - + //[panel setMessage:@"Save Image File"]; [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; [panel setCanSelectHiddenExtension:true]; [panel setAllowedFileTypes:fileType]; NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; - + NSURL* url = [NSURL fileURLWithPath:fileName]; [panel setNameFieldStringValue: fileName]; [panel setDirectoryURL: url]; @@ -193,39 +193,39 @@ void doSaveDialogModeless(const std::string* file, void *userdata) { @autoreleasepool { - NSSavePanel *panel = [NSSavePanel savePanel]; - - NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; - NSArray *fileType = [extensionns componentsSeparatedByString:@","]; - - //[panel setMessage:@"Save Image File"]; - [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; - [panel setCanSelectHiddenExtension:true]; - [panel setAllowedFileTypes:fileType]; - NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; - - NSURL* url = [NSURL fileURLWithPath:fileName]; - [panel setNameFieldStringValue: fileName]; - [panel setDirectoryURL: url]; - - - [panel beginWithCompletionHandler:^(NSModalResponse result) - { + NSSavePanel *panel = [NSSavePanel savePanel]; + + NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; + NSArray *fileType = [extensionns componentsSeparatedByString:@","]; + + //[panel setMessage:@"Save Image File"]; + [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; + [panel setCanSelectHiddenExtension:true]; + [panel setAllowedFileTypes:fileType]; + NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; + + NSURL* url = [NSURL fileURLWithPath:fileName]; + [panel setNameFieldStringValue: fileName]; + [panel setDirectoryURL: url]; + + + [panel beginWithCompletionHandler:^(NSModalResponse result) + { if (result == NSModalResponseOK) - { - NSURL* url = [panel URL]; - NSString* p = [url path]; - std::string outfile([p UTF8String]); - - callback(true, outfile, userdata); - } - else // cancel - { - std::string outfile; - callback(false, outfile, userdata); - } - }]; - } + { + NSURL* url = [panel URL]; + NSString* p = [url path]; + std::string outfile([p UTF8String]); + + callback(true, outfile, userdata); + } + else // cancel + { + std::string outfile; + callback(false, outfile, userdata); + } + }]; + } } #endif diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 3d88e117ac..143781a225 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -1706,6 +1706,11 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id) if (session_floater) { session_floater->restoreFloater(); + if (session_floater->isTornOff() && session_floater->isMinimized()) + { + session_floater->setMinimized(false); + session_floater->setFocus(true); + } } } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 14f0b52174..40de236c90 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1023,7 +1023,6 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() std::string old_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SLVoice.old"); if (gDirUtilp->fileExists(new_log)) { - LLFile::remove(old_log, ENOENT); LLFile::rename(new_log, old_log); } diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 8059914ed7..447f1b652a 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -396,7 +396,7 @@ void LLWebRTCVoiceClient::updateSettings() config.mNoiseSuppressionLevel = noiseSuppressionLevel; audioConfigChanged = true; } - if (audioConfigChanged) + if (audioConfigChanged && mWebRTCDeviceInterface) { mWebRTCDeviceInterface->setAudioConfig(config); } @@ -797,7 +797,10 @@ void LLWebRTCVoiceClient::tuningStart() { if (!mIsInTuningMode) { - mWebRTCDeviceInterface->setTuningMode(true); + if (mWebRTCDeviceInterface) + { + mWebRTCDeviceInterface->setTuningMode(true); + } mIsInTuningMode = true; } } @@ -806,7 +809,10 @@ void LLWebRTCVoiceClient::tuningStop() { if (mIsInTuningMode) { - mWebRTCDeviceInterface->setTuningMode(false); + if (mWebRTCDeviceInterface) + { + mWebRTCDeviceInterface->setTuningMode(false); + } mIsInTuningMode = false; } } @@ -839,6 +845,10 @@ void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume) float LLWebRTCVoiceClient::tuningGetEnergy(void) { + if (!mWebRTCDeviceInterface) + { + return 0.f; + } float rms = mWebRTCDeviceInterface->getTuningAudioLevel(); return TUNING_LEVEL_START_POINT - TUNING_LEVEL_SCALE * rms; } @@ -866,7 +876,10 @@ void LLWebRTCVoiceClient::refreshDeviceLists(bool clearCurrentList) clearCaptureDevices(); clearRenderDevices(); } - mWebRTCDeviceInterface->refreshDevices(); + if (mWebRTCDeviceInterface) + { + mWebRTCDeviceInterface->refreshDevices(); + } } @@ -1174,7 +1187,7 @@ void LLWebRTCVoiceClient::sendPositionUpdate(bool force) void LLWebRTCVoiceClient::updateOwnVolume() { F32 audio_level = 0.0f; - if (!mMuteMic) + if (!mMuteMic && mWebRTCDeviceInterface) { float rms = mWebRTCDeviceInterface->getPeerConnectionAudioLevel(); audio_level = LEVEL_START_POINT - LEVEL_SCALE * rms; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 63b35cf30c..4f828cc0ff 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5025,7 +5025,7 @@ void LLRiggedVolume::update( else { face_begin = face_index; - face_end = face_begin + 1; + face_end = llmin(face_begin + 1, volume->getNumVolumeFaces()); } for (S32 i = face_begin; i < face_end; ++i) { diff --git a/scripts/code_tools/fix_whitespace.py b/scripts/code_tools/fix_whitespace.py index 7a88265479..d5f7ce1cce 100644 --- a/scripts/code_tools/fix_whitespace.py +++ b/scripts/code_tools/fix_whitespace.py @@ -70,7 +70,7 @@ def process_directory(directory, extensions, tab_stop): def main(): parser = argparse.ArgumentParser(description='Convert tabs to spaces in files, considering tab stops.') - parser.add_argument('-e', '--extensions', type=str, default='c,cpp,h,hpp,inl,py,glsl,cmake', help='Comma-separated list of file extensions to process (default: "c,cpp,h,hpp,inl,py,glsl,cmake")') + parser.add_argument('-e', '--extensions', type=str, default='c,cpp,m,mm,h,hpp,inl,py,glsl,cmake', help='Comma-separated list of file extensions to process (default: "c,cpp,h,hpp,inl,py,glsl,cmake")') parser.add_argument('-t', '--tabstop', type=int, default=4, help='Tab stop size (default: 4)') parser.add_argument('-d', '--directory', type=str, required=True, help='Directory to process') |
