diff --git a/.hgtags b/.hgtags
index 0a97b4b9a5..a0ff0c07f8 100755
--- a/.hgtags
+++ b/.hgtags
@@ -510,3 +510,5 @@ d07f76c5b9860fb87924d00ca729f7d4532534d6 3.7.29-release
27e3cf444c4cc645884960a61325a9ee0e9a2d0f 3.8.4-release
e821ef17c6edea4a59997719d8ba416d8c16e143 3.8.5-release
5a5bd148943bfb46cf2ff2ccf376c42dee93d19b 3.8.6-release
+ae3297cdd03ab14f19f3811acbc4acd3eb600336 4.0.0-release
+759710a9acef61aaf7b69f4bc4a5a913de87ad8a 4.0.1-release
diff --git a/BuildParams b/BuildParams
index 9180ae9092..8bcdb2c5e2 100755
--- a/BuildParams
+++ b/BuildParams
@@ -72,12 +72,15 @@ additional_packages = ""
# the viewer_channel_suffix is prefixed by a blank and then appended to the viewer_channel
# for the package in a setting that overrides the compiled-in value
################################################################
-additional_packages = "EDU"
+## Removed 2015-07-02 (MAINT-5360) until we fix packaging step in Team City
+## additional_packages = "EDU"
# The EDU package allows us to create a separate release channel whose expirations
# are synchronized as much as possible with the academic year
-EDU_sourceid = ""
-EDU_viewer_channel_suffix = "edu"
+## Removed 2015-07-02 (MAINT-5360) until we fix packaging step in Team City
+## EDU_sourceid = ""
+## Removed 2015-07-02 (MAINT-5360) until we fix packaging step in Team City
+## EDU_viewer_channel_suffix = "edu"
# Notifications - to configure email notices use the TeamCity parameter
# setting screen for your project or build configuration to set the
diff --git a/autobuild.xml b/autobuild.xml
index e73ebce825..361a963807 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1517,6 +1517,52 @@
version
0.0.1
+ llceflib
+
llphysicsextensions_source
copyright
@@ -1625,66 +1671,6 @@
version
1.0.298370
- llqtwebkit
-
- copyright
- Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- description
- QT cross-platform application and UI framework.
- license
- LGPL
- license_file
- LICENSES/llqtwebkit.txt
- name
- llqtwebkit
- platforms
-
- darwin
-
- archive
-
- hash
- 3c2b6be4c78b2479c3fae612e1053d37
- hash_algorithm
- md5
- url
- http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/canonical_3p-llqtwebkit2/rev/295522/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20141015.tar.bz2
-
- name
- darwin
-
- linux
-
- archive
-
- hash
- d31358176b9ba8c676458cc061767c0b
- hash_algorithm
- md5
- url
- http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/canonical_3p-llqtwebkit2/rev/295522/arch/Linux/installer/llqtwebkit-4.7.1-linux-20141015.tar.bz2
-
- name
- linux
-
- windows
-
- archive
-
- hash
- bb4e8c8006c8a7aef6d3e3c36a8cebbf
- hash_algorithm
- md5
- url
- http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/canonical_3p-llqtwebkit2/rev/295522/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20141015.tar.bz2
-
- name
- windows
-
-
- version
- 4.7.1
-
mesa
license
@@ -2052,9 +2038,9 @@
archive
hash
- 3f8b52280cb1eff2d1acd0214bce1b16
+ 78650a79bda6435e623a940ad425a593
url
- http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/quicktime_3p-update-quicktime/rev/296445/arch/CYGWIN/installer/quicktime-7.3-windows-296445.tar.bz2
+ http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/quicktime_3p-update-quicktime/rev/300073/arch/CYGWIN/installer/quicktime-7.3-windows-300073.tar.bz2
name
windows
@@ -2063,62 +2049,6 @@
version
7.3
- slplugins
-
- copyright
- Second Life Viewer Source Code - Copyright (C) 2010, Linden Research, Inc.
- description
- Second Life Viewer Plugins and launcher
- license
- LGPL
- license_file
- LICENSES/slplugins-license.txt
- name
- slplugins
- platforms
-
- darwin
-
- archive
-
- hash
- f6bfb026572f03a4c8ac6b2b7d7eb0ae
- url
- http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/slplugins_3p-update-slplugins/rev/298079/arch/Darwin/installer/slplugins-3.7.24.297623.298079-darwin-298079.tar.bz2
-
- name
- darwin
-
- linux
-
- archive
-
- hash
- 64b8a3bac95b5888a7ede3d7661a18b8
- url
- http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/slplugins_3p-update-slplugins/rev/298079/arch/Linux/installer/slplugins-3.7.24.297623.298079-linux-298079.tar.bz2
-
- name
- linux
-
- windows
-
- archive
-
- hash
- 3a1ea3385303b78b0327c8cea929ef27
- hash_algorithm
- md5
- url
- http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/slplugins_3p-update-slplugins/rev/298079/arch/CYGWIN/installer/slplugins-3.7.24.297623.298079-windows-298079.tar.bz2
-
- name
- windows
-
-
- version
- 3.7.24.297623.298079
-
slvoice
copyright
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 7493e96c39..33547a78a1 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -186,6 +186,7 @@ Ansariel Hiller
STORM-1984
STORM-1979
MAINT-5533
+ MAINT-5756
Aralara Rajal
Arare Chantilly
CHUIBUG-191
@@ -767,6 +768,7 @@ Kitty Barnett
STORM-1905
VWR-24217
STORM-1804
+ MAINT-5416
Kolor Fall
Komiko Okamoto
Korvel Noh
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 1e1d6dc585..dceafeef29 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -57,12 +57,6 @@ add_subdirectory(${VIEWER_PREFIX}test)
if (ENABLE_MEDIA_PLUGINS)
# viewer media plugins
add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
-
- # llplugin testbed code (is this the right way to include it?)
- if (LL_TESTS AND NOT LINUX)
- add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
- add_subdirectory(${VIEWER_PREFIX}test_apps/llfbconnecttest)
- endif (LL_TESTS AND NOT LINUX)
endif (ENABLE_MEDIA_PLUGINS)
if (LINUX)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 1a3b6c5117..86fc2dfff5 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -166,6 +166,9 @@ if (LINUX)
-pthread
)
+ # force this platform to accept TOS via external browser
+ add_definitions(-DEXTERNAL_TOS)
+
add_definitions(-DAPPID=secondlife)
add_definitions(-fvisibility=hidden)
# don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The viewer doesn't need to catch SIGCHLD anyway.
diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
new file mode 100644
index 0000000000..9cfb7d14c7
--- /dev/null
+++ b/indra/cmake/CEFPlugin.cmake
@@ -0,0 +1,40 @@
+# -*- cmake -*-
+include(Linking)
+include(Prebuilt)
+
+if (USESYSTEMLIBS)
+ set(CEFPLUGIN OFF CACHE BOOL
+ "CEFPLUGIN support for the llplugin/llmedia test apps.")
+else (USESYSTEMLIBS)
+ use_prebuilt_binary(llceflib)
+ set(CEFPLUGIN ON CACHE BOOL
+ "CEFPLUGIN support for the llplugin/llmedia test apps.")
+ set(CEF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/cef)
+endif (USESYSTEMLIBS)
+
+if (WINDOWS)
+ set(CEF_PLUGIN_LIBRARIES
+ libcef.lib
+ libcef_dll_wrapper.lib
+ llceflib.lib
+ )
+elseif (DARWIN)
+ FIND_LIBRARY(APPKIT_LIBRARY AppKit)
+ if (NOT APPKIT_LIBRARY)
+ message(FATAL_ERROR "AppKit not found")
+ endif()
+
+ FIND_LIBRARY(CEF_LIBRARY "Chromium Embedded Framework" ${ARCH_PREBUILT_DIRS_RELEASE})
+ if (NOT CEF_LIBRARY)
+ message(FATAL_ERROR "CEF not found")
+ endif()
+
+ set(CEF_PLUGIN_LIBRARIES
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libLLCefLib.a
+ ${APPKIT_LIBRARY}
+ ${CEF_LIBRARY}
+ )
+
+elseif (LINUX)
+endif (WINDOWS)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index cd7da5d6c1..4dd69649d0 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -14,6 +14,7 @@ set(cmake_SOURCE_FILES
Boost.cmake
BuildVersion.cmake
CARes.cmake
+ CEFPlugin.cmake
CMakeCopyIfDifferent.cmake
ConfigurePkgConfig.cmake
CURL.cmake
@@ -82,18 +83,18 @@ set(cmake_SOURCE_FILES
LLXML.cmake
LScript.cmake
Linking.cmake
-## MediaPluginBase.cmake
+ MediaPluginBase.cmake
NDOF.cmake
OPENAL.cmake
OpenGL.cmake
OpenJPEG.cmake
OpenSSL.cmake
PNG.cmake
-## PluginAPI.cmake
+ PluginAPI.cmake
Prebuilt.cmake
PulseAudio.cmake
Python.cmake
-## QuickTimePlugin.cmake
+ QuickTimePlugin.cmake
TemplateCheck.cmake
Tut.cmake
UI.cmake
@@ -102,7 +103,6 @@ set(cmake_SOURCE_FILES
Variables.cmake
ViewerMiscLibs.cmake
VisualLeakDetector.cmake
-## WebKitLibPlugin.cmake
XmlRpcEpi.cmake
ZLIB.cmake
)
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index c95f0c3702..74fe3f1137 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -6,7 +6,7 @@ set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
include(Variables)
set(ARCH_PREBUILT_DIRS ${AUTOBUILD_INSTALL_DIR}/lib)
-##set(ARCH_PREBUILT_DIRS_PLUGINS ${AUTOBUILD_INSTALL_DIR}/plugins)
+set(ARCH_PREBUILT_DIRS_PLUGINS ${AUTOBUILD_INSTALL_DIR}/plugins)
set(ARCH_PREBUILT_DIRS_RELEASE ${AUTOBUILD_INSTALL_DIR}/lib/release)
set(ARCH_PREBUILT_DIRS_DEBUG ${AUTOBUILD_INSTALL_DIR}/lib/debug)
if (WINDOWS)
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 2fb47c58a7..63e296b556 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -26,7 +26,7 @@ set(VIEWER_PREFIX)
set(INTEGRATION_TESTS_PREFIX)
set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
-set(ENABLE_MEDIA_PLUGINS OFF CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
+set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
if(LIBS_CLOSED_DIR)
file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)
diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake
deleted file mode 100644
index f7c548a2fd..0000000000
--- a/indra/cmake/WebKitLibPlugin.cmake
+++ /dev/null
@@ -1,93 +0,0 @@
-# -*- cmake -*-
-include(Linking)
-include(Prebuilt)
-include(OpenSSL)
-
-if (USESYSTEMLIBS)
- # The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny.
- find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED)
- include(${QT_USE_FILE})
- set(QTDIR $ENV{QTDIR})
- if (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
- message(FATAL_ERROR "\"${QT_BINARY_DIR}\" is unequal \"${QTDIR}/bin\"; "
- "Qt is found by looking for qmake in your PATH. "
- "Please set your PATH such that 'qmake' is found in \$QTDIR/bin, "
- "or unset QTDIR if the found Qt is correct.")
- endif (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
- find_package(LLQtWebkit REQUIRED QUIET)
- # Add the plugins.
- set(QT_PLUGIN_LIBRARIES)
- foreach(qlibname qgif qjpeg)
- find_library(QT_PLUGIN_${qlibname} ${qlibname} PATHS ${QT_PLUGINS_DIR}/imageformats NO_DEFAULT_PATH)
- if (QT_PLUGIN_${qlibname})
- list(APPEND QT_PLUGIN_LIBRARIES ${QT_PLUGIN_${qlibname}})
- else (QT_PLUGIN_${qtlibname})
- message(FATAL_ERROR "Could not find the Qt plugin ${qlibname} in \"${QT_PLUGINS_DIR}/imageformats\"!")
- endif (QT_PLUGIN_${qlibname})
- endforeach(qlibname)
- # qjpeg depends on libjpeg
- list(APPEND QT_PLUGIN_LIBRARIES jpeg)
- set(WEBKITLIBPLUGIN OFF CACHE BOOL
- "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
-else (USESYSTEMLIBS)
- use_prebuilt_binary(llqtwebkit)
- set(WEBKITLIBPLUGIN ON CACHE BOOL
- "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
-endif (USESYSTEMLIBS)
-
-if (WINDOWS)
- set(WEBKIT_PLUGIN_LIBRARIES
- debug llqtwebkitd
- debug QtWebKitd4
- debug QtOpenGLd4
- debug QtNetworkd4
- debug QtGuid4
- debug QtCored4
- debug qtmaind
- optimized llqtwebkit
- optimized QtWebKit4
- optimized QtOpenGL4
- optimized QtNetwork4
- optimized QtGui4
- optimized QtCore4
- optimized qtmain
- )
-elseif (DARWIN)
- set(WEBKIT_PLUGIN_LIBRARIES
- ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.a
- ${ARCH_PREBUILT_DIRS_RELEASE}/libQtWebKit.4.dylib
- ${ARCH_PREBUILT_DIRS_RELEASE}/libQtOpenGL.4.dylib
- ${ARCH_PREBUILT_DIRS_RELEASE}/libQtNetwork.4.dylib
- ${ARCH_PREBUILT_DIRS_RELEASE}/libQtGui.4.dylib
- ${ARCH_PREBUILT_DIRS_RELEASE}/libQtCore.4.dylib
- )
-elseif (LINUX)
- # *HUH: What does this do?
- set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES} ${QT_PLUGIN_LIBRARIES})
- set(WEBKIT_PLUGIN_LIBRARIES
- llqtwebkit
-# qico
-# qpng
-# qtiff
-# qsvg
-# QtSvg
- QtWebKit
- QtOpenGL
- QtNetwork
- ${OPENSSL_LIBRARIES}
- QtGui
- QtCore
-# jscore
-# qgif
-# qjpeg
-# jpeg
- fontconfig
- X11
- Xrender
- GL
-
-# sqlite3
-# Xi
-# SM
- )
-endif (WINDOWS)
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 1d85aa2978..62bd09471a 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -512,11 +512,7 @@ class LLManifest(object):
# ensure that destination path exists
self.cmakedirs(os.path.dirname(dst))
self.created_paths.append(dst)
- if not os.path.isdir(src):
- self.ccopy(src,dst)
- else:
- # src is a dir
- self.ccopytree(src,dst)
+ self.ccopymumble(src, dst)
else:
print "Doesn't exist:", src
@@ -595,28 +591,38 @@ class LLManifest(object):
else:
os.remove(path)
- def ccopy(self, src, dst):
- """ Copy a single file or symlink. Uses filecmp to skip copying for existing files."""
+ def ccopymumble(self, src, dst):
+ """Copy a single symlink, file or directory."""
if os.path.islink(src):
linkto = os.readlink(src)
- if os.path.islink(dst) or os.path.exists(dst):
+ if os.path.islink(dst) or os.path.isfile(dst):
os.remove(dst) # because symlinking over an existing link fails
+ elif os.path.isdir(dst):
+ shutil.rmtree(dst)
os.symlink(linkto, dst)
+ elif os.path.isdir(src):
+ self.ccopytree(src, dst)
else:
- # Don't recopy file if it's up-to-date.
- # If we seem to be not not overwriting files that have been
- # updated, set the last arg to False, but it will take longer.
- if os.path.exists(dst) and filecmp.cmp(src, dst, True):
- return
- # only copy if it's not excluded
- if self.includes(src, dst):
- try:
- os.unlink(dst)
- except OSError, err:
- if err.errno != errno.ENOENT:
- raise
+ self.ccopyfile(src, dst)
+ # XXX What about devices, sockets etc.?
+ # YYY would we put such things into a viewer package?!
- shutil.copy2(src, dst)
+ def ccopyfile(self, src, dst):
+ """ Copy a single file. Uses filecmp to skip copying for existing files."""
+ # Don't recopy file if it's up-to-date.
+ # If we seem to be not not overwriting files that have been
+ # updated, set the last arg to False, but it will take longer.
+ if os.path.exists(dst) and filecmp.cmp(src, dst, True):
+ return
+ # only copy if it's not excluded
+ if self.includes(src, dst):
+ try:
+ os.unlink(dst)
+ except OSError, err:
+ if err.errno != errno.ENOENT:
+ raise
+
+ shutil.copy2(src, dst)
def ccopytree(self, src, dst):
"""Direct copy of shutil.copytree with the additional
@@ -632,11 +638,7 @@ class LLManifest(object):
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
- if os.path.isdir(srcname):
- self.ccopytree(srcname, dstname)
- else:
- self.ccopy(srcname, dstname)
- # XXX What about devices, sockets etc.?
+ self.ccopymumble(srcname, dstname)
except (IOError, os.error), why:
errors.append((srcname, dstname, why))
if errors:
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 73df47b933..7e9ae8d108 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -178,6 +178,11 @@ void LLCurl::Responder::setURL(const std::string& url)
mURL = url;
}
+const std::string& LLCurl::Responder::getURL()
+{
+ return mURL;
+}
+
void LLCurl::Responder::successResult(const LLSD& content)
{
setResult(HTTP_OK, "", content);
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 385d9fffa8..34758433c8 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -147,6 +147,7 @@ public:
public:
void setHTTPMethod(EHTTPMethod method);
void setURL(const std::string& url);
+ const std::string& getURL();
void setResult(S32 status, const std::string& reason, const LLSD& content = LLSD());
void setResponseHeader(const std::string& header, const std::string& value);
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 05fc12e338..8c4ddd524e 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -20,7 +20,6 @@ include_directories(
${LLRENDER_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
- ${LLQTWEBKIT_INCLUDE_DIR}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@@ -68,7 +67,7 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
add_library (llplugin ${llplugin_SOURCE_FILES})
-##add_subdirectory(slplugin)
+add_subdirectory(slplugin)
# Add tests
if (LL_TESTS)
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 4bfd0de81e..3d173d0459 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llpluginclassmedia.cpp
* @brief LLPluginClassMedia handles a plugin which knows about the "media" message class.
*
@@ -6,21 +6,21 @@
* $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$
* @endcond
@@ -41,14 +41,13 @@ static int nextPowerOf2( int value )
{
next_power_of_2 <<= 1;
}
-
+
return next_power_of_2;
}
LLPluginClassMedia::LLPluginClassMedia(LLPluginClassMediaOwner *owner)
{
mOwner = owner;
- mPlugin = NULL;
reset();
//debug use
@@ -63,19 +62,19 @@ LLPluginClassMedia::~LLPluginClassMedia()
}
bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug)
-{
+{
LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL;
LL_DEBUGS("Plugin") << "dir: " << plugin_dir << LL_ENDL;
LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL;
-
- mPlugin = new LLPluginProcessParent(this);
+
+ mPlugin = LLPluginProcessParent::create(this);
mPlugin->setSleepTime(mSleepTime);
-
+
// Queue up the media init message -- it will be sent after all the currently queued messages.
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init");
message.setValue("target", mTarget);
sendMessage(message);
-
+
mPlugin->init(launcher_filename, plugin_dir, plugin_filename, debug);
return true;
@@ -84,10 +83,10 @@ bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::s
void LLPluginClassMedia::reset()
{
- if(mPlugin != NULL)
+ if(mPlugin)
{
- delete mPlugin;
- mPlugin = NULL;
+ mPlugin->requestShutdown();
+ mPlugin.reset();
}
mTextureParamsReceived = false;
@@ -115,7 +114,7 @@ void LLPluginClassMedia::reset()
mTextureHeight = 0;
mMediaWidth = 0;
mMediaHeight = 0;
- mDirtyRect = LLRect::null;
+ mDirtyRect = LLRect::null;
mAutoScaleMedia = false;
mRequestedVolume = 1.0f;
mPriority = PRIORITY_NORMAL;
@@ -132,7 +131,7 @@ void LLPluginClassMedia::reset()
mMediaName.clear();
mMediaDescription.clear();
mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f);
-
+
// media_browser class
mNavigateURI.clear();
mNavigateResultCode = -1;
@@ -140,7 +139,7 @@ void LLPluginClassMedia::reset()
mHistoryBackAvailable = false;
mHistoryForwardAvailable = false;
mStatusText.clear();
- mProgressPercent = 0;
+ mProgressPercent = 0;
mClickURL.clear();
mClickNavType.clear();
mClickTarget.clear();
@@ -148,7 +147,7 @@ void LLPluginClassMedia::reset()
mStatusCode = 0;
mClickEnforceTarget = false;
-
+
// media_time class
mCurrentTime = 0.0f;
mDuration = 0.0f;
@@ -162,7 +161,7 @@ void LLPluginClassMedia::idle(void)
{
mPlugin->idle();
}
-
+
if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()) || (mOwner == NULL))
{
// Can't process a size change at this time
@@ -179,7 +178,7 @@ void LLPluginClassMedia::idle(void)
else
{
mRequestedTextureWidth = mRequestedMediaWidth;
-
+
if(mPadding > 1)
{
// Pad up to a multiple of the specified number of bytes per row
@@ -189,7 +188,7 @@ void LLPluginClassMedia::idle(void)
{
rowbytes += mPadding - pad;
}
-
+
if(rowbytes % mRequestedTextureDepth == 0)
{
mRequestedTextureWidth = rowbytes / mRequestedTextureDepth;
@@ -201,7 +200,7 @@ void LLPluginClassMedia::idle(void)
}
}
-
+
// Size change has been requested but not initiated yet.
size_t newsize = mRequestedTextureWidth * mRequestedTextureHeight * mRequestedTextureDepth;
@@ -216,22 +215,22 @@ void LLPluginClassMedia::idle(void)
mPlugin->removeSharedMemory(mTextureSharedMemoryName);
mTextureSharedMemoryName.clear();
}
-
+
mTextureSharedMemorySize = newsize;
mTextureSharedMemoryName = mPlugin->addSharedMemory(mTextureSharedMemorySize);
if(!mTextureSharedMemoryName.empty())
{
void *addr = mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName);
-
+
// clear texture memory to avoid random screen visual fuzz from uninitialized texture data
memset( addr, 0x00, newsize );
-
+
// We could do this to force an update, but textureValid() will still be returning false until the first roundtrip to the plugin,
// so it may not be worthwhile.
// mDirtyRect.setOriginAndSize(0, 0, mRequestedMediaWidth, mRequestedMediaHeight);
}
}
-
+
// This is our local indicator that a change is in progress.
mTextureWidth = -1;
mTextureHeight = -1;
@@ -240,7 +239,7 @@ void LLPluginClassMedia::idle(void)
// This invalidates any existing dirty rect.
resetDirty();
-
+
// Send a size change message to the plugin
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change");
@@ -254,11 +253,11 @@ void LLPluginClassMedia::idle(void)
message.setValueReal("background_b", mBackgroundColor.mV[VZ]);
message.setValueReal("background_a", mBackgroundColor.mV[VW]);
mPlugin->sendMessage(message); // DO NOT just use sendMessage() here -- we want this to jump ahead of the queue.
-
+
LL_DEBUGS("Plugin") << "Sending size_change" << LL_ENDL;
}
}
-
+
if(mPlugin && mPlugin->isRunning())
{
// Send queued messages
@@ -324,11 +323,11 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaWidth = mDefaultMediaWidth;
mRequestedMediaHeight = mDefaultMediaHeight;
}
-
+
// Save these for size/interest calculations
mFullMediaWidth = mRequestedMediaWidth;
mFullMediaHeight = mRequestedMediaHeight;
-
+
if(mAllowDownsample)
{
switch(mPriority)
@@ -342,19 +341,19 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaHeight /= 2;
}
break;
-
+
default:
// Don't adjust texture size
break;
}
}
-
+
if(mAutoScaleMedia)
{
mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth);
mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
}
-
+
if(mRequestedMediaWidth > 2048)
mRequestedMediaWidth = 2048;
@@ -382,9 +381,9 @@ bool LLPluginClassMedia::textureValid(void)
mRequestedMediaWidth != mMediaWidth ||
mRequestedMediaHeight != mMediaHeight ||
getBitsData() == NULL
- )
+ )
return false;
-
+
return true;
}
@@ -408,8 +407,8 @@ void LLPluginClassMedia::resetDirty(void)
std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
{
std::string result;
-
-
+
+
if(modifiers & MASK_CONTROL)
{
result += "control|";
@@ -432,7 +431,7 @@ std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
{
result += "meta|";
}
-*/
+*/
return result;
}
@@ -540,11 +539,11 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int
// Don't spam unnecessary mouse move events.
return;
}
-
+
mLastMouseX = x;
mLastMouseY = y;
}
-
+
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "mouse_event");
std::string temp;
switch(type)
@@ -559,7 +558,7 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int
message.setValueS32("button", button);
message.setValueS32("x", x);
-
+
// Incoming coordinates are OpenGL-style ((0,0) = lower left), so flip them here if the plugin has requested it.
if(!mRequestedTextureCoordsOpenGL)
{
@@ -569,42 +568,42 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int
message.setValueS32("y", y);
message.setValue("modifiers", translateModifiers(modifiers));
-
+
sendMessage(message);
}
bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data)
{
bool result = true;
-
+
// FIXME:
// HACK: we don't have an easy way to tell if the plugin is going to handle a particular keycode.
// For now, return false for the ones the webkit plugin won't handle properly.
-
+
switch(key_code)
{
- case KEY_BACKSPACE:
- case KEY_TAB:
- case KEY_RETURN:
- case KEY_PAD_RETURN:
- case KEY_SHIFT:
- case KEY_CONTROL:
- case KEY_ALT:
- case KEY_CAPSLOCK:
- case KEY_ESCAPE:
- case KEY_PAGE_UP:
- case KEY_PAGE_DOWN:
- case KEY_END:
- case KEY_HOME:
- case KEY_LEFT:
- case KEY_UP:
- case KEY_RIGHT:
- case KEY_DOWN:
- case KEY_INSERT:
+ case KEY_BACKSPACE:
+ case KEY_TAB:
+ case KEY_RETURN:
+ case KEY_PAD_RETURN:
+ case KEY_SHIFT:
+ case KEY_CONTROL:
+ case KEY_ALT:
+ case KEY_CAPSLOCK:
+ case KEY_ESCAPE:
+ case KEY_PAGE_UP:
+ case KEY_PAGE_DOWN:
+ case KEY_END:
+ case KEY_HOME:
+ case KEY_LEFT:
+ case KEY_UP:
+ case KEY_RIGHT:
+ case KEY_DOWN:
+ case KEY_INSERT:
case KEY_DELETE:
- // These will be handled
+ // These will be handled
break;
-
+
default:
// regular ASCII characters will also be handled
if(key_code >= KEY_SPECIAL)
@@ -615,7 +614,7 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
break;
}
-#if LL_DARWIN
+#if LL_DARWIN
if(modifiers & MASK_ALT)
{
// Option-key modified characters should be handled by the unicode input path instead of this one.
@@ -634,15 +633,15 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
case KEY_EVENT_REPEAT: temp = "repeat"; break;
}
message.setValue("event", temp);
-
+
message.setValueS32("key", key_code);
message.setValue("modifiers", translateModifiers(modifiers));
message.setValueLLSD("native_key_data", native_key_data);
-
+
sendMessage(message);
}
-
+
return result;
}
@@ -653,10 +652,10 @@ void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers)
message.setValueS32("x", x);
message.setValueS32("y", y);
message.setValue("modifiers", translateModifiers(modifiers));
-
+
sendMessage(message);
}
-
+
bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD native_key_data)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "text_event");
@@ -664,18 +663,33 @@ bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD
message.setValue("text", text);
message.setValue("modifiers", translateModifiers(modifiers));
message.setValueLLSD("native_key_data", native_key_data);
-
+
sendMessage(message);
-
+
return true;
}
+void LLPluginClassMedia::setCookie(std::string uri, std::string name, std::string value, std::string domain, std::string path, bool httponly, bool secure)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_cookie");
+
+ message.setValue("uri", uri);
+ message.setValue("name", name);
+ message.setValue("value", value);
+ message.setValue("domain", domain);
+ message.setValue("path", path);
+ message.setValueBoolean("httponly", httponly);
+ message.setValueBoolean("secure", secure);
+
+ sendMessage(message);
+}
+
void LLPluginClassMedia::loadURI(const std::string &uri)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "load_uri");
message.setValue("uri", uri);
-
+
sendMessage(message);
}
@@ -692,7 +706,7 @@ const char* LLPluginClassMedia::priorityToString(EPriority priority)
case PRIORITY_NORMAL: result = "normal"; break;
case PRIORITY_HIGH: result = "high"; break;
}
-
+
return result;
}
@@ -703,44 +717,44 @@ void LLPluginClassMedia::setPriority(EPriority priority)
mPriority = priority;
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_priority");
-
+
std::string priority_string = priorityToString(priority);
switch(priority)
{
- case PRIORITY_UNLOADED:
+ case PRIORITY_UNLOADED:
mSleepTime = 1.0f;
break;
- case PRIORITY_STOPPED:
+ case PRIORITY_STOPPED:
mSleepTime = 1.0f;
break;
- case PRIORITY_HIDDEN:
+ case PRIORITY_HIDDEN:
mSleepTime = 1.0f;
break;
case PRIORITY_SLIDESHOW:
mSleepTime = 1.0f;
break;
- case PRIORITY_LOW:
+ case PRIORITY_LOW:
mSleepTime = 1.0f / 25.0f;
break;
- case PRIORITY_NORMAL:
+ case PRIORITY_NORMAL:
mSleepTime = 1.0f / 50.0f;
break;
- case PRIORITY_HIGH:
+ case PRIORITY_HIGH:
mSleepTime = 1.0f / 100.0f;
break;
}
-
+
message.setValue("priority", priority_string);
sendMessage(message);
-
+
if(mPlugin)
{
mPlugin->setSleepTime(mSleepTime);
}
-
+
LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL;
-
+
// This may affect the calculated size, so recalculate it here.
setSizeInternal();
}
@@ -761,12 +775,12 @@ void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
F64 LLPluginClassMedia::getCPUUsage()
{
F64 result = 0.0f;
-
+
if(mPlugin)
{
result = mPlugin->getCPUUsage();
}
-
+
return result;
}
@@ -814,10 +828,11 @@ void LLPluginClassMedia::paste()
sendMessage(message);
}
-void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path)
+void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
- message.setValue("path", user_data_path);
+ message.setValue("cache_path", user_data_path_cache);
+ message.setValue("cookies_path", user_data_path_cookies);
sendMessage(message);
}
@@ -830,14 +845,14 @@ void LLPluginClassMedia::setLanguageCode(const std::string &language_code)
void LLPluginClassMedia::setPluginsEnabled(const bool enabled)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "plugins_enabled");
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "plugins_enabled");
message.setValueBoolean("enable", enabled);
sendMessage(message);
}
void LLPluginClassMedia::setJavascriptEnabled(const bool enabled)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "javascript_enabled");
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "javascript_enabled");
message.setValueBoolean("enable", enabled);
sendMessage(message);
}
@@ -855,11 +870,11 @@ void LLPluginClassMedia::setTarget(const std::string &target)
mTarget = target;
}
-/* virtual */
+/* virtual */
void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
std::string message_class = message.getClass();
-
+
if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
{
std::string message_name = message.getName();
@@ -870,21 +885,21 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mRequestedTextureFormat = message.getValueU32("format");
mRequestedTextureType = message.getValueU32("type");
mRequestedTextureSwapBytes = message.getValueBoolean("swap_bytes");
- mRequestedTextureCoordsOpenGL = message.getValueBoolean("coords_opengl");
-
+ mRequestedTextureCoordsOpenGL = message.getValueBoolean("coords_opengl");
+
// These two are optional, and will default to 0 if they're not specified.
mDefaultMediaWidth = message.getValueS32("default_width");
mDefaultMediaHeight = message.getValueS32("default_height");
-
+
mAllowDownsample = message.getValueBoolean("allow_downsample");
mPadding = message.getValueS32("padding");
setSizeInternal();
-
+
mTextureParamsReceived = true;
}
else if(message_name == "updated")
- {
+ {
if(message.hasValue("left"))
{
LLRect newDirtyRect;
@@ -892,7 +907,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
newDirtyRect.mTop = message.getValueS32("top");
newDirtyRect.mRight = message.getValueS32("right");
newDirtyRect.mBottom = message.getValueS32("bottom");
-
+
// The plugin is likely to have top and bottom switched, due to vertical flip and OpenGL coordinate confusion.
// If they're backwards, swap them.
if(newDirtyRect.mTop < newDirtyRect.mBottom)
@@ -901,7 +916,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
newDirtyRect.mTop = newDirtyRect.mBottom;
newDirtyRect.mBottom = temp;
}
-
+
if(mDirtyRect.isEmpty())
{
mDirtyRect = newDirtyRect;
@@ -911,7 +926,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mDirtyRect.unionWith(newDirtyRect);
}
- LL_DEBUGS("Plugin") << "adjusted incoming rect is: ("
+ LL_DEBUGS("Plugin") << "adjusted incoming rect is: ("
<< newDirtyRect.mLeft << ", "
<< newDirtyRect.mTop << ", "
<< newDirtyRect.mRight << ", "
@@ -921,10 +936,10 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
<< mDirtyRect.mRight << ", "
<< mDirtyRect.mBottom << ")"
<< LL_ENDL;
-
+
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CONTENT_UPDATED);
- }
-
+ }
+
bool time_duration_updated = false;
int previous_percent = mProgressPercent;
@@ -944,7 +959,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
mCurrentRate = message.getValueReal("current_rate");
}
-
+
if(message.hasValue("loaded_duration"))
{
mLoadedDuration = message.getValueReal("loaded_duration");
@@ -955,7 +970,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
// If the message doesn't contain a loaded_duration param, assume it's equal to duration
mLoadedDuration = mDuration;
}
-
+
// Calculate a percentage based on the loaded duration and total duration.
if(mDuration != 0.0f) // Don't divide by zero.
{
@@ -966,7 +981,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED);
}
-
+
if(previous_percent != mProgressPercent)
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED);
@@ -975,9 +990,9 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
else if(message_name == "media_status")
{
std::string status = message.getValue("status");
-
+
LL_DEBUGS("Plugin") << "Status changed to: " << status << LL_ENDL;
-
+
if(status == "loading")
{
mStatus = LLPluginClassMediaOwner::MEDIA_LOADING;
@@ -1017,24 +1032,24 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
// TODO: check that name matches?
mNaturalMediaWidth = width;
mNaturalMediaHeight = height;
-
+
setSizeInternal();
}
else if(message_name == "size_change_response")
{
std::string name = message.getValue("name");
-
+
// TODO: check that name matches?
-
+
mTextureWidth = message.getValueS32("texture_width");
mTextureHeight = message.getValueS32("texture_height");
mMediaWidth = message.getValueS32("width");
mMediaHeight = message.getValueS32("height");
-
+
// This invalidates any existing dirty rect.
resetDirty();
-
- // TODO: should we verify that the plugin sent back the right values?
+
+ // TODO: should we verify that the plugin sent back the right values?
// Two size changes in a row may cause them to not match, due to queueing, etc.
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_SIZE_CHANGED);
@@ -1075,6 +1090,11 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mAuthRealm = message.getValue("realm");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST);
}
+ else if (message_name == "file_download")
+ {
+ mFileDownloadFilename = message.getValue("filename");
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_FILE_DOWNLOAD);
+ }
else if(message_name == "debug_message")
{
mDebugMessageText = message.getValue("message_text");
@@ -1101,7 +1121,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mNavigateResultString = message.getValue("result_string");
mHistoryBackAvailable = message.getValueBoolean("history_back_available");
mHistoryForwardAvailable = message.getValueBoolean("history_forward_available");
-
+
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE);
}
else if(message_name == "progress")
@@ -1156,7 +1176,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mGeometryY = message.getValueS32("y");
mGeometryWidth = message.getValueS32("width");
mGeometryHeight = message.getValueS32("height");
-
+
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE);
}
else if(message_name == "link_hovered")
@@ -1165,7 +1185,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mHoverLink = message.getValue("link");
mHoverText = message.getValue("title");
// message.getValue("text");
-
+
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LINK_HOVERED);
}
else
@@ -1181,7 +1201,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
// if(message_name == "message_name")
// {
// }
-// else
+// else
{
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
}
@@ -1189,13 +1209,13 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
}
-/* virtual */
+/* virtual */
void LLPluginClassMedia::pluginLaunchFailed()
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH);
}
-/* virtual */
+/* virtual */
void LLPluginClassMedia::pluginDied()
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED);
@@ -1235,7 +1255,7 @@ void LLPluginClassMedia::focus(bool focused)
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "focus");
message.setValueBoolean("focused", focused);
-
+
sendMessage(message);
}
@@ -1262,7 +1282,7 @@ void LLPluginClassMedia::clear_cookies()
void LLPluginClassMedia::set_cookies(const std::string &cookies)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies");
- message.setValue("cookies", cookies);
+ message.setValue("cookies", cookies);
sendMessage(message);
}
@@ -1295,7 +1315,7 @@ void LLPluginClassMedia::browse_reload(bool ignore_cache)
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_reload");
message.setValueBoolean("ignore_cache", ignore_cache);
-
+
sendMessage(message);
}
@@ -1415,7 +1435,7 @@ void LLPluginClassMedia::seek(float time)
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
message.setValueReal("time", time);
-
+
sendMessage(message);
}
@@ -1433,11 +1453,11 @@ void LLPluginClassMedia::setVolume(float volume)
if(volume != mRequestedVolume)
{
mRequestedVolume = volume;
-
+
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_volume");
message.setValueReal("volume", volume);
-
+
sendMessage(message);
}
}
@@ -1456,4 +1476,3 @@ void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history)
LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL;
}
-
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 96d577f43c..fc27b7bea3 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -133,6 +133,8 @@ public:
// Text may be unicode (utf8 encoded)
bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data);
+ void setCookie(std::string uri, std::string name, std::string value, std::string domain, std::string path, bool httponly, bool secure);
+
void loadURI(const std::string &uri);
// "Loading" means uninitialized or any state prior to fully running (processing commands)
@@ -191,7 +193,7 @@ public:
bool canPaste() const { return mCanPaste; };
// These can be called before init(), and they will be queued and sent before the media init message.
- void setUserDataPath(const std::string &user_data_path);
+ void setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies);
void setLanguageCode(const std::string &language_code);
void setPluginsEnabled(const bool enabled);
void setJavascriptEnabled(const bool enabled);
@@ -277,6 +279,10 @@ public:
std::string getHoverText() const { return mHoverText; };
std::string getHoverLink() const { return mHoverLink; };
+ // these are valid during MEDIA_EVENT_LINK_HOVERED
+ std::string getFileDownloadFilename() const { return mFileDownloadFilename; }
+
+
const std::string& getMediaName() const { return mMediaName; };
std::string getMediaDescription() const { return mMediaDescription; };
@@ -372,7 +378,7 @@ protected:
int mPadding;
- LLPluginProcessParent *mPlugin;
+ LLPluginProcessParent::ptr_t mPlugin;
LLRect mDirtyRect;
@@ -424,6 +430,7 @@ protected:
std::string mAuthRealm;
std::string mHoverText;
std::string mHoverLink;
+ std::string mFileDownloadFilename;
/////////////////////////////////////////
// media_time class
diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h
index 2f3edba7f3..391c23d883 100644
--- a/indra/llplugin/llpluginclassmediaowner.h
+++ b/indra/llplugin/llpluginclassmediaowner.h
@@ -64,6 +64,8 @@ public:
MEDIA_EVENT_AUTH_REQUEST, // The plugin wants to display an auth dialog
+ MEDIA_EVENT_FILE_DOWNLOAD, // the plugin wants to download a file
+
MEDIA_EVENT_DEBUG_MESSAGE, // plugin sending back debug information for host to process
MEDIA_EVENT_LINK_HOVERED // Got a "link hovered" event from the plugin
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index f8a282184e..be80d38305 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -33,6 +33,7 @@
#include "llpluginmessagepipe.h"
#include "llpluginmessageclasses.h"
+static const F32 GOODBYE_SECONDS = 20.0f;
static const F32 HEARTBEAT_SECONDS = 1.0f;
static const F32 PLUGIN_IDLE_SECONDS = 1.0f / 100.0f; // Each call to idle will give the plugin this much time.
@@ -194,33 +195,43 @@ void LLPluginProcessChild::idle(void)
}
}
// receivePluginMessage will transition to STATE_UNLOADING
- break;
+ break;
+
+ case STATE_SHUTDOWNREQ:
+ if (mInstance != NULL)
+ {
+ sendMessageToPlugin(LLPluginMessage("base", "cleanup"));
+ delete mInstance;
+ mInstance = NULL;
+ }
+ setState(STATE_UNLOADING);
+ mWaitGoodbye.setTimerExpirySec(GOODBYE_SECONDS);
+ break;
case STATE_UNLOADING:
- if(mInstance != NULL)
- {
- sendMessageToPlugin(LLPluginMessage("base", "cleanup"));
- delete mInstance;
- mInstance = NULL;
- }
- setState(STATE_UNLOADED);
- break;
+ // waiting for goodbye from plugin.
+ if (mWaitGoodbye.hasExpired())
+ {
+ LL_WARNS() << "Wait for goodbye expired. Advancing to UNLOADED" << LL_ENDL;
+ setState(STATE_UNLOADED);
+ }
+ break;
case STATE_UNLOADED:
killSockets();
setState(STATE_DONE);
- break;
+ break;
case STATE_ERROR:
// Close the socket to the launcher
killSockets();
// TODO: Where do we go from here? Just exit()?
setState(STATE_DONE);
- break;
+ break;
case STATE_DONE:
// just sit here.
- break;
+ break;
}
} while (idle_again);
@@ -350,6 +361,10 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
mPluginFile = parsed.getValue("file");
mPluginDir = parsed.getValue("dir");
}
+ else if (message_name == "shutdown_plugin")
+ {
+ setState(STATE_SHUTDOWNREQ);
+ }
else if(message_name == "shm_add")
{
std::string name = parsed.getValue("name");
@@ -495,6 +510,10 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
// Let the parent know it's loaded and initialized.
sendMessageToParent(new_message);
}
+ else if (message_name == "goodbye")
+ {
+ setState(STATE_UNLOADED);
+ }
else if(message_name == "shm_remove_response")
{
// Don't pass this message up to the parent
diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h
index 531422e792..b916cc9528 100644
--- a/indra/llplugin/llpluginprocesschild.h
+++ b/indra/llplugin/llpluginprocesschild.h
@@ -80,6 +80,7 @@ private:
STATE_PLUGIN_LOADED, // plugin library has been loaded
STATE_PLUGIN_INITIALIZING, // plugin is processing init message
STATE_RUNNING, // steady state (processing messages)
+ STATE_SHUTDOWNREQ, // Parent has requested a shutdown.
STATE_UNLOADING, // plugin has sent shutdown_response and needs to be unloaded
STATE_UNLOADED, // plugin has been unloaded
STATE_ERROR, // generic bailout state
@@ -101,12 +102,12 @@ private:
sharedMemoryRegionsType mSharedMemoryRegions;
LLTimer mHeartbeat;
- F64 mSleepTime;
- F64 mCPUElapsed;
+ F64 mSleepTime;
+ F64 mCPUElapsed;
bool mBlockingRequest;
bool mBlockingResponseReceived;
std::queue mMessageQueue;
-
+ LLTimer mWaitGoodbye;
void deliverQueuedMessages();
};
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index b5a2588e1e..0a8e58ac90 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -46,7 +46,7 @@ bool LLPluginProcessParent::sUseReadThread = false;
apr_pollset_t *LLPluginProcessParent::sPollSet = NULL;
bool LLPluginProcessParent::sPollsetNeedsRebuild = false;
LLMutex *LLPluginProcessParent::sInstancesMutex;
-std::list LLPluginProcessParent::sInstances;
+LLPluginProcessParent::mapInstances_t LLPluginProcessParent::sInstances;
LLThread *LLPluginProcessParent::sReadThread = NULL;
@@ -104,27 +104,12 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
// Don't start the timer here -- start it when we actually launch the plugin process.
mHeartbeat.stop();
- // Don't add to the global list until fully constructed.
- {
- LLMutexLock lock(sInstancesMutex);
- sInstances.push_back(this);
- }
}
LLPluginProcessParent::~LLPluginProcessParent()
{
LL_DEBUGS("Plugin") << "destructor" << LL_ENDL;
- // Remove from the global list before beginning destruction.
- {
- // Make sure to get the global mutex _first_ here, to avoid a possible deadlock against LLPluginProcessParent::poll()
- LLMutexLock lock(sInstancesMutex);
- {
- LLMutexLock lock2(&mIncomingQueueMutex);
- sInstances.remove(this);
- }
- }
-
// Destroy any remaining shared memory regions
sharedMemoryRegionsType::iterator iter;
while((iter = mSharedMemoryRegions.begin()) != mSharedMemoryRegions.end())
@@ -139,9 +124,109 @@ LLPluginProcessParent::~LLPluginProcessParent()
}
LLProcess::kill(mProcess);
- killSockets();
+ if (!LLApp::isQuitting())
+ { // If we are quitting, the network sockets will already have been destroyed.
+ killSockets();
+ }
}
+/*static*/
+LLPluginProcessParent::ptr_t LLPluginProcessParent::create(LLPluginProcessParentOwner *owner)
+{
+ ptr_t that(new LLPluginProcessParent(owner));
+
+ // Don't add to the global list until fully constructed.
+ {
+ LLMutexLock lock(sInstancesMutex);
+ sInstances.insert(mapInstances_t::value_type(that.get(), that));
+ }
+
+ return that;
+}
+
+/*static*/
+void LLPluginProcessParent::shutdown()
+{
+ LLMutexLock lock(sInstancesMutex);
+
+ mapInstances_t::iterator it;
+ for (it = sInstances.begin(); it != sInstances.end(); ++it)
+ {
+ (*it).second->setState(STATE_GOODBYE);
+ (*it).second->idle();
+ }
+ sInstances.clear();
+}
+
+
+void LLPluginProcessParent::requestShutdown()
+{
+ setState(STATE_GOODBYE);
+ mOwner = NULL;
+
+ if (LLApp::isQuitting())
+ { // if we're quitting, run the idle once more
+ idle();
+ removeFromProcessing();
+ return;
+ }
+
+ static uint32_t count = 0;
+ std::stringstream namestream;
+
+ namestream << "LLPluginProcessParentListener" << ++count;
+
+ //*HACK!*//
+ // After requestShutdown has been called our previous owner will no longer call
+ // our idle() method. Tie into the event loop here to do that until we are good
+ // and finished.
+ LL_DEBUGS("LLPluginProcessParent") << "listening on \"mainloop\"" << LL_ENDL;
+ mPolling = LLEventPumps::instance().obtain("mainloop")
+ .listen(namestream.str(), boost::bind(&LLPluginProcessParent::pollTick, this));
+
+}
+
+bool LLPluginProcessParent::pollTick()
+{
+ if (isDone())
+ {
+ ptr_t that;
+ {
+ // this grabs a copy of the smart pointer to ourselves to ensure that we do not
+ // get destroyed until after this method returns.
+ LLMutexLock lock(sInstancesMutex);
+ mapInstances_t::iterator it = sInstances.find(this);
+ if (it != sInstances.end())
+ that = (*it).second;
+ }
+
+ removeFromProcessing();
+ return true;
+ }
+
+ idle();
+ return false;
+}
+
+void LLPluginProcessParent::removeFromProcessing()
+{
+ // Remove from the global list before beginning destruction.
+ {
+ // Make sure to get the global mutex _first_ here, to avoid a possible deadlock against LLPluginProcessParent::poll()
+ LLMutexLock lock(sInstancesMutex);
+ {
+ LLMutexLock lock2(&mIncomingQueueMutex);
+ sInstances.erase(this);
+ }
+ }
+}
+
+bool LLPluginProcessParent::wantsPolling() const
+{
+ return (mPollFD.client_data && (mState != STATE_DONE));
+}
+
+
void LLPluginProcessParent::killSockets(void)
{
{
@@ -371,48 +456,48 @@ void LLPluginProcessParent::idle(void)
break;
case STATE_LISTENING:
- {
- // Launch the plugin process.
+ {
+ // Launch the plugin process.
- // Only argument to the launcher is the port number we're listening on
- mProcessParams.args.add(stringize(mBoundPort));
- if (! (mProcess = LLProcess::create(mProcessParams)))
- {
- errorState();
- }
- else
- {
- if(mDebug)
- {
- #if LL_DARWIN
- // If we're set to debug, start up a gdb instance in a new terminal window and have it attach to the plugin process and continue.
+ // Only argument to the launcher is the port number we're listening on
+ mProcessParams.args.add(stringize(mBoundPort));
+ if (! (mProcess = LLProcess::create(mProcessParams)))
+ {
+ errorState();
+ }
+ else
+ {
+ if(mDebug)
+ {
+#if LL_DARWIN
+ // If we're set to debug, start up a gdb instance in a new terminal window and have it attach to the plugin process and continue.
- // The command we're constructing would look like this on the command line:
- // osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell'
+ // The command we're constructing would look like this on the command line:
+ // osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell'
- LLProcess::Params params;
- params.executable = "/usr/bin/osascript";
- params.args.add("-e");
- params.args.add("tell application \"Terminal\"");
- params.args.add("-e");
- params.args.add(STRINGIZE("set win to do script \"gdb -pid "
- << mProcess->getProcessID() << "\""));
- params.args.add("-e");
- params.args.add("do script \"continue\" in win");
- params.args.add("-e");
- params.args.add("end tell");
- mDebugger = LLProcess::create(params);
+ LLProcess::Params params;
+ params.executable = "/usr/bin/osascript";
+ params.args.add("-e");
+ params.args.add("tell application \"Terminal\"");
+ params.args.add("-e");
+ params.args.add(STRINGIZE("set win to do script \"gdb -pid "
+ << mProcess->getProcessID() << "\""));
+ params.args.add("-e");
+ params.args.add("do script \"continue\" in win");
+ params.args.add("-e");
+ params.args.add("end tell");
+ mDebugger = LLProcess::create(params);
- #endif
- }
+#endif
+ }
- // This will allow us to time out if the process never starts.
- mHeartbeat.start();
- mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout);
- setState(STATE_LAUNCHED);
- }
- }
- break;
+ // This will allow us to time out if the process never starts.
+ mHeartbeat.start();
+ mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout);
+ setState(STATE_LAUNCHED);
+ }
+ }
+ break;
case STATE_LAUNCHED:
// waiting for the plugin to connect
@@ -430,7 +515,7 @@ void LLPluginProcessParent::idle(void)
setState(STATE_CONNECTED);
}
}
- break;
+ break;
case STATE_CONNECTED:
// waiting for hello message from the plugin
@@ -439,7 +524,7 @@ void LLPluginProcessParent::idle(void)
{
errorState();
}
- break;
+ break;
case STATE_HELLO:
LL_DEBUGS("Plugin") << "received hello message" << LL_ENDL;
@@ -453,7 +538,7 @@ void LLPluginProcessParent::idle(void)
}
setState(STATE_LOADING);
- break;
+ break;
case STATE_LOADING:
// The load_plugin_response message will kick us from here into STATE_RUNNING
@@ -461,15 +546,23 @@ void LLPluginProcessParent::idle(void)
{
errorState();
}
- break;
+ break;
case STATE_RUNNING:
if(pluginLockedUpOrQuit())
{
errorState();
}
- break;
+ break;
+ case STATE_GOODBYE:
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shutdown_plugin");
+ sendMessage(message);
+ }
+ setState(STATE_EXITING);
+ break;
+
case STATE_EXITING:
if (! LLProcess::isRunning(mProcess))
{
@@ -480,7 +573,7 @@ void LLPluginProcessParent::idle(void)
LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << LL_ENDL;
errorState();
}
- break;
+ break;
case STATE_LAUNCH_FAILURE:
if(mOwner != NULL)
@@ -488,7 +581,7 @@ void LLPluginProcessParent::idle(void)
mOwner->pluginLaunchFailed();
}
setState(STATE_CLEANUP);
- break;
+ break;
case STATE_ERROR:
if(mOwner != NULL)
@@ -496,19 +589,18 @@ void LLPluginProcessParent::idle(void)
mOwner->pluginDied();
}
setState(STATE_CLEANUP);
- break;
+ break;
case STATE_CLEANUP:
LLProcess::kill(mProcess);
killSockets();
setState(STATE_DONE);
- break;
-
+ dirtyPollSet();
+ break;
case STATE_DONE:
// just sit here.
- break;
-
+ break;
}
} while (idle_again);
@@ -651,14 +743,14 @@ void LLPluginProcessParent::updatePollset()
sPollSet = NULL;
}
- std::list::iterator iter;
+ mapInstances_t::iterator iter;
int count = 0;
// Count the number of instances that want to be in the pollset
for(iter = sInstances.begin(); iter != sInstances.end(); iter++)
{
- (*iter)->mPolledInput = false;
- if((*iter)->mPollFD.client_data)
+ (*iter).second->mPolledInput = false;
+ if ((*iter).second->wantsPolling())
{
// This instance has a socket that needs to be polled.
++count;
@@ -686,12 +778,12 @@ void LLPluginProcessParent::updatePollset()
// Pollset was created, add all instances to it.
for(iter = sInstances.begin(); iter != sInstances.end(); iter++)
{
- if((*iter)->mPollFD.client_data)
+ if ((*iter).second->wantsPolling())
{
- status = apr_pollset_add(sPollSet, &((*iter)->mPollFD));
+ status = apr_pollset_add(sPollSet, &((*iter).second->mPollFD));
if(status == APR_SUCCESS)
{
- (*iter)->mPolledInput = true;
+ (*iter).second->mPolledInput = true;
}
else
{
@@ -756,45 +848,27 @@ void LLPluginProcessParent::poll(F64 timeout)
if(status == APR_SUCCESS)
{
// One or more of the descriptors signalled. Call them.
- for(int i = 0; i < count; i++)
- {
- LLPluginProcessParent *self = (LLPluginProcessParent *)(descriptors[i].client_data);
- // NOTE: the descriptor returned here is actually a COPY of the original (even though we create the pollset with APR_POLLSET_NOCOPY).
- // This means that even if the parent has set its mPollFD.client_data to NULL, the old pointer may still there in this descriptor.
- // It's even possible that the old pointer no longer points to a valid LLPluginProcessParent.
- // This means that we can't safely dereference the 'self' pointer here without some extra steps...
- if(self)
- {
- // Make sure this pointer is still in the instances list
- bool valid = false;
- {
- LLMutexLock lock(sInstancesMutex);
- for(std::list::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
- {
- if(*iter == self)
- {
- // Lock the instance's mutex before unlocking the global mutex.
- // This avoids a possible race condition where the instance gets deleted between this check and the servicePoll() call.
- self->mIncomingQueueMutex.lock();
- valid = true;
- break;
- }
- }
- }
-
- if(valid)
- {
- // The instance is still valid.
- // Pull incoming messages off the socket
- self->servicePoll();
- self->mIncomingQueueMutex.unlock();
- }
- else
- {
- LL_DEBUGS("PluginPoll") << "detected deleted instance " << self << LL_ENDL;
- }
+ for (int i = 0; i < count; i++)
+ {
+ void *thatId = descriptors[i].client_data;
+
+ ptr_t that;
+ mapInstances_t::iterator it;
+
+ {
+ LLMutexLock lock(sInstancesMutex);
+ it = sInstances.find(thatId);
+ if (it != sInstances.end())
+ that = (*it).second;
+ }
+
+ if (that)
+ {
+ that->mIncomingQueueMutex.lock();
+ that->servicePoll();
+ that->mIncomingQueueMutex.unlock();
+ }
- }
}
}
else if(APR_STATUS_IS_TIMEUP(status))
@@ -812,6 +886,16 @@ void LLPluginProcessParent::poll(F64 timeout)
LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << LL_ENDL;
}
}
+
+ // Remove instances in the done state from the sInstances map.
+ mapInstances_t::iterator itClean = sInstances.begin();
+ while (itClean != sInstances.end())
+ {
+ if ((*itClean).second->isDone())
+ sInstances.erase(itClean++);
+ else
+ ++itClean;
+ }
}
void LLPluginProcessParent::servicePoll()
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 24be7eb148..df1630255c 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -30,6 +30,7 @@
#define LL_LLPLUGINPROCESSPARENT_H
#include
+#include
#include "llapr.h"
#include "llprocess.h"
@@ -40,8 +41,9 @@
#include "lliosocket.h"
#include "llthread.h"
#include "llsd.h"
+#include "llevents.h"
-class LLPluginProcessParentOwner
+class LLPluginProcessParentOwner : public boost::enable_shared_from_this < LLPluginProcessParentOwner >
{
public:
virtual ~LLPluginProcessParentOwner();
@@ -55,8 +57,11 @@ public:
class LLPluginProcessParent : public LLPluginMessagePipeOwner
{
LOG_CLASS(LLPluginProcessParent);
+
+ LLPluginProcessParent(LLPluginProcessParentOwner *owner);
public:
- LLPluginProcessParent(LLPluginProcessParentOwner *owner);
+ typedef boost::shared_ptr ptr_t;
+
~LLPluginProcessParent();
void init(const std::string &launcher_filename,
@@ -89,7 +94,10 @@ public:
void sendMessage(const LLPluginMessage &message);
void receiveMessage(const LLPluginMessage &message);
-
+
+ static ptr_t create(LLPluginProcessParentOwner *owner);
+ void requestShutdown();
+
// Inherited from LLPluginMessagePipeOwner
/*virtual*/ void receiveMessageRaw(const std::string &message);
/*virtual*/ void receiveMessageEarly(const LLPluginMessage &message);
@@ -121,7 +129,10 @@ public:
static bool canPollThreadRun() { return (sPollSet || sPollsetNeedsRebuild || sUseReadThread); };
static void setUseReadThread(bool use_read_thread);
static bool getUseReadThread() { return sUseReadThread; };
+
+ static void shutdown();
private:
+ typedef std::map mapInstances_t;
enum EState
{
@@ -133,6 +144,7 @@ private:
STATE_HELLO, // first message from the plugin process has been received
STATE_LOADING, // process has been asked to load the plugin
STATE_RUNNING, //
+ STATE_GOODBYE,
STATE_LAUNCH_FAILURE, // Failure before plugin loaded
STATE_ERROR, // generic bailout state
STATE_CLEANUP, // clean everything up
@@ -143,6 +155,9 @@ private:
EState mState;
void setState(EState state);
+ bool wantsPolling() const;
+ void removeFromProcessing();
+
bool pluginLockedUp();
bool pluginLockedUpOrQuit();
@@ -185,12 +200,15 @@ private:
static apr_pollset_t *sPollSet;
static bool sPollsetNeedsRebuild;
static LLMutex *sInstancesMutex;
- static std::list sInstances;
+ static mapInstances_t sInstances;
static void dirtyPollSet();
static void updatePollset();
void servicePoll();
static LLThread *sReadThread;
-
+
+ LLTempBoundListener mPolling;
+ bool pollTick();
+
LLMutex mIncomingQueueMutex;
std::queue mIncomingQueue;
};
diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
index 6c9ba0ae52..684bcf1207 100644
--- a/indra/llplugin/slplugin/slplugin.cpp
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -310,4 +310,3 @@ int main(int argc, char **argv)
return 0;
}
-
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index c1b74b1fd7..afc88fc861 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -821,7 +821,8 @@ LLDAELoader::LLDAELoader(
opaque_userdata,
jointMap,
jointsFromNodes),
-mGeneratedModelLimit(modelLimit)
+mGeneratedModelLimit(modelLimit),
+mForceIdNaming(false)
{
}
@@ -944,6 +945,32 @@ bool LLDAELoader::OpenFile(const std::string& filename)
mTransform.condition();
+ mForceIdNaming = false;
+ std::vector checkNames;
+ for (daeInt idx = 0; idx < count; ++idx)
+ {
+ domMesh* mesh = NULL;
+ db->getElement((daeElement**)&mesh, idx, NULL, COLLADA_TYPE_MESH);
+
+ if (mesh)
+ {
+ std::string name = getLodlessLabel(mesh, false);
+
+ std::vector::iterator it;
+ it = std::find(checkNames.begin(), checkNames.end(), name);
+ if (it != checkNames.end())
+ {
+ LL_WARNS() << "document has duplicate names, using IDs instead" << LL_ENDL;
+ mForceIdNaming = true;
+ break;
+ }
+ else
+ {
+ checkNames.push_back(name);
+ }
+ }
+ }
+
U32 submodel_limit = count > 0 ? mGeneratedModelLimit/count : 0;
for (daeInt idx = 0; idx < count; ++idx)
{ //build map of domEntities to LLModel
@@ -1578,9 +1605,9 @@ void LLDAELoader::processChildJoints( domNode* pParentNode )
//-----------------------------------------------------------------------------
bool LLDAELoader::isNodeAJoint( domNode* pNode )
{
- if ( !pNode )
+ if ( !pNode || !pNode->getName() )
{
- LL_INFOS()<<"Created node is NULL"<mLabel.empty())
{
- label = getLodlessLabel(instance_geo);
+ label = getLodlessLabel(instance_geo, mForceIdNaming);
llassert(!label.empty());
@@ -2159,12 +2186,17 @@ LLImportMaterial LLDAELoader::profileToMaterial(domProfile_COMMON* material, DAE
return mat;
}
-// try to get a decent label for this element
std::string LLDAELoader::getElementLabel(daeElement *element)
+{
+ return getElementLabel(element, mForceIdNaming);
+}
+
+// try to get a decent label for this element
+std::string LLDAELoader::getElementLabel(daeElement *element, bool forceIdNaming)
{
// if we have a name attribute, use it
std::string name = element->getAttribute("name");
- if (name.length())
+ if (name.length() && !forceIdNaming)
{
return name;
}
@@ -2187,7 +2219,7 @@ std::string LLDAELoader::getElementLabel(daeElement *element)
// if parent has a name or ID, use it
std::string name = parent->getAttribute("name");
- if (!name.length())
+ if (!name.length() || forceIdNaming)
{
name = std::string(parent->getID());
}
@@ -2230,9 +2262,9 @@ size_t LLDAELoader::getSuffixPosition(std::string label)
}
// static
-std::string LLDAELoader::getLodlessLabel(daeElement *element)
+std::string LLDAELoader::getLodlessLabel(daeElement *element, bool forceIdNaming)
{
- std::string label = getElementLabel(element);
+ std::string label = getElementLabel(element, forceIdNaming);
size_t ext_pos = getSuffixPosition(label);
if (ext_pos != -1)
{
@@ -2303,8 +2335,13 @@ bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh)
return (status == LLModel::NO_ERRORS);
}
-//static
LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh)
+{
+ return loadModelFromDomMesh(mesh, mForceIdNaming);
+}
+
+//static
+LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh, bool forceIdNaming)
{
LLVolumeParams volume_params;
volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
@@ -2312,7 +2349,7 @@ LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh)
createVolumeFacesFromDomMesh(ret, mesh);
if (ret->mLabel.empty())
{
- ret->mLabel = getElementLabel(mesh);
+ ret->mLabel = getElementLabel(mesh, forceIdNaming);
}
return ret;
}
@@ -2330,7 +2367,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo
LLModel* ret = new LLModel(volume_params, 0.f);
- std::string model_name = getLodlessLabel(mesh);
+ std::string model_name = getLodlessLabel(mesh, mForceIdNaming);
ret->mLabel = model_name + lod_suffix[mLod];
llassert(!ret->mLabel.empty());
diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h
index 7d91a6063b..3ababd3156 100644
--- a/indra/llprimitive/lldaeloader.h
+++ b/indra/llprimitive/lldaeloader.h
@@ -89,19 +89,22 @@ protected:
static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh);
static bool createVolumeFacesFromDomMesh(LLModel* model, domMesh *mesh);
- static LLModel* loadModelFromDomMesh(domMesh* mesh);
+ static LLModel* loadModelFromDomMesh(domMesh* mesh, bool forceIdNaming);
+ LLModel* loadModelFromDomMesh(domMesh* mesh);
// Loads a mesh breaking it into one or more models as necessary
// to get around volume face limitations while retaining >8 materials
//
bool loadModelsFromDomMesh(domMesh* mesh, std::vector& models_out, U32 submodel_limit);
- static std::string getElementLabel(daeElement *element);
+ static std::string getElementLabel(daeElement *element, bool forceIdNaming);
+ std::string getElementLabel(daeElement *element);
static size_t getSuffixPosition(std::string label);
- static std::string getLodlessLabel(daeElement *element);
+ static std::string getLodlessLabel(daeElement *element, bool forceIdNaming = false);
private:
U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels
+ bool mForceIdNaming;
};
#endif // LL_LLDAELLOADER_H
diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp
index 81d92d151b..f86eceb98d 100644
--- a/indra/llprimitive/llmodelloader.cpp
+++ b/indra/llprimitive/llmodelloader.cpp
@@ -116,6 +116,7 @@ LLModelLoader::LLModelLoader(
, LLThread("Model Loader")
, mFilename(filename)
, mLod(lod)
+, mTrySLM(false)
, mFirstTransform(TRUE)
, mNumOfFetchingTextures(0)
, mLoadCallback(load_cb)
@@ -123,6 +124,9 @@ LLModelLoader::LLModelLoader(
, mTextureLoadFunc(texture_load_func)
, mStateCallback(state_cb)
, mOpaqueData(opaque_userdata)
+, mRigParityWithScene(false)
+, mRigValidJointUpload(false)
+, mLegacyRigValid(false)
, mNoNormalize(false)
, mNoOptimize(false)
, mCacheOnlyHitIfRigged(false)
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 9eff74f1e8..186716609c 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -317,9 +317,9 @@ S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID
return mTextureList.setMaterialID(index, pMaterialID);
}
-S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer)
+S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
{
- return mTextureList.setMaterialParams(index, pMaterialParams, isInitFromServer);
+ return mTextureList.setMaterialParams(index, pMaterialParams);
}
LLMaterialPtr LLPrimitive::getTEMaterialParams(const U8 index)
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 54870fbb10..19d9d52817 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -384,7 +384,7 @@ public:
virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
virtual S32 setTEGlow(const U8 te, const F32 glow);
virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
- virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer);
+ virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
virtual void setTESelected(const U8 te, bool sel);
diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp
index 6aae2f97c6..f4f08248b8 100644
--- a/indra/llprimitive/llprimtexturelist.cpp
+++ b/indra/llprimitive/llprimtexturelist.cpp
@@ -368,18 +368,11 @@ S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMateri
return TEM_CHANGE_NONE;
}
-S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer)
+S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
{
if (index < mEntryList.size())
{
- if (!isInitFromServer && mEntryList[index]->isMatParamsInitFromServer())
- {
- return TEM_CHANGE_NONE;
- }
- else
- {
- return mEntryList[index]->setMaterialParams(pMaterialParams);
- }
+ return mEntryList[index]->setMaterialParams(pMaterialParams);
}
return TEM_CHANGE_NONE;
}
diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h
index 63e6372405..49c636e40f 100644
--- a/indra/llprimitive/llprimtexturelist.h
+++ b/indra/llprimitive/llprimtexturelist.h
@@ -105,7 +105,7 @@ public:
S32 setMediaFlags(const U8 index, const U8 media_flags);
S32 setGlow(const U8 index, const F32 glow);
S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID);
- S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer);
+ S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
LLMaterialPtr getMaterialParams(const U8 index);
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 6020031099..284dfc15f4 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -63,7 +63,6 @@ LLTextureEntry::LLTextureEntry()
: mMediaEntry(NULL)
, mSelected(false)
, mMaterialUpdatePending(false)
- , mInitMatParamsFromServer(false)
{
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
@@ -72,7 +71,6 @@ LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
: mMediaEntry(NULL)
, mSelected(false)
, mMaterialUpdatePending(false)
- , mInitMatParamsFromServer(false)
{
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
@@ -81,7 +79,6 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
: mMediaEntry(NULL)
, mSelected(false)
, mMaterialUpdatePending(false)
- , mInitMatParamsFromServer(false)
{
mID = rhs.mID;
mScaleS = rhs.mScaleS;
@@ -565,7 +562,6 @@ S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)
mMaterialUpdatePending = true;
}
mMaterial = pMaterialParams;
- this->mInitMatParamsFromServer = TRUE;
return TEM_CHANGE_TEXTURE;
}
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index 81e2e8a5a2..a40c3988f2 100644
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -160,8 +160,6 @@ public:
const LLMaterialID& getMaterialID() const { return mMaterialID; };
const LLMaterialPtr getMaterialParams() const { return mMaterial; };
- bool isMatParamsInitFromServer() const { return mInitMatParamsFromServer; };
-
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
// to NOT return NULL.
@@ -219,8 +217,6 @@ protected:
bool mMaterialUpdatePending;
LLMaterialID mMaterialID;
LLMaterialPtr mMaterial;
- bool mInitMatParamsFromServer; // Flag to identification when material paramas initialized from
-
// Note the media data is not sent via the same message structure as the rest of the TE
LLMediaEntry* mMediaEntry; // The media data for the face
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index f9f7d07c89..0f260674ed 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -702,77 +702,102 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
BOOL LLGLSLShader::mapUniforms(const vector * uniforms)
{
- BOOL res = TRUE;
-
- mTotalUniformSize = 0;
- mActiveTextureChannels = 0;
- mUniform.clear();
- mUniformMap.clear();
- mUniformNameMap.clear();
- mTexture.clear();
- mValue.clear();
- //initialize arrays
- U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size();
- mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
- mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
-
- bind();
+ BOOL res = TRUE;
- //get the number of active uniforms
- GLint activeCount;
- glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
+ mTotalUniformSize = 0;
+ mActiveTextureChannels = 0;
+ mUniform.clear();
+ mUniformMap.clear();
+ mUniformNameMap.clear();
+ mTexture.clear();
+ mValue.clear();
+ //initialize arrays
+ U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size();
+ mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
+ mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
+
+ bind();
+
+ //get the number of active uniforms
+ GLint activeCount;
+ glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
//........................................................................................................................................
//........................................................................................
/*
EXPLANATION:
- This is part of code is temporary because as the final result the mapUniform() should be rewrited.
- But it's a huge a volume of work which is need to be a more carefully performed for avoid possible
+ This is part of code is temporary because as the final result the mapUniform() should be rewrited.
+ But it's a huge a volume of work which is need to be a more carefully performed for avoid possible
regression's (i.e. it should be formalized a separate ticket in JIRA).
RESON:
- The reason of this code is that SL engine is very sensitive to fact that "diffuseMap" should be appear
- first as uniform parameter which is should get 0-"texture channel" index (see mapUniformTextureChannel() and mActiveTextureChannels)
+ The reason of this code is that SL engine is very sensitive to fact that "diffuseMap" should be appear
+ first as uniform parameter which is should get 0-"texture channel" index (see mapUniformTextureChannel() and mActiveTextureChannels)
it influence to which is texture matrix will be updated during rendering.
But, order of indexe's of uniform variables is not defined and GLSL compiler can change it as want
, even if the "diffuseMap" will be appear and use first in shader code.
As example where this situation appear see: "Deferred Material Shader 28/29/30/31"
- And tickets: MAINT-4165, MAINT-4839
+ And tickets: MAINT-4165, MAINT-4839, MAINT-3568
*/
-
+
S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap");
S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
+ S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
std::set skip_index;
- if(diffuseMap != -1 && bumpMap != -1)
+ if (-1 != diffuseMap && (-1 != bumpMap || -1 != environmentMap))
{
GLenum type;
GLsizei length;
GLint size = -1;
- char name[1024];
+ char name[1024];
+
+ diffuseMap = bumpMap = environmentMap = -1;
- //diffuse map
for (S32 i = 0; i < activeCount; i++)
{
- name[0] = 0;
-
+ name[0] = '\0';
+
glGetActiveUniformARB(mProgramObject, i, 1024, &length, &size, &type, (GLcharARB *)name);
- if(std::string(name) == "diffuseMap") {
+ if (-1 == diffuseMap && std::string(name) == "diffuseMap")
+ {
diffuseMap = i;
+ continue;
}
- if(std::string(name) == "bumpMap") {
+ if (-1 == bumpMap && std::string(name) == "bumpMap")
+ {
bumpMap = i;
+ continue;
+ }
+
+ if (-1 == environmentMap && std::string(name) == "environmentMap")
+ {
+ environmentMap = i;
+ continue;
}
}
-
- if(bumpMap < diffuseMap)
+
+ bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;
+ bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap;
+
+ if (bumpLessDiff && envLessDiff)
+ {
+ mapUniform(diffuseMap, uniforms);
+ mapUniform(bumpMap, uniforms);
+ mapUniform(environmentMap, uniforms);
+
+ skip_index.insert(diffuseMap);
+ skip_index.insert(bumpMap);
+ skip_index.insert(environmentMap);
+ }
+ else if (bumpLessDiff)
{
mapUniform(diffuseMap, uniforms);
mapUniform(bumpMap, uniforms);
@@ -780,26 +805,35 @@ BOOL LLGLSLShader::mapUniforms(const vector * uniforms)
skip_index.insert(diffuseMap);
skip_index.insert(bumpMap);
}
+ else if (envLessDiff)
+ {
+ mapUniform(diffuseMap, uniforms);
+ mapUniform(environmentMap, uniforms);
+
+ skip_index.insert(diffuseMap);
+ skip_index.insert(environmentMap);
+ }
}
//........................................................................................
-
- for (S32 i = 0; i < activeCount; i++)
- {
+
+ for (S32 i = 0; i < activeCount; i++)
+ {
//........................................................................................
- if(skip_index.end() != skip_index.find(i)) continue;
+ if (skip_index.end() != skip_index.find(i)) continue;
//........................................................................................
-
- mapUniform(i, uniforms);
- }
+
+ mapUniform(i, uniforms);
+ }
//........................................................................................................................................
- unbind();
+ unbind();
- LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
- return res;
+ LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
+ return res;
}
+
BOOL LLGLSLShader::link(BOOL suppress_errors)
{
BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 547f0bd398..1a51b96fdf 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -46,12 +46,30 @@ BOOL LLFocusableElement::handleKey(KEY key, MASK mask, BOOL called_from_parent)
return FALSE;
}
+// virtual
+BOOL LLFocusableElement::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
+{
+ return FALSE;
+}
+
// virtual
BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
{
return FALSE;
}
+// virtual
+bool LLFocusableElement::wantsKeyUpKeyDown() const
+{
+ return false;
+}
+
+//virtual
+bool LLFocusableElement::wantsReturnKey() const
+{
+ return false;
+}
+
// virtual
LLFocusableElement::~LLFocusableElement()
{
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index afd2a8ce06..0e3d7d8e59 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -57,8 +57,17 @@ public:
// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+ virtual BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent);
virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
+ /**
+ * If true this LLFocusableElement wants to receive KEYUP and KEYDOWN messages
+ * even for normal character strokes.
+ * Default implementation returns false.
+ */
+ virtual bool wantsKeyUpKeyDown() const;
+ virtual bool wantsReturnKey() const;
+
virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
protected:
virtual void onFocusReceived();
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index 6750ee482a..fc4a007d9e 100644
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -296,7 +296,7 @@ void LLKeywords::processTokensGroup(const LLSD& tokens, const std::string& group
}
color_group = getColorGroup(group);
- LL_INFOS("SyntaxLSL") << "Group: '" << group << "', using color: '" << color_group << "'" << LL_ENDL;
+ LL_DEBUGS("SyntaxLSL") << "Group: '" << group << "', using color: '" << color_group << "'" << LL_ENDL;
if (tokens.isMap())
{
@@ -331,7 +331,14 @@ void LLKeywords::processTokensGroup(const LLSD& tokens, const std::string& group
switch (token_type)
{
case LLKeywordToken::TT_CONSTANT:
- color_group = getColorGroup(group + "-" + getAttribute("type"));
+ if (getAttribute("type").length() > 0)
+ {
+ color_group = getColorGroup(group + "-" + getAttribute("type"));
+ }
+ else
+ {
+ color_group = getColorGroup(group);
+ }
tooltip = "Type: " + getAttribute("type") + ", Value: " + getAttribute("value");
break;
case LLKeywordToken::TT_EVENT:
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 7e235997d8..77e7d375c8 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1715,6 +1715,30 @@ void LLNotifications::cancelByName(const std::string& name)
}
}
+void LLNotifications::cancelByOwner(const LLUUID ownerId)
+{
+ std::vector notifs_to_cancel;
+ for (LLNotificationSet::iterator it = mItems.begin(), end_it = mItems.end();
+ it != end_it;
+ ++it)
+ {
+ LLNotificationPtr pNotif = *it;
+ if (pNotif && pNotif->getPayload().get("owner_id").asUUID() == ownerId)
+ {
+ notifs_to_cancel.push_back(pNotif);
+ }
+ }
+
+ for (std::vector::iterator it = notifs_to_cancel.begin(), end_it = notifs_to_cancel.end();
+ it != end_it;
+ ++it)
+ {
+ LLNotificationPtr pNotif = *it;
+ pNotif->cancel();
+ updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
+ }
+}
+
void LLNotifications::update(const LLNotificationPtr pNotif)
{
LLNotificationSet::iterator it=mItems.find(pNotif);
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 0d673d178b..010e6caba2 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -924,6 +924,7 @@ public:
void add(const LLNotificationPtr pNotif);
void cancel(LLNotificationPtr pNotif);
void cancelByName(const std::string& name);
+ void cancelByOwner(const LLUUID ownerId);
void update(const LLNotificationPtr pNotif);
LLNotificationPtr find(LLUUID uuid);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 7f6cc22e90..576fff5fb2 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -449,7 +449,10 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
//
LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
{
- mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(:\\d{1,5})?\\/\\S*",
+ mPattern = boost::regex("((http://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com)"
+ "|"
+ "(https://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(:\\d{1,5})?))"
+ "\\/\\S*",
boost::regex::perl|boost::regex::icase);
mIcon = "Hand";
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 69eefa736c..23c6d5a954 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -41,7 +41,8 @@ LLUrlRegistry::LLUrlRegistry()
mUrlEntry.reserve(20);
// Urls are matched in the order that they were registered
- registerUrl(new LLUrlEntryNoLink());
+ mUrlEntryNoLink = new LLUrlEntryNoLink();
+ registerUrl(mUrlEntryNoLink);
mUrlEntryIcon = new LLUrlEntryIcon();
registerUrl(mUrlEntryIcon);
mLLUrlEntryInvalidSLURL = new LLUrlEntryInvalidSLURL();
@@ -214,7 +215,6 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
// did we find a match? if so, return its details in the match object
if (match_entry)
{
-
// Skip if link is an email with an empty username (starting with @). See MAINT-5371.
if (match_start > 0 && text.substr(match_start - 1, 1) == "@")
return false;
@@ -223,7 +223,8 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
std::string url = text.substr(match_start, match_end - match_start + 1);
LLUrlEntryBase *stripped_entry = NULL;
- if(LLStringUtil::containsNonprintable(url))
+ if((match_entry != mUrlEntryNoLink) && (match_entry != mUrlEntryHTTPLabel) && (match_entry !=mUrlEntrySLLabel)
+ && LLStringUtil::containsNonprintable(url))
{
LLStringUtil::stripNonprintable(url);
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index 5ce4048d5d..24c3a2b513 100644
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
@@ -98,6 +98,7 @@ private:
LLUrlEntryBase* mLLUrlEntryInvalidSLURL;
LLUrlEntryBase* mUrlEntryHTTPLabel;
LLUrlEntryBase* mUrlEntrySLLabel;
+ LLUrlEntryBase* mUrlEntryNoLink;
};
#endif
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index a8beb9cfc9..8f7cac1f61 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -866,6 +866,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)
return handled;
}
+
BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
{
BOOL handled = FALSE;
@@ -898,6 +899,38 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
return handled;
}
+BOOL LLView::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
+{
+ BOOL handled = FALSE;
+
+ if (getVisible() && getEnabled())
+ {
+ if (called_from_parent)
+ {
+ // Downward traversal
+ handled = childrenHandleKeyUp(key, mask) != NULL;
+ }
+
+ if (!handled)
+ {
+ // For event logging we don't care which widget handles it
+ // So we capture the key at the end of this function once we know if it was handled
+ handled = handleKeyUpHere(key, mask);
+ if (handled)
+ {
+ LL_DEBUGS() << "Key handled by " << getName() << LL_ENDL;
+ }
+ }
+ }
+
+ if (!handled && !called_from_parent && mParentView)
+ {
+ // Upward traversal
+ handled = mParentView->handleKeyUp(key, mask, FALSE);
+ }
+ return handled;
+}
+
// Called from handleKey()
// Handles key in this object. Checking parents and children happens in handleKey()
BOOL LLView::handleKeyHere(KEY key, MASK mask)
@@ -905,6 +938,13 @@ BOOL LLView::handleKeyHere(KEY key, MASK mask)
return FALSE;
}
+// Called from handleKey()
+// Handles key in this object. Checking parents and children happens in handleKey()
+BOOL LLView::handleKeyUpHere(KEY key, MASK mask)
+{
+ return FALSE;
+}
+
BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
{
BOOL handled = FALSE;
@@ -1020,6 +1060,12 @@ LLView* LLView::childrenHandleKey(KEY key, MASK mask)
return childrenHandleCharEvent("Key", &LLView::handleKey, key, mask);
}
+// Called during downward traversal
+LLView* LLView::childrenHandleKeyUp(KEY key, MASK mask)
+{
+ return childrenHandleCharEvent("Key Up", &LLView::handleKeyUp, key, mask);
+}
+
// Called during downward traversal
LLView* LLView::childrenHandleUnicodeChar(llwchar uni_char)
{
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 7861c8f729..8494bb338a 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -378,6 +378,7 @@ public:
// inherited from LLFocusableElement
/* virtual */ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+ /* virtual */ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent);
/* virtual */ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -509,6 +510,7 @@ public:
//virtual BOOL addChildFromParam(const LLInitParam::BaseBlock& params) { return TRUE; }
virtual BOOL handleKeyHere(KEY key, MASK mask);
+ virtual BOOL handleKeyUpHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual void handleReshape(const LLRect& rect, bool by_user);
@@ -538,6 +540,7 @@ protected:
void logMouseEvent();
LLView* childrenHandleKey(KEY key, MASK mask);
+ LLView* childrenHandleKeyUp(KEY key, MASK mask);
LLView* childrenHandleUnicodeChar(llwchar uni_char);
LLView* childrenHandleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop,
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 96e94c0f80..dde54c78c4 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -838,17 +838,21 @@ namespace tut
"search something https://marketplace.secondlife.com/products/search on marketplace and test the https",
"https://marketplace.secondlife.com/products/search");
- testRegex("match urls with port", url,
- "let's specify some port http://secondlife.com:888/status",
- "http://secondlife.com:888/status");
+ testRegex("match HTTPS urls with port", url,
+ "let's specify some port https://secondlife.com:888/status",
+ "https://secondlife.com:888/status");
+
+ testRegex("don't match HTTP urls with port", url,
+ "let's specify some port for HTTP http://secondlife.com:888/status",
+ "");
testRegex("don't match urls w/o protocol", url,
"looks like an url something www.marketplace.secondlife.com/products but no https prefix",
"");
testRegex("but with a protocol www is fine", url,
- "so let's add a protocol http://www.marketplace.secondlife.com:8888/products",
- "http://www.marketplace.secondlife.com:8888/products");
+ "so let's add a protocol https://www.marketplace.secondlife.com:8888/products",
+ "https://www.marketplace.secondlife.com:8888/products");
testRegex("don't match urls w/o protocol", url,
"and even no www something secondlife.com/status",
diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp
index dc40dcdde0..2123ed3939 100644
--- a/indra/llwindow/llkeyboardwin32.cpp
+++ b/indra/llwindow/llkeyboardwin32.cpp
@@ -258,7 +258,7 @@ void LLKeyboardWin32::scanKeyboard()
// *TODO: I KNOW there must be a better way of
// interrogating the key state than this, using async key
// state can cause ALL kinds of bugs - Doug
- if (key < KEY_BUTTON0)
+ if ((key < KEY_BUTTON0) && ((key < '0') || (key > '9')))
{
// ...under windows make sure the key actually still is down.
// ...translate back to windows key
@@ -267,7 +267,7 @@ void LLKeyboardWin32::scanKeyboard()
if (!pending_key_events && !(GetAsyncKeyState(virtual_key) & 0x8000))
{
//LL_INFOS() << "Key up event missed, resetting" << LL_ENDL;
- mKeyLevel[key] = FALSE;
+ mKeyLevel[key] = FALSE;
}
}
}
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index deb8cb90d8..406bc9cf47 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -28,6 +28,11 @@
#include "llwindowmacosx-objc.h"
#import "llappdelegate-objc.h"
+
+
+
+//---------------------------
+
@implementation NSScreen (PointConversion)
+ (NSScreen *)currentScreenForMouseLocation
@@ -42,6 +47,7 @@
return screen;
}
+
- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint
{
float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x));
@@ -57,6 +63,21 @@
@end
+void extractKeyDataFromEvent (NSEvent *theEvent, NativeKeyEventData * eventData)
+{
+ eventData->mKeyEvent = NativeKeyEventData::KEYUNKNOWN;
+ eventData->mEventType = [theEvent type];
+ eventData->mEventModifiers = [theEvent modifierFlags];
+ eventData->mEventKeyCode = [theEvent keyCode];
+ NSString *strEventChars = [theEvent characters];
+ eventData->mEventChars = (strEventChars.length) ? [strEventChars characterAtIndex:0] : 0;
+ NSString *strEventUChars = [theEvent charactersIgnoringModifiers];
+ eventData->mEventUnmodChars = (strEventUChars.length) ? [strEventUChars characterAtIndex:0] : 0;
+ eventData->mEventRepeat = [theEvent isARepeat];
+
+}
+
+
attributedStringInfo getSegments(NSAttributedString *str)
{
attributedStringInfo segments;
@@ -402,11 +423,20 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) keyUp:(NSEvent *)theEvent
{
- callKeyUp([theEvent keyCode], [theEvent modifierFlags]);
+ NativeKeyEventData eventData;
+
+ extractKeyDataFromEvent( theEvent, &eventData );
+ eventData.mKeyEvent = NativeKeyEventData::KEYUP;
+ callKeyUp(&eventData, [theEvent keyCode], [theEvent modifierFlags]);
}
- (void) keyDown:(NSEvent *)theEvent
{
+ NativeKeyEventData eventData;
+
+ extractKeyDataFromEvent( theEvent, &eventData );
+ eventData.mKeyEvent = NativeKeyEventData::KEYDOWN;
+
uint keycode = [theEvent keyCode];
// We must not depend on flagsChange event to detect modifier flags changed,
// must depend on the modifire flags in the event parameter.
@@ -414,7 +444,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
// e.g. OS Window for upload something or Input Window...
// mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit)
mModifiers = [theEvent modifierFlags];
- bool acceptsText = mHasMarkedText ? false : callKeyDown(keycode, mModifiers);
+ bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers);
unichar ch;
if (acceptsText &&
!mMarkedTextAllowed &&
@@ -435,12 +465,17 @@ attributedStringInfo getSegments(NSAttributedString *str)
// Since SL assumes we receive those, we fake it here.
if (mModifiers & NSCommandKeyMask && !mHasMarkedText)
{
- callKeyUp([theEvent keyCode], mModifiers);
+ eventData.mKeyEvent = NativeKeyEventData::KEYUP;
+ callKeyUp(&eventData, [theEvent keyCode], mModifiers);
}
}
- (void)flagsChanged:(NSEvent *)theEvent
{
+ NativeKeyEventData eventData;
+
+ extractKeyDataFromEvent( theEvent, &eventData );
+
mModifiers = [theEvent modifierFlags];
callModifier([theEvent modifierFlags]);
@@ -462,11 +497,13 @@ attributedStringInfo getSegments(NSAttributedString *str)
if (mModifiers & mask)
{
- callKeyDown([theEvent keyCode], 0);
+ eventData.mKeyEvent = NativeKeyEventData::KEYDOWN;
+ callKeyDown(&eventData, [theEvent keyCode], 0);
}
else
{
- callKeyUp([theEvent keyCode], 0);
+ eventData.mKeyEvent = NativeKeyEventData::KEYUP;
+ callKeyUp(&eventData, [theEvent keyCode], 0);
}
}
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index e6e8f27f53..dc184b91fb 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -46,6 +46,26 @@ typedef void *CursorRef;
typedef void *NSWindowRef;
typedef void *GLViewRef;
+
+struct NativeKeyEventData {
+ enum EventType {
+ KEYUNKNOWN,
+ KEYUP,
+ KEYDOWN,
+ KEYCHAR
+ };
+
+ EventType mKeyEvent;
+ uint32_t mEventType;
+ uint32_t mEventModifiers;
+ uint32_t mEventKeyCode;
+ uint32_t mEventChars;
+ uint32_t mEventUnmodChars;
+ bool mEventRepeat;
+};
+
+typedef const NativeKeyEventData * NSKeyEventRef;
+
// These are defined in llappviewermacosx.cpp.
bool initViewer();
void handleQuit();
@@ -102,8 +122,8 @@ void setupInputWindow(NSWindowRef window, GLViewRef view);
// These are all implemented in llwindowmacosx.cpp.
// This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
-bool callKeyUp(unsigned short key, unsigned int mask);
-bool callKeyDown(unsigned short key, unsigned int mask);
+bool callKeyUp(NSKeyEventRef event, unsigned short key, unsigned int mask);
+bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask);
void callResetKeys();
bool callUnicodeCallback(wchar_t character, unsigned int mask);
void callRightMouseDown(float *pos, unsigned int mask);
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 15e054fb5d..0d41884462 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -47,6 +47,10 @@ extern BOOL gDebugWindowProc;
const S32 BITS_PER_PIXEL = 32;
const S32 MAX_NUM_RESOLUTIONS = 32;
+namespace
+{
+ NSKeyEventRef mRawKeyEvent = NULL;
+}
//
// LLWindowMacOSX
//
@@ -194,14 +198,20 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
// These functions are used as wrappers for our internal event handling callbacks.
// It's a good idea to wrap these to avoid reworking more code than we need to within LLWindow.
-bool callKeyUp(unsigned short key, unsigned int mask)
+bool callKeyUp(NSKeyEventRef event, unsigned short key, unsigned int mask)
{
- return gKeyboard->handleKeyUp(key, mask);
+ mRawKeyEvent = event;
+ bool retVal = gKeyboard->handleKeyUp(key, mask);
+ mRawKeyEvent = NULL;
+ return retVal;
}
-bool callKeyDown(unsigned short key, unsigned int mask)
+bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask)
{
- return gKeyboard->handleKeyDown(key, mask);
+ mRawKeyEvent = event;
+ bool retVal = gKeyboard->handleKeyDown(key, mask);
+ mRawKeyEvent = NULL;
+ return retVal;
}
void callResetKeys()
@@ -211,7 +221,23 @@ void callResetKeys()
bool callUnicodeCallback(wchar_t character, unsigned int mask)
{
- return gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask);
+ NativeKeyEventData eventData;
+
+ memset(&eventData, 0, sizeof(NativeKeyEventData));
+
+ eventData.mKeyEvent = NativeKeyEventData::KEYCHAR;
+ eventData.mEventType = 0;
+ eventData.mEventModifiers = mask;
+ eventData.mEventKeyCode = 0;
+ eventData.mEventChars = character;
+ eventData.mEventUnmodChars = character;
+ eventData.mEventRepeat = false;
+
+ mRawKeyEvent = &eventData;
+
+ bool result = gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask);
+ mRawKeyEvent = NULL;
+ return result;
}
void callFocus()
@@ -1713,49 +1739,15 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
LLSD LLWindowMacOSX::getNativeKeyData()
{
LLSD result = LLSD::emptyMap();
-#if 0
+#if 1
if(mRawKeyEvent)
{
- char char_code = 0;
- UInt32 key_code = 0;
- UInt32 modifiers = 0;
- UInt32 keyboard_type = 0;
-
- GetEventParameter (mRawKeyEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &char_code);
- GetEventParameter (mRawKeyEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &key_code);
- GetEventParameter (mRawKeyEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
- GetEventParameter (mRawKeyEvent, kEventParamKeyboardType, typeUInt32, NULL, sizeof(UInt32), NULL, &keyboard_type);
-
- result["char_code"] = (S32)char_code;
- result["key_code"] = (S32)key_code;
- result["modifiers"] = (S32)modifiers;
- result["keyboard_type"] = (S32)keyboard_type;
-
-#if 0
- // This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc)
- // cause llsd serialization to create XML that the llsd deserializer won't parse!
- std::string unicode;
- S32 err = noErr;
- EventParamType actualType = typeUTF8Text;
- UInt32 actualSize = 0;
- char *buffer = NULL;
-
- err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, 0, &actualSize, NULL);
- if(err == noErr)
- {
- // allocate a buffer and get the actual data.
- buffer = new char[actualSize];
- err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, actualSize, &actualSize, buffer);
- if(err == noErr)
- {
- unicode.assign(buffer, actualSize);
- }
- delete[] buffer;
- }
-
- result["unicode"] = unicode;
-#endif
-
+ result["event_type"] = LLSD::Integer(mRawKeyEvent->mEventType);
+ result["event_modifiers"] = LLSD::Integer(mRawKeyEvent->mEventModifiers);
+ result["event_keycode"] = LLSD::Integer(mRawKeyEvent->mEventKeyCode);
+ result["event_chars"] = (mRawKeyEvent->mEventChars) ? LLSD(LLSD::Integer(mRawKeyEvent->mEventChars)) : LLSD();
+ result["event_umodchars"] = (mRawKeyEvent->mEventUnmodChars) ? LLSD(LLSD::Integer(mRawKeyEvent->mEventUnmodChars)) : LLSD();
+ result["event_isrepeat"] = LLSD::Boolean(mRawKeyEvent->mEventRepeat);
}
#endif
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 7e0eb9cf31..875ffe4cd4 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -42,6 +42,7 @@
#include "llgl.h"
#include "llstring.h"
#include "lldir.h"
+#include "llsdutil.h"
#include "llglslshader.h"
// System includes
@@ -2068,6 +2069,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next
window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
window_imp->mKeyVirtualKey = w_param;
+ window_imp->mRawMsg = u_msg;
+ window_imp->mRawWParam = w_param;
+ window_imp->mRawLParam = l_param;
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYDOWN");
{
@@ -2090,6 +2094,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
{
window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
window_imp->mKeyVirtualKey = w_param;
+ window_imp->mRawMsg = u_msg;
+ window_imp->mRawWParam = w_param;
+ window_imp->mRawLParam = l_param;
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP");
LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER);
@@ -2177,6 +2184,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_CHAR:
window_imp->mKeyCharCode = w_param;
+ window_imp->mRawMsg = u_msg;
+ window_imp->mRawWParam = w_param;
+ window_imp->mRawLParam = l_param;
// Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need
// to figure out how that works. - Doug
@@ -3239,6 +3249,9 @@ LLSD LLWindowWin32::getNativeKeyData()
result["scan_code"] = (S32)mKeyScanCode;
result["virtual_key"] = (S32)mKeyVirtualKey;
+ result["msg"] = ll_sd_from_U32(mRawMsg);
+ result["w_param"] = ll_sd_from_U32(mRawWParam);
+ result["l_param"] = ll_sd_from_U32(mRawLParam);
return result;
}
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 2ca8d48fc7..1a775eadaf 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -126,7 +126,7 @@ protected:
HCURSOR loadColorCursor(LPCTSTR name);
BOOL isValid();
void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size);
- LLSD getNativeKeyData();
+ virtual LLSD getNativeKeyData();
// Changes display resolution. Returns true if successful
BOOL setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh);
@@ -208,6 +208,9 @@ protected:
U32 mKeyCharCode;
U32 mKeyScanCode;
U32 mKeyVirtualKey;
+ U32 mRawMsg;
+ U32 mRawWParam;
+ U32 mRawLParam;
friend class LLWindowManager;
};
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index 85318aea3b..24eb3947b4 100644
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
@@ -2,16 +2,17 @@
add_subdirectory(base)
-add_subdirectory(webkit)
-
-add_subdirectory(gstreamer010)
+if (LINUX)
+ add_subdirectory(gstreamer010)
+endif (LINUX)
if (WINDOWS OR DARWIN)
add_subdirectory(quicktime)
+ add_subdirectory(cef)
endif (WINDOWS OR DARWIN)
if (WINDOWS)
add_subdirectory(winmmshim)
endif (WINDOWS)
-add_subdirectory(example)
+### add_subdirectory(example)
diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
similarity index 50%
rename from indra/media_plugins/webkit/CMakeLists.txt
rename to indra/media_plugins/cef/CMakeLists.txt
index 5a8fe90bdd..1f6163e41e 100644
--- a/indra/media_plugins/webkit/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -1,6 +1,6 @@
# -*- cmake -*-
-project(media_plugin_webkit)
+project(media_plugin_cef)
include(00-Common)
include(LLCommon)
@@ -9,17 +9,14 @@ include(LLPlugin)
include(LLMath)
include(LLRender)
include(LLWindow)
-include(UI)
include(Linking)
include(PluginAPI)
include(MediaPluginBase)
include(OpenGL)
-include(PulseAudio)
-include(WebKitLibPlugin)
+include(CEFPlugin)
include_directories(
- ${PULSEAUDIO_INCLUDE_DIRS}
${LLPLUGIN_INCLUDE_DIRS}
${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
@@ -27,14 +24,14 @@ include_directories(
${LLIMAGE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
- ${LLQTWEBKIT_INCLUDE_DIR}
+ ${CEF_INCLUDE_DIR}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
)
-### media_plugin_webkit
+### media_plugin_cef
if(NOT WORD_SIZE EQUAL 32)
if(WINDOWS)
@@ -44,75 +41,72 @@ if(NOT WORD_SIZE EQUAL 32)
endif(WINDOWS)
endif(NOT WORD_SIZE EQUAL 32)
-set(media_plugin_webkit_SOURCE_FILES
- media_plugin_webkit.cpp
+set(media_plugin_cef_SOURCE_FILES
+ media_plugin_cef.cpp
)
-set(media_plugin_webkit_HEADER_FILES
+set(media_plugin_cef_HEADER_FILES
volume_catcher.h
)
-set(media_plugin_webkit_LINK_LIBRARIES
+set (media_plugin_cef_LINK_LIBRARIES
${LLPLUGIN_LIBRARIES}
${MEDIA_PLUGIN_BASE_LIBRARIES}
${LLCOMMON_LIBRARIES}
- ${WEBKIT_PLUGIN_LIBRARIES}
- ${PLUGIN_API_WINDOWS_LIBRARIES}
- ${PULSEAUDIO_LIBRARIES}
-)
+ ${CEF_PLUGIN_LIBRARIES}
+ ${PLUGIN_API_WINDOWS_LIBRARIES})
+
# Select which VolumeCatcher implementation to use
if (LINUX)
- if (PULSEAUDIO_FOUND)
- list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp)
- else (PULSEAUDIO_FOUND)
- list(APPEND media_plugin_webkit_SOURCE_FILES dummy_volume_catcher.cpp)
- endif (PULSEAUDIO_FOUND)
- list(APPEND media_plugin_webkit_LINK_LIBRARIES
- ${UI_LIBRARIES} # for glib/GTK
- )
+ message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n"
+ " Please create a volume_catcher implementation for this platform.")
+
elseif (DARWIN)
- list(APPEND media_plugin_webkit_SOURCE_FILES mac_volume_catcher.cpp)
+ list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher.cpp)
find_library(CORESERVICES_LIBRARY CoreServices)
find_library(AUDIOUNIT_LIBRARY AudioUnit)
- list(APPEND media_plugin_webkit_LINK_LIBRARIES
+ list(APPEND media_plugin_cef_LINK_LIBRARIES
${CORESERVICES_LIBRARY} # for Component Manager calls
${AUDIOUNIT_LIBRARY} # for AudioUnit calls
)
elseif (WINDOWS)
- list(APPEND media_plugin_webkit_SOURCE_FILES windows_volume_catcher.cpp)
+ list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp)
endif (LINUX)
-set_source_files_properties(${media_plugin_webkit_HEADER_FILES}
+set_source_files_properties(${media_plugin_cef_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
-list(APPEND media_plugin_webkit_SOURCE_FILES ${media_plugin_webkit_HEADER_FILES})
+list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES})
-add_library(media_plugin_webkit
+add_library(media_plugin_cef
SHARED
- ${media_plugin_webkit_SOURCE_FILES}
+ ${media_plugin_cef_SOURCE_FILES}
)
-target_link_libraries(media_plugin_webkit ${media_plugin_webkit_LINK_LIBRARIES})
-
-add_dependencies(media_plugin_webkit
+add_dependencies(media_plugin_cef
${LLPLUGIN_LIBRARIES}
${MEDIA_PLUGIN_BASE_LIBRARIES}
${LLCOMMON_LIBRARIES}
)
+target_link_libraries(media_plugin_cef
+ ${media_plugin_cef_LINK_LIBRARIES}
+)
+
if (WINDOWS)
set_target_properties(
- media_plugin_webkit
+ media_plugin_cef
PROPERTIES
- LINK_FLAGS "/MANIFEST:NO"
+ LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT"
+ LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD"
)
endif (WINDOWS)
if (DARWIN)
# Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name
set_target_properties(
- media_plugin_webkit
+ media_plugin_cef
PROPERTIES
PREFIX ""
BUILD_WITH_INSTALL_RPATH 1
@@ -120,13 +114,4 @@ if (DARWIN)
LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp"
)
- # copy the webkit dylib to the build directory
-# add_custom_command(
-# TARGET media_plugin_webkit POST_BUILD
-# # OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllqtwebkit.dylib
-# COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
-# DEPENDS media_plugin_webkit ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib
-# )
-
endif (DARWIN)
-
diff --git a/indra/media_plugins/webkit/mac_volume_catcher.cpp b/indra/media_plugins/cef/mac_volume_catcher.cpp
similarity index 99%
rename from indra/media_plugins/webkit/mac_volume_catcher.cpp
rename to indra/media_plugins/cef/mac_volume_catcher.cpp
index 73e5bf3da3..dddb9c2077 100644
--- a/indra/media_plugins/webkit/mac_volume_catcher.cpp
+++ b/indra/media_plugins/cef/mac_volume_catcher.cpp
@@ -6,7 +6,7 @@
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
new file mode 100644
index 0000000000..9028f73e30
--- /dev/null
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -0,0 +1,886 @@
+/**
+* @file media_plugin_cef.cpp
+* @brief CEF (Chromium Embedding Framework) plugin for LLMedia API plugin system
+*
+* @cond
+* $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$
+* @endcond
+*/
+
+#include "linden_common.h"
+#include "indra_constants.h" // for indra keyboard codes
+
+#include "llgl.h"
+#include "llsdutil.h"
+#include "llplugininstance.h"
+#include "llpluginmessage.h"
+#include "llpluginmessageclasses.h"
+#include "media_plugin_base.h"
+
+#include "boost/function.hpp"
+#include "boost/bind.hpp"
+#include "llCEFLib.h"
+#include "volume_catcher.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+class MediaPluginCEF :
+ public MediaPluginBase
+{
+public:
+ MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginCEF();
+
+ /*virtual*/
+ void receiveMessage(const char* message_string);
+
+private:
+ bool init();
+
+ void onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup);
+ void onCustomSchemeURLCallback(std::string url);
+ void onConsoleMessageCallback(std::string message, std::string source, int line);
+ void onStatusMessageCallback(std::string value);
+ void onTitleChangeCallback(std::string title);
+ void onLoadStartCallback();
+ void onRequestExitCallback();
+ void onLoadEndCallback(int httpStatusCode);
+ void onAddressChangeCallback(std::string url);
+ void onNavigateURLCallback(std::string url, std::string target);
+ bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
+ void onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle);
+ void onFileDownloadCallback(std::string filename);
+
+ void postDebugMessage(const std::string& msg);
+ void authResponse(LLPluginMessage &message);
+
+ LLCEFLib::EKeyboardModifier decodeModifiers(std::string &modifiers);
+ void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers);
+ void keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data);
+ void unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data);
+
+ void checkEditState();
+ void setVolume(F32 vol);
+
+ bool mEnableMediaPluginDebugging;
+ std::string mHostLanguage;
+ bool mCookiesEnabled;
+ bool mPluginsEnabled;
+ bool mJavascriptEnabled;
+ std::string mUserAgentSubtring;
+ std::string mAuthUsername;
+ std::string mAuthPassword;
+ bool mAuthOK;
+ bool mCanCut;
+ bool mCanCopy;
+ bool mCanPaste;
+ std::string mCachePath;
+ std::string mCookiePath;
+ LLCEFLib* mLLCEFLib;
+
+ VolumeCatcher mVolumeCatcher;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
+MediaPluginBase(host_send_func, host_user_data)
+{
+ mWidth = 0;
+ mHeight = 0;
+ mDepth = 4;
+ mPixels = 0;
+ mEnableMediaPluginDebugging = true;
+ mHostLanguage = "en";
+ mCookiesEnabled = true;
+ mPluginsEnabled = false;
+ mJavascriptEnabled = true;
+ mUserAgentSubtring = "";
+ mAuthUsername = "";
+ mAuthPassword = "";
+ mAuthOK = false;
+ mCanCut = false;
+ mCanCopy = false;
+ mCanPaste = false;
+ mCachePath = "";
+ mCookiePath = "";
+ mLLCEFLib = new LLCEFLib();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+MediaPluginCEF::~MediaPluginCEF()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::postDebugMessage(const std::string& msg)
+{
+ if (mEnableMediaPluginDebugging)
+ {
+ std::stringstream str;
+ str << "@Media Msg> " << msg;
+
+ LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message");
+ debug_message.setValue("message_text", str.str());
+ debug_message.setValue("message_level", "info");
+ sendMessage(debug_message);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup)
+{
+ if (mPixels && pixels)
+ {
+ if (is_popup)
+ {
+ for (int line = 0; line < height; ++line)
+ {
+ int inverted_y = mHeight - y - height;
+ int src = line * width * mDepth;
+ int dst = (inverted_y + line) * mWidth * mDepth + x * mDepth;
+
+ if (dst + width * mDepth < mWidth * mHeight * mDepth)
+ {
+ memcpy(mPixels + dst, pixels + src, width * mDepth);
+ }
+ }
+ }
+ else
+ {
+ if (mWidth == width && mHeight == height)
+ {
+ memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
+ }
+
+ }
+ setDirty(0, 0, mWidth, mHeight);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line)
+{
+ std::stringstream str;
+ str << "Console message: " << message << " in file(" << source << ") at line " << line;
+ postDebugMessage(str.str());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onStatusMessageCallback(std::string value)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
+ message.setValue("status", value);
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onTitleChangeCallback(std::string title)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+ message.setValue("name", title);
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onLoadStartCallback()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
+ //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
+ message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack());
+ message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward());
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onRequestExitCallback()
+{
+ mLLCEFLib->shutdown();
+
+ LLPluginMessage message("base", "goodbye");
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onLoadEndCallback(int httpStatusCode)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
+ //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
+ message.setValueS32("result_code", httpStatusCode);
+ message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack());
+ message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward());
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onAddressChangeCallback(std::string url)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
+ message.setValue("uri", url);
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onNavigateURLCallback(std::string url, std::string target)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
+ message.setValue("uri", url);
+ message.setValue("target", target);
+ message.setValue("uuid", ""); // not used right now
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onCustomSchemeURLCallback(std::string url)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
+ message.setValue("uri", url);
+ message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password)
+{
+ mAuthOK = false;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request");
+ message.setValue("url", host);
+ message.setValue("realm", realm);
+ message.setValueBoolean("blocking_request", true);
+
+ // The "blocking_request" key in the message means this sendMessage call will block until a response is received.
+ sendMessage(message);
+
+ if (mAuthOK)
+ {
+ username = mAuthUsername;
+ password = mAuthPassword;
+ }
+
+ return mAuthOK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onFileDownloadCallback(const std::string filename)
+{
+ mAuthOK = false;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
+ message.setValue("filename", filename);
+
+ sendMessage(message);
+}
+
+void MediaPluginCEF::onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle)
+{
+ std::string name = "";
+
+ switch (type)
+ {
+ case LLCEFLib::CT_POINTER:
+ name = "arrow";
+ break;
+ case LLCEFLib::CT_IBEAM:
+ name = "ibeam";
+ break;
+ case LLCEFLib::CT_NORTHSOUTHRESIZE:
+ name = "splitv";
+ break;
+ case LLCEFLib::CT_EASTWESTRESIZE:
+ name = "splith";
+ break;
+ case LLCEFLib::CT_HAND:
+ name = "hand";
+ break;
+
+ default:
+ LL_WARNS() << "Unknown cursor ID: " << (int)type << LL_ENDL;
+ break;
+ }
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed");
+ message.setValue("name", name);
+ sendMessage(message);
+}
+
+void MediaPluginCEF::authResponse(LLPluginMessage &message)
+{
+ mAuthOK = message.getValueBoolean("ok");
+ if (mAuthOK)
+ {
+ mAuthUsername = message.getValue("username");
+ mAuthPassword = message.getValue("password");
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::receiveMessage(const char* message_string)
+{
+ // std::cerr << "MediaPluginCEF::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+ LLPluginMessage message_in;
+
+ if (message_in.parse(message_string) >= 0)
+ {
+ std::string message_class = message_in.getClass();
+ std::string message_name = message_in.getName();
+ if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+ {
+ if (message_name == "init")
+ {
+ LLPluginMessage message("base", "init_response");
+ LLSD versions = LLSD::emptyMap();
+ versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
+ message.setValueLLSD("versions", versions);
+
+ std::string plugin_version = "CEF plugin 1.1.3";
+ message.setValue("plugin_version", plugin_version);
+ sendMessage(message);
+ }
+ else if (message_name == "idle")
+ {
+ mLLCEFLib->update();
+
+ mVolumeCatcher.pump();
+ // this seems bad but unless the state changes (it won't until we figure out
+ // how to get CEF to tell us if copy/cut/paste is available) then this function
+ // will return immediately
+ checkEditState();
+ }
+ else if (message_name == "cleanup")
+ {
+ mLLCEFLib->requestExit();
+ }
+ else if (message_name == "shm_added")
+ {
+ SharedSegmentInfo info;
+ info.mAddress = message_in.getValuePointer("address");
+ info.mSize = (size_t)message_in.getValueS32("size");
+ std::string name = message_in.getValue("name");
+
+ mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+ }
+ else if (message_name == "shm_remove")
+ {
+ std::string name = message_in.getValue("name");
+
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ if (mPixels == iter->second.mAddress)
+ {
+ mPixels = NULL;
+ mTextureSegmentName.clear();
+ }
+ mSharedSegments.erase(iter);
+ }
+ else
+ {
+ }
+
+ LLPluginMessage message("base", "shm_remove_response");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
+ if (message_name == "init")
+ {
+ // event callbacks from LLCefLib
+ mLLCEFLib->setOnPageChangedCallback(boost::bind(&MediaPluginCEF::onPageChangedCallback, this, _1, _2, _3, _4, _5, _6));
+ mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1));
+ mLLCEFLib->setOnConsoleMessageCallback(boost::bind(&MediaPluginCEF::onConsoleMessageCallback, this, _1, _2, _3));
+ mLLCEFLib->setOnStatusMessageCallback(boost::bind(&MediaPluginCEF::onStatusMessageCallback, this, _1));
+ mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1));
+ mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this));
+ mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1));
+ mLLCEFLib->setOnAddressChangeCallback(boost::bind(&MediaPluginCEF::onAddressChangeCallback, this, _1));
+ mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2));
+ mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));
+ mLLCEFLib->setOnFileDownloadCallback(boost::bind(&MediaPluginCEF::onFileDownloadCallback, this, _1));
+ mLLCEFLib->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2));
+ mLLCEFLib->setOnRequestExitCallback(boost::bind(&MediaPluginCEF::onRequestExitCallback, this));
+
+ LLCEFLib::LLCEFLibSettings settings;
+ settings.initial_width = 1024;
+ settings.initial_height = 1024;
+ settings.plugins_enabled = mPluginsEnabled;
+ settings.media_stream_enabled = false; // MAINT-6060 - WebRTC media removed until we can add granualrity/query UI
+ settings.javascript_enabled = mJavascriptEnabled;
+ settings.cookies_enabled = mCookiesEnabled;
+ settings.cookie_store_path = mCookiePath;
+ settings.cache_enabled = true;
+ settings.cache_path = mCachePath;
+ settings.accept_language_list = mHostLanguage;
+ settings.user_agent_substring = mLLCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
+
+ bool result = mLLCEFLib->init(settings);
+ if (!result)
+ {
+ // if this fails, the media system in viewer will put up a message
+ }
+
+ // Plugin gets to decide the texture parameters to use.
+ mDepth = 4;
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+ message.setValueS32("default_width", 1024);
+ message.setValueS32("default_height", 1024);
+ message.setValueS32("depth", mDepth);
+ message.setValueU32("internalformat", GL_RGB);
+ message.setValueU32("format", GL_BGRA);
+ message.setValueU32("type", GL_UNSIGNED_BYTE);
+ message.setValueBoolean("coords_opengl", true);
+ sendMessage(message);
+ }
+ else if (message_name == "set_user_data_path")
+ {
+ std::string user_data_path_cache = message_in.getValue("cache_path");
+ std::string user_data_path_cookies = message_in.getValue("cookies_path");
+ mCachePath = user_data_path_cache + "cef_cache";
+ mCookiePath = user_data_path_cookies + "cef_cookies";
+ }
+ else if (message_name == "size_change")
+ {
+ std::string name = message_in.getValue("name");
+ S32 width = message_in.getValueS32("width");
+ S32 height = message_in.getValueS32("height");
+ S32 texture_width = message_in.getValueS32("texture_width");
+ S32 texture_height = message_in.getValueS32("texture_height");
+
+ if (!name.empty())
+ {
+ // Find the shared memory region with this name
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ mPixels = (unsigned char*)iter->second.mAddress;
+ mWidth = width;
+ mHeight = height;
+
+ mTextureWidth = texture_width;
+ mTextureHeight = texture_height;
+ };
+ };
+
+ mLLCEFLib->setSize(mWidth, mHeight);
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+ message.setValue("name", name);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ message.setValueS32("texture_width", texture_width);
+ message.setValueS32("texture_height", texture_height);
+ sendMessage(message);
+
+ }
+ else if (message_name == "set_language_code")
+ {
+ mHostLanguage = message_in.getValue("language");
+ }
+ else if (message_name == "load_uri")
+ {
+ std::string uri = message_in.getValue("uri");
+ mLLCEFLib->navigate(uri);
+ }
+ else if (message_name == "set_cookie")
+ {
+ std::string uri = message_in.getValue("uri");
+ std::string name = message_in.getValue("name");
+ std::string value = message_in.getValue("value");
+ std::string domain = message_in.getValue("domain");
+ std::string path = message_in.getValue("path");
+ bool httponly = message_in.getValueBoolean("httponly");
+ bool secure = message_in.getValueBoolean("secure");
+ mLLCEFLib->setCookie(uri, name, value, domain, path, httponly, secure);
+ }
+ else if (message_name == "mouse_event")
+ {
+ std::string event = message_in.getValue("event");
+
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+
+ // only even send left mouse button events to LLCEFLib
+ // (partially prompted by crash in OS X CEF when sending right button events)
+ // we catch the right click in viewer and display our own context menu anyway
+ S32 button = message_in.getValueS32("button");
+ LLCEFLib::EMouseButton btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT;
+
+ if (event == "down" && button == 0)
+ {
+ mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOWN, x, y);
+ mLLCEFLib->setFocus(true);
+
+ std::stringstream str;
+ str << "Mouse down at = " << x << ", " << y;
+ postDebugMessage(str.str());
+ }
+ else if (event == "up" && button == 0)
+ {
+ mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_UP, x, y);
+
+ std::stringstream str;
+ str << "Mouse up at = " << x << ", " << y;
+ postDebugMessage(str.str());
+ }
+ else if (event == "double_click")
+ {
+ mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOUBLE_CLICK, x, y);
+ }
+ else
+ {
+ mLLCEFLib->mouseMove(x, y);
+ }
+ }
+ else if (message_name == "scroll_event")
+ {
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+ const int scaling_factor = 40;
+ y *= -scaling_factor;
+
+ mLLCEFLib->mouseWheel(x, y);
+ }
+ else if (message_name == "text_event")
+ {
+ std::string text = message_in.getValue("text");
+ std::string modifiers = message_in.getValue("modifiers");
+ LLSD native_key_data = message_in.getValueLLSD("native_key_data");
+
+ unicodeInput(text, decodeModifiers(modifiers), native_key_data);
+ }
+ else if (message_name == "key_event")
+ {
+#if LL_DARWIN
+ std::string event = message_in.getValue("event");
+ S32 key = message_in.getValueS32("key");
+ LLSD native_key_data = message_in.getValueLLSD("native_key_data");
+
+#if 0
+ if (event == "down")
+ {
+ //mLLCEFLib->keyPress(key, true);
+ mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
+
+ }
+ else if (event == "up")
+ {
+ //mLLCEFLib->keyPress(key, false);
+ mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_UP, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
+ }
+#else
+ // Treat unknown events as key-up for safety.
+ LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP;
+ if (event == "down")
+ {
+ key_event = LLCEFLib::KE_KEY_DOWN;
+ }
+ else if (event == "repeat")
+ {
+ key_event = LLCEFLib::KE_KEY_REPEAT;
+ }
+
+ keyEvent(key_event, key, LLCEFLib::KM_MODIFIER_NONE, native_key_data);
+
+#endif
+#elif LL_WINDOWS
+ std::string event = message_in.getValue("event");
+ S32 key = message_in.getValueS32("key");
+ std::string modifiers = message_in.getValue("modifiers");
+ LLSD native_key_data = message_in.getValueLLSD("native_key_data");
+
+ // Treat unknown events as key-up for safety.
+ LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP;
+ if (event == "down")
+ {
+ key_event = LLCEFLib::KE_KEY_DOWN;
+ }
+ else if (event == "repeat")
+ {
+ key_event = LLCEFLib::KE_KEY_REPEAT;
+ }
+
+ keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
+#endif
+ }
+ else if (message_name == "enable_media_plugin_debugging")
+ {
+ mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
+ }
+ if (message_name == "auth_response")
+ {
+ authResponse(message_in);
+ }
+ if (message_name == "edit_cut")
+ {
+ mLLCEFLib->editCut();
+ }
+ if (message_name == "edit_copy")
+ {
+ mLLCEFLib->editCopy();
+ }
+ if (message_name == "edit_paste")
+ {
+ mLLCEFLib->editPaste();
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
+ {
+ if (message_name == "set_page_zoom_factor")
+ {
+ F32 factor = (F32)message_in.getValueReal("factor");
+ mLLCEFLib->setPageZoom(factor);
+ }
+ if (message_name == "browse_stop")
+ {
+ mLLCEFLib->stop();
+ }
+ else if (message_name == "browse_reload")
+ {
+ bool ignore_cache = true;
+ mLLCEFLib->reload(ignore_cache);
+ }
+ else if (message_name == "browse_forward")
+ {
+ mLLCEFLib->goForward();
+ }
+ else if (message_name == "browse_back")
+ {
+ mLLCEFLib->goBack();
+ }
+ else if (message_name == "cookies_enabled")
+ {
+ mCookiesEnabled = message_in.getValueBoolean("enable");
+ }
+ else if (message_name == "set_user_agent")
+ {
+ mUserAgentSubtring = message_in.getValue("user_agent");
+ }
+ else if (message_name == "show_web_inspector")
+ {
+ mLLCEFLib->showDevTools(true);
+ }
+ else if (message_name == "plugins_enabled")
+ {
+ mPluginsEnabled = message_in.getValueBoolean("enable");
+ }
+ else if (message_name == "javascript_enabled")
+ {
+ mJavascriptEnabled = message_in.getValueBoolean("enable");
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
+ {
+ if (message_name == "set_volume")
+ {
+ F32 volume = (F32)message_in.getValueReal("volume");
+ setVolume(volume);
+ }
+ }
+ else
+ {
+ };
+ }
+}
+
+LLCEFLib::EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
+{
+ int result = 0;
+
+ if (modifiers.find("shift") != std::string::npos)
+ result |= LLCEFLib::KM_MODIFIER_SHIFT;
+
+ if (modifiers.find("alt") != std::string::npos)
+ result |= LLCEFLib::KM_MODIFIER_ALT;
+
+ if (modifiers.find("control") != std::string::npos)
+ result |= LLCEFLib::KM_MODIFIER_CONTROL;
+
+ if (modifiers.find("meta") != std::string::npos)
+ result |= LLCEFLib::KM_MODIFIER_META;
+
+ return (LLCEFLib::EKeyboardModifier)result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers)
+{
+ native_scan_code = 0;
+ native_virtual_key = 0;
+ native_modifiers = 0;
+
+ if (native_key_data.isMap())
+ {
+#if LL_DARWIN
+ native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger());
+ native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger());
+ native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
+#elif LL_WINDOWS
+ native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
+ native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
+ // TODO: I don't think we need to do anything with native modifiers here -- please verify
+#endif
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers_x, LLSD native_key_data = LLSD::emptyMap())
+{
+#if LL_DARWIN
+
+ if (!native_key_data.has("event_type") ||
+ !native_key_data.has("event_modifiers") ||
+ !native_key_data.has("event_keycode") ||
+ !native_key_data.has("event_isrepeat"))
+ return;
+
+ uint32_t eventType = native_key_data["event_type"].asInteger();
+ if (!eventType)
+ return;
+ uint32_t eventModifiers = native_key_data["event_modifiers"].asInteger();
+ uint32_t eventKeycode = native_key_data["event_keycode"].asInteger();
+ char eventChars = static_cast(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger());
+ char eventUChars = static_cast(native_key_data["event_umodchars"].isUndefined() ? 0 : native_key_data["event_umodchars"].asInteger());
+ bool eventIsRepeat = native_key_data["event_isrepeat"].asBoolean();
+
+ mLLCEFLib->keyboardEventOSX(eventType, eventModifiers, (eventChars) ? &eventChars : NULL,
+ (eventUChars) ? &eventUChars : NULL, eventIsRepeat, eventKeycode);
+
+#elif LL_WINDOWS
+ U32 msg = ll_U32_from_sd(native_key_data["msg"]);
+ U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
+ U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
+
+ mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
+#endif
+};
+
+void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+{
+#if LL_DARWIN
+ //mLLCEFLib->keyPress(utf8str[0], true);
+ //mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
+ if (!native_key_data.has("event_chars") || !native_key_data.has("event_umodchars") ||
+ !native_key_data.has("event_keycode") || !native_key_data.has("event_modifiers"))
+ return;
+ uint32_t unicodeChar = native_key_data["event_chars"].asInteger();
+ uint32_t unmodifiedChar = native_key_data["event_umodchars"].asInteger();
+ uint32_t keyCode = native_key_data["event_keycode"].asInteger();
+ uint32_t rawmodifiers = native_key_data["event_modifiers"].asInteger();
+
+ mLLCEFLib->injectUnicodeText(unicodeChar, unmodifiedChar, keyCode, rawmodifiers);
+
+#elif LL_WINDOWS
+ U32 msg = ll_U32_from_sd(native_key_data["msg"]);
+ U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
+ U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
+ mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
+#endif
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::checkEditState()
+{
+ bool can_cut = mLLCEFLib->editCanCut();
+ bool can_copy = mLLCEFLib->editCanCopy();
+ bool can_paste = mLLCEFLib->editCanPaste();
+
+ if ((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste))
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state");
+
+ if (can_cut != mCanCut)
+ {
+ mCanCut = can_cut;
+ message.setValueBoolean("cut", can_cut);
+ }
+
+ if (can_copy != mCanCopy)
+ {
+ mCanCopy = can_copy;
+ message.setValueBoolean("copy", can_copy);
+ }
+
+ if (can_paste != mCanPaste)
+ {
+ mCanPaste = can_paste;
+ message.setValueBoolean("paste", can_paste);
+ }
+
+ sendMessage(message);
+ }
+}
+
+void MediaPluginCEF::setVolume(F32 vol)
+{
+ mVolumeCatcher.setVolume(vol);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool MediaPluginCEF::init()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+ message.setValue("name", "CEF Plugin");
+ sendMessage(message);
+
+ return true;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func,
+ void* host_user_data,
+ LLPluginInstance::sendMessageFunction *plugin_send_func,
+ void **plugin_user_data)
+{
+ MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data);
+ *plugin_send_func = MediaPluginCEF::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
+
+ return 0;
+}
diff --git a/indra/media_plugins/webkit/volume_catcher.h b/indra/media_plugins/cef/volume_catcher.h
similarity index 100%
rename from indra/media_plugins/webkit/volume_catcher.h
rename to indra/media_plugins/cef/volume_catcher.h
diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp
similarity index 100%
rename from indra/media_plugins/webkit/windows_volume_catcher.cpp
rename to indra/media_plugins/cef/windows_volume_catcher.cpp
diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt
index 58391007ff..d7a1874bf3 100644
--- a/indra/media_plugins/quicktime/CMakeLists.txt
+++ b/indra/media_plugins/quicktime/CMakeLists.txt
@@ -63,7 +63,8 @@ if (WINDOWS)
set_target_properties(
media_plugin_quicktime
PROPERTIES
- LINK_FLAGS "/MANIFEST:NO"
+ LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT"
+ LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD"
)
endif (WINDOWS)
diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
index ff1ed8bfbc..7ef5a0fe44 100644
--- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
+++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
@@ -837,7 +837,9 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string)
else if(message_name == "cleanup")
{
// TODO: clean up here
- }
+ LLPluginMessage message("base", "goodbye");
+ sendMessage(message);
+ }
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
diff --git a/indra/media_plugins/webkit/dummy_volume_catcher.cpp b/indra/media_plugins/webkit/dummy_volume_catcher.cpp
deleted file mode 100644
index d54b31b2ae..0000000000
--- a/indra/media_plugins/webkit/dummy_volume_catcher.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file dummy_volume_catcher.cpp
- * @brief A null implementation of the "VolumeCatcher" class for platforms where it's not implemented yet.
- *
- * @cond
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- * @endcond
- */
-
-#include "volume_catcher.h"
-
-
-class VolumeCatcherImpl
-{
-};
-
-/////////////////////////////////////////////////////
-
-VolumeCatcher::VolumeCatcher()
-{
- pimpl = NULL;
-}
-
-VolumeCatcher::~VolumeCatcher()
-{
-}
-
-void VolumeCatcher::setVolume(F32 volume)
-{
-}
-
-void VolumeCatcher::setPan(F32 pan)
-{
-}
-
-void VolumeCatcher::pump()
-{
-}
-
diff --git a/indra/media_plugins/webkit/linux_volume_catcher.cpp b/indra/media_plugins/webkit/linux_volume_catcher.cpp
deleted file mode 100644
index 91be3a89e9..0000000000
--- a/indra/media_plugins/webkit/linux_volume_catcher.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-/**
- * @file linux_volume_catcher.cpp
- * @brief A Linux-specific, PulseAudio-specific hack to detect and volume-adjust new audio sources
- *
- * @cond
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- * @endcond
- */
-
-/*
- The high-level design is as follows:
- 1) Connect to the PulseAudio daemon
- 2) Watch for the creation of new audio players connecting to the daemon (this includes ALSA clients running on the PulseAudio emulation layer, such as Flash plugins)
- 3) Examine any new audio player's PID to see if it belongs to our own process
- 4) If so, tell PA to adjust the volume of that audio player ('sink input' in PA parlance)
- 5) Keep a list of all living audio players that we care about, adjust the volumes of all of them when we get a new setVolume() call
- */
-
-#include "linden_common.h"
-
-#include "volume_catcher.h"
-
-
-extern "C" {
-#include
-#include
-
-#include
-#include
-#include
-#include // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken.
-
-#include "apr_pools.h"
-#include "apr_dso.h"
-}
-
-////////////////////////////////////////////////////
-
-#define DEBUGMSG(...) do {} while(0)
-#define INFOMSG(...) do {} while(0)
-#define WARNMSG(...) do {} while(0)
-
-#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) RTN (*ll##PASYM)(__VA_ARGS__) = NULL
-#include "linux_volume_catcher_pa_syms.inc"
-#include "linux_volume_catcher_paglib_syms.inc"
-#undef LL_PA_SYM
-
-static bool sSymsGrabbed = false;
-static apr_pool_t *sSymPADSOMemoryPool = NULL;
-static apr_dso_handle_t *sSymPADSOHandleG = NULL;
-
-bool grab_pa_syms(std::string pulse_dso_name)
-{
- if (sSymsGrabbed)
- {
- // already have grabbed good syms
- return true;
- }
-
- bool sym_error = false;
- bool rtn = false;
- apr_status_t rv;
- apr_dso_handle_t *sSymPADSOHandle = NULL;
-
-#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0)
-
- //attempt to load the shared library
- apr_pool_create(&sSymPADSOMemoryPool, NULL);
-
- if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle,
- pulse_dso_name.c_str(),
- sSymPADSOMemoryPool) ))
- {
- INFOMSG("Found DSO: %s", pulse_dso_name.c_str());
-
-#include "linux_volume_catcher_pa_syms.inc"
-#include "linux_volume_catcher_paglib_syms.inc"
-
- if ( sSymPADSOHandle )
- {
- sSymPADSOHandleG = sSymPADSOHandle;
- sSymPADSOHandle = NULL;
- }
-
- rtn = !sym_error;
- }
- else
- {
- INFOMSG("Couldn't load DSO: %s", pulse_dso_name.c_str());
- rtn = false; // failure
- }
-
- if (sym_error)
- {
- WARNMSG("Failed to find necessary symbols in PulseAudio libraries.");
- }
-#undef LL_PA_SYM
-
- sSymsGrabbed = rtn;
- return rtn;
-}
-
-
-void ungrab_pa_syms()
-{
- // should be safe to call regardless of whether we've
- // actually grabbed syms.
-
- if ( sSymPADSOHandleG )
- {
- apr_dso_unload(sSymPADSOHandleG);
- sSymPADSOHandleG = NULL;
- }
-
- if ( sSymPADSOMemoryPool )
- {
- apr_pool_destroy(sSymPADSOMemoryPool);
- sSymPADSOMemoryPool = NULL;
- }
-
- // NULL-out all of the symbols we'd grabbed
-#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0)
-#include "linux_volume_catcher_pa_syms.inc"
-#include "linux_volume_catcher_paglib_syms.inc"
-#undef LL_PA_SYM
-
- sSymsGrabbed = false;
-}
-////////////////////////////////////////////////////
-
-// PulseAudio requires a chain of callbacks with C linkage
-extern "C" {
- void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata);
- void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata);
- void callback_context_state(pa_context *context, void *userdata);
-}
-
-
-class VolumeCatcherImpl
-{
-public:
- VolumeCatcherImpl();
- ~VolumeCatcherImpl();
-
- void setVolume(F32 volume);
- void pump(void);
-
- // for internal use - can't be private because used from our C callbacks
-
- bool loadsyms(std::string pulse_dso_name);
- void init();
- void cleanup();
-
- void update_all_volumes(F32 volume);
- void update_index_volume(U32 index, F32 volume);
- void connected_okay();
-
- std::set mSinkInputIndices;
- std::map mSinkInputNumChannels;
- F32 mDesiredVolume;
- pa_glib_mainloop *mMainloop;
- pa_context *mPAContext;
- bool mConnected;
- bool mGotSyms;
-};
-
-VolumeCatcherImpl::VolumeCatcherImpl()
- : mDesiredVolume(0.0f),
- mMainloop(NULL),
- mPAContext(NULL),
- mConnected(false),
- mGotSyms(false)
-{
- init();
-}
-
-VolumeCatcherImpl::~VolumeCatcherImpl()
-{
- cleanup();
-}
-
-bool VolumeCatcherImpl::loadsyms(std::string pulse_dso_name)
-{
- return grab_pa_syms(pulse_dso_name);
-}
-
-void VolumeCatcherImpl::init()
-{
- // try to be as defensive as possible because PA's interface is a
- // bit fragile and (for our purposes) we'd rather simply not function
- // than crash
-
- // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in
- // libpulse.so.0 - this isn't a great assumption, and the two DSOs should
- // probably be loaded separately. Our Linux DSO framework needs refactoring,
- // we do this sort of thing a lot with practically identical logic...
- mGotSyms = loadsyms("libpulse-mainloop-glib.so.0");
- if (!mGotSyms) return;
-
- // better make double-sure glib itself is initialized properly.
- if (!g_thread_supported ()) g_thread_init (NULL);
- g_type_init();
-
- mMainloop = llpa_glib_mainloop_new(g_main_context_default());
- if (mMainloop)
- {
- pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop);
- if (api)
- {
- pa_proplist *proplist = llpa_proplist_new();
- if (proplist)
- {
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1");
-
- // plain old pa_context_new() is broken!
- mPAContext = llpa_context_new_with_proplist(api, NULL, proplist);
- llpa_proplist_free(proplist);
- }
- }
- }
-
- // Now we've set up a PA context and mainloop, try connecting the
- // PA context to a PA daemon.
- if (mPAContext)
- {
- llpa_context_set_state_callback(mPAContext, callback_context_state, this);
- pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN?
- if (llpa_context_connect(mPAContext, NULL, cflags, NULL) >= 0)
- {
- // Okay! We haven't definitely connected, but we
- // haven't definitely failed yet.
- }
- else
- {
- // Failed to connect to PA manager... we'll leave
- // things like that. Perhaps we should try again later.
- }
- }
-}
-
-void VolumeCatcherImpl::cleanup()
-{
- mConnected = false;
-
- if (mGotSyms && mPAContext)
- {
- llpa_context_disconnect(mPAContext);
- llpa_context_unref(mPAContext);
- }
- mPAContext = NULL;
-
- if (mGotSyms && mMainloop)
- {
- llpa_glib_mainloop_free(mMainloop);
- }
- mMainloop = NULL;
-}
-
-void VolumeCatcherImpl::setVolume(F32 volume)
-{
- mDesiredVolume = volume;
-
- if (!mGotSyms) return;
-
- if (mConnected && mPAContext)
- {
- update_all_volumes(mDesiredVolume);
- }
-
- pump();
-}
-
-void VolumeCatcherImpl::pump()
-{
- gboolean may_block = FALSE;
- g_main_context_iteration(g_main_context_default(), may_block);
-}
-
-void VolumeCatcherImpl::connected_okay()
-{
- pa_operation *op;
-
- // fetch global list of existing sinkinputs
- if ((op = llpa_context_get_sink_input_info_list(mPAContext,
- callback_discovered_sinkinput,
- this)))
- {
- llpa_operation_unref(op);
- }
-
- // subscribe to future global sinkinput changes
- llpa_context_set_subscribe_callback(mPAContext,
- callback_subscription_alert,
- this);
- if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t)
- (PA_SUBSCRIPTION_MASK_SINK_INPUT),
- NULL, NULL)))
- {
- llpa_operation_unref(op);
- }
-}
-
-void VolumeCatcherImpl::update_all_volumes(F32 volume)
-{
- for (std::set::iterator it = mSinkInputIndices.begin();
- it != mSinkInputIndices.end(); ++it)
- {
- update_index_volume(*it, volume);
- }
-}
-
-void VolumeCatcherImpl::update_index_volume(U32 index, F32 volume)
-{
- static pa_cvolume cvol;
- llpa_cvolume_set(&cvol, mSinkInputNumChannels[index],
- llpa_sw_volume_from_linear(volume));
-
- pa_context *c = mPAContext;
- uint32_t idx = index;
- const pa_cvolume *cvolumep = &cvol;
- pa_context_success_cb_t cb = NULL; // okay as null
- void *userdata = NULL; // okay as null
-
- pa_operation *op;
- if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata)))
- {
- llpa_operation_unref(op);
- }
-}
-
-
-void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata)
-{
- VolumeCatcherImpl *impl = dynamic_cast((VolumeCatcherImpl*)userdata);
- llassert(impl);
-
- if (0 == eol)
- {
- pa_proplist *proplist = sii->proplist;
- pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID));
-
- if (sinkpid == getpid()) // does the discovered sinkinput belong to this process?
- {
- bool is_new = (impl->mSinkInputIndices.find(sii->index) ==
- impl->mSinkInputIndices.end());
-
- impl->mSinkInputIndices.insert(sii->index);
- impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels;
-
- if (is_new)
- {
- // new!
- impl->update_index_volume(sii->index, impl->mDesiredVolume);
- }
- else
- {
- // seen it already, do nothing.
- }
- }
- }
-}
-
-void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata)
-{
- VolumeCatcherImpl *impl = dynamic_cast((VolumeCatcherImpl*)userdata);
- llassert(impl);
-
- switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
- case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
- if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) ==
- PA_SUBSCRIPTION_EVENT_REMOVE)
- {
- // forget this sinkinput, if we were caring about it
- impl->mSinkInputIndices.erase(index);
- impl->mSinkInputNumChannels.erase(index);
- }
- else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) ==
- PA_SUBSCRIPTION_EVENT_NEW)
- {
- // ask for more info about this new sinkinput
- pa_operation *op;
- if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl)))
- {
- llpa_operation_unref(op);
- }
- }
- else
- {
- // property change on this sinkinput - we don't care.
- }
- break;
-
- default:;
- }
-}
-
-void callback_context_state(pa_context *context, void *userdata)
-{
- VolumeCatcherImpl *impl = dynamic_cast((VolumeCatcherImpl*)userdata);
- llassert(impl);
-
- switch (llpa_context_get_state(context))
- {
- case PA_CONTEXT_READY:
- impl->mConnected = true;
- impl->connected_okay();
- break;
- case PA_CONTEXT_TERMINATED:
- impl->mConnected = false;
- break;
- case PA_CONTEXT_FAILED:
- impl->mConnected = false;
- break;
- default:;
- }
-}
-
-/////////////////////////////////////////////////////
-
-VolumeCatcher::VolumeCatcher()
-{
- pimpl = new VolumeCatcherImpl();
-}
-
-VolumeCatcher::~VolumeCatcher()
-{
- delete pimpl;
- pimpl = NULL;
-}
-
-void VolumeCatcher::setVolume(F32 volume)
-{
- llassert(pimpl);
- pimpl->setVolume(volume);
-}
-
-void VolumeCatcher::setPan(F32 pan)
-{
- // TODO: implement this (if possible)
-}
-
-void VolumeCatcher::pump()
-{
- llassert(pimpl);
- pimpl->pump();
-}
diff --git a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc
deleted file mode 100644
index d806b48428..0000000000
--- a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc
+++ /dev/null
@@ -1,21 +0,0 @@
-// required symbols to grab
-LL_PA_SYM(true, pa_context_connect, int, pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api);
-LL_PA_SYM(true, pa_context_disconnect, void, pa_context *c);
-LL_PA_SYM(true, pa_context_get_sink_input_info, pa_operation*, pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_get_sink_input_info_list, pa_operation*, pa_context *c, pa_sink_input_info_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_get_state, pa_context_state_t, pa_context *c);
-LL_PA_SYM(true, pa_context_new_with_proplist, pa_context*, pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist);
-LL_PA_SYM(true, pa_context_set_sink_input_volume, pa_operation*, pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_set_state_callback, void, pa_context *c, pa_context_notify_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_set_subscribe_callback, void, pa_context *c, pa_context_subscribe_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_subscribe, pa_operation*, pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_unref, void, pa_context *c);
-LL_PA_SYM(true, pa_cvolume_set, pa_cvolume*, pa_cvolume *a, unsigned channels, pa_volume_t v);
-LL_PA_SYM(true, pa_operation_unref, void, pa_operation *o);
-LL_PA_SYM(true, pa_proplist_free, void, pa_proplist* p);
-LL_PA_SYM(true, pa_proplist_gets, const char*, pa_proplist *p, const char *key);
-LL_PA_SYM(true, pa_proplist_new, pa_proplist*, void);
-LL_PA_SYM(true, pa_proplist_sets, int, pa_proplist *p, const char *key, const char *value);
-LL_PA_SYM(true, pa_sw_volume_from_linear, pa_volume_t, double v);
-
-// optional symbols to grab
diff --git a/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc
deleted file mode 100644
index abf628c96c..0000000000
--- a/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc
+++ /dev/null
@@ -1,6 +0,0 @@
-// required symbols to grab
-LL_PA_SYM(true, pa_glib_mainloop_free, void, pa_glib_mainloop* g);
-LL_PA_SYM(true, pa_glib_mainloop_get_api, pa_mainloop_api*, pa_glib_mainloop* g);
-LL_PA_SYM(true, pa_glib_mainloop_new, pa_glib_mainloop *, GMainContext *c);
-
-// optional symbols to grab
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
deleted file mode 100644
index 3edeef51e3..0000000000
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ /dev/null
@@ -1,1481 +0,0 @@
-/**
- * @file media_plugin_webkit.cpp
- * @brief Webkit plugin for LLMedia API plugin system
- *
- * @cond
- * $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$
- * @endcond
- */
-#include "llqtwebkit.h"
-#include "linden_common.h"
-#include "indra_constants.h" // for indra keyboard codes
-
-#include "lltimer.h"
-#include "llgl.h"
-
-#include "llplugininstance.h"
-#include "llpluginmessage.h"
-#include "llpluginmessageclasses.h"
-#include "media_plugin_base.h"
-
-// set to 1 if you're using the version of llqtwebkit that's QPixmap-ified
-#if LL_LINUX
-# define LL_QTWEBKIT_USES_PIXMAPS 0
-extern "C" {
-# include
-# include
-}
-#else
-# define LL_QTWEBKIT_USES_PIXMAPS 0
-#endif // LL_LINUX
-
-# include "volume_catcher.h"
-
-#if LL_WINDOWS
-# include
-#else
-# include
-# include
-#endif
-
-#if LL_WINDOWS
- // *NOTE:Mani - This captures the module handle for the dll. This is used below
- // to get the path to this dll for webkit initialization.
- // I don't know how/if this can be done with apr...
- namespace { HMODULE gModuleHandle;};
- BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
- {
- gModuleHandle = (HMODULE) hinstDLL;
- return TRUE;
- }
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-//
-class MediaPluginWebKit :
- public MediaPluginBase,
- public LLEmbeddedBrowserWindowObserver
-{
-public:
- MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginWebKit();
-
- /*virtual*/ void receiveMessage(const char *message_string);
-
-private:
-
- std::string mProfileDir;
- std::string mHostLanguage;
- std::string mUserAgent;
- bool mCookiesEnabled;
- bool mJavascriptEnabled;
- bool mPluginsEnabled;
- bool mEnableMediaPluginDebugging;
-
- enum
- {
- INIT_STATE_UNINITIALIZED, // LLQtWebkit hasn't been set up yet
- INIT_STATE_INITIALIZED, // LLQtWebkit has been set up, but no browser window has been created yet.
- INIT_STATE_NAVIGATING, // Browser instance has been set up and initial navigate to about:blank has been issued
- INIT_STATE_NAVIGATE_COMPLETE, // initial navigate to about:blank has completed
- INIT_STATE_WAIT_REDRAW, // First real navigate begin has been received, waiting for page changed event to start handling redraws
- INIT_STATE_WAIT_COMPLETE, // Waiting for first real navigate complete event
- INIT_STATE_RUNNING // All initialization gymnastics are complete.
- };
- int mBrowserWindowId;
- int mInitState;
- std::string mInitialNavigateURL;
- bool mNeedsUpdate;
-
- bool mCanCut;
- bool mCanCopy;
- bool mCanPaste;
- int mLastMouseX;
- int mLastMouseY;
- bool mFirstFocus;
- F32 mBackgroundR;
- F32 mBackgroundG;
- F32 mBackgroundB;
- std::string mTarget;
- LLTimer mElapsedTime;
-
- VolumeCatcher mVolumeCatcher;
-
- void postDebugMessage( const std::string& msg )
- {
- if ( mEnableMediaPluginDebugging )
- {
- std::stringstream str;
- str << "@Media Msg> " << "[" << (double)mElapsedTime.getElapsedTimeF32() << "] -- " << msg;
-
- LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message");
- debug_message.setValue("message_text", str.str());
- debug_message.setValue("message_level", "info");
- sendMessage(debug_message);
- }
- }
-
- void setInitState(int state)
- {
-// std::cerr << "changing init state to " << state << std::endl;
- mInitState = state;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void update(int milliseconds)
- {
-#if LL_QTLINUX_DOESNT_HAVE_GLIB
- // pump glib generously, as Linux browser plugins are on the
- // glib main loop, even if the browser itself isn't - ugh
- // This is NOT NEEDED if Qt itself was built with glib
- // mainloop integration.
- GMainContext *mainc = g_main_context_default();
- while(g_main_context_iteration(mainc, FALSE));
-#endif // LL_QTLINUX_DOESNT_HAVE_GLIB
-
- // pump qt
- LLQtWebKit::getInstance()->pump( milliseconds );
-
- mVolumeCatcher.pump();
-
- checkEditState();
-
- if(mInitState == INIT_STATE_NAVIGATE_COMPLETE)
- {
- if(!mInitialNavigateURL.empty())
- {
- // We already have the initial navigate URL -- kick off the navigate.
- LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, mInitialNavigateURL );
- mInitialNavigateURL.clear();
- }
- }
-
- if ( (mInitState > INIT_STATE_WAIT_REDRAW) && mNeedsUpdate )
- {
- const unsigned char* browser_pixels = LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId );
-
- unsigned int rowspan = LLQtWebKit::getInstance()->getBrowserRowSpan( mBrowserWindowId );
- unsigned int height = LLQtWebKit::getInstance()->getBrowserHeight( mBrowserWindowId );
-#if !LL_QTWEBKIT_USES_PIXMAPS
- unsigned int buffer_size = rowspan * height;
-#endif // !LL_QTWEBKIT_USES_PIXMAPS
-
-// std::cerr << "webkit plugin: updating" << std::endl;
-
- // TODO: should get rid of this memcpy if possible
- if ( mPixels && browser_pixels )
- {
-// std::cerr << " memcopy of " << buffer_size << " bytes" << std::endl;
-
-#if LL_QTWEBKIT_USES_PIXMAPS
- // copy the pixel data upside-down because of the co-ord system
- for (int y=0; y 0 && mHeight > 0 )
- {
-// std::cerr << "Setting dirty, " << mWidth << " x " << mHeight << std::endl;
- setDirty( 0, 0, mWidth, mHeight );
- }
-
- mNeedsUpdate = false;
- };
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- bool initBrowser()
- {
- // already initialized
- if ( mInitState > INIT_STATE_UNINITIALIZED )
- return true;
-
- // set up directories
- char cwd[ FILENAME_MAX ]; // I *think* this is defined on all platforms we use
- if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
- {
- LL_WARNS() << "Couldn't get cwd - probably too long - failing to init." << LL_ENDL;
- return false;
- }
- std::string application_dir = std::string( cwd );
-
-#if LL_LINUX
- // take care to initialize glib properly, because some
- // versions of Qt don't, and we indirectly need it for (some
- // versions of) Flash to not crash the browser.
- if (!g_thread_supported ()) g_thread_init (NULL);
- g_type_init();
-#endif
-
-#if LL_DARWIN
- // When running under the Xcode debugger, there's a setting called "Break on Debugger()/DebugStr()" which defaults to being turned on.
- // This causes the environment variable USERBREAK to be set to 1, which causes these legacy calls to break into the debugger.
- // This wouldn't cause any problems except for the fact that the current release version of the Flash plugin has a call to Debugger() in it
- // which gets hit when the plugin is probed by webkit.
- // Unsetting the environment variable here works around this issue.
- unsetenv("USERBREAK");
-#endif
-
-#if LL_WINDOWS
- //*NOTE:Mani - On windows, at least, the component path is the
- // location of this dll's image file.
- std::string component_dir;
- char dll_path[_MAX_PATH];
- DWORD len = GetModuleFileNameA(gModuleHandle, (LPCH)&dll_path, _MAX_PATH);
- while(len && dll_path[ len ] != ('\\') )
- {
- len--;
- }
- if(len >= 0)
- {
- dll_path[len] = 0;
- component_dir = dll_path;
- }
- else
- {
- // *NOTE:Mani - This case should be an rare exception.
- // GetModuleFileNameA should always give you a full path, no?
- component_dir = application_dir;
- }
-#else
- std::string component_dir = application_dir;
-#endif
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "Component dir set to: " + component_dir );
-
- // window handle - needed on Windows and must be app window.
-#if LL_WINDOWS
- char window_title[ MAX_PATH ];
- GetConsoleTitleA( window_title, MAX_PATH );
- void* native_window_handle = (void*)FindWindowA( NULL, window_title );
-#else
- void* native_window_handle = 0;
-#endif
-
- // main browser initialization
- bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, mProfileDir, native_window_handle );
- if ( result )
- {
- mInitState = INIT_STATE_INITIALIZED;
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "browser initialized okay" );
-
- return true;
- };
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "browser nOT initialized." );
-
- return false;
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- bool initBrowserWindow()
- {
- // already initialized
- if ( mInitState > INIT_STATE_INITIALIZED )
- return true;
-
- // not enough information to initialize the browser yet.
- if ( mWidth < 0 || mHeight < 0 || mDepth < 0 ||
- mTextureWidth < 0 || mTextureHeight < 0 )
- {
- return false;
- };
-
- // Set up host language before creating browser window
- if(!mHostLanguage.empty())
- {
- LLQtWebKit::getInstance()->setHostLanguage(mHostLanguage);
- postDebugMessage( "Setting language to " + mHostLanguage );
- }
-
- // turn on/off cookies based on what host app tells us
- LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled );
-
- // turn on/off plugins based on what host app tells us
- LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled );
-
- // turn on/off Javascript based on what host app tells us
-#if LLQTWEBKIT_API_VERSION >= 11
- LLQtWebKit::getInstance()->enableJavaScript( mJavascriptEnabled );
-#else
- LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled );
-#endif
-
- std::stringstream str;
- str << "Cookies enabled = " << mCookiesEnabled << ", plugins enabled = " << mPluginsEnabled << ", Javascript enabled = " << mJavascriptEnabled;
- postDebugMessage( str.str() );
-
- // create single browser window
- mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight, mTarget);
-
- str.str("");
- str.clear();
- str << "Setting browser window size to " << mWidth << " x " << mHeight;
- postDebugMessage( str.str() );
-
- // tell LLQtWebKit about the size of the browser window
- LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
-
- // observer events that LLQtWebKit emits
- LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this );
-
- // append details to agent string
- LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
- postDebugMessage( "Updating user agent with " + mUserAgent );
-
-#if !LL_QTWEBKIT_USES_PIXMAPS
- // don't flip bitmap
- LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true );
-#endif // !LL_QTWEBKIT_USES_PIXMAPS
-
- // set background color
- // convert background color channels from [0.0, 1.0] to [0, 255];
- LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, int(mBackgroundR * 255.0f), int(mBackgroundG * 255.0f), int(mBackgroundB * 255.0f) );
-
- // Set state _before_ starting the navigate, since onNavigateBegin might get called before this call returns.
- setInitState(INIT_STATE_NAVIGATING);
-
- // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance.
- // FIXME: Re-added this because navigating to a "page" initializes things correctly - especially
- // for the HTTP AUTH dialog issues (DEV-41731). Will fix at a later date.
- // Build a data URL like this: "data:text/html,%3Chtml%3E%3Cbody bgcolor=%22#RRGGBB%22%3E%3C/body%3E%3C/html%3E"
- // where RRGGBB is the background color in HTML style
- std::stringstream url;
-
- url << "data:text/html,%3Chtml%3E%3Cbody%20bgcolor=%22#";
- // convert background color channels from [0.0, 1.0] to [0, 255];
- url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundR * 255.0f);
- url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundG * 255.0f);
- url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundB * 255.0f);
- url << "%22%3E%3C/body%3E%3C/html%3E";
-
- //LL_DEBUGS() << "data url is: " << url.str() << LL_ENDL;
-
- // always display loading overlay now
-#if LLQTWEBKIT_API_VERSION >= 16
- LLQtWebKit::getInstance()->enableLoadingOverlay(mBrowserWindowId, true);
-#else
- LL_WARNS() << "Ignoring enableLoadingOverlay() call (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- str.clear();
- str << "Loading overlay enabled = " << mEnableMediaPluginDebugging << " for mBrowserWindowId = " << mBrowserWindowId;
- postDebugMessage( str.str() );
-
- LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, url.str() );
-// LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" );
-
- return true;
- }
-
- void setVolume(F32 vol);
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onCursorChanged(const EventType& event)
- {
- LLQtWebKit::ECursor llqt_cursor = (LLQtWebKit::ECursor)event.getIntValue();
- std::string name;
-
- switch(llqt_cursor)
- {
- case LLQtWebKit::C_ARROW:
- name = "arrow";
- break;
- case LLQtWebKit::C_IBEAM:
- name = "ibeam";
- break;
- case LLQtWebKit::C_SPLITV:
- name = "splitv";
- break;
- case LLQtWebKit::C_SPLITH:
- name = "splith";
- break;
- case LLQtWebKit::C_POINTINGHAND:
- name = "hand";
- break;
-
- default:
- LL_WARNS() << "Unknown cursor ID: " << (int)llqt_cursor << LL_ENDL;
- break;
- }
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed");
- message.setValue("name", name);
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onPageChanged( const EventType& event )
- {
- if(mInitState == INIT_STATE_WAIT_REDRAW)
- {
- setInitState(INIT_STATE_WAIT_COMPLETE);
- }
-
- // flag that an update is required
- mNeedsUpdate = true;
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onNavigateBegin(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
- message.setValue("uri", event.getEventUri());
- message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK));
- message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD));
- sendMessage(message);
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "Navigate begin event at: " + event.getEventUri() );
-
- setStatus(STATUS_LOADING);
- }
-
- if(mInitState == INIT_STATE_NAVIGATE_COMPLETE)
- {
- // Skip the WAIT_REDRAW state now -- with the right background color set, it should no longer be necessary.
-// setInitState(INIT_STATE_WAIT_REDRAW);
- setInitState(INIT_STATE_WAIT_COMPLETE);
- }
-
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onNavigateComplete(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- if(mInitState < INIT_STATE_RUNNING)
- {
- setInitState(INIT_STATE_RUNNING);
-
- // Clear the history, so the "back" button doesn't take you back to "about:blank".
- LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId);
- }
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
- message.setValue("uri", event.getEventUri());
- message.setValueS32("result_code", event.getIntValue());
- message.setValue("result_string", event.getStringValue());
- message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK));
- message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD));
- sendMessage(message);
-
- setStatus(STATUS_LOADED);
- }
- else if(mInitState == INIT_STATE_NAVIGATING)
- {
- setInitState(INIT_STATE_NAVIGATE_COMPLETE);
- }
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "Navigate complete event at: " + event.getEventUri() );
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onUpdateProgress(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "progress");
- message.setValueS32("percent", event.getIntValue());
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onStatusTextChange(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
- message.setValue("status", event.getStringValue());
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onTitleChange(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
- message.setValue("name", event.getStringValue());
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onNavigateErrorPage(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_error_page");
- message.setValueS32("status_code", event.getIntValue());
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onLocationChange(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
- message.setValue("uri", event.getEventUri());
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onClickLinkHref(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
- message.setValue("uri", event.getEventUri());
- message.setValue("target", event.getStringValue());
- message.setValue("uuid", event.getStringValue2());
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onClickLinkNoFollow(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
- message.setValue("uri", event.getEventUri());
-#if LLQTWEBKIT_API_VERSION >= 7
- message.setValue("nav_type", event.getNavigationType());
-#else
- message.setValue("nav_type", "clicked");
-#endif
- sendMessage(message);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onCookieChanged(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookie_set");
- message.setValue("cookie", event.getStringValue());
- // These could be passed through as well, but aren't really needed.
-// message.setValue("uri", event.getEventUri());
-// message.setValueBoolean("dead", (event.getIntValue() != 0))
-
- // debug spam
- postDebugMessage( "Sending cookie_set message from plugin: " + event.getStringValue() );
-
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onWindowCloseRequested(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "close_request");
- message.setValue("uuid", event.getStringValue());
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onWindowGeometryChangeRequested(const EventType& event)
- {
- int x, y, width, height;
- event.getRectValue(x, y, width, height);
-
- // This sometimes gets called with a zero-size request. Don't pass these along.
- if(width > 0 && height > 0)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "geometry_change");
- message.setValue("uuid", event.getStringValue());
- message.setValueS32("x", x);
- message.setValueS32("y", y);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- std::string onRequestFilePicker( const EventType& eventIn )
- {
- return blockingPickFile();
- }
-
- std::string mAuthUsername;
- std::string mAuthPassword;
- bool mAuthOK;
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- bool onAuthRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password)
- {
- mAuthOK = false;
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request");
- message.setValue("url", in_url);
- message.setValue("realm", in_realm);
- message.setValueBoolean("blocking_request", true);
-
- // The "blocking_request" key in the message means this sendMessage call will block until a response is received.
- sendMessage(message);
-
- if(mAuthOK)
- {
- out_username = mAuthUsername;
- out_password = mAuthPassword;
- }
-
- return mAuthOK;
- }
-
- void authResponse(LLPluginMessage &message)
- {
- mAuthOK = message.getValueBoolean("ok");
- if(mAuthOK)
- {
- mAuthUsername = message.getValue("username");
- mAuthPassword = message.getValue("password");
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onLinkHovered(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "link_hovered");
- message.setValue("link", event.getEventUri());
- message.setValue("title", event.getStringValue());
- message.setValue("text", event.getStringValue2());
- sendMessage(message);
- }
- }
-
- LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers)
- {
- int result = 0;
-
- if(modifiers.find("shift") != std::string::npos)
- result |= LLQtWebKit::KM_MODIFIER_SHIFT;
-
- if(modifiers.find("alt") != std::string::npos)
- result |= LLQtWebKit::KM_MODIFIER_ALT;
-
- if(modifiers.find("control") != std::string::npos)
- result |= LLQtWebKit::KM_MODIFIER_CONTROL;
-
- if(modifiers.find("meta") != std::string::npos)
- result |= LLQtWebKit::KM_MODIFIER_META;
-
- return (LLQtWebKit::EKeyboardModifier)result;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void deserializeKeyboardData( LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers )
- {
- native_scan_code = 0;
- native_virtual_key = 0;
- native_modifiers = 0;
-
- if( native_key_data.isMap() )
- {
-#if LL_DARWIN
- native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger());
- native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger());
- native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
-#elif LL_WINDOWS
- native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
- native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
- // TODO: I don't think we need to do anything with native modifiers here -- please verify
-#elif LL_LINUX
- native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
- native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
- native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
-#else
- // Add other platforms here as needed
-#endif
- };
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
- {
- // The incoming values for 'key' will be the ones from indra_constants.h
- std::string utf8_text;
-
- if(key < KEY_SPECIAL)
- {
- // Low-ascii characters need to get passed through.
- utf8_text = (char)key;
- }
-
- // Any special-case handling we want to do for particular keys...
- switch((KEY)key)
- {
- // ASCII codes for some standard keys
- case LLQtWebKit::KEY_BACKSPACE: utf8_text = (char)8; break;
- case LLQtWebKit::KEY_TAB: utf8_text = (char)9; break;
- case LLQtWebKit::KEY_RETURN: utf8_text = (char)13; break;
- case LLQtWebKit::KEY_PAD_RETURN: utf8_text = (char)13; break;
- case LLQtWebKit::KEY_ESCAPE: utf8_text = (char)27; break;
-
- default:
- break;
- }
-
-// std::cerr << "key event " << (int)key_event << ", native_key_data = " << native_key_data << std::endl;
-
- uint32_t native_scan_code = 0;
- uint32_t native_virtual_key = 0;
- uint32_t native_modifiers = 0;
- deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers );
-
- LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
-
- checkEditState();
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
- {
- uint32_t key = LLQtWebKit::KEY_NONE;
-
-// std::cerr << "unicode input, native_key_data = " << native_key_data << std::endl;
-
- if(utf8str.size() == 1)
- {
- // The only way a utf8 string can be one byte long is if it's actually a single 7-bit ascii character.
- // In this case, use it as the key value.
- key = utf8str[0];
- }
-
- uint32_t native_scan_code = 0;
- uint32_t native_virtual_key = 0;
- uint32_t native_modifiers = 0;
- deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers );
-
- LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
- LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
-
- checkEditState();
- };
-
- void checkEditState(void)
- {
- bool can_cut = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT);
- bool can_copy = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY);
- bool can_paste = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE);
-
- if((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste))
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state");
-
- if(can_cut != mCanCut)
- {
- mCanCut = can_cut;
- message.setValueBoolean("cut", can_cut);
- }
-
- if(can_copy != mCanCopy)
- {
- mCanCopy = can_copy;
- message.setValueBoolean("copy", can_copy);
- }
-
- if(can_paste != mCanPaste)
- {
- mCanPaste = can_paste;
- message.setValueBoolean("paste", can_paste);
- }
-
- sendMessage(message);
-
- }
- }
-
- std::string mPickedFile;
-
- std::string blockingPickFile(void)
- {
- mPickedFile.clear();
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
- message.setValueBoolean("blocking_request", true);
-
- // The "blocking_request" key in the message means this sendMessage call will block until a response is received.
- sendMessage(message);
-
- return mPickedFile;
- }
-
- void onPickFileResponse(const std::string &file)
- {
- mPickedFile = file;
- }
-
-};
-
-MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
- MediaPluginBase(host_send_func, host_user_data)
-{
-// std::cerr << "MediaPluginWebKit constructor" << std::endl;
-
- mBrowserWindowId = 0;
- mInitState = INIT_STATE_UNINITIALIZED;
- mNeedsUpdate = true;
- mCanCut = false;
- mCanCopy = false;
- mCanPaste = false;
- mLastMouseX = 0;
- mLastMouseY = 0;
- mFirstFocus = true;
- mBackgroundR = 0.0f;
- mBackgroundG = 0.0f;
- mBackgroundB = 0.0f;
-
- mHostLanguage = "en"; // default to english
- mJavascriptEnabled = true; // default to on
- mPluginsEnabled = true; // default to on
- mEnableMediaPluginDebugging = false;
- mUserAgent = "LLPluginMedia Web Browser";
-
- mElapsedTime.reset();
-}
-
-MediaPluginWebKit::~MediaPluginWebKit()
-{
- // unhook observer
- LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this );
-
- // clean up
- LLQtWebKit::getInstance()->reset();
-
-// std::cerr << "MediaPluginWebKit destructor" << std::endl;
-}
-
-void MediaPluginWebKit::receiveMessage(const char *message_string)
-{
-// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
- LLPluginMessage message_in;
-
- if(message_in.parse(message_string) >= 0)
- {
- std::string message_class = message_in.getClass();
- std::string message_name = message_in.getName();
- if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
- {
- if(message_name == "init")
- {
- LLPluginMessage message("base", "init_response");
- LLSD versions = LLSD::emptyMap();
- versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
- message.setValueLLSD("versions", versions);
-
- std::string plugin_version = "Webkit media plugin, Webkit version ";
- plugin_version += LLQtWebKit::getInstance()->getVersion();
- message.setValue("plugin_version", plugin_version);
- sendMessage(message);
- }
- else if(message_name == "idle")
- {
- // no response is necessary here.
- F64 time = message_in.getValueReal("time");
-
- // Convert time to milliseconds for update()
- update((int)(time * 1000.0f));
- }
- else if(message_name == "cleanup")
- {
- // DTOR most likely won't be called but the recent change to the way this process
- // is (not) killed means we see this message and can do what we need to here.
- // Note: this cleanup is ultimately what writes cookies to the disk
- LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this );
- LLQtWebKit::getInstance()->reset();
- }
- else if(message_name == "shm_added")
- {
- SharedSegmentInfo info;
- info.mAddress = message_in.getValuePointer("address");
- info.mSize = (size_t)message_in.getValueS32("size");
- std::string name = message_in.getValue("name");
-
-// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name
-// << ", size: " << info.mSize
-// << ", address: " << info.mAddress
-// << std::endl;
-
- mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
-
- }
- else if(message_name == "shm_remove")
- {
- std::string name = message_in.getValue("name");
-
-// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory remove, name = " << name << std::endl;
-
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if(iter != mSharedSegments.end())
- {
- if(mPixels == iter->second.mAddress)
- {
- // This is the currently active pixel buffer. Make sure we stop drawing to it.
- mPixels = NULL;
- mTextureSegmentName.clear();
- }
- mSharedSegments.erase(iter);
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
- }
-
- // Send the response so it can be cleaned up.
- LLPluginMessage message("base", "shm_remove_response");
- message.setValue("name", name);
- sendMessage(message);
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
- }
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
- {
- if(message_name == "set_volume")
- {
- F32 volume = (F32)message_in.getValueReal("volume");
- setVolume(volume);
- }
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
- {
- if(message_name == "init")
- {
- mTarget = message_in.getValue("target");
-
- // This is the media init message -- all necessary data for initialization should have been received.
- if(initBrowser())
- {
-
- // Plugin gets to decide the texture parameters to use.
- mDepth = 4;
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
- message.setValueS32("default_width", 1024);
- message.setValueS32("default_height", 1024);
- message.setValueS32("depth", mDepth);
- message.setValueU32("internalformat", GL_RGBA);
- #if LL_QTWEBKIT_USES_PIXMAPS
- message.setValueU32("format", GL_BGRA_EXT); // I hope this isn't system-dependant... is it? If so, we'll have to check the root window's pixel layout or something... yuck.
- #else
- message.setValueU32("format", GL_RGBA);
- #endif // LL_QTWEBKIT_USES_PIXMAPS
- message.setValueU32("type", GL_UNSIGNED_BYTE);
- message.setValueBoolean("coords_opengl", true);
- sendMessage(message);
- }
- else
- {
- // if initialization failed, we're done.
- mDeleteMe = true;
- }
-
- }
- else if(message_name == "set_user_data_path")
- {
- std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter
- mProfileDir = user_data_path + "browser_profile";
-
- // FIXME: Should we do anything with this if it comes in after the browser has been initialized?
- }
- else if(message_name == "set_language_code")
- {
- mHostLanguage = message_in.getValue("language");
-
- // FIXME: Should we do anything with this if it comes in after the browser has been initialized?
- }
- else if(message_name == "plugins_enabled")
- {
- mPluginsEnabled = message_in.getValueBoolean("enable");
- }
- else if(message_name == "javascript_enabled")
- {
- mJavascriptEnabled = message_in.getValueBoolean("enable");
- }
- else if(message_name == "size_change")
- {
- std::string name = message_in.getValue("name");
- S32 width = message_in.getValueS32("width");
- S32 height = message_in.getValueS32("height");
- S32 texture_width = message_in.getValueS32("texture_width");
- S32 texture_height = message_in.getValueS32("texture_height");
- mBackgroundR = (F32)message_in.getValueReal("background_r");
- mBackgroundG = (F32)message_in.getValueReal("background_g");
- mBackgroundB = (F32)message_in.getValueReal("background_b");
-// mBackgroundA = message_in.setValueReal("background_a"); // Ignore any alpha
-
- if(!name.empty())
- {
- // Find the shared memory region with this name
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if(iter != mSharedSegments.end())
- {
- mPixels = (unsigned char*)iter->second.mAddress;
- mWidth = width;
- mHeight = height;
-
- if(initBrowserWindow())
- {
-
- // size changed so tell the browser
- LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
-
- // std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight
- // << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl;
-
- S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId);
-
- // The actual width the browser will be drawing to is probably smaller... let the host know by modifying texture_width in the response.
- if(real_width <= texture_width)
- {
- texture_width = real_width;
- }
- else
- {
- // This won't work -- it'll be bigger than the allocated memory. This is a fatal error.
- // std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl;
- mDeleteMe = true;
- return;
- }
- }
- else
- {
- // Setting up the browser window failed. This is a fatal error.
- mDeleteMe = true;
- }
-
-
- mTextureWidth = texture_width;
- mTextureHeight = texture_height;
-
- };
- };
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
- message.setValue("name", name);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- message.setValueS32("texture_width", texture_width);
- message.setValueS32("texture_height", texture_height);
- sendMessage(message);
-
- }
- else if(message_name == "load_uri")
- {
- std::string uri = message_in.getValue("uri");
-
-// std::cout << "loading URI: " << uri << std::endl;
-
- if(!uri.empty())
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, uri );
- }
- else
- {
- mInitialNavigateURL = uri;
- }
- }
- }
- else if(message_name == "mouse_event")
- {
- std::string event = message_in.getValue("event");
- S32 button = message_in.getValueS32("button");
- mLastMouseX = message_in.getValueS32("x");
- mLastMouseY = message_in.getValueS32("y");
- std::string modifiers = message_in.getValue("modifiers");
-
- // Treat unknown mouse events as mouse-moves.
- LLQtWebKit::EMouseEvent mouse_event = LLQtWebKit::ME_MOUSE_MOVE;
- if(event == "down")
- {
- mouse_event = LLQtWebKit::ME_MOUSE_DOWN;
- }
- else if(event == "up")
- {
- mouse_event = LLQtWebKit::ME_MOUSE_UP;
- }
- else if(event == "double_click")
- {
- mouse_event = LLQtWebKit::ME_MOUSE_DOUBLE_CLICK;
- }
-
- LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId, mouse_event, button, mLastMouseX, mLastMouseY, decodeModifiers(modifiers));
- checkEditState();
- }
- else if(message_name == "scroll_event")
- {
- S32 x = message_in.getValueS32("x");
- S32 y = message_in.getValueS32("y");
- std::string modifiers = message_in.getValue("modifiers");
-
- // Incoming scroll events are adjusted so that 1 detent is approximately 1 unit.
- // Qt expects 1 detent to be 120 units.
- // It also seems that our y scroll direction is inverted vs. what Qt expects.
-
- x *= 120;
- y *= -120;
-
- LLQtWebKit::getInstance()->scrollWheelEvent(mBrowserWindowId, mLastMouseX, mLastMouseY, x, y, decodeModifiers(modifiers));
- }
- else if(message_name == "key_event")
- {
- std::string event = message_in.getValue("event");
- S32 key = message_in.getValueS32("key");
- std::string modifiers = message_in.getValue("modifiers");
- LLSD native_key_data = message_in.getValueLLSD("native_key_data");
-
- // Treat unknown events as key-up for safety.
- LLQtWebKit::EKeyEvent key_event = LLQtWebKit::KE_KEY_UP;
- if(event == "down")
- {
- key_event = LLQtWebKit::KE_KEY_DOWN;
- }
- else if(event == "repeat")
- {
- key_event = LLQtWebKit::KE_KEY_REPEAT;
- }
-
- keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
- }
- else if(message_name == "text_event")
- {
- std::string text = message_in.getValue("text");
- std::string modifiers = message_in.getValue("modifiers");
- LLSD native_key_data = message_in.getValueLLSD("native_key_data");
-
- unicodeInput(text, decodeModifiers(modifiers), native_key_data);
- }
- if(message_name == "edit_cut")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT );
- checkEditState();
- }
- if(message_name == "edit_copy")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY );
- checkEditState();
- }
- if(message_name == "edit_paste")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE );
- checkEditState();
- }
- if(message_name == "pick_file_response")
- {
- onPickFileResponse(message_in.getValue("file"));
- }
- if(message_name == "auth_response")
- {
- authResponse(message_in);
- }
- else
- if(message_name == "enable_media_plugin_debugging")
- {
- mEnableMediaPluginDebugging = message_in.getValueBoolean( "enable" );
- }
- else
- if(message_name == "js_enable_object")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- bool enable = message_in.getValueBoolean( "enable" );
- LLQtWebKit::getInstance()->setSLObjectEnabled( enable );
-#endif
- }
- else
- if(message_name == "js_agent_location")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- F32 x = (F32)message_in.getValueReal("x");
- F32 y = (F32)message_in.getValueReal("y");
- F32 z = (F32)message_in.getValueReal("z");
- LLQtWebKit::getInstance()->setAgentLocation( x, y, z );
- LLQtWebKit::getInstance()->emitLocation();
-#endif
- }
- else
- if(message_name == "js_agent_global_location")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- F32 x = (F32)message_in.getValueReal("x");
- F32 y = (F32)message_in.getValueReal("y");
- F32 z = (F32)message_in.getValueReal("z");
- LLQtWebKit::getInstance()->setAgentGlobalLocation( x, y, z );
- LLQtWebKit::getInstance()->emitLocation();
-#endif
- }
- else
- if(message_name == "js_agent_orientation")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- F32 angle = (F32)message_in.getValueReal("angle");
- LLQtWebKit::getInstance()->setAgentOrientation( angle );
- LLQtWebKit::getInstance()->emitLocation();
-#endif
- }
- else
- if(message_name == "js_agent_region")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- const std::string& region = message_in.getValue("region");
- LLQtWebKit::getInstance()->setAgentRegion( region );
- LLQtWebKit::getInstance()->emitLocation();
-#endif
- }
- else
- if(message_name == "js_agent_maturity")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- const std::string& maturity = message_in.getValue("maturity");
- LLQtWebKit::getInstance()->setAgentMaturity( maturity );
- LLQtWebKit::getInstance()->emitMaturity();
-#endif
- }
- else
- if(message_name == "js_agent_language")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- const std::string& language = message_in.getValue("language");
- LLQtWebKit::getInstance()->setAgentLanguage( language );
- LLQtWebKit::getInstance()->emitLanguage();
-#endif
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
- }
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
- {
- if(message_name == "focus")
- {
- bool val = message_in.getValueBoolean("focused");
- LLQtWebKit::getInstance()->focusBrowser( mBrowserWindowId, val );
-
- if(mFirstFocus && val)
- {
- // On the first focus, post a tab key event. This fixes a problem with initial focus.
- std::string empty;
- keyEvent(LLQtWebKit::KE_KEY_DOWN, KEY_TAB, decodeModifiers(empty));
- keyEvent(LLQtWebKit::KE_KEY_UP, KEY_TAB, decodeModifiers(empty));
- mFirstFocus = false;
- }
- }
- else if(message_name == "set_page_zoom_factor")
- {
-#if LLQTWEBKIT_API_VERSION >= 15
- F32 factor = (F32)message_in.getValueReal("factor");
- LLQtWebKit::getInstance()->setPageZoomFactor(factor);
-#else
- LL_WARNS() << "Ignoring setPageZoomFactor message (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- }
- else if(message_name == "clear_cache")
- {
- LLQtWebKit::getInstance()->clearCache();
- }
- else if(message_name == "clear_cookies")
- {
- LLQtWebKit::getInstance()->clearAllCookies();
- }
- else if(message_name == "enable_cookies")
- {
- mCookiesEnabled = message_in.getValueBoolean("enable");
- LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled );
- }
- else if(message_name == "enable_plugins")
- {
- mPluginsEnabled = message_in.getValueBoolean("enable");
- LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled );
- }
- else if(message_name == "enable_javascript")
- {
- mJavascriptEnabled = message_in.getValueBoolean("enable");
- //LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled );
- }
- else if(message_name == "set_cookies")
- {
- LLQtWebKit::getInstance()->setCookies(message_in.getValue("cookies"));
-
- // debug spam
- postDebugMessage( "Plugin setting cookie: " + message_in.getValue("cookies") );
- }
- else if(message_name == "proxy_setup")
- {
- bool val = message_in.getValueBoolean("enable");
- std::string host = message_in.getValue("host");
- int port = message_in.getValueS32("port");
- LLQtWebKit::getInstance()->enableProxy( val, host, port );
- }
- else if(message_name == "browse_stop")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_STOP );
- }
- else if(message_name == "browse_reload")
- {
- // foo = message_in.getValueBoolean("ignore_cache");
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_RELOAD );
- }
- else if(message_name == "browse_forward")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD );
- }
- else if(message_name == "browse_back")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK );
- }
- else if(message_name == "set_status_redirect")
- {
- int code = message_in.getValueS32("code");
- std::string url = message_in.getValue("url");
- if ( 404 == code ) // browser lib only supports 404 right now
- {
-#if LLQTWEBKIT_API_VERSION < 8
- LLQtWebKit::getInstance()->set404RedirectUrl( mBrowserWindowId, url );
-#endif
- };
- }
- else if(message_name == "set_user_agent")
- {
- mUserAgent = message_in.getValue("user_agent");
- LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
- }
- else if(message_name == "show_web_inspector")
- {
-#if LLQTWEBKIT_API_VERSION >= 10
- bool val = message_in.getValueBoolean("show");
- LLQtWebKit::getInstance()->showWebInspector( val );
-#else
- LL_WARNS() << "Ignoring showWebInspector message (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- }
- else if(message_name == "ignore_ssl_cert_errors")
- {
-#if LLQTWEBKIT_API_VERSION >= 3
- LLQtWebKit::getInstance()->setIgnoreSSLCertErrors( message_in.getValueBoolean("ignore") );
-#else
- LL_WARNS() << "Ignoring ignore_ssl_cert_errors message (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- }
- else if(message_name == "add_certificate_file_path")
- {
-#if LLQTWEBKIT_API_VERSION >= 6
- LLQtWebKit::getInstance()->setCAFile( message_in.getValue("path") );
-#else
- LL_WARNS() << "Ignoring add_certificate_file_path message (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- }
- else if(message_name == "init_history")
- {
- // Initialize browser history
- LLSD history = message_in.getValueLLSD("history");
- // First, clear the URL history
- LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId);
- // Then, add the history items in order
- LLSD::array_iterator iter_history = history.beginArray();
- LLSD::array_iterator end_history = history.endArray();
- for(; iter_history != end_history; ++iter_history)
- {
- std::string url = (*iter_history).asString();
- if(! url.empty()) {
- LLQtWebKit::getInstance()->prependHistoryUrl(mBrowserWindowId, url);
- }
- }
- }
- else if(message_name == "proxy_window_opened")
- {
- std::string target = message_in.getValue("target");
- std::string uuid = message_in.getValue("uuid");
- LLQtWebKit::getInstance()->proxyWindowOpened(mBrowserWindowId, target, uuid);
- }
- else if(message_name == "proxy_window_closed")
- {
- std::string uuid = message_in.getValue("uuid");
- LLQtWebKit::getInstance()->proxyWindowClosed(mBrowserWindowId, uuid);
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl;
- };
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
- };
- }
-}
-
-void MediaPluginWebKit::setVolume(F32 volume)
-{
- mVolumeCatcher.setVolume(volume);
-}
-
-int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
-{
- MediaPluginWebKit *self = new MediaPluginWebKit(host_send_func, host_user_data);
- *plugin_send_func = MediaPluginWebKit::staticReceiveMessage;
- *plugin_user_data = (void*)self;
-
- return 0;
-}
-
-
diff --git a/indra/media_plugins/winmmshim/CMakeLists.txt b/indra/media_plugins/winmmshim/CMakeLists.txt
index bf74f81809..6890589892 100644
--- a/indra/media_plugins/winmmshim/CMakeLists.txt
+++ b/indra/media_plugins/winmmshim/CMakeLists.txt
@@ -22,9 +22,6 @@ set(winmm_shim_HEADER_FILES
list(APPEND winmm_shim_SOURCE_FILES ${winmm_shim_HEADER_FILES})
-set_source_files_properties(${media_plugin_webkit_HEADER_FILES}
- PROPERTIES HEADER_FILE_ONLY TRUE)
-
add_library(winmm_shim
SHARED
${winmm_shim_SOURCE_FILES}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 0d49823c9c..9e2c465145 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -44,7 +44,6 @@ include(OPENAL)
include(OpenGL)
include(OpenSSL)
include(PNG)
-include(Prebuilt)
include(TemplateCheck)
include(UI)
include(UnixInstall)
@@ -62,9 +61,6 @@ if(FMODEX)
include_directories(${FMODEX_INCLUDE_DIR})
endif(FMODEX)
-# install SLPlugin host executable and its dynamic-library plugins
-use_prebuilt_binary(slplugins)
-
include_directories(
${DBUSGLIB_INCLUDE_DIRS}
${JSONCPP_INCLUDE_DIR}
@@ -1373,7 +1369,6 @@ if (DARWIN)
set(viewer_RESOURCE_FILES
secondlife.icns
macview.r
- gpu_table.txt
Info-SecondLife.plist
SecondLife.xib/
# CMake doesn't seem to support Xcode language variants well just yet
@@ -1766,44 +1761,12 @@ if (WINDOWS)
${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt
${CMAKE_CURRENT_SOURCE_DIR}/featuretable_xp.txt
${ARCH_PREBUILT_DIRS_RELEASE}/libeay32.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/qtcore4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/qtgui4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/qtnetwork4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/qtopengl4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/qtwebkit4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/qtxmlpatterns4.dll
${ARCH_PREBUILT_DIRS_RELEASE}/ssleay32.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qgif4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qico4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qjpeg4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qmng4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qsvg4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qtiff4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qcncodecs4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qjpcodecs4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qkrcodecs4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qtwcodecs4.dll
${ARCH_PREBUILT_DIRS_DEBUG}/libeay32.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/qtcored4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/qtguid4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/qtnetworkd4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/qtopengld4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/qtwebkitd4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/qtxmlpatternsd4.dll
${ARCH_PREBUILT_DIRS_DEBUG}/ssleay32.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qgifd4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qicod4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qjpegd4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qmngd4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qsvgd4.dll
- ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qtiffd4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qcncodecsd4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qjpcodecsd4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qkrcodecsd4.dll
- ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qtwcodecsd4.dll
SLPlugin
media_plugin_quicktime
- media_plugin_webkit
+ media_plugin_cef
winmm_shim
windows-crash-logger
)
@@ -1848,10 +1811,10 @@ if (WINDOWS)
add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)
endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
-## add_dependencies(${VIEWER_BINARY_NAME}
-## SLPlugin
-## windows-crash-logger
-## )
+ add_dependencies(${VIEWER_BINARY_NAME}
+ SLPlugin
+ windows-crash-logger
+ )
# sets the 'working directory' for debugging from visual studio.
if (NOT UNATTENDED)
@@ -2018,9 +1981,8 @@ if (LINUX)
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
linux-crash-logger
-## SLPlugin
-## media_plugin_webkit
-## media_plugin_gstreamer010
+ SLPlugin
+ media_plugin_gstreamer010
llcommon
)
@@ -2128,7 +2090,7 @@ if (DARWIN)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
)
-##add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-crash-logger)
+ add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_cef mac-crash-logger)
add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)
if (ENABLE_SIGNING)
@@ -2182,20 +2144,19 @@ if (PACKAGE)
if (DARWIN)
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
# *TODO: Generate these search dirs in the cmake files related to each binary.
-## list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
-## list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
-## list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}")
-## list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/webkit/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2")
-## set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
+ set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
set(VIEWER_EXE_GLOBS "'Second Life' mac-crash-logger")
set(VIEWER_LIB_GLOB "*.dylib")
endif (DARWIN)
if (LINUX)
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux.tar.bz2")
-## set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
+ set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin")
set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 4351a7e3a3..4d54daddb6 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.8.7
+4.0.2
diff --git a/indra/newview/ViewerInstall.cmake b/indra/newview/ViewerInstall.cmake
index 0b0d3e2adc..ac2247c815 100644
--- a/indra/newview/ViewerInstall.cmake
+++ b/indra/newview/ViewerInstall.cmake
@@ -19,7 +19,7 @@ else (IS_ARTWORK_PRESENT)
message(STATUS "WARNING: Artwork is not present, and will not be installed")
endif (IS_ARTWORK_PRESENT)
-install(FILES featuretable_linux.txt featuretable_solaris.txt gpu_table.txt
+install(FILES featuretable_linux.txt featuretable_solaris.txt
DESTINATION ${APP_SHARE_DIR}
)
diff --git a/indra/newview/app_settings/keywords_lsl_default.xml b/indra/newview/app_settings/keywords_lsl_default.xml
index cea7a58949..ddd287faf4 100644
--- a/indra/newview/app_settings/keywords_lsl_default.xml
+++ b/indra/newview/app_settings/keywords_lsl_default.xml
@@ -2314,6 +2314,15 @@
tooltip
Gets the attachment point to which the object is attached.\nReturns 0 if the object is not an attachment (or is an avatar, etc).
+ OBJECT_BODY_SHAPE_TYPE
+
+ type
+ integer
+ value
+ 26
+ tooltip
+ This is a flag used with llGetObjectDetails to get the body type of the avatar, based on shape data.\nIf no data is available, -1.0 is returned.\nThis is normally between 0 and 1.0, with 0.5 and larger considered 'male'
+
OBJECT_CHARACTER_TIME
type
@@ -2323,6 +2332,15 @@
tooltip
Units in seconds
+ OBJECT_CLICK_ACTION
+
+ type
+ integer
+ value
+ 28
+ tooltip
+ This is a flag used with llGetObjectDetails to get the click action.\nThe default is 0
+
OBJECT_CREATOR
type
@@ -2350,6 +2368,24 @@
tooltip
Gets the prims's group key. If id is an avatar, a NULL_KEY is returned.
+ OBJECT_HOVER_HEIGHT
+
+ type
+ integer
+ value
+ 25
+ tooltip
+ This is a flag used with llGetObjectDetails to get hover height of the avatar\nIf no data is available, 0.0 is returned.
+
+ OBJECT_LAST_OWNER_ID
+
+ type
+ integer
+ value
+ 27
+ tooltip
+ Gets the object's last owner ID.
+
OBJECT_NAME
type
@@ -3277,6 +3313,51 @@
tooltip
Play animation going forwards, then backwards.
+ PRIM_ALPHA_MODE
+
+ type
+ integer
+ value
+ 38
+ tooltip
+ Prim parameter for materials using integer face, integer alpha_mode, integer alpha_cutoff.\nDefines how the alpha channel of the diffuse texture should be rendered.\nValid options for alpha_mode are PRIM_ALPHA_MODE_BLEND, _NONE, _MASK, and _EMISSIVE.\nalpha_cutoff is used only for PRIM_ALPHA_MODE_MASK.
+
+ PRIM_ALPHA_MODE_NONE
+
+ type
+ integer
+ value
+ 0
+ tooltip
+ Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be ignored.
+
+ PRIM_ALPHA_MODE_BLEND
+
+ type
+ integer
+ value
+ 1
+ tooltip
+ Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as alpha-blended.
+
+ PRIM_ALPHA_MODE_MASK
+
+ type
+ integer
+ value
+ 2
+ tooltip
+ Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as fully opaque for alpha values above alpha_cutoff and fully transparent otherwise.
+
+ PRIM_ALPHA_MODE_EMISSIVE
+
+ type
+ integer
+ value
+ 3
+ tooltip
+ Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as an emissivity mask.
+
PRIM_BUMP_BARK
type
@@ -3882,6 +3963,15 @@
tooltip
+ PRIM_NORMAL
+
+ type
+ integer
+ value
+ 37
+ tooltip
+ Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians
+
PRIM_OMEGA
type
@@ -4108,6 +4198,15 @@
tooltip
+ PRIM_SPECULAR
+
+ type
+ integer
+ value
+ 36
+ tooltip
+ Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, vector color, integer glossy, integer environment
+
PRIM_TEMP_ON_REZ
type
@@ -5020,6 +5119,15 @@
tooltip
+ REGION_FLAG_BLOCK_FLYOVER
+
+ type
+ integer
+ value
+ 0x8000000
+ tooltip
+
+
REGION_FLAG_BLOCK_TERRAFORM
type
@@ -5979,6 +6087,177 @@
tooltip
+ XP_ERROR_EXPERIENCES_DISABLED
+
+ type
+ integer
+ value
+ 2
+ tooltip
+ The region currently has experiences disabled.
+
+ XP_ERROR_EXPERIENCE_DISABLED
+
+ type
+ integer
+ value
+ 8
+ tooltip
+ The experience owner has temporarily disabled the experience.
+
+ XP_ERROR_EXPERIENCE_SUSPENDED
+
+ type
+ integer
+ value
+ 9
+ tooltip
+ The experience has been suspended by Linden Customer Support.
+
+ XP_ERROR_INVALID_EXPERIENCE
+
+ type
+ integer
+ value
+ 7
+ tooltip
+ The script is associated with an experience that no longer exists.
+
+ XP_ERROR_INVALID_PARAMETERS
+
+ type
+ integer
+ value
+ 3
+ tooltip
+ One of the string arguments was too big to fit in the key-value store.
+
+ XP_ERROR_KEY_NOT_FOUND
+
+ type
+ integer
+ value
+ 14
+ tooltip
+ The requested key does not exist.
+
+ XP_ERROR_MATURITY_EXCEEDED
+
+ type
+ integer
+ value
+ 16
+ tooltip
+ The content rating of the experience exceeds that of the region.
+
+ XP_ERROR_NONE
+
+ type
+ integer
+ value
+ 0
+ tooltip
+ No error was detected.
+
+ XP_ERROR_NOT_FOUND
+
+ type
+ integer
+ value
+ 6
+ tooltip
+ The sim was unable to verify the validity of the experience. Retrying after a short wait is advised.
+
+ XP_ERROR_NOT_PERMITTED
+
+ type
+ integer
+ value
+ 4
+ tooltip
+ This experience is not allowed to run by the requested agent.
+
+ XP_ERROR_NOT_PERMITTED_LAND
+
+ type
+ integer
+ value
+ 17
+ tooltip
+ This experience is not allowed to run on the current region.
+
+ XP_ERROR_NO_EXPERIENCE
+
+ type
+ integer
+ value
+ 5
+ tooltip
+ This script is not associated with an experience.
+
+ XP_ERROR_QUOTA_EXCEEDED
+
+ type
+ integer
+ value
+ 11
+ tooltip
+ An attempted write data to the key-value store failed due to the data quota being met.
+
+ LSL_XP_ERROR_REQUEST_PERM_TIMEOUT
+
+ type
+ integer
+ value
+ 18
+ tooltip
+ The request for experience permissions was ignored and timed out.
+
+ XP_ERROR_RETRY_UPDATE
+
+ type
+ integer
+ value
+ 15
+ tooltip
+ A checked update failed due to an out of date request.
+
+ XP_ERROR_STORAGE_EXCEPTION
+
+ type
+ integer
+ value
+ 13
+ tooltip
+ Unable to communicate with the key-value store.
+
+ XP_ERROR_STORE_DISABLED
+
+ type
+ integer
+ value
+ 12
+ tooltip
+ The key-value store is currently disabled on this region.
+
+ XP_ERROR_THROTTLED
+
+ type
+ integer
+ value
+ 1
+ tooltip
+ The call failed due to too many recent calls.
+
+ XP_ERROR_UNKNOWN_ERROR
+
+ type
+ integer
+ value
+ 10
+ tooltip
+ Other unknown error.
+
ZERO_ROTATION
type
@@ -6280,6 +6559,34 @@
This event is triggered when an email sent to this script arrives.
The number remaining tells how many more emails are known to be still pending.
+ experience_permissions
+
+ arguments
+
+ agent_id
+
+ type
+ key
+ tooltip
+ ID of the agent approving permission for the Experience.
+
+
+
+ experience_permissions_denied
+
+ arguments
+
+ agent_id
+
+ type
+ key
+ tooltip
+ ID of the agent denying permission for the Experience.
+
+
+ tooltip
+ One of the XP_ERROR_... constants describing the reason why the Experience permissions were denied for the agent.
+
http_request
arguments
@@ -6965,6 +7272,29 @@
tooltip
Adjusts the volume (0.0 - 1.0) of the currently playing attached sound.\nThis function has no effect on sounds started with llTriggerSound.
+ llAgentInExperience
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ integer
+ arguments
+
+ AgentID
+
+ type
+ key
+ tooltip
+
+
+
+ tooltip
+
+ Returns TRUE if the agent is in the Experience and the Experience can run in the current location.
+
+
llAllowInventoryDrop
energy
@@ -7696,6 +8026,36 @@
tooltip
Convert link-set to AI/Physics character.\nCreates a path-finding entity, known as a "character", from the object containing the script. Required to activate use of path-finding functions.\nOptions is a list of key/value pairs.
+ llCreateKeyValue
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ key
+ arguments
+
+ Key
+
+ type
+ string
+ tooltip
+
+
+ Value
+
+ type
+ string
+ tooltip
+
+
+
+ tooltip
+
+ Starts an asychronous transaction to create a key-value pair. Will fail with XP_ERROR_STORAGE_EXCEPTION if the key already exists. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value passed to the function.
+
+
llCreateLink
energy
@@ -7751,6 +8111,21 @@
tooltip
Create a list from a string of comma separated values specified in Text.
+ llDataSizeKeyValue
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ key
+ arguments
+
+ tooltip
+
+ Starts an asychronous transaction the request the used and total amount of data allocated for the Experience. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the the amount in use and the third item will be the total available.
+
+
llDeleteCharacter
energy
@@ -7764,6 +8139,29 @@
tooltip
Convert link-set from AI/Physics character to Physics object.\nConvert the current link-set back to a standard object, removing all path-finding properties.
+ llDeleteKeyValue
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ key
+ arguments
+
+ Key
+
+ type
+ string
+ tooltip
+
+
+
+ tooltip
+
+ Starts an asychronous transaction to delete a key-value pair. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key.
+
+
llDeleteSubList
energy
@@ -8915,7 +9313,30 @@
arguments
tooltip
- Returns the object's attachment point, or 0 if not attached.\nReturns the object attachment point, or 0 if not attached.
+ Returns the object's attachment point, or 0 if not attached.
+
+ llGetAttachedList
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ list
+ arguments
+
+
+ ID
+
+ type
+ key
+ tooltip
+ Avatar to get attachments
+
+
+
+ tooltip
+ Returns a list of keys of all visible (not HUD) attachments on the avatar identified by the ID argument
llGetBoundingBox
@@ -9119,6 +9540,52 @@
tooltip
Returns a string with the requested data about the region.
+ llGetExperienceDetails
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ list
+ arguments
+
+ ExperienceID
+
+ type
+ key
+ tooltip
+ May be NULL_KEY to retrieve the details for the script's Experience
+
+
+ tooltip
+
+ Returns a list with the following Experience properties: [Experience Name, Owner ID, Group ID, Experience ID, State, State Message]. State is an integer corresponding to one of the constants XP_ERROR_... and State Message is the string returned by llGetExperienceErrorMessage for that integer.
+
+
+ llGetExperienceErrorMessage
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ string
+ arguments
+
+ Error
+
+ type
+ integer
+ tooltip
+ An Experience error code to translate.
+
+
+ tooltip
+
+ Returns a string describing the error code passed or the string corresponding with XP_ERROR_UNKNOWN_ERROR if the value is not a valid Experience error code.
+
+
llGetForce
energy
@@ -11446,6 +11913,51 @@
tooltip
Returns the name of the prim or avatar specified by ID. The ID must be a valid rezzed prim or avatar key in the current simulator, otherwise an empty string is returned.\nFor avatars, the returned name is the legacy name
+ llKeyCountKeyValue
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ key
+ arguments
+
+ tooltip
+
+ Starts an asychronous transaction the request the number of keys in the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will the the number of keys in the system.
+
+
+ llKeysKeyValue
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ key
+ arguments
+
+ First
+
+ type
+ string
+ tooltip
+ Index of the first key to return.
+
+ Count
+
+ type
+ string
+ tooltip
+ The number of keys to return.
+
+
+ tooltip
+
+ Starts an asychronous transaction the request a number of keys from the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. The error XP_ERROR_KEY_NOT_FOUND is returned if First is greater than or equal to the number of keys in the data store. In the success case the subsequent items will be the keys requested. The number of keys returned may be less than requested if the return value is too large or if there is not enough keys remaining. The order keys are returned is not guaranteed but is stable between subsequent calls as long as no keys are added or removed. Because the keys are returned in a comma-delimited list it is not recommended to use commas in key names if this function is used.
+
+
llLinkParticleSystem
energy
@@ -13577,6 +14089,29 @@
tooltip
Applies Impulse and AngularImpulse to ObjectID.\nApplies the supplied impulse and angular impulse to the object specified.
+ llReadKeyValue
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ key
+ arguments
+
+ Key
+
+ type
+ string
+ tooltip
+
+
+
+ tooltip
+
+ Starts an asychronous transaction to retrieve the value associated with the key given. Will fail with XP_ERROR_KEY_NOT_FOUND if the key does not exist. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key.
+
+
llRefreshPrimURL
energy
@@ -13997,6 +14532,36 @@
tooltip
Requests the display name of the agent. When the display name is available the dataserver event will be raised.\nThe avatar identified does not need to be in the same region or online at the time of the request.\nReturns a key that is used to identify the dataserver event when it is raised.
+ llRequestExperiencePermissions
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ void
+ arguments
+
+ AvatarID
+
+ type
+ key
+ tooltip
+
+
+ unused
+
+ type
+ string
+ tooltip
+ Not used, should be ""
+
+
+ tooltip
+
+ Ask the agent for permission to participate in an experience. This request is similar to llRequestPermissions with the following permissions: PERMISSION_TAKE_CONTROLS, PERMISSION_TRIGGER_ANIMATION, PERMISSION_ATTACH, PERMISSION_TRACK_CAMERA, PERMISSION_CONTROL_CAMERA and PERMISSION_TELEPORT. However, unlike llRequestPermissions the decision to allow or block the request is persistent and applies to all scripts using the experience grid wide. Subsequent calls to llRequestExperiencePermissions from scripts in the experience will receive the same response automatically with no user interaction. One of experience_permissions or experience_permissions_denied will be generated in response to this call. Outstanding permission requests will be lost if the script is derezzed, moved to another region or reset.
+
+
llRequestInventoryData
energy
@@ -17913,6 +18478,50 @@
tooltip
Updates settings for a pathfinding character.
+ llUpdateKeyValue
+
+ energy
+ 10.0
+ sleep
+ 0.0
+ return
+ key
+ arguments
+
+ Key
+
+ type
+ string
+ tooltip
+
+
+ Value
+
+ type
+ string
+ tooltip
+
+
+ Checked
+
+ type
+ integer
+ tooltip
+
+
+ OriginalValue
+
+ type
+ string
+ tooltip
+
+
+
+ tooltip
+
+ Starts an asychronous transaction to update the value associated with the key given. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. If Checked is 1 the existing value in the data store must match the OriginalValue passed or XP_ERROR_RETRY_UPDATE will be returned. If Checked is 0 the key will be created if necessary.
+
+
llVecDist
energy
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 5f378c64e8..1fdfdb51a8 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -734,7 +734,7 @@
F32
Value
60
-
+
AvatarRotateThresholdFast
Comment
@@ -745,7 +745,7 @@
F32
Value
2
-
+
AvatarBakedTextureUploadTimeout
Comment
@@ -1339,7 +1339,7 @@
String
Value
-
+
CacheNumberOfRegionsForObjects
Comment
@@ -3788,7 +3788,7 @@
Boolean
Value
0
-
+
FirstSelectedEnabledPopups
Comment
@@ -3799,7 +3799,7 @@
Boolean
Value
0
-
+
FixedWeather
Comment
@@ -3921,7 +3921,7 @@
Value
SW
-
+
FloaterStatisticsRect
Comment
@@ -4448,7 +4448,7 @@
String
Value
http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/howto/index.html
-
+
HomeSidePanelURL
Comment
@@ -4514,7 +4514,7 @@
Boolean
Value
0
-
+
HostID
Comment
@@ -4602,7 +4602,7 @@
Boolean
Value
0
-
+
IgnorePixelDepth
Comment
@@ -4657,7 +4657,7 @@
F32
Value
0.5
-
+
InspectorShowTime
Comment
@@ -4668,7 +4668,7 @@
F32
Value
3.0
-
+
InstallLanguage
Comment
@@ -5230,7 +5230,7 @@
Value
0.0.0
-
+
LastSnapshotToProfileHeight
Comment
@@ -6309,7 +6309,7 @@
Boolean
Value
0
-
+
MenuAccessKeyTime
Comment
@@ -6474,7 +6474,7 @@
Boolean
Value
0
-
+
MouseSun
Comment
@@ -6639,7 +6639,7 @@
String
Value
-
+
NextLoginLocation
Comment
@@ -6763,7 +6763,7 @@
String
Value
toast
-
+
NotificationFriendIMOptions
Comment
@@ -6819,7 +6819,7 @@
String
Value
toast
-
+
NotificationObjectIMOptions
Comment
@@ -6833,7 +6833,7 @@
String
Value
toast
-
+
NotificationToastLifeTime
Comment
@@ -7392,7 +7392,7 @@
Boolean
Value
0
-
+
PlaySoundFriendIM
Comment
@@ -7503,7 +7503,7 @@
Value
0.9
-
+
PlainTextChatHistory
Comment
@@ -7515,7 +7515,7 @@
Value
0
-
+
PluginInstancesLow
Comment
@@ -7769,7 +7769,7 @@
0.4
-
+
PreviewDirection2
Comment
@@ -8081,7 +8081,7 @@
Type
F32
Value
- 5.0
+ 10.0
MediaRollOffMax
@@ -8379,7 +8379,7 @@
RenderComplexityStaticMax
Comment
- Sets a static max value for scaling of RenderComplexity
+ Sets a static max value for scaling of RenderComplexity
display (-1 for dynamic scaling)
Persist
1
@@ -8457,7 +8457,7 @@
Value
0
-
+
RenderLocalLights
Comment
@@ -8684,7 +8684,7 @@
Persist
1
Type
- Boolean
+ Boolean
Value
0
@@ -8721,7 +8721,7 @@
Value
0
-
+
RenderAnimateRes
Comment
@@ -8894,7 +8894,7 @@
Value
0
-
+
RenderDepthOfField
Comment
@@ -9023,7 +9023,7 @@
Value
0.1
-
+
RenderHighlightBrightness
Comment
@@ -9047,7 +9047,7 @@
Value
0.6
-
+
RenderHighlightColor
Comment
@@ -9076,7 +9076,7 @@
Value
0
-
+
RenderSpecularResX
Comment
@@ -9981,7 +9981,7 @@
Value
1
-
+
RenderAutoMuteByteLimit
Comment
@@ -10036,7 +10036,7 @@
Boolean
Value
0
-
+
RenderAutoHideSurfaceAreaLimit
Comment
@@ -10522,7 +10522,7 @@
Boolean
Value
0
-
+
SelectMovableOnly
Comment
@@ -10764,7 +10764,7 @@
Boolean
Value
1
-
+
ShowCrosshairs
Comment
@@ -10841,7 +10841,7 @@
Boolean
Value
0
-
+
ShowMiniMapButton
Comment
@@ -10908,7 +10908,7 @@
Value
1
- ShowObjectRenderingCost
+ ShowObjectRenderingCost
Comment
Show the object rendering cost in build tools
@@ -10917,9 +10917,9 @@
Type
Boolean
Value
- 1
-
- ShowNavbarFavoritesPanel
+ 1
+
+ ShowNavbarFavoritesPanel
Comment
Show/hide navigation bar favorites panel
@@ -10928,9 +10928,9 @@
Type
Boolean
Value
- 1
+ 1
- ShowNavbarNavigationPanel
+ ShowNavbarNavigationPanel
Comment
Show/hide navigation bar navigation panel
@@ -10939,7 +10939,7 @@
Type
Boolean
Value
- 1
+ 1
ShowWorldMapButton
@@ -11095,7 +11095,7 @@
Value
1
- ShowPGSearchAll
+ ShowPGSearchAll
Comment
Display results of search All that are flagged as general
@@ -11611,7 +11611,7 @@
S32
Value
0
-
+
SnapshotQuality
Comment
@@ -12480,7 +12480,7 @@
String
Value
B56AF90D-6684-48E4-B1E4-722D3DEB2CB6
-
+
NearByChatChannelUUID
Comment
@@ -12491,7 +12491,7 @@
String
Value
E1158BD6-661C-4981-9DAD-4DCBFF062502
-
+
NotificationChannelUUID
Comment
@@ -12502,7 +12502,7 @@
String
Value
AEED3193-8709-4693-8558-7452CCA97AE5
-
+
AlertChannelUUID
Comment
@@ -12513,7 +12513,7 @@
String
Value
F3E07BC8-A973-476D-8C7F-F3B7293975D1
-
+
UIImgWhiteUUID
Comment
@@ -12535,7 +12535,7 @@
S32
Value
2
-
+
UIMaxComboWidth
Comment
@@ -13448,7 +13448,7 @@
String
Value
[i800,i600]
-
+
sourceid
Comment
@@ -14669,7 +14669,7 @@
Boolean
Value
1
-
+
EnablePlaceProfile
Comment
@@ -15491,7 +15491,7 @@
Value
0
-
+
PathfindingLineWidth
Comment
@@ -15532,7 +15532,7 @@
1.0
-
+
HideUIControls
Comment
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
deleted file mode 100644
index badbe486b9..0000000000
--- a/indra/newview/gpu_table.txt
+++ /dev/null
@@ -1,663 +0,0 @@
-//GPU_TABLE - that token on line 1 tags this as a gpu table file
-//
-// Categorizes graphics chips into various classes by name
-//
-// The table contains regular expressions to match
-// against driver strings, a class number, and whether we claim
-// to support them or not.
-//
-// Case is not significant in either the regular expressions or the
-// driver strings; the recognizer code lowercases both before using
-// them.
-//
-// If you modify this table, use the (perl) gpu_table_tester
-// to compare the results of recognizing known cards (it is easy
-// to mess this up by putting things in the wrong order):
-//
-// perl ../../scripts/gpu_table_tester -g gpu_table.txt tests/gpus_seen.txt | diff - tests/gpus_results.txt
-//
-// Format:
-// Fields are separated by one or more tab (not space) characters
-//
-//
-// Class Numbers:
-// 0 - Defaults to low graphics settings. No shaders on by default
-// 1 - Defaults to low-mid graphics settings. Basic shaders on by default
-// 2 - Defaults to mid graphics settings. Atmospherics on by default
-// 3 - Defaults to mid-high graphics settings. Advanced Lighting Model on by default
-// 4 - Defaults to high graphics settings. Ambient Occlusion on by default
-// 5 - Defaults to high-ultra graphics settings. Shadows set to "Sun/Moon+Projectors."
-//
-// Supported Number:
-// 0 - We claim to not support this card.
-// 1 - We claim to support this card.
-//
-
-3Dfx .*3Dfx.* 0 0 0 0
-3Dlabs .*3Dlabs.* 0 0 0 0
-Hijacker .*Mohr.*Hijacker.* 0 0 0 0
-ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0
-ATI ARES .*ATI.*ARES.* 0 0 0 0
-ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0
-ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0
-ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0
-ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 0 2.1
-ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3
-ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0
-ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1
-ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0
-ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0
-ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0
-ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0
-ATI Radeon X1300 .*ATI.*(Radeon|Diamond|ASUS) *X13.* ?.* 2 1 1 2.1
-ATI Radeon X1400 .*ATI.*(Radeon|Diamond|ASUS) *X14.* ?.* 2 1 1 2.1
-ATI Radeon X1500 .*ATI.*(Radeon|Diamond|ASUS) *X15.* ?.* 2 1 1 2.1
-ATI Radeon X1600 .*ATI.*(Radeon|Diamond|ASUS) *X16.* ?.* 2 1 1 2.1
-ATI Radeon X1700 .*ATI.*(Radeon|Diamond|ASUS) *X17.* ?.* 2 1 1 2.1
-ATI Radeon X1800 .*ATI.*(Radeon|Diamond|ASUS) *X18.* ?.* 3 1 1 2.1
-ATI Radeon X1900 .*ATI.*(Radeon|Diamond|ASUS) *X19.* ?.* 2 1 1 2.1
-ATI Radeon X2800 .*ATI.*(Radeon|Diamond|ASUS) *X28.* ?.* 2 1 1 2.1
-ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1
-ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1
-ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3
-ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2
-ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 0 4.1
-ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0
-ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0
-ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2
-ATI FireMV .*ATI.*FireMV.* 0 1 1 3.2
-ATI Generic .*ATI.*Generic.* 0 0 0 0
-ATI Hercules 9800 .*ATI.*Hercules.* 9800.* 1 1 0 0
-ATI IGP 340M .*ATI.*IGP.* 34[0-9]M.* 0 0 0 1.3
-ATI M52 .*ATI.*M52.* 1 1 0 0
-ATI M54 .*ATI.*M54.* 1 1 0 0
-ATI M56 .*ATI.*M56.* 1 1 0 0
-ATI M71 .*ATI.*M71.* 1 1 0 0
-ATI M72 .*ATI.*M72.* 1 1 0 0
-ATI M76 .*ATI.*M76.* 3 1 0 0
-ATI Mobility Radeon 4100 .*ATI.*Mobility.* 41.. 1 1 1 3.3
-ATI Mobility Radeon 5000 .*ATI.*Mobility.* 50.. 1 1 1 4.2
-ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3
-ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0
-ATI Mobility Radeon 9800 .*ATI.*Mobility.* 98.* 1 1 0 0
-ATI Mobility Radeon 9700 .*ATI.*Mobility.* 97.* 0 1 1 2.1
-ATI Mobility Radeon 9600 .*ATI.*Mobility.* 96.* 1 1 1 2.1
-ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD 530v.* 1 1 1 3.3
-ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD 540v.* 1 1 1 3.3
-ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD 545v.* 2 1 1 4
-ATI Mobility Radeon HD 550v .*ATI.*Mobility.*HD 550v.* 3 1 1 4
-ATI Mobility Radeon HD 560v .*ATI.*Mobility.*HD 560v.* 3 1 1 3.2
-ATI Mobility Radeon HD 565v .*ATI.*Mobility.*HD 565v.* 3 1 1 3.3
-ATI Mobility Radeon HD 2300 .*ATI.*Mobility.*HD 23.* 0 1 1 2.1
-ATI Mobility Radeon HD 2400 .*ATI.*Mobility.*HD 24.* 1 1 1 3.3
-ATI Mobility Radeon HD 2600 .*ATI.*Mobility.*HD 26.* 1 1 1 3.3
-ATI Mobility Radeon HD 2700 .*ATI.*Mobility.*HD 27.* 3 1 0 0
-ATI Mobility Radeon HD 3100 .*ATI.*Mobility.*HD 31.* 0 1 0 0
-ATI Mobility Radeon HD 3200 .*ATI.*Mobility.*HD 32.* 0 1 0 0
-ATI Mobility Radeon HD 3400 .*ATI.*Mobility.*HD 34.* 1 1 1 4
-ATI Mobility Radeon HD 3600 .*ATI.*Mobility.*HD 36.* 1 1 1 4
-ATI Mobility Radeon HD 3800 .*ATI.*Mobility.*HD 38.* 3 1 1 3.3
-ATI Mobility Radeon HD 4200 .*ATI.*Mobility.*HD 42.* 1 1 1 4
-ATI Mobility Radeon HD 4300 .*ATI.*Mobility.*(HD |HD)43.* 1 1 1 4
-ATI Mobility Radeon HD 4500 .*ATI.*Mobility.*HD 45.* 1 1 1 4
-ATI Mobility Radeon HD 4600 .*ATI.*Mobility.*HD 46.* 2 1 1 3.3
-ATI Mobility Radeon HD 4800 .*ATI.*Mobility.*HD 48.* 3 1 1 3.3
-ATI Mobility Radeon HD 5000 Series .*ATI.*Mobility.*HD 50.* 3 1 1 3.2
-ATI Mobility Radeon HD 5100 .*ATI.*Mobility.*HD 51.* 3 1 1 3.2
-ATI Mobility Radeon HD 5300 .*ATI.*Mobility.*HD 53.* 3 1 0 0
-ATI Mobility Radeon HD 5400 .*ATI.*Mobility.*HD 54.* 2 1 1 4.2
-ATI Mobility Radeon HD 5500 .*ATI.*Mobility.*HD 55.* 3 1 0 4.2
-ATI Mobility Radeon HD 5600 .*ATI.*Mobility.*HD 56.* 3 1 1 4.2
-ATI Mobility Radeon HD 5700 .*ATI.*Mobility.*HD 57.* 3 1 1 4.1
-ATI Mobility Radeon X1000 .*ATI.*Mobility.*Radeon ?X1..* 2 1 0 2.1
-ATI Mobility Radeon X1200 .*ATI.*Mobility.*Radeon ?X12.* 2 1 0 2.1
-ATI Mobility Radeon X2000 .*ATI.*Mobility.*Radeon ?X20.* 2 1 0 2.1
-ATI Mobility Radeon X2300 .*ATI.*Mobility.*Radeon ?X23.* 2 1 0 2.1
-ATI Mobility Radeon X2500 .*ATI.*Mobility.*Radeon ?X25.* 2 1 0 2.1
-ATI Mobility Radeon XX000 .*ATI.*Mobility.*Radeon ?Xx.* 2 1 0 2.1
-ATI Radeon HD 5xx .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)5x. 1 1 1 4
-ATI Radeon HD 6200D/G/M .*ATI.*AMD Radeon.* (HD|HD )62..[DGM].* 3 1 0 4.2
-ATI Radeon HD 6300D/G/M .*ATI.*AMD Radeon.* (HD|HD )63..[DGM].* 3 1 1 4.2
-ATI Radeon HD 6400D/G/M .*ATI.*AMD Radeon.* (HD|HD )64..[DGM].* 3 1 0 4.2
-ATI Radeon HD 6500D/G/M .*ATI.*AMD Radeon.* (HD|HD )65..[DGM].* 4 1 1 4.2
-ATI Radeon HD 6600D/G/M .*ATI.*AMD Radeon.* (HD|HD )66..[DGM].* 4 1 0 4.2
-ATI Radeon HD 6700D/G/M .*ATI.*AMD Radeon.* (HD|HD )67..[DGM].* 4 1 0 4.2
-ATI Radeon HD 6800D/G/M .*ATI.*AMD Radeon.* (HD|HD )68..[DGM].* 4 1 0 4.2
-ATI Radeon HD 6900D/G/M .*ATI.*AMD Radeon.* (HD|HD )69..[DGM].* 4 1 0 4.2
-ATI Radeon HD 7200D/G/M .*ATI.*AMD Radeon.* (HD|HD )72..[DGM].* 3 1 0 4.2
-ATI Radeon HD 7300D/G/M .*ATI.*AMD Radeon.* (HD|HD )73..[DGM].* 3 1 0 4.2
-ATI Radeon HD 7400D/G/M .*ATI.*AMD Radeon.* (HD|HD )74..[DGM].* 3 1 0 4.2
-ATI Radeon HD 7500D/G/M .*ATI.*AMD Radeon.* (HD|HD )75..[DGM].* 4 1 0 4.2
-ATI Radeon HD 7600D/G/M .*ATI.*AMD Radeon.* (HD|HD )76..[DGM].* 4 1 0 4.2
-ATI Radeon HD 7700D/G/M .*ATI.*AMD Radeon.* (HD|HD )77..[DGM].* 4 1 0 4.2
-ATI Radeon HD 7800D/G/M .*ATI.*AMD Radeon.* (HD|HD )78..[DGM].* 4 1 0 4.2
-ATI Radeon HD 7900D/G/M .*ATI.*AMD Radeon.* (HD|HD )79..[DGM].* 4 1 0 4.2
-ATI Radeon HD 8200D/G/M .*ATI.*AMD Radeon.* (HD|HD )82..[DGM].* 3 1 0 4.2
-ATI Radeon HD 8300D/G/M .*ATI.*AMD Radeon.* (HD|HD )83..[DGM].* 3 1 0 4.2
-ATI Radeon HD 8400D/G/M .*ATI.*AMD Radeon.* (HD|HD )84..[DGM].* 4 1 0 4.2
-ATI Radeon HD 8500D/G/M .*ATI.*AMD Radeon.* (HD|HD )85..[DGM].* 4 1 0 4.2
-ATI Radeon HD 8600D/G/M .*ATI.*AMD Radeon.* (HD|HD )86..[DGM].* 4 1 0 4.2
-ATI Radeon HD 8700D/G/M .*ATI.*AMD Radeon.* (HD|HD )87..[DGM].* 4 1 0 4.2
-ATI Radeon HD 8800D/G/M .*ATI.*AMD Radeon.* (HD|HD )88..[DGM].* 4 1 0 4.2
-ATI Radeon HD 8900D/G/M .*ATI.*AMD Radeon.* (HD|HD )89..[DGM].* 4 1 0 4.2
-ATI Radeon HD 2300 .*ATI.*Radeon.* (HD|HD )23.. 0 1 1 3.3
-ATI Radeon HD 2400 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)24.. 1 1 1 4
-ATI Radeon HD 2600 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)26.. 2 1 1 4
-ATI Radeon HD 2900 .*ATI.*Radeon.* (HD|HD )29.. 3 1 1 3.3
-ATI Radeon HD 3000 .*ATI.*Radeon.* (HD|HD )30.. 0 1 0 0
-ATI Radeon HD 3100 .*ATI.*Radeon.* (HD|HD )31.. 1 1 0 0
-ATI Radeon HD 3200 .*ATI.*Radeon.* (HD|HD )32.. 1 1 1 4
-ATI Radeon HD 3300 .*ATI.*Radeon.* (HD|HD )33.. 1 1 1 3.3
-ATI Radeon HD 3400 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |AH||AX|EAH)34.. 1 1 1 4
-ATI Radeon HD 3500 .*ATI.*Radeon.* (HD|HD )35.. 2 1 0 0
-ATI Radeon HD 3600 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |AH||AX|EAH)36.. 3 1 1 4
-ATI Radeon HD 3700 .*ATI.*Radeon.* (HD|HD )37.. 3 1 0 3.3
-ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3
-ATI Radeon HD 3800 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH|AX|)38.. 3 1 1 4
-ATI Radeon HD 4100 .*ATI.*Radeon.* (HD|HD )41.. 1 1 0 0
-ATI Radeon HD 4200 .*ATI.*Radeon.* (HD|HD )42.. 1 1 1 4
-ATI Radeon HD 4300 .*ATI.*(Radeon|ASUS).* (AH|AX|HD4|HD 4|EAH4|4)3.. 2 1 1 4
-ATI Radeon HD 4400 .*ATI.*Radeon.* (HD|HD )44.. 2 1 0 0
-ATI Radeon HD 4500 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)45.. 2 1 1 3.3
-ATI RADEON E4690 .*ATI.*RADEON.* E46.. 3 1 1 4
-ATI Radeon HD 4600 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)46.. 3 1 1 4
-ATI Radeon HD 4700 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)47.. 3 1 1 3.3
-ATI Radeon HD 4800 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)48.. 3 1 1 4
-ATI Radeon HD 5000 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)50.. 3 1 1 4.2
-ATI Radeon HD 5400 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)54.. 3 1 1 4.2
-ATI Radeon HD 5500 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)55.. 3 1 1 4.2
-ATI Radeon HD 5600 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)56.. 3 1 1 4.2
-ATI Radeon HD 5700 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)57.. 3 1 1 4.2
-ATI Radeon HD 5800 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)58.. 4 1 1 4.2
-ATI Radeon HD 5900 .*ATI.*Radeon.* (HD|HD )59.. 4 1 1 4.2
-ATI Radeon HD 6200 .*ATI.*Radeon.* (HD|HD )62.. 0 1 1 4.2
-ATI Radeon HD 6300 .*ATI.*Radeon.* (HD|HD )63.. 1 1 1 4.2
-ATI Radeon HD 6400 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)64.. 3 1 1 4.2
-ATI Radeon HD 6500 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)65.. 3 1 1 4.2
-ATI Radeon HD 6600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)66.. 3 1 1 4.2
-ATI Radeon HD 6700 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)67.. 3 1 1 4.2
-ATI Radeon HD 6800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)68.. 4 1 1 4.2
-ATI Radeon HD 6900 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)69.. 5 1 1 4.2
-ATI Radeon HD 6x00 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)6x.. 5 1 1 4.2
-ATI Radeon HD 7100 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)71.* 2 1 0 0
-ATI Radeon HD 7200 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)72.* 2 1 0 4.2
-ATI Radeon HD 7300 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)73.* 2 1 0 4.2
-ATI Radeon HD 7400 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)74.* 2 1 0 4.2
-ATI Radeon HD 7500 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)75.* 3 1 1 4.2
-ATI Radeon HD 7600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)76.* 3 1 0 4.2
-ATI Radeon HD 7700 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)77.* 4 1 1 4.2
-ATI Radeon HD 7800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)78.* 5 1 1 4.2
-ATI Radeon HD 7900 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)79.* 5 1 1 4.2
-ATI Radeon HD 7000 Series .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)7000 Series.* 3 1 1 4.2
-ATI Radeon HD 8200 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)82.* 2 1 0 4.2
-ATI Radeon HD 8300 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)83.* 2 1 0 4.2
-ATI Radeon HD 8400 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)84.* 2 1 0 4.2
-ATI Radeon HD 8500 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)85.* 3 1 1 4.2
-ATI Radeon HD 8600 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)86.* 3 1 0 4.2
-ATI Radeon HD 8700 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)87.* 4 1 1 4.2
-ATI Radeon HD 8800 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)88.* 5 1 1 4.2
-ATI Radeon HD 8900 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)89.* 5 1 1 4.2
-ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0
-ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1
-ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4
-ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3
-ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0
-ATI Radeon 6xxx .*ATI.*Radeon 6... 0 1 0 0
-ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2
-ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0
-ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3
-ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0
-ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3
-ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1
-ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1
-ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0
-ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1
-ATI Radeon R7 .*ATI.*(Radeon|ASUS).* R7.* 4 1 0 4.2
-ATI Radeon R9 .*ATI.*(Radeon|ASUS).* R9.* 5 1 0 4.2
-ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0
-ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0
-ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0
-ATI Radeon RX800 .*ATI.*Radeon RX80.* 2 1 0 0
-ATI RS880M .*ATI.*RS880M 1 1 0 0
-ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0
-ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0
-ATI Radeon X300 .*ATI.*Radeon X3.* 1 1 1 2.1
-ATI RADEON X300SE .*ATI.*RADEON[ ]*X300SE* 1 1 1 2.1
-ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0
-ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1
-ATI Radeon X600 .*ATI.*(Radeon |ASUS Extreme A)X6.* 1 1 1 2.1
-ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1
-ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1
-ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0
-ATI Radeon X1000 .*ATI.*Radeon ?X10.* 2 1 0 2.1
-ATI Radeon X1100 .*ATI.*Radeon ?X11.* 2 1 0 2.1
-ATI Radeon X1200 .*ATI.*Radeon ?X12.* 2 1 0 2.1
-ATI Radeon X1xxx .*ATI.*Radeon ?X1xx.* 2 1 0 2.1
-ATI Radeon X12xx .*ATI.*Radeon ?X12x.* 2 1 0 2.1
-ATI Radeon X2xxx .*ATI.*Radeon ?X2x.* 2 1 0 2.1
-ATI Radeon X2300 .*ATI.*Radeon ?X23.* 2 1 0 2.1
-ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1
-ATI Radeon .*ATI.*Radeon$ 3 1 0 0
-ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0
-ATI R300 (9700) .*R300.* 0 1 1 2.1
-ATI R350 (9800) .*R350.* 1 1 0 0
-ATI R580 (X1900) .*R580.* 3 1 0 0
-ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0
-ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0
-ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0
-ATI RV350 (9600) .*RV350.* 0 1 0 0
-ATI RV370 (X300) .*RV370.* 0 1 0 0
-ATI RV410 (X700) .*RV410.* 1 1 0 0
-ATI RV515 .*RV515.* 1 1 0 0
-ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0
-ATI RV380 .*RV380.* 0 1 0 0
-ATI RV530 .*RV530.* 1 1 0 0
-ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0
-ATI RX700 .*RX700.* 1 1 0 0
-AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0
-ATI ROBSON .*(AMD|ATI).*ROBSON.* 3 1 0 4
-AMD ARUBA (HD 6800) .*(AMD|ATI).*ARUBA.* 3 1 1 2.1
-AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1
-AMD BA (HD 6800) .*(AMD|ATI).*BA.* 3 1 1 2.1
-AMD WRESTLER .*(AMD|ATI).*WRESTLER.* 3 1 1 4
-AMD SUMO .*(AMD|ATI).*SUMO.* 3 1 1 4.1
-AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0
-AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0
-AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1 0 2.1
-AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0
-AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0
-AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0
-AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0
-AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 0 1.4
-AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 0 2.1
-AMD PITCAIRN (HD 7870) .*(AMD|ATI).*Pitcairn.* 3 1 0 2.1
-AMD TAHITI (HD 7000) .*(AMD|ATI).*Tahiti.* 3 1 0 2.1
-AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1
-AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2
-AMD RV610 (HD 2400) .*RV610.* 1 1 0 0
-AMD RV620 (HD 3400) .*RV620.* 1 1 0 0
-AMD RV630 (HD 2600) .*RV630.* 2 1 0 0
-AMD RV635 (HD 3600) .*RV635.* 3 1 0 1.4
-AMD RV670 (HD 3800) .*RV670.* 3 1 0 0
-AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0
-AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0
-AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4
-AMD RV730 (HD 4600) .*RV730.* 3 1 0 1.4
-AMD RV740 (HD 4700) .*RV740.* 3 1 0 0
-AMD RV770 (HD 4800) .*RV770.* 3 1 0 0
-AMD RV790 (HD 4800) .*RV790.* 3 1 0 0
-ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3
-ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0
-ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0
-ATI FirePro 2000 .*ATI.*FirePro [V]*2.* 2 1 1 4.2
-ATI FirePro 3000 .*ATI.*FirePro [V]*3.* 2 1 0 0
-ATI FirePro 4000 .*ATI.*FirePro [V]*4.* 2 1 0 4.1
-ATI FirePro 5000 .*ATI.*FirePro [V]*5.* 3 1 0 0
-ATI FirePro 7000 .*ATI.*FirePro [V]*7.* 3 1 0 0
-ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2
-Intel X3100 .*Intel.*X3100.* 1 1 1 2.1
-Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3
-Intel Royal BNA .*Intel.*Royal[ ]*BNA.* 0 0 0 0
-Intel 830M .*Intel.*830M 0 0 0 0
-Intel 845G .*Intel.*845G 0 0 1 1.4
-Intel 855GM .*Intel.*855GM 0 0 1 1.4
-Intel 865G .*Intel.*865G 0 0 1 1.4
-Intel 900 .*Intel.*900.*900 0 0 0 0
-Intel 915GM .*Intel.*915GM 0 0 1 1.4
-Intel 915G .*Intel.*915G 0 0 1 1.4
-Intel 945GM .*Intel.*945GM.* 0 1 1 1.4
-Intel 945G .*Intel.*945G.* 0 1 1 1.4
-Intel 950 .*Intel.*950.* 0 1 1 1.4
-Intel 965 .*Intel.*965.* 0 1 1 2.1
-Intel G33 .*Intel.*G33.* 1 0 1 1.4
-Intel G41 .*Intel.*G41.* 1 1 1 2.1
-Intel G45 .*Intel.*G45.* 1 1 1 2.1
-Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4
-Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4
-Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3
-Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2
-Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2
-Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1
-Intel HD Graphics 2500 .*Intel.*HD Graphics 25.* 2 1 0 4.2
-Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 3.1
-Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1
-Intel HD Graphics 4200 .*Intel.*HD Graphics 42.* 3 1 0 4.2
-Intel HD Graphics 4400 .*Intel.*HD Graphics 44.* 3 1 0 4.2
-Intel HD Graphics 4600 .*Intel.*HD Graphics 46.* 3 1 0 4.2
-Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4.2
-Intel Intel Iris Pro Graphics 5200 .*Intel.*Iris Pro Graphics 52.* 4 1 0 4
-Intel Intel Iris Graphics 5100 .*Intel.*Iris Graphics 51.* 4 1 0 4
-Intel Intel Iris OpenGL Engine .*Intel.*Iris OpenGL.* 4 1 0 4
-Intel Intel Iris Pro OpenGL Engine .*Intel.*Iris Pro OpenGL.* 5 1 0 4
-Intel HD Graphics 5000 .*Intel.*HD Graphics 5.* 4 1 0 4
-Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4
-Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1
-Intel Mobile 45 Express .*Intel.*Mobile.* 45 Express Chipset.* 0 1 0 2.1
-Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1
-Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0
-Intel Montara .*Intel.*Montara.* 0 0 1 1.3
-Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4
-Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3
-Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0
-Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1
-Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1
-Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0
-Matrox .*Matrox.* 0 0 0 0
-Mesa .*Mesa.* 1 0 1 3
-Gallium .*Gallium.* 1 1 1 2.1
-NVIDIA GeForce Pre-Release .*NVIDIA .*GeForce[ ]Pre-Release.* 2 1 1 3.3
-NVIDIA D1xP1 .*NVIDIA .*D1[0-4]P1.* 0 0 0 0
-NVIDIA Mystery PCI Card .*NVIDIA .Corporation [/]PCI]/]SSE2.* 0 0 0 0
-NVIDIA Quadro FX 770M .*Quadro.*FX 77[0-9]M.* 2 1 0 3.3
-NVIDIA Quadro FX 1500M .*Quadro.*FX 150[0-9]M.* 1 1 0 2.1
-NVIDIA Quadro FX 1600M .*Quadro.*FX 160[0-9]M.* 2 1 0 3.3
-NVIDIA Quadro FX 2500M .*Quadro.*FX 250[0-9]M.* 2 1 0 2.1
-NVIDIA Quadro FX 2700M .*Quadro.*FX 270[0-9]M.* 3 1 0 3.3
-NVIDIA Quadro FX 2800M .*Quadro.*FX 280[0-9]M.* 3 1 0 3.3
-NVIDIA Quadro FX 3500 .*Quadro.*FX 3500.* 2 1 0 2.1
-NVIDIA Quadro FX 3600 .*Quadro.*FX 3600.* 3 1 0 3.3
-NVIDIA Quadro FX 3700 .*Quadro.*FX 3700.* 3 1 0 3.3
-NVIDIA Quadro FX 3800 .*Quadro.*FX 3800.* 3 1 0 3.3
-NVIDIA Quadro FX 4500 .*Quadro.*FX 45.* 3 1 0 2.1
-NVIDIA Quadro FX 880M .*Quadro.*FX 88[0-9]M.* 3 1 0 3.3
-NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro FX 4800.* 3 1 0 3.1
-NVIDIA Quadro FX .*NVIDIA .*Quadro FX.* 1 1 0 3.3
-NVIDIA Quadro NVS 1xxM .*NVIDIA .*(Quadro)* NVS *1.[05]M.* 0 1 1 3.3
-NVIDIA Quadro NVS 300M .*NVIDIA .*(Quadro)*[ ]+NVS *30[0-9]M.* 2 1 0 0
-NVIDIA Quadro NVS 320M .*NVIDIA .*(Quadro)*[ ]+NVS *32[0-9]M.* 2 1 0 0
-NVIDIA Quadro NVS 2100M .*NVIDIA .*(Quadro)*[ ]+NVS *210[0-9]M.* 2 1 0 3.3
-NVIDIA Quadro NVS 3100M .*NVIDIA .*(Quadro)*[ ]+NVS *310[0-9]M.* 2 1 0 3.3
-NVIDIA Quadro NVS 4200M .*NVIDIA .*(Quadro)*[ ]+NVS *420[0-9]M.* 2 1 0 4.2
-NVIDIA Quadro NVS 5100M .*NVIDIA .*(Quadro)*[ ]+NVS *510[0-9]M.* 2 1 0 0
-NVIDIA Quadro NVS 5200M .*NVIDIA .*(Quadro)*[ ]+NVS *520[0-9]M.* 2 1 0 0
-NVIDIA Quadro NVS 5400M .*NVIDIA .*(Quadro)*[ ]+NVS *540[0-9]M.* 2 1 0 0
-NVIDIA Quadro NVS .*NVIDIA .*(Quadro)*[ ]+NVS 0 1 0 4.2
-NVIDIA Quadro2 .*Quadro2.* 0 1 0 1.5
-NVIDIA Quadro 1000M .*Quadro.* (K1|1)00[0-9]M.* 2 1 0 4.2
-NVIDIA Quadro 1100M .*Quadro.* *110[0-9]M.* 2 1 0 3.3
-NVIDIA Quadro K600 .*Quadro.* (K6|6)0[0-9][^0].* 2 1 0 4.2
-NVIDIA Quadro K1000 .*Quadro.* (K1|1)00[0-9].* 2 1 0 4.2
-NVIDIA Quadro 2000 M/D .*Quadro.* (K2|2)000.* 3 1 0 4.2
-NVIDIA Quadro 3000M .*Quadro.* (K3|3)00[0-9]M.* 3 1 0 4.2
-NVIDIA Quadro 4000M .*Quadro.* (K4|4)00[0-9]M.* 3 1 0 4.2
-NVIDIA Quadro 4000 .*Quadro.* (K4|4)000.* 3 1 0 4.2
-NVIDIA Quadro 50x0 M .*Quadro.* (K5|5)0.0.* 3 1 0 4.2
-NVIDIA Quadro 6000 .*Quadro.* (K6|6)000.* 3 1 0 0
-NVIDIA Quadro 400 .*Quadro.* 400.* 2 1 0 3.3
-NVIDIA Quadro 600 .*Quadro.* 600.* 2 1 0 4.2
-NVIDIA Quadro4 .*Quadro4.* 0 1 0 1.5
-NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0
-NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0
-NVIDIA G 100M .*NVIDIA .*G *10[0-9]M.* 1 1 1 3.3
-NVIDIA G 110M .*NVIDIA .*G *11[0-9]M.* 1 1 1 3.3
-NVIDIA G 120M .*NVIDIA .*G *12[0-9]M.* 1 1 1 3.3
-NVIDIA G 200M .*NVIDIA .*G *20[0-9]M.* 1 1 0 0
-NVIDIA G 410M .*NVIDIA .*G *41[0-9]M.* 3 1 1 4.2
-NVIDIA GT 130M .*NVIDIA .*GT *13[0-9]M.* 3 1 1 3.3
-NVIDIA GT 140M .*NVIDIA .*GT *14[0-9]M.* 3 1 1 3.3
-NVIDIA GT 150M .*NVIDIA .*GTS *15[0-9]M.* 2 1 0 0
-NVIDIA GTS 160M .*NVIDIA .*GTS *16[0-9]M.* 2 1 0 0
-NVIDIA G210M .*NVIDIA .*G *21[0-9]M.* 3 1 0 3.3
-NVIDIA GT 220M .*NVIDIA .*GT 22[0-9]M.* 3 1 1 3.3
-NVIDIA GT 230M .*NVIDIA .*GT 23[0-9]M.* 3 1 1 3.3
-NVIDIA GT 240M .*NVIDIA .*GT 24[0-9]M.* 3 1 1 3.3
-NVIDIA GT 260M .*NVIDIA .*GT 26[0-9]M.* 3 1 1 3.3
-NVIDIA GTS 250M .*NVIDIA .*GTS 25[0-9]M.* 3 1 0 3.3
-NVIDIA GTS 260M .*NVIDIA .*GTS 26[0-9]M.* 3 1 0 0
-NVIDIA GTX 260M .*NVIDIA .*GTX 26[0-9]M.* 3 1 0 3.3
-NVIDIA GTX 270M .*NVIDIA .*GTX 27[0-9]M.* 3 1 0 0
-NVIDIA GTX 280M .*NVIDIA .*GTX 28[0-9]M.* 3 1 0 3.3
-NVIDIA 300M .*NVIDIA .*GT 30[0-9]M.* 3 1 1 4.2
-NVIDIA G 310M .*NVIDIA .*G[T]* 31[0-9]M.* 2 1 0 3.3
-NVIDIA GT 320M .*NVIDIA .*G[T]* 32[0-9]M.* 3 1 0 3.3
-NVIDIA GT 330M .*NVIDIA .*G[T]* 33[0-9]M.* 3 1 1 3.3
-NVIDIA GT 340M .*NVIDIA .*G[T]* 34[0-9]M.* 4 1 1 3.3
-NVIDIA GTS 350M .*NVIDIA .*GTS 35[0-9]M.* 4 1 1 3.3
-NVIDIA GTS 360M .*NVIDIA .*GTS 36[0-9]M.* 5 1 1 3.3
-NVIDIA 310M .*NVIDIA .*31[0-9]M.* 2 1 0 3.3
-NVIDIA 320M .*NVIDIA .*320M.* 2 1 0 3.3
-NVIDIA 400M .*NVIDIA .*[ ]+40[0-9]M.* 2 1 0 0
-NVIDIA 410M .*NVIDIA .*[ ]+41[0-9]M.* 3 1 0 0
-NVIDIA GT 420M .*NVIDIA .*GT *42[0-9]M.* 3 1 1 4.3
-NVIDIA GT 430M .*NVIDIA .*GT *43[0-9]M.* 3 1 1 4.3
-NVIDIA GT 440M .*NVIDIA .*GT *44[0-9]M.* 3 1 1 4.3
-NVIDIA GT 450M .*NVIDIA .*GT *45[0-9]M.* 3 1 0 0
-NVIDIA GTX 460M .*NVIDIA .*GTX *46[0-9]M.* 4 1 1 4.3
-NVIDIA GTX 470M .*NVIDIA .*GTX *47[0-9]M.* 3 1 0 4.3
-NVIDIA GTX 480M .*NVIDIA .*GTX *48[0-9]M.* 3 1 1 4.3
-NVIDIA GT 520M .*NVIDIA .*GT *52[0-9]M.* 3 1 1 4.3
-NVIDIA GT 530M .*NVIDIA .*GT *53[0-9]M.* 3 1 1 4.3
-NVIDIA GT 540M .*NVIDIA .*GT *54[0-9]M.* 3 1 1 4.3
-NVIDIA GT 550M .*NVIDIA .*GT *55[0-9]M.* 3 1 1 4.3
-NVIDIA GTX 560M .*NVIDIA .*GTX *56[0-9]M.* 3 1 0 4.3
-NVIDIA GTX 570M .*NVIDIA .*GTX *57[0-9]M.* 5 1 0 4.3
-NVIDIA GTX 580M .*NVIDIA .*GTX *58[0-9]M.* 5 1 1 4.3
-NVIDIA 610M .*NVIDIA.* 61[0-9]M.* 3 1 1 4.3
-NVIDIA GT 620M .*NVIDIA .*GT *62[0-9]M.* 3 1 0 4.3
-NVIDIA GT 630M .*NVIDIA .*GT *63[0-9]M.* 3 1 0 4.3
-NVIDIA GT 640M .*NVIDIA .*GT *64[0-9]M.* 3 1 0 4.3
-NVIDIA GT 650M .*NVIDIA .*GT *65[0-9]M.* 3 1 0 4.3
-NVIDIA GTX 660M .*NVIDIA .*GTX *66[0-9]M.* 5 1 0 4.3
-NVIDIA GTX 670M .*NVIDIA .*GTX *67[0-9]M.* 5 1 1 4.3
-NVIDIA GTX 680M .*NVIDIA .*GTX *68[0-9]M.* 5 1 0 4.3
-NVIDIA GTX 690M .*NVIDIA .*GTX *69[0-9]M.* 5 1 0 4.3
-NVIDIA 710M .*NVIDIA.* 71[0-9]M.* 3 1 0 4.3
-NVIDIA GT 720M .*NVIDIA .*GT *72[0-9]M.* 3 1 0 4.3
-NVIDIA GT 730M .*NVIDIA .*GT *73[0-9]M.* 3 1 0 4.3
-NVIDIA GT 740M .*NVIDIA .*GT *74[0-9]M.* 3 1 0 4.3
-NVIDIA GT 750M .*NVIDIA .*GT *75[0-9]M.* 3 1 0 4.3
-NVIDIA GTX 760M .*NVIDIA .*GTX *76[0-9]M.* 5 1 0 4.3
-NVIDIA GTX 770M .*NVIDIA .*GTX *77[0-9]M.* 5 1 0 4.3
-NVIDIA GTX 780M .*NVIDIA .*GTX *78[0-9]M.* 5 1 0 4.3
-NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2
-NVIDIA GT 120 .*NVIDIA .*GT 12.* 2 1 0 3.3
-NVIDIA GT 130 .*NVIDIA .*GT 13.* 2 1 0 3.3
-NVIDIA GT 140 .*NVIDIA .*GT 14.* 2 1 0 3.3
-NVIDIA GT 150 .*NVIDIA .*GT 15.* 2 1 1 3.3
-NVIDIA GTS 150 .*NVIDIA .*GTS 15.* 2 1 0 0
-NVIDIA 200 .*NVIDIA .[ ]+200[^0].* 2 1 1 3.3
-NVIDIA G200 .*NVIDIA .*G[ ]*200.* 2 1 1 3.3
-NVIDIA G210 .*NVIDIA .*G[ ]*210.* 3 1 1 3.3
-NVIDIA 205 .*NVIDIA .*205[^0]*.* 3 1 1 3.3
-NVIDIA 210 .*NVIDIA .*210$ 3 1 1 3.3
-NVIDIA GeForce 210 .*NVIDIA .*(GeForce)[ ]210[^0]*$ 3 1 1 3.3
-NVIDIA GT 220 .*NVIDIA .*GT *22.* 2 1 1 3.3
-NVIDIA GT 230 .*NVIDIA .*GT *23.* 2 1 1 3.3
-NVIDIA GT 240 .*NVIDIA .*GT *24.* 4 1 1 3.3
-NVIDIA GTS 240 .*NVIDIA .*GTS *24.* 4 1 1 3.3
-NVIDIA GTS 250 .*NVIDIA .*GTS *25.* 4 1 1 3.3
-NVIDIA GTS 360 .*NVIDIA .*GTS *36.* 4 1 1 3.3
-NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 4 1 1 3.3
-NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 4 1 0 3.3
-NVIDIA GTX 280 .*NVIDIA .*GTX *28.* 4 1 1 3.3
-NVIDIA GTX 290 .*NVIDIA .*GTX *29.* 5 1 0 3.3
-NVIDIA GT 320 .*NVIDIA .*GT *32.* 3 1 0 3.3
-NVIDIA GT 330 .*NVIDIA .*GT *33.* 3 1 0 3.3
-NVIDIA GT 340 .*NVIDIA .*GT *34.* 3 1 0 0
-NVIDIA 310 .*NVIDIA .*310[^0M]*.* 3 1 1 3.3
-NVIDIA 315 .*NVIDIA .*315[^0M]*.* 3 1 1 3.3
-NVIDIA 320 .*NVIDIA .*320[^0M]*.* 3 1 1 3.3
-NVIDIA 405 .*NVIDIA .*405[^0]*.* 3 1 0 3.3
-NVIDIA 410 .*NVIDIA .*410[^0]*.* 3 1 0 3.3
-NVIDIA GT 415 .*NVIDIA .*GT *415.* 3 1 1 4.3
-NVIDIA GT 420 .*NVIDIA .*GT *42.* 3 1 1 4.3
-NVIDIA GT 430 .*NVIDIA .*GT *43.* 3 1 1 4.3
-NVIDIA GT 440 .*NVIDIA .*GT *44.* 4 1 1 4.3
-NVIDIA GT 450 .*NVIDIA .*GT *45.* 4 1 1 4.3
-NVIDIA GTS 450 .*NVIDIA .*GTS *45.* 4 1 1 4.3
-NVIDIA GTX 460 .*NVIDIA .*GTX *46.* 5 1 1 4.3
-NVIDIA GTX 470 .*NVIDIA .*GTX *47.* 5 1 1 4.3
-NVIDIA GTX 480 .*NVIDIA .*GTX *48.* 5 1 1 4.3
-NVIDIA 505 .*NVIDIA .*505[^0]*.* 3 1 0 0
-NVIDIA 510 .*NVIDIA .*510[^0]*.* 3 1 0 0
-NVIDIA GT 520 .*NVIDIA .*GT *52.* 3 1 1 4.3
-NVIDIA GT 530 .*NVIDIA .*GT *53.* 3 1 1 4.3
-NVIDIA GT 540 .*NVIDIA .*GT *54.* 3 1 1 4.3
-NVIDIA GT 550 .*NVIDIA .*GT *55.* 3 1 1 4.3
-NVIDIA GTX 550 .*NVIDIA .*GTX *55.* 5 1 1 4.3
-NVIDIA GTX 560 .*NVIDIA .*GTX *56.* 5 1 1 4.3
-NVIDIA GTX 570 .*NVIDIA .*GTX *57.* 5 1 1 4.3
-NVIDIA GTX 580 .*NVIDIA .*GTX *58.* 5 1 1 4.3
-NVIDIA GTX 590 .*NVIDIA .*GTX *59.* 5 1 1 4.3
-NVIDIA 605 .*NVIDIA .*605[^0]*.* 3 1 1 4.3
-NVIDIA GT 61x .*NVIDIA .*GT 61.* 3 1 1 4.3
-NVIDIA GT 62x .*NVIDIA .*GT 62.* 3 1 0 4.3
-NVIDIA GT 63x .*NVIDIA .*GT 63.* 3 1 0 4.3
-NVIDIA GT 64x .*NVIDIA .*GT 64.* 3 1 0 4.3
-NVIDIA GT 65x .*NVIDIA .*GT 65.* 3 1 1 4.3
-NVIDIA GTX 64x .*NVIDIA .*GTX 64.* 3 1 1 4.3
-NVIDIA GTX 65x .*NVIDIA .*GTX 65.* 3 1 1 4.3
-NVIDIA GTX 66x .*NVIDIA .*GTX 66.* 5 1 0 4.3
-NVIDIA GTX 67x .*NVIDIA .*GTX 67.* 5 1 1 4.3
-NVIDIA GTX 68x .*NVIDIA .*GTX 68.* 5 1 1 4.3
-NVIDIA GTX 69x .*NVIDIA .*GTX 69.* 5 1 1 4.3
-NVIDIA GT 71x .*NVIDIA .*GT *71.* 3 1 0 4.3
-NVIDIA GT 72x .*NVIDIA .*GT *72.* 3 1 0 4.3
-NVIDIA GT 73x .*NVIDIA .*GT *73.* 3 1 0 4.3
-NVIDIA GT 74x .*NVIDIA .*GT *74.* 3 1 0 4.3
-NVIDIA GTX 75x .*NVIDIA .*GTX *75.* 3 1 0 4.3
-NVIDIA GTX 76x .*NVIDIA .*GTX *76.* 5 1 0 4.3
-NVIDIA GTX 77x .*NVIDIA .*GTX *77.* 5 1 0 4.3
-NVIDIA GTX 78x .*NVIDIA .*GTX *78.* 5 1 0 4.3
-NVIDIA GTX TITAN .*NVIDIA .*GTX *TITAN.* 5 1 0 4.3
-NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2
-NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0
-NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0
-NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0
-NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0
-NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0
-NVIDIA GK106 .*NVIDIA .*GK106.* 5 1 0 4.3
-NVIDIA GeForce .*GeForce 256.* 0 0 0 0
-NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5
-NVIDIA GeForce 3 .*GeForce ?3 ?.* 2 1 1 2.1
-NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 0 0
-NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5
-NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 0 0
-NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 0 0
-NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 0 0
-NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 0 0
-NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2
-NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1
-NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1
-NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1
-NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1
-NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1
-NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1
-NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1
-NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0
-NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1
-NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1
-NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1
-NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1
-NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1
-NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1 0 3.3
-NVIDIA GeForce 8200M .*NVIDIA .*GeForce 820[0-9]M.* 1 1 0 3.3
-NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 0 3.3
-NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3
-NVIDIA GeForce 8400M .*NVIDIA .*GeForce 840[0-9]M.* 1 1 1 3.3
-NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3
-NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3
-NVIDIA GeForce 8600M .*NVIDIA .*GeForce 860[0-9]M.* 2 1 1 3.3
-NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3
-NVIDIA GeForce 8700M .*NVIDIA .*GeForce 870[0-9]M.* 2 1 1 3.3
-NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0
-NVIDIA GeForce 8800M .*NVIDIA .*GeForce 880[0-9]M.* 2 1 1 3.3
-NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3
-NVIDIA GeForce 9100M .*NVIDIA .*GeForce 910[0-9]M.* 0 1 0 3.3
-NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3
-NVIDIA GeForce 9200M .*NVIDIA .*GeForce 920[0-9]M.* 1 1 0 3.3
-NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3
-NVIDIA GeForce 9300M .*NVIDIA .*GeForce 930[0-9]M.* 1 1 1 3.3
-NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3
-NVIDIA GeForce 9400M .*NVIDIA .*GeForce 940[0-9]M.* 2 1 1 3.3
-NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3
-NVIDIA GeForce 9500M .*NVIDIA .*GeForce 950[0-9]M.* 1 1 1 3.3
-NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3
-NVIDIA GeForce 9600M .*NVIDIA .*GeForce 960[0-9]M.* 2 1 1 3.3
-NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3
-NVIDIA GeForce 9700M .*NVIDIA .*GeForce 970[0-9]M.* 0 1 1 3.3
-NVIDIA GeForce 9800M .*NVIDIA .*GeForce 980[0-9]M.* 2 1 1 3.3
-NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3
-NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0
-NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1
-NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0
-NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1
-NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1
-NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1
-NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0
-NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1
-NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0
-NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1 0 1.5
-NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0
-NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0
-NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1
-NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5
-NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0
-NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0
-NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0
-NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1
-NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1 0 1.5
-NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 1 2.1
-NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0
-NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1
-NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0
-NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1
-NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1 0 2.1
-NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0
-NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1
-NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1
-NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1
-NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1
-NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0
-NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1
-NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0
-NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0
-NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0
-NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0
-NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0
-NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0
-NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0
-NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0
-NVIDIA N10 .*NVIDIA .*N10.* 1 1 0 2.1
-NVIDIA GeForce PCX .*GeForce PCX.* 0 1 0 1.5
-NVIDIA PCI .*NVIDIA PCI[ ]* 0 0 0 2.1
-NVIDIA Generic .*NVIDIA Generic.* 0 0 0 2.1
-NVIDIA Generic Unknown .*NVIDIA .*Unknown.* 0 0 0 2.1
-NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0
-NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0
-NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0
-NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0
-NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0
-NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0
-NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0
-NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3
-NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0
-NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1 0 2.1
-NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0
-NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0
-NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0
-NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0
-NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0
-NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0
-NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0
-NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1
-NVIDIA Corporation N11M .*NVIDIA .*N11M.* 2 1 0 3.1
-NVIDIA RIVA TNT .*RIVA TNT.* 0 0 0 1.5
-NVIDIA GRID .*NVIDIA .*GRID.* 0 0 0 1.5
-NVIDIA ION 2 .*NVIDIA .* *[I][O][N] 2.* 2 1 0 0
-NVIDIA ION a .*NVIDIA .*[I][O][N]$ 2 1 1 3.3
-NVIDIA ION b .*NVIDIA .*(Corporation) [I][O][N].* 2 1 1 3.3
-S3 .*S3 *(Graphics)*.* 0 0 1 1.4
-SiS SiS.* 0 0 1 1.5
-Trident Trident.* 0 0 0 0
-Tungsten Graphics Tungsten.* 0 0 0 0
-XGI XGI.* 0 0 0 0
-VIA VIA.* 0 0 0 0
-Apple Generic Apple.*Generic.* 0 0 0 0
-Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0
-Oracle VirtualBox.* 0 1 1 2.1
-Humper Humper.* 0 1 1 2.1
-PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3
-ATI GeForce Lulz .*ATI.*GeForce.* 0 0 0 0
-
-
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 297bd9a05b..3f32be1d68 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -275,9 +275,24 @@ bool LLAgent::isActionAllowed(const LLSD& sdname)
if (param == "speak")
{
- if ( gAgent.isVoiceConnected() &&
- LLViewerParcelMgr::getInstance()->allowAgentVoice() &&
- ! LLVoiceClient::getInstance()->inTuningMode() )
+ bool allow_agent_voice = false;
+ LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
+ if (channel != NULL)
+ {
+ if (channel->getSessionName().empty() && channel->getSessionID().isNull())
+ {
+ // default channel
+ allow_agent_voice = LLViewerParcelMgr::getInstance()->allowAgentVoice();
+ }
+ else
+ {
+ allow_agent_voice = channel->isActive() && channel->callStarted();
+ }
+ }
+
+ if (gAgent.isVoiceConnected() &&
+ allow_agent_voice &&
+ !LLVoiceClient::getInstance()->inTuningMode())
{
retval = true;
}
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index cce1eb5895..b76a66ab39 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1043,7 +1043,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (mismatched == 0 && !update_inventory)
{
LL_DEBUGS("Avatar") << "no changes, bailing out" << LL_ENDL;
- mCOFChangeInProgress = false;
+ notifyLoadingFinished();
return;
}
@@ -1100,7 +1100,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (mismatched == 0)
{
LL_DEBUGS("Avatar") << "inventory updated, wearable assets not changed, bailing out" << LL_ENDL;
- mCOFChangeInProgress = false;
+ notifyLoadingFinished();
return;
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 142a3250c8..3d9b1a72a8 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1869,7 +1869,7 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)
{
++n_clothes;
}
- else if (item->getType() == LLAssetType::AT_BODYPART)
+ else if (item->getType() == LLAssetType::AT_BODYPART || item->getType() == LLAssetType::AT_GESTURE)
{
return isAgentAvatarValid();
}
@@ -3825,6 +3825,10 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
{
LL_DEBUGS("Avatar") << "ATT removing attachment " << item->getName() << " id " << item->getUUID() << LL_ENDL;
}
+ if (item && item->getType() == LLAssetType::AT_BODYPART)
+ {
+ continue;
+ }
removeCOFItemLinks(linked_item_id, cb);
addDoomedTempAttachment(linked_item_id);
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 7cfb8fdf42..1341cde95f 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -124,6 +124,9 @@
#include "llleap.h"
#include "stringize.h"
#include "llcoros.h"
+#if !LL_LINUX
+#include "cef/llceflib.h"
+#endif
// Third party library includes
#include
@@ -131,7 +134,6 @@
#include
#include
-
#if LL_WINDOWS
# include // For _SH_DENYWR in processMarkerFiles
#else
@@ -327,7 +329,10 @@ BOOL gDisconnected = FALSE;
// used to restore texture state after a mode switch
LLFrameTimer gRestoreGLTimer;
BOOL gRestoreGL = FALSE;
-BOOL gUseWireframe = FALSE;
+BOOL gUseWireframe = FALSE;
+
+//use for remember deferred mode in wireframe switch
+BOOL gInitialDeferredModeForWireframe = FALSE;
// VFS globals - see llappviewer.h
LLVFS* gStaticVFS = NULL;
@@ -1728,6 +1733,9 @@ bool LLAppViewer::cleanup()
// to ensure shutdown order
LLMortician::setZealous(TRUE);
+ // Give any remaining SLPlugin instances a chance to exit cleanly.
+ LLPluginProcessParent::shutdown();
+
LLVoiceClient::getInstance()->terminate();
disconnectViewer();
@@ -2784,11 +2792,11 @@ bool LLAppViewer::initConfiguration()
//
gWindowTitle = LLTrans::getString("APP_NAME");
#if LL_DEBUG
- gWindowTitle += std::string(" [DEBUG]")
+ gWindowTitle += std::string(" [DEBUG]");
#endif
if (!gArgs.empty())
{
- gWindowTitle += std::string(" ") + gArgs;
+ gWindowTitle += std::string(" ") + gArgs;
}
LLStringUtil::truncate(gWindowTitle, 255);
@@ -3370,8 +3378,11 @@ LLSD LLAppViewer::getViewerInfo() const
info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
}
- // TODO: Implement media plugin version query
- info["QT_WEBKIT_VERSION"] = "4.7.1 (version number hard-coded)";
+#if !LL_LINUX
+ info["LLCEFLIB_VERSION"] = LLCEFLIB_VERSION;
+#else
+ info["LLCEFLIB_VERSION"] = "Undefined";
+#endif
S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN);
if (packets_in > 0)
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 311e548cfb..539881c80e 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -390,6 +390,7 @@ extern BOOL gDisconnected;
extern LLFrameTimer gRestoreGLTimer;
extern BOOL gRestoreGL;
extern BOOL gUseWireframe;
+extern BOOL gInitialDeferredModeForWireframe;
// VFS globals - gVFS is for general use
// gStaticVFS is read-only and is shipped w/ the viewer
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index d2b1dcbf35..121ce647a6 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -618,7 +618,10 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
case LLAssetType::AT_NOTECARD:
{
// Update the UI with the new asset.
- LLPreviewNotecard* nc = LLFloaterReg::findTypedInstance("preview_notecard", LLSD(item_id));
+ LLSD floater_key;
+ floater_key["taskid"] = task_id;
+ floater_key["itemid"] = item_id;
+ LLPreviewNotecard* nc = LLFloaterReg::findTypedInstance("preview_notecard", floater_key);
if(nc)
{
// *HACK: we have to delete the asset in the VFS so
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index dc0835eb1c..4b426081d0 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -526,7 +526,7 @@ protected:
showSystemContextMenu(x,y);
if(mAvatarID.notNull() && mSourceType == CHAT_SOURCE_AGENT)
showAvatarContextMenu(x,y);
- if(mAvatarID.notNull() && mSourceType == CHAT_SOURCE_OBJECT && SYSTEM_FROM != mFrom)
+ if(mAvatarID.notNull() && mSourceType == CHAT_SOURCE_OBJECT)
showObjectContextMenu(x,y);
}
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 8ce5aca909..307f93e28c 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -483,7 +483,7 @@ void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel
const LLAssetType::EType item_type = item->getType();
if (item_type == LLAssetType::AT_CLOTHING) continue;
LLPanelInventoryListItemBase* item_panel = NULL;
- if (item_type == LLAssetType::AT_OBJECT)
+ if (item_type == LLAssetType::AT_OBJECT || item_type == LLAssetType::AT_GESTURE)
{
item_panel = buildAttachemntListItem(item);
mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 33ce3d0111..33675bd261 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -220,24 +220,7 @@ void LLDrawPoolTerrain::render(S32 pass)
// Special-case for land ownership feedback
if (gSavedSettings.getBOOL("ShowParcelOwners"))
{
- if (mVertexShaderLevel > 1)
- { //use fullbright shader for highlighting
- LLGLSLShader* old_shader = sShader;
- sShader->unbind();
- sShader = &gHighlightProgram;
- sShader->bind();
- gGL.diffuseColor4f(1,1,1,1);
- LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-1.0f, -1.0f);
- renderOwnership();
- sShader = old_shader;
- sShader->bind();
- }
- else
- {
- gPipeline.disableLights();
- renderOwnership();
- }
+ hilightParcelOwners();
}
}
@@ -265,7 +248,15 @@ void LLDrawPoolTerrain::renderDeferred(S32 pass)
{
return;
}
+
renderFullShader();
+
+ // Special-case for land ownership feedback
+ if (gSavedSettings.getBOOL("ShowParcelOwners"))
+ {
+ hilightParcelOwners();
+ }
+
}
void LLDrawPoolTerrain::beginShadowPass(S32 pass)
@@ -454,6 +445,28 @@ void LLDrawPoolTerrain::renderFullShader()
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
+void LLDrawPoolTerrain::hilightParcelOwners()
+{
+ if (mVertexShaderLevel > 1)
+ { //use fullbright shader for highlighting
+ LLGLSLShader* old_shader = sShader;
+ sShader->unbind();
+ sShader = &gHighlightProgram;
+ sShader->bind();
+ gGL.diffuseColor4f(1, 1, 1, 1);
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.0f, -1.0f);
+ renderOwnership();
+ sShader = old_shader;
+ sShader->bind();
+ }
+ else
+ {
+ gPipeline.disableLights();
+ renderOwnership();
+ }
+}
+
void LLDrawPoolTerrain::renderFull4TU()
{
// Hack! Get the region that this draw pool is rendering from!
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 2163d087e1..55f75e2644 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -76,6 +76,7 @@ public:
static S32 sDetailMode;
static F32 sDetailScale; // meters per texture
+
protected:
void renderSimple();
void renderOwnership();
@@ -84,6 +85,9 @@ protected:
void renderFull4TU();
void renderFullShader();
void drawLoop();
+
+private:
+ void hilightParcelOwners();
};
#endif // LL_LLDRAWPOOLSIMPLE_H
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index f2602c8c7d..61b5748201 100644
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -237,6 +237,7 @@ LLExpandableTextBox::LLExpandableTextBox(const Params& p)
LLTextBoxEx::Params textbox_params = p.textbox;
textbox_params.rect(rc);
mTextBox = LLUICtrlFactory::create(textbox_params);
+ mTextBox->setContentTrusted(false);
mScroll->addChild(mTextBox);
updateTextBoxRect();
@@ -260,6 +261,11 @@ void LLExpandableTextBox::draw()
LLUICtrl::draw();
}
+void LLExpandableTextBox::setContentTrusted(bool trusted_content)
+{
+ mTextBox->setContentTrusted(trusted_content);
+}
+
void LLExpandableTextBox::collapseIfPosChanged()
{
if(mExpanded)
diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h
index 5dea35bb82..90d46ab262 100644
--- a/indra/newview/llexpandabletextbox.h
+++ b/indra/newview/llexpandabletextbox.h
@@ -194,6 +194,8 @@ protected:
*/
virtual S32 recalculateTextDelta(S32 text_delta);
+ void setContentTrusted(bool trusted_content);
+
protected:
std::string mText;
diff --git a/indra/newview/llexperienceassociationresponder.cpp b/indra/newview/llexperienceassociationresponder.cpp
index 7f2363aadc..f62ca7d75f 100644
--- a/indra/newview/llexperienceassociationresponder.cpp
+++ b/indra/newview/llexperienceassociationresponder.cpp
@@ -51,10 +51,18 @@ void ExperienceAssociationResponder::fetchAssociatedExperience(LLSD& request, ca
LLViewerObject* object = gObjectList.findObject(request["object-id"]);
if (!object)
{
- LL_WARNS() << "Failed to find object with ID " << request["object-id"] << " in fetchAssociatedExperience" << LL_ENDL;
- return;
+ LL_DEBUGS() << "Object with ID " << request["object-id"] << " not found via gObjectList.findObject() in fetchAssociatedExperience" << LL_ENDL;
+ LL_DEBUGS() << "Using gAgent.getRegion() instead of object->getRegion()" << LL_ENDL;
+ }
+ LLViewerRegion* region = NULL;
+ if (object)
+ {
+ region = object->getRegion();
+ }
+ else
+ {
+ region = gAgent.getRegion();
}
- LLViewerRegion* region = object->getRegion();
if (region)
{
std::string lookup_url=region->getCapability("GetMetadata");
@@ -66,6 +74,10 @@ void ExperienceAssociationResponder::fetchAssociatedExperience(LLSD& request, ca
LLHTTPClient::post(lookup_url, request, new ExperienceAssociationResponder(callback));
}
}
+ else
+ {
+ LL_WARNS() << "Failed to lookup region in fetchAssociatedExperience. Fetch request not sent." << LL_ENDL;
+ }
}
void ExperienceAssociationResponder::httpFailure()
diff --git a/indra/newview/llexperiencelog.cpp b/indra/newview/llexperiencelog.cpp
index ec6134a4b3..ee5d561927 100644
--- a/indra/newview/llexperiencelog.cpp
+++ b/indra/newview/llexperiencelog.cpp
@@ -112,6 +112,7 @@ void LLExperienceLog::handleExperienceMessage(LLSD& message)
}
message["Time"] = time_of_day;
mEvents[day].append(message);
+ mEventsToSave[day].append(message);
mSignals(message);
}
@@ -180,9 +181,8 @@ void LLExperienceLog::notify( LLSD& message )
void LLExperienceLog::saveEvents()
{
- eraseExpired();
std::string filename = getFilename();
- LLSD settings = LLSD::emptyMap().with("Events", mEvents);
+ LLSD settings = LLSD::emptyMap().with("Events", mEventsToSave);
settings["MaxDays"] = (int)mMaxDays;
settings["Notify"] = mNotifyNewEvent;
@@ -217,9 +217,8 @@ void LLExperienceLog::loadEvents()
if(mMaxDays > 0 && settings.has("Events"))
{
mEvents = settings["Events"];
+ mEventsToSave = mEvents;
}
-
- eraseExpired();
}
LLExperienceLog::~LLExperienceLog()
@@ -235,6 +234,26 @@ void LLExperienceLog::eraseExpired()
}
}
+bool LLExperienceLog::isNotExpired(std::string& date)
+{
+ LLDate event_date;
+ S32 month, day, year;
+ S32 matched = sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day);
+ if (matched != 3) return false;
+ event_date.fromYMDHMS(year, month, day);
+ const U32 seconds_in_day = 24 * 60 * 60;
+ S32 curr_year = 0, curr_month = 0, curr_day = 0;
+
+
+ LLDate curr_date = LLDate::now();
+ curr_date.split(&curr_year, &curr_month, &curr_day);
+ curr_date.fromYMDHMS(curr_year, curr_month, curr_day); // Set hour, min, and sec to 0
+
+ LLDate boundary_date = LLDate(curr_date.secondsSinceEpoch() - seconds_in_day*getMaxDays());
+ return event_date >= boundary_date;
+
+}
+
const LLSD& LLExperienceLog::getEvents() const
{
return mEvents;
@@ -248,10 +267,6 @@ void LLExperienceLog::clear()
void LLExperienceLog::setMaxDays( U32 val )
{
mMaxDays = val;
- if(mMaxDays > 0)
- {
- eraseExpired();
- }
}
LLExperienceLog::callback_connection_t LLExperienceLog::addUpdateSignal( const callback_slot_t& cb )
diff --git a/indra/newview/llexperiencelog.h b/indra/newview/llexperiencelog.h
index 1e473e27d5..ac227db336 100644
--- a/indra/newview/llexperiencelog.h
+++ b/indra/newview/llexperiencelog.h
@@ -59,6 +59,8 @@ public:
static void notify(LLSD& message);
static std::string getFilename();
static std::string getPermissionString(const LLSD& message, const std::string& base);
+ void setEventsToSave(LLSD new_events){mEventsToSave = new_events; }
+ bool isNotExpired(std::string& date);
protected:
LLExperienceLog();
void handleExperienceMessage(LLSD& message);
@@ -68,7 +70,10 @@ protected:
void saveEvents();
void eraseExpired();
+
+
LLSD mEvents;
+ LLSD mEventsToSave;
callback_signal_t mSignals;
callback_connection_t mNotifyConnection;
U32 mMaxDays;
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 8f3eaaa207..b779d8f461 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -655,11 +655,12 @@ void LLFavoritesBarCtrl::changed(U32 mask)
LLInventoryModel::cat_array_t cats;
LLIsType is_type(LLAssetType::AT_LANDMARK);
gInventory.collectDescendentsIf(mFavoriteFolderId, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
-
+
for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
{
LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());
}
+
updateButtons();
if (!mItemsChangedTimer.getStarted())
{
@@ -751,7 +752,11 @@ void LLFavoritesBarCtrl::updateButtons()
if(mGetPrevItems)
{
- LLFavoritesOrderStorage::instance().mPrevFavorites = mItems;
+ for (LLInventoryModel::item_array_t::iterator it = mItems.begin(); it != mItems.end(); it++)
+ {
+ LLFavoritesOrderStorage::instance().mFavoriteNames[(*it)->getUUID()]= (*it)->getName();
+ }
+ LLFavoritesOrderStorage::instance().mPrevFavorites = mItems;
mGetPrevItems = false;
}
@@ -778,7 +783,7 @@ void LLFavoritesBarCtrl::updateButtons()
const LLViewerInventoryItem *item = mItems[first_changed_item_index].get();
if (item)
{
- // an child's order and mItems should be same
+ // an child's order and mItems should be same
if (button->getLandmarkId() != item->getUUID() // sort order has been changed
|| button->getLabelSelected() != item->getName() // favorite's name has been changed
|| button->getRect().mRight < rightest_point) // favbar's width has been changed
@@ -1617,7 +1622,7 @@ void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
{
LLSD user_llsd = fav_llsd[av_name.getUserName()];
- if (user_llsd.beginArray()->has("id"))
+ if ((user_llsd.beginArray()!= user_llsd.endArray()) && user_llsd.beginArray()->has("id"))
{
for (LLSD::array_iterator iter = user_llsd.beginArray();iter != user_llsd.endArray(); ++iter)
{
@@ -1783,10 +1788,20 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)
gInventory.collectDescendentsIf(favorite_folder, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
std::sort(items.begin(), items.end(), LLFavoritesSort());
+ bool name_changed = false;
- if((items != mPrevFavorites) || pref_changed)
+ for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
{
- std::string filename = getStoredFavoritesFilename();
+ if(mFavoriteNames[(*it)->getUUID()] != ((*it)->getName()))
+ {
+ mFavoriteNames[(*it)->getUUID()] = (*it)->getName();
+ name_changed = true;
+ }
+ }
+
+ if((items != mPrevFavorites) || name_changed || pref_changed)
+ {
+ std::string filename = getStoredFavoritesFilename();
if (!filename.empty())
{
llifstream in_file;
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 66fc8b2ae7..846d62227a 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -218,6 +218,7 @@ public:
const static S32 NO_INDEX;
static bool mSaveOnExit;
bool mUpdateRequired;
+ std::map mFavoriteNames;
private:
friend class LLSingleton;
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index ea39f812fd..b1e3f2bb14 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -60,8 +60,6 @@
#include "lldxhardware.h"
#endif
-#define LL_EXPORT_GPU_TABLE 0
-
#if LL_DARWIN
const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_mac.%s.txt";
diff --git a/indra/newview/llfloaterexperienceprofile.cpp b/indra/newview/llfloaterexperienceprofile.cpp
index 197162487d..fd226d656c 100644
--- a/indra/newview/llfloaterexperienceprofile.cpp
+++ b/indra/newview/llfloaterexperienceprofile.cpp
@@ -117,12 +117,20 @@ LLExperienceHandler gExperienceHandler;
LLFloaterExperienceProfile::LLFloaterExperienceProfile(const LLSD& data)
: LLFloater(data)
- , mExperienceId(data.asUUID())
, mSaveCompleteAction(NOTHING)
, mDirty(false)
, mForceClose(false)
{
-
+ if (data.has("experience_id"))
+ {
+ mExperienceId = data["experience_id"].asUUID();
+ mPostEdit = data.has("edit_experience") && data["edit_experience"].asBoolean();
+ }
+ else
+ {
+ mExperienceId = data.asUUID();
+ mPostEdit = false;
+ }
}
@@ -329,7 +337,13 @@ BOOL LLFloaterExperienceProfile::postBuild()
LLEventPumps::instance().obtain("experience_permission").listen(mExperienceId.asString()+"-profile",
boost::bind(&LLFloaterExperienceProfile::experiencePermission, getDerivedHandle(this), _1));
-
+
+ if (mPostEdit && mExperienceId.notNull())
+ {
+ mPostEdit = false;
+ changeToEdit();
+ }
+
return TRUE;
}
@@ -356,9 +370,7 @@ bool LLFloaterExperienceProfile::experiencePermission( LLHandle("tab_container");
-
- tabs->selectTabByName("edit_panel_experience_info");
+ changeToEdit();
}
@@ -829,6 +841,13 @@ void LLFloaterExperienceProfile::changeToView()
}
}
+void LLFloaterExperienceProfile::changeToEdit()
+{
+ LLTabContainer* tabs = getChild("tab_container");
+
+ tabs->selectTabByName("edit_panel_experience_info");
+}
+
void LLFloaterExperienceProfile::onClickLocation()
{
LLViewerRegion* region = gAgent.getRegion();
diff --git a/indra/newview/llfloaterexperienceprofile.h b/indra/newview/llfloaterexperienceprofile.h
index 78d54eb447..14e033d240 100644
--- a/indra/newview/llfloaterexperienceprofile.h
+++ b/indra/newview/llfloaterexperienceprofile.h
@@ -76,6 +76,7 @@ protected:
void setEditGroup(LLUUID group_id);
void changeToView();
+ void changeToEdit();
void experienceForgotten();
void experienceBlocked();
@@ -99,6 +100,7 @@ protected:
int mSaveCompleteAction;
bool mDirty;
bool mForceClose;
+ bool mPostEdit; // edit experience after opening and updating it
};
#endif // LL_LLFLOATEREXPERIENCEPROFILE_H
diff --git a/indra/newview/llfloaterexperiences.cpp b/indra/newview/llfloaterexperiences.cpp
index 777dc382cd..63f1fab823 100644
--- a/indra/newview/llfloaterexperiences.cpp
+++ b/indra/newview/llfloaterexperiences.cpp
@@ -303,6 +303,32 @@ void LLFloaterExperiences::checkPurchaseInfo(LLPanelExperiences* panel, const LL
LLFloaterExperiences::findInstance()->updateInfo("GetCreatorExperiences","Contrib_Experiences_Tab");
}
+void LLFloaterExperiences::checkAndOpen(LLPanelExperiences* panel, const LLSD& content) const
+{
+ checkPurchaseInfo(panel, content);
+
+ // determine new item
+ const LLSD& response_ids = content["experience_ids"];
+
+ if (mPrepurchaseIds.size() + 1 == response_ids.size())
+ {
+ // we have a new element
+ for (LLSD::array_const_iterator it = response_ids.beginArray(); it != response_ids.endArray(); ++it)
+ {
+ LLUUID experience_id = it->asUUID();
+ if (std::find(mPrepurchaseIds.begin(), mPrepurchaseIds.end(), experience_id) == mPrepurchaseIds.end())
+ {
+ // new element found, open it
+ LLSD args;
+ args["experience_id"] = experience_id;
+ args["edit_experience"] = true;
+ LLFloaterReg::showInstance("experience_profile", args, true);
+ break;
+ }
+ }
+ }
+}
+
void LLFloaterExperiences::updateInfo(std::string experiences, std::string tab)
{
LLViewerRegion* region = gAgent.getRegion();
@@ -318,18 +344,28 @@ void LLFloaterExperiences::updateInfo(std::string experiences, std::string tab)
}
}
-void LLFloaterExperiences::sendPurchaseRequest() const
+void LLFloaterExperiences::sendPurchaseRequest()
{
LLViewerRegion* region = gAgent.getRegion();
std::string url = region->getCapability("AgentExperiences");
if(!url.empty())
{
LLSD content;
+ const std::string tab_owned_name = "Owned_Experiences_Tab";
+
+ // extract ids for experiences that we already have
+ LLTabContainer* tabs = getChild("xp_tabs");
+ LLPanelExperiences* tab_owned = (LLPanelExperiences*)tabs->getPanelByName(tab_owned_name);
+ mPrepurchaseIds.clear();
+ if (tab_owned)
+ {
+ tab_owned->getExperienceIdsList(mPrepurchaseIds);
+ }
LLExperienceListResponder::NameMap nameMap;
- nameMap["experience_ids"]="Owned_Experiences_Tab";
+ nameMap["experience_ids"] = tab_owned_name;
LLExperienceListResponder* responder = new LLExperienceListResponder(getDerivedHandle(), nameMap, "ExperienceAcquireFailed");
- responder->mCallback = boost::bind(&LLFloaterExperiences::checkPurchaseInfo, this, _1, _2);
+ responder->mCallback = boost::bind(&LLFloaterExperiences::checkAndOpen, this, _1, _2);
LLHTTPClient::post(url, content, responder);
}
}
diff --git a/indra/newview/llfloaterexperiences.h b/indra/newview/llfloaterexperiences.h
index 769283ff07..06fd6c93d6 100644
--- a/indra/newview/llfloaterexperiences.h
+++ b/indra/newview/llfloaterexperiences.h
@@ -49,12 +49,14 @@ protected:
LLPanelExperiences* addTab(const std::string& name, bool select);
bool updatePermissions(const LLSD& permission);
- void sendPurchaseRequest() const;
+ void sendPurchaseRequest();
void checkPurchaseInfo(LLPanelExperiences* panel, const LLSD& content)const;
+ void checkAndOpen(LLPanelExperiences* panel, const LLSD& content) const;
void updateInfo(std::string experiences, std::string tab);
private:
+ std::vector mPrepurchaseIds;
};
#endif //LL_LLFLOATEREXPERIENCES_H
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index f1a6ef78a6..15b67b905d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1916,19 +1916,17 @@ bool LLFloaterIMContainer::canBanSelectedMember(const LLUUID& participant_uuid)
if (gdatap->isRoleMemberDataComplete())
{
- if (!gdatap->mMembers.size())
- {
- return false;
- }
-
- LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find((participant_uuid));
- if (mi != gdatap->mMembers.end())
- {
- LLGroupMemberData* member_data = (*mi).second;
- // Is the member an owner?
- if (member_data && member_data->isInRole(gdatap->mOwnerRole))
+ if (gdatap->mMembers.size())
+ {
+ LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find((participant_uuid));
+ if (mi != gdatap->mMembers.end())
{
- return false;
+ LLGroupMemberData* member_data = (*mi).second;
+ // Is the member an owner?
+ if (member_data && member_data->isInRole(gdatap->mOwnerRole))
+ {
+ return false;
+ }
}
}
}
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 41005144a7..861dc88983 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -2573,6 +2573,112 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
shader->bind();
}
}
+void LLModelPreview::genModelBBox()
+{
+ LLVector3 min, max;
+ min = this->mModelLoader->mExtents[0];
+ max = this->mModelLoader->mExtents[1];
+ std::vector v_list;
+ v_list.resize(4);
+ std::map > face_list;
+
+ // Face 0
+ v_list[0] = LLVector3(min.mV[VX], max.mV[VY], max.mV[VZ]);
+ v_list[1] = LLVector3(min.mV[VX], min.mV[VY], max.mV[VZ]);
+ v_list[2] = LLVector3(max.mV[VX], min.mV[VY], max.mV[VZ]);
+ v_list[3] = LLVector3(max.mV[VX], max.mV[VY], max.mV[VZ]);
+ face_list.insert(std::pair >(0, v_list));
+
+ // Face 1
+ v_list[0] = LLVector3(max.mV[VX], min.mV[VY], max.mV[VZ]);
+ v_list[1] = LLVector3(max.mV[VX], min.mV[VY], min.mV[VZ]);
+ v_list[2] = LLVector3(max.mV[VX], max.mV[VY], min.mV[VZ]);
+ v_list[3] = LLVector3(max.mV[VX], max.mV[VY], max.mV[VZ]);
+ face_list.insert(std::pair >(1, v_list));
+
+ // Face 2
+ v_list[0] = LLVector3(min.mV[VX], max.mV[VY], min.mV[VZ]);
+ v_list[1] = LLVector3(min.mV[VX], max.mV[VY], max.mV[VZ]);
+ v_list[2] = LLVector3(max.mV[VX], max.mV[VY], max.mV[VZ]);
+ v_list[3] = LLVector3(max.mV[VX], max.mV[VY], min.mV[VZ]);
+ face_list.insert(std::pair >(2, v_list));
+
+ // Face 3
+ v_list[0] = LLVector3(min.mV[VX], max.mV[VY], max.mV[VZ]);
+ v_list[1] = LLVector3(min.mV[VX], max.mV[VY], min.mV[VZ]);
+ v_list[2] = LLVector3(min.mV[VX], min.mV[VY], min.mV[VZ]);
+ v_list[3] = LLVector3(min.mV[VX], min.mV[VY], max.mV[VZ]);
+ face_list.insert(std::pair >(3, v_list));
+
+ // Face 4
+ v_list[0] = LLVector3(min.mV[VX], min.mV[VY], max.mV[VZ]);
+ v_list[1] = LLVector3(min.mV[VX], min.mV[VY], min.mV[VZ]);
+ v_list[2] = LLVector3(max.mV[VX], min.mV[VY], min.mV[VZ]);
+ v_list[3] = LLVector3(max.mV[VX], min.mV[VY], max.mV[VZ]);
+ face_list.insert(std::pair >(4, v_list));
+
+ // Face 5
+ v_list[0] = LLVector3(min.mV[VX], min.mV[VY], min.mV[VZ]);
+ v_list[1] = LLVector3(min.mV[VX], max.mV[VY], min.mV[VZ]);
+ v_list[2] = LLVector3(max.mV[VX], max.mV[VY], min.mV[VZ]);
+ v_list[3] = LLVector3(max.mV[VX], min.mV[VY], min.mV[VZ]);
+ face_list.insert(std::pair >(5, v_list));
+
+ U16 Idx[] = { 0, 1, 2, 3, 0, 2, };
+
+ U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
+ LLPointer buff = new LLVertexBuffer(type_mask, 0);
+ buff->allocateBuffer(4, 6, true);
+
+ LLStrider pos;
+ LLStrider idx;
+ LLStrider norm;
+ LLStrider tc;
+
+ buff->getVertexStrider(pos);
+ buff->getIndexStrider(idx);
+
+ buff->getNormalStrider(norm);
+ buff->getTexCoord0Strider(tc);
+
+ for (U32 i = 0; i < 6; ++i)
+ {
+ idx[i] = Idx[i];
+ }
+
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
+ LLModel* mdl = new LLModel(volume_params, 0.f);
+ mdl->mLabel = "BBOX"; // please adopt name from high LOD (mBaseModel) or from original model otherwise it breaks search mechanics which is name based
+
+ mdl->setNumVolumeFaces(6);
+ for (U8 i = 0; i < 6; ++i)
+ {
+ for (U8 j = 0; j < 4; ++j)
+ {
+ pos[j] = face_list[i][j];
+ }
+
+ mdl->setVolumeFaceData(i, pos, norm, tc, idx, buff->getNumVerts(), buff->getNumIndices());
+ }
+
+ if (validate_model(mdl))
+ {
+ LLMatrix4 mat;
+ std::map materials;
+ std::vector instance_list;
+ instance_list.push_back(LLModelInstance(mdl, mdl->mLabel, mat, materials));
+
+ for (S32 i = LLModel::LOD_HIGH - 1; i >= 0; i--)
+ {
+ mModel[i].clear();
+ mModel[i].push_back(mdl);
+
+ mScene[i].clear();
+ mScene[i].insert(std::pair >(mat, instance_list));
+ }
+ }
+}
void LLModelPreview::updateStatusMessages()
{
@@ -3563,6 +3669,7 @@ BOOL LLModelPreview::render()
fmp->enableViewOption("show_skin_weight");
fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
mFMP->childEnable("upload_skin");
+ mFMP->childSetValue("show_skin_weight", skin_weight);
}
}
else
@@ -3683,7 +3790,7 @@ BOOL LLModelPreview::render()
}
else
{
- LL_INFOS(" ") << "Vertex Buffer[" << mPreviewLOD << "]" << " is EMPTY!!!" << LL_ENDL;
+ LL_INFOS() << "Vertex Buffer[" << mPreviewLOD << "]" << " is EMPTY!!!" << LL_ENDL;
regen = TRUE;
}
}
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 7a518c798b..07e29d09c7 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -262,6 +262,7 @@ public:
void loadModel(std::string filename, S32 lod, bool force_disable_slm = false);
void loadModelCallback(S32 lod);
void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
+ void genModelBBox(); // Generate just a model BBox if we can't generate proper LOD
void generateNormals();
void restoreNormals();
U32 calcResourceCost();
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index dac610eda1..f7861fb4fd 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -108,6 +108,7 @@
#include "llpluginclassmedia.h"
#include "llteleporthistorystorage.h"
#include "llproxy.h"
+#include "llweb.h"
#include "lllogininstance.h" // to check if logged in yet
#include "llsdserialize.h"
@@ -1942,6 +1943,16 @@ BOOL LLPanelPreference::postBuild()
gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&LLPanelPreference::Updater::update, mBandWidthUpdater, _2));
}
+#ifdef EXTERNAL_TOS
+ LLRadioGroup* ext_browser_settings = getChild("preferred_browser_behavior");
+ if (ext_browser_settings)
+ {
+ // turn off ability to set external/internal browser
+ ext_browser_settings->setSelectedByValue(LLWeb::BROWSER_EXTERNAL_ONLY, true);
+ ext_browser_settings->setEnabled(false);
+ }
+#endif
+
apply();
return true;
}
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 6dbb202c9d..987a7449ee 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -370,6 +370,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mLandImpactsObserver(NULL),
mDirty(TRUE),
+ mHasSelection(TRUE),
mNeedMediaTitle(TRUE)
{
gFloaterTools = this;
@@ -541,7 +542,14 @@ void LLFloaterTools::refresh()
void LLFloaterTools::draw()
{
- if (mDirty)
+ BOOL has_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
+ if(!has_selection && (mHasSelection != has_selection))
+ {
+ mDirty = TRUE;
+ }
+ mHasSelection = has_selection;
+
+ if (mDirty)
{
refresh();
mDirty = FALSE;
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index df481b8d4c..8f586f7da6 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -198,6 +198,7 @@ public:
private:
BOOL mDirty;
+ BOOL mHasSelection;
std::map mStatusText;
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index d604b8619a..f8681fe098 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -118,25 +118,32 @@ void LLFloaterTopObjects::setMode(U32 mode)
// static
void LLFloaterTopObjects::handle_land_reply(LLMessageSystem* msg, void** data)
{
- LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects");
- if(!instance) return;
- // Make sure dialog is on screen
- LLFloaterReg::showInstance("top_objects");
- instance->handleReply(msg, data);
-
- //HACK: for some reason sometimes top scripts originally comes back
- //with no results even though they're there
- if (!instance->mObjectListIDs.size() && !instance->mInitialized)
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects");
+ if(instance && instance->isInVisibleChain())
+ {
+ instance->handleReply(msg, data);
+ //HACK: for some reason sometimes top scripts originally comes back
+ //with no results even though they're there
+ if (!instance->mObjectListIDs.size() && !instance->mInitialized)
+ {
+ instance->onRefresh();
+ instance->mInitialized = TRUE;
+ }
+ }
+ else
{
- instance->onRefresh();
- instance->mInitialized = TRUE;
+ LLFloaterRegionInfo* region_info_floater = LLFloaterReg::getTypedInstance("region_info");
+ if(region_info_floater)
+ {
+ region_info_floater->enableTopButtons();
+ }
}
}
void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
{
- U32 request_flags;
+ U32 request_flags;
U32 total_count;
msg->getU32Fast(_PREHASH_RequestData, _PREHASH_RequestFlags, request_flags);
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index ae33acb842..4cb1ca6cc0 100644
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -46,7 +46,6 @@
#include "message.h"
#include "llstartup.h" // login_alert_done
-
LLFloaterTOS::LLFloaterTOS(const LLSD& data)
: LLModalDialog( data["message"].asString() ),
mMessage(data["message"].asString()),
@@ -85,7 +84,7 @@ protected:
{
if ( mParent )
{
- mParent->setSiteIsAlive( true );
+ mParent->setSiteIsAlive(true);
}
}
@@ -136,6 +135,20 @@ BOOL LLFloaterTOS::postBuild()
LLMediaCtrl* web_browser = getChild("tos_html");
if ( web_browser )
{
+// if we are forced to send users to an external site in their system browser
+// (e.g.) Linux users because of lack of media support for HTML ToS page
+// remove exisiting UI and replace with a link to external page where users can accept ToS
+#ifdef EXTERNAL_TOS
+ LLTextBox* header = getChild("tos_heading");
+ if (header)
+ header->setVisible(false);
+
+ LLTextBox* external_prompt = getChild("external_tos_required");
+ if (external_prompt)
+ external_prompt->setVisible(true);
+
+ web_browser->setVisible(false);
+#else
web_browser->addObserver(this);
// Don't use the start_url parameter for this browser instance -- it may finish loading before we get to add our observer.
@@ -147,6 +160,7 @@ BOOL LLFloaterTOS::postBuild()
// All links from tos_html should be opened in external browser
media_plugin->setOverrideClickTarget("_external");
}
+#endif
}
return TRUE;
@@ -154,6 +168,13 @@ BOOL LLFloaterTOS::postBuild()
void LLFloaterTOS::setSiteIsAlive( bool alive )
{
+// if we are forced to send users to an external site in their system browser
+// (e.g.) Linux users because of lack of media support for HTML ToS page
+// force the regular HTML UI to deactivate so alternative is rendered instead.
+#ifdef EXTERNAL_TOS
+ mSiteAlive = false;
+#else
+
mSiteAlive = alive;
// only do this for TOS pages
@@ -182,6 +203,7 @@ void LLFloaterTOS::setSiteIsAlive( bool alive )
tos_agreement->setEnabled( true );
}
}
+#endif
}
LLFloaterTOS::~LLFloaterTOS()
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 4d92fee04f..e1315adfde 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -772,7 +772,7 @@ void LLGroupMgrGroupData::banMemberById(const LLUUID& participant_uuid)
mPendingBanRequest = true;
mPendingBanMemberID = participant_uuid;
- if (!mMemberDataComplete)
+ if (!mMemberDataComplete || !mMembers.size())
{
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mID);
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index c990eda074..9782c792c9 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -80,6 +80,8 @@
#include "lllandmarkactions.h"
#include "llpanellandmarks.h"
+#include
+
void copy_slurl_to_clipboard_callback_inv(const std::string& slurl);
typedef std::pair two_uuids_t;
@@ -99,7 +101,7 @@ struct LLMoveInv
using namespace LLOldEvents;
// Function declarations
-bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
+bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, boost::shared_ptr);
bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
void teleport_via_landmark(const LLUUID& asset_id);
static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
@@ -295,7 +297,11 @@ BOOL LLInvFVBridge::callback_cutToClipboard(const LLSD& notification, const LLSD
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0) // YES
{
- return perform_cutToClipboard();
+ const LLInventoryObject* obj = gInventory.getObject(mUUID);
+ LLUUID parent_uuid = obj->getParentUUID();
+ BOOL result = perform_cutToClipboard();
+ gInventory.addChangedMask(LLInventoryObserver::STRUCTURE, parent_uuid);
+ return result;
}
return FALSE;
}
@@ -2789,7 +2795,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
return accept;
}
-void warn_move_inventory(LLViewerObject* object, LLMoveInv* move_inv)
+void warn_move_inventory(LLViewerObject* object, boost::shared_ptr move_inv)
{
const char* dialog = NULL;
if (object->flagScripted())
@@ -2800,7 +2806,34 @@ void warn_move_inventory(LLViewerObject* object, LLMoveInv* move_inv)
{
dialog = "MoveInventoryFromObject";
}
- LLNotificationsUtil::add(dialog, LLSD(), LLSD(), boost::bind(move_task_inventory_callback, _1, _2, move_inv));
+
+ static LLNotificationPtr notification_ptr;
+ static boost::shared_ptr inv_ptr;
+
+ // Notification blocks user from interacting with inventories so everything that comes after first message
+ // is part of this message - don'r show it again
+ // Note: workaround for MAINT-5495 untill proper refactoring and warning system for Drag&Drop can be made.
+ if (notification_ptr == NULL
+ || !notification_ptr->isActive()
+ || LLNotificationsUtil::find(notification_ptr->getID()) == NULL
+ || inv_ptr->mCategoryID != move_inv->mCategoryID
+ || inv_ptr->mObjectID != move_inv->mObjectID)
+ {
+ notification_ptr = LLNotificationsUtil::add(dialog, LLSD(), LLSD(), boost::bind(move_task_inventory_callback, _1, _2, move_inv));
+ inv_ptr = move_inv;
+ }
+ else
+ {
+ // Notification is alive and not responded, operating inv_ptr should be safe so attach new data
+ two_uuids_list_t::iterator move_it;
+ for (move_it = move_inv->mMoveList.begin();
+ move_it != move_inv->mMoveList.end();
+ ++move_it)
+ {
+ inv_ptr->mMoveList.push_back(*move_it);
+ }
+ move_inv.reset();
+ }
}
// Move/copy all inventory items from the Contents folder of an in-world
@@ -2888,7 +2921,7 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
if(drop && accept)
{
it = inventory_objects.begin();
- LLMoveInv* move_inv = new LLMoveInv;
+ boost::shared_ptr move_inv(new LLMoveInv);
move_inv->mObjectID = object_id;
move_inv->mCategoryID = category_id;
move_inv->mCallback = callback;
@@ -4404,7 +4437,7 @@ LLFontGL::StyleFlags LLMarketplaceFolderBridge::getLabelStyle() const
// helper stuff
-bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv* move_inv)
+bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, boost::shared_ptr move_inv)
{
LLFloaterOpenObject::LLCatAndWear* cat_and_wear = (LLFloaterOpenObject::LLCatAndWear* )move_inv->mUserData;
LLViewerObject* object = gObjectList.findObject(move_inv->mObjectID);
@@ -4440,7 +4473,7 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
move_inv->mCallback(option, move_inv->mUserData);
}
- delete move_inv;
+ move_inv.reset(); //since notification will persist
return false;
}
@@ -4856,7 +4889,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
if (accept && drop)
{
- LLMoveInv* move_inv = new LLMoveInv;
+ boost::shared_ptr move_inv (new LLMoveInv());
move_inv->mObjectID = inv_item->getParentUUID();
two_uuids_t item_pair(mUUID, inv_item->getUUID());
move_inv->mMoveList.push_back(item_pair);
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 6aaf45c35d..984c650128 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1605,7 +1605,7 @@ bool sort_alpha(const LLViewerInventoryCategory* cat1, const LLViewerInventoryCa
void dump_trace(std::string& message, S32 depth, LLError::ELevel log_level)
{
- llinfos << "validate_marketplacelistings : error = "<< log_level << ", depth = " << depth << ", message = " << message << llendl;
+ LL_INFOS() << "validate_marketplacelistings : error = "<< log_level << ", depth = " << depth << ", message = " << message << LL_ENDL;
}
// Make all relevant business logic checks on the marketplace listings starting with the folder as argument.
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index f172aa0955..ed40483029 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -749,18 +749,20 @@ void LLManipRotate::renderActiveRing( F32 radius, F32 width, const LLColor4& fro
void LLManipRotate::renderSnapGuides()
{
- LLVector3 grid_origin;
- LLVector3 grid_scale;
- LLQuaternion grid_rotation;
- LLVector3 constraint_axis = getConstraintAxis();
-
- LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
-
- if (!gSavedSettings.getBOOL("SnapEnabled"))
+ static LLCachedControl snap_enabled(gSavedSettings, "SnapEnabled", true);
+ if (!snap_enabled)
{
return;
}
+ LLVector3 grid_origin;
+ LLVector3 grid_scale;
+ LLQuaternion grid_rotation;
+
+ LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale, true);
+
+ LLVector3 constraint_axis = getConstraintAxis();
+
LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
LLVector3 cam_at_axis;
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
@@ -1294,7 +1296,7 @@ LLVector3 LLManipRotate::getConstraintAxis()
else
{
S32 axis_dir = mManipPart - LL_ROT_X;
- if ((axis_dir >= 0) && (axis_dir < 3))
+ if ((axis_dir >= LL_NO_PART) && (axis_dir < LL_Z_ARROW))
{
axis.mV[axis_dir] = 1.f;
}
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 73faed7ef5..9cf3249983 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -57,6 +57,7 @@
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llnotifications.h"
+#include "llnotificationsutil.h"
#include "lllineeditor.h"
#include "llfloaterwebcontent.h"
#include "llwindowshade.h"
@@ -426,6 +427,23 @@ BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
return result;
}
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleKeyUpHere(KEY key, MASK mask)
+{
+ BOOL result = FALSE;
+
+ if (mMediaSource)
+ {
+ result = mMediaSource->handleKeyUpHere(key, mask);
+ }
+
+ if (!result)
+ result = LLPanel::handleKeyUpHere(key, mask);
+
+ return result;
+}
+
////////////////////////////////////////////////////////////////////////////////
//
void LLMediaCtrl::onVisibilityChange ( BOOL new_visibility )
@@ -989,19 +1007,23 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
std::string uuid = self->getClickUUID();
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << target << "\", uri is " << url << LL_ENDL;
- LLNotification::Params notify_params;
- notify_params.name = "PopupAttempt";
- notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID);
- notify_params.functor.function = boost::bind(&LLMediaCtrl::onPopup, this, _1, _2);
+ LLWeb::loadURL(url, target, std::string());
- if (mTrusted)
- {
- LLNotifications::instance().forceResponse(notify_params, 0);
- }
- else
- {
- LLNotifications::instance().add(notify_params);
- }
+ // CP: removing this code because we no longer support popups so this breaks the flow.
+ // replaced with a bare call to LLWeb::LoadURL(...)
+ //LLNotification::Params notify_params;
+ //notify_params.name = "PopupAttempt";
+ //notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID);
+ //notify_params.functor.function = boost::bind(&LLMediaCtrl::onPopup, this, _1, _2);
+
+ //if (mTrusted)
+ //{
+ // LLNotifications::instance().forceResponse(notify_params, 0);
+ //}
+ //else
+ //{
+ // LLNotifications::instance().add(notify_params);
+ //}
break;
};
@@ -1072,6 +1094,13 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
};
break;
+ case MEDIA_EVENT_FILE_DOWNLOAD:
+ {
+ //llinfos << "Media event - file download requested - filename is " << self->getFileDownloadFilename() << llendl;
+ //LLNotificationsUtil::add("MediaFileDownloadUnsupported");
+ };
+ break;
+
case MEDIA_EVENT_DEBUG_MESSAGE:
{
LL_INFOS("media") << self->getDebugMessageText() << LL_ENDL;
@@ -1150,3 +1179,13 @@ void LLMediaCtrl::updateContextMenuParent(LLView* pNewParent)
{
mContextMenu->updateParent(pNewParent);
}
+
+bool LLMediaCtrl::wantsKeyUpKeyDown() const
+{
+ return true;
+}
+
+bool LLMediaCtrl::wantsReturnKey() const
+{
+ return true;
+}
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 988733b85a..291d87073e 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -151,6 +151,7 @@ public:
// over-rides
virtual BOOL handleKeyHere( KEY key, MASK mask);
+ virtual BOOL handleKeyUpHere(KEY key, MASK mask);
virtual void onVisibilityChange ( BOOL new_visibility );
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE);
@@ -171,6 +172,10 @@ public:
void updateContextMenuParent(LLView* pNewParent);
+ // The Browser windows want keyup and keydown events. Overridden from LLFocusableElement to return true.
+ virtual bool wantsKeyUpKeyDown() const;
+ virtual bool wantsReturnKey() const;
+
protected:
void convertInputCoords(S32& x, S32& y);
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index d79baf90e7..3f4f2446e8 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -315,6 +315,11 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
{
LLPipeline::removeMutedAVsLights(avatarp);
}
+ //remove agent's notifications as well
+ if (localmute.mType == LLMute::AGENT)
+ {
+ LLNotifications::instance().cancelByOwner(localmute.mID);
+ }
return TRUE;
}
}
diff --git a/indra/newview/llpanelexperiencelog.cpp b/indra/newview/llpanelexperiencelog.cpp
index df03ef7526..30576a8d67 100644
--- a/indra/newview/llpanelexperiencelog.cpp
+++ b/indra/newview/llpanelexperiencelog.cpp
@@ -54,7 +54,6 @@ LLPanelExperienceLog::LLPanelExperienceLog( )
buildFromFile("panel_experience_log.xml");
}
-
BOOL LLPanelExperienceLog::postBuild( void )
{
LLExperienceLog* log = LLExperienceLog::getInstance();
@@ -112,7 +111,7 @@ void LLPanelExperienceLog::refresh()
int itemsToSkip = mPageSize*mCurrentPage;
int items = 0;
bool moreItems = false;
-
+ LLSD events_to_save = events;
if (!events.emptyMap())
{
LLSD::map_const_iterator day = events.endMap();
@@ -120,6 +119,13 @@ void LLPanelExperienceLog::refresh()
{
--day;
const LLSD& dayArray = day->second;
+
+ std::string date = day->first;
+ if(!LLExperienceLog::instance().isNotExpired(date))
+ {
+ events_to_save.erase(day->first);
+ continue;
+ }
int size = dayArray.size();
if(itemsToSkip > size)
{
@@ -164,6 +170,7 @@ void LLPanelExperienceLog::refresh()
}
} while (day != events.beginMap());
}
+ LLExperienceLog::getInstance()->setEventsToSave(events_to_save);
if(waiting)
{
mEventList->deleteAllItems();
@@ -237,12 +244,8 @@ void LLPanelExperienceLog::notifyChanged()
void LLPanelExperienceLog::logSizeChanged()
{
int value = (int)(getChild("logsizespinner")->get());
- bool dirty = value > 0 && value < LLExperienceLog::instance().getMaxDays();
LLExperienceLog::instance().setMaxDays(value);
- if(dirty)
- {
- refresh();
- }
+ refresh();
}
void LLPanelExperienceLog::onSelectionChanged()
diff --git a/indra/newview/llpanelexperiences.cpp b/indra/newview/llpanelexperiences.cpp
index 3ee4b5e968..37981b36a9 100644
--- a/indra/newview/llpanelexperiences.cpp
+++ b/indra/newview/llpanelexperiences.cpp
@@ -98,6 +98,16 @@ void LLPanelExperiences::setExperienceList( const LLSD& experiences )
mExperiencesList->sort();
}
+void LLPanelExperiences::getExperienceIdsList(std::vector& result)
+{
+ std::vector ids;
+ mExperiencesList->getValues(ids);
+ for (LLSD::array_const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ result.push_back(it->asUUID());
+ }
+}
+
LLPanelExperiences* LLPanelExperiences::create(const std::string& name)
{
LLPanelExperiences* panel= new LLPanelExperiences();
diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h
index 0370499583..f29fdfdecb 100644
--- a/indra/newview/llpanelexperiences.h
+++ b/indra/newview/llpanelexperiences.h
@@ -58,6 +58,7 @@ public:
/*virtual*/ void onClosePanel();
void setExperienceList(const LLSD& experiences);
+ void getExperienceIdsList(std::vector& result);
LLExperienceItem* getSelectedExperienceItem();
void removeExperiences( const LLSD& ids );
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index afc1a789c4..21d8b4248c 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -49,6 +49,7 @@
#include "llmaterialmgr.h"
#include "llmediaentry.h"
#include "llnotificationsutil.h"
+#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llspinctrl.h"
@@ -90,10 +91,10 @@ std::string USE_TEXTURE;
LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
{
LLComboBox* combobox_matmedia = getChild("combobox matmedia");
- LLComboBox* combobox_mattype = getChild("combobox mattype");
+ LLRadioGroup* radio_mat_type = getChild("radio_material_type");
LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
- (combobox_mattype ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
+ (radio_mat_type ? (LLRender::eTexIndex)radio_mat_type->getSelectedIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
@@ -162,7 +163,6 @@ BOOL LLPanelFace::postBuild()
LLComboBox* mComboTexGen;
LLComboBox* mComboMatMedia;
- LLComboBox* mComboMatType;
LLCheckBoxCtrl *mCheckFullbright;
@@ -283,12 +283,12 @@ BOOL LLPanelFace::postBuild()
mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
}
- mComboMatType = getChild("combobox mattype");
- if(mComboMatType)
- {
- mComboMatType->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
- mComboMatType->selectNthItem(MATTYPE_DIFFUSE);
- }
+ LLRadioGroup* radio_mat_type = getChild("radio_material_type");
+ if(radio_mat_type)
+ {
+ radio_mat_type->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
+ radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
+ }
mCtrlGlow = getChild("glow");
if(mCtrlGlow)
@@ -676,20 +676,21 @@ void LLPanelFace::updateUI()
}
getChildView("combobox matmedia")->setEnabled(editable);
- LLComboBox* combobox_mattype = getChild("combobox mattype");
- if (combobox_mattype)
+ LLRadioGroup* radio_mat_type = getChild("radio_material_type");
+ if(radio_mat_type)
{
- if (combobox_mattype->getCurrentIndex() < MATTYPE_DIFFUSE)
- {
- combobox_mattype->selectNthItem(MATTYPE_DIFFUSE);
- }
+ if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE)
+ {
+ radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
+ }
+
}
else
{
- LL_WARNS("Materials") << "failed getChild for 'combobox mattype'" << LL_ENDL;
+ LL_WARNS("Materials") << "failed getChild for 'radio_material_type'" << LL_ENDL;
}
- getChildView("combobox mattype")->setEnabled(editable);
+ getChildView("radio_material_type")->setEnabled(editable);
updateVisibility();
bool identical = true; // true because it is anded below
@@ -1200,8 +1201,7 @@ void LLPanelFace::updateUI()
BOOL identical_repeats = true;
F32 repeats = 1.0f;
- U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE;
-
+ U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
switch (material_type)
@@ -1466,22 +1466,21 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
void LLPanelFace::updateVisibility()
{
LLComboBox* combo_matmedia = getChild("combobox matmedia");
- LLComboBox* combo_mattype = getChild("combobox mattype");
+ LLRadioGroup* radio_mat_type = getChild("radio_material_type");
LLComboBox* combo_shininess = getChild("combobox shininess");
LLComboBox* combo_bumpiness = getChild("combobox bumpiness");
- if (!combo_mattype || !combo_matmedia || !combo_shininess || !combo_bumpiness)
+ if (!radio_mat_type || !combo_matmedia || !combo_shininess || !combo_bumpiness)
{
LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
return;
}
U32 materials_media = combo_matmedia->getCurrentIndex();
- U32 material_type = combo_mattype->getCurrentIndex();
+ U32 material_type = radio_mat_type->getSelectedIndex();
bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled()));
bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled();
bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
- getChildView("combobox mattype")->setVisible(!show_media);
- getChildView("rptctrl")->setVisible(true);
+ getChildView("radio_material_type")->setVisible(!show_media);
// Media controls
getChildView("media_info")->setVisible(show_media);
@@ -1608,9 +1607,9 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh
}
LLComboBox* combo_matmedia = getChild("combobox matmedia");
- LLComboBox* combo_mattype = getChild("combobox mattype");
+ LLRadioGroup* radio_mat_type = getChild("radio_material_type");
U32 materials_media = combo_matmedia->getCurrentIndex();
- U32 material_type = combo_mattype->getCurrentIndex();
+ U32 material_type = radio_mat_type->getSelectedIndex();
bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
U32 shiny_value = comboShiny->getCurrentIndex();
@@ -1693,11 +1692,11 @@ void LLPanelFace::updateAlphaControls()
mat_media = combobox_matmedia->getCurrentIndex();
}
- LLComboBox* combobox_mattype = getChild("combobox mattype");
U32 mat_type = MATTYPE_DIFFUSE;
- if (combobox_mattype)
+ LLRadioGroup* radio_mat_type = getChild("radio_material_type");
+ if(radio_mat_type)
{
- mat_type = combobox_mattype->getCurrentIndex();
+ mat_type = radio_mat_type->getSelectedIndex();
}
show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL);
@@ -1985,12 +1984,11 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
LLUICtrl* repeats_ctrl = self->getChild("rptctrl");
LLComboBox* combo_matmedia = self->getChild("combobox matmedia");
- LLComboBox* combo_mattype = self->getChild("combobox mattype");
+ LLRadioGroup* radio_mat_type = self->getChild("radio_material_type");
U32 materials_media = combo_matmedia->getCurrentIndex();
-
- U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? combo_mattype->getCurrentIndex() : 0;
+ U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : 0;
F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
F32 obj_scale_s = 1.0f;
@@ -2114,12 +2112,12 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
{
LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL;
- LLComboBox* combo_mattype = getChild("combobox mattype");
- if (!combo_mattype)
+ LLRadioGroup* radio_mat_type = getChild("radio_material_type");
+ if(radio_mat_type)
{
- return;
+ return;
}
- U32 mattype = combo_mattype->getCurrentIndex();
+ U32 mattype = radio_mat_type->getSelectedIndex();
std::string which_control="texture control";
switch (mattype)
{
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index d7e89b4832..9823e84cd9 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -307,7 +307,7 @@ private:
LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material);
}
- object->setTEMaterialParams(face, new_material, TRUE);
+ object->setTEMaterialParams(face, new_material);
return new_material;
}
return NULL;
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index c8af5b6718..c4211d5508 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -905,7 +905,11 @@ void LLTaskTextureBridge::openItem()
LLPreviewTexture* preview = LLFloaterReg::showTypedInstance("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES);
if(preview)
{
- preview->setAuxItem(findItem());
+ LLInventoryItem* item = findItem();
+ if(item)
+ {
+ preview->setAuxItem(item);
+ }
preview->setObjectID(mPanel->getTaskUUID());
}
}
@@ -1171,7 +1175,10 @@ void LLTaskNotecardBridge::openItem()
|| object->permModify()
|| gAgent.isGodlike())
{
- LLPreviewNotecard* preview = LLFloaterReg::showTypedInstance("preview_notecard", LLSD(mUUID), TAKE_FOCUS_YES);
+ LLSD floater_key;
+ floater_key["taskid"] = mPanel->getTaskUUID();
+ floater_key["itemid"] = mUUID;
+ LLPreviewNotecard* preview = LLFloaterReg::showTypedInstance("preview_notecard", floater_key, TAKE_FOCUS_YES);
if (preview)
{
preview->setObjectID(mPanel->getTaskUUID());
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 496168229d..01a22df9e1 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -1059,6 +1059,9 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
case LLAssetType::AT_BODYPART:
applyListViewFilter(LVIT_BODYPART);
break;
+ case LLAssetType::AT_GESTURE:
+ applyListViewFilter(LVIT_GESTURES);
+ break;
case LLAssetType::AT_CLOTHING:
default:
applyListViewFilter(LVIT_CLOTHING);
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 30870daf40..841bb4337a 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -80,6 +80,7 @@ public:
{
LVIT_ALL = 0,
LVIT_CLOTHING,
+ LVIT_GESTURES,
LVIT_BODYPART,
LVIT_ATTACHMENT,
LVIT_SHAPE,
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index de4efc8612..73b928f014 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -587,7 +587,12 @@ BOOL LLPanelPeople::postBuild()
getChild("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
getChild("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
getChild("fbc_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
- getChild("groupcount")->setURLClickedCallback(boost::bind(&LLPanelPeople::onGroupLimitInfo, this));
+
+ if(gMaxAgentGroups <= BASE_MAX_AGENT_GROUPS)
+ {
+ getChild("groupcount")->setText(getString("GroupCountWithInfo"));
+ getChild("groupcount")->setURLClickedCallback(boost::bind(&LLPanelPeople::onGroupLimitInfo, this));
+ }
mTabContainer = getChild("tabs");
mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 8fa9aac024..40326cfb39 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -148,6 +148,9 @@ BOOL LLPanelPickInfo::postBuild()
mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
+ LLTextEditor* text_desc = getChild(XML_DESC);
+ text_desc->setContentTrusted(false);
+
return TRUE;
}
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index e62b5a4f1d..32b72fdd68 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -201,7 +201,7 @@ void LLPanelPlaceInfo::setErrorStatus(S32 status, const std::string& reason)
// virtual
void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
{
- if(parcel_data.snapshot_id.notNull())
+ if(mSnapshotCtrl)
{
mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id);
}
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 1a665d4c1d..2fa4ee376a 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -224,6 +224,8 @@ void LLPanelPlaceProfile::resetLocation()
mSubdivideText->setValue(loading);
mResaleText->setValue(loading);
mSaleToText->setValue(loading);
+
+ getChild("sales_tab")->setVisible(TRUE);
}
// virtual
@@ -538,6 +540,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
F32 dwell;
BOOL for_sale;
vpm->getDisplayInfo(&area, &claim_price, &rent_price, &for_sale, &dwell);
+ mForSalePanel->setVisible(for_sale);
if (for_sale)
{
const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
@@ -556,8 +559,6 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
mSaleToText->setText(getString("anyone"));
}
- mForSalePanel->setVisible(for_sale);
-
const U8* sign = (U8*)getString("price_text").c_str();
const U8* sqm = (U8*)getString("area_text").c_str();
@@ -614,6 +615,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
mYouAreHerePanel->setVisible(is_current_parcel);
getChild("sales_tab")->setVisible(for_sale);
+ mAccordionCtrl->arrange();
}
void LLPanelPlaceProfile::updateEstateName(const std::string& name)
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 75e0ed3741..d86a8b4480 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -131,7 +131,7 @@ protected:
{
bp_selected = true;
}
- else if (type == LLAssetType::AT_OBJECT)
+ else if (type == LLAssetType::AT_OBJECT || type == LLAssetType::AT_GESTURE)
{
attachments_selected = true;
}
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 9f88b0db5f..f100c996b3 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -233,6 +233,7 @@ void LLPreviewNotecard::loadAsset()
else
{
LLHost source_sim = LLHost::invalid;
+ LLSD* user_data = new LLSD();
if (mObjectUUID.notNull())
{
LLViewerObject *objectp = gObjectList.findObject(mObjectUUID);
@@ -251,7 +252,13 @@ void LLPreviewNotecard::loadAsset()
mAssetStatus = PREVIEW_ASSET_LOADED;
return;
}
+ user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID);
}
+ else
+ {
+ user_data = new LLSD(mItemUUID);
+ }
+
gAssetStorage->getInvItemAsset(source_sim,
gAgent.getID(),
gAgent.getSessionID(),
@@ -261,7 +268,7 @@ void LLPreviewNotecard::loadAsset()
item->getAssetUUID(),
item->getType(),
&onLoadComplete,
- (void*)new LLUUID(mItemUUID),
+ (void*)user_data,
TRUE);
mAssetStatus = PREVIEW_ASSET_LOADING;
}
@@ -304,9 +311,8 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
void* user_data, S32 status, LLExtStat ext_status)
{
LL_INFOS() << "LLPreviewNotecard::onLoadComplete()" << LL_ENDL;
- LLUUID* item_id = (LLUUID*)user_data;
-
- LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance("preview_notecard", LLSD(*item_id));
+ LLSD* floater_key = (LLSD*)user_data;
+ LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance("preview_notecard", *floater_key);
if( preview )
{
if(0 == status)
@@ -362,7 +368,7 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
preview->mAssetStatus = PREVIEW_ASSET_ERROR;
}
}
- delete item_id;
+ delete floater_key;
}
// static
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 55bcb3dc65..7620046ee3 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1210,7 +1210,7 @@ void LLSelectMgr::setGridMode(EGridMode mode)
updateSelectionCenter();
}
-void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale)
+void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale, bool for_snap_guides)
{
mGridObjects.cleanupNodes();
@@ -1235,7 +1235,15 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
}
else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())
{
- mGridRotation = first_grid_object->getRenderRotation();
+ LLSelectNode *node = mSelectedObjects->findNode(first_grid_object);
+ if (!for_snap_guides && node)
+ {
+ mGridRotation = node->mSavedRotation;
+ }
+ else
+ {
+ mGridRotation = first_grid_object->getRenderRotation();
+ }
LLVector4a min_extents(F32_MAX);
LLVector4a max_extents(-F32_MAX);
@@ -2127,7 +2135,7 @@ void LLSelectMgr::selectionRemoveMaterial()
{
LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
LLMaterialMgr::getInstance()->remove(object->getID(),face);
- object->setTEMaterialParams(face, NULL, FALSE);
+ object->setTEMaterialParams(face, NULL);
}
return true;
}
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 87d25e3a8c..90f7fdfe13 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -527,7 +527,7 @@ public:
void clearGridObjects();
void setGridMode(EGridMode mode);
EGridMode getGridMode() { return mGridMode; }
- void getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale);
+ void getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale, bool for_snap_guides = false);
BOOL getTEMode() { return mTEMode; }
void setTEMode(BOOL b) { mTEMode = b; }
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 6af9d61a54..8561a89ae5 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -463,7 +463,10 @@ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_pare
if (old_rect.getWidth() != width || old_rect.getHeight() != height)
{
LL_DEBUGS() << "window reshaped, updating thumbnail" << LL_ENDL;
- updateSnapshot(TRUE);
+ if (mViewContainer && mViewContainer->isInVisibleChain())
+ {
+ updateSnapshot(TRUE);
+ }
}
}
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5e342099d7..22944493c9 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3770,8 +3770,9 @@ public:
LLVector4a *mTangent;
LLDrawable* mHit;
BOOL mPickTransparent;
+ BOOL mPickRigged;
- LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent,
+ LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged,
S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
: mStart(start),
mEnd(end),
@@ -3781,7 +3782,8 @@ public:
mNormal(normal),
mTangent(tangent),
mHit(NULL),
- mPickTransparent(pick_transparent)
+ mPickTransparent(pick_transparent),
+ mPickRigged(pick_rigged)
{
}
@@ -3864,9 +3866,9 @@ public:
if (vobj->isAvatar())
{
LLVOAvatar* avatar = (LLVOAvatar*) vobj;
- if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools))
+ if ((mPickRigged) || ((avatar->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
+ LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
if (hit)
{
mEnd = intersection;
@@ -3882,7 +3884,7 @@ public:
}
}
- if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
+ if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mPickRigged, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
{
mEnd = intersection; // shorten ray so we only find CLOSER hits
if (mIntersection)
@@ -3900,7 +3902,8 @@ public:
} LL_ALIGN_POSTFIX(16);
LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- BOOL pick_transparent,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit, // return the face hit
LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
@@ -3909,7 +3912,7 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, co
)
{
- LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
+ LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, face_hit, intersection, tex_coord, normal, tangent);
LLDrawable* drawable = intersect.check(mOctree);
return drawable;
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 08a4d00d0f..7633e46200 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -386,6 +386,7 @@ public:
LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit, // return the face hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 965aad517d..8a027fdbfa 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -3245,12 +3245,15 @@ bool process_login_success_response()
gAgentUsername = first_name;
}
- if(response.has("last_name") && !gAgentUsername.empty() && (gAgentUsername != "Resident"))
+ if(response.has("last_name") && !gAgentUsername.empty())
{
std::string last_name = response["last_name"].asString();
- LLStringUtil::replaceChar(last_name, '"', ' ');
- LLStringUtil::trim(last_name);
- gAgentUsername = gAgentUsername + " " + last_name;
+ if (last_name != "Resident")
+ {
+ LLStringUtil::replaceChar(last_name, '"', ' ');
+ LLStringUtil::trim(last_name);
+ gAgentUsername = gAgentUsername + " " + last_name;
+ }
}
if(gDisplayName.empty())
diff --git a/indra/newview/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp
index 057d80457c..2a58f018e7 100644
--- a/indra/newview/llsyswellitem.cpp
+++ b/indra/newview/llsyswellitem.cpp
@@ -43,6 +43,7 @@ LLSysWellItem::LLSysWellItem(const Params& p) : LLPanel(p),
mTitle = getChild("title");
mCloseBtn = getChild("close_btn");
+ mTitle->setContentTrusted(false);
mTitle->setValue(p.title);
mCloseBtn->setClickedCallback(boost::bind(&LLSysWellItem::onClickCloseBtn,this));
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index e62b0607d1..5306ee6be0 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -2523,7 +2523,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mFetchDebugger(NULL),
mFetchSource(LLTextureFetch::FROM_ALL),
mOriginFetchSource(LLTextureFetch::FROM_ALL),
- mFetcherLocked(FALSE)
+ mFetcherLocked(FALSE),
+ mTextureInfoMainThread(false)
{
mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), U32Bytes(gSavedSettings.getU32("TextureLoggingThreshold")));
@@ -3129,6 +3130,7 @@ void LLTextureFetch::shutDownImageDecodeThread()
// Threads: Ttf
void LLTextureFetch::startThread()
{
+ mTextureInfo.startRecording();
}
// Threads: Ttf
@@ -3139,6 +3141,8 @@ void LLTextureFetch::endThread()
<< ", ResWaits: " << mTotalResourceWaitCount
<< ", TotalHTTPReq: " << getTotalNumHTTPRequests()
<< LL_ENDL;
+
+ mTextureInfo.stopRecording();
}
// Threads: Ttf
@@ -3542,8 +3546,8 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
if (log_to_viewer_log || log_to_sim)
{
U64Microseconds timeNow = LLTimer::getTotalTime();
- mTextureInfo.setRequestSize(id, worker->mFileSize);
- mTextureInfo.setRequestCompleteTimeAndLog(id, timeNow);
+ mTextureInfoMainThread.setRequestSize(id, worker->mFileSize);
+ mTextureInfoMainThread.setRequestCompleteTimeAndLog(id, timeNow);
}
}
worker->unlockWorkMutex(); // -Mw
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 27779a31e0..a2658ecd85 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -332,6 +332,7 @@ private:
F32 mTextureBandwidth; //
F32 mMaxBandwidth; // Mfnq
LLTextureInfo mTextureInfo;
+ LLTextureInfo mTextureInfoMainThread;
// XXX possible delete
U32Bits mHTTPTextureBits; // Mfnq
diff --git a/indra/newview/lltextureinfo.cpp b/indra/newview/lltextureinfo.cpp
index 59d692b287..473d8ce709 100644
--- a/indra/newview/lltextureinfo.cpp
+++ b/indra/newview/lltextureinfo.cpp
@@ -36,14 +36,16 @@ static LLTrace::CountStatHandle sTextureDownloadsCompleted("texture_downloa
static LLTrace::CountStatHandle sTextureDataDownloaded("texture_data_downloaded", "amount of texture data downloaded");
static LLTrace::CountStatHandle sTexureDownloadTime("texture_download_time", "amount of time spent fetching textures");
-LLTextureInfo::LLTextureInfo() :
+LLTextureInfo::LLTextureInfo(bool postponeStartRecoreder) :
mLogTextureDownloadsToViewerLog(false),
mLogTextureDownloadsToSimulator(false),
mTextureDownloadProtocol("NONE"),
mTextureLogThreshold(LLUnits::Kilobytes::fromValue(100))
{
- mTextures.clear();
- mRecording.start();
+ if (!postponeStartRecoreder)
+ {
+ startRecording();
+ }
}
void LLTextureInfo::setUpLogging(bool writeToViewerLog, bool sendToSim, U32Bytes textureLogThreshold)
@@ -78,15 +80,7 @@ U32 LLTextureInfo::getTextureInfoMapSize()
bool LLTextureInfo::has(const LLUUID& id)
{
- std::map::iterator iterator = mTextures.find(id);
- if (iterator == mTextures.end())
- {
- return false;
- }
- else
- {
- return true;
- }
+ return mTextures.end() != mTextures.find(id);
}
void LLTextureInfo::setRequestStartTime(const LLUUID& id, U64 startTime)
@@ -192,15 +186,12 @@ void LLTextureInfo::setRequestCompleteTimeAndLog(const LLUUID& id, U64Microsecon
LLSD LLTextureInfo::getAverages()
{
LLSD averagedTextureData;
- S32 averageDownloadRate;
- U32Milliseconds download_time = mRecording.getSum(sTexureDownloadTime);
- if(download_time == (U32Milliseconds)0)
+ S32 averageDownloadRate = 0;
+ unsigned int download_time = mRecording.getSum(sTexureDownloadTime).valueInUnits();
+
+ if (0 != download_time)
{
- averageDownloadRate = 0;
- }
- else
- {
- averageDownloadRate = mRecording.getSum(sTextureDataDownloaded).valueInUnits() / download_time.valueInUnits();
+ averageDownloadRate = mRecording.getSum(sTextureDataDownloaded).valueInUnits() / download_time;
}
averagedTextureData["bits_per_second"] = averageDownloadRate;
@@ -212,6 +203,16 @@ LLSD LLTextureInfo::getAverages()
return averagedTextureData;
}
+void LLTextureInfo::startRecording()
+{
+ mRecording.start();
+}
+
+void LLTextureInfo::stopRecording()
+{
+ mRecording.stop();
+}
+
void LLTextureInfo::resetTextureStatistics()
{
mRecording.restart();
diff --git a/indra/newview/lltextureinfo.h b/indra/newview/lltextureinfo.h
index 176f2cbb74..03721bdd73 100644
--- a/indra/newview/lltextureinfo.h
+++ b/indra/newview/lltextureinfo.h
@@ -35,7 +35,7 @@
class LLTextureInfo
{
public:
- LLTextureInfo();
+ LLTextureInfo(bool postponeStartRecoreder = true);
~LLTextureInfo();
void setUpLogging(bool writeToViewerLog, bool sendToSim, U32Bytes textureLogThreshold);
@@ -53,6 +53,8 @@ public:
void resetTextureStatistics();
U32 getTextureInfoMapSize();
LLSD getAverages();
+ void startRecording();
+ void stopRecording();
private:
void addRequest(const LLUUID& id);
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index e22f527a65..cafe757c1a 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -98,6 +98,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
LLStringUtil::format(timeStr, substitution);
LLViewerTextEditor* pMessageText = getChild("message");
+ pMessageText->setContentTrusted(false);
pMessageText->clear();
LLStyle::Params style;
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 5a63f6e286..76a791c6e9 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -267,7 +267,7 @@ BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask)
BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask)
{
mMouseDown = TRUE;
- gViewerWindow->pickAsync(x, y, mask, pickCallback, TRUE);
+ gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
return TRUE;
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 5c9aedcf8f..78d9c7a3f4 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -861,12 +861,12 @@ void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAccep
if (mDrop)
{
// don't allow drag and drop onto transparent objects
- pick(gViewerWindow->pickImmediate(x, y, FALSE));
+ pick(gViewerWindow->pickImmediate(x, y, FALSE, FALSE));
}
else
{
// don't allow drag and drop onto transparent objects
- gViewerWindow->pickAsync(x, y, mask, pickCallback, FALSE);
+ gViewerWindow->pickAsync(x, y, mask, pickCallback, FALSE, FALSE);
}
*acceptance = mLastAccept;
@@ -1013,13 +1013,10 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
// causing a dirty inventory) and we can do an update, stall the user
// while fetching the inventory.
//
- // Note: fetch only if inventory is both dirty and not present since previously checked faces
- // could have requested new fetch for same item (removed inventory and marked as dirty=false).
- // Objects without listeners (dirty==true and inventory!=NULL. In this specific case - before
- // first fetch) shouldn't be updated either since we won't receive any changes.
- if (hit_obj->isInventoryDirty() && hit_obj->getInventoryRoot() == NULL)
+ // Fetch if inventory is dirty and listener is present (otherwise we will not receive update)
+ if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners())
{
- hit_obj->fetchInventoryFromServer();
+ hit_obj->requestInventory();
LLSD args;
args["ERROR_MESSAGE"] = "Unable to add texture.\nPlease wait a few seconds and try again.";
LLNotificationsUtil::add("ErrorMessage", args);
@@ -1099,10 +1096,12 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
{
hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
}
- // Force the object to update its refetch its inventory so it has this texture.
- hit_obj->fetchInventoryFromServer();
- // TODO: Check to see if adding the item was successful; if not, then
- // we should return false here.
+ // Force the object to update and refetch its inventory so it has this texture.
+ hit_obj->dirtyInventory();
+ hit_obj->requestInventory();
+ // TODO: Check to see if adding the item was successful; if not, then
+ // we should return false here. This will requre a separate listener
+ // since without listener, we have no way to receive update
}
return TRUE;
}
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index 15f3c36674..c4696c3a01 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -135,7 +135,7 @@ BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)
gViewerWindow->hideCursor();
- gViewerWindow->pickAsync(x, y, mask, pickCallback, FALSE, TRUE);
+ gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ FALSE, /*BOOL pick_rigged*/ FALSE, /*BOOL pick_unselectable*/ TRUE);
return TRUE;
}
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index fa6694b93b..92e8af985b 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -146,7 +146,7 @@ BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask)
if (!gAgent.leftButtonGrabbed())
{
// can grab transparent objects (how touch event propagates, scripters rely on this)
- gViewerWindow->pickAsync(x, y, mask, pickCallback, TRUE);
+ gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
}
mClickedInMouselook = gAgentCamera.cameraMouselook();
return TRUE;
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 2081297717..abb9a63238 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -106,8 +106,8 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
mMouseDownX = x;
mMouseDownY = y;
- //left mouse down always picks transparent
- mPick = gViewerWindow->pickImmediate(x, y, TRUE);
+ //left mouse down always picks transparent (but see handleMouseUp)
+ mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
mPick.mKeyMask = mask;
mMouseButtonDown = true;
@@ -122,7 +122,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
// don't pick transparent so users can't "pay" transparent objects
- mPick = gViewerWindow->pickImmediate(x, y, FALSE, TRUE);
+ mPick = gViewerWindow->pickImmediate(x, y, /*BOOL pick_transparent*/ FALSE, /*BOOL pick_rigged*/ TRUE, /*BOOL pick_particle*/ TRUE);
mPick.mKeyMask = mask;
// claim not handled so UI focus stays same
@@ -546,7 +546,7 @@ void LLToolPie::selectionPropertiesReceived()
BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
{
- mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE);
+ mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE, FALSE);
LLViewerObject *parent = NULL;
LLViewerObject *object = mHoverPick.getObject();
LLSelectMgr::getInstance()->setHoverObject(object, mHoverPick.mObjectFace);
@@ -592,7 +592,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
else
{
// perform a separate pick that detects transparent objects since they respond to 1-click actions
- LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE);
+ LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
LLViewerObject* click_action_object = click_action_pick.getObject();
@@ -661,30 +661,52 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
&& gAgentAvatarp
&& !gAgentAvatarp->isSitting()
&& !mBlockClickToWalk // another behavior hasn't cancelled click to walk
- && !mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick
- && (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land
- || mPick.mObjectID.notNull())) // or on an object
+ )
{
- // handle special cases of steering picks
- LLViewerObject* avatar_object = mPick.getObject();
+ // We may be doing click to walk, but we don't want to use a target on
+ // a transparent object because the user thought they were clicking on
+ // whatever they were seeing through it, so recompute what was clicked on
+ // ignoring transparent objects
+ LLPickInfo savedPick = mPick;
+ mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY,
+ FALSE /* ignore transparent */,
+ FALSE /* ignore particles */);
- // get pointer to avatar
- while (avatar_object && !avatar_object->isAvatar())
- {
- avatar_object = (LLViewerObject*)avatar_object->getParent();
- }
+ if (!mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick
+ && (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land
+ || mPick.mObjectID.notNull())) // or on an object
+ {
+ // handle special cases of steering picks
+ LLViewerObject* avatar_object = mPick.getObject();
- if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf())
- {
- const F64 SELF_CLICK_WALK_DISTANCE = 3.0;
- // pretend we picked some point a bit in front of avatar
- mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE;
- }
- gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
- walkToClickedLocation();
- LLFirstUse::notMoving(false);
+ // get pointer to avatar
+ while (avatar_object && !avatar_object->isAvatar())
+ {
+ avatar_object = (LLViewerObject*)avatar_object->getParent();
+ }
- return TRUE;
+ if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf())
+ {
+ const F64 SELF_CLICK_WALK_DISTANCE = 3.0;
+ // pretend we picked some point a bit in front of avatar
+ mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE;
+ }
+ gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
+ walkToClickedLocation();
+ LLFirstUse::notMoving(false);
+
+ return TRUE;
+ }
+ else
+ {
+ LL_DEBUGS("maint5901") << "walk target was "
+ << (mPick.mPosGlobal.isExactlyZero() ? "zero" : "not zero")
+ << ", pick type was " << (mPick.mPickType == LLPickInfo::PICK_LAND ? "land" : "not land")
+ << ", pick object was " << mPick.mObjectID
+ << LL_ENDL;
+ // we didn't click to walk, so restore the original target
+ mPick = savedPick;
+ }
}
gViewerWindow->setCursor(UI_CURSOR_ARROW);
if (hasMouseCapture())
@@ -716,14 +738,33 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
LL_INFOS() << "LLToolPie handleDoubleClick (becoming mouseDown)" << LL_ENDL;
}
+ if (handleMediaDblClick(mPick))
+ {
+ return TRUE;
+ }
+
if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))
{
+ // We may be doing double click to walk, but we don't want to use a target on
+ // a transparent object because the user thought they were clicking on
+ // whatever they were seeing through it, so recompute what was clicked on
+ // ignoring transparent objects
+ LLPickInfo savedPick = mPick;
+ mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY,
+ FALSE /* ignore transparent */,
+ FALSE /* ignore particles */);
+
if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||
(mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero()))
{
walkToClickedLocation();
return TRUE;
}
+ else
+ {
+ // restore the original pick for any other purpose
+ mPick = savedPick;
+ }
}
else if (gSavedSettings.getBOOL("DoubleClickTeleport"))
{
@@ -1404,56 +1445,110 @@ static void handle_click_action_play()
bool LLToolPie::handleMediaClick(const LLPickInfo& pick)
{
- //FIXME: how do we handle object in different parcel than us?
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- LLPointer objectp = pick.getObject();
+ //FIXME: how do we handle object in different parcel than us?
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ LLPointer objectp = pick.getObject();
- if (!parcel ||
- objectp.isNull() ||
- pick.mObjectFace < 0 ||
- pick.mObjectFace >= objectp->getNumTEs())
- {
- LLViewerMediaFocus::getInstance()->clearFocus();
+ if (!parcel ||
+ objectp.isNull() ||
+ pick.mObjectFace < 0 ||
+ pick.mObjectFace >= objectp->getNumTEs())
+ {
+ LLViewerMediaFocus::getInstance()->clearFocus();
- return false;
- }
+ return false;
+ }
- // Does this face have media?
- const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
- if(!tep)
- return false;
+ // Does this face have media?
+ const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
+ if (!tep)
+ return false;
- LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
- if(!mep)
- return false;
-
- viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
+ LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
+ if (!mep)
+ return false;
- if (gSavedSettings.getBOOL("MediaOnAPrimUI"))
- {
- if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull())
- {
- // It's okay to give this a null impl
- LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal);
- }
- else
- {
- // Make sure keyboard focus is set to the media focus object.
- gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance());
- LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl();
-
- media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE));
- mMediaMouseCaptureID = mep->getMediaID();
- setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture.
- }
+ viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
- return true;
- }
+ if (gSavedSettings.getBOOL("MediaOnAPrimUI"))
+ {
+ if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull())
+ {
+ // It's okay to give this a null impl
+ LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal);
+ }
+ else
+ {
+ // Make sure keyboard focus is set to the media focus object.
+ gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance());
+ LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl();
- LLViewerMediaFocus::getInstance()->clearFocus();
+ media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE));
+ mMediaMouseCaptureID = mep->getMediaID();
+ setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture.
+ }
- return false;
+ return true;
+ }
+
+ LLViewerMediaFocus::getInstance()->clearFocus();
+
+ return false;
+}
+
+bool LLToolPie::handleMediaDblClick(const LLPickInfo& pick)
+{
+ //FIXME: how do we handle object in different parcel than us?
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ LLPointer objectp = pick.getObject();
+
+
+ if (!parcel ||
+ objectp.isNull() ||
+ pick.mObjectFace < 0 ||
+ pick.mObjectFace >= objectp->getNumTEs())
+ {
+ LLViewerMediaFocus::getInstance()->clearFocus();
+
+ return false;
+ }
+
+ // Does this face have media?
+ const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
+ if (!tep)
+ return false;
+
+ LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
+ if (!mep)
+ return false;
+
+ viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
+
+ if (gSavedSettings.getBOOL("MediaOnAPrimUI"))
+ {
+ if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull())
+ {
+ // It's okay to give this a null impl
+ LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal);
+ }
+ else
+ {
+ // Make sure keyboard focus is set to the media focus object.
+ gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance());
+ LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl();
+
+ media_impl->mouseDoubleClick(pick.mUVCoords, gKeyboard->currentMask(TRUE));
+ mMediaMouseCaptureID = mep->getMediaID();
+ setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture.
+ }
+
+ return true;
+ }
+
+ LLViewerMediaFocus::getInstance()->clearFocus();
+
+ return false;
}
bool LLToolPie::handleMediaHover(const LLPickInfo& pick)
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 68fe8bc4a5..c4a2f4a35b 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -88,7 +88,8 @@ private:
ECursorType cursorFromObject(LLViewerObject* object);
bool handleMediaClick(const LLPickInfo& info);
- bool handleMediaHover(const LLPickInfo& info);
+ bool handleMediaDblClick(const LLPickInfo& info);
+ bool handleMediaHover(const LLPickInfo& info);
bool handleMediaMouseUp();
BOOL handleTooltipLand(std::string line, std::string tooltip_msg);
BOOL handleTooltipObject( LLViewerObject* hover_object, std::string line, std::string tooltip_msg);
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index ceb57d0172..814bade56a 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -80,7 +80,7 @@ BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj,
// Viewer-side pick to find the right sim to create the object on.
// First find the surface the object will be created on.
- LLPickInfo pick = gViewerWindow->pickImmediate(x, y, FALSE);
+ LLPickInfo pick = gViewerWindow->pickImmediate(x, y, FALSE, FALSE);
// Note: use the frontmost non-flora version because (a) plants usually have lots of alpha and (b) pants' Havok
// representations (if any) are NOT the same as their viewer representation.
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 812abe9dbd..1fcc9a0711 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -63,7 +63,7 @@ LLToolSelect::LLToolSelect( LLToolComposite* composite )
BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
{
// do immediate pick query
- mPick = gViewerWindow->pickImmediate(x, y, TRUE);
+ mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
// Pass mousedown to agent
LLTool::handleMouseDown(x, y, mask);
diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp
index c5616fb208..71dc8001d4 100644
--- a/indra/newview/lltoolselectrect.cpp
+++ b/indra/newview/lltoolselectrect.cpp
@@ -71,7 +71,7 @@ void dialog_refresh_all(void);
BOOL LLToolSelectRect::handleMouseDown(S32 x, S32 y, MASK mask)
{
- handlePick(gViewerWindow->pickImmediate(x, y, TRUE));
+ handlePick(gViewerWindow->pickImmediate(x, y, TRUE, FALSE));
LLTool::handleMouseDown(x, y, mask);
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index ada829eb4b..2186ed3c52 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -423,7 +423,7 @@ void camera_move_backward( EKeystate s )
void camera_move_forward_sitting( EKeystate s )
{
if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return;
- if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
+ if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
{
agent_push_forward(s);
}
@@ -438,7 +438,7 @@ void camera_move_backward_sitting( EKeystate s )
{
if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return;
- if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
+ if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
{
agent_push_backward(s);
}
@@ -729,7 +729,10 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL
return mKeyHandledByUI[translated_key];
}
-
+BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask)
+{
+ return gViewerWindow->handleKeyUp(translated_key, translated_mask);
+}
BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name)
{
diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h
index ca73212ed1..110dc89d28 100644
--- a/indra/newview/llviewerkeyboard.h
+++ b/indra/newview/llviewerkeyboard.h
@@ -89,6 +89,7 @@ public:
LLViewerKeyboard();
BOOL handleKey(KEY key, MASK mask, BOOL repeated);
+ BOOL handleKeyUp(KEY key, MASK mask);
S32 loadBindings(const std::string& filename); // returns number bound, 0 on error
S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 3eae0f8d86..ffae3c0e1f 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -5,21 +5,21 @@
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -66,6 +66,7 @@
#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llvovolume.h"
+#include "llfloaterreg.h"
#include "llwebprofile.h"
#include "llwindow.h"
#include "llvieweraudio.h"
@@ -167,7 +168,7 @@ public:
{
LL_ERRS() << "impl already has an outstanding responder" << LL_ENDL;
}
-
+
mMediaImpl->mMimeTypeProbe = this;
}
@@ -189,19 +190,19 @@ private:
std::string mime_type = media_type.substr(0, idx1);
LL_DEBUGS() << "status is " << getStatus() << ", media type \"" << media_type << "\"" << LL_ENDL;
-
+
// 2xx status codes indicate success.
// Most 4xx status codes are successful enough for our purposes.
// 499 is the error code for host not found, timeout, etc.
- // 500 means "Internal Server error" but we decided it's okay to
+ // 500 means "Internal Server error" but we decided it's okay to
// accept this and go past it in the MIME type probe
// 302 means the resource can be found temporarily in a different place - added this for join.secondlife.com
// 499 is a code specifc to join.secondlife.com apparently safe to ignore
// if( ((status >= 200) && (status < 300)) ||
-// ((status >= 400) && (status < 499)) ||
+// ((status >= 400) && (status < 499)) ||
// (status == 500) ||
// (status == 302) ||
-// (status == 499)
+// (status == 499)
// )
// We now no longer check the error code returned from the probe.
// If we have a mime type, use it. If not, default to the web plugin and let it handle error reporting.
@@ -229,7 +230,7 @@ private:
// the call to initializeMedia may disconnect the responder, which will clear mMediaImpl.
// Make a local copy so we can call loadURI() afterwards.
LLViewerMediaImpl *impl = mMediaImpl;
-
+
if(impl && !mInitialized && ! mime_type.empty())
{
if(impl->initializeMedia(mime_type))
@@ -240,13 +241,13 @@ private:
}
}
}
-
+
public:
void cancelRequest()
{
disconnectOwner();
}
-
+
private:
void disconnectOwner()
{
@@ -261,8 +262,8 @@ private:
}
mMediaImpl = NULL;
}
-
-
+
+
public:
LLViewerMediaImpl *mMediaImpl;
bool mInitialized;
@@ -284,13 +285,12 @@ public:
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
- // We don't care about the content of the response, only the Set-Cookie header.
- LL_DEBUGS("MediaAuth") << dumpResponse()
- << " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
+ const std::string url = getURL();
+
const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE);
-
+
// *TODO: What about bad status codes? Does this destroy previous cookies?
- LLViewerMedia::openIDCookieResponse(cookie);
+ LLViewerMedia::openIDCookieResponse(url, cookie);
}
};
@@ -313,7 +313,7 @@ public:
const LLIOPipe::buffer_ptr_t& buffer)
{
// We don't care about the content of the response, only the set-cookie header.
- LL_WARNS("MediaAuth") << dumpResponse()
+ LL_WARNS("MediaAuth") << dumpResponse()
<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
LLSD stripped_content = getResponseHeaders();
@@ -364,7 +364,7 @@ static void remove_media_impl(LLViewerMediaImpl* media)
{
LLViewerMedia::impl_list::iterator iter = sViewerMediaImplList.begin();
LLViewerMedia::impl_list::iterator end = sViewerMediaImplList.end();
-
+
for(; iter != end; iter++)
{
if(media == *iter)
@@ -391,8 +391,8 @@ static bool sViewerMediaMuteListObserverInitialized = false;
// static
viewer_media_t LLViewerMedia::newMediaImpl(
const LLUUID& texture_id,
- S32 media_width,
- S32 media_height,
+ S32 media_width,
+ S32 media_height,
U8 media_auto_scale,
U8 media_loop)
{
@@ -416,24 +416,24 @@ viewer_media_t LLViewerMedia::newMediaImpl(
}
viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self)
-{
+{
// Try to find media with the same media ID
viewer_media_t media_impl = getMediaImplFromTextureID(media_entry->getMediaID());
-
- LL_DEBUGS() << "called, current URL is \"" << media_entry->getCurrentURL()
- << "\", previous URL is \"" << previous_url
+
+ LL_DEBUGS() << "called, current URL is \"" << media_entry->getCurrentURL()
+ << "\", previous URL is \"" << previous_url
<< "\", update_from_self is " << (update_from_self?"true":"false")
<< LL_ENDL;
-
+
bool was_loaded = false;
bool needs_navigate = false;
-
+
if(media_impl)
- {
+ {
was_loaded = media_impl->hasMedia();
-
+
media_impl->setHomeURL(media_entry->getHomeURL());
-
+
media_impl->mMediaAutoScale = media_entry->getAutoScale();
media_impl->mMediaLoop = media_entry->getAutoLoop();
media_impl->mMediaWidth = media_entry->getWidthPixels();
@@ -446,7 +446,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
media_impl->mMediaSource->setLoop(media_impl->mMediaLoop);
media_impl->mMediaSource->setSize(media_entry->getWidthPixels(), media_entry->getHeightPixels());
}
-
+
bool url_changed = (media_impl->mMediaEntryURL != previous_url);
if(media_impl->mMediaEntryURL.empty())
{
@@ -454,7 +454,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
{
// The current media URL is now empty. Unload the media source.
media_impl->unload();
-
+
LL_DEBUGS() << "Unloading media instance (new current URL is empty)." << LL_ENDL;
}
}
@@ -463,26 +463,26 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
// The current media URL is not empty.
// If (the media was already loaded OR the media was set to autoplay) AND this update didn't come from this agent,
// do a navigate.
- bool auto_play = media_impl->isAutoPlayable();
+ bool auto_play = media_impl->isAutoPlayable();
if((was_loaded || auto_play) && !update_from_self)
{
needs_navigate = url_changed;
}
-
- LL_DEBUGS() << "was_loaded is " << (was_loaded?"true":"false")
- << ", auto_play is " << (auto_play?"true":"false")
+
+ LL_DEBUGS() << "was_loaded is " << (was_loaded?"true":"false")
+ << ", auto_play is " << (auto_play?"true":"false")
<< ", needs_navigate is " << (needs_navigate?"true":"false") << LL_ENDL;
}
}
else
{
media_impl = newMediaImpl(
- media_entry->getMediaID(),
+ media_entry->getMediaID(),
media_entry->getWidthPixels(),
- media_entry->getHeightPixels(),
- media_entry->getAutoScale(),
+ media_entry->getHeightPixels(),
+ media_entry->getAutoScale(),
media_entry->getAutoLoop());
-
+
media_impl->setHomeURL(media_entry->getHomeURL());
media_impl->mMediaAutoPlay = media_entry->getAutoPlay();
media_impl->mMediaEntryURL = media_entry->getCurrentURL();
@@ -491,7 +491,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
needs_navigate = true;
}
}
-
+
if(media_impl)
{
if(needs_navigate)
@@ -510,7 +510,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
LL_DEBUGS() << "updating URL in the media impl to " << media_impl->mMediaEntryURL << LL_ENDL;
}
}
-
+
return media_impl;
}
@@ -519,7 +519,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& texture_id)
{
LLViewerMediaImpl* result = NULL;
-
+
// Look up the texture ID in the texture id->impl map.
impl_id_map::iterator iter = sViewerMediaTextureIDMap.find(texture_id);
if(iter != sViewerMediaTextureIDMap.end())
@@ -534,7 +534,7 @@ LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& textur
// static
std::string LLViewerMedia::getCurrentUserAgent()
{
- // Don't use user-visible string to avoid
+ // Don't use user-visible string to avoid
// punctuation and strange characters.
std::string skin_name = gSavedSettings.getString("SkinCurrent");
@@ -553,7 +553,7 @@ std::string LLViewerMedia::getCurrentUserAgent()
codec << LLVersionInfo::getVersion();
codec << " (" << channel << "; " << skin_name << " skin)";
LL_INFOS() << codec.str() << LL_ENDL;
-
+
return codec.str();
}
@@ -562,7 +562,7 @@ std::string LLViewerMedia::getCurrentUserAgent()
void LLViewerMedia::updateBrowserUserAgent()
{
std::string user_agent = getCurrentUserAgent();
-
+
impl_list::iterator iter = sViewerMediaImplList.begin();
impl_list::iterator end = sViewerMediaImplList.end();
@@ -651,7 +651,7 @@ void LLViewerMedia::muteListChanged()
bool LLViewerMedia::isInterestingEnough(const LLVOVolume *object, const F64 &object_interest)
{
bool result = false;
-
+
if (NULL == object)
{
result = false;
@@ -667,13 +667,13 @@ bool LLViewerMedia::isInterestingEnough(const LLVOVolume *object, const F64 &obj
{
result = true;
}
- else
+ else
{
LL_DEBUGS() << "object interest = " << object_interest << ", lowest loadable = " << sLowestLoadableImplInterest << LL_ENDL;
if(object_interest >= sLowestLoadableImplInterest)
result = true;
}
-
+
return result;
}
@@ -780,13 +780,13 @@ static LLTrace::BlockTimerStatHandle FTM_MEDIA_MISC("Misc");
void LLViewerMedia::updateMedia(void *dummy_arg)
{
LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE);
-
+
// Enable/disable the plugin read thread
LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread"));
-
+
// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
createSpareBrowserMediaSource();
-
+
sAnyMediaShowing = false;
sUpdatedCookies = getCookieStore()->getChangedCookies();
if(!sUpdatedCookies.empty())
@@ -794,7 +794,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
LL_DEBUGS() << "updated cookies will be sent to all loaded plugins: " << LL_ENDL;
LL_DEBUGS() << sUpdatedCookies << LL_ENDL;
}
-
+
impl_list::iterator iter = sViewerMediaImplList.begin();
impl_list::iterator end = sViewerMediaImplList.end();
@@ -807,14 +807,14 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
pimpl->calculateInterest();
}
}
-
+
// Let the spare media source actually launch
if(sSpareBrowserMediaSource)
{
LL_RECORD_BLOCK_TIME(FTM_MEDIA_SPARE_IDLE);
sSpareBrowserMediaSource->idle();
}
-
+
{
LL_RECORD_BLOCK_TIME(FTM_MEDIA_SORT);
// Sort the static instance list using our interest criteria
@@ -824,14 +824,14 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
// Go through the list again and adjust according to priority.
iter = sViewerMediaImplList.begin();
end = sViewerMediaImplList.end();
-
+
F64 total_cpu = 0.0f;
int impl_count_total = 0;
int impl_count_interest_low = 0;
int impl_count_interest_normal = 0;
-
+
std::vector proximity_order;
-
+
bool inworld_media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
bool inworld_audio_enabled = gSavedSettings.getBOOL("AudioStreamingMusic");
U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal");
@@ -840,19 +840,19 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
F32 max_cpu = gSavedSettings.getF32("PluginInstancesCPULimit");
// Setting max_cpu to 0.0 disables CPU usage checking.
bool check_cpu_usage = (max_cpu != 0.0f);
-
+
LLViewerMediaImpl* lowest_interest_loadable = NULL;
-
+
// Notes on tweakable params:
// max_instances must be set high enough to allow the various instances used in the UI (for the help browser, search, etc.) to be loaded.
// If max_normal + max_low is less than max_instances, things will tend to get unloaded instead of being set to slideshow.
-
+
{
LL_RECORD_BLOCK_TIME(FTM_MEDIA_MISC);
for(; iter != end; iter++)
{
LLViewerMediaImpl* pimpl = *iter;
-
+
LLPluginClassMedia::EPriority new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
if(pimpl->isForcedUnloaded() || (impl_count_total >= (int)max_instances))
@@ -883,7 +883,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
else
{
// Look at interest and CPU usage for instances that aren't in any of the above states.
-
+
// Heuristic -- if the media texture's approximate screen area is less than 1/4 of the native area of the texture,
// turn it down to low instead of normal. This may downsample for plugins that support it.
bool media_is_small = false;
@@ -897,7 +897,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
{
media_is_small = true;
}
-
+
if(pimpl->getInterest() == 0.0f)
{
// This media is completely invisible, due to being outside the view frustrum or out of range.
@@ -919,11 +919,11 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
// The next max_low inworld get turned down
new_priority = LLPluginClassMedia::PRIORITY_LOW;
impl_count_interest_low++;
-
+
// Set the low priority size for downsampling to approximately the size the texture is displayed at.
{
F32 approximate_interest_dimension = (F32) sqrt(pimpl->getInterest());
-
+
pimpl->setLowPrioritySizeLimit(ll_round(approximate_interest_dimension));
}
}
@@ -933,18 +933,18 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
new_priority = LLPluginClassMedia::PRIORITY_SLIDESHOW;
}
}
-
+
if(!pimpl->getUsedInUI() && (new_priority != LLPluginClassMedia::PRIORITY_UNLOADED))
{
// This is a loadable inworld impl -- the last one in the list in this class defines the lowest loadable interest.
lowest_interest_loadable = pimpl;
-
+
impl_count_total++;
}
// Overrides if the window is minimized or we lost focus (taking care
// not to accidentally "raise" the priority either)
- if (!gViewerWindow->getActive() /* viewer window minimized? */
+ if (!gViewerWindow->getActive() /* viewer window minimized? */
&& new_priority > LLPluginClassMedia::PRIORITY_HIDDEN)
{
new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
@@ -954,7 +954,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
{
new_priority = LLPluginClassMedia::PRIORITY_LOW;
}
-
+
if(!inworld_media_enabled)
{
// If inworld media is locked out, force all inworld media to stay unloaded.
@@ -972,7 +972,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
}
}
pimpl->setPriority(new_priority);
-
+
if(pimpl->getUsedInUI())
{
// Any impls used in the UI should not be in the proximity list.
@@ -984,7 +984,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
}
total_cpu += pimpl->getCPUUsage();
-
+
if (!pimpl->getUsedInUI() && pimpl->hasMedia())
{
sAnyMediaShowing = true;
@@ -1008,7 +1008,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
sLowestLoadableImplInterest = object->getPixelArea();
}
}
-
+
if(gSavedSettings.getBOOL("MediaPerformanceManagerDebug"))
{
// Give impls the same ordering as the priority list
@@ -1017,7 +1017,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
else
{
LL_RECORD_BLOCK_TIME(FTM_MEDIA_SORT2);
- // Use a distance-based sort for proximity values.
+ // Use a distance-based sort for proximity values.
std::stable_sort(proximity_order.begin(), proximity_order.end(), proximity_comparitor);
}
@@ -1026,7 +1026,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
{
proximity_order[i]->mProximity = i;
}
-
+
LL_DEBUGS("PluginPriority") << "Total reported CPU usage is " << total_cpu << LL_ENDL;
}
@@ -1045,11 +1045,11 @@ void LLViewerMedia::setAllMediaEnabled(bool val)
// Set "tentative" autoplay first. We need to do this here or else
// re-enabling won't start up the media below.
gSavedSettings.setBOOL("MediaTentativeAutoPlay", val);
-
- // Then
+
+ // Then
impl_list::iterator iter = sViewerMediaImplList.begin();
impl_list::iterator end = sViewerMediaImplList.end();
-
+
for(; iter != end; iter++)
{
LLViewerMediaImpl* pimpl = *iter;
@@ -1058,18 +1058,18 @@ void LLViewerMedia::setAllMediaEnabled(bool val)
pimpl->setDisabled(!val);
}
}
-
+
// Also do Parcel Media and Parcel Audio
if (val)
{
if (!LLViewerMedia::isParcelMediaPlaying() && LLViewerMedia::hasParcelMedia())
- {
+ {
LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel());
}
-
+
if (gSavedSettings.getBOOL("AudioStreamingMusic") &&
!LLViewerMedia::isParcelAudioPlaying() &&
- gAudiop &&
+ gAudiop &&
LLViewerMedia::hasParcelAudio())
{
if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying())
@@ -1142,26 +1142,26 @@ void LLViewerMedia::clearAllCookies()
pimpl->mMediaSource->clear_cookies();
}
}
-
+
// Clear all cookies from the cookie store
getCookieStore()->setAllCookies("");
// FIXME: this may not be sufficient, since the on-disk cookie file won't get written until some browser instance exits cleanly.
// It also won't clear cookies for other accounts, or for any account if we're not logged in, and won't do anything at all if there are no webkit plugins loaded.
// Until such time as we can centralize cookie storage, the following hack should cover these cases:
-
+
// HACK: Look for cookie files in all possible places and delete them.
// NOTE: this assumes knowledge of what happens inside the webkit plugin (it's what adds 'browser_profile' to the path and names the cookie file)
-
+
// Places that cookie files can be:
// /browser_profile/cookies
// /first_last/browser_profile/cookies (note that there may be any number of these!)
// /first_last/plugin_cookies.txt (note that there may be any number of these!)
-
+
std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter();
std::string target;
std::string filename;
-
+
LL_DEBUGS() << "base dir = " << base_dir << LL_ENDL;
// The non-logged-in version is easy
@@ -1174,7 +1174,7 @@ void LLViewerMedia::clearAllCookies()
{
LLFile::remove(target);
}
-
+
// the hard part: iterate over all user directories and delete the cookie file from each one
LLDirIterator dir_iter(base_dir, "*_*");
while (dir_iter.next(filename))
@@ -1184,26 +1184,26 @@ void LLViewerMedia::clearAllCookies()
gDirUtilp->append(target, "cookies");
LL_DEBUGS() << "target = " << target << LL_ENDL;
if(LLFile::isfile(target))
- {
+ {
LLFile::remove(target);
}
-
+
// Other accounts may have new-style cookie files too -- delete them as well
target = gDirUtilp->add(base_dir, filename);
gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME);
LL_DEBUGS() << "target = " << target << LL_ENDL;
if(LLFile::isfile(target))
- {
+ {
LLFile::remove(target);
}
}
-
+
// If we have an OpenID cookie, re-add it to the cookie store.
- setOpenIDCookie();
+ setOpenIDCookie(std::string());
}
-
+
/////////////////////////////////////////////////////////////////////////////////////////
-// static
+// static
void LLViewerMedia::clearAllCaches()
{
// Clear all plugins' caches
@@ -1215,9 +1215,9 @@ void LLViewerMedia::clearAllCaches()
pimpl->clearCache();
}
}
-
+
/////////////////////////////////////////////////////////////////////////////////////////
-// static
+// static
void LLViewerMedia::setCookiesEnabled(bool enabled)
{
// Set the "cookies enabled" flag for all loaded plugins
@@ -1232,9 +1232,9 @@ void LLViewerMedia::setCookiesEnabled(bool enabled)
}
}
}
-
+
/////////////////////////////////////////////////////////////////////////////////////////
-// static
+// static
void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int port)
{
// Set the proxy config for all loaded plugins
@@ -1251,7 +1251,7 @@ void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int por
}
/////////////////////////////////////////////////////////////////////////////////////////
-// static
+// static
/////////////////////////////////////////////////////////////////////////////////////////
// static
LLPluginCookieStore *LLViewerMedia::getCookieStore()
@@ -1260,7 +1260,7 @@ LLPluginCookieStore *LLViewerMedia::getCookieStore()
{
sCookieStore = new LLPluginCookieStore;
}
-
+
return sCookieStore;
}
@@ -1276,7 +1276,7 @@ void LLViewerMedia::loadCookieFile()
LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL;
return;
}
-
+
// open the file for reading
llifstream file(resolved_filename.c_str());
if (!file.is_open())
@@ -1284,11 +1284,11 @@ void LLViewerMedia::loadCookieFile()
LL_WARNS() << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << LL_ENDL;
return;
}
-
+
getCookieStore()->readAllCookies(file, true);
file.close();
-
+
// send the clear_cookies message to all loaded plugins
impl_list::iterator iter = sViewerMediaImplList.begin();
impl_list::iterator end = sViewerMediaImplList.end();
@@ -1300,9 +1300,9 @@ void LLViewerMedia::loadCookieFile()
pimpl->mMediaSource->clear_cookies();
}
}
-
+
// If we have an OpenID cookie, re-add it to the cookie store.
- setOpenIDCookie();
+ setOpenIDCookie(std::string());
}
@@ -1337,23 +1337,23 @@ void LLViewerMedia::saveCookieFile()
void LLViewerMedia::addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path, bool secure)
{
std::stringstream cookie;
-
+
cookie << name << "=" << LLPluginCookieStore::quoteString(value);
-
+
if(expires.notNull())
{
cookie << "; expires=" << expires.asRFC1123();
}
-
+
cookie << "; domain=" << domain;
cookie << "; path=" << path;
-
+
if(secure)
{
cookie << "; secure";
}
-
+
getCookieStore()->setCookies(cookie.str());
}
@@ -1370,7 +1370,7 @@ void LLViewerMedia::addSessionCookie(const std::string &name, const std::string
void LLViewerMedia::removeCookie(const std::string &name, const std::string &domain, const std::string &path )
{
// To remove a cookie, add one with the same name, domain, and path that expires in the past.
-
+
addCookie(name, "", domain, LLDate(LLDate::now().secondsSinceEpoch() - 1.0), path);
}
@@ -1388,9 +1388,34 @@ LLSD LLViewerMedia::getHeaders()
return headers;
}
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // static
+bool LLViewerMedia::parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path, bool& httponly, bool& secure)
+{
+ std::size_t name_pos = raw_cookie.find_first_of("=");
+ if (name_pos != std::string::npos)
+ {
+ name = raw_cookie.substr(0, name_pos);
+ std::size_t value_pos = raw_cookie.find_first_of(";", name_pos);
+ if (value_pos != std::string::npos)
+ {
+ value = raw_cookie.substr(name_pos + 1, value_pos - name_pos - 1);
+ path = "/"; // assume root path for now
+
+ httponly = true; // hard coded for now
+ secure = true;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
/////////////////////////////////////////////////////////////////////////////////////////
// static
-void LLViewerMedia::setOpenIDCookie()
+void LLViewerMedia::setOpenIDCookie(const std::string& url)
{
if(!sOpenIDCookie.empty())
{
@@ -1398,7 +1423,7 @@ void LLViewerMedia::setOpenIDCookie()
// We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that.
// We therefore do it here.
std::string authority = sOpenIDURL.mAuthority;
- std::string::size_type host_start = authority.find('@');
+ std::string::size_type host_start = authority.find('@');
if(host_start == std::string::npos)
{
// no username/password
@@ -1406,20 +1431,43 @@ void LLViewerMedia::setOpenIDCookie()
}
else
{
- // Hostname starts after the @.
+ // Hostname starts after the @.
// (If the hostname part is empty, this may put host_start at the end of the string. In that case, it will end up passing through an empty hostname, which is correct.)
++host_start;
}
- std::string::size_type host_end = authority.rfind(':');
+ std::string::size_type host_end = authority.rfind(':');
if((host_end == std::string::npos) || (host_end < host_start))
{
// no port
host_end = authority.size();
}
-
+
getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start));
- // Do a web profile get so we can store the cookie
+ if (url.length())
+ {
+ LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild("destination_guide_contents");
+ if (media_instance)
+ {
+ std::string cookie_host = authority.substr(host_start, host_end - host_start);
+ std::string cookie_name = "";
+ std::string cookie_value = "";
+ std::string cookie_path = "";
+ bool httponly = true;
+ bool secure = true;
+ if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) &&
+ media_instance->getMediaPlugin())
+ {
+ media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path, httponly, secure);
+ }
+ }
+ }
+
+ // NOTE: this is the original OpenID cookie code, so of which is no longer needed now that we
+ // are using CEF - it's very intertwined with other code so, for the moment, I'm going to
+ // leave it alone and make a task to come back to it once we're sure the CEF cookie code is robust.
+
+ // Do a web profile get so we can store the cookie
LLSD headers = LLSD::emptyMap();
headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
headers[HTTP_OUT_HEADER_COOKIE] = sOpenIDCookie;
@@ -1430,7 +1478,7 @@ void LLViewerMedia::setOpenIDCookie()
LL_DEBUGS("MediaAuth") << "Requesting " << profile_url << LL_ENDL;
LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL;
- LLHTTPClient::get(profile_url,
+ LLHTTPClient::get(profile_url,
new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
headers);
}
@@ -1442,12 +1490,12 @@ void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string
{
LL_DEBUGS("MediaAuth") << "url = \"" << openid_url << "\", token = \"" << openid_token << "\"" << LL_ENDL;
- // post the token to the url
+ // post the token to the url
// the responder will need to extract the cookie(s).
// Save the OpenID URL for later -- we may need the host when adding the cookie.
sOpenIDURL.init(openid_url.c_str());
-
+
// We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies.
sOpenIDCookie.clear();
@@ -1462,24 +1510,24 @@ void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string
U8 *data = new U8[size];
memcpy(data, openid_token.data(), size);
- LLHTTPClient::postRaw(
- openid_url,
- data,
- size,
+ LLHTTPClient::postRaw(
+ openid_url,
+ data,
+ size,
new LLViewerMediaOpenIDResponder(),
headers);
-
+
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
-void LLViewerMedia::openIDCookieResponse(const std::string &cookie)
+void LLViewerMedia::openIDCookieResponse(const std::string& url, const std::string &cookie)
{
LL_DEBUGS("MediaAuth") << "Cookie received: \"" << cookie << "\"" << LL_ENDL;
-
+
sOpenIDCookie += cookie;
- setOpenIDCookie();
+ setOpenIDCookie(url);
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -1488,7 +1536,7 @@ void LLViewerMedia::proxyWindowOpened(const std::string &target, const std::stri
{
if(uuid.empty())
return;
-
+
for (impl_list::iterator iter = sViewerMediaImplList.begin(); iter != sViewerMediaImplList.end(); iter++)
{
if((*iter)->mMediaSource && (*iter)->mMediaSource->pluginSupportsMediaBrowser())
@@ -1525,7 +1573,7 @@ void LLViewerMedia::createSpareBrowserMediaSource()
if (!sSpareBrowserMediaSource && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))
{
// The null owner will keep the browser plugin from fully initializing
- // (specifically, it keeps LLPluginClassMedia from negotiating a size change,
+ // (specifically, it keeps LLPluginClassMedia from negotiating a size change,
// which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color)
sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType(HTTP_CONTENT_TEXT_HTML, NULL, 0, 0);
}
@@ -1537,7 +1585,7 @@ LLPluginClassMedia* LLViewerMedia::getSpareBrowserMediaSource()
{
LLPluginClassMedia* result = sSpareBrowserMediaSource;
sSpareBrowserMediaSource = NULL;
- return result;
+ return result;
};
bool LLViewerMedia::hasInWorldMedia()
@@ -1626,12 +1674,12 @@ void LLViewerMedia::setOnlyAudibleMediaTextureID(const LLUUID& texture_id)
//////////////////////////////////////////////////////////////////////////////////////////
// LLViewerMediaImpl
//////////////////////////////////////////////////////////////////////////////////////////
-LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
- S32 media_width,
- S32 media_height,
- U8 media_auto_scale,
+LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
+ S32 media_width,
+ S32 media_height,
+ U8 media_auto_scale,
U8 media_loop)
-:
+:
mMediaSource( NULL ),
mMovieImageHasMips(false),
mMediaWidth(media_width),
@@ -1672,7 +1720,7 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
mTrustedBrowser(false),
mZoomFactor(1.0),
mCleanBrowser(false)
-{
+{
// Set up the mute list observer if it hasn't been set up already.
if(!sViewerMediaMuteListObserverInitialized)
@@ -1680,11 +1728,11 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
LLMuteList::getInstance()->addObserver(&sViewerMediaMuteListObserver);
sViewerMediaMuteListObserverInitialized = true;
}
-
+
add_media_impl(this);
setTextureID(texture_id);
-
+
// connect this media_impl to the media texture, creating it if it doesn't exist.0
// This is necessary because we need to be able to use getMaxVirtualSize() even if the media plugin is not loaded.
LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture(mTextureId);
@@ -1699,7 +1747,7 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
LLViewerMediaImpl::~LLViewerMediaImpl()
{
destroyMediaSource();
-
+
LLViewerMediaTexture::removeMediaImplFromTexture(mTextureId) ;
setTextureID();
@@ -1711,7 +1759,7 @@ void LLViewerMediaImpl::emitEvent(LLPluginClassMedia* plugin, LLViewerMediaObser
{
// Broadcast to observers using the superclass version
LLViewerMediaEventEmitter::emitEvent(plugin, event);
-
+
// If this media is on one or more LLVOVolume objects, tell them about the event as well.
std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
while(iter != mObjectList.end())
@@ -1727,7 +1775,7 @@ bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
{
bool mimeTypeChanged = (mMimeType != mime_type);
bool pluginChanged = (LLMIMETypes::implType(mCurrentMimeType) != LLMIMETypes::implType(mime_type));
-
+
if(!mMediaSource || pluginChanged)
{
// We don't have a plugin at all, or the new mime type is handled by a different plugin than the old mime type.
@@ -1750,7 +1798,7 @@ void LLViewerMediaImpl::createMediaSource()
// This media shouldn't be created yet.
return;
}
-
+
if(! mMediaURL.empty())
{
navigateInternal();
@@ -1776,15 +1824,15 @@ void LLViewerMediaImpl::destroyMediaSource()
{
oldImage->setPlaying(FALSE) ;
}
-
+
cancelMimeTypeProbe();
-
+
if(mMediaSource)
{
mMediaSource->setDeleteOK(true) ;
delete mMediaSource;
mMediaSource = NULL;
- }
+ }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -1799,11 +1847,11 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
{
std::string plugin_basename = LLMIMETypes::implType(media_type);
LLPluginClassMedia* media_source = NULL;
-
+
// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
// If a spare was already created before PluginAttachDebuggerToPlugins was set, don't use it.
// Do not use a spare if launching with full viewer control (e.g. Facebook, Twitter and few others)
- if ((plugin_basename == "media_plugin_webkit") &&
+ if ((plugin_basename == "media_plugin_cef") &&
!gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins") && !clean_browser)
{
media_source = LLViewerMedia::getSpareBrowserMediaSource();
@@ -1812,7 +1860,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
media_source->setOwner(owner);
media_source->setTarget(target);
media_source->setSize(default_width, default_height);
-
+
return media_source;
}
}
@@ -1824,8 +1872,12 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
{
std::string launcher_name = gDirUtilp->getLLPluginLauncher();
std::string plugin_name = gDirUtilp->getLLPluginFilename(plugin_basename);
- std::string user_data_path = gDirUtilp->getOSUserAppDir();
- user_data_path += gDirUtilp->getDirDelimiter();
+
+ std::string user_data_path_cache = gDirUtilp->getCacheDir(false);
+ user_data_path_cache += gDirUtilp->getDirDelimiter();
+
+ std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir();
+ user_data_path_cookies += gDirUtilp->getDirDelimiter();
// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)
// If the linden username returned is blank, that can only mean we are
@@ -1836,8 +1888,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
if ( ! linden_user_dir.empty() )
{
// gDirUtilp->getLindenUserDir() is whole path, not just Linden name
- user_data_path = linden_user_dir;
- user_data_path += gDirUtilp->getDirDelimiter();
+ user_data_path_cookies = linden_user_dir;
+ user_data_path_cookies += gDirUtilp->getDirDelimiter();
};
// See if the plugin executable exists
@@ -1854,7 +1906,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
{
media_source = new LLPluginClassMedia(owner);
media_source->setSize(default_width, default_height);
- media_source->setUserDataPath(user_data_path);
+ media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies);
media_source->setLanguageCode(LLUI::getLanguage());
// collect 'cookies enabled' setting from prefs and send to embedded browser
@@ -1868,12 +1920,15 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
// collect 'javascript enabled' setting from prefs and send to embedded browser
bool javascript_enabled = gSavedSettings.getBOOL( "BrowserJavascriptEnabled" );
media_source->setJavascriptEnabled( javascript_enabled || clean_browser);
-
+
bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled || clean_browser);
+ // need to set agent string here before instance created
+ media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent());
+
media_source->setTarget(target);
-
+
const std::string plugin_dir = gDirUtilp->getLLPluginDir();
if (media_source->init(launcher_name, plugin_dir, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins")))
{
@@ -1886,14 +1941,14 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
}
}
}
-
+
LL_WARNS_ONCE("Plugin") << "plugin initialization failed for mime type: " << media_type << LL_ENDL;
LLSD args;
args["MIME_TYPE"] = media_type;
LLNotificationsUtil::add("NoPlugin", args);
return NULL;
-}
+}
//////////////////////////////////////////////////////////////////////////////////////////
bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
@@ -1904,10 +1959,10 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
mMediaWidth = mMediaSource->getSetWidth();
mMediaHeight = mMediaSource->getSetHeight();
}
-
+
// Always delete the old media impl first.
destroyMediaSource();
-
+
// and unconditionally set the mime type
mMimeType = media_type;
@@ -1915,7 +1970,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
{
// This impl should not be loaded at this time.
LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL;
-
+
return false;
}
@@ -1926,7 +1981,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
mCurrentMimeType = mMimeType;
LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight, mTarget, mCleanBrowser);
-
+
if (media_source)
{
media_source->setDisableTimeout(gSavedSettings.getBOOL("DebugPluginDisableTimeout"));
@@ -1935,7 +1990,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent());
media_source->focus(mHasFocus);
media_source->setBackgroundColor(mBackgroundColor);
-
+
if(gSavedSettings.getBOOL("BrowserIgnoreSSLCertErrors"))
{
media_source->ignore_ssl_cert_errors(true);
@@ -1943,19 +1998,19 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
// the correct way to deal with certs it to load ours from CA.pem and append them to the ones
// Qt/WebKit loads from your system location.
- // Note: This needs the new CA.pem file with the Equifax Secure Certificate Authority
+ // Note: This needs the new CA.pem file with the Equifax Secure Certificate Authority
// cert at the bottom: (MIIDIDCCAomgAwIBAgIENd70zzANBg)
std::string ca_path = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "CA.pem" );
media_source->addCertificateFilePath( ca_path );
media_source->proxy_setup(gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort"));
-
+
if(mClearCache)
{
mClearCache = false;
media_source->clear_cache();
}
-
+
// TODO: Only send cookies to plugins that need them
// Ideally, the plugin should tell us whether it handles cookies or not -- either via the init response or through a separate message.
// Due to the ordering of messages, it's possible we wouldn't get that information back in time to send cookies before sending a navigate message,
@@ -1966,7 +2021,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
{
media_source->set_cookies(all_cookies);
}
-
+
mMediaSource = media_source;
mMediaSource->setDeleteOK(false) ;
updateVolume();
@@ -2009,16 +2064,16 @@ void LLViewerMediaImpl::loadURI()
std::string sanitized_uri = (u.query().empty() ? uri : u.scheme() + "://" + u.authority() + u.path());
LL_INFOS() << "Asking media source to load URI: " << sanitized_uri << LL_ENDL;
}
-
+
mMediaSource->loadURI( uri );
-
- // A non-zero mPreviousMediaTime means that either this media was previously unloaded by the priority code while playing/paused,
+
+ // A non-zero mPreviousMediaTime means that either this media was previously unloaded by the priority code while playing/paused,
// or a seek happened before the media loaded. In either case, seek to the saved time.
if(mPreviousMediaTime != 0.0f)
{
seek(mPreviousMediaTime);
}
-
+
if(mPreviousMediaState == MEDIA_PLAYING)
{
// This media was playing before this instance was unloaded.
@@ -2071,11 +2126,11 @@ void LLViewerMediaImpl::play()
// This may be the case where the plugin's priority is PRIORITY_UNLOADED
return;
}
-
+
// Only do this if the media source was just loaded.
loadURI();
}
-
+
// always start the media
start();
}
@@ -2176,10 +2231,10 @@ void LLViewerMediaImpl::updateVolume()
{
if(mMediaSource)
{
- // always scale the volume by the global media volume
+ // always scale the volume by the global media volume
F32 volume = mRequestedVolume * LLViewerMedia::getVolume();
- if (mProximityCamera > 0)
+ if (mProximityCamera > 0)
{
if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMax"))
{
@@ -2218,7 +2273,7 @@ F32 LLViewerMediaImpl::getVolume()
void LLViewerMediaImpl::focus(bool focus)
{
mHasFocus = focus;
-
+
if (mMediaSource)
{
// call focus just for the hell of it, even though this apopears to be a nop
@@ -2246,7 +2301,7 @@ std::string LLViewerMediaImpl::getCurrentMediaURL()
{
return mCurrentMediaURL;
}
-
+
return mMediaURL;
}
@@ -2314,17 +2369,17 @@ void LLViewerMediaImpl::mouseMove(S32 x, S32 y, MASK mask)
}
//////////////////////////////////////////////////////////////////////////////////////////
-//static
+//static
void LLViewerMediaImpl::scaleTextureCoords(const LLVector2& texture_coords, S32 *x, S32 *y)
{
F32 texture_x = texture_coords.mV[VX];
F32 texture_y = texture_coords.mV[VY];
-
+
// Deal with repeating textures by wrapping the coordinates into the range [0, 1.0)
texture_x = fmodf(texture_x, 1.0f);
if(texture_x < 0.0f)
texture_x = 1.0 + texture_x;
-
+
texture_y = fmodf(texture_y, 1.0f);
if(texture_y < 0.0f)
texture_y = 1.0 + texture_y;
@@ -2352,7 +2407,7 @@ void LLViewerMediaImpl::mouseDown(const LLVector2& texture_coords, MASK mask, S3
void LLViewerMediaImpl::mouseUp(const LLVector2& texture_coords, MASK mask, S32 button)
{
if(mMediaSource)
- {
+ {
S32 x, y;
scaleTextureCoords(texture_coords, &x, &y);
@@ -2363,7 +2418,7 @@ void LLViewerMediaImpl::mouseUp(const LLVector2& texture_coords, MASK mask, S32
void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords, MASK mask)
{
if(mMediaSource)
- {
+ {
S32 x, y;
scaleTextureCoords(texture_coords, &x, &y);
@@ -2371,6 +2426,17 @@ void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords, MASK mask)
}
}
+void LLViewerMediaImpl::mouseDoubleClick(const LLVector2& texture_coords, MASK mask)
+{
+ if (mMediaSource)
+ {
+ S32 x, y;
+ scaleTextureCoords(texture_coords, &x, &y);
+
+ mouseDoubleClick(x, y, mask);
+ }
+}
+
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button)
{
@@ -2405,18 +2471,18 @@ void LLViewerMediaImpl::onMouseCaptureLost()
}
//////////////////////////////////////////////////////////////////////////////////////////
-BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask)
-{
+BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask)
+{
// NOTE: this is called when the mouse is released when we have capture.
// Due to the way mouse coordinates are mapped to the object, we can't use the x and y coordinates that come in with the event.
-
+
if(hasMouseCapture())
{
// Release the mouse -- this will also send a mouseup to the media
gFocusMgr.setMouseCapture( FALSE );
}
- return TRUE;
+ return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2492,14 +2558,14 @@ void LLViewerMediaImpl::updateJavascriptObject()
}
//////////////////////////////////////////////////////////////////////////////////////////
-const std::string& LLViewerMediaImpl::getName() const
-{
+const std::string& LLViewerMediaImpl::getName() const
+{
if (mMediaSource)
{
return mMediaSource->getMediaName();
}
-
- return LLStringUtil::null;
+
+ return LLStringUtil::null;
};
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2555,21 +2621,21 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
// Don't carry media play state across distinct URLs.
resetPreviousMediaState();
}
-
+
// Always set the current URL and MIME type.
mMediaURL = url;
mMimeType = mime_type;
mCleanBrowser = clean_browser;
-
+
// Clear the current media URL, since it will no longer be correct.
mCurrentMediaURL.clear();
-
+
// if mime type discovery was requested, we'll need to do it when the media loads
mNavigateRediscoverType = rediscover_type;
-
+
// and if this was a server request, the navigate on load will also need to be one.
mNavigateServerRequest = server_request;
-
+
// An explicit navigate resets the "failed" flag.
mMediaSourceFailed = false;
@@ -2585,7 +2651,7 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
// This impl should not be loaded at this time.
LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL;
-
+
return;
}
@@ -2609,13 +2675,13 @@ void LLViewerMediaImpl::navigateInternal()
mNavigateSuspendedDeferred = true;
return;
}
-
+
if(mMimeTypeProbe != NULL)
{
LL_WARNS() << "MIME type probe already in progress -- bailing out." << LL_ENDL;
return;
}
-
+
if(mNavigateServerRequest)
{
setNavState(MEDIANAVSTATE_SERVER_SENT);
@@ -2624,12 +2690,12 @@ void LLViewerMediaImpl::navigateInternal()
{
setNavState(MEDIANAVSTATE_NONE);
}
-
+
// If the caller has specified a non-empty MIME type, look that up in our MIME types list.
// If we have a plugin for that MIME type, use that instead of attempting auto-discovery.
// This helps in supporting legacy media content where the server the media resides on returns a bogus MIME type
// but the parcel owner has correctly set the MIME type in the parcel media settings.
-
+
if(!mMimeType.empty() && (mMimeType != LLMIMETypes::getDefaultMimeType()))
{
std::string plugin_basename = LLMIMETypes::implType(mMimeType);
@@ -2698,27 +2764,47 @@ void LLViewerMediaImpl::navigateStop()
bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
{
bool result = false;
-
+
if (mMediaSource)
{
// FIXME: THIS IS SO WRONG.
// Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it...
- if( MASK_CONTROL & mask && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END)
+ if (MASK_CONTROL & mask && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END)
{
result = true;
}
-
- if(!result)
+
+ if (!result)
{
-
- LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
-
- result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask, native_key_data);
- // Since the viewer internal event dispatching doesn't give us key-up events, simulate one here.
- (void)mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP ,key, mask, native_key_data);
+ LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
+ result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN, key, mask, native_key_data);
}
}
-
+
+ return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+bool LLViewerMediaImpl::handleKeyUpHere(KEY key, MASK mask)
+{
+ bool result = false;
+
+ if (mMediaSource)
+ {
+ // FIXME: THIS IS SO WRONG.
+ // Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it...
+ if (MASK_CONTROL & mask && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END)
+ {
+ result = true;
+ }
+
+ if (!result)
+ {
+ LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
+ result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP, key, mask, native_key_data);
+ }
+ }
+
return result;
}
@@ -2726,7 +2812,7 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)
{
bool result = false;
-
+
if (mMediaSource)
{
// only accept 'printable' characters, sigh...
@@ -2734,11 +2820,11 @@ bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)
&& uni_char != 127) // SDL thinks this is 'delete' - yuck.
{
LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
-
+
mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE), native_key_data);
}
}
-
+
return result;
}
@@ -2817,15 +2903,15 @@ void LLViewerMediaImpl::update()
}
}
-
+
if(mMediaSource == NULL)
{
return;
}
-
+
// Make sure a navigate doesn't happen during the idle -- it can cause mMediaSource to get destroyed, which can cause a crash.
setNavigateSuspended(true);
-
+
mMediaSource->idle();
setNavigateSuspended(false);
@@ -2834,7 +2920,7 @@ void LLViewerMediaImpl::update()
{
return;
}
-
+
if(mMediaSource->isPluginExited())
{
resetPreviousMediaState();
@@ -2846,18 +2932,18 @@ void LLViewerMediaImpl::update()
{
return;
}
-
+
if(mSuspendUpdates || !mVisible)
{
return;
}
-
+
LLViewerMediaTexture* placeholder_image = updatePlaceholderImage();
-
+
if(placeholder_image)
{
LLRect dirty_rect;
-
+
// Since we're updating this texture, we know it's playing. Tell the texture to do its replacement magic so it gets rendered.
placeholder_image->setPlaying(TRUE);
@@ -2868,7 +2954,7 @@ void LLViewerMediaImpl::update()
S32 y_pos = llmax(dirty_rect.mBottom, 0);
S32 width = llmin(dirty_rect.mRight, placeholder_image->getWidth()) - x_pos;
S32 height = llmin(dirty_rect.mTop, placeholder_image->getHeight()) - y_pos;
-
+
if(width > 0 && height > 0)
{
@@ -2881,21 +2967,21 @@ void LLViewerMediaImpl::update()
// Offset the pixels pointer to match x_pos and y_pos
data += ( x_pos * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() );
data += ( y_pos * mMediaSource->getTextureDepth() );
-
+
{
LL_RECORD_BLOCK_TIME(FTM_MEDIA_SET_SUBIMAGE);
placeholder_image->setSubImage(
- data,
- mMediaSource->getBitsWidth(),
+ data,
+ mMediaSource->getBitsWidth(),
mMediaSource->getBitsHeight(),
- x_pos,
- y_pos,
- width,
+ x_pos,
+ y_pos,
+ width,
height);
}
}
-
+
mMediaSource->resetDirty();
}
}
@@ -2916,10 +3002,10 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
// The code that created this instance will read from the plugin's bits.
return NULL;
}
-
+
LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mTextureId );
-
- if (mNeedsNewTexture
+
+ if (mNeedsNewTexture
|| placeholder_image->getUseMipMaps()
|| (placeholder_image->getWidth() != mMediaSource->getTextureWidth())
|| (placeholder_image->getHeight() != mMediaSource->getTextureHeight())
@@ -2933,7 +3019,7 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
int texture_width = mMediaSource->getTextureWidth();
int texture_height = mMediaSource->getTextureHeight();
int texture_depth = mMediaSource->getTextureDepth();
-
+
// MEDIAOPT: check to see if size actually changed before doing work
placeholder_image->destroyGLTexture();
// MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
@@ -2959,13 +3045,13 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
// FIXME
// placeholder_image->mIsMediaTexture = true;
mNeedsNewTexture = false;
-
- // If the amount of the texture being drawn by the media goes down in either width or height,
+
+ // If the amount of the texture being drawn by the media goes down in either width or height,
// recreate the texture to avoid leaving parts of the old image behind.
mTextureUsedWidth = mMediaSource->getWidth();
mTextureUsedHeight = mMediaSource->getHeight();
}
-
+
return placeholder_image;
}
@@ -2980,14 +3066,14 @@ LLUUID LLViewerMediaImpl::getMediaTextureID() const
void LLViewerMediaImpl::setVisible(bool visible)
{
mVisible = visible;
-
+
if(mVisible)
{
if(mMediaSource && mMediaSource->isPluginExited())
{
destroyMediaSource();
}
-
+
if(!mMediaSource)
{
createMediaSource();
@@ -3021,12 +3107,12 @@ void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y)
bool LLViewerMediaImpl::isMediaTimeBased()
{
bool result = false;
-
+
if(mMediaSource)
{
result = mMediaSource->pluginSupportsMediaTime();
}
-
+
return result;
}
@@ -3034,14 +3120,14 @@ bool LLViewerMediaImpl::isMediaTimeBased()
bool LLViewerMediaImpl::isMediaPlaying()
{
bool result = false;
-
+
if(mMediaSource)
{
EMediaStatus status = mMediaSource->getStatus();
if(status == MEDIA_PLAYING || status == MEDIA_LOADING)
result = true;
}
-
+
return result;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -3054,7 +3140,7 @@ bool LLViewerMediaImpl::isMediaPaused()
if(mMediaSource->getStatus() == MEDIA_PAUSED)
result = true;
}
-
+
return result;
}
@@ -3082,7 +3168,7 @@ void LLViewerMediaImpl::setDisabled(bool disabled, bool forcePlayOnEnable)
{
// Only do this on actual state transitions.
mIsDisabled = disabled;
-
+
if(mIsDisabled)
{
// We just disabled this media. Clear all state.
@@ -3108,13 +3194,13 @@ bool LLViewerMediaImpl::isForcedUnloaded() const
{
return true;
}
-
+
// If this media's class is not supposed to be shown, unload
if (!shouldShowBasedOnClass())
{
return true;
}
-
+
return false;
}
@@ -3127,19 +3213,19 @@ bool LLViewerMediaImpl::isPlayable() const
// All of the forced-unloaded criteria also imply not playable.
return false;
}
-
+
if(hasMedia())
{
// Anything that's already playing is, by definition, playable.
return true;
}
-
+
if(!mMediaURL.empty())
{
// If something has navigated the instance, it's ready to be played.
return true;
}
-
+
return false;
}
@@ -3151,7 +3237,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
{
case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
{
- LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL;
+ LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL;
std::string url = plugin->getClickURL();
std::string nav_type = plugin->getClickNavType();
LLURLDispatcher::dispatch(url, nav_type, NULL, mTrustedBrowser);
@@ -3170,7 +3256,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
// Reset the last known state of the media to defaults.
resetPreviousMediaState();
-
+
// TODO: may want a different message for this case?
LLSD args;
args["PLUGIN"] = LLMIMETypes::implType(mCurrentMimeType);
@@ -3192,13 +3278,13 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
//LLNotificationsUtil::add("MediaPluginFailed", args);
}
break;
-
+
case MEDIA_EVENT_CURSOR_CHANGED:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << plugin->getCursorName() << LL_ENDL;
std::string cursor = plugin->getCursorName();
-
+
if(cursor == "arrow")
mLastSetCursor = UI_CURSOR_ARROW;
else if(cursor == "ibeam")
@@ -3214,6 +3300,13 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
}
break;
+ case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD:
+ {
+ //llinfos << "Media event - file download requested - filename is " << self->getFileDownloadFilename() << llendl;
+ LLNotificationsUtil::add("MediaFileDownloadUnsupported");
+ }
+ break;
+
case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN:
{
LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL;
@@ -3259,7 +3352,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
}
}
break;
-
+
case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
{
LL_DEBUGS("Media") << "MEDIA_EVENT_LOCATION_CHANGED, uri is: " << plugin->getLocation() << LL_ENDL;
@@ -3296,15 +3389,15 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
{
// Display a file picker
std::string response;
-
+
LLFilePicker& picker = LLFilePicker::instance();
if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL))
{
// The user didn't pick a file -- the empty response string will indicate this.
}
-
+
response = picker.getFirstFile();
-
+
plugin->sendPickFileResponse(response);
}
break;
@@ -3460,7 +3553,7 @@ void LLViewerMediaImpl::calculateInterest()
{
LL_RECORD_BLOCK_TIME(FTM_MEDIA_CALCULATE_INTEREST);
LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId );
-
+
if(texture != NULL)
{
mInterest = texture->getMaxVirtualSize();
@@ -3470,7 +3563,7 @@ void LLViewerMediaImpl::calculateInterest()
// This will be a relatively common case now, since it will always be true for unloaded media.
mInterest = 0.0f;
}
-
+
// Calculate distance from the avatar, for use in the proximity calculation.
mProximityDistance = 0.0f;
mProximityCamera = 0.0f;
@@ -3480,7 +3573,7 @@ void LLViewerMediaImpl::calculateInterest()
std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
LLVOVolume* objp = *iter ;
llassert_always(objp != NULL) ;
-
+
// The distance calculation is invalid for HUD attachments -- leave both mProximityDistance and mProximityCamera at 0 for them.
if(!objp->isHUDAttachment())
{
@@ -3493,12 +3586,12 @@ void LLViewerMediaImpl::calculateInterest()
mProximityCamera = camera_delta.magVec();
}
}
-
+
if(mNeedsMuteCheck)
{
// Check all objects this instance is associated with, and those objects' owners, against the mute list
mIsMuted = false;
-
+
std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
for(; iter != mObjectList.end() ; ++iter)
{
@@ -3525,7 +3618,7 @@ void LLViewerMediaImpl::calculateInterest()
}
}
}
-
+
mNeedsMuteCheck = false;
}
}
@@ -3533,7 +3626,7 @@ void LLViewerMediaImpl::calculateInterest()
F64 LLViewerMediaImpl::getApproximateTextureInterest()
{
F64 result = 0.0f;
-
+
if(mMediaSource)
{
result = mMediaSource->getFullWidth();
@@ -3551,8 +3644,8 @@ F64 LLViewerMediaImpl::getApproximateTextureInterest()
void LLViewerMediaImpl::setUsedInUI(bool used_in_ui)
{
- mUsedInUI = used_in_ui;
-
+ mUsedInUI = used_in_ui;
+
// HACK: Force elements used in UI to load right away.
// This fixes some issues where UI code that uses the browser instance doesn't expect it to be unloaded.
if(mUsedInUI && (mPriority == LLPluginClassMedia::PRIORITY_UNLOADED))
@@ -3572,7 +3665,7 @@ void LLViewerMediaImpl::setUsedInUI(bool used_in_ui)
void LLViewerMediaImpl::setBackgroundColor(LLColor4 color)
{
- mBackgroundColor = color;
+ mBackgroundColor = color;
if(mMediaSource)
{
@@ -3583,12 +3676,12 @@ void LLViewerMediaImpl::setBackgroundColor(LLColor4 color)
F64 LLViewerMediaImpl::getCPUUsage() const
{
F64 result = 0.0f;
-
+
if(mMediaSource)
{
result = mMediaSource->getCPUUsage();
}
-
+
return result;
}
@@ -3602,19 +3695,19 @@ void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority)
<< " to " << LLPluginClassMedia::priorityToString(priority)
<< LL_ENDL;
}
-
+
mPriority = priority;
-
+
if(priority == LLPluginClassMedia::PRIORITY_UNLOADED)
{
if(mMediaSource)
{
// Need to unload the media source
-
+
// First, save off previous media state
mPreviousMediaState = mMediaSource->getStatus();
mPreviousMediaTime = mMediaSource->getCurrentTime();
-
+
destroyMediaSource();
}
}
@@ -3623,7 +3716,7 @@ void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority)
{
mMediaSource->setPriority(mPriority);
}
-
+
// NOTE: loading (or reloading) media sources whose priority has risen above PRIORITY_UNLOADED is done in update().
}
@@ -3638,8 +3731,8 @@ void LLViewerMediaImpl::setLowPrioritySizeLimit(int size)
void LLViewerMediaImpl::setNavState(EMediaNavState state)
{
mMediaNavState = state;
-
- switch (state)
+
+ switch (state)
{
case MEDIANAVSTATE_NONE: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_NONE" << LL_ENDL; break;
case MEDIANAVSTATE_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_BEGUN" << LL_ENDL; break;
@@ -3678,7 +3771,7 @@ void LLViewerMediaImpl::cancelMimeTypeProbe()
// There doesn't seem to be a way to actually cancel an outstanding request.
// Simulate it by telling the LLMimeDiscoveryResponder not to write back any results.
mMimeTypeProbe->cancelRequest();
-
+
// The above should already have set mMimeTypeProbe to NULL.
if(mMimeTypeProbe != NULL)
{
@@ -3687,7 +3780,7 @@ void LLViewerMediaImpl::cancelMimeTypeProbe()
}
}
-void LLViewerMediaImpl::addObject(LLVOVolume* obj)
+void LLViewerMediaImpl::addObject(LLVOVolume* obj)
{
std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
for(; iter != mObjectList.end() ; ++iter)
@@ -3701,14 +3794,14 @@ void LLViewerMediaImpl::addObject(LLVOVolume* obj)
mObjectList.push_back(obj) ;
mNeedsMuteCheck = true;
}
-
-void LLViewerMediaImpl::removeObject(LLVOVolume* obj)
+
+void LLViewerMediaImpl::removeObject(LLVOVolume* obj)
{
- mObjectList.remove(obj) ;
+ mObjectList.remove(obj) ;
mNeedsMuteCheck = true;
}
-
-const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const
+
+const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const
{
return &mObjectList ;
}
@@ -3716,13 +3809,13 @@ const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const
LLVOVolume *LLViewerMediaImpl::getSomeObject()
{
LLVOVolume *result = NULL;
-
+
std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
if(iter != mObjectList.end())
{
result = *iter;
}
-
+
return result;
}
@@ -3735,12 +3828,12 @@ void LLViewerMediaImpl::setTextureID(LLUUID id)
// Remove this item's entry from the map
sViewerMediaTextureIDMap.erase(mTextureId);
}
-
+
if(id.notNull())
{
sViewerMediaTextureIDMap.insert(LLViewerMedia::impl_id_map::value_type(id, this));
}
-
+
mTextureId = id;
}
}
@@ -3749,7 +3842,7 @@ void LLViewerMediaImpl::setTextureID(LLUUID id)
//
bool LLViewerMediaImpl::isAutoPlayable() const
{
- return (mMediaAutoPlay &&
+ return (mMediaAutoPlay &&
gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
gSavedSettings.getBOOL("MediaTentativeAutoPlay"));
}
@@ -3760,20 +3853,20 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const
{
// If this is parcel media or in the UI, return true always
if (getUsedInUI() || isParcelMedia()) return true;
-
+
bool attached_to_another_avatar = isAttachedToAnotherAvatar();
bool inside_parcel = isInAgentParcel();
-
+
// LL_INFOS() << " hasFocus = " << hasFocus() <<
// " others = " << (attached_to_another_avatar && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING)) <<
// " within = " << (inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING)) <<
// " outside = " << (!inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING)) << LL_ENDL;
-
+
// If it has focus, we should show it
// This is incorrect, and causes EXT-6750 (disabled attachment media still plays)
// if (hasFocus())
// return true;
-
+
// If it is attached to an avatar and the pref is off, we shouldn't show it
if (attached_to_another_avatar)
{
@@ -3786,7 +3879,7 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const
return show_media_within_parcel;
}
- else
+ else
{
static LLCachedControl show_media_outside_parcel(gSavedSettings, LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING, true);
@@ -3799,7 +3892,7 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const
bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const
{
bool result = false;
-
+
std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin();
std::list< LLVOVolume* >::const_iterator end = mObjectList.end();
for ( ; iter != end; iter++)
@@ -3843,7 +3936,7 @@ bool LLViewerMediaImpl::isObjectAttachedToAnotherAvatar(LLVOVolume *obj)
bool LLViewerMediaImpl::isInAgentParcel() const
{
bool result = false;
-
+
std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin();
std::list< LLVOVolume* >::const_iterator end = mObjectList.end();
for ( ; iter != end; iter++)
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 1ce42e97b8..ede408dd0c 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -150,7 +150,7 @@ public:
static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") );
static void openIDSetup(const std::string &openid_url, const std::string &openid_token);
- static void openIDCookieResponse(const std::string &cookie);
+ static void openIDCookieResponse(const std::string& url, const std::string &cookie);
static void proxyWindowOpened(const std::string &target, const std::string &uuid);
static void proxyWindowClosed(const std::string &uuid);
@@ -163,7 +163,8 @@ public:
static LLSD getHeaders();
private:
- static void setOpenIDCookie();
+ static bool parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path, bool& httponly, bool& secure);
+ static void setOpenIDCookie(const std::string& url);
static void onTeleportFinished();
static LLPluginCookieStore *sCookieStore;
@@ -225,7 +226,8 @@ public:
void mouseDown(const LLVector2& texture_coords, MASK mask, S32 button = 0);
void mouseUp(const LLVector2& texture_coords, MASK mask, S32 button = 0);
void mouseMove(const LLVector2& texture_coords, MASK mask);
- void mouseDoubleClick(S32 x,S32 y, MASK mask, S32 button = 0);
+ void mouseDoubleClick(const LLVector2& texture_coords, MASK mask);
+ void mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button = 0);
void scrollWheel(S32 x, S32 y, MASK mask);
void mouseCapture();
@@ -238,6 +240,7 @@ public:
void navigateInternal();
void navigateStop();
bool handleKeyHere(KEY key, MASK mask);
+ bool handleKeyUpHere(KEY key, MASK mask);
bool handleUnicodeCharHere(llwchar uni_char);
bool canNavigateForward();
bool canNavigateBack();
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index aa019dfdd8..7b4df3d3da 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -352,6 +352,18 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)
return true;
}
+BOOL LLViewerMediaFocus::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
+{
+ LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
+ if (media_impl)
+ {
+ media_impl->handleKeyUpHere(key, mask);
+ }
+ return true;
+}
+
+
+
BOOL LLViewerMediaFocus::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
{
LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
@@ -603,3 +615,13 @@ LLUUID LLViewerMediaFocus::getControlsMediaID()
return LLUUID::null;
}
+
+bool LLViewerMediaFocus::wantsKeyUpKeyDown() const
+{
+ return true;
+}
+
+bool LLViewerMediaFocus::wantsReturnKey() const
+{
+ return true;
+}
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
index f03dd8751e..0b2a64868e 100644
--- a/indra/newview/llviewermediafocus.h
+++ b/indra/newview/llviewermediafocus.h
@@ -56,6 +56,7 @@ public:
/*virtual*/ bool getFocus();
/*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+ /*virtual*/ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent);
/*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
@@ -87,6 +88,10 @@ public:
// Return the ID of the media instance the controls are currently attached to (either focus or hover).
LLUUID getControlsMediaID();
+ // The MoaP object wants keyup and keydown events. Overridden to return true.
+ virtual bool wantsKeyUpKeyDown() const;
+ virtual bool wantsReturnKey() const;
+
protected:
/*virtual*/ void onFocusReceived();
/*virtual*/ void onFocusLost();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 38d62dee5e..de219edcff 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -1245,9 +1245,24 @@ class LLAdvancedToggleWireframe : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
gUseWireframe = !(gUseWireframe);
+
+ if (gUseWireframe)
+ {
+ gInitialDeferredModeForWireframe = LLPipeline::sRenderDeferred;
+ }
+
gWindowResized = TRUE;
LLPipeline::updateRenderDeferred();
gPipeline.resetVertexBuffers();
+
+ if (!gUseWireframe && !gInitialDeferredModeForWireframe && LLPipeline::sRenderDeferred != gInitialDeferredModeForWireframe && gPipeline.isInit())
+ {
+ LLPipeline::refreshCachedSettings();
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ LLViewerShaderMgr::instance()->setShaders();
+ }
+
return true;
}
};
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 05d116704e..d79c84bee3 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -232,6 +232,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mRenderMedia(FALSE),
mBestUpdatePrecision(0),
mText(),
+ mHudText(""),
+ mHudTextColor(LLColor4::white),
mLastInterpUpdateSecs(0.f),
mLastMessageUpdateSecs(0.f),
mLatestRecvPacketID(0),
@@ -1413,12 +1415,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// Setup object text
if (!mText)
{
- mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
- mText->setFont(LLFontGL::getFontSansSerif());
- mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
- mText->setMaxLines(-1);
- mText->setSourceObject(this);
- mText->setOnHUDAttachment(isHUDAttachment());
+ initHudText();
}
std::string temp_string;
@@ -1432,6 +1429,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
mText->setColor(LLColor4(coloru));
mText->setString(temp_string);
+ mHudText = temp_string;
+ mHudTextColor = LLColor4(coloru);
+
setChanged(MOVED | SILHOUETTE);
}
else if (mText.notNull())
@@ -1794,12 +1794,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// Setup object text
if (!mText && (value & 0x4))
{
- mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
- mText->setFont(LLFontGL::getFontSansSerif());
- mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
- mText->setMaxLines(-1); // Set to match current agni behavior.
- mText->setSourceObject(this);
- mText->setOnHUDAttachment(isHUDAttachment());
+ initHudText();
}
if (value & 0x4)
@@ -1812,6 +1807,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
mText->setColor(LLColor4(coloru));
mText->setString(temp_string);
+ mHudText = temp_string;
+ mHudTextColor = LLColor4(coloru);
+
setChanged(TEXTURE);
}
else if(mText.notNull())
@@ -2840,6 +2838,11 @@ void LLViewerObject::clearInventoryListeners()
mInventoryCallbacks.clear();
}
+bool LLViewerObject::hasInventoryListeners()
+{
+ return !mInventoryCallbacks.empty();
+}
+
void LLViewerObject::requestInventory()
{
if(mInventoryDirty && mInventory && !mInventoryCallbacks.empty())
@@ -2847,15 +2850,20 @@ void LLViewerObject::requestInventory()
mInventory->clear(); // will deref and delete entries
delete mInventory;
mInventory = NULL;
- mInventoryDirty = FALSE; //since we are going to request it now
}
+
if(mInventory)
{
+ // inventory is either up to date or doesn't has a listener
+ // if it is dirty, leave it this way in case we gain a listener
doInventoryCallback();
}
- // throw away duplicate requests
else
{
+ // since we are going to request it now
+ mInventoryDirty = FALSE;
+
+ // Note: throws away duplicate requests
fetchInventoryFromServer();
}
}
@@ -2865,8 +2873,6 @@ void LLViewerObject::fetchInventoryFromServer()
if (!mInventoryPending)
{
delete mInventory;
- mInventory = NULL;
- mInventoryDirty = FALSE;
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RequestTaskInventory);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -4090,6 +4096,7 @@ LLViewerObject* LLViewerObject::getRootEdit() const
BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -4652,7 +4659,7 @@ S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID
return retval;
}
-S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams, bool isInitFromServer)
+S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
S32 retval = 0;
const LLTextureEntry *tep = getTE(te);
@@ -4662,14 +4669,13 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
return 0;
}
- setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
- setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
-
- retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams, isInitFromServer);
+ retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
<< ", object " << mID
<< " (" << retval << ")"
<< LL_ENDL;
+ setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
+ setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
refreshMaterials();
return retval;
@@ -4963,12 +4969,7 @@ void LLViewerObject::setDebugText(const std::string &utf8text)
if (!mText)
{
- mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
- mText->setFont(LLFontGL::getFontSansSerif());
- mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
- mText->setMaxLines(-1);
- mText->setSourceObject(this);
- mText->setOnHUDAttachment(isHUDAttachment());
+ initHudText();
}
mText->setColor(LLColor4::white);
mText->setString(utf8text);
@@ -4977,6 +4978,25 @@ void LLViewerObject::setDebugText(const std::string &utf8text)
updateText();
}
+void LLViewerObject::initHudText()
+{
+ mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
+ mText->setFont(LLFontGL::getFontSansSerif());
+ mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
+ mText->setMaxLines(-1);
+ mText->setSourceObject(this);
+ mText->setOnHUDAttachment(isHUDAttachment());
+}
+
+void LLViewerObject::restoreHudText()
+{
+ if(mText)
+ {
+ mText->setColor(mHudTextColor);
+ mText->setString(mHudText);
+ }
+}
+
void LLViewerObject::setIcon(LLViewerTexture* icon_image)
{
if (!mIcon)
@@ -5023,7 +5043,13 @@ void LLViewerObject::updateText()
{
if (mText.notNull())
{
- LLVector3 up_offset(0,0,0);
+ LLVOAvatar* avatar = getAvatar();
+ if (avatar)
+ {
+ mText->setHidden(avatar->isInMuteList());
+ }
+
+ LLVector3 up_offset(0,0,0);
up_offset.mV[2] = getScale().mV[VZ]*0.6f;
if (mDrawable.notNull())
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index db2749f413..cb8acfdcf8 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -268,6 +268,7 @@ public:
virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -330,7 +331,7 @@ public:
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags );
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
- /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams, bool isInitFromServer);
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
// Used by Materials update functions to properly kick off rebuilds
// of VBs etc when materials updates require changes.
@@ -403,6 +404,8 @@ public:
void setCanSelect(BOOL canSelect);
void setDebugText(const std::string &utf8text);
+ void initHudText();
+ void restoreHudText();
void setIcon(LLViewerTexture* icon_image);
void clearIcon();
@@ -436,8 +439,8 @@ public:
void removeInventoryListener(LLVOInventoryListener* listener);
BOOL isInventoryPending() { return mInventoryPending; }
void clearInventoryListeners();
+ bool hasInventoryListeners();
void requestInventory();
- void fetchInventoryFromServer();
static void processTaskInv(LLMessageSystem* msg, void** user_data);
void removeInventory(const LLUUID& item_id);
@@ -593,6 +596,9 @@ private:
static void initObjectDataMap();
+ // forms task inventory request if none are pending
+ void fetchInventoryFromServer();
+
public:
//
// Viewer-side only types - use the LL_PCODE_APP mask.
@@ -670,6 +676,9 @@ public:
LLPointer mText;
LLPointer mIcon;
+ std::string mHudText;
+ LLColor4 mHudTextColor;
+
static BOOL sUseSharedDrawables;
protected:
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 75732a1e19..61e918215c 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1282,7 +1282,7 @@ void LLViewerObjectList::clearDebugText()
{
for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
- (*iter)->setDebugText("");
+ (*iter)->restoreHudText();
}
}
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 37b249dddd..fc275eb2f0 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -590,7 +590,13 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL;
}
break;
-
+
+ case MEDIA_EVENT_FILE_DOWNLOAD:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_FILE_DOWNLOAD" << LL_ENDL;
+ }
+ break;
+
case MEDIA_EVENT_GEOMETRY_CHANGE:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ba84d7aa2c..f96c4b7bf0 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1137,7 +1137,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
if (prim_media_dnd_enabled)
{
- LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/ );
+ LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/, FALSE );
LLUUID object_id = pick_info.getObjectID();
S32 object_face = pick_info.mObjectFace;
@@ -1381,7 +1381,11 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
// it's all entered/processed.
if (key == KEY_RETURN && mask == MASK_NONE)
{
- return FALSE;
+ // RIDER: although, at times some of the controlls (in particular the CEF viewer
+ // would like to know about the KEYDOWN for an enter key... so ask and pass it along.
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+ if (keyboard_focus && !keyboard_focus->wantsReturnKey())
+ return FALSE;
}
return gViewerKeyboard.handleKey(key, mask, repeated);
@@ -1399,10 +1403,9 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
tool_inspectp->keyUp(key, mask);
}
- return FALSE;
+ return gViewerKeyboard.handleKeyUp(key, mask);
}
-
void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
{
LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
@@ -2019,6 +2022,7 @@ void LLViewerWindow::initWorldUI()
}
gHUDView = new LLHUDView(hud_rect);
getRootView()->addChild(gHUDView);
+ getRootView()->sendChildToBack(gHUDView);
}
LLPanel* panel_ssf_container = getRootView()->getChild("state_management_buttons_container");
@@ -2544,21 +2548,67 @@ void LLViewerWindow::draw()
//#endif
}
+// Takes a single keyup event, usually when UI is visible
+BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
+{
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+
+ if (keyboard_focus
+ && !(mask & (MASK_CONTROL | MASK_ALT))
+ && !gFocusMgr.getKeystrokesOnly())
+ {
+ // We have keyboard focus, and it's not an accelerator
+ if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown())
+ {
+ return keyboard_focus->handleKeyUp(key, mask, FALSE);
+ }
+ else if (key < 0x80)
+ {
+ // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
+ return (gFocusMgr.getKeyboardFocus() != NULL);
+ }
+ }
+
+ if (keyboard_focus)
+ {
+ if (keyboard_focus->handleKeyUp(key, mask, FALSE))
+ {
+ LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned true" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+ return TRUE;
+ }
+ else {
+ LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned FALSE" << LL_ENDL;
+ }
+ }
+
+ // don't pass keys on to world when something in ui has focus
+ return gFocusMgr.childHasKeyboardFocus(mRootView)
+ || LLMenuGL::getKeyboardMode()
+ || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive());
+}
+
// Takes a single keydown event, usually when UI is visible
BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
{
// hide tooltips on keypress
LLToolTipMgr::instance().blockToolTips();
- if (gFocusMgr.getKeyboardFocus()
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+
+ if (keyboard_focus
&& !(mask & (MASK_CONTROL | MASK_ALT))
&& !gFocusMgr.getKeystrokesOnly())
{
// We have keyboard focus, and it's not an accelerator
- if (key < 0x80)
+ if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown())
+ {
+ return keyboard_focus->handleKey(key, mask, FALSE );
+ }
+ else if (key < 0x80)
{
// Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
- return (gFocusMgr.getKeyboardFocus() != NULL);
+ return (keyboard_focus != NULL);
}
}
@@ -2572,7 +2622,6 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
return TRUE;
}
- LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
// give menus a chance to handle modified (Ctrl, Alt) shortcut keys before current focus
// as long as focus isn't locked
@@ -2598,7 +2647,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
// give floaters first chance to handle TAB key
// so frontmost floater gets focus
// if nothing has focus, go to first or last UI element as appropriate
- if (key == KEY_TAB && (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL))
+ if (key == KEY_TAB && (mask & MASK_CONTROL || keyboard_focus == NULL))
{
LL_WARNS() << "LLviewerWindow::handleKey give floaters first chance at tab key " << LL_ENDL;
if (gMenuHolder) gMenuHolder->hideMenus();
@@ -2936,7 +2985,7 @@ void LLViewerWindow::updateUI()
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
{
gDebugRaycastFaceHit = -1;
- gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
+ gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE,
&gDebugRaycastFaceHit,
&gDebugRaycastIntersection,
&gDebugRaycastTexCoord,
@@ -3764,6 +3813,7 @@ void LLViewerWindow::pickAsync( S32 x,
MASK mask,
void (*callback)(const LLPickInfo& info),
BOOL pick_transparent,
+ BOOL pick_rigged,
BOOL pick_unselectable)
{
BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
@@ -3774,7 +3824,7 @@ void LLViewerWindow::pickAsync( S32 x,
pick_transparent = TRUE;
}
- LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, FALSE, TRUE, pick_unselectable, callback);
+ LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, TRUE, pick_unselectable, callback);
schedulePick(pick_info);
}
@@ -3830,7 +3880,7 @@ void LLViewerWindow::returnEmptyPicks()
}
// Performs the GL object/land pick.
-LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_particle)
+LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle)
{
BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
@@ -3842,7 +3892,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans
// shortcut queueing in mPicks and just update mLastPick in place
MASK key_mask = gKeyboard->currentMask(TRUE);
- mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_particle, TRUE, FALSE, NULL);
+ mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, TRUE, FALSE, NULL);
mLastPick.fetchResults();
return mLastPick;
@@ -3878,6 +3928,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
LLViewerObject *this_object,
S32 this_face,
BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit,
LLVector4a *intersection,
LLVector2 *uv,
@@ -3948,7 +3999,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
{
if (this_object->isHUDAttachment()) // is a HUD object?
{
- if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent,
+ if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged,
face_hit, intersection, uv, normal, tangent))
{
found = this_object;
@@ -3956,7 +4007,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
}
else // is a world object
{
- if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent,
+ if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, pick_rigged,
face_hit, intersection, uv, normal, tangent))
{
found = this_object;
@@ -3970,7 +4021,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
if (!found) // if not found in HUD, look in world:
{
- found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent,
+ found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged,
face_hit, intersection, uv, normal, tangent);
if (found && !pick_transparent)
{
@@ -5246,6 +5297,7 @@ LLPickInfo::LLPickInfo()
mBinormal(),
mHUDIcon(NULL),
mPickTransparent(FALSE),
+ mPickRigged(FALSE),
mPickParticle(FALSE)
{
}
@@ -5253,6 +5305,7 @@ LLPickInfo::LLPickInfo()
LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
MASK keyboard_mask,
BOOL pick_transparent,
+ BOOL pick_rigged,
BOOL pick_particle,
BOOL pick_uv_coords,
BOOL pick_unselectable,
@@ -5271,6 +5324,7 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
mBinormal(),
mHUDIcon(NULL),
mPickTransparent(pick_transparent),
+ mPickRigged(pick_rigged),
mPickParticle(pick_particle),
mPickUnselectable(pick_unselectable)
{
@@ -5302,7 +5356,7 @@ void LLPickInfo::fetchResults()
}
LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
- NULL, -1, mPickTransparent, &face_hit,
+ NULL, -1, mPickTransparent, mPickRigged, &face_hit,
&intersection, &uv, &normal, &tangent, &start, &end);
mPickPt = mMousePt;
@@ -5447,7 +5501,7 @@ void LLPickInfo::getSurfaceInfo()
if (objectp)
{
if (gViewerWindow->cursorIntersect(ll_round((F32)mMousePt.mX), ll_round((F32)mMousePt.mY), 1024.f,
- objectp, -1, mPickTransparent,
+ objectp, -1, mPickTransparent, mPickRigged,
&mObjectFace,
&intersection,
&mSTCoords,
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 7fde52d4e1..d34e76f6f6 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -89,6 +89,7 @@ public:
LLPickInfo(const LLCoordGL& mouse_pos,
MASK keyboard_mask,
BOOL pick_transparent,
+ BOOL pick_rigged,
BOOL pick_particle,
BOOL pick_surface_info,
BOOL pick_unselectable,
@@ -123,6 +124,7 @@ public:
LLVector4 mTangent;
LLVector3 mBinormal;
BOOL mPickTransparent;
+ BOOL mPickRigged;
BOOL mPickParticle;
BOOL mPickUnselectable;
void getSurfaceInfo();
@@ -314,6 +316,7 @@ public:
LLView* getHintHolder() { return mHintHolder.get(); }
LLView* getLoginPanelHolder() { return mLoginPanelHolder.get(); }
BOOL handleKey(KEY key, MASK mask);
+ BOOL handleKeyUp(KEY key, MASK mask);
void handleScrollWheel (S32 clicks);
// add and remove views from "popup" layer
@@ -367,8 +370,9 @@ public:
MASK mask,
void (*callback)(const LLPickInfo& pick_info),
BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
BOOL pick_unselectable = FALSE);
- LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_particle = FALSE);
+ LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE);
LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
LLVector4a* intersection);
@@ -376,6 +380,7 @@ public:
LLViewerObject *this_object = NULL,
S32 this_face = -1,
BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
S32* face_hit = NULL,
LLVector4a *intersection = NULL,
LLVector2 *uv = NULL,
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b97a1bde99..6f7b23ba01 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1511,6 +1511,7 @@ void LLVOAvatar::renderJoints()
BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -1610,6 +1611,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -1640,7 +1642,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
{
LLViewerObject* attached_object = (*attachment_iter);
- if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 5b4379165a..09d8662034 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -165,6 +165,7 @@ public:
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -173,6 +174,7 @@ public:
LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 8d8f33b601..de63a3963c 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -770,7 +770,7 @@ void LLVOGrass::updateDrawable(BOOL force_damped)
}
// virtual
-BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index 71d358362d..5634e048eb 100644
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -78,6 +78,7 @@ public:
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 1ba0868544..6e5db526b0 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -469,6 +469,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
BOOL LLVOPartGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index a94a2291ed..2ef8b1c848 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -72,6 +72,7 @@ public:
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index 79e1921f1b..897bace4e1 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -936,7 +936,7 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
}
}
-BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index 3383b16dd9..884dbb3be3 100644
--- a/indra/newview/llvosurfacepatch.h
+++ b/indra/newview/llvosurfacepatch.h
@@ -84,6 +84,7 @@ public:
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 367fa21b91..4dcc267e96 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -1110,7 +1110,7 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
mDrawable->setPositionGroup(pos);
}
-BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index c862de8230..c16ed70bb4 100644
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -108,6 +108,7 @@ public:
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 19d61f6e33..b0eb60cc76 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2022,7 +2022,7 @@ void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLM
LLTextureEntry* texture_entry = pVol->getTE(te);
if (texture_entry && (texture_entry->getMaterialID() == pMaterialID))
{
- pVol->setTEMaterialParams(te, pMaterialParams, FALSE);
+ pVol->setTEMaterialParams(te, pMaterialParams);
}
}
}
@@ -2093,7 +2093,7 @@ bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
{
LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
- LLViewerObject::setTEMaterialParams(it->first, it->second, FALSE);
+ LLViewerObject::setTEMaterialParams(it->first, it->second);
}
//clear wait-list
@@ -2170,7 +2170,7 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
{
LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
- LLViewerObject::setTEMaterialParams(it->first, it->second, FALSE);
+ LLViewerObject::setTEMaterialParams(it->first, it->second);
}
//clear wait-list
@@ -2179,7 +2179,7 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
return 0 != new_material.size();
}
-S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams, bool isInitFromServer)
+S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
LLMaterialPtr pMaterial = const_cast(pMaterialParams);
@@ -2276,7 +2276,7 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa
}
}
- S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial, isInitFromServer);
+ S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial);
LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this), te) ? " selected" : " not selected" )
@@ -3883,7 +3883,7 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
}
-BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -3902,9 +3902,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
if (mDrawable->isState(LLDrawable::RIGGED))
{
- if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf())
+ if ((pick_rigged) || ((getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- updateRiggedVolume();
+ updateRiggedVolume(true);
volume = mRiggedVolume;
transform = false;
}
@@ -4083,10 +4083,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
bool LLVOVolume::treatAsRigged()
{
- return LLFloater::isVisible(gFloaterTools) &&
- isAttachment() &&
- getAvatar() &&
- getAvatar()->isSelf() &&
+ return isSelected() &&
+ isAttachment() &&
mDrawable.notNull() &&
mDrawable->isState(LLDrawable::RIGGED);
}
@@ -4105,12 +4103,12 @@ void LLVOVolume::clearRiggedVolume()
}
}
-void LLVOVolume::updateRiggedVolume()
+void LLVOVolume::updateRiggedVolume(bool force_update)
{
//Update mRiggedVolume to match current animation frame of avatar.
//Also update position/size in octree.
- if (!treatAsRigged())
+ if ((!force_update) && (!treatAsRigged()))
{
clearRiggedVolume();
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index ff7438ac09..a331908320 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -140,6 +140,7 @@ public:
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
+ BOOL pick_rigged = FALSE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -192,7 +193,7 @@ public:
static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
- /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams, bool isInitFromServer);
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
/*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
/*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
@@ -312,7 +313,7 @@ public:
//rigged volume update (for raycasting)
- void updateRiggedVolume();
+ void updateRiggedVolume(bool force_update = false);
LLRiggedVolume* getRiggedVolume();
//returns true if volume should be treated as a rigged volume
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 1c3808ce68..f8981d0c51 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -35,6 +35,7 @@
#include "llappearancemgr.h"
#include "llinventoryfunctions.h"
#include "llinventoryicon.h"
+#include "llgesturemgr.h"
#include "lltransutil.h"
#include "llviewerattachmenu.h"
#include "llvoavatarself.h"
@@ -55,7 +56,8 @@ bool LLFindOutfitItems::operator()(LLInventoryCategory* cat,
{
if((item->getType() == LLAssetType::AT_CLOTHING)
|| (item->getType() == LLAssetType::AT_BODYPART)
- || (item->getType() == LLAssetType::AT_OBJECT))
+ || (item->getType() == LLAssetType::AT_OBJECT)
+ || (item->getType() == LLAssetType::AT_GESTURE))
{
return TRUE;
}
@@ -491,6 +493,7 @@ LLWearableItemTypeNameComparator::LLWearableItemTypeNameComparator()
mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANK_1, false, false);
mWearableOrder[LLAssetType::AT_OBJECT] = LLWearableTypeOrder(ORDER_RANK_2, true, true);
mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANK_3, false, true);
+ mWearableOrder[LLAssetType::AT_GESTURE] = LLWearableTypeOrder(ORDER_RANK_4, true, false);
}
void LLWearableItemTypeNameComparator::setOrder(LLAssetType::EType items_of_type, LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_items_by_name, bool sort_wearable_items_by_name)
@@ -989,6 +992,10 @@ void LLWearableItemsList::ContextMenu::updateMask(U32& mask, LLAssetType::EType
{
mask |= MASK_ATTACHMENT;
}
+ else if (at == LLAssetType::AT_GESTURE)
+ {
+ mask |= MASK_GESTURE;
+ }
else
{
mask |= MASK_UNKNOWN;
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index e6788ab249..df4b1a8a50 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -310,6 +310,7 @@ public:
ORDER_RANK_1 = 1,
ORDER_RANK_2,
ORDER_RANK_3,
+ ORDER_RANK_4,
ORDER_RANK_UNKNOWN
};
@@ -419,7 +420,8 @@ public:
MASK_CLOTHING = 0x01,
MASK_BODYPART = 0x02,
MASK_ATTACHMENT = 0x04,
- MASK_UNKNOWN = 0x08,
+ MASK_GESTURE = 0x08,
+ MASK_UNKNOWN = 0x16,
};
/* virtual */ LLContextMenu* createMenu();
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index 0be6e49834..b37e41fb85 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -234,6 +234,9 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url,
//static
bool LLWeb::useExternalBrowser(const std::string &url)
{
+#ifdef EXTERNAL_TOS
+ return true;
+#else
if (gSavedSettings.getU32("PreferredBrowserBehavior") == BROWSER_EXTERNAL_ONLY)
{
return true;
@@ -250,4 +253,5 @@ bool LLWeb::useExternalBrowser(const std::string &url)
return !(boost::regex_search(uri_string, matches, pattern));
}
return false;
+#endif
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 03712c1065..3c58ce0c09 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7059,7 +7059,7 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, face_hit, &position, NULL, NULL, NULL);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL);
if (hit)
{
drawable = hit;
@@ -7085,7 +7085,8 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start,
}
LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
- BOOL pick_transparent,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit,
LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
@@ -7117,7 +7118,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(j);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -7174,7 +7175,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
LLVector4a delta;
@@ -7262,7 +7263,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, c
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
if (part)
{
- LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, face_hit, intersection, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -7709,7 +7710,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
LLVector4a result;
result.clear();
- gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
+ gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE,
NULL,
&result);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index ce2f4b17b1..97e11a151f 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -183,6 +183,7 @@ public:
//get the object between start and end that's closest to start.
LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
+ BOOL pick_rigged,
S32* face_hit, // return the face hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml
index 9a6f5e0166..d427376574 100644
--- a/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml
@@ -141,35 +141,35 @@ Maximal erlaubt sind [MAX_LENGTH] Sekunden.
Ausdruck
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Vorschau während:
-
-
-
-
+
+
+
+
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index edf028bf60..384ae6bb1e 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -2,13 +2,13 @@
+ width="634">
"Parcel_PG_Dark"
@@ -39,17 +39,18 @@
+ tab_position="left"
+ tab_width="140"
+ tab_padding_right="3"
+ top="6"
+ width="633">
@@ -302,7 +303,7 @@
label="Deed"
layout="topleft"
left_pad="2"
- right="-10"
+ right="-154"
name="Deed..."
tool_tip="You may only deed land if you are an officer in the selected group."
top_delta="-2"
@@ -365,7 +366,7 @@
label="Sell Land"
layout="topleft"
left_pad="5"
- right="-10"
+ right="-154"
name="Sell Land..."
width="145"
top_delta="-25"/>
@@ -412,7 +413,7 @@
label="Cancel Land Sale"
label_selected="Cancel Land Sale"
layout="topleft"
- right="-10"
+ right="-154"
name="Cancel Land Sale"
left_pad="5"
top_pad="7"
@@ -527,7 +528,7 @@
height="23"
label="Buy For Group"
layout="topleft"
- right="-10"
+ right="-154"
name="Buy For Group..."
top_delta="0"
width="180" />
@@ -547,7 +548,7 @@
height="23"
label="Abandon Land"
layout="topleft"
- right="-10"
+ right="-154"
name="Abandon Land..."
top_pad="-47"
width="180" />
@@ -645,8 +646,8 @@
type="string"
length="1"
enabled="false"
- follows="all"
- height="200"
+ follows="top|left"
+ height="175"
layout="topleft"
left="10"
max_length="65535"
@@ -663,7 +664,7 @@
halign="right"
layout="topleft"
right="-10"
- top_pad="0"
+ top_pad="25"
mouse_opaque="false"
name="covenant_timestamp_text"
width="460">
@@ -930,7 +931,7 @@
label_selected="Show"
layout="topleft"
name="ShowOwner"
- right="-140"
+ right="-284"
width="60"
top_delta="-6"/>
@@ -978,7 +979,7 @@
label_selected="Show"
layout="topleft"
name="ShowGroup"
- right="-140"
+ right="-284"
width="60"
top_delta="-6"/>
@@ -1026,7 +1027,7 @@
label_selected="Show"
layout="topleft"
name="ShowOther"
- right="-140"
+ right="-284"
width="60"
top_delta="-6"/>
@@ -1122,13 +1123,13 @@
left_pad="6"
name="Return objects..."
top_delta="0"
- right="-10"
+ right="-154"
width="164" />
@@ -1357,7 +1358,7 @@ Only large parcels can be listed in search.
enabled="true"
height="23"
layout="topleft"
- left="20"
+ left="164"
top="194"
name="land category"
visible="true"
@@ -1494,7 +1495,7 @@ Only large parcels can be listed in search.
label_selected="Set"
layout="topleft"
name="Set"
- left="255"
+ left="399"
tool_tip="Sets the landing point where visitors arrive. Sets to your avatar's location inside this parcel."
width="50" />