From 88fe6da622eccd2ad2874bb59610932a982f7c9e Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 18 Dec 2012 11:44:20 -0800 Subject: FIX (SPECULATIVE) MAINT-1340 - Media Volume control broken on Vista+ systems --- .../webkit/windows_volume_catcher.cpp | 52 +++++++++++++++++----- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/webkit/windows_volume_catcher.cpp index 5fb84756ee..b0c3134eb0 100644 --- a/indra/media_plugins/webkit/windows_volume_catcher.cpp +++ b/indra/media_plugins/webkit/windows_volume_catcher.cpp @@ -48,18 +48,37 @@ private: set_volume_func_t mSetVolumeFunc; set_mute_func_t mSetMuteFunc; + // tests if running on Vista, 7, 8 + once in CTOR + bool isWindowsVistaOrHigher(); + F32 mVolume; F32 mPan; + bool mSystemIsVistaOrHigher; }; + +bool VolumeCatcherImpl::isWindowsVistaOrHigher() +{ + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + return osvi.dwMajorVersion >= 6; +} + VolumeCatcherImpl::VolumeCatcherImpl() -: mVolume(1.0f), // default volume is max - mPan(0.f) // default pan is centered +: mVolume(1.0f), // default volume is max + mPan(0.f) // default pan is centered { - HMODULE handle = ::LoadLibrary(L"winmm.dll"); - if(handle) + mSystemIsVistaOrHigher = isWindowsVistaOrHigher(); + + if ( mSystemIsVistaOrHigher ) { - mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume"); - mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute"); + HMODULE handle = ::LoadLibrary(L"winmm.dll"); + if(handle) + { + mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume"); + mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute"); + } } } @@ -67,18 +86,29 @@ VolumeCatcherImpl::~VolumeCatcherImpl() { } - void VolumeCatcherImpl::setVolume(F32 volume) { mVolume = volume; - if (mSetMuteFunc) + if ( mSystemIsVistaOrHigher ) { - mSetMuteFunc(volume == 0.f); + // set both left/right to same volume + // TODO: use pan value to set independently + DWORD left_channel = (DWORD)(mVolume * 65535.0f); + DWORD right_channel = (DWORD)(mVolume * 65535.0f); + DWORD hw_volume = left_channel << 16 | right_channel; + ::waveOutSetVolume(NULL, hw_volume); } - if (mSetVolumeFunc) + else { - mSetVolumeFunc(mVolume); + if (mSetMuteFunc) + { + mSetMuteFunc(volume == 0.f); + } + if (mSetVolumeFunc) + { + mSetVolumeFunc(mVolume); + } } } -- cgit v1.2.3 From 6c3375356e7366f4384d9233a43d2c58a01e7241 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 21 Dec 2012 22:21:58 +0000 Subject: SH-3331 Fix incorrect overrun message when sending body with HTTP request. During readcallback, would generate an overrun-type message about reading position beyond end-of-data. Mistake was is messaging when state is exactly at end of data (which is expected) versus an overrun. Both result in declaring end-of-data to libcurl. Also changed some of the status logging for the metrics payload to be less chatty on success, more informative on error. --- indra/llcorehttp/_httpoprequest.cpp | 9 +++++++-- indra/newview/lltexturefetch.cpp | 9 +++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 7db19b1841..51a8eaf998 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -580,8 +580,13 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void const size_t body_size(op->mReqBody->size()); if (body_size <= op->mCurlBodyPos) { - LL_WARNS("HttpCore") << "Request body position beyond body size. Aborting request." - << LL_ENDL; + if (body_size < op->mCurlBodyPos) + { + // Warn but continue if the read position moves beyond end-of-body + // for some reason. + LL_WARNS("HttpCore") << "Request body position beyond body size. Truncating request body." + << LL_ENDL; + } return 0; } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index a2854dd6d8..8af403c1c6 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -3678,13 +3678,14 @@ public: if (status) { - LL_WARNS("Texture") << "Successfully delivered asset metrics to grid." - << LL_ENDL; + LL_DEBUGS("Texture") << "Successfully delivered asset metrics to grid." + << LL_ENDL; } else { - LL_WARNS("Texture") << "Error delivering asset metrics to grid. Reason: " - << status.toString() << LL_ENDL; + LL_WARNS("Texture") << "Error delivering asset metrics to grid. Status: " + << status.toHex() + << ", Reason: " << status.toString() << LL_ENDL; } } }; // end class AssetReportHandler -- cgit v1.2.3 From 11e506f2eb979a5ddfc3ca6f9c626771ab012a78 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 21 Dec 2012 22:24:34 +0000 Subject: SH-3357 Texture fetch debugger not running correctly under drano- http phase 1 Some missing counter initialization kept the debugger from entering the startup state giving the appearance of a do- nothing floater. Also found some unbound recursion that might need looking at in the future. (There's a comment.) --- indra/newview/llfloatertexturefetchdebugger.cpp | 2 +- indra/newview/lltexturefetch.cpp | 45 +++++++++++++------------ indra/newview/lltexturefetch.h | 2 -- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp index 9157389187..9a23d99802 100644 --- a/indra/newview/llfloatertexturefetchdebugger.cpp +++ b/indra/newview/llfloatertexturefetchdebugger.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * 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 diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 8af403c1c6..cd4fa78cab 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -3885,11 +3885,15 @@ private: LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) : + LLCore::HttpHandler(), mFetcher(fetcher), mTextureCache(cache), mImageDecodeThread(imagedecodethread), mHttpHeaders(NULL), - mHttpPolicyClass(fetcher->getPolicyClass()) + mHttpPolicyClass(fetcher->getPolicyClass()), + mNbCurlCompleted(0), + mTempIndex(0), + mHistoryListIndex(0) { init(); } @@ -3915,6 +3919,7 @@ void LLTextureFetchDebugger::init() mDecodingTime = -1.f; mHTTPTime = -1.f; mGLCreationTime = -1.f; + mTotalFetchingTime = 0.f; mRefetchVisCacheTime = -1.f; mRefetchVisHTTPTime = -1.f; @@ -3941,6 +3946,9 @@ void LLTextureFetchDebugger::init() mFreezeHistory = FALSE; mStopDebug = FALSE; mClearHistory = FALSE; + mRefetchNonVis = FALSE; + + mNbCurlRequests = 0; if (! mHttpHeaders) { @@ -4014,7 +4022,8 @@ bool LLTextureFetchDebugger::processStartDebug(F32 max_time) S32 pending = 0; pending += LLAppViewer::getTextureCache()->update(1); pending += LLAppViewer::getImageDecodeThread()->update(1); - pending += LLAppViewer::getTextureFetch()->update(1); + // pending += LLAppViewer::getTextureFetch()->update(1); // This causes infinite recursion in some cases + pending += mNbCurlRequests; if(!pending) { break; @@ -4304,7 +4313,6 @@ void LLTextureFetchDebugger::debugHTTP() { mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE; mFetchingHistory[i].mCurlReceivedSize = 0; - mFetchingHistory[i].mHTTPFailCount = 0; mFetchingHistory[i].mFormattedImage = NULL; } mNbCurlRequests = 0; @@ -4328,8 +4336,6 @@ S32 LLTextureFetchDebugger::fillCurlQueue() S32 size = mFetchingHistory.size(); for (S32 i = 0 ; i < size ; i++) { - mNbCurlRequests++; - if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE) { continue; @@ -4355,15 +4361,22 @@ S32 LLTextureFetchDebugger::fillCurlQueue() mFetchingHistory[i].mHttpHandle = handle; mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; mNbCurlRequests++; - // Hack - if (mNbCurlRequests == HTTP_REQUESTS_IN_QUEUE_HIGH_WATER) // emulate normal pipeline + if (mNbCurlRequests >= HTTP_REQUESTS_IN_QUEUE_HIGH_WATER) // emulate normal pipeline { break; } } else { - break; + // Failed to queue request, log it and mark it done. + LLCore::HttpStatus status(mFetcher->getHttpRequest().getStatus()); + + LL_WARNS("Texture") << "Couldn't issue HTTP request in debugger for texture " + << mFetchingHistory[i].mID + << ", status: " << status.toHex() + << " reason: " << status.toString() + << LL_ENDL; + mFetchingHistory[i].mCurlState = FetchEntry::CURL_DONE; } } //llinfos << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << llendl; @@ -4717,14 +4730,13 @@ void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpRespon LLCore::HttpStatus status(response->getStatus()); mNbCurlRequests--; + mNbCurlCompleted++; + fetch.mCurlState = FetchEntry::CURL_DONE; if (status) { const bool partial(par_status == status); LLCore::BufferArray * ba(response->getBody()); // *Not* holding reference to body - fetch.mCurlState = FetchEntry::CURL_DONE; - mNbCurlCompleted++; - S32 data_size = ba ? ba->size() : 0; fetch.mCurlReceivedSize += data_size; //llinfos << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << llendl; @@ -4756,17 +4768,6 @@ void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpRespon llinfos << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID << ", status: " << status.toHex() << " reason: " << status.toString() << llendl; - fetch.mHTTPFailCount++; - if(fetch.mHTTPFailCount < 5) - { - // Fetch will have to be redone - fetch.mCurlState = FetchEntry::CURL_NOT_DONE; - } - else //skip - { - fetch.mCurlState = FetchEntry::CURL_DONE; - mNbCurlCompleted++; - } } } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 3a99432b48..2377a54f92 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -449,7 +449,6 @@ private: LLPointer mRawImage; e_curl_state mCurlState; S32 mCurlReceivedSize; - S32 mHTTPFailCount; LLCore::HttpHandle mHttpHandle; FetchEntry() : @@ -465,7 +464,6 @@ private: mFetchedSize(f_size), mDecodedSize(d_size), mNeedsAux(false), - mHTTPFailCount(0), mHttpHandle(LLCORE_HTTP_HANDLE_INVALID) {} }; -- cgit v1.2.3 From 34f231cc66bc746228fe367712447058d76757b3 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 9 Jan 2013 20:39:06 -0500 Subject: MAINT-1481: remove linux-updater; move logic to Linux update_install Now that the viewer's own background updater logic is responsible for downloading a new installer, the only functionality we still use in linux-updater that couldn't be expressed more simply in bash is the UI. But since most Linux distros capable of running SL at all have zenity, and all will have xmessage, we can handle even the UI part. Add xmenity wrapper script so update_install doesn't have to care which is present, and make the bash script that used to launch linux-updater do the real work. --- indra/CMakeLists.txt | 3 +- indra/linux_updater/CMakeLists.txt | 51 -- indra/linux_updater/linux_updater.cpp | 926 --------------------- indra/newview/CMakeLists.txt | 1 - indra/newview/viewer_manifest.py | 17 +- .../updater/scripts/linux/update_install | 151 +++- .../updater/scripts/linux/xmenity | 55 ++ 7 files changed, 210 insertions(+), 994 deletions(-) delete mode 100644 indra/linux_updater/CMakeLists.txt delete mode 100644 indra/linux_updater/linux_updater.cpp create mode 100755 indra/viewer_components/updater/scripts/linux/xmenity diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 24c98bfada..001bb4b935 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -82,8 +82,7 @@ if (VIEWER) if (LINUX) add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) - add_subdirectory(${VIEWER_PREFIX}linux_updater) - add_dependencies(viewer linux-crash-logger-strip-target linux-updater) + add_dependencies(viewer linux-crash-logger-strip-target) elseif (DARWIN) add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) add_subdirectory(${VIEWER_PREFIX}mac_updater) diff --git a/indra/linux_updater/CMakeLists.txt b/indra/linux_updater/CMakeLists.txt deleted file mode 100644 index 4377a6333c..0000000000 --- a/indra/linux_updater/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -# -*- cmake -*- - -project(linux_updater) - -include(00-Common) -include(CURL) -include(CARes) -include(OpenSSL) -include(UI) -include(LLCommon) -include(LLVFS) -include(LLXML) -include(LLUI) -include(Linking) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LLUI_INCLUDE_DIRS} - ${CURL_INCLUDE_DIRS} - ${CARES_INCLUDE_DIRS} - ${OPENSSL_INCLUDE_DIRS} - ${UI_INCLUDE_DIRS} - ) - -set(linux_updater_SOURCE_FILES linux_updater.cpp) - -set(linux_updater_HEADER_FILES CMakeLists.txt) - -set_source_files_properties(${linux_updater_HEADER_FILES} - PROPERTIES HEADER_FILES_ONLY TRUE) - -list(APPEND linux_updater_SOURCE_FILES ${linux_updater_HEADER_FILES}) - -add_executable(linux-updater ${linux_updater_SOURCE_FILES}) - -target_link_libraries(linux-updater - ${CURL_LIBRARIES} - ${CARES_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${UI_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLUI_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ) - -add_custom_target(linux-updater-target ALL - DEPENDS linux-updater) diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp deleted file mode 100644 index 991dfd9dce..0000000000 --- a/indra/linux_updater/linux_updater.cpp +++ /dev/null @@ -1,926 +0,0 @@ -/** - * @file linux_updater.cpp - * @author Kyle Ambroff , Tofu Linden - * @brief Viewer update program for unix platforms that support GTK+ - * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include -#include -#include - -#include "linden_common.h" -#include "llerrorcontrol.h" -#include "llfile.h" -#include "lldir.h" -#include "lldiriterator.h" - -/*==========================================================================*| -// IQA-490: Use of LLTrans -- by this program at least -- appears to be buggy. -// With it, the 3.3.2 beta 1 linux-updater.bin crashes; without it seems stable. -#include "llxmlnode.h" -#include "lltrans.h" -|*==========================================================================*/ - -static class LLTrans -{ -public: - LLTrans(); - static std::string getString(const std::string& key); - -private: - std::string _getString(const std::string& key) const; - - typedef std::map MessageMap; - MessageMap mMessages; -} sLLTransInstance; - -#include -#include -#include - -extern "C" { -#include -} - -const guint UPDATE_PROGRESS_TIMEOUT = 100; -const guint UPDATE_PROGRESS_TEXT_TIMEOUT = 1000; -const guint ROTATE_IMAGE_TIMEOUT = 8000; - -typedef struct _updater_app_state { - std::string app_name; - std::string url; - std::string file; - std::string image_dir; - std::string dest_dir; - std::string strings_dirs; - std::string strings_file; - - LLDirIterator *image_dir_iter; - - GtkWidget *window; - GtkWidget *progress_bar; - GtkWidget *image; - - double progress_value; - bool activity_mode; - - guint image_rotation_timeout_id; - guint progress_update_timeout_id; - guint update_progress_text_timeout_id; - - bool failure; -} UpdaterAppState; - -// List of entries from strings.xml to always replace -static std::set default_trans_args; -void init_default_trans_args() -{ - default_trans_args.insert("SECOND_LIFE"); // World - default_trans_args.insert("APP_NAME"); - default_trans_args.insert("SECOND_LIFE_GRID"); - default_trans_args.insert("SUPPORT_SITE"); -} - -bool translate_init(std::string comma_delim_path_list, - std::string base_xml_name) -{ - return true; -/*==========================================================================*| - init_default_trans_args(); - - // extract paths string vector from comma-delimited flat string - std::vector paths; - LLStringUtil::getTokens(comma_delim_path_list, paths, ","); // split over ',' - - for(std::vector::iterator it = paths.begin(), end_it = paths.end(); - it != end_it; - ++it) - { - (*it) = gDirUtilp->findSkinnedFilename(*it, base_xml_name); - } - - // suck the translation xml files into memory - LLXMLNodePtr root; - bool success = LLXMLNode::getLayeredXMLNode(root, paths); - if (!success) - { - // couldn't load string table XML - return false; - } - else - { - // get those strings out of the XML - LLTrans::parseStrings(root, default_trans_args); - return true; - } -|*==========================================================================*/ -} - - -void updater_app_ui_init(void); -void updater_app_quit(UpdaterAppState *app_state); -void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state); -std::string next_image_filename(std::string& image_path, LLDirIterator& iter); -void display_error(GtkWidget *parent, std::string title, std::string message); -BOOL install_package(std::string package_file, std::string destination); -BOOL spawn_viewer(UpdaterAppState *app_state); - -extern "C" { - void on_window_closed(GtkWidget *sender, GdkEvent *event, gpointer state); - gpointer worker_thread_cb(gpointer *data); - int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow); - gboolean rotate_image_cb(gpointer data); - gboolean progress_update_timeout(gpointer data); - gboolean update_progress_text_timeout(gpointer data); -} - -void updater_app_ui_init(UpdaterAppState *app_state) -{ - GtkWidget *vbox; - GtkWidget *summary_label; - GtkWidget *description_label; - GtkWidget *frame; - - llassert(app_state != NULL); - - // set up window and main container - std::string window_title = LLTrans::getString("UpdaterWindowTitle"); - app_state->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(app_state->window), - window_title.c_str()); - gtk_window_set_resizable(GTK_WINDOW(app_state->window), FALSE); - gtk_window_set_position(GTK_WINDOW(app_state->window), - GTK_WIN_POS_CENTER_ALWAYS); - - gtk_container_set_border_width(GTK_CONTAINER(app_state->window), 12); - g_signal_connect(G_OBJECT(app_state->window), "delete-event", - G_CALLBACK(on_window_closed), app_state); - - vbox = gtk_vbox_new(FALSE, 6); - gtk_container_add(GTK_CONTAINER(app_state->window), vbox); - - // set top label - std::ostringstream label_ostr; - label_ostr << "" - << LLTrans::getString("UpdaterNowUpdating") - << ""; - - summary_label = gtk_label_new(NULL); - gtk_label_set_use_markup(GTK_LABEL(summary_label), TRUE); - gtk_label_set_markup(GTK_LABEL(summary_label), - label_ostr.str().c_str()); - gtk_misc_set_alignment(GTK_MISC(summary_label), 0, 0.5); - gtk_box_pack_start(GTK_BOX(vbox), summary_label, FALSE, FALSE, 0); - - // create the description label - description_label = gtk_label_new(LLTrans::getString("UpdaterUpdatingDescriptive").c_str()); - gtk_label_set_line_wrap(GTK_LABEL(description_label), TRUE); - gtk_misc_set_alignment(GTK_MISC(description_label), 0, 0.5); - gtk_box_pack_start(GTK_BOX(vbox), description_label, FALSE, FALSE, 0); - - // If an image path has been set, load the background images - if (!app_state->image_dir.empty()) { - frame = gtk_frame_new(NULL); - gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); - gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); - - // load the first image - app_state->image = gtk_image_new_from_file - (next_image_filename(app_state->image_dir, *app_state->image_dir_iter).c_str()); - gtk_widget_set_size_request(app_state->image, 340, 310); - gtk_container_add(GTK_CONTAINER(frame), app_state->image); - - // rotate the images every 5 seconds - app_state->image_rotation_timeout_id = g_timeout_add - (ROTATE_IMAGE_TIMEOUT, rotate_image_cb, app_state); - } - - // set up progress bar, and update it roughly every 1/10 of a second - app_state->progress_bar = gtk_progress_bar_new(); - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar), - LLTrans::getString("UpdaterProgressBarTextWithEllipses").c_str()); - gtk_box_pack_start(GTK_BOX(vbox), - app_state->progress_bar, FALSE, TRUE, 0); - app_state->progress_update_timeout_id = g_timeout_add - (UPDATE_PROGRESS_TIMEOUT, progress_update_timeout, app_state); - app_state->update_progress_text_timeout_id = g_timeout_add - (UPDATE_PROGRESS_TEXT_TIMEOUT, update_progress_text_timeout, app_state); - - gtk_widget_show_all(app_state->window); -} - -gboolean rotate_image_cb(gpointer data) -{ - UpdaterAppState *app_state; - std::string filename; - - llassert(data != NULL); - app_state = (UpdaterAppState *) data; - - filename = next_image_filename(app_state->image_dir, *app_state->image_dir_iter); - - gdk_threads_enter(); - gtk_image_set_from_file(GTK_IMAGE(app_state->image), filename.c_str()); - gdk_threads_leave(); - - return TRUE; -} - -std::string next_image_filename(std::string& image_path, LLDirIterator& iter) -{ - std::string image_filename; - iter.next(image_filename); - return gDirUtilp->add(image_path, image_filename); -} - -void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data) -{ - UpdaterAppState *app_state; - - llassert(data != NULL); - app_state = (UpdaterAppState *) data; - - updater_app_quit(app_state); -} - -void updater_app_quit(UpdaterAppState *app_state) -{ - if (app_state != NULL) - { - g_source_remove(app_state->progress_update_timeout_id); - - if (!app_state->image_dir.empty()) - { - g_source_remove(app_state->image_rotation_timeout_id); - } - } - - gtk_main_quit(); -} - -void display_error(GtkWidget *parent, std::string title, std::string message) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new(GTK_WINDOW(parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "%s", message.c_str()); - gtk_window_set_title(GTK_WINDOW(dialog), title.c_str()); - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); -} - -gpointer worker_thread_cb(gpointer data) -{ - UpdaterAppState *app_state; - CURL *curl; - CURLcode result; - FILE *package_file; - GError *error = NULL; - int fd; - - //g_return_val_if_fail (data != NULL, NULL); - app_state = (UpdaterAppState *) data; - - try { - - if(!app_state->url.empty()) - { - char* tmp_local_filename = NULL; - // create temporary file to store the package. - fd = g_file_open_tmp - ("secondlife-update-XXXXXX", &tmp_local_filename, &error); - if (error != NULL) - { - llerrs << "Unable to create temporary file: " - << error->message - << llendl; - - g_error_free(error); - throw 0; - } - - if(tmp_local_filename != NULL) - { - app_state->file = tmp_local_filename; - g_free(tmp_local_filename); - } - - package_file = fdopen(fd, "wb"); - if (package_file == NULL) - { - llerrs << "Failed to create temporary file: " - << app_state->file.c_str() - << llendl; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailDownloadTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - throw 0; - } - - // initialize curl and start downloading the package - llinfos << "Downloading package: " << app_state->url << llendl; - - curl = curl_easy_init(); - if (curl == NULL) - { - llerrs << "Failed to initialize libcurl" << llendl; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailDownloadTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - throw 0; - } - - curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str()); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, - &download_progress_cb); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state); - - result = curl_easy_perform(curl); - fclose(package_file); - curl_easy_cleanup(curl); - - if (result) - { - llerrs << "Failed to download update: " - << app_state->url - << llendl; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailDownloadTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - - throw 0; - } - } - - // now pulse the progres bar back and forth while the package is - // being unpacked - gdk_threads_enter(); - std::string installing_msg = LLTrans::getString("UpdaterNowInstalling"); - gtk_progress_bar_set_text( - GTK_PROGRESS_BAR(app_state->progress_bar), - installing_msg.c_str()); - app_state->activity_mode = TRUE; - gdk_threads_leave(); - - // *TODO: if the destination is not writable, terminate this - // thread and show file chooser? - if (!install_package(app_state->file.c_str(), app_state->dest_dir)) - { - llwarns << "Failed to install package to destination: " - << app_state->dest_dir - << llendl; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailInstallTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - //"Failed to update " + app_state->app_name, - gdk_threads_leave(); - throw 0; - } - - // try to spawn the new viewer - if (!spawn_viewer(app_state)) - { - llwarns << "Viewer was not installed properly in : " - << app_state->dest_dir - << llendl; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailStartTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - throw 0; - } - } - catch (...) - { - app_state->failure = TRUE; - } - - gdk_threads_enter(); - updater_app_quit(app_state); - gdk_threads_leave(); - - return NULL; -} - - -gboolean less_anal_gspawnsync(gchar **argv, - gchar **stderr_output, - gint *child_exit_status, - GError **spawn_error) -{ - // store current SIGCHLD handler if there is one, replace with default - // handler to make glib happy - struct sigaction sigchld_backup; - struct sigaction sigchld_appease_glib; - sigchld_appease_glib.sa_handler = SIG_DFL; - sigemptyset(&sigchld_appease_glib.sa_mask); - sigchld_appease_glib.sa_flags = 0; - sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup); - - gboolean rtn = g_spawn_sync(NULL, - argv, - NULL, - (GSpawnFlags) (G_SPAWN_STDOUT_TO_DEV_NULL), - NULL, - NULL, - NULL, - stderr_output, - child_exit_status, - spawn_error); - - // restore SIGCHLD handler - sigaction(SIGCHLD, &sigchld_backup, NULL); - - return rtn; -} - - -// perform a rename, or perform a (prompted) root rename if that fails -int -rename_with_sudo_fallback(const std::string& filename, const std::string& newname) -{ - int rtncode = ::rename(filename.c_str(), newname.c_str()); - lldebugs << "rename result is: " << rtncode << " / " << errno << llendl; - if (rtncode && (EACCES == errno || EPERM == errno || EXDEV == errno)) - { - llinfos << "Permission problem in rename, or moving between different mount points. Retrying as a mv under a sudo." << llendl; - // failed due to permissions, try again as a gksudo or kdesu mv wrapper hack - char *sudo_cmd = NULL; - sudo_cmd = g_find_program_in_path("gksudo"); - if (!sudo_cmd) - { - sudo_cmd = g_find_program_in_path("kdesu"); - } - if (sudo_cmd) - { - char *mv_cmd = NULL; - mv_cmd = g_find_program_in_path("mv"); - if (mv_cmd) - { - char *src_string_copy = g_strdup(filename.c_str()); - char *dst_string_copy = g_strdup(newname.c_str()); - char* argv[] = - { - sudo_cmd, - mv_cmd, - src_string_copy, - dst_string_copy, - NULL - }; - - gchar *stderr_output = NULL; - gint child_exit_status = 0; - GError *spawn_error = NULL; - if (!less_anal_gspawnsync(argv, &stderr_output, - &child_exit_status, &spawn_error)) - { - llwarns << "Failed to spawn child process: " - << spawn_error->message - << llendl; - } - else if (child_exit_status) - { - llwarns << "mv command failed: " - << (stderr_output ? stderr_output : "(no reason given)") - << llendl; - } - else - { - // everything looks good, clear the error code - rtncode = 0; - } - - g_free(src_string_copy); - g_free(dst_string_copy); - if (spawn_error) g_error_free(spawn_error); - } - } - } - return rtncode; -} - -gboolean install_package(std::string package_file, std::string destination) -{ - char *tar_cmd = NULL; - std::ostringstream command; - - // Find the absolute path to the 'tar' command. - tar_cmd = g_find_program_in_path("tar"); - if (!tar_cmd) - { - llerrs << "`tar' was not found in $PATH" << llendl; - return FALSE; - } - llinfos << "Found tar command: " << tar_cmd << llendl; - - // Unpack the tarball in a temporary place first, then move it to - // its final destination - std::string tmp_dest_dir = gDirUtilp->getTempFilename(); - if (LLFile::mkdir(tmp_dest_dir, 0744)) - { - llerrs << "Failed to create directory: " - << destination - << llendl; - - return FALSE; - } - - char *package_file_string_copy = g_strdup(package_file.c_str()); - char *tmp_dest_dir_string_copy = g_strdup(tmp_dest_dir.c_str()); - gchar *argv[8] = { - tar_cmd, - const_cast("--strip"), const_cast("1"), - const_cast("-xjf"), - package_file_string_copy, - const_cast("-C"), tmp_dest_dir_string_copy, - NULL, - }; - - llinfos << "Untarring package: " << package_file << llendl; - - // store current SIGCHLD handler if there is one, replace with default - // handler to make glib happy - struct sigaction sigchld_backup; - struct sigaction sigchld_appease_glib; - sigchld_appease_glib.sa_handler = SIG_DFL; - sigemptyset(&sigchld_appease_glib.sa_mask); - sigchld_appease_glib.sa_flags = 0; - sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup); - - gchar *stderr_output = NULL; - gint child_exit_status = 0; - GError *untar_error = NULL; - if (!less_anal_gspawnsync(argv, &stderr_output, - &child_exit_status, &untar_error)) - { - llwarns << "Failed to spawn child process: " - << untar_error->message - << llendl; - return FALSE; - } - - if (child_exit_status) - { - llwarns << "Untar command failed: " - << (stderr_output ? stderr_output : "(no reason given)") - << llendl; - return FALSE; - } - - g_free(tar_cmd); - g_free(package_file_string_copy); - g_free(tmp_dest_dir_string_copy); - g_free(stderr_output); - if (untar_error) g_error_free(untar_error); - - // move the existing package out of the way if it exists - if (gDirUtilp->fileExists(destination)) - { - std::string backup_dir = destination + ".backup"; - int oldcounter = 1; - while (gDirUtilp->fileExists(backup_dir)) - { - // find a foo.backup.N folder name that isn't taken yet - backup_dir = destination + ".backup." + llformat("%d", oldcounter); - ++oldcounter; - } - - if (rename_with_sudo_fallback(destination, backup_dir)) - { - llwarns << "Failed to move directory: '" - << destination << "' -> '" << backup_dir - << llendl; - return FALSE; - } - } - - // The package has been unpacked in a staging directory, now we just - // need to move it to its destination. - if (rename_with_sudo_fallback(tmp_dest_dir, destination)) - { - llwarns << "Failed to move installation to the destination: " - << destination - << llendl; - return FALSE; - } - - // \0/ Success! - return TRUE; -} - -gboolean progress_update_timeout(gpointer data) -{ - UpdaterAppState *app_state; - - llassert(data != NULL); - - app_state = (UpdaterAppState *) data; - - gdk_threads_enter(); - if (app_state->activity_mode) - { - gtk_progress_bar_pulse - (GTK_PROGRESS_BAR(app_state->progress_bar)); - } - else - { - gtk_progress_set_value(GTK_PROGRESS(app_state->progress_bar), - app_state->progress_value); - } - gdk_threads_leave(); - - return TRUE; -} - -gboolean update_progress_text_timeout(gpointer data) -{ - UpdaterAppState *app_state; - - llassert(data != NULL); - app_state = (UpdaterAppState *) data; - - if (app_state->activity_mode == TRUE) - { - // We no longer need this timeout, it will be removed. - return FALSE; - } - - if (!app_state->progress_value) - { - return TRUE; - } - - std::string progress_text = llformat((LLTrans::getString("UpdaterProgressBarText")+" (%.0f%%)").c_str(), app_state->progress_value); - - gdk_threads_enter(); - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar), - progress_text.c_str()); - gdk_threads_leave(); - - return TRUE; -} - -int download_progress_cb(gpointer data, - double t, - double d, - double utotal, - double ulnow) -{ - UpdaterAppState *app_state; - - llassert(data != NULL); - app_state = (UpdaterAppState *) data; - - if (t <= 0.0) - { - app_state->progress_value = 0; - } - else - { - app_state->progress_value = d * 100.0 / t; - } - return 0; -} - -BOOL spawn_viewer(UpdaterAppState *app_state) -{ - llassert(app_state != NULL); - - std::string cmd = app_state->dest_dir + "/secondlife"; - GError *error = NULL; - - // We want to spawn the Viewer on the same display as the updater app - gboolean success = gdk_spawn_command_line_on_screen - (gtk_widget_get_screen(app_state->window), cmd.c_str(), &error); - - if (!success) - { - llwarns << "Failed to launch viewer: " << error->message - << llendl; - } - - if (error) g_error_free(error); - - return success; -} - -void show_usage_and_exit() -{ - std::cout << "Usage: linux-updater <--url URL | --file FILE> --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE" - << "[--image-dir PATH]" - << std::endl; - exit(1); -} - -void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state) -{ - int i; - - for (i = 1; i < argc; i++) - { - if ((!strcmp(argv[i], "--url")) && (++i < argc)) - { - app_state->url = argv[i]; - } - else if ((!strcmp(argv[i], "--file")) && (++i < argc)) - { - app_state->file = argv[i]; - } - else if ((!strcmp(argv[i], "--name")) && (++i < argc)) - { - app_state->app_name = argv[i]; - } - else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc)) - { - app_state->image_dir = argv[i]; - app_state->image_dir_iter = new LLDirIterator(argv[i], "*.jpg"); - } - else if ((!strcmp(argv[i], "--dest")) && (++i < argc)) - { - app_state->dest_dir = argv[i]; - } - else if ((!strcmp(argv[i], "--stringsdir")) && (++i < argc)) - { - app_state->strings_dirs = argv[i]; - } - else if ((!strcmp(argv[i], "--stringsfile")) && (++i < argc)) - { - app_state->strings_file = argv[i]; - } - else - { - // show usage, an invalid option was given. - show_usage_and_exit(); - } - } - - if (app_state->app_name.empty() - || (app_state->url.empty() && app_state->file.empty()) - || app_state->dest_dir.empty()) - { - show_usage_and_exit(); - } - - app_state->progress_value = 0.0; - app_state->activity_mode = FALSE; - app_state->failure = FALSE; - - translate_init(app_state->strings_dirs, app_state->strings_file); -} - -int main(int argc, char **argv) -{ - UpdaterAppState* app_state = new UpdaterAppState; - GThread *worker_thread; - - parse_args_and_init(argc, argv, app_state); - - // Initialize logger, and rename old log file - gDirUtilp->initAppDirs("SecondLife"); - LLError::initForApplication - (gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); - std::string old_log_file = gDirUtilp->getExpandedFilename - (LL_PATH_LOGS, "updater.log.old"); - std::string log_file = - gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log"); - LLFile::rename(log_file, old_log_file); - LLError::logToFile(log_file); - - // initialize gthreads and gtk+ - if (!g_thread_supported()) - { - g_thread_init(NULL); - gdk_threads_init(); - } - - gtk_init(&argc, &argv); - - // create UI - updater_app_ui_init(app_state); - - //llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl; - - // create download thread - worker_thread = g_thread_create - (GThreadFunc(worker_thread_cb), app_state, FALSE, NULL); - - gdk_threads_enter(); - gtk_main(); - gdk_threads_leave(); - - // Delete the file only if created from url download. - if(!app_state->url.empty() && !app_state->file.empty()) - { - if (gDirUtilp->fileExists(app_state->file)) - { - LLFile::remove(app_state->file); - } - } - - bool success = !app_state->failure; - delete app_state->image_dir_iter; - delete app_state; - return success ? 0 : 1; -} - -/***************************************************************************** -* Dummy LLTrans implementation (IQA-490) -*****************************************************************************/ -static LLTrans sStaticStrings; - -// lookup -std::string LLTrans::_getString(const std::string& key) const -{ - MessageMap::const_iterator found = mMessages.find(key); - if (found != mMessages.end()) - { - return found->second; - } - LL_WARNS("linux_updater") << "No message for key '" << key - << "' -- add to LLTrans::LLTrans() in linux_updater.cpp" - << LL_ENDL; - return key; -} - -// static lookup -std::string LLTrans::getString(const std::string& key) -{ - return sLLTransInstance._getString(key); -} - -// initialization -LLTrans::LLTrans() -{ - typedef std::pair Pair; - static const Pair data[] = - { - Pair("UpdaterFailDownloadTitle", - "Failed to download update"), - Pair("UpdaterFailInstallTitle", - "Failed to install update"), - Pair("UpdaterFailStartTitle", - "Failed to start viewer"), - Pair("UpdaterFailUpdateDescriptive", - "An error occurred while updating Second Life. " - "Please download the latest version from www.secondlife.com."), - Pair("UpdaterNowInstalling", - "Installing Second Life..."), - Pair("UpdaterNowUpdating", - "Now updating Second Life..."), - Pair("UpdaterProgressBarText", - "Downloading update"), - Pair("UpdaterProgressBarTextWithEllipses", - "Downloading update..."), - Pair("UpdaterUpdatingDescriptive", - "Your Second Life Viewer is being updated to the latest release. " - "This may take some time, so please be patient."), - Pair("UpdaterWindowTitle", - "Second Life Update") - }; - - BOOST_FOREACH(Pair pair, data) - { - mMessages[pair.first] = pair.second; - } -} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 0197ac794f..22960a2d0d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1865,7 +1865,6 @@ if (LINUX) set(COPY_INPUT_DEPENDENCIES ${VIEWER_BINARY_NAME} linux-crash-logger - linux-updater SLPlugin media_plugin_webkit media_plugin_gstreamer010 diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index ea75d4f4f6..bc623aee00 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -968,9 +968,9 @@ class LinuxManifest(ViewerManifest): if self.prefix(src="", dst="bin"): self.path("secondlife-bin","do-not-directly-run-secondlife-bin") self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") - self.path("../linux_updater/linux-updater", "linux-updater.bin") self.path2basename("../llplugin/slplugin", "SLPlugin") self.path2basename("../viewer_components/updater/scripts/linux", "update_install") + self.path2basename("../viewer_components/updater/scripts/linux", "xmenity") self.end_prefix("bin") if self.prefix("res-sdl"): @@ -1001,7 +1001,7 @@ class LinuxManifest(ViewerManifest): def copy_finish(self): # Force executable permissions to be set for scripts # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802 - for script in 'secondlife', 'bin/update_install': + for script in 'secondlife', 'bin/update_install', 'bin/xmenity': self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script)) def package_finish(self): @@ -1017,9 +1017,7 @@ class LinuxManifest(ViewerManifest): else: installer_name += '_' + self.channel_oneword().upper() - if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): - print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" - self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + self.strip_binaries() # Fix access permissions self.run_command(""" @@ -1054,6 +1052,11 @@ class LinuxManifest(ViewerManifest): 'dst': self.get_dst_prefix(), 'inst': self.build_path_of(installer_name)}) + def strip_binaries(self): + if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): + print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" + self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! \( -name update_install -o -name xmenity \) | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + class Linux_i686Manifest(LinuxManifest): def construct(self): super(Linux_i686Manifest, self).construct() @@ -1139,9 +1142,7 @@ class Linux_i686Manifest(LinuxManifest): self.path("libvivoxplatform.so") self.end_prefix("lib") - if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): - print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" - self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + self.strip_binaries() class Linux_x86_64Manifest(LinuxManifest): diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index e0505a9f72..7c08966830 100644 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -1,10 +1,149 @@ #! /bin/bash -INSTALL_DIR=$(cd "$(dirname "$0")/.." ; pwd) -export LD_LIBRARY_PATH="$INSTALL_DIR/lib" -bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life Viewer" --stringsdir "$INSTALL_DIR/skins/default/xui/en" --stringsfile "strings.xml" -if [ $? -ne 0 ] - then echo $3 >> "$2" +# @file update_install +# @author Nat Goodspeed +# @date 2013-01-09 +# @brief Update the containing Second Life application bundle to the version in +# the specified tarball. +# +# This bash implementation is derived from the previous linux-updater.bin +# application. +# +# $LicenseInfo:firstyear=2013&license=viewerlgpl$ +# Copyright (c) 2013, Linden Research, Inc. +# $/LicenseInfo$ + +tarball="$1" # the file to install +markerfile="$2" # create this file on failure +mandatory="$3" # what to write to markerfile on failure + +function log { + # our log file will be open as stderr -- but until we set up that + # redirection, logging to stderr is better than nothing + echo "$*" 1>&2 +} + +function status { + log "$@" + # Prefix with '#' so xmenity will recognize it as a status message + echo "#$*" +} + +function fail { + # Log the message + log "$@" + # tell subsequent viewer things went south + echo "$mandatory" > "$markerfile" + # add boilerplate + local msg="An error occurred while updating Second Life: +$* +Please download the latest viewer from www.secondlife.com." + # Restate test from xmenity to detect whether we can use zenity or must + # fall back to xmessage + zenpath="$(which zenity)" + if [ -n "$zenpath" -a -x "$zenpath" ] + then "$zenpath" --error --title "Second Life Viewer Updater" \ + --width=320 --height=120 --text="$msg" + else xmessage -buttons -OK:2 -center "$msg" + fi + exit 1 +} + +function sudo_mv { + # If we have write permission to both parent directories, shouldn't need + # sudo. + if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ] + then mv "$1" "$2" || fail "Couldn't move $1 to $2" + else # use one of the likely sudo programs + sudo="$(which gksudo)" + if [ -z "$sudo" ] + then sudo="$(which kdesu)" + fi + if [ -z "$sudo" ] + then # couldn't find either one, just try it anyway + mv "$1" "$2" || fail "Couldn't move $1 to $2" + else # even with sudo, could fail, e.g. different filesystems + "$sudo" mv "$1" "$2" || fail "Couldn't move $1 to $2" + fi + fi +} + +# empty array +cleanups=() + +function cleanup { + # wacky bash syntax for appending to array + cleanups[${#cleanups[*]}]="$*" +} + +function onexit { + for action in "${cleanups[@]}" + do # don't quote, support actions consisting of multiple words + $action + done +} + +trap 'onexit' EXIT + +mydir="$(dirname "$0")" +# We happen to know that the viewer specifies a marker-file pathname within +# the logs directory. +logsdir="$(dirname "$markerfile")" +logname="$logsdir/updater.log" + +# move aside old updater.log; we're about to create a new one +[ -f "$logname" ] && mv "$logname" "$logname.old" + +# Set up redirections for this script such that stderr is logged, while +# special stdout messages drive our UI, as described in xmenity. +exec 2> "$logname" | "$mydir/xmenity" +# Piping to xmenity requires that we end with a line consisting of the string +# "100" to terminate zenity progress bar. +cleanup echo 100 + +# Rather than setting up a special pipeline to timestamp every line of stderr, +# produce header lines into log file indicating timestamp and the arguments +# with which we were invoked. +date 1>&2 +log "$0 $*" + +# Log every command we execute, along with any stderr it might produce +set -x + +status 'Installing Second Life...' + +# Creating tempdir under /tmp means it's possible that tempdir is on a +# different filesystem than INSTALL_DIR. One is tempted to create tempdir on a +# path derived from `dirname INSTALL_DIR`, but then we might need to add +# another sudo prompt to create it. +tempdir="/tmp/$(basename "$0").$$" +tempinstall="$tempdir/install" +mkdir -p "$tempinstall" || fail "Couldn't create $tempinstall" +cleanup rm -rf "$tempdir" + +# If we already knew the name of the tarball's top-level directory, we could +# just move that when all was said and done. Since we don't, untarring to the +# 'install' subdir with --strip 1 effectively renames that top-level +# directory. +tar --strip 1 -xjf "$tarball" -C "$tempinstall" || fail "Untar command failed" + +INSTALL_DIR="$(cd "$mydir/.." ; pwd)" + +# Considering we're launched from a subdirectory of INSTALL_DIR, would be +# surprising if it did NOT already exist... +if [ -f "$INSTALL_DIR" ] +then backup="$INSTALL_DIR.backup" + backupn=1 + while [ -f "$backup" ] + do backup="$INSTALL_DIR.backup.$backupn" + ((backupn += 1)) + done + sudo_mv "$INSTALL_DIR" "$backup" fi +# We unpacked the tarball into tempinstall. Move that. +sudo_mv "$tempinstall" "$INSTALL_DIR" + +rm -f "$tarball" -rm -f "$1" +# launch the updated viewer +"$INSTALL_DIR/secondlife" & diff --git a/indra/viewer_components/updater/scripts/linux/xmenity b/indra/viewer_components/updater/scripts/linux/xmenity new file mode 100755 index 0000000000..c0c033904c --- /dev/null +++ b/indra/viewer_components/updater/scripts/linux/xmenity @@ -0,0 +1,55 @@ +#!/bin/bash + +# @file xmenity +# @author Nat Goodspeed +# @date 2013-01-09 +# @brief Provide progress UI for bash scripts (e.g. update_install) using +# zenity if available, xmessage if not. +# +# $LicenseInfo:firstyear=2013&license=viewerlgpl$ +# Copyright (c) 2013, Linden Research, Inc. +# $/LicenseInfo$ + +# This script invokes either zenity --progress or, if zenity is unavailable, +# wraps xmessage in a zenity-like interface. That is its mutant power. +# Pass $1 as the title for your zenity box. It is ignored by xmessage. +# Send updates on stdin: +# A line containing only a decimal integer from 0 - 100 sets that progress. +# End with 100 to tell zenity to terminate. +# A line starting with '#' replaces the progress text. +# All other stdin lines are ignored. + +zenpath="$(which zenity)" +if [ -n "$zenpath" -a -x "$zenpath" ] +then # if executable zenity is on PATH, run that instead of this. + exec "$zenpath" --progress --title="$1" --auto-close --width=320 --height=120 +fi + +# Arriving here means we don't have zenity available. The remainder of this +# script is the xmessage wrapper. + +# We operate by leaving one background xmessage process running. This is the +# pid of that process. +xmpid="" + +function clear_message { + [ -n "$xmpid" ] && kill $xmpid + xmpid="" +} + +# Cancel any pending xmessage, regardless of how we exit. +trap 'clear_message' EXIT + +while read line +do # terminate like zenity --progress + [ "$line" == "100" ] && break + # ignore everything but replacement text + nohash="${line#'#'}" + # if stripping leading hash doesn't change line, it doesn't have one + [ "$nohash" == "$line" ] && continue + # clear any previous message + clear_message + # put up a new xmessage and capture its pid + xmessage -buttons OK:2 -center "$nohash" & + xmpid=$! +done -- cgit v1.2.3 From 6e9782f79f6d3cac2bfeb72c6cd43b409020c76e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 10 Jan 2013 09:40:20 -0500 Subject: MAINT-1481: minor bug fix plus incomplete UI tweaks. Test for existence of target name using -e rather than -f. (-d would work too, but in this case we must respond to any name collision, whether file or directory.) Instead of terminating on failure, make sudo_mv return rc of the [sudo] mv command to its caller. If the attempt to move new install to actual viewer directory fails, restore previous viewer before failing. When redirecting the script's stderr to updater.log, first save existing stderr to another file descriptor, and restore it when we launch viewer. Otherwise updater.log ends up collecting the viewer's duplicate stderr log output! The construct 'exec ... | program' doesn't work. In fact it causes any other redirections on that command to fail too. Remove it -- real fix pending. --- .../updater/scripts/linux/update_install | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index 7c08966830..167e2b7881 100644 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -53,7 +53,7 @@ function sudo_mv { # If we have write permission to both parent directories, shouldn't need # sudo. if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ] - then mv "$1" "$2" || fail "Couldn't move $1 to $2" + then mv "$1" "$2" else # use one of the likely sudo programs sudo="$(which gksudo)" if [ -z "$sudo" ] @@ -61,9 +61,9 @@ function sudo_mv { fi if [ -z "$sudo" ] then # couldn't find either one, just try it anyway - mv "$1" "$2" || fail "Couldn't move $1 to $2" + mv "$1" "$2" else # even with sudo, could fail, e.g. different filesystems - "$sudo" mv "$1" "$2" || fail "Couldn't move $1 to $2" + "$sudo" mv "$1" "$2" fi fi } @@ -94,9 +94,9 @@ logname="$logsdir/updater.log" # move aside old updater.log; we're about to create a new one [ -f "$logname" ] && mv "$logname" "$logname.old" -# Set up redirections for this script such that stderr is logged, while -# special stdout messages drive our UI, as described in xmenity. -exec 2> "$logname" | "$mydir/xmenity" +# Set up redirections for this script such that stderr is logged. (But first +# move the previous stderr to file descriptor 3.) +exec 3>&2- 2> "$logname" # Piping to xmenity requires that we end with a line consisting of the string # "100" to terminate zenity progress bar. cleanup echo 100 @@ -131,19 +131,25 @@ INSTALL_DIR="$(cd "$mydir/.." ; pwd)" # Considering we're launched from a subdirectory of INSTALL_DIR, would be # surprising if it did NOT already exist... -if [ -f "$INSTALL_DIR" ] +if [ -e "$INSTALL_DIR" ] then backup="$INSTALL_DIR.backup" backupn=1 - while [ -f "$backup" ] + while [ -e "$backup" ] do backup="$INSTALL_DIR.backup.$backupn" ((backupn += 1)) done - sudo_mv "$INSTALL_DIR" "$backup" + sudo_mv "$INSTALL_DIR" "$backup" || fail "Couldn't move $INSTALL_DIR to $backup" fi # We unpacked the tarball into tempinstall. Move that. -sudo_mv "$tempinstall" "$INSTALL_DIR" +if ! sudo_mv "$tempinstall" "$INSTALL_DIR" +then # If we failed to move the temp install to INSTALL_DIR, try to restore + # INSTALL_DIR from backup + sudo_mv "$backup" "$INSTALL_DIR" + fail "Couldn't move $1 to $2" +fi rm -f "$tarball" -# launch the updated viewer -"$INSTALL_DIR/secondlife" & +# Launch the updated viewer. Restore original stderr from file descriptor 3, +# though -- otherwise updater.log gets cluttered with the viewer log! +"$INSTALL_DIR/secondlife" 2>&3- & -- cgit v1.2.3 From 83f625445b87b8c5cb53c1a152f03402c0606dee Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 11 Jan 2013 12:24:44 -0500 Subject: MAINT-1481: Remove xmenity script and viewer_manifest.py references. --- indra/newview/viewer_manifest.py | 5 +- .../updater/scripts/linux/xmenity | 55 ---------------------- 2 files changed, 2 insertions(+), 58 deletions(-) delete mode 100755 indra/viewer_components/updater/scripts/linux/xmenity diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index bc623aee00..e7108141ee 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -970,7 +970,6 @@ class LinuxManifest(ViewerManifest): self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") self.path2basename("../llplugin/slplugin", "SLPlugin") self.path2basename("../viewer_components/updater/scripts/linux", "update_install") - self.path2basename("../viewer_components/updater/scripts/linux", "xmenity") self.end_prefix("bin") if self.prefix("res-sdl"): @@ -1001,7 +1000,7 @@ class LinuxManifest(ViewerManifest): def copy_finish(self): # Force executable permissions to be set for scripts # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802 - for script in 'secondlife', 'bin/update_install', 'bin/xmenity': + for script in 'secondlife', 'bin/update_install': self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script)) def package_finish(self): @@ -1055,7 +1054,7 @@ class LinuxManifest(ViewerManifest): def strip_binaries(self): if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" - self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! \( -name update_install -o -name xmenity \) | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure class Linux_i686Manifest(LinuxManifest): def construct(self): diff --git a/indra/viewer_components/updater/scripts/linux/xmenity b/indra/viewer_components/updater/scripts/linux/xmenity deleted file mode 100755 index c0c033904c..0000000000 --- a/indra/viewer_components/updater/scripts/linux/xmenity +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -# @file xmenity -# @author Nat Goodspeed -# @date 2013-01-09 -# @brief Provide progress UI for bash scripts (e.g. update_install) using -# zenity if available, xmessage if not. -# -# $LicenseInfo:firstyear=2013&license=viewerlgpl$ -# Copyright (c) 2013, Linden Research, Inc. -# $/LicenseInfo$ - -# This script invokes either zenity --progress or, if zenity is unavailable, -# wraps xmessage in a zenity-like interface. That is its mutant power. -# Pass $1 as the title for your zenity box. It is ignored by xmessage. -# Send updates on stdin: -# A line containing only a decimal integer from 0 - 100 sets that progress. -# End with 100 to tell zenity to terminate. -# A line starting with '#' replaces the progress text. -# All other stdin lines are ignored. - -zenpath="$(which zenity)" -if [ -n "$zenpath" -a -x "$zenpath" ] -then # if executable zenity is on PATH, run that instead of this. - exec "$zenpath" --progress --title="$1" --auto-close --width=320 --height=120 -fi - -# Arriving here means we don't have zenity available. The remainder of this -# script is the xmessage wrapper. - -# We operate by leaving one background xmessage process running. This is the -# pid of that process. -xmpid="" - -function clear_message { - [ -n "$xmpid" ] && kill $xmpid - xmpid="" -} - -# Cancel any pending xmessage, regardless of how we exit. -trap 'clear_message' EXIT - -while read line -do # terminate like zenity --progress - [ "$line" == "100" ] && break - # ignore everything but replacement text - nohash="${line#'#'}" - # if stripping leading hash doesn't change line, it doesn't have one - [ "$nohash" == "$line" ] && continue - # clear any previous message - clear_message - # put up a new xmessage and capture its pid - xmessage -buttons OK:2 -center "$nohash" & - xmpid=$! -done -- cgit v1.2.3 From 9e755ee98d6851154874a735c559c80509d7501d Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 11 Jan 2013 12:36:03 -0500 Subject: MAINT-1481: Clean up update_install UI, including error output. Capture actual error output from mkdir and mv; display it to user. Introduce mysudo function used by sudo_mv function for graphical sudo command. Since update_install actually only displays a single status message, just use zenity --info instead of a zenity progress box: need not update its message. Borrow semantics for clear_message and status functions from xmenity script. Introduce errorbox function so we only have to make zenity/xmessage test once. Move cleanup, onexit to top so we can use for clear_message. --- .../updater/scripts/linux/update_install | 164 ++++++++++++++------- 1 file changed, 113 insertions(+), 51 deletions(-) diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index 167e2b7881..0f624c4dee 100644 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -13,78 +13,136 @@ # Copyright (c) 2013, Linden Research, Inc. # $/LicenseInfo$ +# **************************************************************************** +# script parameters +# **************************************************************************** tarball="$1" # the file to install markerfile="$2" # create this file on failure mandatory="$3" # what to write to markerfile on failure +# **************************************************************************** +# helper functions +# **************************************************************************** +# empty array +cleanups=() + +# add a cleanup action to execute on exit +function cleanup { + # wacky bash syntax for appending to array + cleanups[${#cleanups[*]}]="$*" +} + +# called implicitly on exit +function onexit { + for action in "${cleanups[@]}" + do # don't quote, support actions consisting of multiple words + $action + done +} +trap 'onexit' EXIT + +# write to log file function log { # our log file will be open as stderr -- but until we set up that # redirection, logging to stderr is better than nothing echo "$*" 1>&2 } -function status { - log "$@" - # Prefix with '#' so xmenity will recognize it as a status message - echo "#$*" +# We display status by leaving one background xmessage process running. This +# is the pid of that process. +statuspid="" + +function clear_message { + [ -n "$statuspid" ] && kill $statuspid + statuspid="" } +# make sure we remove any message box we might have put up +cleanup clear_message + +# can we use zenity, or must we fall back to xmessage? +zenpath="$(which zenity)" +if [ -n "$zenpath" ] +then # zenity on PATH and is executable + # display a message box and continue + function status { + # clear any previous message + clear_message + # put up a new zenity box and capture its pid + "$zenpath" --info --title "Second Life Viewer Updater" \ + --width=320 --height=120 --text="$*" & + statuspid=$! + } + + # display an error box and wait for user + function errorbox { + "$zenpath" --error --title "Second Life Viewer Updater" \ + --width=320 --height=120 --text="$*" + } + +else # no zenity, use xmessage instead + # display a message box and continue + function status { + # clear any previous message + clear_message + # put up a new xmessage and capture its pid + xmessage -buttons OK:2 -center "$*" & + statuspid=$! + } + + # display an error box and wait for user + function errorbox { + xmessage -buttons OK:2 -center "$*" + } +fi + +# display an error box and terminate function fail { # Log the message log "$@" # tell subsequent viewer things went south echo "$mandatory" > "$markerfile" # add boilerplate - local msg="An error occurred while updating Second Life: + errorbox "An error occurred while updating Second Life: $* Please download the latest viewer from www.secondlife.com." - # Restate test from xmenity to detect whether we can use zenity or must - # fall back to xmessage - zenpath="$(which zenity)" - if [ -n "$zenpath" -a -x "$zenpath" ] - then "$zenpath" --error --title "Second Life Viewer Updater" \ - --width=320 --height=120 --text="$msg" - else xmessage -buttons -OK:2 -center "$msg" - fi exit 1 } +# Find a graphical sudo program and define mysudo function. On error, $? is +# nonzero; output is in $err instead of being written to stdout/stderr. +gksudo="$(which gksudo)" +kdesu="$(which kdesu)" +if [ -n "$gksudo" ] +then function mysudo { + # gksudo allows you to specify description + err="$("$gksudo" --description "Second Life Viewer Updater" "$@" 2>&1)" + } +elif [ -n "$kdesu" ] +then function mysudo { + err="$("$kdesu" "$@" 2>&1)" + } +else # couldn't find either one, just try it anyway + function mysudo { + err="$("$@" 2>&1)" + } +fi + +# Move directories, using mysudo if we think it necessary. On error, $? is +# nonzero; output is in $err instead of being written to stdout/stderr. function sudo_mv { # If we have write permission to both parent directories, shouldn't need # sudo. if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ] - then mv "$1" "$2" - else # use one of the likely sudo programs - sudo="$(which gksudo)" - if [ -z "$sudo" ] - then sudo="$(which kdesu)" - fi - if [ -z "$sudo" ] - then # couldn't find either one, just try it anyway - mv "$1" "$2" - else # even with sudo, could fail, e.g. different filesystems - "$sudo" mv "$1" "$2" - fi + then err="$(mv "$@" 2>&1)" + else # use available sudo program; mysudo sets $? and $err + mysudo mv "$@" fi } -# empty array -cleanups=() - -function cleanup { - # wacky bash syntax for appending to array - cleanups[${#cleanups[*]}]="$*" -} - -function onexit { - for action in "${cleanups[@]}" - do # don't quote, support actions consisting of multiple words - $action - done -} - -trap 'onexit' EXIT - +# **************************************************************************** +# main script logic +# **************************************************************************** mydir="$(dirname "$0")" # We happen to know that the viewer specifies a marker-file pathname within # the logs directory. @@ -97,9 +155,6 @@ logname="$logsdir/updater.log" # Set up redirections for this script such that stderr is logged. (But first # move the previous stderr to file descriptor 3.) exec 3>&2- 2> "$logname" -# Piping to xmenity requires that we end with a line consisting of the string -# "100" to terminate zenity progress bar. -cleanup echo 100 # Rather than setting up a special pipeline to timestamp every line of stderr, # produce header lines into log file indicating timestamp and the arguments @@ -114,17 +169,19 @@ status 'Installing Second Life...' # Creating tempdir under /tmp means it's possible that tempdir is on a # different filesystem than INSTALL_DIR. One is tempted to create tempdir on a -# path derived from `dirname INSTALL_DIR`, but then we might need to add -# another sudo prompt to create it. +# path derived from `dirname INSTALL_DIR` -- but it seems modern 'mv' can +# handle moving across filesystems?? tempdir="/tmp/$(basename "$0").$$" tempinstall="$tempdir/install" -mkdir -p "$tempinstall" || fail "Couldn't create $tempinstall" +# capture the actual error message, if any +err="$(mkdir -p "$tempinstall" 2>&1)" || fail "$err" cleanup rm -rf "$tempdir" # If we already knew the name of the tarball's top-level directory, we could # just move that when all was said and done. Since we don't, untarring to the # 'install' subdir with --strip 1 effectively renames that top-level # directory. +# untar failures tend to be voluminous -- don't even try to capture, just log tar --strip 1 -xjf "$tarball" -C "$tempinstall" || fail "Untar command failed" INSTALL_DIR="$(cd "$mydir/.." ; pwd)" @@ -138,16 +195,21 @@ then backup="$INSTALL_DIR.backup" do backup="$INSTALL_DIR.backup.$backupn" ((backupn += 1)) done - sudo_mv "$INSTALL_DIR" "$backup" || fail "Couldn't move $INSTALL_DIR to $backup" + # on error, fail with actual error message from sudo_mv: permissions, + # cross-filesystem mv, ...? + sudo_mv "$INSTALL_DIR" "$backup" || fail "$err" fi # We unpacked the tarball into tempinstall. Move that. if ! sudo_mv "$tempinstall" "$INSTALL_DIR" then # If we failed to move the temp install to INSTALL_DIR, try to restore - # INSTALL_DIR from backup + # INSTALL_DIR from backup. Save $err because next sudo_mv will trash it! + realerr="$err" sudo_mv "$backup" "$INSTALL_DIR" - fail "Couldn't move $1 to $2" + fail "$realerr" fi +# Removing the tarball here, rather than with a 'cleanup' action, means we +# only remove it if we succeeded. rm -f "$tarball" # Launch the updated viewer. Restore original stderr from file descriptor 3, -- cgit v1.2.3 From 22db60ed0dfd606ab8f8d49141446442a4a72a48 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 11 Jan 2013 15:58:50 -0500 Subject: MAINT-1481: use 'mktemp -d' to generate tempdir. Responding to Lex's code-review comments. --- indra/viewer_components/updater/scripts/linux/update_install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index 0f624c4dee..a9df9042fd 100644 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -171,7 +171,7 @@ status 'Installing Second Life...' # different filesystem than INSTALL_DIR. One is tempted to create tempdir on a # path derived from `dirname INSTALL_DIR` -- but it seems modern 'mv' can # handle moving across filesystems?? -tempdir="/tmp/$(basename "$0").$$" +tempdir="$(mktemp -d)" tempinstall="$tempdir/install" # capture the actual error message, if any err="$(mkdir -p "$tempinstall" 2>&1)" || fail "$err" -- cgit v1.2.3 From 627e531d333bcf9ed684883ad494a25b2c83af8e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 11 Jan 2013 17:17:13 -0600 Subject: MAINT-417 Backed out changeset: 7273a1ac51e8 --- indra/newview/llviewerkeyboard.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index f5d3341c66..1aa9fd8a45 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -160,11 +160,6 @@ void agent_push_backward( EKeystate s ) camera_move_backward(s); return; } - else if (gAgentAvatarp->isSitting()) - { - gAgentCamera.changeCameraToThirdPerson(); - return; - } agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); } -- cgit v1.2.3 From 90fb925d845a96f7dc5a8f9fa175ce9da3f75cce Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 11 Jan 2013 15:23:18 -0800 Subject: fix line endings --- indra/media_plugins/webkit/windows_volume_catcher.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/webkit/windows_volume_catcher.cpp index b0c3134eb0..957704da47 100644 --- a/indra/media_plugins/webkit/windows_volume_catcher.cpp +++ b/indra/media_plugins/webkit/windows_volume_catcher.cpp @@ -56,14 +56,14 @@ private: bool mSystemIsVistaOrHigher; }; -bool VolumeCatcherImpl::isWindowsVistaOrHigher() -{ - OSVERSIONINFO osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osvi); - return osvi.dwMajorVersion >= 6; -} +bool VolumeCatcherImpl::isWindowsVistaOrHigher() +{ + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + return osvi.dwMajorVersion >= 6; +} VolumeCatcherImpl::VolumeCatcherImpl() : mVolume(1.0f), // default volume is max -- cgit v1.2.3 From a9a4483df2c608cde1eafe8440c2aa48ce1aa336 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 11 Jan 2013 18:39:25 -0500 Subject: tag merge of DRTVWR-281 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 51a13fbc09..a567853c7c 100755 --- a/.hgtags +++ b/.hgtags @@ -395,3 +395,4 @@ a36f1f354b02aa6e448ca13685de167d0a0a3d03 DRTVWR-272 37dba00ad820de3a808d4039396b162a9c275b3e DRTVWR-269 c374035d459af3c03dea2dd90880dfc25de64706 DRTVWR-275 05d9f1dd7a954069af2a33abedb7713fa36a04cb 3.4.4-beta4 +5df4802bec93c8d0a509946d826bb4c50c5442ec DRTVWR-281 -- cgit v1.2.3 From 33d77848902972cd2814c86dda40d81068bdd8e3 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 14 Jan 2013 09:50:09 -0500 Subject: tag merge of DRTVWR-283 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 49d77e7e45..2e062c0b25 100644 --- a/.hgtags +++ b/.hgtags @@ -402,3 +402,4 @@ af6b711a97073431953b55ee808aaa09900c27e5 DRTVWR-276 8302fefde6c8f4a64bfc7f04929f8bc85f5c6c7b DRTVWR-279 c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280 40a2265058abc9fde4914c10185f916435818621 3.4.5-beta1 +7c1c33ba4cfd2d15ca51cc1ac440eca551331a4a DRTVWR-283 -- cgit v1.2.3 From c842494b774eedc6066f317853a82586ab85524e Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 14 Jan 2013 10:43:57 -0500 Subject: Added tag 3.4.5-beta2 for changeset 6b9c7dbebef7 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index aea2e8a416..e5cb4405e0 100644 --- a/.hgtags +++ b/.hgtags @@ -404,3 +404,4 @@ c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280 40a2265058abc9fde4914c10185f916435818621 3.4.5-beta1 5df4802bec93c8d0a509946d826bb4c50c5442ec DRTVWR-281 7c1c33ba4cfd2d15ca51cc1ac440eca551331a4a DRTVWR-283 +6b9c7dbebef793230d64e1b452577c8b142d4143 3.4.5-beta2 -- cgit v1.2.3 From fc06874061ad2b838c736874fd6cf5cdd25c789e Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 15 Jan 2013 08:49:03 -0500 Subject: tag merge of DRTVWR-282 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 9a0da76384..cb9232784c 100644 --- a/.hgtags +++ b/.hgtags @@ -398,3 +398,4 @@ c374035d459af3c03dea2dd90880dfc25de64706 DRTVWR-275 7c6dfdc1b7a2ce0d8e3a8f3ce3058547ea065c0f DRTVWR-250 b9ff9730daa53a541925300cbd02bb14575a5705 DRTVWR-277 af6b711a97073431953b55ee808aaa09900c27e5 DRTVWR-276 +37947e4f771f001b551581bf7cd0051c3153beed DRTVWR-282 -- cgit v1.2.3 From a3aa1205b2e865f8482b7d02862412604552cf32 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 15 Jan 2013 17:52:17 -0500 Subject: tag merge of DRTVWR-284 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 49d77e7e45..3426285847 100644 --- a/.hgtags +++ b/.hgtags @@ -402,3 +402,4 @@ af6b711a97073431953b55ee808aaa09900c27e5 DRTVWR-276 8302fefde6c8f4a64bfc7f04929f8bc85f5c6c7b DRTVWR-279 c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280 40a2265058abc9fde4914c10185f916435818621 3.4.5-beta1 +6482cceb91cda68b799f3e6cdc66d33bf123547a DRTVWR-284 -- cgit v1.2.3 From 622d4f39a50f07fe59bef2e7cdbacb3f8e837ee7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 16 Jan 2013 15:20:32 -0600 Subject: MAINT-2242 Fix for shader compilation errors on Intel HD graphics chips. --- .../shaders/class1/objects/previewV.glsl | 39 ++++++++++++++++++++-- indra/newview/llviewershadermgr.cpp | 7 ++-- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl index da3387e7a5..7f3f84398b 100644 --- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl @@ -23,9 +23,6 @@ * $/LicenseInfo$ */ -float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); - uniform mat3 normal_matrix; uniform mat4 texture_matrix0; uniform mat4 modelview_matrix; @@ -45,6 +42,42 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; +//=================================================================================================== +//declare these here explicitly to separate them from atmospheric lighting elsewhere to work around +//drivers that are picky about functions being declared but not defined even if they aren't called +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float da = clamp(1.0/(la * d), 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} +//==================================================================================================== + + void main() { //transform vertex diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 142cb2090d..ba9818946c 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -2025,11 +2025,11 @@ BOOL LLViewerShaderMgr::loadShadersObject() if (success) { gObjectPreviewProgram.mName = "Simple Shader"; - gObjectPreviewProgram.mFeatures.calculatesLighting = true; + gObjectPreviewProgram.mFeatures.calculatesLighting = false; gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false; - gObjectPreviewProgram.mFeatures.hasGamma = true; + gObjectPreviewProgram.mFeatures.hasGamma = false; gObjectPreviewProgram.mFeatures.hasAtmospherics = false; - gObjectPreviewProgram.mFeatures.hasLighting = true; + gObjectPreviewProgram.mFeatures.hasLighting = false; gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0; gObjectPreviewProgram.mFeatures.disableTextureIndex = true; gObjectPreviewProgram.mShaderFiles.clear(); @@ -2037,6 +2037,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB)); gObjectPreviewProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; success = gObjectPreviewProgram.createShader(NULL, NULL); + gObjectPreviewProgram.mFeatures.hasLighting = true; } if (success) -- cgit v1.2.3 From 7ecfa28c431a3599a99e92775d963241e1b943c0 Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Wed, 16 Jan 2013 15:21:11 -0800 Subject: MAINT-2247 Child object does not update rotation while selected. --- indra/newview/lldrawable.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index b7270e696e..647c3355ca 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -550,6 +550,8 @@ F32 LLDrawable::updateXform(BOOL undamped) else { dist_squared = dist_vec_squared(old_pos, target_pos); + dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; + dist_squared += dist_vec_squared(old_scale, target_scale); } LLVector3 vec = mCurrentScale-target_scale; -- cgit v1.2.3 From 23336feed2b68f3b11266eaae545ce78875bb2ee Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 18 Jan 2013 12:51:16 -0500 Subject: tag merge of DRTVWR-286 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index e5cb4405e0..0053ac25d5 100644 --- a/.hgtags +++ b/.hgtags @@ -405,3 +405,4 @@ c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280 5df4802bec93c8d0a509946d826bb4c50c5442ec DRTVWR-281 7c1c33ba4cfd2d15ca51cc1ac440eca551331a4a DRTVWR-283 6b9c7dbebef793230d64e1b452577c8b142d4143 3.4.5-beta2 +ccf991e02dc2f63fb646324230d54832683f4a9b DRTVWR-286 -- cgit v1.2.3 From 2c58a49f23d4fbc633ee0a223b823a306c91ea35 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 22 Jan 2013 16:42:51 -0500 Subject: tag merge of DRTVWR-287 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index e5cb4405e0..74404c98fe 100644 --- a/.hgtags +++ b/.hgtags @@ -405,3 +405,4 @@ c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280 5df4802bec93c8d0a509946d826bb4c50c5442ec DRTVWR-281 7c1c33ba4cfd2d15ca51cc1ac440eca551331a4a DRTVWR-283 6b9c7dbebef793230d64e1b452577c8b142d4143 3.4.5-beta2 +2d849850558a5a0324b398d1c102d30bcbdfb88f DRTVWR-287 -- cgit v1.2.3 From cebde0a32b4a8163010d9cbf5e6b3036865ed943 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 23 Jan 2013 11:43:16 -0500 Subject: Added tag 3.4.5-beta3 for changeset e06898df8644 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 61af8c05e8..83c86a413d 100644 --- a/.hgtags +++ b/.hgtags @@ -407,3 +407,4 @@ c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280 6b9c7dbebef793230d64e1b452577c8b142d4143 3.4.5-beta2 ccf991e02dc2f63fb646324230d54832683f4a9b DRTVWR-286 2d849850558a5a0324b398d1c102d30bcbdfb88f DRTVWR-287 +e06898df8644fe567bee94f817d03abc1c380993 3.4.5-beta3 -- cgit v1.2.3 From 27e13e7330ad4c93b0c6e38398588e9a130c5ea9 Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Thu, 24 Jan 2013 09:17:02 -0800 Subject: MAINT-2275 Child prims are "left behind" by animated, moving (physical) linksets --- indra/newview/lldrawable.cpp | 59 +++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 647c3355ca..d394ce5b21 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -517,42 +517,45 @@ F32 LLDrawable::updateXform(BOOL undamped) F32 dist_squared = 0.f; F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera); - if (damped && isVisible()) + if (isVisible()) { - F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); - LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt); - dist_squared = dist_vec_squared(new_pos, target_pos); + if (damped) + { + F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); + LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt); + dist_squared = dist_vec_squared(new_pos, target_pos); - LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot); - dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f; + LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot); + dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f; - LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt); - dist_squared += dist_vec_squared(new_scale, target_scale); + LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt); + dist_squared += dist_vec_squared(new_scale, target_scale); - if ((dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED * camdist2) && - (dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED)) - { - // interpolate - target_pos = new_pos; - target_rot = new_rot; - target_scale = new_scale; + if ((dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED * camdist2) && + (dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED)) + { + // interpolate + target_pos = new_pos; + target_rot = new_rot; + target_scale = new_scale; + } + else if (mVObjp->getAngularVelocity().isExactlyZero()) + { + // snap to final position (only if no target omega is applied) + dist_squared = 0.0f; + if (getVOVolume() && !isRoot()) + { //child prim snapping to some position, needs a rebuild + gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); + } + } } - else if (mVObjp->getAngularVelocity().isExactlyZero()) + else { - // snap to final position (only if no target omega is applied) - dist_squared = 0.0f; - if (getVOVolume() && !isRoot()) - { //child prim snapping to some position, needs a rebuild - gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); - } + dist_squared = dist_vec_squared(old_pos, target_pos); + dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; + dist_squared += dist_vec_squared(old_scale, target_scale); } } - else - { - dist_squared = dist_vec_squared(old_pos, target_pos); - dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; - dist_squared += dist_vec_squared(old_scale, target_scale); - } LLVector3 vec = mCurrentScale-target_scale; -- cgit v1.2.3 From da9442b3238ca25b11932fd6d437964ab2f5be7b Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Thu, 24 Jan 2013 09:45:31 -0800 Subject: MAINT-2277 Yellow "fence" (selection) of the parcel doesn't update after selecting the other parcel * Removed bogus check on matching parcel data coming in. --- indra/newview/llviewerparcelmgr.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 33f632b25d..77e382b8c7 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1540,17 +1540,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use // Actually extract the data. if (parcel) { - if (sequence_id == SELECTED_PARCEL_SEQ_ID - && parcel->getLocalID() != INVALID_PARCEL_ID - && parcel->getLocalID() != local_id) - { - // The parcel has a valid parcel ID but it doesn't match the parcel - // for the data received. - llinfos << "Expecting data for parcel " << parcel->getLocalID() \ - << " but got data for parcel " << local_id << llendl; - return; - } - parcel->init(owner_id, FALSE, FALSE, FALSE, claim_date, claim_price_per_meter, rent_price_per_meter, -- cgit v1.2.3 From aee0766f35d724bfddc4be6b6f0b100467f3b1f4 Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Thu, 24 Jan 2013 13:21:45 -0800 Subject: MAINT-2275 Child prims are "left behind" by animated, moving (physical) linksets * A fix that doesn't break doors. Reverst MAINT-2247 --- indra/newview/lldrawable.cpp | 62 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index d394ce5b21..b15ffec9e3 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -517,45 +517,45 @@ F32 LLDrawable::updateXform(BOOL undamped) F32 dist_squared = 0.f; F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera); - if (isVisible()) + if (damped && isVisible()) { - if (damped) - { - F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); - LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt); - dist_squared = dist_vec_squared(new_pos, target_pos); + F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); + LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt); + dist_squared = dist_vec_squared(new_pos, target_pos); - LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot); - dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f; + LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot); + // FIXME: This can be negative! It is be possible for some rots to 'cancel out' pos or size changes. + dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f; - LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt); - dist_squared += dist_vec_squared(new_scale, target_scale); + LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt); + dist_squared += dist_vec_squared(new_scale, target_scale); - if ((dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED * camdist2) && - (dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED)) - { - // interpolate - target_pos = new_pos; - target_rot = new_rot; - target_scale = new_scale; - } - else if (mVObjp->getAngularVelocity().isExactlyZero()) - { - // snap to final position (only if no target omega is applied) - dist_squared = 0.0f; - if (getVOVolume() && !isRoot()) - { //child prim snapping to some position, needs a rebuild - gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); - } - } + if ((dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED * camdist2) && + (dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED)) + { + // interpolate + target_pos = new_pos; + target_rot = new_rot; + target_scale = new_scale; } - else + else if (mVObjp->getAngularVelocity().isExactlyZero()) { - dist_squared = dist_vec_squared(old_pos, target_pos); - dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; - dist_squared += dist_vec_squared(old_scale, target_scale); + // snap to final position (only if no target omega is applied) + dist_squared = 0.0f; + if (getVOVolume() && !isRoot()) + { //child prim snapping to some position, needs a rebuild + gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); + } } } + else + { + dist_squared = dist_vec_squared(old_pos, target_pos); + + // The following "makes sense" and fixes MAINT-2247 but causes MAINT-2275 + //dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; + //dist_squared += dist_vec_squared(old_scale, target_scale); + } LLVector3 vec = mCurrentScale-target_scale; -- cgit v1.2.3 From 51c8ffa2e222262dbfcc5430b2b1113a3dc0157c Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Thu, 24 Jan 2013 17:09:01 -0500 Subject: tag merge of DRTVWR-289 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 83c86a413d..c1b7ebf528 100644 --- a/.hgtags +++ b/.hgtags @@ -408,3 +408,4 @@ c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280 ccf991e02dc2f63fb646324230d54832683f4a9b DRTVWR-286 2d849850558a5a0324b398d1c102d30bcbdfb88f DRTVWR-287 e06898df8644fe567bee94f817d03abc1c380993 3.4.5-beta3 +a676b4d6c037b39fe5b8e42cf8839a9303936089 DRTVWR-289 -- cgit v1.2.3 From 4d589df2fd9a19cef248987e9f1f71b9be1f9aaa Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Thu, 24 Jan 2013 15:32:36 -0800 Subject: MAINT-2275 Child prims are "left behind" by animated, moving (physical) linksets * A fix that doesn't break tanks. Reverts MAINT-1742 --- indra/newview/lldrawable.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index b15ffec9e3..d041baea90 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -550,9 +550,10 @@ F32 LLDrawable::updateXform(BOOL undamped) } else { - dist_squared = dist_vec_squared(old_pos, target_pos); + // The following fixes MAINT-1742 but breaks vehicles similar to MAINT-2275 + // dist_squared = dist_vec_squared(old_pos, target_pos); - // The following "makes sense" and fixes MAINT-2247 but causes MAINT-2275 + // The following fixes MAINT-2247 but causes MAINT-2275 //dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f; //dist_squared += dist_vec_squared(old_scale, target_scale); } -- cgit v1.2.3 From c1827f7cf9c3340e9630a47f194108f03b1be1c4 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 25 Jan 2013 13:11:52 -0500 Subject: tag merge of DRTVWR-290 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 83c86a413d..09a13fb246 100644 --- a/.hgtags +++ b/.hgtags @@ -408,3 +408,4 @@ c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280 ccf991e02dc2f63fb646324230d54832683f4a9b DRTVWR-286 2d849850558a5a0324b398d1c102d30bcbdfb88f DRTVWR-287 e06898df8644fe567bee94f817d03abc1c380993 3.4.5-beta3 +28fa8b944a0c1869636ab00cc400f5aa71f6fa3c DRTVWR-290 -- cgit v1.2.3 From 276800e6f2d4521f6b3a987cf1a4ace95282092d Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 29 Jan 2013 18:09:13 -0500 Subject: MAINT-2281: correct test for XP --- indra/media_plugins/webkit/windows_volume_catcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/webkit/windows_volume_catcher.cpp index 957704da47..cc4630c1b8 100644 --- a/indra/media_plugins/webkit/windows_volume_catcher.cpp +++ b/indra/media_plugins/webkit/windows_volume_catcher.cpp @@ -90,7 +90,7 @@ void VolumeCatcherImpl::setVolume(F32 volume) { mVolume = volume; - if ( mSystemIsVistaOrHigher ) + if ( ! mSystemIsVistaOrHigher ) { // set both left/right to same volume // TODO: use pan value to set independently -- cgit v1.2.3 From 564f11679d52a777b992c25bbff7e4f914dac7ad Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Fri, 25 Jan 2013 23:29:09 +0000 Subject: [MAINT-2233] Duplicate entries in notifications.xml - Removed duplicate notification elements --- .../newview/skins/default/xui/en/notifications.xml | 1738 -------------------- 1 file changed, 1738 deletions(-) diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 44c18c2cce..c8f5cbb2b0 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -8872,14 +8872,6 @@ Cannot save to object contents: Item with that name already exists in inventory Cannot save to object contents: This would modify the attachment permissions. - - fail -Not permitted to edit this! - - - - fail -You don't have permission to modify that object. - - - - fail -Can't enable physics for an object that contributes to the navmesh. - - - - fail -Can't enable physics for keyframed objects. - - - - fail -Can't enable physics for object -- insufficient land resources. - - - - fail -Can't enable physics for object with physics resource cost greater than [MAX_OBJECTS] - - - - - fail -[AV_FREEZER] has frozen you. You cannot move or interact with the world. - - - - fail -[AV_FREEZER] has frozen you for [AV_FREEZE_TIME] seconds. You cannot move or interact with the world. - - - - fail -Avatar frozen. - - - - fail -[AV_FREEZER] has unfrozen you. - - - - fail -Avatar unfrozen. - - - - fail -Freeze failed because you don't have admin permission for that parcel. - - - - fail -Your freeze expired, go about your business. - - - - fail -Sorry, can't freeze that user. - - - - fail -You are now the owner of object [OBJECT_NAME] - - - - fail -Can't rez object at [OBJECT_POS] because the owner of this land does not allow it. Use the land tool to see land ownership. - - - - fail -Object can not be rezzed because there are too many requests. - - - - fail -You cannot sit because you cannot move at this time. - - - - fail -You cannot sit because you are not allowed on that land. - - - - fail -Try moving closer. Can't sit on object because -it is not in the same region as you. - - - - fail -Unable to create new object. The region is full. - - - - fail -Failed to place object at specified location. Please try again. - - - - fail -You Can't create trees and grass on land you don't own. - - - - fail -Copy failed because you lack permission to copy the object '[OBJ_NAME]'. - - - - fail -Copy failed because the object '[OBJ_NAME]' cannot be transferred to you. - - - - fail -Copy failed because the object '[OBJ_NAME]' contributes to navmesh. - - - - fail -Duplicate with no root objects selected. - - - - fail -Can't duplicate objects because the region is full. - - - - fail -Can't duplicate objects - Can't find the parcel they are on. - - - - fail -Can't create object because -the parcel is full. - - - - fail -Attempt to rez an object failed. - - - - fail -Unable to create item that has caused problems on this region. - - - - fail -That inventory item has been blacklisted. - - - - fail -You are not currently allowed to create objects. - - - - fail -Land Search Blocked. -You have performed too many land searches too quickly. -Please try again in a minute. - - - - fail -Not enough script resources available to attach object! - - - - fail -You died and have been teleported to your home location - - - - fail -You are no longer allowed here and have [EJECT_TIME] seconds to leave. - - - - fail -You can't enter this region because -the server is full. - - - - fail -Save Back To Inventory has been disabled. - - - - fail -Cannot save '[OBJ_NAME]' to object contents because the object it was rezzed from no longer exists. - - - - fail -Cannot save '[OBJ_NAME]' to object contents because you do not have permission to modify the object '[DEST_NAME]'. - - - - fail -Cannot save '[OBJ_NAME]' back to inventory -- this operation has been disabled. - - - - fail -You cannot copy your selection because you do not have permission to copy the object '[OBJ_NAME]'. - - - - fail -You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable. - - - - fail -You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable. - - - - fail -Removal of the object '[OBJ_NAME]' from the simulator is disallowed by the permissions system. - - - - fail -Cannot save your selection because you do not have permission to modify the object '[OBJ_NAME]'. - - - - fail -Cannot save your selection because the object '[OBJ_NAME]' is not copyable. - - - - fail -You cannot take your selection because you do not have permission to modify the object '[OBJ_NAME]'. - - - - fail -Internal Error: Unknown destination type. - - - - fail -Delete failed because object not found - - - - fail -Sorry, can't eject that user. - - - - fail -This region does not allow you to set your home location here. - - - - fail -You can only set your 'Home Location' on your land or at a mainland Infohub. - - - - fail -Home position set. - - - - fail -Avatar ejected. - - - - fail -Eject failed because you don't have admin permission for that parcel. - - - - fail -Can't move object '[OBJECT_NAME]' to -[OBJ_POSITION] in region [REGION_NAME] because the parcel is full. - - - - fail -Can't move object '[OBJECT_NAME]' to -[OBJ_POSITION] in region [REGION_NAME] because your objects are not allowed on this parcel. - - - - fail -Can't move object '[OBJECT_NAME]' to -[OBJ_POSITION] in region [REGION_NAME] because there are not enough resources for this object on this parcel. - - - - fail -Can't move object '[OBJECT_NAME]' to -[OBJ_POSITION] in region [REGION_NAME] because the other region is running an older version which does not support receiving this object via region crossing. - - - - fail -Can't move object '[OBJECT_NAME]' to -[OBJ_POSITION] in region [REGION_NAME] because you cannot modify the navmesh across region boundaries. - - - - fail -Can't move object '[OBJECT_NAME]' to -[OBJ_POSITION] in region [REGION_NAME] because of an unknown reason. ([FAILURE_TYPE]) - - - - fail -You don't have permission to modify that object - - - - fail -Can't enable physics for an object that contributes to the navmesh. - - - - fail -Can't enable physics for keyframed objects. - - - - fail -Can't enable physics for object -- insufficient land resources. - - - - fail -Can't enable physics for object with physics resource cost greater than [MAX_OBJECTS] - - - - fail -This object cannot have a concave piece because it is phantom and contributes to the navmesh. - - - - fail -Unable to add item! - - - - fail -Unable to edit this! - - - - fail -Not permitted to edit this. - - - - fail -Not permitted to copy that inventory. - - - - fail -Cannot save to object contents: Item no longer exists. - - - - fail -Cannot save to object contents: Item with that name already exists in inventory - - - - fail -Cannot save to object contents: This would modify the attachment permissions. - - - - fail -Not permitted to edit this! - - - - fail -Too many scripts. - - - - fail -Unable to add script! - - - - fail -Asset server didn't respond in a timely fashion. Object returned to sim. - - - - fail -This region does not have physics shapes enabled. - - - - fail -You cannot modify the navmesh across region boundaries. - - - - fail -You don't have permission to modify that object. - - - - fail -Can't enable physics for an object that contributes to the navmesh. - - - - fail -Can't enable physics for keyframed objects. - - - - fail -Can't enable physics for object -- insufficient land resources. - - - - fail -Can't enable physics for object with physics resource cost greater than [MAX_OBJECTS] - - - - fail -Cannot set physics properties on that object type. - - - - fail -Cannot set root prim to have no shape. - - - - fail -This region does not have physics materials enabled. - - - - fail -Only root prims may have their physics materials adjusted. - - - - fail -Setting physics materials on characters is not yet supported. - - - - fail -One or more of the specified physics material properties was invalid. - - - - fail -You may not alter the stitching type of a mesh object. - - - - fail -You may not alter the shape of a mesh object - - - - fail -You can't enter this region because \nthe region is full. - - - - fail -Link failed -- owners differ - - - - fail -Link failed -- cannot modify the navmesh across region boundaries. - - - - fail -Link failed because you do not have edit permission. - - - - fail -Link failed -- too many primitives - - - - fail -Link failed -- cannot link no-copy with no-transfer - - - - fail -Link failed -- nothing linkable. - - - - fail -Link failed -- too many pathfinding characters - - - - fail -Link failed -- insufficient land resources - - - - fail -Object uses too many physics resources -- its dynamics have been disabled. - - - - fail -You have been teleported home by the object '[OBJECT_NAME]' on the parcel '[PARCEL_NAME]' - - - - fail -You have been teleported home by the object '[OBJECT_NAME]' - - - - fail -You have been teleported by an attachment on [ITEM_ID] - - - - fail -You have been teleported by the object '[OBJECT_NAME]' on the parcel '[PARCEL_NAME]' - - - - fail -You have been teleported by the object '[OBJECT_NAME]' owned by [OWNER_ID] - - - - fail -You have been teleported by the object '[OBJECT_NAME]' owned by an unknown user. - - - - fail -Unable to create requested object. The region is full. - - - - fail -You can't attach multiple objects to one spot. - - - - fail -You can't create multiple objects here. - - - - fail -Unable to create requested object. Object is missing from database. - - - - fail -Unable to create requested object. The request timed out. Please try again. - - - - fail -Unable to create requested object. Please try again. - - - - fail -Rez failed, requested object took too long to load. - - - - fail -Failed to place object at specified location. Please try again. - - - - fail -You cannot create plants on this land. - - - - fail -Cannot restore object. No world position found. - - - - fail -Unable to rez object because its mesh data is invalid. - - - - fail -Unable to rez object because there are already too many scripts in this region. - - - - fail -Your access privileges don't allow you to create objects there. - - - - fail -You are not currently allowed to create objects. - - - - fail -Invalid object parameters - - - - fail -Your access privileges don't allow you to duplicate objects here. - - - - fail -You are not allowed to change this shape. - - - - fail -Your access privileges don't allow you to claim objects here. - - - - fail -Deed failed because you do not have permission to deed objects for your group. - - - - fail -Your access privileges don't allow you to buy objects here. - - - - fail -Cannot attach object because an avatar is sitting on it. - - - - fail -Trees and grasses cannot be worn as attachments. - - - - fail -Cannot attach group-owned objects. - - - - fail -Cannot attach objects that you don't own. - - - - fail -Cannot attach objects that contribute to navmesh. - - - - fail -Cannot attach object because you do not have permission to move it. - - - - fail -Not enough script resources available to attach object! - - - - fail -You can't drop objects here; try the Free Trial area. - - - - fail -You can't drop mesh attachments. Detach to inventory and then rez in world. - - - - fail -Failed to drop attachment: you don't have permission to drop there. - - - - fail -Failed to drop attachment: insufficient available land resource. - - - - fail -Failed to drop attachments: insufficient available resources. - - - - fail -Cannot drop object here. Parcel is full. - - - - fail -Can't touch/grab this object because you are banned from the land parcel. - - - - fail -Please narrow your delete parameters. - - - - fail -Unable to upload asset. - - - - fail -Could not find user to teleport home - - - - fail -godlike request failed - - - - fail -generic request failed - - - - fail -Unable to upload postcard. Try again later. - - - - fail -Unable to fetch inventory details for the group notice. - - - - fail -Unable to send group notice -- not permitted. - - - - fail -Unable to send group notice -- could not construct inventory. - - - - fail -Unable to parse inventory in notice. - - - - fail -Terrain upload failed. - - - - fail -Terrain file written. - - - - fail -Terrain file written, starting download... - - - - fail -Terrain baked. - - - - fail -Only the first 10 selected objects have been disabled. Refresh and make additional selections if required. - - - - fail -You need to update your viewer to buy this parcel. - - - - fail -You can't buy this land due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. Please go to the Knowledge Base for details on accessing areas with this maturity Rating. - - - - fail -Unable to buy, this parcel is not for sale. - - - - fail -Unable to buy, the sale price or land area has changed. - - - - fail -You are not the authorized buyer for this parcel. - - - - fail -You cannot purchase this parcel because it is already awaiting purchase aut - - - - fail -You cannot build objects here because doing so would overflow the parcel. - - - - fail -You selected land with different owners. Please select a smaller area and try again. - - - - fail -Not enough leased parcels in selection to join. - - - - fail -Can't divide land.\nThere is more than one parcel selected.\nTry selecting a smaller piece of land. - - - - fail -Can't divide land.\nCan't find the parcel.\nPlease report with Help -> Reprt Bug... - - - - fail -Can't divide land. Whole parcel is selected.\nTry selecting a smaller piece of land. - - - - fail -Land has been divided. - - - - fail -You purchased a pass. - - - - fail -Region does not allow classified advertisements. - - - - fail -Your pass to this land is about to expire. - - - - fail -There is no suitable surface to sit on, try another spot. - - - - fail -No room to sit here, try another spot. - - - - fail -Autopilot canceled - - - - fail -Claim object failed because you don't have permission - - - - fail -Claim object failed because you don't have enough L$. - - - - fail -Cannot deed group-owned land. - - - - fail -Buy object failed because you don't have enough L$. - - - - fail -Buy inventory failed because you do not have enough L$ - - - - fail -You don't have enough L$ to buy a pass to this land. - - - - fail -Unable to buy pass right now. Try again later. - - - - fail -Can't create object because \nthe parcel is full. - - - - fail -Failed to place object at specified location. Please try again. - - - - fail -Unable to create landmark for event. - - - - fail -Your godlike powers break the freeze! - - - - fail -Request for special powers failed. This request has been logged. - - - - fail -The system is currently unable to process your request. The request timed out. - - - - fail -The system is unable to process your request. - - - - fail -Insufficient funds to create primitve. - - - - fail -Insufficient funds to create object. - - - - fail -Reset Home position since Home wasn't legal. - - - - fail -You cannot currently invite anyone to your location because the region is full. Try again later. - - - - fail -This region does not allow you to set your home location here. - - - - fail -You can only set your 'Home Location' on your land or at a mainland Infohub. - - - - fail -Home position set. - - - - fail -Cannot derez object due to inventory fault. - - - - fail -Cannot create requested inventory. - - - - fail -Cannot create requested inventory folder. - - - - fail -Cannot create that inventory. - - - - fail -Cannot create landmark. - - - - fail -Cannot create outfit right now. Try again in a minute. - - - - fail -Inventory is not for sale. - - - - fail -Unable to find inventory item. - - - - fail -Unable to find object. - - - - fail -Money transfers to objects are currently disabled in this region. - - - - fail -Could not figure out who to pay. - - - - fail -You cannot give L$ to public objects. - - - - fail -Inventory creation on in-world object failed. - - - - fail -An internal error prevented us from properly updating your viewer. The L$ balance or parcel holdings displayed in your viewer may not reflect your actual balance on the servers. - - - -- cgit v1.2.3 From 2ce44afc7f69ddf92b857c8999e255c528d2f393 Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Sat, 26 Jan 2013 01:47:37 +0000 Subject: [MAINT-2233] Duplicate entries in notifications.xml - Removed duplicate entry from panel_preferences_general.xml --- .../skins/default/xui/en/panel_preferences_graphics1.xml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 849f3ef73d..7eb0fac2be 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -152,19 +152,6 @@ width="80"> Mid - - High - Date: Mon, 28 Jan 2013 10:15:10 -0800 Subject: For MAINT-2276 a workaround to unblock 3.4.5 beta review: ted --- indra/newview/llpaneloutfitedit.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 35e2e96bab..36234b9536 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -186,8 +186,11 @@ private: // Populate the menu with items like "New Skin", "New Pants", etc. static void populateCreateWearableSubmenus(LLMenuGL* menu) { - LLView* menu_clothes = gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE); - LLView* menu_bp = gMenuHolder->getChildView("COF.Geear.New_Body_Parts", FALSE); + // MAINT-2276...these menus are created as dummies because they are not available + // when this function is called. This prevents their parent from popping up later. + // + //LLView* menu_clothes = gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE); + //LLView* menu_bp = gMenuHolder->getChildView("COF.Geear.New_Body_Parts", FALSE); for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i) { @@ -200,8 +203,11 @@ private: p.on_click.function_name = "Wearable.Create"; p.on_click.parameter = LLSD(type_name); - LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? - menu_clothes : menu_bp; + //LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? menu_clothes : menu_bp; + // This is a work-around for MAINT-2276 wherein the parent toggleable menu does not appear + // It puts everything under one menu, but that menu appears, which is better than not. + // + LLView* parent = menu; LLUICtrlFactory::create(p, parent); } } -- cgit v1.2.3 From bfbf4a6c46be52e64147e0be4a4bdc4a81392cd7 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 29 Jan 2013 14:12:55 -0500 Subject: Added tag DRTVWR-291 for changeset 7f09bbc28c29 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index afe117d3f6..be03ca6932 100644 --- a/.hgtags +++ b/.hgtags @@ -410,3 +410,4 @@ ccf991e02dc2f63fb646324230d54832683f4a9b DRTVWR-286 e06898df8644fe567bee94f817d03abc1c380993 3.4.5-beta3 a676b4d6c037b39fe5b8e42cf8839a9303936089 DRTVWR-289 28fa8b944a0c1869636ab00cc400f5aa71f6fa3c DRTVWR-290 +7f09bbc28c297f14b67961be7b6575445fa160e8 DRTVWR-291 -- cgit v1.2.3 From 07deaaef88f2b532bd47e6bc5a24ea2c2ce9794d Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 29 Jan 2013 18:27:40 -0500 Subject: tag merge of DRTVWR-292 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index be03ca6932..d220aa6855 100644 --- a/.hgtags +++ b/.hgtags @@ -411,3 +411,4 @@ e06898df8644fe567bee94f817d03abc1c380993 3.4.5-beta3 a676b4d6c037b39fe5b8e42cf8839a9303936089 DRTVWR-289 28fa8b944a0c1869636ab00cc400f5aa71f6fa3c DRTVWR-290 7f09bbc28c297f14b67961be7b6575445fa160e8 DRTVWR-291 +b23419a2748483c98f3b84b630468a21c88feba5 DRTVWR-292 -- cgit v1.2.3 From 2fa8205d4dfea3fd57bcdb2973805d110e38c44f Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 29 Jan 2013 18:39:51 -0500 Subject: MAINT-2281: correct test for XP (corrected fix I applied incorrectly) --- indra/media_plugins/webkit/windows_volume_catcher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/webkit/windows_volume_catcher.cpp index cc4630c1b8..0cfb810906 100644 --- a/indra/media_plugins/webkit/windows_volume_catcher.cpp +++ b/indra/media_plugins/webkit/windows_volume_catcher.cpp @@ -71,7 +71,7 @@ VolumeCatcherImpl::VolumeCatcherImpl() { mSystemIsVistaOrHigher = isWindowsVistaOrHigher(); - if ( mSystemIsVistaOrHigher ) + if ( ! mSystemIsVistaOrHigher ) { HMODULE handle = ::LoadLibrary(L"winmm.dll"); if(handle) @@ -90,7 +90,7 @@ void VolumeCatcherImpl::setVolume(F32 volume) { mVolume = volume; - if ( ! mSystemIsVistaOrHigher ) + if ( mSystemIsVistaOrHigher ) { // set both left/right to same volume // TODO: use pan value to set independently -- cgit v1.2.3