From ab9e83030671f0d309eada847af7055213dfe501 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 24 Mar 2015 00:42:42 +0100
Subject: Refer to new QuickTime third party package with fixes for VS2013 &
 re-add QuickTime media plugin

---
 indra/cmake/CMakeLists.txt                   |  6 +++---
 indra/cmake/Linking.cmake                    |  2 +-
 indra/cmake/Variables.cmake                  |  2 +-
 indra/llplugin/CMakeLists.txt                |  2 +-
 indra/llplugin/slplugin/slplugin.cpp         |  1 -
 indra/media_plugins/CMakeLists.txt           |  8 +++++---
 indra/media_plugins/quicktime/CMakeLists.txt |  3 ++-
 indra/newview/CMakeLists.txt                 | 30 ++++++++++++----------------
 8 files changed, 26 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index cd7da5d6c1..8d43afd1e2 100755
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -82,18 +82,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
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index c95f0c3702..74fe3f1137 100755
--- 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 faca12c347..aa9127eea9 100755
--- 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/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 05fc12e338..75d89aac78 100755
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -68,7 +68,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/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
index 6c9ba0ae52..684bcf1207 100755
--- 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/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index 85318aea3b..956e8fe890 100755
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
@@ -2,9 +2,11 @@
 
 add_subdirectory(base)
 
-add_subdirectory(webkit)
+### add_subdirectory(webkit)
 
-add_subdirectory(gstreamer010)
+if (LINUX)
+    add_subdirectory(gstreamer010)
+endif (LINUX)
 
 if (WINDOWS OR DARWIN)
     add_subdirectory(quicktime)
@@ -14,4 +16,4 @@ if (WINDOWS)
     add_subdirectory(winmmshim)
 endif (WINDOWS)
 
-add_subdirectory(example)
+### add_subdirectory(example)
diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt
index 58391007ff..d7a1874bf3 100755
--- 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/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 8c5bc9777c..82de50ee64 100755
--- 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}
@@ -1824,10 +1820,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)
@@ -1994,9 +1990,9 @@ if (LINUX)
   set(COPY_INPUT_DEPENDENCIES
     ${VIEWER_BINARY_NAME}
     linux-crash-logger
-##  SLPlugin
-##  media_plugin_webkit
-##  media_plugin_gstreamer010
+    SLPlugin
+    media_plugin_webkit
+    media_plugin_gstreamer010
     llcommon
     )
 
@@ -2108,7 +2104,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_webkit mac-crash-logger)
   add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)
 
   if (ENABLE_SIGNING)
@@ -2163,20 +2159,20 @@ 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/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}")
     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)
-- 
cgit v1.2.3


From f8989216a4dff518655a9af540f0404449e37a20 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 24 Mar 2015 16:41:47 -0400
Subject: Attempt to restore copying newly-built SLPlugin et al. - UNTESTED

---
 indra/newview/viewer_manifest.py | 117 +++++++++++++++++++++++++--------------
 1 file changed, 74 insertions(+), 43 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 32cf9d3df6..e7affd4f63 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -340,9 +340,9 @@ class Windows_i686_Manifest(ViewerManifest):
             self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())
 
         # Plugin host application
-        # The current slplugin package places slplugin.exe right into the
-        # packages base directory.
-        self.path2basename(pkgdir, "slplugin.exe")
+        self.path2basename(os.path.join(os.pardir,
+                                        'llplugin', 'slplugin', self.args['configuration']),
+                           "slplugin.exe")
         
         self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat")
         # Get shared libs from the shared libs staging directory
@@ -424,16 +424,63 @@ class Windows_i686_Manifest(ViewerManifest):
         self.path("featuretable_xp.txt")
 
         # Media plugins - QuickTime
-        # Media plugins - WebKit/Qt
-        if self.prefix(src=os.path.join(pkgdir, "llplugin"), dst="llplugin"):
+        if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
             self.path("media_plugin_quicktime.dll")
+            self.end_prefix()
+
+        # Media plugins - WebKit/Qt
+        if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"):
             self.path("media_plugin_webkit.dll")
-            self.path("qtcore4.dll")
-            self.path("qtgui4.dll")
-            self.path("qtnetwork4.dll")
-            self.path("qtopengl4.dll")
-            self.path("qtwebkit4.dll")
-            self.path("qtxmlpatterns4.dll")
+            self.end_prefix()
+
+        # winmm.dll shim
+        if self.prefix(src='../media_plugins/winmmshim/%s' % self.args['configuration'], dst=""):
+            self.path("winmm.dll")
+            self.end_prefix()
+
+
+        if self.args['configuration'].lower() == 'debug':
+            if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'debug'),
+                           dst="llplugin"):
+                self.path("libeay32.dll")
+                self.path("qtcored4.dll")
+                self.path("qtguid4.dll")
+                self.path("qtnetworkd4.dll")
+                self.path("qtopengld4.dll")
+                self.path("qtwebkitd4.dll")
+                self.path("qtxmlpatternsd4.dll")
+                self.path("ssleay32.dll")
+
+                # For WebKit/Qt plugin runtimes (image format plugins)
+                if self.prefix(src="imageformats", dst="imageformats"):
+                    self.path("qgifd4.dll")
+                    self.path("qicod4.dll")
+                    self.path("qjpegd4.dll")
+                    self.path("qmngd4.dll")
+                    self.path("qsvgd4.dll")
+                    self.path("qtiffd4.dll")
+                    self.end_prefix()
+
+                # For WebKit/Qt plugin runtimes (codec/character encoding plugins)
+                if self.prefix(src="codecs", dst="codecs"):
+                    self.path("qcncodecsd4.dll")
+                    self.path("qjpcodecsd4.dll")
+                    self.path("qkrcodecsd4.dll")
+                    self.path("qtwcodecsd4.dll")
+                    self.end_prefix()
+
+                self.end_prefix()
+        else:
+            if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release'),
+                           dst="llplugin"):
+                self.path("libeay32.dll")
+                self.path("qtcore4.dll")
+                self.path("qtgui4.dll")
+                self.path("qtnetwork4.dll")
+                self.path("qtopengl4.dll")
+                self.path("qtwebkit4.dll")
+                self.path("qtxmlpatterns4.dll")
+                self.path("ssleay32.dll")
 
             # For WebKit/Qt plugin runtimes (image format plugins)
             if self.prefix(src="imageformats", dst="imageformats"):
@@ -455,23 +502,6 @@ class Windows_i686_Manifest(ViewerManifest):
 
         self.end_prefix()
 
-        # winmm.dll shim
-        if self.prefix(src='../media_plugins/winmmshim/%s' % self.args['configuration'], dst=""):
-            self.path("winmm.dll")
-            self.end_prefix()
-
-        if self.args['configuration'].lower() == 'debug':
-            if self.prefix(src=debpkgdir, dst="llplugin"):
-                self.path("libeay32.dll")
-                self.path("ssleay32.dll")
-                self.end_prefix()
-
-        else:
-            if self.prefix(src=relpkgdir, dst="llplugin"):
-                self.path("libeay32.dll")
-                self.path("ssleay32.dll")
-                self.end_prefix()
-
         # pull in the crash logger and updater from other projects
         # tag:"crash-logger" here as a cue to the exporter
         self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],
@@ -735,14 +765,13 @@ class Darwin_i386_Manifest(ViewerManifest):
                         dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
                 
                 # our apps
-                for app_bld_dir, app in ((os.path.join(os.pardir,
-                                                       "mac_crash_logger",
-                                                       self.args['configuration']),
-                                          "mac-crash-logger.app"),
+                for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
                                          # plugin launcher
-                                         (pkgdir, "SLPlugin.app"),
+                                         (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
                                          ):
-                    self.path2basename(app_bld_dir, app)
+                    self.path2basename(os.path.join(os.pardir,
+                                                    app_bld_dir, self.args['configuration']),
+                                       app)
 
                     # our apps dependencies on shared libs
                     # for each app, for each dylib we collected in dylibs,
@@ -776,19 +805,21 @@ class Darwin_i386_Manifest(ViewerManifest):
 
                 # Qt4 codecs go to llplugin.  Not certain why but this is the first
                 # location probed according to dtruss so we'll go with that.
-                if self.prefix(src=os.path.join(pkgdir, "llplugin/codecs/"), dst="llplugin/codecs"):
+                if self.prefix(src="../packages/plugins/codecs/", dst="llplugin/codecs"):
                     self.path("libq*.dylib")
                     self.end_prefix("llplugin/codecs")
 
                 # Similarly for imageformats.
-                if self.prefix(src=os.path.join(pkgdir, "llplugin/imageformats/"), dst="llplugin/imageformats"):
+                if self.prefix(src="../packages/plugins/imageformats/", dst="llplugin/imageformats"):
                     self.path("libq*.dylib")
                     self.end_prefix("llplugin/imageformats")
 
                 # SLPlugin plugins proper
-                if self.prefix(src=os.path.join(pkgdir, "llplugin"), dst="llplugin"):
-                    self.path("media_plugin_quicktime.dylib")
-                    self.path("media_plugin_webkit.dylib")
+                if self.prefix(src="", dst="llplugin"):
+                    self.path2basename("../media_plugins/quicktime/" + self.args['configuration'],
+                                       "media_plugin_quicktime.dylib")
+                    self.path2basename("../media_plugins/webkit/" + self.args['configuration'],
+                                       "media_plugin_webkit.dylib")
                     self.end_prefix("llplugin")
 
                 self.end_prefix("Resources")
@@ -981,7 +1012,7 @@ class LinuxManifest(ViewerManifest):
         if self.prefix(src="", dst="bin"):
             self.path("secondlife-bin","do-not-directly-run-secondlife-bin")
             self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
-            self.path2basename(pkgdir, "SLPlugin")
+            self.path2basename("../llplugin/slplugin", "SLPlugin")
             self.path2basename("../viewer_components/updater/scripts/linux", "update_install")
             self.end_prefix("bin")
 
@@ -1001,9 +1032,9 @@ class LinuxManifest(ViewerManifest):
             self.end_prefix(icon_path)
 
         # plugins
-        if self.prefix(src=os.path.join(pkgdir, "llplugin"), dst="bin/llplugin"):
-            self.path("libmedia_plugin_webkit.so")
-            self.path("libmedia_plugin_gstreamer.so")
+        if self.prefix(src="", dst="bin/llplugin"):
+            self.path2basename("../media_plugins/webkit", "libmedia_plugin_webkit.so")
+            self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so")
             self.end_prefix("bin/llplugin")
 
         # llcommon
-- 
cgit v1.2.3


From dbdef626d650de288697848977155e223cbba9ad Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 24 Mar 2015 17:22:58 -0700
Subject: Add new media plugin (currently renders squares as example) in
 preparation for new CEF code

---
 indra/cmake/CEFPlugin.cmake                       |  16 +
 indra/cmake/CMakeLists.txt                        |   1 +
 indra/media_plugins/CMakeLists.txt                |   4 +-
 indra/media_plugins/cef/CMakeLists.txt            |  86 +++++
 indra/media_plugins/cef/media_plugin_cef.cpp      | 413 ++++++++++++++++++++++
 indra/newview/CMakeLists.txt                      |   4 +-
 indra/newview/llviewermedia.cpp                   |   2 +-
 indra/newview/skins/default/xui/en/mime_types.xml |  40 +--
 indra/newview/viewer_manifest.py                  |   6 +-
 9 files changed, 545 insertions(+), 27 deletions(-)
 create mode 100644 indra/cmake/CEFPlugin.cmake
 create mode 100644 indra/media_plugins/cef/CMakeLists.txt
 create mode 100644 indra/media_plugins/cef/media_plugin_cef.cpp

(limited to 'indra')

diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
new file mode 100644
index 0000000000..29e7ff3d32
--- /dev/null
+++ b/indra/cmake/CEFPlugin.cmake
@@ -0,0 +1,16 @@
+# -*- cmake -*-
+include(Linking)
+include(Prebuilt)
+
+if (USESYSTEMLIBS)
+    set(CEFPLUGIN OFF CACHE BOOL
+        "CEFPLUGIN support for the llplugin/llmedia test apps.")
+else (USESYSTEMLIBS)
+    set(CEFPLUGIN ON CACHE BOOL
+        "CEFPLUGIN support for the llplugin/llmedia test apps.")
+endif (USESYSTEMLIBS)
+
+if (WINDOWS)
+elseif (DARWIN)
+elseif (LINUX)
+endif (WINDOWS)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 8d43afd1e2..2298b0f284 100755
--- 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
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index 956e8fe890..0e0f84d1fd 100755
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
@@ -2,7 +2,9 @@
 
 add_subdirectory(base)
 
-### add_subdirectory(webkit)
+if (WINDOWS)
+    add_subdirectory(cef)
+endif (WINDOWS)
 
 if (LINUX)
     add_subdirectory(gstreamer010)
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
new file mode 100644
index 0000000000..663303f0eb
--- /dev/null
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -0,0 +1,86 @@
+# -*- cmake -*-
+
+project(media_plugin_cef)
+
+include(00-Common)
+include(LLCommon)
+include(LLImage)
+include(LLPlugin)
+include(LLMath)
+include(LLRender)
+include(LLWindow)
+include(Linking)
+include(PluginAPI)
+include(MediaPluginBase)
+include(OpenGL)
+
+include(CEFPlugin)
+
+include_directories(
+    ${LLPLUGIN_INCLUDE_DIRS}
+    ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
+    ${LLCOMMON_INCLUDE_DIRS}
+    ${LLMATH_INCLUDE_DIRS}
+    ${LLIMAGE_INCLUDE_DIRS}
+    ${LLRENDER_INCLUDE_DIRS}
+    ${LLWINDOW_INCLUDE_DIRS}
+)
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
+
+
+### media_plugin_cef
+
+if(NOT WORD_SIZE EQUAL 32)
+  if(WINDOWS)
+    add_definitions(/FIXED:NO)
+  else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
+    add_definitions(-fPIC)
+  endif(WINDOWS)
+endif(NOT WORD_SIZE EQUAL 32)
+
+set(media_plugin_cef_SOURCE_FILES
+    media_plugin_cef.cpp
+    )
+
+add_library(media_plugin_cef
+    SHARED
+    ${media_plugin_cef_SOURCE_FILES}
+)
+
+target_link_libraries(media_plugin_cef
+  ${LLPLUGIN_LIBRARIES}
+  ${MEDIA_PLUGIN_BASE_LIBRARIES}
+  ${LLCOMMON_LIBRARIES}
+  ${CEF_PLUGIN_LIBRARIES}
+  ${PLUGIN_API_WINDOWS_LIBRARIES}
+)
+
+add_dependencies(media_plugin_cef
+  ${LLPLUGIN_LIBRARIES}
+  ${MEDIA_PLUGIN_BASE_LIBRARIES}
+  ${LLCOMMON_LIBRARIES}
+)
+
+if (WINDOWS)
+  set_target_properties(
+    media_plugin_cef
+    PROPERTIES
+    LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /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_cef
+    PROPERTIES
+    PREFIX ""
+    BUILD_WITH_INSTALL_RPATH 1
+    INSTALL_NAME_DIR "@executable_path"
+    LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp"
+  )
+
+endif (DARWIN)
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..ada297373a
--- /dev/null
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -0,0 +1,413 @@
+/**
+ * @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 "llgl.h"
+#include "llplugininstance.h"
+#include "llpluginmessage.h"
+#include "llpluginmessageclasses.h"
+#include "media_plugin_base.h"
+
+#include <time.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 update( F64 milliseconds );
+        void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b );
+        bool mFirstTime;
+
+        time_t mLastUpdateTime;
+        enum Constants { ENumObjects = 10 };
+        unsigned char* mBackgroundPixels;
+        int mColorR[ ENumObjects ];
+        int mColorG[ ENumObjects ];
+        int mColorB[ ENumObjects ];
+        int mXpos[ ENumObjects ];
+        int mYpos[ ENumObjects ];
+        int mXInc[ ENumObjects ];
+        int mYInc[ ENumObjects ];
+        int mBlockSize[ ENumObjects ];
+        bool mMouseButtonDown;
+        bool mStopAction;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+MediaPluginCEF::MediaPluginCEF( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) :
+    MediaPluginBase( host_send_func, host_user_data )
+{
+    mFirstTime = true;
+    mWidth = 0;
+    mHeight = 0;
+    mDepth = 4;
+    mPixels = 0;
+    mMouseButtonDown = false;
+    mStopAction = false;
+    mLastUpdateTime = 0;
+	mBackgroundPixels = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+MediaPluginCEF::~MediaPluginCEF()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::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 = "CEF plugin 1.0..0";
+                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")
+            {
+            }
+            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)
+                    {
+                        // 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)
+        {
+            if(message_name == "init")
+            {
+                // 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_RGBA);
+                message.setValueU32("type", GL_UNSIGNED_BYTE);
+                message.setValueBoolean("coords_opengl", true);
+                sendMessage(message);
+            }
+            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;
+                    };
+                };
+
+                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")
+            {
+            }
+            else if(message_name == "mouse_event")
+            {
+                std::string event = message_in.getValue("event");
+                if(event == "down")
+                {
+
+                }
+                else if(event == "up")
+                {
+                }
+                else if(event == "double_click")
+                {
+                }
+            }
+        }
+        else
+        {
+//          std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
+        };
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b )
+{
+    // make sure we don't write outside the buffer
+    if ( ( x < 0 ) || ( x >= mWidth ) || ( y < 0 ) || ( y >= mHeight ) )
+        return;
+
+    if ( mBackgroundPixels != NULL )
+    {
+        unsigned char *pixel = mBackgroundPixels;
+        pixel += y * mWidth * mDepth;
+        pixel += ( x * mDepth );
+        pixel[ 0 ] = b;
+        pixel[ 1 ] = g;
+        pixel[ 2 ] = r;
+
+        setDirty( x, y, x + 1, y + 1 );
+    };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::update( F64 milliseconds )
+{
+    if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 )
+        return;
+
+    if ( mPixels == 0 )
+            return;
+
+    if ( mFirstTime )
+    {
+        for( int n = 0; n < ENumObjects; ++n )
+        {
+            mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 );
+            mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 );
+
+            mColorR[ n ] = rand() % 0x60 + 0x60;
+            mColorG[ n ] = rand() % 0x60 + 0x60;
+            mColorB[ n ] = rand() % 0x60 + 0x60;
+
+            mXInc[ n ] = 0;
+            while ( mXInc[ n ] == 0 )
+                mXInc[ n ] = rand() % 7 - 3;
+
+            mYInc[ n ] = 0;
+            while ( mYInc[ n ] == 0 )
+                mYInc[ n ] = rand() % 9 - 4;
+
+            mBlockSize[ n ] = rand() % 0x30 + 0x10;
+        };
+
+        delete [] mBackgroundPixels;
+
+        mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ];
+
+        mFirstTime = false;
+    };
+
+    if ( mStopAction )
+        return;
+
+    if ( time( NULL ) > mLastUpdateTime + 3 )
+    {
+        const int num_squares = rand() % 20 + 4;
+        int sqr1_r = rand() % 0x80 + 0x20;
+        int sqr1_g = rand() % 0x80 + 0x20;
+        int sqr1_b = rand() % 0x80 + 0x20;
+        int sqr2_r = rand() % 0x80 + 0x20;
+        int sqr2_g = rand() % 0x80 + 0x20;
+        int sqr2_b = rand() % 0x80 + 0x20;
+
+        for ( int y1 = 0; y1 < num_squares; ++y1 )
+        {
+            for ( int x1 = 0; x1 < num_squares; ++x1 )
+            {
+                int px_start = mWidth * x1 / num_squares;
+                int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares;
+                int py_start = mHeight * y1 / num_squares;
+                int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares;
+
+                for( int y2 = py_start; y2 < py_end; ++y2 )
+                {
+                    for( int x2 = px_start; x2 < px_end; ++x2 )
+                    {
+                        int rowspan = mWidth * mDepth;
+
+                        if ( ( y1 % 2 ) ^ ( x1 % 2 ) )
+                        {
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r;
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g;
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b;
+                        }
+                        else
+                        {
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r;
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g;
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b;
+                        };
+                    };
+                };
+            };
+        };
+
+        time( &mLastUpdateTime );
+    };
+
+    memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth );
+
+    for( int n = 0; n < ENumObjects; ++n )
+    {
+        if ( rand() % 50 == 0 )
+        {
+                mXInc[ n ] = 0;
+                while ( mXInc[ n ] == 0 )
+                    mXInc[ n ] = rand() % 7 - 3;
+
+                mYInc[ n ] = 0;
+                while ( mYInc[ n ] == 0 )
+                    mYInc[ n ] = rand() % 9 - 4;
+        };
+
+        if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] )
+            mXInc[ n ]= -mXInc[ n ];
+
+        if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] )
+            mYInc[ n ]= -mYInc[ n ];
+
+        mXpos[ n ] += mXInc[ n ];
+        mYpos[ n ] += mYInc[ n ];
+
+        for( int y = 0; y < mBlockSize[ n ]; ++y )
+        {
+            for( int x = 0; x < mBlockSize[ n ]; ++x )
+            {
+                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ];
+                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ];
+                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ];
+            };
+        };
+    };
+
+    setDirty( 0, 0, mWidth, mHeight );
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool MediaPluginCEF::init()
+{
+    LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text" );
+    message.setValue( "name", "Example 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/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 82de50ee64..b03f1717aa 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1775,7 +1775,7 @@ if (WINDOWS)
       ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qtwcodecsd4.dll
       SLPlugin
       media_plugin_quicktime
-      media_plugin_webkit
+      media_plugin_cef
       winmm_shim
       windows-crash-logger
       )
@@ -2104,7 +2104,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)
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index c758bbcc9e..fd24bbf891 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1803,7 +1803,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 	// 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();
diff --git a/indra/newview/skins/default/xui/en/mime_types.xml b/indra/newview/skins/default/xui/en/mime_types.xml
index f5f2223330..7cb4a6e53b 100755
--- a/indra/newview/skins/default/xui/en/mime_types.xml
+++ b/indra/newview/skins/default/xui/en/mime_types.xml
@@ -7,7 +7,7 @@
 		none
 	</defaultwidget>
 	<defaultimpl>
-		media_plugin_webkit
+		media_plugin_cef
 	</defaultimpl>
 	<widgetset name="web">
 		<label name="web_label">
@@ -141,7 +141,7 @@
 			none
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="none/none">
@@ -152,7 +152,7 @@
 			none
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="audio/*">
@@ -185,7 +185,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
@@ -207,7 +207,7 @@
 			web
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/ogg">
@@ -229,7 +229,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/postscript">
@@ -240,7 +240,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/rtf">
@@ -251,7 +251,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/smil">
@@ -262,7 +262,7 @@
 			movie
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/xhtml+xml">
@@ -273,7 +273,7 @@
 			web
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/x-director">
@@ -284,7 +284,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="audio/mid">
@@ -339,7 +339,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="image/gif">
@@ -350,7 +350,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="image/jpeg">
@@ -361,7 +361,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="image/png">
@@ -372,7 +372,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="image/svg+xml">
@@ -383,7 +383,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="image/tiff">
@@ -394,7 +394,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="text/html">
@@ -405,7 +405,7 @@
 			web
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="text/plain">
@@ -416,7 +416,7 @@
 			text
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="text/xml">
@@ -427,7 +427,7 @@
 			text
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="video/mpeg">
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index e7affd4f63..62467750a0 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -428,9 +428,9 @@ class Windows_i686_Manifest(ViewerManifest):
             self.path("media_plugin_quicktime.dll")
             self.end_prefix()
 
-        # Media plugins - WebKit/Qt
-        if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"):
-            self.path("media_plugin_webkit.dll")
+        # Media plugins - CEF
+        if self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"):
+            self.path("media_plugin_cef.dll")
             self.end_prefix()
 
         # winmm.dll shim
-- 
cgit v1.2.3


From 0fe901d67ea7c1f34d3f415a1537bfa676a79fef Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 25 Mar 2015 15:42:35 -0700
Subject: Point to initial pass at a CEF package in autobuild and make sure
 autobuild configure picks it up

---
 indra/cmake/CEFPlugin.cmake | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
index 29e7ff3d32..f7153bb4d9 100644
--- a/indra/cmake/CEFPlugin.cmake
+++ b/indra/cmake/CEFPlugin.cmake
@@ -6,6 +6,7 @@ if (USESYSTEMLIBS)
     set(CEFPLUGIN OFF CACHE BOOL
         "CEFPLUGIN support for the llplugin/llmedia test apps.")
 else (USESYSTEMLIBS)
+    use_prebuilt_binary(cef)
     set(CEFPLUGIN ON CACHE BOOL
         "CEFPLUGIN support for the llplugin/llmedia test apps.")
 endif (USESYSTEMLIBS)
-- 
cgit v1.2.3


From d368babe7cc84ac6d8532e9d2438620cfa6d172d Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 25 Mar 2015 16:16:51 -0700
Subject: Make VS2013 look inside include/cef folder for headers

---
 indra/cmake/CEFPlugin.cmake            | 1 +
 indra/media_plugins/cef/CMakeLists.txt | 1 +
 2 files changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
index f7153bb4d9..84cfaac074 100644
--- a/indra/cmake/CEFPlugin.cmake
+++ b/indra/cmake/CEFPlugin.cmake
@@ -9,6 +9,7 @@ else (USESYSTEMLIBS)
     use_prebuilt_binary(cef)
     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)
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 663303f0eb..7465fe727a 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -24,6 +24,7 @@ include_directories(
     ${LLIMAGE_INCLUDE_DIRS}
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
+    ${CEF_INCLUDE_DIR}
 )
 include_directories(SYSTEM
     ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-- 
cgit v1.2.3


From 834a94caec7691a957c0816f38ac00d765fa5021 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 26 Mar 2015 04:35:13 +0100
Subject: point to new cef tpl with right headers, update cmaake and
 viewer_manifest logic to copy files to right place

---
 indra/cmake/CEFPlugin.cmake                  |   5 +
 indra/media_plugins/cef/media_plugin_cef.cpp | 574 +++++++++++----------------
 indra/newview/viewer_manifest.py             | 142 ++++---
 3 files changed, 328 insertions(+), 393 deletions(-)

(limited to 'indra')

diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
index 84cfaac074..682aeea6b9 100644
--- a/indra/cmake/CEFPlugin.cmake
+++ b/indra/cmake/CEFPlugin.cmake
@@ -13,6 +13,11 @@ else (USESYSTEMLIBS)
 endif (USESYSTEMLIBS)
 
 if (WINDOWS)
+    set(CEF_PLUGIN_LIBRARIES
+        libcef.lib
+        libcef_dll_wrapper.lib
+        llceflib.lib
+    )
 elseif (DARWIN)
 elseif (LINUX)
 endif (WINDOWS)
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index ada297373a..7f0f40bcaa 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -34,380 +34,282 @@
 #include "llpluginmessageclasses.h"
 #include "media_plugin_base.h"
 
+#include <functional>
+#include "llCEFLib.h"
+
 #include <time.h>
 
 ////////////////////////////////////////////////////////////////////////////////
 //
 class MediaPluginCEF :
-        public MediaPluginBase
+	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 update( F64 milliseconds );
-        void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b );
-        bool mFirstTime;
-
-        time_t mLastUpdateTime;
-        enum Constants { ENumObjects = 10 };
-        unsigned char* mBackgroundPixels;
-        int mColorR[ ENumObjects ];
-        int mColorG[ ENumObjects ];
-        int mColorB[ ENumObjects ];
-        int mXpos[ ENumObjects ];
-        int mYpos[ ENumObjects ];
-        int mXInc[ ENumObjects ];
-        int mYInc[ ENumObjects ];
-        int mBlockSize[ ENumObjects ];
-        bool mMouseButtonDown;
-        bool mStopAction;
+public:
+	MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+	~MediaPluginCEF();
+
+	/*virtual*/ void receiveMessage(const char* message_string);
+
+private:
+	bool init();
+	void update(F64 milliseconds);
+	bool mFirstTime;
+
+    // TODO FIX ME
+	void pageChangedCallback(unsigned char* pixels, int width, int height)
+	{
+		if (mPixels && pixels)
+		{
+			memcpy(mPixels, pixels, width * height * mDepth);
+			setDirty(0, 0, mWidth, mHeight);
+		}
+	}
+
+	void MediaPluginCEF::postDebugMessage(const std::string& msg);
+
+	bool mEnableMediaPluginDebugging;
+	LLCEFLib* mLLCEFLib;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-MediaPluginCEF::MediaPluginCEF( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) :
-    MediaPluginBase( host_send_func, host_user_data )
+MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
+MediaPluginBase(host_send_func, host_user_data)
 {
-    mFirstTime = true;
-    mWidth = 0;
-    mHeight = 0;
-    mDepth = 4;
-    mPixels = 0;
-    mMouseButtonDown = false;
-    mStopAction = false;
-    mLastUpdateTime = 0;
-	mBackgroundPixels = 0;
+	mWidth = 0;
+	mHeight = 0;
+	mDepth = 4;
+	mPixels = 0;
+	mEnableMediaPluginDebugging = false;
+
+	mLLCEFLib = new LLCEFLib();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //
 MediaPluginCEF::~MediaPluginCEF()
 {
+	mLLCEFLib->reset();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginCEF::receiveMessage( const char* message_string )
+void MediaPluginCEF::postDebugMessage(const std::string& msg)
 {
-//  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 = "CEF plugin 1.0..0";
-                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")
-            {
-            }
-            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)
-                    {
-                        // 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)
-        {
-            if(message_name == "init")
-            {
-                // 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_RGBA);
-                message.setValueU32("type", GL_UNSIGNED_BYTE);
-                message.setValueBoolean("coords_opengl", true);
-                sendMessage(message);
-            }
-            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;
-                    };
-                };
-
-                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")
-            {
-            }
-            else if(message_name == "mouse_event")
-            {
-                std::string event = message_in.getValue("event");
-                if(event == "down")
-                {
-
-                }
-                else if(event == "up")
-                {
-                }
-                else if(event == "double_click")
-                {
-                }
-            }
-        }
-        else
-        {
-//          std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
-        };
-    }
+	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::write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b )
+void MediaPluginCEF::receiveMessage(const char* message_string)
 {
-    // make sure we don't write outside the buffer
-    if ( ( x < 0 ) || ( x >= mWidth ) || ( y < 0 ) || ( y >= mHeight ) )
-        return;
-
-    if ( mBackgroundPixels != NULL )
-    {
-        unsigned char *pixel = mBackgroundPixels;
-        pixel += y * mWidth * mDepth;
-        pixel += ( x * mDepth );
-        pixel[ 0 ] = b;
-        pixel[ 1 ] = g;
-        pixel[ 2 ] = r;
-
-        setDirty( x, y, x + 1, y + 1 );
-    };
+	//  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 = "Example plugin 1.0..0";
+				message.setValue("plugin_version", plugin_version);
+				sendMessage(message);
+			}
+			else if (message_name == "idle")
+			{
+				mLLCEFLib->update();
+			}
+			else if (message_name == "cleanup")
+			{
+			}
+			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)
+					{
+						// 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)
+		{
+			if (message_name == "init")
+			{
+
+				mLLCEFLib->setPageChangedCallback(std::bind(&MediaPluginCEF::pageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+
+				bool result = mLLCEFLib->init(1024, 1024);
+				if (!result)
+				{
+					MessageBoxA(0, "FAIL INIT", 0, 0);
+				}
+
+				// 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", false);
+				sendMessage(message);
+			}
+			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 == "load_uri")
+			{
+				std::string uri = message_in.getValue("uri");
+				mLLCEFLib->navigate(uri);
+			}
+			else if (message_name == "mouse_event")
+			{
+				std::string event = message_in.getValue("event");
+				//S32 button = message_in.getValueS32("button");
+				S32 x = message_in.getValueS32("x");
+				S32 y = message_in.getValueS32("y");
+
+
+
+				//std::string modifiers = message_in.getValue("modifiers");
+
+				if (event == "down")
+				{
+					mLLCEFLib->mouseButton(0, true, x, y);
+
+					std::stringstream str;
+					str << "Mouse down at = " << x << ", " << y;
+					postDebugMessage(str.str());
+				}
+				else if (event == "up")
+				{
+					mLLCEFLib->mouseButton(0, false, x, y);
+				}
+				else if (event == "double_click")
+				{
+				}
+				else
+				{
+					mLLCEFLib->mouseMove(x, y);
+				}
+			}
+			else
+				if (message_name == "enable_media_plugin_debugging")
+				{
+					mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
+				}
+		}
+		else
+		{
+			//          std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
+		};
+	}
 }
 
-////////////////////////////////////////////////////////////////////////////////
-//
-void MediaPluginCEF::update( F64 milliseconds )
-{
-    if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 )
-        return;
-
-    if ( mPixels == 0 )
-            return;
-
-    if ( mFirstTime )
-    {
-        for( int n = 0; n < ENumObjects; ++n )
-        {
-            mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 );
-            mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 );
-
-            mColorR[ n ] = rand() % 0x60 + 0x60;
-            mColorG[ n ] = rand() % 0x60 + 0x60;
-            mColorB[ n ] = rand() % 0x60 + 0x60;
-
-            mXInc[ n ] = 0;
-            while ( mXInc[ n ] == 0 )
-                mXInc[ n ] = rand() % 7 - 3;
-
-            mYInc[ n ] = 0;
-            while ( mYInc[ n ] == 0 )
-                mYInc[ n ] = rand() % 9 - 4;
-
-            mBlockSize[ n ] = rand() % 0x30 + 0x10;
-        };
-
-        delete [] mBackgroundPixels;
-
-        mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ];
-
-        mFirstTime = false;
-    };
-
-    if ( mStopAction )
-        return;
-
-    if ( time( NULL ) > mLastUpdateTime + 3 )
-    {
-        const int num_squares = rand() % 20 + 4;
-        int sqr1_r = rand() % 0x80 + 0x20;
-        int sqr1_g = rand() % 0x80 + 0x20;
-        int sqr1_b = rand() % 0x80 + 0x20;
-        int sqr2_r = rand() % 0x80 + 0x20;
-        int sqr2_g = rand() % 0x80 + 0x20;
-        int sqr2_b = rand() % 0x80 + 0x20;
-
-        for ( int y1 = 0; y1 < num_squares; ++y1 )
-        {
-            for ( int x1 = 0; x1 < num_squares; ++x1 )
-            {
-                int px_start = mWidth * x1 / num_squares;
-                int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares;
-                int py_start = mHeight * y1 / num_squares;
-                int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares;
-
-                for( int y2 = py_start; y2 < py_end; ++y2 )
-                {
-                    for( int x2 = px_start; x2 < px_end; ++x2 )
-                    {
-                        int rowspan = mWidth * mDepth;
-
-                        if ( ( y1 % 2 ) ^ ( x1 % 2 ) )
-                        {
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r;
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g;
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b;
-                        }
-                        else
-                        {
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r;
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g;
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b;
-                        };
-                    };
-                };
-            };
-        };
-
-        time( &mLastUpdateTime );
-    };
-
-    memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth );
-
-    for( int n = 0; n < ENumObjects; ++n )
-    {
-        if ( rand() % 50 == 0 )
-        {
-                mXInc[ n ] = 0;
-                while ( mXInc[ n ] == 0 )
-                    mXInc[ n ] = rand() % 7 - 3;
-
-                mYInc[ n ] = 0;
-                while ( mYInc[ n ] == 0 )
-                    mYInc[ n ] = rand() % 9 - 4;
-        };
-
-        if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] )
-            mXInc[ n ]= -mXInc[ n ];
-
-        if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] )
-            mYInc[ n ]= -mYInc[ n ];
-
-        mXpos[ n ] += mXInc[ n ];
-        mYpos[ n ] += mYInc[ n ];
-
-        for( int y = 0; y < mBlockSize[ n ]; ++y )
-        {
-            for( int x = 0; x < mBlockSize[ n ]; ++x )
-            {
-                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ];
-                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ];
-                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ];
-            };
-        };
-    };
-
-    setDirty( 0, 0, mWidth, mHeight );
-};
-
 ////////////////////////////////////////////////////////////////////////////////
 //
 bool MediaPluginCEF::init()
 {
-    LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text" );
-    message.setValue( "name", "Example Plugin" );
-    sendMessage( message );
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+	message.setValue("name", "Example Plugin");
+	sendMessage(message);
 
-    return true;
+	return true;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func,
-                        void* host_user_data,
-                        LLPluginInstance::sendMessageFunction *plugin_send_func,
-                        void **plugin_user_data )
+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;
+	MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data);
+	*plugin_send_func = MediaPluginCEF::staticReceiveMessage;
+	*plugin_user_data = (void*)self;
 
-    return 0;
+	return 0;
 }
-
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 62467750a0..8613cbed57 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -438,69 +438,97 @@ class Windows_i686_Manifest(ViewerManifest):
             self.path("winmm.dll")
             self.end_prefix()
 
-
+        # CEF runtime files - debug
         if self.args['configuration'].lower() == 'debug':
-            if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'debug'),
-                           dst="llplugin"):
-                self.path("libeay32.dll")
-                self.path("qtcored4.dll")
-                self.path("qtguid4.dll")
-                self.path("qtnetworkd4.dll")
-                self.path("qtopengld4.dll")
-                self.path("qtwebkitd4.dll")
-                self.path("qtxmlpatternsd4.dll")
-                self.path("ssleay32.dll")
-
-                # For WebKit/Qt plugin runtimes (image format plugins)
-                if self.prefix(src="imageformats", dst="imageformats"):
-                    self.path("qgifd4.dll")
-                    self.path("qicod4.dll")
-                    self.path("qjpegd4.dll")
-                    self.path("qmngd4.dll")
-                    self.path("qsvgd4.dll")
-                    self.path("qtiffd4.dll")
-                    self.end_prefix()
-
-                # For WebKit/Qt plugin runtimes (codec/character encoding plugins)
-                if self.prefix(src="codecs", dst="codecs"):
-                    self.path("qcncodecsd4.dll")
-                    self.path("qjpcodecsd4.dll")
-                    self.path("qkrcodecsd4.dll")
-                    self.path("qtwcodecsd4.dll")
-                    self.end_prefix()
-
+            if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'debug'), dst="llplugin"):
+                self.path("d3dcompiler_43.dll")
+                self.path("d3dcompiler_47.dll")
+                self.path("ffmpegsumo.dll")
+                self.path("libcef.dll")
+                self.path("libEGL.dll")
+                self.path("libGLESv2.dll")
+                self.path("llceflib_host.exe")
+                self.path("pdf.dll")
+                self.path("wow_helper.exe")
                 self.end_prefix()
         else:
-            if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release'),
-                           dst="llplugin"):
-                self.path("libeay32.dll")
-                self.path("qtcore4.dll")
-                self.path("qtgui4.dll")
-                self.path("qtnetwork4.dll")
-                self.path("qtopengl4.dll")
-                self.path("qtwebkit4.dll")
-                self.path("qtxmlpatterns4.dll")
-                self.path("ssleay32.dll")
-
-            # For WebKit/Qt plugin runtimes (image format plugins)
-            if self.prefix(src="imageformats", dst="imageformats"):
-                self.path("qgif4.dll")
-                self.path("qico4.dll")
-                self.path("qjpeg4.dll")
-                self.path("qmng4.dll")
-                self.path("qsvg4.dll")
-                self.path("qtiff4.dll")
+        # CEF runtime files - not debug (release, relwithdebinfo etc.)
+            if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"):
+                self.path("d3dcompiler_43.dll")
+                self.path("d3dcompiler_47.dll")
+                self.path("ffmpegsumo.dll")
+                self.path("libcef.dll")
+                self.path("libEGL.dll")
+                self.path("libGLESv2.dll")
+                self.path("llceflib_host.exe")
+                self.path("pdf.dll")
+                self.path("wow_helper.exe")
                 self.end_prefix()
 
-            # For WebKit/Qt plugin runtimes (codec/character encoding plugins)
-            if self.prefix(src="codecs", dst="codecs"):
-                self.path("qcncodecs4.dll")
-                self.path("qjpcodecs4.dll")
-                self.path("qkrcodecs4.dll")
-                self.path("qtwcodecs4.dll")
-                self.end_prefix()
+        # CEF files common to all configurations
+        if self.prefix(src=os.path.join(os.pardir, 'packages', 'resources'), dst="llplugin"):
+            self.path("cef.pak")
+            self.path("cef_100_percent.pak")
+            self.path("cef_200_percent.pak")
+            self.path("devtools_resources.pak")
+            self.path("icudtl.dat")
+            self.end_prefix()
 
-        self.end_prefix()
+        if self.prefix(src=os.path.join(os.pardir, 'packages', 'resources', 'locales'), dst=os.path.join('llplugin', 'locales')):
+            self.path("am.pak")
+            self.path("ar.pak")
+            self.path("bg.pak")
+            self.path("bn.pak")
+            self.path("ca.pak")
+            self.path("cs.pak")
+            self.path("da.pak")
+            self.path("de.pak")
+            self.path("el.pak")
+            self.path("en-GB.pak")
+            self.path("en-US.pak")
+            self.path("es-419.pak")
+            self.path("es.pak")
+            self.path("et.pak")
+            self.path("fa.pak")
+            self.path("fi.pak")
+            self.path("fil.pak")
+            self.path("fr.pak")
+            self.path("gu.pak")
+            self.path("he.pak")
+            self.path("hi.pak")
+            self.path("hr.pak")
+            self.path("hu.pak")
+            self.path("id.pak")
+            self.path("it.pak")
+            self.path("ja.pak")
+            self.path("kn.pak")
+            self.path("ko.pak")
+            self.path("lt.pak")
+            self.path("lv.pak")
+            self.path("ml.pak")
+            self.path("mr.pak")
+            self.path("ms.pak")
+            self.path("nb.pak")
+            self.path("nl.pak")
+            self.path("pl.pak")
+            self.path("pt-BR.pak")
+            self.path("pt-PT.pak")
+            self.path("ro.pak")
+            self.path("ru.pak")
+            self.path("sk.pak")
+            self.path("sl.pak")
+            self.path("sr.pak")
+            self.path("sv.pak")
+            self.path("sw.pak")
+            self.path("ta.pak")
+            self.path("te.pak")
+            self.path("th.pak")
+            self.path("tr.pak")
+            self.path("uk.pak")
+            self.path("vi.pak")
+            self.path("zh-CN.pak")
+            self.path("zh-TW.pak")
+            self.end_prefix()
 
         # pull in the crash logger and updater from other projects
         # tag:"crash-logger" here as a cue to the exporter
-- 
cgit v1.2.3


From 9e43798e899a0a337d53ac1fa5a1984d3dfeb0f1 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 26 Mar 2015 18:37:51 +0100
Subject: Remove standlone media plugin and fb connect test apps while we
 transition to CEF

---
 indra/CMakeLists.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 10692402a5..2d45bc938e 100755
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -60,8 +60,9 @@ 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)
+    #removed during webkit -> cef update
+    #add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
+    #add_subdirectory(${VIEWER_PREFIX}test_apps/llfbconnecttest)
   endif (LL_TESTS AND NOT LINUX)
 endif (ENABLE_MEDIA_PLUGINS)
 
-- 
cgit v1.2.3


From efffc4b0748d1fe950f46aaafe3ded679536d934 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Sat, 28 Mar 2015 01:49:20 +0100
Subject: add support for keyboard (rudimentary & broken), mouse wheel and open
 links in same page

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 136 ++++++++++++++++++---------
 1 file changed, 90 insertions(+), 46 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 7f0f40bcaa..2e8e419e02 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -1,30 +1,30 @@
 /**
- * @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
- */
+* @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"
 
@@ -37,7 +37,7 @@
 #include <functional>
 #include "llCEFLib.h"
 
-#include <time.h>
+#include <time.h>  // remove me
 
 ////////////////////////////////////////////////////////////////////////////////
 //
@@ -48,19 +48,21 @@ public:
 	MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
 	~MediaPluginCEF();
 
-	/*virtual*/ void receiveMessage(const char* message_string);
+	/*virtual*/
+	void receiveMessage(const char* message_string);
 
 private:
 	bool init();
-	void update(F64 milliseconds);
-	bool mFirstTime;
 
-    // TODO FIX ME
+	// TODO FIX ME
 	void pageChangedCallback(unsigned char* pixels, int width, int height)
 	{
 		if (mPixels && pixels)
 		{
-			memcpy(mPixels, pixels, width * height * mDepth);
+			if (mWidth == width && mHeight == height)
+			{
+				memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
+			}
 			setDirty(0, 0, mWidth, mHeight);
 		}
 	}
@@ -80,7 +82,7 @@ MediaPluginBase(host_send_func, host_user_data)
 	mHeight = 0;
 	mDepth = 4;
 	mPixels = 0;
-	mEnableMediaPluginDebugging = false;
+	mEnableMediaPluginDebugging = true;
 
 	mLLCEFLib = new LLCEFLib();
 }
@@ -96,7 +98,7 @@ MediaPluginCEF::~MediaPluginCEF()
 //
 void MediaPluginCEF::postDebugMessage(const std::string& msg)
 {
-	if (mEnableMediaPluginDebugging)
+	//if (mEnableMediaPluginDebugging)
 	{
 		std::stringstream str;
 		str << "@Media Msg> " << msg;
@@ -160,7 +162,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				{
 					if (mPixels == iter->second.mAddress)
 					{
-						// This is the currently active pixel buffer.  Make sure we stop drawing to it.
 						mPixels = NULL;
 						mTextureSegmentName.clear();
 					}
@@ -168,17 +169,16 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				}
 				else
 				{
-					//                  std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
+					//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;
+				//std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
 			}
 		}
 		else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
@@ -191,7 +191,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				bool result = mLLCEFLib->init(1024, 1024);
 				if (!result)
 				{
-					MessageBoxA(0, "FAIL INIT", 0, 0);
+					//MessageBoxA(0, "FAIL INIT", 0, 0);
 				}
 
 				// Plugin gets to decide the texture parameters to use.
@@ -252,14 +252,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				S32 x = message_in.getValueS32("x");
 				S32 y = message_in.getValueS32("y");
 
-
-
 				//std::string modifiers = message_in.getValue("modifiers");
 
 				if (event == "down")
 				{
 					mLLCEFLib->mouseButton(0, true, x, y);
-
+					mLLCEFLib->setFocus(true);
 					std::stringstream str;
 					str << "Mouse down at = " << x << ", " << y;
 					postDebugMessage(str.str());
@@ -276,15 +274,61 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 					mLLCEFLib->mouseMove(x, y);
 				}
 			}
-			else
-				if (message_name == "enable_media_plugin_debugging")
+			else if (message_name == "scroll_event")
+			{
+				S32 y = message_in.getValueS32("y");
+				const int scaling_factor = 40;
+				y *= -scaling_factor;
+
+				mLLCEFLib->mouseWheel(y);
+			}
+			else if (message_name == "text_event")
+			{
+				std::string event = message_in.getValue("event");
+				S32 key = message_in.getValue("text")[0];
+				std::string modifiers = message_in.getValue("modifiers");
+				LLSD native_key_data = message_in.getValueLLSD("native_key_data");
+
+				//int native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
+
+				//if (event == "down")
+				{
+					mLLCEFLib->keyPress(key, true);
+				}
+				//else
+				//if (event == "up")
 				{
-					mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
+					mLLCEFLib->keyPress(key, false);
 				}
+			}
+			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");
+
+				int native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
+				native_scan_code = 8;
+
+				if (event == "down")
+				{
+					mLLCEFLib->keyPress(native_scan_code, true);
+				}
+				else
+				if (event == "up")
+				{
+					mLLCEFLib->keyPress(native_scan_code, false);
+				}
+			}
+			else if (message_name == "enable_media_plugin_debugging")
+			{
+				mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
+			}
 		}
 		else
 		{
-			//          std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
+			//std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
 		};
 	}
 }
-- 
cgit v1.2.3


From 3728730839bf670ae22dd644aa1905e8e9c34560 Mon Sep 17 00:00:00 2001
From: Callum Prentice <callum@lindenlab.com>
Date: Thu, 4 Jun 2015 16:27:33 -0700
Subject: Add CEF into OS X build

---
 indra/media_plugins/CMakeLists.txt | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index 0e0f84d1fd..24eb3947b4 100755
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
@@ -2,16 +2,13 @@
 
 add_subdirectory(base)
 
-if (WINDOWS)
-    add_subdirectory(cef)
-endif (WINDOWS)
-
 if (LINUX)
     add_subdirectory(gstreamer010)
 endif (LINUX)
 
 if (WINDOWS OR DARWIN)
     add_subdirectory(quicktime)
+    add_subdirectory(cef)
 endif (WINDOWS OR DARWIN)
 
 if (WINDOWS)
-- 
cgit v1.2.3


From 3298dccfee96600eaa2e824485f767dc1da677c6 Mon Sep 17 00:00:00 2001
From: Callum Prentice <callum@lindenlab.com>
Date: Thu, 4 Jun 2015 16:28:00 -0700
Subject: Copy OS X media plugin to right place

---
 indra/newview/viewer_manifest.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 8613cbed57..1efe082325 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -846,8 +846,8 @@ class Darwin_i386_Manifest(ViewerManifest):
                 if self.prefix(src="", dst="llplugin"):
                     self.path2basename("../media_plugins/quicktime/" + self.args['configuration'],
                                        "media_plugin_quicktime.dylib")
-                    self.path2basename("../media_plugins/webkit/" + self.args['configuration'],
-                                       "media_plugin_webkit.dylib")
+                    self.path2basename("../media_plugins/cef/" + self.args['configuration'],
+                                       "media_plugin_cef.dylib")
                     self.end_prefix("llplugin")
 
                 self.end_prefix("Resources")
-- 
cgit v1.2.3


From d0320020b3b556294773e5f94b740d79ca9318da Mon Sep 17 00:00:00 2001
From: Callum Prentice <callum@lindenlab.com>
Date: Thu, 4 Jun 2015 16:32:03 -0700
Subject: Point all media with MIME type that used to be webkit, at the new CEF
 plugin

---
 .../skins/default/xui/en/mime_types_mac.xml        | 38 +++++++++++-----------
 1 file changed, 19 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/mime_types_mac.xml b/indra/newview/skins/default/xui/en/mime_types_mac.xml
index 90230f12dd..f71c24b2e4 100755
--- a/indra/newview/skins/default/xui/en/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/en/mime_types_mac.xml
@@ -7,7 +7,7 @@
 		none
 	</defaultwidget>
 	<defaultimpl>
-		media_plugin_webkit
+		media_plugin_cef
 	</defaultimpl>
 	<widgetset name="web">
 		<label name="web_label">
@@ -152,7 +152,7 @@
 			none
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="audio/*">
@@ -185,7 +185,7 @@
 			image
 		</widgettype>
         <impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
@@ -207,7 +207,7 @@
 			web
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/ogg">
@@ -229,7 +229,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/postscript">
@@ -240,7 +240,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/rtf">
@@ -251,7 +251,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/smil">
@@ -262,7 +262,7 @@
 			movie
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/xhtml+xml">
@@ -273,7 +273,7 @@
 			web
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="application/x-director">
@@ -284,7 +284,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="audio/mid">
@@ -339,7 +339,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="image/gif">
@@ -350,7 +350,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="image/jpeg">
@@ -361,7 +361,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="image/png">
@@ -372,7 +372,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="image/svg+xml">
@@ -383,7 +383,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="image/tiff">
@@ -394,7 +394,7 @@
 			image
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="text/html">
@@ -405,7 +405,7 @@
 			web
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="text/plain">
@@ -416,7 +416,7 @@
 			text
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype name="text/xml">
@@ -427,7 +427,7 @@
 			text
 		</widgettype>
 		<impl>
-			media_plugin_webkit
+			media_plugin_cef
 		</impl>
 	</mimetype>
 	<mimetype menu="1" name="video/mpeg">
-- 
cgit v1.2.3


From 6c203273574dfa23e4363144db63378df60bb3fe Mon Sep 17 00:00:00 2001
From: Callum Prentice <callum@lindenlab.com>
Date: Mon, 8 Jun 2015 16:47:16 -0700
Subject: Fixed for OS X version - in progress

---
 indra/cmake/CEFPlugin.cmake                  |  6 ++++++
 indra/media_plugins/cef/media_plugin_cef.cpp | 14 ++++++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
index 682aeea6b9..fdb3b6b272 100644
--- a/indra/cmake/CEFPlugin.cmake
+++ b/indra/cmake/CEFPlugin.cmake
@@ -19,5 +19,11 @@ if (WINDOWS)
         llceflib.lib
     )
 elseif (DARWIN)
+    set(CEF_PLUGIN_LIBRARIES
+        ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
+        ${ARCH_PREBUILT_DIRS_RELEASE}/libLLCefLib.a
+
+        #${ARCH_PREBUILT_DIRS_RELEASE}/libQtWebKit.4.dylib
+       )
 elseif (LINUX)
 endif (WINDOWS)
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 2e8e419e02..098dd67c0d 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -34,7 +34,8 @@
 #include "llpluginmessageclasses.h"
 #include "media_plugin_base.h"
 
-#include <functional>
+#include "../../../build-darwin-i386/packages/include/boost/function.hpp"
+#include "../../../build-darwin-i386/packages/include/boost/bind.hpp"
 #include "llCEFLib.h"
 
 #include <time.h>  // remove me
@@ -67,7 +68,7 @@ private:
 		}
 	}
 
-	void MediaPluginCEF::postDebugMessage(const std::string& msg);
+	void postDebugMessage(const std::string& msg);
 
 	bool mEnableMediaPluginDebugging;
 	LLCEFLib* mLLCEFLib;
@@ -186,9 +187,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			if (message_name == "init")
 			{
 
-				mLLCEFLib->setPageChangedCallback(std::bind(&MediaPluginCEF::pageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+				mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3));
 
-				bool result = mLLCEFLib->init(1024, 1024);
+	            LLCEFLibSettings settings;
+	            settings.inital_width = 1024;
+	            settings.inital_height = 1024;
+	            settings.javascript_enabled = true;
+	            settings.cookies_enabled = true;
+				bool result = mLLCEFLib->init(settings);
 				if (!result)
 				{
 					//MessageBoxA(0, "FAIL INIT", 0, 0);
-- 
cgit v1.2.3


From ac88d58ff5fa273ae0dc71fdf24f6ad03d925d4f Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 10 Jun 2015 18:32:41 -0700
Subject: Changes to let CMake generate determine where the build files for OS
 X CEF media plugin are

---
 indra/cmake/CEFPlugin.cmake | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
index fdb3b6b272..9cfb7d14c7 100644
--- a/indra/cmake/CEFPlugin.cmake
+++ b/indra/cmake/CEFPlugin.cmake
@@ -6,7 +6,7 @@ if (USESYSTEMLIBS)
     set(CEFPLUGIN OFF CACHE BOOL
         "CEFPLUGIN support for the llplugin/llmedia test apps.")
 else (USESYSTEMLIBS)
-    use_prebuilt_binary(cef)
+    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)
@@ -19,11 +19,22 @@ if (WINDOWS)
         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
-
-        #${ARCH_PREBUILT_DIRS_RELEASE}/libQtWebKit.4.dylib
+        ${APPKIT_LIBRARY}
+        ${CEF_LIBRARY}
        )
+
 elseif (LINUX)
 endif (WINDOWS)
-- 
cgit v1.2.3


From a2339f66e4a806e90469f24272ef8599375698fd Mon Sep 17 00:00:00 2001
From: Callum Prentice <callum@lindenlab.com>
Date: Thu, 11 Jun 2015 16:31:37 -0700
Subject: Add commands to move CEF runtime files to right place and fix up
 media_plugin_cef with install_name_tool (note, this generates 2 copies of CEF
 framework - will fix later)

---
 indra/newview/viewer_manifest.py | 52 ++++++++++++++++------------------------
 1 file changed, 20 insertions(+), 32 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 1efe082325..83ba3e2ea0 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -812,37 +812,16 @@ class Darwin_i386_Manifest(ViewerManifest):
                             symlinkf(src, dst)
                         except OSError as err:
                             print "Can't symlink %s -> %s: %s" % (src, dst, err)
-                # SLPlugin.app/Contents/Resources gets those Qt4 libraries it needs.
-                if self.prefix(src="", dst="SLPlugin.app/Contents/Resources"):
-                    for libfile in ('libQtCore.4.dylib',
-                                    'libQtCore.4.7.1.dylib',
-                                    'libQtGui.4.dylib',
-                                    'libQtGui.4.7.1.dylib',
-                                    'libQtNetwork.4.dylib',
-                                    'libQtNetwork.4.7.1.dylib',
-                                    'libQtOpenGL.4.dylib',
-                                    'libQtOpenGL.4.7.1.dylib',
-                                    'libQtSvg.4.dylib',
-                                    'libQtSvg.4.7.1.dylib',
-                                    'libQtWebKit.4.dylib',
-                                    'libQtWebKit.4.7.1.dylib',
-                                    'libQtXml.4.dylib',
-                                    'libQtXml.4.7.1.dylib'):
-                        self.path2basename(relpkgdir, libfile)
-                    self.end_prefix("SLPlugin.app/Contents/Resources")
-
-                # Qt4 codecs go to llplugin.  Not certain why but this is the first
-                # location probed according to dtruss so we'll go with that.
-                if self.prefix(src="../packages/plugins/codecs/", dst="llplugin/codecs"):
-                    self.path("libq*.dylib")
-                    self.end_prefix("llplugin/codecs")
-
-                # Similarly for imageformats.
-                if self.prefix(src="../packages/plugins/imageformats/", dst="llplugin/imageformats"):
-                    self.path("libq*.dylib")
-                    self.end_prefix("llplugin/imageformats")
-
-                # SLPlugin plugins proper
+
+                # LLCefLib helper apps go inside SLPlugin.app
+                if self.prefix(src="", dst="SLPlugin.app/Contents/Frameworks"):
+                    for helperappfile in ('LLCefLib Helper.app',
+                                          'Chromium Embedded Framework.framework',  # TODO replace with symlink
+                                          'LLCefLib Helper EH.app'):
+                        self.path2basename(relpkgdir, helperappfile)
+                    self.end_prefix()
+
+                # SLPlugin plugins
                 if self.prefix(src="", dst="llplugin"):
                     self.path2basename("../media_plugins/quicktime/" + self.args['configuration'],
                                        "media_plugin_quicktime.dylib")
@@ -852,8 +831,18 @@ class Darwin_i386_Manifest(ViewerManifest):
 
                 self.end_prefix("Resources")
 
+                # CEF framework goes inside Second Life.app/Contents/Frameworks
+                if self.prefix(src="", dst="Frameworks"):
+                    frameworkfile="Chromium Embedded Framework.framework"
+                    self.path2basename(relpkgdir, frameworkfile)
+                    self.end_prefix("Frameworks")
+
             self.end_prefix("Contents")
 
+        # fix up media_plugin.dylib so it knows where to look for CEF files it needs
+        self.run_command('install_name_tool -change "@executable_path/Chromium Embedded Framework" "@executable_path/../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" "%(config)s/Second Life.app/Contents/Resources/llplugin/media_plugin_cef.dylib"' %
+                        { 'config' : self.args['configuration'] })
+
         # NOTE: the -S argument to strip causes it to keep enough info for
         # annotated backtraces (i.e. function names in the crash log).  'strip' with no
         # arguments yields a slightly smaller binary but makes crash logs mostly useless.
@@ -863,7 +852,6 @@ class Darwin_i386_Manifest(ViewerManifest):
             self.run_command('strip -S %(viewer_binary)r' %
                              { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')})
 
-
     def copy_finish(self):
         # Force executable permissions to be set for scripts
         # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802
-- 
cgit v1.2.3


From f97fb4d80f7e6f4b810e06457afbd65a16390adc Mon Sep 17 00:00:00 2001
From: Callum Prentice <callum@lindenlab.com>
Date: Thu, 18 Jun 2015 12:01:13 -0700
Subject: Add code in viewer_manifest.py to create a symlink for second copy of
 CEF framework vs copying in second version

---
 indra/newview/viewer_manifest.py | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 357124cfee..06deacee52 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -820,9 +820,11 @@ class Darwin_i386_Manifest(ViewerManifest):
                 # LLCefLib helper apps go inside SLPlugin.app
                 if self.prefix(src="", dst="SLPlugin.app/Contents/Frameworks"):
                     for helperappfile in ('LLCefLib Helper.app',
-                                          'Chromium Embedded Framework.framework',  # TODO replace with symlink
                                           'LLCefLib Helper EH.app'):
                         self.path2basename(relpkgdir, helperappfile)
+
+                    pluginframeworkpath = self.dst_path_of('Chromium Embedded Framework.framework');
+
                     self.end_prefix()
 
                 # SLPlugin plugins
@@ -841,6 +843,24 @@ class Darwin_i386_Manifest(ViewerManifest):
                     self.path2basename(relpkgdir, frameworkfile)
                     self.end_prefix("Frameworks")
 
+                # This code constructs a relative path from the
+                # target framework folder back to the location of the symlink.
+                # It needs to be relative so that the symlink still works when
+                # (as is normal) the user moves the app bunlde out of the DMG
+                # and into the /Applications folder. Note we also call 'raise'
+                # to terminate the process if we get an error since without
+                # this symlink, Second Life web media can't possibly work.
+                # Real Framework folder:
+                #   Second Life.app/Contents/Frameworks/Chromium Embedded Framework.framework/
+                # Location of symlink and why it'ds relavie 
+                #   Second Life.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework/
+                frameworkpath = os.path.join(os.pardir, os.pardir, os.pardir, os.pardir, "Frameworks", "Chromium Embedded Framework.framework")
+                try:
+                    symlinkf(frameworkpath, pluginframeworkpath)
+                except OSError as err:
+                    print "Can't symlink %s -> %s: %s" % (frameworkpath, pluginframeworkpath, err)
+                    raise
+
             self.end_prefix("Contents")
 
         # fix up media_plugin.dylib so it knows where to look for CEF files it needs
-- 
cgit v1.2.3


From c7842dda37b2c99f02818ff4adca7ad598d0d8ea Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 18 Jun 2015 18:56:01 -0400
Subject: Update llmanifest.LLManifest.copy_action() to handle symlinks for
 directories as well as for files.

---
 indra/lib/python/indra/util/llmanifest.py | 56 ++++++++++++++++---------------
 1 file changed, 29 insertions(+), 27 deletions(-)

(limited to 'indra')

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
-
-                shutil.copy2(src, dst)
+            self.ccopyfile(src, dst)
+            # XXX What about devices, sockets etc.?
+            # YYY would we put such things into a viewer package?!
+
+    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:
-- 
cgit v1.2.3


From d80a24803d0865e0bef13bc059b416eed548494d Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Mon, 22 Jun 2015 16:14:13 -0700
Subject: I can't believe I really added these lines - pretend you didn't see
 them

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 098dd67c0d..187c6a241d 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -34,8 +34,8 @@
 #include "llpluginmessageclasses.h"
 #include "media_plugin_base.h"
 
-#include "../../../build-darwin-i386/packages/include/boost/function.hpp"
-#include "../../../build-darwin-i386/packages/include/boost/bind.hpp"
+#include "boost/function.hpp"
+#include "boost/bind.hpp"
 #include "llCEFLib.h"
 
 #include <time.h>  // remove me
-- 
cgit v1.2.3


From f7908a50294adff3456436074075a677a9c6239b Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 30 Jun 2015 00:07:58 +0100
Subject: Point to new version of LLCefLib with support for second life URLs,
 version string, navigation commands

---
 indra/media_plugins/cef/media_plugin_cef.cpp   | 143 +++++++++++++++++++++----
 indra/newview/llappviewer.cpp                  |   5 +-
 indra/newview/skins/default/xui/en/strings.xml |   2 +-
 3 files changed, 127 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 187c6a241d..3b82071ae8 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -38,8 +38,6 @@
 #include "boost/bind.hpp"
 #include "llCEFLib.h"
 
-#include <time.h>  // remove me
-
 ////////////////////////////////////////////////////////////////////////////////
 //
 class MediaPluginCEF :
@@ -55,19 +53,15 @@ public:
 private:
 	bool init();
 
-	// TODO FIX ME
-	void pageChangedCallback(unsigned char* pixels, int width, int height)
-	{
-		if (mPixels && pixels)
-		{
-			if (mWidth == width && mHeight == height)
-			{
-				memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
-			}
-			setDirty(0, 0, mWidth, mHeight);
-		}
-	}
-
+	void pageChangedCallback(unsigned char* pixels, int width, int height);
+	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 onLoadEndCallback(int httpStatusCode);
+	void onNavigateURLCallback(std::string url);
+
 	void postDebugMessage(const std::string& msg);
 
 	bool mEnableMediaPluginDebugging;
@@ -99,7 +93,7 @@ MediaPluginCEF::~MediaPluginCEF()
 //
 void MediaPluginCEF::postDebugMessage(const std::string& msg)
 {
-	//if (mEnableMediaPluginDebugging)
+	if (mEnableMediaPluginDebugging)
 	{
 		std::stringstream str;
 		str << "@Media Msg> " << msg;
@@ -111,6 +105,89 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg)
 	}
 }
 
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::pageChangedCallback(unsigned char* pixels, int width, int height)
+{
+	if (mPixels && pixels)
+	{
+		if (mWidth == width && mHeight == height)
+		{
+			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
+		}
+		setDirty(0, 0, mWidth, mHeight);
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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::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::onNavigateURLCallback(std::string url)
+{
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
+	message.setValue("uri", url);
+	sendMessage(message);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 void MediaPluginCEF::receiveMessage(const char* message_string)
@@ -133,7 +210,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
 				message.setValueLLSD("versions", versions);
 
-				std::string plugin_version = "Example plugin 1.0..0";
+				std::string plugin_version = "CEF plugin 1.0.0";
 				message.setValue("plugin_version", plugin_version);
 				sendMessage(message);
 			}
@@ -186,8 +263,15 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 		{
 			if (message_name == "init")
 			{
-
+				// event callbacks from LLCefLib
 				mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3));
+				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->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1));
 
 	            LLCEFLibSettings settings;
 	            settings.inital_width = 1024;
@@ -197,6 +281,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				bool result = mLLCEFLib->init(settings);
 				if (!result)
 				{
+// TODO - return something to indicate failure
 					//MessageBoxA(0, "FAIL INIT", 0, 0);
 				}
 
@@ -332,6 +417,26 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
 			}
 		}
+		else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
+		{
+			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
 		{
 			//std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
@@ -344,7 +449,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 bool MediaPluginCEF::init()
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
-	message.setValue("name", "Example Plugin");
+	message.setValue("name", "CEF Plugin");
 	sendMessage(message);
 
 	return true;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6dc71bc94e..d2b9259ef7 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -123,6 +123,7 @@
 #include "llleap.h"
 #include "stringize.h"
 #include "llcoros.h"
+#include "cef/llceflib.h"
 
 // Third party library includes
 #include <boost/bind.hpp>
@@ -130,7 +131,6 @@
 #include <boost/algorithm/string.hpp>
 #include <boost/regex.hpp>
 
-
 #if LL_WINDOWS
 #	include <share.h> // For _SH_DENYWR in processMarkerFiles
 #else
@@ -3369,8 +3369,7 @@ 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)";
+	info["LLCEFLIB_VERSION"] = LLCEFLIB_VERSION;
 
 	S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN);
 	if (packets_in > 0)
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f77678e5f8..d6ac91e45f 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -50,7 +50,7 @@ OpenGL Version: [OPENGL_VERSION]
 libcurl Version: [LIBCURL_VERSION]
 J2C Decoder Version: [J2C_VERSION]
 Audio Driver Version: [AUDIO_DRIVER_VERSION]
-Qt Webkit Version: [QT_WEBKIT_VERSION]
+LLCEFLib/CEF Version: [LLCEFLIB_VERSION]
 Voice Server Version: [VOICE_VERSION]
 	</string>
 	<string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string>
-- 
cgit v1.2.3


From d89b4109f9ac3f1ef95480823df292bbc8200347 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 2 Jul 2015 09:39:41 -0700
Subject: 2015 and we still care about line endings.. sigh

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 100 ++++++++++++++-------------
 1 file changed, 53 insertions(+), 47 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 3b82071ae8..358b35bbe2 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -53,15 +53,15 @@ public:
 private:
 	bool init();
 
-	void pageChangedCallback(unsigned char* pixels, int width, int height);
-	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 onLoadEndCallback(int httpStatusCode);
-	void onNavigateURLCallback(std::string url);
-
+	void pageChangedCallback(unsigned char* pixels, int width, int height);
+	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 onLoadEndCallback(int httpStatusCode);
+	void onNavigateURLCallback(std::string url);
+
 	void postDebugMessage(const std::string& msg);
 
 	bool mEnableMediaPluginDebugging;
@@ -123,10 +123,10 @@ void MediaPluginCEF::pageChangedCallback(unsigned char* pixels, int width, int h
 //
 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);
+	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);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -142,8 +142,8 @@ void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string s
 //
 void MediaPluginCEF::onStatusMessageCallback(std::string value)
 {
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
-	message.setValue("status", value);
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
+	message.setValue("status", value);
 	sendMessage(message);
 }
 
@@ -151,19 +151,19 @@ void MediaPluginCEF::onStatusMessageCallback(std::string value)
 //
 void MediaPluginCEF::onTitleChangeCallback(std::string title)
 {
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
-	message.setValue("name", title);
-	sendMessage(message);
+	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());
+	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);
 }
 
@@ -171,11 +171,11 @@ void MediaPluginCEF::onLoadStartCallback()
 //
 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());
+	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);
 }
 
@@ -183,9 +183,9 @@ void MediaPluginCEF::onLoadEndCallback(int httpStatusCode)
 //
 void MediaPluginCEF::onNavigateURLCallback(std::string url)
 {
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
-	message.setValue("uri", url);
-	sendMessage(message);
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
+	message.setValue("uri", url);
+	sendMessage(message);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -419,23 +419,28 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 		}
 		else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
 		{
-			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();
-			}
+			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
 		{
@@ -468,3 +473,4 @@ int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func,
 
 	return 0;
 }
+
-- 
cgit v1.2.3


From adb0706aa0f3778fda9921172eaabefd3177dbdc Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 2 Jul 2015 23:56:19 +0100
Subject: plugin and llceflib code for improved mouse support

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 358b35bbe2..ccb8a93f87 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -339,26 +339,35 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			else if (message_name == "mouse_event")
 			{
 				std::string event = message_in.getValue("event");
-				//S32 button = message_in.getValueS32("button");
+				
 				S32 x = message_in.getValueS32("x");
 				S32 y = message_in.getValueS32("y");
 
 				//std::string modifiers = message_in.getValue("modifiers");
 
+				S32 button = message_in.getValueS32("button");
+				EMouseButton btn = MB_MOUSE_BUTTON_LEFT;
+				if (button == 0) btn = MB_MOUSE_BUTTON_LEFT;
+				if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT;
+				if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE;
+
 				if (event == "down")
 				{
-					mLLCEFLib->mouseButton(0, true, x, y);
-					mLLCEFLib->setFocus(true);
+					mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y);
 					std::stringstream str;
 					str << "Mouse down at = " << x << ", " << y;
 					postDebugMessage(str.str());
 				}
 				else if (event == "up")
 				{
-					mLLCEFLib->mouseButton(0, false, x, y);
+					mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y);
+					std::stringstream str;
+					str << "Mouse up at = " << x << ", " << y;
+					postDebugMessage(str.str());
 				}
 				else if (event == "double_click")
 				{
+					// TODO: do we need this ?
 				}
 				else
 				{
-- 
cgit v1.2.3


From ca49ad736a06aa796610f068f6419c39b8535251 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Fri, 10 Jul 2015 01:01:07 +0100
Subject: Initial support for keyboard (in progress) but includes many viewer
 changes to plumb in Key Up events

---
 indra/llui/llfocusmgr.cpp                    |   6 +
 indra/llui/llfocusmgr.h                      |   1 +
 indra/llui/llview.cpp                        |  46 +++++++
 indra/llui/llview.h                          |   3 +
 indra/media_plugins/cef/media_plugin_cef.cpp | 189 +++++++++++++++++++++++----
 indra/newview/llmediactrl.cpp                |  27 +++-
 indra/newview/llmediactrl.h                  |   3 +-
 indra/newview/llviewerkeyboard.cpp           |   5 +-
 indra/newview/llviewerkeyboard.h             |   1 +
 indra/newview/llviewermedia.cpp              |  41 ++++--
 indra/newview/llviewermedia.h                |   1 +
 indra/newview/llviewermediafocus.cpp         |   7 +
 indra/newview/llviewermediafocus.h           |   1 +
 indra/newview/llviewerwindow.cpp             |  38 +++++-
 indra/newview/llviewerwindow.h               |   3 +-
 15 files changed, 324 insertions(+), 48 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 547f0bd398..fb811452be 100755
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -46,6 +46,12 @@ 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)
 {
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index afd2a8ce06..950ac55325 100755
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -57,6 +57,7 @@ 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);
 
 	virtual void	onTopLost();	// called when registered as top ctrl and user clicks elsewhere
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index a8beb9cfc9..8f7cac1f61 100755
--- 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 100755
--- 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/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index ccb8a93f87..f4ffd6d634 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -27,6 +27,7 @@
 */
 
 #include "linden_common.h"
+#include "indra_constants.h" // for indra keyboard codes
 
 #include "llgl.h"
 #include "llplugininstance.h"
@@ -64,6 +65,12 @@ private:
 
 	void postDebugMessage(const std::string& msg);
 
+
+	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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data);
+	void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data);
+
 	bool mEnableMediaPluginDebugging;
 	LLCEFLib* mLLCEFLib;
 };
@@ -273,15 +280,15 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1));
 				mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1));
 
-	            LLCEFLibSettings settings;
-	            settings.inital_width = 1024;
-	            settings.inital_height = 1024;
-	            settings.javascript_enabled = true;
-	            settings.cookies_enabled = true;
+				LLCEFLibSettings settings;
+				settings.inital_width = 1024;
+				settings.inital_height = 1024;
+				settings.javascript_enabled = true;
+				settings.cookies_enabled = true;
 				bool result = mLLCEFLib->init(settings);
 				if (!result)
 				{
-// TODO - return something to indicate failure
+					// TODO - return something to indicate failure
 					//MessageBoxA(0, "FAIL INIT", 0, 0);
 				}
 
@@ -339,7 +346,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			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");
 
@@ -354,6 +361,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				if (event == "down")
 				{
 					mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y);
+					mLLCEFLib->setFocus(true);
+
 					std::stringstream str;
 					str << "Mouse down at = " << x << ", " << y;
 					postDebugMessage(str.str());
@@ -361,6 +370,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				else if (event == "up")
 				{
 					mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y);
+
 					std::stringstream str;
 					str << "Mouse up at = " << x << ", " << y;
 					postDebugMessage(str.str());
@@ -384,42 +394,31 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			}
 			else if (message_name == "text_event")
 			{
-				std::string event = message_in.getValue("event");
-				S32 key = message_in.getValue("text")[0];
+				std::string text = message_in.getValue("text");
 				std::string modifiers = message_in.getValue("modifiers");
 				LLSD native_key_data = message_in.getValueLLSD("native_key_data");
 
-				//int native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
-
-				//if (event == "down")
-				{
-					mLLCEFLib->keyPress(key, true);
-				}
-				//else
-				//if (event == "up")
-				{
-					mLLCEFLib->keyPress(key, false);
-				}
+				unicodeInput(text, decodeModifiers(modifiers), native_key_data);
 			}
 			else if (message_name == "key_event")
 			{
 				std::string event = message_in.getValue("event");
-				//S32 key = message_in.getValueS32("key");
+				S32 key = message_in.getValueS32("key");
 				std::string modifiers = message_in.getValue("modifiers");
 				LLSD native_key_data = message_in.getValueLLSD("native_key_data");
 
-				int native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
-				native_scan_code = 8;
-
+				// Treat unknown events as key-up for safety.
+				EKeyEvent key_event = KE_KEY_UP;
 				if (event == "down")
 				{
-					mLLCEFLib->keyPress(native_scan_code, true);
+					key_event = KE_KEY_DOWN;
 				}
-				else
-				if (event == "up")
+				else if (event == "repeat")
 				{
-					mLLCEFLib->keyPress(native_scan_code, false);
+					key_event = KE_KEY_REPEAT;
 				}
+
+				keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
 			}
 			else if (message_name == "enable_media_plugin_debugging")
 			{
@@ -458,6 +457,140 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 	}
 }
 
+EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
+{
+	int result = 0;
+
+	if (modifiers.find("shift") != std::string::npos)
+		result |= KM_MODIFIER_SHIFT;
+
+	if (modifiers.find("alt") != std::string::npos)
+		result |= KM_MODIFIER_ALT;
+
+	if (modifiers.find("control") != std::string::npos)
+		result |= KM_MODIFIER_CONTROL;
+
+	if (modifiers.find("meta") != std::string::npos)
+		result |= KM_MODIFIER_META;
+
+	return (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(EKeyEvent key_event, int key, 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 < 128)
+	{
+		// 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 KEY_BACKSPACE:		utf8_text = (char)8;		break;
+		case KEY_TAB:			utf8_text = (char)9;		break;
+		case KEY_RETURN:		utf8_text = (char)13;		break;
+		case KEY_PAD_RETURN:	utf8_text = (char)13;		break;
+		case KEY_ESCAPE:		utf8_text = (char)27;		break;
+
+	default:
+		break;
+	}
+
+	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);
+
+	//std::stringstream str;
+	//str << "@@@@@ KEYBOARD EVENT native_modifiers = " << native_modifiers;
+	//postDebugMessage(str.str());
+
+	mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
+
+
+	std::stringstream str;
+	str << "@@@@@@@@@@@@@@@@ MediaPluginCEF::keyEvent";
+	postDebugMessage(str.str());
+
+	//uint32_t msg = native_key_data["msg"].asInteger();
+	//uint32_t wparam = native_key_data["w_param"].asInteger();
+	//uint64_t lparam = native_key_data["l_param"].asInteger();
+
+	//std::stringstream str;
+	//str << "@@@@@@@@@@@@@@@@ keyEvent Native message" << msg << ", " << wparam << ", " << lparam;
+	//postDebugMessage(str.str());
+
+	//mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
+
+
+	//checkEditState();
+};
+
+void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+{
+	uint32_t key = KEY_NONE;
+
+	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);
+
+	std::stringstream str;
+	str << "@@@@@@@@@@@@@@@@ MediaPluginCEF::unicodeInput";
+	postDebugMessage(str.str());
+
+	//uint32_t msg = native_key_data["msg"].asInteger();
+	//uint32_t wparam = native_key_data["w_param"].asInteger();
+	//uint64_t lparam = native_key_data["l_param"].asInteger();
+
+	//std::stringstream str;
+	//str << "@@@@@@@@@@@@@@@@ unicodeInput Native message" << msg << ", " << wparam << ", " << lparam;
+	//postDebugMessage(str.str());
+
+	//mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
+
+	mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
+	mLLCEFLib->keyboardEvent(KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
+
+	//	checkEditState();
+};
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 bool MediaPluginCEF::init()
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index b96bdd73ff..d1bb799015 100755
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -410,18 +410,35 @@ void LLMediaCtrl::onOpenWebInspector()
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
+BOOL LLMediaCtrl::handleKeyHere(KEY key, MASK mask)
 {
 	BOOL result = FALSE;
-	
+
 	if (mMediaSource)
 	{
 		result = mMediaSource->handleKeyHere(key, mask);
 	}
-	
-	if ( ! result )
+
+	if (!result)
 		result = LLPanel::handleKeyHere(key, 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;
 }
 
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 785c57b78a..469ff38ee6 100755
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -150,7 +150,8 @@ public:
 		void setTrustedContent(bool trusted);
 
 		// over-rides
-		virtual BOOL handleKeyHere( KEY key, MASK mask);
+		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);
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index ada829eb4b..1ab672aafc 100755
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -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 100755
--- 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 aa4943b8e8..60a5f99e19 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -2698,27 +2698,48 @@ 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);
+			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;
 }
 
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 6803adfaa2..f2da30e10b 100755
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -238,6 +238,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..1265ca0a70 100755
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -352,6 +352,13 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)
 	return true;
 }
 
+BOOL LLViewerMediaFocus::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
+{
+	return true;
+}
+
+
+
 BOOL LLViewerMediaFocus::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
 {
 	LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
index f03dd8751e..42c841df15 100755
--- 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);
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e317989f04..ed4acfddc4 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1399,10 +1399,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);
@@ -2542,6 +2541,41 @@ void LLViewerWindow::draw()
 //#endif
 }
 
+// Takes a single keydown event, usually when UI is visible
+BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
+{
+	if (gFocusMgr.getKeyboardFocus()
+		&& !(mask & (MASK_CONTROL | MASK_ALT))
+		&& !gFocusMgr.getKeystrokesOnly())
+	{
+		// We have keyboard focus, and it's not an accelerator
+		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);
+		}
+	}
+
+	LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+	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)
 {
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 7fde52d4e1..dac6328eaa 100755
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -314,7 +314,8 @@ public:
 	LLView*			getHintHolder() { return mHintHolder.get(); }
 	LLView*			getLoginPanelHolder() { return mLoginPanelHolder.get(); }
 	BOOL			handleKey(KEY key, MASK mask);
-	void			handleScrollWheel	(S32 clicks);
+	BOOL			handleKeyUp(KEY key, MASK mask);
+	void			handleScrollWheel(S32 clicks);
 
 	// add and remove views from "popup" layer
 	void			addPopup(LLView* popup);
-- 
cgit v1.2.3


From 83a9ae7b3c66e87179362f0da9fa7a378b1527e2 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 15 Jul 2015 02:27:33 +0100
Subject: New keyboard code for windows that uses system messages directly and
 works ok.  Points to new LLCEFLib

---
 indra/llwindow/llwindowwin32.cpp             | 13 ++++
 indra/llwindow/llwindowwin32.h               |  3 +
 indra/media_plugins/cef/media_plugin_cef.cpp | 90 +++-------------------------
 3 files changed, 25 insertions(+), 81 deletions(-)

(limited to 'indra')

diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index cd2be87fad..7503d95263 100755
--- 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
@@ -3238,6 +3248,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..376bef3e50 100755
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -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/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index f4ffd6d634..c1724fba3e 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -30,6 +30,7 @@
 #include "indra_constants.h" // for indra keyboard codes
 
 #include "llgl.h"
+#include "llsdutil.h"
 #include "llplugininstance.h"
 #include "llpluginmessage.h"
 #include "llpluginmessageclasses.h"
@@ -502,93 +503,20 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat
 //
 void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, 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;
+	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"]);
 
-	if (key < 128)
-	{
-		// 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 KEY_BACKSPACE:		utf8_text = (char)8;		break;
-		case KEY_TAB:			utf8_text = (char)9;		break;
-		case KEY_RETURN:		utf8_text = (char)13;		break;
-		case KEY_PAD_RETURN:	utf8_text = (char)13;		break;
-		case KEY_ESCAPE:		utf8_text = (char)27;		break;
-
-	default:
-		break;
-	}
-
-	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);
-
-	//std::stringstream str;
-	//str << "@@@@@ KEYBOARD EVENT native_modifiers = " << native_modifiers;
-	//postDebugMessage(str.str());
-
-	mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
-
-
-	std::stringstream str;
-	str << "@@@@@@@@@@@@@@@@ MediaPluginCEF::keyEvent";
-	postDebugMessage(str.str());
-
-	//uint32_t msg = native_key_data["msg"].asInteger();
-	//uint32_t wparam = native_key_data["w_param"].asInteger();
-	//uint64_t lparam = native_key_data["l_param"].asInteger();
-
-	//std::stringstream str;
-	//str << "@@@@@@@@@@@@@@@@ keyEvent Native message" << msg << ", " << wparam << ", " << lparam;
-	//postDebugMessage(str.str());
-
-	//mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
-
-
-	//checkEditState();
+	mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
 };
 
 void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
 {
-	uint32_t key = KEY_NONE;
-
-	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);
-
-	std::stringstream str;
-	str << "@@@@@@@@@@@@@@@@ MediaPluginCEF::unicodeInput";
-	postDebugMessage(str.str());
-
-	//uint32_t msg = native_key_data["msg"].asInteger();
-	//uint32_t wparam = native_key_data["w_param"].asInteger();
-	//uint64_t lparam = native_key_data["l_param"].asInteger();
-
-	//std::stringstream str;
-	//str << "@@@@@@@@@@@@@@@@ unicodeInput Native message" << msg << ", " << wparam << ", " << lparam;
-	//postDebugMessage(str.str());
-
-	//mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
-
-	mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
-	mLLCEFLib->keyboardEvent(KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
+	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"]);
 
-	//	checkEditState();
+	mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
 };
 
 ////////////////////////////////////////////////////////////////////////////////
-- 
cgit v1.2.3


From 224cfc6ec0624561d433afe8a38598f132def913 Mon Sep 17 00:00:00 2001
From: callum <none@none>
Date: Wed, 15 Jul 2015 18:43:57 -0700
Subject: Still making small changes to try to fix OS X keyboards

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 53 ++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index c1724fba3e..f07eef28f4 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -403,6 +403,20 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			}
 			else if (message_name == "key_event")
 			{
+#if LL_DARWIN
+				std::string event = message_in.getValue("event");
+				S32 key = message_in.getValueS32("key");
+				if (event == "down")
+				{
+					mLLCEFLib->keyPress(key, true);
+				}
+				else if (event == "up")
+				{
+					mLLCEFLib->keyPress(key, false);
+				}
+
+#elif LL_WINDOWS
+
 				std::string event = message_in.getValue("event");
 				S32 key = message_in.getValueS32("key");
 				std::string modifiers = message_in.getValue("modifiers");
@@ -420,6 +434,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				}
 
 				keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
+
+#endif
+
 			}
 			else if (message_name == "enable_media_plugin_debugging")
 			{
@@ -495,7 +512,7 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat
 		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 
+#endif
 	};
 };
 
@@ -503,20 +520,50 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat
 //
 void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
 {
+#if LL_DARWIN
+	std::string utf8_text;
+
+	if (key < 128)
+	{
+		utf8_text = (char)key;
+	}
+
+	switch ((KEY)key)
+	{
+		case KEY_BACKSPACE:		utf8_text = (char)8;		break;
+		case KEY_TAB:			utf8_text = (char)9;		break;
+		case KEY_RETURN:		utf8_text = (char)13;		break;
+		case KEY_PAD_RETURN:	utf8_text = (char)13;		break;
+		case KEY_ESCAPE:		utf8_text = (char)27;		break;
+
+	default:
+		break;
+	}
+
+	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);
+
+	mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
+#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, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
 {
+#if LL_DARWIN
+	mLLCEFLib->keyPress(utf8str[0], true);
+#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
 };
 
 ////////////////////////////////////////////////////////////////////////////////
-- 
cgit v1.2.3


From 0d6d281cb3c54b08eb845199ba24992bddcf9bae Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 16 Jul 2015 16:11:19 -0700
Subject: Point to LLCEFLib with updated 2357 version and support for setting
 language for embedded browser

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 1193 +++++++++++++-------------
 indra/newview/viewer_manifest.py             |    6 +-
 2 files changed, 604 insertions(+), 595 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index f07eef28f4..70a8eb5d9b 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -1,593 +1,600 @@
-/**
-* @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"
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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 pageChangedCallback(unsigned char* pixels, int width, int height);
-	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 onLoadEndCallback(int httpStatusCode);
-	void onNavigateURLCallback(std::string url);
-
-	void postDebugMessage(const std::string& msg);
-
-
-	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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data);
-	void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data);
-
-	bool mEnableMediaPluginDebugging;
-	LLCEFLib* mLLCEFLib;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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;
-
-	mLLCEFLib = new LLCEFLib();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-MediaPluginCEF::~MediaPluginCEF()
-{
-	mLLCEFLib->reset();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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::pageChangedCallback(unsigned char* pixels, int width, int height)
-{
-	if (mPixels && pixels)
-	{
-		if (mWidth == width && mHeight == height)
-		{
-			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
-		}
-		setDirty(0, 0, mWidth, mHeight);
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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::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::onNavigateURLCallback(std::string url)
-{
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
-	message.setValue("uri", url);
-	sendMessage(message);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void MediaPluginCEF::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 = "CEF plugin 1.0.0";
-				message.setValue("plugin_version", plugin_version);
-				sendMessage(message);
-			}
-			else if (message_name == "idle")
-			{
-				mLLCEFLib->update();
-			}
-			else if (message_name == "cleanup")
-			{
-			}
-			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
-				{
-					//std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
-				}
-
-				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)
-		{
-			if (message_name == "init")
-			{
-				// event callbacks from LLCefLib
-				mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3));
-				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->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1));
-
-				LLCEFLibSettings settings;
-				settings.inital_width = 1024;
-				settings.inital_height = 1024;
-				settings.javascript_enabled = true;
-				settings.cookies_enabled = true;
-				bool result = mLLCEFLib->init(settings);
-				if (!result)
-				{
-					// TODO - return something to indicate failure
-					//MessageBoxA(0, "FAIL INIT", 0, 0);
-				}
-
-				// 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", false);
-				sendMessage(message);
-			}
-			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 == "load_uri")
-			{
-				std::string uri = message_in.getValue("uri");
-				mLLCEFLib->navigate(uri);
-			}
-			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");
-
-				//std::string modifiers = message_in.getValue("modifiers");
-
-				S32 button = message_in.getValueS32("button");
-				EMouseButton btn = MB_MOUSE_BUTTON_LEFT;
-				if (button == 0) btn = MB_MOUSE_BUTTON_LEFT;
-				if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT;
-				if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE;
-
-				if (event == "down")
-				{
-					mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y);
-					mLLCEFLib->setFocus(true);
-
-					std::stringstream str;
-					str << "Mouse down at = " << x << ", " << y;
-					postDebugMessage(str.str());
-				}
-				else if (event == "up")
-				{
-					mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y);
-
-					std::stringstream str;
-					str << "Mouse up at = " << x << ", " << y;
-					postDebugMessage(str.str());
-				}
-				else if (event == "double_click")
-				{
-					// TODO: do we need this ?
-				}
-				else
-				{
-					mLLCEFLib->mouseMove(x, y);
-				}
-			}
-			else if (message_name == "scroll_event")
-			{
-				S32 y = message_in.getValueS32("y");
-				const int scaling_factor = 40;
-				y *= -scaling_factor;
-
-				mLLCEFLib->mouseWheel(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");
-				if (event == "down")
-				{
-					mLLCEFLib->keyPress(key, true);
-				}
-				else if (event == "up")
-				{
-					mLLCEFLib->keyPress(key, false);
-				}
-
-#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.
-				EKeyEvent key_event = KE_KEY_UP;
-				if (event == "down")
-				{
-					key_event = KE_KEY_DOWN;
-				}
-				else if (event == "repeat")
-				{
-					key_event = 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");
-			}
-		}
-		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
-		{
-			//std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
-		};
-	}
-}
-
-EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
-{
-	int result = 0;
-
-	if (modifiers.find("shift") != std::string::npos)
-		result |= KM_MODIFIER_SHIFT;
-
-	if (modifiers.find("alt") != std::string::npos)
-		result |= KM_MODIFIER_ALT;
-
-	if (modifiers.find("control") != std::string::npos)
-		result |= KM_MODIFIER_CONTROL;
-
-	if (modifiers.find("meta") != std::string::npos)
-		result |= KM_MODIFIER_META;
-
-	return (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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
-{
-#if LL_DARWIN
-	std::string utf8_text;
-
-	if (key < 128)
-	{
-		utf8_text = (char)key;
-	}
-
-	switch ((KEY)key)
-	{
-		case KEY_BACKSPACE:		utf8_text = (char)8;		break;
-		case KEY_TAB:			utf8_text = (char)9;		break;
-		case KEY_RETURN:		utf8_text = (char)13;		break;
-		case KEY_PAD_RETURN:	utf8_text = (char)13;		break;
-		case KEY_ESCAPE:		utf8_text = (char)27;		break;
-
-	default:
-		break;
-	}
-
-	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);
-
-	mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
-#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, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
-{
-#if LL_DARWIN
-	mLLCEFLib->keyPress(utf8str[0], true);
-#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
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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;
-}
-
+/**
+* @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"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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 pageChangedCallback(unsigned char* pixels, int width, int height);
+	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 onLoadEndCallback(int httpStatusCode);
+	void onNavigateURLCallback(std::string url);
+
+	void postDebugMessage(const std::string& msg);
+
+
+	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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data);
+	void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data);
+
+	bool mEnableMediaPluginDebugging;
+	std::string mHostLanguage;
+	LLCEFLib* mLLCEFLib;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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";
+
+	mLLCEFLib = new LLCEFLib();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+MediaPluginCEF::~MediaPluginCEF()
+{
+	mLLCEFLib->reset();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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::pageChangedCallback(unsigned char* pixels, int width, int height)
+{
+	if (mPixels && pixels)
+	{
+		if (mWidth == width && mHeight == height)
+		{
+			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
+		}
+		setDirty(0, 0, mWidth, mHeight);
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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::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::onNavigateURLCallback(std::string url)
+{
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
+	message.setValue("uri", url);
+	sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::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 = "CEF plugin 1.0.0";
+				message.setValue("plugin_version", plugin_version);
+				sendMessage(message);
+			}
+			else if (message_name == "idle")
+			{
+				mLLCEFLib->update();
+			}
+			else if (message_name == "cleanup")
+			{
+			}
+			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
+				{
+					//std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
+				}
+
+				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)
+		{
+			if (message_name == "init")
+			{
+				// event callbacks from LLCefLib
+				mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3));
+				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->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1));
+
+				LLCEFLibSettings settings;
+				settings.inital_width = 1024;
+				settings.inital_height = 1024;
+				settings.javascript_enabled = true;
+				settings.cookies_enabled = true;
+				settings.accept_language_list = mHostLanguage;
+				bool result = mLLCEFLib->init(settings);
+				if (!result)
+				{
+					// TODO - return something to indicate failure
+					//MessageBoxA(0, "FAIL INIT", 0, 0);
+				}
+
+				// 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", false);
+				sendMessage(message);
+			}
+			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 == "mouse_event")
+			{
+				std::string event = message_in.getValue("event");
+
+				S32 x = message_in.getValueS32("x");
+				S32 y = message_in.getValueS32("y");
+
+				//std::string modifiers = message_in.getValue("modifiers");
+
+				S32 button = message_in.getValueS32("button");
+				EMouseButton btn = MB_MOUSE_BUTTON_LEFT;
+				if (button == 0) btn = MB_MOUSE_BUTTON_LEFT;
+				if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT;
+				if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE;
+
+				if (event == "down")
+				{
+					mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y);
+					mLLCEFLib->setFocus(true);
+
+					std::stringstream str;
+					str << "Mouse down at = " << x << ", " << y;
+					postDebugMessage(str.str());
+				}
+				else if (event == "up")
+				{
+					mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y);
+
+					std::stringstream str;
+					str << "Mouse up at = " << x << ", " << y;
+					postDebugMessage(str.str());
+				}
+				else if (event == "double_click")
+				{
+					// TODO: do we need this ?
+				}
+				else
+				{
+					mLLCEFLib->mouseMove(x, y);
+				}
+			}
+			else if (message_name == "scroll_event")
+			{
+				S32 y = message_in.getValueS32("y");
+				const int scaling_factor = 40;
+				y *= -scaling_factor;
+
+				mLLCEFLib->mouseWheel(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");
+				if (event == "down")
+				{
+					mLLCEFLib->keyPress(key, true);
+				}
+				else if (event == "up")
+				{
+					mLLCEFLib->keyPress(key, false);
+				}
+
+#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.
+				EKeyEvent key_event = KE_KEY_UP;
+				if (event == "down")
+				{
+					key_event = KE_KEY_DOWN;
+				}
+				else if (event == "repeat")
+				{
+					key_event = 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");
+			}
+		}
+		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
+		{
+			//std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
+		};
+	}
+}
+
+EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
+{
+	int result = 0;
+
+	if (modifiers.find("shift") != std::string::npos)
+		result |= KM_MODIFIER_SHIFT;
+
+	if (modifiers.find("alt") != std::string::npos)
+		result |= KM_MODIFIER_ALT;
+
+	if (modifiers.find("control") != std::string::npos)
+		result |= KM_MODIFIER_CONTROL;
+
+	if (modifiers.find("meta") != std::string::npos)
+		result |= KM_MODIFIER_META;
+
+	return (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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+{
+#if LL_DARWIN
+	std::string utf8_text;
+
+	if (key < 128)
+	{
+		utf8_text = (char)key;
+	}
+
+	switch ((KEY)key)
+	{
+		case KEY_BACKSPACE:		utf8_text = (char)8;		break;
+		case KEY_TAB:			utf8_text = (char)9;		break;
+		case KEY_RETURN:		utf8_text = (char)13;		break;
+		case KEY_PAD_RETURN:	utf8_text = (char)13;		break;
+		case KEY_ESCAPE:		utf8_text = (char)27;		break;
+
+	default:
+		break;
+	}
+
+	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);
+
+	mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
+#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, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+{
+#if LL_DARWIN
+	mLLCEFLib->keyPress(utf8str[0], true);
+#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
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 06deacee52..ad8a236f92 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -452,7 +452,8 @@ class Windows_i686_Manifest(ViewerManifest):
                 self.path("libEGL.dll")
                 self.path("libGLESv2.dll")
                 self.path("llceflib_host.exe")
-                self.path("pdf.dll")
+                self.path("natives_blob.bin")
+                self.path("snapshot_blob.bin")
                 self.path("wow_helper.exe")
                 self.end_prefix()
         else:
@@ -465,7 +466,8 @@ class Windows_i686_Manifest(ViewerManifest):
                 self.path("libEGL.dll")
                 self.path("libGLESv2.dll")
                 self.path("llceflib_host.exe")
-                self.path("pdf.dll")
+                self.path("natives_blob.bin")
+                self.path("snapshot_blob.bin")
                 self.path("wow_helper.exe")
                 self.end_prefix()
 
-- 
cgit v1.2.3


From 8e3acf461e3f3536b621a533d6ab15bc9e0a36be Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Fri, 17 Jul 2015 16:14:42 -0700
Subject: Changes to implement enable/disable cookies, javascript, plugins

---
 indra/llplugin/llpluginclassmedia.cpp        |  6 ++---
 indra/media_plugins/cef/media_plugin_cef.cpp | 34 +++++++++++++++++++++-------
 2 files changed, 29 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 52626b0302..f0c547c8d1 100755
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -828,14 +828,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);
 }
@@ -1266,7 +1266,7 @@ void LLPluginClassMedia::set_cookies(const std::string &cookies)
 
 void LLPluginClassMedia::enable_cookies(bool enable)
 {
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies");
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookies_enabled");
 	message.setValueBoolean("enable", enable);
 	sendMessage(message);
 }
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 70a8eb5d9b..4bde7e7d49 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -74,6 +74,9 @@ private:
 
 	bool mEnableMediaPluginDebugging;
 	std::string mHostLanguage;
+	bool mCookiesEnabled;
+	bool mPluginsEnabled;
+	bool mJavascriptEnabled;
 	LLCEFLib* mLLCEFLib;
 };
 
@@ -88,7 +91,9 @@ MediaPluginBase(host_send_func, host_user_data)
 	mPixels = 0;
 	mEnableMediaPluginDebugging = true;
 	mHostLanguage = "en";
-
+	mCookiesEnabled = true;
+	mPluginsEnabled = false;
+	mJavascriptEnabled = true;
 	mLLCEFLib = new LLCEFLib();
 }
 
@@ -286,14 +291,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				LLCEFLibSettings settings;
 				settings.inital_width = 1024;
 				settings.inital_height = 1024;
-				settings.javascript_enabled = true;
-				settings.cookies_enabled = true;
+				settings.plugins_enabled = mPluginsEnabled;
+				settings.javascript_enabled = mJavascriptEnabled;
+				settings.cookies_enabled = mCookiesEnabled;
 				settings.accept_language_list = mHostLanguage;
 				bool result = mLLCEFLib->init(settings);
 				if (!result)
 				{
-					// TODO - return something to indicate failure
-					//MessageBoxA(0, "FAIL INIT", 0, 0);
+					// if this fails, the media system in viewer will put up a message
 				}
 
 				// Plugin gets to decide the texture parameters to use.
@@ -423,7 +428,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				}
 
 #elif LL_WINDOWS
-
 				std::string event = message_in.getValue("event");
 				S32 key = message_in.getValueS32("key");
 				std::string modifiers = message_in.getValue("modifiers");
@@ -441,9 +445,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				}
 
 				keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
-
 #endif
-
 			}
 			else if (message_name == "enable_media_plugin_debugging")
 			{
@@ -474,6 +476,22 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			{
 				mLLCEFLib->goBack();
 			}
+			else if (message_name == "cookies_enabled")
+			{
+				mCookiesEnabled = message_in.getValueBoolean("enable");
+std::stringstream str;
+str << "@@@@@@@##### cookies_enabled - mCookiesEnabled = " << mCookiesEnabled;
+postDebugMessage(str.str());
+
+			}
+			else if (message_name == "plugins_enabled")
+			{
+				mPluginsEnabled = message_in.getValueBoolean("enable");
+			}
+			else if (message_name == "javascript_enabled")
+			{
+				mJavascriptEnabled = message_in.getValueBoolean("enable");
+			}
 		}
 		else
 		{
-- 
cgit v1.2.3


From 7cc5db9fdb19d8e798412295280fdf1d86cd0da8 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Fri, 24 Jul 2015 23:54:09 +0100
Subject: Include support for http auth.  also improve mouse handling with drag
 select

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 48 +++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 4bde7e7d49..56bb4e469b 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -52,6 +52,7 @@ public:
 	/*virtual*/
 	void receiveMessage(const char* message_string);
 
+
 private:
 	bool init();
 
@@ -63,9 +64,10 @@ private:
 	void onLoadStartCallback();
 	void onLoadEndCallback(int httpStatusCode);
 	void onNavigateURLCallback(std::string url);
+	bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
 
 	void postDebugMessage(const std::string& msg);
-
+	void authResponse(LLPluginMessage &message);
 
 	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);
@@ -77,6 +79,9 @@ private:
 	bool mCookiesEnabled;
 	bool mPluginsEnabled;
 	bool mJavascriptEnabled;
+	std::string mAuthUsername;
+	std::string mAuthPassword;
+	bool mAuthOK;
 	LLCEFLib* mLLCEFLib;
 };
 
@@ -94,6 +99,9 @@ MediaPluginBase(host_send_func, host_user_data)
 	mCookiesEnabled = true;
 	mPluginsEnabled = false;
 	mJavascriptEnabled = true;
+	mAuthUsername = "";
+	mAuthPassword = "";
+	mAuthOK = false;
 	mLLCEFLib = new LLCEFLib();
 }
 
@@ -203,6 +211,39 @@ void MediaPluginCEF::onNavigateURLCallback(std::string url)
 	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::authResponse(LLPluginMessage &message)
+{
+	mAuthOK = message.getValueBoolean("ok");
+	if (mAuthOK)
+	{
+		mAuthUsername = message.getValue("username");
+		mAuthPassword = message.getValue("password");
+	}
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 void MediaPluginCEF::receiveMessage(const char* message_string)
@@ -287,6 +328,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this));
 				mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1));
 				mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1));
+				mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));
 
 				LLCEFLibSettings settings;
 				settings.inital_width = 1024;
@@ -451,6 +493,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			{
 				mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
 			}
+			if (message_name == "auth_response")
+			{
+				authResponse(message_in);
+			}
 		}
 		else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
 		{
-- 
cgit v1.2.3


From a75a4e2a4f0b8bc65aa45368326fce0e6635c4ac Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Mon, 27 Jul 2015 16:09:04 -0700
Subject: Bring in lastest version of LLCEFLIb & set user agent string before
 browser instance created

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 1336 +++++++++++++-------------
 indra/newview/llviewermedia.cpp              |    3 +
 2 files changed, 677 insertions(+), 662 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 56bb4e469b..fcedc3355d 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -1,664 +1,676 @@
-/**
-* @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"
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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 pageChangedCallback(unsigned char* pixels, int width, int height);
-	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 onLoadEndCallback(int httpStatusCode);
-	void onNavigateURLCallback(std::string url);
-	bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
-
-	void postDebugMessage(const std::string& msg);
-	void authResponse(LLPluginMessage &message);
-
-	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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data);
-	void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data);
-
-	bool mEnableMediaPluginDebugging;
-	std::string mHostLanguage;
-	bool mCookiesEnabled;
-	bool mPluginsEnabled;
-	bool mJavascriptEnabled;
-	std::string mAuthUsername;
-	std::string mAuthPassword;
-	bool mAuthOK;
-	LLCEFLib* mLLCEFLib;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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;
-	mAuthUsername = "";
-	mAuthPassword = "";
-	mAuthOK = false;
-	mLLCEFLib = new LLCEFLib();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-MediaPluginCEF::~MediaPluginCEF()
-{
-	mLLCEFLib->reset();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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::pageChangedCallback(unsigned char* pixels, int width, int height)
-{
-	if (mPixels && pixels)
-	{
-		if (mWidth == width && mHeight == height)
-		{
-			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
-		}
-		setDirty(0, 0, mWidth, mHeight);
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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::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::onNavigateURLCallback(std::string url)
-{
-	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
-	message.setValue("uri", url);
-	sendMessage(message);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
+/**
+* @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"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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 width, int height);
+	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 onLoadEndCallback(int httpStatusCode);
+	void onNavigateURLCallback(std::string url);
+	bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
+
+	void postDebugMessage(const std::string& msg);
+	void authResponse(LLPluginMessage &message);
+
+	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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data);
+	void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data);
+
+	bool mEnableMediaPluginDebugging;
+	std::string mHostLanguage;
+	bool mCookiesEnabled;
+	bool mPluginsEnabled;
+	bool mJavascriptEnabled;
+	std::string mUserAgentSubtring;
+	std::string mAuthUsername;
+	std::string mAuthPassword;
+	bool mAuthOK;
+	LLCEFLib* mLLCEFLib;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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;
+	mLLCEFLib = new LLCEFLib();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+MediaPluginCEF::~MediaPluginCEF()
+{
+	mLLCEFLib->reset();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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 width, int height)
+{
+	if (mPixels && pixels)
+	{
+		if (mWidth == width && mHeight == height)
+		{
+			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
+		}
+		setDirty(0, 0, mWidth, mHeight);
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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::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::onNavigateURLCallback(std::string url)
+{
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
+	message.setValue("uri", url);
+	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::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 << "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 = "CEF plugin 1.0.0";
-				message.setValue("plugin_version", plugin_version);
-				sendMessage(message);
-			}
-			else if (message_name == "idle")
-			{
-				mLLCEFLib->update();
-			}
-			else if (message_name == "cleanup")
-			{
-			}
-			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
-				{
-					//std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
-				}
-
-				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)
-		{
-			if (message_name == "init")
-			{
-				// event callbacks from LLCefLib
-				mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3));
-				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->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1));
+{
+	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::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 << "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 = "CEF plugin 1.0.0";
+				message.setValue("plugin_version", plugin_version);
+				sendMessage(message);
+			}
+			else if (message_name == "idle")
+			{
+				mLLCEFLib->update();
+			}
+			else if (message_name == "cleanup")
+			{
+			}
+			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
+				{
+					//std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
+				}
+
+				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)
+		{
+			if (message_name == "init")
+			{
+				// event callbacks from LLCefLib
+				mLLCEFLib->setOnPageChangedCallback(boost::bind(&MediaPluginCEF::onPageChangedCallback, this, _1, _2, _3));
+				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->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1));
 				mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));
-
-				LLCEFLibSettings settings;
-				settings.inital_width = 1024;
-				settings.inital_height = 1024;
-				settings.plugins_enabled = mPluginsEnabled;
-				settings.javascript_enabled = mJavascriptEnabled;
-				settings.cookies_enabled = mCookiesEnabled;
-				settings.accept_language_list = mHostLanguage;
-				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", false);
-				sendMessage(message);
-			}
-			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 == "mouse_event")
-			{
-				std::string event = message_in.getValue("event");
-
-				S32 x = message_in.getValueS32("x");
-				S32 y = message_in.getValueS32("y");
-
-				//std::string modifiers = message_in.getValue("modifiers");
-
-				S32 button = message_in.getValueS32("button");
-				EMouseButton btn = MB_MOUSE_BUTTON_LEFT;
-				if (button == 0) btn = MB_MOUSE_BUTTON_LEFT;
-				if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT;
-				if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE;
-
-				if (event == "down")
-				{
-					mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y);
-					mLLCEFLib->setFocus(true);
-
-					std::stringstream str;
-					str << "Mouse down at = " << x << ", " << y;
-					postDebugMessage(str.str());
-				}
-				else if (event == "up")
-				{
-					mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y);
-
-					std::stringstream str;
-					str << "Mouse up at = " << x << ", " << y;
-					postDebugMessage(str.str());
-				}
-				else if (event == "double_click")
-				{
-					// TODO: do we need this ?
-				}
-				else
-				{
-					mLLCEFLib->mouseMove(x, y);
-				}
-			}
-			else if (message_name == "scroll_event")
-			{
-				S32 y = message_in.getValueS32("y");
-				const int scaling_factor = 40;
-				y *= -scaling_factor;
-
-				mLLCEFLib->mouseWheel(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");
-				if (event == "down")
-				{
-					mLLCEFLib->keyPress(key, true);
-				}
-				else if (event == "up")
-				{
-					mLLCEFLib->keyPress(key, false);
-				}
-
-#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.
-				EKeyEvent key_event = KE_KEY_UP;
-				if (event == "down")
-				{
-					key_event = KE_KEY_DOWN;
-				}
-				else if (event == "repeat")
-				{
-					key_event = 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);
-			}
-		}
-		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");
-std::stringstream str;
-str << "@@@@@@@##### cookies_enabled - mCookiesEnabled = " << mCookiesEnabled;
-postDebugMessage(str.str());
-
-			}
-			else if (message_name == "plugins_enabled")
-			{
-				mPluginsEnabled = message_in.getValueBoolean("enable");
-			}
-			else if (message_name == "javascript_enabled")
-			{
-				mJavascriptEnabled = message_in.getValueBoolean("enable");
-			}
-		}
-		else
-		{
-			//std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
-		};
-	}
-}
-
-EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
-{
-	int result = 0;
-
-	if (modifiers.find("shift") != std::string::npos)
-		result |= KM_MODIFIER_SHIFT;
-
-	if (modifiers.find("alt") != std::string::npos)
-		result |= KM_MODIFIER_ALT;
-
-	if (modifiers.find("control") != std::string::npos)
-		result |= KM_MODIFIER_CONTROL;
-
-	if (modifiers.find("meta") != std::string::npos)
-		result |= KM_MODIFIER_META;
-
-	return (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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
-{
-#if LL_DARWIN
-	std::string utf8_text;
-
-	if (key < 128)
-	{
-		utf8_text = (char)key;
-	}
-
-	switch ((KEY)key)
-	{
-		case KEY_BACKSPACE:		utf8_text = (char)8;		break;
-		case KEY_TAB:			utf8_text = (char)9;		break;
-		case KEY_RETURN:		utf8_text = (char)13;		break;
-		case KEY_PAD_RETURN:	utf8_text = (char)13;		break;
-		case KEY_ESCAPE:		utf8_text = (char)27;		break;
-
-	default:
-		break;
-	}
-
-	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);
-
-	mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
-#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, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
-{
-#if LL_DARWIN
-	mLLCEFLib->keyPress(utf8str[0], true);
-#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
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-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;
-}
-
+
+				LLCEFLibSettings settings;
+				settings.inital_width = 1024;
+				settings.inital_height = 1024;
+				settings.plugins_enabled = mPluginsEnabled;
+				settings.javascript_enabled = mJavascriptEnabled;
+				settings.cookies_enabled = mCookiesEnabled;
+				settings.accept_language_list = mHostLanguage;
+				settings.user_agent_substring = mUserAgentSubtring;
+
+				std::stringstream str;
+				str << "@@@@@@@@@@ Initializing with  = user_agent_substring = " << mUserAgentSubtring;
+				postDebugMessage(str.str());
+
+				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", false);
+				sendMessage(message);
+			}
+			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 == "mouse_event")
+			{
+				std::string event = message_in.getValue("event");
+
+				S32 x = message_in.getValueS32("x");
+				S32 y = message_in.getValueS32("y");
+
+				//std::string modifiers = message_in.getValue("modifiers");
+
+				S32 button = message_in.getValueS32("button");
+				EMouseButton btn = MB_MOUSE_BUTTON_LEFT;
+				if (button == 0) btn = MB_MOUSE_BUTTON_LEFT;
+				if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT;
+				if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE;
+
+				if (event == "down")
+				{
+					mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y);
+					mLLCEFLib->setFocus(true);
+
+					std::stringstream str;
+					str << "Mouse down at = " << x << ", " << y;
+					postDebugMessage(str.str());
+				}
+				else if (event == "up")
+				{
+					mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y);
+
+					std::stringstream str;
+					str << "Mouse up at = " << x << ", " << y;
+					postDebugMessage(str.str());
+				}
+				else if (event == "double_click")
+				{
+					// TODO: do we need this ?
+				}
+				else
+				{
+					mLLCEFLib->mouseMove(x, y);
+				}
+			}
+			else if (message_name == "scroll_event")
+			{
+				S32 y = message_in.getValueS32("y");
+				const int scaling_factor = 40;
+				y *= -scaling_factor;
+
+				mLLCEFLib->mouseWheel(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");
+				if (event == "down")
+				{
+					mLLCEFLib->keyPress(key, true);
+				}
+				else if (event == "up")
+				{
+					mLLCEFLib->keyPress(key, false);
+				}
+
+#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.
+				EKeyEvent key_event = KE_KEY_UP;
+				if (event == "down")
+				{
+					key_event = KE_KEY_DOWN;
+				}
+				else if (event == "repeat")
+				{
+					key_event = 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);
+			}
+		}
+		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");
+
+				std::stringstream str;
+				str << "@@@@@@@@@@ setting mUserAgentSubtring = " << mUserAgentSubtring;
+				postDebugMessage(str.str());
+			}
+			else if (message_name == "plugins_enabled")
+			{
+				mPluginsEnabled = message_in.getValueBoolean("enable");
+			}
+			else if (message_name == "javascript_enabled")
+			{
+				mJavascriptEnabled = message_in.getValueBoolean("enable");
+			}
+		}
+		else
+		{
+			//std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
+		};
+	}
+}
+
+EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
+{
+	int result = 0;
+
+	if (modifiers.find("shift") != std::string::npos)
+		result |= KM_MODIFIER_SHIFT;
+
+	if (modifiers.find("alt") != std::string::npos)
+		result |= KM_MODIFIER_ALT;
+
+	if (modifiers.find("control") != std::string::npos)
+		result |= KM_MODIFIER_CONTROL;
+
+	if (modifiers.find("meta") != std::string::npos)
+		result |= KM_MODIFIER_META;
+
+	return (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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+{
+#if LL_DARWIN
+	std::string utf8_text;
+
+	if (key < 128)
+	{
+		utf8_text = (char)key;
+	}
+
+	switch ((KEY)key)
+	{
+		case KEY_BACKSPACE:		utf8_text = (char)8;		break;
+		case KEY_TAB:			utf8_text = (char)9;		break;
+		case KEY_RETURN:		utf8_text = (char)13;		break;
+		case KEY_PAD_RETURN:	utf8_text = (char)13;		break;
+		case KEY_ESCAPE:		utf8_text = (char)27;		break;
+
+	default:
+		break;
+	}
+
+	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);
+
+	mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
+#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, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+{
+#if LL_DARWIN
+	mLLCEFLib->keyPress(utf8str[0], true);
+#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
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 60a5f99e19..5eab0a15ab 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1872,6 +1872,9 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 			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();
-- 
cgit v1.2.3


From 7505501aea76e014b205d64accf89a9d30abac3a Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 1 Sep 2015 17:43:30 -0700
Subject: get update llceflib with cookie/cache code and implement cache/cookie
 folders in viewer

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index fcedc3355d..a0a80e3a3a 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -83,6 +83,8 @@ private:
 	std::string mAuthUsername;
 	std::string mAuthPassword;
 	bool mAuthOK;
+	std::string mCachePath;
+	std::string mCookiePath;
 	LLCEFLib* mLLCEFLib;
 };
 
@@ -104,6 +106,8 @@ MediaPluginBase(host_send_func, host_user_data)
 	mAuthUsername = "";
 	mAuthPassword = "";
 	mAuthOK = false;
+	mCachePath = "";
+	mCookiePath = "";
 	mLLCEFLib = new LLCEFLib();
 }
 
@@ -338,6 +342,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				settings.plugins_enabled = mPluginsEnabled;
 				settings.javascript_enabled = mJavascriptEnabled;
 				settings.cookies_enabled = mCookiesEnabled;
+				settings.cache_path = mCachePath;
+				settings.cookie_store_path = mCookiePath;
 				settings.accept_language_list = mHostLanguage;
 				settings.user_agent_substring = mUserAgentSubtring;
 
@@ -363,6 +369,16 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				message.setValueBoolean("coords_opengl", false);
 				sendMessage(message);
 			}
+			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
+				mCachePath = user_data_path + "cef_cache";
+				mCookiePath = user_data_path + "cef_cookies";
+
+				std::stringstream str;
+				str << "@@@@@@@@@@ setting data paths to " << mCachePath << " and " << mCookiePath;
+				postDebugMessage(str.str());
+			}
 			else if (message_name == "size_change")
 			{
 				std::string name = message_in.getValue("name");
-- 
cgit v1.2.3


From d44eeb48d380215bae0d036976f6daa11082af07 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 1 Sep 2015 17:46:29 -0700
Subject: Remove debugging crud

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index a0a80e3a3a..f49187a897 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -83,7 +83,7 @@ private:
 	std::string mAuthUsername;
 	std::string mAuthPassword;
 	bool mAuthOK;
-	std::string mCachePath;
+	std::string mCachePath;
 	std::string mCookiePath;
 	LLCEFLib* mLLCEFLib;
 };
@@ -106,7 +106,7 @@ MediaPluginBase(host_send_func, host_user_data)
 	mAuthUsername = "";
 	mAuthPassword = "";
 	mAuthOK = false;
-	mCachePath = "";
+	mCachePath = "";
 	mCookiePath = "";
 	mLLCEFLib = new LLCEFLib();
 }
@@ -347,10 +347,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				settings.accept_language_list = mHostLanguage;
 				settings.user_agent_substring = mUserAgentSubtring;
 
-				std::stringstream str;
-				str << "@@@@@@@@@@ Initializing with  = user_agent_substring = " << mUserAgentSubtring;
-				postDebugMessage(str.str());
-
 				bool result = mLLCEFLib->init(settings);
 				if (!result)
 				{
@@ -369,15 +365,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				message.setValueBoolean("coords_opengl", false);
 				sendMessage(message);
 			}
-			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
-				mCachePath = user_data_path + "cef_cache";
-				mCookiePath = user_data_path + "cef_cookies";
-
-				std::stringstream str;
-				str << "@@@@@@@@@@ setting data paths to " << mCachePath << " and " << mCookiePath;
-				postDebugMessage(str.str());
+			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
+				mCachePath = user_data_path + "cef_cache";
+				mCookiePath = user_data_path + "cef_cookies";
 			}
 			else if (message_name == "size_change")
 			{
@@ -553,10 +545,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			else if (message_name == "set_user_agent")
 			{
 				mUserAgentSubtring = message_in.getValue("user_agent");
-
-				std::stringstream str;
-				str << "@@@@@@@@@@ setting mUserAgentSubtring = " << mUserAgentSubtring;
-				postDebugMessage(str.str());
 			}
 			else if (message_name == "plugins_enabled")
 			{
-- 
cgit v1.2.3


From 33da4d9d5dd05bbc9dc232525b59017f7ecbbcdd Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 2 Sep 2015 17:31:40 -0700
Subject: Add support for copy/cut/paste into and out of browser (Note -
 feature in LLQtWebKit (canPaste, canCut etc.) not present so right click menu
 always enables options

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 71 +++++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index f49187a897..f51a2715bb 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -64,6 +64,7 @@ private:
 	void onLoadStartCallback();
 	void onLoadEndCallback(int httpStatusCode);
 	void onNavigateURLCallback(std::string url);
+	void onExternalTargetLinkCallback(std::string url);
 	bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
 
 	void postDebugMessage(const std::string& msg);
@@ -74,6 +75,8 @@ private:
 	void keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data);
 	void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data);
 
+	void checkEditState();
+
 	bool mEnableMediaPluginDebugging;
 	std::string mHostLanguage;
 	bool mCookiesEnabled;
@@ -83,6 +86,9 @@ private:
 	std::string mAuthUsername;
 	std::string mAuthPassword;
 	bool mAuthOK;
+	bool mCanCut;
+	bool mCanCopy;
+	bool mCanPaste;
 	std::string mCachePath;
 	std::string mCookiePath;
 	LLCEFLib* mLLCEFLib;
@@ -106,6 +112,9 @@ MediaPluginBase(host_send_func, host_user_data)
 	mAuthUsername = "";
 	mAuthPassword = "";
 	mAuthOK = false;
+	mCanCut = false;
+	mCanCopy = false;
+	mCanPaste = false;
 	mCachePath = "";
 	mCookiePath = "";
 	mLLCEFLib = new LLCEFLib();
@@ -217,6 +226,13 @@ void MediaPluginCEF::onNavigateURLCallback(std::string url)
 	sendMessage(message);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// triggered when user clicks link with "external" attribute
+void MediaPluginCEF::onExternalTargetLinkCallback(std::string url) 
+{
+
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password)
@@ -279,6 +295,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			else if (message_name == "idle")
 			{
 				mLLCEFLib->update();
+
+				// 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")
 			{
@@ -335,6 +356,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1));
 				mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1));
 				mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));
+				mLLCEFLib->setOnExternalTargetLinkCallback(boost::bind(&MediaPluginCEF::onExternalTargetLinkCallback, this, _1));
 
 				LLCEFLibSettings settings;
 				settings.inital_width = 1024;
@@ -342,8 +364,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				settings.plugins_enabled = mPluginsEnabled;
 				settings.javascript_enabled = mJavascriptEnabled;
 				settings.cookies_enabled = mCookiesEnabled;
-				settings.cache_path = mCachePath;
 				settings.cookie_store_path = mCookiePath;
+				settings.cache_enabled = true;
+				settings.cache_path = mCachePath;
 				settings.accept_language_list = mHostLanguage;
 				settings.user_agent_substring = mUserAgentSubtring;
 
@@ -513,6 +536,18 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			{
 				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)
 		{
@@ -653,6 +688,40 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier
 #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);
+	}
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 bool MediaPluginCEF::init()
-- 
cgit v1.2.3


From 236b3b9f842c86e1f176068ab70b82f83874e2ab Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 3 Sep 2015 18:16:46 -0700
Subject: support for external links and location_changed messages

---
 indra/llplugin/llpluginclassmedia.cpp             |  2 +-
 indra/media_plugins/cef/media_plugin_cef.cpp      | 37 ++++++++++++-----------
 indra/newview/llmediactrl.cpp                     | 30 ++++++++++--------
 indra/newview/skins/default/xui/en/menu_login.xml |  2 +-
 4 files changed, 39 insertions(+), 32 deletions(-)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index f0c547c8d1..5e0902c84d 100755
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -1121,7 +1121,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 		{
 			mClickURL = message.getValue("uri");
 			mClickTarget = message.getValue("target");
-			mClickUUID = message.getValue("uuid");
+			//mClickUUID = message.getValue("uuid");
 			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);
 		}
 		else if(message_name == "click_nofollow")
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index f51a2715bb..97364d949a 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -63,8 +63,8 @@ private:
 	void onTitleChangeCallback(std::string title);
 	void onLoadStartCallback();
 	void onLoadEndCallback(int httpStatusCode);
-	void onNavigateURLCallback(std::string url);
-	void onExternalTargetLinkCallback(std::string url);
+	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 postDebugMessage(const std::string& msg);
@@ -157,16 +157,6 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int width, int
 	}
 }
 
-////////////////////////////////////////////////////////////////////////////////
-//
-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);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 //
 void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line)
@@ -219,7 +209,7 @@ void MediaPluginCEF::onLoadEndCallback(int httpStatusCode)
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginCEF::onNavigateURLCallback(std::string url)
+void MediaPluginCEF::onAddressChangeCallback(std::string url)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
 	message.setValue("uri", url);
@@ -227,10 +217,24 @@ void MediaPluginCEF::onNavigateURLCallback(std::string url)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// triggered when user clicks link with "external" attribute
-void MediaPluginCEF::onExternalTargetLinkCallback(std::string url) 
+//
+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);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -354,9 +358,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1));
 				mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this));
 				mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1));
-				mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1));
+				mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2));
 				mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));
-				mLLCEFLib->setOnExternalTargetLinkCallback(boost::bind(&MediaPluginCEF::onExternalTargetLinkCallback, this, _1));
 
 				LLCEFLibSettings settings;
 				settings.inital_width = 1024;
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index d1bb799015..40d352f9b7 100755
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -993,19 +993,23 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 			std::string target = self->getClickTarget();
 			std::string uuid = self->getClickUUID();
 
-			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);
-			}
+			LLWeb::loadURL(url, target, std::string());
+
+			// 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;
 		};
 
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index e91eea04d1..f59c5e35a6 100755
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -230,7 +230,7 @@
        name="Web Content Floater Debug Test">
         <menu_item_call.on_click
          function="Advanced.WebContentTest"
-         parameter="http://google.com"/>
+         parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/>
       </menu_item_call>
       <menu
        create_jump_keys="true"
-- 
cgit v1.2.3


From 83f26facbf717504b0ab4677cb6dd64534f6b844 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 3 Sep 2015 19:59:57 -0700
Subject: point to new version of llceflib with fixed support for secondlife://
 URLs

---
 indra/media_plugins/cef/media_plugin_cef.cpp       | 1 -
 indra/newview/skins/default/xui/en/menu_viewer.xml | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 97364d949a..f45ab5575c 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -52,7 +52,6 @@ public:
 	/*virtual*/
 	void receiveMessage(const char* message_string);
 
-
 private:
 	bool init();
 
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 2463c5f43b..a633ef3a52 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -3185,7 +3185,7 @@
            shortcut="control|shift|Z">
             <menu_item_call.on_click
              function="Advanced.WebContentTest"
-             parameter="http://google.com"/>
+             parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/>
           </menu_item_call>
           <menu_item_call
            label="FB Connect Test"
-- 
cgit v1.2.3


From 52e56af35eed8ffff522e13e028206243e1302f6 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 10 Sep 2015 15:11:28 -0700
Subject: Pull in LLCefLib with inverted output switched on and change viewer
 to uninvert things

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index f45ab5575c..e812341f8c 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -387,7 +387,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				message.setValueU32("internalformat", GL_RGB);
 				message.setValueU32("format", GL_BGRA);
 				message.setValueU32("type", GL_UNSIGNED_BYTE);
-				message.setValueBoolean("coords_opengl", false);
+				message.setValueBoolean("coords_opengl", true);
 				sendMessage(message);
 			}
 			else if (message_name == "set_user_data_path")
-- 
cgit v1.2.3


From 6a119e327d7b7196e03581561545fb8501c79067 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 16 Sep 2015 22:14:55 -0700
Subject: tmp chckin - still needs latest llceflib to build

---
 indra/llplugin/llpluginclassmedia.cpp        | 242 ++++++++++++++-------------
 indra/media_plugins/cef/media_plugin_cef.cpp |  10 +-
 2 files changed, 129 insertions(+), 123 deletions(-)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 5e0902c84d..c1464db834 100755
--- 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,7 +41,7 @@ static int nextPowerOf2( int value )
 	{
 		next_power_of_2 <<= 1;
 	}
-	
+
 	return next_power_of_2;
 }
 
@@ -63,19 +63,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->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;
@@ -115,7 +115,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 +132,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,13 +140,13 @@ void LLPluginClassMedia::reset()
 	mHistoryBackAvailable = false;
 	mHistoryForwardAvailable = false;
 	mStatusText.clear();
-	mProgressPercent = 0;	
+	mProgressPercent = 0;
 	mClickURL.clear();
 	mClickNavType.clear();
 	mClickTarget.clear();
 	mClickUUID.clear();
 	mStatusCode = 0;
-	
+
 	// media_time class
 	mCurrentTime = 0.0f;
 	mDuration = 0.0f;
@@ -160,7 +160,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
@@ -177,7 +177,7 @@ void LLPluginClassMedia::idle(void)
 		else
 		{
 			mRequestedTextureWidth = mRequestedMediaWidth;
-			
+
 			if(mPadding > 1)
 			{
 				// Pad up to a multiple of the specified number of bytes per row
@@ -187,7 +187,7 @@ void LLPluginClassMedia::idle(void)
 				{
 					rowbytes += mPadding - pad;
 				}
-				
+
 				if(rowbytes % mRequestedTextureDepth == 0)
 				{
 					mRequestedTextureWidth = rowbytes / mRequestedTextureDepth;
@@ -199,7 +199,7 @@ void LLPluginClassMedia::idle(void)
 			}
 		}
 
-		
+
 		// Size change has been requested but not initiated yet.
 		size_t newsize = mRequestedTextureWidth * mRequestedTextureHeight * mRequestedTextureDepth;
 
@@ -214,22 +214,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;
@@ -238,7 +238,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");
@@ -252,11 +252,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
@@ -322,11 +322,11 @@ void LLPluginClassMedia::setSizeInternal(void)
 		mRequestedMediaWidth = mDefaultMediaWidth;
 		mRequestedMediaHeight = mDefaultMediaHeight;
 	}
-	
+
 	// Save these for size/interest calculations
 	mFullMediaWidth = mRequestedMediaWidth;
 	mFullMediaHeight = mRequestedMediaHeight;
-	
+
 	if(mAllowDownsample)
 	{
 		switch(mPriority)
@@ -340,19 +340,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;
 
@@ -380,9 +380,9 @@ bool LLPluginClassMedia::textureValid(void)
 		mRequestedMediaWidth != mMediaWidth ||
 		mRequestedMediaHeight != mMediaHeight ||
 		getBitsData() == NULL
-	)	
+	)
 		return false;
-	
+
 	return true;
 }
 
@@ -406,8 +406,8 @@ void LLPluginClassMedia::resetDirty(void)
 std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
 {
 	std::string result;
-	
-	
+
+
 	if(modifiers & MASK_CONTROL)
 	{
 		result += "control|";
@@ -430,7 +430,7 @@ std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
 	{
 		result += "meta|";
 	}
-*/	
+*/
 	return result;
 }
 
@@ -538,11 +538,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)
@@ -557,7 +557,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)
 	{
@@ -567,42 +567,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)
@@ -613,7 +613,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.
@@ -632,15 +632,17 @@ 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;
 }
 
@@ -651,10 +653,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");
@@ -662,9 +664,9 @@ 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;
 }
 
@@ -673,7 +675,7 @@ void LLPluginClassMedia::loadURI(const std::string &uri)
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "load_uri");
 
 	message.setValue("uri", uri);
-	
+
 	sendMessage(message);
 }
 
@@ -690,7 +692,7 @@ const char* LLPluginClassMedia::priorityToString(EPriority priority)
 		case PRIORITY_NORMAL:		result = "normal";		break;
 		case PRIORITY_HIGH:			result = "high";		break;
 	}
-	
+
 	return result;
 }
 
@@ -701,44 +703,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();
 	}
@@ -759,12 +761,12 @@ void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
 F64 LLPluginClassMedia::getCPUUsage()
 {
 	F64 result = 0.0f;
-	
+
 	if(mPlugin)
 	{
 		result = mPlugin->getCPUUsage();
 	}
-	
+
 	return result;
 }
 
@@ -853,11 +855,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();
@@ -868,21 +870,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;
@@ -890,7 +892,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)
@@ -899,7 +901,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 					newDirtyRect.mTop = newDirtyRect.mBottom;
 					newDirtyRect.mBottom = temp;
 				}
-				
+
 				if(mDirtyRect.isEmpty())
 				{
 					mDirtyRect = newDirtyRect;
@@ -909,7 +911,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 << ", "
@@ -919,10 +921,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;
@@ -942,7 +944,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 			{
 				mCurrentRate = message.getValueReal("current_rate");
 			}
-			
+
 			if(message.hasValue("loaded_duration"))
 			{
 				mLoadedDuration = message.getValueReal("loaded_duration");
@@ -953,7 +955,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.
 			{
@@ -964,7 +966,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 			{
 				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED);
 			}
-			
+
 			if(previous_percent != mProgressPercent)
 			{
 				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED);
@@ -973,9 +975,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;
@@ -1015,24 +1017,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);
@@ -1099,7 +1101,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")
@@ -1154,7 +1156,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")
@@ -1163,7 +1165,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
@@ -1179,7 +1181,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;
 		}
@@ -1187,13 +1189,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);
@@ -1233,7 +1235,7 @@ void LLPluginClassMedia::focus(bool focused)
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "focus");
 
 	message.setValueBoolean("focused", focused);
-	
+
 	sendMessage(message);
 }
 
@@ -1260,7 +1262,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);
 }
 
@@ -1293,7 +1295,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);
 }
 
@@ -1407,7 +1409,7 @@ void LLPluginClassMedia::seek(float time)
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
 
 	message.setValueReal("time", time);
-	
+
 	sendMessage(message);
 }
 
@@ -1425,11 +1427,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);
 	}
 }
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index e812341f8c..c668076d93 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -503,11 +503,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				S32 key = message_in.getValueS32("key");
 				if (event == "down")
 				{
-					mLLCEFLib->keyPress(key, true);
+					//mLLCEFLib->keyPress(key, true);
+					mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)key, 0, KM_MODIFIER_NONE, 0, 0, 0);
+
 				}
 				else if (event == "up")
 				{
-					mLLCEFLib->keyPress(key, false);
+					//mLLCEFLib->keyPress(key, false);
+					mLLCEFLib->keyboardEvent(KE_KEY_UP, (uint32_t)key, 0, KM_MODIFIER_NONE, 0, 0, 0);
 				}
 
 #elif LL_WINDOWS
@@ -681,7 +684,8 @@ void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier mo
 void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
 {
 #if LL_DARWIN
-	mLLCEFLib->keyPress(utf8str[0], true);
+	//mLLCEFLib->keyPress(utf8str[0], true);
+	mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, KM_MODIFIER_NONE, 0, 0, 0);
 #elif LL_WINDOWS
 	U32 msg = ll_U32_from_sd(native_key_data["msg"]);
 	U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
-- 
cgit v1.2.3


From 533e4f3652b1b6da4a364117e20f6d88c4f9647a Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Mon, 21 Sep 2015 15:37:49 -0700
Subject: Remove UI for no longer used Enabled Media Popups checkbox

---
 .../skins/default/xui/en/panel_preferences_setup.xml        | 13 -------------
 1 file changed, 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 1e9a1aa27c..eafe575a06 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -224,19 +224,6 @@
     radio_style="false"
     width="400"
     top_pad="5"/>
-  <check_box
-    top_delta="4"
-    enabled="true"
-    follows="left|top"
-    height="14"
-    initial_value="false"
-    control_name="MediaEnablePopups"
-    label="Enable media browser pop-ups"
-    left_delta="0"
-    mouse_opaque="true"
-    name="media_popup_enabled"
-    width="400"           
-    top_pad="5"/>
   <text
      type="string"
      length="1"
-- 
cgit v1.2.3


From 3e20770f350652b91fd4b4a5bbef9b5f03561310 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Sat, 26 Sep 2015 18:53:17 -0700
Subject: Point to new third party llcef package and fix typo in interface

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 4 ++--
 indra/newview/viewer_manifest.py             | 5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index c668076d93..ca7339669b 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -361,8 +361,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));
 
 				LLCEFLibSettings settings;
-				settings.inital_width = 1024;
-				settings.inital_height = 1024;
+				settings.initial_width = 1024;
+				settings.initial_height = 1024;
 				settings.plugins_enabled = mPluginsEnabled;
 				settings.javascript_enabled = mJavascriptEnabled;
 				settings.cookies_enabled = mCookiesEnabled;
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index ad8a236f92..bc5be822d0 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -447,13 +447,13 @@ class Windows_i686_Manifest(ViewerManifest):
             if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'debug'), dst="llplugin"):
                 self.path("d3dcompiler_43.dll")
                 self.path("d3dcompiler_47.dll")
-                self.path("ffmpegsumo.dll")
                 self.path("libcef.dll")
                 self.path("libEGL.dll")
                 self.path("libGLESv2.dll")
                 self.path("llceflib_host.exe")
                 self.path("natives_blob.bin")
                 self.path("snapshot_blob.bin")
+                self.path("widevinecdmadapter.dll")
                 self.path("wow_helper.exe")
                 self.end_prefix()
         else:
@@ -461,13 +461,13 @@ class Windows_i686_Manifest(ViewerManifest):
             if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"):
                 self.path("d3dcompiler_43.dll")
                 self.path("d3dcompiler_47.dll")
-                self.path("ffmpegsumo.dll")
                 self.path("libcef.dll")
                 self.path("libEGL.dll")
                 self.path("libGLESv2.dll")
                 self.path("llceflib_host.exe")
                 self.path("natives_blob.bin")
                 self.path("snapshot_blob.bin")
+                self.path("widevinecdmadapter.dll")
                 self.path("wow_helper.exe")
                 self.end_prefix()
 
@@ -476,6 +476,7 @@ class Windows_i686_Manifest(ViewerManifest):
             self.path("cef.pak")
             self.path("cef_100_percent.pak")
             self.path("cef_200_percent.pak")
+            self.path("cef_extensions.pak")
             self.path("devtools_resources.pak")
             self.path("icudtl.dat")
             self.end_prefix()
-- 
cgit v1.2.3


From fba31a22a132f855dc59014f4e9b93f15d45708d Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 29 Sep 2015 14:06:00 -0700
Subject: SL-229 (fix) update viewer version number to 4.0.0

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 0cbfaed0d9..fcdb2e109f 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.8.5
+4.0.0
-- 
cgit v1.2.3


From a0c0bc6b4033acf8d395708b5515215699905acc Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 30 Sep 2015 16:34:49 -0700
Subject: Update CEF media plugin to reflect changes in LLCEFLib

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 76 ++++++++++++++++++++--------
 1 file changed, 55 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index ca7339669b..da39cd353b 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -65,14 +65,15 @@ private:
 	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 postDebugMessage(const std::string& msg);
 	void authResponse(LLPluginMessage &message);
 
-	EKeyboardModifier decodeModifiers(std::string &modifiers);
+	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(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data);
-	void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data);
+	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();
 
@@ -259,6 +260,38 @@ bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::strin
 	return mAuthOK;
 }
 
+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");
@@ -359,8 +392,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1));
 				mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2));
 				mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));
+				mLLCEFLib->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2));
 
-				LLCEFLibSettings settings;
+				LLCEFLib::LLCEFLibSettings settings;
 				settings.initial_width = 1024;
 				settings.initial_height = 1024;
 				settings.plugins_enabled = mPluginsEnabled;
@@ -449,14 +483,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				//std::string modifiers = message_in.getValue("modifiers");
 
 				S32 button = message_in.getValueS32("button");
-				EMouseButton btn = MB_MOUSE_BUTTON_LEFT;
-				if (button == 0) btn = MB_MOUSE_BUTTON_LEFT;
-				if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT;
-				if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE;
+				LLCEFLib::EMouseButton btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT;
+				if (button == 0) btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT;
+				if (button == 1) btn = LLCEFLib::MB_MOUSE_BUTTON_RIGHT;
+				if (button == 2) btn = LLCEFLib::MB_MOUSE_BUTTON_MIDDLE;
 
 				if (event == "down")
 				{
-					mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y);
+					mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOWN, x, y);
 					mLLCEFLib->setFocus(true);
 
 					std::stringstream str;
@@ -465,7 +499,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				}
 				else if (event == "up")
 				{
-					mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y);
+					mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_UP, x, y);
 
 					std::stringstream str;
 					str << "Mouse up at = " << x << ", " << y;
@@ -520,14 +554,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				LLSD native_key_data = message_in.getValueLLSD("native_key_data");
 
 				// Treat unknown events as key-up for safety.
-				EKeyEvent key_event = KE_KEY_UP;
+				LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP;
 				if (event == "down")
 				{
-					key_event = KE_KEY_DOWN;
+					key_event = LLCEFLib::KE_KEY_DOWN;
 				}
 				else if (event == "repeat")
 				{
-					key_event = KE_KEY_REPEAT;
+					key_event = LLCEFLib::KE_KEY_REPEAT;
 				}
 
 				keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
@@ -602,23 +636,23 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 	}
 }
 
-EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
+LLCEFLib::EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
 {
 	int result = 0;
 
 	if (modifiers.find("shift") != std::string::npos)
-		result |= KM_MODIFIER_SHIFT;
+		result |= LLCEFLib::KM_MODIFIER_SHIFT;
 
 	if (modifiers.find("alt") != std::string::npos)
-		result |= KM_MODIFIER_ALT;
+		result |= LLCEFLib::KM_MODIFIER_ALT;
 
 	if (modifiers.find("control") != std::string::npos)
-		result |= KM_MODIFIER_CONTROL;
+		result |= LLCEFLib::KM_MODIFIER_CONTROL;
 
 	if (modifiers.find("meta") != std::string::npos)
-		result |= KM_MODIFIER_META;
+		result |= LLCEFLib::KM_MODIFIER_META;
 
-	return (EKeyboardModifier)result;
+	return (LLCEFLib::EKeyboardModifier)result;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -645,7 +679,7 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
 {
 #if LL_DARWIN
 	std::string utf8_text;
@@ -681,7 +715,7 @@ void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier mo
 #endif
 };
 
-void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
 {
 #if LL_DARWIN
 	//mLLCEFLib->keyPress(utf8str[0], true);
-- 
cgit v1.2.3


From ca871f25e921dd2fd3ea7c7b7b8a8c53bd4f7eb1 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 1 Oct 2015 09:57:53 -0700
Subject: Fix OS X missing scope qualifiers

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index da39cd353b..9b87eca726 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -538,13 +538,13 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				if (event == "down")
 				{
 					//mLLCEFLib->keyPress(key, true);
-					mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)key, 0, KM_MODIFIER_NONE, 0, 0, 0);
+					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(KE_KEY_UP, (uint32_t)key, 0, KM_MODIFIER_NONE, 0, 0, 0);
+					mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_UP, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
 				}
 
 #elif LL_WINDOWS
@@ -719,7 +719,7 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboar
 {
 #if LL_DARWIN
 	//mLLCEFLib->keyPress(utf8str[0], true);
-	mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, KM_MODIFIER_NONE, 0, 0, 0);
+	mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
 #elif LL_WINDOWS
 	U32 msg = ll_U32_from_sd(native_key_data["msg"]);
 	U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
-- 
cgit v1.2.3


From cb7f84a470d7afeb1501cf5514333c6ee15d96df Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Fri, 2 Oct 2015 11:14:28 -0700
Subject: MAINT-5687: Remove old webkit from the make files and the repo. 
 Ensure that it is no longer meaningfully referenced.

---
 indra/CMakeLists.txt                               |    7 -
 indra/cmake/CMakeLists.txt                         |    1 -
 indra/cmake/WebKitLibPlugin.cmake                  |   93 -
 indra/llplugin/CMakeLists.txt                      |    1 -
 indra/media_plugins/webkit/CMakeLists.txt          |  132 --
 .../media_plugins/webkit/dummy_volume_catcher.cpp  |   58 -
 .../media_plugins/webkit/linux_volume_catcher.cpp  |  468 ----
 .../webkit/linux_volume_catcher_pa_syms.inc        |   21 -
 .../webkit/linux_volume_catcher_paglib_syms.inc    |    6 -
 indra/media_plugins/webkit/mac_volume_catcher.cpp  |  275 ---
 indra/media_plugins/webkit/media_plugin_webkit.cpp | 1481 ------------
 indra/media_plugins/webkit/volume_catcher.h        |   54 -
 .../webkit/windows_volume_catcher.cpp              |  147 --
 indra/media_plugins/winmmshim/CMakeLists.txt       |    3 -
 indra/newview/CMakeLists.txt                       |    4 -
 indra/newview/llappviewer.cpp                      |    6 +
 indra/newview/viewer_manifest.py                   |    2 -
 indra/test_apps/llfbconnecttest/CMakeLists.txt     |  372 ---
 indra/test_apps/llfbconnecttest/README.Linden      |   20 -
 indra/test_apps/llfbconnecttest/bookmarks.txt      |    4 -
 .../test_apps/llfbconnecttest/llfbconnecttest.cpp  | 2394 --------------------
 indra/test_apps/llfbconnecttest/llfbconnecttest.h  |  173 --
 indra/test_apps/llplugintest/CMakeLists.txt        |  138 --
 indra/test_apps/llplugintest/llmediaplugintest.cpp | 2377 -------------------
 indra/test_apps/llplugintest/llmediaplugintest.h   |  207 --
 25 files changed, 6 insertions(+), 8438 deletions(-)
 delete mode 100755 indra/cmake/WebKitLibPlugin.cmake
 delete mode 100755 indra/media_plugins/webkit/CMakeLists.txt
 delete mode 100755 indra/media_plugins/webkit/dummy_volume_catcher.cpp
 delete mode 100755 indra/media_plugins/webkit/linux_volume_catcher.cpp
 delete mode 100755 indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc
 delete mode 100755 indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc
 delete mode 100755 indra/media_plugins/webkit/mac_volume_catcher.cpp
 delete mode 100755 indra/media_plugins/webkit/media_plugin_webkit.cpp
 delete mode 100755 indra/media_plugins/webkit/volume_catcher.h
 delete mode 100755 indra/media_plugins/webkit/windows_volume_catcher.cpp
 delete mode 100644 indra/test_apps/llfbconnecttest/CMakeLists.txt
 delete mode 100644 indra/test_apps/llfbconnecttest/README.Linden
 delete mode 100644 indra/test_apps/llfbconnecttest/bookmarks.txt
 delete mode 100644 indra/test_apps/llfbconnecttest/llfbconnecttest.cpp
 delete mode 100644 indra/test_apps/llfbconnecttest/llfbconnecttest.h
 delete mode 100755 indra/test_apps/llplugintest/llmediaplugintest.cpp
 delete mode 100755 indra/test_apps/llplugintest/llmediaplugintest.h

(limited to 'indra')

diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 2d45bc938e..133c5ee265 100755
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -57,13 +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)
-    #removed during webkit -> cef update
-    #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/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 2298b0f284..4dd69649d0 100755
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -103,7 +103,6 @@ set(cmake_SOURCE_FILES
     Variables.cmake
     ViewerMiscLibs.cmake
     VisualLeakDetector.cmake
-##  WebKitLibPlugin.cmake
     XmlRpcEpi.cmake
     ZLIB.cmake
     )
diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake
deleted file mode 100755
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/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 75d89aac78..8c4ddd524e 100755
--- 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}
diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt
deleted file mode 100755
index 5a8fe90bdd..0000000000
--- a/indra/media_plugins/webkit/CMakeLists.txt
+++ /dev/null
@@ -1,132 +0,0 @@
-# -*- cmake -*-
-
-project(media_plugin_webkit)
-
-include(00-Common)
-include(LLCommon)
-include(LLImage)
-include(LLPlugin)
-include(LLMath)
-include(LLRender)
-include(LLWindow)
-include(UI)
-include(Linking)
-include(PluginAPI)
-include(MediaPluginBase)
-include(OpenGL)
-include(PulseAudio)
-
-include(WebKitLibPlugin)
-
-include_directories(
-    ${PULSEAUDIO_INCLUDE_DIRS}
-    ${LLPLUGIN_INCLUDE_DIRS}
-    ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${LLQTWEBKIT_INCLUDE_DIR}
-)
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
-
-
-### media_plugin_webkit
-
-if(NOT WORD_SIZE EQUAL 32)
-  if(WINDOWS)
-    add_definitions(/FIXED:NO)
-  else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
-    add_definitions(-fPIC)
-  endif(WINDOWS)
-endif(NOT WORD_SIZE EQUAL 32)
-
-set(media_plugin_webkit_SOURCE_FILES
-    media_plugin_webkit.cpp
-    )
-
-set(media_plugin_webkit_HEADER_FILES
-    volume_catcher.h
-    )
-
-set(media_plugin_webkit_LINK_LIBRARIES
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${WEBKIT_PLUGIN_LIBRARIES}
-  ${PLUGIN_API_WINDOWS_LIBRARIES}
-  ${PULSEAUDIO_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
-       )
-elseif (DARWIN)
-  list(APPEND media_plugin_webkit_SOURCE_FILES mac_volume_catcher.cpp)
-  find_library(CORESERVICES_LIBRARY CoreServices)
-  find_library(AUDIOUNIT_LIBRARY AudioUnit)
-  list(APPEND media_plugin_webkit_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)
-endif (LINUX)
-
-set_source_files_properties(${media_plugin_webkit_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
-list(APPEND media_plugin_webkit_SOURCE_FILES ${media_plugin_webkit_HEADER_FILES})
-
-add_library(media_plugin_webkit
-    SHARED
-    ${media_plugin_webkit_SOURCE_FILES}
-)
-
-target_link_libraries(media_plugin_webkit ${media_plugin_webkit_LINK_LIBRARIES})
-
-add_dependencies(media_plugin_webkit
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-)
-
-if (WINDOWS)
-  set_target_properties(
-    media_plugin_webkit
-    PROPERTIES
-    LINK_FLAGS "/MANIFEST:NO"
-    )
-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
-    PROPERTIES
-    PREFIX ""
-    BUILD_WITH_INSTALL_RPATH 1
-    INSTALL_NAME_DIR "@executable_path"
-    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/dummy_volume_catcher.cpp b/indra/media_plugins/webkit/dummy_volume_catcher.cpp
deleted file mode 100755
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 100755
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 <glib.h>
-#include <glib-object.h>
-
-#include <pulse/introspect.h>
-#include <pulse/context.h>
-#include <pulse/subscribe.h>
-#include <pulse/glib-mainloop.h> // 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<U32> mSinkInputIndices;
-	std::map<U32,U32> 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<U32>::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*>((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*>((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*>((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 100755
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 100755
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/mac_volume_catcher.cpp b/indra/media_plugins/webkit/mac_volume_catcher.cpp
deleted file mode 100755
index 73e5bf3da3..0000000000
--- a/indra/media_plugins/webkit/mac_volume_catcher.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-/** 
- * @file mac_volume_catcher.cpp
- * @brief A Mac OS X specific hack to control the volume level of all audio channels opened by a process.
- *
- * @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
- */
-
-/**************************************************************************************************************
-	This code works by using CaptureComponent to capture the "Default Output" audio component
-	(kAudioUnitType_Output/kAudioUnitSubType_DefaultOutput) and delegating all calls to the original component.
-	It does this just to keep track of all instances of the default output component, so that it can set the
-	kHALOutputParam_Volume parameter on all of them to adjust the output volume.
-**************************************************************************************************************/
-
-#include "volume_catcher.h"
-
-#include <QuickTime/QuickTime.h>
-#include <AudioUnit/AudioUnit.h>
-#include <list>
-
-#if LL_DARWIN
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-
-struct VolumeCatcherStorage;
-
-class VolumeCatcherImpl
-{
-public:
-
-	void setVolume(F32 volume);
-	void setPan(F32 pan);
-	
-	void setInstanceVolume(VolumeCatcherStorage *instance);
-	
-	std::list<VolumeCatcherStorage*> mComponentInstances;
-	Component mOriginalDefaultOutput;
-	Component mVolumeAdjuster;
-	
-	static VolumeCatcherImpl *getInstance();
-private:
-	// This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
-	VolumeCatcherImpl();
-	static VolumeCatcherImpl *sInstance;
-	
-	// The singlar instance of this class is expected to last until the process exits.
-	// To ensure this, we declare the destructor here but never define it, so any code which attempts to destroy the instance will not link.
-	~VolumeCatcherImpl();	
-	
-	F32 mVolume;
-	F32 mPan;
-};
-
-VolumeCatcherImpl *VolumeCatcherImpl::sInstance = NULL;;
-
-struct VolumeCatcherStorage
-{
-	ComponentInstance self;
-	ComponentInstance delegate;
-};
-
-static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage);
-static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self);
-static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self);
-
-VolumeCatcherImpl *VolumeCatcherImpl::getInstance()
-{
-	if(!sInstance)
-	{
-		sInstance = new VolumeCatcherImpl;
-	}
-	
-	return sInstance;
-}
-
-VolumeCatcherImpl::VolumeCatcherImpl()
-{
-	mVolume = 1.0;	// default to full volume
-	mPan = 0.0;		// and center pan
-		
-	ComponentDescription desc;
-	desc.componentType = kAudioUnitType_Output;
-	desc.componentSubType = kAudioUnitSubType_DefaultOutput;
-	desc.componentManufacturer = kAudioUnitManufacturer_Apple;
-	desc.componentFlags = 0;
-	desc.componentFlagsMask = 0;
-	
-	// Find the original default output component
-	mOriginalDefaultOutput = FindNextComponent(NULL, &desc);
-
-	// Register our own output component with the same parameters
-	mVolumeAdjuster = RegisterComponent(&desc, NewComponentRoutineUPP(volume_catcher_component_entry), 0, NULL, NULL, NULL);
-
-	// Capture the original component, so we always get found instead.
-	CaptureComponent(mOriginalDefaultOutput, mVolumeAdjuster);
-
-}
-
-static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage)
-{
-	ComponentResult result = badComponentSelector;
-	VolumeCatcherStorage *storage = (VolumeCatcherStorage*)componentStorage;
-	
-	switch(cp->what)
-	{
-		case kComponentOpenSelect:
-//			std::cerr << "kComponentOpenSelect" << std::endl;
-			result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_open, uppCallComponentOpenProcInfo);
-		break;
-
-		case kComponentCloseSelect:
-//			std::cerr << "kComponentCloseSelect" << std::endl;
-			result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_close, uppCallComponentCloseProcInfo);
-			// CallComponentFunctionWithStorageProcInfo
-		break;
-		
-		default:
-//			std::cerr << "Delegating selector: " << cp->what << " to component instance " << storage->delegate << std::endl;
-			result = DelegateComponentCall(cp, storage->delegate);
-		break;
-	}
-	
-	return result;
-}
-
-static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self)
-{
-	ComponentResult result = noErr;
-	VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();	
-	
-	storage = new VolumeCatcherStorage;
-
-	storage->self = self;
-	storage->delegate = NULL;
-
-	result = OpenAComponent(impl->mOriginalDefaultOutput, &(storage->delegate));
-	
-	if(result != noErr)
-	{
-//		std::cerr << "OpenAComponent result = " << result << ", component ref = " << storage->delegate << std::endl;
-		
-		// If we failed to open the delagate component, our open is going to fail.  Clean things up.
-		delete storage;
-	}
-	else
-	{
-		// Success -- set up this component's storage
-		SetComponentInstanceStorage(self, (Handle)storage);
-
-		// add this instance to the global list
-		impl->mComponentInstances.push_back(storage);	
-		
-		// and set up the initial volume
-		impl->setInstanceVolume(storage);
-	}
-
-	return result;
-}
-
-static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self)
-{
-	ComponentResult result = noErr;
-	
-	if(storage)
-	{
-		if(storage->delegate)
-		{
-			CloseComponent(storage->delegate);
-			storage->delegate = NULL;
-		}
-		
-		VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();	
-		impl->mComponentInstances.remove(storage);
-		delete[] storage;
-	}
-		
-	return result;
-}
-
-void VolumeCatcherImpl::setVolume(F32 volume)
-{
-	VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();	
-	impl->mVolume = volume;
-	
-	// Iterate through all known instances, setting the volume on each.
-	for(std::list<VolumeCatcherStorage*>::iterator iter = mComponentInstances.begin(); iter != mComponentInstances.end(); ++iter)
-	{
-		impl->setInstanceVolume(*iter);
-	}
-}
-
-void VolumeCatcherImpl::setPan(F32 pan)
-{
-	VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();	
-	impl->mPan = pan;
-	
-	// TODO: implement this.
-	// This will probably require adding a "panner" audio unit to the chain somehow.
-	// There's also a "3d mixer" component that we might be able to use...
-}
-
-void VolumeCatcherImpl::setInstanceVolume(VolumeCatcherStorage *instance)
-{
-//	std::cerr << "Setting volume on component instance: " << (instance->delegate) << " to " << mVolume << std::endl;
-	
-	OSStatus err = noErr;
-	
-	if(instance && instance->delegate)
-	{
-		err = AudioUnitSetParameter(
-				instance->delegate, 
-				kHALOutputParam_Volume, 
-				kAudioUnitScope_Global,
-				0, 
-				mVolume, 
-				0);
-	}
-	
-	if(err)
-	{
-//		std::cerr << "    AudioUnitSetParameter returned " << err << std::endl;
-	}
-}
-
-/////////////////////////////////////////////////////
-
-VolumeCatcher::VolumeCatcher()
-{
-	pimpl = VolumeCatcherImpl::getInstance();
-}
-
-VolumeCatcher::~VolumeCatcher()
-{
-	// Let the instance persist until exit.
-}
-
-void VolumeCatcher::setVolume(F32 volume)
-{
-	pimpl->setVolume(volume);
-}
-
-void VolumeCatcher::setPan(F32 pan)
-{
-	pimpl->setPan(pan);
-}
-
-void VolumeCatcher::pump()
-{
-	// No periodic tasks are necessary for this implementation.
-}
-
-#if LL_DARWIN
-#pragma GCC diagnostic warning "-Wdeprecated-declarations"
-#endif
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
deleted file mode 100755
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 <glib.h>
-# include <glib-object.h>
-}
-#else
-# define LL_QTWEBKIT_USES_PIXMAPS 0
-#endif // LL_LINUX
-
-# include "volume_catcher.h"
-
-#if LL_WINDOWS
-# include <direct.h>
-#else
-# include <unistd.h>
-# include <stdlib.h>
-#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<height; ++y)
-				{
-					memcpy( &mPixels[(height-y-1)*rowspan], &browser_pixels[y*rowspan], rowspan );
-				}
-#else
-				memcpy( mPixels, browser_pixels, buffer_size );
-#endif // LL_QTWEBKIT_USES_PIXMAPS
-			}
-
-			if ( mWidth > 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/webkit/volume_catcher.h b/indra/media_plugins/webkit/volume_catcher.h
deleted file mode 100755
index 337f2913d3..0000000000
--- a/indra/media_plugins/webkit/volume_catcher.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/** 
- * @file volume_catcher.h
- * @brief Interface to a class with platform-specific implementations that allows control of the audio volume of all sources in the current process.
- *
- * @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
- */
-
-#ifndef VOLUME_CATCHER_H
-#define VOLUME_CATCHER_H
-
-#include "linden_common.h"
-
-class VolumeCatcherImpl;
-
-class VolumeCatcher
-{
- public:
-	VolumeCatcher();
-	~VolumeCatcher();
-
-	void setVolume(F32 volume); // 0.0 - 1.0
-	
-	// Set the left-right pan of audio sources
-	// where -1.0 = left, 0 = center, and 1.0 = right
-	void setPan(F32 pan); 
-
-	void pump(); // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume
-	
- private:
-	VolumeCatcherImpl *pimpl;
-};
-
-#endif // VOLUME_CATCHER_H
diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/webkit/windows_volume_catcher.cpp
deleted file mode 100755
index 0cfb810906..0000000000
--- a/indra/media_plugins/webkit/windows_volume_catcher.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/** 
- * @file windows_volume_catcher.cpp
- * @brief A Windows implementation of volume level control of all audio channels opened by a process.
- *
- * @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"
-#include <windows.h>
-#include "llsingleton.h"
-class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl>
-{
-friend LLSingleton<VolumeCatcherImpl>;
-public:
-
-	void setVolume(F32 volume);
-	void setPan(F32 pan);
-	
-private:
-	// This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
-	VolumeCatcherImpl();
-	~VolumeCatcherImpl();
-
-	typedef void (WINAPI *set_volume_func_t)(F32);
-	typedef void (WINAPI *set_mute_func_t)(bool);
-
-	set_volume_func_t mSetVolumeFunc;
-	set_mute_func_t mSetMuteFunc;
-
-	// tests if running on Vista, 7, 8 + once in CTOR
-	bool isWindowsVistaOrHigher();
-
-	F32 	mVolume;
-	F32 	mPan;
-	bool mSystemIsVistaOrHigher;
-};
-
-bool VolumeCatcherImpl::isWindowsVistaOrHigher()
-{
-	OSVERSIONINFO osvi;
-	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
-	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-	GetVersionEx(&osvi);
-	return osvi.dwMajorVersion >= 6;
-}
-
-VolumeCatcherImpl::VolumeCatcherImpl()
-:	mVolume(1.0f),			// default volume is max
-	mPan(0.f)				// default pan is centered
-{
-	mSystemIsVistaOrHigher = isWindowsVistaOrHigher();
-
-	if ( ! mSystemIsVistaOrHigher )
-	{
-		HMODULE handle = ::LoadLibrary(L"winmm.dll");
-		if(handle)
-		{
-			mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume");
-			mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute");
-		}
-	}
-}
-
-VolumeCatcherImpl::~VolumeCatcherImpl()
-{
-}
-
-void VolumeCatcherImpl::setVolume(F32 volume)
-{
-	mVolume = volume;
-
-	if ( mSystemIsVistaOrHigher )
-	{
-		// set both left/right to same volume
-		// TODO: use pan value to set independently
-		DWORD left_channel  = (DWORD)(mVolume * 65535.0f);
-		DWORD right_channel =  (DWORD)(mVolume * 65535.0f);
-		DWORD hw_volume = left_channel << 16 | right_channel;
-		::waveOutSetVolume(NULL, hw_volume);
-	}
-	else
-	{
-		if (mSetMuteFunc)
-		{
-			mSetMuteFunc(volume == 0.f);
-		}
-		if (mSetVolumeFunc)
-		{
-			mSetVolumeFunc(mVolume);
-		}
-	}
-}
-
-void VolumeCatcherImpl::setPan(F32 pan)
-{	// remember pan for calculating individual channel levels later
-	mPan = pan;
-}
-
-/////////////////////////////////////////////////////
-
-VolumeCatcher::VolumeCatcher()
-{
-	pimpl = VolumeCatcherImpl::getInstance();
-}
-
-VolumeCatcher::~VolumeCatcher()
-{
-	// Let the instance persist until exit.
-}
-
-void VolumeCatcher::setVolume(F32 volume)
-{
-	pimpl->setVolume(volume);
-}
-
-void VolumeCatcher::setPan(F32 pan)
-{
-	pimpl->setPan(pan);
-}
-
-void VolumeCatcher::pump()
-{
-	// No periodic tasks are necessary for this implementation.
-}
-
-
diff --git a/indra/media_plugins/winmmshim/CMakeLists.txt b/indra/media_plugins/winmmshim/CMakeLists.txt
index bf74f81809..6890589892 100755
--- 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 d575e5cd8c..087d508c42 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1764,7 +1764,6 @@ if (WINDOWS)
       ${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
@@ -1782,7 +1781,6 @@ if (WINDOWS)
       ${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
@@ -2013,7 +2011,6 @@ if (LINUX)
     ${VIEWER_BINARY_NAME}
     linux-crash-logger
     SLPlugin
-    media_plugin_webkit
     media_plugin_gstreamer010
     llcommon
     )
@@ -2185,7 +2182,6 @@ if (PACKAGE)
     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}")
     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' mac-crash-logger")
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 663f1a3550..68976dcfe3 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -124,7 +124,9 @@
 #include "llleap.h"
 #include "stringize.h"
 #include "llcoros.h"
+#if !LL_LINUX
 #include "cef/llceflib.h"
+#endif
 
 // Third party library includes
 #include <boost/bind.hpp>
@@ -3370,7 +3372,11 @@ LLSD LLAppViewer::getViewerInfo() const
 		info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
 	}
 
+#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/viewer_manifest.py b/indra/newview/viewer_manifest.py
index bc5be822d0..15ec946e63 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1076,7 +1076,6 @@ class LinuxManifest(ViewerManifest):
 
         # plugins
         if self.prefix(src="", dst="bin/llplugin"):
-            self.path2basename("../media_plugins/webkit", "libmedia_plugin_webkit.so")
             self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so")
             self.end_prefix("bin/llplugin")
 
@@ -1224,7 +1223,6 @@ class Linux_i686_Manifest(LinuxManifest):
                 self.path("libQtNetwork.so*")
                 self.path("libQtOpenGL.so*")
                 self.path("libQtSvg.so*")
-                self.path("libQtWebKit.so*")
                 self.path("libQtXml.so*")
                 self.end_prefix("lib")
 
diff --git a/indra/test_apps/llfbconnecttest/CMakeLists.txt b/indra/test_apps/llfbconnecttest/CMakeLists.txt
deleted file mode 100644
index 25aaebb783..0000000000
--- a/indra/test_apps/llfbconnecttest/CMakeLists.txt
+++ /dev/null
@@ -1,372 +0,0 @@
-# -*- cmake -*-
-project(llfbconnecttest)
-
-include(00-Common)
-include(FindOpenGL)
-include(LLCommon)
-include(LLPlugin)
-include(Linking)
-include(LLSharedLibs)
-include(PluginAPI)
-include(LLImage)
-include(LLMath)
-include(LLMessage)
-include(LLRender)
-include(LLWindow)
-include(Glut)
-include(Glui)
-
-include_directories(
-    ${LLPLUGIN_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-)
-
-if (DARWIN)
-    include(CMakeFindFrameworks)
-    find_library(COREFOUNDATION_LIBRARY CoreFoundation)
-endif (DARWIN)
-
-### llfbconnecttest
-
-set(llfbconnecttest_SOURCE_FILES
-    llfbconnecttest.cpp
-    llfbconnecttest.h
-    bookmarks.txt
-    )
-
-add_executable(llfbconnecttest
-    WIN32
-    MACOSX_BUNDLE
-    ${llfbconnecttest_SOURCE_FILES}
-)
-
-set_target_properties(llfbconnecttest
-    PROPERTIES
-    WIN32_EXECUTABLE
-    FALSE
-)
-
-target_link_libraries(llfbconnecttest
-  ${GLUT_LIBRARY}
-  ${GLUI_LIBRARY}
-  ${OPENGL_LIBRARIES}
-  ${LLPLUGIN_LIBRARIES}
-  ${LLMESSAGE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${PLUGIN_API_WINDOWS_LIBRARIES}
-)
-
-if (DARWIN)
-  # The testbed needs to use a couple of CoreFoundation calls now, to deal with being a bundled app.
-  target_link_libraries(llfbconnecttest
-    ${COREFOUNDATION_LIBRARY}
-  )
-endif (DARWIN)
-
-add_dependencies(llfbconnecttest
-  stage_third_party_libs
-  SLPlugin
-  media_plugin_webkit
-  ${LLPLUGIN_LIBRARIES}
-  ${LLMESSAGE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-)
-
-# turn off weird GLUI pragma 
-add_definitions(-DGLUI_NO_LIB_PRAGMA)
-
-if (DARWIN OR LINUX)
-  # glui.h contains code that triggers the "overloaded-virtual" warning in gcc.  
-  set_source_files_properties(llfbconnecttest.cpp PROPERTIES COMPILE_FLAGS "-Wno-overloaded-virtual")
-endif (DARWIN OR LINUX)
-
-# Gather build products of the various dependencies into the build directory for the testbed.
-
-if (DARWIN)
-  # path inside the app bundle where we'll need to copy plugins and other related files
-  set(PLUGINS_DESTINATION_DIR
-    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llfbconnecttest.app/Contents/Resources
-  )
-  
-  # create the Contents/Resources directory
-  add_custom_command(
-    TARGET llfbconnecttest POST_BUILD
-    COMMAND ${CMAKE_COMMAND}
-    ARGS
-      -E
-      make_directory
-      ${PLUGINS_DESTINATION_DIR}
-    COMMENT "Creating Resources directory in app bundle."
-  ) 
-else (DARWIN)
-  set(PLUGINS_DESTINATION_DIR
-    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
-  )
-endif (DARWIN)
-
-set(BUILT_SLPLUGIN $<TARGET_FILE:SLPlugin>)
-add_custom_command(TARGET llfbconnecttest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN}  ${PLUGINS_DESTINATION_DIR}
-  DEPENDS ${BUILT_SLPLUGIN}
-)
-
-set(BUILT_LLCOMMON $<TARGET_FILE:llcommon>)
-add_custom_command(TARGET llfbconnecttest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON}  ${PLUGINS_DESTINATION_DIR}
-  DEPENDS ${BUILT_LLCOMMON}
-)
-
-
-set(BUILT_WEBKIT_PLUGIN $<TARGET_FILE:media_plugin_webkit>)
-add_custom_command(TARGET llfbconnecttest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN}  ${PLUGINS_DESTINATION_DIR}
-  DEPENDS ${BUILT_WEBKIT_PLUGIN}
-)
-
-# copy over bookmarks file if llfbconnecttest gets built
-set(BUILT_LLFBCONNECTTEST $<TARGET_FILE:llfbconnecttest>)
-add_custom_command(TARGET llfbconnecttest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/
-  DEPENDS ${BUILT_LLFBCONNECTTEST}
-)
-
-# also copy it to the same place as SLPlugin, which is what the mac wants...
-add_custom_command(TARGET llfbconnecttest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR}
-  DEPENDS ${BUILT_LLFBCONNECTTEST}
-)
-
-if(WINDOWS)
-  #********************
-  # Plugin test library deploy
-  #
-  # Debug config runtime files required for the FB connect test
-  set(fbconnecttest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}")
-  set(fbconnecttest_debug_files
-    libeay32.dll
-    libglib-2.0-0.dll
-    libgmodule-2.0-0.dll
-    libgobject-2.0-0.dll
-    libgthread-2.0-0.dll
-    qtcored4.dll
-    qtguid4.dll
-    qtnetworkd4.dll
-    qtopengld4.dll
-    qtwebkitd4.dll
-    ssleay32.dll
-    )
-  copy_if_different(
-    ${fbconnecttest_debug_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Debug"
-    out_targets
-    ${fbconnecttest_debug_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-  
-  # Debug config runtime files required for the FB connect test (Qt image format plugins)
-  set(fbconecttest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}/imageformats")
-  set(fbconecttest_debug_files
-    qgifd4.dll
-    qicod4.dll
-    qjpegd4.dll
-    qmngd4.dll
-    qsvgd4.dll
-    qtiffd4.dll
-    )
-  copy_if_different(
-    ${fbconecttest_debug_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Debug/imageformats"
-    out_targets
-    ${fbconecttest_debug_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-
-  # Debug config runtime files required for the FB connect test (Qt codec plugins)
-  set(fbconnecttest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}/codecs")
-  set(fbconnecttest_debug_files
-    qcncodecsd4.dll
-    qjpcodecsd4.dll
-    qkrcodecsd4.dll
-    qtwcodecsd4.dll
-    )
-  copy_if_different(
-    ${fbconnecttest_debug_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Debug/codecs"
-    out_targets
-    ${fbconnecttest_debug_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
- 
-  # Release & ReleaseDebInfo config runtime files required for the FB connect test
-  set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
-  set(fbconnecttest_release_files
-    libeay32.dll
-    libglib-2.0-0.dll
-    libgmodule-2.0-0.dll
-    libgobject-2.0-0.dll
-    libgthread-2.0-0.dll
-    qtcore4.dll
-    qtgui4.dll
-    qtnetwork4.dll
-    qtopengl4.dll
-    qtwebkit4.dll
-    qtxmlpatterns4.dll
-    ssleay32.dll
-    )
-  copy_if_different(
-    ${fbconnecttest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Release"
-    out_targets
-    ${fbconnecttest_release_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-
-  copy_if_different(
-    ${fbconnecttest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo"
-    out_targets
-    ${fbconnecttest_release_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-
-  # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt image format plugins)
-  set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}/imageformats")
-  set(fbconnecttest_release_files
-    qgif4.dll
-    qico4.dll
-    qjpeg4.dll
-    qmng4.dll
-    qsvg4.dll
-    qtiff4.dll
-    )
-  copy_if_different(
-    ${fbconnecttest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Release/imageformats"
-    out_targets
-    ${fbconnecttest_release_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-
-  copy_if_different(
-    ${fbconnecttest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/imageformats"
-    out_targets
-    ${fbconnecttest_release_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-
-  # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt codec plugins)
-  set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}/codecs")
-  set(fbconnecttest_release_files
-    qcncodecs4.dll  
-    qjpcodecs4.dll  
-    qkrcodecs4.dll  
-    qtwcodecs4.dll  
-    )
-  copy_if_different(
-    ${fbconnecttest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Release/codecs"
-    out_targets
-    ${fbconnecttest_release_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-
-  copy_if_different(
-    ${fbconnecttest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/codecs"
-    out_targets
-    ${fbconnecttest_release_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
- 
-   add_custom_target(copy_fbconnecttest_libs ALL
-     DEPENDS 
-     ${fbconnect_test_targets}
-     )
-
-  add_dependencies(llfbconnecttest copy_fbconnecttest_libs)
-
-endif(WINDOWS)
-
-if (DARWIN)
-  set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
-  set(fbconnecttest_release_files
-    libexception_handler.dylib
-    libaprutil-1.0.dylib
-    libapr-1.0.dylib
-    libexpat.1.5.2.dylib
-    libQtCore.4.7.1.dylib
-    libQtCore.4.dylib
-    libQtGui.4.7.1.dylib
-    libQtGui.4.dylib
-    libQtNetwork.4.7.1.dylib
-    libQtNetwork.4.dylib
-    libQtOpenGL.4.7.1.dylib
-    libQtOpenGL.4.dylib
-    libQtWebKit.4.7.1.dylib
-    libQtWebKit.4.dylib
-    libQtSvg.4.7.1.dylib
-    libQtSvg.4.dylib
-    libQtXml.4.7.1.dylib
-    libQtXml.4.dylib
-    )
-  copy_if_different(
-    ${fbconnecttest_release_src_dir}
-    "${PLUGINS_DESTINATION_DIR}"
-    out_targets
-    ${fbconnecttest_release_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-
-  # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt image format plugins)
-  set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/imageformats")
-  set(fbconnecttest_release_files
-    libqgif.dylib
-    libqico.dylib
-    libqjpeg.dylib
-    libqmng.dylib
-    libqsvg.dylib
-    libqtiff.dylib
-    )
-  copy_if_different(
-    ${fbconnecttest_release_src_dir}
-    "${PLUGINS_DESTINATION_DIR}/imageformats"
-    out_targets
-    ${fbconnecttest_release_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-
-  # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt codec plugins)
-  set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/codecs")
-  set(fbconnecttest_release_files
-    libqcncodecs.dylib
-    libqjpcodecs.dylib
-    libqkrcodecs.dylib
-    libqtwcodecs.dylib
-    )
-  copy_if_different(
-    ${fbconnecttest_release_src_dir}
-    "${PLUGINS_DESTINATION_DIR}/codecs"
-    out_targets
-    ${fbconnecttest_release_files}
-    )
-  set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
-
-  add_custom_target(copy_fbconnecttest_libs ALL
-    DEPENDS 
-    ${fbconnect_test_targets}
-    )
-
-  add_dependencies(llfbconnecttest copy_fbconnecttest_libs)
-endif (DARWIN)
-
-if (LINUX)
-
-endif (LINUX)
-
-ll_deploy_sharedlibs_command(llfbconnecttest) 
diff --git a/indra/test_apps/llfbconnecttest/README.Linden b/indra/test_apps/llfbconnecttest/README.Linden
deleted file mode 100644
index 7488ce680a..0000000000
--- a/indra/test_apps/llfbconnecttest/README.Linden
+++ /dev/null
@@ -1,20 +0,0 @@
-
-1.  Description
-
-    Exercises SLPlugin.  Specific functions and goals aren't clear
-    from the source.
-
-2.  Running
-
-  2.1  Mac
-
-    Make certain '.' is included in PATH.  E.g.:
-
-       PATH=.:"$PATH" open build-darwin-i386/test_apps/llfbconnecttest/RelWithDebInfo/llfbconnecttest.app
-
-    Otherwise the program won't find SLPlugin and will timeout and
-    fail after 30 seconds and give you little information as to why.
-
-    Running 'dtruss' on plugin test applications will give you a great
-    deal of insight into why they aren't activating.
-
diff --git a/indra/test_apps/llfbconnecttest/bookmarks.txt b/indra/test_apps/llfbconnecttest/bookmarks.txt
deleted file mode 100644
index 3995627ea9..0000000000
--- a/indra/test_apps/llfbconnecttest/bookmarks.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# format is description, url (don't put ',' chars in description :)
-# if no ',' found, whole line is used for both description and url
-Google Home Page,http://www.google.com
-Facebook Home Page,http://www.facebook.com
diff --git a/indra/test_apps/llfbconnecttest/llfbconnecttest.cpp b/indra/test_apps/llfbconnecttest/llfbconnecttest.cpp
deleted file mode 100644
index 483a15c468..0000000000
--- a/indra/test_apps/llfbconnecttest/llfbconnecttest.cpp
+++ /dev/null
@@ -1,2394 +0,0 @@
-/**
- * @file LLFBConnectTest.cpp
- * @brief Facebook Connect Test App
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include "indra_constants.h"
-
-#include "llapr.h"
-#include "llerrorcontrol.h"
-
-#include <math.h>
-#include <iomanip>
-#include <sstream>
-#include <ctime>
-
-#include "llfbconnecttest.h"
-
-#if __APPLE__
-	#include <GLUT/glut.h>
-	#include <CoreFoundation/CoreFoundation.h>
-#else
-	#define FREEGLUT_STATIC
-	#include "GL/freeglut.h"
-	#define GLUI_FREEGLUT
-#endif
-
-#if LL_WINDOWS
-#pragma warning(disable: 4263)
-#pragma warning(disable: 4264)
-#endif
-#include "glui.h"
-
-
-LLFBConnectTest* gApplication = 0;
-static void gluiCallbackWrapper( int control_id );
-
-////////////////////////////////////////////////////////////////////////////////
-//
-static bool isTexture( GLuint texture )
-{
-	bool result = false;
-
-	// glIsTexture will sometimes return false for real textures... do this instead.
-	if(texture != 0)
-		result = true;
-
-	return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel::mediaPanel()
-{
-	mMediaTextureHandle = 0;
-	mPickTextureHandle = 0;
-	mMediaSource = NULL;
-	mPickTexturePixels = NULL;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel::~mediaPanel()
-{
-	// delete OpenGL texture handles
-	if ( isTexture( mPickTextureHandle ) )
-	{
-		std::cerr << "remMediaPanel: deleting pick texture " << mPickTextureHandle << std::endl;
-		glDeleteTextures( 1, &mPickTextureHandle );
-		mPickTextureHandle = 0;
-	}
-
-	if ( isTexture( mMediaTextureHandle ) )
-	{
-		std::cerr << "remMediaPanel: deleting media texture " << mMediaTextureHandle << std::endl;
-		glDeleteTextures( 1, &mMediaTextureHandle );
-		mMediaTextureHandle = 0;
-	}
-
-	if(mPickTexturePixels)
-	{
-		delete mPickTexturePixels;
-	}
-
-	if(mMediaSource)
-	{
-		delete mMediaSource;
-	}
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-LLFBConnectTest::LLFBConnectTest( int app_window, int window_width, int window_height ) :
-	mVersionMajor( 2 ),
-	mVersionMinor( 0 ),
-	mVersionPatch( 0 ),
-	mMaxPanels( 25 ),
-	mViewportAspect( 0 ),
-	mAppWindow( app_window ),
-	mCurMouseX( 0 ),
-	mCurMouseY( 0 ),
-	mFuzzyMedia( true ),
-	mSelectedPanel( 0 ),
-	mDistanceCameraToSelectedGeometry( 0.0f ),
-	//mMediaBrowserControlEnableCookies( 0 ),
-	mMediaBrowserControlBackButton( 0 ),
-	mMediaBrowserControlForwardButton( 0 ),
-	//mMediaTimeControlVolume( 100 ),
-	//mMediaTimeControlSeekSeconds( 0 ),
-	//mGluiMediaTimeControlWindowFlag( true ),
-	mGluiMediaBrowserControlWindowFlag( true ),
-	mMediaBrowserControlBackButtonFlag( true ),
-	mMediaBrowserControlForwardButtonFlag( true ),
-	mHomeWebUrl( "https://cryptic-ridge-1632.herokuapp.com/" )
-{
-	// debugging spam
-	std::cout << std::endl << "             GLUT version: " << "3.7.6" << std::endl;	// no way to get real version from GLUT
-	std::cout << std::endl << "             GLUI version: " << GLUI_Master.get_version() << std::endl;
-	std::cout << std::endl << "Media Plugin Test version: " << mVersionMajor << "." << mVersionMinor << "." << mVersionPatch << std::endl;
-
-	// bookmark title
-	mBookmarks.push_back( std::pair< std::string, std::string >( "--- Bookmarks ---", "" ) );
-
-	// insert hardcoded URLs here as required for testing
-	//mBookmarks.push_back( std::pair< std::string, std::string >( "description", "url" ) );
-
-	// read bookmarks from file.
-	// note: uses command in ./CmakeLists.txt which copies bookmmarks file from source directory
-	//       to app directory (WITHOUT build configuration dir) (this is cwd in Windows within MSVC)
-	//		 For example, test_apps\llplugintest and not test_apps\llplugintest\Release
-	//		 This may need to be changed for Mac/Linux builds.
-	// See https://jira.lindenlab.com/browse/DEV-31350 for large list of media URLs from AGNI
-	const std::string bookmarks_filename( "bookmarks.txt" );
-	std::ifstream file_handle( bookmarks_filename.c_str() );
-	if ( file_handle.is_open() )
-	{
-		std::cout << "Reading bookmarks for test" << std::endl;
-		while( ! file_handle.eof() )
-		{
-			std::string line;
-			std::getline( file_handle, line );
-			if ( file_handle.eof() )
-				break;
-
-			if ( line.substr( 0, 1 ) != "#" )
-			{
-				size_t comma_pos = line.find_first_of( ',' );
-				if ( comma_pos != std::string::npos )
-				{
-					std::string description = line.substr( 0, comma_pos );
-					std::string url = line.substr( comma_pos + 1 );
-					mBookmarks.push_back( std::pair< std::string, std::string >( description, url ) );
-				}
-				else
-				{
-					mBookmarks.push_back( std::pair< std::string, std::string >( line, line ) );
-				};
-			};
-		};
-		std::cout << "Read " << mBookmarks.size() << " bookmarks" << std::endl;
-	}
-	else
-	{
-		std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl;
-	};
-
-	// initialize linden lab APR module
-	ll_init_apr();
-
-	// Set up llerror logging
-	{
-		LLError::initForApplication(".");
-		LLError::setDefaultLevel(LLError::LEVEL_INFO);
-		//LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG);
-	}
-
-	// lots of randomness in this app
-	srand( ( unsigned int )time( 0 ) );
-
-	// build GUI
-	makeChrome();
-
-	// OpenGL initialilzation
-	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
-	glClearDepth( 1.0f );
-	glEnable( GL_DEPTH_TEST );
-	glEnable( GL_COLOR_MATERIAL );
-	glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
-	glDepthFunc( GL_LEQUAL );
-	glEnable( GL_TEXTURE_2D );
-	glDisable( GL_BLEND );
-	glColor3f( 1.0f, 1.0f, 1.0f );
-	glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
-	glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
-
-	// start with a sane view
-	resetView();
-
-	// initial media panel
-	const int num_initial_panels = 1;
-	for( int i = 0; i < num_initial_panels; ++i )
-	{
-		//addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
-		addMediaPanel( mHomeWebUrl );
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-LLFBConnectTest::~LLFBConnectTest()
-{
-	// delete all media panels
-	for( int i = 0; i < (int)mMediaPanels.size(); ++i )
-	{
-		remMediaPanel( mMediaPanels[ i ] );
-	};
-	
-	// Stop the plugin read thread if it's running.
-	LLPluginProcessParent::setUseReadThread(false);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::reshape( int width, int height )
-{
-	// update viewport (the active window inside the chrome)
-	int viewport_x, viewport_y;
-	int viewport_height, viewport_width;
-	GLUI_Master.get_viewport_area( &viewport_x, &viewport_y, &viewport_width, &viewport_height );
-	mViewportAspect = (float)( viewport_width ) / (float)( viewport_height );
-	glViewport( viewport_x, viewport_y, viewport_width, viewport_height );
-
-	// save these as we'll need them later
-	mWindowWidth = width;
-	mWindowHeight = height;
-
-	// adjust size of URL bar so it doesn't get clipped
-	mUrlEdit->set_w( mWindowWidth - 360 );
-
-	// GLUI requires this
-	if ( glutGetWindow() != mAppWindow )
-		glutSetWindow( mAppWindow );
-
-	// trigger re-display
-	glutPostRedisplay();
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::bindTexture(GLuint texture, GLint row_length, GLint alignment)
-{
-	glEnable( GL_TEXTURE_2D );
-
-	glBindTexture( GL_TEXTURE_2D, texture );
-	glPixelStorei( GL_UNPACK_ROW_LENGTH, row_length );
-	glPixelStorei( GL_UNPACK_ALIGNMENT, alignment );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-bool LLFBConnectTest::checkGLError(const char *name)
-{
-	bool result = false;
-	GLenum error = glGetError();
-
-	if(error != GL_NO_ERROR)
-	{
-		// For some reason, glGenTextures is returning GL_INVALID_VALUE...
-		std::cout << name << " ERROR 0x" << std::hex << error << std::dec << std::endl;
-		result = true;
-	}
-
-	return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-GLfloat LLFBConnectTest::distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z )
-{
-	GLdouble camera_pos_x = 0.0f;
-	GLdouble camera_pos_y = 0.0f;
-	GLdouble camera_pos_z = 0.0f;
-
-	GLdouble modelMatrix[16];
-	GLdouble projMatrix[16];
-	GLint viewport[4];
-
-	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
-	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
-	glGetIntegerv(GL_VIEWPORT, viewport);
-
-	gluUnProject(
-		(viewport[2]-viewport[0])/2 , (viewport[3]-viewport[1])/2,
-		0.0,
-		modelMatrix, projMatrix, viewport,
-		&camera_pos_x, &camera_pos_y, &camera_pos_z );
-
-	GLfloat distance =
-		sqrt( ( camera_pos_x - point_x ) * ( camera_pos_x - point_x ) +
-			  ( camera_pos_y - point_y ) * ( camera_pos_y - point_y ) +
-			  ( camera_pos_z - point_z ) * ( camera_pos_z - point_z ) );
-
-	return distance;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::drawGeometry( int panel, bool selected )
-{
-	// texture coordinates for each panel
-	GLfloat non_opengl_texture_coords[ 8 ] = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
-	GLfloat opengl_texture_coords[ 8 ] =     { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
-
-	GLfloat *texture_coords = mMediaPanels[ panel ]->mAppTextureCoordsOpenGL?opengl_texture_coords:non_opengl_texture_coords;
-
-	// base coordinates for each panel
-	GLfloat base_vertex_pos[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
-
-	// calculate posiitons
-	const int num_panels = (int)mMediaPanels.size();
-	const int num_rows = (int)sqrt( (float)num_panels );
-	const int num_cols = num_panels / num_rows;
-	const int panel_x = ( panel / num_rows );
-	const int panel_y = ( panel % num_rows );
-
-	// default spacing is small - make it larger if checkbox set - for testing positional audio
-	float spacing = 0.1f;
-	//if ( mLargePanelSpacing )
-	//	spacing = 2.0f;
-
-	const GLfloat offset_x = num_cols * ( 1.0 + spacing ) / 2;
-	const GLfloat offset_y = num_rows * ( 1.0 + spacing ) / 2;
-
-	// Adjust for media aspect ratios
-	{
-		float aspect = 1.0f;
-
-		if(mMediaPanels[ panel ]->mMediaHeight != 0)
-		{
-			aspect = (float)mMediaPanels[ panel ]->mMediaWidth / (float)mMediaPanels[ panel ]->mMediaHeight;
-		}
-
-		if(aspect > 1.0f)
-		{
-			// media is wider than it is high -- adjust the top and bottom in
-			for( int corner = 0; corner < 4; ++corner )
-			{
-				float temp = base_vertex_pos[corner * 2 + 1];
-
-				if(temp < 0.5f)
-					temp += 0.5 - (0.5f / aspect);
-				else
-					temp -= 0.5 - (0.5f / aspect);
-
-				base_vertex_pos[corner * 2 + 1] = temp;
-			}
-		}
-		else if(aspect < 1.0f)
-		{
-			// media is higher than it is wide -- adjust the left and right sides in
-			for( int corner = 0; corner < 4; ++corner )
-			{
-				float temp = base_vertex_pos[corner * 2];
-
-				if(temp < 0.5f)
-					temp += 0.5f - (0.5f * aspect);
-				else
-					temp -= 0.5f - (0.5f * aspect);
-
-				base_vertex_pos[corner * 2] = temp;
-			}
-		}
-	}
-
-	glBegin( GL_QUADS );
-	for( int corner = 0; corner < 4; ++corner )
-	{
-		glTexCoord2f( texture_coords[ corner * 2 ], texture_coords[ corner * 2 + 1 ] );
-		GLfloat x = base_vertex_pos[ corner * 2 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f;
-		GLfloat y = base_vertex_pos[ corner * 2 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f;
-
-		glVertex3f( x, y, 0.0f );
-	};
-	glEnd();
-
-	// calculate distance to this panel if it's selected
-	if ( selected )
-	{
-		GLfloat point_x = base_vertex_pos[ 0 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f;
-		GLfloat point_y = base_vertex_pos[ 0 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f;
-		GLfloat point_z = 0.0f;
-		mDistanceCameraToSelectedGeometry = distanceToCamera( point_x, point_y, point_z );
-	};
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::startPanelHighlight( float red, float green, float blue, float line_width )
-{
-	glPushAttrib( GL_ALL_ATTRIB_BITS );
-	glEnable( GL_POLYGON_OFFSET_FILL );
-	glPolygonOffset( -2.5f, -2.5f );
-	glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
-	glLineWidth( line_width );
-	glColor3f( red, green, blue );
-	glDisable( GL_TEXTURE_2D );
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::endPanelHighlight()
-{
-	glPopAttrib();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::draw( int draw_type )
-{
-	for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-	{
-		// drawing pick texture
-		if ( draw_type == DrawTypePickTexture )
-		{
-			// only bother with pick if we have something to render
-			// Actually, we need to pick even if we're not ready to render.
-			// Otherwise you can't select and remove a panel which has gone bad.
-			//if ( mMediaPanels[ panel ]->mReadyToRender )
-			{
-				glMatrixMode( GL_TEXTURE );
-				glPushMatrix();
-
-				// pick texture is a power of 2 so no need to scale
-				glLoadIdentity();
-
-				// bind to media texture
-				glLoadIdentity();
-				bindTexture( mMediaPanels[ panel ]->mPickTextureHandle );
-				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
-
-				// draw geometry using pick texture
-				drawGeometry( panel, false );
-
-				glMatrixMode( GL_TEXTURE );
-				glPopMatrix();
-			};
-		}
-		else
-		if ( draw_type == DrawTypeMediaTexture )
-		{
-			bool texture_valid = false;
-			bool plugin_exited = false;
-
-			if(mMediaPanels[ panel ]->mMediaSource)
-			{
-				texture_valid = mMediaPanels[ panel ]->mMediaSource->textureValid();
-				plugin_exited = mMediaPanels[ panel ]->mMediaSource->isPluginExited();
-			}
-
-			// save texture matrix (changes for each panel)
-			glMatrixMode( GL_TEXTURE );
-			glPushMatrix();
-
-			// only process texture if the media is ready to draw
-			// (we still want to draw the geometry)
-			if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid )
-			{
-				// bind to media texture
-				bindTexture( mMediaPanels[ panel ]->mMediaTextureHandle );
-
-				if ( mFuzzyMedia )
-				{
-					glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
-					glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
-				}
-				else
-				{
-					glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-					glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
-				}
-
-				// scale to fit panel
-				glScalef( mMediaPanels[ panel ]->mTextureScaleX,
-							mMediaPanels[ panel ]->mTextureScaleY,
-								1.0f );
-			};
-
-			float intensity = plugin_exited?0.25f:1.0f;
-
-			// highlight the selected panel
-			if ( mSelectedPanel && ( mMediaPanels[ panel ]->mId == mSelectedPanel->mId ) )
-			{
-				startPanelHighlight( intensity, intensity, 0.0f, 5.0f );
-				drawGeometry( panel, true );
-				endPanelHighlight();
-			}
-			else
-			// this panel not able to render yet since it
-			// doesn't have enough information
-			if ( !mMediaPanels[ panel ]->mReadyToRender )
-			{
-				startPanelHighlight( intensity, 0.0f, 0.0f, 2.0f );
-				drawGeometry( panel, false );
-				endPanelHighlight();
-			}
-			else
-			// just display a border around the media
-			{
-				startPanelHighlight( 0.0f, intensity, 0.0f, 2.0f );
-				drawGeometry( panel, false );
-				endPanelHighlight();
-			};
-
-			if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid )
-			{
-				// draw visual geometry
-				drawGeometry( panel, false );
-			}
-
-			// restore texture matrix (changes for each panel)
-			glMatrixMode( GL_TEXTURE );
-			glPopMatrix();
-		};
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::display()
-{
-	// GLUI requires this
-	if ( glutGetWindow() != mAppWindow )
-		glutSetWindow( mAppWindow );
-
-	// start with a clean slate
-	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
-	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
-	// set up OpenGL view
-	glMatrixMode( GL_PROJECTION );
-	glLoadIdentity();
-	glFrustum( -mViewportAspect * 0.04f, mViewportAspect * 0.04f, -0.04f, 0.04f, 0.1f, 50.0f );
-	glMatrixMode( GL_MODELVIEW );
-	glLoadIdentity();
-	glTranslatef( 0.0, 0.0, 0.0f );
-	glTranslatef( mViewPos[ 0 ], mViewPos[ 1 ], -mViewPos[ 2 ] );
-	glMultMatrixf( mViewRotation );
-
-	// draw pick texture
-	draw( DrawTypePickTexture );
-
-	// read colors and get coordinate values
-	glReadPixels( mCurMouseX, mCurMouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, mPixelReadColor );
-
-	// clear the pick render (otherwise it may depth-fight with the textures rendered later)
-	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
-	// draw visible geometry
-	draw( DrawTypeMediaTexture );
-
-	glutSwapBuffers();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::idle()
-{
-//	checkGLError("LLFBConnectTest::idle");
-
-	// GLUI requires this
-	if ( glutGetWindow() != mAppWindow )
-		glutSetWindow( mAppWindow );
-
-	// random creation/destruction of panels enabled?
-/*
-	const time_t panel_timeout_time = 5;
-	if ( mRandomPanelCount )
-	{
-		// time for a change
-		static time_t last_panel_time = 0;
-		if ( time( NULL ) - last_panel_time > panel_timeout_time )
-		{
-			if ( rand() % 2 == 0 )
-			{
-				if ( mMediaPanels.size() < 16 )
-				{
-					std::cout << "Randomly adding new panel" << std::endl;
-					addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
-				};
-			}
-			else
-			{
-				if ( mMediaPanels.size() > 0 )
-				{
-					std::cout << "Deleting selected panel" << std::endl;
-					remMediaPanel( mSelectedPanel );
-				};
-			};
-			time( &last_panel_time );
-		};
-	};
-
-	// random selection of bookmarks enabled?
-	const time_t bookmark_timeout_time = 5;
-	if ( mRandomBookmarks )
-	{
-		// time for a change
-		static time_t last_bookmark_time = 0;
-		if ( time( NULL ) - last_bookmark_time > bookmark_timeout_time )
-		{
-			// go to a different random bookmark on each panel
-			for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-			{
-				std::string uri = mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second;
-
-				std::cout << "Random: navigating to : " << uri << std::endl;
-
-				std::string mime_type = mimeTypeFromUrl( uri );
-
-				if ( mime_type != mMediaPanels[ panel ]->mMimeType )
-				{
-					replaceMediaPanel( mMediaPanels[ panel ], uri );
-				}
-				else
-				{
-					mMediaPanels[ panel ]->mMediaSource->loadURI( uri );
-					mMediaPanels[ panel ]->mMediaSource->start();
-				};
-			};
-
-			time( &last_bookmark_time );
-		};
-	};
-*/
-	// update UI
-	if ( mSelectedPanel )
-	{
-		// set volume based on slider if we have time media
-		//if ( mGluiMediaTimeControlWindowFlag )
-		//{
-		//	mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f );
-		//};
-
-		// NOTE: it is absurd that we need cache the state of GLUI controls
-		//       but enabling/disabling controls drags framerate from 500+
-		//		 down to 15. Not a problem for plugin system - only this test
-		// enable/disable time based UI controls based on type of plugin
-		if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
-		{
-			/*
-			if ( ! mGluiMediaTimeControlWindowFlag )
-			{
-				mGluiMediaTimeControlWindow->enable();
-				mGluiMediaTimeControlWindowFlag = true;
-			};
-			*/
-		}
-		else
-		{
-			/*
-			if ( mGluiMediaTimeControlWindowFlag )
-			{
-				mGluiMediaTimeControlWindow->disable();
-				mGluiMediaTimeControlWindowFlag = false;
-			};
-			*/
-		};
-
-		// enable/disable browser based UI controls based on type of plugin
-		if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() )
-		{
-			if ( ! mGluiMediaBrowserControlWindowFlag )
-			{
-				mGluiMediaBrowserControlWindow->enable();
-				mGluiMediaBrowserControlWindowFlag = true;
-			};
-		}
-		else
-		{
-			if ( mGluiMediaBrowserControlWindowFlag )
-			{
-				mGluiMediaBrowserControlWindow->disable();
-				mGluiMediaBrowserControlWindowFlag = false;
-			};
-		};
-
-		// enable/disable browser back button depending on browser history
-		if ( mSelectedPanel->mMediaSource->getHistoryBackAvailable()  )
-		{
-			if ( ! mMediaBrowserControlBackButtonFlag )
-			{
-				mMediaBrowserControlBackButton->enable();
-				mMediaBrowserControlBackButtonFlag = true;
-			};
-		}
-		else
-		{
-			if ( mMediaBrowserControlBackButtonFlag )
-			{
-				mMediaBrowserControlBackButton->disable();
-				mMediaBrowserControlBackButtonFlag = false;
-			};
-		};
-
-		// enable/disable browser forward button depending on browser history
-		if ( mSelectedPanel->mMediaSource->getHistoryForwardAvailable()  )
-		{
-			if ( ! mMediaBrowserControlForwardButtonFlag )
-			{
-				mMediaBrowserControlForwardButton->enable();
-				mMediaBrowserControlForwardButtonFlag = true;
-			};
-		}
-		else
-		{
-			if ( mMediaBrowserControlForwardButtonFlag )
-			{
-				mMediaBrowserControlForwardButton->disable();
-				mMediaBrowserControlForwardButtonFlag = false;
-			};
-		};
-
-		// NOTE: This is *very* slow and not worth optimising
-		updateStatusBar();
-	};
-
-	// update all the panels
-	for( int panel_index = 0; panel_index < (int)mMediaPanels.size(); ++panel_index )
-	{
-		mediaPanel *panel = mMediaPanels[ panel_index ];
-
-		// call plugins idle function so it can potentially update itself
-		panel->mMediaSource->idle();
-
-		// update each media panel
-		updateMediaPanel( panel );
-
-		LLRect dirty_rect;
-		if ( ! panel->mMediaSource->textureValid() )
-		{
-			//std::cout << "texture invalid, skipping update..." << std::endl;
-		}
-		else
-		if ( panel &&
-			 ( panel->mMediaWidth != panel->mMediaSource->getWidth() ||
-			   panel->mMediaHeight != panel->mMediaSource->getHeight() ) )
-		{
-			//std::cout << "Resize in progress, skipping update..." << std::endl;
-		}
-		else
-		if ( panel->mMediaSource->getDirty( &dirty_rect ) )
-		{
-			const unsigned char* pixels = panel->mMediaSource->getBitsData();
-			if ( pixels && isTexture(panel->mMediaTextureHandle))
-			{
-				int x_offset = dirty_rect.mLeft;
-				int y_offset = dirty_rect.mBottom;
-				int width = dirty_rect.mRight - dirty_rect.mLeft;
-				int height = dirty_rect.mTop - dirty_rect.mBottom;
-
-				if((dirty_rect.mRight <= panel->mTextureWidth) && (dirty_rect.mTop <= panel->mTextureHeight))
-				{
-					// Offset the pixels pointer properly
-					pixels += ( y_offset * panel->mMediaSource->getTextureDepth() * panel->mMediaSource->getBitsWidth() );
-					pixels += ( x_offset * panel->mMediaSource->getTextureDepth() );
-
-					// set up texture
-					bindTexture( panel->mMediaTextureHandle, panel->mMediaSource->getBitsWidth() );
-					if ( mFuzzyMedia )
-					{
-						glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
-						glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
-					}
-					else
-					{
-						glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-						glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
-					};
-
-					checkGLError("glTexParameteri");
-
-					if(panel->mMediaSource->getTextureFormatSwapBytes())
-					{
-						glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
-						checkGLError("glPixelStorei");
-					}
-
-					// draw portion that changes into texture
-					glTexSubImage2D( GL_TEXTURE_2D, 0,
-						x_offset,
-						y_offset,
-						width,
-						height,
-						panel->mMediaSource->getTextureFormatPrimary(),
-						panel->mMediaSource->getTextureFormatType(),
-						pixels );
-
-					if(checkGLError("glTexSubImage2D"))
-					{
-						std::cerr << "    panel ID=" << panel->mId << std::endl;
-						std::cerr << "    texture size = " << panel->mTextureWidth << " x " << panel->mTextureHeight << std::endl;
-						std::cerr << "    media size = " << panel->mMediaWidth << " x " << panel->mMediaHeight << std::endl;
-						std::cerr << "    dirty rect = " << dirty_rect.mLeft << ", " << dirty_rect.mBottom << ", " << dirty_rect.mRight << ", " << dirty_rect.mTop << std::endl;
-						std::cerr << "    texture width = " << panel->mMediaSource->getBitsWidth() << std::endl;
-						std::cerr << "    format primary = 0x" << std::hex << panel->mMediaSource->getTextureFormatPrimary() << std::dec << std::endl;
-						std::cerr << "    format type = 0x" << std::hex << panel->mMediaSource->getTextureFormatType() << std::dec << std::endl;
-						std::cerr << "    pixels = " << (void*)pixels << std::endl;
-					}
-
-					if(panel->mMediaSource->getTextureFormatSwapBytes())
-					{
-						glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
-						checkGLError("glPixelStorei");
-					}
-
-					panel->mMediaSource->resetDirty();
-
-					panel->mReadyToRender = true;
-				}
-				else
-				{
-					std::cerr << "dirty rect is outside current media size, skipping update" << std::endl;
-				}
-			};
-		};
-	};
-
-	// GLUI requires this
-	if ( glutGetWindow() != mAppWindow )
-		glutSetWindow( mAppWindow );
-
-	// trigger re-display
-	glutPostRedisplay();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::windowPosToTexturePos( int window_x, int window_y,
-											   int& media_x, int& media_y,
-											   int& id )
-{
-	if ( ! mSelectedPanel )
-	{
-		media_x = 0;
-		media_y = 0;
-		id = 0;
-		return;
-	};
-
-	// record cursor poisiton for a readback next frame
-	mCurMouseX = window_x;
-	// OpenGL app == coordinate system this way
-	// NOTE: unrelated to settings in plugin - this
-	// is just for this app
-	mCurMouseY = mWindowHeight - window_y;
-
-	// extract x (0..1023, y (0..1023) and id (0..15) from RGB components
-	unsigned long pixel_read_color_bits = ( mPixelReadColor[ 0 ] << 16 ) | ( mPixelReadColor[ 1 ] << 8 ) | mPixelReadColor[ 2 ];
-	int texture_x = pixel_read_color_bits & 0x3ff;
-	int texture_y = ( pixel_read_color_bits >> 10 ) & 0x3ff;
-	id = ( pixel_read_color_bits >> 20 ) & 0x0f;
-
-	// scale to size of media (1024 because we use 10 bits for X and Y from 24)
-	media_x = (int)( ( (float)mSelectedPanel->mMediaWidth * (float)texture_x ) / 1024.0f );
-	media_y = (int)( ( (float)mSelectedPanel->mMediaHeight * (float)texture_y ) / 1024.0f );
-
-	// we assume the plugin uses an inverted coordinate scheme like OpenGL
-	// if not, the plugin code inverts the Y coordinate for us - we don't need to
-	media_y = mSelectedPanel->mMediaHeight - media_y;
-
-	if ( media_x > 0 && media_y > 0 )
-	{
-		//std::cout << "      mouse coords: " << mCurMouseX << " x " << mCurMouseY << " and id = " << id  << std::endl;
-		//std::cout << "raw texture coords: " << texture_x << " x " << texture_y << " and id = " << id  << std::endl;
-		//std::cout << "      media coords: " << media_x << " x " << media_y << " and id = " << id  << std::endl;
-		//std::cout << std::endl;
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::selectPanelById( int id )
-{
-	for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-	{
-		if ( mMediaPanels[ panel ]->mId == id )
-		{
-			selectPanel(mMediaPanels[ panel ]);
-			return;
-		};
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::selectPanel( mediaPanel* panel )
-{
-	if( mSelectedPanel == panel )
-		return;
-
-	// turn off volume before we delete it
-	if( mSelectedPanel && mSelectedPanel->mMediaSource )
-	{
-		mSelectedPanel->mMediaSource->setVolume( 0.0f );
-		mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_LOW );
-	};
-
-	mSelectedPanel = panel;
-
-	if( mSelectedPanel && mSelectedPanel->mMediaSource )
-	{
-		//mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f );
-		mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_NORMAL );
-
-		if(!mSelectedPanel->mStartUrl.empty())
-		{
-			mUrlEdit->set_text(const_cast<char*>(mSelectedPanel->mStartUrl.c_str()) );
-		}
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel*  LLFBConnectTest::findMediaPanel( LLPluginClassMedia* source )
-{
-	mediaPanel *result = NULL;
-
-	for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-	{
-		if ( mMediaPanels[ panel ]->mMediaSource == source )
-		{
-			result = mMediaPanels[ panel ];
-		}
-	}
-
-	return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel* LLFBConnectTest::findMediaPanel( const std::string &target_name )
-{
-	mediaPanel *result = NULL;
-
-	for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-	{
-		if ( mMediaPanels[ panel ]->mTarget == target_name )
-		{
-			result = mMediaPanels[ panel ];
-		}
-	}
-
-	return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::navigateToNewURI( std::string uri )
-{
-	if ( uri.length() )
-	{
-		std::string mime_type = mimeTypeFromUrl( uri );
-
-		if ( !mSelectedPanel->mMediaSource->isPluginExited() && (mime_type == mSelectedPanel->mMimeType) )
-		{
-			std::cout << "MIME type is the same" << std::endl;
-			mSelectedPanel->mMediaSource->loadURI( uri );
-			mSelectedPanel->mMediaSource->start();
-			mBookmarkList->do_selection( 0 );
-		}
-		else
-		{
-			std::cout << "MIME type changed or plugin had exited" << std::endl;
-			replaceMediaPanel( mSelectedPanel, uri );
-			mBookmarkList->do_selection( 0 );
-		}
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::initUrlHistory( std::string uris )
-{
-	if ( uris.length() > 0 )
-	{
-		std::cout << "init URL : " << uris << std::endl;
-		LLSD historySD;
-
-		char *cstr, *p;
-		cstr = new char[uris.size()+1];
-		strcpy(cstr, uris.c_str());
-		const char *DELIMS = " ,;";
-		p = strtok(cstr, DELIMS);
-		while (p != NULL) {
-			historySD.insert(0, p);
-			p = strtok(NULL, DELIMS);
-		}
-		mSelectedPanel->mMediaSource->initializeUrlHistory(historySD);
-		delete[] cstr;
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::gluiCallback( int control_id )
-{
-	if ( control_id == mIdBookmarks )
-	{
-		std::string uri = mBookmarks[ mSelBookmark ].second;
-
-		navigateToNewURI( uri );
-	}
-	else
-    if ( control_id == mIdUrlEdit)
-	{
-		std::string uri = mUrlEdit->get_text();
-
-		navigateToNewURI( uri );
-	}
-/*
-	else
-	if ( control_id == mIdUrlInitHistoryEdit )
-	{
-		std::string uri = mUrlInitHistoryEdit->get_text();
-
-		initUrlHistory( uri );
-	}
-	else
-	if ( control_id == mIdControlAddPanel )
-	{
-		addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
-	}
-	else
-	if ( control_id == mIdControlRemPanel )
-	{
-		remMediaPanel( mSelectedPanel );
-	}
-	else
-	if ( control_id == mIdDisableTimeout )
-	{
-		// Set the "disable timeout" flag for all active plugins.
-		for( int i = 0; i < (int)mMediaPanels.size(); ++i )
-		{
-			mMediaPanels[ i ]->mMediaSource->setDisableTimeout(mDisableTimeout);
-		}
-	}
-	else
-	if ( control_id == mIdUsePluginReadThread )
-	{
-		LLPluginProcessParent::setUseReadThread(mUsePluginReadThread);
-	}
-	else
-	if ( control_id == mIdControlCrashPlugin )
-	{
-		// send message to plugin and ask it to crash
-		// (switch out for ReleaseCandidate version :) )
-		if(mSelectedPanel && mSelectedPanel->mMediaSource)
-		{
-			mSelectedPanel->mMediaSource->crashPlugin();
-		}
-	}
-	else
-	if ( control_id == mIdControlHangPlugin )
-	{
-		// send message to plugin and ask it to hang
-		// (switch out for ReleaseCandidate version :) )
-		if(mSelectedPanel && mSelectedPanel->mMediaSource)
-		{
-			mSelectedPanel->mMediaSource->hangPlugin();
-		}
-	}
-	else
-*/
-	if ( control_id == mIdControlExitApp )
-	{
-		// text for exiting plugin system cleanly
-		delete this;	// clean up
-		exit( 0 );
-	}
-/*
-	else
-	if ( control_id == mIdMediaTimeControlPlay )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->setLoop( false );
-			mSelectedPanel->mMediaSource->start();
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlLoop )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->setLoop( true );
-			mSelectedPanel->mMediaSource->start();
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlPause )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->pause();
-	}
-	else
-	if ( control_id == mIdMediaTimeControlStop )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->stop();
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlSeek )
-	{
-		if ( mSelectedPanel )
-		{
-			// get value from spinner
-			float seconds_to_seek = mMediaTimeControlSeekSeconds;
-			mSelectedPanel->mMediaSource->seek( seconds_to_seek );
-			mSelectedPanel->mMediaSource->start();
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlRewind )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->setLoop( false );
-			mSelectedPanel->mMediaSource->start(-2.0f);
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlFastForward )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->setLoop( false );
-			mSelectedPanel->mMediaSource->start(2.0f);
-		};
-	}
-	else
-*/
-	if ( control_id == mIdMediaBrowserControlBack )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->browse_back();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlStop )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->browse_stop();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlForward )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->browse_forward();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlHome )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->loadURI( mHomeWebUrl );
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlReload )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->browse_reload( true );
-	}
-/*
-	else
-	if ( control_id == mIdMediaBrowserControlClearCache )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->clear_cache();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlClearCookies )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->clear_cookies();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlEnableCookies )
-	{
-		if ( mSelectedPanel )
-		{
-			if ( mMediaBrowserControlEnableCookies )
-			{
-				mSelectedPanel->mMediaSource->enable_cookies( true );
-			}
-			else
-			{
-				mSelectedPanel->mMediaSource->enable_cookies( false );
-			}
-		};
-	};
-*/
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::keyboard( int key )
-{
-	//if ( key == 'a' || key == 'A' )
-	//	addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
-	//else
-	//if ( key == 'r' || key == 'R' )
-	//	remMediaPanel( mSelectedPanel );
-	//else
-	//if ( key == 'd' || key == 'D' )
-	//	dumpPanelInfo();
-	//else
-	if ( key == 27 )
-	{
-		std::cout << "Application finished - exiting..." << std::endl;
-		delete this;
-		exit( 0 );
-	};
-
-	mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 , LLSD());
-	mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0, LLSD());
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::mouseButton( int button, int state, int x, int y )
-{
-	if ( button == GLUT_LEFT_BUTTON )
-	{
-		if ( state == GLUT_DOWN )
-		{
-			int media_x, media_y, id;
-			windowPosToTexturePos( x, y, media_x, media_y, id );
-
-			if ( mSelectedPanel )
-				mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_DOWN, 0, media_x, media_y, 0 );
-		}
-		else
-		if ( state == GLUT_UP )
-		{
-			int media_x, media_y, id;
-			windowPosToTexturePos( x, y, media_x, media_y, id );
-
-			// only select a panel if we're on a panel
-			// (HACK: strictly speaking this rules out clicking on
-			// the origin of a panel but that's very unlikely)
-			if ( media_x > 0 && media_y > 0 )
-			{
-				selectPanelById( id );
-
-				if ( mSelectedPanel )
-					mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_UP, 0, media_x, media_y, 0 );
-			};
-		};
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::mousePassive( int x, int y )
-{
-	int media_x, media_y, id;
-	windowPosToTexturePos( x, y, media_x, media_y, id );
-
-	if ( mSelectedPanel )
-		mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::mouseMove( int x, int y )
-{
-	int media_x, media_y, id;
-	windowPosToTexturePos( x, y, media_x, media_y, id );
-
-	if ( mSelectedPanel )
-		mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::makeChrome()
-{
-	// IDs used by GLUI
-	int start_id = 0x1000;
-
-	// right side window - geometry manipulators
-#if __APPLE__
-	// the Apple GLUT implementation doesn't seem to set the graphic offset of subwindows correctly when they overlap in certain ways.
-	// Use a separate controls window in this case.
-	// GLUI window at right containing manipulation controls and other buttons
-	int x = glutGet(GLUT_WINDOW_X) + glutGet(GLUT_WINDOW_WIDTH) + 4;
-	int y = glutGet(GLUT_WINDOW_Y);
-	GLUI* right_glui_window = GLUI_Master.create_glui( "", 0, x, y );
-#else
-	GLUI* right_glui_window = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_RIGHT );
-#endif
-	mViewRotationCtrl = right_glui_window->add_rotation( "Rotation", mViewRotation );
-	mViewTranslationCtrl = right_glui_window->add_translation( "Translate", GLUI_TRANSLATION_XY, mViewPos );
-	mViewTranslationCtrl->set_speed( 0.01f );
-	mViewScaleCtrl = right_glui_window->add_translation( "Scale", GLUI_TRANSLATION_Z, &mViewPos[ 2 ] );
-	mViewScaleCtrl->set_speed( 0.05f );
-	right_glui_window->set_main_gfx_window( mAppWindow );
-
-	// right side window - app controls
-	/*
-	mIdControlAddPanel = start_id++;
-	right_glui_window->add_statictext( "" );
-	right_glui_window->add_separator();
-	right_glui_window->add_statictext( "" );
-	right_glui_window->add_button( "Add panel", mIdControlAddPanel, gluiCallbackWrapper );
-	right_glui_window->add_statictext( "" );
-	mIdControlRemPanel = start_id++;
-	right_glui_window->add_button( "Rem panel", mIdControlRemPanel, gluiCallbackWrapper );
-	right_glui_window->add_statictext( "" );
-	right_glui_window->add_separator();
-	right_glui_window->add_statictext( "" );
-	mIdControlCrashPlugin = start_id++;
-	right_glui_window->add_button( "Crash plugin", mIdControlCrashPlugin, gluiCallbackWrapper );
-	mIdControlHangPlugin = start_id++;
-	right_glui_window->add_button( "Hang plugin", mIdControlHangPlugin, gluiCallbackWrapper );
-	*/
-	right_glui_window->add_statictext( "" );
-	right_glui_window->add_separator();
-	right_glui_window->add_statictext( "" );
-	mIdControlExitApp = start_id++;
-	right_glui_window->add_button( "Exit app", mIdControlExitApp, gluiCallbackWrapper );
-
-	//// top window - holds bookmark UI
-	mIdBookmarks = start_id++;
-	mSelBookmark = 0;
-	GLUI* glui_window_top = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	mBookmarkList = glui_window_top->add_listbox( "", &mSelBookmark, mIdBookmarks, gluiCallbackWrapper );
-	// only add the first 50 bookmarks - list can be very long sometimes (30,000+)
-	// when testing list of media URLs from AGNI for example
-	for( unsigned int each = 0; each < mBookmarks.size() && each < 50; ++each )
-		mBookmarkList->add_item( each, const_cast< char* >( mBookmarks[ each ].first.c_str() ) );
-	glui_window_top->set_main_gfx_window( mAppWindow );
-
-	glui_window_top->add_column( false );
-	mIdUrlEdit = start_id++;
-	mUrlEdit = glui_window_top->add_edittext( "Url:", GLUI_EDITTEXT_TEXT, 0, mIdUrlEdit, gluiCallbackWrapper );
-	mUrlEdit->set_w( 600 );
-	//GLUI* glui_window_top2 = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	//mIdUrlInitHistoryEdit = start_id++;
-	//mUrlInitHistoryEdit = glui_window_top2->add_edittext( "Init History (separate by commas or semicolons):",
-	//	GLUI_EDITTEXT_TEXT, 0, mIdUrlInitHistoryEdit, gluiCallbackWrapper );
-	//mUrlInitHistoryEdit->set_w( 800 );
-
-	// top window - media controls for "time" media types (e.g. movies)
-/*
-	mGluiMediaTimeControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	mGluiMediaTimeControlWindow->set_main_gfx_window( mAppWindow );
-	mIdMediaTimeControlPlay = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "PLAY", mIdMediaTimeControlPlay, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlLoop = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "LOOP", mIdMediaTimeControlLoop, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlPause = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "PAUSE", mIdMediaTimeControlPause, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-
-	GLUI_Button  *button;
-	mIdMediaTimeControlRewind = start_id++;
-	button = mGluiMediaTimeControlWindow->add_button( "<<", mIdMediaTimeControlRewind, gluiCallbackWrapper );
-	button->set_w(30);
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlFastForward = start_id++;
-	button = mGluiMediaTimeControlWindow->add_button( ">>", mIdMediaTimeControlFastForward, gluiCallbackWrapper );
-	button->set_w(30);
-
-	mGluiMediaTimeControlWindow->add_column( true );
-
-	mIdMediaTimeControlStop = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "STOP", mIdMediaTimeControlStop, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlVolume = start_id++;
-	GLUI_Spinner* spinner = mGluiMediaTimeControlWindow->add_spinner( "Volume", 2, &mMediaTimeControlVolume, mIdMediaTimeControlVolume, gluiCallbackWrapper);
-	spinner->set_float_limits( 0, 100 );
-	mGluiMediaTimeControlWindow->add_column( true );
-	mIdMediaTimeControlSeekSeconds = start_id++;
-	spinner = mGluiMediaTimeControlWindow->add_spinner( "", 2, &mMediaTimeControlSeekSeconds, mIdMediaTimeControlSeekSeconds, gluiCallbackWrapper);
-	spinner->set_float_limits( 0, 200 );
-	spinner->set_w( 32 );
-	spinner->set_speed( 0.025f );
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlSeek = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "SEEK", mIdMediaTimeControlSeek, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-*/
-
-	// top window - media controls for "browser" media types (e.g. web browser)
-	mGluiMediaBrowserControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	mGluiMediaBrowserControlWindow->set_main_gfx_window( mAppWindow );
-	mIdMediaBrowserControlBack = start_id++;
-	mMediaBrowserControlBackButton = mGluiMediaBrowserControlWindow->add_button( "BACK", mIdMediaBrowserControlBack, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlStop = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "STOP", mIdMediaBrowserControlStop, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlForward = start_id++;
-	mMediaBrowserControlForwardButton = mGluiMediaBrowserControlWindow->add_button( "FORWARD", mIdMediaBrowserControlForward, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlHome = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "HOME", mIdMediaBrowserControlHome, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlReload = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "RELOAD", mIdMediaBrowserControlReload, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	/*
-	mIdMediaBrowserControlClearCache = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "CLEAR CACHE", mIdMediaBrowserControlClearCache, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlClearCookies = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "CLEAR COOKIES", mIdMediaBrowserControlClearCookies, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlEnableCookies = start_id++;
-	mMediaBrowserControlEnableCookies = 0;
-	mGluiMediaBrowserControlWindow->add_checkbox( "Enable Cookies", &mMediaBrowserControlEnableCookies, mIdMediaBrowserControlEnableCookies, gluiCallbackWrapper );
-
-	// top window - misc controls
-	GLUI* glui_window_misc_control = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	mIdRandomPanelCount = start_id++;
-	mRandomPanelCount = 0;
-	glui_window_misc_control->add_checkbox( "Randomize panel count", &mRandomPanelCount, mIdRandomPanelCount, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-	mIdRandomBookmarks = start_id++;
-	mRandomBookmarks = 0;
-	glui_window_misc_control->add_checkbox( "Randomize bookmarks", &mRandomBookmarks, mIdRandomBookmarks, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-
-	mIdDisableTimeout = start_id++;
-	mDisableTimeout = 0;
-	glui_window_misc_control->add_checkbox( "Disable plugin timeout", &mDisableTimeout, mIdDisableTimeout, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-
-	mIdUsePluginReadThread = start_id++;
-	mUsePluginReadThread = 0;
-	glui_window_misc_control->add_checkbox( "Use plugin read thread", &mUsePluginReadThread, mIdUsePluginReadThread, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-
-	mIdLargePanelSpacing = start_id++;
-	mLargePanelSpacing = 0;
-	glui_window_misc_control->add_checkbox( "Large Panel Spacing", &mLargePanelSpacing, mIdLargePanelSpacing, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-*/
-	// bottom window - status
-	mBottomGLUIWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_BOTTOM );
-	mStatusText = mBottomGLUIWindow->add_statictext( "" );
-	mBottomGLUIWindow->set_main_gfx_window( mAppWindow );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::resetView()
-{
-	mViewRotationCtrl->reset();
-
-	mViewScaleCtrl->set_x( 0.0f );
-	mViewScaleCtrl->set_y( 0.0f );
-	mViewScaleCtrl->set_z( 1.3f );
-
-	mViewTranslationCtrl->set_x( 0.0f );
-	mViewTranslationCtrl->set_y( 0.0f );
-	mViewTranslationCtrl->set_z( 0.0f );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels )
-{
-	int pick_texture_width = 1024;
-	int pick_texture_height = 1024;
-	int pick_texture_depth = 3;
-	unsigned char* ptr = new unsigned char[ pick_texture_width * pick_texture_height * pick_texture_depth ];
-	for( int y = 0; y < pick_texture_height; ++y )
-	{
-		for( int x = 0; x < pick_texture_width * pick_texture_depth ; x += pick_texture_depth )
-		{
-			unsigned long bits = 0L;
-			bits |= ( id << 20 ) | ( y << 10 ) | ( x / 3 );
-			unsigned char r_component = ( bits >> 16 ) & 0xff;
-			unsigned char g_component = ( bits >> 8 ) & 0xff;
-			unsigned char b_component = bits & 0xff;
-
-			ptr[ y * pick_texture_width * pick_texture_depth + x + 0 ] = r_component;
-			ptr[ y * pick_texture_width * pick_texture_depth + x + 1 ] = g_component;
-			ptr[ y * pick_texture_width * pick_texture_depth + x + 2 ] = b_component;
-		};
-	};
-
-	glGenTextures( 1, texture_handle );
-
-	checkGLError("glGenTextures");
-	std::cout << "glGenTextures returned " << *texture_handle << std::endl;
-
-	bindTexture( *texture_handle );
-	glTexImage2D( GL_TEXTURE_2D, 0,
-					GL_RGB,
-						pick_texture_width, pick_texture_height,
-							0, GL_RGB, GL_UNSIGNED_BYTE, ptr );
-
-	*texture_pixels = ptr;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-std::string LLFBConnectTest::mimeTypeFromUrl( std::string& url )
-{
-	// default to web
-	std::string mime_type = "text/html";
-
-	// we may need a more advanced MIME type accessor later :-)
-	if ( url.find( ".mov" ) != std::string::npos )	// Movies
-		mime_type = "video/quicktime";
-	else
-	if ( url.find( ".txt" ) != std::string::npos )	// Apple Text descriptors
-		mime_type = "video/quicktime";
-	else
-	if ( url.find( ".mp3" ) != std::string::npos )	// Apple Text descriptors
-		mime_type = "video/quicktime";
-	else
-	if ( url.find( "example://" ) != std::string::npos )	// Example plugin
-		mime_type = "example/example";
-
-	return mime_type;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-std::string LLFBConnectTest::pluginNameFromMimeType( std::string& mime_type )
-{
-#if LL_DARWIN
-	std::string plugin_name( "media_plugin_null.dylib" );
-	if ( mime_type == "video/quicktime" )
-		plugin_name = "media_plugin_quicktime.dylib";
-	else
-	if ( mime_type == "text/html" )
-		plugin_name = "media_plugin_webkit.dylib";
-
-#elif LL_WINDOWS
-	std::string plugin_name( "media_plugin_null.dll" );
-
-	if ( mime_type == "video/quicktime" )
-		plugin_name = "media_plugin_quicktime.dll";
-	else
-	if ( mime_type == "text/html" )
-		plugin_name = "media_plugin_webkit.dll";
-	else
-	if ( mime_type == "example/example" )
-		plugin_name = "media_plugin_example.dll";
-
-#elif LL_LINUX
-	std::string plugin_name( "libmedia_plugin_null.so" );
-
-	if ( mime_type == "video/quicktime" )
-		plugin_name = "libmedia_plugin_quicktime.so";
-	else
-	if ( mime_type == "text/html" )
-		plugin_name = "libmedia_plugin_webkit.so";
-#endif
-	return plugin_name;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel* LLFBConnectTest::addMediaPanel( std::string url )
-{
-	// Get the plugin filename using the URL
-	std::string mime_type = mimeTypeFromUrl( url );
-	std::string plugin_name = pluginNameFromMimeType( mime_type );
-
-	// create a random size for the new media
-	int media_width;
-	int media_height;
-	getRandomMediaSize( media_width, media_height, mime_type );
-	media_width = 1024;
-	media_height = 1536;
-
-	// make a new plugin
-	LLPluginClassMedia* media_source = new LLPluginClassMedia(this);
-
-	// enable cookies so the FB login works
-	media_source->enable_cookies(true);
-
-	// tell the plugin what size we asked for
-	media_source->setSize( media_width, media_height );
-
-	// Use the launcher start and initialize the plugin
-#if LL_DARWIN || LL_LINUX
-	std::string launcher_name( "SLPlugin" );
-#elif LL_WINDOWS
-	std::string launcher_name( "SLPlugin.exe" );
-#endif
-
-	// for this test app, use the cwd as the user data path (ugh).
-#if LL_WINDOWS
-	std::string user_data_path = ".\\";
-#else
-        char cwd[ FILENAME_MAX ];
-	if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
-	{
-		std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl;
-		return NULL;
-	}
-	std::string user_data_path = std::string( cwd ) + "/";
-#endif
-	media_source->setUserDataPath(user_data_path);
-	media_source->init( launcher_name, user_data_path, plugin_name, false );
-	//media_source->setDisableTimeout(mDisableTimeout);
-
-	// make a new panel and save parameters
-	mediaPanel* panel = new mediaPanel;
-	panel->mMediaSource = media_source;
-	panel->mStartUrl = url;
-	panel->mMimeType = mime_type;
-	panel->mMediaWidth = media_width;
-	panel->mMediaHeight = media_height;
-	panel->mTextureWidth = 0;
-	panel->mTextureHeight = 0;
-	panel->mTextureScaleX = 0;
-	panel->mTextureScaleY = 0;
-	panel->mMediaTextureHandle = 0;
-	panel->mPickTextureHandle = 0;
-	panel->mAppTextureCoordsOpenGL = false;	// really need an 'undefined' state here too
-	panel->mReadyToRender = false;
-
-	// look through current media panels to find an unused index number
-	bool id_exists = true;
-	for( int nid = 0; nid < mMaxPanels; ++nid )
-	{
-		// does this id exist already?
-		id_exists = false;
-		for( int pid = 0; pid < (int)mMediaPanels.size(); ++pid )
-		{
-			if ( nid == mMediaPanels[ pid ]->mId )
-			{
-				id_exists = true;
-				break;
-			};
-		};
-
-		// id wasn't found so we can use it
-		if ( ! id_exists )
-		{
-			panel->mId = nid;
-			break;
-		};
-	};
-
-	// if we get here and this flag is set, there is no room for any more panels
-	if ( id_exists )
-	{
-		std::cout << "No room for any more panels" << std::endl;
-	}
-	else
-	{
-		// now we have the ID we can use it to make the
-		// pick texture (id is baked into texture pixels)
-		makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels );
-
-		// save this in the list of panels
-		mMediaPanels.push_back( panel );
-
-		// select the panel that was just created
-		selectPanel( panel );
-
-		// load and start the URL
-		panel->mMediaSource->loadURI( url );
-		panel->mMediaSource->start();
-
-		std::cout << "Adding new media panel for " << url << "(" << media_width << "x" << media_height << ") with index " << panel->mId << " - total panels = " << mMediaPanels.size() << std::endl;
-	}
-	
-	return panel;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::updateMediaPanel( mediaPanel* panel )
-{
-//	checkGLError("LLFBConnectTest::updateMediaPanel");
-
-	if ( ! panel )
-		return;
-
-	if(!panel->mMediaSource || !panel->mMediaSource->textureValid())
-	{
-		panel->mReadyToRender = false;
-		return;
-	}
-
-	// take a reference copy of the plugin values since they
-	// might change during this lifetime of this function
-	int plugin_media_width = panel->mMediaSource->getWidth();
-	int plugin_media_height = panel->mMediaSource->getHeight();
-	int plugin_texture_width = panel->mMediaSource->getBitsWidth();
-	int plugin_texture_height = panel->mMediaSource->getBitsHeight();
-
-	// If the texture isn't created or the media or texture dimensions changed AND
-	// the sizes are valid then we need to delete the old media texture (if necessary)
-	// then make a new one.
-	if ((panel->mMediaTextureHandle == 0 ||
-		 panel->mMediaWidth != plugin_media_width ||
-		 panel->mMediaHeight != plugin_media_height ||
-		 panel->mTextureWidth != plugin_texture_width ||
-		 panel->mTextureHeight != plugin_texture_height) &&
-		( plugin_media_width > 0 && plugin_media_height > 0 &&
-		  plugin_texture_width > 0 && plugin_texture_height > 0 ) )
-	{
-		std::cout << "Valid media size (" <<  plugin_media_width << " x " << plugin_media_height
-				<< ") and texture size (" <<  plugin_texture_width << " x " << plugin_texture_height
-				<< ") for panel with ID=" << panel->mId << " - making texture" << std::endl;
-
-		// delete old GL texture
-		if ( isTexture( panel->mMediaTextureHandle ) )
-		{
-			std::cerr << "updateMediaPanel: deleting texture " << panel->mMediaTextureHandle << std::endl;
-			glDeleteTextures( 1, &panel->mMediaTextureHandle );
-			panel->mMediaTextureHandle = 0;
-		}
-
-		std::cerr << "before: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl;
-
-		// make a GL texture based on the dimensions the plugin told us
-		GLuint new_texture = 0;
-		glGenTextures( 1, &new_texture );
-
-		checkGLError("glGenTextures");
-
-		std::cout << "glGenTextures returned " << new_texture << std::endl;
-
-		panel->mMediaTextureHandle = new_texture;
-
-		bindTexture( panel->mMediaTextureHandle );
-
-		std::cout << "Setting texture size to " << plugin_texture_width << " x " << plugin_texture_height << std::endl;
-		glTexImage2D( GL_TEXTURE_2D, 0,
-			GL_RGB,
-				plugin_texture_width, plugin_texture_height,
-					0, GL_RGB, GL_UNSIGNED_BYTE,
-						0 );
-
-
-		std::cerr << "after: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl;
-	};
-
-	// update our record of the media and texture dimensions
-	// NOTE: do this after we we check for sizes changes
-	panel->mMediaWidth = plugin_media_width;
-	panel->mMediaHeight = plugin_media_height;
-	panel->mTextureWidth = plugin_texture_width;
-	panel->mTextureHeight = plugin_texture_height;
-	if ( plugin_texture_width > 0 )
-	{
-		panel->mTextureScaleX = (double)panel->mMediaWidth / (double)panel->mTextureWidth;
-	};
-	if ( plugin_texture_height > 0 )
-	{
-		panel->mTextureScaleY = (double)panel->mMediaHeight / (double)panel->mTextureHeight;
-	};
-
-	// update the flag which tells us if the media source uses OprnGL coords or not.
-	panel->mAppTextureCoordsOpenGL = panel->mMediaSource->getTextureCoordsOpenGL();
-
-	// Check to see if we have enough to render this panel.
-	// If we do, set a flag that the display functions use so
-	// they only render a panel with media if it's ready.
-	if ( panel->mMediaWidth < 0 ||
-		 panel->mMediaHeight < 0 ||
-		 panel->mTextureWidth < 1 ||
-		 panel->mTextureHeight < 1 ||
-		 panel->mMediaTextureHandle == 0 )
-	{
-		panel->mReadyToRender = false;
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel* LLFBConnectTest::replaceMediaPanel( mediaPanel* panel, std::string url )
-{
-	// no media panels so we can't change anything - have to add
-	if ( mMediaPanels.size() == 0 )
-		return NULL;
-
-	// sanity check
-	if ( ! panel )
-		return NULL;
-
-	int index;
-	for(index = 0; index < (int)mMediaPanels.size(); index++)
-	{
-		if(mMediaPanels[index] == panel)
-			break;
-	}
-
-	if(index >= (int)mMediaPanels.size())
-	{
-		// panel isn't in mMediaPanels
-		return NULL;
-	}
-
-	std::cout << "Replacing media panel with index " << panel->mId << std::endl;
-
-	int panel_id = panel->mId;
-
-	if(mSelectedPanel == panel)
-		mSelectedPanel = NULL;
-
-	delete panel;
-
-	// Get the plugin filename using the URL
-	std::string mime_type = mimeTypeFromUrl( url );
-	std::string plugin_name = pluginNameFromMimeType( mime_type );
-
-	// create a random size for the new media
-	int media_width;
-	int media_height;
-	getRandomMediaSize( media_width, media_height, mime_type );
-
-	// make a new plugin
-	LLPluginClassMedia* media_source = new LLPluginClassMedia(this);
-
-	// tell the plugin what size we asked for
-	media_source->setSize( media_width, media_height );
-
-	// Use the launcher start and initialize the plugin
-#if LL_DARWIN || LL_LINUX
-	std::string launcher_name( "SLPlugin" );
-#elif LL_WINDOWS
-	std::string launcher_name( "SLPlugin.exe" );
-#endif
-
-	// for this test app, use the cwd as the user data path (ugh).
-#if LL_WINDOWS
-	std::string user_data_path = ".\\";
-#else
-        char cwd[ FILENAME_MAX ];
-	if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
-	{
-		std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl;
-		return NULL;
-	}
-	std::string user_data_path = std::string( cwd ) + "/";
-#endif
-
-	media_source->setUserDataPath(user_data_path);
-	media_source->init( launcher_name, user_data_path, plugin_name, false );
-	//media_source->setDisableTimeout(mDisableTimeout);
-
-	// make a new panel and save parameters
-	panel = new mediaPanel;
-	panel->mMediaSource = media_source;
-	panel->mStartUrl = url;
-	panel->mMimeType = mime_type;
-	panel->mMediaWidth = media_width;
-	panel->mMediaHeight = media_height;
-	panel->mTextureWidth = 0;
-	panel->mTextureHeight = 0;
-	panel->mTextureScaleX = 0;
-	panel->mTextureScaleY = 0;
-	panel->mMediaTextureHandle = 0;
-	panel->mPickTextureHandle = 0;
-	panel->mAppTextureCoordsOpenGL = false;	// really need an 'undefined' state here too
-	panel->mReadyToRender = false;
-
-	panel->mId = panel_id;
-
-	// Replace the entry in the panels array
-	mMediaPanels[index] = panel;
-
-	// now we have the ID we can use it to make the
-	// pick texture (id is baked into texture pixels)
-	makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels );
-
-	// select the panel that was just created
-	selectPanel( panel );
-
-	// load and start the URL
-	panel->mMediaSource->loadURI( url );
-	panel->mMediaSource->start();
-	
-	return panel;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::getRandomMediaSize( int& width, int& height, std::string mime_type )
-{
-	// Make a new media source with a random size which we'll either
-	// directly or the media plugin will tell us what it wants later.
-	// Use a random size so we can test support for weird media sizes.
-	// (Almost everything else will get filled in later once the
-	// plugin responds)
-	// NB. Do we need to enforce that width is on 4 pixel boundary?
-	width = ( ( rand() % 170 ) + 30 ) * 4;
-	height = ( ( rand() % 170 ) + 30 ) * 4;
-
-	// adjust this random size if it's a browser so we get
-	// a more useful size for testing..
-	if ( mime_type == "text/html" || mime_type == "example/example"  )
-	{
-		width = ( ( rand() % 100 ) + 100 ) * 4;
-		height = ( width * ( ( rand() % 400 ) + 1000 ) ) / 1000;
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::remMediaPanel( mediaPanel* panel )
-{
-	// always leave one panel
-	if ( mMediaPanels.size() == 1 )
-		return;
-
-	// sanity check - don't think this can happen but see above for a case where it might...
-	if ( ! panel )
-		return;
-
-	std::cout << "Removing media panel with index " << panel->mId << " - total panels = " << mMediaPanels.size() - 1 << std::endl;
-
-	if(mSelectedPanel == panel)
-		mSelectedPanel = NULL;
-
-	delete panel;
-
-	// remove from storage list
-	for( int i = 0; i < (int)mMediaPanels.size(); ++i )
-	{
-		if ( mMediaPanels[ i ] == panel )
-		{
-			mMediaPanels.erase( mMediaPanels.begin() + i );
-			break;
-		};
-	};
-
-	// select the first panel
-	selectPanel( mMediaPanels[ 0 ] );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::updateStatusBar()
-{
-	if ( ! mSelectedPanel )
-		return;
-
-	// cache results - this is a very slow function
-	static int cached_id = -1;
-	static int cached_media_width = -1;
-	static int cached_media_height = -1;
-	static int cached_texture_width = -1;
-	static int cached_texture_height = -1;
-	static bool cached_supports_browser_media = true;
-	static bool cached_supports_time_media = false;
-	static int cached_movie_time = -1;
-	static GLfloat cached_distance = -1.0f;
-
-	static std::string cached_plugin_version = "";
-	if (
-		 cached_id == mSelectedPanel->mId &&
-		 cached_media_width == mSelectedPanel->mMediaWidth &&
-		 cached_media_height  == mSelectedPanel->mMediaHeight &&
-		 cached_texture_width == mSelectedPanel->mTextureWidth &&
-		 cached_texture_height == mSelectedPanel->mTextureHeight &&
-		 cached_supports_browser_media == mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() &&
-		 cached_supports_time_media == mSelectedPanel->mMediaSource->pluginSupportsMediaTime() &&
-		 cached_plugin_version == mSelectedPanel->mMediaSource->getPluginVersion() &&
-		 cached_movie_time == (int)mSelectedPanel->mMediaSource->getCurrentTime() &&
-		 cached_distance == mDistanceCameraToSelectedGeometry
-	   )
-	{
-		// nothing changed so don't spend time here
-		return;
-	};
-
-	std::ostringstream stream( "" );
-
-	stream.str( "" );
-	stream.clear();
-
-	stream << "Id: ";
-	stream << std::setw( 2 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mId;
-	stream << " | ";
-	stream << "Media: ";
-	stream << std::setw( 3 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mMediaWidth;
-	stream << " x ";
-	stream << std::setw( 3 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mMediaHeight;
-	stream << " | ";
-	stream << "Texture: ";
-	stream << std::setw( 4 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mTextureWidth;
-	stream << " x ";
-	stream << std::setw( 4 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mTextureHeight;
-
-	stream << " | ";
-	stream << "Distance: ";
-	stream << std::setw( 6 );
-	stream << std::setprecision( 3 );
-	stream << std::setprecision( 3 );
-	stream << mDistanceCameraToSelectedGeometry;
-	stream << " | ";
-
-	if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() )
-		stream << "BROWSER";
-	else
-	if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
-		stream << "TIME   ";
-	stream << " | ";
-	stream << mSelectedPanel->mMediaSource->getPluginVersion();
-	stream << " | ";
-	if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
-	{
-		stream << std::setw( 3 ) << std::setfill( '0' );
-		stream << (int)mSelectedPanel->mMediaSource->getCurrentTime();
-		stream << " / ";
-		stream << std::setw( 3 ) << std::setfill( '0' );
-		stream << (int)mSelectedPanel->mMediaSource->getDuration();
-		stream << " @ ";
-		stream << (int)mSelectedPanel->mMediaSource->getCurrentPlayRate();
-		stream << " | ";
-	};
-
-	glutSetWindow( mBottomGLUIWindow->get_glut_window_id() );
-	mStatusText->set_text( const_cast< char*>( stream.str().c_str() ) );
-	glutSetWindow( mAppWindow );
-
-	// caching
-	cached_id = mSelectedPanel->mId;
-	cached_media_width = mSelectedPanel->mMediaWidth;
-	cached_media_height = mSelectedPanel->mMediaHeight;
-	cached_texture_width = mSelectedPanel->mTextureWidth;
-	cached_texture_height = mSelectedPanel->mTextureHeight;
-	cached_supports_browser_media = mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser();
-	cached_supports_time_media = mSelectedPanel->mMediaSource->pluginSupportsMediaTime();
-	cached_plugin_version = mSelectedPanel->mMediaSource->getPluginVersion();
-	cached_movie_time = (int)mSelectedPanel->mMediaSource->getCurrentTime();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::dumpPanelInfo()
-{
-	std::cout << std::endl << "===== Media Panels =====" << std::endl;
-	for( int i = 0; i < (int)mMediaPanels.size(); ++i )
-	{
-		std::cout << std::setw( 2 ) << std::setfill( '0' );
-		std::cout << i + 1 << "> ";
-		std::cout << "Id: ";
-		std::cout << std::setw( 2 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mId;
-		std::cout << " | ";
-		std::cout << "Media: ";
-		std::cout << std::setw( 3 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mMediaWidth;
-		std::cout << " x ";
-		std::cout << std::setw( 3 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mMediaHeight;
-		std::cout << " | ";
-		std::cout << "Texture: ";
-		std::cout << std::setw( 4 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mTextureWidth;
-		std::cout << " x ";
-		std::cout << std::setw( 4 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mTextureHeight;
-		std::cout << " | ";
-		if ( mMediaPanels[ i ] == mSelectedPanel )
-			std::cout << "(selected)";
-
-		std::cout << std::endl;
-	};
-	std::cout << "========================" << std::endl;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLFBConnectTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
-{
-	// Uncomment this to make things much, much quieter.
-//	return;
-
-	switch(event)
-	{
-		case MEDIA_EVENT_CONTENT_UPDATED:
-			// too spammy -- don't log these
-//			std::cerr <<  "Media event:  MEDIA_EVENT_CONTENT_UPDATED " << std::endl;
-		break;
-
-		case MEDIA_EVENT_TIME_DURATION_UPDATED:
-			// too spammy -- don't log these
-//			std::cerr <<  "Media event:  MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << std::endl;
-		break;
-
-		case MEDIA_EVENT_SIZE_CHANGED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_SIZE_CHANGED " << std::endl;
-		break;
-
-		case MEDIA_EVENT_CURSOR_CHANGED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << std::endl;
-		break;
-
-		case MEDIA_EVENT_NAVIGATE_BEGIN:
-			std::cerr <<  "Media event:  MEDIA_EVENT_NAVIGATE_BEGIN " << std::endl;
-		break;
-
-		case MEDIA_EVENT_NAVIGATE_COMPLETE:
-			std::cerr <<  "Media event:  MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << std::endl;
-		break;
-
-		case MEDIA_EVENT_PROGRESS_UPDATED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << std::endl;
-		break;
-
-		case MEDIA_EVENT_STATUS_TEXT_CHANGED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << std::endl;
-		break;
-
-		case MEDIA_EVENT_NAME_CHANGED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_NAME_CHANGED, new name is: " << self->getMediaName() << std::endl;
-			glutSetWindowTitle( self->getMediaName().c_str() );
-		break;
-
-		case MEDIA_EVENT_LOCATION_CHANGED:
-		{
-			std::cerr <<  "Media event:  MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << std::endl;
-			mediaPanel* panel = findMediaPanel(self);
-			if(panel != NULL)
-			{
-				panel->mStartUrl = self->getLocation();
-				if(panel == mSelectedPanel)
-				{
-					mUrlEdit->set_text(const_cast<char*>(panel->mStartUrl.c_str()) );
-				}
-			}
-		}
-		break;
-
-		case MEDIA_EVENT_NAVIGATE_ERROR_PAGE:
-			std::cerr <<  "Media event:  MEDIA_EVENT_NAVIGATE_ERROR_PAGE, uri is: " << self->getClickURL() << std::endl;
-		break;
-			
-		case MEDIA_EVENT_CLICK_LINK_HREF:
-		{
-			std::cerr <<  "Media event:  MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << ", target is " << self->getClickTarget() << std::endl;
-			// retrieve the event parameters
-			std::string url = self->getClickURL();
-			std::string target = self->getClickTarget();
-			
-			if(target == "_external")
-			{
-				// this should open in an external browser, but since this is a test app we don't care.
-			}
-			else if(target == "_blank")
-			{
-				// Create a new panel with the specified URL.
-				addMediaPanel(url);
-			}
-			else // other named target
-			{
-				mediaPanel *target_panel = findMediaPanel(target);
-				if(target_panel)
-				{
-					target_panel = replaceMediaPanel(target_panel, url);
-				}
-				else
-				{
-					target_panel = addMediaPanel(url);
-				}
-
-				if(target_panel)
-				{
-					target_panel->mTarget = target;
-				}
-			}
-		}
-		break;
-
-		case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
-			std::cerr <<  "Media event:  MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << std::endl;
-		break;
-
-		case MEDIA_EVENT_PLUGIN_FAILED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED" << std::endl;
-		break;
-
-		case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH:
-			std::cerr <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << std::endl;
-		break;
-
-		case MEDIA_EVENT_CLOSE_REQUEST:
-			std::cerr <<  "Media event:  MEDIA_EVENT_CLOSE_REQUEST" << std::endl;
-		break;
-		
-		case MEDIA_EVENT_PICK_FILE_REQUEST:
-			std::cerr <<  "Media event:  MEDIA_EVENT_PICK_FILE_REQUEST" << std::endl;
-			// TODO: display an actual file picker
-			self->sendPickFileResponse("cake");
-		break;
-
-		case MEDIA_EVENT_GEOMETRY_CHANGE:
-			std::cerr <<  "Media event:  MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() 
-				<< ", x = " << self->getGeometryX() 
-				<< ", y = " << self->getGeometryY() 
-				<< ", width = " << self->getGeometryWidth() 
-				<< ", height = " << self->getGeometryHeight() 
-				<< std::endl;
-		break;
-
-		case MEDIA_EVENT_AUTH_REQUEST:
-		{
-			//std::cerr <<  "Media event:  MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() ", realm " << self->getAuthRealm() << std::endl;
-
-			// TODO: display an auth dialog
-			self->sendAuthResponse(false, "", "");
-		}
-		break;
-
-		case MEDIA_EVENT_LINK_HOVERED:
-		{
-			std::cerr <<  "Media event:  MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << std::endl;
-		}
-		break;
-
-		default:
-		{
-			std::cerr <<  "Media event:  <unknown>, code is: " << int(event) << std::endl;
-		}
-		break;
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-static void gluiCallbackWrapper( int control_id )
-{
-	if ( gApplication )
-		gApplication->gluiCallback( control_id );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutReshape( int width, int height )
-{
-	if ( gApplication )
-		gApplication->reshape( width, height );
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutDisplay()
-{
-	if ( gApplication )
-		gApplication->display();
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutIdle(int update_ms)
-{
-	GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms);
-
-	if ( gApplication )
-		gApplication->idle();
-
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutKeyboard( unsigned char key, int x, int y )
-{
-	if ( gApplication )
-		gApplication->keyboard( key );
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutMousePassive( int x, int y )
-{
-	if ( gApplication )
-		gApplication->mousePassive( x, y );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutMouseMove( int x , int y )
-{
-	if ( gApplication )
-		gApplication->mouseMove( x, y );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutMouseButton( int button, int state, int x, int y )
-{
-	if ( gApplication )
-		gApplication->mouseButton( button, state, x, y );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-int main( int argc, char* argv[] )
-{
-#if LL_DARWIN
-	// Set the current working directory to <application bundle>/Contents/Resources/
-	CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
-	if(resources_url != NULL)
-	{
-		CFStringRef resources_string = CFURLCopyFileSystemPath(resources_url, kCFURLPOSIXPathStyle);
-		CFRelease(resources_url);
-		if(resources_string != NULL)
-		{
-			char buffer[PATH_MAX] = "";
-			if(CFStringGetCString(resources_string, buffer, sizeof(buffer), kCFStringEncodingUTF8))
-			{
-				chdir(buffer);
-			}
-			CFRelease(resources_string);
-		}
-	}
-#endif
-
-	glutInit( &argc, argv );
-	glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
-
-	const int app_window_x = 80;
-	const int app_window_y = 0;
-	const int app_window_width = 960;
-	const int app_window_height = 960;
-
-	glutInitWindowPosition( app_window_x, app_window_y );
-	glutInitWindowSize( app_window_width, app_window_height );
-
-	int app_window_handle = glutCreateWindow( "LLFBConnectTest" );
-
-	glutDisplayFunc( glutDisplay );
-
-	GLUI_Master.set_glutReshapeFunc( glutReshape );
-	GLUI_Master.set_glutKeyboardFunc( glutKeyboard );
-	GLUI_Master.set_glutMouseFunc( glutMouseButton );
-
-	glutPassiveMotionFunc( glutMousePassive );
-	glutMotionFunc( glutMouseMove );
-
-	glutSetWindow( app_window_handle );
-
-	gApplication = new LLFBConnectTest( app_window_handle, app_window_width, app_window_height );
-
-	// update at approximately 60hz
-	int update_ms = 1000 / 60;
-
-	GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms);
-
-	glutMainLoop();
-
-	delete gApplication;
-}
diff --git a/indra/test_apps/llfbconnecttest/llfbconnecttest.h b/indra/test_apps/llfbconnecttest/llfbconnecttest.h
deleted file mode 100644
index 77e4d096d0..0000000000
--- a/indra/test_apps/llfbconnecttest/llfbconnecttest.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * @file LLFBConnectTest.cpp
- * @brief Facebook Connect Test App
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_FB_CONNECT_H
-#define LL_FB_CONNECT_H
-
-#include <vector>
-#include <string>
-#include "llpluginclassmedia.h"
-#include "llgl.h"
-
-// Forward declarations
-class GLUI_Rotation;
-class GLUI_Translation;
-class GLUI_Listbox;
-class GLUI_EditText;
-class GLUI_StaticText;
-class GLUI;
-class GLUI_Button;
-
-////////////////////////////////////////////////////////////////////////////////
-//
-struct mediaPanel
-{
-	public:
-		mediaPanel();
-		~mediaPanel();
-		int mId;
-		std::string mStartUrl;
-		std::string mMimeType;
-		std::string mTarget;
-		LLPluginClassMedia *mMediaSource;
-		int mMediaWidth;
-		int mMediaHeight;
-		int mTextureWidth;
-		int mTextureHeight;
-		double mTextureScaleX;
-		double mTextureScaleY;
-		GLuint mMediaTextureHandle;
-		GLuint mPickTextureHandle;
-		unsigned char* mPickTexturePixels;
-		bool mAppTextureCoordsOpenGL;
-		bool mReadyToRender;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-class LLFBConnectTest : public LLPluginClassMediaOwner
-{
-	public:
-		LLFBConnectTest( int app_window, int window_width, int window_height );
-		~LLFBConnectTest();
-
-		void reshape( int width, int height );
-		void display();
-		void idle();
-		void gluiCallback( int control_id );
-		void keyboard( int key );
-		void mousePassive( int x, int y );
-		void mouseButton( int button, int state, int x, int y );
-		void mouseMove( int x, int y );
-
-		void bindTexture(GLuint texture, GLint row_length = 0, GLint alignment = 1);
-		bool checkGLError(const char *name = "OpenGL");
-		void drawGeometry( int panel, bool selected );
-		void startPanelHighlight( float red, float green, float blue, float line_width );
-		void endPanelHighlight();
-		enum { DrawTypePickTexture, DrawTypeMediaTexture };
-		void draw( int draw_type );
-		void windowPosToTexturePos( int window_x, int window_y, int& media_x, int& media_y, int& id );
-
-		mediaPanel* addMediaPanel( std::string url );
-		void updateMediaPanel( mediaPanel* panel );
-		void remMediaPanel( mediaPanel* panel );
-		mediaPanel* replaceMediaPanel( mediaPanel* panel, std::string url );
-		void getRandomMediaSize( int& width, int& height, std::string mime_type );
-		void navigateToNewURI( std::string uri );
-        void initUrlHistory( std::string uri );
-		void selectPanelById( int id );
-		void selectPanel( mediaPanel* panel );
-		mediaPanel* findMediaPanel( LLPluginClassMedia* panel );
-		mediaPanel* findMediaPanel( const std::string &target_name );
-		void makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels );
-		void makeChrome();
-		void resetView();
-
-		void dumpPanelInfo();
-		void updateStatusBar();
-
-		GLfloat distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z );
-		
-
-	// Inherited from LLPluginClassMediaOwner
-	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent);
-
-	private:
-		const int mVersionMajor;
-		const int mVersionMinor;
-		const int mVersionPatch;
-		const int mMaxPanels;
-		int mAppWindow;
-		int mWindowWidth;
-		int mWindowHeight;
-		int mCurMouseX;
-		int mCurMouseY;
-		unsigned char mPixelReadColor[ 3 ];
-		bool mFuzzyMedia;
-		const std::string mHomeWebUrl;
-
-		std::vector< mediaPanel* > mMediaPanels;
-		mediaPanel* mSelectedPanel;
-		std::string mimeTypeFromUrl( std::string& url );
-		std::string pluginNameFromMimeType( std::string& mime_type );
-
-		GLUI_Rotation* mViewRotationCtrl;
-		GLUI_Translation* mViewScaleCtrl;
-		GLUI_Translation* mViewTranslationCtrl;
-		float mViewportAspect;
-		float mViewPos[ 3 ];
-		float mViewRotation[ 16 ];
-
-		float mDistanceCameraToSelectedGeometry;
-
-		std::vector< std::pair< std::string, std::string > > mBookmarks;
-		GLUI_Listbox* mBookmarkList;
-		int mIdBookmarks;
-		int mIdUrlEdit;
-		GLUI_EditText* mUrlEdit;
-		int mSelBookmark;
-
-		int mIdControlExitApp;
-
-		GLUI* mGluiMediaBrowserControlWindow;
-		int mIdMediaBrowserControlBack;
-		GLUI_Button* mMediaBrowserControlBackButton;
-		int mIdMediaBrowserControlStop;
-		int mIdMediaBrowserControlForward;
-		GLUI_Button* mMediaBrowserControlForwardButton;
-		bool mGluiMediaBrowserControlWindowFlag;
-		bool mMediaBrowserControlBackButtonFlag;
-		bool mMediaBrowserControlForwardButtonFlag;
-		int mIdMediaBrowserControlHome;
-		int mIdMediaBrowserControlReload;
-
-		GLUI* mBottomGLUIWindow;
-		GLUI_StaticText* mStatusText;
-};
-
-#endif	// LL_FB_CONNECT_H
-
diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt
index 0c8bdc464d..18f7e36d20 100755
--- a/indra/test_apps/llplugintest/CMakeLists.txt
+++ b/indra/test_apps/llplugintest/CMakeLists.txt
@@ -254,138 +254,8 @@ endif (DARWIN)
 #  )
 #endif (DARWIN)
 
-### llmediaplugintest
-
-set(llmediaplugintest_SOURCE_FILES
-    llmediaplugintest.cpp
-    llmediaplugintest.h
-    bookmarks.txt
-    )
-
-add_executable(llmediaplugintest
-    WIN32
-    MACOSX_BUNDLE
-    ${llmediaplugintest_SOURCE_FILES}
-)
-
-set_target_properties(llmediaplugintest
-    PROPERTIES
-    WIN32_EXECUTABLE
-    FALSE
-)
-
-target_link_libraries(llmediaplugintest
-  ${GLUT_LIBRARY}
-  ${GLUI_LIBRARY}
-  ${OPENGL_LIBRARIES}
-  ${LLPLUGIN_LIBRARIES}
-  ${LLMESSAGE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${PLUGIN_API_WINDOWS_LIBRARIES}
-)
-
-if (DARWIN)
-  # The testbed needs to use a couple of CoreFoundation calls now, to deal with being a bundled app.
-  target_link_libraries(llmediaplugintest
-    ${COREFOUNDATION_LIBRARY}
-  )
-endif (DARWIN)
-
-add_dependencies(llmediaplugintest
-  stage_third_party_libs
-  SLPlugin
-  media_plugin_quicktime
-  media_plugin_webkit
-  media_plugin_example
-  ${LLPLUGIN_LIBRARIES}
-  ${LLMESSAGE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-)
-
-# turn off weird GLUI pragma 
-add_definitions(-DGLUI_NO_LIB_PRAGMA)
-
-if (DARWIN OR LINUX)
-  # glui.h contains code that triggers the "overloaded-virtual" warning in gcc.  
-  set_source_files_properties(llmediaplugintest.cpp PROPERTIES COMPILE_FLAGS "-Wno-overloaded-virtual")
-endif (DARWIN OR LINUX)
-
 # Gather build products of the various dependencies into the build directory for the testbed.
 
-if (DARWIN)
-  # path inside the app bundle where we'll need to copy plugins and other related files
-  set(PLUGINS_DESTINATION_DIR
-    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llmediaplugintest.app/Contents/Resources
-  )
-  
-  # create the Contents/Resources directory
-  add_custom_command(
-    TARGET llmediaplugintest POST_BUILD
-    COMMAND ${CMAKE_COMMAND}
-    ARGS
-      -E
-      make_directory
-      ${PLUGINS_DESTINATION_DIR}
-    COMMENT "Creating Resources directory in app bundle."
-  ) 
-else (DARWIN)
-  set(PLUGINS_DESTINATION_DIR
-    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
-  )
-endif (DARWIN)
-
-set(BUILT_SLPLUGIN $<TARGET_FILE:SLPlugin>)
-add_custom_command(TARGET llmediaplugintest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN}  ${PLUGINS_DESTINATION_DIR}
-  DEPENDS ${BUILT_SLPLUGIN}
-)
-
-set(BUILT_LLCOMMON $<TARGET_FILE:llcommon>)
-add_custom_command(TARGET llmediaplugintest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON}  ${PLUGINS_DESTINATION_DIR}
-  DEPENDS ${BUILT_LLCOMMON}
-)
-
-set(BUILT_WEBKIT_PLUGIN $<TARGET_FILE:media_plugin_webkit>)
-add_custom_command(TARGET llmediaplugintest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN}  ${PLUGINS_DESTINATION_DIR}
-  DEPENDS ${BUILT_WEBKIT_PLUGIN}
-)
-
-if (DARWIN OR WINDOWS)
-  set(BUILT_QUICKTIME_PLUGIN $<TARGET_FILE:media_plugin_quicktime>)
-  add_custom_command(TARGET llmediaplugintest POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_QUICKTIME_PLUGIN}  ${PLUGINS_DESTINATION_DIR}
-    DEPENDS ${BUILT_QUICKTIME_PLUGIN}
-  )
-endif (DARWIN OR WINDOWS)
-
-set(BUILT_EXAMPLE_PLUGIN $<TARGET_FILE:media_plugin_example>)
-add_custom_command(TARGET llmediaplugintest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_EXAMPLE_PLUGIN}  ${PLUGINS_DESTINATION_DIR}
-  DEPENDS ${BUILT_EXAMPLE_PLUGIN}
-)
-
-# copy over bookmarks file if llmediaplugintest gets built
-set(BUILT_LLMEDIAPLUGINTEST $<TARGET_FILE:llmediaplugintest>)
-add_custom_command(TARGET llmediaplugintest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/
-  DEPENDS ${BUILT_LLMEDIAPLUGINTEST}
-)
-
-# also copy it to the same place as SLPlugin, which is what the mac wants...
-add_custom_command(TARGET llmediaplugintest POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR}
-  DEPENDS ${BUILT_LLMEDIAPLUGINTEST}
-)
-
-if (DARWIN)
-#   add_custom_command(TARGET llmediaplugintest POST_BUILD
-#     COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${PLUGINS_DESTINATION_DIR}
-#     DEPENDS ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib
-#   )
-endif (DARWIN)
-
 if(WINDOWS)
   #********************
   # Plugin test library deploy
@@ -402,7 +272,6 @@ if(WINDOWS)
     qtguid4.dll
     qtnetworkd4.dll
     qtopengld4.dll
-    qtwebkitd4.dll
     ssleay32.dll
     )
   copy_if_different(
@@ -459,7 +328,6 @@ if(WINDOWS)
     qtgui4.dll
     qtnetwork4.dll
     qtopengl4.dll
-    qtwebkit4.dll
     qtxmlpatterns4.dll
     ssleay32.dll
     )
@@ -534,8 +402,6 @@ if(WINDOWS)
      ${plugin_test_targets}
      )
 
-  add_dependencies(llmediaplugintest copy_plugintest_libs)
-
 endif(WINDOWS)
 
 if (DARWIN)
@@ -553,8 +419,6 @@ if (DARWIN)
     libQtNetwork.4.dylib
     libQtOpenGL.4.7.1.dylib
     libQtOpenGL.4.dylib
-    libQtWebKit.4.7.1.dylib
-    libQtWebKit.4.dylib
     libQtSvg.4.7.1.dylib
     libQtSvg.4.dylib
     libQtXml.4.7.1.dylib
@@ -607,7 +471,5 @@ if (DARWIN)
     ${plugin_test_targets}
     )
 
-  add_dependencies(llmediaplugintest copy_plugintest_libs)
 endif (DARWIN)
 
-ll_deploy_sharedlibs_command(llmediaplugintest) 
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
deleted file mode 100755
index fa4f5abd28..0000000000
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ /dev/null
@@ -1,2377 +0,0 @@
-/**
- * @file LLMediaPluginTest.cpp
- * @brief Primary test application for LLMedia (Separate Process) Plugin system
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include "indra_constants.h"
-
-#include "llapr.h"
-#include "llerrorcontrol.h"
-
-#include <math.h>
-#include <iomanip>
-#include <sstream>
-#include <ctime>
-
-#include "llmediaplugintest.h"
-
-
-#if LL_WINDOWS
-#pragma warning(disable: 4263)
-#pragma warning(disable: 4264)
-#endif
-
-#if __APPLE__
-	#include <GLUT/glut.h>
-	#include <CoreFoundation/CoreFoundation.h>
-#else
-	#define FREEGLUT_STATIC
-	#include "GL/freeglut.h"
-	#define GLUI_FREEGLUT
-#endif
-
-#include "glui.h"
-
-
-LLMediaPluginTest* gApplication = 0;
-static void gluiCallbackWrapper( int control_id );
-
-////////////////////////////////////////////////////////////////////////////////
-//
-static bool isTexture( GLuint texture )
-{
-	bool result = false;
-
-	// glIsTexture will sometimes return false for real textures... do this instead.
-	if(texture != 0)
-		result = true;
-
-	return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel::mediaPanel()
-{
-	mMediaTextureHandle = 0;
-	mPickTextureHandle = 0;
-	mMediaSource = NULL;
-	mPickTexturePixels = NULL;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel::~mediaPanel()
-{
-	// delete OpenGL texture handles
-	if ( isTexture( mPickTextureHandle ) )
-	{
-		std::cerr << "remMediaPanel: deleting pick texture " << mPickTextureHandle << std::endl;
-		glDeleteTextures( 1, &mPickTextureHandle );
-		mPickTextureHandle = 0;
-	}
-
-	if ( isTexture( mMediaTextureHandle ) )
-	{
-		std::cerr << "remMediaPanel: deleting media texture " << mMediaTextureHandle << std::endl;
-		glDeleteTextures( 1, &mMediaTextureHandle );
-		mMediaTextureHandle = 0;
-	}
-
-	if(mPickTexturePixels)
-	{
-		delete mPickTexturePixels;
-	}
-
-	if(mMediaSource)
-	{
-		delete mMediaSource;
-	}
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int window_height ) :
-	mVersionMajor( 2 ),
-	mVersionMinor( 0 ),
-	mVersionPatch( 0 ),
-	mMaxPanels( 25 ),
-	mViewportAspect( 0 ),
-	mAppWindow( app_window ),
-	mCurMouseX( 0 ),
-	mCurMouseY( 0 ),
-	mFuzzyMedia( true ),
-	mSelectedPanel( 0 ),
-	mDistanceCameraToSelectedGeometry( 0.0f ),
-	mMediaBrowserControlEnableCookies( 0 ),
-	mMediaBrowserControlBackButton( 0 ),
-	mMediaBrowserControlForwardButton( 0 ),
-	mMediaTimeControlVolume( 100 ),
-	mMediaTimeControlSeekSeconds( 0 ),
-	mGluiMediaTimeControlWindowFlag( true ),
-	mGluiMediaBrowserControlWindowFlag( true ),
-	mMediaBrowserControlBackButtonFlag( true ),
-	mMediaBrowserControlForwardButtonFlag( true ),
-	mHomeWebUrl( "http://www.google.com/" )
-{
-	// debugging spam
-	std::cout << std::endl << "             GLUT version: " << "3.7.6" << std::endl;	// no way to get real version from GLUT
-	std::cout << std::endl << "             GLUI version: " << GLUI_Master.get_version() << std::endl;
-	std::cout << std::endl << "Media Plugin Test version: " << mVersionMajor << "." << mVersionMinor << "." << mVersionPatch << std::endl;
-
-	// bookmark title
-	mBookmarks.push_back( std::pair< std::string, std::string >( "--- Bookmarks ---", "" ) );
-
-	// insert hardcoded URLs here as required for testing
-	//mBookmarks.push_back( std::pair< std::string, std::string >( "description", "url" ) );
-
-	// read bookmarks from file.
-	// note: uses command in ./CmakeLists.txt which copies bookmmarks file from source directory
-	//       to app directory (WITHOUT build configuration dir) (this is cwd in Windows within MSVC)
-	//		 For example, test_apps\llplugintest and not test_apps\llplugintest\Release
-	//		 This may need to be changed for Mac/Linux builds.
-	// See https://jira.lindenlab.com/browse/DEV-31350 for large list of media URLs from AGNI
-	const std::string bookmarks_filename( "bookmarks.txt" );
-	std::ifstream file_handle( bookmarks_filename.c_str() );
-	if ( file_handle.is_open() )
-	{
-		std::cout << "Reading bookmarks for test" << std::endl;
-		while( ! file_handle.eof() )
-		{
-			std::string line;
-			std::getline( file_handle, line );
-			if ( file_handle.eof() )
-				break;
-
-			if ( line.substr( 0, 1 ) != "#" )
-			{
-				size_t comma_pos = line.find_first_of( ',' );
-				if ( comma_pos != std::string::npos )
-				{
-					std::string description = line.substr( 0, comma_pos );
-					std::string url = line.substr( comma_pos + 1 );
-					mBookmarks.push_back( std::pair< std::string, std::string >( description, url ) );
-				}
-				else
-				{
-					mBookmarks.push_back( std::pair< std::string, std::string >( line, line ) );
-				};
-			};
-		};
-		std::cout << "Read " << mBookmarks.size() << " bookmarks" << std::endl;
-	}
-	else
-	{
-		std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl;
-	};
-
-	// initialize linden lab APR module
-	ll_init_apr();
-
-	// Set up llerror logging
-	{
-		LLError::initForApplication(".");
-		LLError::setDefaultLevel(LLError::LEVEL_INFO);
-		//LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG);
-	}
-
-	// lots of randomness in this app
-	srand( ( unsigned int )time( 0 ) );
-
-	// build GUI
-	makeChrome();
-
-	// OpenGL initialilzation
-	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
-	glClearDepth( 1.0f );
-	glEnable( GL_DEPTH_TEST );
-	glEnable( GL_COLOR_MATERIAL );
-	glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
-	glDepthFunc( GL_LEQUAL );
-	glEnable( GL_TEXTURE_2D );
-	glDisable( GL_BLEND );
-	glColor3f( 1.0f, 1.0f, 1.0f );
-	glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
-	glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
-
-	// start with a sane view
-	resetView();
-
-	// initial media panel
-	const int num_initial_panels = 1;
-	for( int i = 0; i < num_initial_panels; ++i )
-	{
-		//addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
-		addMediaPanel( mHomeWebUrl );
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-LLMediaPluginTest::~LLMediaPluginTest()
-{
-	// delete all media panels
-	for( int i = 0; i < (int)mMediaPanels.size(); ++i )
-	{
-		remMediaPanel( mMediaPanels[ i ] );
-	};
-	
-	// Stop the plugin read thread if it's running.
-	LLPluginProcessParent::setUseReadThread(false);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::reshape( int width, int height )
-{
-	// update viewport (the active window inside the chrome)
-	int viewport_x, viewport_y;
-	int viewport_height, viewport_width;
-	GLUI_Master.get_viewport_area( &viewport_x, &viewport_y, &viewport_width, &viewport_height );
-	mViewportAspect = (float)( viewport_width ) / (float)( viewport_height );
-	glViewport( viewport_x, viewport_y, viewport_width, viewport_height );
-
-	// save these as we'll need them later
-	mWindowWidth = width;
-	mWindowHeight = height;
-
-	// adjust size of URL bar so it doesn't get clipped
-	mUrlEdit->set_w( mWindowWidth - 360 );
-
-	// GLUI requires this
-	if ( glutGetWindow() != mAppWindow )
-		glutSetWindow( mAppWindow );
-
-	// trigger re-display
-	glutPostRedisplay();
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::bindTexture(GLuint texture, GLint row_length, GLint alignment)
-{
-	glEnable( GL_TEXTURE_2D );
-
-	glBindTexture( GL_TEXTURE_2D, texture );
-	glPixelStorei( GL_UNPACK_ROW_LENGTH, row_length );
-	glPixelStorei( GL_UNPACK_ALIGNMENT, alignment );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-bool LLMediaPluginTest::checkGLError(const char *name)
-{
-	bool result = false;
-	GLenum error = glGetError();
-
-	if(error != GL_NO_ERROR)
-	{
-		// For some reason, glGenTextures is returning GL_INVALID_VALUE...
-		std::cout << name << " ERROR 0x" << std::hex << error << std::dec << std::endl;
-		result = true;
-	}
-
-	return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-GLfloat LLMediaPluginTest::distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z )
-{
-	GLdouble camera_pos_x = 0.0f;
-	GLdouble camera_pos_y = 0.0f;
-	GLdouble camera_pos_z = 0.0f;
-
-	GLdouble modelMatrix[16];
-	GLdouble projMatrix[16];
-	GLint viewport[4];
-
-	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
-	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
-	glGetIntegerv(GL_VIEWPORT, viewport);
-
-	gluUnProject(
-		(viewport[2]-viewport[0])/2 , (viewport[3]-viewport[1])/2,
-		0.0,
-		modelMatrix, projMatrix, viewport,
-		&camera_pos_x, &camera_pos_y, &camera_pos_z );
-
-	GLfloat distance =
-		sqrt( ( camera_pos_x - point_x ) * ( camera_pos_x - point_x ) +
-			  ( camera_pos_y - point_y ) * ( camera_pos_y - point_y ) +
-			  ( camera_pos_z - point_z ) * ( camera_pos_z - point_z ) );
-
-	return distance;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::drawGeometry( int panel, bool selected )
-{
-	// texture coordinates for each panel
-	GLfloat non_opengl_texture_coords[ 8 ] = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
-	GLfloat opengl_texture_coords[ 8 ] =     { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
-
-	GLfloat *texture_coords = mMediaPanels[ panel ]->mAppTextureCoordsOpenGL?opengl_texture_coords:non_opengl_texture_coords;
-
-	// base coordinates for each panel
-	GLfloat base_vertex_pos[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
-
-	// calculate posiitons
-	const int num_panels = (int)mMediaPanels.size();
-	const int num_rows = (int)sqrt( (float)num_panels );
-	const int num_cols = num_panels / num_rows;
-	const int panel_x = ( panel / num_rows );
-	const int panel_y = ( panel % num_rows );
-
-	// default spacing is small - make it larger if checkbox set - for testing positional audio
-	float spacing = 0.1f;
-	if ( mLargePanelSpacing )
-		spacing = 2.0f;
-
-	const GLfloat offset_x = num_cols * ( 1.0 + spacing ) / 2;
-	const GLfloat offset_y = num_rows * ( 1.0 + spacing ) / 2;
-
-	// Adjust for media aspect ratios
-	{
-		float aspect = 1.0f;
-
-		if(mMediaPanels[ panel ]->mMediaHeight != 0)
-		{
-			aspect = (float)mMediaPanels[ panel ]->mMediaWidth / (float)mMediaPanels[ panel ]->mMediaHeight;
-		}
-
-		if(aspect > 1.0f)
-		{
-			// media is wider than it is high -- adjust the top and bottom in
-			for( int corner = 0; corner < 4; ++corner )
-			{
-				float temp = base_vertex_pos[corner * 2 + 1];
-
-				if(temp < 0.5f)
-					temp += 0.5 - (0.5f / aspect);
-				else
-					temp -= 0.5 - (0.5f / aspect);
-
-				base_vertex_pos[corner * 2 + 1] = temp;
-			}
-		}
-		else if(aspect < 1.0f)
-		{
-			// media is higher than it is wide -- adjust the left and right sides in
-			for( int corner = 0; corner < 4; ++corner )
-			{
-				float temp = base_vertex_pos[corner * 2];
-
-				if(temp < 0.5f)
-					temp += 0.5f - (0.5f * aspect);
-				else
-					temp -= 0.5f - (0.5f * aspect);
-
-				base_vertex_pos[corner * 2] = temp;
-			}
-		}
-	}
-
-	glBegin( GL_QUADS );
-	for( int corner = 0; corner < 4; ++corner )
-	{
-		glTexCoord2f( texture_coords[ corner * 2 ], texture_coords[ corner * 2 + 1 ] );
-		GLfloat x = base_vertex_pos[ corner * 2 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f;
-		GLfloat y = base_vertex_pos[ corner * 2 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f;
-
-		glVertex3f( x, y, 0.0f );
-	};
-	glEnd();
-
-	// calculate distance to this panel if it's selected
-	if ( selected )
-	{
-		GLfloat point_x = base_vertex_pos[ 0 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f;
-		GLfloat point_y = base_vertex_pos[ 0 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f;
-		GLfloat point_z = 0.0f;
-		mDistanceCameraToSelectedGeometry = distanceToCamera( point_x, point_y, point_z );
-	};
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::startPanelHighlight( float red, float green, float blue, float line_width )
-{
-	glPushAttrib( GL_ALL_ATTRIB_BITS );
-	glEnable( GL_POLYGON_OFFSET_FILL );
-	glPolygonOffset( -2.5f, -2.5f );
-	glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
-	glLineWidth( line_width );
-	glColor3f( red, green, blue );
-	glDisable( GL_TEXTURE_2D );
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::endPanelHighlight()
-{
-	glPopAttrib();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::draw( int draw_type )
-{
-	for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-	{
-		// drawing pick texture
-		if ( draw_type == DrawTypePickTexture )
-		{
-			// only bother with pick if we have something to render
-			// Actually, we need to pick even if we're not ready to render.
-			// Otherwise you can't select and remove a panel which has gone bad.
-			//if ( mMediaPanels[ panel ]->mReadyToRender )
-			{
-				glMatrixMode( GL_TEXTURE );
-				glPushMatrix();
-
-				// pick texture is a power of 2 so no need to scale
-				glLoadIdentity();
-
-				// bind to media texture
-				glLoadIdentity();
-				bindTexture( mMediaPanels[ panel ]->mPickTextureHandle );
-				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
-
-				// draw geometry using pick texture
-				drawGeometry( panel, false );
-
-				glMatrixMode( GL_TEXTURE );
-				glPopMatrix();
-			};
-		}
-		else
-		if ( draw_type == DrawTypeMediaTexture )
-		{
-			bool texture_valid = false;
-			bool plugin_exited = false;
-
-			if(mMediaPanels[ panel ]->mMediaSource)
-			{
-				texture_valid = mMediaPanels[ panel ]->mMediaSource->textureValid();
-				plugin_exited = mMediaPanels[ panel ]->mMediaSource->isPluginExited();
-			}
-
-			// save texture matrix (changes for each panel)
-			glMatrixMode( GL_TEXTURE );
-			glPushMatrix();
-
-			// only process texture if the media is ready to draw
-			// (we still want to draw the geometry)
-			if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid )
-			{
-				// bind to media texture
-				bindTexture( mMediaPanels[ panel ]->mMediaTextureHandle );
-
-				if ( mFuzzyMedia )
-				{
-					glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
-					glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
-				}
-				else
-				{
-					glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-					glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
-				}
-
-				// scale to fit panel
-				glScalef( mMediaPanels[ panel ]->mTextureScaleX,
-							mMediaPanels[ panel ]->mTextureScaleY,
-								1.0f );
-			};
-
-			float intensity = plugin_exited?0.25f:1.0f;
-
-			// highlight the selected panel
-			if ( mSelectedPanel && ( mMediaPanels[ panel ]->mId == mSelectedPanel->mId ) )
-			{
-				startPanelHighlight( intensity, intensity, 0.0f, 5.0f );
-				drawGeometry( panel, true );
-				endPanelHighlight();
-			}
-			else
-			// this panel not able to render yet since it
-			// doesn't have enough information
-			if ( !mMediaPanels[ panel ]->mReadyToRender )
-			{
-				startPanelHighlight( intensity, 0.0f, 0.0f, 2.0f );
-				drawGeometry( panel, false );
-				endPanelHighlight();
-			}
-			else
-			// just display a border around the media
-			{
-				startPanelHighlight( 0.0f, intensity, 0.0f, 2.0f );
-				drawGeometry( panel, false );
-				endPanelHighlight();
-			};
-
-			if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid )
-			{
-				// draw visual geometry
-				drawGeometry( panel, false );
-			}
-
-			// restore texture matrix (changes for each panel)
-			glMatrixMode( GL_TEXTURE );
-			glPopMatrix();
-		};
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::display()
-{
-	// GLUI requires this
-	if ( glutGetWindow() != mAppWindow )
-		glutSetWindow( mAppWindow );
-
-	// start with a clean slate
-	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
-	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
-	// set up OpenGL view
-	glMatrixMode( GL_PROJECTION );
-	glLoadIdentity();
-	glFrustum( -mViewportAspect * 0.04f, mViewportAspect * 0.04f, -0.04f, 0.04f, 0.1f, 50.0f );
-	glMatrixMode( GL_MODELVIEW );
-	glLoadIdentity();
-	glTranslatef( 0.0, 0.0, 0.0f );
-	glTranslatef( mViewPos[ 0 ], mViewPos[ 1 ], -mViewPos[ 2 ] );
-	glMultMatrixf( mViewRotation );
-
-	// draw pick texture
-	draw( DrawTypePickTexture );
-
-	// read colors and get coordinate values
-	glReadPixels( mCurMouseX, mCurMouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, mPixelReadColor );
-
-	// clear the pick render (otherwise it may depth-fight with the textures rendered later)
-	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
-	// draw visible geometry
-	draw( DrawTypeMediaTexture );
-
-	glutSwapBuffers();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::idle()
-{
-//	checkGLError("LLMediaPluginTest::idle");
-
-	// GLUI requires this
-	if ( glutGetWindow() != mAppWindow )
-		glutSetWindow( mAppWindow );
-
-	// random creation/destruction of panels enabled?
-	const time_t panel_timeout_time = 5;
-	if ( mRandomPanelCount )
-	{
-		// time for a change
-		static time_t last_panel_time = 0;
-		if ( time( NULL ) - last_panel_time > panel_timeout_time )
-		{
-			if ( rand() % 2 == 0 )
-			{
-				if ( mMediaPanels.size() < 16 )
-				{
-					std::cout << "Randomly adding new panel" << std::endl;
-					addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
-				};
-			}
-			else
-			{
-				if ( mMediaPanels.size() > 0 )
-				{
-					std::cout << "Deleting selected panel" << std::endl;
-					remMediaPanel( mSelectedPanel );
-				};
-			};
-			time( &last_panel_time );
-		};
-	};
-
-	// random selection of bookmarks enabled?
-	const time_t bookmark_timeout_time = 5;
-	if ( mRandomBookmarks )
-	{
-		// time for a change
-		static time_t last_bookmark_time = 0;
-		if ( time( NULL ) - last_bookmark_time > bookmark_timeout_time )
-		{
-			// go to a different random bookmark on each panel
-			for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-			{
-				std::string uri = mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second;
-
-				std::cout << "Random: navigating to : " << uri << std::endl;
-
-				std::string mime_type = mimeTypeFromUrl( uri );
-
-				if ( mime_type != mMediaPanels[ panel ]->mMimeType )
-				{
-					replaceMediaPanel( mMediaPanels[ panel ], uri );
-				}
-				else
-				{
-					mMediaPanels[ panel ]->mMediaSource->loadURI( uri );
-					mMediaPanels[ panel ]->mMediaSource->start();
-				};
-			};
-
-			time( &last_bookmark_time );
-		};
-	};
-
-	// update UI
-	if ( mSelectedPanel )
-	{
-		// set volume based on slider if we have time media
-		//if ( mGluiMediaTimeControlWindowFlag )
-		//{
-		//	mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f );
-		//};
-
-		// NOTE: it is absurd that we need cache the state of GLUI controls
-		//       but enabling/disabling controls drags framerate from 500+
-		//		 down to 15. Not a problem for plugin system - only this test
-		// enable/disable time based UI controls based on type of plugin
-		if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
-		{
-			if ( ! mGluiMediaTimeControlWindowFlag )
-			{
-				mGluiMediaTimeControlWindow->enable();
-				mGluiMediaTimeControlWindowFlag = true;
-			};
-		}
-		else
-		{
-			if ( mGluiMediaTimeControlWindowFlag )
-			{
-				mGluiMediaTimeControlWindow->disable();
-				mGluiMediaTimeControlWindowFlag = false;
-			};
-		};
-
-		// enable/disable browser based UI controls based on type of plugin
-		if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() )
-		{
-			if ( ! mGluiMediaBrowserControlWindowFlag )
-			{
-				mGluiMediaBrowserControlWindow->enable();
-				mGluiMediaBrowserControlWindowFlag = true;
-			};
-		}
-		else
-		{
-			if ( mGluiMediaBrowserControlWindowFlag )
-			{
-				mGluiMediaBrowserControlWindow->disable();
-				mGluiMediaBrowserControlWindowFlag = false;
-			};
-		};
-
-		// enable/disable browser back button depending on browser history
-		if ( mSelectedPanel->mMediaSource->getHistoryBackAvailable()  )
-		{
-			if ( ! mMediaBrowserControlBackButtonFlag )
-			{
-				mMediaBrowserControlBackButton->enable();
-				mMediaBrowserControlBackButtonFlag = true;
-			};
-		}
-		else
-		{
-			if ( mMediaBrowserControlBackButtonFlag )
-			{
-				mMediaBrowserControlBackButton->disable();
-				mMediaBrowserControlBackButtonFlag = false;
-			};
-		};
-
-		// enable/disable browser forward button depending on browser history
-		if ( mSelectedPanel->mMediaSource->getHistoryForwardAvailable()  )
-		{
-			if ( ! mMediaBrowserControlForwardButtonFlag )
-			{
-				mMediaBrowserControlForwardButton->enable();
-				mMediaBrowserControlForwardButtonFlag = true;
-			};
-		}
-		else
-		{
-			if ( mMediaBrowserControlForwardButtonFlag )
-			{
-				mMediaBrowserControlForwardButton->disable();
-				mMediaBrowserControlForwardButtonFlag = false;
-			};
-		};
-
-		// NOTE: This is *very* slow and not worth optimising
-		updateStatusBar();
-	};
-
-	// update all the panels
-	for( int panel_index = 0; panel_index < (int)mMediaPanels.size(); ++panel_index )
-	{
-		mediaPanel *panel = mMediaPanels[ panel_index ];
-
-		// call plugins idle function so it can potentially update itself
-		panel->mMediaSource->idle();
-
-		// update each media panel
-		updateMediaPanel( panel );
-
-		LLRect dirty_rect;
-		if ( ! panel->mMediaSource->textureValid() )
-		{
-			//std::cout << "texture invalid, skipping update..." << std::endl;
-		}
-		else
-		if ( panel &&
-			 ( panel->mMediaWidth != panel->mMediaSource->getWidth() ||
-			   panel->mMediaHeight != panel->mMediaSource->getHeight() ) )
-		{
-			//std::cout << "Resize in progress, skipping update..." << std::endl;
-		}
-		else
-		if ( panel->mMediaSource->getDirty( &dirty_rect ) )
-		{
-			const unsigned char* pixels = panel->mMediaSource->getBitsData();
-			if ( pixels && isTexture(panel->mMediaTextureHandle))
-			{
-				int x_offset = dirty_rect.mLeft;
-				int y_offset = dirty_rect.mBottom;
-				int width = dirty_rect.mRight - dirty_rect.mLeft;
-				int height = dirty_rect.mTop - dirty_rect.mBottom;
-
-				if((dirty_rect.mRight <= panel->mTextureWidth) && (dirty_rect.mTop <= panel->mTextureHeight))
-				{
-					// Offset the pixels pointer properly
-					pixels += ( y_offset * panel->mMediaSource->getTextureDepth() * panel->mMediaSource->getBitsWidth() );
-					pixels += ( x_offset * panel->mMediaSource->getTextureDepth() );
-
-					// set up texture
-					bindTexture( panel->mMediaTextureHandle, panel->mMediaSource->getBitsWidth() );
-					if ( mFuzzyMedia )
-					{
-						glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
-						glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
-					}
-					else
-					{
-						glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-						glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
-					};
-
-					checkGLError("glTexParameteri");
-
-					if(panel->mMediaSource->getTextureFormatSwapBytes())
-					{
-						glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
-						checkGLError("glPixelStorei");
-					}
-
-					// draw portion that changes into texture
-					glTexSubImage2D( GL_TEXTURE_2D, 0,
-						x_offset,
-						y_offset,
-						width,
-						height,
-						panel->mMediaSource->getTextureFormatPrimary(),
-						panel->mMediaSource->getTextureFormatType(),
-						pixels );
-
-					if(checkGLError("glTexSubImage2D"))
-					{
-						std::cerr << "    panel ID=" << panel->mId << std::endl;
-						std::cerr << "    texture size = " << panel->mTextureWidth << " x " << panel->mTextureHeight << std::endl;
-						std::cerr << "    media size = " << panel->mMediaWidth << " x " << panel->mMediaHeight << std::endl;
-						std::cerr << "    dirty rect = " << dirty_rect.mLeft << ", " << dirty_rect.mBottom << ", " << dirty_rect.mRight << ", " << dirty_rect.mTop << std::endl;
-						std::cerr << "    texture width = " << panel->mMediaSource->getBitsWidth() << std::endl;
-						std::cerr << "    format primary = 0x" << std::hex << panel->mMediaSource->getTextureFormatPrimary() << std::dec << std::endl;
-						std::cerr << "    format type = 0x" << std::hex << panel->mMediaSource->getTextureFormatType() << std::dec << std::endl;
-						std::cerr << "    pixels = " << (void*)pixels << std::endl;
-					}
-
-					if(panel->mMediaSource->getTextureFormatSwapBytes())
-					{
-						glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
-						checkGLError("glPixelStorei");
-					}
-
-					panel->mMediaSource->resetDirty();
-
-					panel->mReadyToRender = true;
-				}
-				else
-				{
-					std::cerr << "dirty rect is outside current media size, skipping update" << std::endl;
-				}
-			};
-		};
-	};
-
-	// GLUI requires this
-	if ( glutGetWindow() != mAppWindow )
-		glutSetWindow( mAppWindow );
-
-	// trigger re-display
-	glutPostRedisplay();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::windowPosToTexturePos( int window_x, int window_y,
-											   int& media_x, int& media_y,
-											   int& id )
-{
-	if ( ! mSelectedPanel )
-	{
-		media_x = 0;
-		media_y = 0;
-		id = 0;
-		return;
-	};
-
-	// record cursor poisiton for a readback next frame
-	mCurMouseX = window_x;
-	// OpenGL app == coordinate system this way
-	// NOTE: unrelated to settings in plugin - this
-	// is just for this app
-	mCurMouseY = mWindowHeight - window_y;
-
-	// extract x (0..1023, y (0..1023) and id (0..15) from RGB components
-	unsigned long pixel_read_color_bits = ( mPixelReadColor[ 0 ] << 16 ) | ( mPixelReadColor[ 1 ] << 8 ) | mPixelReadColor[ 2 ];
-	int texture_x = pixel_read_color_bits & 0x3ff;
-	int texture_y = ( pixel_read_color_bits >> 10 ) & 0x3ff;
-	id = ( pixel_read_color_bits >> 20 ) & 0x0f;
-
-	// scale to size of media (1024 because we use 10 bits for X and Y from 24)
-	media_x = (int)( ( (float)mSelectedPanel->mMediaWidth * (float)texture_x ) / 1024.0f );
-	media_y = (int)( ( (float)mSelectedPanel->mMediaHeight * (float)texture_y ) / 1024.0f );
-
-	// we assume the plugin uses an inverted coordinate scheme like OpenGL
-	// if not, the plugin code inverts the Y coordinate for us - we don't need to
-	media_y = mSelectedPanel->mMediaHeight - media_y;
-
-	if ( media_x > 0 && media_y > 0 )
-	{
-		//std::cout << "      mouse coords: " << mCurMouseX << " x " << mCurMouseY << " and id = " << id  << std::endl;
-		//std::cout << "raw texture coords: " << texture_x << " x " << texture_y << " and id = " << id  << std::endl;
-		//std::cout << "      media coords: " << media_x << " x " << media_y << " and id = " << id  << std::endl;
-		//std::cout << std::endl;
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::selectPanelById( int id )
-{
-	for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-	{
-		if ( mMediaPanels[ panel ]->mId == id )
-		{
-			selectPanel(mMediaPanels[ panel ]);
-			return;
-		};
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::selectPanel( mediaPanel* panel )
-{
-	if( mSelectedPanel == panel )
-		return;
-
-	// turn off volume before we delete it
-	if( mSelectedPanel && mSelectedPanel->mMediaSource )
-	{
-		mSelectedPanel->mMediaSource->setVolume( 0.0f );
-		mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_LOW );
-	};
-
-	mSelectedPanel = panel;
-
-	if( mSelectedPanel && mSelectedPanel->mMediaSource )
-	{
-		mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f );
-		mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_NORMAL );
-
-		if(!mSelectedPanel->mStartUrl.empty())
-		{
-			mUrlEdit->set_text(const_cast<char*>(mSelectedPanel->mStartUrl.c_str()) );
-		}
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel*  LLMediaPluginTest::findMediaPanel( LLPluginClassMedia* source )
-{
-	mediaPanel *result = NULL;
-
-	for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-	{
-		if ( mMediaPanels[ panel ]->mMediaSource == source )
-		{
-			result = mMediaPanels[ panel ];
-		}
-	}
-
-	return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel* LLMediaPluginTest::findMediaPanel( const std::string &target_name )
-{
-	mediaPanel *result = NULL;
-
-	for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
-	{
-		if ( mMediaPanels[ panel ]->mTarget == target_name )
-		{
-			result = mMediaPanels[ panel ];
-		}
-	}
-
-	return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::navigateToNewURI( std::string uri )
-{
-	if ( uri.length() )
-	{
-		std::string mime_type = mimeTypeFromUrl( uri );
-
-		if ( !mSelectedPanel->mMediaSource->isPluginExited() && (mime_type == mSelectedPanel->mMimeType) )
-		{
-			std::cout << "MIME type is the same" << std::endl;
-			mSelectedPanel->mMediaSource->loadURI( uri );
-			mSelectedPanel->mMediaSource->start();
-			mBookmarkList->do_selection( 0 );
-		}
-		else
-		{
-			std::cout << "MIME type changed or plugin had exited" << std::endl;
-			replaceMediaPanel( mSelectedPanel, uri );
-			mBookmarkList->do_selection( 0 );
-		}
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::initUrlHistory( std::string uris )
-{
-	if ( uris.length() > 0 )
-	{
-		std::cout << "init URL : " << uris << std::endl;
-		LLSD historySD;
-
-		char *cstr, *p;
-		cstr = new char[uris.size()+1];
-		strcpy(cstr, uris.c_str());
-		const char *DELIMS = " ,;";
-		p = strtok(cstr, DELIMS);
-		while (p != NULL) {
-			historySD.insert(0, p);
-			p = strtok(NULL, DELIMS);
-		}
-		mSelectedPanel->mMediaSource->initializeUrlHistory(historySD);
-		delete[] cstr;
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::gluiCallback( int control_id )
-{
-	if ( control_id == mIdBookmarks )
-	{
-		std::string uri = mBookmarks[ mSelBookmark ].second;
-
-		navigateToNewURI( uri );
-	}
-	else
-    if ( control_id == mIdUrlEdit)
-	{
-		std::string uri = mUrlEdit->get_text();
-
-		navigateToNewURI( uri );
-	}
-	else
-	if ( control_id == mIdUrlInitHistoryEdit )
-	{
-		std::string uri = mUrlInitHistoryEdit->get_text();
-
-		initUrlHistory( uri );
-	}
-	else
-	if ( control_id == mIdControlAddPanel )
-	{
-		addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
-	}
-	else
-	if ( control_id == mIdControlRemPanel )
-	{
-		remMediaPanel( mSelectedPanel );
-	}
-	else
-	if ( control_id == mIdDisableTimeout )
-	{
-		// Set the "disable timeout" flag for all active plugins.
-		for( int i = 0; i < (int)mMediaPanels.size(); ++i )
-		{
-			mMediaPanels[ i ]->mMediaSource->setDisableTimeout(mDisableTimeout);
-		}
-	}
-	else
-	if ( control_id == mIdUsePluginReadThread )
-	{
-		LLPluginProcessParent::setUseReadThread(mUsePluginReadThread);
-	}
-	else
-	if ( control_id == mIdControlCrashPlugin )
-	{
-		// send message to plugin and ask it to crash
-		// (switch out for ReleaseCandidate version :) )
-		if(mSelectedPanel && mSelectedPanel->mMediaSource)
-		{
-			mSelectedPanel->mMediaSource->crashPlugin();
-		}
-	}
-	else
-	if ( control_id == mIdControlHangPlugin )
-	{
-		// send message to plugin and ask it to hang
-		// (switch out for ReleaseCandidate version :) )
-		if(mSelectedPanel && mSelectedPanel->mMediaSource)
-		{
-			mSelectedPanel->mMediaSource->hangPlugin();
-		}
-	}
-	else
-	if ( control_id == mIdControlExitApp )
-	{
-		// text for exiting plugin system cleanly
-		delete this;	// clean up
-		exit( 0 );
-	}
-	else
-	if ( control_id == mIdMediaTimeControlPlay )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->setLoop( false );
-			mSelectedPanel->mMediaSource->start();
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlLoop )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->setLoop( true );
-			mSelectedPanel->mMediaSource->start();
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlPause )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->pause();
-	}
-	else
-	if ( control_id == mIdMediaTimeControlStop )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->stop();
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlSeek )
-	{
-		if ( mSelectedPanel )
-		{
-			// get value from spinner
-			float seconds_to_seek = mMediaTimeControlSeekSeconds;
-			mSelectedPanel->mMediaSource->seek( seconds_to_seek );
-			mSelectedPanel->mMediaSource->start();
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlRewind )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->setLoop( false );
-			mSelectedPanel->mMediaSource->start(-2.0f);
-		};
-	}
-	else
-	if ( control_id == mIdMediaTimeControlFastForward )
-	{
-		if ( mSelectedPanel )
-		{
-			mSelectedPanel->mMediaSource->setLoop( false );
-			mSelectedPanel->mMediaSource->start(2.0f);
-		};
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlBack )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->browse_back();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlStop )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->browse_stop();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlForward )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->browse_forward();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlHome )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->loadURI( mHomeWebUrl );
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlReload )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->browse_reload( true );
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlClearCache )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->clear_cache();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlClearCookies )
-	{
-		if ( mSelectedPanel )
-			mSelectedPanel->mMediaSource->clear_cookies();
-	}
-	else
-	if ( control_id == mIdMediaBrowserControlEnableCookies )
-	{
-		if ( mSelectedPanel )
-		{
-			if ( mMediaBrowserControlEnableCookies )
-			{
-				mSelectedPanel->mMediaSource->enable_cookies( true );
-			}
-			else
-			{
-				mSelectedPanel->mMediaSource->enable_cookies( false );
-			}
-		};
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::keyboard( int key )
-{
-	//if ( key == 'a' || key == 'A' )
-	//	addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
-	//else
-	//if ( key == 'r' || key == 'R' )
-	//	remMediaPanel( mSelectedPanel );
-	//else
-	//if ( key == 'd' || key == 'D' )
-	//	dumpPanelInfo();
-	//else
-	if ( key == 27 )
-	{
-		std::cout << "Application finished - exiting..." << std::endl;
-		delete this;
-		exit( 0 );
-	};
-
-	mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 , LLSD());
-	mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0, LLSD());
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::mouseButton( int button, int state, int x, int y )
-{
-	if ( button == GLUT_LEFT_BUTTON )
-	{
-		if ( state == GLUT_DOWN )
-		{
-			int media_x, media_y, id;
-			windowPosToTexturePos( x, y, media_x, media_y, id );
-
-			if ( mSelectedPanel )
-				mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_DOWN, 0, media_x, media_y, 0 );
-		}
-		else
-		if ( state == GLUT_UP )
-		{
-			int media_x, media_y, id;
-			windowPosToTexturePos( x, y, media_x, media_y, id );
-
-			// only select a panel if we're on a panel
-			// (HACK: strictly speaking this rules out clicking on
-			// the origin of a panel but that's very unlikely)
-			if ( media_x > 0 && media_y > 0 )
-			{
-				selectPanelById( id );
-
-				if ( mSelectedPanel )
-					mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_UP, 0, media_x, media_y, 0 );
-			};
-		};
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::mousePassive( int x, int y )
-{
-	int media_x, media_y, id;
-	windowPosToTexturePos( x, y, media_x, media_y, id );
-
-	if ( mSelectedPanel )
-		mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::mouseMove( int x, int y )
-{
-	int media_x, media_y, id;
-	windowPosToTexturePos( x, y, media_x, media_y, id );
-
-	if ( mSelectedPanel )
-		mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::makeChrome()
-{
-	// IDs used by GLUI
-	int start_id = 0x1000;
-
-	// right side window - geometry manipulators
-#if __APPLE__
-	// the Apple GLUT implementation doesn't seem to set the graphic offset of subwindows correctly when they overlap in certain ways.
-	// Use a separate controls window in this case.
-	// GLUI window at right containing manipulation controls and other buttons
-	int x = glutGet(GLUT_WINDOW_X) + glutGet(GLUT_WINDOW_WIDTH) + 4;
-	int y = glutGet(GLUT_WINDOW_Y);
-	GLUI* right_glui_window = GLUI_Master.create_glui( "", 0, x, y );
-#else
-	GLUI* right_glui_window = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_RIGHT );
-#endif
-	mViewRotationCtrl = right_glui_window->add_rotation( "Rotation", mViewRotation );
-	mViewTranslationCtrl = right_glui_window->add_translation( "Translate", GLUI_TRANSLATION_XY, mViewPos );
-	mViewTranslationCtrl->set_speed( 0.01f );
-	mViewScaleCtrl = right_glui_window->add_translation( "Scale", GLUI_TRANSLATION_Z, &mViewPos[ 2 ] );
-	mViewScaleCtrl->set_speed( 0.05f );
-	right_glui_window->set_main_gfx_window( mAppWindow );
-
-	// right side window - app controls
-	mIdControlAddPanel = start_id++;
-	right_glui_window->add_statictext( "" );
-	right_glui_window->add_separator();
-	right_glui_window->add_statictext( "" );
-	right_glui_window->add_button( "Add panel", mIdControlAddPanel, gluiCallbackWrapper );
-	right_glui_window->add_statictext( "" );
-	mIdControlRemPanel = start_id++;
-	right_glui_window->add_button( "Rem panel", mIdControlRemPanel, gluiCallbackWrapper );
-	right_glui_window->add_statictext( "" );
-	right_glui_window->add_separator();
-	right_glui_window->add_statictext( "" );
-	mIdControlCrashPlugin = start_id++;
-	right_glui_window->add_button( "Crash plugin", mIdControlCrashPlugin, gluiCallbackWrapper );
-	mIdControlHangPlugin = start_id++;
-	right_glui_window->add_button( "Hang plugin", mIdControlHangPlugin, gluiCallbackWrapper );
-
-	right_glui_window->add_statictext( "" );
-	right_glui_window->add_separator();
-	right_glui_window->add_statictext( "" );
-	mIdControlExitApp = start_id++;
-	right_glui_window->add_button( "Exit app", mIdControlExitApp, gluiCallbackWrapper );
-
-	//// top window - holds bookmark UI
-	mIdBookmarks = start_id++;
-	mSelBookmark = 0;
-	GLUI* glui_window_top = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	mBookmarkList = glui_window_top->add_listbox( "", &mSelBookmark, mIdBookmarks, gluiCallbackWrapper );
-	// only add the first 50 bookmarks - list can be very long sometimes (30,000+)
-	// when testing list of media URLs from AGNI for example
-	for( unsigned int each = 0; each < mBookmarks.size() && each < 50; ++each )
-		mBookmarkList->add_item( each, const_cast< char* >( mBookmarks[ each ].first.c_str() ) );
-	glui_window_top->set_main_gfx_window( mAppWindow );
-
-	glui_window_top->add_column( false );
-	mIdUrlEdit = start_id++;
-	mUrlEdit = glui_window_top->add_edittext( "Url:", GLUI_EDITTEXT_TEXT, 0, mIdUrlEdit, gluiCallbackWrapper );
-	mUrlEdit->set_w( 600 );
-	GLUI* glui_window_top2 = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	mIdUrlInitHistoryEdit = start_id++;
-	mUrlInitHistoryEdit = glui_window_top2->add_edittext( "Init History (separate by commas or semicolons):",
-		GLUI_EDITTEXT_TEXT, 0, mIdUrlInitHistoryEdit, gluiCallbackWrapper );
-	mUrlInitHistoryEdit->set_w( 800 );
-
-	// top window - media controls for "time" media types (e.g. movies)
-	mGluiMediaTimeControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	mGluiMediaTimeControlWindow->set_main_gfx_window( mAppWindow );
-	mIdMediaTimeControlPlay = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "PLAY", mIdMediaTimeControlPlay, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlLoop = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "LOOP", mIdMediaTimeControlLoop, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlPause = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "PAUSE", mIdMediaTimeControlPause, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-
-	GLUI_Button  *button;
-	mIdMediaTimeControlRewind = start_id++;
-	button = mGluiMediaTimeControlWindow->add_button( "<<", mIdMediaTimeControlRewind, gluiCallbackWrapper );
-	button->set_w(30);
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlFastForward = start_id++;
-	button = mGluiMediaTimeControlWindow->add_button( ">>", mIdMediaTimeControlFastForward, gluiCallbackWrapper );
-	button->set_w(30);
-
-	mGluiMediaTimeControlWindow->add_column( true );
-
-	mIdMediaTimeControlStop = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "STOP", mIdMediaTimeControlStop, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlVolume = start_id++;
-	GLUI_Spinner* spinner = mGluiMediaTimeControlWindow->add_spinner( "Volume", 2, &mMediaTimeControlVolume, mIdMediaTimeControlVolume, gluiCallbackWrapper);
-	spinner->set_float_limits( 0, 100 );
-	mGluiMediaTimeControlWindow->add_column( true );
-	mIdMediaTimeControlSeekSeconds = start_id++;
-	spinner = mGluiMediaTimeControlWindow->add_spinner( "", 2, &mMediaTimeControlSeekSeconds, mIdMediaTimeControlSeekSeconds, gluiCallbackWrapper);
-	spinner->set_float_limits( 0, 200 );
-	spinner->set_w( 32 );
-	spinner->set_speed( 0.025f );
-	mGluiMediaTimeControlWindow->add_column( false );
-	mIdMediaTimeControlSeek = start_id++;
-	mGluiMediaTimeControlWindow->add_button( "SEEK", mIdMediaTimeControlSeek, gluiCallbackWrapper );
-	mGluiMediaTimeControlWindow->add_column( false );
-
-
-	// top window - media controls for "browser" media types (e.g. web browser)
-	mGluiMediaBrowserControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	mGluiMediaBrowserControlWindow->set_main_gfx_window( mAppWindow );
-	mIdMediaBrowserControlBack = start_id++;
-	mMediaBrowserControlBackButton = mGluiMediaBrowserControlWindow->add_button( "BACK", mIdMediaBrowserControlBack, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlStop = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "STOP", mIdMediaBrowserControlStop, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlForward = start_id++;
-	mMediaBrowserControlForwardButton = mGluiMediaBrowserControlWindow->add_button( "FORWARD", mIdMediaBrowserControlForward, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlHome = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "HOME", mIdMediaBrowserControlHome, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlReload = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "RELOAD", mIdMediaBrowserControlReload, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlClearCache = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "CLEAR CACHE", mIdMediaBrowserControlClearCache, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlClearCookies = start_id++;
-	mGluiMediaBrowserControlWindow->add_button( "CLEAR COOKIES", mIdMediaBrowserControlClearCookies, gluiCallbackWrapper );
-	mGluiMediaBrowserControlWindow->add_column( false );
-	mIdMediaBrowserControlEnableCookies = start_id++;
-	mMediaBrowserControlEnableCookies = 0;
-	mGluiMediaBrowserControlWindow->add_checkbox( "Enable Cookies", &mMediaBrowserControlEnableCookies, mIdMediaBrowserControlEnableCookies, gluiCallbackWrapper );
-
-	// top window - misc controls
-	GLUI* glui_window_misc_control = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
-	mIdRandomPanelCount = start_id++;
-	mRandomPanelCount = 0;
-	glui_window_misc_control->add_checkbox( "Randomize panel count", &mRandomPanelCount, mIdRandomPanelCount, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-	mIdRandomBookmarks = start_id++;
-	mRandomBookmarks = 0;
-	glui_window_misc_control->add_checkbox( "Randomize bookmarks", &mRandomBookmarks, mIdRandomBookmarks, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-
-	mIdDisableTimeout = start_id++;
-	mDisableTimeout = 0;
-	glui_window_misc_control->add_checkbox( "Disable plugin timeout", &mDisableTimeout, mIdDisableTimeout, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-
-	mIdUsePluginReadThread = start_id++;
-	mUsePluginReadThread = 0;
-	glui_window_misc_control->add_checkbox( "Use plugin read thread", &mUsePluginReadThread, mIdUsePluginReadThread, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-
-	mIdLargePanelSpacing = start_id++;
-	mLargePanelSpacing = 0;
-	glui_window_misc_control->add_checkbox( "Large Panel Spacing", &mLargePanelSpacing, mIdLargePanelSpacing, gluiCallbackWrapper );
-	glui_window_misc_control->set_main_gfx_window( mAppWindow );
-	glui_window_misc_control->add_column( true );
-
-	// bottom window - status
-	mBottomGLUIWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_BOTTOM );
-	mStatusText = mBottomGLUIWindow->add_statictext( "" );
-	mBottomGLUIWindow->set_main_gfx_window( mAppWindow );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::resetView()
-{
-	mViewRotationCtrl->reset();
-
-	mViewScaleCtrl->set_x( 0.0f );
-	mViewScaleCtrl->set_y( 0.0f );
-	mViewScaleCtrl->set_z( 3.0f );
-
-	mViewTranslationCtrl->set_x( 0.0f );
-	mViewTranslationCtrl->set_y( 0.0f );
-	mViewTranslationCtrl->set_z( 0.0f );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels )
-{
-	int pick_texture_width = 1024;
-	int pick_texture_height = 1024;
-	int pick_texture_depth = 3;
-	unsigned char* ptr = new unsigned char[ pick_texture_width * pick_texture_height * pick_texture_depth ];
-	for( int y = 0; y < pick_texture_height; ++y )
-	{
-		for( int x = 0; x < pick_texture_width * pick_texture_depth ; x += pick_texture_depth )
-		{
-			unsigned long bits = 0L;
-			bits |= ( id << 20 ) | ( y << 10 ) | ( x / 3 );
-			unsigned char r_component = ( bits >> 16 ) & 0xff;
-			unsigned char g_component = ( bits >> 8 ) & 0xff;
-			unsigned char b_component = bits & 0xff;
-
-			ptr[ y * pick_texture_width * pick_texture_depth + x + 0 ] = r_component;
-			ptr[ y * pick_texture_width * pick_texture_depth + x + 1 ] = g_component;
-			ptr[ y * pick_texture_width * pick_texture_depth + x + 2 ] = b_component;
-		};
-	};
-
-	glGenTextures( 1, texture_handle );
-
-	checkGLError("glGenTextures");
-	std::cout << "glGenTextures returned " << *texture_handle << std::endl;
-
-	bindTexture( *texture_handle );
-	glTexImage2D( GL_TEXTURE_2D, 0,
-					GL_RGB,
-						pick_texture_width, pick_texture_height,
-							0, GL_RGB, GL_UNSIGNED_BYTE, ptr );
-
-	*texture_pixels = ptr;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-std::string LLMediaPluginTest::mimeTypeFromUrl( std::string& url )
-{
-	// default to web
-	std::string mime_type = "text/html";
-
-	// we may need a more advanced MIME type accessor later :-)
-	if ( url.find( ".mov" ) != std::string::npos )	// Movies
-		mime_type = "video/quicktime";
-	else
-	if ( url.find( ".txt" ) != std::string::npos )	// Apple Text descriptors
-		mime_type = "video/quicktime";
-	else
-	if ( url.find( ".mp3" ) != std::string::npos )	// Apple Text descriptors
-		mime_type = "video/quicktime";
-	else
-	if ( url.find( "example://" ) != std::string::npos )	// Example plugin
-		mime_type = "example/example";
-
-	return mime_type;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-std::string LLMediaPluginTest::pluginNameFromMimeType( std::string& mime_type )
-{
-#if LL_DARWIN
-	std::string plugin_name( "media_plugin_null.dylib" );
-	if ( mime_type == "video/quicktime" )
-		plugin_name = "media_plugin_quicktime.dylib";
-	else
-	if ( mime_type == "text/html" )
-		plugin_name = "media_plugin_webkit.dylib";
-
-#elif LL_WINDOWS
-	std::string plugin_name( "media_plugin_null.dll" );
-
-	if ( mime_type == "video/quicktime" )
-		plugin_name = "media_plugin_quicktime.dll";
-	else
-	if ( mime_type == "text/html" )
-		plugin_name = "media_plugin_webkit.dll";
-	else
-	if ( mime_type == "example/example" )
-		plugin_name = "media_plugin_example.dll";
-
-#elif LL_LINUX
-	std::string plugin_name( "libmedia_plugin_null.so" );
-
-	if ( mime_type == "video/quicktime" )
-		plugin_name = "libmedia_plugin_quicktime.so";
-	else
-	if ( mime_type == "text/html" )
-		plugin_name = "libmedia_plugin_webkit.so";
-#endif
-	return plugin_name;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel* LLMediaPluginTest::addMediaPanel( std::string url )
-{
-	// Get the plugin filename using the URL
-	std::string mime_type = mimeTypeFromUrl( url );
-	std::string plugin_name = pluginNameFromMimeType( mime_type );
-
-	// create a random size for the new media
-	int media_width;
-	int media_height;
-	getRandomMediaSize( media_width, media_height, mime_type );
-
-	// make a new plugin
-	LLPluginClassMedia* media_source = new LLPluginClassMedia(this);
-
-	// tell the plugin what size we asked for
-	media_source->setSize( media_width, media_height );
-
-	// Use the launcher start and initialize the plugin
-#if LL_DARWIN || LL_LINUX
-	std::string launcher_name( "SLPlugin" );
-#elif LL_WINDOWS
-	std::string launcher_name( "SLPlugin.exe" );
-#endif
-
-	// for this test app, use the cwd as the user data path (ugh).
-#if LL_WINDOWS
-	std::string user_data_path = ".\\";
-#else
-        char cwd[ FILENAME_MAX ];
-	if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
-	{
-		std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl;
-		return NULL;
-	}
-	std::string user_data_path = std::string( cwd ) + "/";
-#endif
-	media_source->setUserDataPath(user_data_path);
-	media_source->init( launcher_name, user_data_path, plugin_name, false );
-	media_source->setDisableTimeout(mDisableTimeout);
-
-	// make a new panel and save parameters
-	mediaPanel* panel = new mediaPanel;
-	panel->mMediaSource = media_source;
-	panel->mStartUrl = url;
-	panel->mMimeType = mime_type;
-	panel->mMediaWidth = media_width;
-	panel->mMediaHeight = media_height;
-	panel->mTextureWidth = 0;
-	panel->mTextureHeight = 0;
-	panel->mTextureScaleX = 0;
-	panel->mTextureScaleY = 0;
-	panel->mMediaTextureHandle = 0;
-	panel->mPickTextureHandle = 0;
-	panel->mAppTextureCoordsOpenGL = false;	// really need an 'undefined' state here too
-	panel->mReadyToRender = false;
-
-	// look through current media panels to find an unused index number
-	bool id_exists = true;
-	for( int nid = 0; nid < mMaxPanels; ++nid )
-	{
-		// does this id exist already?
-		id_exists = false;
-		for( int pid = 0; pid < (int)mMediaPanels.size(); ++pid )
-		{
-			if ( nid == mMediaPanels[ pid ]->mId )
-			{
-				id_exists = true;
-				break;
-			};
-		};
-
-		// id wasn't found so we can use it
-		if ( ! id_exists )
-		{
-			panel->mId = nid;
-			break;
-		};
-	};
-
-	// if we get here and this flag is set, there is no room for any more panels
-	if ( id_exists )
-	{
-		std::cout << "No room for any more panels" << std::endl;
-	}
-	else
-	{
-		// now we have the ID we can use it to make the
-		// pick texture (id is baked into texture pixels)
-		makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels );
-
-		// save this in the list of panels
-		mMediaPanels.push_back( panel );
-
-		// select the panel that was just created
-		selectPanel( panel );
-
-		// load and start the URL
-		panel->mMediaSource->loadURI( url );
-		panel->mMediaSource->start();
-
-		std::cout << "Adding new media panel for " << url << "(" << media_width << "x" << media_height << ") with index " << panel->mId << " - total panels = " << mMediaPanels.size() << std::endl;
-	}
-	
-	return panel;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::updateMediaPanel( mediaPanel* panel )
-{
-//	checkGLError("LLMediaPluginTest::updateMediaPanel");
-
-	if ( ! panel )
-		return;
-
-	if(!panel->mMediaSource || !panel->mMediaSource->textureValid())
-	{
-		panel->mReadyToRender = false;
-		return;
-	}
-
-	// take a reference copy of the plugin values since they
-	// might change during this lifetime of this function
-	int plugin_media_width = panel->mMediaSource->getWidth();
-	int plugin_media_height = panel->mMediaSource->getHeight();
-	int plugin_texture_width = panel->mMediaSource->getBitsWidth();
-	int plugin_texture_height = panel->mMediaSource->getBitsHeight();
-
-	// If the texture isn't created or the media or texture dimensions changed AND
-	// the sizes are valid then we need to delete the old media texture (if necessary)
-	// then make a new one.
-	if ((panel->mMediaTextureHandle == 0 ||
-		 panel->mMediaWidth != plugin_media_width ||
-		 panel->mMediaHeight != plugin_media_height ||
-		 panel->mTextureWidth != plugin_texture_width ||
-		 panel->mTextureHeight != plugin_texture_height) &&
-		( plugin_media_width > 0 && plugin_media_height > 0 &&
-		  plugin_texture_width > 0 && plugin_texture_height > 0 ) )
-	{
-		std::cout << "Valid media size (" <<  plugin_media_width << " x " << plugin_media_height
-				<< ") and texture size (" <<  plugin_texture_width << " x " << plugin_texture_height
-				<< ") for panel with ID=" << panel->mId << " - making texture" << std::endl;
-
-		// delete old GL texture
-		if ( isTexture( panel->mMediaTextureHandle ) )
-		{
-			std::cerr << "updateMediaPanel: deleting texture " << panel->mMediaTextureHandle << std::endl;
-			glDeleteTextures( 1, &panel->mMediaTextureHandle );
-			panel->mMediaTextureHandle = 0;
-		}
-
-		std::cerr << "before: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl;
-
-		// make a GL texture based on the dimensions the plugin told us
-		GLuint new_texture = 0;
-		glGenTextures( 1, &new_texture );
-
-		checkGLError("glGenTextures");
-
-		std::cout << "glGenTextures returned " << new_texture << std::endl;
-
-		panel->mMediaTextureHandle = new_texture;
-
-		bindTexture( panel->mMediaTextureHandle );
-
-		std::cout << "Setting texture size to " << plugin_texture_width << " x " << plugin_texture_height << std::endl;
-		glTexImage2D( GL_TEXTURE_2D, 0,
-			GL_RGB,
-				plugin_texture_width, plugin_texture_height,
-					0, GL_RGB, GL_UNSIGNED_BYTE,
-						0 );
-
-
-		std::cerr << "after: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl;
-	};
-
-	// update our record of the media and texture dimensions
-	// NOTE: do this after we we check for sizes changes
-	panel->mMediaWidth = plugin_media_width;
-	panel->mMediaHeight = plugin_media_height;
-	panel->mTextureWidth = plugin_texture_width;
-	panel->mTextureHeight = plugin_texture_height;
-	if ( plugin_texture_width > 0 )
-	{
-		panel->mTextureScaleX = (double)panel->mMediaWidth / (double)panel->mTextureWidth;
-	};
-	if ( plugin_texture_height > 0 )
-	{
-		panel->mTextureScaleY = (double)panel->mMediaHeight / (double)panel->mTextureHeight;
-	};
-
-	// update the flag which tells us if the media source uses OprnGL coords or not.
-	panel->mAppTextureCoordsOpenGL = panel->mMediaSource->getTextureCoordsOpenGL();
-
-	// Check to see if we have enough to render this panel.
-	// If we do, set a flag that the display functions use so
-	// they only render a panel with media if it's ready.
-	if ( panel->mMediaWidth < 0 ||
-		 panel->mMediaHeight < 0 ||
-		 panel->mTextureWidth < 1 ||
-		 panel->mTextureHeight < 1 ||
-		 panel->mMediaTextureHandle == 0 )
-	{
-		panel->mReadyToRender = false;
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-mediaPanel* LLMediaPluginTest::replaceMediaPanel( mediaPanel* panel, std::string url )
-{
-	// no media panels so we can't change anything - have to add
-	if ( mMediaPanels.size() == 0 )
-		return NULL;
-
-	// sanity check
-	if ( ! panel )
-		return NULL;
-
-	int index;
-	for(index = 0; index < (int)mMediaPanels.size(); index++)
-	{
-		if(mMediaPanels[index] == panel)
-			break;
-	}
-
-	if(index >= (int)mMediaPanels.size())
-	{
-		// panel isn't in mMediaPanels
-		return NULL;
-	}
-
-	std::cout << "Replacing media panel with index " << panel->mId << std::endl;
-
-	int panel_id = panel->mId;
-
-	if(mSelectedPanel == panel)
-		mSelectedPanel = NULL;
-
-	delete panel;
-
-	// Get the plugin filename using the URL
-	std::string mime_type = mimeTypeFromUrl( url );
-	std::string plugin_name = pluginNameFromMimeType( mime_type );
-
-	// create a random size for the new media
-	int media_width;
-	int media_height;
-	getRandomMediaSize( media_width, media_height, mime_type );
-
-	// make a new plugin
-	LLPluginClassMedia* media_source = new LLPluginClassMedia(this);
-
-	// tell the plugin what size we asked for
-	media_source->setSize( media_width, media_height );
-
-	// Use the launcher start and initialize the plugin
-#if LL_DARWIN || LL_LINUX
-	std::string launcher_name( "SLPlugin" );
-#elif LL_WINDOWS
-	std::string launcher_name( "SLPlugin.exe" );
-#endif
-
-	// for this test app, use the cwd as the user data path (ugh).
-#if LL_WINDOWS
-	std::string user_data_path = ".\\";
-#else
-        char cwd[ FILENAME_MAX ];
-	if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
-	{
-		std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl;
-		return NULL;
-	}
-	std::string user_data_path = std::string( cwd ) + "/";
-#endif
-
-	media_source->setUserDataPath(user_data_path);
-	media_source->init( launcher_name, user_data_path, plugin_name, false );
-	media_source->setDisableTimeout(mDisableTimeout);
-
-	// make a new panel and save parameters
-	panel = new mediaPanel;
-	panel->mMediaSource = media_source;
-	panel->mStartUrl = url;
-	panel->mMimeType = mime_type;
-	panel->mMediaWidth = media_width;
-	panel->mMediaHeight = media_height;
-	panel->mTextureWidth = 0;
-	panel->mTextureHeight = 0;
-	panel->mTextureScaleX = 0;
-	panel->mTextureScaleY = 0;
-	panel->mMediaTextureHandle = 0;
-	panel->mPickTextureHandle = 0;
-	panel->mAppTextureCoordsOpenGL = false;	// really need an 'undefined' state here too
-	panel->mReadyToRender = false;
-
-	panel->mId = panel_id;
-
-	// Replace the entry in the panels array
-	mMediaPanels[index] = panel;
-
-	// now we have the ID we can use it to make the
-	// pick texture (id is baked into texture pixels)
-	makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels );
-
-	// select the panel that was just created
-	selectPanel( panel );
-
-	// load and start the URL
-	panel->mMediaSource->loadURI( url );
-	panel->mMediaSource->start();
-	
-	return panel;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::getRandomMediaSize( int& width, int& height, std::string mime_type )
-{
-	// Make a new media source with a random size which we'll either
-	// directly or the media plugin will tell us what it wants later.
-	// Use a random size so we can test support for weird media sizes.
-	// (Almost everything else will get filled in later once the
-	// plugin responds)
-	// NB. Do we need to enforce that width is on 4 pixel boundary?
-	width = ( ( rand() % 170 ) + 30 ) * 4;
-	height = ( ( rand() % 170 ) + 30 ) * 4;
-
-	// adjust this random size if it's a browser so we get
-	// a more useful size for testing..
-	if ( mime_type == "text/html" || mime_type == "example/example"  )
-	{
-		width = ( ( rand() % 100 ) + 100 ) * 4;
-		height = ( width * ( ( rand() % 400 ) + 1000 ) ) / 1000;
-	};
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::remMediaPanel( mediaPanel* panel )
-{
-	// always leave one panel
-	if ( mMediaPanels.size() == 1 )
-		return;
-
-	// sanity check - don't think this can happen but see above for a case where it might...
-	if ( ! panel )
-		return;
-
-	std::cout << "Removing media panel with index " << panel->mId << " - total panels = " << mMediaPanels.size() - 1 << std::endl;
-
-	if(mSelectedPanel == panel)
-		mSelectedPanel = NULL;
-
-	delete panel;
-
-	// remove from storage list
-	for( int i = 0; i < (int)mMediaPanels.size(); ++i )
-	{
-		if ( mMediaPanels[ i ] == panel )
-		{
-			mMediaPanels.erase( mMediaPanels.begin() + i );
-			break;
-		};
-	};
-
-	// select the first panel
-	selectPanel( mMediaPanels[ 0 ] );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::updateStatusBar()
-{
-	if ( ! mSelectedPanel )
-		return;
-
-	// cache results - this is a very slow function
-	static int cached_id = -1;
-	static int cached_media_width = -1;
-	static int cached_media_height = -1;
-	static int cached_texture_width = -1;
-	static int cached_texture_height = -1;
-	static bool cached_supports_browser_media = true;
-	static bool cached_supports_time_media = false;
-	static int cached_movie_time = -1;
-	static GLfloat cached_distance = -1.0f;
-
-	static std::string cached_plugin_version = "";
-	if (
-		 cached_id == mSelectedPanel->mId &&
-		 cached_media_width == mSelectedPanel->mMediaWidth &&
-		 cached_media_height  == mSelectedPanel->mMediaHeight &&
-		 cached_texture_width == mSelectedPanel->mTextureWidth &&
-		 cached_texture_height == mSelectedPanel->mTextureHeight &&
-		 cached_supports_browser_media == mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() &&
-		 cached_supports_time_media == mSelectedPanel->mMediaSource->pluginSupportsMediaTime() &&
-		 cached_plugin_version == mSelectedPanel->mMediaSource->getPluginVersion() &&
-		 cached_movie_time == (int)mSelectedPanel->mMediaSource->getCurrentTime() &&
-		 cached_distance == mDistanceCameraToSelectedGeometry
-	   )
-	{
-		// nothing changed so don't spend time here
-		return;
-	};
-
-	std::ostringstream stream( "" );
-
-	stream.str( "" );
-	stream.clear();
-
-	stream << "Id: ";
-	stream << std::setw( 2 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mId;
-	stream << " | ";
-	stream << "Media: ";
-	stream << std::setw( 3 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mMediaWidth;
-	stream << " x ";
-	stream << std::setw( 3 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mMediaHeight;
-	stream << " | ";
-	stream << "Texture: ";
-	stream << std::setw( 4 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mTextureWidth;
-	stream << " x ";
-	stream << std::setw( 4 ) << std::setfill( '0' );
-	stream << mSelectedPanel->mTextureHeight;
-
-	stream << " | ";
-	stream << "Distance: ";
-	stream << std::setw( 6 );
-	stream << std::setprecision( 3 );
-	stream << std::setprecision( 3 );
-	stream << mDistanceCameraToSelectedGeometry;
-	stream << " | ";
-
-	if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() )
-		stream << "BROWSER";
-	else
-	if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
-		stream << "TIME   ";
-	stream << " | ";
-	stream << mSelectedPanel->mMediaSource->getPluginVersion();
-	stream << " | ";
-	if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
-	{
-		stream << std::setw( 3 ) << std::setfill( '0' );
-		stream << (int)mSelectedPanel->mMediaSource->getCurrentTime();
-		stream << " / ";
-		stream << std::setw( 3 ) << std::setfill( '0' );
-		stream << (int)mSelectedPanel->mMediaSource->getDuration();
-		stream << " @ ";
-		stream << (int)mSelectedPanel->mMediaSource->getCurrentPlayRate();
-		stream << " | ";
-	};
-
-	glutSetWindow( mBottomGLUIWindow->get_glut_window_id() );
-	mStatusText->set_text( const_cast< char*>( stream.str().c_str() ) );
-	glutSetWindow( mAppWindow );
-
-	// caching
-	cached_id = mSelectedPanel->mId;
-	cached_media_width = mSelectedPanel->mMediaWidth;
-	cached_media_height = mSelectedPanel->mMediaHeight;
-	cached_texture_width = mSelectedPanel->mTextureWidth;
-	cached_texture_height = mSelectedPanel->mTextureHeight;
-	cached_supports_browser_media = mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser();
-	cached_supports_time_media = mSelectedPanel->mMediaSource->pluginSupportsMediaTime();
-	cached_plugin_version = mSelectedPanel->mMediaSource->getPluginVersion();
-	cached_movie_time = (int)mSelectedPanel->mMediaSource->getCurrentTime();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::dumpPanelInfo()
-{
-	std::cout << std::endl << "===== Media Panels =====" << std::endl;
-	for( int i = 0; i < (int)mMediaPanels.size(); ++i )
-	{
-		std::cout << std::setw( 2 ) << std::setfill( '0' );
-		std::cout << i + 1 << "> ";
-		std::cout << "Id: ";
-		std::cout << std::setw( 2 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mId;
-		std::cout << " | ";
-		std::cout << "Media: ";
-		std::cout << std::setw( 3 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mMediaWidth;
-		std::cout << " x ";
-		std::cout << std::setw( 3 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mMediaHeight;
-		std::cout << " | ";
-		std::cout << "Texture: ";
-		std::cout << std::setw( 4 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mTextureWidth;
-		std::cout << " x ";
-		std::cout << std::setw( 4 ) << std::setfill( '0' );
-		std::cout << mMediaPanels[ i ]->mTextureHeight;
-		std::cout << " | ";
-		if ( mMediaPanels[ i ] == mSelectedPanel )
-			std::cout << "(selected)";
-
-		std::cout << std::endl;
-	};
-	std::cout << "========================" << std::endl;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
-{
-	// Uncomment this to make things much, much quieter.
-//	return;
-
-	switch(event)
-	{
-		case MEDIA_EVENT_CONTENT_UPDATED:
-			// too spammy -- don't log these
-//			std::cerr <<  "Media event:  MEDIA_EVENT_CONTENT_UPDATED " << std::endl;
-		break;
-
-		case MEDIA_EVENT_TIME_DURATION_UPDATED:
-			// too spammy -- don't log these
-//			std::cerr <<  "Media event:  MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << std::endl;
-		break;
-
-		case MEDIA_EVENT_SIZE_CHANGED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_SIZE_CHANGED " << std::endl;
-		break;
-
-		case MEDIA_EVENT_CURSOR_CHANGED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << std::endl;
-		break;
-
-		case MEDIA_EVENT_NAVIGATE_BEGIN:
-			std::cerr <<  "Media event:  MEDIA_EVENT_NAVIGATE_BEGIN " << std::endl;
-		break;
-
-		case MEDIA_EVENT_NAVIGATE_COMPLETE:
-			std::cerr <<  "Media event:  MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << std::endl;
-		break;
-
-		case MEDIA_EVENT_PROGRESS_UPDATED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << std::endl;
-		break;
-
-		case MEDIA_EVENT_STATUS_TEXT_CHANGED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << std::endl;
-		break;
-
-		case MEDIA_EVENT_NAME_CHANGED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_NAME_CHANGED, new name is: " << self->getMediaName() << std::endl;
-			glutSetWindowTitle( self->getMediaName().c_str() );
-		break;
-
-		case MEDIA_EVENT_LOCATION_CHANGED:
-		{
-			std::cerr <<  "Media event:  MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << std::endl;
-			mediaPanel* panel = findMediaPanel(self);
-			if(panel != NULL)
-			{
-				panel->mStartUrl = self->getLocation();
-				if(panel == mSelectedPanel)
-				{
-					mUrlEdit->set_text(const_cast<char*>(panel->mStartUrl.c_str()) );
-				}
-			}
-		}
-		break;
-
-		case MEDIA_EVENT_NAVIGATE_ERROR_PAGE:
-			std::cerr <<  "Media event:  MEDIA_EVENT_NAVIGATE_ERROR_PAGE, uri is: " << self->getClickURL() << std::endl;
-		break;
-			
-		case MEDIA_EVENT_CLICK_LINK_HREF:
-		{
-			std::cerr <<  "Media event:  MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << ", target is " << self->getClickTarget() << std::endl;
-			// retrieve the event parameters
-			std::string url = self->getClickURL();
-			std::string target = self->getClickTarget();
-			
-			if(target == "_external")
-			{
-				// this should open in an external browser, but since this is a test app we don't care.
-			}
-			else if(target == "_blank")
-			{
-				// Create a new panel with the specified URL.
-				addMediaPanel(url);
-			}
-			else // other named target
-			{
-				mediaPanel *target_panel = findMediaPanel(target);
-				if(target_panel)
-				{
-					target_panel = replaceMediaPanel(target_panel, url);
-				}
-				else
-				{
-					target_panel = addMediaPanel(url);
-				}
-
-				if(target_panel)
-				{
-					target_panel->mTarget = target;
-				}
-			}
-		}
-		break;
-
-		case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
-			std::cerr <<  "Media event:  MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << std::endl;
-		break;
-
-		case MEDIA_EVENT_PLUGIN_FAILED:
-			std::cerr <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED" << std::endl;
-		break;
-
-		case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH:
-			std::cerr <<  "Media event:  MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << std::endl;
-		break;
-
-		case MEDIA_EVENT_CLOSE_REQUEST:
-			std::cerr <<  "Media event:  MEDIA_EVENT_CLOSE_REQUEST" << std::endl;
-		break;
-		
-		case MEDIA_EVENT_PICK_FILE_REQUEST:
-			std::cerr <<  "Media event:  MEDIA_EVENT_PICK_FILE_REQUEST" << std::endl;
-			// TODO: display an actual file picker
-			self->sendPickFileResponse("cake");
-		break;
-
-		case MEDIA_EVENT_GEOMETRY_CHANGE:
-			std::cerr <<  "Media event:  MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() 
-				<< ", x = " << self->getGeometryX() 
-				<< ", y = " << self->getGeometryY() 
-				<< ", width = " << self->getGeometryWidth() 
-				<< ", height = " << self->getGeometryHeight() 
-				<< std::endl;
-		break;
-
-		case MEDIA_EVENT_AUTH_REQUEST:
-		{
-			//std::cerr <<  "Media event:  MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() ", realm " << self->getAuthRealm() << std::endl;
-
-			// TODO: display an auth dialog
-			self->sendAuthResponse(false, "", "");
-		}
-		break;
-
-		case MEDIA_EVENT_LINK_HOVERED:
-		{
-			std::cerr <<  "Media event:  MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << std::endl;
-		}
-		break;
-
-		default:
-		{
-			std::cerr <<  "Media event:  <unknown>, code is: " << int(event) << std::endl;
-		}
-		break;
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-static void gluiCallbackWrapper( int control_id )
-{
-	if ( gApplication )
-		gApplication->gluiCallback( control_id );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutReshape( int width, int height )
-{
-	if ( gApplication )
-		gApplication->reshape( width, height );
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutDisplay()
-{
-	if ( gApplication )
-		gApplication->display();
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutIdle(int update_ms)
-{
-	GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms);
-
-	if ( gApplication )
-		gApplication->idle();
-
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutKeyboard( unsigned char key, int x, int y )
-{
-	if ( gApplication )
-		gApplication->keyboard( key );
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutMousePassive( int x, int y )
-{
-	if ( gApplication )
-		gApplication->mousePassive( x, y );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutMouseMove( int x , int y )
-{
-	if ( gApplication )
-		gApplication->mouseMove( x, y );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void glutMouseButton( int button, int state, int x, int y )
-{
-	if ( gApplication )
-		gApplication->mouseButton( button, state, x, y );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-int main( int argc, char* argv[] )
-{
-#if LL_DARWIN
-	// Set the current working directory to <application bundle>/Contents/Resources/
-	CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
-	if(resources_url != NULL)
-	{
-		CFStringRef resources_string = CFURLCopyFileSystemPath(resources_url, kCFURLPOSIXPathStyle);
-		CFRelease(resources_url);
-		if(resources_string != NULL)
-		{
-			char buffer[PATH_MAX] = "";
-			if(CFStringGetCString(resources_string, buffer, sizeof(buffer), kCFStringEncodingUTF8))
-			{
-				chdir(buffer);
-			}
-			CFRelease(resources_string);
-		}
-	}
-#endif
-
-	glutInit( &argc, argv );
-	glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
-
-	const int app_window_x = 80;
-	const int app_window_y = 0;
-	const int app_window_width = 960;
-	const int app_window_height = 960;
-
-	glutInitWindowPosition( app_window_x, app_window_y );
-	glutInitWindowSize( app_window_width, app_window_height );
-
-	int app_window_handle = glutCreateWindow( "LLMediaPluginTest" );
-
-	glutDisplayFunc( glutDisplay );
-
-	GLUI_Master.set_glutReshapeFunc( glutReshape );
-	GLUI_Master.set_glutKeyboardFunc( glutKeyboard );
-	GLUI_Master.set_glutMouseFunc( glutMouseButton );
-
-	glutPassiveMotionFunc( glutMousePassive );
-	glutMotionFunc( glutMouseMove );
-
-	glutSetWindow( app_window_handle );
-
-	gApplication = new LLMediaPluginTest( app_window_handle, app_window_width, app_window_height );
-
-	// update at approximately 60hz
-	int update_ms = 1000 / 60;
-
-	GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms);
-
-	glutMainLoop();
-
-	delete gApplication;
-}
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.h b/indra/test_apps/llplugintest/llmediaplugintest.h
deleted file mode 100755
index 1f6f18e43c..0000000000
--- a/indra/test_apps/llplugintest/llmediaplugintest.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/**
- * @file LLMediaPluginTest.cpp
- * @brief Primary test application for LLMedia (Separate Process) Plugin system
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_MEDIA_PLUGIN_TEST_H
-#define LL_MEDIA_PLUGIN_TEST_H
-
-#include <vector>
-#include <string>
-#include "llpluginclassmedia.h"
-#include "llgl.h"
-
-// Forward declarations
-class GLUI_Rotation;
-class GLUI_Translation;
-class GLUI_Listbox;
-class GLUI_EditText;
-class GLUI_StaticText;
-class GLUI;
-class GLUI_Button;
-
-////////////////////////////////////////////////////////////////////////////////
-//
-struct mediaPanel
-{
-	public:
-		mediaPanel();
-		~mediaPanel();
-		int mId;
-		std::string mStartUrl;
-		std::string mMimeType;
-		std::string mTarget;
-		LLPluginClassMedia *mMediaSource;
-		int mMediaWidth;
-		int mMediaHeight;
-		int mTextureWidth;
-		int mTextureHeight;
-		double mTextureScaleX;
-		double mTextureScaleY;
-		GLuint mMediaTextureHandle;
-		GLuint mPickTextureHandle;
-		unsigned char* mPickTexturePixels;
-		bool mAppTextureCoordsOpenGL;
-		bool mReadyToRender;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-class LLMediaPluginTest : public LLPluginClassMediaOwner
-{
-	public:
-		LLMediaPluginTest( int app_window, int window_width, int window_height );
-		~LLMediaPluginTest();
-
-		void reshape( int width, int height );
-		void display();
-		void idle();
-		void gluiCallback( int control_id );
-		void keyboard( int key );
-		void mousePassive( int x, int y );
-		void mouseButton( int button, int state, int x, int y );
-		void mouseMove( int x, int y );
-
-		void bindTexture(GLuint texture, GLint row_length = 0, GLint alignment = 1);
-		bool checkGLError(const char *name = "OpenGL");
-		void drawGeometry( int panel, bool selected );
-		void startPanelHighlight( float red, float green, float blue, float line_width );
-		void endPanelHighlight();
-		enum { DrawTypePickTexture, DrawTypeMediaTexture };
-		void draw( int draw_type );
-		void windowPosToTexturePos( int window_x, int window_y, int& media_x, int& media_y, int& id );
-
-		mediaPanel* addMediaPanel( std::string url );
-		void updateMediaPanel( mediaPanel* panel );
-		void remMediaPanel( mediaPanel* panel );
-		mediaPanel* replaceMediaPanel( mediaPanel* panel, std::string url );
-		void getRandomMediaSize( int& width, int& height, std::string mime_type );
-		void navigateToNewURI( std::string uri );
-        void initUrlHistory( std::string uri );
-		void selectPanelById( int id );
-		void selectPanel( mediaPanel* panel );
-		mediaPanel* findMediaPanel( LLPluginClassMedia* panel );
-		mediaPanel* findMediaPanel( const std::string &target_name );
-		void makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels );
-		void makeChrome();
-		void resetView();
-
-		void dumpPanelInfo();
-		void updateStatusBar();
-
-		GLfloat distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z );
-		
-
-	// Inherited from LLPluginClassMediaOwner
-	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent);
-
-	private:
-		const int mVersionMajor;
-		const int mVersionMinor;
-		const int mVersionPatch;
-		const int mMaxPanels;
-		int mAppWindow;
-		int mWindowWidth;
-		int mWindowHeight;
-		int mCurMouseX;
-		int mCurMouseY;
-		unsigned char mPixelReadColor[ 3 ];
-		bool mFuzzyMedia;
-		const std::string mHomeWebUrl;
-
-		std::vector< mediaPanel* > mMediaPanels;
-		mediaPanel* mSelectedPanel;
-		std::string mimeTypeFromUrl( std::string& url );
-		std::string pluginNameFromMimeType( std::string& mime_type );
-
-		GLUI_Rotation* mViewRotationCtrl;
-		GLUI_Translation* mViewScaleCtrl;
-		GLUI_Translation* mViewTranslationCtrl;
-		float mViewportAspect;
-		float mViewPos[ 3 ];
-		float mViewRotation[ 16 ];
-
-		float mDistanceCameraToSelectedGeometry;
-
-		int mIdControlAddPanel;
-		int mIdControlRemPanel;
-
-		std::vector< std::pair< std::string, std::string > > mBookmarks;
-		GLUI_Listbox* mBookmarkList;
-		int mIdBookmarks;
-		int mIdUrlEdit;
-		GLUI_EditText* mUrlEdit;
-        int mIdUrlInitHistoryEdit;
-		GLUI_EditText* mUrlInitHistoryEdit;
-		int mSelBookmark;
-		int mIdRandomPanelCount;
-		int mRandomPanelCount;
-		int mIdRandomBookmarks;
-		int mRandomBookmarks;
-		int mIdDisableTimeout;
-		int mDisableTimeout;
-		int mIdUsePluginReadThread;
-		int mUsePluginReadThread;
-		int mIdLargePanelSpacing;
-		int mLargePanelSpacing;
-		int mIdControlCrashPlugin;
-		int mIdControlHangPlugin;
-		int mIdControlExitApp;
-
-		GLUI* mGluiMediaTimeControlWindow;
-		int mIdMediaTimeControlPlay;
-		int mIdMediaTimeControlLoop;
-		int mIdMediaTimeControlPause;
-		int mIdMediaTimeControlStop;
-		int mIdMediaTimeControlSeek;
-		int mIdMediaTimeControlVolume;
-		int mMediaTimeControlVolume;
-		int mIdMediaTimeControlSeekSeconds;
-		int mMediaTimeControlSeekSeconds;
-		int mIdMediaTimeControlRewind;
-		int mIdMediaTimeControlFastForward;
-
-		GLUI* mGluiMediaBrowserControlWindow;
-		int mIdMediaBrowserControlBack;
-		GLUI_Button* mMediaBrowserControlBackButton;
-		int mIdMediaBrowserControlStop;
-		int mIdMediaBrowserControlForward;
-		GLUI_Button* mMediaBrowserControlForwardButton;
-		bool mGluiMediaTimeControlWindowFlag;
-		bool mGluiMediaBrowserControlWindowFlag;
-		bool mMediaBrowserControlBackButtonFlag;
-		bool mMediaBrowserControlForwardButtonFlag;
-		int mIdMediaBrowserControlHome;
-		int mIdMediaBrowserControlReload;
-		int mIdMediaBrowserControlClearCache;
-		int mIdMediaBrowserControlClearCookies;
-		int mIdMediaBrowserControlEnableCookies;
-		int mMediaBrowserControlEnableCookies;
-
-		GLUI* mBottomGLUIWindow;
-		GLUI_StaticText* mStatusText;
-};
-
-#endif	// LL_MEDIA_PLUGIN_TEST_H
-
-- 
cgit v1.2.3


From 2fc42c1221393161fcd882b6bb73a7a6da9d07e2 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Fri, 2 Oct 2015 12:21:09 -0700
Subject: MAINT-5687: Further purge QT and webkit from the build.

---
 indra/newview/CMakeLists.txt                |  30 ------
 indra/newview/viewer_manifest.py            |  30 ------
 indra/test_apps/llplugintest/CMakeLists.txt | 139 ----------------------------
 3 files changed, 199 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 087d508c42..73ed651e65 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1760,39 +1760,9 @@ 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}/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}/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_cef
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 15ec946e63..9a65171d44 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1216,36 +1216,6 @@ class Linux_i686_Manifest(LinuxManifest):
                 self.path("libvivoxplatform.so")
                 self.end_prefix("lib")
 
-            # plugin runtime
-            if self.prefix(src=os.path.join(pkgdir, "lib"), dst="lib"):
-                self.path("libQtCore.so*")
-                self.path("libQtGui.so*")
-                self.path("libQtNetwork.so*")
-                self.path("libQtOpenGL.so*")
-                self.path("libQtSvg.so*")
-                self.path("libQtXml.so*")
-                self.end_prefix("lib")
-
-            # For WebKit/Qt plugin runtimes (image format plugins)
-            if self.prefix(src=os.path.join(pkgdir, "llplugin", "imageformats"),
-                           dst="bin/llplugin/imageformats"):
-                self.path("libqgif.so")
-                self.path("libqico.so")
-                self.path("libqjpeg.so")
-                self.path("libqmng.so")
-                self.path("libqsvg.so")
-                self.path("libqtiff.so")
-                self.end_prefix("bin/llplugin/imageformats")
-
-            # For WebKit/Qt plugin runtimes (codec/character encoding plugins)
-            if self.prefix(src=os.path.join(pkgdir, "llplugin", "codecs"),
-                           dst="bin/llplugin/codecs"):
-                self.path("libqcncodecs.so")
-                self.path("libqjpcodecs.so")
-                self.path("libqkrcodecs.so")
-                self.path("libqtwcodecs.so")
-                self.end_prefix("bin/llplugin/codecs")
-
             self.strip_binaries()
 
 
diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt
index 18f7e36d20..e682eaccca 100755
--- a/indra/test_apps/llplugintest/CMakeLists.txt
+++ b/indra/test_apps/llplugintest/CMakeLists.txt
@@ -268,10 +268,6 @@ if(WINDOWS)
     libgmodule-2.0-0.dll
     libgobject-2.0-0.dll
     libgthread-2.0-0.dll
-    qtcored4.dll
-    qtguid4.dll
-    qtnetworkd4.dll
-    qtopengld4.dll
     ssleay32.dll
     )
   copy_if_different(
@@ -282,40 +278,6 @@ if(WINDOWS)
     )
   set(plugin_test_targets ${plugin_test_targets} ${out_targets})
   
-  # Debug config runtime files required for the plugin test mule (Qt image format plugins)
-  set(plugintest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}/imageformats")
-  set(plugintest_debug_files
-    qgifd4.dll
-    qicod4.dll
-    qjpegd4.dll
-    qmngd4.dll
-    qsvgd4.dll
-    qtiffd4.dll
-    )
-  copy_if_different(
-    ${plugintest_debug_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Debug/imageformats"
-    out_targets
-    ${plugintest_debug_files}
-    )
-  set(plugin_test_targets ${plugin_test_targets} ${out_targets})
-
-  # Debug config runtime files required for the plugin test mule (Qt codec plugins)
-  set(plugintest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}/codecs")
-  set(plugintest_debug_files
-    qcncodecsd4.dll
-    qjpcodecsd4.dll
-    qkrcodecsd4.dll
-    qtwcodecsd4.dll
-    )
-  copy_if_different(
-    ${plugintest_debug_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Debug/codecs"
-    out_targets
-    ${plugintest_debug_files}
-    )
-  set(plugin_test_targets ${plugin_test_targets} ${out_targets})
- 
   # Release & ReleaseDebInfo config runtime files required for the plugin test mule
   set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
   set(plugintest_release_files
@@ -324,11 +286,6 @@ if(WINDOWS)
     libgmodule-2.0-0.dll
     libgobject-2.0-0.dll
     libgthread-2.0-0.dll
-    qtcore4.dll
-    qtgui4.dll
-    qtnetwork4.dll
-    qtopengl4.dll
-    qtxmlpatterns4.dll
     ssleay32.dll
     )
   copy_if_different(
@@ -347,56 +304,6 @@ if(WINDOWS)
     )
   set(plugin_test_targets ${plugin_test_targets} ${out_targets})
 
-  # Release & ReleaseDebInfo config runtime files required for the plugin test mule (Qt image format plugins)
-  set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}/imageformats")
-  set(plugintest_release_files
-    qgif4.dll
-    qico4.dll
-    qjpeg4.dll
-    qmng4.dll
-    qsvg4.dll
-    qtiff4.dll
-    )
-  copy_if_different(
-    ${plugintest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Release/imageformats"
-    out_targets
-    ${plugintest_release_files}
-    )
-  set(plugin_test_targets ${plugin_test_targets} ${out_targets})
-
-  copy_if_different(
-    ${plugintest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/imageformats"
-    out_targets
-    ${plugintest_release_files}
-    )
-  set(plugin_test_targets ${plugin_test_targets} ${out_targets})
-
-  # Release & ReleaseDebInfo config runtime files required for the plugin test mule (Qt codec plugins)
-  set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}/codecs")
-  set(plugintest_release_files
-    qcncodecs4.dll  
-    qjpcodecs4.dll  
-    qkrcodecs4.dll  
-    qtwcodecs4.dll  
-    )
-  copy_if_different(
-    ${plugintest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/Release/codecs"
-    out_targets
-    ${plugintest_release_files}
-    )
-  set(plugin_test_targets ${plugin_test_targets} ${out_targets})
-
-  copy_if_different(
-    ${plugintest_release_src_dir}
-    "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/codecs"
-    out_targets
-    ${plugintest_release_files}
-    )
-  set(plugin_test_targets ${plugin_test_targets} ${out_targets})
- 
    add_custom_target(copy_plugintest_libs ALL
      DEPENDS 
      ${plugin_test_targets}
@@ -411,18 +318,6 @@ if (DARWIN)
     libaprutil-1.0.dylib
     libapr-1.0.dylib
     libexpat.1.5.2.dylib
-    libQtCore.4.7.1.dylib
-    libQtCore.4.dylib
-    libQtGui.4.7.1.dylib
-    libQtGui.4.dylib
-    libQtNetwork.4.7.1.dylib
-    libQtNetwork.4.dylib
-    libQtOpenGL.4.7.1.dylib
-    libQtOpenGL.4.dylib
-    libQtSvg.4.7.1.dylib
-    libQtSvg.4.dylib
-    libQtXml.4.7.1.dylib
-    libQtXml.4.dylib
     )
   copy_if_different(
     ${plugintest_release_src_dir}
@@ -432,40 +327,6 @@ if (DARWIN)
     )
   set(plugin_test_targets ${plugin_test_targets} ${out_targets})
 
-  # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt image format plugins)
-  set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/imageformats")
-  set(plugintest_release_files
-    libqgif.dylib
-    libqico.dylib
-    libqjpeg.dylib
-    libqmng.dylib
-    libqsvg.dylib
-    libqtiff.dylib
-    )
-  copy_if_different(
-    ${plugintest_release_src_dir}
-    "${PLUGINS_DESTINATION_DIR}/imageformats"
-    out_targets
-    ${plugintest_release_files}
-    )
-  set(plugin_test_targets ${plugin_test_targets} ${out_targets})
-
-  # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt codec plugins)
-  set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/codecs")
-  set(plugintest_release_files
-    libqcncodecs.dylib
-    libqjpcodecs.dylib
-    libqkrcodecs.dylib
-    libqtwcodecs.dylib
-    )
-  copy_if_different(
-    ${plugintest_release_src_dir}
-    "${PLUGINS_DESTINATION_DIR}/codecs"
-    out_targets
-    ${plugintest_release_files}
-    )
-  set(plugin_test_targets ${plugin_test_targets} ${out_targets})
-
   add_custom_target(copy_plugintest_libs ALL
     DEPENDS 
     ${plugin_test_targets}
-- 
cgit v1.2.3


From ebcee8d7e7cb6ead01e1061fd1cf1720ee7e1a45 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 6 Oct 2015 15:24:57 -0700
Subject: MAINT-5703 fix - add observer to media plugin so
 MEDIA_LOCATION_CHANGED events get propagated throughout system

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 9b87eca726..5b9ff6cac8 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -390,6 +390,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				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->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2));
-- 
cgit v1.2.3


From 295d392b1c1ed6182eb2dce528fd396eab2ed2b2 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Fri, 9 Oct 2015 10:09:18 -0700
Subject: MAINT-5715, MAINT-5717, MAINT-5718: Replace the the volume catcher
 that was removed with the QT viewer.  Addresses panning and fading issues,
 teleport and viewer mute controls.

---
 indra/media_plugins/cef/CMakeLists.txt             |  34 ++-
 indra/media_plugins/cef/mac_volume_catcher.cpp     | 275 +++++++++++++++++++++
 indra/media_plugins/cef/media_plugin_cef.cpp       |  20 +-
 indra/media_plugins/cef/volume_catcher.h           |  54 ++++
 indra/media_plugins/cef/windows_volume_catcher.cpp | 147 +++++++++++
 5 files changed, 525 insertions(+), 5 deletions(-)
 create mode 100644 indra/media_plugins/cef/mac_volume_catcher.cpp
 create mode 100644 indra/media_plugins/cef/volume_catcher.h
 create mode 100644 indra/media_plugins/cef/windows_volume_catcher.cpp

(limited to 'indra')

diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 7465fe727a..9bd6dbc5e9 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -45,23 +45,49 @@ set(media_plugin_cef_SOURCE_FILES
     media_plugin_cef.cpp
     )
 
+set(media_plugin_webkit_HEADER_FILES
+    volume_catcher.h
+    )
+
+# Select which VolumeCatcher implementation to use
+if (LINUX)
+  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_cef_SOURCE_FILES mac_volume_catcher.cpp)
+  find_library(CORESERVICES_LIBRARY CoreServices)
+  find_library(AUDIOUNIT_LIBRARY AudioUnit)
+  list(APPEND media_plugin_cef_SOURCE_FILES
+       ${CORESERVICES_LIBRARY}     # for Component Manager calls
+       ${AUDIOUNIT_LIBRARY}        # for AudioUnit calls
+       )
+elseif (WINDOWS)
+  list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp)
+endif (LINUX)
+
+set_source_files_properties(${media_plugin_webkit_HEADER_FILES}
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES})
+
 add_library(media_plugin_cef
     SHARED
     ${media_plugin_cef_SOURCE_FILES}
 )
 
-target_link_libraries(media_plugin_cef
+add_dependencies(media_plugin_cef
   ${LLPLUGIN_LIBRARIES}
   ${MEDIA_PLUGIN_BASE_LIBRARIES}
   ${LLCOMMON_LIBRARIES}
-  ${CEF_PLUGIN_LIBRARIES}
-  ${PLUGIN_API_WINDOWS_LIBRARIES}
 )
 
-add_dependencies(media_plugin_cef
+target_link_libraries(media_plugin_cef
   ${LLPLUGIN_LIBRARIES}
   ${MEDIA_PLUGIN_BASE_LIBRARIES}
   ${LLCOMMON_LIBRARIES}
+  ${CEF_PLUGIN_LIBRARIES}
+  ${PLUGIN_API_WINDOWS_LIBRARIES}
 )
 
 if (WINDOWS)
diff --git a/indra/media_plugins/cef/mac_volume_catcher.cpp b/indra/media_plugins/cef/mac_volume_catcher.cpp
new file mode 100644
index 0000000000..73e5bf3da3
--- /dev/null
+++ b/indra/media_plugins/cef/mac_volume_catcher.cpp
@@ -0,0 +1,275 @@
+/** 
+ * @file mac_volume_catcher.cpp
+ * @brief A Mac OS X specific hack to control the volume level of all audio channels opened by a process.
+ *
+ * @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
+ */
+
+/**************************************************************************************************************
+	This code works by using CaptureComponent to capture the "Default Output" audio component
+	(kAudioUnitType_Output/kAudioUnitSubType_DefaultOutput) and delegating all calls to the original component.
+	It does this just to keep track of all instances of the default output component, so that it can set the
+	kHALOutputParam_Volume parameter on all of them to adjust the output volume.
+**************************************************************************************************************/
+
+#include "volume_catcher.h"
+
+#include <QuickTime/QuickTime.h>
+#include <AudioUnit/AudioUnit.h>
+#include <list>
+
+#if LL_DARWIN
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+struct VolumeCatcherStorage;
+
+class VolumeCatcherImpl
+{
+public:
+
+	void setVolume(F32 volume);
+	void setPan(F32 pan);
+	
+	void setInstanceVolume(VolumeCatcherStorage *instance);
+	
+	std::list<VolumeCatcherStorage*> mComponentInstances;
+	Component mOriginalDefaultOutput;
+	Component mVolumeAdjuster;
+	
+	static VolumeCatcherImpl *getInstance();
+private:
+	// This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
+	VolumeCatcherImpl();
+	static VolumeCatcherImpl *sInstance;
+	
+	// The singlar instance of this class is expected to last until the process exits.
+	// To ensure this, we declare the destructor here but never define it, so any code which attempts to destroy the instance will not link.
+	~VolumeCatcherImpl();	
+	
+	F32 mVolume;
+	F32 mPan;
+};
+
+VolumeCatcherImpl *VolumeCatcherImpl::sInstance = NULL;;
+
+struct VolumeCatcherStorage
+{
+	ComponentInstance self;
+	ComponentInstance delegate;
+};
+
+static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage);
+static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self);
+static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self);
+
+VolumeCatcherImpl *VolumeCatcherImpl::getInstance()
+{
+	if(!sInstance)
+	{
+		sInstance = new VolumeCatcherImpl;
+	}
+	
+	return sInstance;
+}
+
+VolumeCatcherImpl::VolumeCatcherImpl()
+{
+	mVolume = 1.0;	// default to full volume
+	mPan = 0.0;		// and center pan
+		
+	ComponentDescription desc;
+	desc.componentType = kAudioUnitType_Output;
+	desc.componentSubType = kAudioUnitSubType_DefaultOutput;
+	desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+	desc.componentFlags = 0;
+	desc.componentFlagsMask = 0;
+	
+	// Find the original default output component
+	mOriginalDefaultOutput = FindNextComponent(NULL, &desc);
+
+	// Register our own output component with the same parameters
+	mVolumeAdjuster = RegisterComponent(&desc, NewComponentRoutineUPP(volume_catcher_component_entry), 0, NULL, NULL, NULL);
+
+	// Capture the original component, so we always get found instead.
+	CaptureComponent(mOriginalDefaultOutput, mVolumeAdjuster);
+
+}
+
+static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage)
+{
+	ComponentResult result = badComponentSelector;
+	VolumeCatcherStorage *storage = (VolumeCatcherStorage*)componentStorage;
+	
+	switch(cp->what)
+	{
+		case kComponentOpenSelect:
+//			std::cerr << "kComponentOpenSelect" << std::endl;
+			result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_open, uppCallComponentOpenProcInfo);
+		break;
+
+		case kComponentCloseSelect:
+//			std::cerr << "kComponentCloseSelect" << std::endl;
+			result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_close, uppCallComponentCloseProcInfo);
+			// CallComponentFunctionWithStorageProcInfo
+		break;
+		
+		default:
+//			std::cerr << "Delegating selector: " << cp->what << " to component instance " << storage->delegate << std::endl;
+			result = DelegateComponentCall(cp, storage->delegate);
+		break;
+	}
+	
+	return result;
+}
+
+static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self)
+{
+	ComponentResult result = noErr;
+	VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();	
+	
+	storage = new VolumeCatcherStorage;
+
+	storage->self = self;
+	storage->delegate = NULL;
+
+	result = OpenAComponent(impl->mOriginalDefaultOutput, &(storage->delegate));
+	
+	if(result != noErr)
+	{
+//		std::cerr << "OpenAComponent result = " << result << ", component ref = " << storage->delegate << std::endl;
+		
+		// If we failed to open the delagate component, our open is going to fail.  Clean things up.
+		delete storage;
+	}
+	else
+	{
+		// Success -- set up this component's storage
+		SetComponentInstanceStorage(self, (Handle)storage);
+
+		// add this instance to the global list
+		impl->mComponentInstances.push_back(storage);	
+		
+		// and set up the initial volume
+		impl->setInstanceVolume(storage);
+	}
+
+	return result;
+}
+
+static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self)
+{
+	ComponentResult result = noErr;
+	
+	if(storage)
+	{
+		if(storage->delegate)
+		{
+			CloseComponent(storage->delegate);
+			storage->delegate = NULL;
+		}
+		
+		VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();	
+		impl->mComponentInstances.remove(storage);
+		delete[] storage;
+	}
+		
+	return result;
+}
+
+void VolumeCatcherImpl::setVolume(F32 volume)
+{
+	VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();	
+	impl->mVolume = volume;
+	
+	// Iterate through all known instances, setting the volume on each.
+	for(std::list<VolumeCatcherStorage*>::iterator iter = mComponentInstances.begin(); iter != mComponentInstances.end(); ++iter)
+	{
+		impl->setInstanceVolume(*iter);
+	}
+}
+
+void VolumeCatcherImpl::setPan(F32 pan)
+{
+	VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();	
+	impl->mPan = pan;
+	
+	// TODO: implement this.
+	// This will probably require adding a "panner" audio unit to the chain somehow.
+	// There's also a "3d mixer" component that we might be able to use...
+}
+
+void VolumeCatcherImpl::setInstanceVolume(VolumeCatcherStorage *instance)
+{
+//	std::cerr << "Setting volume on component instance: " << (instance->delegate) << " to " << mVolume << std::endl;
+	
+	OSStatus err = noErr;
+	
+	if(instance && instance->delegate)
+	{
+		err = AudioUnitSetParameter(
+				instance->delegate, 
+				kHALOutputParam_Volume, 
+				kAudioUnitScope_Global,
+				0, 
+				mVolume, 
+				0);
+	}
+	
+	if(err)
+	{
+//		std::cerr << "    AudioUnitSetParameter returned " << err << std::endl;
+	}
+}
+
+/////////////////////////////////////////////////////
+
+VolumeCatcher::VolumeCatcher()
+{
+	pimpl = VolumeCatcherImpl::getInstance();
+}
+
+VolumeCatcher::~VolumeCatcher()
+{
+	// Let the instance persist until exit.
+}
+
+void VolumeCatcher::setVolume(F32 volume)
+{
+	pimpl->setVolume(volume);
+}
+
+void VolumeCatcher::setPan(F32 pan)
+{
+	pimpl->setPan(pan);
+}
+
+void VolumeCatcher::pump()
+{
+	// No periodic tasks are necessary for this implementation.
+}
+
+#if LL_DARWIN
+#pragma GCC diagnostic warning "-Wdeprecated-declarations"
+#endif
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 5b9ff6cac8..3f3d9dc657 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -39,6 +39,7 @@
 #include "boost/function.hpp"
 #include "boost/bind.hpp"
 #include "llCEFLib.h"
+#include "volume_catcher.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 //
@@ -76,6 +77,7 @@ private:
 	void unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data);
 
 	void checkEditState();
+    void setVolume(F32 vol);
 
 	bool mEnableMediaPluginDebugging;
 	std::string mHostLanguage;
@@ -92,6 +94,8 @@ private:
 	std::string mCachePath;
 	std::string mCookiePath;
 	LLCEFLib* mLLCEFLib;
+
+    VolumeCatcher mVolumeCatcher;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -332,6 +336,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			{
 				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
@@ -630,7 +635,15 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mJavascriptEnabled = message_in.getValueBoolean("enable");
 			}
 		}
-		else
+        else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
+        {
+            if (message_name == "set_volume")
+            {
+                F32 volume = (F32)message_in.getValueReal("volume");
+                setVolume(volume);
+            }
+        }
+        else
 		{
 			//std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
 		};
@@ -763,6 +776,11 @@ void MediaPluginCEF::checkEditState()
 	}
 }
 
+void MediaPluginCEF::setVolume(F32 vol)
+{
+    mVolumeCatcher.setVolume(vol);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 bool MediaPluginCEF::init()
diff --git a/indra/media_plugins/cef/volume_catcher.h b/indra/media_plugins/cef/volume_catcher.h
new file mode 100644
index 0000000000..337f2913d3
--- /dev/null
+++ b/indra/media_plugins/cef/volume_catcher.h
@@ -0,0 +1,54 @@
+/** 
+ * @file volume_catcher.h
+ * @brief Interface to a class with platform-specific implementations that allows control of the audio volume of all sources in the current process.
+ *
+ * @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
+ */
+
+#ifndef VOLUME_CATCHER_H
+#define VOLUME_CATCHER_H
+
+#include "linden_common.h"
+
+class VolumeCatcherImpl;
+
+class VolumeCatcher
+{
+ public:
+	VolumeCatcher();
+	~VolumeCatcher();
+
+	void setVolume(F32 volume); // 0.0 - 1.0
+	
+	// Set the left-right pan of audio sources
+	// where -1.0 = left, 0 = center, and 1.0 = right
+	void setPan(F32 pan); 
+
+	void pump(); // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume
+	
+ private:
+	VolumeCatcherImpl *pimpl;
+};
+
+#endif // VOLUME_CATCHER_H
diff --git a/indra/media_plugins/cef/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp
new file mode 100644
index 0000000000..0cfb810906
--- /dev/null
+++ b/indra/media_plugins/cef/windows_volume_catcher.cpp
@@ -0,0 +1,147 @@
+/** 
+ * @file windows_volume_catcher.cpp
+ * @brief A Windows implementation of volume level control of all audio channels opened by a process.
+ *
+ * @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"
+#include <windows.h>
+#include "llsingleton.h"
+class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl>
+{
+friend LLSingleton<VolumeCatcherImpl>;
+public:
+
+	void setVolume(F32 volume);
+	void setPan(F32 pan);
+	
+private:
+	// This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
+	VolumeCatcherImpl();
+	~VolumeCatcherImpl();
+
+	typedef void (WINAPI *set_volume_func_t)(F32);
+	typedef void (WINAPI *set_mute_func_t)(bool);
+
+	set_volume_func_t mSetVolumeFunc;
+	set_mute_func_t mSetMuteFunc;
+
+	// tests if running on Vista, 7, 8 + once in CTOR
+	bool isWindowsVistaOrHigher();
+
+	F32 	mVolume;
+	F32 	mPan;
+	bool mSystemIsVistaOrHigher;
+};
+
+bool VolumeCatcherImpl::isWindowsVistaOrHigher()
+{
+	OSVERSIONINFO osvi;
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+	GetVersionEx(&osvi);
+	return osvi.dwMajorVersion >= 6;
+}
+
+VolumeCatcherImpl::VolumeCatcherImpl()
+:	mVolume(1.0f),			// default volume is max
+	mPan(0.f)				// default pan is centered
+{
+	mSystemIsVistaOrHigher = isWindowsVistaOrHigher();
+
+	if ( ! mSystemIsVistaOrHigher )
+	{
+		HMODULE handle = ::LoadLibrary(L"winmm.dll");
+		if(handle)
+		{
+			mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume");
+			mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute");
+		}
+	}
+}
+
+VolumeCatcherImpl::~VolumeCatcherImpl()
+{
+}
+
+void VolumeCatcherImpl::setVolume(F32 volume)
+{
+	mVolume = volume;
+
+	if ( mSystemIsVistaOrHigher )
+	{
+		// set both left/right to same volume
+		// TODO: use pan value to set independently
+		DWORD left_channel  = (DWORD)(mVolume * 65535.0f);
+		DWORD right_channel =  (DWORD)(mVolume * 65535.0f);
+		DWORD hw_volume = left_channel << 16 | right_channel;
+		::waveOutSetVolume(NULL, hw_volume);
+	}
+	else
+	{
+		if (mSetMuteFunc)
+		{
+			mSetMuteFunc(volume == 0.f);
+		}
+		if (mSetVolumeFunc)
+		{
+			mSetVolumeFunc(mVolume);
+		}
+	}
+}
+
+void VolumeCatcherImpl::setPan(F32 pan)
+{	// remember pan for calculating individual channel levels later
+	mPan = pan;
+}
+
+/////////////////////////////////////////////////////
+
+VolumeCatcher::VolumeCatcher()
+{
+	pimpl = VolumeCatcherImpl::getInstance();
+}
+
+VolumeCatcher::~VolumeCatcher()
+{
+	// Let the instance persist until exit.
+}
+
+void VolumeCatcher::setVolume(F32 volume)
+{
+	pimpl->setVolume(volume);
+}
+
+void VolumeCatcher::setPan(F32 pan)
+{
+	pimpl->setPan(pan);
+}
+
+void VolumeCatcher::pump()
+{
+	// No periodic tasks are necessary for this implementation.
+}
+
+
-- 
cgit v1.2.3


From 506e7271a7b69cc08a9096a6642a0b3f1b0ce04a Mon Sep 17 00:00:00 2001
From: rider <rider@lindenlab.com>
Date: Fri, 9 Oct 2015 11:51:10 -0700
Subject: CMake fixes for mac build.

---
 indra/media_plugins/cef/CMakeLists.txt         | 22 +++++++++++++---------
 indra/media_plugins/cef/mac_volume_catcher.cpp |  2 +-
 2 files changed, 14 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 9bd6dbc5e9..16015be672 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -45,20 +45,28 @@ 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_cef_LINK_LIBRARIES
+  ${LLPLUGIN_LIBRARIES}
+  ${MEDIA_PLUGIN_BASE_LIBRARIES}
+  ${LLCOMMON_LIBRARIES}
+  ${CEF_PLUGIN_LIBRARIES}
+  ${PLUGIN_API_WINDOWS_LIBRARIES})
+
+
 # Select which VolumeCatcher implementation to use
 if (LINUX)
-  message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n" 
+  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_cef_SOURCE_FILES mac_volume_catcher.cpp)
   find_library(CORESERVICES_LIBRARY CoreServices)
   find_library(AUDIOUNIT_LIBRARY AudioUnit)
-  list(APPEND media_plugin_cef_SOURCE_FILES
+  list(APPEND media_plugin_cef_LINK_LIBRARIES
        ${CORESERVICES_LIBRARY}     # for Component Manager calls
        ${AUDIOUNIT_LIBRARY}        # for AudioUnit calls
        )
@@ -66,7 +74,7 @@ elseif (WINDOWS)
   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_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES})
@@ -83,11 +91,7 @@ add_dependencies(media_plugin_cef
 )
 
 target_link_libraries(media_plugin_cef
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${CEF_PLUGIN_LIBRARIES}
-  ${PLUGIN_API_WINDOWS_LIBRARIES}
+  ${media_plugin_cef_LINK_LIBRARIES}
 )
 
 if (WINDOWS)
diff --git a/indra/media_plugins/cef/mac_volume_catcher.cpp b/indra/media_plugins/cef/mac_volume_catcher.cpp
index 73e5bf3da3..dddb9c2077 100644
--- a/indra/media_plugins/cef/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;
-- 
cgit v1.2.3


From 2a899b49dd5d0a4ff4b4ab2e36bda48ff1473f0a Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Mon, 19 Oct 2015 18:43:48 -0700
Subject: MAINT-5711 FIX profiles and marketplace are asking for a login each
 session

---
 indra/llplugin/llpluginclassmedia.cpp        | 13 +++++++++
 indra/llplugin/llpluginclassmedia.h          |  2 ++
 indra/media_plugins/cef/media_plugin_cef.cpp |  9 ++++++
 indra/newview/llviewermedia.cpp              | 41 ++++++++++++++++++++++++++++
 indra/newview/llviewermedia.h                |  1 +
 5 files changed, 66 insertions(+)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index c1464db834..b48f664a2a 100755
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -670,6 +670,19 @@ bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD
 	return true;
 }
 
+void LLPluginClassMedia::setCookie(std::string uri, std::string name, std::string value, std::string domain, std::string path)
+{
+	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);
+
+	sendMessage(message);
+}
+
 void LLPluginClassMedia::loadURI(const std::string &uri)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "load_uri");
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 5fe8254331..3f53551b90 100755
--- 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);
+
 	void loadURI(const std::string &uri);
 	
 	// "Loading" means uninitialized or any state prior to fully running (processing commands)
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 3f3d9dc657..7f538e16d8 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -479,6 +479,15 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				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");
+				mLLCEFLib->setCookie(uri, name, value, domain, path);
+			}
 			else if (message_name == "mouse_event")
 			{
 				std::string event = message_in.getValue("event");
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 5eab0a15ab..3342fddade 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -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"
@@ -1388,6 +1389,28 @@ LLSD LLViewerMedia::getHeaders()
 	return headers;
 }
 
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // static
+bool LLViewerMedia::parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path)
+{
+	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
+
+			return true;
+		}
+	}
+
+	return false;
+}
+
+
 /////////////////////////////////////////////////////////////////////////////////////////
 // static
 void LLViewerMedia::setOpenIDCookie()
@@ -1419,6 +1442,24 @@ void LLViewerMedia::setOpenIDCookie()
 		
 		getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start));
 
+		LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("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 = "";
+			if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path))
+			{
+				std::string url = "http://id.secondlife.com/openid/webkit";
+				media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path);
+			}
+		};
+
+		// 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] = "*/*";
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index f2da30e10b..0101c85e79 100755
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -163,6 +163,7 @@ public:
 	static LLSD getHeaders();
 	
 private:
+	static bool parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path);
 	static void setOpenIDCookie();
 	static void onTeleportFinished();
 	
-- 
cgit v1.2.3


From c16e726d0e2a8c607ce441eb5bf2419b16b41cab Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 20 Oct 2015 14:44:36 -0700
Subject: MAINT-5711 FIX2 auto login for profiles - final part retrieves the
 URL to set cookie for from the message sent over by login.cgi

---
 indra/llmessage/llcurl.cpp      |  5 +++++
 indra/llmessage/llcurl.h        |  1 +
 indra/newview/llviewermedia.cpp | 43 +++++++++++++++++++++++------------------
 indra/newview/llviewermedia.h   |  4 ++--
 4 files changed, 32 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 73df47b933..7e9ae8d108 100755
--- 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..14d4a14deb 100755
--- 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& Responder::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/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 3342fddade..1098b2a7e1 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -285,13 +285,16 @@ public:
 		const LLChannelDescriptors& channels,
 		const LLIOPipe::buffer_ptr_t& buffer)
 	{
+		const std::string url = getURL();
+		llinfos << "@@@ URL to set cookie on" << url << llendl;
+
 		// We don't care about the content of the response, only the Set-Cookie header.
-		LL_DEBUGS("MediaAuth") << dumpResponse() 
-				<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
+		llinfos << dumpResponse() 
+				<< " [headers:" << getResponseHeaders() << "]" << llendl;
 		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);
 	}
 
 };
@@ -1200,7 +1203,7 @@ void LLViewerMedia::clearAllCookies()
 	}
 	
 	// If we have an OpenID cookie, re-add it to the cookie store.
-	setOpenIDCookie();
+	setOpenIDCookie(std::string());
 }
 	
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -1303,7 +1306,7 @@ void LLViewerMedia::loadCookieFile()
 	}
 	
 	// If we have an OpenID cookie, re-add it to the cookie store.
-	setOpenIDCookie();
+	setOpenIDCookie(std::string());
 }
 
 
@@ -1413,7 +1416,7 @@ bool LLViewerMedia::parseRawCookie(const std::string raw_cookie, std::string& na
 
 /////////////////////////////////////////////////////////////////////////////////////////
 // static
-void LLViewerMedia::setOpenIDCookie()
+void LLViewerMedia::setOpenIDCookie(const std::string& url)
 {
 	if(!sOpenIDCookie.empty())
 	{
@@ -1442,19 +1445,21 @@ void LLViewerMedia::setOpenIDCookie()
 		
 		getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start));
 
-		LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("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 = "";
-			if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path))
+		if (url.length())
+		{
+			LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
+			if (media_instance)
 			{
-				std::string url = "http://id.secondlife.com/openid/webkit";
-				media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path);
+				std::string cookie_host = authority.substr(host_start, host_end - host_start);
+				std::string cookie_name = "";
+				std::string cookie_value = "";
+				std::string cookie_path = "";
+				if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path))
+				{
+					media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path);
+				}
 			}
-		};
+		}
 
 		// 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 
@@ -1514,13 +1519,13 @@ void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string
 
 /////////////////////////////////////////////////////////////////////////////////////////
 // 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);
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 0101c85e79..45d211f232 100755
--- 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);
@@ -164,7 +164,7 @@ public:
 	
 private:
 	static bool parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path);
-	static void setOpenIDCookie();
+	static void setOpenIDCookie(const std::string& url);
 	static void onTeleportFinished();
 	
 	static LLPluginCookieStore *sCookieStore;
-- 
cgit v1.2.3


From 0c3c3347c79e61a34dfebc01ca75100d2afb4073 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 20 Oct 2015 17:25:42 -0700
Subject: silly typo that builds on windows - this fixes mac/linux builds

---
 indra/llmessage/llcurl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 14d4a14deb..34758433c8 100755
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -147,7 +147,7 @@ public:
 	public:
 		void setHTTPMethod(EHTTPMethod method);
 		void setURL(const std::string& url);
-		const std::string& Responder::getURL();
+		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);
 
-- 
cgit v1.2.3


From 8c74ed2a58f5443b931374489b04ba80fb11a590 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 21 Oct 2015 09:05:19 -0700
Subject: Fix windows line endings

---
 indra/llplugin/llpluginclassmedia.cpp        | 267 ++++++------
 indra/media_plugins/cef/media_plugin_cef.cpp |  17 +-
 indra/newview/llviewermedia.cpp              | 624 +++++++++++++--------------
 3 files changed, 453 insertions(+), 455 deletions(-)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index fd04fc4b62..c4b57aab1d 100755
--- 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,7 +41,7 @@ static int nextPowerOf2( int value )
 	{
 		next_power_of_2 <<= 1;
 	}
-	
+
 	return next_power_of_2;
 }
 
@@ -63,19 +63,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->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;
@@ -115,7 +115,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 +132,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,15 +140,15 @@ void LLPluginClassMedia::reset()
 	mHistoryBackAvailable = false;
 	mHistoryForwardAvailable = false;
 	mStatusText.clear();
-	mProgressPercent = 0;	
+	mProgressPercent = 0;
 	mClickURL.clear();
 	mClickNavType.clear();
 	mClickTarget.clear();
 	mClickUUID.clear();
 	mStatusCode = 0;
-	
+
 	mClickEnforceTarget = false;
-	
+
 	// media_time class
 	mCurrentTime = 0.0f;
 	mDuration = 0.0f;
@@ -162,7 +162,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 +179,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 +189,7 @@ void LLPluginClassMedia::idle(void)
 				{
 					rowbytes += mPadding - pad;
 				}
-				
+
 				if(rowbytes % mRequestedTextureDepth == 0)
 				{
 					mRequestedTextureWidth = rowbytes / mRequestedTextureDepth;
@@ -201,7 +201,7 @@ void LLPluginClassMedia::idle(void)
 			}
 		}
 
-		
+
 		// Size change has been requested but not initiated yet.
 		size_t newsize = mRequestedTextureWidth * mRequestedTextureHeight * mRequestedTextureDepth;
 
@@ -216,22 +216,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 +240,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 +254,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 +324,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 +342,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 +382,9 @@ bool LLPluginClassMedia::textureValid(void)
 		mRequestedMediaWidth != mMediaWidth ||
 		mRequestedMediaHeight != mMediaHeight ||
 		getBitsData() == NULL
-	)	
+	)
 		return false;
-	
+
 	return true;
 }
 
@@ -408,8 +408,8 @@ void LLPluginClassMedia::resetDirty(void)
 std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
 {
 	std::string result;
-	
-	
+
+
 	if(modifiers & MASK_CONTROL)
 	{
 		result += "control|";
@@ -432,7 +432,7 @@ std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
 	{
 		result += "meta|";
 	}
-*/	
+*/
 	return result;
 }
 
@@ -540,11 +540,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 +559,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 +569,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 +615,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 +634,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 +653,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,31 +664,31 @@ 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)
-{
-	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);
-
-	sendMessage(message);
-}
+void LLPluginClassMedia::setCookie(std::string uri, std::string name, std::string value, std::string domain, std::string path)
+{
+	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);
+
+	sendMessage(message);
+}
 
 void LLPluginClassMedia::loadURI(const std::string &uri)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "load_uri");
 
 	message.setValue("uri", uri);
-	
+
 	sendMessage(message);
 }
 
@@ -705,7 +705,7 @@ const char* LLPluginClassMedia::priorityToString(EPriority priority)
 		case PRIORITY_NORMAL:		result = "normal";		break;
 		case PRIORITY_HIGH:			result = "high";		break;
 	}
-	
+
 	return result;
 }
 
@@ -716,44 +716,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();
 	}
@@ -774,12 +774,12 @@ void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
 F64 LLPluginClassMedia::getCPUUsage()
 {
 	F64 result = 0.0f;
-	
+
 	if(mPlugin)
 	{
 		result = mPlugin->getCPUUsage();
 	}
-	
+
 	return result;
 }
 
@@ -868,11 +868,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();
@@ -883,21 +883,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;
@@ -905,7 +905,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)
@@ -914,7 +914,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 					newDirtyRect.mTop = newDirtyRect.mBottom;
 					newDirtyRect.mBottom = temp;
 				}
-				
+
 				if(mDirtyRect.isEmpty())
 				{
 					mDirtyRect = newDirtyRect;
@@ -924,7 +924,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 << ", "
@@ -934,10 +934,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;
@@ -957,7 +957,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 			{
 				mCurrentRate = message.getValueReal("current_rate");
 			}
-			
+
 			if(message.hasValue("loaded_duration"))
 			{
 				mLoadedDuration = message.getValueReal("loaded_duration");
@@ -968,7 +968,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.
 			{
@@ -979,7 +979,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 			{
 				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED);
 			}
-			
+
 			if(previous_percent != mProgressPercent)
 			{
 				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED);
@@ -988,9 +988,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;
@@ -1030,24 +1030,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);
@@ -1114,7 +1114,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")
@@ -1169,7 +1169,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")
@@ -1178,7 +1178,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
@@ -1194,7 +1194,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;
 		}
@@ -1202,13 +1202,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);
@@ -1248,7 +1248,7 @@ void LLPluginClassMedia::focus(bool focused)
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "focus");
 
 	message.setValueBoolean("focused", focused);
-	
+
 	sendMessage(message);
 }
 
@@ -1275,7 +1275,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);
 }
 
@@ -1308,7 +1308,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);
 }
 
@@ -1428,7 +1428,7 @@ void LLPluginClassMedia::seek(float time)
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
 
 	message.setValueReal("time", time);
-	
+
 	sendMessage(message);
 }
 
@@ -1446,11 +1446,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);
 	}
 }
@@ -1469,4 +1469,3 @@ void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history)
 
 	LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL;
 }
-
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 7f538e16d8..5b08807619 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -479,14 +479,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				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");
-				mLLCEFLib->setCookie(uri, name, value, domain, path);
+			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");
+				mLLCEFLib->setCookie(uri, name, value, domain, path);
 			}
 			else if (message_name == "mouse_event")
 			{
@@ -814,4 +814,3 @@ int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func,
 
 	return 0;
 }
-
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 1098b2a7e1..49d6c1021e 100755
--- 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$
  */
@@ -168,7 +168,7 @@ public:
 		{
 			LL_ERRS() << "impl already has an outstanding responder" << LL_ENDL;
 		}
-		
+
 		mMediaImpl->mMimeTypeProbe = this;
 	}
 
@@ -190,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.
@@ -230,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))
@@ -241,13 +241,13 @@ private:
 			}
 		}
 	}
-	
+
 public:
 	void cancelRequest()
 	{
 		disconnectOwner();
 	}
-	
+
 private:
 	void disconnectOwner()
 	{
@@ -262,8 +262,8 @@ private:
 		}
 		mMediaImpl = NULL;
 	}
-	
-	
+
+
 public:
 		LLViewerMediaImpl *mMediaImpl;
 		bool mInitialized;
@@ -289,10 +289,10 @@ public:
 		llinfos << "@@@ URL to set cookie on" << url << llendl;
 
 		// We don't care about the content of the response, only the Set-Cookie header.
-		llinfos << dumpResponse() 
+		llinfos << dumpResponse()
 				<< " [headers:" << getResponseHeaders() << "]" << llendl;
 		const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE);
-		
+
 		// *TODO: What about bad status codes?  Does this destroy previous cookies?
 		LLViewerMedia::openIDCookieResponse(url, cookie);
 	}
@@ -317,7 +317,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();
@@ -368,7 +368,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)
@@ -395,8 +395,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)
 {
@@ -420,24 +420,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();
@@ -450,7 +450,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())
 		{
@@ -458,7 +458,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;
 			}
 		}
@@ -467,26 +467,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();
@@ -495,7 +495,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
 			needs_navigate = true;
 		}
 	}
-	
+
 	if(media_impl)
 	{
 		if(needs_navigate)
@@ -514,7 +514,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;
 }
 
@@ -523,7 +523,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())
@@ -538,7 +538,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");
 
@@ -557,7 +557,7 @@ std::string LLViewerMedia::getCurrentUserAgent()
 	codec << LLVersionInfo::getVersion();
 	codec << " (" << channel << "; " << skin_name << " skin)";
 	LL_INFOS() << codec.str() << LL_ENDL;
-	
+
 	return codec.str();
 }
 
@@ -566,7 +566,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();
 
@@ -655,7 +655,7 @@ void LLViewerMedia::muteListChanged()
 bool LLViewerMedia::isInterestingEnough(const LLVOVolume *object, const F64 &object_interest)
 {
 	bool result = false;
-	
+
 	if (NULL == object)
 	{
 		result = false;
@@ -671,13 +671,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;
 }
 
@@ -784,13 +784,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())
@@ -798,7 +798,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();
 
@@ -811,14 +811,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
@@ -828,14 +828,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<LLViewerMediaImpl*> proximity_order;
-	
+
 	bool inworld_media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
 	bool inworld_audio_enabled = gSavedSettings.getBOOL("AudioStreamingMusic");
 	U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal");
@@ -844,19 +844,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))
@@ -887,7 +887,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;
@@ -901,7 +901,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.
@@ -923,11 +923,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));
 					}
 				}
@@ -937,18 +937,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;
@@ -958,7 +958,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.
@@ -976,7 +976,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.
@@ -988,7 +988,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 			}
 
 			total_cpu += pimpl->getCPUUsage();
-		
+
 			if (!pimpl->getUsedInUI() && pimpl->hasMedia())
 			{
 				sAnyMediaShowing = true;
@@ -1012,7 +1012,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 			sLowestLoadableImplInterest = object->getPixelArea();
 		}
 	}
-	
+
 	if(gSavedSettings.getBOOL("MediaPerformanceManagerDebug"))
 	{
 		// Give impls the same ordering as the priority list
@@ -1021,7 +1021,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);
 	}
 
@@ -1030,7 +1030,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 	{
 		proximity_order[i]->mProximity = i;
 	}
-	
+
 	LL_DEBUGS("PluginPriority") << "Total reported CPU usage is " << total_cpu << LL_ENDL;
 
 }
@@ -1049,11 +1049,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;
@@ -1062,18 +1062,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())
@@ -1146,26 +1146,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:
 	// <getOSUserAppDir>/browser_profile/cookies
 	// <getOSUserAppDir>/first_last/browser_profile/cookies  (note that there may be any number of these!)
 	// <getOSUserAppDir>/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
@@ -1178,7 +1178,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))
@@ -1188,26 +1188,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(std::string());
 }
-	
+
 /////////////////////////////////////////////////////////////////////////////////////////
-// static 
+// static
 void LLViewerMedia::clearAllCaches()
 {
 	// Clear all plugins' caches
@@ -1219,9 +1219,9 @@ void LLViewerMedia::clearAllCaches()
 		pimpl->clearCache();
 	}
 }
-	
+
 /////////////////////////////////////////////////////////////////////////////////////////
-// static 
+// static
 void LLViewerMedia::setCookiesEnabled(bool enabled)
 {
 	// Set the "cookies enabled" flag for all loaded plugins
@@ -1236,9 +1236,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
@@ -1255,7 +1255,7 @@ void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int por
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
-// static 
+// static
 /////////////////////////////////////////////////////////////////////////////////////////
 // static
 LLPluginCookieStore *LLViewerMedia::getCookieStore()
@@ -1264,7 +1264,7 @@ LLPluginCookieStore *LLViewerMedia::getCookieStore()
 	{
 		sCookieStore = new LLPluginCookieStore;
 	}
-	
+
 	return sCookieStore;
 }
 
@@ -1280,7 +1280,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())
@@ -1288,11 +1288,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();
@@ -1304,7 +1304,7 @@ void LLViewerMedia::loadCookieFile()
 			pimpl->mMediaSource->clear_cookies();
 		}
 	}
-	
+
 	// If we have an OpenID cookie, re-add it to the cookie store.
 	setOpenIDCookie(std::string());
 }
@@ -1341,23 +1341,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());
 }
 
@@ -1374,7 +1374,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);
 }
 
@@ -1392,26 +1392,26 @@ LLSD LLViewerMedia::getHeaders()
 	return headers;
 }
 
- /////////////////////////////////////////////////////////////////////////////////////////
- // static
-bool LLViewerMedia::parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path)
-{
-	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
-
-			return true;
-		}
-	}
-
-	return false;
-}
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // static
+bool LLViewerMedia::parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path)
+{
+	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
+
+			return true;
+		}
+	}
+
+	return false;
+}
 
 
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -1424,7 +1424,7 @@ void LLViewerMedia::setOpenIDCookie(const std::string& url)
 		// 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
@@ -1432,40 +1432,40 @@ void LLViewerMedia::setOpenIDCookie(const std::string& url)
 		}
 		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));
 
 		if (url.length())
 		{
-			LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("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 = "";
-				if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path))
-				{
-					media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path);
-				}
-			}
-		}
-
-		// 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 
+			LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("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 = "";
+				if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path))
+				{
+					media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path);
+				}
+			}
+		}
+
+		// 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;
@@ -1476,7 +1476,7 @@ void LLViewerMedia::setOpenIDCookie(const std::string& url)
 
 		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);
 	}
@@ -1488,12 +1488,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();
 
@@ -1508,13 +1508,13 @@ 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);
-			
+
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -1522,7 +1522,7 @@ void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string
 void LLViewerMedia::openIDCookieResponse(const std::string& url, const std::string &cookie)
 {
 	LL_DEBUGS("MediaAuth") << "Cookie received: \"" << cookie << "\"" << LL_ENDL;
-	
+
 	sOpenIDCookie += cookie;
 
 	setOpenIDCookie(url);
@@ -1534,7 +1534,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())
@@ -1571,7 +1571,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);
 	}
@@ -1583,7 +1583,7 @@ LLPluginClassMedia* LLViewerMedia::getSpareBrowserMediaSource()
 {
 	LLPluginClassMedia* result = sSpareBrowserMediaSource;
 	sSpareBrowserMediaSource = NULL;
-	return result; 
+	return result;
 };
 
 bool LLViewerMedia::hasInWorldMedia()
@@ -1672,12 +1672,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),
@@ -1718,7 +1718,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)
@@ -1726,11 +1726,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);
@@ -1745,7 +1745,7 @@ LLViewerMediaImpl::LLViewerMediaImpl(	  const LLUUID& texture_id,
 LLViewerMediaImpl::~LLViewerMediaImpl()
 {
 	destroyMediaSource();
-	
+
 	LLViewerMediaTexture::removeMediaImplFromTexture(mTextureId) ;
 
 	setTextureID();
@@ -1757,7 +1757,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())
@@ -1773,7 +1773,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.
@@ -1796,7 +1796,7 @@ void LLViewerMediaImpl::createMediaSource()
 		// This media shouldn't be created yet.
 		return;
 	}
-	
+
 	if(! mMediaURL.empty())
 	{
 		navigateInternal();
@@ -1822,15 +1822,15 @@ void LLViewerMediaImpl::destroyMediaSource()
 	{
 		oldImage->setPlaying(FALSE) ;
 	}
-	
+
 	cancelMimeTypeProbe();
-	
+
 	if(mMediaSource)
 	{
 		mMediaSource->setDeleteOK(true) ;
 		delete mMediaSource;
 		mMediaSource = NULL;
-	}	
+	}
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -1845,7 +1845,7 @@ 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)
@@ -1858,7 +1858,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;
 		}
 	}
@@ -1914,7 +1914,7 @@ 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);
 
@@ -1922,7 +1922,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 			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")))
 			{
@@ -1935,14 +1935,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)
@@ -1953,10 +1953,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;
 
@@ -1964,7 +1964,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;
 	}
 
@@ -1975,7 +1975,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"));
@@ -1984,7 +1984,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);
@@ -1992,19 +1992,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,
@@ -2015,7 +2015,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
 		{
 			media_source->set_cookies(all_cookies);
 		}
-				
+
 		mMediaSource = media_source;
 		mMediaSource->setDeleteOK(false) ;
 		updateVolume();
@@ -2058,16 +2058,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.
@@ -2120,11 +2120,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();
 }
@@ -2225,10 +2225,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"))
 			{
@@ -2267,7 +2267,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
@@ -2295,7 +2295,7 @@ std::string LLViewerMediaImpl::getCurrentMediaURL()
 	{
 		return mCurrentMediaURL;
 	}
-	
+
 	return mMediaURL;
 }
 
@@ -2363,17 +2363,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;
@@ -2401,7 +2401,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);
 
@@ -2412,7 +2412,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);
 
@@ -2454,18 +2454,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;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -2541,14 +2541,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;
 };
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -2604,21 +2604,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;
 
@@ -2634,7 +2634,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;
 	}
 
@@ -2658,13 +2658,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);
@@ -2673,12 +2673,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);
@@ -2796,7 +2796,7 @@ bool LLViewerMediaImpl::handleKeyUpHere(KEY key, MASK mask)
 bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)
 {
 	bool result = false;
-	
+
 	if (mMediaSource)
 	{
 		// only accept 'printable' characters, sigh...
@@ -2804,11 +2804,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;
 }
 
@@ -2887,15 +2887,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);
@@ -2904,7 +2904,7 @@ void LLViewerMediaImpl::update()
 	{
 		return;
 	}
-	
+
 	if(mMediaSource->isPluginExited())
 	{
 		resetPreviousMediaState();
@@ -2916,18 +2916,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);
 
@@ -2938,7 +2938,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)
 			{
 
@@ -2951,21 +2951,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();
 		}
 	}
@@ -2986,10 +2986,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())
@@ -3003,7 +3003,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?
@@ -3029,13 +3029,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;
 }
 
@@ -3050,14 +3050,14 @@ LLUUID LLViewerMediaImpl::getMediaTextureID() const
 void LLViewerMediaImpl::setVisible(bool visible)
 {
 	mVisible = visible;
-	
+
 	if(mVisible)
 	{
 		if(mMediaSource && mMediaSource->isPluginExited())
 		{
 			destroyMediaSource();
 		}
-		
+
 		if(!mMediaSource)
 		{
 			createMediaSource();
@@ -3091,12 +3091,12 @@ void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y)
 bool LLViewerMediaImpl::isMediaTimeBased()
 {
 	bool result = false;
-	
+
 	if(mMediaSource)
 	{
 		result = mMediaSource->pluginSupportsMediaTime();
 	}
-	
+
 	return result;
 }
 
@@ -3104,14 +3104,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;
 }
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -3124,7 +3124,7 @@ bool LLViewerMediaImpl::isMediaPaused()
 		if(mMediaSource->getStatus() == MEDIA_PAUSED)
 			result = true;
 	}
-	
+
 	return result;
 }
 
@@ -3152,7 +3152,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.
@@ -3178,13 +3178,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;
 }
 
@@ -3197,19 +3197,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;
 }
 
@@ -3221,7 +3221,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);
@@ -3240,7 +3240,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);
@@ -3262,13 +3262,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")
@@ -3329,7 +3329,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;
@@ -3366,15 +3366,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;
@@ -3530,7 +3530,7 @@ void LLViewerMediaImpl::calculateInterest()
 {
 	LL_RECORD_BLOCK_TIME(FTM_MEDIA_CALCULATE_INTEREST);
 	LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId );
-	
+
 	if(texture != NULL)
 	{
 		mInterest = texture->getMaxVirtualSize();
@@ -3540,7 +3540,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;
@@ -3550,7 +3550,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())
 		{
@@ -3563,12 +3563,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)
 		{
@@ -3595,7 +3595,7 @@ void LLViewerMediaImpl::calculateInterest()
 				}
 			}
 		}
-		
+
 		mNeedsMuteCheck = false;
 	}
 }
@@ -3603,7 +3603,7 @@ void LLViewerMediaImpl::calculateInterest()
 F64 LLViewerMediaImpl::getApproximateTextureInterest()
 {
 	F64 result = 0.0f;
-	
+
 	if(mMediaSource)
 	{
 		result = mMediaSource->getFullWidth();
@@ -3621,8 +3621,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))
@@ -3642,7 +3642,7 @@ void LLViewerMediaImpl::setUsedInUI(bool used_in_ui)
 
 void LLViewerMediaImpl::setBackgroundColor(LLColor4 color)
 {
-	mBackgroundColor = color; 
+	mBackgroundColor = color;
 
 	if(mMediaSource)
 	{
@@ -3653,12 +3653,12 @@ void LLViewerMediaImpl::setBackgroundColor(LLColor4 color)
 F64 LLViewerMediaImpl::getCPUUsage() const
 {
 	F64 result = 0.0f;
-	
+
 	if(mMediaSource)
 	{
 		result = mMediaSource->getCPUUsage();
 	}
-	
+
 	return result;
 }
 
@@ -3672,19 +3672,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();
 		}
 	}
@@ -3693,7 +3693,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().
 }
 
@@ -3708,8 +3708,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;
@@ -3748,7 +3748,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)
 		{
@@ -3757,7 +3757,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)
@@ -3771,14 +3771,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 ;
 }
@@ -3786,13 +3786,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;
 }
 
@@ -3805,12 +3805,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;
 	}
 }
@@ -3819,7 +3819,7 @@ void LLViewerMediaImpl::setTextureID(LLUUID id)
 //
 bool LLViewerMediaImpl::isAutoPlayable() const
 {
-	return (mMediaAutoPlay && 
+	return (mMediaAutoPlay &&
 			gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
 			gSavedSettings.getBOOL("MediaTentativeAutoPlay"));
 }
@@ -3830,20 +3830,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)
 	{
@@ -3856,7 +3856,7 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const
 
 		return show_media_within_parcel;
 	}
-	else 
+	else
 	{
 		static LLCachedControl<bool> show_media_outside_parcel(gSavedSettings, LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING, true);
 
@@ -3869,7 +3869,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++)
@@ -3913,7 +3913,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++)
-- 
cgit v1.2.3


From 16cd296e30e95fbacefff4e291fbdd6fbf0c2c43 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 22 Oct 2015 13:24:43 -0700
Subject: MAINT-5775 FIX Split out cookies and cache directories into separate
 folders and move cache to same place as viewer cache

---
 indra/llplugin/llpluginclassmedia.cpp        |  5 +++--
 indra/llplugin/llpluginclassmedia.h          |  2 +-
 indra/media_plugins/cef/media_plugin_cef.cpp |  7 ++++---
 indra/newview/llviewermedia.cpp              | 18 +++++++++---------
 4 files changed, 17 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index c4b57aab1d..53fae52021 100755
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -827,10 +827,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);
 }
 
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 255fb0e2f1..a0167bc5fc 100755
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -193,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);
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 5b08807619..bb2270181e 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -432,9 +432,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			}
 			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
-				mCachePath = user_data_path + "cef_cache";
-				mCookiePath = user_data_path + "cef_cookies";
+				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")
 			{
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 49d6c1021e..7e3d88fa64 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -286,11 +286,7 @@ public:
 		const LLIOPipe::buffer_ptr_t& buffer)
 	{
 		const std::string url = getURL();
-		llinfos << "@@@ URL to set cookie on" << url << llendl;
 
-		// We don't care about the content of the response, only the Set-Cookie header.
-		llinfos << dumpResponse()
-				<< " [headers:" << getResponseHeaders() << "]" << llendl;
 		const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE);
 
 		// *TODO: What about bad status codes?  Does this destroy previous cookies?
@@ -1870,8 +1866,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
@@ -1882,8 +1882,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
@@ -1900,7 +1900,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
-- 
cgit v1.2.3


From 9833a50260fb45d5f0033200ae756834c0cc9940 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Tue, 27 Oct 2015 15:17:12 -0700
Subject: MAINT-5754: For MoaP and MediaCtrls forward all events including
 KEYUP and KEYDOWN to the CEF plugin.

---
 indra/llui/llfocusmgr.cpp                    | 12 ++++++++++
 indra/llui/llfocusmgr.h                      |  8 +++++++
 indra/llwindow/llkeyboardwin32.cpp           |  4 ++--
 indra/llwindow/llwindowwin32.h               |  2 +-
 indra/media_plugins/cef/media_plugin_cef.cpp |  2 ++
 indra/newview/llinventoryfunctions.cpp       |  2 +-
 indra/newview/llmediactrl.cpp                | 10 ++++++++
 indra/newview/llmediactrl.h                  |  4 ++++
 indra/newview/llviewermedia.cpp              |  9 ++++----
 indra/newview/llviewermediafocus.cpp         | 17 +++++++++++++-
 indra/newview/llviewermediafocus.h           |  4 ++++
 indra/newview/llviewerwindow.cpp             | 34 ++++++++++++++++++++--------
 12 files changed, 88 insertions(+), 20 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index fb811452be..1a51b96fdf 100755
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -58,6 +58,18 @@ BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa
 	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 950ac55325..0e3d7d8e59 100755
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -60,6 +60,14 @@ public:
 	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/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp
index dc40dcdde0..2123ed3939 100755
--- 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/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 376bef3e50..1a775eadaf 100755
--- 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);
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 5b08807619..2a1ef1484a 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -734,6 +734,8 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::
 	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"]);
+    //if ((msg == WM_CHAR) && (key_event == ))
+
 	mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
 #endif
 };
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 6aaf45c35d..984c650128 100755
--- 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/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index d999c6f52b..9b8e24a8e8 100755
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -1171,3 +1171,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 cb3a864d63..291d87073e 100755
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -172,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/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 49d6c1021e..8a16243ec1 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -286,11 +286,11 @@ public:
 		const LLIOPipe::buffer_ptr_t& buffer)
 	{
 		const std::string url = getURL();
-		llinfos << "@@@ URL to set cookie on" << url << llendl;
+		LL_INFOS() << "@@@ URL to set cookie on" << url << LL_ENDL;
 
 		// We don't care about the content of the response, only the Set-Cookie header.
-		llinfos << dumpResponse()
-				<< " [headers:" << getResponseHeaders() << "]" << llendl;
+		LL_INFOS() << dumpResponse()
+				<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
 		const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE);
 
 		// *TODO: What about bad status codes?  Does this destroy previous cookies?
@@ -2759,8 +2759,7 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
 
 		if (!result)
 		{
-
-			LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
+            LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
 			result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN, key, mask, native_key_data);
 		}
 	}
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index 1265ca0a70..7b4df3d3da 100755
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -354,7 +354,12 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)
 
 BOOL LLViewerMediaFocus::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
 {
-	return true;
+    LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
+    if (media_impl)
+    {
+        media_impl->handleKeyUpHere(key, mask);
+    }
+    return true;
 }
 
 
@@ -610,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 42c841df15..0b2a64868e 100755
--- a/indra/newview/llviewermediafocus.h
+++ b/indra/newview/llviewermediafocus.h
@@ -88,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/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index b6212e0958..6be63ef889 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -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);
@@ -2543,22 +2547,27 @@ void LLViewerWindow::draw()
 //#endif
 }
 
-// Takes a single keydown event, usually when UI is visible
+// Takes a single keyup event, usually when UI is visible
 BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
 {
-	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);
 		}
 	}
 
-	LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
 	if (keyboard_focus)
 	{
 		if (keyboard_focus->handleKeyUp(key, mask, FALSE))
@@ -2584,15 +2593,21 @@ 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);
 		}
 	}
 
@@ -2606,7 +2621,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
@@ -2632,7 +2646,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();
-- 
cgit v1.2.3


From bd817f6f422991c2653493436c7845e75ea9d855 Mon Sep 17 00:00:00 2001
From: rider <rider@lindenlab.com>
Date: Fri, 6 Nov 2015 14:12:30 -0800
Subject: MAINT-5754: Basic keyboard functionality on the Mac.  Still
 incomplete

---
 indra/llwindow/llopenglview-objc.mm          | 45 ++++++++++++++++++++++++----
 indra/llwindow/llwindowmacosx-objc.h         | 23 ++++++++++++--
 indra/llwindow/llwindowmacosx.cpp            | 38 ++++++++++++-----------
 indra/media_plugins/cef/media_plugin_cef.cpp | 41 ++++++++++++++++++-------
 indra/newview/llappviewer.cpp                |  2 +-
 indra/newview/llviewermedia.cpp              |  3 +-
 indra/newview/llviewerwindow.cpp             |  2 +-
 7 files changed, 116 insertions(+), 38 deletions(-)

(limited to 'indra')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index deb8cb90d8..7bb20240d2 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -42,6 +42,7 @@
     return screen;
 }
 
+
 - (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint
 {
     float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x));
@@ -57,6 +58,24 @@
 
 @end
 
+void extractKeyDataFromEvent (NSEvent *theEvent, NativeKeyEventData * eventData)
+{
+    if ([theEvent characters].length)
+    {
+        eventData->mCharacter = (wchar_t)[[theEvent characters] characterAtIndex:0];
+    }
+    else
+    {
+        eventData->mCharacter = [theEvent keyCode];
+    }
+    eventData->mKeyEvent = NativeKeyEventData::KEYUNKNOWN;
+    eventData->mKeyCode = [theEvent keyCode];
+    eventData->mKeyModifiers = [theEvent modifierFlags];
+    eventData->mScanCode = [theEvent keyCode ];
+    eventData->mKeyboardType = 0;
+}
+
+
 attributedStringInfo getSegments(NSAttributedString *str)
 {
 	attributedStringInfo segments;
@@ -402,11 +421,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 +442,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 +463,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 +495,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..2455d6aeb9 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -46,6 +46,25 @@ typedef void *CursorRef;
 typedef void *NSWindowRef;
 typedef void *GLViewRef;
 
+
+struct NativeKeyEventData {
+    enum EventType {
+        KEYUNKNOWN,
+        KEYUP,
+        KEYDOWN,
+        KEYCHAR
+    };
+    
+    EventType   mKeyEvent;
+    uint32_t    mKeyCode;
+    uint32_t    mScanCode;
+    uint32_t    mKeyModifiers;
+    uint32_t    mKeyboardType;
+    wchar_t     mCharacter;
+};
+
+typedef const NativeKeyEventData * NSKeyEventRef;
+
 // These are defined in llappviewermacosx.cpp.
 bool initViewer();
 void handleQuit();
@@ -102,8 +121,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..2a104c1877 100755
--- 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()
@@ -1713,23 +1723,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;
+        result["char_code"] = (S32)(mRawKeyEvent)->mCharacter;
+        result["scan_code"] = (S32)(mRawKeyEvent)->mScanCode;
+		result["key_code"] = (S32)(mRawKeyEvent->mKeyCode);
+		result["modifiers"] = (S32)(mRawKeyEvent->mKeyModifiers);
+		result["keyboard_type"] = (S32)(mRawKeyEvent->mKeyboardType);
 
 #if 0
 		// This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc)
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index bb2270181e..d653aaace9 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -551,6 +551,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 #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);
@@ -562,7 +565,21 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 					//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");
@@ -708,12 +725,20 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::
 #if LL_DARWIN
 	std::string utf8_text;
 
+    uint32_t native_char_code = native_key_data["char_code"].asInteger();
+    uint32_t native_scan_code = native_key_data["scan_code"].asInteger();
+    uint32_t native_virtual_key = native_key_data["key_code"].asInteger();
+    uint32_t native_modifiers = native_key_data["modifiers"].asInteger();
+
+    
+    
 	if (key < 128)
 	{
-		utf8_text = (char)key;
+		utf8_text = (char)native_virtual_key;
 	}
-
+    
 	switch ((KEY)key)
+    
 	{
 		case KEY_BACKSPACE:		utf8_text = (char)8;		break;
 		case KEY_TAB:			utf8_text = (char)9;		break;
@@ -725,16 +750,12 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::
 		break;
 	}
 
-	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);
-
-	mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
+	mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(), native_modifiers, native_scan_code, native_virtual_key, native_modifiers);
 #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
 };
@@ -743,7 +764,7 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboar
 {
 #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);
+	//mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
 #elif LL_WINDOWS
 	U32 msg = ll_U32_from_sd(native_key_data["msg"]);
 	U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 9e80e26e3f..03a8756ac8 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2786,7 +2786,7 @@ bool LLAppViewer::initConfiguration()
 	//
 	gWindowTitle = LLTrans::getString("APP_NAME");
 #if LL_DEBUG
-	gWindowTitle += std::string(" [DEBUG]")
+    gWindowTitle += std::string(" [DEBUG]");
 #endif
 	if (!gArgs.empty())
 	{
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 0824a7def7..626938f7b5 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1450,7 +1450,8 @@ void LLViewerMedia::setOpenIDCookie(const std::string& url)
 				std::string cookie_name = "";
 				std::string cookie_value = "";
 				std::string cookie_path = "";
-				if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path))
+				if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path) &&
+                    media_instance->getMediaPlugin())
 				{
 					media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path);
 				}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 6be63ef889..86a90a2c24 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2559,7 +2559,7 @@ BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
 		// We have keyboard focus, and it's not an accelerator
         if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown())
         {
-            return keyboard_focus->handleKey(key, mask, FALSE);
+            return keyboard_focus->handleKeyUp(key, mask, FALSE);
         }
         else if (key < 0x80)
 		{
-- 
cgit v1.2.3


From 5449ae73b337c026afa93e99a47b670c28c8eb80 Mon Sep 17 00:00:00 2001
From: rider <rider@lindenlab.com>
Date: Sat, 7 Nov 2015 12:09:08 -0800
Subject: MAINT-5754: Finish key modifier experiment.  Still not working.

---
 indra/llwindow/llopenglview-objc.mm          | 24 +++++++++++++++++++++++-
 indra/llwindow/llwindowmacosx.cpp            |  1 +
 indra/media_plugins/cef/media_plugin_cef.cpp | 20 ++++++++++++++++----
 3 files changed, 40 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 7bb20240d2..81e90accb7 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -28,6 +28,18 @@
 #include "llwindowmacosx-objc.h"
 #import "llappdelegate-objc.h"
 
+
+
+//---------------------------
+// Coppied from indra_constants.h
+//#include "indra_constats.h"
+const uint32_t MASK_CONTROL =		0x0001;		// Mapped to cmd on Macs
+const uint32_t MASK_ALT =			0x0002;
+const uint32_t MASK_SHIFT =			0x0004;
+//const uint32_t MASK_MAC_CONTROL =	0x0008;		// Un-mapped Ctrl key on Macs, not used on Windows
+
+//---------------------------
+
 @implementation NSScreen (PointConversion)
 
 + (NSScreen *)currentScreenForMouseLocation
@@ -70,7 +82,17 @@ void extractKeyDataFromEvent (NSEvent *theEvent, NativeKeyEventData * eventData)
     }
     eventData->mKeyEvent = NativeKeyEventData::KEYUNKNOWN;
     eventData->mKeyCode = [theEvent keyCode];
-    eventData->mKeyModifiers = [theEvent modifierFlags];
+
+    unsigned int modifiers = [theEvent modifierFlags];
+    
+    if (modifiers & (NSAlphaShiftKeyMask | NSShiftKeyMask))
+        modifiers |= MASK_SHIFT;
+    if (modifiers & NSAlternateKeyMask)
+        modifiers |= MASK_ALT;
+    if (modifiers & NSControlKeyMask)
+        modifiers |= MASK_CONTROL;
+    
+    eventData->mKeyModifiers = modifiers;
     eventData->mScanCode = [theEvent keyCode ];
     eventData->mKeyboardType = 0;
 }
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 2a104c1877..7bc5d263e4 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1733,6 +1733,7 @@ LLSD LLWindowMacOSX::getNativeKeyData()
 		result["modifiers"] = (S32)(mRawKeyEvent->mKeyModifiers);
 		result["keyboard_type"] = (S32)(mRawKeyEvent->mKeyboardType);
 
+        
 #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!
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index d653aaace9..7d60c1a5ed 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -720,7 +720,7 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers_x, LLSD native_key_data = LLSD::emptyMap())
 {
 #if LL_DARWIN
 	std::string utf8_text;
@@ -729,14 +729,23 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::
     uint32_t native_scan_code = native_key_data["scan_code"].asInteger();
     uint32_t native_virtual_key = native_key_data["key_code"].asInteger();
     uint32_t native_modifiers = native_key_data["modifiers"].asInteger();
-
-    
     
 	if (key < 128)
 	{
 		utf8_text = (char)native_virtual_key;
 	}
     
+    unsigned int modifers = LLCEFLib::KM_MODIFIER_NONE;
+
+    if (native_modifiers & (MASK_CONTROL | MASK_MAC_CONTROL))
+        modifers |= LLCEFLib::KM_MODIFIER_CONTROL;
+    if (native_modifiers & MASK_SHIFT)
+        modifers |= LLCEFLib::KM_MODIFIER_SHIFT;
+    if (native_modifiers & MASK_ALT)
+        modifers |= LLCEFLib::KM_MODIFIER_ALT;
+
+    //modifers |= LLCEFLib::KM_MODIFIER_META;
+    
 	switch ((KEY)key)
     
 	{
@@ -750,7 +759,10 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::
 		break;
 	}
 
-	mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(), native_modifiers, native_scan_code, native_virtual_key, native_modifiers);
+	mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(),
+            static_cast<LLCEFLib::EKeyboardModifier>(modifers),
+            native_scan_code, native_virtual_key, native_modifiers);
+    
 #elif LL_WINDOWS
 	U32 msg = ll_U32_from_sd(native_key_data["msg"]);
 	U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
-- 
cgit v1.2.3


From 66848f7a94438f2fe9edd4fad9c12ea44ad285b2 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Mon, 9 Nov 2015 11:53:09 -0800
Subject: Undo the clobbering that the PR did :)

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 7d60c1a5ed..ea451ed5b6 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -128,7 +128,7 @@ MediaPluginBase(host_send_func, host_user_data)
 //
 MediaPluginCEF::~MediaPluginCEF()
 {
-	mLLCEFLib->reset();
+	mLLCEFLib->requestExit();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -532,11 +532,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			}
 			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(y);
+				mLLCEFLib->mouseWheel(x, y);
 			}
 			else if (message_name == "text_event")
 			{
-- 
cgit v1.2.3


From abc9df45dae46e7372e8beb840a1294e5a64a94d Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Mon, 9 Nov 2015 15:09:41 -0800
Subject: Fix MAINT-5773 Surface Plugins Enabled as a preference and default to
 OFF

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 5f378c64e8..6fac330db4 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2005,7 +2005,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>1</integer>
+      <integer>0</integer>
     </map>
     <key>ChatBarCustomWidth</key>
     <map>
-- 
cgit v1.2.3


From 059925eafb66dc0e2d8ef9c113ca8980a34c655d Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Tue, 10 Nov 2015 13:45:30 -0800
Subject: Added code to initiate controlled shutdown of plugins with timeouts
 for misbeahving plugin.

---
 indra/llplugin/llpluginclassmedia.cpp          |   9 +-
 indra/llplugin/llpluginclassmedia.h            |   2 +-
 indra/llplugin/llpluginprocesschild.cpp        |  43 +++-
 indra/llplugin/llpluginprocesschild.h          |   7 +-
 indra/llplugin/llpluginprocessparent.cpp       | 308 ++++++++++++++++---------
 indra/llplugin/llpluginprocessparent.h         |  28 ++-
 indra/newview/llappviewer.cpp                  |   3 +
 indra/newview/tests/llmediadataclient_test.cpp |   2 +-
 8 files changed, 263 insertions(+), 139 deletions(-)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 53fae52021..85653a0fcc 100755
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -48,7 +48,6 @@ static int nextPowerOf2( int value )
 LLPluginClassMedia::LLPluginClassMedia(LLPluginClassMediaOwner *owner)
 {
 	mOwner = owner;
-	mPlugin = NULL;
 	reset();
 
 	//debug use
@@ -68,7 +67,7 @@ bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::s
 	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.
@@ -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;
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index a0167bc5fc..fe02696084 100755
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -374,7 +374,7 @@ protected:
 	int			mPadding;
 	
 	
-	LLPluginProcessParent *mPlugin;
+	LLPluginProcessParent::ptr_t mPlugin;
 	
 	LLRect mDirtyRect;
 	
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index f8a282184e..be80d38305 100755
--- 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 100755
--- 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<std::string> mMessageQueue;
-	
+    LLTimer mWaitGoodbye;
 	void deliverQueuedMessages();
 	
 };
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index b5a2588e1e..0a8e58ac90 100755
--- 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*> 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'
-
-						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
-					}
+						    // 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);
+
+#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<LLPluginProcessParent*>::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<LLPluginProcessParent*>::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 100755
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -30,6 +30,7 @@
 #define LL_LLPLUGINPROCESSPARENT_H
 
 #include <queue>
+#include <boost/enable_shared_from_this.hpp>
 
 #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<LLPluginProcessParent> 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<void *, ptr_t> 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<LLPluginProcessParent*> sInstances;
+    static mapInstances_t sInstances;
 	static void dirtyPollSet();
 	static void updatePollset();
 	void servicePoll();
 	static LLThread *sReadThread;
-	
+
+    LLTempBoundListener mPolling;
+    bool pollTick();
+
 	LLMutex mIncomingQueueMutex;
 	std::queue<LLPluginMessage> mIncomingQueue;
 };
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 03a8756ac8..f0cfd052cf 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1730,6 +1730,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();
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 6f57daf151..7cb4aeb121 100755
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -26,7 +26,7 @@
 
 #include "linden_common.h"
 #include "../llviewerprecompiledheaders.h"
- 
+
 #include <iostream>
 #include "../test/lltut.h"
 
-- 
cgit v1.2.3


From 148de7ceeb1acd6fe76f0986812e32d2488202b7 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Tue, 10 Nov 2015 14:26:47 -0800
Subject: Have the media_cef plugin post goodbye back to the plugin.

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index ea451ed5b6..86157bf852 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -344,6 +344,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			}
 			else if (message_name == "cleanup")
 			{
+                LLPluginMessage message("base", "goodbye");
+                sendMessage(message);
 			}
 			else if (message_name == "shm_added")
 			{
-- 
cgit v1.2.3


From a9a3cafa9194794850f97bec15e1d176389dd7eb Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Wed, 11 Nov 2015 08:55:18 -0800
Subject: Adding plugin goodbye response to quicktime plugin.

---
 indra/media_plugins/quicktime/media_plugin_quicktime.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
index ff1ed8bfbc..7ef5a0fe44 100755
--- 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;
-- 
cgit v1.2.3


From f563ef61004c70c05c2ca78a8fbdd85ed1dbf1a6 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 11 Nov 2015 09:53:51 -0800
Subject: Add callback for when CEF asks to shutdown

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 86157bf852..d14254d3d7 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -62,6 +62,7 @@ private:
 	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);
@@ -128,7 +129,6 @@ MediaPluginBase(host_send_func, host_user_data)
 //
 MediaPluginCEF::~MediaPluginCEF()
 {
-	mLLCEFLib->requestExit();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -199,6 +199,16 @@ void MediaPluginCEF::onLoadStartCallback()
 	sendMessage(message);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onRequestExitCallback()
+{
+	mLLCEFLib->shutdown();
+
+	LLPluginMessage message("base", "goodbye");
+	sendMessage(message);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 void MediaPluginCEF::onLoadEndCallback(int httpStatusCode)
@@ -344,8 +354,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			}
 			else if (message_name == "cleanup")
 			{
-                LLPluginMessage message("base", "goodbye");
-                sendMessage(message);
+				mLLCEFLib->requestExit();
 			}
 			else if (message_name == "shm_added")
 			{
@@ -401,6 +410,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2));
 				mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));
 				mLLCEFLib->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2));
+				mLLCEFLib->setOnRequestExitCallback(boost::bind(&MediaPluginCEF::onRequestExitCallback, this));
 
 				LLCEFLib::LLCEFLibSettings settings;
 				settings.initial_width = 1024;
-- 
cgit v1.2.3


From f8050dbac2861d76adfe8630abe09ca5fb2666f7 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 11 Nov 2015 16:28:11 -0800
Subject: Fix MAINT-5832 Add /LTCG flag to linker for media_plugin_cef.dll to
 avoid linker restarts

---
 indra/media_plugins/cef/CMakeLists.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 16015be672..1f6163e41e 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -61,7 +61,7 @@ set (media_plugin_cef_LINK_LIBRARIES
 if (LINUX)
   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_cef_SOURCE_FILES mac_volume_catcher.cpp)
   find_library(CORESERVICES_LIBRARY CoreServices)
@@ -98,7 +98,7 @@ if (WINDOWS)
   set_target_properties(
     media_plugin_cef
     PROPERTIES
-    LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT"
+    LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT"
     LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD"
     )
 endif (WINDOWS)
-- 
cgit v1.2.3


From ec55f2cd10db838140b34b04717e9e50a6b736ce Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Fri, 13 Nov 2015 16:19:16 -0800
Subject: MAINT-5862 Fix Provide a way for new Linux users to accept ToS

---
 indra/cmake/00-Common.cmake                        |  3 +++
 indra/newview/llfloaterpreference.cpp              | 11 +++++++++
 indra/newview/llfloatertos.cpp                     | 26 ++++++++++++++++++++--
 indra/newview/llweb.cpp                            |  4 ++++
 indra/newview/skins/default/xui/en/floater_tos.xml | 15 +++++++++++++
 5 files changed, 57 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 1a3b6c5117..86fc2dfff5 100755
--- 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/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index dac610eda1..f7861fb4fd 100755
--- 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<LLRadioGroup>("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/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index ae33acb842..4cb1ca6cc0 100755
--- 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<LLMediaCtrl>("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<LLTextBox>("tos_heading");
+		if (header)
+			header->setVisible(false);
+
+		LLTextBox* external_prompt = getChild<LLTextBox>("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/llweb.cpp b/indra/newview/llweb.cpp
index 0be6e49834..b37e41fb85 100755
--- 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/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml
index af1617eb39..c5313391c6 100755
--- a/indra/newview/skins/default/xui/en/floater_tos.xml
+++ b/indra/newview/skins/default/xui/en/floater_tos.xml
@@ -57,6 +57,21 @@
      width="552">
         Please read the following Terms of Service and Privacy Policy carefully. To continue logging in to [SECOND_LIFE], you must accept the agreement.
     </text>
+     <text
+     type="string"
+     length="1"
+     follows="left|top"
+     font="SansSerif"
+     height="30"
+     layout="topleft"
+     left="16"
+     name="external_tos_required"
+     visible="false"
+     top="32"
+     word_wrap="true"
+     width="552">
+       To continue logging in to [SECOND_LIFE], you must accept the [https://id.secondlife.com/openid/login?return_to=https%3A%2F%2Fmy.secondlife.com%2Fopenid Terms of Service and Privacy Policy].
+     </text>
     <web_browser
       trusted_content="true" 
      follows="left|top"
-- 
cgit v1.2.3


From c2ad041c23b0097aec30acc7447a42f96d515d3b Mon Sep 17 00:00:00 2001
From: rider <rider@lindenlab.com>
Date: Fri, 13 Nov 2015 16:22:34 -0800
Subject: Encode keyboard event for reconstruction in the plugin.

---
 indra/llwindow/llopenglview-objc.mm          | 36 +++++-----------------
 indra/llwindow/llwindowmacosx-objc.h         | 11 ++++---
 indra/llwindow/llwindowmacosx.cpp            | 39 ++++-------------------
 indra/media_plugins/cef/media_plugin_cef.cpp | 46 ++++++----------------------
 4 files changed, 29 insertions(+), 103 deletions(-)

(limited to 'indra')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 81e90accb7..406bc9cf47 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -30,13 +30,6 @@
 
 
 
-//---------------------------
-// Coppied from indra_constants.h
-//#include "indra_constats.h"
-const uint32_t MASK_CONTROL =		0x0001;		// Mapped to cmd on Macs
-const uint32_t MASK_ALT =			0x0002;
-const uint32_t MASK_SHIFT =			0x0004;
-//const uint32_t MASK_MAC_CONTROL =	0x0008;		// Un-mapped Ctrl key on Macs, not used on Windows
 
 //---------------------------
 
@@ -72,29 +65,16 @@ const uint32_t MASK_SHIFT =			0x0004;
 
 void extractKeyDataFromEvent (NSEvent *theEvent, NativeKeyEventData * eventData)
 {
-    if ([theEvent characters].length)
-    {
-        eventData->mCharacter = (wchar_t)[[theEvent characters] characterAtIndex:0];
-    }
-    else
-    {
-        eventData->mCharacter = [theEvent keyCode];
-    }
     eventData->mKeyEvent = NativeKeyEventData::KEYUNKNOWN;
-    eventData->mKeyCode = [theEvent keyCode];
+    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];
 
-    unsigned int modifiers = [theEvent modifierFlags];
-    
-    if (modifiers & (NSAlphaShiftKeyMask | NSShiftKeyMask))
-        modifiers |= MASK_SHIFT;
-    if (modifiers & NSAlternateKeyMask)
-        modifiers |= MASK_ALT;
-    if (modifiers & NSControlKeyMask)
-        modifiers |= MASK_CONTROL;
-    
-    eventData->mKeyModifiers = modifiers;
-    eventData->mScanCode = [theEvent keyCode ];
-    eventData->mKeyboardType = 0;
 }
 
 
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 2455d6aeb9..dc184b91fb 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -56,11 +56,12 @@ struct NativeKeyEventData {
     };
     
     EventType   mKeyEvent;
-    uint32_t    mKeyCode;
-    uint32_t    mScanCode;
-    uint32_t    mKeyModifiers;
-    uint32_t    mKeyboardType;
-    wchar_t     mCharacter;
+    uint32_t    mEventType;
+    uint32_t    mEventModifiers;
+    uint32_t    mEventKeyCode;
+    uint32_t    mEventChars;
+    uint32_t    mEventUnmodChars;
+    bool        mEventRepeat;
 };
 
 typedef const NativeKeyEventData * NSKeyEventRef;
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 7bc5d263e4..952c6751db 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1726,39 +1726,12 @@ LLSD LLWindowMacOSX::getNativeKeyData()
 #if 1
 	if(mRawKeyEvent)
 	{
-
-        result["char_code"] = (S32)(mRawKeyEvent)->mCharacter;
-        result["scan_code"] = (S32)(mRawKeyEvent)->mScanCode;
-		result["key_code"] = (S32)(mRawKeyEvent->mKeyCode);
-		result["modifiers"] = (S32)(mRawKeyEvent->mKeyModifiers);
-		result["keyboard_type"] = (S32)(mRawKeyEvent->mKeyboardType);
-
-        
-#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/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 86157bf852..9e7c390eb2 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -726,46 +726,18 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat
 void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers_x, LLSD native_key_data = LLSD::emptyMap())
 {
 #if LL_DARWIN
-	std::string utf8_text;
 
-    uint32_t native_char_code = native_key_data["char_code"].asInteger();
-    uint32_t native_scan_code = native_key_data["scan_code"].asInteger();
-    uint32_t native_virtual_key = native_key_data["key_code"].asInteger();
-    uint32_t native_modifiers = native_key_data["modifiers"].asInteger();
-    
-	if (key < 128)
-	{
-		utf8_text = (char)native_virtual_key;
-	}
-    
-    unsigned int modifers = LLCEFLib::KM_MODIFIER_NONE;
-
-    if (native_modifiers & (MASK_CONTROL | MASK_MAC_CONTROL))
-        modifers |= LLCEFLib::KM_MODIFIER_CONTROL;
-    if (native_modifiers & MASK_SHIFT)
-        modifers |= LLCEFLib::KM_MODIFIER_SHIFT;
-    if (native_modifiers & MASK_ALT)
-        modifers |= LLCEFLib::KM_MODIFIER_ALT;
-
-    //modifers |= LLCEFLib::KM_MODIFIER_META;
-    
-	switch ((KEY)key)
-    
-	{
-		case KEY_BACKSPACE:		utf8_text = (char)8;		break;
-		case KEY_TAB:			utf8_text = (char)9;		break;
-		case KEY_RETURN:		utf8_text = (char)13;		break;
-		case KEY_PAD_RETURN:	utf8_text = (char)13;		break;
-		case KEY_ESCAPE:		utf8_text = (char)27;		break;
-
-	default:
-		break;
-	}
+    uint32_t eventType = native_key_data["event_type"].asInteger();
+    uint32_t eventModifiers = native_key_data["event_modifiers"].asInteger();
+    uint32_t eventKeycode = native_key_data["event_keycode"].asInteger();
+    char eventChars = static_cast<char>(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger());
+    char eventUChars = static_cast<char>(native_key_data["event_umodchars"].isUndefined() ? 0 : native_key_data["event_umodchars"].asInteger());
+    bool eventIsRepeat = native_key_data["event_isrepeat"].asBoolean();
 
-	mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(),
-            static_cast<LLCEFLib::EKeyboardModifier>(modifers),
-            native_scan_code, native_virtual_key, native_modifiers);
     
+    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"]);
-- 
cgit v1.2.3


From df29aab81ba962d29b541fb84ffe0a682abcfaf5 Mon Sep 17 00:00:00 2001
From: rider <rider@lindenlab.com>
Date: Fri, 13 Nov 2015 16:38:35 -0800
Subject: Throw away any incomplete llsd messages that may have get sent on CR

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 9e7c390eb2..be69858d47 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -727,6 +727,12 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::
 {
 #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();
     uint32_t eventModifiers = native_key_data["event_modifiers"].asInteger();
     uint32_t eventKeycode = native_key_data["event_keycode"].asInteger();
-- 
cgit v1.2.3


From e63aeb29ab8e0c173f17a2c343c66ab4ef84c0ad Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Mon, 16 Nov 2015 10:55:00 -0800
Subject: Fix MAINT-5855 media navigation bars overlap all floaters in viewer

---
 indra/newview/llviewerwindow.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 86a90a2c24..4d1cacca1f 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2022,6 +2022,7 @@ void LLViewerWindow::initWorldUI()
 		}
 		gHUDView = new LLHUDView(hud_rect);
 		getRootView()->addChild(gHUDView);
+		getRootView()->sendChildToBack(gHUDView);
 	}
 
 	LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container");
-- 
cgit v1.2.3


From 311b376ab50bacf2bf113616af2a5bbedfcd5ee5 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Mon, 16 Nov 2015 16:09:40 -0800
Subject: Update SetCookie code for new LLCEFLib API and add support for
 shoing/hising developer console (Inspector)

---
 indra/llplugin/llpluginclassmedia.cpp        |  4 +++-
 indra/llplugin/llpluginclassmedia.h          |  2 +-
 indra/media_plugins/cef/media_plugin_cef.cpp |  8 +++++++-
 indra/newview/llviewermedia.cpp              | 11 ++++++++---
 indra/newview/llviewermedia.h                |  2 +-
 5 files changed, 20 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 85653a0fcc..23c5cd8794 100755
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -669,7 +669,7 @@ bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD
 	return true;
 }
 
-void LLPluginClassMedia::setCookie(std::string uri, std::string name, std::string value, std::string domain, std::string path)
+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");
 
@@ -678,6 +678,8 @@ void LLPluginClassMedia::setCookie(std::string uri, std::string name, std::strin
 	message.setValue("value", value);
 	message.setValue("domain", domain);
 	message.setValue("path", path);
+	message.setValueBoolean("httponly", httponly);
+	message.setValueBoolean("secure", secure);
 
 	sendMessage(message);
 }
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index fe02696084..62652da9bc 100755
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -133,7 +133,7 @@ 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);
+	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);
 	
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 60f6264db4..a53b453b3e 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -499,7 +499,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				std::string value = message_in.getValue("value");
 				std::string domain = message_in.getValue("domain");
 				std::string path = message_in.getValue("path");
-				mLLCEFLib->setCookie(uri, name, value, domain, 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")
 			{
@@ -666,6 +668,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			{
 				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");
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 626938f7b5..cc56a9db8d 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1390,7 +1390,7 @@ LLSD LLViewerMedia::getHeaders()
 
  /////////////////////////////////////////////////////////////////////////////////////////
  // static
-bool LLViewerMedia::parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path)
+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)
@@ -1402,6 +1402,9 @@ bool LLViewerMedia::parseRawCookie(const std::string raw_cookie, std::string& na
 			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;
 		}
 	}
@@ -1450,10 +1453,12 @@ void LLViewerMedia::setOpenIDCookie(const std::string& url)
 				std::string cookie_name = "";
 				std::string cookie_value = "";
 				std::string cookie_path = "";
-				if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, 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);
+					media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path, httponly, secure);
 				}
 			}
 		}
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 4ee1b56a2a..01d4b0786f 100755
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -163,7 +163,7 @@ public:
 	static LLSD getHeaders();
 	
 private:
-	static bool parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path);
+	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();
 	
-- 
cgit v1.2.3


From 32691c441664821fcb29824461ed85277ae418c8 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 18 Nov 2015 18:17:50 -0800
Subject: initial support for dropdown menus/select widgits

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index a53b453b3e..ec3518100b 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -56,7 +56,7 @@ public:
 private:
 	bool init();
 
-	void onPageChangedCallback(unsigned char* pixels, int width, int height);
+	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);
@@ -149,13 +149,31 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg)
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int width, int height)
+void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup)
 {
 	if (mPixels && pixels)
 	{
-		if (mWidth == width && mHeight == height)
+		if (is_popup)
 		{
-			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
+			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);
 	}
@@ -399,7 +417,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			if (message_name == "init")
 			{
 				// event callbacks from LLCefLib
-				mLLCEFLib->setOnPageChangedCallback(boost::bind(&MediaPluginCEF::onPageChangedCallback, this, _1, _2, _3));
+				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));
-- 
cgit v1.2.3


From d61e1ce11ab35b54141eff355e1477ff8172aa41 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Thu, 19 Nov 2015 10:23:32 -0800
Subject: MAINT-5846: Change media roll of begining to 10m

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 6fac330db4..bedbed2dcc 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8081,7 +8081,7 @@
     <key>Type</key>
     <string>F32</string>
     <key>Value</key>
-    <real>5.0</real>
+    <real>10.0</real>
   </map>
   <key>MediaRollOffMax</key>
   <map>
-- 
cgit v1.2.3


From f2a6e0f89c45e06742204efd92acc494bb14d9bd Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Thu, 19 Nov 2015 16:39:40 -0800
Subject: Fix javascript_enabled && plugins_enabled (wrong media class) and
 pull in new LLCEFLib

---
 indra/llplugin/llpluginclassmedia.cpp        | 4 ++--
 indra/media_plugins/cef/media_plugin_cef.cpp | 7 ++-----
 2 files changed, 4 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 23c5cd8794..4965d7ce08 100755
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -845,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);
 }
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index ec3518100b..182b7f2546 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -338,7 +338,7 @@ void MediaPluginCEF::authResponse(LLPluginMessage &message)
 //
 void MediaPluginCEF::receiveMessage(const char* message_string)
 {
-	//  std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+	//  std::cerr << "MediaPluginCEF::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
 	LLPluginMessage message_in;
 
 	if (message_in.parse(message_string) >= 0)
@@ -356,7 +356,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
 				message.setValueLLSD("versions", versions);
 
-				std::string plugin_version = "CEF plugin 1.0.0";
+				std::string plugin_version = "CEF plugin 1.1.3";
 				message.setValue("plugin_version", plugin_version);
 				sendMessage(message);
 			}
@@ -400,7 +400,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				}
 				else
 				{
-					//std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
 				}
 
 				LLPluginMessage message("base", "shm_remove_response");
@@ -409,7 +408,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			}
 			else
 			{
-				//std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
 			}
 		}
 		else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
@@ -709,7 +707,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
         }
         else
 		{
-			//std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
 		};
 	}
 }
-- 
cgit v1.2.3


From 94ea5dce50e97aa6ee7bd36790a995c9ae4dbeba Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Fri, 20 Nov 2015 17:34:46 -0800
Subject: pull in llceflib changes for user agent, flash plugins and pdf

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 182b7f2546..c8a52ff5fe 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -438,7 +438,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				settings.cache_enabled = true;
 				settings.cache_path = mCachePath;
 				settings.accept_language_list = mHostLanguage;
-				settings.user_agent_substring = mUserAgentSubtring;
+				settings.user_agent_substring = mLLCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
 
 				bool result = mLLCEFLib->init(settings);
 				if (!result)
-- 
cgit v1.2.3


From cc0faa34243047303c5cc066525e93c49bc5920d Mon Sep 17 00:00:00 2001
From: Callum Prentice <callum@lindenlab.com>
Date: Mon, 23 Nov 2015 12:01:32 -0800
Subject: Refrain from sending right mouse button events - crashes OS X - and
 we don't need them

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index c8a52ff5fe..77e6d35b11 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -526,15 +526,13 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				S32 x = message_in.getValueS32("x");
 				S32 y = message_in.getValueS32("y");
 
-				//std::string modifiers = message_in.getValue("modifiers");
-
+				// 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 (button == 0) btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT;
-				if (button == 1) btn = LLCEFLib::MB_MOUSE_BUTTON_RIGHT;
-				if (button == 2) btn = LLCEFLib::MB_MOUSE_BUTTON_MIDDLE;
 
-				if (event == "down")
+				if (event == "down" && button == 0)
 				{
 					mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOWN, x, y);
 					mLLCEFLib->setFocus(true);
@@ -543,7 +541,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 					str << "Mouse down at = " << x << ", " << y;
 					postDebugMessage(str.str());
 				}
-				else if (event == "up")
+				else if (event == "up" && button == 0)
 				{
 					mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_UP, x, y);
 
-- 
cgit v1.2.3


From eb484d5051c48e3bd35a2f06915eb75cf5c8c1fc Mon Sep 17 00:00:00 2001
From: rider <rider@lindenlab.com>
Date: Thu, 3 Dec 2015 13:32:06 -0800
Subject: MAINT-5909: Enable unicode text input on mac and feed that directly
 into the viewer.  Windows fixes still required.

---
 indra/llwindow/llwindowmacosx.cpp            | 18 +++++++++++++++++-
 indra/media_plugins/cef/media_plugin_cef.cpp | 15 +++++++++++++--
 2 files changed, 30 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 952c6751db..0d41884462 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -221,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()
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 77e6d35b11..919d83bc09 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -763,16 +763,17 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::
         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<char>(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger());
     char eventUChars = static_cast<char>(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"]);
@@ -787,6 +788,16 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboar
 #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"]);
-- 
cgit v1.2.3


From c3877be95468b3c26157cc98e9d40e264645a883 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Fri, 4 Dec 2015 11:21:32 -0800
Subject: MAINT-5941 [Valhalla] Default flash to on by default (reverts
 MAINT-5773)

---
 indra/newview/app_settings/settings.xml | 108 ++++++++++++++++----------------
 1 file changed, 54 insertions(+), 54 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index bedbed2dcc..1fdfdb51a8 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -734,7 +734,7 @@
       <string>F32</string>
       <key>Value</key>
       <integer>60</integer>
-    </map>  
+    </map>
     <key>AvatarRotateThresholdFast</key>
     <map>
       <key>Comment</key>
@@ -745,7 +745,7 @@
       <string>F32</string>
       <key>Value</key>
       <integer>2</integer>
-    </map>  
+    </map>
     <key>AvatarBakedTextureUploadTimeout</key>
     <map>
       <key>Comment</key>
@@ -1339,7 +1339,7 @@
       <string>String</string>
       <key>Value</key>
       <string />
-    </map>	
+    </map>
     <key>CacheNumberOfRegionsForObjects</key>
     <map>
       <key>Comment</key>
@@ -2005,7 +2005,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>ChatBarCustomWidth</key>
     <map>
@@ -3788,7 +3788,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
-    </map>	
+    </map>
 	<key>FirstSelectedEnabledPopups</key>
     <map>
       <key>Comment</key>
@@ -3799,7 +3799,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
-    </map>		
+    </map>
     <key>FixedWeather</key>
     <map>
       <key>Comment</key>
@@ -3921,7 +3921,7 @@
       <key>Value</key>
       <string>SW</string>
     </map>
-  
+
     <key>FloaterStatisticsRect</key>
     <map>
       <key>Comment</key>
@@ -4448,7 +4448,7 @@
       <string>String</string>
       <key>Value</key>
       <string>http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/howto/index.html</string>
-    </map>    
+    </map>
     <key>HomeSidePanelURL</key>
     <map>
       <key>Comment</key>
@@ -4514,7 +4514,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
-    </map>	
+    </map>
     <key>HostID</key>
     <map>
       <key>Comment</key>
@@ -4602,7 +4602,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
-    </map>  
+    </map>
     <key>IgnorePixelDepth</key>
     <map>
       <key>Comment</key>
@@ -4657,7 +4657,7 @@
       <string>F32</string>
       <key>Value</key>
       <real>0.5</real>
-    </map> 
+    </map>
 	<key>InspectorShowTime</key>
     <map>
       <key>Comment</key>
@@ -4668,7 +4668,7 @@
       <string>F32</string>
       <key>Value</key>
       <real>3.0</real>
-    </map> 
+    </map>
     <key>InstallLanguage</key>
     <map>
       <key>Comment</key>
@@ -5230,7 +5230,7 @@
       <key>Value</key>
       <string>0.0.0</string>
     </map>
-  
+
     <key>LastSnapshotToProfileHeight</key>
     <map>
       <key>Comment</key>
@@ -6309,7 +6309,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
-    </map>  
+    </map>
     <key>MenuAccessKeyTime</key>
     <map>
       <key>Comment</key>
@@ -6474,7 +6474,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
-    </map> 
+    </map>
     <key>MouseSun</key>
     <map>
       <key>Comment</key>
@@ -6639,7 +6639,7 @@
       <string>String</string>
       <key>Value</key>
       <string />
-    </map>	
+    </map>
     <key>NextLoginLocation</key>
     <map>
       <key>Comment</key>
@@ -6763,7 +6763,7 @@
       <string>String</string>
       <key>Value</key>
       <string>toast</string>
-    </map>  
+    </map>
     <key>NotificationFriendIMOptions</key>
     <map>
       <key>Comment</key>
@@ -6819,7 +6819,7 @@
       <string>String</string>
       <key>Value</key>
       <string>toast</string>
-    </map>  
+    </map>
     <key>NotificationObjectIMOptions</key>
     <map>
       <key>Comment</key>
@@ -6833,7 +6833,7 @@
       <string>String</string>
       <key>Value</key>
       <string>toast</string>
-    </map>  
+    </map>
     <key>NotificationToastLifeTime</key>
     <map>
       <key>Comment</key>
@@ -7392,7 +7392,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
-    </map>  
+    </map>
     <key>PlaySoundFriendIM</key>
     <map>
       <key>Comment</key>
@@ -7503,7 +7503,7 @@
       <key>Value</key>
       <real>0.9</real>
     </map>
-    
+
    <key>PlainTextChatHistory</key>
     <map>
       <key>Comment</key>
@@ -7515,7 +7515,7 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    
+
     <key>PluginInstancesLow</key>
     <map>
       <key>Comment</key>
@@ -7769,7 +7769,7 @@
       <real>0.4</real>
     </array>
   </map>
-  
+
   <key>PreviewDirection2</key>
   <map>
     <key>Comment</key>
@@ -8379,7 +8379,7 @@
   <key>RenderComplexityStaticMax</key>
     <map>
       <key>Comment</key>
-      <string>Sets a static max value for scaling of RenderComplexity 
+      <string>Sets a static max value for scaling of RenderComplexity
         display (-1 for dynamic scaling)</string>
       <key>Persist</key>
       <integer>1</integer>
@@ -8457,7 +8457,7 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-   
+
   <key>RenderLocalLights</key>
   <map>
     <key>Comment</key>
@@ -8684,7 +8684,7 @@
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
-      <string>Boolean</string> 
+      <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
     </map>
@@ -8721,7 +8721,7 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
- 
+
   <key>RenderAnimateRes</key>
   <map>
     <key>Comment</key>
@@ -8894,7 +8894,7 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
-  
+
   <key>RenderDepthOfField</key>
   <map>
     <key>Comment</key>
@@ -9023,7 +9023,7 @@
     <key>Value</key>
     <real>0.1</real>
   </map>
-  
+
   <key>RenderHighlightBrightness</key>
   <map>
     <key>Comment</key>
@@ -9047,7 +9047,7 @@
     <key>Value</key>
     <real>0.6</real>
   </map>
-  
+
   <key>RenderHighlightColor</key>
   <map>
     <key>Comment</key>
@@ -9076,7 +9076,7 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
-  
+
   <key>RenderSpecularResX</key>
   <map>
     <key>Comment</key>
@@ -9981,7 +9981,7 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-  
+
   <key>RenderAutoMuteByteLimit</key>
   <map>
     <key>Comment</key>
@@ -10036,7 +10036,7 @@
     <string>Boolean</string>
     <key>Value</key>
     <integer>0</integer>
-  </map>    
+  </map>
   <key>RenderAutoHideSurfaceAreaLimit</key>
   <map>
     <key>Comment</key>
@@ -10522,7 +10522,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
-    </map>	
+    </map>
     <key>SelectMovableOnly</key>
     <map>
       <key>Comment</key>
@@ -10764,7 +10764,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>1</integer>
-    </map>	
+    </map>
     <key>ShowCrosshairs</key>
     <map>
       <key>Comment</key>
@@ -10841,7 +10841,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>0</integer>
-    </map>    
+    </map>
     <key>ShowMiniMapButton</key>
     <map>
       <key>Comment</key>
@@ -10908,7 +10908,7 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>ShowObjectRenderingCost</key>                
+    <key>ShowObjectRenderingCost</key>
     <map>
       <key>Comment</key>
       <string>Show the object rendering cost  in  build tools</string>
@@ -10917,9 +10917,9 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>1</integer>   
-    </map>        
-    <key>ShowNavbarFavoritesPanel</key>    
+      <integer>1</integer>
+    </map>
+    <key>ShowNavbarFavoritesPanel</key>
     <map>
       <key>Comment</key>
       <string>Show/hide navigation bar favorites panel</string>
@@ -10928,9 +10928,9 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>1</integer>   
+      <integer>1</integer>
     </map>
-    <key>ShowNavbarNavigationPanel</key>        
+    <key>ShowNavbarNavigationPanel</key>
     <map>
       <key>Comment</key>
       <string>Show/hide navigation bar navigation panel</string>
@@ -10939,7 +10939,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>1</integer>   
+      <integer>1</integer>
     </map>
     <key>ShowWorldMapButton</key>
     <map>
@@ -11095,7 +11095,7 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>ShowPGSearchAll</key>    
+    <key>ShowPGSearchAll</key>
     <map>
       <key>Comment</key>
       <string>Display results of search All that are flagged as general</string>
@@ -11611,7 +11611,7 @@
       <string>S32</string>
       <key>Value</key>
       <integer>0</integer>
-    </map>  
+    </map>
     <key>SnapshotQuality</key>
     <map>
       <key>Comment</key>
@@ -12480,7 +12480,7 @@
       <string>String</string>
       <key>Value</key>
       <string>B56AF90D-6684-48E4-B1E4-722D3DEB2CB6</string>
-    </map>  
+    </map>
     <key>NearByChatChannelUUID</key>
     <map>
       <key>Comment</key>
@@ -12491,7 +12491,7 @@
       <string>String</string>
       <key>Value</key>
       <string>E1158BD6-661C-4981-9DAD-4DCBFF062502</string>
-    </map>  
+    </map>
     <key>NotificationChannelUUID</key>
     <map>
       <key>Comment</key>
@@ -12502,7 +12502,7 @@
       <string>String</string>
       <key>Value</key>
       <string>AEED3193-8709-4693-8558-7452CCA97AE5</string>
-    </map>  
+    </map>
     <key>AlertChannelUUID</key>
     <map>
       <key>Comment</key>
@@ -12513,7 +12513,7 @@
       <string>String</string>
       <key>Value</key>
       <string>F3E07BC8-A973-476D-8C7F-F3B7293975D1</string>
-    </map>  
+    </map>
     <key>UIImgWhiteUUID</key>
     <map>
       <key>Comment</key>
@@ -12535,7 +12535,7 @@
       <string>S32</string>
       <key>Value</key>
       <integer>2</integer>
-    </map> 
+    </map>
     <key>UIMaxComboWidth</key>
     <map>
       <key>Comment</key>
@@ -13448,7 +13448,7 @@
       <string>String</string>
       <key>Value</key>
       <string>[i800,i600]</string>
-    </map>  
+    </map>
     <key>sourceid</key>
     <map>
       <key>Comment</key>
@@ -14669,7 +14669,7 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>1</integer>
-    </map>    
+    </map>
     <key>EnablePlaceProfile</key>
     <map>
       <key>Comment</key>
@@ -15491,7 +15491,7 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
-  
+
   <key>PathfindingLineWidth</key>
   <map>
     <key>Comment</key>
@@ -15532,7 +15532,7 @@
         <real>1.0</real>
       </array>
     </map>
-    
+
     <key>HideUIControls</key>
     <map>
       <key>Comment</key>
-- 
cgit v1.2.3


From 9384eac91b974dfd918d0edf6022cc3e0b0c9daf Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 9 Dec 2015 07:36:06 -0500
Subject: MAINT-5862: Change the Linux wording in the ToS floater per Grumpity.

---
 indra/newview/skins/default/xui/en/floater_tos.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml
index c5313391c6..590d9d1844 100755
--- a/indra/newview/skins/default/xui/en/floater_tos.xml
+++ b/indra/newview/skins/default/xui/en/floater_tos.xml
@@ -70,7 +70,7 @@
      top="32"
      word_wrap="true"
      width="552">
-       To continue logging in to [SECOND_LIFE], you must accept the [https://id.secondlife.com/openid/login?return_to=https%3A%2F%2Fmy.secondlife.com%2Fopenid Terms of Service and Privacy Policy].
+       You will need to go to my.secondlife.com and log in to accept the Terms of Service before you can proceed. Thank you!
      </text>
     <web_browser
       trusted_content="true" 
-- 
cgit v1.2.3


From 5f1fe20e9ec530b1e4c4384474011e913180671c Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Fri, 11 Dec 2015 16:15:34 -0800
Subject: Missed a commit for MAINT-5948 - enable double click

---
 indra/media_plugins/cef/media_plugin_cef.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 919d83bc09..19df1fa640 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -245,7 +245,7 @@ void MediaPluginCEF::onAddressChangeCallback(std::string url)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
 	message.setValue("uri", url);
-	sendMessage(message);
+	sendMessage(message); 
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -551,7 +551,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				}
 				else if (event == "double_click")
 				{
-					// TODO: do we need this ?
+					mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOUBLE_CLICK, x, y);
 				}
 				else
 				{
-- 
cgit v1.2.3


From 3e46058651570f8e3a8cd20b597544bb07fea0a9 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Mon, 14 Dec 2015 14:14:29 -0800
Subject: MAINT-5962: Added routine for checking MoaP double click and
 forwarding those double click events into to the plugin.

---
 indra/newview/lltoolpie.cpp     | 141 ++++++++++++++++++++++++++++------------
 indra/newview/lltoolpie.h       |   3 +-
 indra/newview/llviewermedia.cpp |  11 ++++
 indra/newview/llviewermedia.h   |   3 +-
 4 files changed, 115 insertions(+), 43 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 60a7d284ef..4d41c792ca 100755
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -738,6 +738,11 @@ 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
@@ -1440,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<LLViewerObject> objectp = pick.getObject();
+    //FIXME: how do we handle object in different parcel than us?
+    LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+    LLPointer<LLViewerObject> 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<LLViewerObject> 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 100755
--- 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/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index cc56a9db8d..ab685205cf 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -2426,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)
 {
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 01d4b0786f..ede408dd0c 100755
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -226,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();
 	
-- 
cgit v1.2.3


From 3bf8929d932a6253177be55766cd2a80bb6e224d Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 15 Dec 2015 15:24:41 -0800
Subject: MAINT-5966 - file download failures need feedback

---
 indra/llplugin/llpluginclassmedia.cpp                |  5 +++++
 indra/llplugin/llpluginclassmedia.h                  |  5 +++++
 indra/llplugin/llpluginclassmediaowner.h             |  2 ++
 indra/media_plugins/cef/media_plugin_cef.cpp         | 14 ++++++++++++++
 indra/newview/llmediactrl.cpp                        |  8 ++++++++
 indra/newview/llviewermedia.cpp                      |  7 +++++++
 indra/newview/skins/default/xui/en/notifications.xml | 17 +++++++++++++++--
 7 files changed, 56 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 4965d7ce08..3d173d0459 100755
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -1090,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");
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 62652da9bc..fc27b7bea3 100755
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -279,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; };
 
@@ -426,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 100755
--- 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/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 19df1fa640..a2479cc946 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -68,6 +68,7 @@ private:
 	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);
@@ -292,6 +293,18 @@ bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::strin
 	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 = "";
@@ -425,6 +438,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				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));
 
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 9b8e24a8e8..9cf3249983 100755
--- 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"
@@ -1093,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; 
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index ab685205cf..ffae3c0e1f 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -3300,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;
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 70ba4d5077..b4c5cba1fd 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1592,10 +1592,23 @@ The object may be out of range or may have been deleted.
    icon="alertmodal.tga"
    name="CannotDownloadFile"
    type="alertmodal">
-Unable to download file
-  <tag>fail</tag>
+    Unable to download file
+    <tag>fail</tag>
   </notification>
 
+  <notification
+  name="MediaFileDownloadUnsupported"
+  label=""
+  type="alert">
+    <unique/>
+    <tag>confirm</tag>
+    You have requested a file download, which is not supported within [SECOND_LIFE].
+    <usetemplate
+     ignoretext="Warn about unsupported file downloads"
+     name="okignore"
+     yestext="OK"/>
+  </notification>
+  
   <notification
    icon="alertmodal.tga"
    name="CannotWriteFile"
-- 
cgit v1.2.3


From e07c2f8491bf439fe895da6812d68f1887341625 Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Tue, 15 Dec 2015 16:34:06 -0800
Subject: Fix for OS X and Linux - their compilers do not like missing entries
 in case statement

---
 indra/newview/llviewerparcelmedia.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 37b249dddd..fc275eb2f0 100755
--- 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;
-- 
cgit v1.2.3


From dd3b3a4fcae6b144d9ca38e10f01872d2cc3ed6f Mon Sep 17 00:00:00 2001
From: callum_linden <none@none>
Date: Wed, 16 Dec 2015 18:09:30 -0800
Subject: maint-5875 fix llceflib_host.exe' error about missing MSVCP120.dll

---
 indra/newview/viewer_manifest.py | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 9a65171d44..f7992dba90 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -471,6 +471,12 @@ class Windows_i686_Manifest(ViewerManifest):
                 self.path("wow_helper.exe")
                 self.end_prefix()
 
+        # MSVC DLLs needed for CEF and have to be in same directory as plugin
+        if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release'), dst="llplugin"):
+            self.path("msvcp120.dll")
+            self.path("msvcr120.dll")
+            self.end_prefix()
+
         # CEF files common to all configurations
         if self.prefix(src=os.path.join(os.pardir, 'packages', 'resources'), dst="llplugin"):
             self.path("cef.pak")
-- 
cgit v1.2.3


From 7b993d15b70d419dc0a7c8d92286d34a2635537d Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 18 Dec 2015 06:30:19 -0500
Subject: increment viewer version to 4.0.1

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index fcdb2e109f..1454f6ed4b 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-4.0.0
+4.0.1
-- 
cgit v1.2.3