Nicky 2015-09-03 14:38:13 +02:00
commit 46d5cd7f24
37 changed files with 1452 additions and 346 deletions

View File

@ -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:
# <username>_<reponame>.email = <email-address>

View File

@ -1679,6 +1679,52 @@
<key>version</key>
<string>0.0.1</string>
</map>
<key>llceflib</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2014, Linden Research, Inc.</string>
<key>description</key>
<string>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)</string>
<key>license</key>
<string>LGPL</string>
<key>license_file</key>
<string>LICENSES/LICENSE-source.txt</string>
<key>name</key>
<string>llceflib</string>
<key>platforms</key>
<map>
<key>darwin</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>6b727137b63a321298cba87863db2147</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>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</string>
</map>
<key>name</key>
<string>darwin</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>fba9f44aa66b81d41a26df4eed116eb9</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>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</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>version</key>
<string>1.0.1.304772</string>
</map>
<key>llphysicsextensions_source</key>
<map>
<key>copyright</key>
@ -1787,66 +1833,6 @@
<key>version</key>
<string>1.0.298370</string>
</map>
<key>llqtwebkit</key>
<map>
<key>copyright</key>
<string>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</string>
<key>description</key>
<string>QT cross-platform application and UI framework.</string>
<key>license</key>
<string>LGPL</string>
<key>license_file</key>
<string>LICENSES/llqtwebkit.txt</string>
<key>name</key>
<string>llqtwebkit</string>
<key>platforms</key>
<map>
<key>darwin</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>3c2b6be4c78b2479c3fae612e1053d37</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>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</string>
</map>
<key>name</key>
<string>darwin</string>
</map>
<key>linux</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>d31358176b9ba8c676458cc061767c0b</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>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</string>
</map>
<key>name</key>
<string>linux</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>bb4e8c8006c8a7aef6d3e3c36a8cebbf</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>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</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>version</key>
<string>4.7.1</string>
</map>
<key>mesa</key>
<map>
<key>license</key>
@ -2214,9 +2200,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>3f8b52280cb1eff2d1acd0214bce1b16</string>
<string>78650a79bda6435e623a940ad425a593</string>
<key>url</key>
<string>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</string>
<string>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</string>
</map>
<key>name</key>
<string>windows</string>
@ -2225,62 +2211,6 @@
<key>version</key>
<string>7.3</string>
</map>
<key>slplugins</key>
<map>
<key>copyright</key>
<string>Second Life Viewer Source Code - Copyright (C) 2010, Linden Research, Inc.</string>
<key>description</key>
<string>Second Life Viewer Plugins and launcher</string>
<key>license</key>
<string>LGPL</string>
<key>license_file</key>
<string>LICENSES/slplugins-license.txt</string>
<key>name</key>
<string>slplugins</string>
<key>platforms</key>
<map>
<key>darwin</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>f6bfb026572f03a4c8ac6b2b7d7eb0ae</string>
<key>url</key>
<string>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</string>
</map>
<key>name</key>
<string>darwin</string>
</map>
<key>linux</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>64b8a3bac95b5888a7ede3d7661a18b8</string>
<key>url</key>
<string>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</string>
</map>
<key>name</key>
<string>linux</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>3a1ea3385303b78b0327c8cea929ef27</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>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</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>version</key>
<string>3.7.24.297623.298079</string>
</map>
<key>slvoice</key>
<map>
<key>copyright</key>

View File

@ -88,8 +88,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)

View File

