From dbdef626d650de288697848977155e223cbba9ad Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 24 Mar 2015 17:22:58 -0700 Subject: Add new media plugin (currently renders squares as example) in preparation for new CEF code --- indra/media_plugins/cef/CMakeLists.txt | 86 ++++++ indra/media_plugins/cef/media_plugin_cef.cpp | 413 +++++++++++++++++++++++++++ 2 files changed, 499 insertions(+) create mode 100644 indra/media_plugins/cef/CMakeLists.txt create mode 100644 indra/media_plugins/cef/media_plugin_cef.cpp (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt new file mode 100644 index 0000000000..663303f0eb --- /dev/null +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -0,0 +1,86 @@ +# -*- cmake -*- + +project(media_plugin_cef) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLPlugin) +include(LLMath) +include(LLRender) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(MediaPluginBase) +include(OpenGL) + +include(CEFPlugin) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} +) +include_directories(SYSTEM + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ) + + +### media_plugin_cef + +if(NOT WORD_SIZE EQUAL 32) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif(NOT WORD_SIZE EQUAL 32) + +set(media_plugin_cef_SOURCE_FILES + media_plugin_cef.cpp + ) + +add_library(media_plugin_cef + SHARED + ${media_plugin_cef_SOURCE_FILES} +) + +target_link_libraries(media_plugin_cef + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${CEF_PLUGIN_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} +) + +add_dependencies(media_plugin_cef + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + +if (WINDOWS) + set_target_properties( + media_plugin_cef + PROPERTIES + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT" + LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD" + ) +endif (WINDOWS) + +if (DARWIN) + # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name + set_target_properties( + media_plugin_cef + PROPERTIES + PREFIX "" + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_NAME_DIR "@executable_path" + LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" + ) + +endif (DARWIN) diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp new file mode 100644 index 0000000000..ada297373a --- /dev/null +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -0,0 +1,413 @@ +/** + * @file media_plugin_cef.cpp + * @brief CEF (Chromium Embedding Framework) plugin for LLMedia API plugin system + * + * @cond + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#include "linden_common.h" + +#include "llgl.h" +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#include + +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginCEF : + public MediaPluginBase +{ + public: + MediaPluginCEF( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ); + ~MediaPluginCEF(); + + /*virtual*/ void receiveMessage( const char* message_string ); + + private: + bool init(); + void update( F64 milliseconds ); + void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ); + bool mFirstTime; + + time_t mLastUpdateTime; + enum Constants { ENumObjects = 10 }; + unsigned char* mBackgroundPixels; + int mColorR[ ENumObjects ]; + int mColorG[ ENumObjects ]; + int mColorB[ ENumObjects ]; + int mXpos[ ENumObjects ]; + int mYpos[ ENumObjects ]; + int mXInc[ ENumObjects ]; + int mYInc[ ENumObjects ]; + int mBlockSize[ ENumObjects ]; + bool mMouseButtonDown; + bool mStopAction; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginCEF::MediaPluginCEF( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) : + MediaPluginBase( host_send_func, host_user_data ) +{ + mFirstTime = true; + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; + mMouseButtonDown = false; + mStopAction = false; + mLastUpdateTime = 0; + mBackgroundPixels = 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginCEF::~MediaPluginCEF() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::receiveMessage( const char* message_string ) +{ +// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + message.setValueLLSD("versions", versions); + + std::string plugin_version = "CEF plugin 1.0..0"; + message.setValue("plugin_version", plugin_version); + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + F64 time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if(message_name == "cleanup") + { + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + else + { +// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { +// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "init") + { + // Plugin gets to decide the texture parameters to use. + mDepth = 4; + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("default_width", 1024); + message.setValueS32("default_height", 1024); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueU32("format", GL_RGBA); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", true); + sendMessage(message); + } + else if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + }; + }; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + } + else if(message_name == "load_uri") + { + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + if(event == "down") + { + + } + else if(event == "up") + { + } + else if(event == "double_click") + { + } + } + } + else + { +// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; + }; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ) +{ + // make sure we don't write outside the buffer + if ( ( x < 0 ) || ( x >= mWidth ) || ( y < 0 ) || ( y >= mHeight ) ) + return; + + if ( mBackgroundPixels != NULL ) + { + unsigned char *pixel = mBackgroundPixels; + pixel += y * mWidth * mDepth; + pixel += ( x * mDepth ); + pixel[ 0 ] = b; + pixel[ 1 ] = g; + pixel[ 2 ] = r; + + setDirty( x, y, x + 1, y + 1 ); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::update( F64 milliseconds ) +{ + if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 ) + return; + + if ( mPixels == 0 ) + return; + + if ( mFirstTime ) + { + for( int n = 0; n < ENumObjects; ++n ) + { + mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 ); + mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 ); + + mColorR[ n ] = rand() % 0x60 + 0x60; + mColorG[ n ] = rand() % 0x60 + 0x60; + mColorB[ n ] = rand() % 0x60 + 0x60; + + mXInc[ n ] = 0; + while ( mXInc[ n ] == 0 ) + mXInc[ n ] = rand() % 7 - 3; + + mYInc[ n ] = 0; + while ( mYInc[ n ] == 0 ) + mYInc[ n ] = rand() % 9 - 4; + + mBlockSize[ n ] = rand() % 0x30 + 0x10; + }; + + delete [] mBackgroundPixels; + + mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ]; + + mFirstTime = false; + }; + + if ( mStopAction ) + return; + + if ( time( NULL ) > mLastUpdateTime + 3 ) + { + const int num_squares = rand() % 20 + 4; + int sqr1_r = rand() % 0x80 + 0x20; + int sqr1_g = rand() % 0x80 + 0x20; + int sqr1_b = rand() % 0x80 + 0x20; + int sqr2_r = rand() % 0x80 + 0x20; + int sqr2_g = rand() % 0x80 + 0x20; + int sqr2_b = rand() % 0x80 + 0x20; + + for ( int y1 = 0; y1 < num_squares; ++y1 ) + { + for ( int x1 = 0; x1 < num_squares; ++x1 ) + { + int px_start = mWidth * x1 / num_squares; + int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares; + int py_start = mHeight * y1 / num_squares; + int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares; + + for( int y2 = py_start; y2 < py_end; ++y2 ) + { + for( int x2 = px_start; x2 < px_end; ++x2 ) + { + int rowspan = mWidth * mDepth; + + if ( ( y1 % 2 ) ^ ( x1 % 2 ) ) + { + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b; + } + else + { + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b; + }; + }; + }; + }; + }; + + time( &mLastUpdateTime ); + }; + + memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth ); + + for( int n = 0; n < ENumObjects; ++n ) + { + if ( rand() % 50 == 0 ) + { + mXInc[ n ] = 0; + while ( mXInc[ n ] == 0 ) + mXInc[ n ] = rand() % 7 - 3; + + mYInc[ n ] = 0; + while ( mYInc[ n ] == 0 ) + mYInc[ n ] = rand() % 9 - 4; + }; + + if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] ) + mXInc[ n ]= -mXInc[ n ]; + + if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] ) + mYInc[ n ]= -mYInc[ n ]; + + mXpos[ n ] += mXInc[ n ]; + mYpos[ n ] += mYInc[ n ]; + + for( int y = 0; y < mBlockSize[ n ]; ++y ) + { + for( int x = 0; x < mBlockSize[ n ]; ++x ) + { + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ]; + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ]; + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ]; + }; + }; + }; + + setDirty( 0, 0, mWidth, mHeight ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +bool MediaPluginCEF::init() +{ + LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text" ); + message.setValue( "name", "Example Plugin" ); + sendMessage( message ); + + return true; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func, + void* host_user_data, + LLPluginInstance::sendMessageFunction *plugin_send_func, + void **plugin_user_data ) +{ + MediaPluginCEF* self = new MediaPluginCEF( host_send_func, host_user_data ); + *plugin_send_func = MediaPluginCEF::staticReceiveMessage; + *plugin_user_data = ( void* )self; + + return 0; +} + -- cgit v1.2.3 From d368babe7cc84ac6d8532e9d2438620cfa6d172d Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 25 Mar 2015 16:16:51 -0700 Subject: Make VS2013 look inside include/cef folder for headers --- indra/media_plugins/cef/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index 663303f0eb..7465fe727a 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -24,6 +24,7 @@ include_directories( ${LLIMAGE_INCLUDE_DIRS} ${LLRENDER_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS} + ${CEF_INCLUDE_DIR} ) include_directories(SYSTEM ${LLCOMMON_SYSTEM_INCLUDE_DIRS} -- cgit v1.2.3 From 834a94caec7691a957c0816f38ac00d765fa5021 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 26 Mar 2015 04:35:13 +0100 Subject: point to new cef tpl with right headers, update cmaake and viewer_manifest logic to copy files to right place --- indra/media_plugins/cef/media_plugin_cef.cpp | 574 +++++++++++---------------- 1 file changed, 238 insertions(+), 336 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index ada297373a..7f0f40bcaa 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -34,380 +34,282 @@ #include "llpluginmessageclasses.h" #include "media_plugin_base.h" +#include +#include "llCEFLib.h" + #include //////////////////////////////////////////////////////////////////////////////// // class MediaPluginCEF : - public MediaPluginBase + public MediaPluginBase { - public: - MediaPluginCEF( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ); - ~MediaPluginCEF(); - - /*virtual*/ void receiveMessage( const char* message_string ); - - private: - bool init(); - void update( F64 milliseconds ); - void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ); - bool mFirstTime; - - time_t mLastUpdateTime; - enum Constants { ENumObjects = 10 }; - unsigned char* mBackgroundPixels; - int mColorR[ ENumObjects ]; - int mColorG[ ENumObjects ]; - int mColorB[ ENumObjects ]; - int mXpos[ ENumObjects ]; - int mYpos[ ENumObjects ]; - int mXInc[ ENumObjects ]; - int mYInc[ ENumObjects ]; - int mBlockSize[ ENumObjects ]; - bool mMouseButtonDown; - bool mStopAction; +public: + MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginCEF(); + + /*virtual*/ void receiveMessage(const char* message_string); + +private: + bool init(); + void update(F64 milliseconds); + bool mFirstTime; + + // TODO FIX ME + void pageChangedCallback(unsigned char* pixels, int width, int height) + { + if (mPixels && pixels) + { + memcpy(mPixels, pixels, width * height * mDepth); + setDirty(0, 0, mWidth, mHeight); + } + } + + void MediaPluginCEF::postDebugMessage(const std::string& msg); + + bool mEnableMediaPluginDebugging; + LLCEFLib* mLLCEFLib; }; //////////////////////////////////////////////////////////////////////////////// // -MediaPluginCEF::MediaPluginCEF( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) : - MediaPluginBase( host_send_func, host_user_data ) +MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : +MediaPluginBase(host_send_func, host_user_data) { - mFirstTime = true; - mWidth = 0; - mHeight = 0; - mDepth = 4; - mPixels = 0; - mMouseButtonDown = false; - mStopAction = false; - mLastUpdateTime = 0; - mBackgroundPixels = 0; + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; + mEnableMediaPluginDebugging = false; + + mLLCEFLib = new LLCEFLib(); } //////////////////////////////////////////////////////////////////////////////// // MediaPluginCEF::~MediaPluginCEF() { + mLLCEFLib->reset(); } //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::receiveMessage( const char* message_string ) +void MediaPluginCEF::postDebugMessage(const std::string& msg) { -// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; - LLPluginMessage message_in; - - if(message_in.parse(message_string) >= 0) - { - std::string message_class = message_in.getClass(); - std::string message_name = message_in.getName(); - if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) - { - if(message_name == "init") - { - LLPluginMessage message("base", "init_response"); - LLSD versions = LLSD::emptyMap(); - versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; - message.setValueLLSD("versions", versions); - - std::string plugin_version = "CEF plugin 1.0..0"; - message.setValue("plugin_version", plugin_version); - sendMessage(message); - } - else if(message_name == "idle") - { - // no response is necessary here. - F64 time = message_in.getValueReal("time"); - - // Convert time to milliseconds for update() - update((int)(time * 1000.0f)); - } - else if(message_name == "cleanup") - { - } - else if(message_name == "shm_added") - { - SharedSegmentInfo info; - info.mAddress = message_in.getValuePointer("address"); - info.mSize = (size_t)message_in.getValueS32("size"); - std::string name = message_in.getValue("name"); - - mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - - } - else if(message_name == "shm_remove") - { - std::string name = message_in.getValue("name"); - - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - if(mPixels == iter->second.mAddress) - { - // This is the currently active pixel buffer. Make sure we stop drawing to it. - mPixels = NULL; - mTextureSegmentName.clear(); - } - mSharedSegments.erase(iter); - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; - } - - // Send the response so it can be cleaned up. - LLPluginMessage message("base", "shm_remove_response"); - message.setValue("name", name); - sendMessage(message); - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) - { - if(message_name == "init") - { - // Plugin gets to decide the texture parameters to use. - mDepth = 4; - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - message.setValueS32("default_width", 1024); - message.setValueS32("default_height", 1024); - message.setValueS32("depth", mDepth); - message.setValueU32("internalformat", GL_RGB); - message.setValueU32("format", GL_RGBA); - message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", true); - sendMessage(message); - } - else if(message_name == "size_change") - { - std::string name = message_in.getValue("name"); - S32 width = message_in.getValueS32("width"); - S32 height = message_in.getValueS32("height"); - S32 texture_width = message_in.getValueS32("texture_width"); - S32 texture_height = message_in.getValueS32("texture_height"); - - if(!name.empty()) - { - // Find the shared memory region with this name - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - mPixels = (unsigned char*)iter->second.mAddress; - mWidth = width; - mHeight = height; - - mTextureWidth = texture_width; - mTextureHeight = texture_height; - }; - }; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); - message.setValue("name", name); - message.setValueS32("width", width); - message.setValueS32("height", height); - message.setValueS32("texture_width", texture_width); - message.setValueS32("texture_height", texture_height); - sendMessage(message); - - } - else if(message_name == "load_uri") - { - } - else if(message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - if(event == "down") - { - - } - else if(event == "up") - { - } - else if(event == "double_click") - { - } - } - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; - }; - } + if (mEnableMediaPluginDebugging) + { + std::stringstream str; + str << "@Media Msg> " << msg; + + LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message"); + debug_message.setValue("message_text", str.str()); + debug_message.setValue("message_level", "info"); + sendMessage(debug_message); + } } //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ) +void MediaPluginCEF::receiveMessage(const char* message_string) { - // make sure we don't write outside the buffer - if ( ( x < 0 ) || ( x >= mWidth ) || ( y < 0 ) || ( y >= mHeight ) ) - return; - - if ( mBackgroundPixels != NULL ) - { - unsigned char *pixel = mBackgroundPixels; - pixel += y * mWidth * mDepth; - pixel += ( x * mDepth ); - pixel[ 0 ] = b; - pixel[ 1 ] = g; - pixel[ 2 ] = r; - - setDirty( x, y, x + 1, y + 1 ); - }; + // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if (message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if (message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + message.setValueLLSD("versions", versions); + + std::string plugin_version = "Example plugin 1.0..0"; + message.setValue("plugin_version", plugin_version); + sendMessage(message); + } + else if (message_name == "idle") + { + mLLCEFLib->update(); + } + else if (message_name == "cleanup") + { + } + else if (message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if (message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + if (mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + else + { + // std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + // std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if (message_name == "init") + { + + mLLCEFLib->setPageChangedCallback(std::bind(&MediaPluginCEF::pageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + + bool result = mLLCEFLib->init(1024, 1024); + if (!result) + { + MessageBoxA(0, "FAIL INIT", 0, 0); + } + + // Plugin gets to decide the texture parameters to use. + mDepth = 4; + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("default_width", 1024); + message.setValueS32("default_height", 1024); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueU32("format", GL_BGRA); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", false); + sendMessage(message); + } + else if (message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + if (!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + }; + }; + + mLLCEFLib->setSize(mWidth, mHeight); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + } + else if (message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + mLLCEFLib->navigate(uri); + } + else if (message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + //S32 button = message_in.getValueS32("button"); + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + + + + //std::string modifiers = message_in.getValue("modifiers"); + + if (event == "down") + { + mLLCEFLib->mouseButton(0, true, x, y); + + std::stringstream str; + str << "Mouse down at = " << x << ", " << y; + postDebugMessage(str.str()); + } + else if (event == "up") + { + mLLCEFLib->mouseButton(0, false, x, y); + } + else if (event == "double_click") + { + } + else + { + mLLCEFLib->mouseMove(x, y); + } + } + else + if (message_name == "enable_media_plugin_debugging") + { + mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); + } + } + else + { + // std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; + }; + } } -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::update( F64 milliseconds ) -{ - if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 ) - return; - - if ( mPixels == 0 ) - return; - - if ( mFirstTime ) - { - for( int n = 0; n < ENumObjects; ++n ) - { - mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 ); - mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 ); - - mColorR[ n ] = rand() % 0x60 + 0x60; - mColorG[ n ] = rand() % 0x60 + 0x60; - mColorB[ n ] = rand() % 0x60 + 0x60; - - mXInc[ n ] = 0; - while ( mXInc[ n ] == 0 ) - mXInc[ n ] = rand() % 7 - 3; - - mYInc[ n ] = 0; - while ( mYInc[ n ] == 0 ) - mYInc[ n ] = rand() % 9 - 4; - - mBlockSize[ n ] = rand() % 0x30 + 0x10; - }; - - delete [] mBackgroundPixels; - - mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ]; - - mFirstTime = false; - }; - - if ( mStopAction ) - return; - - if ( time( NULL ) > mLastUpdateTime + 3 ) - { - const int num_squares = rand() % 20 + 4; - int sqr1_r = rand() % 0x80 + 0x20; - int sqr1_g = rand() % 0x80 + 0x20; - int sqr1_b = rand() % 0x80 + 0x20; - int sqr2_r = rand() % 0x80 + 0x20; - int sqr2_g = rand() % 0x80 + 0x20; - int sqr2_b = rand() % 0x80 + 0x20; - - for ( int y1 = 0; y1 < num_squares; ++y1 ) - { - for ( int x1 = 0; x1 < num_squares; ++x1 ) - { - int px_start = mWidth * x1 / num_squares; - int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares; - int py_start = mHeight * y1 / num_squares; - int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares; - - for( int y2 = py_start; y2 < py_end; ++y2 ) - { - for( int x2 = px_start; x2 < px_end; ++x2 ) - { - int rowspan = mWidth * mDepth; - - if ( ( y1 % 2 ) ^ ( x1 % 2 ) ) - { - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b; - } - else - { - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b; - }; - }; - }; - }; - }; - - time( &mLastUpdateTime ); - }; - - memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth ); - - for( int n = 0; n < ENumObjects; ++n ) - { - if ( rand() % 50 == 0 ) - { - mXInc[ n ] = 0; - while ( mXInc[ n ] == 0 ) - mXInc[ n ] = rand() % 7 - 3; - - mYInc[ n ] = 0; - while ( mYInc[ n ] == 0 ) - mYInc[ n ] = rand() % 9 - 4; - }; - - if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] ) - mXInc[ n ]= -mXInc[ n ]; - - if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] ) - mYInc[ n ]= -mYInc[ n ]; - - mXpos[ n ] += mXInc[ n ]; - mYpos[ n ] += mYInc[ n ]; - - for( int y = 0; y < mBlockSize[ n ]; ++y ) - { - for( int x = 0; x < mBlockSize[ n ]; ++x ) - { - mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ]; - mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ]; - mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ]; - }; - }; - }; - - setDirty( 0, 0, mWidth, mHeight ); -}; - //////////////////////////////////////////////////////////////////////////////// // bool MediaPluginCEF::init() { - LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text" ); - message.setValue( "name", "Example Plugin" ); - sendMessage( message ); + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", "Example Plugin"); + sendMessage(message); - return true; + return true; }; //////////////////////////////////////////////////////////////////////////////// // -int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func, - void* host_user_data, - LLPluginInstance::sendMessageFunction *plugin_send_func, - void **plugin_user_data ) +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, + void* host_user_data, + LLPluginInstance::sendMessageFunction *plugin_send_func, + void **plugin_user_data) { - MediaPluginCEF* self = new MediaPluginCEF( host_send_func, host_user_data ); - *plugin_send_func = MediaPluginCEF::staticReceiveMessage; - *plugin_user_data = ( void* )self; + MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data); + *plugin_send_func = MediaPluginCEF::staticReceiveMessage; + *plugin_user_data = (void*)self; - return 0; + return 0; } - -- cgit v1.2.3 From efffc4b0748d1fe950f46aaafe3ded679536d934 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Sat, 28 Mar 2015 01:49:20 +0100 Subject: add support for keyboard (rudimentary & broken), mouse wheel and open links in same page --- indra/media_plugins/cef/media_plugin_cef.cpp | 136 ++++++++++++++++++--------- 1 file changed, 90 insertions(+), 46 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 7f0f40bcaa..2e8e419e02 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -1,30 +1,30 @@ /** - * @file media_plugin_cef.cpp - * @brief CEF (Chromium Embedding Framework) plugin for LLMedia API plugin system - * - * @cond - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * @endcond - */ +* @file media_plugin_cef.cpp +* @brief CEF (Chromium Embedding Framework) plugin for LLMedia API plugin system +* +* @cond +* $LicenseInfo:firstyear=2008&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +* @endcond +*/ #include "linden_common.h" @@ -37,7 +37,7 @@ #include #include "llCEFLib.h" -#include +#include // remove me //////////////////////////////////////////////////////////////////////////////// // @@ -48,19 +48,21 @@ public: MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); ~MediaPluginCEF(); - /*virtual*/ void receiveMessage(const char* message_string); + /*virtual*/ + void receiveMessage(const char* message_string); private: bool init(); - void update(F64 milliseconds); - bool mFirstTime; - // TODO FIX ME + // TODO FIX ME void pageChangedCallback(unsigned char* pixels, int width, int height) { if (mPixels && pixels) { - memcpy(mPixels, pixels, width * height * mDepth); + if (mWidth == width && mHeight == height) + { + memcpy(mPixels, pixels, mWidth * mHeight * mDepth); + } setDirty(0, 0, mWidth, mHeight); } } @@ -80,7 +82,7 @@ MediaPluginBase(host_send_func, host_user_data) mHeight = 0; mDepth = 4; mPixels = 0; - mEnableMediaPluginDebugging = false; + mEnableMediaPluginDebugging = true; mLLCEFLib = new LLCEFLib(); } @@ -96,7 +98,7 @@ MediaPluginCEF::~MediaPluginCEF() // void MediaPluginCEF::postDebugMessage(const std::string& msg) { - if (mEnableMediaPluginDebugging) + //if (mEnableMediaPluginDebugging) { std::stringstream str; str << "@Media Msg> " << msg; @@ -160,7 +162,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { if (mPixels == iter->second.mAddress) { - // This is the currently active pixel buffer. Make sure we stop drawing to it. mPixels = NULL; mTextureSegmentName.clear(); } @@ -168,17 +169,16 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else { - // std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; } - // Send the response so it can be cleaned up. LLPluginMessage message("base", "shm_remove_response"); message.setValue("name", name); sendMessage(message); } else { - // std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; } } else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) @@ -191,7 +191,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) bool result = mLLCEFLib->init(1024, 1024); if (!result) { - MessageBoxA(0, "FAIL INIT", 0, 0); + //MessageBoxA(0, "FAIL INIT", 0, 0); } // Plugin gets to decide the texture parameters to use. @@ -252,14 +252,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string) S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); - - //std::string modifiers = message_in.getValue("modifiers"); if (event == "down") { mLLCEFLib->mouseButton(0, true, x, y); - + mLLCEFLib->setFocus(true); std::stringstream str; str << "Mouse down at = " << x << ", " << y; postDebugMessage(str.str()); @@ -276,15 +274,61 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->mouseMove(x, y); } } - else - if (message_name == "enable_media_plugin_debugging") + else if (message_name == "scroll_event") + { + S32 y = message_in.getValueS32("y"); + const int scaling_factor = 40; + y *= -scaling_factor; + + mLLCEFLib->mouseWheel(y); + } + else if (message_name == "text_event") + { + std::string event = message_in.getValue("event"); + S32 key = message_in.getValue("text")[0]; + std::string modifiers = message_in.getValue("modifiers"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); + + //int native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); + + //if (event == "down") + { + mLLCEFLib->keyPress(key, true); + } + //else + //if (event == "up") { - mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); + mLLCEFLib->keyPress(key, false); } + } + else if (message_name == "key_event") + { + std::string event = message_in.getValue("event"); + //S32 key = message_in.getValueS32("key"); + std::string modifiers = message_in.getValue("modifiers"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); + + int native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); + native_scan_code = 8; + + if (event == "down") + { + mLLCEFLib->keyPress(native_scan_code, true); + } + else + if (event == "up") + { + mLLCEFLib->keyPress(native_scan_code, false); + } + } + else if (message_name == "enable_media_plugin_debugging") + { + mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); + } } else { - // std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; }; } } -- cgit v1.2.3 From 6c203273574dfa23e4363144db63378df60bb3fe Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Mon, 8 Jun 2015 16:47:16 -0700 Subject: Fixed for OS X version - in progress --- indra/media_plugins/cef/media_plugin_cef.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 2e8e419e02..098dd67c0d 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -34,7 +34,8 @@ #include "llpluginmessageclasses.h" #include "media_plugin_base.h" -#include +#include "../../../build-darwin-i386/packages/include/boost/function.hpp" +#include "../../../build-darwin-i386/packages/include/boost/bind.hpp" #include "llCEFLib.h" #include // remove me @@ -67,7 +68,7 @@ private: } } - void MediaPluginCEF::postDebugMessage(const std::string& msg); + void postDebugMessage(const std::string& msg); bool mEnableMediaPluginDebugging; LLCEFLib* mLLCEFLib; @@ -186,9 +187,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string) if (message_name == "init") { - mLLCEFLib->setPageChangedCallback(std::bind(&MediaPluginCEF::pageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3)); - bool result = mLLCEFLib->init(1024, 1024); + LLCEFLibSettings settings; + settings.inital_width = 1024; + settings.inital_height = 1024; + settings.javascript_enabled = true; + settings.cookies_enabled = true; + bool result = mLLCEFLib->init(settings); if (!result) { //MessageBoxA(0, "FAIL INIT", 0, 0); -- cgit v1.2.3 From d80a24803d0865e0bef13bc059b416eed548494d Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 22 Jun 2015 16:14:13 -0700 Subject: I can't believe I really added these lines - pretend you didn't see them --- indra/media_plugins/cef/media_plugin_cef.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 098dd67c0d..187c6a241d 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -34,8 +34,8 @@ #include "llpluginmessageclasses.h" #include "media_plugin_base.h" -#include "../../../build-darwin-i386/packages/include/boost/function.hpp" -#include "../../../build-darwin-i386/packages/include/boost/bind.hpp" +#include "boost/function.hpp" +#include "boost/bind.hpp" #include "llCEFLib.h" #include // remove me -- cgit v1.2.3 From f7908a50294adff3456436074075a677a9c6239b Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 30 Jun 2015 00:07:58 +0100 Subject: Point to new version of LLCefLib with support for second life URLs, version string, navigation commands --- indra/media_plugins/cef/media_plugin_cef.cpp | 143 +++++++++++++++++++++++---- 1 file changed, 124 insertions(+), 19 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 187c6a241d..3b82071ae8 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -38,8 +38,6 @@ #include "boost/bind.hpp" #include "llCEFLib.h" -#include // remove me - //////////////////////////////////////////////////////////////////////////////// // class MediaPluginCEF : @@ -55,19 +53,15 @@ public: private: bool init(); - // TODO FIX ME - void pageChangedCallback(unsigned char* pixels, int width, int height) - { - if (mPixels && pixels) - { - if (mWidth == width && mHeight == height) - { - memcpy(mPixels, pixels, mWidth * mHeight * mDepth); - } - setDirty(0, 0, mWidth, mHeight); - } - } - + void pageChangedCallback(unsigned char* pixels, int width, int height); + void onCustomSchemeURLCallback(std::string url); + void onConsoleMessageCallback(std::string message, std::string source, int line); + void onStatusMessageCallback(std::string value); + void onTitleChangeCallback(std::string title); + void onLoadStartCallback(); + void onLoadEndCallback(int httpStatusCode); + void onNavigateURLCallback(std::string url); + void postDebugMessage(const std::string& msg); bool mEnableMediaPluginDebugging; @@ -99,7 +93,7 @@ MediaPluginCEF::~MediaPluginCEF() // void MediaPluginCEF::postDebugMessage(const std::string& msg) { - //if (mEnableMediaPluginDebugging) + if (mEnableMediaPluginDebugging) { std::stringstream str; str << "@Media Msg> " << msg; @@ -111,6 +105,89 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg) } } +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::pageChangedCallback(unsigned char* pixels, int width, int height) +{ + if (mPixels && pixels) + { + if (mWidth == width && mHeight == height) + { + memcpy(mPixels, pixels, mWidth * mHeight * mDepth); + } + setDirty(0, 0, mWidth, mHeight); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); + message.setValue("uri", url); + message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line) +{ + std::stringstream str; + str << "Console message: " << message << " in file(" << source << ") at line " << line; + postDebugMessage(str.str()); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onStatusMessageCallback(std::string value) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); + message.setValue("status", value); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onTitleChangeCallback(std::string title) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", title); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onLoadStartCallback() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); + //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? + message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); + message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onLoadEndCallback(int httpStatusCode) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); + //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? + message.setValueS32("result_code", httpStatusCode); + message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); + message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onNavigateURLCallback(std::string url) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); + message.setValue("uri", url); + sendMessage(message); +} + //////////////////////////////////////////////////////////////////////////////// // void MediaPluginCEF::receiveMessage(const char* message_string) @@ -133,7 +210,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; message.setValueLLSD("versions", versions); - std::string plugin_version = "Example plugin 1.0..0"; + std::string plugin_version = "CEF plugin 1.0.0"; message.setValue("plugin_version", plugin_version); sendMessage(message); } @@ -186,8 +263,15 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { if (message_name == "init") { - + // event callbacks from LLCefLib mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3)); + mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1)); + mLLCEFLib->setOnConsoleMessageCallback(boost::bind(&MediaPluginCEF::onConsoleMessageCallback, this, _1, _2, _3)); + mLLCEFLib->setOnStatusMessageCallback(boost::bind(&MediaPluginCEF::onStatusMessageCallback, this, _1)); + mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1)); + mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this)); + mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); + mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1)); LLCEFLibSettings settings; settings.inital_width = 1024; @@ -197,6 +281,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) bool result = mLLCEFLib->init(settings); if (!result) { +// TODO - return something to indicate failure //MessageBoxA(0, "FAIL INIT", 0, 0); } @@ -332,6 +417,26 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); } } + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) + { + if (message_name == "browse_stop") + { + mLLCEFLib->stop(); + } + else if (message_name == "browse_reload") + { + bool ignore_cache = true; + mLLCEFLib->reload(ignore_cache); + } + else if (message_name == "browse_forward") + { + mLLCEFLib->goForward(); + } + else if (message_name == "browse_back") + { + mLLCEFLib->goBack(); + } + } else { //std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; @@ -344,7 +449,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) bool MediaPluginCEF::init() { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); - message.setValue("name", "Example Plugin"); + message.setValue("name", "CEF Plugin"); sendMessage(message); return true; -- cgit v1.2.3 From d89b4109f9ac3f1ef95480823df292bbc8200347 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 2 Jul 2015 09:39:41 -0700 Subject: 2015 and we still care about line endings.. sigh --- indra/media_plugins/cef/media_plugin_cef.cpp | 100 ++++++++++++++------------- 1 file changed, 53 insertions(+), 47 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 3b82071ae8..358b35bbe2 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -53,15 +53,15 @@ public: private: bool init(); - void pageChangedCallback(unsigned char* pixels, int width, int height); - void onCustomSchemeURLCallback(std::string url); - void onConsoleMessageCallback(std::string message, std::string source, int line); - void onStatusMessageCallback(std::string value); - void onTitleChangeCallback(std::string title); - void onLoadStartCallback(); - void onLoadEndCallback(int httpStatusCode); - void onNavigateURLCallback(std::string url); - + void pageChangedCallback(unsigned char* pixels, int width, int height); + void onCustomSchemeURLCallback(std::string url); + void onConsoleMessageCallback(std::string message, std::string source, int line); + void onStatusMessageCallback(std::string value); + void onTitleChangeCallback(std::string title); + void onLoadStartCallback(); + void onLoadEndCallback(int httpStatusCode); + void onNavigateURLCallback(std::string url); + void postDebugMessage(const std::string& msg); bool mEnableMediaPluginDebugging; @@ -123,10 +123,10 @@ void MediaPluginCEF::pageChangedCallback(unsigned char* pixels, int width, int h // void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); - message.setValue("uri", url); - message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to - sendMessage(message); + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); + message.setValue("uri", url); + message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to + sendMessage(message); } //////////////////////////////////////////////////////////////////////////////// @@ -142,8 +142,8 @@ void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string s // void MediaPluginCEF::onStatusMessageCallback(std::string value) { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); - message.setValue("status", value); + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); + message.setValue("status", value); sendMessage(message); } @@ -151,19 +151,19 @@ void MediaPluginCEF::onStatusMessageCallback(std::string value) // void MediaPluginCEF::onTitleChangeCallback(std::string title) { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); - message.setValue("name", title); - sendMessage(message); + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", title); + sendMessage(message); } //////////////////////////////////////////////////////////////////////////////// // void MediaPluginCEF::onLoadStartCallback() { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); - //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? - message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); - message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); + //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? + message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); + message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); sendMessage(message); } @@ -171,11 +171,11 @@ void MediaPluginCEF::onLoadStartCallback() // void MediaPluginCEF::onLoadEndCallback(int httpStatusCode) { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); - //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? - message.setValueS32("result_code", httpStatusCode); - message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); - message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); + //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? + message.setValueS32("result_code", httpStatusCode); + message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); + message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); sendMessage(message); } @@ -183,9 +183,9 @@ void MediaPluginCEF::onLoadEndCallback(int httpStatusCode) // void MediaPluginCEF::onNavigateURLCallback(std::string url) { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); - message.setValue("uri", url); - sendMessage(message); + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); + message.setValue("uri", url); + sendMessage(message); } //////////////////////////////////////////////////////////////////////////////// @@ -419,23 +419,28 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) { - if (message_name == "browse_stop") - { - mLLCEFLib->stop(); - } - else if (message_name == "browse_reload") - { - bool ignore_cache = true; - mLLCEFLib->reload(ignore_cache); - } - else if (message_name == "browse_forward") - { - mLLCEFLib->goForward(); - } - else if (message_name == "browse_back") - { - mLLCEFLib->goBack(); - } + if (message_name == "set_page_zoom_factor") + { + F32 factor = (F32)message_in.getValueReal("factor"); + mLLCEFLib->setPageZoom(factor); + } + if (message_name == "browse_stop") + { + mLLCEFLib->stop(); + } + else if (message_name == "browse_reload") + { + bool ignore_cache = true; + mLLCEFLib->reload(ignore_cache); + } + else if (message_name == "browse_forward") + { + mLLCEFLib->goForward(); + } + else if (message_name == "browse_back") + { + mLLCEFLib->goBack(); + } } else { @@ -468,3 +473,4 @@ int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, return 0; } + -- cgit v1.2.3 From adb0706aa0f3778fda9921172eaabefd3177dbdc Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 2 Jul 2015 23:56:19 +0100 Subject: plugin and llceflib code for improved mouse support --- indra/media_plugins/cef/media_plugin_cef.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 358b35bbe2..ccb8a93f87 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -339,26 +339,35 @@ void MediaPluginCEF::receiveMessage(const char* message_string) else if (message_name == "mouse_event") { std::string event = message_in.getValue("event"); - //S32 button = message_in.getValueS32("button"); + S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); //std::string modifiers = message_in.getValue("modifiers"); + S32 button = message_in.getValueS32("button"); + EMouseButton btn = MB_MOUSE_BUTTON_LEFT; + if (button == 0) btn = MB_MOUSE_BUTTON_LEFT; + if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT; + if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE; + if (event == "down") { - mLLCEFLib->mouseButton(0, true, x, y); - mLLCEFLib->setFocus(true); + mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y); std::stringstream str; str << "Mouse down at = " << x << ", " << y; postDebugMessage(str.str()); } else if (event == "up") { - mLLCEFLib->mouseButton(0, false, x, y); + mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y); + std::stringstream str; + str << "Mouse up at = " << x << ", " << y; + postDebugMessage(str.str()); } else if (event == "double_click") { + // TODO: do we need this ? } else { -- cgit v1.2.3 From ca49ad736a06aa796610f068f6419c39b8535251 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 10 Jul 2015 01:01:07 +0100 Subject: Initial support for keyboard (in progress) but includes many viewer changes to plumb in Key Up events --- indra/media_plugins/cef/media_plugin_cef.cpp | 189 +++++++++++++++++++++++---- 1 file changed, 161 insertions(+), 28 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index ccb8a93f87..f4ffd6d634 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -27,6 +27,7 @@ */ #include "linden_common.h" +#include "indra_constants.h" // for indra keyboard codes #include "llgl.h" #include "llplugininstance.h" @@ -64,6 +65,12 @@ private: void postDebugMessage(const std::string& msg); + + EKeyboardModifier decodeModifiers(std::string &modifiers); + void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers); + void keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data); + void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data); + bool mEnableMediaPluginDebugging; LLCEFLib* mLLCEFLib; }; @@ -273,15 +280,15 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1)); - LLCEFLibSettings settings; - settings.inital_width = 1024; - settings.inital_height = 1024; - settings.javascript_enabled = true; - settings.cookies_enabled = true; + LLCEFLibSettings settings; + settings.inital_width = 1024; + settings.inital_height = 1024; + settings.javascript_enabled = true; + settings.cookies_enabled = true; bool result = mLLCEFLib->init(settings); if (!result) { -// TODO - return something to indicate failure + // TODO - return something to indicate failure //MessageBoxA(0, "FAIL INIT", 0, 0); } @@ -339,7 +346,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) else if (message_name == "mouse_event") { std::string event = message_in.getValue("event"); - + S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); @@ -354,6 +361,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string) if (event == "down") { mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y); + mLLCEFLib->setFocus(true); + std::stringstream str; str << "Mouse down at = " << x << ", " << y; postDebugMessage(str.str()); @@ -361,6 +370,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) else if (event == "up") { mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y); + std::stringstream str; str << "Mouse up at = " << x << ", " << y; postDebugMessage(str.str()); @@ -384,42 +394,31 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else if (message_name == "text_event") { - std::string event = message_in.getValue("event"); - S32 key = message_in.getValue("text")[0]; + std::string text = message_in.getValue("text"); std::string modifiers = message_in.getValue("modifiers"); LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - //int native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); - - //if (event == "down") - { - mLLCEFLib->keyPress(key, true); - } - //else - //if (event == "up") - { - mLLCEFLib->keyPress(key, false); - } + unicodeInput(text, decodeModifiers(modifiers), native_key_data); } else if (message_name == "key_event") { std::string event = message_in.getValue("event"); - //S32 key = message_in.getValueS32("key"); + S32 key = message_in.getValueS32("key"); std::string modifiers = message_in.getValue("modifiers"); LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - int native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); - native_scan_code = 8; - + // Treat unknown events as key-up for safety. + EKeyEvent key_event = KE_KEY_UP; if (event == "down") { - mLLCEFLib->keyPress(native_scan_code, true); + key_event = KE_KEY_DOWN; } - else - if (event == "up") + else if (event == "repeat") { - mLLCEFLib->keyPress(native_scan_code, false); + key_event = KE_KEY_REPEAT; } + + keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); } else if (message_name == "enable_media_plugin_debugging") { @@ -458,6 +457,140 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } } +EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers) +{ + int result = 0; + + if (modifiers.find("shift") != std::string::npos) + result |= KM_MODIFIER_SHIFT; + + if (modifiers.find("alt") != std::string::npos) + result |= KM_MODIFIER_ALT; + + if (modifiers.find("control") != std::string::npos) + result |= KM_MODIFIER_CONTROL; + + if (modifiers.find("meta") != std::string::npos) + result |= KM_MODIFIER_META; + + return (EKeyboardModifier)result; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers) +{ + native_scan_code = 0; + native_virtual_key = 0; + native_modifiers = 0; + + if (native_key_data.isMap()) + { +#if LL_DARWIN + native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger()); + native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger()); + native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); +#elif LL_WINDOWS + native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); + native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); + // TODO: I don't think we need to do anything with native modifiers here -- please verify +#endif + }; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +{ + // The incoming values for 'key' will be the ones from indra_constants.h + std::string utf8_text; + + if (key < 128) + { + // Low-ascii characters need to get passed through. + utf8_text = (char)key; + } + + // Any special-case handling we want to do for particular keys... + switch ((KEY)key) + { + // ASCII codes for some standard keys + case KEY_BACKSPACE: utf8_text = (char)8; break; + case KEY_TAB: utf8_text = (char)9; break; + case KEY_RETURN: utf8_text = (char)13; break; + case KEY_PAD_RETURN: utf8_text = (char)13; break; + case KEY_ESCAPE: utf8_text = (char)27; break; + + default: + break; + } + + uint32_t native_scan_code = 0; + uint32_t native_virtual_key = 0; + uint32_t native_modifiers = 0; + deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); + + //std::stringstream str; + //str << "@@@@@ KEYBOARD EVENT native_modifiers = " << native_modifiers; + //postDebugMessage(str.str()); + + mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); + + + std::stringstream str; + str << "@@@@@@@@@@@@@@@@ MediaPluginCEF::keyEvent"; + postDebugMessage(str.str()); + + //uint32_t msg = native_key_data["msg"].asInteger(); + //uint32_t wparam = native_key_data["w_param"].asInteger(); + //uint64_t lparam = native_key_data["l_param"].asInteger(); + + //std::stringstream str; + //str << "@@@@@@@@@@@@@@@@ keyEvent Native message" << msg << ", " << wparam << ", " << lparam; + //postDebugMessage(str.str()); + + //mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); + + + //checkEditState(); +}; + +void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +{ + uint32_t key = KEY_NONE; + + if (utf8str.size() == 1) + { + // The only way a utf8 string can be one byte long is if it's actually a single 7-bit ascii character. + // In this case, use it as the key value. + key = utf8str[0]; + } + + uint32_t native_scan_code = 0; + uint32_t native_virtual_key = 0; + uint32_t native_modifiers = 0; + deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); + + std::stringstream str; + str << "@@@@@@@@@@@@@@@@ MediaPluginCEF::unicodeInput"; + postDebugMessage(str.str()); + + //uint32_t msg = native_key_data["msg"].asInteger(); + //uint32_t wparam = native_key_data["w_param"].asInteger(); + //uint64_t lparam = native_key_data["l_param"].asInteger(); + + //std::stringstream str; + //str << "@@@@@@@@@@@@@@@@ unicodeInput Native message" << msg << ", " << wparam << ", " << lparam; + //postDebugMessage(str.str()); + + //mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); + + mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); + mLLCEFLib->keyboardEvent(KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); + + // checkEditState(); +}; + //////////////////////////////////////////////////////////////////////////////// // bool MediaPluginCEF::init() -- cgit v1.2.3 From 83a9ae7b3c66e87179362f0da9fa7a378b1527e2 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 15 Jul 2015 02:27:33 +0100 Subject: New keyboard code for windows that uses system messages directly and works ok. Points to new LLCEFLib --- indra/media_plugins/cef/media_plugin_cef.cpp | 90 +++------------------------- 1 file changed, 9 insertions(+), 81 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index f4ffd6d634..c1724fba3e 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -30,6 +30,7 @@ #include "indra_constants.h" // for indra keyboard codes #include "llgl.h" +#include "llsdutil.h" #include "llplugininstance.h" #include "llpluginmessage.h" #include "llpluginmessageclasses.h" @@ -502,93 +503,20 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat // void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) { - // The incoming values for 'key' will be the ones from indra_constants.h - std::string utf8_text; + U32 msg = ll_U32_from_sd(native_key_data["msg"]); + U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); + U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); - if (key < 128) - { - // Low-ascii characters need to get passed through. - utf8_text = (char)key; - } - - // Any special-case handling we want to do for particular keys... - switch ((KEY)key) - { - // ASCII codes for some standard keys - case KEY_BACKSPACE: utf8_text = (char)8; break; - case KEY_TAB: utf8_text = (char)9; break; - case KEY_RETURN: utf8_text = (char)13; break; - case KEY_PAD_RETURN: utf8_text = (char)13; break; - case KEY_ESCAPE: utf8_text = (char)27; break; - - default: - break; - } - - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); - - //std::stringstream str; - //str << "@@@@@ KEYBOARD EVENT native_modifiers = " << native_modifiers; - //postDebugMessage(str.str()); - - mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); - - - std::stringstream str; - str << "@@@@@@@@@@@@@@@@ MediaPluginCEF::keyEvent"; - postDebugMessage(str.str()); - - //uint32_t msg = native_key_data["msg"].asInteger(); - //uint32_t wparam = native_key_data["w_param"].asInteger(); - //uint64_t lparam = native_key_data["l_param"].asInteger(); - - //std::stringstream str; - //str << "@@@@@@@@@@@@@@@@ keyEvent Native message" << msg << ", " << wparam << ", " << lparam; - //postDebugMessage(str.str()); - - //mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); - - - //checkEditState(); + mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); }; void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) { - uint32_t key = KEY_NONE; - - if (utf8str.size() == 1) - { - // The only way a utf8 string can be one byte long is if it's actually a single 7-bit ascii character. - // In this case, use it as the key value. - key = utf8str[0]; - } - - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); - - std::stringstream str; - str << "@@@@@@@@@@@@@@@@ MediaPluginCEF::unicodeInput"; - postDebugMessage(str.str()); - - //uint32_t msg = native_key_data["msg"].asInteger(); - //uint32_t wparam = native_key_data["w_param"].asInteger(); - //uint64_t lparam = native_key_data["l_param"].asInteger(); - - //std::stringstream str; - //str << "@@@@@@@@@@@@@@@@ unicodeInput Native message" << msg << ", " << wparam << ", " << lparam; - //postDebugMessage(str.str()); - - //mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); - - mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); - mLLCEFLib->keyboardEvent(KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); + U32 msg = ll_U32_from_sd(native_key_data["msg"]); + U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); + U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); - // checkEditState(); + mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); }; //////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 224cfc6ec0624561d433afe8a38598f132def913 Mon Sep 17 00:00:00 2001 From: callum Date: Wed, 15 Jul 2015 18:43:57 -0700 Subject: Still making small changes to try to fix OS X keyboards --- indra/media_plugins/cef/media_plugin_cef.cpp | 53 ++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index c1724fba3e..f07eef28f4 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -403,6 +403,20 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else if (message_name == "key_event") { +#if LL_DARWIN + std::string event = message_in.getValue("event"); + S32 key = message_in.getValueS32("key"); + if (event == "down") + { + mLLCEFLib->keyPress(key, true); + } + else if (event == "up") + { + mLLCEFLib->keyPress(key, false); + } + +#elif LL_WINDOWS + std::string event = message_in.getValue("event"); S32 key = message_in.getValueS32("key"); std::string modifiers = message_in.getValue("modifiers"); @@ -420,6 +434,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); + +#endif + } else if (message_name == "enable_media_plugin_debugging") { @@ -495,7 +512,7 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); // TODO: I don't think we need to do anything with native modifiers here -- please verify -#endif +#endif }; }; @@ -503,20 +520,50 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat // void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) { +#if LL_DARWIN + std::string utf8_text; + + if (key < 128) + { + utf8_text = (char)key; + } + + switch ((KEY)key) + { + case KEY_BACKSPACE: utf8_text = (char)8; break; + case KEY_TAB: utf8_text = (char)9; break; + case KEY_RETURN: utf8_text = (char)13; break; + case KEY_PAD_RETURN: utf8_text = (char)13; break; + case KEY_ESCAPE: utf8_text = (char)27; break; + + default: + break; + } + + uint32_t native_scan_code = 0; + uint32_t native_virtual_key = 0; + uint32_t native_modifiers = 0; + deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); + + mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); +#elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); - mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); +#endif }; void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) { +#if LL_DARWIN + mLLCEFLib->keyPress(utf8str[0], true); +#elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); - mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); +#endif }; //////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 0d6d281cb3c54b08eb845199ba24992bddcf9bae Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 16 Jul 2015 16:11:19 -0700 Subject: Point to LLCEFLib with updated 2357 version and support for setting language for embedded browser --- indra/media_plugins/cef/media_plugin_cef.cpp | 1193 +++++++++++++------------- 1 file changed, 600 insertions(+), 593 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index f07eef28f4..70a8eb5d9b 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -1,593 +1,600 @@ -/** -* @file media_plugin_cef.cpp -* @brief CEF (Chromium Embedding Framework) plugin for LLMedia API plugin system -* -* @cond -* $LicenseInfo:firstyear=2008&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2010, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -* @endcond -*/ - -#include "linden_common.h" -#include "indra_constants.h" // for indra keyboard codes - -#include "llgl.h" -#include "llsdutil.h" -#include "llplugininstance.h" -#include "llpluginmessage.h" -#include "llpluginmessageclasses.h" -#include "media_plugin_base.h" - -#include "boost/function.hpp" -#include "boost/bind.hpp" -#include "llCEFLib.h" - -//////////////////////////////////////////////////////////////////////////////// -// -class MediaPluginCEF : - public MediaPluginBase -{ -public: - MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginCEF(); - - /*virtual*/ - void receiveMessage(const char* message_string); - -private: - bool init(); - - void pageChangedCallback(unsigned char* pixels, int width, int height); - void onCustomSchemeURLCallback(std::string url); - void onConsoleMessageCallback(std::string message, std::string source, int line); - void onStatusMessageCallback(std::string value); - void onTitleChangeCallback(std::string title); - void onLoadStartCallback(); - void onLoadEndCallback(int httpStatusCode); - void onNavigateURLCallback(std::string url); - - void postDebugMessage(const std::string& msg); - - - EKeyboardModifier decodeModifiers(std::string &modifiers); - void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers); - void keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data); - void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data); - - bool mEnableMediaPluginDebugging; - LLCEFLib* mLLCEFLib; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : -MediaPluginBase(host_send_func, host_user_data) -{ - mWidth = 0; - mHeight = 0; - mDepth = 4; - mPixels = 0; - mEnableMediaPluginDebugging = true; - - mLLCEFLib = new LLCEFLib(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -MediaPluginCEF::~MediaPluginCEF() -{ - mLLCEFLib->reset(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::postDebugMessage(const std::string& msg) -{ - if (mEnableMediaPluginDebugging) - { - std::stringstream str; - str << "@Media Msg> " << msg; - - LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message"); - debug_message.setValue("message_text", str.str()); - debug_message.setValue("message_level", "info"); - sendMessage(debug_message); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::pageChangedCallback(unsigned char* pixels, int width, int height) -{ - if (mPixels && pixels) - { - if (mWidth == width && mHeight == height) - { - memcpy(mPixels, pixels, mWidth * mHeight * mDepth); - } - setDirty(0, 0, mWidth, mHeight); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); - message.setValue("uri", url); - message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line) -{ - std::stringstream str; - str << "Console message: " << message << " in file(" << source << ") at line " << line; - postDebugMessage(str.str()); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onStatusMessageCallback(std::string value) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); - message.setValue("status", value); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onTitleChangeCallback(std::string title) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); - message.setValue("name", title); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onLoadStartCallback() -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); - //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? - message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); - message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onLoadEndCallback(int httpStatusCode) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); - //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? - message.setValueS32("result_code", httpStatusCode); - message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); - message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onNavigateURLCallback(std::string url) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); - message.setValue("uri", url); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::receiveMessage(const char* message_string) -{ - // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; - LLPluginMessage message_in; - - if (message_in.parse(message_string) >= 0) - { - std::string message_class = message_in.getClass(); - std::string message_name = message_in.getName(); - if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE) - { - if (message_name == "init") - { - LLPluginMessage message("base", "init_response"); - LLSD versions = LLSD::emptyMap(); - versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; - message.setValueLLSD("versions", versions); - - std::string plugin_version = "CEF plugin 1.0.0"; - message.setValue("plugin_version", plugin_version); - sendMessage(message); - } - else if (message_name == "idle") - { - mLLCEFLib->update(); - } - else if (message_name == "cleanup") - { - } - else if (message_name == "shm_added") - { - SharedSegmentInfo info; - info.mAddress = message_in.getValuePointer("address"); - info.mSize = (size_t)message_in.getValueS32("size"); - std::string name = message_in.getValue("name"); - - mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - - } - else if (message_name == "shm_remove") - { - std::string name = message_in.getValue("name"); - - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if (iter != mSharedSegments.end()) - { - if (mPixels == iter->second.mAddress) - { - mPixels = NULL; - mTextureSegmentName.clear(); - } - mSharedSegments.erase(iter); - } - else - { - //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; - } - - LLPluginMessage message("base", "shm_remove_response"); - message.setValue("name", name); - sendMessage(message); - } - else - { - //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; - } - } - else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) - { - if (message_name == "init") - { - // event callbacks from LLCefLib - mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3)); - mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1)); - mLLCEFLib->setOnConsoleMessageCallback(boost::bind(&MediaPluginCEF::onConsoleMessageCallback, this, _1, _2, _3)); - mLLCEFLib->setOnStatusMessageCallback(boost::bind(&MediaPluginCEF::onStatusMessageCallback, this, _1)); - mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1)); - mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this)); - mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); - mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1)); - - LLCEFLibSettings settings; - settings.inital_width = 1024; - settings.inital_height = 1024; - settings.javascript_enabled = true; - settings.cookies_enabled = true; - bool result = mLLCEFLib->init(settings); - if (!result) - { - // TODO - return something to indicate failure - //MessageBoxA(0, "FAIL INIT", 0, 0); - } - - // Plugin gets to decide the texture parameters to use. - mDepth = 4; - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - message.setValueS32("default_width", 1024); - message.setValueS32("default_height", 1024); - message.setValueS32("depth", mDepth); - message.setValueU32("internalformat", GL_RGB); - message.setValueU32("format", GL_BGRA); - message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", false); - sendMessage(message); - } - else if (message_name == "size_change") - { - std::string name = message_in.getValue("name"); - S32 width = message_in.getValueS32("width"); - S32 height = message_in.getValueS32("height"); - S32 texture_width = message_in.getValueS32("texture_width"); - S32 texture_height = message_in.getValueS32("texture_height"); - - if (!name.empty()) - { - // Find the shared memory region with this name - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if (iter != mSharedSegments.end()) - { - mPixels = (unsigned char*)iter->second.mAddress; - mWidth = width; - mHeight = height; - - mTextureWidth = texture_width; - mTextureHeight = texture_height; - }; - }; - - mLLCEFLib->setSize(mWidth, mHeight); - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); - message.setValue("name", name); - message.setValueS32("width", width); - message.setValueS32("height", height); - message.setValueS32("texture_width", texture_width); - message.setValueS32("texture_height", texture_height); - sendMessage(message); - - } - else if (message_name == "load_uri") - { - std::string uri = message_in.getValue("uri"); - mLLCEFLib->navigate(uri); - } - else if (message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - - S32 x = message_in.getValueS32("x"); - S32 y = message_in.getValueS32("y"); - - //std::string modifiers = message_in.getValue("modifiers"); - - S32 button = message_in.getValueS32("button"); - EMouseButton btn = MB_MOUSE_BUTTON_LEFT; - if (button == 0) btn = MB_MOUSE_BUTTON_LEFT; - if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT; - if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE; - - if (event == "down") - { - mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y); - mLLCEFLib->setFocus(true); - - std::stringstream str; - str << "Mouse down at = " << x << ", " << y; - postDebugMessage(str.str()); - } - else if (event == "up") - { - mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y); - - std::stringstream str; - str << "Mouse up at = " << x << ", " << y; - postDebugMessage(str.str()); - } - else if (event == "double_click") - { - // TODO: do we need this ? - } - else - { - mLLCEFLib->mouseMove(x, y); - } - } - else if (message_name == "scroll_event") - { - S32 y = message_in.getValueS32("y"); - const int scaling_factor = 40; - y *= -scaling_factor; - - mLLCEFLib->mouseWheel(y); - } - else if (message_name == "text_event") - { - std::string text = message_in.getValue("text"); - std::string modifiers = message_in.getValue("modifiers"); - LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - - unicodeInput(text, decodeModifiers(modifiers), native_key_data); - } - else if (message_name == "key_event") - { -#if LL_DARWIN - std::string event = message_in.getValue("event"); - S32 key = message_in.getValueS32("key"); - if (event == "down") - { - mLLCEFLib->keyPress(key, true); - } - else if (event == "up") - { - mLLCEFLib->keyPress(key, false); - } - -#elif LL_WINDOWS - - std::string event = message_in.getValue("event"); - S32 key = message_in.getValueS32("key"); - std::string modifiers = message_in.getValue("modifiers"); - LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - - // Treat unknown events as key-up for safety. - EKeyEvent key_event = KE_KEY_UP; - if (event == "down") - { - key_event = KE_KEY_DOWN; - } - else if (event == "repeat") - { - key_event = KE_KEY_REPEAT; - } - - keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); - -#endif - - } - else if (message_name == "enable_media_plugin_debugging") - { - mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); - } - } - else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) - { - if (message_name == "set_page_zoom_factor") - { - F32 factor = (F32)message_in.getValueReal("factor"); - mLLCEFLib->setPageZoom(factor); - } - if (message_name == "browse_stop") - { - mLLCEFLib->stop(); - } - else if (message_name == "browse_reload") - { - bool ignore_cache = true; - mLLCEFLib->reload(ignore_cache); - } - else if (message_name == "browse_forward") - { - mLLCEFLib->goForward(); - } - else if (message_name == "browse_back") - { - mLLCEFLib->goBack(); - } - } - else - { - //std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; - }; - } -} - -EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers) -{ - int result = 0; - - if (modifiers.find("shift") != std::string::npos) - result |= KM_MODIFIER_SHIFT; - - if (modifiers.find("alt") != std::string::npos) - result |= KM_MODIFIER_ALT; - - if (modifiers.find("control") != std::string::npos) - result |= KM_MODIFIER_CONTROL; - - if (modifiers.find("meta") != std::string::npos) - result |= KM_MODIFIER_META; - - return (EKeyboardModifier)result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers) -{ - native_scan_code = 0; - native_virtual_key = 0; - native_modifiers = 0; - - if (native_key_data.isMap()) - { -#if LL_DARWIN - native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger()); - native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); -#elif LL_WINDOWS - native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); - // TODO: I don't think we need to do anything with native modifiers here -- please verify -#endif - }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) -{ -#if LL_DARWIN - std::string utf8_text; - - if (key < 128) - { - utf8_text = (char)key; - } - - switch ((KEY)key) - { - case KEY_BACKSPACE: utf8_text = (char)8; break; - case KEY_TAB: utf8_text = (char)9; break; - case KEY_RETURN: utf8_text = (char)13; break; - case KEY_PAD_RETURN: utf8_text = (char)13; break; - case KEY_ESCAPE: utf8_text = (char)27; break; - - default: - break; - } - - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); - - mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); -#elif LL_WINDOWS - U32 msg = ll_U32_from_sd(native_key_data["msg"]); - U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); - U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); - mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); -#endif -}; - -void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) -{ -#if LL_DARWIN - mLLCEFLib->keyPress(utf8str[0], true); -#elif LL_WINDOWS - U32 msg = ll_U32_from_sd(native_key_data["msg"]); - U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); - U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); - mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); -#endif -}; - -//////////////////////////////////////////////////////////////////////////////// -// -bool MediaPluginCEF::init() -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); - message.setValue("name", "CEF Plugin"); - sendMessage(message); - - return true; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, - void* host_user_data, - LLPluginInstance::sendMessageFunction *plugin_send_func, - void **plugin_user_data) -{ - MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data); - *plugin_send_func = MediaPluginCEF::staticReceiveMessage; - *plugin_user_data = (void*)self; - - return 0; -} - +/** +* @file media_plugin_cef.cpp +* @brief CEF (Chromium Embedding Framework) plugin for LLMedia API plugin system +* +* @cond +* $LicenseInfo:firstyear=2008&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +* @endcond +*/ + +#include "linden_common.h" +#include "indra_constants.h" // for indra keyboard codes + +#include "llgl.h" +#include "llsdutil.h" +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#include "boost/function.hpp" +#include "boost/bind.hpp" +#include "llCEFLib.h" + +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginCEF : + public MediaPluginBase +{ +public: + MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginCEF(); + + /*virtual*/ + void receiveMessage(const char* message_string); + +private: + bool init(); + + void pageChangedCallback(unsigned char* pixels, int width, int height); + void onCustomSchemeURLCallback(std::string url); + void onConsoleMessageCallback(std::string message, std::string source, int line); + void onStatusMessageCallback(std::string value); + void onTitleChangeCallback(std::string title); + void onLoadStartCallback(); + void onLoadEndCallback(int httpStatusCode); + void onNavigateURLCallback(std::string url); + + void postDebugMessage(const std::string& msg); + + + EKeyboardModifier decodeModifiers(std::string &modifiers); + void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers); + void keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data); + void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data); + + bool mEnableMediaPluginDebugging; + std::string mHostLanguage; + LLCEFLib* mLLCEFLib; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : +MediaPluginBase(host_send_func, host_user_data) +{ + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; + mEnableMediaPluginDebugging = true; + mHostLanguage = "en"; + + mLLCEFLib = new LLCEFLib(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginCEF::~MediaPluginCEF() +{ + mLLCEFLib->reset(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::postDebugMessage(const std::string& msg) +{ + if (mEnableMediaPluginDebugging) + { + std::stringstream str; + str << "@Media Msg> " << msg; + + LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message"); + debug_message.setValue("message_text", str.str()); + debug_message.setValue("message_level", "info"); + sendMessage(debug_message); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::pageChangedCallback(unsigned char* pixels, int width, int height) +{ + if (mPixels && pixels) + { + if (mWidth == width && mHeight == height) + { + memcpy(mPixels, pixels, mWidth * mHeight * mDepth); + } + setDirty(0, 0, mWidth, mHeight); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); + message.setValue("uri", url); + message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line) +{ + std::stringstream str; + str << "Console message: " << message << " in file(" << source << ") at line " << line; + postDebugMessage(str.str()); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onStatusMessageCallback(std::string value) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); + message.setValue("status", value); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onTitleChangeCallback(std::string title) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", title); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onLoadStartCallback() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); + //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? + message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); + message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onLoadEndCallback(int httpStatusCode) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); + //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? + message.setValueS32("result_code", httpStatusCode); + message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); + message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onNavigateURLCallback(std::string url) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); + message.setValue("uri", url); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::receiveMessage(const char* message_string) +{ + // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if (message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if (message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + message.setValueLLSD("versions", versions); + + std::string plugin_version = "CEF plugin 1.0.0"; + message.setValue("plugin_version", plugin_version); + sendMessage(message); + } + else if (message_name == "idle") + { + mLLCEFLib->update(); + } + else if (message_name == "cleanup") + { + } + else if (message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if (message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + if (mPixels == iter->second.mAddress) + { + mPixels = NULL; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + } + + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if (message_name == "init") + { + // event callbacks from LLCefLib + mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3)); + mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1)); + mLLCEFLib->setOnConsoleMessageCallback(boost::bind(&MediaPluginCEF::onConsoleMessageCallback, this, _1, _2, _3)); + mLLCEFLib->setOnStatusMessageCallback(boost::bind(&MediaPluginCEF::onStatusMessageCallback, this, _1)); + mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1)); + mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this)); + mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); + mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1)); + + LLCEFLibSettings settings; + settings.inital_width = 1024; + settings.inital_height = 1024; + settings.javascript_enabled = true; + settings.cookies_enabled = true; + settings.accept_language_list = mHostLanguage; + bool result = mLLCEFLib->init(settings); + if (!result) + { + // TODO - return something to indicate failure + //MessageBoxA(0, "FAIL INIT", 0, 0); + } + + // Plugin gets to decide the texture parameters to use. + mDepth = 4; + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("default_width", 1024); + message.setValueS32("default_height", 1024); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueU32("format", GL_BGRA); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", false); + sendMessage(message); + } + else if (message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + if (!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + }; + }; + + mLLCEFLib->setSize(mWidth, mHeight); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + } + else if (message_name == "set_language_code") + { + mHostLanguage = message_in.getValue("language"); + } + else if (message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + mLLCEFLib->navigate(uri); + } + else if (message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + + //std::string modifiers = message_in.getValue("modifiers"); + + S32 button = message_in.getValueS32("button"); + EMouseButton btn = MB_MOUSE_BUTTON_LEFT; + if (button == 0) btn = MB_MOUSE_BUTTON_LEFT; + if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT; + if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE; + + if (event == "down") + { + mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y); + mLLCEFLib->setFocus(true); + + std::stringstream str; + str << "Mouse down at = " << x << ", " << y; + postDebugMessage(str.str()); + } + else if (event == "up") + { + mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y); + + std::stringstream str; + str << "Mouse up at = " << x << ", " << y; + postDebugMessage(str.str()); + } + else if (event == "double_click") + { + // TODO: do we need this ? + } + else + { + mLLCEFLib->mouseMove(x, y); + } + } + else if (message_name == "scroll_event") + { + S32 y = message_in.getValueS32("y"); + const int scaling_factor = 40; + y *= -scaling_factor; + + mLLCEFLib->mouseWheel(y); + } + else if (message_name == "text_event") + { + std::string text = message_in.getValue("text"); + std::string modifiers = message_in.getValue("modifiers"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); + + unicodeInput(text, decodeModifiers(modifiers), native_key_data); + } + else if (message_name == "key_event") + { +#if LL_DARWIN + std::string event = message_in.getValue("event"); + S32 key = message_in.getValueS32("key"); + if (event == "down") + { + mLLCEFLib->keyPress(key, true); + } + else if (event == "up") + { + mLLCEFLib->keyPress(key, false); + } + +#elif LL_WINDOWS + + std::string event = message_in.getValue("event"); + S32 key = message_in.getValueS32("key"); + std::string modifiers = message_in.getValue("modifiers"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); + + // Treat unknown events as key-up for safety. + EKeyEvent key_event = KE_KEY_UP; + if (event == "down") + { + key_event = KE_KEY_DOWN; + } + else if (event == "repeat") + { + key_event = KE_KEY_REPEAT; + } + + keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); + +#endif + + } + else if (message_name == "enable_media_plugin_debugging") + { + mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); + } + } + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) + { + if (message_name == "set_page_zoom_factor") + { + F32 factor = (F32)message_in.getValueReal("factor"); + mLLCEFLib->setPageZoom(factor); + } + if (message_name == "browse_stop") + { + mLLCEFLib->stop(); + } + else if (message_name == "browse_reload") + { + bool ignore_cache = true; + mLLCEFLib->reload(ignore_cache); + } + else if (message_name == "browse_forward") + { + mLLCEFLib->goForward(); + } + else if (message_name == "browse_back") + { + mLLCEFLib->goBack(); + } + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; + }; + } +} + +EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers) +{ + int result = 0; + + if (modifiers.find("shift") != std::string::npos) + result |= KM_MODIFIER_SHIFT; + + if (modifiers.find("alt") != std::string::npos) + result |= KM_MODIFIER_ALT; + + if (modifiers.find("control") != std::string::npos) + result |= KM_MODIFIER_CONTROL; + + if (modifiers.find("meta") != std::string::npos) + result |= KM_MODIFIER_META; + + return (EKeyboardModifier)result; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers) +{ + native_scan_code = 0; + native_virtual_key = 0; + native_modifiers = 0; + + if (native_key_data.isMap()) + { +#if LL_DARWIN + native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger()); + native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger()); + native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); +#elif LL_WINDOWS + native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); + native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); + // TODO: I don't think we need to do anything with native modifiers here -- please verify +#endif + }; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +{ +#if LL_DARWIN + std::string utf8_text; + + if (key < 128) + { + utf8_text = (char)key; + } + + switch ((KEY)key) + { + case KEY_BACKSPACE: utf8_text = (char)8; break; + case KEY_TAB: utf8_text = (char)9; break; + case KEY_RETURN: utf8_text = (char)13; break; + case KEY_PAD_RETURN: utf8_text = (char)13; break; + case KEY_ESCAPE: utf8_text = (char)27; break; + + default: + break; + } + + uint32_t native_scan_code = 0; + uint32_t native_virtual_key = 0; + uint32_t native_modifiers = 0; + deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); + + mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); +#elif LL_WINDOWS + U32 msg = ll_U32_from_sd(native_key_data["msg"]); + U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); + U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); + mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); +#endif +}; + +void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +{ +#if LL_DARWIN + mLLCEFLib->keyPress(utf8str[0], true); +#elif LL_WINDOWS + U32 msg = ll_U32_from_sd(native_key_data["msg"]); + U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); + U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); + mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); +#endif +}; + +//////////////////////////////////////////////////////////////////////////////// +// +bool MediaPluginCEF::init() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", "CEF Plugin"); + sendMessage(message); + + return true; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, + void* host_user_data, + LLPluginInstance::sendMessageFunction *plugin_send_func, + void **plugin_user_data) +{ + MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data); + *plugin_send_func = MediaPluginCEF::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} + -- cgit v1.2.3 From 8e3acf461e3f3536b621a533d6ab15bc9e0a36be Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 17 Jul 2015 16:14:42 -0700 Subject: Changes to implement enable/disable cookies, javascript, plugins --- indra/media_plugins/cef/media_plugin_cef.cpp | 34 +++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 70a8eb5d9b..4bde7e7d49 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -74,6 +74,9 @@ private: bool mEnableMediaPluginDebugging; std::string mHostLanguage; + bool mCookiesEnabled; + bool mPluginsEnabled; + bool mJavascriptEnabled; LLCEFLib* mLLCEFLib; }; @@ -88,7 +91,9 @@ MediaPluginBase(host_send_func, host_user_data) mPixels = 0; mEnableMediaPluginDebugging = true; mHostLanguage = "en"; - + mCookiesEnabled = true; + mPluginsEnabled = false; + mJavascriptEnabled = true; mLLCEFLib = new LLCEFLib(); } @@ -286,14 +291,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string) LLCEFLibSettings settings; settings.inital_width = 1024; settings.inital_height = 1024; - settings.javascript_enabled = true; - settings.cookies_enabled = true; + settings.plugins_enabled = mPluginsEnabled; + settings.javascript_enabled = mJavascriptEnabled; + settings.cookies_enabled = mCookiesEnabled; settings.accept_language_list = mHostLanguage; bool result = mLLCEFLib->init(settings); if (!result) { - // TODO - return something to indicate failure - //MessageBoxA(0, "FAIL INIT", 0, 0); + // if this fails, the media system in viewer will put up a message } // Plugin gets to decide the texture parameters to use. @@ -423,7 +428,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } #elif LL_WINDOWS - std::string event = message_in.getValue("event"); S32 key = message_in.getValueS32("key"); std::string modifiers = message_in.getValue("modifiers"); @@ -441,9 +445,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); - #endif - } else if (message_name == "enable_media_plugin_debugging") { @@ -474,6 +476,22 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mLLCEFLib->goBack(); } + else if (message_name == "cookies_enabled") + { + mCookiesEnabled = message_in.getValueBoolean("enable"); +std::stringstream str; +str << "@@@@@@@##### cookies_enabled - mCookiesEnabled = " << mCookiesEnabled; +postDebugMessage(str.str()); + + } + else if (message_name == "plugins_enabled") + { + mPluginsEnabled = message_in.getValueBoolean("enable"); + } + else if (message_name == "javascript_enabled") + { + mJavascriptEnabled = message_in.getValueBoolean("enable"); + } } else { -- cgit v1.2.3 From 7cc5db9fdb19d8e798412295280fdf1d86cd0da8 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 24 Jul 2015 23:54:09 +0100 Subject: Include support for http auth. also improve mouse handling with drag select --- indra/media_plugins/cef/media_plugin_cef.cpp | 48 +++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 4bde7e7d49..56bb4e469b 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -52,6 +52,7 @@ public: /*virtual*/ void receiveMessage(const char* message_string); + private: bool init(); @@ -63,9 +64,10 @@ private: void onLoadStartCallback(); void onLoadEndCallback(int httpStatusCode); void onNavigateURLCallback(std::string url); + bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password); void postDebugMessage(const std::string& msg); - + void authResponse(LLPluginMessage &message); EKeyboardModifier decodeModifiers(std::string &modifiers); void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers); @@ -77,6 +79,9 @@ private: bool mCookiesEnabled; bool mPluginsEnabled; bool mJavascriptEnabled; + std::string mAuthUsername; + std::string mAuthPassword; + bool mAuthOK; LLCEFLib* mLLCEFLib; }; @@ -94,6 +99,9 @@ MediaPluginBase(host_send_func, host_user_data) mCookiesEnabled = true; mPluginsEnabled = false; mJavascriptEnabled = true; + mAuthUsername = ""; + mAuthPassword = ""; + mAuthOK = false; mLLCEFLib = new LLCEFLib(); } @@ -203,6 +211,39 @@ void MediaPluginCEF::onNavigateURLCallback(std::string url) sendMessage(message); } +//////////////////////////////////////////////////////////////////////////////// +// +bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password) +{ + mAuthOK = false; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request"); + message.setValue("url", host); + message.setValue("realm", realm); + message.setValueBoolean("blocking_request", true); + + // The "blocking_request" key in the message means this sendMessage call will block until a response is received. + sendMessage(message); + + if (mAuthOK) + { + username = mAuthUsername; + password = mAuthPassword; + } + + return mAuthOK; +} + +void MediaPluginCEF::authResponse(LLPluginMessage &message) +{ + mAuthOK = message.getValueBoolean("ok"); + if (mAuthOK) + { + mAuthUsername = message.getValue("username"); + mAuthPassword = message.getValue("password"); + } +} + //////////////////////////////////////////////////////////////////////////////// // void MediaPluginCEF::receiveMessage(const char* message_string) @@ -287,6 +328,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this)); mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1)); + mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4)); LLCEFLibSettings settings; settings.inital_width = 1024; @@ -451,6 +493,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); } + if (message_name == "auth_response") + { + authResponse(message_in); + } } else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) { -- cgit v1.2.3 From a75a4e2a4f0b8bc65aa45368326fce0e6635c4ac Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 27 Jul 2015 16:09:04 -0700 Subject: Bring in lastest version of LLCEFLIb & set user agent string before browser instance created --- indra/media_plugins/cef/media_plugin_cef.cpp | 1336 +++++++++++++------------- 1 file changed, 674 insertions(+), 662 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 56bb4e469b..fcedc3355d 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -1,664 +1,676 @@ -/** -* @file media_plugin_cef.cpp -* @brief CEF (Chromium Embedding Framework) plugin for LLMedia API plugin system -* -* @cond -* $LicenseInfo:firstyear=2008&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2010, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -* @endcond -*/ - -#include "linden_common.h" -#include "indra_constants.h" // for indra keyboard codes - -#include "llgl.h" -#include "llsdutil.h" -#include "llplugininstance.h" -#include "llpluginmessage.h" -#include "llpluginmessageclasses.h" -#include "media_plugin_base.h" - -#include "boost/function.hpp" -#include "boost/bind.hpp" -#include "llCEFLib.h" - -//////////////////////////////////////////////////////////////////////////////// -// -class MediaPluginCEF : - public MediaPluginBase -{ -public: - MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginCEF(); - - /*virtual*/ - void receiveMessage(const char* message_string); - - -private: - bool init(); - - void pageChangedCallback(unsigned char* pixels, int width, int height); - void onCustomSchemeURLCallback(std::string url); - void onConsoleMessageCallback(std::string message, std::string source, int line); - void onStatusMessageCallback(std::string value); - void onTitleChangeCallback(std::string title); - void onLoadStartCallback(); - void onLoadEndCallback(int httpStatusCode); - void onNavigateURLCallback(std::string url); - bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password); - - void postDebugMessage(const std::string& msg); - void authResponse(LLPluginMessage &message); - - EKeyboardModifier decodeModifiers(std::string &modifiers); - void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers); - void keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data); - void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data); - - bool mEnableMediaPluginDebugging; - std::string mHostLanguage; - bool mCookiesEnabled; - bool mPluginsEnabled; - bool mJavascriptEnabled; - std::string mAuthUsername; - std::string mAuthPassword; - bool mAuthOK; - LLCEFLib* mLLCEFLib; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : -MediaPluginBase(host_send_func, host_user_data) -{ - mWidth = 0; - mHeight = 0; - mDepth = 4; - mPixels = 0; - mEnableMediaPluginDebugging = true; - mHostLanguage = "en"; - mCookiesEnabled = true; - mPluginsEnabled = false; - mJavascriptEnabled = true; - mAuthUsername = ""; - mAuthPassword = ""; - mAuthOK = false; - mLLCEFLib = new LLCEFLib(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -MediaPluginCEF::~MediaPluginCEF() -{ - mLLCEFLib->reset(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::postDebugMessage(const std::string& msg) -{ - if (mEnableMediaPluginDebugging) - { - std::stringstream str; - str << "@Media Msg> " << msg; - - LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message"); - debug_message.setValue("message_text", str.str()); - debug_message.setValue("message_level", "info"); - sendMessage(debug_message); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::pageChangedCallback(unsigned char* pixels, int width, int height) -{ - if (mPixels && pixels) - { - if (mWidth == width && mHeight == height) - { - memcpy(mPixels, pixels, mWidth * mHeight * mDepth); - } - setDirty(0, 0, mWidth, mHeight); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); - message.setValue("uri", url); - message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line) -{ - std::stringstream str; - str << "Console message: " << message << " in file(" << source << ") at line " << line; - postDebugMessage(str.str()); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onStatusMessageCallback(std::string value) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); - message.setValue("status", value); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onTitleChangeCallback(std::string title) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); - message.setValue("name", title); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onLoadStartCallback() -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); - //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? - message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); - message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onLoadEndCallback(int httpStatusCode) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); - //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? - message.setValueS32("result_code", httpStatusCode); - message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); - message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onNavigateURLCallback(std::string url) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); - message.setValue("uri", url); - sendMessage(message); -} - -//////////////////////////////////////////////////////////////////////////////// -// +/** +* @file media_plugin_cef.cpp +* @brief CEF (Chromium Embedding Framework) plugin for LLMedia API plugin system +* +* @cond +* $LicenseInfo:firstyear=2008&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +* @endcond +*/ + +#include "linden_common.h" +#include "indra_constants.h" // for indra keyboard codes + +#include "llgl.h" +#include "llsdutil.h" +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#include "boost/function.hpp" +#include "boost/bind.hpp" +#include "llCEFLib.h" + +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginCEF : + public MediaPluginBase +{ +public: + MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginCEF(); + + /*virtual*/ + void receiveMessage(const char* message_string); + + +private: + bool init(); + + void onPageChangedCallback(unsigned char* pixels, int width, int height); + void onCustomSchemeURLCallback(std::string url); + void onConsoleMessageCallback(std::string message, std::string source, int line); + void onStatusMessageCallback(std::string value); + void onTitleChangeCallback(std::string title); + void onLoadStartCallback(); + void onLoadEndCallback(int httpStatusCode); + void onNavigateURLCallback(std::string url); + bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password); + + void postDebugMessage(const std::string& msg); + void authResponse(LLPluginMessage &message); + + EKeyboardModifier decodeModifiers(std::string &modifiers); + void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers); + void keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data); + void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data); + + bool mEnableMediaPluginDebugging; + std::string mHostLanguage; + bool mCookiesEnabled; + bool mPluginsEnabled; + bool mJavascriptEnabled; + std::string mUserAgentSubtring; + std::string mAuthUsername; + std::string mAuthPassword; + bool mAuthOK; + LLCEFLib* mLLCEFLib; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : +MediaPluginBase(host_send_func, host_user_data) +{ + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; + mEnableMediaPluginDebugging = true; + mHostLanguage = "en"; + mCookiesEnabled = true; + mPluginsEnabled = false; + mJavascriptEnabled = true; + mUserAgentSubtring = ""; + mAuthUsername = ""; + mAuthPassword = ""; + mAuthOK = false; + mLLCEFLib = new LLCEFLib(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginCEF::~MediaPluginCEF() +{ + mLLCEFLib->reset(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::postDebugMessage(const std::string& msg) +{ + if (mEnableMediaPluginDebugging) + { + std::stringstream str; + str << "@Media Msg> " << msg; + + LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message"); + debug_message.setValue("message_text", str.str()); + debug_message.setValue("message_level", "info"); + sendMessage(debug_message); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int width, int height) +{ + if (mPixels && pixels) + { + if (mWidth == width && mHeight == height) + { + memcpy(mPixels, pixels, mWidth * mHeight * mDepth); + } + setDirty(0, 0, mWidth, mHeight); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); + message.setValue("uri", url); + message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line) +{ + std::stringstream str; + str << "Console message: " << message << " in file(" << source << ") at line " << line; + postDebugMessage(str.str()); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onStatusMessageCallback(std::string value) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); + message.setValue("status", value); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onTitleChangeCallback(std::string title) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", title); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onLoadStartCallback() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); + //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? + message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); + message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onLoadEndCallback(int httpStatusCode) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); + //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed? + message.setValueS32("result_code", httpStatusCode); + message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack()); + message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward()); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onNavigateURLCallback(std::string url) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); + message.setValue("uri", url); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password) -{ - mAuthOK = false; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request"); - message.setValue("url", host); - message.setValue("realm", realm); - message.setValueBoolean("blocking_request", true); - - // The "blocking_request" key in the message means this sendMessage call will block until a response is received. - sendMessage(message); - - if (mAuthOK) - { - username = mAuthUsername; - password = mAuthPassword; - } - - return mAuthOK; -} - -void MediaPluginCEF::authResponse(LLPluginMessage &message) -{ - mAuthOK = message.getValueBoolean("ok"); - if (mAuthOK) - { - mAuthUsername = message.getValue("username"); - mAuthPassword = message.getValue("password"); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::receiveMessage(const char* message_string) -{ - // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; - LLPluginMessage message_in; - - if (message_in.parse(message_string) >= 0) - { - std::string message_class = message_in.getClass(); - std::string message_name = message_in.getName(); - if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE) - { - if (message_name == "init") - { - LLPluginMessage message("base", "init_response"); - LLSD versions = LLSD::emptyMap(); - versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; - message.setValueLLSD("versions", versions); - - std::string plugin_version = "CEF plugin 1.0.0"; - message.setValue("plugin_version", plugin_version); - sendMessage(message); - } - else if (message_name == "idle") - { - mLLCEFLib->update(); - } - else if (message_name == "cleanup") - { - } - else if (message_name == "shm_added") - { - SharedSegmentInfo info; - info.mAddress = message_in.getValuePointer("address"); - info.mSize = (size_t)message_in.getValueS32("size"); - std::string name = message_in.getValue("name"); - - mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - - } - else if (message_name == "shm_remove") - { - std::string name = message_in.getValue("name"); - - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if (iter != mSharedSegments.end()) - { - if (mPixels == iter->second.mAddress) - { - mPixels = NULL; - mTextureSegmentName.clear(); - } - mSharedSegments.erase(iter); - } - else - { - //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; - } - - LLPluginMessage message("base", "shm_remove_response"); - message.setValue("name", name); - sendMessage(message); - } - else - { - //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; - } - } - else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) - { - if (message_name == "init") - { - // event callbacks from LLCefLib - mLLCEFLib->setPageChangedCallback(boost::bind(&MediaPluginCEF::pageChangedCallback, this, _1, _2, _3)); - mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1)); - mLLCEFLib->setOnConsoleMessageCallback(boost::bind(&MediaPluginCEF::onConsoleMessageCallback, this, _1, _2, _3)); - mLLCEFLib->setOnStatusMessageCallback(boost::bind(&MediaPluginCEF::onStatusMessageCallback, this, _1)); - mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1)); - mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this)); - mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); - mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1)); +{ + mAuthOK = false; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request"); + message.setValue("url", host); + message.setValue("realm", realm); + message.setValueBoolean("blocking_request", true); + + // The "blocking_request" key in the message means this sendMessage call will block until a response is received. + sendMessage(message); + + if (mAuthOK) + { + username = mAuthUsername; + password = mAuthPassword; + } + + return mAuthOK; +} + +void MediaPluginCEF::authResponse(LLPluginMessage &message) +{ + mAuthOK = message.getValueBoolean("ok"); + if (mAuthOK) + { + mAuthUsername = message.getValue("username"); + mAuthPassword = message.getValue("password"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::receiveMessage(const char* message_string) +{ + // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if (message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if (message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + message.setValueLLSD("versions", versions); + + std::string plugin_version = "CEF plugin 1.0.0"; + message.setValue("plugin_version", plugin_version); + sendMessage(message); + } + else if (message_name == "idle") + { + mLLCEFLib->update(); + } + else if (message_name == "cleanup") + { + } + else if (message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if (message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + if (mPixels == iter->second.mAddress) + { + mPixels = NULL; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + } + + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if (message_name == "init") + { + // event callbacks from LLCefLib + mLLCEFLib->setOnPageChangedCallback(boost::bind(&MediaPluginCEF::onPageChangedCallback, this, _1, _2, _3)); + mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1)); + mLLCEFLib->setOnConsoleMessageCallback(boost::bind(&MediaPluginCEF::onConsoleMessageCallback, this, _1, _2, _3)); + mLLCEFLib->setOnStatusMessageCallback(boost::bind(&MediaPluginCEF::onStatusMessageCallback, this, _1)); + mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1)); + mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this)); + mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); + mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1)); mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4)); - - LLCEFLibSettings settings; - settings.inital_width = 1024; - settings.inital_height = 1024; - settings.plugins_enabled = mPluginsEnabled; - settings.javascript_enabled = mJavascriptEnabled; - settings.cookies_enabled = mCookiesEnabled; - settings.accept_language_list = mHostLanguage; - bool result = mLLCEFLib->init(settings); - if (!result) - { - // if this fails, the media system in viewer will put up a message - } - - // Plugin gets to decide the texture parameters to use. - mDepth = 4; - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - message.setValueS32("default_width", 1024); - message.setValueS32("default_height", 1024); - message.setValueS32("depth", mDepth); - message.setValueU32("internalformat", GL_RGB); - message.setValueU32("format", GL_BGRA); - message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", false); - sendMessage(message); - } - else if (message_name == "size_change") - { - std::string name = message_in.getValue("name"); - S32 width = message_in.getValueS32("width"); - S32 height = message_in.getValueS32("height"); - S32 texture_width = message_in.getValueS32("texture_width"); - S32 texture_height = message_in.getValueS32("texture_height"); - - if (!name.empty()) - { - // Find the shared memory region with this name - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if (iter != mSharedSegments.end()) - { - mPixels = (unsigned char*)iter->second.mAddress; - mWidth = width; - mHeight = height; - - mTextureWidth = texture_width; - mTextureHeight = texture_height; - }; - }; - - mLLCEFLib->setSize(mWidth, mHeight); - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); - message.setValue("name", name); - message.setValueS32("width", width); - message.setValueS32("height", height); - message.setValueS32("texture_width", texture_width); - message.setValueS32("texture_height", texture_height); - sendMessage(message); - - } - else if (message_name == "set_language_code") - { - mHostLanguage = message_in.getValue("language"); - } - else if (message_name == "load_uri") - { - std::string uri = message_in.getValue("uri"); - mLLCEFLib->navigate(uri); - } - else if (message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - - S32 x = message_in.getValueS32("x"); - S32 y = message_in.getValueS32("y"); - - //std::string modifiers = message_in.getValue("modifiers"); - - S32 button = message_in.getValueS32("button"); - EMouseButton btn = MB_MOUSE_BUTTON_LEFT; - if (button == 0) btn = MB_MOUSE_BUTTON_LEFT; - if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT; - if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE; - - if (event == "down") - { - mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y); - mLLCEFLib->setFocus(true); - - std::stringstream str; - str << "Mouse down at = " << x << ", " << y; - postDebugMessage(str.str()); - } - else if (event == "up") - { - mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y); - - std::stringstream str; - str << "Mouse up at = " << x << ", " << y; - postDebugMessage(str.str()); - } - else if (event == "double_click") - { - // TODO: do we need this ? - } - else - { - mLLCEFLib->mouseMove(x, y); - } - } - else if (message_name == "scroll_event") - { - S32 y = message_in.getValueS32("y"); - const int scaling_factor = 40; - y *= -scaling_factor; - - mLLCEFLib->mouseWheel(y); - } - else if (message_name == "text_event") - { - std::string text = message_in.getValue("text"); - std::string modifiers = message_in.getValue("modifiers"); - LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - - unicodeInput(text, decodeModifiers(modifiers), native_key_data); - } - else if (message_name == "key_event") - { -#if LL_DARWIN - std::string event = message_in.getValue("event"); - S32 key = message_in.getValueS32("key"); - if (event == "down") - { - mLLCEFLib->keyPress(key, true); - } - else if (event == "up") - { - mLLCEFLib->keyPress(key, false); - } - -#elif LL_WINDOWS - std::string event = message_in.getValue("event"); - S32 key = message_in.getValueS32("key"); - std::string modifiers = message_in.getValue("modifiers"); - LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - - // Treat unknown events as key-up for safety. - EKeyEvent key_event = KE_KEY_UP; - if (event == "down") - { - key_event = KE_KEY_DOWN; - } - else if (event == "repeat") - { - key_event = KE_KEY_REPEAT; - } - - keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); -#endif - } - else if (message_name == "enable_media_plugin_debugging") - { - mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); - } - if (message_name == "auth_response") - { - authResponse(message_in); - } - } - else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) - { - if (message_name == "set_page_zoom_factor") - { - F32 factor = (F32)message_in.getValueReal("factor"); - mLLCEFLib->setPageZoom(factor); - } - if (message_name == "browse_stop") - { - mLLCEFLib->stop(); - } - else if (message_name == "browse_reload") - { - bool ignore_cache = true; - mLLCEFLib->reload(ignore_cache); - } - else if (message_name == "browse_forward") - { - mLLCEFLib->goForward(); - } - else if (message_name == "browse_back") - { - mLLCEFLib->goBack(); - } - else if (message_name == "cookies_enabled") - { - mCookiesEnabled = message_in.getValueBoolean("enable"); -std::stringstream str; -str << "@@@@@@@##### cookies_enabled - mCookiesEnabled = " << mCookiesEnabled; -postDebugMessage(str.str()); - - } - else if (message_name == "plugins_enabled") - { - mPluginsEnabled = message_in.getValueBoolean("enable"); - } - else if (message_name == "javascript_enabled") - { - mJavascriptEnabled = message_in.getValueBoolean("enable"); - } - } - else - { - //std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; - }; - } -} - -EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers) -{ - int result = 0; - - if (modifiers.find("shift") != std::string::npos) - result |= KM_MODIFIER_SHIFT; - - if (modifiers.find("alt") != std::string::npos) - result |= KM_MODIFIER_ALT; - - if (modifiers.find("control") != std::string::npos) - result |= KM_MODIFIER_CONTROL; - - if (modifiers.find("meta") != std::string::npos) - result |= KM_MODIFIER_META; - - return (EKeyboardModifier)result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers) -{ - native_scan_code = 0; - native_virtual_key = 0; - native_modifiers = 0; - - if (native_key_data.isMap()) - { -#if LL_DARWIN - native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger()); - native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); -#elif LL_WINDOWS - native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); - // TODO: I don't think we need to do anything with native modifiers here -- please verify -#endif - }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) -{ -#if LL_DARWIN - std::string utf8_text; - - if (key < 128) - { - utf8_text = (char)key; - } - - switch ((KEY)key) - { - case KEY_BACKSPACE: utf8_text = (char)8; break; - case KEY_TAB: utf8_text = (char)9; break; - case KEY_RETURN: utf8_text = (char)13; break; - case KEY_PAD_RETURN: utf8_text = (char)13; break; - case KEY_ESCAPE: utf8_text = (char)27; break; - - default: - break; - } - - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); - - mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); -#elif LL_WINDOWS - U32 msg = ll_U32_from_sd(native_key_data["msg"]); - U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); - U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); - mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); -#endif -}; - -void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) -{ -#if LL_DARWIN - mLLCEFLib->keyPress(utf8str[0], true); -#elif LL_WINDOWS - U32 msg = ll_U32_from_sd(native_key_data["msg"]); - U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); - U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); - mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); -#endif -}; - -//////////////////////////////////////////////////////////////////////////////// -// -bool MediaPluginCEF::init() -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); - message.setValue("name", "CEF Plugin"); - sendMessage(message); - - return true; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, - void* host_user_data, - LLPluginInstance::sendMessageFunction *plugin_send_func, - void **plugin_user_data) -{ - MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data); - *plugin_send_func = MediaPluginCEF::staticReceiveMessage; - *plugin_user_data = (void*)self; - - return 0; -} - + + LLCEFLibSettings settings; + settings.inital_width = 1024; + settings.inital_height = 1024; + settings.plugins_enabled = mPluginsEnabled; + settings.javascript_enabled = mJavascriptEnabled; + settings.cookies_enabled = mCookiesEnabled; + settings.accept_language_list = mHostLanguage; + settings.user_agent_substring = mUserAgentSubtring; + + std::stringstream str; + str << "@@@@@@@@@@ Initializing with = user_agent_substring = " << mUserAgentSubtring; + postDebugMessage(str.str()); + + bool result = mLLCEFLib->init(settings); + if (!result) + { + // if this fails, the media system in viewer will put up a message + } + + // Plugin gets to decide the texture parameters to use. + mDepth = 4; + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("default_width", 1024); + message.setValueS32("default_height", 1024); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueU32("format", GL_BGRA); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", false); + sendMessage(message); + } + else if (message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + if (!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + }; + }; + + mLLCEFLib->setSize(mWidth, mHeight); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + } + else if (message_name == "set_language_code") + { + mHostLanguage = message_in.getValue("language"); + } + else if (message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + mLLCEFLib->navigate(uri); + } + else if (message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + + //std::string modifiers = message_in.getValue("modifiers"); + + S32 button = message_in.getValueS32("button"); + EMouseButton btn = MB_MOUSE_BUTTON_LEFT; + if (button == 0) btn = MB_MOUSE_BUTTON_LEFT; + if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT; + if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE; + + if (event == "down") + { + mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y); + mLLCEFLib->setFocus(true); + + std::stringstream str; + str << "Mouse down at = " << x << ", " << y; + postDebugMessage(str.str()); + } + else if (event == "up") + { + mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y); + + std::stringstream str; + str << "Mouse up at = " << x << ", " << y; + postDebugMessage(str.str()); + } + else if (event == "double_click") + { + // TODO: do we need this ? + } + else + { + mLLCEFLib->mouseMove(x, y); + } + } + else if (message_name == "scroll_event") + { + S32 y = message_in.getValueS32("y"); + const int scaling_factor = 40; + y *= -scaling_factor; + + mLLCEFLib->mouseWheel(y); + } + else if (message_name == "text_event") + { + std::string text = message_in.getValue("text"); + std::string modifiers = message_in.getValue("modifiers"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); + + unicodeInput(text, decodeModifiers(modifiers), native_key_data); + } + else if (message_name == "key_event") + { +#if LL_DARWIN + std::string event = message_in.getValue("event"); + S32 key = message_in.getValueS32("key"); + if (event == "down") + { + mLLCEFLib->keyPress(key, true); + } + else if (event == "up") + { + mLLCEFLib->keyPress(key, false); + } + +#elif LL_WINDOWS + std::string event = message_in.getValue("event"); + S32 key = message_in.getValueS32("key"); + std::string modifiers = message_in.getValue("modifiers"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); + + // Treat unknown events as key-up for safety. + EKeyEvent key_event = KE_KEY_UP; + if (event == "down") + { + key_event = KE_KEY_DOWN; + } + else if (event == "repeat") + { + key_event = KE_KEY_REPEAT; + } + + keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); +#endif + } + else if (message_name == "enable_media_plugin_debugging") + { + mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); + } + if (message_name == "auth_response") + { + authResponse(message_in); + } + } + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) + { + if (message_name == "set_page_zoom_factor") + { + F32 factor = (F32)message_in.getValueReal("factor"); + mLLCEFLib->setPageZoom(factor); + } + if (message_name == "browse_stop") + { + mLLCEFLib->stop(); + } + else if (message_name == "browse_reload") + { + bool ignore_cache = true; + mLLCEFLib->reload(ignore_cache); + } + else if (message_name == "browse_forward") + { + mLLCEFLib->goForward(); + } + else if (message_name == "browse_back") + { + mLLCEFLib->goBack(); + } + else if (message_name == "cookies_enabled") + { + mCookiesEnabled = message_in.getValueBoolean("enable"); + } + else if (message_name == "set_user_agent") + { + mUserAgentSubtring = message_in.getValue("user_agent"); + + std::stringstream str; + str << "@@@@@@@@@@ setting mUserAgentSubtring = " << mUserAgentSubtring; + postDebugMessage(str.str()); + } + else if (message_name == "plugins_enabled") + { + mPluginsEnabled = message_in.getValueBoolean("enable"); + } + else if (message_name == "javascript_enabled") + { + mJavascriptEnabled = message_in.getValueBoolean("enable"); + } + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; + }; + } +} + +EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers) +{ + int result = 0; + + if (modifiers.find("shift") != std::string::npos) + result |= KM_MODIFIER_SHIFT; + + if (modifiers.find("alt") != std::string::npos) + result |= KM_MODIFIER_ALT; + + if (modifiers.find("control") != std::string::npos) + result |= KM_MODIFIER_CONTROL; + + if (modifiers.find("meta") != std::string::npos) + result |= KM_MODIFIER_META; + + return (EKeyboardModifier)result; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers) +{ + native_scan_code = 0; + native_virtual_key = 0; + native_modifiers = 0; + + if (native_key_data.isMap()) + { +#if LL_DARWIN + native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger()); + native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger()); + native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); +#elif LL_WINDOWS + native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); + native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); + // TODO: I don't think we need to do anything with native modifiers here -- please verify +#endif + }; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +{ +#if LL_DARWIN + std::string utf8_text; + + if (key < 128) + { + utf8_text = (char)key; + } + + switch ((KEY)key) + { + case KEY_BACKSPACE: utf8_text = (char)8; break; + case KEY_TAB: utf8_text = (char)9; break; + case KEY_RETURN: utf8_text = (char)13; break; + case KEY_PAD_RETURN: utf8_text = (char)13; break; + case KEY_ESCAPE: utf8_text = (char)27; break; + + default: + break; + } + + uint32_t native_scan_code = 0; + uint32_t native_virtual_key = 0; + uint32_t native_modifiers = 0; + deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); + + mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); +#elif LL_WINDOWS + U32 msg = ll_U32_from_sd(native_key_data["msg"]); + U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); + U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); + mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); +#endif +}; + +void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +{ +#if LL_DARWIN + mLLCEFLib->keyPress(utf8str[0], true); +#elif LL_WINDOWS + U32 msg = ll_U32_from_sd(native_key_data["msg"]); + U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); + U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); + mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); +#endif +}; + +//////////////////////////////////////////////////////////////////////////////// +// +bool MediaPluginCEF::init() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", "CEF Plugin"); + sendMessage(message); + + return true; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, + void* host_user_data, + LLPluginInstance::sendMessageFunction *plugin_send_func, + void **plugin_user_data) +{ + MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data); + *plugin_send_func = MediaPluginCEF::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} + -- cgit v1.2.3 From 7505501aea76e014b205d64accf89a9d30abac3a Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 1 Sep 2015 17:43:30 -0700 Subject: get update llceflib with cookie/cache code and implement cache/cookie folders in viewer --- indra/media_plugins/cef/media_plugin_cef.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index fcedc3355d..a0a80e3a3a 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -83,6 +83,8 @@ private: std::string mAuthUsername; std::string mAuthPassword; bool mAuthOK; + std::string mCachePath; + std::string mCookiePath; LLCEFLib* mLLCEFLib; }; @@ -104,6 +106,8 @@ MediaPluginBase(host_send_func, host_user_data) mAuthUsername = ""; mAuthPassword = ""; mAuthOK = false; + mCachePath = ""; + mCookiePath = ""; mLLCEFLib = new LLCEFLib(); } @@ -338,6 +342,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string) settings.plugins_enabled = mPluginsEnabled; settings.javascript_enabled = mJavascriptEnabled; settings.cookies_enabled = mCookiesEnabled; + settings.cache_path = mCachePath; + settings.cookie_store_path = mCookiePath; settings.accept_language_list = mHostLanguage; settings.user_agent_substring = mUserAgentSubtring; @@ -363,6 +369,16 @@ void MediaPluginCEF::receiveMessage(const char* message_string) message.setValueBoolean("coords_opengl", false); sendMessage(message); } + else if (message_name == "set_user_data_path") + { + std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter + mCachePath = user_data_path + "cef_cache"; + mCookiePath = user_data_path + "cef_cookies"; + + std::stringstream str; + str << "@@@@@@@@@@ setting data paths to " << mCachePath << " and " << mCookiePath; + postDebugMessage(str.str()); + } else if (message_name == "size_change") { std::string name = message_in.getValue("name"); -- cgit v1.2.3 From d44eeb48d380215bae0d036976f6daa11082af07 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 1 Sep 2015 17:46:29 -0700 Subject: Remove debugging crud --- indra/media_plugins/cef/media_plugin_cef.cpp | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index a0a80e3a3a..f49187a897 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -83,7 +83,7 @@ private: std::string mAuthUsername; std::string mAuthPassword; bool mAuthOK; - std::string mCachePath; + std::string mCachePath; std::string mCookiePath; LLCEFLib* mLLCEFLib; }; @@ -106,7 +106,7 @@ MediaPluginBase(host_send_func, host_user_data) mAuthUsername = ""; mAuthPassword = ""; mAuthOK = false; - mCachePath = ""; + mCachePath = ""; mCookiePath = ""; mLLCEFLib = new LLCEFLib(); } @@ -347,10 +347,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) settings.accept_language_list = mHostLanguage; settings.user_agent_substring = mUserAgentSubtring; - std::stringstream str; - str << "@@@@@@@@@@ Initializing with = user_agent_substring = " << mUserAgentSubtring; - postDebugMessage(str.str()); - bool result = mLLCEFLib->init(settings); if (!result) { @@ -369,15 +365,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string) message.setValueBoolean("coords_opengl", false); sendMessage(message); } - else if (message_name == "set_user_data_path") - { - std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter - mCachePath = user_data_path + "cef_cache"; - mCookiePath = user_data_path + "cef_cookies"; - - std::stringstream str; - str << "@@@@@@@@@@ setting data paths to " << mCachePath << " and " << mCookiePath; - postDebugMessage(str.str()); + else if (message_name == "set_user_data_path") + { + std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter + mCachePath = user_data_path + "cef_cache"; + mCookiePath = user_data_path + "cef_cookies"; } else if (message_name == "size_change") { @@ -553,10 +545,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) else if (message_name == "set_user_agent") { mUserAgentSubtring = message_in.getValue("user_agent"); - - std::stringstream str; - str << "@@@@@@@@@@ setting mUserAgentSubtring = " << mUserAgentSubtring; - postDebugMessage(str.str()); } else if (message_name == "plugins_enabled") { -- cgit v1.2.3 From 33da4d9d5dd05bbc9dc232525b59017f7ecbbcdd Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 2 Sep 2015 17:31:40 -0700 Subject: Add support for copy/cut/paste into and out of browser (Note - feature in LLQtWebKit (canPaste, canCut etc.) not present so right click menu always enables options --- indra/media_plugins/cef/media_plugin_cef.cpp | 71 +++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index f49187a897..f51a2715bb 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -64,6 +64,7 @@ private: void onLoadStartCallback(); void onLoadEndCallback(int httpStatusCode); void onNavigateURLCallback(std::string url); + void onExternalTargetLinkCallback(std::string url); bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password); void postDebugMessage(const std::string& msg); @@ -74,6 +75,8 @@ private: void keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data); void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data); + void checkEditState(); + bool mEnableMediaPluginDebugging; std::string mHostLanguage; bool mCookiesEnabled; @@ -83,6 +86,9 @@ private: std::string mAuthUsername; std::string mAuthPassword; bool mAuthOK; + bool mCanCut; + bool mCanCopy; + bool mCanPaste; std::string mCachePath; std::string mCookiePath; LLCEFLib* mLLCEFLib; @@ -106,6 +112,9 @@ MediaPluginBase(host_send_func, host_user_data) mAuthUsername = ""; mAuthPassword = ""; mAuthOK = false; + mCanCut = false; + mCanCopy = false; + mCanPaste = false; mCachePath = ""; mCookiePath = ""; mLLCEFLib = new LLCEFLib(); @@ -217,6 +226,13 @@ void MediaPluginCEF::onNavigateURLCallback(std::string url) sendMessage(message); } +//////////////////////////////////////////////////////////////////////////////// +// triggered when user clicks link with "external" attribute +void MediaPluginCEF::onExternalTargetLinkCallback(std::string url) +{ + +} + //////////////////////////////////////////////////////////////////////////////// // bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password) @@ -279,6 +295,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string) else if (message_name == "idle") { mLLCEFLib->update(); + + // this seems bad but unless the state changes (it won't until we figure out + // how to get CEF to tell us if copy/cut/paste is available) then this function + // will return immediately + checkEditState(); } else if (message_name == "cleanup") { @@ -335,6 +356,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1)); mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4)); + mLLCEFLib->setOnExternalTargetLinkCallback(boost::bind(&MediaPluginCEF::onExternalTargetLinkCallback, this, _1)); LLCEFLibSettings settings; settings.inital_width = 1024; @@ -342,8 +364,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) settings.plugins_enabled = mPluginsEnabled; settings.javascript_enabled = mJavascriptEnabled; settings.cookies_enabled = mCookiesEnabled; - settings.cache_path = mCachePath; settings.cookie_store_path = mCookiePath; + settings.cache_enabled = true; + settings.cache_path = mCachePath; settings.accept_language_list = mHostLanguage; settings.user_agent_substring = mUserAgentSubtring; @@ -513,6 +536,18 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { authResponse(message_in); } + if (message_name == "edit_cut") + { + mLLCEFLib->editCut(); + } + if (message_name == "edit_copy") + { + mLLCEFLib->editCopy(); + } + if (message_name == "edit_paste") + { + mLLCEFLib->editPaste(); + } } else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) { @@ -653,6 +688,40 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier #endif }; +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::checkEditState() +{ + bool can_cut = mLLCEFLib->editCanCut(); + bool can_copy = mLLCEFLib->editCanCopy(); + bool can_paste = mLLCEFLib->editCanPaste(); + + if ((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste)) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state"); + + if (can_cut != mCanCut) + { + mCanCut = can_cut; + message.setValueBoolean("cut", can_cut); + } + + if (can_copy != mCanCopy) + { + mCanCopy = can_copy; + message.setValueBoolean("copy", can_copy); + } + + if (can_paste != mCanPaste) + { + mCanPaste = can_paste; + message.setValueBoolean("paste", can_paste); + } + + sendMessage(message); + } +} + //////////////////////////////////////////////////////////////////////////////// // bool MediaPluginCEF::init() -- cgit v1.2.3 From 236b3b9f842c86e1f176068ab70b82f83874e2ab Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 3 Sep 2015 18:16:46 -0700 Subject: support for external links and location_changed messages --- indra/media_plugins/cef/media_plugin_cef.cpp | 37 +++++++++++++++------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index f51a2715bb..97364d949a 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -63,8 +63,8 @@ private: void onTitleChangeCallback(std::string title); void onLoadStartCallback(); void onLoadEndCallback(int httpStatusCode); - void onNavigateURLCallback(std::string url); - void onExternalTargetLinkCallback(std::string url); + void onAddressChangeCallback(std::string url); + void onNavigateURLCallback(std::string url, std::string target); bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password); void postDebugMessage(const std::string& msg); @@ -157,16 +157,6 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int width, int } } -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) -{ - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); - message.setValue("uri", url); - message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to - sendMessage(message); -} - //////////////////////////////////////////////////////////////////////////////// // void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line) @@ -219,7 +209,7 @@ void MediaPluginCEF::onLoadEndCallback(int httpStatusCode) //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::onNavigateURLCallback(std::string url) +void MediaPluginCEF::onAddressChangeCallback(std::string url) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); message.setValue("uri", url); @@ -227,10 +217,24 @@ void MediaPluginCEF::onNavigateURLCallback(std::string url) } //////////////////////////////////////////////////////////////////////////////// -// triggered when user clicks link with "external" attribute -void MediaPluginCEF::onExternalTargetLinkCallback(std::string url) +// +void MediaPluginCEF::onNavigateURLCallback(std::string url, std::string target) { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); + message.setValue("uri", url); + message.setValue("target", target); + message.setValue("uuid", ""); // not used right now + sendMessage(message); +} +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); + message.setValue("uri", url); + message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to + sendMessage(message); } //////////////////////////////////////////////////////////////////////////////// @@ -354,9 +358,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1)); mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this)); mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); - mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1)); + mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2)); mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4)); - mLLCEFLib->setOnExternalTargetLinkCallback(boost::bind(&MediaPluginCEF::onExternalTargetLinkCallback, this, _1)); LLCEFLibSettings settings; settings.inital_width = 1024; -- cgit v1.2.3 From 83f26facbf717504b0ab4677cb6dd64534f6b844 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 3 Sep 2015 19:59:57 -0700 Subject: point to new version of llceflib with fixed support for secondlife:// URLs --- indra/media_plugins/cef/media_plugin_cef.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 97364d949a..f45ab5575c 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -52,7 +52,6 @@ public: /*virtual*/ void receiveMessage(const char* message_string); - private: bool init(); -- cgit v1.2.3 From 52e56af35eed8ffff522e13e028206243e1302f6 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 10 Sep 2015 15:11:28 -0700 Subject: Pull in LLCefLib with inverted output switched on and change viewer to uninvert things --- indra/media_plugins/cef/media_plugin_cef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index f45ab5575c..e812341f8c 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -387,7 +387,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) message.setValueU32("internalformat", GL_RGB); message.setValueU32("format", GL_BGRA); message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", false); + message.setValueBoolean("coords_opengl", true); sendMessage(message); } else if (message_name == "set_user_data_path") -- cgit v1.2.3 From 6a119e327d7b7196e03581561545fb8501c79067 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 16 Sep 2015 22:14:55 -0700 Subject: tmp chckin - still needs latest llceflib to build --- indra/media_plugins/cef/media_plugin_cef.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index e812341f8c..c668076d93 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -503,11 +503,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string) S32 key = message_in.getValueS32("key"); if (event == "down") { - mLLCEFLib->keyPress(key, true); + //mLLCEFLib->keyPress(key, true); + mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)key, 0, KM_MODIFIER_NONE, 0, 0, 0); + } else if (event == "up") { - mLLCEFLib->keyPress(key, false); + //mLLCEFLib->keyPress(key, false); + mLLCEFLib->keyboardEvent(KE_KEY_UP, (uint32_t)key, 0, KM_MODIFIER_NONE, 0, 0, 0); } #elif LL_WINDOWS @@ -681,7 +684,8 @@ void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier mo void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) { #if LL_DARWIN - mLLCEFLib->keyPress(utf8str[0], true); + //mLLCEFLib->keyPress(utf8str[0], true); + mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, KM_MODIFIER_NONE, 0, 0, 0); #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); -- cgit v1.2.3 From 3e20770f350652b91fd4b4a5bbef9b5f03561310 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Sat, 26 Sep 2015 18:53:17 -0700 Subject: Point to new third party llcef package and fix typo in interface --- indra/media_plugins/cef/media_plugin_cef.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index c668076d93..ca7339669b 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -361,8 +361,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4)); LLCEFLibSettings settings; - settings.inital_width = 1024; - settings.inital_height = 1024; + settings.initial_width = 1024; + settings.initial_height = 1024; settings.plugins_enabled = mPluginsEnabled; settings.javascript_enabled = mJavascriptEnabled; settings.cookies_enabled = mCookiesEnabled; -- cgit v1.2.3 From a0c0bc6b4033acf8d395708b5515215699905acc Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 30 Sep 2015 16:34:49 -0700 Subject: Update CEF media plugin to reflect changes in LLCEFLib --- indra/media_plugins/cef/media_plugin_cef.cpp | 76 ++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 21 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index ca7339669b..da39cd353b 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -65,14 +65,15 @@ private: void onAddressChangeCallback(std::string url); void onNavigateURLCallback(std::string url, std::string target); bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password); + void onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle); void postDebugMessage(const std::string& msg); void authResponse(LLPluginMessage &message); - EKeyboardModifier decodeModifiers(std::string &modifiers); + LLCEFLib::EKeyboardModifier decodeModifiers(std::string &modifiers); void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers); - void keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data); - void unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data); + void keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data); + void unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data); void checkEditState(); @@ -259,6 +260,38 @@ bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::strin return mAuthOK; } +void MediaPluginCEF::onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle) +{ + std::string name = ""; + + switch (type) + { + case LLCEFLib::CT_POINTER: + name = "arrow"; + break; + case LLCEFLib::CT_IBEAM: + name = "ibeam"; + break; + case LLCEFLib::CT_NORTHSOUTHRESIZE: + name = "splitv"; + break; + case LLCEFLib::CT_EASTWESTRESIZE: + name = "splith"; + break; + case LLCEFLib::CT_HAND: + name = "hand"; + break; + + default: + LL_WARNS() << "Unknown cursor ID: " << (int)type << LL_ENDL; + break; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed"); + message.setValue("name", name); + sendMessage(message); +} + void MediaPluginCEF::authResponse(LLPluginMessage &message) { mAuthOK = message.getValueBoolean("ok"); @@ -359,8 +392,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2)); mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4)); + mLLCEFLib->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2)); - LLCEFLibSettings settings; + LLCEFLib::LLCEFLibSettings settings; settings.initial_width = 1024; settings.initial_height = 1024; settings.plugins_enabled = mPluginsEnabled; @@ -449,14 +483,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string) //std::string modifiers = message_in.getValue("modifiers"); S32 button = message_in.getValueS32("button"); - EMouseButton btn = MB_MOUSE_BUTTON_LEFT; - if (button == 0) btn = MB_MOUSE_BUTTON_LEFT; - if (button == 1) btn = MB_MOUSE_BUTTON_RIGHT; - if (button == 2) btn = MB_MOUSE_BUTTON_MIDDLE; + LLCEFLib::EMouseButton btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT; + if (button == 0) btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT; + if (button == 1) btn = LLCEFLib::MB_MOUSE_BUTTON_RIGHT; + if (button == 2) btn = LLCEFLib::MB_MOUSE_BUTTON_MIDDLE; if (event == "down") { - mLLCEFLib->mouseButton(btn, ME_MOUSE_DOWN, x, y); + mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOWN, x, y); mLLCEFLib->setFocus(true); std::stringstream str; @@ -465,7 +499,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else if (event == "up") { - mLLCEFLib->mouseButton(btn, ME_MOUSE_UP, x, y); + mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_UP, x, y); std::stringstream str; str << "Mouse up at = " << x << ", " << y; @@ -520,14 +554,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string) LLSD native_key_data = message_in.getValueLLSD("native_key_data"); // Treat unknown events as key-up for safety. - EKeyEvent key_event = KE_KEY_UP; + LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP; if (event == "down") { - key_event = KE_KEY_DOWN; + key_event = LLCEFLib::KE_KEY_DOWN; } else if (event == "repeat") { - key_event = KE_KEY_REPEAT; + key_event = LLCEFLib::KE_KEY_REPEAT; } keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); @@ -602,23 +636,23 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } } -EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers) +LLCEFLib::EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers) { int result = 0; if (modifiers.find("shift") != std::string::npos) - result |= KM_MODIFIER_SHIFT; + result |= LLCEFLib::KM_MODIFIER_SHIFT; if (modifiers.find("alt") != std::string::npos) - result |= KM_MODIFIER_ALT; + result |= LLCEFLib::KM_MODIFIER_ALT; if (modifiers.find("control") != std::string::npos) - result |= KM_MODIFIER_CONTROL; + result |= LLCEFLib::KM_MODIFIER_CONTROL; if (modifiers.find("meta") != std::string::npos) - result |= KM_MODIFIER_META; + result |= LLCEFLib::KM_MODIFIER_META; - return (EKeyboardModifier)result; + return (LLCEFLib::EKeyboardModifier)result; } //////////////////////////////////////////////////////////////////////////////// @@ -645,7 +679,7 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) { #if LL_DARWIN std::string utf8_text; @@ -681,7 +715,7 @@ void MediaPluginCEF::keyEvent(EKeyEvent key_event, int key, EKeyboardModifier mo #endif }; -void MediaPluginCEF::unicodeInput(const std::string &utf8str, EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) { #if LL_DARWIN //mLLCEFLib->keyPress(utf8str[0], true); -- cgit v1.2.3 From ca871f25e921dd2fd3ea7c7b7b8a8c53bd4f7eb1 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 1 Oct 2015 09:57:53 -0700 Subject: Fix OS X missing scope qualifiers --- indra/media_plugins/cef/media_plugin_cef.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index da39cd353b..9b87eca726 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -538,13 +538,13 @@ void MediaPluginCEF::receiveMessage(const char* message_string) if (event == "down") { //mLLCEFLib->keyPress(key, true); - mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)key, 0, KM_MODIFIER_NONE, 0, 0, 0); + mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); } else if (event == "up") { //mLLCEFLib->keyPress(key, false); - mLLCEFLib->keyboardEvent(KE_KEY_UP, (uint32_t)key, 0, KM_MODIFIER_NONE, 0, 0, 0); + mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_UP, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); } #elif LL_WINDOWS @@ -719,7 +719,7 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboar { #if LL_DARWIN //mLLCEFLib->keyPress(utf8str[0], true); - mLLCEFLib->keyboardEvent(KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, KM_MODIFIER_NONE, 0, 0, 0); + mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); -- cgit v1.2.3 From ebcee8d7e7cb6ead01e1061fd1cf1720ee7e1a45 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 6 Oct 2015 15:24:57 -0700 Subject: MAINT-5703 fix - add observer to media plugin so MEDIA_LOCATION_CHANGED events get propagated throughout system --- indra/media_plugins/cef/media_plugin_cef.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 9b87eca726..5b9ff6cac8 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -390,6 +390,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->setOnTitleChangeCallback(boost::bind(&MediaPluginCEF::onTitleChangeCallback, this, _1)); mLLCEFLib->setOnLoadStartCallback(boost::bind(&MediaPluginCEF::onLoadStartCallback, this)); mLLCEFLib->setOnLoadEndCallback(boost::bind(&MediaPluginCEF::onLoadEndCallback, this, _1)); + mLLCEFLib->setOnAddressChangeCallback(boost::bind(&MediaPluginCEF::onAddressChangeCallback, this, _1)); mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2)); mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4)); mLLCEFLib->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2)); -- cgit v1.2.3 From 295d392b1c1ed6182eb2dce528fd396eab2ed2b2 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Fri, 9 Oct 2015 10:09:18 -0700 Subject: MAINT-5715, MAINT-5717, MAINT-5718: Replace the the volume catcher that was removed with the QT viewer. Addresses panning and fading issues, teleport and viewer mute controls. --- indra/media_plugins/cef/CMakeLists.txt | 34 ++- indra/media_plugins/cef/mac_volume_catcher.cpp | 275 +++++++++++++++++++++ indra/media_plugins/cef/media_plugin_cef.cpp | 20 +- indra/media_plugins/cef/volume_catcher.h | 54 ++++ indra/media_plugins/cef/windows_volume_catcher.cpp | 147 +++++++++++ 5 files changed, 525 insertions(+), 5 deletions(-) create mode 100644 indra/media_plugins/cef/mac_volume_catcher.cpp create mode 100644 indra/media_plugins/cef/volume_catcher.h create mode 100644 indra/media_plugins/cef/windows_volume_catcher.cpp (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index 7465fe727a..9bd6dbc5e9 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -45,23 +45,49 @@ set(media_plugin_cef_SOURCE_FILES media_plugin_cef.cpp ) +set(media_plugin_webkit_HEADER_FILES + volume_catcher.h + ) + +# Select which VolumeCatcher implementation to use +if (LINUX) + message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n" + " Please create a volume_catcher implementation for this platform.") + +elseif (DARWIN) + list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher.cpp) + find_library(CORESERVICES_LIBRARY CoreServices) + find_library(AUDIOUNIT_LIBRARY AudioUnit) + list(APPEND media_plugin_cef_SOURCE_FILES + ${CORESERVICES_LIBRARY} # for Component Manager calls + ${AUDIOUNIT_LIBRARY} # for AudioUnit calls + ) +elseif (WINDOWS) + list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp) +endif (LINUX) + +set_source_files_properties(${media_plugin_webkit_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES}) + add_library(media_plugin_cef SHARED ${media_plugin_cef_SOURCE_FILES} ) -target_link_libraries(media_plugin_cef +add_dependencies(media_plugin_cef ${LLPLUGIN_LIBRARIES} ${MEDIA_PLUGIN_BASE_LIBRARIES} ${LLCOMMON_LIBRARIES} - ${CEF_PLUGIN_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES} ) -add_dependencies(media_plugin_cef +target_link_libraries(media_plugin_cef ${LLPLUGIN_LIBRARIES} ${MEDIA_PLUGIN_BASE_LIBRARIES} ${LLCOMMON_LIBRARIES} + ${CEF_PLUGIN_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} ) if (WINDOWS) diff --git a/indra/media_plugins/cef/mac_volume_catcher.cpp b/indra/media_plugins/cef/mac_volume_catcher.cpp new file mode 100644 index 0000000000..73e5bf3da3 --- /dev/null +++ b/indra/media_plugins/cef/mac_volume_catcher.cpp @@ -0,0 +1,275 @@ +/** + * @file mac_volume_catcher.cpp + * @brief A Mac OS X specific hack to control the volume level of all audio channels opened by a process. + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +/************************************************************************************************************** + This code works by using CaptureComponent to capture the "Default Output" audio component + (kAudioUnitType_Output/kAudioUnitSubType_DefaultOutput) and delegating all calls to the original component. + It does this just to keep track of all instances of the default output component, so that it can set the + kHALOutputParam_Volume parameter on all of them to adjust the output volume. +**************************************************************************************************************/ + +#include "volume_catcher.h" + +#include +#include +#include + +#if LL_DARWIN +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +struct VolumeCatcherStorage; + +class VolumeCatcherImpl +{ +public: + + void setVolume(F32 volume); + void setPan(F32 pan); + + void setInstanceVolume(VolumeCatcherStorage *instance); + + std::list mComponentInstances; + Component mOriginalDefaultOutput; + Component mVolumeAdjuster; + + static VolumeCatcherImpl *getInstance(); +private: + // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. + VolumeCatcherImpl(); + static VolumeCatcherImpl *sInstance; + + // The singlar instance of this class is expected to last until the process exits. + // To ensure this, we declare the destructor here but never define it, so any code which attempts to destroy the instance will not link. + ~VolumeCatcherImpl(); + + F32 mVolume; + F32 mPan; +}; + +VolumeCatcherImpl *VolumeCatcherImpl::sInstance = NULL;; + +struct VolumeCatcherStorage +{ + ComponentInstance self; + ComponentInstance delegate; +}; + +static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage); +static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self); +static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self); + +VolumeCatcherImpl *VolumeCatcherImpl::getInstance() +{ + if(!sInstance) + { + sInstance = new VolumeCatcherImpl; + } + + return sInstance; +} + +VolumeCatcherImpl::VolumeCatcherImpl() +{ + mVolume = 1.0; // default to full volume + mPan = 0.0; // and center pan + + ComponentDescription desc; + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_DefaultOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + // Find the original default output component + mOriginalDefaultOutput = FindNextComponent(NULL, &desc); + + // Register our own output component with the same parameters + mVolumeAdjuster = RegisterComponent(&desc, NewComponentRoutineUPP(volume_catcher_component_entry), 0, NULL, NULL, NULL); + + // Capture the original component, so we always get found instead. + CaptureComponent(mOriginalDefaultOutput, mVolumeAdjuster); + +} + +static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage) +{ + ComponentResult result = badComponentSelector; + VolumeCatcherStorage *storage = (VolumeCatcherStorage*)componentStorage; + + switch(cp->what) + { + case kComponentOpenSelect: +// std::cerr << "kComponentOpenSelect" << std::endl; + result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_open, uppCallComponentOpenProcInfo); + break; + + case kComponentCloseSelect: +// std::cerr << "kComponentCloseSelect" << std::endl; + result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_close, uppCallComponentCloseProcInfo); + // CallComponentFunctionWithStorageProcInfo + break; + + default: +// std::cerr << "Delegating selector: " << cp->what << " to component instance " << storage->delegate << std::endl; + result = DelegateComponentCall(cp, storage->delegate); + break; + } + + return result; +} + +static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self) +{ + ComponentResult result = noErr; + VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance(); + + storage = new VolumeCatcherStorage; + + storage->self = self; + storage->delegate = NULL; + + result = OpenAComponent(impl->mOriginalDefaultOutput, &(storage->delegate)); + + if(result != noErr) + { +// std::cerr << "OpenAComponent result = " << result << ", component ref = " << storage->delegate << std::endl; + + // If we failed to open the delagate component, our open is going to fail. Clean things up. + delete storage; + } + else + { + // Success -- set up this component's storage + SetComponentInstanceStorage(self, (Handle)storage); + + // add this instance to the global list + impl->mComponentInstances.push_back(storage); + + // and set up the initial volume + impl->setInstanceVolume(storage); + } + + return result; +} + +static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self) +{ + ComponentResult result = noErr; + + if(storage) + { + if(storage->delegate) + { + CloseComponent(storage->delegate); + storage->delegate = NULL; + } + + VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance(); + impl->mComponentInstances.remove(storage); + delete[] storage; + } + + return result; +} + +void VolumeCatcherImpl::setVolume(F32 volume) +{ + VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance(); + impl->mVolume = volume; + + // Iterate through all known instances, setting the volume on each. + for(std::list::iterator iter = mComponentInstances.begin(); iter != mComponentInstances.end(); ++iter) + { + impl->setInstanceVolume(*iter); + } +} + +void VolumeCatcherImpl::setPan(F32 pan) +{ + VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance(); + impl->mPan = pan; + + // TODO: implement this. + // This will probably require adding a "panner" audio unit to the chain somehow. + // There's also a "3d mixer" component that we might be able to use... +} + +void VolumeCatcherImpl::setInstanceVolume(VolumeCatcherStorage *instance) +{ +// std::cerr << "Setting volume on component instance: " << (instance->delegate) << " to " << mVolume << std::endl; + + OSStatus err = noErr; + + if(instance && instance->delegate) + { + err = AudioUnitSetParameter( + instance->delegate, + kHALOutputParam_Volume, + kAudioUnitScope_Global, + 0, + mVolume, + 0); + } + + if(err) + { +// std::cerr << " AudioUnitSetParameter returned " << err << std::endl; + } +} + +///////////////////////////////////////////////////// + +VolumeCatcher::VolumeCatcher() +{ + pimpl = VolumeCatcherImpl::getInstance(); +} + +VolumeCatcher::~VolumeCatcher() +{ + // Let the instance persist until exit. +} + +void VolumeCatcher::setVolume(F32 volume) +{ + pimpl->setVolume(volume); +} + +void VolumeCatcher::setPan(F32 pan) +{ + pimpl->setPan(pan); +} + +void VolumeCatcher::pump() +{ + // No periodic tasks are necessary for this implementation. +} + +#if LL_DARWIN +#pragma GCC diagnostic warning "-Wdeprecated-declarations" +#endif diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 5b9ff6cac8..3f3d9dc657 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -39,6 +39,7 @@ #include "boost/function.hpp" #include "boost/bind.hpp" #include "llCEFLib.h" +#include "volume_catcher.h" //////////////////////////////////////////////////////////////////////////////// // @@ -76,6 +77,7 @@ private: void unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data); void checkEditState(); + void setVolume(F32 vol); bool mEnableMediaPluginDebugging; std::string mHostLanguage; @@ -92,6 +94,8 @@ private: std::string mCachePath; std::string mCookiePath; LLCEFLib* mLLCEFLib; + + VolumeCatcher mVolumeCatcher; }; //////////////////////////////////////////////////////////////////////////////// @@ -332,6 +336,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mLLCEFLib->update(); + mVolumeCatcher.pump(); // this seems bad but unless the state changes (it won't until we figure out // how to get CEF to tell us if copy/cut/paste is available) then this function // will return immediately @@ -630,7 +635,15 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mJavascriptEnabled = message_in.getValueBoolean("enable"); } } - else + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if (message_name == "set_volume") + { + F32 volume = (F32)message_in.getValueReal("volume"); + setVolume(volume); + } + } + else { //std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; }; @@ -763,6 +776,11 @@ void MediaPluginCEF::checkEditState() } } +void MediaPluginCEF::setVolume(F32 vol) +{ + mVolumeCatcher.setVolume(vol); +} + //////////////////////////////////////////////////////////////////////////////// // bool MediaPluginCEF::init() diff --git a/indra/media_plugins/cef/volume_catcher.h b/indra/media_plugins/cef/volume_catcher.h new file mode 100644 index 0000000000..337f2913d3 --- /dev/null +++ b/indra/media_plugins/cef/volume_catcher.h @@ -0,0 +1,54 @@ +/** + * @file volume_catcher.h + * @brief Interface to a class with platform-specific implementations that allows control of the audio volume of all sources in the current process. + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#ifndef VOLUME_CATCHER_H +#define VOLUME_CATCHER_H + +#include "linden_common.h" + +class VolumeCatcherImpl; + +class VolumeCatcher +{ + public: + VolumeCatcher(); + ~VolumeCatcher(); + + void setVolume(F32 volume); // 0.0 - 1.0 + + // Set the left-right pan of audio sources + // where -1.0 = left, 0 = center, and 1.0 = right + void setPan(F32 pan); + + void pump(); // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume + + private: + VolumeCatcherImpl *pimpl; +}; + +#endif // VOLUME_CATCHER_H diff --git a/indra/media_plugins/cef/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp new file mode 100644 index 0000000000..0cfb810906 --- /dev/null +++ b/indra/media_plugins/cef/windows_volume_catcher.cpp @@ -0,0 +1,147 @@ +/** + * @file windows_volume_catcher.cpp + * @brief A Windows implementation of volume level control of all audio channels opened by a process. + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#include "volume_catcher.h" +#include +#include "llsingleton.h" +class VolumeCatcherImpl : public LLSingleton +{ +friend LLSingleton; +public: + + void setVolume(F32 volume); + void setPan(F32 pan); + +private: + // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. + VolumeCatcherImpl(); + ~VolumeCatcherImpl(); + + typedef void (WINAPI *set_volume_func_t)(F32); + typedef void (WINAPI *set_mute_func_t)(bool); + + set_volume_func_t mSetVolumeFunc; + set_mute_func_t mSetMuteFunc; + + // tests if running on Vista, 7, 8 + once in CTOR + bool isWindowsVistaOrHigher(); + + F32 mVolume; + F32 mPan; + bool mSystemIsVistaOrHigher; +}; + +bool VolumeCatcherImpl::isWindowsVistaOrHigher() +{ + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + return osvi.dwMajorVersion >= 6; +} + +VolumeCatcherImpl::VolumeCatcherImpl() +: mVolume(1.0f), // default volume is max + mPan(0.f) // default pan is centered +{ + mSystemIsVistaOrHigher = isWindowsVistaOrHigher(); + + if ( ! mSystemIsVistaOrHigher ) + { + HMODULE handle = ::LoadLibrary(L"winmm.dll"); + if(handle) + { + mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume"); + mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute"); + } + } +} + +VolumeCatcherImpl::~VolumeCatcherImpl() +{ +} + +void VolumeCatcherImpl::setVolume(F32 volume) +{ + mVolume = volume; + + if ( mSystemIsVistaOrHigher ) + { + // set both left/right to same volume + // TODO: use pan value to set independently + DWORD left_channel = (DWORD)(mVolume * 65535.0f); + DWORD right_channel = (DWORD)(mVolume * 65535.0f); + DWORD hw_volume = left_channel << 16 | right_channel; + ::waveOutSetVolume(NULL, hw_volume); + } + else + { + if (mSetMuteFunc) + { + mSetMuteFunc(volume == 0.f); + } + if (mSetVolumeFunc) + { + mSetVolumeFunc(mVolume); + } + } +} + +void VolumeCatcherImpl::setPan(F32 pan) +{ // remember pan for calculating individual channel levels later + mPan = pan; +} + +///////////////////////////////////////////////////// + +VolumeCatcher::VolumeCatcher() +{ + pimpl = VolumeCatcherImpl::getInstance(); +} + +VolumeCatcher::~VolumeCatcher() +{ + // Let the instance persist until exit. +} + +void VolumeCatcher::setVolume(F32 volume) +{ + pimpl->setVolume(volume); +} + +void VolumeCatcher::setPan(F32 pan) +{ + pimpl->setPan(pan); +} + +void VolumeCatcher::pump() +{ + // No periodic tasks are necessary for this implementation. +} + + -- cgit v1.2.3 From 506e7271a7b69cc08a9096a6642a0b3f1b0ce04a Mon Sep 17 00:00:00 2001 From: rider Date: Fri, 9 Oct 2015 11:51:10 -0700 Subject: CMake fixes for mac build. --- indra/media_plugins/cef/CMakeLists.txt | 22 +++++++++++++--------- indra/media_plugins/cef/mac_volume_catcher.cpp | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index 9bd6dbc5e9..16015be672 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -45,20 +45,28 @@ set(media_plugin_cef_SOURCE_FILES media_plugin_cef.cpp ) -set(media_plugin_webkit_HEADER_FILES +set(media_plugin_cef_HEADER_FILES volume_catcher.h ) +set (media_plugin_cef_LINK_LIBRARIES + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${CEF_PLUGIN_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES}) + + # Select which VolumeCatcher implementation to use if (LINUX) - message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n" + message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n" " Please create a volume_catcher implementation for this platform.") elseif (DARWIN) list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher.cpp) find_library(CORESERVICES_LIBRARY CoreServices) find_library(AUDIOUNIT_LIBRARY AudioUnit) - list(APPEND media_plugin_cef_SOURCE_FILES + list(APPEND media_plugin_cef_LINK_LIBRARIES ${CORESERVICES_LIBRARY} # for Component Manager calls ${AUDIOUNIT_LIBRARY} # for AudioUnit calls ) @@ -66,7 +74,7 @@ elseif (WINDOWS) list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp) endif (LINUX) -set_source_files_properties(${media_plugin_webkit_HEADER_FILES} +set_source_files_properties(${media_plugin_cef_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES}) @@ -83,11 +91,7 @@ add_dependencies(media_plugin_cef ) target_link_libraries(media_plugin_cef - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${CEF_PLUGIN_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES} + ${media_plugin_cef_LINK_LIBRARIES} ) if (WINDOWS) diff --git a/indra/media_plugins/cef/mac_volume_catcher.cpp b/indra/media_plugins/cef/mac_volume_catcher.cpp index 73e5bf3da3..dddb9c2077 100644 --- a/indra/media_plugins/cef/mac_volume_catcher.cpp +++ b/indra/media_plugins/cef/mac_volume_catcher.cpp @@ -6,7 +6,7 @@ * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; -- cgit v1.2.3 From 2a899b49dd5d0a4ff4b4ab2e36bda48ff1473f0a Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 19 Oct 2015 18:43:48 -0700 Subject: MAINT-5711 FIX profiles and marketplace are asking for a login each session --- indra/media_plugins/cef/media_plugin_cef.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 3f3d9dc657..7f538e16d8 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -479,6 +479,15 @@ void MediaPluginCEF::receiveMessage(const char* message_string) std::string uri = message_in.getValue("uri"); mLLCEFLib->navigate(uri); } + else if (message_name == "set_cookie") + { + std::string uri = message_in.getValue("uri"); + std::string name = message_in.getValue("name"); + std::string value = message_in.getValue("value"); + std::string domain = message_in.getValue("domain"); + std::string path = message_in.getValue("path"); + mLLCEFLib->setCookie(uri, name, value, domain, path); + } else if (message_name == "mouse_event") { std::string event = message_in.getValue("event"); -- cgit v1.2.3 From 8c74ed2a58f5443b931374489b04ba80fb11a590 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 21 Oct 2015 09:05:19 -0700 Subject: Fix windows line endings --- indra/media_plugins/cef/media_plugin_cef.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 7f538e16d8..5b08807619 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -479,14 +479,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string) std::string uri = message_in.getValue("uri"); mLLCEFLib->navigate(uri); } - else if (message_name == "set_cookie") - { - std::string uri = message_in.getValue("uri"); - std::string name = message_in.getValue("name"); - std::string value = message_in.getValue("value"); - std::string domain = message_in.getValue("domain"); - std::string path = message_in.getValue("path"); - mLLCEFLib->setCookie(uri, name, value, domain, path); + else if (message_name == "set_cookie") + { + std::string uri = message_in.getValue("uri"); + std::string name = message_in.getValue("name"); + std::string value = message_in.getValue("value"); + std::string domain = message_in.getValue("domain"); + std::string path = message_in.getValue("path"); + mLLCEFLib->setCookie(uri, name, value, domain, path); } else if (message_name == "mouse_event") { @@ -814,4 +814,3 @@ int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, return 0; } - -- cgit v1.2.3 From 16cd296e30e95fbacefff4e291fbdd6fbf0c2c43 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 22 Oct 2015 13:24:43 -0700 Subject: MAINT-5775 FIX Split out cookies and cache directories into separate folders and move cache to same place as viewer cache --- indra/media_plugins/cef/media_plugin_cef.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 5b08807619..bb2270181e 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -432,9 +432,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else if (message_name == "set_user_data_path") { - std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter - mCachePath = user_data_path + "cef_cache"; - mCookiePath = user_data_path + "cef_cookies"; + std::string user_data_path_cache = message_in.getValue("cache_path"); + std::string user_data_path_cookies = message_in.getValue("cookies_path"); + mCachePath = user_data_path_cache + "cef_cache"; + mCookiePath = user_data_path_cookies + "cef_cookies"; } else if (message_name == "size_change") { -- cgit v1.2.3 From bd817f6f422991c2653493436c7845e75ea9d855 Mon Sep 17 00:00:00 2001 From: rider Date: Fri, 6 Nov 2015 14:12:30 -0800 Subject: MAINT-5754: Basic keyboard functionality on the Mac. Still incomplete --- indra/media_plugins/cef/media_plugin_cef.cpp | 41 +++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index bb2270181e..d653aaace9 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -551,6 +551,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) #if LL_DARWIN std::string event = message_in.getValue("event"); S32 key = message_in.getValueS32("key"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); + +#if 0 if (event == "down") { //mLLCEFLib->keyPress(key, true); @@ -562,7 +565,21 @@ void MediaPluginCEF::receiveMessage(const char* message_string) //mLLCEFLib->keyPress(key, false); mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_UP, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); } - +#else + // Treat unknown events as key-up for safety. + LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP; + if (event == "down") + { + key_event = LLCEFLib::KE_KEY_DOWN; + } + else if (event == "repeat") + { + key_event = LLCEFLib::KE_KEY_REPEAT; + } + + keyEvent(key_event, key, LLCEFLib::KM_MODIFIER_NONE, native_key_data); + +#endif #elif LL_WINDOWS std::string event = message_in.getValue("event"); S32 key = message_in.getValueS32("key"); @@ -708,12 +725,20 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib:: #if LL_DARWIN std::string utf8_text; + uint32_t native_char_code = native_key_data["char_code"].asInteger(); + uint32_t native_scan_code = native_key_data["scan_code"].asInteger(); + uint32_t native_virtual_key = native_key_data["key_code"].asInteger(); + uint32_t native_modifiers = native_key_data["modifiers"].asInteger(); + + + if (key < 128) { - utf8_text = (char)key; + utf8_text = (char)native_virtual_key; } - + switch ((KEY)key) + { case KEY_BACKSPACE: utf8_text = (char)8; break; case KEY_TAB: utf8_text = (char)9; break; @@ -725,16 +750,12 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib:: break; } - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData(native_key_data, native_scan_code, native_virtual_key, native_modifiers); - - mLLCEFLib->keyboardEvent(key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); + mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(), native_modifiers, native_scan_code, native_virtual_key, native_modifiers); #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); + mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam); #endif }; @@ -743,7 +764,7 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboar { #if LL_DARWIN //mLLCEFLib->keyPress(utf8str[0], true); - mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); + //mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); -- cgit v1.2.3 From 5449ae73b337c026afa93e99a47b670c28c8eb80 Mon Sep 17 00:00:00 2001 From: rider Date: Sat, 7 Nov 2015 12:09:08 -0800 Subject: MAINT-5754: Finish key modifier experiment. Still not working. --- indra/media_plugins/cef/media_plugin_cef.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index d653aaace9..7d60c1a5ed 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -720,7 +720,7 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) +void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers_x, LLSD native_key_data = LLSD::emptyMap()) { #if LL_DARWIN std::string utf8_text; @@ -729,14 +729,23 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib:: uint32_t native_scan_code = native_key_data["scan_code"].asInteger(); uint32_t native_virtual_key = native_key_data["key_code"].asInteger(); uint32_t native_modifiers = native_key_data["modifiers"].asInteger(); - - if (key < 128) { utf8_text = (char)native_virtual_key; } + unsigned int modifers = LLCEFLib::KM_MODIFIER_NONE; + + if (native_modifiers & (MASK_CONTROL | MASK_MAC_CONTROL)) + modifers |= LLCEFLib::KM_MODIFIER_CONTROL; + if (native_modifiers & MASK_SHIFT) + modifers |= LLCEFLib::KM_MODIFIER_SHIFT; + if (native_modifiers & MASK_ALT) + modifers |= LLCEFLib::KM_MODIFIER_ALT; + + //modifers |= LLCEFLib::KM_MODIFIER_META; + switch ((KEY)key) { @@ -750,7 +759,10 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib:: break; } - mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(), native_modifiers, native_scan_code, native_virtual_key, native_modifiers); + mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(), + static_cast(modifers), + native_scan_code, native_virtual_key, native_modifiers); + #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); -- cgit v1.2.3 From 66848f7a94438f2fe9edd4fad9c12ea44ad285b2 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 9 Nov 2015 11:53:09 -0800 Subject: Undo the clobbering that the PR did :) --- indra/media_plugins/cef/media_plugin_cef.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 7d60c1a5ed..ea451ed5b6 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -128,7 +128,7 @@ MediaPluginBase(host_send_func, host_user_data) // MediaPluginCEF::~MediaPluginCEF() { - mLLCEFLib->reset(); + mLLCEFLib->requestExit(); } //////////////////////////////////////////////////////////////////////////////// @@ -532,11 +532,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else if (message_name == "scroll_event") { + S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); const int scaling_factor = 40; y *= -scaling_factor; - mLLCEFLib->mouseWheel(y); + mLLCEFLib->mouseWheel(x, y); } else if (message_name == "text_event") { -- cgit v1.2.3 From 148de7ceeb1acd6fe76f0986812e32d2488202b7 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 10 Nov 2015 14:26:47 -0800 Subject: Have the media_cef plugin post goodbye back to the plugin. --- indra/media_plugins/cef/media_plugin_cef.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index ea451ed5b6..86157bf852 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -344,6 +344,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else if (message_name == "cleanup") { + LLPluginMessage message("base", "goodbye"); + sendMessage(message); } else if (message_name == "shm_added") { -- cgit v1.2.3 From f563ef61004c70c05c2ca78a8fbdd85ed1dbf1a6 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 11 Nov 2015 09:53:51 -0800 Subject: Add callback for when CEF asks to shutdown --- indra/media_plugins/cef/media_plugin_cef.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 86157bf852..d14254d3d7 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -62,6 +62,7 @@ private: void onStatusMessageCallback(std::string value); void onTitleChangeCallback(std::string title); void onLoadStartCallback(); + void onRequestExitCallback(); void onLoadEndCallback(int httpStatusCode); void onAddressChangeCallback(std::string url); void onNavigateURLCallback(std::string url, std::string target); @@ -128,7 +129,6 @@ MediaPluginBase(host_send_func, host_user_data) // MediaPluginCEF::~MediaPluginCEF() { - mLLCEFLib->requestExit(); } //////////////////////////////////////////////////////////////////////////////// @@ -199,6 +199,16 @@ void MediaPluginCEF::onLoadStartCallback() sendMessage(message); } +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onRequestExitCallback() +{ + mLLCEFLib->shutdown(); + + LLPluginMessage message("base", "goodbye"); + sendMessage(message); +} + //////////////////////////////////////////////////////////////////////////////// // void MediaPluginCEF::onLoadEndCallback(int httpStatusCode) @@ -344,8 +354,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else if (message_name == "cleanup") { - LLPluginMessage message("base", "goodbye"); - sendMessage(message); + mLLCEFLib->requestExit(); } else if (message_name == "shm_added") { @@ -401,6 +410,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2)); mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4)); mLLCEFLib->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2)); + mLLCEFLib->setOnRequestExitCallback(boost::bind(&MediaPluginCEF::onRequestExitCallback, this)); LLCEFLib::LLCEFLibSettings settings; settings.initial_width = 1024; -- cgit v1.2.3 From f8050dbac2861d76adfe8630abe09ca5fb2666f7 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 11 Nov 2015 16:28:11 -0800 Subject: Fix MAINT-5832 Add /LTCG flag to linker for media_plugin_cef.dll to avoid linker restarts --- indra/media_plugins/cef/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index 16015be672..1f6163e41e 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -61,7 +61,7 @@ set (media_plugin_cef_LINK_LIBRARIES if (LINUX) message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n" " Please create a volume_catcher implementation for this platform.") - + elseif (DARWIN) list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher.cpp) find_library(CORESERVICES_LIBRARY CoreServices) @@ -98,7 +98,7 @@ if (WINDOWS) set_target_properties( media_plugin_cef PROPERTIES - LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT" + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT" LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD" ) endif (WINDOWS) -- cgit v1.2.3 From c2ad041c23b0097aec30acc7447a42f96d515d3b Mon Sep 17 00:00:00 2001 From: rider Date: Fri, 13 Nov 2015 16:22:34 -0800 Subject: Encode keyboard event for reconstruction in the plugin. --- indra/media_plugins/cef/media_plugin_cef.cpp | 46 ++++++---------------------- 1 file changed, 9 insertions(+), 37 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 86157bf852..9e7c390eb2 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -726,46 +726,18 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers_x, LLSD native_key_data = LLSD::emptyMap()) { #if LL_DARWIN - std::string utf8_text; - uint32_t native_char_code = native_key_data["char_code"].asInteger(); - uint32_t native_scan_code = native_key_data["scan_code"].asInteger(); - uint32_t native_virtual_key = native_key_data["key_code"].asInteger(); - uint32_t native_modifiers = native_key_data["modifiers"].asInteger(); - - if (key < 128) - { - utf8_text = (char)native_virtual_key; - } - - unsigned int modifers = LLCEFLib::KM_MODIFIER_NONE; - - if (native_modifiers & (MASK_CONTROL | MASK_MAC_CONTROL)) - modifers |= LLCEFLib::KM_MODIFIER_CONTROL; - if (native_modifiers & MASK_SHIFT) - modifers |= LLCEFLib::KM_MODIFIER_SHIFT; - if (native_modifiers & MASK_ALT) - modifers |= LLCEFLib::KM_MODIFIER_ALT; - - //modifers |= LLCEFLib::KM_MODIFIER_META; - - switch ((KEY)key) - - { - case KEY_BACKSPACE: utf8_text = (char)8; break; - case KEY_TAB: utf8_text = (char)9; break; - case KEY_RETURN: utf8_text = (char)13; break; - case KEY_PAD_RETURN: utf8_text = (char)13; break; - case KEY_ESCAPE: utf8_text = (char)27; break; - - default: - break; - } + uint32_t eventType = native_key_data["event_type"].asInteger(); + uint32_t eventModifiers = native_key_data["event_modifiers"].asInteger(); + uint32_t eventKeycode = native_key_data["event_keycode"].asInteger(); + char eventChars = static_cast(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger()); + char eventUChars = static_cast(native_key_data["event_umodchars"].isUndefined() ? 0 : native_key_data["event_umodchars"].asInteger()); + bool eventIsRepeat = native_key_data["event_isrepeat"].asBoolean(); - mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(), - static_cast(modifers), - native_scan_code, native_virtual_key, native_modifiers); + mLLCEFLib->keyboardEventOSX(eventType, eventModifiers, (eventChars) ? &eventChars : NULL, + (eventUChars) ? &eventUChars : NULL, eventIsRepeat, eventKeycode); + #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); -- cgit v1.2.3 From df29aab81ba962d29b541fb84ffe0a682abcfaf5 Mon Sep 17 00:00:00 2001 From: rider Date: Fri, 13 Nov 2015 16:38:35 -0800 Subject: Throw away any incomplete llsd messages that may have get sent on CR --- indra/media_plugins/cef/media_plugin_cef.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 9e7c390eb2..be69858d47 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -727,6 +727,12 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib:: { #if LL_DARWIN + if (!native_key_data.has("event_type") || + !native_key_data.has("event_modifiers") || + !native_key_data.has("event_keycode") || + !native_key_data.has("event_isrepeat")) + return; + uint32_t eventType = native_key_data["event_type"].asInteger(); uint32_t eventModifiers = native_key_data["event_modifiers"].asInteger(); uint32_t eventKeycode = native_key_data["event_keycode"].asInteger(); -- cgit v1.2.3 From 311b376ab50bacf2bf113616af2a5bbedfcd5ee5 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 16 Nov 2015 16:09:40 -0800 Subject: Update SetCookie code for new LLCEFLib API and add support for shoing/hising developer console (Inspector) --- indra/media_plugins/cef/media_plugin_cef.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 60f6264db4..a53b453b3e 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -499,7 +499,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) std::string value = message_in.getValue("value"); std::string domain = message_in.getValue("domain"); std::string path = message_in.getValue("path"); - mLLCEFLib->setCookie(uri, name, value, domain, path); + bool httponly = message_in.getValueBoolean("httponly"); + bool secure = message_in.getValueBoolean("secure"); + mLLCEFLib->setCookie(uri, name, value, domain, path, httponly, secure); } else if (message_name == "mouse_event") { @@ -666,6 +668,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mUserAgentSubtring = message_in.getValue("user_agent"); } + else if (message_name == "show_web_inspector") + { + mLLCEFLib->showDevTools(true); + } else if (message_name == "plugins_enabled") { mPluginsEnabled = message_in.getValueBoolean("enable"); -- cgit v1.2.3 From 32691c441664821fcb29824461ed85277ae418c8 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 18 Nov 2015 18:17:50 -0800 Subject: initial support for dropdown menus/select widgits --- indra/media_plugins/cef/media_plugin_cef.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index a53b453b3e..ec3518100b 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -56,7 +56,7 @@ public: private: bool init(); - void onPageChangedCallback(unsigned char* pixels, int width, int height); + void onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup); void onCustomSchemeURLCallback(std::string url); void onConsoleMessageCallback(std::string message, std::string source, int line); void onStatusMessageCallback(std::string value); @@ -149,13 +149,31 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg) //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int width, int height) +void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup) { if (mPixels && pixels) { - if (mWidth == width && mHeight == height) + if (is_popup) { - memcpy(mPixels, pixels, mWidth * mHeight * mDepth); + for (int line = 0; line < height; ++line) + { + int inverted_y = mHeight - y - height; + int src = line * width * mDepth; + int dst = (inverted_y + line) * mWidth * mDepth + x * mDepth; + + if (dst + width * mDepth < mWidth * mHeight * mDepth) + { + memcpy(mPixels + dst, pixels + src, width * mDepth); + } + } + } + else + { + if (mWidth == width && mHeight == height) + { + memcpy(mPixels, pixels, mWidth * mHeight * mDepth); + } + } setDirty(0, 0, mWidth, mHeight); } @@ -399,7 +417,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) if (message_name == "init") { // event callbacks from LLCefLib - mLLCEFLib->setOnPageChangedCallback(boost::bind(&MediaPluginCEF::onPageChangedCallback, this, _1, _2, _3)); + mLLCEFLib->setOnPageChangedCallback(boost::bind(&MediaPluginCEF::onPageChangedCallback, this, _1, _2, _3, _4, _5, _6)); mLLCEFLib->setOnCustomSchemeURLCallback(boost::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, _1)); mLLCEFLib->setOnConsoleMessageCallback(boost::bind(&MediaPluginCEF::onConsoleMessageCallback, this, _1, _2, _3)); mLLCEFLib->setOnStatusMessageCallback(boost::bind(&MediaPluginCEF::onStatusMessageCallback, this, _1)); -- cgit v1.2.3 From f2a6e0f89c45e06742204efd92acc494bb14d9bd Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 19 Nov 2015 16:39:40 -0800 Subject: Fix javascript_enabled && plugins_enabled (wrong media class) and pull in new LLCEFLib --- indra/media_plugins/cef/media_plugin_cef.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index ec3518100b..182b7f2546 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -338,7 +338,7 @@ void MediaPluginCEF::authResponse(LLPluginMessage &message) // void MediaPluginCEF::receiveMessage(const char* message_string) { - // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + // std::cerr << "MediaPluginCEF::receiveMessage: received message: \"" << message_string << "\"" << std::endl; LLPluginMessage message_in; if (message_in.parse(message_string) >= 0) @@ -356,7 +356,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; message.setValueLLSD("versions", versions); - std::string plugin_version = "CEF plugin 1.0.0"; + std::string plugin_version = "CEF plugin 1.1.3"; message.setValue("plugin_version", plugin_version); sendMessage(message); } @@ -400,7 +400,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else { - //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; } LLPluginMessage message("base", "shm_remove_response"); @@ -409,7 +408,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else { - //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; } } else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) @@ -709,7 +707,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else { - //std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; }; } } -- cgit v1.2.3 From 94ea5dce50e97aa6ee7bd36790a995c9ae4dbeba Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 20 Nov 2015 17:34:46 -0800 Subject: pull in llceflib changes for user agent, flash plugins and pdf --- indra/media_plugins/cef/media_plugin_cef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 182b7f2546..c8a52ff5fe 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -438,7 +438,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) settings.cache_enabled = true; settings.cache_path = mCachePath; settings.accept_language_list = mHostLanguage; - settings.user_agent_substring = mUserAgentSubtring; + settings.user_agent_substring = mLLCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring); bool result = mLLCEFLib->init(settings); if (!result) -- cgit v1.2.3 From cc0faa34243047303c5cc066525e93c49bc5920d Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Mon, 23 Nov 2015 12:01:32 -0800 Subject: Refrain from sending right mouse button events - crashes OS X - and we don't need them --- indra/media_plugins/cef/media_plugin_cef.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index c8a52ff5fe..77e6d35b11 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -526,15 +526,13 @@ void MediaPluginCEF::receiveMessage(const char* message_string) S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); - //std::string modifiers = message_in.getValue("modifiers"); - + // only even send left mouse button events to LLCEFLib + // (partially prompted by crash in OS X CEF when sending right button events) + // we catch the right click in viewer and display our own context menu anyway S32 button = message_in.getValueS32("button"); LLCEFLib::EMouseButton btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT; - if (button == 0) btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT; - if (button == 1) btn = LLCEFLib::MB_MOUSE_BUTTON_RIGHT; - if (button == 2) btn = LLCEFLib::MB_MOUSE_BUTTON_MIDDLE; - if (event == "down") + if (event == "down" && button == 0) { mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOWN, x, y); mLLCEFLib->setFocus(true); @@ -543,7 +541,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) str << "Mouse down at = " << x << ", " << y; postDebugMessage(str.str()); } - else if (event == "up") + else if (event == "up" && button == 0) { mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_UP, x, y); -- cgit v1.2.3 From eb484d5051c48e3bd35a2f06915eb75cf5c8c1fc Mon Sep 17 00:00:00 2001 From: rider Date: Thu, 3 Dec 2015 13:32:06 -0800 Subject: MAINT-5909: Enable unicode text input on mac and feed that directly into the viewer. Windows fixes still required. --- indra/media_plugins/cef/media_plugin_cef.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 77e6d35b11..919d83bc09 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -763,16 +763,17 @@ void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib:: return; uint32_t eventType = native_key_data["event_type"].asInteger(); + if (!eventType) + return; uint32_t eventModifiers = native_key_data["event_modifiers"].asInteger(); uint32_t eventKeycode = native_key_data["event_keycode"].asInteger(); char eventChars = static_cast(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger()); char eventUChars = static_cast(native_key_data["event_umodchars"].isUndefined() ? 0 : native_key_data["event_umodchars"].asInteger()); bool eventIsRepeat = native_key_data["event_isrepeat"].asBoolean(); - mLLCEFLib->keyboardEventOSX(eventType, eventModifiers, (eventChars) ? &eventChars : NULL, (eventUChars) ? &eventUChars : NULL, eventIsRepeat, eventKeycode); - + #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); @@ -787,6 +788,16 @@ void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboar #if LL_DARWIN //mLLCEFLib->keyPress(utf8str[0], true); //mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0); + if (!native_key_data.has("event_chars") || !native_key_data.has("event_umodchars") || + !native_key_data.has("event_keycode") || !native_key_data.has("event_modifiers")) + return; + uint32_t unicodeChar = native_key_data["event_chars"].asInteger(); + uint32_t unmodifiedChar = native_key_data["event_umodchars"].asInteger(); + uint32_t keyCode = native_key_data["event_keycode"].asInteger(); + uint32_t rawmodifiers = native_key_data["event_modifiers"].asInteger(); + + mLLCEFLib->injectUnicodeText(unicodeChar, unmodifiedChar, keyCode, rawmodifiers); + #elif LL_WINDOWS U32 msg = ll_U32_from_sd(native_key_data["msg"]); U32 wparam = ll_U32_from_sd(native_key_data["w_param"]); -- cgit v1.2.3 From 5f1fe20e9ec530b1e4c4384474011e913180671c Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 11 Dec 2015 16:15:34 -0800 Subject: Missed a commit for MAINT-5948 - enable double click --- indra/media_plugins/cef/media_plugin_cef.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 919d83bc09..19df1fa640 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -245,7 +245,7 @@ void MediaPluginCEF::onAddressChangeCallback(std::string url) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); message.setValue("uri", url); - sendMessage(message); + sendMessage(message); } //////////////////////////////////////////////////////////////////////////////// @@ -551,7 +551,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } else if (event == "double_click") { - // TODO: do we need this ? + mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOUBLE_CLICK, x, y); } else { -- cgit v1.2.3 From 3bf8929d932a6253177be55766cd2a80bb6e224d Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 15 Dec 2015 15:24:41 -0800 Subject: MAINT-5966 - file download failures need feedback --- indra/media_plugins/cef/media_plugin_cef.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'indra/media_plugins/cef') diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 19df1fa640..a2479cc946 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -68,6 +68,7 @@ private: void onNavigateURLCallback(std::string url, std::string target); bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password); void onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle); + void onFileDownloadCallback(std::string filename); void postDebugMessage(const std::string& msg); void authResponse(LLPluginMessage &message); @@ -292,6 +293,18 @@ bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::strin return mAuthOK; } +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onFileDownloadCallback(const std::string filename) +{ + mAuthOK = false; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download"); + message.setValue("filename", filename); + + sendMessage(message); +} + void MediaPluginCEF::onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle) { std::string name = ""; @@ -425,6 +438,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mLLCEFLib->setOnAddressChangeCallback(boost::bind(&MediaPluginCEF::onAddressChangeCallback, this, _1)); mLLCEFLib->setOnNavigateURLCallback(boost::bind(&MediaPluginCEF::onNavigateURLCallback, this, _1, _2)); mLLCEFLib->setOnHTTPAuthCallback(boost::bind(&MediaPluginCEF::onHTTPAuthCallback, this, _1, _2, _3, _4)); + mLLCEFLib->setOnFileDownloadCallback(boost::bind(&MediaPluginCEF::onFileDownloadCallback, this, _1)); mLLCEFLib->setOnCursorChangedCallback(boost::bind(&MediaPluginCEF::onCursorChangedCallback, this, _1, _2)); mLLCEFLib->setOnRequestExitCallback(boost::bind(&MediaPluginCEF::onRequestExitCallback, this)); -- cgit v1.2.3