From ab9e83030671f0d309eada847af7055213dfe501 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 24 Mar 2015 00:42:42 +0100 Subject: [PATCH 01/43] 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) From f8989216a4dff518655a9af540f0404449e37a20 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 24 Mar 2015 16:41:47 -0400 Subject: [PATCH 02/43] 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 From dbdef626d650de288697848977155e223cbba9ad Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 24 Mar 2015 17:22:58 -0700 Subject: [PATCH 03/43] 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 +- .../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) From d368babe7cc84ac6d8532e9d2438620cfa6d172d Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 25 Mar 2015 16:16:51 -0700 Subject: [PATCH 05/43] 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} From 834a94caec7691a957c0816f38ac00d765fa5021 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 26 Mar 2015 04:35:13 +0100 Subject: [PATCH 06/43] 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 | 562 ++++++++----------- indra/newview/viewer_manifest.py | 142 +++-- 4 files changed, 324 insertions(+), 389 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(); +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 ); - void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ); - bool mFirstTime; +private: + bool init(); + void update(F64 milliseconds); + 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; + // 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 (mEnableMediaPluginDebugging) + { + std::stringstream str; + str << "@Media Msg> " << msg; - 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; - }; - } + 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; + // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; - if ( mBackgroundPixels != NULL ) - { - unsigned char *pixel = mBackgroundPixels; - pixel += y * mWidth * mDepth; - pixel += ( x * mDepth ); - pixel[ 0 ] = b; - pixel[ 1 ] = g; - pixel[ 2 ] = r; + 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); - setDirty( x, y, x + 1, y + 1 ); - }; + 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 From 9e43798e899a0a337d53ac1fa5a1984d3dfeb0f1 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 26 Mar 2015 18:37:51 +0100 Subject: [PATCH 07/43] 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) From efffc4b0748d1fe950f46aaafe3ded679536d934 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Sat, 28 Mar 2015 01:49:20 +0100 Subject: [PATCH 08/43] 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") { - mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); + mLLCEFLib->keyPress(key, true); } + //else + //if (event == "up") + { + 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; }; } } From 3728730839bf670ae22dd644aa1905e8e9c34560 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 4 Jun 2015 16:27:33 -0700 Subject: [PATCH 09/43] 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) From 3298dccfee96600eaa2e824485f767dc1da677c6 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 4 Jun 2015 16:28:00 -0700 Subject: [PATCH 10/43] 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") From d0320020b3b556294773e5f94b740d79ca9318da Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 4 Jun 2015 16:32:03 -0700 Subject: [PATCH 11/43] 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 From ac88d58ff5fa273ae0dc71fdf24f6ad03d925d4f Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 10 Jun 2015 18:32:41 -0700 Subject: [PATCH 14/43] 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) From a2339f66e4a806e90469f24272ef8599375698fd Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 11 Jun 2015 16:31:37 -0700 Subject: [PATCH 15/43] 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 | 48 ++++++++++++-------------------- 1 file changed, 18 insertions(+), 30 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") + # 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() - # 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 + # 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 From fa5f62bf9fe1f1c2621d123b39eedcf2dbb6ddac Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Mon, 15 Jun 2015 14:19:40 -0700 Subject: [PATCH 16/43] 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 From 34d2c90299a201c5e27684cf0d0d9a85af01cdf5 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 16 Jun 2015 14:30:48 -0700 Subject: [PATCH 17/43] 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 From 5c4d04359dcad2a8868a75589416a3ed86f3469b Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Wed, 17 Jun 2015 12:32:09 -0700 Subject: [PATCH 18/43] 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 From 559f71bf90bb19a885e0ee7a4c9341d27619e701 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Wed, 17 Jun 2015 15:47:32 -0700 Subject: [PATCH 19/43] 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 From f97fb4d80f7e6f4b810e06457afbd65a16390adc Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 18 Jun 2015 12:01:13 -0700 Subject: [PATCH 20/43] 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 From c7842dda37b2c99f02818ff4adca7ad598d0d8ea Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 18 Jun 2015 18:56:01 -0400 Subject: [PATCH 21/43] Update llmanifest.LLManifest.copy_action() to handle symlinks for directories as well as for files. --- indra/lib/python/indra/util/llmanifest.py | 54 ++++++++++++----------- 1 file changed, 28 insertions(+), 26 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 + self.ccopyfile(src, dst) + # XXX What about devices, sockets etc.? + # YYY would we put such things into a viewer package?! - shutil.copy2(src, dst) + def ccopyfile(self, src, dst): + """ Copy a single file. Uses filecmp to skip copying for existing files.""" + # Don't recopy file if it's up-to-date. + # If we seem to be not not overwriting files that have been + # updated, set the last arg to False, but it will take longer. + if os.path.exists(dst) and filecmp.cmp(src, dst, True): + return + # only copy if it's not excluded + if self.includes(src, dst): + try: + os.unlink(dst) + except OSError, err: + if err.errno != errno.ENOENT: + raise + + shutil.copy2(src, dst) def ccopytree(self, src, dst): """Direct copy of shutil.copytree with the additional @@ -632,11 +638,7 @@ class LLManifest(object): srcname = os.path.join(src, name) dstname = os.path.join(dst, name) try: - if os.path.isdir(srcname): - self.ccopytree(srcname, dstname) - else: - self.ccopy(srcname, dstname) - # XXX What about devices, sockets etc.? + self.ccopymumble(srcname, dstname) except (IOError, os.error), why: errors.append((srcname, dstname, why)) if errors: From d80a24803d0865e0bef13bc059b416eed548494d Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 22 Jun 2015 16:14:13 -0700 Subject: [PATCH 22/43] 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 From 3aed694ad9dad4250a6afbc7fd51a22cde9c7b0f Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 22 Jun 2015 17:00:23 -0700 Subject: [PATCH 23/43] 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 From f7908a50294adff3456436074075a677a9c6239b Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 30 Jun 2015 00:07:58 +0100 Subject: [PATCH 24/43] 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 +- .../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]%) From d89b4109f9ac3f1ef95480823df292bbc8200347 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 2 Jul 2015 09:39:41 -0700 Subject: [PATCH 25/43] 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; } + From 16e750583137743099407d0280c87d2e9da7f551 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 2 Jul 2015 12:52:07 -0700 Subject: [PATCH 26/43] 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 = From adb0706aa0f3778fda9921172eaabefd3177dbdc Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 2 Jul 2015 23:56:19 +0100 Subject: [PATCH 27/43] 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 { From ca49ad736a06aa796610f068f6419c39b8535251 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 10 Jul 2015 01:01:07 +0100 Subject: [PATCH 28/43] 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); From a5f1226f248c4d32f7ea84967e3e2f3acc0e0698 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 13 Jul 2015 23:54:30 +0100 Subject: [PATCH 29/43] 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 From d2aacce64f5bc16edc351a7e1a02de880b23ee9e Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Mon, 13 Jul 2015 16:11:34 -0700 Subject: [PATCH 30/43] 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(); }; //////////////////////////////////////////////////////////////////////////////// From 83a9ae7b3c66e87179362f0da9fa7a378b1527e2 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 15 Jul 2015 02:27:33 +0100 Subject: [PATCH 31/43] 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; + 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 (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(); + mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); }; //////////////////////////////////////////////////////////////////////////////// From 224cfc6ec0624561d433afe8a38598f132def913 Mon Sep 17 00:00:00 2001 From: callum Date: Wed, 15 Jul 2015 18:43:57 -0700 Subject: [PATCH 32/43] 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 }; //////////////////////////////////////////////////////////////////////////////// From af54cd28db4dae0e2e5c81d2caf0749c07da207f Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 16 Jul 2015 17:25:20 +0100 Subject: [PATCH 33/43] 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 From 0d6d281cb3c54b08eb845199ba24992bddcf9bae Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 16 Jul 2015 16:11:19 -0700 Subject: [PATCH 34/43] 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() From 8e3acf461e3f3536b621a533d6ab15bc9e0a36be Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 17 Jul 2015 16:14:42 -0700 Subject: [PATCH 35/43] 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 { From ae54b68893f36bd0667e87565ec07ffe78c485ee Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 20 Jul 2015 18:23:21 +0100 Subject: [PATCH 36/43] 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 From a016f92b299331858284fb27a5e4718d0e9485fb Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 20 Jul 2015 23:48:26 +0100 Subject: [PATCH 37/43] 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 From 7cc5db9fdb19d8e798412295280fdf1d86cd0da8 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 24 Jul 2015 23:54:09 +0100 Subject: [PATCH 38/43] 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) { From a75a4e2a4f0b8bc65aa45368326fce0e6635c4ac Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 27 Jul 2015 16:09:04 -0700 Subject: [PATCH 39/43] 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(); From 4ae4e3ffc0c843d021e77a89e58612fc06d0c936 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 31 Jul 2015 16:19:18 -0700 Subject: [PATCH 40/43] 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 From 7505501aea76e014b205d64accf89a9d30abac3a Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 1 Sep 2015 17:43:30 -0700 Subject: [PATCH 41/43] 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"); From d44eeb48d380215bae0d036976f6daa11082af07 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 1 Sep 2015 17:46:29 -0700 Subject: [PATCH 42/43] 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") { From 33da4d9d5dd05bbc9dc232525b59017f7ecbbcdd Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 2 Sep 2015 17:31:40 -0700 Subject: [PATCH 43/43] 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()