summaryrefslogtreecommitdiff
path: root/indra/media_plugins
diff options
context:
space:
mode:
Diffstat (limited to 'indra/media_plugins')
-rwxr-xr-xindra/media_plugins/CMakeLists.txt9
-rw-r--r--[-rwxr-xr-x]indra/media_plugins/cef/CMakeLists.txt (renamed from indra/media_plugins/webkit/CMakeLists.txt)75
-rw-r--r--[-rwxr-xr-x]indra/media_plugins/cef/mac_volume_catcher.cpp (renamed from indra/media_plugins/webkit/mac_volume_catcher.cpp)2
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp885
-rw-r--r--[-rwxr-xr-x]indra/media_plugins/cef/volume_catcher.h (renamed from indra/media_plugins/webkit/volume_catcher.h)0
-rw-r--r--[-rwxr-xr-x]indra/media_plugins/cef/windows_volume_catcher.cpp (renamed from indra/media_plugins/webkit/windows_volume_catcher.cpp)0
-rwxr-xr-xindra/media_plugins/quicktime/CMakeLists.txt3
-rwxr-xr-xindra/media_plugins/quicktime/media_plugin_quicktime.cpp4
-rwxr-xr-xindra/media_plugins/webkit/dummy_volume_catcher.cpp58
-rwxr-xr-xindra/media_plugins/webkit/linux_volume_catcher.cpp468
-rwxr-xr-xindra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc21
-rwxr-xr-xindra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc6
-rwxr-xr-xindra/media_plugins/webkit/media_plugin_webkit.cpp1481
-rwxr-xr-xindra/media_plugins/winmmshim/CMakeLists.txt3
14 files changed, 926 insertions, 2089 deletions
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index 85318aea3b..24eb3947b4 100755
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
@@ -2,16 +2,17 @@
add_subdirectory(base)
-add_subdirectory(webkit)
-
-add_subdirectory(gstreamer010)
+if (LINUX)
+ add_subdirectory(gstreamer010)
+endif (LINUX)
if (WINDOWS OR DARWIN)
add_subdirectory(quicktime)
+ add_subdirectory(cef)
endif (WINDOWS OR DARWIN)
if (WINDOWS)
add_subdirectory(winmmshim)
endif (WINDOWS)
-add_subdirectory(example)
+### add_subdirectory(example)
diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 5a8fe90bdd..1f6163e41e 100755..100644
--- a/indra/media_plugins/webkit/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -1,6 +1,6 @@
# -*- cmake -*-
-project(media_plugin_webkit)
+project(media_plugin_cef)
include(00-Common)
include(LLCommon)
@@ -9,17 +9,14 @@ include(LLPlugin)
include(LLMath)
include(LLRender)
include(LLWindow)
-include(UI)
include(Linking)
include(PluginAPI)
include(MediaPluginBase)
include(OpenGL)
-include(PulseAudio)
-include(WebKitLibPlugin)
+include(CEFPlugin)
include_directories(
- ${PULSEAUDIO_INCLUDE_DIRS}
${LLPLUGIN_INCLUDE_DIRS}
${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
@@ -27,14 +24,14 @@ include_directories(
${LLIMAGE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
- ${LLQTWEBKIT_INCLUDE_DIR}
+ ${CEF_INCLUDE_DIR}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
)
-### media_plugin_webkit
+### media_plugin_cef
if(NOT WORD_SIZE EQUAL 32)
if(WINDOWS)
@@ -44,75 +41,72 @@ if(NOT WORD_SIZE EQUAL 32)
endif(WINDOWS)
endif(NOT WORD_SIZE EQUAL 32)
-set(media_plugin_webkit_SOURCE_FILES
- media_plugin_webkit.cpp
+set(media_plugin_cef_SOURCE_FILES
+ media_plugin_cef.cpp
)
-set(media_plugin_webkit_HEADER_FILES
+set(media_plugin_cef_HEADER_FILES
volume_catcher.h
)
-set(media_plugin_webkit_LINK_LIBRARIES
+set (media_plugin_cef_LINK_LIBRARIES
${LLPLUGIN_LIBRARIES}
${MEDIA_PLUGIN_BASE_LIBRARIES}
${LLCOMMON_LIBRARIES}
- ${WEBKIT_PLUGIN_LIBRARIES}
- ${PLUGIN_API_WINDOWS_LIBRARIES}
- ${PULSEAUDIO_LIBRARIES}
-)
+ ${CEF_PLUGIN_LIBRARIES}
+ ${PLUGIN_API_WINDOWS_LIBRARIES})
+
# Select which VolumeCatcher implementation to use
if (LINUX)
- if (PULSEAUDIO_FOUND)
- list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp)
- else (PULSEAUDIO_FOUND)
- list(APPEND media_plugin_webkit_SOURCE_FILES dummy_volume_catcher.cpp)
- endif (PULSEAUDIO_FOUND)
- list(APPEND media_plugin_webkit_LINK_LIBRARIES
- ${UI_LIBRARIES} # for glib/GTK
- )
+ message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n"
+ " Please create a volume_catcher implementation for this platform.")
+
elseif (DARWIN)
- list(APPEND media_plugin_webkit_SOURCE_FILES mac_volume_catcher.cpp)
+ list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher.cpp)
find_library(CORESERVICES_LIBRARY CoreServices)
find_library(AUDIOUNIT_LIBRARY AudioUnit)
- list(APPEND media_plugin_webkit_LINK_LIBRARIES
+ list(APPEND media_plugin_cef_LINK_LIBRARIES
${CORESERVICES_LIBRARY} # for Component Manager calls
${AUDIOUNIT_LIBRARY} # for AudioUnit calls
)
elseif (WINDOWS)
- list(APPEND media_plugin_webkit_SOURCE_FILES windows_volume_catcher.cpp)
+ list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp)
endif (LINUX)
-set_source_files_properties(${media_plugin_webkit_HEADER_FILES}
+set_source_files_properties(${media_plugin_cef_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
-list(APPEND media_plugin_webkit_SOURCE_FILES ${media_plugin_webkit_HEADER_FILES})
+list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES})
-add_library(media_plugin_webkit
+add_library(media_plugin_cef
SHARED
- ${media_plugin_webkit_SOURCE_FILES}
+ ${media_plugin_cef_SOURCE_FILES}
)
-target_link_libraries(media_plugin_webkit ${media_plugin_webkit_LINK_LIBRARIES})
-
-add_dependencies(media_plugin_webkit
+add_dependencies(media_plugin_cef
${LLPLUGIN_LIBRARIES}
${MEDIA_PLUGIN_BASE_LIBRARIES}
${LLCOMMON_LIBRARIES}
)
+target_link_libraries(media_plugin_cef
+ ${media_plugin_cef_LINK_LIBRARIES}
+)
+
if (WINDOWS)
set_target_properties(
- media_plugin_webkit
+ media_plugin_cef
PROPERTIES
- LINK_FLAGS "/MANIFEST:NO"
+ LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT"
+ LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD"
)
endif (WINDOWS)
if (DARWIN)
# Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name
set_target_properties(
- media_plugin_webkit
+ media_plugin_cef
PROPERTIES
PREFIX ""
BUILD_WITH_INSTALL_RPATH 1
@@ -120,13 +114,4 @@ if (DARWIN)
LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp"
)
- # copy the webkit dylib to the build directory
-# add_custom_command(
-# TARGET media_plugin_webkit POST_BUILD
-# # OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllqtwebkit.dylib
-# COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
-# DEPENDS media_plugin_webkit ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib
-# )
-
endif (DARWIN)
-
diff --git a/indra/media_plugins/webkit/mac_volume_catcher.cpp b/indra/media_plugins/cef/mac_volume_catcher.cpp
index 73e5bf3da3..dddb9c2077 100755..100644
--- a/indra/media_plugins/webkit/mac_volume_catcher.cpp
+++ b/indra/media_plugins/cef/mac_volume_catcher.cpp
@@ -6,7 +6,7 @@
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
new file mode 100644
index 0000000000..a2479cc946
--- /dev/null
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -0,0 +1,885 @@
+/**
+* @file media_plugin_cef.cpp
+* @brief CEF (Chromium Embedding Framework) plugin for LLMedia API plugin system
+*
+* @cond
+* $LicenseInfo:firstyear=2008&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+* @endcond
+*/
+
+#include "linden_common.h"
+#include "indra_constants.h" // for indra keyboard codes
+
+#include "llgl.h"
+#include "llsdutil.h"
+#include "llplugininstance.h"
+#include "llpluginmessage.h"
+#include "llpluginmessageclasses.h"
+#include "media_plugin_base.h"
+
+#include "boost/function.hpp"
+#include "boost/bind.hpp"
+#include "llCEFLib.h"
+#include "volume_catcher.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+class MediaPluginCEF :
+ public MediaPluginBase
+{
+public:
+ MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginCEF();
+
+ /*virtual*/
+ void receiveMessage(const char* message_string);
+
+private:
+ bool init();
+
+ void onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup);
+ void onCustomSchemeURLCallback(std::string url);
+ void onConsoleMessageCallback(std::string message, std::string source, int line);
+ void onStatusMessageCallback(std::string value);
+ void onTitleChangeCallback(std::string title);
+ void onLoadStartCallback();
+ void onRequestExitCallback();
+ void onLoadEndCallback(int httpStatusCode);
+ void onAddressChangeCallback(std::string url);
+ void onNavigateURLCallback(std::string url, std::string target);
+ bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
+ void onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle);
+ void onFileDownloadCallback(std::string filename);
+
+ void postDebugMessage(const std::string& msg);
+ void authResponse(LLPluginMessage &message);
+
+ LLCEFLib::EKeyboardModifier decodeModifiers(std::string &modifiers);
+ void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers);
+ void keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data);
+ void unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data);
+
+ void checkEditState();
+ void setVolume(F32 vol);
+
+ bool mEnableMediaPluginDebugging;
+ std::string mHostLanguage;
+ bool mCookiesEnabled;
+ bool mPluginsEnabled;
+ bool mJavascriptEnabled;
+ std::string mUserAgentSubtring;
+ std::string mAuthUsername;
+ std::string mAuthPassword;
+ bool mAuthOK;
+ bool mCanCut;
+ bool mCanCopy;
+ bool mCanPaste;
+ std::string mCachePath;
+ std::string mCookiePath;
+ LLCEFLib* mLLCEFLib;
+
+ VolumeCatcher mVolumeCatcher;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
+MediaPluginBase(host_send_func, host_user_data)
+{
+ mWidth = 0;
+ mHeight = 0;
+ mDepth = 4;
+ mPixels = 0;
+ mEnableMediaPluginDebugging = true;
+ mHostLanguage = "en";
+ mCookiesEnabled = true;
+ mPluginsEnabled = false;
+ mJavascriptEnabled = true;
+ mUserAgentSubtring = "";
+ mAuthUsername = "";
+ mAuthPassword = "";
+ mAuthOK = false;
+ mCanCut = false;
+ mCanCopy = false;
+ mCanPaste = false;
+ mCachePath = "";
+ mCookiePath = "";
+ mLLCEFLib = new LLCEFLib();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+MediaPluginCEF::~MediaPluginCEF()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::postDebugMessage(const std::string& msg)
+{
+ if (mEnableMediaPluginDebugging)
+ {
+ std::stringstream str;
+ str << "@Media Msg> " << msg;
+
+ LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message");
+ debug_message.setValue("message_text", str.str());
+ debug_message.setValue("message_level", "info");
+ sendMessage(debug_message);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup)
+{
+ if (mPixels && pixels)
+ {
+ if (is_popup)
+ {
+ for (int line = 0; line < height; ++line)
+ {
+ int inverted_y = mHeight - y - height;
+ int src = line * width * mDepth;
+ int dst = (inverted_y + line) * mWidth * mDepth + x * mDepth;
+
+ if (dst + width * mDepth < mWidth * mHeight * mDepth)
+ {
+ memcpy(mPixels + dst, pixels + src, width * mDepth);
+ }
+ }
+ }
+ else
+ {
+ if (mWidth == width && mHeight == height)
+ {
+ memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
+ }
+
+ }
+ setDirty(0, 0, mWidth, mHeight);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line)
+{
+ std::stringstream str;
+ str << "Console message: " << message << " in file(" << source << ") at line " << line;
+ postDebugMessage(str.str());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onStatusMessageCallback(std::string value)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
+ message.setValue("status", value);
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onTitleChangeCallback(std::string title)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+ message.setValue("name", title);
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onLoadStartCallback()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
+ //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
+ message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack());
+ message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward());
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onRequestExitCallback()
+{
+ mLLCEFLib->shutdown();
+
+ LLPluginMessage message("base", "goodbye");
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onLoadEndCallback(int httpStatusCode)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
+ //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
+ message.setValueS32("result_code", httpStatusCode);
+ message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack());
+ message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward());
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onAddressChangeCallback(std::string url)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
+ message.setValue("uri", url);
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onNavigateURLCallback(std::string url, std::string target)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
+ message.setValue("uri", url);
+ message.setValue("target", target);
+ message.setValue("uuid", ""); // not used right now
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onCustomSchemeURLCallback(std::string url)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
+ message.setValue("uri", url);
+ message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password)
+{
+ mAuthOK = false;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request");
+ message.setValue("url", host);
+ message.setValue("realm", realm);
+ message.setValueBoolean("blocking_request", true);
+
+ // The "blocking_request" key in the message means this sendMessage call will block until a response is received.
+ sendMessage(message);
+
+ if (mAuthOK)
+ {
+ username = mAuthUsername;
+ password = mAuthPassword;
+ }
+
+ return mAuthOK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::onFileDownloadCallback(const std::string filename)
+{
+ mAuthOK = false;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
+ message.setValue("filename", filename);
+
+ sendMessage(message);
+}
+
+void MediaPluginCEF::onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle)
+{
+ std::string name = "";
+
+ switch (type)
+ {
+ case LLCEFLib::CT_POINTER:
+ name = "arrow";
+ break;
+ case LLCEFLib::CT_IBEAM:
+ name = "ibeam";
+ break;
+ case LLCEFLib::CT_NORTHSOUTHRESIZE:
+ name = "splitv";
+ break;
+ case LLCEFLib::CT_EASTWESTRESIZE:
+ name = "splith";
+ break;
+ case LLCEFLib::CT_HAND:
+ name = "hand";
+ break;
+
+ default:
+ LL_WARNS() << "Unknown cursor ID: " << (int)type << LL_ENDL;
+ break;
+ }
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed");
+ message.setValue("name", name);
+ sendMessage(message);
+}
+
+void MediaPluginCEF::authResponse(LLPluginMessage &message)
+{
+ mAuthOK = message.getValueBoolean("ok");
+ if (mAuthOK)
+ {
+ mAuthUsername = message.getValue("username");
+ mAuthPassword = message.getValue("password");
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::receiveMessage(const char* message_string)
+{
+ // std::cerr << "MediaPluginCEF::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+ LLPluginMessage message_in;
+
+ if (message_in.parse(message_string) >= 0)
+ {
+ std::string message_class = message_in.getClass();
+ std::string message_name = message_in.getName();
+ if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+ {
+ if (message_name == "init")
+ {
+ LLPluginMessage message("base", "init_response");
+ LLSD versions = LLSD::emptyMap();
+ versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
+ message.setValueLLSD("versions", versions);
+
+ std::string plugin_version = "CEF plugin 1.1.3";
+ message.setValue("plugin_version", plugin_version);
+ sendMessage(message);
+ }
+ else if (message_name == "idle")
+ {
+ mLLCEFLib->update();
+
+ mVolumeCatcher.pump();
+ // this seems bad but unless the state changes (it won't until we figure out
+ // how to get CEF to tell us if copy/cut/paste is available) then this function
+ // will return immediately
+ checkEditState();
+ }
+ else if (message_name == "cleanup")
+ {
+ mLLCEFLib->requestExit();
+ }
+ else if (message_name == "shm_added")
+ {
+ SharedSegmentInfo info;
+ info.mAddress = message_in.getValuePointer("address");
+ info.mSize = (size_t)message_in.getValueS32("size");
+ std::string name = message_in.getValue("name");
+
+ mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+ }
+ else if (message_name == "shm_remove")
+ {
+ std::string name = message_in.getValue("name");
+
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ if (mPixels == iter->second.mAddress)
+ {
+ mPixels = NULL;
+ mTextureSegmentName.clear();
+ }
+ mSharedSegments.erase(iter);
+ }
+ else
+ {
+ }
+
+ LLPluginMessage message("base", "shm_remove_response");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
+ if (message_name == "init")
+ {
+ // event callbacks from LLCefLib
+ mLLCEFLib->setOnPageChangedCallback(boost::bind(&MediaPluginCEF::onPageChangedCallback, this, _1, _2, _3, _4, _5, _6));
+ mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1));
+ mLLCEFLib->setOnConsoleMessageCallback(boost::bind(&MediaPluginCEF::onConsoleMessageCallback, this, _1, _2, _3));
+ mLLCEFLib->setOnStatusMessageCallback(boost::bind(&MediaPluginCEF::onStatusMessageCallback, this, _1));
+ mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1));
+ mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this));
+ mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1));
+ mLLCEFLib->setOnAddressChangeCallback(boost::bind(&MediaPluginCEF::onAddressChangeCallback, this, _1));
+ mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2));
+ mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4));
+ mLLCEFLib->setOnFileDownloadCallback(boost::bind(&MediaPluginCEF::onFileDownloadCallback, this, _1));
+ mLLCEFLib->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2));
+ mLLCEFLib->setOnRequestExitCallback(boost::bind(&MediaPluginCEF::onRequestExitCallback, this));
+
+ LLCEFLib::LLCEFLibSettings settings;
+ settings.initial_width = 1024;
+ settings.initial_height = 1024;
+ settings.plugins_enabled = mPluginsEnabled;
+ settings.javascript_enabled = mJavascriptEnabled;
+ settings.cookies_enabled = mCookiesEnabled;
+ settings.cookie_store_path = mCookiePath;
+ settings.cache_enabled = true;
+ settings.cache_path = mCachePath;
+ settings.accept_language_list = mHostLanguage;
+ settings.user_agent_substring = mLLCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
+
+ bool result = mLLCEFLib->init(settings);
+ if (!result)
+ {
+ // if this fails, the media system in viewer will put up a message
+ }
+
+ // Plugin gets to decide the texture parameters to use.
+ mDepth = 4;
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+ message.setValueS32("default_width", 1024);
+ message.setValueS32("default_height", 1024);
+ message.setValueS32("depth", mDepth);
+ message.setValueU32("internalformat", GL_RGB);
+ message.setValueU32("format", GL_BGRA);
+ message.setValueU32("type", GL_UNSIGNED_BYTE);
+ message.setValueBoolean("coords_opengl", true);
+ sendMessage(message);
+ }
+ else if (message_name == "set_user_data_path")
+ {
+ std::string user_data_path_cache = message_in.getValue("cache_path");
+ std::string user_data_path_cookies = message_in.getValue("cookies_path");
+ mCachePath = user_data_path_cache + "cef_cache";
+ mCookiePath = user_data_path_cookies + "cef_cookies";
+ }
+ else if (message_name == "size_change")
+ {
+ std::string name = message_in.getValue("name");
+ S32 width = message_in.getValueS32("width");
+ S32 height = message_in.getValueS32("height");
+ S32 texture_width = message_in.getValueS32("texture_width");
+ S32 texture_height = message_in.getValueS32("texture_height");
+
+ if (!name.empty())
+ {
+ // Find the shared memory region with this name
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ mPixels = (unsigned char*)iter->second.mAddress;
+ mWidth = width;
+ mHeight = height;
+
+ mTextureWidth = texture_width;
+ mTextureHeight = texture_height;
+ };
+ };
+
+ mLLCEFLib->setSize(mWidth, mHeight);
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+ message.setValue("name", name);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ message.setValueS32("texture_width", texture_width);
+ message.setValueS32("texture_height", texture_height);
+ sendMessage(message);
+
+ }
+ else if (message_name == "set_language_code")
+ {
+ mHostLanguage = message_in.getValue("language");
+ }
+ else if (message_name == "load_uri")
+ {
+ std::string uri = message_in.getValue("uri");
+ mLLCEFLib->navigate(uri);
+ }
+ else if (message_name == "set_cookie")
+ {
+ std::string uri = message_in.getValue("uri");
+ std::string name = message_in.getValue("name");
+ std::string value = message_in.getValue("value");
+ std::string domain = message_in.getValue("domain");
+ std::string path = message_in.getValue("path");
+ bool httponly = message_in.getValueBoolean("httponly");
+ bool secure = message_in.getValueBoolean("secure");
+ mLLCEFLib->setCookie(uri, name, value, domain, path, httponly, secure);
+ }
+ else if (message_name == "mouse_event")
+ {
+ std::string event = message_in.getValue("event");
+
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+
+ // only even send left mouse button events to LLCEFLib
+ // (partially prompted by crash in OS X CEF when sending right button events)
+ // we catch the right click in viewer and display our own context menu anyway
+ S32 button = message_in.getValueS32("button");
+ LLCEFLib::EMouseButton btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT;
+
+ if (event == "down" && button == 0)
+ {
+ mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOWN, x, y);
+ mLLCEFLib->setFocus(true);
+
+ std::stringstream str;
+ str << "Mouse down at = " << x << ", " << y;
+ postDebugMessage(str.str());
+ }
+ else if (event == "up" && button == 0)
+ {
+ mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_UP, x, y);
+
+ std::stringstream str;
+ str << "Mouse up at = " << x << ", " << y;
+ postDebugMessage(str.str());
+ }
+ else if (event == "double_click")
+ {
+ mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOUBLE_CLICK, x, y);
+ }
+ else
+ {
+ mLLCEFLib->mouseMove(x, y);
+ }
+ }
+ else if (message_name == "scroll_event")
+ {
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+ const int scaling_factor = 40;
+ y *= -scaling_factor;
+
+ mLLCEFLib->mouseWheel(x, y);
+ }
+ else if (message_name == "text_event")
+ {
+ std::string text = message_in.getValue("text");
+ std::string modifiers = message_in.getValue("modifiers");
+ LLSD native_key_data = message_in.getValueLLSD("native_key_data");
+
+ unicodeInput(text, decodeModifiers(modifiers), native_key_data);
+ }
+ else if (message_name == "key_event")
+ {
+#if LL_DARWIN
+ std::string event = message_in.getValue("event");
+ S32 key = message_in.getValueS32("key");
+ LLSD native_key_data = message_in.getValueLLSD("native_key_data");
+
+#if 0
+ if (event == "down")
+ {
+ //mLLCEFLib->keyPress(key, true);
+ mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
+
+ }
+ else if (event == "up")
+ {
+ //mLLCEFLib->keyPress(key, false);
+ mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_UP, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
+ }
+#else
+ // Treat unknown events as key-up for safety.
+ LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP;
+ if (event == "down")
+ {
+ key_event = LLCEFLib::KE_KEY_DOWN;
+ }
+ else if (event == "repeat")
+ {
+ key_event = LLCEFLib::KE_KEY_REPEAT;
+ }
+
+ keyEvent(key_event, key, LLCEFLib::KM_MODIFIER_NONE, native_key_data);
+
+#endif
+#elif LL_WINDOWS
+ std::string event = message_in.getValue("event");
+ S32 key = message_in.getValueS32("key");
+ std::string modifiers = message_in.getValue("modifiers");
+ LLSD native_key_data = message_in.getValueLLSD("native_key_data");
+
+ // Treat unknown events as key-up for safety.
+ LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP;
+ if (event == "down")
+ {
+ key_event = LLCEFLib::KE_KEY_DOWN;
+ }
+ else if (event == "repeat")
+ {
+ key_event = LLCEFLib::KE_KEY_REPEAT;
+ }
+
+ keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
+#endif
+ }
+ else if (message_name == "enable_media_plugin_debugging")
+ {
+ mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
+ }
+ if (message_name == "auth_response")
+ {
+ authResponse(message_in);
+ }
+ if (message_name == "edit_cut")
+ {
+ mLLCEFLib->editCut();
+ }
+ if (message_name == "edit_copy")
+ {
+ mLLCEFLib->editCopy();
+ }
+ if (message_name == "edit_paste")
+ {
+ mLLCEFLib->editPaste();
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
+ {
+ if (message_name == "set_page_zoom_factor")
+ {
+ F32 factor = (F32)message_in.getValueReal("factor");
+ mLLCEFLib->setPageZoom(factor);
+ }
+ if (message_name == "browse_stop")
+ {
+ mLLCEFLib->stop();
+ }
+ else if (message_name == "browse_reload")
+ {
+ bool ignore_cache = true;
+ mLLCEFLib->reload(ignore_cache);
+ }
+ else if (message_name == "browse_forward")
+ {
+ mLLCEFLib->goForward();
+ }
+ else if (message_name == "browse_back")
+ {
+ mLLCEFLib->goBack();
+ }
+ else if (message_name == "cookies_enabled")
+ {
+ mCookiesEnabled = message_in.getValueBoolean("enable");
+ }
+ else if (message_name == "set_user_agent")
+ {
+ mUserAgentSubtring = message_in.getValue("user_agent");
+ }
+ else if (message_name == "show_web_inspector")
+ {
+ mLLCEFLib->showDevTools(true);
+ }
+ else if (message_name == "plugins_enabled")
+ {
+ mPluginsEnabled = message_in.getValueBoolean("enable");
+ }
+ else if (message_name == "javascript_enabled")
+ {
+ mJavascriptEnabled = message_in.getValueBoolean("enable");
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
+ {
+ if (message_name == "set_volume")
+ {
+ F32 volume = (F32)message_in.getValueReal("volume");
+ setVolume(volume);
+ }
+ }
+ else
+ {
+ };
+ }
+}
+
+LLCEFLib::EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
+{
+ int result = 0;
+
+ if (modifiers.find("shift") != std::string::npos)
+ result |= LLCEFLib::KM_MODIFIER_SHIFT;
+
+ if (modifiers.find("alt") != std::string::npos)
+ result |= LLCEFLib::KM_MODIFIER_ALT;
+
+ if (modifiers.find("control") != std::string::npos)
+ result |= LLCEFLib::KM_MODIFIER_CONTROL;
+
+ if (modifiers.find("meta") != std::string::npos)
+ result |= LLCEFLib::KM_MODIFIER_META;
+
+ return (LLCEFLib::EKeyboardModifier)result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers)
+{
+ native_scan_code = 0;
+ native_virtual_key = 0;
+ native_modifiers = 0;
+
+ if (native_key_data.isMap())
+ {
+#if LL_DARWIN
+ native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger());
+ native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger());
+ native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
+#elif LL_WINDOWS
+ native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
+ native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
+ // TODO: I don't think we need to do anything with native modifiers here -- please verify
+#endif
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers_x, LLSD native_key_data = LLSD::emptyMap())
+{
+#if LL_DARWIN
+
+ if (!native_key_data.has("event_type") ||
+ !native_key_data.has("event_modifiers") ||
+ !native_key_data.has("event_keycode") ||
+ !native_key_data.has("event_isrepeat"))
+ return;
+
+ uint32_t eventType = native_key_data["event_type"].asInteger();
+ if (!eventType)
+ return;
+ uint32_t eventModifiers = native_key_data["event_modifiers"].asInteger();
+ uint32_t eventKeycode = native_key_data["event_keycode"].asInteger();
+ char eventChars = static_cast<char>(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger());
+ char eventUChars = static_cast<char>(native_key_data["event_umodchars"].isUndefined() ? 0 : native_key_data["event_umodchars"].asInteger());
+ bool eventIsRepeat = native_key_data["event_isrepeat"].asBoolean();
+
+ mLLCEFLib->keyboardEventOSX(eventType, eventModifiers, (eventChars) ? &eventChars : NULL,
+ (eventUChars) ? &eventUChars : NULL, eventIsRepeat, eventKeycode);
+
+#elif LL_WINDOWS
+ U32 msg = ll_U32_from_sd(native_key_data["msg"]);
+ U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
+ U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
+
+ mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
+#endif
+};
+
+void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
+{
+#if LL_DARWIN
+ //mLLCEFLib->keyPress(utf8str[0], true);
+ //mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
+ if (!native_key_data.has("event_chars") || !native_key_data.has("event_umodchars") ||
+ !native_key_data.has("event_keycode") || !native_key_data.has("event_modifiers"))
+ return;
+ uint32_t unicodeChar = native_key_data["event_chars"].asInteger();
+ uint32_t unmodifiedChar = native_key_data["event_umodchars"].asInteger();
+ uint32_t keyCode = native_key_data["event_keycode"].asInteger();
+ uint32_t rawmodifiers = native_key_data["event_modifiers"].asInteger();
+
+ mLLCEFLib->injectUnicodeText(unicodeChar, unmodifiedChar, keyCode, rawmodifiers);
+
+#elif LL_WINDOWS
+ U32 msg = ll_U32_from_sd(native_key_data["msg"]);
+ U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
+ U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
+ mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
+#endif
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void MediaPluginCEF::checkEditState()
+{
+ bool can_cut = mLLCEFLib->editCanCut();
+ bool can_copy = mLLCEFLib->editCanCopy();
+ bool can_paste = mLLCEFLib->editCanPaste();
+
+ if ((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste))
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state");
+
+ if (can_cut != mCanCut)
+ {
+ mCanCut = can_cut;
+ message.setValueBoolean("cut", can_cut);
+ }
+
+ if (can_copy != mCanCopy)
+ {
+ mCanCopy = can_copy;
+ message.setValueBoolean("copy", can_copy);
+ }
+
+ if (can_paste != mCanPaste)
+ {
+ mCanPaste = can_paste;
+ message.setValueBoolean("paste", can_paste);
+ }
+
+ sendMessage(message);
+ }
+}
+
+void MediaPluginCEF::setVolume(F32 vol)
+{
+ mVolumeCatcher.setVolume(vol);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool MediaPluginCEF::init()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+ message.setValue("name", "CEF Plugin");
+ sendMessage(message);
+
+ return true;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func,
+ void* host_user_data,
+ LLPluginInstance::sendMessageFunction *plugin_send_func,
+ void **plugin_user_data)
+{
+ MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data);
+ *plugin_send_func = MediaPluginCEF::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
+
+ return 0;
+}
diff --git a/indra/media_plugins/webkit/volume_catcher.h b/indra/media_plugins/cef/volume_catcher.h
index 337f2913d3..337f2913d3 100755..100644
--- a/indra/media_plugins/webkit/volume_catcher.h
+++ b/indra/media_plugins/cef/volume_catcher.h
diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp
index 0cfb810906..0cfb810906 100755..100644
--- a/indra/media_plugins/webkit/windows_volume_catcher.cpp
+++ b/indra/media_plugins/cef/windows_volume_catcher.cpp
diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt
index 58391007ff..d7a1874bf3 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/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
index ff1ed8bfbc..7ef5a0fe44 100755
--- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
+++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
@@ -837,7 +837,9 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string)
else if(message_name == "cleanup")
{
// TODO: clean up here
- }
+ LLPluginMessage message("base", "goodbye");
+ sendMessage(message);
+ }
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
diff --git a/indra/media_plugins/webkit/dummy_volume_catcher.cpp b/indra/media_plugins/webkit/dummy_volume_catcher.cpp
deleted file mode 100755
index d54b31b2ae..0000000000
--- a/indra/media_plugins/webkit/dummy_volume_catcher.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file dummy_volume_catcher.cpp
- * @brief A null implementation of the "VolumeCatcher" class for platforms where it's not implemented yet.
- *
- * @cond
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- * @endcond
- */
-
-#include "volume_catcher.h"
-
-
-class VolumeCatcherImpl
-{
-};
-
-/////////////////////////////////////////////////////
-
-VolumeCatcher::VolumeCatcher()
-{
- pimpl = NULL;
-}
-
-VolumeCatcher::~VolumeCatcher()
-{
-}
-
-void VolumeCatcher::setVolume(F32 volume)
-{
-}
-
-void VolumeCatcher::setPan(F32 pan)
-{
-}
-
-void VolumeCatcher::pump()
-{
-}
-
diff --git a/indra/media_plugins/webkit/linux_volume_catcher.cpp b/indra/media_plugins/webkit/linux_volume_catcher.cpp
deleted file mode 100755
index 91be3a89e9..0000000000
--- a/indra/media_plugins/webkit/linux_volume_catcher.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-/**
- * @file linux_volume_catcher.cpp
- * @brief A Linux-specific, PulseAudio-specific hack to detect and volume-adjust new audio sources
- *
- * @cond
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- * @endcond
- */
-
-/*
- The high-level design is as follows:
- 1) Connect to the PulseAudio daemon
- 2) Watch for the creation of new audio players connecting to the daemon (this includes ALSA clients running on the PulseAudio emulation layer, such as Flash plugins)
- 3) Examine any new audio player's PID to see if it belongs to our own process
- 4) If so, tell PA to adjust the volume of that audio player ('sink input' in PA parlance)
- 5) Keep a list of all living audio players that we care about, adjust the volumes of all of them when we get a new setVolume() call
- */
-
-#include "linden_common.h"
-
-#include "volume_catcher.h"
-
-
-extern "C" {
-#include <glib.h>
-#include <glib-object.h>
-
-#include <pulse/introspect.h>
-#include <pulse/context.h>
-#include <pulse/subscribe.h>
-#include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken.
-
-#include "apr_pools.h"
-#include "apr_dso.h"
-}
-
-////////////////////////////////////////////////////
-
-#define DEBUGMSG(...) do {} while(0)
-#define INFOMSG(...) do {} while(0)
-#define WARNMSG(...) do {} while(0)
-
-#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) RTN (*ll##PASYM)(__VA_ARGS__) = NULL
-#include "linux_volume_catcher_pa_syms.inc"
-#include "linux_volume_catcher_paglib_syms.inc"
-#undef LL_PA_SYM
-
-static bool sSymsGrabbed = false;
-static apr_pool_t *sSymPADSOMemoryPool = NULL;
-static apr_dso_handle_t *sSymPADSOHandleG = NULL;
-
-bool grab_pa_syms(std::string pulse_dso_name)
-{
- if (sSymsGrabbed)
- {
- // already have grabbed good syms
- return true;
- }
-
- bool sym_error = false;
- bool rtn = false;
- apr_status_t rv;
- apr_dso_handle_t *sSymPADSOHandle = NULL;
-
-#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0)
-
- //attempt to load the shared library
- apr_pool_create(&sSymPADSOMemoryPool, NULL);
-
- if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle,
- pulse_dso_name.c_str(),
- sSymPADSOMemoryPool) ))
- {
- INFOMSG("Found DSO: %s", pulse_dso_name.c_str());
-
-#include "linux_volume_catcher_pa_syms.inc"
-#include "linux_volume_catcher_paglib_syms.inc"
-
- if ( sSymPADSOHandle )
- {
- sSymPADSOHandleG = sSymPADSOHandle;
- sSymPADSOHandle = NULL;
- }
-
- rtn = !sym_error;
- }
- else
- {
- INFOMSG("Couldn't load DSO: %s", pulse_dso_name.c_str());
- rtn = false; // failure
- }
-
- if (sym_error)
- {
- WARNMSG("Failed to find necessary symbols in PulseAudio libraries.");
- }
-#undef LL_PA_SYM
-
- sSymsGrabbed = rtn;
- return rtn;
-}
-
-
-void ungrab_pa_syms()
-{
- // should be safe to call regardless of whether we've
- // actually grabbed syms.
-
- if ( sSymPADSOHandleG )
- {
- apr_dso_unload(sSymPADSOHandleG);
- sSymPADSOHandleG = NULL;
- }
-
- if ( sSymPADSOMemoryPool )
- {
- apr_pool_destroy(sSymPADSOMemoryPool);
- sSymPADSOMemoryPool = NULL;
- }
-
- // NULL-out all of the symbols we'd grabbed
-#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0)
-#include "linux_volume_catcher_pa_syms.inc"
-#include "linux_volume_catcher_paglib_syms.inc"
-#undef LL_PA_SYM
-
- sSymsGrabbed = false;
-}
-////////////////////////////////////////////////////
-
-// PulseAudio requires a chain of callbacks with C linkage
-extern "C" {
- void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata);
- void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata);
- void callback_context_state(pa_context *context, void *userdata);
-}
-
-
-class VolumeCatcherImpl
-{
-public:
- VolumeCatcherImpl();
- ~VolumeCatcherImpl();
-
- void setVolume(F32 volume);
- void pump(void);
-
- // for internal use - can't be private because used from our C callbacks
-
- bool loadsyms(std::string pulse_dso_name);
- void init();
- void cleanup();
-
- void update_all_volumes(F32 volume);
- void update_index_volume(U32 index, F32 volume);
- void connected_okay();
-
- std::set<U32> mSinkInputIndices;
- std::map<U32,U32> mSinkInputNumChannels;
- F32 mDesiredVolume;
- pa_glib_mainloop *mMainloop;
- pa_context *mPAContext;
- bool mConnected;
- bool mGotSyms;
-};
-
-VolumeCatcherImpl::VolumeCatcherImpl()
- : mDesiredVolume(0.0f),
- mMainloop(NULL),
- mPAContext(NULL),
- mConnected(false),
- mGotSyms(false)
-{
- init();
-}
-
-VolumeCatcherImpl::~VolumeCatcherImpl()
-{
- cleanup();
-}
-
-bool VolumeCatcherImpl::loadsyms(std::string pulse_dso_name)
-{
- return grab_pa_syms(pulse_dso_name);
-}
-
-void VolumeCatcherImpl::init()
-{
- // try to be as defensive as possible because PA's interface is a
- // bit fragile and (for our purposes) we'd rather simply not function
- // than crash
-
- // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in
- // libpulse.so.0 - this isn't a great assumption, and the two DSOs should
- // probably be loaded separately. Our Linux DSO framework needs refactoring,
- // we do this sort of thing a lot with practically identical logic...
- mGotSyms = loadsyms("libpulse-mainloop-glib.so.0");
- if (!mGotSyms) return;
-
- // better make double-sure glib itself is initialized properly.
- if (!g_thread_supported ()) g_thread_init (NULL);
- g_type_init();
-
- mMainloop = llpa_glib_mainloop_new(g_main_context_default());
- if (mMainloop)
- {
- pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop);
- if (api)
- {
- pa_proplist *proplist = llpa_proplist_new();
- if (proplist)
- {
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1");
-
- // plain old pa_context_new() is broken!
- mPAContext = llpa_context_new_with_proplist(api, NULL, proplist);
- llpa_proplist_free(proplist);
- }
- }
- }
-
- // Now we've set up a PA context and mainloop, try connecting the
- // PA context to a PA daemon.
- if (mPAContext)
- {
- llpa_context_set_state_callback(mPAContext, callback_context_state, this);
- pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN?
- if (llpa_context_connect(mPAContext, NULL, cflags, NULL) >= 0)
- {
- // Okay! We haven't definitely connected, but we
- // haven't definitely failed yet.
- }
- else
- {
- // Failed to connect to PA manager... we'll leave
- // things like that. Perhaps we should try again later.
- }
- }
-}
-
-void VolumeCatcherImpl::cleanup()
-{
- mConnected = false;
-
- if (mGotSyms && mPAContext)
- {
- llpa_context_disconnect(mPAContext);
- llpa_context_unref(mPAContext);
- }
- mPAContext = NULL;
-
- if (mGotSyms && mMainloop)
- {
- llpa_glib_mainloop_free(mMainloop);
- }
- mMainloop = NULL;
-}
-
-void VolumeCatcherImpl::setVolume(F32 volume)
-{
- mDesiredVolume = volume;
-
- if (!mGotSyms) return;
-
- if (mConnected && mPAContext)
- {
- update_all_volumes(mDesiredVolume);
- }
-
- pump();
-}
-
-void VolumeCatcherImpl::pump()
-{
- gboolean may_block = FALSE;
- g_main_context_iteration(g_main_context_default(), may_block);
-}
-
-void VolumeCatcherImpl::connected_okay()
-{
- pa_operation *op;
-
- // fetch global list of existing sinkinputs
- if ((op = llpa_context_get_sink_input_info_list(mPAContext,
- callback_discovered_sinkinput,
- this)))
- {
- llpa_operation_unref(op);
- }
-
- // subscribe to future global sinkinput changes
- llpa_context_set_subscribe_callback(mPAContext,
- callback_subscription_alert,
- this);
- if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t)
- (PA_SUBSCRIPTION_MASK_SINK_INPUT),
- NULL, NULL)))
- {
- llpa_operation_unref(op);
- }
-}
-
-void VolumeCatcherImpl::update_all_volumes(F32 volume)
-{
- for (std::set<U32>::iterator it = mSinkInputIndices.begin();
- it != mSinkInputIndices.end(); ++it)
- {
- update_index_volume(*it, volume);
- }
-}
-
-void VolumeCatcherImpl::update_index_volume(U32 index, F32 volume)
-{
- static pa_cvolume cvol;
- llpa_cvolume_set(&cvol, mSinkInputNumChannels[index],
- llpa_sw_volume_from_linear(volume));
-
- pa_context *c = mPAContext;
- uint32_t idx = index;
- const pa_cvolume *cvolumep = &cvol;
- pa_context_success_cb_t cb = NULL; // okay as null
- void *userdata = NULL; // okay as null
-
- pa_operation *op;
- if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata)))
- {
- llpa_operation_unref(op);
- }
-}
-
-
-void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata)
-{
- VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
- llassert(impl);
-
- if (0 == eol)
- {
- pa_proplist *proplist = sii->proplist;
- pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID));
-
- if (sinkpid == getpid()) // does the discovered sinkinput belong to this process?
- {
- bool is_new = (impl->mSinkInputIndices.find(sii->index) ==
- impl->mSinkInputIndices.end());
-
- impl->mSinkInputIndices.insert(sii->index);
- impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels;
-
- if (is_new)
- {
- // new!
- impl->update_index_volume(sii->index, impl->mDesiredVolume);
- }
- else
- {
- // seen it already, do nothing.
- }
- }
- }
-}
-
-void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata)
-{
- VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
- llassert(impl);
-
- switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
- case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
- if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) ==
- PA_SUBSCRIPTION_EVENT_REMOVE)
- {
- // forget this sinkinput, if we were caring about it
- impl->mSinkInputIndices.erase(index);
- impl->mSinkInputNumChannels.erase(index);
- }
- else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) ==
- PA_SUBSCRIPTION_EVENT_NEW)
- {
- // ask for more info about this new sinkinput
- pa_operation *op;
- if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl)))
- {
- llpa_operation_unref(op);
- }
- }
- else
- {
- // property change on this sinkinput - we don't care.
- }
- break;
-
- default:;
- }
-}
-
-void callback_context_state(pa_context *context, void *userdata)
-{
- VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
- llassert(impl);
-
- switch (llpa_context_get_state(context))
- {
- case PA_CONTEXT_READY:
- impl->mConnected = true;
- impl->connected_okay();
- break;
- case PA_CONTEXT_TERMINATED:
- impl->mConnected = false;
- break;
- case PA_CONTEXT_FAILED:
- impl->mConnected = false;
- break;
- default:;
- }
-}
-
-/////////////////////////////////////////////////////
-
-VolumeCatcher::VolumeCatcher()
-{
- pimpl = new VolumeCatcherImpl();
-}
-
-VolumeCatcher::~VolumeCatcher()
-{
- delete pimpl;
- pimpl = NULL;
-}
-
-void VolumeCatcher::setVolume(F32 volume)
-{
- llassert(pimpl);
- pimpl->setVolume(volume);
-}
-
-void VolumeCatcher::setPan(F32 pan)
-{
- // TODO: implement this (if possible)
-}
-
-void VolumeCatcher::pump()
-{
- llassert(pimpl);
- pimpl->pump();
-}
diff --git a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc
deleted file mode 100755
index d806b48428..0000000000
--- a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc
+++ /dev/null
@@ -1,21 +0,0 @@
-// required symbols to grab
-LL_PA_SYM(true, pa_context_connect, int, pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api);
-LL_PA_SYM(true, pa_context_disconnect, void, pa_context *c);
-LL_PA_SYM(true, pa_context_get_sink_input_info, pa_operation*, pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_get_sink_input_info_list, pa_operation*, pa_context *c, pa_sink_input_info_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_get_state, pa_context_state_t, pa_context *c);
-LL_PA_SYM(true, pa_context_new_with_proplist, pa_context*, pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist);
-LL_PA_SYM(true, pa_context_set_sink_input_volume, pa_operation*, pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_set_state_callback, void, pa_context *c, pa_context_notify_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_set_subscribe_callback, void, pa_context *c, pa_context_subscribe_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_subscribe, pa_operation*, pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata);
-LL_PA_SYM(true, pa_context_unref, void, pa_context *c);
-LL_PA_SYM(true, pa_cvolume_set, pa_cvolume*, pa_cvolume *a, unsigned channels, pa_volume_t v);
-LL_PA_SYM(true, pa_operation_unref, void, pa_operation *o);
-LL_PA_SYM(true, pa_proplist_free, void, pa_proplist* p);
-LL_PA_SYM(true, pa_proplist_gets, const char*, pa_proplist *p, const char *key);
-LL_PA_SYM(true, pa_proplist_new, pa_proplist*, void);
-LL_PA_SYM(true, pa_proplist_sets, int, pa_proplist *p, const char *key, const char *value);
-LL_PA_SYM(true, pa_sw_volume_from_linear, pa_volume_t, double v);
-
-// optional symbols to grab
diff --git a/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc
deleted file mode 100755
index abf628c96c..0000000000
--- a/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc
+++ /dev/null
@@ -1,6 +0,0 @@
-// required symbols to grab
-LL_PA_SYM(true, pa_glib_mainloop_free, void, pa_glib_mainloop* g);
-LL_PA_SYM(true, pa_glib_mainloop_get_api, pa_mainloop_api*, pa_glib_mainloop* g);
-LL_PA_SYM(true, pa_glib_mainloop_new, pa_glib_mainloop *, GMainContext *c);
-
-// optional symbols to grab
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
deleted file mode 100755
index 3edeef51e3..0000000000
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ /dev/null
@@ -1,1481 +0,0 @@
-/**
- * @file media_plugin_webkit.cpp
- * @brief Webkit plugin for LLMedia API plugin system
- *
- * @cond
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- * @endcond
- */
-#include "llqtwebkit.h"
-#include "linden_common.h"
-#include "indra_constants.h" // for indra keyboard codes
-
-#include "lltimer.h"
-#include "llgl.h"
-
-#include "llplugininstance.h"
-#include "llpluginmessage.h"
-#include "llpluginmessageclasses.h"
-#include "media_plugin_base.h"
-
-// set to 1 if you're using the version of llqtwebkit that's QPixmap-ified
-#if LL_LINUX
-# define LL_QTWEBKIT_USES_PIXMAPS 0
-extern "C" {
-# include <glib.h>
-# include <glib-object.h>
-}
-#else
-# define LL_QTWEBKIT_USES_PIXMAPS 0
-#endif // LL_LINUX
-
-# include "volume_catcher.h"
-
-#if LL_WINDOWS
-# include <direct.h>
-#else
-# include <unistd.h>
-# include <stdlib.h>
-#endif
-
-#if LL_WINDOWS
- // *NOTE:Mani - This captures the module handle for the dll. This is used below
- // to get the path to this dll for webkit initialization.
- // I don't know how/if this can be done with apr...
- namespace { HMODULE gModuleHandle;};
- BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
- {
- gModuleHandle = (HMODULE) hinstDLL;
- return TRUE;
- }
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-//
-class MediaPluginWebKit :
- public MediaPluginBase,
- public LLEmbeddedBrowserWindowObserver
-{
-public:
- MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginWebKit();
-
- /*virtual*/ void receiveMessage(const char *message_string);
-
-private:
-
- std::string mProfileDir;
- std::string mHostLanguage;
- std::string mUserAgent;
- bool mCookiesEnabled;
- bool mJavascriptEnabled;
- bool mPluginsEnabled;
- bool mEnableMediaPluginDebugging;
-
- enum
- {
- INIT_STATE_UNINITIALIZED, // LLQtWebkit hasn't been set up yet
- INIT_STATE_INITIALIZED, // LLQtWebkit has been set up, but no browser window has been created yet.
- INIT_STATE_NAVIGATING, // Browser instance has been set up and initial navigate to about:blank has been issued
- INIT_STATE_NAVIGATE_COMPLETE, // initial navigate to about:blank has completed
- INIT_STATE_WAIT_REDRAW, // First real navigate begin has been received, waiting for page changed event to start handling redraws
- INIT_STATE_WAIT_COMPLETE, // Waiting for first real navigate complete event
- INIT_STATE_RUNNING // All initialization gymnastics are complete.
- };
- int mBrowserWindowId;
- int mInitState;
- std::string mInitialNavigateURL;
- bool mNeedsUpdate;
-
- bool mCanCut;
- bool mCanCopy;
- bool mCanPaste;
- int mLastMouseX;
- int mLastMouseY;
- bool mFirstFocus;
- F32 mBackgroundR;
- F32 mBackgroundG;
- F32 mBackgroundB;
- std::string mTarget;
- LLTimer mElapsedTime;
-
- VolumeCatcher mVolumeCatcher;
-
- void postDebugMessage( const std::string& msg )
- {
- if ( mEnableMediaPluginDebugging )
- {
- std::stringstream str;
- str << "@Media Msg> " << "[" << (double)mElapsedTime.getElapsedTimeF32() << "] -- " << msg;
-
- LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message");
- debug_message.setValue("message_text", str.str());
- debug_message.setValue("message_level", "info");
- sendMessage(debug_message);
- }
- }
-
- void setInitState(int state)
- {
-// std::cerr << "changing init state to " << state << std::endl;
- mInitState = state;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void update(int milliseconds)
- {
-#if LL_QTLINUX_DOESNT_HAVE_GLIB
- // pump glib generously, as Linux browser plugins are on the
- // glib main loop, even if the browser itself isn't - ugh
- // This is NOT NEEDED if Qt itself was built with glib
- // mainloop integration.
- GMainContext *mainc = g_main_context_default();
- while(g_main_context_iteration(mainc, FALSE));
-#endif // LL_QTLINUX_DOESNT_HAVE_GLIB
-
- // pump qt
- LLQtWebKit::getInstance()->pump( milliseconds );
-
- mVolumeCatcher.pump();
-
- checkEditState();
-
- if(mInitState == INIT_STATE_NAVIGATE_COMPLETE)
- {
- if(!mInitialNavigateURL.empty())
- {
- // We already have the initial navigate URL -- kick off the navigate.
- LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, mInitialNavigateURL );
- mInitialNavigateURL.clear();
- }
- }
-
- if ( (mInitState > INIT_STATE_WAIT_REDRAW) && mNeedsUpdate )
- {
- const unsigned char* browser_pixels = LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId );
-
- unsigned int rowspan = LLQtWebKit::getInstance()->getBrowserRowSpan( mBrowserWindowId );
- unsigned int height = LLQtWebKit::getInstance()->getBrowserHeight( mBrowserWindowId );
-#if !LL_QTWEBKIT_USES_PIXMAPS
- unsigned int buffer_size = rowspan * height;
-#endif // !LL_QTWEBKIT_USES_PIXMAPS
-
-// std::cerr << "webkit plugin: updating" << std::endl;
-
- // TODO: should get rid of this memcpy if possible
- if ( mPixels && browser_pixels )
- {
-// std::cerr << " memcopy of " << buffer_size << " bytes" << std::endl;
-
-#if LL_QTWEBKIT_USES_PIXMAPS
- // copy the pixel data upside-down because of the co-ord system
- for (int y=0; y<height; ++y)
- {
- memcpy( &mPixels[(height-y-1)*rowspan], &browser_pixels[y*rowspan], rowspan );
- }
-#else
- memcpy( mPixels, browser_pixels, buffer_size );
-#endif // LL_QTWEBKIT_USES_PIXMAPS
- }
-
- if ( mWidth > 0 && mHeight > 0 )
- {
-// std::cerr << "Setting dirty, " << mWidth << " x " << mHeight << std::endl;
- setDirty( 0, 0, mWidth, mHeight );
- }
-
- mNeedsUpdate = false;
- };
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- bool initBrowser()
- {
- // already initialized
- if ( mInitState > INIT_STATE_UNINITIALIZED )
- return true;
-
- // set up directories
- char cwd[ FILENAME_MAX ]; // I *think* this is defined on all platforms we use
- if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
- {
- LL_WARNS() << "Couldn't get cwd - probably too long - failing to init." << LL_ENDL;
- return false;
- }
- std::string application_dir = std::string( cwd );
-
-#if LL_LINUX
- // take care to initialize glib properly, because some
- // versions of Qt don't, and we indirectly need it for (some
- // versions of) Flash to not crash the browser.
- if (!g_thread_supported ()) g_thread_init (NULL);
- g_type_init();
-#endif
-
-#if LL_DARWIN
- // When running under the Xcode debugger, there's a setting called "Break on Debugger()/DebugStr()" which defaults to being turned on.
- // This causes the environment variable USERBREAK to be set to 1, which causes these legacy calls to break into the debugger.
- // This wouldn't cause any problems except for the fact that the current release version of the Flash plugin has a call to Debugger() in it
- // which gets hit when the plugin is probed by webkit.
- // Unsetting the environment variable here works around this issue.
- unsetenv("USERBREAK");
-#endif
-
-#if LL_WINDOWS
- //*NOTE:Mani - On windows, at least, the component path is the
- // location of this dll's image file.
- std::string component_dir;
- char dll_path[_MAX_PATH];
- DWORD len = GetModuleFileNameA(gModuleHandle, (LPCH)&dll_path, _MAX_PATH);
- while(len && dll_path[ len ] != ('\\') )
- {
- len--;
- }
- if(len >= 0)
- {
- dll_path[len] = 0;
- component_dir = dll_path;
- }
- else
- {
- // *NOTE:Mani - This case should be an rare exception.
- // GetModuleFileNameA should always give you a full path, no?
- component_dir = application_dir;
- }
-#else
- std::string component_dir = application_dir;
-#endif
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "Component dir set to: " + component_dir );
-
- // window handle - needed on Windows and must be app window.
-#if LL_WINDOWS
- char window_title[ MAX_PATH ];
- GetConsoleTitleA( window_title, MAX_PATH );
- void* native_window_handle = (void*)FindWindowA( NULL, window_title );
-#else
- void* native_window_handle = 0;
-#endif
-
- // main browser initialization
- bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, mProfileDir, native_window_handle );
- if ( result )
- {
- mInitState = INIT_STATE_INITIALIZED;
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "browser initialized okay" );
-
- return true;
- };
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "browser nOT initialized." );
-
- return false;
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- bool initBrowserWindow()
- {
- // already initialized
- if ( mInitState > INIT_STATE_INITIALIZED )
- return true;
-
- // not enough information to initialize the browser yet.
- if ( mWidth < 0 || mHeight < 0 || mDepth < 0 ||
- mTextureWidth < 0 || mTextureHeight < 0 )
- {
- return false;
- };
-
- // Set up host language before creating browser window
- if(!mHostLanguage.empty())
- {
- LLQtWebKit::getInstance()->setHostLanguage(mHostLanguage);
- postDebugMessage( "Setting language to " + mHostLanguage );
- }
-
- // turn on/off cookies based on what host app tells us
- LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled );
-
- // turn on/off plugins based on what host app tells us
- LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled );
-
- // turn on/off Javascript based on what host app tells us
-#if LLQTWEBKIT_API_VERSION >= 11
- LLQtWebKit::getInstance()->enableJavaScript( mJavascriptEnabled );
-#else
- LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled );
-#endif
-
- std::stringstream str;
- str << "Cookies enabled = " << mCookiesEnabled << ", plugins enabled = " << mPluginsEnabled << ", Javascript enabled = " << mJavascriptEnabled;
- postDebugMessage( str.str() );
-
- // create single browser window
- mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight, mTarget);
-
- str.str("");
- str.clear();
- str << "Setting browser window size to " << mWidth << " x " << mHeight;
- postDebugMessage( str.str() );
-
- // tell LLQtWebKit about the size of the browser window
- LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
-
- // observer events that LLQtWebKit emits
- LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this );
-
- // append details to agent string
- LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
- postDebugMessage( "Updating user agent with " + mUserAgent );
-
-#if !LL_QTWEBKIT_USES_PIXMAPS
- // don't flip bitmap
- LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true );
-#endif // !LL_QTWEBKIT_USES_PIXMAPS
-
- // set background color
- // convert background color channels from [0.0, 1.0] to [0, 255];
- LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, int(mBackgroundR * 255.0f), int(mBackgroundG * 255.0f), int(mBackgroundB * 255.0f) );
-
- // Set state _before_ starting the navigate, since onNavigateBegin might get called before this call returns.
- setInitState(INIT_STATE_NAVIGATING);
-
- // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance.
- // FIXME: Re-added this because navigating to a "page" initializes things correctly - especially
- // for the HTTP AUTH dialog issues (DEV-41731). Will fix at a later date.
- // Build a data URL like this: "data:text/html,%3Chtml%3E%3Cbody bgcolor=%22#RRGGBB%22%3E%3C/body%3E%3C/html%3E"
- // where RRGGBB is the background color in HTML style
- std::stringstream url;
-
- url << "data:text/html,%3Chtml%3E%3Cbody%20bgcolor=%22#";
- // convert background color channels from [0.0, 1.0] to [0, 255];
- url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundR * 255.0f);
- url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundG * 255.0f);
- url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundB * 255.0f);
- url << "%22%3E%3C/body%3E%3C/html%3E";
-
- //LL_DEBUGS() << "data url is: " << url.str() << LL_ENDL;
-
- // always display loading overlay now
-#if LLQTWEBKIT_API_VERSION >= 16
- LLQtWebKit::getInstance()->enableLoadingOverlay(mBrowserWindowId, true);
-#else
- LL_WARNS() << "Ignoring enableLoadingOverlay() call (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- str.clear();
- str << "Loading overlay enabled = " << mEnableMediaPluginDebugging << " for mBrowserWindowId = " << mBrowserWindowId;
- postDebugMessage( str.str() );
-
- LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, url.str() );
-// LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" );
-
- return true;
- }
-
- void setVolume(F32 vol);
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onCursorChanged(const EventType& event)
- {
- LLQtWebKit::ECursor llqt_cursor = (LLQtWebKit::ECursor)event.getIntValue();
- std::string name;
-
- switch(llqt_cursor)
- {
- case LLQtWebKit::C_ARROW:
- name = "arrow";
- break;
- case LLQtWebKit::C_IBEAM:
- name = "ibeam";
- break;
- case LLQtWebKit::C_SPLITV:
- name = "splitv";
- break;
- case LLQtWebKit::C_SPLITH:
- name = "splith";
- break;
- case LLQtWebKit::C_POINTINGHAND:
- name = "hand";
- break;
-
- default:
- LL_WARNS() << "Unknown cursor ID: " << (int)llqt_cursor << LL_ENDL;
- break;
- }
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed");
- message.setValue("name", name);
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onPageChanged( const EventType& event )
- {
- if(mInitState == INIT_STATE_WAIT_REDRAW)
- {
- setInitState(INIT_STATE_WAIT_COMPLETE);
- }
-
- // flag that an update is required
- mNeedsUpdate = true;
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onNavigateBegin(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
- message.setValue("uri", event.getEventUri());
- message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK));
- message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD));
- sendMessage(message);
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "Navigate begin event at: " + event.getEventUri() );
-
- setStatus(STATUS_LOADING);
- }
-
- if(mInitState == INIT_STATE_NAVIGATE_COMPLETE)
- {
- // Skip the WAIT_REDRAW state now -- with the right background color set, it should no longer be necessary.
-// setInitState(INIT_STATE_WAIT_REDRAW);
- setInitState(INIT_STATE_WAIT_COMPLETE);
- }
-
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onNavigateComplete(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- if(mInitState < INIT_STATE_RUNNING)
- {
- setInitState(INIT_STATE_RUNNING);
-
- // Clear the history, so the "back" button doesn't take you back to "about:blank".
- LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId);
- }
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
- message.setValue("uri", event.getEventUri());
- message.setValueS32("result_code", event.getIntValue());
- message.setValue("result_string", event.getStringValue());
- message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK));
- message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD));
- sendMessage(message);
-
- setStatus(STATUS_LOADED);
- }
- else if(mInitState == INIT_STATE_NAVIGATING)
- {
- setInitState(INIT_STATE_NAVIGATE_COMPLETE);
- }
-
- // debug spam sent to viewer and displayed in the log as usual
- postDebugMessage( "Navigate complete event at: " + event.getEventUri() );
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onUpdateProgress(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "progress");
- message.setValueS32("percent", event.getIntValue());
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onStatusTextChange(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
- message.setValue("status", event.getStringValue());
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onTitleChange(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
- message.setValue("name", event.getStringValue());
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onNavigateErrorPage(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_error_page");
- message.setValueS32("status_code", event.getIntValue());
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onLocationChange(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
- message.setValue("uri", event.getEventUri());
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onClickLinkHref(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
- message.setValue("uri", event.getEventUri());
- message.setValue("target", event.getStringValue());
- message.setValue("uuid", event.getStringValue2());
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onClickLinkNoFollow(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
- message.setValue("uri", event.getEventUri());
-#if LLQTWEBKIT_API_VERSION >= 7
- message.setValue("nav_type", event.getNavigationType());
-#else
- message.setValue("nav_type", "clicked");
-#endif
- sendMessage(message);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onCookieChanged(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookie_set");
- message.setValue("cookie", event.getStringValue());
- // These could be passed through as well, but aren't really needed.
-// message.setValue("uri", event.getEventUri());
-// message.setValueBoolean("dead", (event.getIntValue() != 0))
-
- // debug spam
- postDebugMessage( "Sending cookie_set message from plugin: " + event.getStringValue() );
-
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onWindowCloseRequested(const EventType& event)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "close_request");
- message.setValue("uuid", event.getStringValue());
- sendMessage(message);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onWindowGeometryChangeRequested(const EventType& event)
- {
- int x, y, width, height;
- event.getRectValue(x, y, width, height);
-
- // This sometimes gets called with a zero-size request. Don't pass these along.
- if(width > 0 && height > 0)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "geometry_change");
- message.setValue("uuid", event.getStringValue());
- message.setValueS32("x", x);
- message.setValueS32("y", y);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- sendMessage(message);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- std::string onRequestFilePicker( const EventType& eventIn )
- {
- return blockingPickFile();
- }
-
- std::string mAuthUsername;
- std::string mAuthPassword;
- bool mAuthOK;
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- bool onAuthRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password)
- {
- mAuthOK = false;
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request");
- message.setValue("url", in_url);
- message.setValue("realm", in_realm);
- message.setValueBoolean("blocking_request", true);
-
- // The "blocking_request" key in the message means this sendMessage call will block until a response is received.
- sendMessage(message);
-
- if(mAuthOK)
- {
- out_username = mAuthUsername;
- out_password = mAuthPassword;
- }
-
- return mAuthOK;
- }
-
- void authResponse(LLPluginMessage &message)
- {
- mAuthOK = message.getValueBoolean("ok");
- if(mAuthOK)
- {
- mAuthUsername = message.getValue("username");
- mAuthPassword = message.getValue("password");
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // virtual
- void onLinkHovered(const EventType& event)
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "link_hovered");
- message.setValue("link", event.getEventUri());
- message.setValue("title", event.getStringValue());
- message.setValue("text", event.getStringValue2());
- sendMessage(message);
- }
- }
-
- LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers)
- {
- int result = 0;
-
- if(modifiers.find("shift") != std::string::npos)
- result |= LLQtWebKit::KM_MODIFIER_SHIFT;
-
- if(modifiers.find("alt") != std::string::npos)
- result |= LLQtWebKit::KM_MODIFIER_ALT;
-
- if(modifiers.find("control") != std::string::npos)
- result |= LLQtWebKit::KM_MODIFIER_CONTROL;
-
- if(modifiers.find("meta") != std::string::npos)
- result |= LLQtWebKit::KM_MODIFIER_META;
-
- return (LLQtWebKit::EKeyboardModifier)result;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void deserializeKeyboardData( LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers )
- {
- native_scan_code = 0;
- native_virtual_key = 0;
- native_modifiers = 0;
-
- if( native_key_data.isMap() )
- {
-#if LL_DARWIN
- native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger());
- native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger());
- native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
-#elif LL_WINDOWS
- native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
- native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
- // TODO: I don't think we need to do anything with native modifiers here -- please verify
-#elif LL_LINUX
- native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
- native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
- native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
-#else
- // Add other platforms here as needed
-#endif
- };
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
- {
- // The incoming values for 'key' will be the ones from indra_constants.h
- std::string utf8_text;
-
- if(key < KEY_SPECIAL)
- {
- // Low-ascii characters need to get passed through.
- utf8_text = (char)key;
- }
-
- // Any special-case handling we want to do for particular keys...
- switch((KEY)key)
- {
- // ASCII codes for some standard keys
- case LLQtWebKit::KEY_BACKSPACE: utf8_text = (char)8; break;
- case LLQtWebKit::KEY_TAB: utf8_text = (char)9; break;
- case LLQtWebKit::KEY_RETURN: utf8_text = (char)13; break;
- case LLQtWebKit::KEY_PAD_RETURN: utf8_text = (char)13; break;
- case LLQtWebKit::KEY_ESCAPE: utf8_text = (char)27; break;
-
- default:
- break;
- }
-
-// std::cerr << "key event " << (int)key_event << ", native_key_data = " << native_key_data << std::endl;
-
- uint32_t native_scan_code = 0;
- uint32_t native_virtual_key = 0;
- uint32_t native_modifiers = 0;
- deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers );
-
- LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
-
- checkEditState();
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
- {
- uint32_t key = LLQtWebKit::KEY_NONE;
-
-// std::cerr << "unicode input, native_key_data = " << native_key_data << std::endl;
-
- if(utf8str.size() == 1)
- {
- // The only way a utf8 string can be one byte long is if it's actually a single 7-bit ascii character.
- // In this case, use it as the key value.
- key = utf8str[0];
- }
-
- uint32_t native_scan_code = 0;
- uint32_t native_virtual_key = 0;
- uint32_t native_modifiers = 0;
- deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers );
-
- LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
- LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
-
- checkEditState();
- };
-
- void checkEditState(void)
- {
- bool can_cut = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT);
- bool can_copy = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY);
- bool can_paste = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE);
-
- if((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste))
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state");
-
- if(can_cut != mCanCut)
- {
- mCanCut = can_cut;
- message.setValueBoolean("cut", can_cut);
- }
-
- if(can_copy != mCanCopy)
- {
- mCanCopy = can_copy;
- message.setValueBoolean("copy", can_copy);
- }
-
- if(can_paste != mCanPaste)
- {
- mCanPaste = can_paste;
- message.setValueBoolean("paste", can_paste);
- }
-
- sendMessage(message);
-
- }
- }
-
- std::string mPickedFile;
-
- std::string blockingPickFile(void)
- {
- mPickedFile.clear();
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
- message.setValueBoolean("blocking_request", true);
-
- // The "blocking_request" key in the message means this sendMessage call will block until a response is received.
- sendMessage(message);
-
- return mPickedFile;
- }
-
- void onPickFileResponse(const std::string &file)
- {
- mPickedFile = file;
- }
-
-};
-
-MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
- MediaPluginBase(host_send_func, host_user_data)
-{
-// std::cerr << "MediaPluginWebKit constructor" << std::endl;
-
- mBrowserWindowId = 0;
- mInitState = INIT_STATE_UNINITIALIZED;
- mNeedsUpdate = true;
- mCanCut = false;
- mCanCopy = false;
- mCanPaste = false;
- mLastMouseX = 0;
- mLastMouseY = 0;
- mFirstFocus = true;
- mBackgroundR = 0.0f;
- mBackgroundG = 0.0f;
- mBackgroundB = 0.0f;
-
- mHostLanguage = "en"; // default to english
- mJavascriptEnabled = true; // default to on
- mPluginsEnabled = true; // default to on
- mEnableMediaPluginDebugging = false;
- mUserAgent = "LLPluginMedia Web Browser";
-
- mElapsedTime.reset();
-}
-
-MediaPluginWebKit::~MediaPluginWebKit()
-{
- // unhook observer
- LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this );
-
- // clean up
- LLQtWebKit::getInstance()->reset();
-
-// std::cerr << "MediaPluginWebKit destructor" << std::endl;
-}
-
-void MediaPluginWebKit::receiveMessage(const char *message_string)
-{
-// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
- LLPluginMessage message_in;
-
- if(message_in.parse(message_string) >= 0)
- {
- std::string message_class = message_in.getClass();
- std::string message_name = message_in.getName();
- if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
- {
- if(message_name == "init")
- {
- LLPluginMessage message("base", "init_response");
- LLSD versions = LLSD::emptyMap();
- versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
- message.setValueLLSD("versions", versions);
-
- std::string plugin_version = "Webkit media plugin, Webkit version ";
- plugin_version += LLQtWebKit::getInstance()->getVersion();
- message.setValue("plugin_version", plugin_version);
- sendMessage(message);
- }
- else if(message_name == "idle")
- {
- // no response is necessary here.
- F64 time = message_in.getValueReal("time");
-
- // Convert time to milliseconds for update()
- update((int)(time * 1000.0f));
- }
- else if(message_name == "cleanup")
- {
- // DTOR most likely won't be called but the recent change to the way this process
- // is (not) killed means we see this message and can do what we need to here.
- // Note: this cleanup is ultimately what writes cookies to the disk
- LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this );
- LLQtWebKit::getInstance()->reset();
- }
- else if(message_name == "shm_added")
- {
- SharedSegmentInfo info;
- info.mAddress = message_in.getValuePointer("address");
- info.mSize = (size_t)message_in.getValueS32("size");
- std::string name = message_in.getValue("name");
-
-// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name
-// << ", size: " << info.mSize
-// << ", address: " << info.mAddress
-// << std::endl;
-
- mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
-
- }
- else if(message_name == "shm_remove")
- {
- std::string name = message_in.getValue("name");
-
-// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory remove, name = " << name << std::endl;
-
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if(iter != mSharedSegments.end())
- {
- if(mPixels == iter->second.mAddress)
- {
- // This is the currently active pixel buffer. Make sure we stop drawing to it.
- mPixels = NULL;
- mTextureSegmentName.clear();
- }
- mSharedSegments.erase(iter);
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
- }
-
- // Send the response so it can be cleaned up.
- LLPluginMessage message("base", "shm_remove_response");
- message.setValue("name", name);
- sendMessage(message);
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
- }
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
- {
- if(message_name == "set_volume")
- {
- F32 volume = (F32)message_in.getValueReal("volume");
- setVolume(volume);
- }
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
- {
- if(message_name == "init")
- {
- mTarget = message_in.getValue("target");
-
- // This is the media init message -- all necessary data for initialization should have been received.
- if(initBrowser())
- {
-
- // Plugin gets to decide the texture parameters to use.
- mDepth = 4;
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
- message.setValueS32("default_width", 1024);
- message.setValueS32("default_height", 1024);
- message.setValueS32("depth", mDepth);
- message.setValueU32("internalformat", GL_RGBA);
- #if LL_QTWEBKIT_USES_PIXMAPS
- message.setValueU32("format", GL_BGRA_EXT); // I hope this isn't system-dependant... is it? If so, we'll have to check the root window's pixel layout or something... yuck.
- #else
- message.setValueU32("format", GL_RGBA);
- #endif // LL_QTWEBKIT_USES_PIXMAPS
- message.setValueU32("type", GL_UNSIGNED_BYTE);
- message.setValueBoolean("coords_opengl", true);
- sendMessage(message);
- }
- else
- {
- // if initialization failed, we're done.
- mDeleteMe = true;
- }
-
- }
- else if(message_name == "set_user_data_path")
- {
- std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter
- mProfileDir = user_data_path + "browser_profile";
-
- // FIXME: Should we do anything with this if it comes in after the browser has been initialized?
- }
- else if(message_name == "set_language_code")
- {
- mHostLanguage = message_in.getValue("language");
-
- // FIXME: Should we do anything with this if it comes in after the browser has been initialized?
- }
- else if(message_name == "plugins_enabled")
- {
- mPluginsEnabled = message_in.getValueBoolean("enable");
- }
- else if(message_name == "javascript_enabled")
- {
- mJavascriptEnabled = message_in.getValueBoolean("enable");
- }
- else if(message_name == "size_change")
- {
- std::string name = message_in.getValue("name");
- S32 width = message_in.getValueS32("width");
- S32 height = message_in.getValueS32("height");
- S32 texture_width = message_in.getValueS32("texture_width");
- S32 texture_height = message_in.getValueS32("texture_height");
- mBackgroundR = (F32)message_in.getValueReal("background_r");
- mBackgroundG = (F32)message_in.getValueReal("background_g");
- mBackgroundB = (F32)message_in.getValueReal("background_b");
-// mBackgroundA = message_in.setValueReal("background_a"); // Ignore any alpha
-
- if(!name.empty())
- {
- // Find the shared memory region with this name
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if(iter != mSharedSegments.end())
- {
- mPixels = (unsigned char*)iter->second.mAddress;
- mWidth = width;
- mHeight = height;
-
- if(initBrowserWindow())
- {
-
- // size changed so tell the browser
- LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
-
- // std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight
- // << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl;
-
- S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId);
-
- // The actual width the browser will be drawing to is probably smaller... let the host know by modifying texture_width in the response.
- if(real_width <= texture_width)
- {
- texture_width = real_width;
- }
- else
- {
- // This won't work -- it'll be bigger than the allocated memory. This is a fatal error.
- // std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl;
- mDeleteMe = true;
- return;
- }
- }
- else
- {
- // Setting up the browser window failed. This is a fatal error.
- mDeleteMe = true;
- }
-
-
- mTextureWidth = texture_width;
- mTextureHeight = texture_height;
-
- };
- };
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
- message.setValue("name", name);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- message.setValueS32("texture_width", texture_width);
- message.setValueS32("texture_height", texture_height);
- sendMessage(message);
-
- }
- else if(message_name == "load_uri")
- {
- std::string uri = message_in.getValue("uri");
-
-// std::cout << "loading URI: " << uri << std::endl;
-
- if(!uri.empty())
- {
- if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
- {
- LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, uri );
- }
- else
- {
- mInitialNavigateURL = uri;
- }
- }
- }
- else if(message_name == "mouse_event")
- {
- std::string event = message_in.getValue("event");
- S32 button = message_in.getValueS32("button");
- mLastMouseX = message_in.getValueS32("x");
- mLastMouseY = message_in.getValueS32("y");
- std::string modifiers = message_in.getValue("modifiers");
-
- // Treat unknown mouse events as mouse-moves.
- LLQtWebKit::EMouseEvent mouse_event = LLQtWebKit::ME_MOUSE_MOVE;
- if(event == "down")
- {
- mouse_event = LLQtWebKit::ME_MOUSE_DOWN;
- }
- else if(event == "up")
- {
- mouse_event = LLQtWebKit::ME_MOUSE_UP;
- }
- else if(event == "double_click")
- {
- mouse_event = LLQtWebKit::ME_MOUSE_DOUBLE_CLICK;
- }
-
- LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId, mouse_event, button, mLastMouseX, mLastMouseY, decodeModifiers(modifiers));
- checkEditState();
- }
- else if(message_name == "scroll_event")
- {
- S32 x = message_in.getValueS32("x");
- S32 y = message_in.getValueS32("y");
- std::string modifiers = message_in.getValue("modifiers");
-
- // Incoming scroll events are adjusted so that 1 detent is approximately 1 unit.
- // Qt expects 1 detent to be 120 units.
- // It also seems that our y scroll direction is inverted vs. what Qt expects.
-
- x *= 120;
- y *= -120;
-
- LLQtWebKit::getInstance()->scrollWheelEvent(mBrowserWindowId, mLastMouseX, mLastMouseY, x, y, decodeModifiers(modifiers));
- }
- else if(message_name == "key_event")
- {
- std::string event = message_in.getValue("event");
- S32 key = message_in.getValueS32("key");
- std::string modifiers = message_in.getValue("modifiers");
- LLSD native_key_data = message_in.getValueLLSD("native_key_data");
-
- // Treat unknown events as key-up for safety.
- LLQtWebKit::EKeyEvent key_event = LLQtWebKit::KE_KEY_UP;
- if(event == "down")
- {
- key_event = LLQtWebKit::KE_KEY_DOWN;
- }
- else if(event == "repeat")
- {
- key_event = LLQtWebKit::KE_KEY_REPEAT;
- }
-
- keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
- }
- else if(message_name == "text_event")
- {
- std::string text = message_in.getValue("text");
- std::string modifiers = message_in.getValue("modifiers");
- LLSD native_key_data = message_in.getValueLLSD("native_key_data");
-
- unicodeInput(text, decodeModifiers(modifiers), native_key_data);
- }
- if(message_name == "edit_cut")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT );
- checkEditState();
- }
- if(message_name == "edit_copy")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY );
- checkEditState();
- }
- if(message_name == "edit_paste")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE );
- checkEditState();
- }
- if(message_name == "pick_file_response")
- {
- onPickFileResponse(message_in.getValue("file"));
- }
- if(message_name == "auth_response")
- {
- authResponse(message_in);
- }
- else
- if(message_name == "enable_media_plugin_debugging")
- {
- mEnableMediaPluginDebugging = message_in.getValueBoolean( "enable" );
- }
- else
- if(message_name == "js_enable_object")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- bool enable = message_in.getValueBoolean( "enable" );
- LLQtWebKit::getInstance()->setSLObjectEnabled( enable );
-#endif
- }
- else
- if(message_name == "js_agent_location")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- F32 x = (F32)message_in.getValueReal("x");
- F32 y = (F32)message_in.getValueReal("y");
- F32 z = (F32)message_in.getValueReal("z");
- LLQtWebKit::getInstance()->setAgentLocation( x, y, z );
- LLQtWebKit::getInstance()->emitLocation();
-#endif
- }
- else
- if(message_name == "js_agent_global_location")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- F32 x = (F32)message_in.getValueReal("x");
- F32 y = (F32)message_in.getValueReal("y");
- F32 z = (F32)message_in.getValueReal("z");
- LLQtWebKit::getInstance()->setAgentGlobalLocation( x, y, z );
- LLQtWebKit::getInstance()->emitLocation();
-#endif
- }
- else
- if(message_name == "js_agent_orientation")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- F32 angle = (F32)message_in.getValueReal("angle");
- LLQtWebKit::getInstance()->setAgentOrientation( angle );
- LLQtWebKit::getInstance()->emitLocation();
-#endif
- }
- else
- if(message_name == "js_agent_region")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- const std::string& region = message_in.getValue("region");
- LLQtWebKit::getInstance()->setAgentRegion( region );
- LLQtWebKit::getInstance()->emitLocation();
-#endif
- }
- else
- if(message_name == "js_agent_maturity")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- const std::string& maturity = message_in.getValue("maturity");
- LLQtWebKit::getInstance()->setAgentMaturity( maturity );
- LLQtWebKit::getInstance()->emitMaturity();
-#endif
- }
- else
- if(message_name == "js_agent_language")
- {
-#if LLQTWEBKIT_API_VERSION >= 9
- const std::string& language = message_in.getValue("language");
- LLQtWebKit::getInstance()->setAgentLanguage( language );
- LLQtWebKit::getInstance()->emitLanguage();
-#endif
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
- }
- }
- else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
- {
- if(message_name == "focus")
- {
- bool val = message_in.getValueBoolean("focused");
- LLQtWebKit::getInstance()->focusBrowser( mBrowserWindowId, val );
-
- if(mFirstFocus && val)
- {
- // On the first focus, post a tab key event. This fixes a problem with initial focus.
- std::string empty;
- keyEvent(LLQtWebKit::KE_KEY_DOWN, KEY_TAB, decodeModifiers(empty));
- keyEvent(LLQtWebKit::KE_KEY_UP, KEY_TAB, decodeModifiers(empty));
- mFirstFocus = false;
- }
- }
- else if(message_name == "set_page_zoom_factor")
- {
-#if LLQTWEBKIT_API_VERSION >= 15
- F32 factor = (F32)message_in.getValueReal("factor");
- LLQtWebKit::getInstance()->setPageZoomFactor(factor);
-#else
- LL_WARNS() << "Ignoring setPageZoomFactor message (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- }
- else if(message_name == "clear_cache")
- {
- LLQtWebKit::getInstance()->clearCache();
- }
- else if(message_name == "clear_cookies")
- {
- LLQtWebKit::getInstance()->clearAllCookies();
- }
- else if(message_name == "enable_cookies")
- {
- mCookiesEnabled = message_in.getValueBoolean("enable");
- LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled );
- }
- else if(message_name == "enable_plugins")
- {
- mPluginsEnabled = message_in.getValueBoolean("enable");
- LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled );
- }
- else if(message_name == "enable_javascript")
- {
- mJavascriptEnabled = message_in.getValueBoolean("enable");
- //LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled );
- }
- else if(message_name == "set_cookies")
- {
- LLQtWebKit::getInstance()->setCookies(message_in.getValue("cookies"));
-
- // debug spam
- postDebugMessage( "Plugin setting cookie: " + message_in.getValue("cookies") );
- }
- else if(message_name == "proxy_setup")
- {
- bool val = message_in.getValueBoolean("enable");
- std::string host = message_in.getValue("host");
- int port = message_in.getValueS32("port");
- LLQtWebKit::getInstance()->enableProxy( val, host, port );
- }
- else if(message_name == "browse_stop")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_STOP );
- }
- else if(message_name == "browse_reload")
- {
- // foo = message_in.getValueBoolean("ignore_cache");
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_RELOAD );
- }
- else if(message_name == "browse_forward")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD );
- }
- else if(message_name == "browse_back")
- {
- LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK );
- }
- else if(message_name == "set_status_redirect")
- {
- int code = message_in.getValueS32("code");
- std::string url = message_in.getValue("url");
- if ( 404 == code ) // browser lib only supports 404 right now
- {
-#if LLQTWEBKIT_API_VERSION < 8
- LLQtWebKit::getInstance()->set404RedirectUrl( mBrowserWindowId, url );
-#endif
- };
- }
- else if(message_name == "set_user_agent")
- {
- mUserAgent = message_in.getValue("user_agent");
- LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
- }
- else if(message_name == "show_web_inspector")
- {
-#if LLQTWEBKIT_API_VERSION >= 10
- bool val = message_in.getValueBoolean("show");
- LLQtWebKit::getInstance()->showWebInspector( val );
-#else
- LL_WARNS() << "Ignoring showWebInspector message (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- }
- else if(message_name == "ignore_ssl_cert_errors")
- {
-#if LLQTWEBKIT_API_VERSION >= 3
- LLQtWebKit::getInstance()->setIgnoreSSLCertErrors( message_in.getValueBoolean("ignore") );
-#else
- LL_WARNS() << "Ignoring ignore_ssl_cert_errors message (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- }
- else if(message_name == "add_certificate_file_path")
- {
-#if LLQTWEBKIT_API_VERSION >= 6
- LLQtWebKit::getInstance()->setCAFile( message_in.getValue("path") );
-#else
- LL_WARNS() << "Ignoring add_certificate_file_path message (llqtwebkit version is too old)." << LL_ENDL;
-#endif
- }
- else if(message_name == "init_history")
- {
- // Initialize browser history
- LLSD history = message_in.getValueLLSD("history");
- // First, clear the URL history
- LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId);
- // Then, add the history items in order
- LLSD::array_iterator iter_history = history.beginArray();
- LLSD::array_iterator end_history = history.endArray();
- for(; iter_history != end_history; ++iter_history)
- {
- std::string url = (*iter_history).asString();
- if(! url.empty()) {
- LLQtWebKit::getInstance()->prependHistoryUrl(mBrowserWindowId, url);
- }
- }
- }
- else if(message_name == "proxy_window_opened")
- {
- std::string target = message_in.getValue("target");
- std::string uuid = message_in.getValue("uuid");
- LLQtWebKit::getInstance()->proxyWindowOpened(mBrowserWindowId, target, uuid);
- }
- else if(message_name == "proxy_window_closed")
- {
- std::string uuid = message_in.getValue("uuid");
- LLQtWebKit::getInstance()->proxyWindowClosed(mBrowserWindowId, uuid);
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl;
- };
- }
- else
- {
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
- };
- }
-}
-
-void MediaPluginWebKit::setVolume(F32 volume)
-{
- mVolumeCatcher.setVolume(volume);
-}
-
-int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
-{
- MediaPluginWebKit *self = new MediaPluginWebKit(host_send_func, host_user_data);
- *plugin_send_func = MediaPluginWebKit::staticReceiveMessage;
- *plugin_user_data = (void*)self;
-
- return 0;
-}
-
-
diff --git a/indra/media_plugins/winmmshim/CMakeLists.txt b/indra/media_plugins/winmmshim/CMakeLists.txt
index bf74f81809..6890589892 100755
--- a/indra/media_plugins/winmmshim/CMakeLists.txt
+++ b/indra/media_plugins/winmmshim/CMakeLists.txt
@@ -22,9 +22,6 @@ set(winmm_shim_HEADER_FILES
list(APPEND winmm_shim_SOURCE_FILES ${winmm_shim_HEADER_FILES})
-set_source_files_properties(${media_plugin_webkit_HEADER_FILES}
- PROPERTIES HEADER_FILE_ONLY TRUE)
-
add_library(winmm_shim
SHARED
${winmm_shim_SOURCE_FILES}