@ -0,0 +1,40 @@
# -*- cmake -*-
include(Linking)
include(Prebuilt)
if (USESYSTEMLIBS)
set(CEFPLUGIN OFF CACHE BOOL
"CEFPLUGIN support for the llplugin/llmedia test apps.")
else (USESYSTEMLIBS)
use_prebuilt_binary(llceflib)
set(CEFPLUGIN ON CACHE BOOL
"CEFPLUGIN support for the llplugin/llmedia test apps.")
set(CEF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/cef)
endif (USESYSTEMLIBS)
if (WINDOWS)
set(CEF_PLUGIN_LIBRARIES
libcef.lib
libcef_dll_wrapper.lib
llceflib.lib
)
elseif (DARWIN)
FIND_LIBRARY(APPKIT_LIBRARY AppKit)
if (NOT APPKIT_LIBRARY)
message(FATAL_ERROR "AppKit not found")
endif()
FIND_LIBRARY(CEF_LIBRARY "Chromium Embedded Framework" ${ARCH_PREBUILT_DIRS_RELEASE})
if (NOT CEF_LIBRARY)
message(FATAL_ERROR "CEF not found")
endif()
set(CEF_PLUGIN_LIBRARIES
${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
${ARCH_PREBUILT_DIRS_RELEASE}/libLLCefLib.a
${APPKIT_LIBRARY}
${CEF_LIBRARY}
)
elseif (LINUX)
endif (WINDOWS)

View File

@ -14,6 +14,7 @@ set(cmake_SOURCE_FILES
Boost.cmake
BuildVersion.cmake
CARes.cmake
CEFPlugin.cmake
CMakeCopyIfDifferent.cmake
ConfigurePkgConfig.cmake
CURL.cmake
@ -84,18 +85,18 @@ set(cmake_SOURCE_FILES
LeapMotion.cmake
# <FS:CR> We'll be fine without you -> 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
Teapot.cmake # <FS:AW opensim currency support>
TemplateCheck.cmake
Tut.cmake

View File

@ -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)

View File

@ -36,12 +36,12 @@ set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable f
set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
# <FS:ND> When building for Linux x64 we enable building the media plugins, in all other cases we use the prebuild 32 bit packages
# 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 (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
set( ENABLE_MEDIA_PLUGINS ON CACHE FORCE "Build with media plugins" )
else (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
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")
endif (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
# </FS:ND>

View File

@ -520,11 +520,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
@ -603,28 +599,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
@ -640,11 +646,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:

View File

@ -70,9 +70,7 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
add_library (llplugin ${llplugin_SOURCE_FILES})
if (ENABLE_MEDIA_PLUGINS)
add_subdirectory(slplugin)
endif (ENABLE_MEDIA_PLUGINS)
add_subdirectory(slplugin)
# Add tests
if (LL_TESTS)

View File

@ -830,14 +830,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);
}
@ -1276,7 +1276,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);
}

View File

@ -317,4 +317,3 @@ int main(int argc, char **argv)
return 0;
}

View File

@ -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)
{

View File

@ -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

View File

@ -927,6 +927,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;
@ -959,6 +960,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)
@ -966,6 +999,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;
@ -1081,6 +1121,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)
{

View File

@ -384,6 +384,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,
@ -515,6 +516,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);
@ -544,6 +546,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,

View File

@ -42,6 +42,7 @@
#include "llgl.h"
#include "llstring.h"
#include "lldir.h"
#include "llsdutil.h"
#include "llglslshader.h"
// System includes
@ -2089,6 +2090,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");
{
@ -2111,6 +2115,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);
@ -2198,6 +2205,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
@ -3299,6 +3309,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;
}

View File

@ -217,6 +217,9 @@ protected:
U32 mKeyCharCode;
U32 mKeyScanCode;
U32 mKeyVirtualKey;
U32 mRawMsg;
U32 mRawWParam;
U32 mRawLParam;
friend class LLWindowManager;
// <FS:ND> Allow to query for window chrome sizes.

View File

@ -1,16 +1,17 @@
# -*- cmake -*-
add_subdirectory(base)
add_subdirectory(webkit)
add_subdirectory(gstreamer010)
if (LINUX)
add_subdirectory(gstreamer010)
endif (LINUX)
if (WINDOWS OR DARWIN)
add_subdirectory(quicktime)
add_subdirectory(cef)
endif (WINDOWS OR DARWIN)
if (WINDOWS)
add_subdirectory(winmmshim)
endif (WINDOWS)
add_subdirectory(example)
### add_subdirectory(example)

View File

@ -0,0 +1,87 @@
# -*- 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}
${CEF_INCLUDE_DIR}
)
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)

View File

