From ab9e83030671f0d309eada847af7055213dfe501 Mon Sep 17 00:00:00 2001 From: callum_linden 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 --- autobuild.xml | 60 +--------------------------- 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 ++++++-------- 9 files changed, 28 insertions(+), 86 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index e74825f945..629a356975 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -2052,9 +2052,9 @@ archive hash - 3f8b52280cb1eff2d1acd0214bce1b16 + 78650a79bda6435e623a940ad425a593 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/quicktime_3p-update-quicktime/rev/296445/arch/CYGWIN/installer/quicktime-7.3-windows-296445.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/quicktime_3p-update-quicktime/rev/300073/arch/CYGWIN/installer/quicktime-7.3-windows-300073.tar.bz2 name windows @@ -2063,62 +2063,6 @@ version 7.3 - slplugins - - copyright - Second Life Viewer Source Code - Copyright (C) 2010, Linden Research, Inc. - description - Second Life Viewer Plugins and launcher - license - LGPL - license_file - LICENSES/slplugins-license.txt - name - slplugins - platforms - - darwin - - archive - - hash - f6bfb026572f03a4c8ac6b2b7d7eb0ae - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/slplugins_3p-update-slplugins/rev/298079/arch/Darwin/installer/slplugins-3.7.24.297623.298079-darwin-298079.tar.bz2 - - name - darwin - - linux - - archive - - hash - 64b8a3bac95b5888a7ede3d7661a18b8 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/slplugins_3p-update-slplugins/rev/298079/arch/Linux/installer/slplugins-3.7.24.297623.298079-linux-298079.tar.bz2 - - name - linux - - windows - - archive - - hash - 3a1ea3385303b78b0327c8cea929ef27 - hash_algorithm - md5 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/slplugins_3p-update-slplugins/rev/298079/arch/CYGWIN/installer/slplugins-3.7.24.297623.298079-windows-298079.tar.bz2 - - name - windows - - - version - 3.7.24.297623.298079 - slvoice copyright diff --git a/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 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(-) 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 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 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 + +//////////////////////////////////////////////////////////////////////////////// +// +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 - media_plugin_webkit + media_plugin_cef - llqtwebkit + cef copyright - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + >Copyright (c) 2008-2014 Marshall A. Greenblatt. Portions Copyright (c) 2006-2009 Google Inc. All rights reserved description - QT cross-platform application and UI framework. + Chromium Embedded Framework (CEF) Standard Binary Distribution license - LGPL + BSD license_file - LICENSES/llqtwebkit.txt + LICENSES/BSD.txt name - llqtwebkit + cef platforms - darwin - - archive - - hash - 3c2b6be4c78b2479c3fae612e1053d37 - hash_algorithm - md5 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/canonical_3p-llqtwebkit2/rev/295522/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20141015.tar.bz2 - - name - darwin - - linux - - archive - - hash - d31358176b9ba8c676458cc061767c0b - hash_algorithm - md5 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/canonical_3p-llqtwebkit2/rev/295522/arch/Linux/installer/llqtwebkit-4.7.1-linux-20141015.tar.bz2 - - name - linux - windows archive hash - bb4e8c8006c8a7aef6d3e3c36a8cebbf + bb6eda4480a04068e76a1d14c908e591 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/canonical_3p-llqtwebkit2/rev/295522/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20141015.tar.bz2 + https://callum-linden.s3.amazonaws.com/cef-3.2272.2035.80000-windows-800000.tar.bz2 name windows version - 4.7.1 + 3.2272.2035.999999 mesa 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 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(+) 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 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 --- autobuild.xml | 4 +- indra/cmake/CEFPlugin.cmake | 5 + indra/media_plugins/cef/media_plugin_cef.cpp | 574 +++++++++++---------------- indra/newview/viewer_manifest.py | 142 ++++--- 4 files changed, 330 insertions(+), 395 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index d43e316825..13ec9c0f6b 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1644,11 +1644,11 @@ archive hash - bb6eda4480a04068e76a1d14c908e591 + f80eb840c1924e3727fff65246f01c12 hash_algorithm md5 url - https://callum-linden.s3.amazonaws.com/cef-3.2272.2035.80000-windows-800000.tar.bz2 + https://callum-linden.s3.amazonaws.com/cef-3.2272.2035.888888-windows-888888.tar.bz2 name windows 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 +#include "llCEFLib.h" + #include //////////////////////////////////////////////////////////////////////////////// // 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 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(-) 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 Date: Sat, 28 Mar 2015 01:49:20 +0100 Subject: add support for keyboard (rudimentary & broken), mouse wheel and open links in same page --- autobuild.xml | 4 +- indra/media_plugins/cef/media_plugin_cef.cpp | 136 ++++++++++++++++++--------- 2 files changed, 92 insertions(+), 48 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 13ec9c0f6b..69c836b0d0 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1644,11 +1644,11 @@ archive hash - f80eb840c1924e3727fff65246f01c12 + 13da924b4d075b1557bf710e94aa98d9 hash_algorithm md5 url - https://callum-linden.s3.amazonaws.com/cef-3.2272.2035.888888-windows-888888.tar.bz2 + https://callum-linden.s3.amazonaws.com/cef-3.2272.2035.900001-windows-900001.tar.bz2 name windows 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 #include "llCEFLib.h" -#include +#include // 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 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(-) 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 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(-) 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 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(-) 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 - media_plugin_webkit + media_plugin_cef - cef + llceflib copyright >Copyright (c) 2008-2014 Marshall A. Greenblatt. Portions Copyright (c) 2006-2009 Google Inc. All rights reserved @@ -1634,9 +1634,9 @@ license BSD license_file - LICENSES/BSD.txt + LICENSES/CEF_BSD.txt name - cef + llceflib platforms windows @@ -1653,6 +1653,20 @@ name windows + darwin + + archive + + hash + c4463827f97993abdd2184b4314ea5f0 + hash_algorithm + md5 + url + https://callum-linden.s3.amazonaws.com/llceflib-0.3.2171.2069.5005-darwin-5005.tar.bz2 + + name + darwin + version 3.2272.2035.999999 -- cgit v1.2.3 From ac88d58ff5fa273ae0dc71fdf24f6ad03d925d4f Mon Sep 17 00:00:00 2001 From: callum_linden 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(-) 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 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(-) 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 fa5f62bf9fe1f1c2621d123b39eedcf2dbb6ddac Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Mon, 15 Jun 2015 14:19:40 -0700 Subject: Point to fixed (no companion files) LLCefLib package --- autobuild.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 7dbf1a7094..55d9316277 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1658,11 +1658,11 @@ archive hash - c4463827f97993abdd2184b4314ea5f0 + d32c6e5eeb91d06a8811cb0d7aa15003 hash_algorithm md5 url - https://callum-linden.s3.amazonaws.com/llceflib-0.3.2171.2069.5005-darwin-5005.tar.bz2 + https://callum-linden.s3.amazonaws.com/llceflib-0.3.2171.2069.5020-darwin-5020.tar.bz2 name darwin -- cgit v1.2.3 From 34d2c90299a201c5e27684cf0d0d9a85af01cdf5 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 16 Jun 2015 14:30:48 -0700 Subject: Point to new llceflib created via xcodebuild scripts --- autobuild.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 55d9316277..d1e1d97f03 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1658,11 +1658,11 @@ archive hash - d32c6e5eeb91d06a8811cb0d7aa15003 + 03e808b3c47eb7e62bd5b3f1108b793b hash_algorithm md5 url - https://callum-linden.s3.amazonaws.com/llceflib-0.3.2171.2069.5020-darwin-5020.tar.bz2 + https://callum-linden.s3.amazonaws.com/llceflib-0.3.2171.2069.7000-darwin-7000.tar.bz2 name darwin -- cgit v1.2.3 From 5c4d04359dcad2a8868a75589416a3ed86f3469b Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Wed, 17 Jun 2015 12:32:09 -0700 Subject: Point to *FIRST* Team City & autobuild generated version of LLCefLib for OSX --- autobuild.xml | 92 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index d1e1d97f03..931300bf94 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1517,6 +1517,52 @@ version 0.0.1 + llceflib + + copyright + Copyright (c) 2014, Linden Research, Inc. + description + LLCefLib implements a headless web browser, rendering modern web content to a memory buffer and providing an API for injecting mouse and keyboard events. It uses the Chromium Embedded Framework (https://bitbucket.org/chromiumembedded/cef) + license + LGPL + license_file + LICENSES/LICENSE-source.txt + name + llceflib + platforms + + darwin + + archive + + hash + 29d0bd1d71b3408de279762fffce375b + hash_algorithm + md5 + url + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/302723/arch/Darwin/installer/llceflib-1.0.0.(CEF3.2171.2069-32).302723-darwin-302723.tar.bz2 + + name + darwin + + windows + + archive + + hash + 13da924b4d075b1557bf710e94aa98d9 + hash_algorithm + md5 + url + https://callum-linden.s3.amazonaws.com/cef-3.2272.2035.900001-windows-900001.tar.bz2 + + name + windows + + + version + 1.0.0.(CEF3.2171.2069-32).302723 + llphysicsextensions_source copyright @@ -1625,52 +1671,6 @@ version 1.0.298370 - llceflib - - copyright - >Copyright (c) 2008-2014 Marshall A. Greenblatt. Portions Copyright (c) 2006-2009 Google Inc. All rights reserved - description - Chromium Embedded Framework (CEF) Standard Binary Distribution - license - BSD - license_file - LICENSES/CEF_BSD.txt - name - llceflib - platforms - - windows - - archive - - hash - 13da924b4d075b1557bf710e94aa98d9 - hash_algorithm - md5 - url - https://callum-linden.s3.amazonaws.com/cef-3.2272.2035.900001-windows-900001.tar.bz2 - - name - windows - - darwin - - archive - - hash - 03e808b3c47eb7e62bd5b3f1108b793b - hash_algorithm - md5 - url - https://callum-linden.s3.amazonaws.com/llceflib-0.3.2171.2069.7000-darwin-7000.tar.bz2 - - name - darwin - - - version - 3.2272.2035.999999 - mesa license -- cgit v1.2.3 From 559f71bf90bb19a885e0ee7a4c9341d27619e701 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Wed, 17 Jun 2015 15:47:32 -0700 Subject: Update version of LLCefLib we use - no functional changesin LLCefLib - just improved build script for its third party library --- autobuild.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 931300bf94..6e1e16a8a3 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 29d0bd1d71b3408de279762fffce375b + 47e50c4116920688aafe2590f0c05182 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/302723/arch/Darwin/installer/llceflib-1.0.0.(CEF3.2171.2069-32).302723-darwin-302723.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/302731/arch/Darwin/installer/llceflib-1.0.0.(CEF3.2171.2069-32).302731-darwin-302731.tar.bz2 name darwin @@ -1561,7 +1561,7 @@ version - 1.0.0.(CEF3.2171.2069-32).302723 + 1.0.0.(CEF3.2171.2069-32).302731 llphysicsextensions_source -- cgit v1.2.3 From f97fb4d80f7e6f4b810e06457afbd65a16390adc Mon Sep 17 00:00:00 2001 From: Callum Prentice 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(-) 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 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(-) 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 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(-) 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 // remove me -- cgit v1.2.3 From 3aed694ad9dad4250a6afbc7fd51a22cde9c7b0f Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 22 Jun 2015 17:00:23 -0700 Subject: Replace hand-rolled LLCefLib (Windows) package with one generated by third party scripts --- autobuild.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 6e1e16a8a3..8cf011af9f 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1550,18 +1550,18 @@ archive hash - 13da924b4d075b1557bf710e94aa98d9 + 274594d16e60e77752935e6d73ca2637 hash_algorithm md5 url - https://callum-linden.s3.amazonaws.com/cef-3.2272.2035.900001-windows-900001.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/302873/arch/CYGWIN/installer/llceflib-1.0.0.(CEF-WIN-3.2272.gbda8dc7-32).302873-windows-302873.tar.bz2 name windows version - 1.0.0.(CEF3.2171.2069-32).302731 + 1.0.0.(CEF-WIN-3.2272.gbda8dc7-32).302873 llphysicsextensions_source -- cgit v1.2.3 From f7908a50294adff3456436074075a677a9c6239b Mon Sep 17 00:00:00 2001 From: callum_linden 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 --- autobuild.xml | 10 +- indra/media_plugins/cef/media_plugin_cef.cpp | 143 +++++++++++++++++++++---- indra/newview/llappviewer.cpp | 5 +- indra/newview/skins/default/xui/en/strings.xml | 2 +- 4 files changed, 132 insertions(+), 28 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 8cf011af9f..c3f0297c00 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 47e50c4116920688aafe2590f0c05182 + 706fa86b0fd7621456d4b8a6747a8c3f hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/302731/arch/Darwin/installer/llceflib-1.0.0.(CEF3.2171.2069-32).302731-darwin-302731.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303093/arch/Darwin/installer/llceflib-1.0.0.(CEF-OSX-3.2171.2069-32).303093-darwin-303093.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 274594d16e60e77752935e6d73ca2637 + 0867f50bc1292bc0f1a66f2008feab51 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/302873/arch/CYGWIN/installer/llceflib-1.0.0.(CEF-WIN-3.2272.gbda8dc7-32).302873-windows-302873.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303093/arch/CYGWIN/installer/llceflib-1.0.0.(CEF-WIN-3.2272.gbda8dc7-32).303093-windows-303093.tar.bz2 name windows version - 1.0.0.(CEF-WIN-3.2272.gbda8dc7-32).302873 + 1.0.0.(CEF-WIN-3.2272.gbda8dc7-32).303093 llphysicsextensions_source 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 // 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 @@ -130,7 +131,6 @@ #include #include - #if LL_WINDOWS # include // 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] Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) -- cgit v1.2.3 From d89b4109f9ac3f1ef95480823df292bbc8200347 Mon Sep 17 00:00:00 2001 From: callum_linden 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(-) 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 16e750583137743099407d0280c87d2e9da7f551 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 2 Jul 2015 12:52:07 -0700 Subject: Removed EDU builds for this project via BuildParams change until we can fix TC packaging --- BuildParams | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/BuildParams b/BuildParams index aeea3b1246..15fb56ec17 100755 --- a/BuildParams +++ b/BuildParams @@ -70,12 +70,15 @@ additional_packages = "" # the viewer_channel_suffix is prefixed by a blank and then appended to the viewer_channel # for the package in a setting that overrides the compiled-in value ################################################################ -additional_packages = "EDU" +## Removed 2015-07-02 (MAINT-5360) until we fix packaging step in Team City +## additional_packages = "EDU" # The EDU package allows us to create a separate release channel whose expirations # are synchronized as much as possible with the academic year -EDU_sourceid = "" -EDU_viewer_channel_suffix = "edu" +## Removed 2015-07-02 (MAINT-5360) until we fix packaging step in Team City +## EDU_sourceid = "" +## Removed 2015-07-02 (MAINT-5360) until we fix packaging step in Team City +## EDU_viewer_channel_suffix = "edu" # Notifications - to configure email notices, add a setting like this: # _.email = -- cgit v1.2.3 From adb0706aa0f3778fda9921172eaabefd3177dbdc Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 2 Jul 2015 23:56:19 +0100 Subject: plugin and llceflib code for improved mouse support --- autobuild.xml | 10 +++++----- indra/media_plugins/cef/media_plugin_cef.cpp | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index c3f0297c00..92317bcaa6 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 706fa86b0fd7621456d4b8a6747a8c3f + 15f7db04113c492d32918ff518cddca7 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303093/arch/Darwin/installer/llceflib-1.0.0.(CEF-OSX-3.2171.2069-32).303093-darwin-303093.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303194/arch/Darwin/installer/llceflib-1.0.0.CEF-OSX-3.2171.2069-32.303194-darwin-303194.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 0867f50bc1292bc0f1a66f2008feab51 + c0c6e8d79001145c90a7136a1f5a3c18 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303093/arch/CYGWIN/installer/llceflib-1.0.0.(CEF-WIN-3.2272.gbda8dc7-32).303093-windows-303093.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303194/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303194-windows-303194.tar.bz2 name windows version - 1.0.0.(CEF-WIN-3.2272.gbda8dc7-32).303093 + 1.0.0.CEF-OSX-3.2171.2069-32.303194 llphysicsextensions_source 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 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 --- autobuild.xml | 6 +- 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 +- 16 files changed, 327 insertions(+), 51 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 92317bcaa6..3d428bdc6c 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1550,18 +1550,18 @@ archive hash - c0c6e8d79001145c90a7136a1f5a3c18 + 8917cca1b73357edd9b2ccbfd6291968 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303194/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303194-windows-303194.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303377/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303377-windows-303377.tar.bz2 name windows version - 1.0.0.CEF-OSX-3.2171.2069-32.303194 + 1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303377 llphysicsextensions_source 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 a5f1226f248c4d32f7ea84967e3e2f3acc0e0698 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 13 Jul 2015 23:54:30 +0100 Subject: rebuild llceflib for windows - no changes in functionality --- autobuild.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 3d428bdc6c..e09626ad41 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1550,18 +1550,18 @@ archive hash - 8917cca1b73357edd9b2ccbfd6291968 + baaf891741e1d21a4f73ac0b6045b6a1 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303377/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303377-windows-303377.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303466/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303466-windows-303466.tar.bz2 name windows version - 1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303377 + 1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303466 llphysicsextensions_source -- cgit v1.2.3 From d2aacce64f5bc16edc351a7e1a02de880b23ee9e Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Mon, 13 Jul 2015 16:11:34 -0700 Subject: more hacks for keyboard --- autobuild.xml | 6 ++--- indra/media_plugins/cef/media_plugin_cef.cpp | 37 ---------------------------- 2 files changed, 3 insertions(+), 40 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 3d428bdc6c..6fde36d3d4 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 15f7db04113c492d32918ff518cddca7 + 6f48889b4a1e404a0a9f89bdcf48d511 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303194/arch/Darwin/installer/llceflib-1.0.0.CEF-OSX-3.2171.2069-32.303194-darwin-303194.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303466/arch/Darwin/installer/llceflib-1.0.0.CEF-OSX-3.2171.2069-32.303466-darwin-303466.tar.bz2 name darwin @@ -1561,7 +1561,7 @@ version - 1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303377 + 1.0.0.CEF-OSX-3.2171.2069-32.303466 llphysicsextensions_source diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index f4ffd6d634..0715879b0b 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -530,29 +530,7 @@ void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier mo 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()) @@ -571,24 +549,9 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier 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(); }; //////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 83a9ae7b3c66e87179362f0da9fa7a378b1527e2 Mon Sep 17 00:00:00 2001 From: callum_linden 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 --- autobuild.xml | 10 ++-- indra/llwindow/llwindowwin32.cpp | 13 ++++ indra/llwindow/llwindowwin32.h | 3 + indra/media_plugins/cef/media_plugin_cef.cpp | 90 +++------------------------- 4 files changed, 30 insertions(+), 86 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index e09626ad41..9a1484fd50 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 15f7db04113c492d32918ff518cddca7 + cd6b75ae4ebcf592155fada871b5e4e8 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303194/arch/Darwin/installer/llceflib-1.0.0.CEF-OSX-3.2171.2069-32.303194-darwin-303194.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303548/arch/Darwin/installer/llceflib-1.0.0.CEF-OSX-3.2171.2069-32.303548-darwin-303548.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - baaf891741e1d21a4f73ac0b6045b6a1 + d0dfc921a000ae10b0d931782ac782e6 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303466/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303466-windows-303466.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303548/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303548-windows-303548.tar.bz2 name windows version - 1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303466 + 1.0.0.CEF-OSX-3.2171.2069-32.303548 llphysicsextensions_source 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 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(-) 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 af54cd28db4dae0e2e5c81d2caf0749c07da207f Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 16 Jul 2015 17:25:20 +0100 Subject: point to new versions of LLCEFLib with improved keyboard for OS X --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 9a1484fd50..ae7fbfb7f5 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - cd6b75ae4ebcf592155fada871b5e4e8 + a13465c821d747eb70faf12bb441f79a hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303548/arch/Darwin/installer/llceflib-1.0.0.CEF-OSX-3.2171.2069-32.303548-darwin-303548.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303597/arch/Darwin/installer/llceflib-1.0.0.CEF-OSX-3.2171.2069-32.303597-darwin-303597.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - d0dfc921a000ae10b0d931782ac782e6 + d3532a19f33ba42cfcfc14a3889134ef hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303548/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303548-windows-303548.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303597/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303597-windows-303597.tar.bz2 name windows version - 1.0.0.CEF-OSX-3.2171.2069-32.303548 + 1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303597 llphysicsextensions_source -- cgit v1.2.3 From 0d6d281cb3c54b08eb845199ba24992bddcf9bae Mon Sep 17 00:00:00 2001 From: callum_linden 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 --- autobuild.xml | 6 +- indra/media_plugins/cef/media_plugin_cef.cpp | 1193 +++++++++++++------------- indra/newview/viewer_manifest.py | 6 +- 3 files changed, 607 insertions(+), 598 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index ae7fbfb7f5..b05e333139 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1550,18 +1550,18 @@ archive hash - d3532a19f33ba42cfcfc14a3889134ef + bae64d0e6d787daa6299079351ceacf8 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303597/arch/CYGWIN/installer/llceflib-1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303597-windows-303597.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303625/arch/CYGWIN/installer/llceflib-1.0.0.303625-windows-303625.tar.bz2 name windows version - 1.0.0.CEF-WIN-3.2272.gbda8dc7-32.303597 + 1.0.0.303625 llphysicsextensions_source 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 Date: Fri, 17 Jul 2015 16:14:42 -0700 Subject: Changes to implement enable/disable cookies, javascript, plugins --- autobuild.xml | 6 ++--- indra/llplugin/llpluginclassmedia.cpp | 6 ++--- indra/media_plugins/cef/media_plugin_cef.cpp | 34 +++++++++++++++++++++------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b05e333139..829ab72ff3 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1550,18 +1550,18 @@ archive hash - bae64d0e6d787daa6299079351ceacf8 + b5feef8c87b9c352fccdb74665f59cc8 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303625/arch/CYGWIN/installer/llceflib-1.0.0.303625-windows-303625.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303645/arch/CYGWIN/installer/llceflib-1.0.0.303645-windows-303645.tar.bz2 name windows version - 1.0.0.303625 + 1.0.0.303645 llphysicsextensions_source 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 ae54b68893f36bd0667e87565ec07ffe78c485ee Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 20 Jul 2015 18:23:21 +0100 Subject: point to new versions of llceflib --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 829ab72ff3..caac75cd4a 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - a13465c821d747eb70faf12bb441f79a + 560a9a53427e88ffb3bac2f91c83d27b hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303597/arch/Darwin/installer/llceflib-1.0.0.CEF-OSX-3.2171.2069-32.303597-darwin-303597.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303671/arch/Darwin/installer/llceflib-1.0.1.303671-darwin-303671.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - b5feef8c87b9c352fccdb74665f59cc8 + b94f4bdb20748bc07a36993d46cc3b39 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303645/arch/CYGWIN/installer/llceflib-1.0.0.303645-windows-303645.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303671/arch/CYGWIN/installer/llceflib-1.0.1.303671-windows-303671.tar.bz2 name windows version - 1.0.0.303645 + 1.0.1.303671 llphysicsextensions_source -- cgit v1.2.3 From a016f92b299331858284fb27a5e4718d0e9485fb Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 20 Jul 2015 23:48:26 +0100 Subject: Point to new build of llceflib with better exit handling --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index caac75cd4a..541005db79 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 560a9a53427e88ffb3bac2f91c83d27b + 57d4b1a1066573bff5f9ef7e11e4157e hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303671/arch/Darwin/installer/llceflib-1.0.1.303671-darwin-303671.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303693/arch/Darwin/installer/llceflib-1.0.1.303693-darwin-303693.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - b94f4bdb20748bc07a36993d46cc3b39 + 09b802c5bb6230958e2e7c7a8523f8ac hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303671/arch/CYGWIN/installer/llceflib-1.0.1.303671-windows-303671.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303693/arch/CYGWIN/installer/llceflib-1.0.1.303693-windows-303693.tar.bz2 name windows version - 1.0.1.303671 + 1.0.1.303693 llphysicsextensions_source -- cgit v1.2.3 From 7cc5db9fdb19d8e798412295280fdf1d86cd0da8 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 24 Jul 2015 23:54:09 +0100 Subject: Include support for http auth. also improve mouse handling with drag select --- autobuild.xml | 10 +++--- indra/media_plugins/cef/media_plugin_cef.cpp | 48 +++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 541005db79..d7f1e92141 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 57d4b1a1066573bff5f9ef7e11e4157e + 5a4a0ed7fa23e19e9b7513a29668d226 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303693/arch/Darwin/installer/llceflib-1.0.1.303693-darwin-303693.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303823/arch/Darwin/installer/llceflib-1.0.1.303823-darwin-303823.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 09b802c5bb6230958e2e7c7a8523f8ac + 1327780d088ce50447f82aecdc5bbb4d hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303693/arch/CYGWIN/installer/llceflib-1.0.1.303693-windows-303693.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303823/arch/CYGWIN/installer/llceflib-1.0.1.303823-windows-303823.tar.bz2 name windows version - 1.0.1.303693 + 1.0.1.303823 llphysicsextensions_source 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 Date: Mon, 27 Jul 2015 16:09:04 -0700 Subject: Bring in lastest version of LLCEFLIb & set user agent string before browser instance created --- autobuild.xml | 6 +- indra/media_plugins/cef/media_plugin_cef.cpp | 1336 +++++++++++++------------- indra/newview/llviewermedia.cpp | 3 + 3 files changed, 680 insertions(+), 665 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index d7f1e92141..2ebbf30dfe 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1550,18 +1550,18 @@ archive hash - 1327780d088ce50447f82aecdc5bbb4d + 93ad2ceba9352e37be4e6df7bf26c553 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303823/arch/CYGWIN/installer/llceflib-1.0.1.303823-windows-303823.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303868/arch/CYGWIN/installer/llceflib-1.0.1.303868-windows-303868.tar.bz2 name windows version - 1.0.1.303823 + 1.0.1.303868 llphysicsextensions_source 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 4ae4e3ffc0c843d021e77a89e58612fc06d0c936 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 31 Jul 2015 16:19:18 -0700 Subject: Push out latest versions of LLCEFLib for conference --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 2ebbf30dfe..476cce2788 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 5a4a0ed7fa23e19e9b7513a29668d226 + ec98f409e9a2144f1ee3226d141a58c2 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303823/arch/Darwin/installer/llceflib-1.0.1.303823-darwin-303823.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304052/arch/Darwin/installer/llceflib-1.0.1.304052-darwin-304052.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 93ad2ceba9352e37be4e6df7bf26c553 + f0874ffdbf023589a1bd2ddb4b0fe239 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/303868/arch/CYGWIN/installer/llceflib-1.0.1.303868-windows-303868.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304052/arch/CYGWIN/installer/llceflib-1.0.1.304052-windows-304052.tar.bz2 name windows version - 1.0.1.303868 + 1.0.1.304052 llphysicsextensions_source -- cgit v1.2.3 From 7505501aea76e014b205d64accf89a9d30abac3a Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 1 Sep 2015 17:43:30 -0700 Subject: get update llceflib with cookie/cache code and implement cache/cookie folders in viewer --- autobuild.xml | 10 +++++----- indra/media_plugins/cef/media_plugin_cef.cpp | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 476cce2788..f6d684322c 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - ec98f409e9a2144f1ee3226d141a58c2 + 66f0127fcb3b2169a15fb09ae0387977 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304052/arch/Darwin/installer/llceflib-1.0.1.304052-darwin-304052.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304745/arch/Darwin/installer/llceflib-1.0.1.304745-darwin-304745.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - f0874ffdbf023589a1bd2ddb4b0fe239 + beff3d2db9cfac56e8e6c2ceabfa10f1 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304052/arch/CYGWIN/installer/llceflib-1.0.1.304052-windows-304052.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304745/arch/CYGWIN/installer/llceflib-1.0.1.304745-windows-304745.tar.bz2 name windows version - 1.0.1.304052 + 1.0.1.304745 llphysicsextensions_source 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 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(-) 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 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 --- autobuild.xml | 10 ++-- indra/media_plugins/cef/media_plugin_cef.cpp | 71 +++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index f6d684322c..e0963fecbe 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 66f0127fcb3b2169a15fb09ae0387977 + 6b727137b63a321298cba87863db2147 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304745/arch/Darwin/installer/llceflib-1.0.1.304745-darwin-304745.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304772/arch/Darwin/installer/llceflib-1.0.1.304772-darwin-304772.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - beff3d2db9cfac56e8e6c2ceabfa10f1 + fba9f44aa66b81d41a26df4eed116eb9 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304745/arch/CYGWIN/installer/llceflib-1.0.1.304745-windows-304745.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304772/arch/CYGWIN/installer/llceflib-1.0.1.304772-windows-304772.tar.bz2 name windows version - 1.0.1.304745 + 1.0.1.304772 llphysicsextensions_source 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 Date: Thu, 3 Sep 2015 18:16:46 -0700 Subject: support for external links and location_changed messages --- autobuild.xml | 10 +++--- 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 +- 5 files changed, 44 insertions(+), 37 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index e0963fecbe..b9aa26229f 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 6b727137b63a321298cba87863db2147 + da616a0e8f7ebf6de7ade8fe741e1998 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304772/arch/Darwin/installer/llceflib-1.0.1.304772-darwin-304772.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304832/arch/Darwin/installer/llceflib-1.0.1.304832-darwin-304832.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - fba9f44aa66b81d41a26df4eed116eb9 + 19d398a3e91eb30edbd9f3e85963210d hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304772/arch/CYGWIN/installer/llceflib-1.0.1.304772-windows-304772.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304832/arch/CYGWIN/installer/llceflib-1.0.1.304832-windows-304832.tar.bz2 name windows version - 1.0.1.304772 + 1.0.1.304832 llphysicsextensions_source 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"> + parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> Date: Thu, 3 Sep 2015 19:59:57 -0700 Subject: point to new version of llceflib with fixed support for secondlife:// URLs --- autobuild.xml | 10 +++++----- indra/media_plugins/cef/media_plugin_cef.cpp | 1 - indra/newview/skins/default/xui/en/menu_viewer.xml | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b9aa26229f..303a8fc6bf 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - da616a0e8f7ebf6de7ade8fe741e1998 + 23faf62c138f7662e5c79fbe4fdfef90 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304832/arch/Darwin/installer/llceflib-1.0.1.304832-darwin-304832.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304837/arch/Darwin/installer/llceflib-1.0.1.304837-darwin-304837.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 19d398a3e91eb30edbd9f3e85963210d + eb823208a81ecc85e35afb8ef3131109 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304832/arch/CYGWIN/installer/llceflib-1.0.1.304832-windows-304832.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304837/arch/CYGWIN/installer/llceflib-1.0.1.304837-windows-304837.tar.bz2 name windows version - 1.0.1.304832 + 1.0.1.304837 llphysicsextensions_source 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"> + parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> Date: Thu, 10 Sep 2015 15:11:28 -0700 Subject: Pull in LLCefLib with inverted output switched on and change viewer to uninvert things --- autobuild.xml | 10 +++++----- indra/media_plugins/cef/media_plugin_cef.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 303a8fc6bf..30fed7a70a 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 23faf62c138f7662e5c79fbe4fdfef90 + ebf0c4f90793c07156b9065d7197ae99 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304837/arch/Darwin/installer/llceflib-1.0.1.304837-darwin-304837.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305013/arch/Darwin/installer/llceflib-1.0.1.305013-darwin-305013.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - eb823208a81ecc85e35afb8ef3131109 + 0208a3f65f1fad65a9a059ccc58d26c9 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/304837/arch/CYGWIN/installer/llceflib-1.0.1.304837-windows-304837.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305013/arch/CYGWIN/installer/llceflib-1.0.1.305013-windows-305013.tar.bz2 name windows version - 1.0.1.304837 + 1.0.1.305013 llphysicsextensions_source 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 43b98fba8b84dbec66ca67af61f24e9d7ab41259 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 10 Sep 2015 16:36:22 -0700 Subject: fix for LLCEFLib on OSX - not liking direct initialization of std::vector --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 30fed7a70a..cbabafdc37 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - ebf0c4f90793c07156b9065d7197ae99 + 2f728b667714eb4f5fdfe928105667f8 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305013/arch/Darwin/installer/llceflib-1.0.1.305013-darwin-305013.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305022/arch/Darwin/installer/llceflib-1.0.1.305022-darwin-305022.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 0208a3f65f1fad65a9a059ccc58d26c9 + cfcd9a0cb79db5dcf84aa7fdc6788340 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305013/arch/CYGWIN/installer/llceflib-1.0.1.305013-windows-305013.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305022/arch/CYGWIN/installer/llceflib-1.0.1.305022-windows-305022.tar.bz2 name windows version - 1.0.1.305013 + 1.0.1.305022 llphysicsextensions_source -- cgit v1.2.3 From 6a119e327d7b7196e03581561545fb8501c79067 Mon Sep 17 00:00:00 2001 From: callum_linden 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(-) 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 21f9800b4026fb692d6a859f127bb276b63d8da0 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 17 Sep 2015 10:10:01 -0700 Subject: Pull in new LLCefLib with improved OS X keyboard code --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index cbabafdc37..3084a1ab3c 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 2f728b667714eb4f5fdfe928105667f8 + a2fad3f3b7a414fe75e13e242f897ede hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305022/arch/Darwin/installer/llceflib-1.0.1.305022-darwin-305022.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305214/arch/Darwin/installer/llceflib-1.0.1.305214-darwin-305214.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - cfcd9a0cb79db5dcf84aa7fdc6788340 + 6364e944645d75c7a67fcc2b62b705fe hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305022/arch/CYGWIN/installer/llceflib-1.0.1.305022-windows-305022.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305214/arch/CYGWIN/installer/llceflib-1.0.1.305214-windows-305214.tar.bz2 name windows version - 1.0.1.305022 + 1.0.1.305214 llphysicsextensions_source -- cgit v1.2.3 From 8984132a8a11dfed8e2618763fae511ee3616123 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 21 Sep 2015 15:37:09 -0700 Subject: Point to new version of LLCEFLib that is built from CEF rev 2454 (Chrome 45) --- autobuild.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 3084a1ab3c..2c7f32c1be 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1550,18 +1550,18 @@ archive hash - 6364e944645d75c7a67fcc2b62b705fe + c6ef922e9adadcac8c8128b5d335aad2 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305214/arch/CYGWIN/installer/llceflib-1.0.1.305214-windows-305214.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305308/arch/CYGWIN/installer/llceflib-1.1.0.305308-windows-305308.tar.bz2 name windows version - 1.0.1.305214 + 1.1.0.305308 llphysicsextensions_source -- cgit v1.2.3 From 533e4f3652b1b6da4a364117e20f6d88c4f9647a Mon Sep 17 00:00:00 2001 From: callum_linden 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(-) 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"/> - Date: Tue, 22 Sep 2015 02:43:23 +0100 Subject: Pick up tiny change in version string formatting from library: --- autobuild.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 2c7f32c1be..63cd761a8f 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1550,18 +1550,18 @@ archive hash - c6ef922e9adadcac8c8128b5d335aad2 + 32ab846d7848aad28cac71d5543bad8c hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305308/arch/CYGWIN/installer/llceflib-1.1.0.305308-windows-305308.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305320/arch/CYGWIN/installer/llceflib-1.1.0.305320-windows-305320.tar.bz2 name windows version - 1.1.0.305308 + 1.1.0.305320 llphysicsextensions_source -- cgit v1.2.3 From 3e20770f350652b91fd4b4a5bbef9b5f03561310 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Sat, 26 Sep 2015 18:53:17 -0700 Subject: Point to new third party llcef package and fix typo in interface --- autobuild.xml | 10 +++++----- indra/media_plugins/cef/media_plugin_cef.cpp | 4 ++-- indra/newview/viewer_manifest.py | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 63cd761a8f..3c0e35f681 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - a2fad3f3b7a414fe75e13e242f897ede + 84008a5652228d7ce89ebc31c2b08347 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305214/arch/Darwin/installer/llceflib-1.0.1.305214-darwin-305214.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305469/arch/Darwin/installer/llceflib-1.1.0.305469-darwin-305469.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 32ab846d7848aad28cac71d5543bad8c + 254db281a410be2e25511f25e9b56c15 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305320/arch/CYGWIN/installer/llceflib-1.1.0.305320-windows-305320.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305469/arch/CYGWIN/installer/llceflib-1.1.0.305469-windows-305469.tar.bz2 name windows version - 1.1.0.305320 + 1.1.0.305469 llphysicsextensions_source 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 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(-) 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 781bd116b8d95c3975d046cb463838190ed40119 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 29 Sep 2015 18:16:04 -0700 Subject: Point to new LLCefLib with cursor change code --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 3c0e35f681..7830f9f931 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 84008a5652228d7ce89ebc31c2b08347 + 049eb4de1025544f303d9671656e7dca hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305469/arch/Darwin/installer/llceflib-1.1.0.305469-darwin-305469.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305541/arch/Darwin/installer/llceflib-1.1.0.305541-darwin-305541.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 254db281a410be2e25511f25e9b56c15 + 91b7ef23553cc3c4b8d71d40540960db hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llceflib_3p-llceflib/rev/305469/arch/CYGWIN/installer/llceflib-1.1.0.305469-windows-305469.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305541/arch/CYGWIN/installer/llceflib-1.1.0.305541-windows-305541.tar.bz2 name windows version - 1.1.0.305469 + 1.1.0.305541 llphysicsextensions_source -- cgit v1.2.3 From 03047c901397c15944bc506022e5dd026f637188 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 29 Sep 2015 18:30:31 -0700 Subject: Pull in Aura Linden's new Diet Havok libraries --- autobuild.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 7830f9f931..2c2d720272 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1056,9 +1056,9 @@ archive hash - 5c5b4820999ae9e398801d6a46f45897 + 9ba77782f6ad95f12fee840e57de1a27 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/havok-source_3p-update-havok-source/rev/297312/arch/Darwin/installer/havok_source-2012.1-darwin-297312.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/Diet_3p-havok-source-diet/rev/305498/arch/Darwin/installer/havok_source-2012.1-darwin-305498.tar.bz2 name darwin @@ -1068,9 +1068,9 @@ archive hash - 6b0f41ddddfa60d8424d8a2e0bc2077d + a6128dfdda6f4789fc701884e8fd3f6a url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/havok-source_3p-update-havok-source/rev/296959/arch/Linux/installer/havok_source-2012.1-linux-296959.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/Diet_3p-havok-source-diet/rev/305498/arch/Linux/installer/havok_source-2012.1-linux-305498.tar.bz2 name linux @@ -1080,9 +1080,9 @@ archive hash - ab30ae74a665950d73ea559f019ff358 + 109095e04eff7351f301df396ec861ef url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/havok-source_3p-update-havok-source/rev/297566/arch/CYGWIN/installer/havok_source-2012.1-windows-297566.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/Diet_3p-havok-source-diet/rev/305498/arch/CYGWIN/installer/havok_source-2012.1-windows-305498.tar.bz2 name windows -- cgit v1.2.3 From b10c48efff3b054a95a9e0140f280c152c4a8488 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 30 Sep 2015 16:13:55 -0700 Subject: Add in LLCEFLib with onCursorChange code to viewer --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 2c2d720272..ec9cadac77 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 049eb4de1025544f303d9671656e7dca + a3742b7fd1ebf1aa15daab8b57a952a3 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305541/arch/Darwin/installer/llceflib-1.1.0.305541-darwin-305541.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305573/arch/Darwin/installer/llceflib-1.1.0.305573-darwin-305573.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 91b7ef23553cc3c4b8d71d40540960db + d9c2f27bcbf2758ec9c32508ae8d3655 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305541/arch/CYGWIN/installer/llceflib-1.1.0.305541-windows-305541.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305573/arch/CYGWIN/installer/llceflib-1.1.0.305573-windows-305573.tar.bz2 name windows version - 1.1.0.305541 + 1.1.0.305573 llphysicsextensions_source -- cgit v1.2.3 From a0c0bc6b4033acf8d395708b5515215699905acc Mon Sep 17 00:00:00 2001 From: callum_linden 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(-) 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 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(-) 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 1b99c2754c28519c42a3e31dd6c2a20ddab3032f Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 1 Oct 2015 15:51:34 -0700 Subject: Revert to old, fat but working Havok libraries for all platforms --- autobuild.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index ec9cadac77..5bc8b4055b 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1056,9 +1056,9 @@ archive hash - 9ba77782f6ad95f12fee840e57de1a27 + 5c5b4820999ae9e398801d6a46f45897 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/Diet_3p-havok-source-diet/rev/305498/arch/Darwin/installer/havok_source-2012.1-darwin-305498.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/havok-source_3p-update-havok-source/rev/297312/arch/Darwin/installer/havok_source-2012.1-darwin-297312.tar.bz2 name darwin @@ -1068,9 +1068,9 @@ archive hash - a6128dfdda6f4789fc701884e8fd3f6a + 6b0f41ddddfa60d8424d8a2e0bc2077d url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/Diet_3p-havok-source-diet/rev/305498/arch/Linux/installer/havok_source-2012.1-linux-305498.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/havok-source_3p-update-havok-source/rev/296959/arch/Linux/installer/havok_source-2012.1-linux-296959.tar.bz2 name linux @@ -1080,9 +1080,9 @@ archive hash - 109095e04eff7351f301df396ec861ef + ab30ae74a665950d73ea559f019ff358 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/Diet_3p-havok-source-diet/rev/305498/arch/CYGWIN/installer/havok_source-2012.1-windows-305498.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/havok-source_3p-update-havok-source/rev/297566/arch/CYGWIN/installer/havok_source-2012.1-windows-297566.tar.bz2 name windows -- cgit v1.2.3 From 8edc0a1c7b17bffe5af82735341839d1dc47ae9a Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 1 Oct 2015 16:56:25 -0700 Subject: Pick up latest LLCEFLib --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 5bc8b4055b..cb33e23c52 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - a3742b7fd1ebf1aa15daab8b57a952a3 + 8655aa7c3ad64bc1a333bd159e604a38 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305573/arch/Darwin/installer/llceflib-1.1.0.305573-darwin-305573.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305626/arch/Darwin/installer/llceflib-1.1.0.305626-darwin-305626.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - d9c2f27bcbf2758ec9c32508ae8d3655 + 246e4f3a5e2852233a728771bca45bf4 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305573/arch/CYGWIN/installer/llceflib-1.1.0.305573-windows-305573.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305626/arch/CYGWIN/installer/llceflib-1.1.0.305626-windows-305626.tar.bz2 name windows version - 1.1.0.305573 + 1.1.0.305626 llphysicsextensions_source -- cgit v1.2.3 From cb7f84a470d7afeb1501cf5514333c6ee15d96df Mon Sep 17 00:00:00 2001 From: Rider Linden 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 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 -#include - -#include -#include -#include -#include // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken. - -#include "apr_pools.h" -#include "apr_dso.h" -} - -//////////////////////////////////////////////////// - -#define DEBUGMSG(...) do {} while(0) -#define INFOMSG(...) do {} while(0) -#define WARNMSG(...) do {} while(0) - -#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) RTN (*ll##PASYM)(__VA_ARGS__) = NULL -#include "linux_volume_catcher_pa_syms.inc" -#include "linux_volume_catcher_paglib_syms.inc" -#undef LL_PA_SYM - -static bool sSymsGrabbed = false; -static apr_pool_t *sSymPADSOMemoryPool = NULL; -static apr_dso_handle_t *sSymPADSOHandleG = NULL; - -bool grab_pa_syms(std::string pulse_dso_name) -{ - if (sSymsGrabbed) - { - // already have grabbed good syms - return true; - } - - bool sym_error = false; - bool rtn = false; - apr_status_t rv; - apr_dso_handle_t *sSymPADSOHandle = NULL; - -#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0) - - //attempt to load the shared library - apr_pool_create(&sSymPADSOMemoryPool, NULL); - - if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle, - pulse_dso_name.c_str(), - sSymPADSOMemoryPool) )) - { - INFOMSG("Found DSO: %s", pulse_dso_name.c_str()); - -#include "linux_volume_catcher_pa_syms.inc" -#include "linux_volume_catcher_paglib_syms.inc" - - if ( sSymPADSOHandle ) - { - sSymPADSOHandleG = sSymPADSOHandle; - sSymPADSOHandle = NULL; - } - - rtn = !sym_error; - } - else - { - INFOMSG("Couldn't load DSO: %s", pulse_dso_name.c_str()); - rtn = false; // failure - } - - if (sym_error) - { - WARNMSG("Failed to find necessary symbols in PulseAudio libraries."); - } -#undef LL_PA_SYM - - sSymsGrabbed = rtn; - return rtn; -} - - -void ungrab_pa_syms() -{ - // should be safe to call regardless of whether we've - // actually grabbed syms. - - if ( sSymPADSOHandleG ) - { - apr_dso_unload(sSymPADSOHandleG); - sSymPADSOHandleG = NULL; - } - - if ( sSymPADSOMemoryPool ) - { - apr_pool_destroy(sSymPADSOMemoryPool); - sSymPADSOMemoryPool = NULL; - } - - // NULL-out all of the symbols we'd grabbed -#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0) -#include "linux_volume_catcher_pa_syms.inc" -#include "linux_volume_catcher_paglib_syms.inc" -#undef LL_PA_SYM - - sSymsGrabbed = false; -} -//////////////////////////////////////////////////// - -// PulseAudio requires a chain of callbacks with C linkage -extern "C" { - void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata); - void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata); - void callback_context_state(pa_context *context, void *userdata); -} - - -class VolumeCatcherImpl -{ -public: - VolumeCatcherImpl(); - ~VolumeCatcherImpl(); - - void setVolume(F32 volume); - void pump(void); - - // for internal use - can't be private because used from our C callbacks - - bool loadsyms(std::string pulse_dso_name); - void init(); - void cleanup(); - - void update_all_volumes(F32 volume); - void update_index_volume(U32 index, F32 volume); - void connected_okay(); - - std::set mSinkInputIndices; - std::map mSinkInputNumChannels; - F32 mDesiredVolume; - pa_glib_mainloop *mMainloop; - pa_context *mPAContext; - bool mConnected; - bool mGotSyms; -}; - -VolumeCatcherImpl::VolumeCatcherImpl() - : mDesiredVolume(0.0f), - mMainloop(NULL), - mPAContext(NULL), - mConnected(false), - mGotSyms(false) -{ - init(); -} - -VolumeCatcherImpl::~VolumeCatcherImpl() -{ - cleanup(); -} - -bool VolumeCatcherImpl::loadsyms(std::string pulse_dso_name) -{ - return grab_pa_syms(pulse_dso_name); -} - -void VolumeCatcherImpl::init() -{ - // try to be as defensive as possible because PA's interface is a - // bit fragile and (for our purposes) we'd rather simply not function - // than crash - - // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in - // libpulse.so.0 - this isn't a great assumption, and the two DSOs should - // probably be loaded separately. Our Linux DSO framework needs refactoring, - // we do this sort of thing a lot with practically identical logic... - mGotSyms = loadsyms("libpulse-mainloop-glib.so.0"); - if (!mGotSyms) return; - - // better make double-sure glib itself is initialized properly. - if (!g_thread_supported ()) g_thread_init (NULL); - g_type_init(); - - mMainloop = llpa_glib_mainloop_new(g_main_context_default()); - if (mMainloop) - { - pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop); - if (api) - { - pa_proplist *proplist = llpa_proplist_new(); - if (proplist) - { - llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player"); - llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust"); - llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster"); - llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1"); - - // plain old pa_context_new() is broken! - mPAContext = llpa_context_new_with_proplist(api, NULL, proplist); - llpa_proplist_free(proplist); - } - } - } - - // Now we've set up a PA context and mainloop, try connecting the - // PA context to a PA daemon. - if (mPAContext) - { - llpa_context_set_state_callback(mPAContext, callback_context_state, this); - pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN? - if (llpa_context_connect(mPAContext, NULL, cflags, NULL) >= 0) - { - // Okay! We haven't definitely connected, but we - // haven't definitely failed yet. - } - else - { - // Failed to connect to PA manager... we'll leave - // things like that. Perhaps we should try again later. - } - } -} - -void VolumeCatcherImpl::cleanup() -{ - mConnected = false; - - if (mGotSyms && mPAContext) - { - llpa_context_disconnect(mPAContext); - llpa_context_unref(mPAContext); - } - mPAContext = NULL; - - if (mGotSyms && mMainloop) - { - llpa_glib_mainloop_free(mMainloop); - } - mMainloop = NULL; -} - -void VolumeCatcherImpl::setVolume(F32 volume) -{ - mDesiredVolume = volume; - - if (!mGotSyms) return; - - if (mConnected && mPAContext) - { - update_all_volumes(mDesiredVolume); - } - - pump(); -} - -void VolumeCatcherImpl::pump() -{ - gboolean may_block = FALSE; - g_main_context_iteration(g_main_context_default(), may_block); -} - -void VolumeCatcherImpl::connected_okay() -{ - pa_operation *op; - - // fetch global list of existing sinkinputs - if ((op = llpa_context_get_sink_input_info_list(mPAContext, - callback_discovered_sinkinput, - this))) - { - llpa_operation_unref(op); - } - - // subscribe to future global sinkinput changes - llpa_context_set_subscribe_callback(mPAContext, - callback_subscription_alert, - this); - if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t) - (PA_SUBSCRIPTION_MASK_SINK_INPUT), - NULL, NULL))) - { - llpa_operation_unref(op); - } -} - -void VolumeCatcherImpl::update_all_volumes(F32 volume) -{ - for (std::set::iterator it = mSinkInputIndices.begin(); - it != mSinkInputIndices.end(); ++it) - { - update_index_volume(*it, volume); - } -} - -void VolumeCatcherImpl::update_index_volume(U32 index, F32 volume) -{ - static pa_cvolume cvol; - llpa_cvolume_set(&cvol, mSinkInputNumChannels[index], - llpa_sw_volume_from_linear(volume)); - - pa_context *c = mPAContext; - uint32_t idx = index; - const pa_cvolume *cvolumep = &cvol; - pa_context_success_cb_t cb = NULL; // okay as null - void *userdata = NULL; // okay as null - - pa_operation *op; - if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata))) - { - llpa_operation_unref(op); - } -} - - -void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata) -{ - VolumeCatcherImpl *impl = dynamic_cast((VolumeCatcherImpl*)userdata); - llassert(impl); - - if (0 == eol) - { - pa_proplist *proplist = sii->proplist; - pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID)); - - if (sinkpid == getpid()) // does the discovered sinkinput belong to this process? - { - bool is_new = (impl->mSinkInputIndices.find(sii->index) == - impl->mSinkInputIndices.end()); - - impl->mSinkInputIndices.insert(sii->index); - impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels; - - if (is_new) - { - // new! - impl->update_index_volume(sii->index, impl->mDesiredVolume); - } - else - { - // seen it already, do nothing. - } - } - } -} - -void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata) -{ - VolumeCatcherImpl *impl = dynamic_cast((VolumeCatcherImpl*)userdata); - llassert(impl); - - switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { - case PA_SUBSCRIPTION_EVENT_SINK_INPUT: - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == - PA_SUBSCRIPTION_EVENT_REMOVE) - { - // forget this sinkinput, if we were caring about it - impl->mSinkInputIndices.erase(index); - impl->mSinkInputNumChannels.erase(index); - } - else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == - PA_SUBSCRIPTION_EVENT_NEW) - { - // ask for more info about this new sinkinput - pa_operation *op; - if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl))) - { - llpa_operation_unref(op); - } - } - else - { - // property change on this sinkinput - we don't care. - } - break; - - default:; - } -} - -void callback_context_state(pa_context *context, void *userdata) -{ - VolumeCatcherImpl *impl = dynamic_cast((VolumeCatcherImpl*)userdata); - llassert(impl); - - switch (llpa_context_get_state(context)) - { - case PA_CONTEXT_READY: - impl->mConnected = true; - impl->connected_okay(); - break; - case PA_CONTEXT_TERMINATED: - impl->mConnected = false; - break; - case PA_CONTEXT_FAILED: - impl->mConnected = false; - break; - default:; - } -} - -///////////////////////////////////////////////////// - -VolumeCatcher::VolumeCatcher() -{ - pimpl = new VolumeCatcherImpl(); -} - -VolumeCatcher::~VolumeCatcher() -{ - delete pimpl; - pimpl = NULL; -} - -void VolumeCatcher::setVolume(F32 volume) -{ - llassert(pimpl); - pimpl->setVolume(volume); -} - -void VolumeCatcher::setPan(F32 pan) -{ - // TODO: implement this (if possible) -} - -void VolumeCatcher::pump() -{ - llassert(pimpl); - pimpl->pump(); -} diff --git a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc deleted file mode 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 -#include -#include - -#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 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::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 -# include -} -#else -# define LL_QTWEBKIT_USES_PIXMAPS 0 -#endif // LL_LINUX - -# include "volume_catcher.h" - -#if LL_WINDOWS -# include -#else -# include -# include -#endif - -#if LL_WINDOWS - // *NOTE:Mani - This captures the module handle for the dll. This is used below - // to get the path to this dll for webkit initialization. - // I don't know how/if this can be done with apr... - namespace { HMODULE gModuleHandle;}; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) - { - gModuleHandle = (HMODULE) hinstDLL; - return TRUE; - } -#endif - -//////////////////////////////////////////////////////////////////////////////// -// -class MediaPluginWebKit : - public MediaPluginBase, - public LLEmbeddedBrowserWindowObserver -{ -public: - MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginWebKit(); - - /*virtual*/ void receiveMessage(const char *message_string); - -private: - - std::string mProfileDir; - std::string mHostLanguage; - std::string mUserAgent; - bool mCookiesEnabled; - bool mJavascriptEnabled; - bool mPluginsEnabled; - bool mEnableMediaPluginDebugging; - - enum - { - INIT_STATE_UNINITIALIZED, // LLQtWebkit hasn't been set up yet - INIT_STATE_INITIALIZED, // LLQtWebkit has been set up, but no browser window has been created yet. - INIT_STATE_NAVIGATING, // Browser instance has been set up and initial navigate to about:blank has been issued - INIT_STATE_NAVIGATE_COMPLETE, // initial navigate to about:blank has completed - INIT_STATE_WAIT_REDRAW, // First real navigate begin has been received, waiting for page changed event to start handling redraws - INIT_STATE_WAIT_COMPLETE, // Waiting for first real navigate complete event - INIT_STATE_RUNNING // All initialization gymnastics are complete. - }; - int mBrowserWindowId; - int mInitState; - std::string mInitialNavigateURL; - bool mNeedsUpdate; - - bool mCanCut; - bool mCanCopy; - bool mCanPaste; - int mLastMouseX; - int mLastMouseY; - bool mFirstFocus; - F32 mBackgroundR; - F32 mBackgroundG; - F32 mBackgroundB; - std::string mTarget; - LLTimer mElapsedTime; - - VolumeCatcher mVolumeCatcher; - - void postDebugMessage( const std::string& msg ) - { - if ( mEnableMediaPluginDebugging ) - { - std::stringstream str; - str << "@Media Msg> " << "[" << (double)mElapsedTime.getElapsedTimeF32() << "] -- " << msg; - - LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message"); - debug_message.setValue("message_text", str.str()); - debug_message.setValue("message_level", "info"); - sendMessage(debug_message); - } - } - - void setInitState(int state) - { -// std::cerr << "changing init state to " << state << std::endl; - mInitState = state; - } - - //////////////////////////////////////////////////////////////////////////////// - // - void update(int milliseconds) - { -#if LL_QTLINUX_DOESNT_HAVE_GLIB - // pump glib generously, as Linux browser plugins are on the - // glib main loop, even if the browser itself isn't - ugh - // This is NOT NEEDED if Qt itself was built with glib - // mainloop integration. - GMainContext *mainc = g_main_context_default(); - while(g_main_context_iteration(mainc, FALSE)); -#endif // LL_QTLINUX_DOESNT_HAVE_GLIB - - // pump qt - LLQtWebKit::getInstance()->pump( milliseconds ); - - mVolumeCatcher.pump(); - - checkEditState(); - - if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) - { - if(!mInitialNavigateURL.empty()) - { - // We already have the initial navigate URL -- kick off the navigate. - LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, mInitialNavigateURL ); - mInitialNavigateURL.clear(); - } - } - - if ( (mInitState > INIT_STATE_WAIT_REDRAW) && mNeedsUpdate ) - { - const unsigned char* browser_pixels = LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId ); - - unsigned int rowspan = LLQtWebKit::getInstance()->getBrowserRowSpan( mBrowserWindowId ); - unsigned int height = LLQtWebKit::getInstance()->getBrowserHeight( mBrowserWindowId ); -#if !LL_QTWEBKIT_USES_PIXMAPS - unsigned int buffer_size = rowspan * height; -#endif // !LL_QTWEBKIT_USES_PIXMAPS - -// std::cerr << "webkit plugin: updating" << std::endl; - - // TODO: should get rid of this memcpy if possible - if ( mPixels && browser_pixels ) - { -// std::cerr << " memcopy of " << buffer_size << " bytes" << std::endl; - -#if LL_QTWEBKIT_USES_PIXMAPS - // copy the pixel data upside-down because of the co-ord system - for (int y=0; y 0 && mHeight > 0 ) - { -// std::cerr << "Setting dirty, " << mWidth << " x " << mHeight << std::endl; - setDirty( 0, 0, mWidth, mHeight ); - } - - mNeedsUpdate = false; - }; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - bool initBrowser() - { - // already initialized - if ( mInitState > INIT_STATE_UNINITIALIZED ) - return true; - - // set up directories - char cwd[ FILENAME_MAX ]; // I *think* this is defined on all platforms we use - if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) - { - LL_WARNS() << "Couldn't get cwd - probably too long - failing to init." << LL_ENDL; - return false; - } - std::string application_dir = std::string( cwd ); - -#if LL_LINUX - // take care to initialize glib properly, because some - // versions of Qt don't, and we indirectly need it for (some - // versions of) Flash to not crash the browser. - if (!g_thread_supported ()) g_thread_init (NULL); - g_type_init(); -#endif - -#if LL_DARWIN - // When running under the Xcode debugger, there's a setting called "Break on Debugger()/DebugStr()" which defaults to being turned on. - // This causes the environment variable USERBREAK to be set to 1, which causes these legacy calls to break into the debugger. - // This wouldn't cause any problems except for the fact that the current release version of the Flash plugin has a call to Debugger() in it - // which gets hit when the plugin is probed by webkit. - // Unsetting the environment variable here works around this issue. - unsetenv("USERBREAK"); -#endif - -#if LL_WINDOWS - //*NOTE:Mani - On windows, at least, the component path is the - // location of this dll's image file. - std::string component_dir; - char dll_path[_MAX_PATH]; - DWORD len = GetModuleFileNameA(gModuleHandle, (LPCH)&dll_path, _MAX_PATH); - while(len && dll_path[ len ] != ('\\') ) - { - len--; - } - if(len >= 0) - { - dll_path[len] = 0; - component_dir = dll_path; - } - else - { - // *NOTE:Mani - This case should be an rare exception. - // GetModuleFileNameA should always give you a full path, no? - component_dir = application_dir; - } -#else - std::string component_dir = application_dir; -#endif - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "Component dir set to: " + component_dir ); - - // window handle - needed on Windows and must be app window. -#if LL_WINDOWS - char window_title[ MAX_PATH ]; - GetConsoleTitleA( window_title, MAX_PATH ); - void* native_window_handle = (void*)FindWindowA( NULL, window_title ); -#else - void* native_window_handle = 0; -#endif - - // main browser initialization - bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, mProfileDir, native_window_handle ); - if ( result ) - { - mInitState = INIT_STATE_INITIALIZED; - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "browser initialized okay" ); - - return true; - }; - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "browser nOT initialized." ); - - return false; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - bool initBrowserWindow() - { - // already initialized - if ( mInitState > INIT_STATE_INITIALIZED ) - return true; - - // not enough information to initialize the browser yet. - if ( mWidth < 0 || mHeight < 0 || mDepth < 0 || - mTextureWidth < 0 || mTextureHeight < 0 ) - { - return false; - }; - - // Set up host language before creating browser window - if(!mHostLanguage.empty()) - { - LLQtWebKit::getInstance()->setHostLanguage(mHostLanguage); - postDebugMessage( "Setting language to " + mHostLanguage ); - } - - // turn on/off cookies based on what host app tells us - LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled ); - - // turn on/off plugins based on what host app tells us - LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled ); - - // turn on/off Javascript based on what host app tells us -#if LLQTWEBKIT_API_VERSION >= 11 - LLQtWebKit::getInstance()->enableJavaScript( mJavascriptEnabled ); -#else - LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled ); -#endif - - std::stringstream str; - str << "Cookies enabled = " << mCookiesEnabled << ", plugins enabled = " << mPluginsEnabled << ", Javascript enabled = " << mJavascriptEnabled; - postDebugMessage( str.str() ); - - // create single browser window - mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight, mTarget); - - str.str(""); - str.clear(); - str << "Setting browser window size to " << mWidth << " x " << mHeight; - postDebugMessage( str.str() ); - - // tell LLQtWebKit about the size of the browser window - LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); - - // observer events that LLQtWebKit emits - LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this ); - - // append details to agent string - LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); - postDebugMessage( "Updating user agent with " + mUserAgent ); - -#if !LL_QTWEBKIT_USES_PIXMAPS - // don't flip bitmap - LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); -#endif // !LL_QTWEBKIT_USES_PIXMAPS - - // set background color - // convert background color channels from [0.0, 1.0] to [0, 255]; - LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, int(mBackgroundR * 255.0f), int(mBackgroundG * 255.0f), int(mBackgroundB * 255.0f) ); - - // Set state _before_ starting the navigate, since onNavigateBegin might get called before this call returns. - setInitState(INIT_STATE_NAVIGATING); - - // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance. - // FIXME: Re-added this because navigating to a "page" initializes things correctly - especially - // for the HTTP AUTH dialog issues (DEV-41731). Will fix at a later date. - // Build a data URL like this: "data:text/html,%3Chtml%3E%3Cbody bgcolor=%22#RRGGBB%22%3E%3C/body%3E%3C/html%3E" - // where RRGGBB is the background color in HTML style - std::stringstream url; - - url << "data:text/html,%3Chtml%3E%3Cbody%20bgcolor=%22#"; - // convert background color channels from [0.0, 1.0] to [0, 255]; - url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundR * 255.0f); - url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundG * 255.0f); - url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundB * 255.0f); - url << "%22%3E%3C/body%3E%3C/html%3E"; - - //LL_DEBUGS() << "data url is: " << url.str() << LL_ENDL; - - // always display loading overlay now -#if LLQTWEBKIT_API_VERSION >= 16 - LLQtWebKit::getInstance()->enableLoadingOverlay(mBrowserWindowId, true); -#else - LL_WARNS() << "Ignoring enableLoadingOverlay() call (llqtwebkit version is too old)." << LL_ENDL; -#endif - str.clear(); - str << "Loading overlay enabled = " << mEnableMediaPluginDebugging << " for mBrowserWindowId = " << mBrowserWindowId; - postDebugMessage( str.str() ); - - LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, url.str() ); -// LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" ); - - return true; - } - - void setVolume(F32 vol); - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onCursorChanged(const EventType& event) - { - LLQtWebKit::ECursor llqt_cursor = (LLQtWebKit::ECursor)event.getIntValue(); - std::string name; - - switch(llqt_cursor) - { - case LLQtWebKit::C_ARROW: - name = "arrow"; - break; - case LLQtWebKit::C_IBEAM: - name = "ibeam"; - break; - case LLQtWebKit::C_SPLITV: - name = "splitv"; - break; - case LLQtWebKit::C_SPLITH: - name = "splith"; - break; - case LLQtWebKit::C_POINTINGHAND: - name = "hand"; - break; - - default: - LL_WARNS() << "Unknown cursor ID: " << (int)llqt_cursor << LL_ENDL; - break; - } - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed"); - message.setValue("name", name); - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onPageChanged( const EventType& event ) - { - if(mInitState == INIT_STATE_WAIT_REDRAW) - { - setInitState(INIT_STATE_WAIT_COMPLETE); - } - - // flag that an update is required - mNeedsUpdate = true; - }; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onNavigateBegin(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); - message.setValue("uri", event.getEventUri()); - message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK)); - message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD)); - sendMessage(message); - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "Navigate begin event at: " + event.getEventUri() ); - - setStatus(STATUS_LOADING); - } - - if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) - { - // Skip the WAIT_REDRAW state now -- with the right background color set, it should no longer be necessary. -// setInitState(INIT_STATE_WAIT_REDRAW); - setInitState(INIT_STATE_WAIT_COMPLETE); - } - - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onNavigateComplete(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - if(mInitState < INIT_STATE_RUNNING) - { - setInitState(INIT_STATE_RUNNING); - - // Clear the history, so the "back" button doesn't take you back to "about:blank". - LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId); - } - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); - message.setValue("uri", event.getEventUri()); - message.setValueS32("result_code", event.getIntValue()); - message.setValue("result_string", event.getStringValue()); - message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK)); - message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD)); - sendMessage(message); - - setStatus(STATUS_LOADED); - } - else if(mInitState == INIT_STATE_NAVIGATING) - { - setInitState(INIT_STATE_NAVIGATE_COMPLETE); - } - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "Navigate complete event at: " + event.getEventUri() ); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onUpdateProgress(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "progress"); - message.setValueS32("percent", event.getIntValue()); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onStatusTextChange(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); - message.setValue("status", event.getStringValue()); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onTitleChange(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); - message.setValue("name", event.getStringValue()); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onNavigateErrorPage(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_error_page"); - message.setValueS32("status_code", event.getIntValue()); - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onLocationChange(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); - message.setValue("uri", event.getEventUri()); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onClickLinkHref(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); - message.setValue("uri", event.getEventUri()); - message.setValue("target", event.getStringValue()); - message.setValue("uuid", event.getStringValue2()); - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onClickLinkNoFollow(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); - message.setValue("uri", event.getEventUri()); -#if LLQTWEBKIT_API_VERSION >= 7 - message.setValue("nav_type", event.getNavigationType()); -#else - message.setValue("nav_type", "clicked"); -#endif - sendMessage(message); - } - - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onCookieChanged(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookie_set"); - message.setValue("cookie", event.getStringValue()); - // These could be passed through as well, but aren't really needed. -// message.setValue("uri", event.getEventUri()); -// message.setValueBoolean("dead", (event.getIntValue() != 0)) - - // debug spam - postDebugMessage( "Sending cookie_set message from plugin: " + event.getStringValue() ); - - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onWindowCloseRequested(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "close_request"); - message.setValue("uuid", event.getStringValue()); - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onWindowGeometryChangeRequested(const EventType& event) - { - int x, y, width, height; - event.getRectValue(x, y, width, height); - - // This sometimes gets called with a zero-size request. Don't pass these along. - if(width > 0 && height > 0) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "geometry_change"); - message.setValue("uuid", event.getStringValue()); - message.setValueS32("x", x); - message.setValueS32("y", y); - message.setValueS32("width", width); - message.setValueS32("height", height); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - std::string onRequestFilePicker( const EventType& eventIn ) - { - return blockingPickFile(); - } - - std::string mAuthUsername; - std::string mAuthPassword; - bool mAuthOK; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - bool onAuthRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password) - { - mAuthOK = false; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request"); - message.setValue("url", in_url); - message.setValue("realm", in_realm); - message.setValueBoolean("blocking_request", true); - - // The "blocking_request" key in the message means this sendMessage call will block until a response is received. - sendMessage(message); - - if(mAuthOK) - { - out_username = mAuthUsername; - out_password = mAuthPassword; - } - - return mAuthOK; - } - - void authResponse(LLPluginMessage &message) - { - mAuthOK = message.getValueBoolean("ok"); - if(mAuthOK) - { - mAuthUsername = message.getValue("username"); - mAuthPassword = message.getValue("password"); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onLinkHovered(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "link_hovered"); - message.setValue("link", event.getEventUri()); - message.setValue("title", event.getStringValue()); - message.setValue("text", event.getStringValue2()); - sendMessage(message); - } - } - - LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers) - { - int result = 0; - - if(modifiers.find("shift") != std::string::npos) - result |= LLQtWebKit::KM_MODIFIER_SHIFT; - - if(modifiers.find("alt") != std::string::npos) - result |= LLQtWebKit::KM_MODIFIER_ALT; - - if(modifiers.find("control") != std::string::npos) - result |= LLQtWebKit::KM_MODIFIER_CONTROL; - - if(modifiers.find("meta") != std::string::npos) - result |= LLQtWebKit::KM_MODIFIER_META; - - return (LLQtWebKit::EKeyboardModifier)result; - } - - //////////////////////////////////////////////////////////////////////////////// - // - void deserializeKeyboardData( LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers ) - { - native_scan_code = 0; - native_virtual_key = 0; - native_modifiers = 0; - - if( native_key_data.isMap() ) - { -#if LL_DARWIN - native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger()); - native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); -#elif LL_WINDOWS - native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); - // TODO: I don't think we need to do anything with native modifiers here -- please verify -#elif LL_LINUX - native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); - native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); -#else - // Add other platforms here as needed -#endif - }; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) - { - // The incoming values for 'key' will be the ones from indra_constants.h - std::string utf8_text; - - if(key < KEY_SPECIAL) - { - // Low-ascii characters need to get passed through. - utf8_text = (char)key; - } - - // Any special-case handling we want to do for particular keys... - switch((KEY)key) - { - // ASCII codes for some standard keys - case LLQtWebKit::KEY_BACKSPACE: utf8_text = (char)8; break; - case LLQtWebKit::KEY_TAB: utf8_text = (char)9; break; - case LLQtWebKit::KEY_RETURN: utf8_text = (char)13; break; - case LLQtWebKit::KEY_PAD_RETURN: utf8_text = (char)13; break; - case LLQtWebKit::KEY_ESCAPE: utf8_text = (char)27; break; - - default: - break; - } - -// std::cerr << "key event " << (int)key_event << ", native_key_data = " << native_key_data << std::endl; - - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers ); - - LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); - - checkEditState(); - }; - - //////////////////////////////////////////////////////////////////////////////// - // - void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) - { - uint32_t key = LLQtWebKit::KEY_NONE; - -// std::cerr << "unicode input, native_key_data = " << native_key_data << std::endl; - - if(utf8str.size() == 1) - { - // The only way a utf8 string can be one byte long is if it's actually a single 7-bit ascii character. - // In this case, use it as the key value. - key = utf8str[0]; - } - - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers ); - - LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); - LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); - - checkEditState(); - }; - - void checkEditState(void) - { - bool can_cut = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT); - bool can_copy = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY); - bool can_paste = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE); - - if((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste)) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state"); - - if(can_cut != mCanCut) - { - mCanCut = can_cut; - message.setValueBoolean("cut", can_cut); - } - - if(can_copy != mCanCopy) - { - mCanCopy = can_copy; - message.setValueBoolean("copy", can_copy); - } - - if(can_paste != mCanPaste) - { - mCanPaste = can_paste; - message.setValueBoolean("paste", can_paste); - } - - sendMessage(message); - - } - } - - std::string mPickedFile; - - std::string blockingPickFile(void) - { - mPickedFile.clear(); - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file"); - message.setValueBoolean("blocking_request", true); - - // The "blocking_request" key in the message means this sendMessage call will block until a response is received. - sendMessage(message); - - return mPickedFile; - } - - void onPickFileResponse(const std::string &file) - { - mPickedFile = file; - } - -}; - -MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : - MediaPluginBase(host_send_func, host_user_data) -{ -// std::cerr << "MediaPluginWebKit constructor" << std::endl; - - mBrowserWindowId = 0; - mInitState = INIT_STATE_UNINITIALIZED; - mNeedsUpdate = true; - mCanCut = false; - mCanCopy = false; - mCanPaste = false; - mLastMouseX = 0; - mLastMouseY = 0; - mFirstFocus = true; - mBackgroundR = 0.0f; - mBackgroundG = 0.0f; - mBackgroundB = 0.0f; - - mHostLanguage = "en"; // default to english - mJavascriptEnabled = true; // default to on - mPluginsEnabled = true; // default to on - mEnableMediaPluginDebugging = false; - mUserAgent = "LLPluginMedia Web Browser"; - - mElapsedTime.reset(); -} - -MediaPluginWebKit::~MediaPluginWebKit() -{ - // unhook observer - LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this ); - - // clean up - LLQtWebKit::getInstance()->reset(); - -// std::cerr << "MediaPluginWebKit destructor" << std::endl; -} - -void MediaPluginWebKit::receiveMessage(const char *message_string) -{ -// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; - LLPluginMessage message_in; - - if(message_in.parse(message_string) >= 0) - { - std::string message_class = message_in.getClass(); - std::string message_name = message_in.getName(); - if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) - { - if(message_name == "init") - { - LLPluginMessage message("base", "init_response"); - LLSD versions = LLSD::emptyMap(); - versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; - message.setValueLLSD("versions", versions); - - std::string plugin_version = "Webkit media plugin, Webkit version "; - plugin_version += LLQtWebKit::getInstance()->getVersion(); - message.setValue("plugin_version", plugin_version); - sendMessage(message); - } - else if(message_name == "idle") - { - // no response is necessary here. - F64 time = message_in.getValueReal("time"); - - // Convert time to milliseconds for update() - update((int)(time * 1000.0f)); - } - else if(message_name == "cleanup") - { - // DTOR most likely won't be called but the recent change to the way this process - // is (not) killed means we see this message and can do what we need to here. - // Note: this cleanup is ultimately what writes cookies to the disk - LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this ); - LLQtWebKit::getInstance()->reset(); - } - else if(message_name == "shm_added") - { - SharedSegmentInfo info; - info.mAddress = message_in.getValuePointer("address"); - info.mSize = (size_t)message_in.getValueS32("size"); - std::string name = message_in.getValue("name"); - -// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name -// << ", size: " << info.mSize -// << ", address: " << info.mAddress -// << std::endl; - - mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - - } - else if(message_name == "shm_remove") - { - std::string name = message_in.getValue("name"); - -// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory remove, name = " << name << std::endl; - - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - if(mPixels == iter->second.mAddress) - { - // This is the currently active pixel buffer. Make sure we stop drawing to it. - mPixels = NULL; - mTextureSegmentName.clear(); - } - mSharedSegments.erase(iter); - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; - } - - // Send the response so it can be cleaned up. - LLPluginMessage message("base", "shm_remove_response"); - message.setValue("name", name); - sendMessage(message); - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) - { - if(message_name == "set_volume") - { - F32 volume = (F32)message_in.getValueReal("volume"); - setVolume(volume); - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) - { - if(message_name == "init") - { - mTarget = message_in.getValue("target"); - - // This is the media init message -- all necessary data for initialization should have been received. - if(initBrowser()) - { - - // Plugin gets to decide the texture parameters to use. - mDepth = 4; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - message.setValueS32("default_width", 1024); - message.setValueS32("default_height", 1024); - message.setValueS32("depth", mDepth); - message.setValueU32("internalformat", GL_RGBA); - #if LL_QTWEBKIT_USES_PIXMAPS - message.setValueU32("format", GL_BGRA_EXT); // I hope this isn't system-dependant... is it? If so, we'll have to check the root window's pixel layout or something... yuck. - #else - message.setValueU32("format", GL_RGBA); - #endif // LL_QTWEBKIT_USES_PIXMAPS - message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", true); - sendMessage(message); - } - else - { - // if initialization failed, we're done. - mDeleteMe = true; - } - - } - else if(message_name == "set_user_data_path") - { - std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter - mProfileDir = user_data_path + "browser_profile"; - - // FIXME: Should we do anything with this if it comes in after the browser has been initialized? - } - else if(message_name == "set_language_code") - { - mHostLanguage = message_in.getValue("language"); - - // FIXME: Should we do anything with this if it comes in after the browser has been initialized? - } - else if(message_name == "plugins_enabled") - { - mPluginsEnabled = message_in.getValueBoolean("enable"); - } - else if(message_name == "javascript_enabled") - { - mJavascriptEnabled = message_in.getValueBoolean("enable"); - } - else if(message_name == "size_change") - { - std::string name = message_in.getValue("name"); - S32 width = message_in.getValueS32("width"); - S32 height = message_in.getValueS32("height"); - S32 texture_width = message_in.getValueS32("texture_width"); - S32 texture_height = message_in.getValueS32("texture_height"); - mBackgroundR = (F32)message_in.getValueReal("background_r"); - mBackgroundG = (F32)message_in.getValueReal("background_g"); - mBackgroundB = (F32)message_in.getValueReal("background_b"); -// mBackgroundA = message_in.setValueReal("background_a"); // Ignore any alpha - - if(!name.empty()) - { - // Find the shared memory region with this name - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - mPixels = (unsigned char*)iter->second.mAddress; - mWidth = width; - mHeight = height; - - if(initBrowserWindow()) - { - - // size changed so tell the browser - LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); - - // std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight - // << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl; - - S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId); - - // The actual width the browser will be drawing to is probably smaller... let the host know by modifying texture_width in the response. - if(real_width <= texture_width) - { - texture_width = real_width; - } - else - { - // This won't work -- it'll be bigger than the allocated memory. This is a fatal error. - // std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl; - mDeleteMe = true; - return; - } - } - else - { - // Setting up the browser window failed. This is a fatal error. - mDeleteMe = true; - } - - - mTextureWidth = texture_width; - mTextureHeight = texture_height; - - }; - }; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); - message.setValue("name", name); - message.setValueS32("width", width); - message.setValueS32("height", height); - message.setValueS32("texture_width", texture_width); - message.setValueS32("texture_height", texture_height); - sendMessage(message); - - } - else if(message_name == "load_uri") - { - std::string uri = message_in.getValue("uri"); - -// std::cout << "loading URI: " << uri << std::endl; - - if(!uri.empty()) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, uri ); - } - else - { - mInitialNavigateURL = uri; - } - } - } - else if(message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - S32 button = message_in.getValueS32("button"); - mLastMouseX = message_in.getValueS32("x"); - mLastMouseY = message_in.getValueS32("y"); - std::string modifiers = message_in.getValue("modifiers"); - - // Treat unknown mouse events as mouse-moves. - LLQtWebKit::EMouseEvent mouse_event = LLQtWebKit::ME_MOUSE_MOVE; - if(event == "down") - { - mouse_event = LLQtWebKit::ME_MOUSE_DOWN; - } - else if(event == "up") - { - mouse_event = LLQtWebKit::ME_MOUSE_UP; - } - else if(event == "double_click") - { - mouse_event = LLQtWebKit::ME_MOUSE_DOUBLE_CLICK; - } - - LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId, mouse_event, button, mLastMouseX, mLastMouseY, decodeModifiers(modifiers)); - checkEditState(); - } - else if(message_name == "scroll_event") - { - S32 x = message_in.getValueS32("x"); - S32 y = message_in.getValueS32("y"); - std::string modifiers = message_in.getValue("modifiers"); - - // Incoming scroll events are adjusted so that 1 detent is approximately 1 unit. - // Qt expects 1 detent to be 120 units. - // It also seems that our y scroll direction is inverted vs. what Qt expects. - - x *= 120; - y *= -120; - - LLQtWebKit::getInstance()->scrollWheelEvent(mBrowserWindowId, mLastMouseX, mLastMouseY, x, y, decodeModifiers(modifiers)); - } - else if(message_name == "key_event") - { - std::string event = message_in.getValue("event"); - S32 key = message_in.getValueS32("key"); - std::string modifiers = message_in.getValue("modifiers"); - LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - - // Treat unknown events as key-up for safety. - LLQtWebKit::EKeyEvent key_event = LLQtWebKit::KE_KEY_UP; - if(event == "down") - { - key_event = LLQtWebKit::KE_KEY_DOWN; - } - else if(event == "repeat") - { - key_event = LLQtWebKit::KE_KEY_REPEAT; - } - - keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); - } - else if(message_name == "text_event") - { - std::string text = message_in.getValue("text"); - std::string modifiers = message_in.getValue("modifiers"); - LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - - unicodeInput(text, decodeModifiers(modifiers), native_key_data); - } - if(message_name == "edit_cut") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT ); - checkEditState(); - } - if(message_name == "edit_copy") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY ); - checkEditState(); - } - if(message_name == "edit_paste") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE ); - checkEditState(); - } - if(message_name == "pick_file_response") - { - onPickFileResponse(message_in.getValue("file")); - } - if(message_name == "auth_response") - { - authResponse(message_in); - } - else - if(message_name == "enable_media_plugin_debugging") - { - mEnableMediaPluginDebugging = message_in.getValueBoolean( "enable" ); - } - else - if(message_name == "js_enable_object") - { -#if LLQTWEBKIT_API_VERSION >= 9 - bool enable = message_in.getValueBoolean( "enable" ); - LLQtWebKit::getInstance()->setSLObjectEnabled( enable ); -#endif - } - else - if(message_name == "js_agent_location") - { -#if LLQTWEBKIT_API_VERSION >= 9 - F32 x = (F32)message_in.getValueReal("x"); - F32 y = (F32)message_in.getValueReal("y"); - F32 z = (F32)message_in.getValueReal("z"); - LLQtWebKit::getInstance()->setAgentLocation( x, y, z ); - LLQtWebKit::getInstance()->emitLocation(); -#endif - } - else - if(message_name == "js_agent_global_location") - { -#if LLQTWEBKIT_API_VERSION >= 9 - F32 x = (F32)message_in.getValueReal("x"); - F32 y = (F32)message_in.getValueReal("y"); - F32 z = (F32)message_in.getValueReal("z"); - LLQtWebKit::getInstance()->setAgentGlobalLocation( x, y, z ); - LLQtWebKit::getInstance()->emitLocation(); -#endif - } - else - if(message_name == "js_agent_orientation") - { -#if LLQTWEBKIT_API_VERSION >= 9 - F32 angle = (F32)message_in.getValueReal("angle"); - LLQtWebKit::getInstance()->setAgentOrientation( angle ); - LLQtWebKit::getInstance()->emitLocation(); -#endif - } - else - if(message_name == "js_agent_region") - { -#if LLQTWEBKIT_API_VERSION >= 9 - const std::string& region = message_in.getValue("region"); - LLQtWebKit::getInstance()->setAgentRegion( region ); - LLQtWebKit::getInstance()->emitLocation(); -#endif - } - else - if(message_name == "js_agent_maturity") - { -#if LLQTWEBKIT_API_VERSION >= 9 - const std::string& maturity = message_in.getValue("maturity"); - LLQtWebKit::getInstance()->setAgentMaturity( maturity ); - LLQtWebKit::getInstance()->emitMaturity(); -#endif - } - else - if(message_name == "js_agent_language") - { -#if LLQTWEBKIT_API_VERSION >= 9 - const std::string& language = message_in.getValue("language"); - LLQtWebKit::getInstance()->setAgentLanguage( language ); - LLQtWebKit::getInstance()->emitLanguage(); -#endif - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl; - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) - { - if(message_name == "focus") - { - bool val = message_in.getValueBoolean("focused"); - LLQtWebKit::getInstance()->focusBrowser( mBrowserWindowId, val ); - - if(mFirstFocus && val) - { - // On the first focus, post a tab key event. This fixes a problem with initial focus. - std::string empty; - keyEvent(LLQtWebKit::KE_KEY_DOWN, KEY_TAB, decodeModifiers(empty)); - keyEvent(LLQtWebKit::KE_KEY_UP, KEY_TAB, decodeModifiers(empty)); - mFirstFocus = false; - } - } - else if(message_name == "set_page_zoom_factor") - { -#if LLQTWEBKIT_API_VERSION >= 15 - F32 factor = (F32)message_in.getValueReal("factor"); - LLQtWebKit::getInstance()->setPageZoomFactor(factor); -#else - LL_WARNS() << "Ignoring setPageZoomFactor message (llqtwebkit version is too old)." << LL_ENDL; -#endif - } - else if(message_name == "clear_cache") - { - LLQtWebKit::getInstance()->clearCache(); - } - else if(message_name == "clear_cookies") - { - LLQtWebKit::getInstance()->clearAllCookies(); - } - else if(message_name == "enable_cookies") - { - mCookiesEnabled = message_in.getValueBoolean("enable"); - LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled ); - } - else if(message_name == "enable_plugins") - { - mPluginsEnabled = message_in.getValueBoolean("enable"); - LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled ); - } - else if(message_name == "enable_javascript") - { - mJavascriptEnabled = message_in.getValueBoolean("enable"); - //LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled ); - } - else if(message_name == "set_cookies") - { - LLQtWebKit::getInstance()->setCookies(message_in.getValue("cookies")); - - // debug spam - postDebugMessage( "Plugin setting cookie: " + message_in.getValue("cookies") ); - } - else if(message_name == "proxy_setup") - { - bool val = message_in.getValueBoolean("enable"); - std::string host = message_in.getValue("host"); - int port = message_in.getValueS32("port"); - LLQtWebKit::getInstance()->enableProxy( val, host, port ); - } - else if(message_name == "browse_stop") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_STOP ); - } - else if(message_name == "browse_reload") - { - // foo = message_in.getValueBoolean("ignore_cache"); - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_RELOAD ); - } - else if(message_name == "browse_forward") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD ); - } - else if(message_name == "browse_back") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK ); - } - else if(message_name == "set_status_redirect") - { - int code = message_in.getValueS32("code"); - std::string url = message_in.getValue("url"); - if ( 404 == code ) // browser lib only supports 404 right now - { -#if LLQTWEBKIT_API_VERSION < 8 - LLQtWebKit::getInstance()->set404RedirectUrl( mBrowserWindowId, url ); -#endif - }; - } - else if(message_name == "set_user_agent") - { - mUserAgent = message_in.getValue("user_agent"); - LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); - } - else if(message_name == "show_web_inspector") - { -#if LLQTWEBKIT_API_VERSION >= 10 - bool val = message_in.getValueBoolean("show"); - LLQtWebKit::getInstance()->showWebInspector( val ); -#else - LL_WARNS() << "Ignoring showWebInspector message (llqtwebkit version is too old)." << LL_ENDL; -#endif - } - else if(message_name == "ignore_ssl_cert_errors") - { -#if LLQTWEBKIT_API_VERSION >= 3 - LLQtWebKit::getInstance()->setIgnoreSSLCertErrors( message_in.getValueBoolean("ignore") ); -#else - LL_WARNS() << "Ignoring ignore_ssl_cert_errors message (llqtwebkit version is too old)." << LL_ENDL; -#endif - } - else if(message_name == "add_certificate_file_path") - { -#if LLQTWEBKIT_API_VERSION >= 6 - LLQtWebKit::getInstance()->setCAFile( message_in.getValue("path") ); -#else - LL_WARNS() << "Ignoring add_certificate_file_path message (llqtwebkit version is too old)." << LL_ENDL; -#endif - } - else if(message_name == "init_history") - { - // Initialize browser history - LLSD history = message_in.getValueLLSD("history"); - // First, clear the URL history - LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId); - // Then, add the history items in order - LLSD::array_iterator iter_history = history.beginArray(); - LLSD::array_iterator end_history = history.endArray(); - for(; iter_history != end_history; ++iter_history) - { - std::string url = (*iter_history).asString(); - if(! url.empty()) { - LLQtWebKit::getInstance()->prependHistoryUrl(mBrowserWindowId, url); - } - } - } - else if(message_name == "proxy_window_opened") - { - std::string target = message_in.getValue("target"); - std::string uuid = message_in.getValue("uuid"); - LLQtWebKit::getInstance()->proxyWindowOpened(mBrowserWindowId, target, uuid); - } - else if(message_name == "proxy_window_closed") - { - std::string uuid = message_in.getValue("uuid"); - LLQtWebKit::getInstance()->proxyWindowClosed(mBrowserWindowId, uuid); - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl; - }; - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; - }; - } -} - -void MediaPluginWebKit::setVolume(F32 volume) -{ - mVolumeCatcher.setVolume(volume); -} - -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) -{ - MediaPluginWebKit *self = new MediaPluginWebKit(host_send_func, host_user_data); - *plugin_send_func = MediaPluginWebKit::staticReceiveMessage; - *plugin_user_data = (void*)self; - - return 0; -} - - diff --git a/indra/media_plugins/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 -#include "llsingleton.h" -class VolumeCatcherImpl : public LLSingleton -{ -friend LLSingleton; -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 @@ -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 $) -add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_SLPLUGIN} -) - -set(BUILT_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 $) -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 $) -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 -#include -#include -#include - -#include "llfbconnecttest.h" - -#if __APPLE__ - #include - #include -#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(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(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: , 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 /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 -#include -#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 $) -add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_SLPLUGIN} -) - -set(BUILT_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 $) -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 $) - 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 $) -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 $) -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 -#include -#include -#include - -#include "llmediaplugintest.h" - - -#if LL_WINDOWS -#pragma warning(disable: 4263) -#pragma warning(disable: 4264) -#endif - -#if __APPLE__ - #include - #include -#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(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(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: , 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 /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 -#include -#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 d68721d2533bcc5f88a43980530d0c324356c473 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 2 Oct 2015 12:06:45 -0700 Subject: Point to latest LLCEFLib package ready for PV --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index cb33e23c52..7aad200bcb 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 8655aa7c3ad64bc1a333bd159e604a38 + d4699b948951903c7657389f12fb5637 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305626/arch/Darwin/installer/llceflib-1.1.0.305626-darwin-305626.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305639/arch/Darwin/installer/llceflib-1.2.0.305639-darwin-305639.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 246e4f3a5e2852233a728771bca45bf4 + a7b4a0c8c1a756f41b152d7ba6101179 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305626/arch/CYGWIN/installer/llceflib-1.1.0.305626-windows-305626.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305639/arch/CYGWIN/installer/llceflib-1.2.0.305639-windows-305639.tar.bz2 name windows version - 1.1.0.305626 + 1.2.0.305639 llphysicsextensions_source -- cgit v1.2.3 From 2fc42c1221393161fcd882b6bb73a7a6da9d07e2 Mon Sep 17 00:00:00 2001 From: Rider Linden 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(-) 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 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(+) 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 0725bd2d5eddee94e9adc64b83f4c457b9cac725 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 7 Oct 2015 14:45:11 -0700 Subject: Point to new version of LLCEFLib that doesn't crash on OS X --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 7aad200bcb..cf6f0c8d6b 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - d4699b948951903c7657389f12fb5637 + fe44151af823734c3fdfedce9a91fa49 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305639/arch/Darwin/installer/llceflib-1.2.0.305639-darwin-305639.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305753/arch/Darwin/installer/llceflib-1.2.0.305753-darwin-305753.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - a7b4a0c8c1a756f41b152d7ba6101179 + 72dd692c7ee372ba67117ec2c37d69a9 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305639/arch/CYGWIN/installer/llceflib-1.2.0.305639-windows-305639.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305753/arch/CYGWIN/installer/llceflib-1.2.0.305753-windows-305753.tar.bz2 name windows version - 1.2.0.305639 + 1.2.0.305753 llphysicsextensions_source -- cgit v1.2.3 From 295d392b1c1ed6182eb2dce528fd396eab2ed2b2 Mon Sep 17 00:00:00 2001 From: Rider Linden 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 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 +#include +#include + +#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 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::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 +#include "llsingleton.h" +class VolumeCatcherImpl : public LLSingleton +{ +friend LLSingleton; +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 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(-) 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 Date: Mon, 19 Oct 2015 18:43:48 -0700 Subject: MAINT-5711 FIX profiles and marketplace are asking for a login each session --- autobuild.xml | 10 +++---- 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 + 6 files changed, 71 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index cf6f0c8d6b..e6f1bb11aa 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - fe44151af823734c3fdfedce9a91fa49 + e1c24780a5ee341fc38b860f27827df5 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305753/arch/Darwin/installer/llceflib-1.2.0.305753-darwin-305753.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/306266/arch/Darwin/installer/llceflib-1.2.0.306266-darwin-306266.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 72dd692c7ee372ba67117ec2c37d69a9 + ab90c7250d2b0859f2094c113101277b hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/305753/arch/CYGWIN/installer/llceflib-1.2.0.305753-windows-305753.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/306266/arch/CYGWIN/installer/llceflib-1.2.0.306266-windows-306266.tar.bz2 name windows version - 1.2.0.305753 + 1.2.0.306266 llphysicsextensions_source 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("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 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(-) 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("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("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 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(-) 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 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(-) 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 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: // /browser_profile/cookies // /first_last/browser_profile/cookies (note that there may be any number of these!) // /first_last/plugin_cookies.txt (note that there may be any number of these!) - + std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter(); std::string target; std::string filename; - + LL_DEBUGS() << "base dir = " << base_dir << LL_ENDL; // The non-logged-in version is easy @@ -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("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("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 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 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(-) 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 7d8909a670c4c7e4c72f5cc423354d737f4841cc Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 22 Oct 2015 18:28:57 -0700 Subject: Pull in LLCEFLib changes for OS X cookies (partial) and local web storage quotas --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index e6f1bb11aa..28973dbe54 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - e1c24780a5ee341fc38b860f27827df5 + 594967d448010267ca5023e2dc9ee934 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/306266/arch/Darwin/installer/llceflib-1.2.0.306266-darwin-306266.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/306495/arch/Darwin/installer/llceflib-1.2.0.306495-darwin-306495.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - ab90c7250d2b0859f2094c113101277b + 010aef659d02dbba158ebd869a8e71b4 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/306266/arch/CYGWIN/installer/llceflib-1.2.0.306266-windows-306266.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/306495/arch/CYGWIN/installer/llceflib-1.2.0.306495-windows-306495.tar.bz2 name windows version - 1.2.0.306266 + 1.2.0.306495 llphysicsextensions_source -- cgit v1.2.3 From 9833a50260fb45d5f0033200ae756834c0cc9940 Mon Sep 17 00:00:00 2001 From: Rider Linden 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(-) 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 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(-) 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 8b8331feab2538ef2fdfea5bb13311e6d9b61384 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 6 Nov 2015 16:55:30 -0800 Subject: Pull in LLCEFLib with working OS X cookies and tweak keyboard code to build - needs some love to work... --- autobuild.xml | 10 +++++----- indra/media_plugins/cef/media_plugin_cef.cpp | 25 +++++++++++++++---------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 28973dbe54..3a614de45e 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 594967d448010267ca5023e2dc9ee934 + f222975b084f8ef74b91fcca0c3ef922 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/306495/arch/Darwin/installer/llceflib-1.2.0.306495-darwin-306495.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307407/arch/Darwin/installer/llceflib-1.3.1.307407-darwin-307407.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 010aef659d02dbba158ebd869a8e71b4 + f7a3525643066a80fa085d52844e7466 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/306495/arch/CYGWIN/installer/llceflib-1.2.0.306495-windows-306495.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307407/arch/CYGWIN/installer/llceflib-1.3.1.307407-windows-307407.tar.bz2 name windows version - 1.2.0.306495 + 1.3.1.307407 llphysicsextensions_source diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index d653aaace9..75e1055d2d 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("y"); 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") { @@ -576,9 +577,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { 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"); @@ -730,15 +731,15 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib:: 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; } - + switch ((KEY)key) - + { case KEY_BACKSPACE: utf8_text = (char)8; break; case KEY_TAB: utf8_text = (char)9; break; @@ -750,12 +751,16 @@ 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(), 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 }; -- cgit v1.2.3 From 5449ae73b337c026afa93e99a47b670c28c8eb80 Mon Sep 17 00:00:00 2001 From: rider 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(-) 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(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 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(-) 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 9cc97a096f71ecfd934f1a74b0c07dbbedeecef4 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Mon, 9 Nov 2015 13:48:01 -0800 Subject: pull in new LLCEFLib code with fix for OS X keyboard --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 3a614de45e..7af52eea82 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - f222975b084f8ef74b91fcca0c3ef922 + 7fb5595afb2396aec2edc676e5621544 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307407/arch/Darwin/installer/llceflib-1.3.1.307407-darwin-307407.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307532/arch/Darwin/installer/llceflib-1.3.1.307532-darwin-307532.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - f7a3525643066a80fa085d52844e7466 + 2b2bf3b2628b4412b37df8bf02776796 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307407/arch/CYGWIN/installer/llceflib-1.3.1.307407-windows-307407.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307532/arch/CYGWIN/installer/llceflib-1.3.1.307532-windows-307532.tar.bz2 name windows version - 1.3.1.307407 + 1.3.1.307532 llphysicsextensions_source -- cgit v1.2.3 From abc9df45dae46e7372e8beb840a1294e5a64a94d Mon Sep 17 00:00:00 2001 From: callum_linden 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(-) 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 @@ Type Boolean Value - 1 + 0 ChatBarCustomWidth -- cgit v1.2.3 From 059925eafb66dc0e2d8ef9c113ca8980a34c655d Mon Sep 17 00:00:00 2001 From: Rider Linden 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(-) 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 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::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::iterator iter; + mapInstances_t::iterator iter; int count = 0; // Count the number of instances that want to be in the pollset for(iter = sInstances.begin(); iter != sInstances.end(); iter++) { - (*iter)->mPolledInput = false; - if((*iter)->mPollFD.client_data) + (*iter).second->mPolledInput = false; + if ((*iter).second->wantsPolling()) { // This instance has a socket that needs to be polled. ++count; @@ -686,12 +778,12 @@ void LLPluginProcessParent::updatePollset() // Pollset was created, add all instances to it. for(iter = sInstances.begin(); iter != sInstances.end(); iter++) { - if((*iter)->mPollFD.client_data) + if ((*iter).second->wantsPolling()) { - status = apr_pollset_add(sPollSet, &((*iter)->mPollFD)); + status = apr_pollset_add(sPollSet, &((*iter).second->mPollFD)); if(status == APR_SUCCESS) { - (*iter)->mPolledInput = true; + (*iter).second->mPolledInput = true; } else { @@ -756,45 +848,27 @@ void LLPluginProcessParent::poll(F64 timeout) if(status == APR_SUCCESS) { // One or more of the descriptors signalled. Call them. - for(int i = 0; i < count; i++) - { - LLPluginProcessParent *self = (LLPluginProcessParent *)(descriptors[i].client_data); - // NOTE: the descriptor returned here is actually a COPY of the original (even though we create the pollset with APR_POLLSET_NOCOPY). - // This means that even if the parent has set its mPollFD.client_data to NULL, the old pointer may still there in this descriptor. - // It's even possible that the old pointer no longer points to a valid LLPluginProcessParent. - // This means that we can't safely dereference the 'self' pointer here without some extra steps... - if(self) - { - // Make sure this pointer is still in the instances list - bool valid = false; - { - LLMutexLock lock(sInstancesMutex); - for(std::list::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) - { - if(*iter == self) - { - // Lock the instance's mutex before unlocking the global mutex. - // This avoids a possible race condition where the instance gets deleted between this check and the servicePoll() call. - self->mIncomingQueueMutex.lock(); - valid = true; - break; - } - } - } - - if(valid) - { - // The instance is still valid. - // Pull incoming messages off the socket - self->servicePoll(); - self->mIncomingQueueMutex.unlock(); - } - else - { - LL_DEBUGS("PluginPoll") << "detected deleted instance " << self << LL_ENDL; - } + for (int i = 0; i < count; i++) + { + void *thatId = descriptors[i].client_data; + + ptr_t that; + mapInstances_t::iterator it; + + { + LLMutexLock lock(sInstancesMutex); + it = sInstances.find(thatId); + if (it != sInstances.end()) + that = (*it).second; + } + + if (that) + { + that->mIncomingQueueMutex.lock(); + that->servicePoll(); + that->mIncomingQueueMutex.unlock(); + } - } } } else if(APR_STATUS_IS_TIMEUP(status)) @@ -812,6 +886,16 @@ void LLPluginProcessParent::poll(F64 timeout) LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << LL_ENDL; } } + + // Remove instances in the done state from the sInstances map. + mapInstances_t::iterator itClean = sInstances.begin(); + while (itClean != sInstances.end()) + { + if ((*itClean).second->isDone()) + sInstances.erase(itClean++); + else + ++itClean; + } } void LLPluginProcessParent::servicePoll() diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index 24be7eb148..df1630255c 100755 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -30,6 +30,7 @@ #define LL_LLPLUGINPROCESSPARENT_H #include +#include #include "llapr.h" #include "llprocess.h" @@ -40,8 +41,9 @@ #include "lliosocket.h" #include "llthread.h" #include "llsd.h" +#include "llevents.h" -class LLPluginProcessParentOwner +class LLPluginProcessParentOwner : public boost::enable_shared_from_this < LLPluginProcessParentOwner > { public: virtual ~LLPluginProcessParentOwner(); @@ -55,8 +57,11 @@ public: class LLPluginProcessParent : public LLPluginMessagePipeOwner { LOG_CLASS(LLPluginProcessParent); + + LLPluginProcessParent(LLPluginProcessParentOwner *owner); public: - LLPluginProcessParent(LLPluginProcessParentOwner *owner); + typedef boost::shared_ptr ptr_t; + ~LLPluginProcessParent(); void init(const std::string &launcher_filename, @@ -89,7 +94,10 @@ public: void sendMessage(const LLPluginMessage &message); void receiveMessage(const LLPluginMessage &message); - + + static ptr_t create(LLPluginProcessParentOwner *owner); + void requestShutdown(); + // Inherited from LLPluginMessagePipeOwner /*virtual*/ void receiveMessageRaw(const std::string &message); /*virtual*/ void receiveMessageEarly(const LLPluginMessage &message); @@ -121,7 +129,10 @@ public: static bool canPollThreadRun() { return (sPollSet || sPollsetNeedsRebuild || sUseReadThread); }; static void setUseReadThread(bool use_read_thread); static bool getUseReadThread() { return sUseReadThread; }; + + static void shutdown(); private: + typedef std::map mapInstances_t; enum EState { @@ -133,6 +144,7 @@ private: STATE_HELLO, // first message from the plugin process has been received STATE_LOADING, // process has been asked to load the plugin STATE_RUNNING, // + STATE_GOODBYE, STATE_LAUNCH_FAILURE, // Failure before plugin loaded STATE_ERROR, // generic bailout state STATE_CLEANUP, // clean everything up @@ -143,6 +155,9 @@ private: EState mState; void setState(EState state); + bool wantsPolling() const; + void removeFromProcessing(); + bool pluginLockedUp(); bool pluginLockedUpOrQuit(); @@ -185,12 +200,15 @@ private: static apr_pollset_t *sPollSet; static bool sPollsetNeedsRebuild; static LLMutex *sInstancesMutex; - static std::list sInstances; + static mapInstances_t sInstances; static void dirtyPollSet(); static void updatePollset(); void servicePoll(); static LLThread *sReadThread; - + + LLTempBoundListener mPolling; + bool pollTick(); + LLMutex mIncomingQueueMutex; std::queue mIncomingQueue; }; diff --git a/indra/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 #include "../test/lltut.h" -- cgit v1.2.3 From 148de7ceeb1acd6fe76f0986812e32d2488202b7 Mon Sep 17 00:00:00 2001 From: Rider Linden 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(+) 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 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(-) 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 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(-) 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 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(-) 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 9efd3c61333384307f5b1d14957ac3c664317391 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 12 Nov 2015 22:04:45 +0000 Subject: Bump LLCEFLib version number and pull in 3P package in preparation for RC --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 7af52eea82..eb83c3707c 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 7fb5595afb2396aec2edc676e5621544 + 3a4f392de89520729301495d03f374bd hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307532/arch/Darwin/installer/llceflib-1.3.1.307532-darwin-307532.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307762/arch/Darwin/installer/llceflib-1.4.0.307762-darwin-307762.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 2b2bf3b2628b4412b37df8bf02776796 + 5a93e18390edfb8bba783e4a0c6c48a0 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307532/arch/CYGWIN/installer/llceflib-1.3.1.307532-windows-307532.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307762/arch/CYGWIN/installer/llceflib-1.4.0.307762-windows-307762.tar.bz2 name windows version - 1.3.1.307532 + 1.4.0.307762 llphysicsextensions_source -- cgit v1.2.3 From 2091813119fbe915ad1427ad51202e67ff086180 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 13 Nov 2015 09:34:22 -0800 Subject: Pull in new LLCEFLib with improved OS X keyboard handling --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index eb83c3707c..98978ef06c 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 3a4f392de89520729301495d03f374bd + 2d45b5e3157984fc38d9c57c0dacf89f hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307762/arch/Darwin/installer/llceflib-1.4.0.307762-darwin-307762.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307799/arch/Darwin/installer/llceflib-1.4.0.307799-darwin-307799.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 5a93e18390edfb8bba783e4a0c6c48a0 + aa27060c311bf6e9e0f86fa5c5b25129 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307762/arch/CYGWIN/installer/llceflib-1.4.0.307762-windows-307762.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307799/arch/CYGWIN/installer/llceflib-1.4.0.307799-windows-307799.tar.bz2 name windows version - 1.4.0.307762 + 1.4.0.307799 llphysicsextensions_source -- cgit v1.2.3 From ec55f2cd10db838140b34b04717e9e50a6b736ce Mon Sep 17 00:00:00 2001 From: callum_linden 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(-) 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("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("tos_html"); if ( web_browser ) { +// if we are forced to send users to an external site in their system browser +// (e.g.) Linux users because of lack of media support for HTML ToS page +// remove exisiting UI and replace with a link to external page where users can accept ToS +#ifdef EXTERNAL_TOS + LLTextBox* header = getChild("tos_heading"); + if (header) + header->setVisible(false); + + LLTextBox* external_prompt = getChild("external_tos_required"); + if (external_prompt) + external_prompt->setVisible(true); + + web_browser->setVisible(false); +#else web_browser->addObserver(this); // Don't use the start_url parameter for this browser instance -- it may finish loading before we get to add our observer. @@ -147,6 +160,7 @@ BOOL LLFloaterTOS::postBuild() // All links from tos_html should be opened in external browser media_plugin->setOverrideClickTarget("_external"); } +#endif } return TRUE; @@ -154,6 +168,13 @@ BOOL LLFloaterTOS::postBuild() void LLFloaterTOS::setSiteIsAlive( bool alive ) { +// if we are forced to send users to an external site in their system browser +// (e.g.) Linux users because of lack of media support for HTML ToS page +// force the regular HTML UI to deactivate so alternative is rendered instead. +#ifdef EXTERNAL_TOS + mSiteAlive = false; +#else + mSiteAlive = alive; // only do this for TOS pages @@ -182,6 +203,7 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) tos_agreement->setEnabled( true ); } } +#endif } LLFloaterTOS::~LLFloaterTOS() diff --git a/indra/newview/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. + + 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]. + 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(-) 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(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger()); + char eventUChars = static_cast(native_key_data["event_umodchars"].isUndefined() ? 0 : native_key_data["event_umodchars"].asInteger()); + bool eventIsRepeat = native_key_data["event_isrepeat"].asBoolean(); - mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(), - static_cast(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 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(+) 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 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(+) 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("state_management_buttons_container"); -- cgit v1.2.3 From 311b376ab50bacf2bf113616af2a5bbedfcd5ee5 Mon Sep 17 00:00:00 2001 From: callum_linden 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) --- autobuild.xml | 10 +++++----- 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 +- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 98978ef06c..c140159999 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 2d45b5e3157984fc38d9c57c0dacf89f + db32cc2c0d898d69d01ef61df81424e8 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307799/arch/Darwin/installer/llceflib-1.4.0.307799-darwin-307799.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307893/arch/Darwin/installer/llceflib-1.4.0.307893-darwin-307893.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - aa27060c311bf6e9e0f86fa5c5b25129 + 3c7f10479a6c4e0910df91b195be393f hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307799/arch/CYGWIN/installer/llceflib-1.4.0.307799-windows-307799.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307893/arch/CYGWIN/installer/llceflib-1.4.0.307893-windows-307893.tar.bz2 name windows version - 1.4.0.307799 + 1.4.0.307893 llphysicsextensions_source 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 Date: Wed, 18 Nov 2015 18:17:50 -0800 Subject: initial support for dropdown menus/select widgits --- autobuild.xml | 10 +++++----- indra/media_plugins/cef/media_plugin_cef.cpp | 28 +++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index c140159999..a62f75a0c1 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - db32cc2c0d898d69d01ef61df81424e8 + e632f94b6f94a9563ccdfca6da38fb27 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307893/arch/Darwin/installer/llceflib-1.4.0.307893-darwin-307893.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308049/arch/Darwin/installer/llceflib-1.4.0.308049-darwin-308049.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 3c7f10479a6c4e0910df91b195be393f + 41454f05cea1149d5124d28fc3db6ae0 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/307893/arch/CYGWIN/installer/llceflib-1.4.0.307893-windows-307893.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308049/arch/CYGWIN/installer/llceflib-1.4.0.308049-windows-308049.tar.bz2 name windows version - 1.4.0.307893 + 1.4.0.308049 llphysicsextensions_source 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 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(-) 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 @@ Type F32 Value - 5.0 + 10.0 MediaRollOffMax -- cgit v1.2.3 From f2a6e0f89c45e06742204efd92acc494bb14d9bd Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 19 Nov 2015 16:39:40 -0800 Subject: Fix javascript_enabled && plugins_enabled (wrong media class) and pull in new LLCEFLib --- autobuild.xml | 10 +++++----- indra/llplugin/llpluginclassmedia.cpp | 4 ++-- indra/media_plugins/cef/media_plugin_cef.cpp | 7 ++----- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index a62f75a0c1..dc002f1080 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - e632f94b6f94a9563ccdfca6da38fb27 + d2a2221741c31c28ec28e974b035099c hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308049/arch/Darwin/installer/llceflib-1.4.0.308049-darwin-308049.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308076/arch/Darwin/installer/llceflib-1.4.0.308076-darwin-308076.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 41454f05cea1149d5124d28fc3db6ae0 + 8e4a649ecc7ba1f39b5d54fed935ac14 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308049/arch/CYGWIN/installer/llceflib-1.4.0.308049-windows-308049.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308076/arch/CYGWIN/installer/llceflib-1.4.0.308076-windows-308076.tar.bz2 name windows version - 1.4.0.308049 + 1.4.0.308076 llphysicsextensions_source 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 Date: Fri, 20 Nov 2015 17:34:46 -0800 Subject: pull in llceflib changes for user agent, flash plugins and pdf --- autobuild.xml | 10 +++++----- indra/media_plugins/cef/media_plugin_cef.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index dc002f1080..4d77a74c5b 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - d2a2221741c31c28ec28e974b035099c + a58244a2348197aec11ac9f3dcf5c2ff hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308076/arch/Darwin/installer/llceflib-1.4.0.308076-darwin-308076.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308140/arch/Darwin/installer/llceflib-1.4.0.308140-darwin-308140.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 8e4a649ecc7ba1f39b5d54fed935ac14 + 880970d9fa0da5922044de5716d59043 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308076/arch/CYGWIN/installer/llceflib-1.4.0.308076-windows-308076.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308140/arch/CYGWIN/installer/llceflib-1.4.0.308140-windows-308140.tar.bz2 name windows version - 1.4.0.308076 + 1.4.0.308140 llphysicsextensions_source 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 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 --- autobuild.xml | 10 +++++----- indra/media_plugins/cef/media_plugin_cef.cpp | 12 +++++------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 4d77a74c5b..dfa1e36457 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - a58244a2348197aec11ac9f3dcf5c2ff + bcc015c5943397b612da1cdc29df4340 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308140/arch/Darwin/installer/llceflib-1.4.0.308140-darwin-308140.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308183/arch/Darwin/installer/llceflib-1.4.0.308183-darwin-308183.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 880970d9fa0da5922044de5716d59043 + 77d35679760ba467a90ca07b60877376 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308140/arch/CYGWIN/installer/llceflib-1.4.0.308140-windows-308140.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308183/arch/CYGWIN/installer/llceflib-1.4.0.308183-windows-308183.tar.bz2 name windows version - 1.4.0.308140 + 1.4.0.308183 llphysicsextensions_source 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 b5c4565c62433d603a673d94f691c687ac907c7d Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 25 Nov 2015 15:33:05 -0500 Subject: MAINT-5901: Make avatar auto pilot work correctly through transparent objects --- indra/newview/lltoolpie.cpp | 86 ++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 2081297717..60a7d284ef 100755 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -106,7 +106,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) mMouseDownX = x; mMouseDownY = y; - //left mouse down always picks transparent + //left mouse down always picks transparent (but see handleMouseUp) mPick = gViewerWindow->pickImmediate(x, y, TRUE); mPick.mKeyMask = mask; @@ -661,30 +661,52 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask) && gAgentAvatarp && !gAgentAvatarp->isSitting() && !mBlockClickToWalk // another behavior hasn't cancelled click to walk - && !mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick - && (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land - || mPick.mObjectID.notNull())) // or on an object - { - // handle special cases of steering picks - LLViewerObject* avatar_object = mPick.getObject(); - - // get pointer to avatar - while (avatar_object && !avatar_object->isAvatar()) - { - avatar_object = (LLViewerObject*)avatar_object->getParent(); - } - - if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf()) - { - const F64 SELF_CLICK_WALK_DISTANCE = 3.0; - // pretend we picked some point a bit in front of avatar - mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE; - } - gAgentCamera.setFocusOnAvatar(TRUE, TRUE); - walkToClickedLocation(); - LLFirstUse::notMoving(false); - - return TRUE; + ) + { + // We may be doing click to walk, but we don't want to use a target on + // a transparent object because the user thought they were clicking on + // whatever they were seeing through it, so recompute what was clicked on + // ignoring transparent objects + LLPickInfo savedPick = mPick; + mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY, + FALSE /* ignore transparent */, + FALSE /* ignore particles */); + + if (!mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick + && (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land + || mPick.mObjectID.notNull())) // or on an object + { + // handle special cases of steering picks + LLViewerObject* avatar_object = mPick.getObject(); + + // get pointer to avatar + while (avatar_object && !avatar_object->isAvatar()) + { + avatar_object = (LLViewerObject*)avatar_object->getParent(); + } + + if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf()) + { + const F64 SELF_CLICK_WALK_DISTANCE = 3.0; + // pretend we picked some point a bit in front of avatar + mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE; + } + gAgentCamera.setFocusOnAvatar(TRUE, TRUE); + walkToClickedLocation(); + LLFirstUse::notMoving(false); + + return TRUE; + } + else + { + LL_DEBUGS("maint5901") << "walk target was " + << (mPick.mPosGlobal.isExactlyZero() ? "zero" : "not zero") + << ", pick type was " << (mPick.mPickType == LLPickInfo::PICK_LAND ? "land" : "not land") + << ", pick object was " << mPick.mObjectID + << LL_ENDL; + // we didn't click to walk, so restore the original target + mPick = savedPick; + } } gViewerWindow->setCursor(UI_CURSOR_ARROW); if (hasMouseCapture()) @@ -718,12 +740,26 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask) if (gSavedSettings.getBOOL("DoubleClickAutoPilot")) { + // We may be doing double click to walk, but we don't want to use a target on + // a transparent object because the user thought they were clicking on + // whatever they were seeing through it, so recompute what was clicked on + // ignoring transparent objects + LLPickInfo savedPick = mPick; + mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY, + FALSE /* ignore transparent */, + FALSE /* ignore particles */); + if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) || (mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero())) { walkToClickedLocation(); return TRUE; } + else + { + // restore the original pick for any other purpose + mPick = savedPick; + } } else if (gSavedSettings.getBOOL("DoubleClickTeleport")) { -- cgit v1.2.3 From 76821ac8c83ffc5ad00f37ad884c4e272830e197 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 30 Nov 2015 17:14:15 -0800 Subject: Point to new LLCEFLib built against autobuild install version of boost - no functional changes --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index dfa1e36457..8b217bf800 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - bcc015c5943397b612da1cdc29df4340 + 745fc3299d4c0e011fc294a3f7c23982 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308183/arch/Darwin/installer/llceflib-1.4.0.308183-darwin-308183.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308429/arch/Darwin/installer/llceflib-1.4.0.308429-darwin-308429.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 77d35679760ba467a90ca07b60877376 + b7530e755306d645f8743fa37dfdbd5b hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308183/arch/CYGWIN/installer/llceflib-1.4.0.308183-windows-308183.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308429/arch/CYGWIN/installer/llceflib-1.4.0.308429-windows-308429.tar.bz2 name windows version - 1.4.0.308183 + 1.4.0.308429 llphysicsextensions_source -- cgit v1.2.3 From 8f147c1551ddc8ba0f58664a9e83ed73d5e98064 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 1 Dec 2015 12:56:39 -0800 Subject: Fix the MD5 for CEF lib in autobuild --- autobuild.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 8b217bf800..a141eaa49a 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,7 +1536,7 @@ archive hash - 745fc3299d4c0e011fc294a3f7c23982 + 4858378399cca5a1bd2cd51944b047df hash_algorithm md5 url @@ -1550,7 +1550,7 @@ archive hash - b7530e755306d645f8743fa37dfdbd5b + 3c909642aa61dd014b34a09ee8baa16a hash_algorithm md5 url -- cgit v1.2.3 From 43b7928c680ec5803d793a4f27ece21b6992b590 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 1 Dec 2015 15:42:01 -0800 Subject: Point to fix in LLCEFLib for MAINT-5911 Pressing return (or enter) no longer performs a search --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index a141eaa49a..b7b9d121d3 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 4858378399cca5a1bd2cd51944b047df + 86b603069d9cde982afabc8adcad547e hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308429/arch/Darwin/installer/llceflib-1.4.0.308429-darwin-308429.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308479/arch/Darwin/installer/llceflib-1.4.0.308479-darwin-308479.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 3c909642aa61dd014b34a09ee8baa16a + 98c38df27bde123bf42324d00db60ddf hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308429/arch/CYGWIN/installer/llceflib-1.4.0.308429-windows-308429.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308479/arch/CYGWIN/installer/llceflib-1.4.0.308479-windows-308479.tar.bz2 name windows version - 1.4.0.308429 + 1.4.0.308479 llphysicsextensions_source -- cgit v1.2.3 From eb484d5051c48e3bd35a2f06915eb75cf5c8c1fc Mon Sep 17 00:00:00 2001 From: rider 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(-) 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(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger()); char eventUChars = static_cast(native_key_data["event_umodchars"].isUndefined() ? 0 : native_key_data["event_umodchars"].asInteger()); bool eventIsRepeat = native_key_data["event_isrepeat"].asBoolean(); - mLLCEFLib->keyboardEventOSX(eventType, eventModifiers, (eventChars) ? &eventChars : NULL, (eventUChars) ? &eventUChars : NULL, eventIsRepeat, eventKeycode); - + #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); @@ -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 d795dfa6ec872ff67384da4837dfe3c2b5e0a4e6 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 4 Dec 2015 08:52:05 -0800 Subject: Pull in new LLCEFLib with @rider's fixes for ENTER and Japanese text entry --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b7b9d121d3..6749d489e5 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 86b603069d9cde982afabc8adcad547e + a78ea1cebcc73147f26970ebbfee5e44 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308479/arch/Darwin/installer/llceflib-1.4.0.308479-darwin-308479.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308620/arch/Darwin/installer/llceflib-1.4.0.308620-darwin-308620.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 98c38df27bde123bf42324d00db60ddf + c23c942b0d207221c6bf0c9b9a46a615 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308479/arch/CYGWIN/installer/llceflib-1.4.0.308479-windows-308479.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308620/arch/CYGWIN/installer/llceflib-1.4.0.308620-windows-308620.tar.bz2 name windows version - 1.4.0.308479 + 1.4.0.308620 llphysicsextensions_source -- cgit v1.2.3 From c3877be95468b3c26157cc98e9d40e264645a883 Mon Sep 17 00:00:00 2001 From: callum_linden 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(-) 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 @@ F32 Value 60 - + AvatarRotateThresholdFast Comment @@ -745,7 +745,7 @@ F32 Value 2 - + AvatarBakedTextureUploadTimeout Comment @@ -1339,7 +1339,7 @@ String Value - + CacheNumberOfRegionsForObjects Comment @@ -2005,7 +2005,7 @@ Type Boolean Value - 0 + 1 ChatBarCustomWidth @@ -3788,7 +3788,7 @@ Boolean Value 0 - + FirstSelectedEnabledPopups Comment @@ -3799,7 +3799,7 @@ Boolean Value 0 - + FixedWeather Comment @@ -3921,7 +3921,7 @@ Value SW - + FloaterStatisticsRect Comment @@ -4448,7 +4448,7 @@ String Value http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/howto/index.html - + HomeSidePanelURL Comment @@ -4514,7 +4514,7 @@ Boolean Value 0 - + HostID Comment @@ -4602,7 +4602,7 @@ Boolean Value 0 - + IgnorePixelDepth Comment @@ -4657,7 +4657,7 @@ F32 Value 0.5 - + InspectorShowTime Comment @@ -4668,7 +4668,7 @@ F32 Value 3.0 - + InstallLanguage Comment @@ -5230,7 +5230,7 @@ Value 0.0.0 - + LastSnapshotToProfileHeight Comment @@ -6309,7 +6309,7 @@ Boolean Value 0 - + MenuAccessKeyTime Comment @@ -6474,7 +6474,7 @@ Boolean Value 0 - + MouseSun Comment @@ -6639,7 +6639,7 @@ String Value - + NextLoginLocation Comment @@ -6763,7 +6763,7 @@ String Value toast - + NotificationFriendIMOptions Comment @@ -6819,7 +6819,7 @@ String Value toast - + NotificationObjectIMOptions Comment @@ -6833,7 +6833,7 @@ String Value toast - + NotificationToastLifeTime Comment @@ -7392,7 +7392,7 @@ Boolean Value 0 - + PlaySoundFriendIM Comment @@ -7503,7 +7503,7 @@ Value 0.9 - + PlainTextChatHistory Comment @@ -7515,7 +7515,7 @@ Value 0 - + PluginInstancesLow Comment @@ -7769,7 +7769,7 @@ 0.4 - + PreviewDirection2 Comment @@ -8379,7 +8379,7 @@ RenderComplexityStaticMax Comment - Sets a static max value for scaling of RenderComplexity + Sets a static max value for scaling of RenderComplexity display (-1 for dynamic scaling) Persist 1 @@ -8457,7 +8457,7 @@ Value 0 - + RenderLocalLights Comment @@ -8684,7 +8684,7 @@ Persist 1 Type - Boolean + Boolean Value 0 @@ -8721,7 +8721,7 @@ Value 0 - + RenderAnimateRes Comment @@ -8894,7 +8894,7 @@ Value 0 - + RenderDepthOfField Comment @@ -9023,7 +9023,7 @@ Value 0.1 - + RenderHighlightBrightness Comment @@ -9047,7 +9047,7 @@ Value 0.6 - + RenderHighlightColor Comment @@ -9076,7 +9076,7 @@ Value 0 - + RenderSpecularResX Comment @@ -9981,7 +9981,7 @@ Value 1 - + RenderAutoMuteByteLimit Comment @@ -10036,7 +10036,7 @@ Boolean Value 0 - + RenderAutoHideSurfaceAreaLimit Comment @@ -10522,7 +10522,7 @@ Boolean Value 0 - + SelectMovableOnly Comment @@ -10764,7 +10764,7 @@ Boolean Value 1 - + ShowCrosshairs Comment @@ -10841,7 +10841,7 @@ Boolean Value 0 - + ShowMiniMapButton Comment @@ -10908,7 +10908,7 @@ Value 1 - ShowObjectRenderingCost + ShowObjectRenderingCost Comment Show the object rendering cost in build tools @@ -10917,9 +10917,9 @@ Type Boolean Value - 1 - - ShowNavbarFavoritesPanel + 1 + + ShowNavbarFavoritesPanel Comment Show/hide navigation bar favorites panel @@ -10928,9 +10928,9 @@ Type Boolean Value - 1 + 1 - ShowNavbarNavigationPanel + ShowNavbarNavigationPanel Comment Show/hide navigation bar navigation panel @@ -10939,7 +10939,7 @@ Type Boolean Value - 1 + 1 ShowWorldMapButton @@ -11095,7 +11095,7 @@ Value 1 - ShowPGSearchAll + ShowPGSearchAll Comment Display results of search All that are flagged as general @@ -11611,7 +11611,7 @@ S32 Value 0 - + SnapshotQuality Comment @@ -12480,7 +12480,7 @@ String Value B56AF90D-6684-48E4-B1E4-722D3DEB2CB6 - + NearByChatChannelUUID Comment @@ -12491,7 +12491,7 @@ String Value E1158BD6-661C-4981-9DAD-4DCBFF062502 - + NotificationChannelUUID Comment @@ -12502,7 +12502,7 @@ String Value AEED3193-8709-4693-8558-7452CCA97AE5 - + AlertChannelUUID Comment @@ -12513,7 +12513,7 @@ String Value F3E07BC8-A973-476D-8C7F-F3B7293975D1 - + UIImgWhiteUUID Comment @@ -12535,7 +12535,7 @@ S32 Value 2 - + UIMaxComboWidth Comment @@ -13448,7 +13448,7 @@ String Value [i800,i600] - + sourceid Comment @@ -14669,7 +14669,7 @@ Boolean Value 1 - + EnablePlaceProfile Comment @@ -15491,7 +15491,7 @@ Value 0 - + PathfindingLineWidth Comment @@ -15532,7 +15532,7 @@ 1.0 - + HideUIControls Comment -- cgit v1.2.3 From 9384eac91b974dfd918d0edf6022cc3e0b0c9daf Mon Sep 17 00:00:00 2001 From: Nat Goodspeed 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(-) 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! Date: Fri, 11 Dec 2015 12:21:31 -0800 Subject: pick up new version of LLCEFLib with fixes for BUG-10880 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 6749d489e5..befcfb1017 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - a78ea1cebcc73147f26970ebbfee5e44 + 43b12075b27d9f135783c0640fe533b2 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308620/arch/Darwin/installer/llceflib-1.4.0.308620-darwin-308620.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309003/arch/Darwin/installer/llceflib-1.4.0.309003-darwin-309003.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - c23c942b0d207221c6bf0c9b9a46a615 + 2ca973bd33b196d48b5c14342f5f412b hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/308620/arch/CYGWIN/installer/llceflib-1.4.0.308620-windows-308620.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309003/arch/CYGWIN/installer/llceflib-1.4.0.309003-windows-309003.tar.bz2 name windows version - 1.4.0.308620 + 1.4.0.309003 llphysicsextensions_source -- cgit v1.2.3 From 5f1fe20e9ec530b1e4c4384474011e913180671c Mon Sep 17 00:00:00 2001 From: callum_linden 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(-) 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 6582c0238b95f7f1853311cccab3faf5b0da64db Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 14 Dec 2015 11:37:41 -0800 Subject: Pull in new LLCEFLib with updated version number --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index befcfb1017..e41b036dc2 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 43b12075b27d9f135783c0640fe533b2 + 4672806a0dfc8a07bb808baa1811730a hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309003/arch/Darwin/installer/llceflib-1.4.0.309003-darwin-309003.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309128/arch/Darwin/installer/llceflib-1.5.0.309128-darwin-309128.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 2ca973bd33b196d48b5c14342f5f412b + 5a1ed7307db45125807eb16b2f4e8130 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309003/arch/CYGWIN/installer/llceflib-1.4.0.309003-windows-309003.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309128/arch/CYGWIN/installer/llceflib-1.5.0.309128-windows-309128.tar.bz2 name windows version - 1.4.0.309003 + 1.5.0.309128 llphysicsextensions_source -- cgit v1.2.3 From 3e46058651570f8e3a8cd20b597544bb07fea0a9 Mon Sep 17 00:00:00 2001 From: Rider Linden 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(-) 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 objectp = pick.getObject(); + //FIXME: how do we handle object in different parcel than us? + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + LLPointer objectp = pick.getObject(); - if (!parcel || - objectp.isNull() || - pick.mObjectFace < 0 || - pick.mObjectFace >= objectp->getNumTEs()) - { - LLViewerMediaFocus::getInstance()->clearFocus(); + if (!parcel || + objectp.isNull() || + pick.mObjectFace < 0 || + pick.mObjectFace >= objectp->getNumTEs()) + { + LLViewerMediaFocus::getInstance()->clearFocus(); - return false; - } + return false; + } - // Does this face have media? - const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); - if(!tep) - return false; + // Does this face have media? + const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); + if (!tep) + return false; - LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL; - if(!mep) - return false; - - viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); + LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL; + if (!mep) + return false; - if (gSavedSettings.getBOOL("MediaOnAPrimUI")) - { - if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull()) - { - // It's okay to give this a null impl - LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal); - } - else - { - // Make sure keyboard focus is set to the media focus object. - gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance()); - LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl(); - - media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE)); - mMediaMouseCaptureID = mep->getMediaID(); - setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture. - } + viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); - return true; - } + if (gSavedSettings.getBOOL("MediaOnAPrimUI")) + { + if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull()) + { + // It's okay to give this a null impl + LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal); + } + else + { + // Make sure keyboard focus is set to the media focus object. + gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance()); + LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl(); - LLViewerMediaFocus::getInstance()->clearFocus(); + media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE)); + mMediaMouseCaptureID = mep->getMediaID(); + setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture. + } - return false; + return true; + } + + LLViewerMediaFocus::getInstance()->clearFocus(); + + return false; +} + +bool LLToolPie::handleMediaDblClick(const LLPickInfo& pick) +{ + //FIXME: how do we handle object in different parcel than us? + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + LLPointer objectp = pick.getObject(); + + + if (!parcel || + objectp.isNull() || + pick.mObjectFace < 0 || + pick.mObjectFace >= objectp->getNumTEs()) + { + LLViewerMediaFocus::getInstance()->clearFocus(); + + return false; + } + + // Does this face have media? + const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); + if (!tep) + return false; + + LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL; + if (!mep) + return false; + + viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); + + if (gSavedSettings.getBOOL("MediaOnAPrimUI")) + { + if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull()) + { + // It's okay to give this a null impl + LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal); + } + else + { + // Make sure keyboard focus is set to the media focus object. + gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance()); + LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl(); + + media_impl->mouseDoubleClick(pick.mUVCoords, gKeyboard->currentMask(TRUE)); + mMediaMouseCaptureID = mep->getMediaID(); + setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture. + } + + return true; + } + + LLViewerMediaFocus::getInstance()->clearFocus(); + + return false; } bool LLToolPie::handleMediaHover(const LLPickInfo& pick) diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index 68fe8bc4a5..c4a2f4a35b 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 Date: Tue, 15 Dec 2015 15:24:41 -0800 Subject: MAINT-5966 - file download failures need feedback --- autobuild.xml | 10 +++++----- 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 +++++++++++++++-- 8 files changed, 61 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index e41b036dc2..824bf4b690 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1536,11 +1536,11 @@ archive hash - 4672806a0dfc8a07bb808baa1811730a + 5a0f74f8e736d91d2c2c6cbc71db90bd hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309128/arch/Darwin/installer/llceflib-1.5.0.309128-darwin-309128.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309177/arch/Darwin/installer/llceflib-1.5.1.309177-darwin-309177.tar.bz2 name darwin @@ -1550,18 +1550,18 @@ archive hash - 5a1ed7307db45125807eb16b2f4e8130 + 5ed007e503cd768681ba282fd6d7aa76 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309128/arch/CYGWIN/installer/llceflib-1.5.0.309128-windows-309128.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/309177/arch/CYGWIN/installer/llceflib-1.5.1.309177-windows-309177.tar.bz2 name windows version - 1.5.0.309128 + 1.5.1.309177 llphysicsextensions_source 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 - fail + Unable to download file + fail + + + confirm + You have requested a file download, which is not supported within [SECOND_LIFE]. + + + 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(-) 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 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(+) 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 142be5b06228e393530bf9594cc952e5a9b04f39 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 18 Dec 2015 06:30:19 -0500 Subject: Added tag 4.0.0-release for changeset ae3297cdd03a --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 0a97b4b9a5..5c4559b232 100755 --- a/.hgtags +++ b/.hgtags @@ -510,3 +510,4 @@ d07f76c5b9860fb87924d00ca729f7d4532534d6 3.7.29-release 27e3cf444c4cc645884960a61325a9ee0e9a2d0f 3.8.4-release e821ef17c6edea4a59997719d8ba416d8c16e143 3.8.5-release 5a5bd148943bfb46cf2ff2ccf376c42dee93d19b 3.8.6-release +ae3297cdd03ab14f19f3811acbc4acd3eb600336 4.0.0-release -- cgit v1.2.3 From 7b993d15b70d419dc0a7c8d92286d34a2635537d Mon Sep 17 00:00:00 2001 From: Oz Linden 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(-) 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