@ -0,0 +1,749 @@
/**
* @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);
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);
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);
void checkEditState();
bool mEnableMediaPluginDebugging;
std::string mHostLanguage;
bool mCookiesEnabled;
bool mPluginsEnabled;
bool mJavascriptEnabled;
std::string mUserAgentSubtring;
std::string mAuthUsername;
std::string mAuthPassword;
bool mAuthOK;
bool mCanCut;
bool mCanCopy;
bool mCanPaste;
std::string mCachePath;
std::string mCookiePath;
LLCEFLib* mLLCEFLib;
};
////////////////////////////////////////////////////////////////////////////////
//
MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
MediaPluginBase(host_send_func, host_user_data)
{
mWidth = 0;
mHeight = 0;
mDepth = 4;
mPixels = 0;
mEnableMediaPluginDebugging = true;
mHostLanguage = "en";
mCookiesEnabled = true;
mPluginsEnabled = false;
mJavascriptEnabled = true;
mUserAgentSubtring = "";
mAuthUsername = "";
mAuthPassword = "";
mAuthOK = false;
mCanCut = false;
mCanCopy = false;
mCanPaste = false;
mCachePath = "";
mCookiePath = "";
mLLCEFLib = new LLCEFLib();
}
////////////////////////////////////////////////////////////////////////////////
//
MediaPluginCEF::~MediaPluginCEF()
{
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);
}
////////////////////////////////////////////////////////////////////////////////
// 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)
{
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();
// 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")
{
}
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));
mLLCEFLib->setOnExternalTargetLinkCallback(boost::bind(&MediaPluginCEF::onExternalTargetLinkCallback, this, _1));
LLCEFLibSettings settings;
settings.inital_width = 1024;
settings.inital_height = 1024;
settings.plugins_enabled = mPluginsEnabled;
settings.javascript_enabled = mJavascriptEnabled;
settings.cookies_enabled = mCookiesEnabled;
settings.cookie_store_path = mCookiePath;
settings.cache_enabled = true;
settings.cache_path = mCachePath;
settings.accept_language_list = mHostLanguage;
settings.user_agent_substring = mUserAgentSubtring;
bool result = mLLCEFLib->init(settings);
if (!result)
{
// if this fails, the media system in viewer will put up a message
}
// Plugin gets to decide the texture parameters to use.
mDepth = 4;
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
message.setValueS32("default_width", 1024);
message.setValueS32("default_height", 1024);
message.setValueS32("depth", mDepth);
message.setValueU32("internalformat", GL_RGB);
message.setValueU32("format", GL_BGRA);
message.setValueU32("type", GL_UNSIGNED_BYTE);
message.setValueBoolean("coords_opengl", 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";
}
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);
}
if (message_name == "edit_cut")
{
mLLCEFLib->editCut();
}
if (message_name == "edit_copy")
{
mLLCEFLib->editCopy();
}
if (message_name == "edit_paste")
{
mLLCEFLib->editPaste();
}
}
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
{
if (message_name == "set_page_zoom_factor")
{
F32 factor = (F32)message_in.getValueReal("factor");
mLLCEFLib->setPageZoom(factor);
}
if (message_name == "browse_stop")
{
mLLCEFLib->stop();
}
else if (message_name == "browse_reload")
{
bool ignore_cache = true;
mLLCEFLib->reload(ignore_cache);
}
else if (message_name == "browse_forward")
{
mLLCEFLib->goForward();
}
else if (message_name == "browse_back")
{
mLLCEFLib->goBack();
}
else if (message_name == "cookies_enabled")
{
mCookiesEnabled = message_in.getValueBoolean("enable");
}
else if (message_name == "set_user_agent")
{
mUserAgentSubtring = message_in.getValue("user_agent");
}
else if (message_name == "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
};
////////////////////////////////////////////////////////////////////////////////
//
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()
{
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;
}

View File

@ -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)

View File

@ -45,7 +45,6 @@ include(OPENAL)
include(OpenGL)
include(OpenSSL)
include(PNG)
include(Prebuilt)
include(Teapot)# <FS:AW opensim currency support>
include(TemplateCheck)
include(UI)
@ -74,11 +73,6 @@ if(FMODEX)
include_directories(${FMODEX_INCLUDE_DIR})
endif(FMODEX)
# install SLPlugin host executable and its dynamic-library plugins
if (NOT ENABLE_MEDIA_PLUGINS)
use_prebuilt_binary(slplugins)
endif (NOT ENABLE_MEDIA_PLUGINS)
if(LEAPMOTION)
add_definitions(-DUSE_LEAPMOTION=1)
include_directories(${LEAP_MOTION_INCLUDE_DIR})
@ -2155,7 +2149,7 @@ if (WINDOWS)
${ARCH_PREBUILT_DIRS_RELEASE}/growl.dll
SLPlugin
media_plugin_quicktime
media_plugin_webkit
media_plugin_cef
winmm_shim
windows-crash-logger
)
@ -2219,10 +2213,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)
@ -2408,9 +2402,9 @@ if (NOT ENABLE_MEDIA_PLUGINS)
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
)
else (NOT ENABLE_MEDIA_PLUGINS)
@ -2535,7 +2529,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)
@ -2591,10 +2585,10 @@ 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}/firestorm-symbols-darwin.tar.bz2")
## set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
@ -2605,7 +2599,7 @@ if (PACKAGE)
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/firestorm-symbols-linux.tar.bz2")
## set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
set(VIEWER_EXE_GLOBS "do-not-directly-run-firestorm-bin")
set(VIEWER_EXE_GLOBS "do-not-directly-run-firestorm-bin SLPlugin")
set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
endif (LINUX)

View File

@ -140,6 +140,7 @@
#include "llleap.h"
#include "stringize.h"
#include "llcoros.h"
#include "cef/llceflib.h"
// Third party library includes
#include <boost/bind.hpp>
@ -3990,8 +3991,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;
// <FS:ND> Use the total accumulated samples.
//S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN);

View File

@ -427,18 +427,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;
}

View File

@ -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);

View File

@ -790,7 +790,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)
{

View File

@ -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

View File

@ -1831,7 +1831,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();
@ -1900,6 +1900,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();
@ -2744,27 +2747,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;
}

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -1481,10 +1481,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);
@ -2594,7 +2593,7 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
}
}
else
{
{
// <FS:Ansariel> Don't care about viewer maturity
//switch (LLVersionInfo::getViewerMaturity())
//{
@ -2623,11 +2622,11 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
//}
if (LLGridManager::getInstance()->isInSLBeta())
{
new_bg_color = LLUIColorTable::instance().getColor("MenuNonProductionBgColor");
new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
}
else
else
{
new_bg_color = LLUIColorTable::instance().getColor("MenuBarBgColor");
new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
}
// </FS:Ansariel>
}
@ -2907,6 +2906,41 @@ void LLViewerWindow::setTitle(const std::string& win_title)
}
//-TT
// 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)
{

View File

@ -321,7 +321,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);

View File

@ -7,7 +7,7 @@
none
</defaultwidget>
<defaultimpl>
media_plugin_webkit
media_plugin_cef
</defaultimpl>
<widgetset name="web">
<label name="web_label">
@ -141,7 +141,7 @@
none
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="none/none">
@ -152,7 +152,7 @@
none
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="audio/*">
@ -185,7 +185,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
@ -207,7 +207,7 @@
web
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/ogg">
@ -229,7 +229,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/postscript">
@ -240,7 +240,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/rtf">
@ -251,7 +251,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/smil">
@ -262,7 +262,7 @@
movie
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/xhtml+xml">
@ -273,7 +273,7 @@
web
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/x-director">
@ -284,7 +284,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="audio/mid">
@ -339,7 +339,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/gif">
@ -350,7 +350,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/jpeg">
@ -361,7 +361,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/png">
@ -372,7 +372,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="image/svg+xml">
@ -383,7 +383,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/tiff">
@ -394,7 +394,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="text/html">
@ -405,7 +405,7 @@
web
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="text/plain">
@ -416,7 +416,7 @@
text
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="text/xml">
@ -427,7 +427,7 @@
text
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="video/mpeg">

View File

@ -7,7 +7,7 @@
none
</defaultwidget>
<defaultimpl>
media_plugin_webkit
media_plugin_cef
</defaultimpl>
<widgetset name="web">
<label name="web_label">
@ -152,7 +152,7 @@
none
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="audio/*">
@ -185,7 +185,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
@ -207,7 +207,7 @@
web
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/ogg">
@ -229,7 +229,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/postscript">
@ -240,7 +240,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/rtf">
@ -251,7 +251,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/smil">
@ -262,7 +262,7 @@
movie
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/xhtml+xml">
@ -273,7 +273,7 @@
web
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="application/x-director">
@ -284,7 +284,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="audio/mid">
@ -339,7 +339,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/gif">
@ -350,7 +350,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/jpeg">
@ -361,7 +361,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/png">
@ -372,7 +372,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="image/svg+xml">
@ -383,7 +383,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="image/tiff">
@ -394,7 +394,7 @@
image
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="text/html">
@ -405,7 +405,7 @@
web
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="text/plain">
@ -416,7 +416,7 @@
text
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype name="text/xml">
@ -427,7 +427,7 @@
text
</widgettype>
<impl>
media_plugin_webkit
media_plugin_cef
</impl>
</mimetype>
<mimetype menu="1" name="video/mpeg">

View File

@ -54,7 +54,7 @@ RestrainedLove API: [RLV_VERSION]
libcurl Version: [LIBCURL_VERSION]
J2C Decoder Version: [J2C_VERSION]
Audio Driver Version: [AUDIO_DRIVER_VERSION]
Qt Webkit Version: [QT_WEBKIT_VERSION]
LLCEFLib/CEF Version: [LLCEFLIB_VERSION]
Voice Server Version: [VOICE_VERSION]
</string>
<string name="AboutSettings">

View File

@ -417,9 +417,9 @@ class Windows_i686_Manifest(ViewerManifest):
self.path(src='%s/firestorm-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")
@ -531,64 +531,114 @@ class Windows_i686_Manifest(ViewerManifest):
self.path("VivoxAUP.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.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()
# <FS:ND> we need 32 bit openssl from the pre build plugins
self.path("ssleay32.dll")
self.path("libeay32.dll")
# </FS:ND>
# 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")
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()
self.end_prefix()
# Media plugins - CEF
if self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_cef.dll")
self.end_prefix()
# winmm.dll shim
if self.prefix(src='../media_plugins/winmmshim/%s' % self.args['configuration'], dst=""):
self.path("winmm.dll")
self.end_prefix()
"""
<FS:ND> This would clobber the 32 bit openssl dlls with 64 bit ones from a 64 bit viewer, skip this step.
# CEF runtime files - debug
if self.args['configuration'].lower() == 'debug':
if self.prefix(src=debpkgdir, dst="llplugin"):
self.path("libeay32.dll")
self.path("ssleay32.dll")
if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'debug'), dst="llplugin"):
self.path("d3dcompiler_43.dll")
self.path("d3dcompiler_47.dll")
self.path("ffmpegsumo.dll")
self.path("libcef.dll")
self.path("libEGL.dll")
self.path("libGLESv2.dll")
self.path("llceflib_host.exe")
self.path("natives_blob.bin")
self.path("snapshot_blob.bin")
self.path("wow_helper.exe")
self.end_prefix()
else:
# 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("natives_blob.bin")
self.path("snapshot_blob.bin")
self.path("wow_helper.exe")
self.end_prefix()
else:
if self.prefix(src=relpkgdir, dst="llplugin"):
self.path("libeay32.dll")
self.path("ssleay32.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()
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
self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],
@ -893,14 +943,13 @@ class DarwinManifest(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,
@ -913,46 +962,57 @@ class DarwinManifest(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=os.path.join(pkgdir, "llplugin/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',
'LLCefLib Helper EH.app'):
self.path2basename(relpkgdir, helperappfile)
# Similarly for imageformats.
if self.prefix(src=os.path.join(pkgdir, "llplugin/imageformats/"), dst="llplugin/imageformats"):
self.path("libq*.dylib")
self.end_prefix("llplugin/imageformats")
pluginframeworkpath = self.dst_path_of('Chromium Embedded Framework.framework');
# 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")
self.end_prefix()
# SLPlugin plugins
if self.prefix(src="", dst="llplugin"):
self.path2basename("../media_plugins/quicktime/" + self.args['configuration'],
"media_plugin_quicktime.dylib")
self.path2basename("../media_plugins/cef/" + self.args['configuration'],
"media_plugin_cef.dylib")
self.end_prefix("llplugin")
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")
# 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
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.
@ -962,7 +1022,6 @@ class DarwinManifest(ViewerManifest):
self.run_command('strip -S %(viewer_binary)r' %
{ 'viewer_binary' : self.dst_path_of('Contents/MacOS/Firestorm')})
def copy_finish(self):
# Force executable permissions to be set for scripts
# see CHOP-223 and http://mercurial.selenic.com/bts/issue1802
@ -1215,7 +1274,7 @@ class LinuxManifest(ViewerManifest):
if self.prefix(src="", dst="bin"):
self.path("firestorm-bin","do-not-directly-run-firestorm-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")
@ -1235,11 +1294,90 @@ 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.path( "../media_plugins/cef/libmedia_plugin_cef.so", "libmedia_plugin_cef.so" )
self.end_prefix("bin/llplugin")
# CEF files
if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release'), dst="lib"):
self.path( "libcef.so" )
self.path( "libllceflib.so" )
self.end_prefix()
if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="bin"):
self.path( "chrome-sandbox" )
self.path( "llceflib_host" )
self.path( "natives_blob.bin" )
self.path( "snapshot_blob.bin" )
self.path( "libffmpegsumo.so" )
self.end_prefix()
if self.prefix(src=os.path.join(os.pardir, 'packages', 'resources'), dst="bin"):
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()
if self.prefix(src=os.path.join(os.pardir, 'packages', 'resources', 'locales'), dst=os.path.join('bin', '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()
# llcommon
if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"):
print "Skipping llcommon.so (assuming llcommon was linked statically)"
@ -1379,7 +1517,7 @@ class LinuxManifest(ViewerManifest):
def strip_binaries(self):
if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():
print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build"
self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install \! -name *.pak \! -name *.dat \! -name *.bin | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
class Linux_i686_Manifest(LinuxManifest):
def construct(self):