Remove llqtwebkit, add cef
This commit is contained in:
@@ -1889,38 +1889,6 @@
|
||||
<key>version</key>
|
||||
<string>1.0.298370</string>
|
||||
</map>
|
||||
<key>llqtwebkit</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 2015 The Qt Company Ltd.</string>
|
||||
<key>description</key>
|
||||
<string>QT cross-platform applicaiton and UI framework.</string>
|
||||
<key>license</key>
|
||||
<string>LGPL</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/llqtwebkit.txt</string>
|
||||
<key>name</key>
|
||||
<string>llqtwebkit</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>433fb6ae8370375cf55013812e59f01d</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>http://depot.alchemyviewer.org/pub/windows64/lib-vc14/llqtwebkit-4.8.7-windows64-201512130225.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>4.8.7</string>
|
||||
</map>
|
||||
<key>mesa</key>
|
||||
<map>
|
||||
<key>license</key>
|
||||
|
||||
@@ -45,10 +45,6 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llvfs)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llwindow)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llxml)
|
||||
|
||||
if(STANDALONE)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llqtwebkit)
|
||||
endif(STANDALONE)
|
||||
|
||||
if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
|
||||
add_subdirectory(${LIBS_CLOSED_PREFIX}copy_win_scripts)
|
||||
endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
|
||||
|
||||
40
indra/cmake/CEFPlugin.cmake
Normal file
40
indra/cmake/CEFPlugin.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- cmake -*-
|
||||
include(Linking)
|
||||
include(Prebuilt)
|
||||
|
||||
if (USESYSTEMLIBS)
|
||||
set(CEFPLUGIN OFF CACHE BOOL
|
||||
"CEFPLUGIN support for the llplugin/llmedia test apps.")
|
||||
else (USESYSTEMLIBS)
|
||||
use_prebuilt_binary(llceflib)
|
||||
set(CEFPLUGIN ON CACHE BOOL
|
||||
"CEFPLUGIN support for the llplugin/llmedia test apps.")
|
||||
set(CEF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/cef)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
||||
if (WINDOWS)
|
||||
set(CEF_PLUGIN_LIBRARIES
|
||||
libcef.lib
|
||||
libcef_dll_wrapper.lib
|
||||
llceflib.lib
|
||||
)
|
||||
elseif (DARWIN)
|
||||
FIND_LIBRARY(APPKIT_LIBRARY AppKit)
|
||||
if (NOT APPKIT_LIBRARY)
|
||||
message(FATAL_ERROR "AppKit not found")
|
||||
endif()
|
||||
|
||||
FIND_LIBRARY(CEF_LIBRARY "Chromium Embedded Framework" ${ARCH_PREBUILT_DIRS_RELEASE})
|
||||
if (NOT CEF_LIBRARY)
|
||||
message(FATAL_ERROR "CEF not found")
|
||||
endif()
|
||||
|
||||
set(CEF_PLUGIN_LIBRARIES
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libLLCefLib.a
|
||||
${APPKIT_LIBRARY}
|
||||
${CEF_LIBRARY}
|
||||
)
|
||||
|
||||
elseif (LINUX)
|
||||
endif (WINDOWS)
|
||||
@@ -16,6 +16,7 @@ set(cmake_SOURCE_FILES
|
||||
Boost.cmake
|
||||
BuildVersion.cmake
|
||||
CARes.cmake
|
||||
CEFPlugin.cmake
|
||||
CMakeCopyIfDifferent.cmake
|
||||
CURL.cmake
|
||||
Colladadom.cmake
|
||||
@@ -39,7 +40,6 @@ set(cmake_SOURCE_FILES
|
||||
FindGooglePerfTools.cmake
|
||||
FindHunSpell.cmake
|
||||
FindJsonCpp.cmake
|
||||
FindLLQtWebkit.cmake
|
||||
FindNDOF.cmake
|
||||
FindOpenJPEG.cmake
|
||||
FindTut.cmake
|
||||
@@ -69,7 +69,6 @@ set(cmake_SOURCE_FILES
|
||||
LLPrimitive.cmake
|
||||
LLPhysicsExtensions.cmake
|
||||
LLSharedLibs.cmake
|
||||
LLQtWebkit.cmake
|
||||
LLRender.cmake
|
||||
LLSharedLibs.cmake
|
||||
LLUI.cmake
|
||||
@@ -90,7 +89,6 @@ set(cmake_SOURCE_FILES
|
||||
Prebuilt.cmake
|
||||
PulseAudio.cmake
|
||||
Python.cmake
|
||||
Qt4.cmake
|
||||
QuickTimePlugin.cmake
|
||||
RunBuildTest.cmake
|
||||
StateMachine.cmake
|
||||
@@ -100,7 +98,6 @@ set(cmake_SOURCE_FILES
|
||||
UnixInstall.cmake
|
||||
Variables.cmake
|
||||
ViewerMiscLibs.cmake
|
||||
WebKitLibPlugin.cmake
|
||||
XmlRpcEpi.cmake
|
||||
ZLIB.cmake
|
||||
)
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
# - Find llqtwebkit
|
||||
# Find the llqtwebkit includes and library
|
||||
# This module defines
|
||||
# LLQTWEBKIT_INCLUDE_DIR, where to find llqtwebkit.h, etc.
|
||||
# LLQTWEBKIT_LIBRARY, the llqtwebkit library with full path.
|
||||
# LLQTWEBKIT_FOUND, If false, do not try to use llqtwebkit.
|
||||
# also defined, but not for general use are
|
||||
# LLQTWEBKIT_LIBRARIES, the libraries needed to use llqtwebkit.
|
||||
# LLQTWEBKIT_LIBRARY_DIRS, where to find the llqtwebkit library.
|
||||
# LLQTWEBKIT_DEFINITIONS - You should add_definitions(${LLQTWEBKIT_DEFINITIONS})
|
||||
# before compiling code that includes llqtwebkit library files.
|
||||
|
||||
# Try to use pkg-config first.
|
||||
# This allows to have two different libllqtwebkit packages installed:
|
||||
# one for viewer 2.x and one for viewer 1.x.
|
||||
include(FindPkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
if (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
|
||||
set(_PACKAGE_ARGS libllqtwebkit>=${LLQtWebkit_FIND_VERSION} REQUIRED)
|
||||
else (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
|
||||
set(_PACKAGE_ARGS libllqtwebkit)
|
||||
endif (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
|
||||
if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_LESS "2.8")
|
||||
# As virtually nobody will have a pkg-config file for this, do this check always quiet.
|
||||
# Unfortunately cmake 2.8 or higher is required for pkg_check_modules to have a 'QUIET'.
|
||||
set(_PACKAGE_ARGS ${_PACKAGE_ARGS} QUIET)
|
||||
endif ()
|
||||
pkg_check_modules(LLQTWEBKIT ${_PACKAGE_ARGS})
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
set(LLQTWEBKIT_DEFINITIONS ${LLQTWEBKIT_CFLAGS_OTHER})
|
||||
|
||||
find_path(LLQTWEBKIT_INCLUDE_DIR llqtwebkit.h NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_INCLUDE_DIRS})
|
||||
|
||||
find_library(LLQTWEBKIT_LIBRARY NAMES llqtwebkit NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_LIBRARY_DIRS})
|
||||
|
||||
if (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND) # If pkg-config couldn't find it, pretend we don't have pkg-config.
|
||||
set(LLQTWEBKIT_LIBRARIES llqtwebkit)
|
||||
get_filename_component(LLQTWEBKIT_LIBRARY_DIRS ${LLQTWEBKIT_LIBRARY} PATH)
|
||||
endif (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set LLQTWEBKIT_FOUND
|
||||
# to TRUE if all listed variables are TRUE.
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
LLQTWEBKIT
|
||||
DEFAULT_MSG
|
||||
LLQTWEBKIT_LIBRARY
|
||||
LLQTWEBKIT_INCLUDE_DIR
|
||||
LLQTWEBKIT_LIBRARIES
|
||||
LLQTWEBKIT_LIBRARY_DIRS
|
||||
)
|
||||
|
||||
mark_as_advanced(
|
||||
LLQTWEBKIT_LIBRARY
|
||||
LLQTWEBKIT_INCLUDE_DIR
|
||||
LLQTWEBKIT_LIBRARIES
|
||||
LLQTWEBKIT_LIBRARY_DIRS
|
||||
LLQTWEBKIT_DEFINITIONS
|
||||
)
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
if (STANDALONE)
|
||||
set(LLQTWEBKIT_INCLUDE_DIR
|
||||
${LIBS_OPEN_DIR}/llqtwebkit
|
||||
)
|
||||
|
||||
set(LLQTWEBKIT_LIBRARY
|
||||
llqtwebkit
|
||||
)
|
||||
endif (STANDALONE)
|
||||
@@ -1,12 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
if (STANDALONE)
|
||||
set(Qt4_FIND_REQUIRED ON)
|
||||
|
||||
include(FindQt4)
|
||||
|
||||
find_package(Qt4 4.7.0 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED)
|
||||
include(${QT_USE_FILE})
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
endif (STANDALONE)
|
||||
@@ -1,64 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
include(Linking)
|
||||
include(Prebuilt)
|
||||
include(LLQtWebkit)
|
||||
include(Qt4)
|
||||
|
||||
if (STANDALONE)
|
||||
set(WEBKITLIBPLUGIN OFF CACHE BOOL
|
||||
"WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(llqtwebkit)
|
||||
set(WEBKITLIBPLUGIN ON CACHE BOOL
|
||||
"WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
|
||||
endif (STANDALONE)
|
||||
|
||||
if (WINDOWS)
|
||||
set(WEBKIT_PLUGIN_LIBRARIES
|
||||
debug llqtwebkitd
|
||||
debug QtWebKitd4
|
||||
debug QtOpenGLd4
|
||||
debug QtNetworkd4
|
||||
debug QtGuid4
|
||||
debug QtCored4
|
||||
debug qtmaind
|
||||
optimized llqtwebkit
|
||||
optimized QtWebKit4
|
||||
optimized QtOpenGL4
|
||||
optimized QtNetwork4
|
||||
optimized QtGui4
|
||||
optimized QtCore4
|
||||
optimized qtmain
|
||||
)
|
||||
elseif (DARWIN)
|
||||
set(WEBKIT_PLUGIN_LIBRARIES
|
||||
debug libllqtwebkit.dylib
|
||||
optimized libllqtwebkit.dylib
|
||||
)
|
||||
elseif (LINUX)
|
||||
if (STANDALONE)
|
||||
set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES} ${QT_PLUGIN_LIBRARIES})
|
||||
else (STANDALONE)
|
||||
set(WEBKIT_PLUGIN_LIBRARIES
|
||||
llqtwebkit
|
||||
QtWebKit
|
||||
QtOpenGL
|
||||
QtNetwork
|
||||
QtGui
|
||||
QtCore
|
||||
crypto
|
||||
ssl
|
||||
# qgif
|
||||
# qjpeg
|
||||
jpeg
|
||||
fontconfig
|
||||
X11
|
||||
Xrender
|
||||
Xext
|
||||
GL
|
||||
)
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 4) # Singu TODO: update webkit
|
||||
set(WEBKIT_PLUGIN_LIBRARIES ${WEBKIT_PLUGIN_LIBRARIES} jscore)
|
||||
endif (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
endif (STANDALONE)
|
||||
endif (WINDOWS)
|
||||
@@ -34,19 +34,19 @@
|
||||
|
||||
// Add this in if we want boost math constants.
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
#pragma warning(push)
|
||||
// warning C4348: 'boost::spirit::terminal<...>::result_helper': redefinition of default parameter: parameter 3, 4
|
||||
#pragma warning(disable: 4348)
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
#pragma warning(push)
|
||||
// warning C4348: 'boost::spirit::terminal<...>::result_helper': redefinition of default parameter: parameter 3, 4
|
||||
#pragma warning(disable: 4348)
|
||||
#endif
|
||||
|
||||
//#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/spirit/include/phoenix.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
#pragma warning(pop)
|
||||
#if defined(LL_WINDOWS)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
namespace expression {
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ include_directories(
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
${LLMESSAGE_INCLUDE_DIRS}
|
||||
${LLRENDER_INCLUDE_DIRS}
|
||||
${LLQTWEBKIT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(llplugin_SOURCE_FILES
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* @file llpluginclassmedia.cpp
|
||||
* @brief LLPluginClassMedia handles a plugin which knows about the "media" message class.
|
||||
*
|
||||
@@ -6,21 +6,21 @@
|
||||
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
* @endcond
|
||||
@@ -41,7 +41,7 @@ static int nextPowerOf2( int value )
|
||||
{
|
||||
next_power_of_2 <<= 1;
|
||||
}
|
||||
|
||||
|
||||
return next_power_of_2;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ void LLPluginClassMedia::reset_impl(void)
|
||||
mMediaName.clear();
|
||||
mMediaDescription.clear();
|
||||
mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
|
||||
// media_browser class
|
||||
mNavigateURI.clear();
|
||||
mNavigateResultCode = -1;
|
||||
@@ -112,13 +112,13 @@ void LLPluginClassMedia::reset_impl(void)
|
||||
mHistoryBackAvailable = false;
|
||||
mHistoryForwardAvailable = false;
|
||||
mStatusText.clear();
|
||||
mProgressPercent = 0;
|
||||
mProgressPercent = 0;
|
||||
mClickURL.clear();
|
||||
mClickNavType.clear();
|
||||
mClickTarget.clear();
|
||||
mClickUUID.clear();
|
||||
mStatusCode = 0;
|
||||
|
||||
|
||||
// media_time class
|
||||
mCurrentTime = 0.0f;
|
||||
mDuration = 0.0f;
|
||||
@@ -144,7 +144,7 @@ void LLPluginClassMedia::idle_impl(void)
|
||||
else
|
||||
{
|
||||
mRequestedTextureWidth = mRequestedMediaWidth;
|
||||
|
||||
|
||||
if(mPadding > 1)
|
||||
{
|
||||
// Pad up to a multiple of the specified number of bytes per row
|
||||
@@ -154,7 +154,7 @@ void LLPluginClassMedia::idle_impl(void)
|
||||
{
|
||||
rowbytes += mPadding - pad;
|
||||
}
|
||||
|
||||
|
||||
if(rowbytes % mRequestedTextureDepth == 0)
|
||||
{
|
||||
mRequestedTextureWidth = rowbytes / mRequestedTextureDepth;
|
||||
@@ -166,7 +166,7 @@ void LLPluginClassMedia::idle_impl(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Size change has been requested but not initiated yet.
|
||||
size_t newsize = mRequestedTextureWidth * mRequestedTextureHeight * mRequestedTextureDepth;
|
||||
|
||||
@@ -181,22 +181,22 @@ void LLPluginClassMedia::idle_impl(void)
|
||||
mPlugin->removeSharedMemory(mTextureSharedMemoryName);
|
||||
mTextureSharedMemoryName.clear();
|
||||
}
|
||||
|
||||
|
||||
mTextureSharedMemorySize = newsize;
|
||||
mTextureSharedMemoryName = mPlugin->addSharedMemory(mTextureSharedMemorySize);
|
||||
if(!mTextureSharedMemoryName.empty())
|
||||
{
|
||||
void *addr = mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName);
|
||||
|
||||
|
||||
// clear texture memory to avoid random screen visual fuzz from uninitialized texture data
|
||||
memset( addr, 0x00, newsize );
|
||||
|
||||
|
||||
// We could do this to force an update, but textureValid() will still be returning false until the first roundtrip to the plugin,
|
||||
// so it may not be worthwhile.
|
||||
// mDirtyRect.setOriginAndSize(0, 0, mRequestedMediaWidth, mRequestedMediaHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This is our local indicator that a change is in progress.
|
||||
mTextureWidth = -1;
|
||||
mTextureHeight = -1;
|
||||
@@ -205,7 +205,7 @@ void LLPluginClassMedia::idle_impl(void)
|
||||
|
||||
// This invalidates any existing dirty rect.
|
||||
resetDirty();
|
||||
|
||||
|
||||
// Send a size change message to the plugin
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change");
|
||||
@@ -219,7 +219,7 @@ void LLPluginClassMedia::idle_impl(void)
|
||||
message.setValueReal("background_b", mBackgroundColor.mV[VZ]);
|
||||
message.setValueReal("background_a", mBackgroundColor.mV[VW]);
|
||||
mPlugin->sendMessage(message); // DO NOT just use sendMessage() here -- we want this to jump ahead of the queue.
|
||||
|
||||
|
||||
LL_DEBUGS("Plugin") << "Sending size_change" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
@@ -278,11 +278,11 @@ void LLPluginClassMedia::setSizeInternal(void)
|
||||
mRequestedMediaWidth = mDefaultMediaWidth;
|
||||
mRequestedMediaHeight = mDefaultMediaHeight;
|
||||
}
|
||||
|
||||
|
||||
// Save these for size/interest calculations
|
||||
mFullMediaWidth = mRequestedMediaWidth;
|
||||
mFullMediaHeight = mRequestedMediaHeight;
|
||||
|
||||
|
||||
if(mAllowDownsample)
|
||||
{
|
||||
switch(mPriority)
|
||||
@@ -296,19 +296,19 @@ void LLPluginClassMedia::setSizeInternal(void)
|
||||
mRequestedMediaHeight /= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
// Don't adjust texture size
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(mAutoScaleMedia)
|
||||
{
|
||||
mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth);
|
||||
mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
|
||||
}
|
||||
|
||||
|
||||
if(mRequestedMediaWidth > 2048)
|
||||
mRequestedMediaWidth = 2048;
|
||||
|
||||
@@ -336,9 +336,9 @@ bool LLPluginClassMedia::textureValid(void)
|
||||
mRequestedMediaWidth != mMediaWidth ||
|
||||
mRequestedMediaHeight != mMediaHeight ||
|
||||
getBitsData() == NULL
|
||||
)
|
||||
)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -362,8 +362,8 @@ void LLPluginClassMedia::resetDirty(void)
|
||||
std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
|
||||
|
||||
|
||||
if(modifiers & MASK_CONTROL)
|
||||
{
|
||||
result += "control|";
|
||||
@@ -386,7 +386,7 @@ std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
|
||||
{
|
||||
result += "meta|";
|
||||
}
|
||||
*/
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -494,11 +494,11 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int
|
||||
// Don't spam unnecessary mouse move events.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mLastMouseX = x;
|
||||
mLastMouseY = y;
|
||||
}
|
||||
|
||||
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "mouse_event");
|
||||
std::string temp;
|
||||
switch(type)
|
||||
@@ -513,7 +513,7 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int
|
||||
message.setValueS32("button", button);
|
||||
|
||||
message.setValueS32("x", x);
|
||||
|
||||
|
||||
// Incoming coordinates are OpenGL-style ((0,0) = lower left), so flip them here if the plugin has requested it.
|
||||
if(!mRequestedTextureCoordsOpenGL)
|
||||
{
|
||||
@@ -523,42 +523,42 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int
|
||||
message.setValueS32("y", y);
|
||||
|
||||
message.setValue("modifiers", translateModifiers(modifiers));
|
||||
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
|
||||
// FIXME:
|
||||
// HACK: we don't have an easy way to tell if the plugin is going to handle a particular keycode.
|
||||
// For now, return false for the ones the webkit plugin won't handle properly.
|
||||
|
||||
|
||||
switch(key_code)
|
||||
{
|
||||
case KEY_BACKSPACE:
|
||||
case KEY_TAB:
|
||||
case KEY_RETURN:
|
||||
case KEY_PAD_RETURN:
|
||||
case KEY_SHIFT:
|
||||
case KEY_CONTROL:
|
||||
case KEY_ALT:
|
||||
case KEY_CAPSLOCK:
|
||||
case KEY_ESCAPE:
|
||||
case KEY_PAGE_UP:
|
||||
case KEY_PAGE_DOWN:
|
||||
case KEY_END:
|
||||
case KEY_HOME:
|
||||
case KEY_LEFT:
|
||||
case KEY_UP:
|
||||
case KEY_RIGHT:
|
||||
case KEY_DOWN:
|
||||
case KEY_INSERT:
|
||||
case KEY_BACKSPACE:
|
||||
case KEY_TAB:
|
||||
case KEY_RETURN:
|
||||
case KEY_PAD_RETURN:
|
||||
case KEY_SHIFT:
|
||||
case KEY_CONTROL:
|
||||
case KEY_ALT:
|
||||
case KEY_CAPSLOCK:
|
||||
case KEY_ESCAPE:
|
||||
case KEY_PAGE_UP:
|
||||
case KEY_PAGE_DOWN:
|
||||
case KEY_END:
|
||||
case KEY_HOME:
|
||||
case KEY_LEFT:
|
||||
case KEY_UP:
|
||||
case KEY_RIGHT:
|
||||
case KEY_DOWN:
|
||||
case KEY_INSERT:
|
||||
case KEY_DELETE:
|
||||
// These will be handled
|
||||
// These will be handled
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
// regular ASCII characters will also be handled
|
||||
if(key_code >= KEY_SPECIAL)
|
||||
@@ -569,7 +569,7 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
|
||||
break;
|
||||
}
|
||||
|
||||
#if LL_DARWIN
|
||||
#if LL_DARWIN
|
||||
if(modifiers & MASK_ALT)
|
||||
{
|
||||
// Option-key modified characters should be handled by the unicode input path instead of this one.
|
||||
@@ -588,15 +588,15 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
|
||||
case KEY_EVENT_REPEAT: temp = "repeat"; break;
|
||||
}
|
||||
message.setValue("event", temp);
|
||||
|
||||
|
||||
message.setValueS32("key", key_code);
|
||||
|
||||
message.setValue("modifiers", translateModifiers(modifiers));
|
||||
message.setValueLLSD("native_key_data", native_key_data);
|
||||
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -607,10 +607,10 @@ void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers)
|
||||
message.setValueS32("x", x);
|
||||
message.setValueS32("y", y);
|
||||
message.setValue("modifiers", translateModifiers(modifiers));
|
||||
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
|
||||
bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD native_key_data)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "text_event");
|
||||
@@ -618,18 +618,33 @@ bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD
|
||||
message.setValue("text", text);
|
||||
message.setValue("modifiers", translateModifiers(modifiers));
|
||||
message.setValueLLSD("native_key_data", native_key_data);
|
||||
|
||||
|
||||
sendMessage(message);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::setCookie(std::string uri, std::string name, std::string value, std::string domain, std::string path, bool httponly, bool secure)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_cookie");
|
||||
|
||||
message.setValue("uri", uri);
|
||||
message.setValue("name", name);
|
||||
message.setValue("value", value);
|
||||
message.setValue("domain", domain);
|
||||
message.setValue("path", path);
|
||||
message.setValueBoolean("httponly", httponly);
|
||||
message.setValueBoolean("secure", secure);
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::loadURI(const std::string &uri)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "load_uri");
|
||||
|
||||
message.setValue("uri", uri);
|
||||
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
@@ -645,6 +660,7 @@ void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
|
||||
if(mLowPrioritySizeLimit != power)
|
||||
{
|
||||
mLowPrioritySizeLimit = power;
|
||||
|
||||
// This may affect the calculated size, so recalculate it here.
|
||||
setSizeInternal();
|
||||
}
|
||||
@@ -653,12 +669,12 @@ void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
|
||||
F64 LLPluginClassMedia::getCPUUsage()
|
||||
{
|
||||
F64 result = 0.0f;
|
||||
|
||||
|
||||
if(mPlugin)
|
||||
{
|
||||
result = mPlugin->getCPUUsage();
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -706,10 +722,12 @@ void LLPluginClassMedia::paste()
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path)
|
||||
void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_logs)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
|
||||
message.setValue("path", user_data_path);
|
||||
message.setValue("cache_path", user_data_path_cache);
|
||||
message.setValue("cookies_path", user_data_path_cookies);
|
||||
message.setValue("logs_path", user_data_path_logs);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
@@ -722,14 +740,14 @@ void LLPluginClassMedia::setLanguageCode(const std::string &language_code)
|
||||
|
||||
void LLPluginClassMedia::setPluginsEnabled(const bool enabled)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "plugins_enabled");
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "plugins_enabled");
|
||||
message.setValueBoolean("enable", enabled);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::setJavascriptEnabled(const bool enabled)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "javascript_enabled");
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "javascript_enabled");
|
||||
message.setValueBoolean("enable", enabled);
|
||||
sendMessage(message);
|
||||
}
|
||||
@@ -746,7 +764,8 @@ void LLPluginClassMedia::setTarget(const std::string &target)
|
||||
{
|
||||
mTarget = target;
|
||||
}
|
||||
/* virtual */
|
||||
|
||||
/* virtual */
|
||||
void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
{
|
||||
std::string message_class = message.getClass();
|
||||
@@ -765,21 +784,21 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
mRequestedTextureFormat = message.getValueU32("format");
|
||||
mRequestedTextureType = message.getValueU32("type");
|
||||
mRequestedTextureSwapBytes = message.getValueBoolean("swap_bytes");
|
||||
mRequestedTextureCoordsOpenGL = message.getValueBoolean("coords_opengl");
|
||||
|
||||
mRequestedTextureCoordsOpenGL = message.getValueBoolean("coords_opengl");
|
||||
|
||||
// These two are optional, and will default to 0 if they're not specified.
|
||||
mDefaultMediaWidth = message.getValueS32("default_width");
|
||||
mDefaultMediaHeight = message.getValueS32("default_height");
|
||||
|
||||
|
||||
mAllowDownsample = message.getValueBoolean("allow_downsample");
|
||||
mPadding = message.getValueS32("padding");
|
||||
|
||||
setSizeInternal();
|
||||
|
||||
|
||||
mTextureParamsReceived = true;
|
||||
}
|
||||
else if(message_name == "updated")
|
||||
{
|
||||
{
|
||||
if(message.hasValue("left"))
|
||||
{
|
||||
LLRect newDirtyRect;
|
||||
@@ -787,7 +806,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
newDirtyRect.mTop = message.getValueS32("top");
|
||||
newDirtyRect.mRight = message.getValueS32("right");
|
||||
newDirtyRect.mBottom = message.getValueS32("bottom");
|
||||
|
||||
|
||||
// The plugin is likely to have top and bottom switched, due to vertical flip and OpenGL coordinate confusion.
|
||||
// If they're backwards, swap them.
|
||||
if(newDirtyRect.mTop < newDirtyRect.mBottom)
|
||||
@@ -796,7 +815,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
newDirtyRect.mTop = newDirtyRect.mBottom;
|
||||
newDirtyRect.mBottom = temp;
|
||||
}
|
||||
|
||||
|
||||
if(mDirtyRect.isEmpty())
|
||||
{
|
||||
mDirtyRect = newDirtyRect;
|
||||
@@ -816,10 +835,10 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
<< mDirtyRect.mRight << ", "
|
||||
<< mDirtyRect.mBottom << ")"
|
||||
<< LL_ENDL;
|
||||
|
||||
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CONTENT_UPDATED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool time_duration_updated = false;
|
||||
int previous_percent = mProgressPercent;
|
||||
@@ -839,7 +858,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
{
|
||||
mCurrentRate = message.getValueReal("current_rate");
|
||||
}
|
||||
|
||||
|
||||
if(message.hasValue("loaded_duration"))
|
||||
{
|
||||
mLoadedDuration = message.getValueReal("loaded_duration");
|
||||
@@ -850,7 +869,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
// If the message doesn't contain a loaded_duration param, assume it's equal to duration
|
||||
mLoadedDuration = mDuration;
|
||||
}
|
||||
|
||||
|
||||
// Calculate a percentage based on the loaded duration and total duration.
|
||||
if(mDuration != 0.0f) // Don't divide by zero.
|
||||
{
|
||||
@@ -861,7 +880,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
{
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED);
|
||||
}
|
||||
|
||||
|
||||
if(previous_percent != mProgressPercent)
|
||||
{
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED);
|
||||
@@ -870,9 +889,9 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
else if(message_name == "media_status")
|
||||
{
|
||||
std::string status = message.getValue("status");
|
||||
|
||||
|
||||
LL_DEBUGS("Plugin") << "Status changed to: " << status << LL_ENDL;
|
||||
|
||||
|
||||
if(status == "loading")
|
||||
{
|
||||
mStatus = LLPluginClassMediaOwner::MEDIA_LOADING;
|
||||
@@ -912,24 +931,24 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
// TODO: check that name matches?
|
||||
mNaturalMediaWidth = width;
|
||||
mNaturalMediaHeight = height;
|
||||
|
||||
|
||||
setSizeInternal();
|
||||
}
|
||||
else if(message_name == "size_change_response")
|
||||
{
|
||||
std::string name = message.getValue("name");
|
||||
|
||||
|
||||
// TODO: check that name matches?
|
||||
|
||||
|
||||
mTextureWidth = message.getValueS32("texture_width");
|
||||
mTextureHeight = message.getValueS32("texture_height");
|
||||
mMediaWidth = message.getValueS32("width");
|
||||
mMediaHeight = message.getValueS32("height");
|
||||
|
||||
|
||||
// This invalidates any existing dirty rect.
|
||||
resetDirty();
|
||||
|
||||
// TODO: should we verify that the plugin sent back the right values?
|
||||
|
||||
// TODO: should we verify that the plugin sent back the right values?
|
||||
// Two size changes in a row may cause them to not match, due to queueing, etc.
|
||||
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_SIZE_CHANGED);
|
||||
@@ -969,7 +988,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
mAuthURL = message.getValue("url");
|
||||
mAuthRealm = message.getValue("realm");
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST);
|
||||
}
|
||||
}
|
||||
else if (message_name == "file_download")
|
||||
{
|
||||
mFileDownloadFilename = message.getValue("filename");
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_FILE_DOWNLOAD);
|
||||
}
|
||||
else if(message_name == "debug_message")
|
||||
{
|
||||
mDebugMessageText = message.getValue("message_text");
|
||||
@@ -996,7 +1020,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
mNavigateResultString = message.getValue("result_string");
|
||||
mHistoryBackAvailable = message.getValueBoolean("history_back_available");
|
||||
mHistoryForwardAvailable = message.getValueBoolean("history_forward_available");
|
||||
|
||||
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE);
|
||||
}
|
||||
else if(message_name == "progress")
|
||||
@@ -1051,7 +1075,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
mGeometryY = message.getValueS32("y");
|
||||
mGeometryWidth = message.getValueS32("width");
|
||||
mGeometryHeight = message.getValueS32("height");
|
||||
|
||||
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE);
|
||||
}
|
||||
else if(message_name == "link_hovered")
|
||||
@@ -1060,7 +1084,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
mHoverLink = message.getValue("link");
|
||||
mHoverText = message.getValue("title");
|
||||
// message.getValue("text");
|
||||
|
||||
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LINK_HOVERED);
|
||||
}
|
||||
else
|
||||
@@ -1076,20 +1100,21 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
// if(message_name == "message_name")
|
||||
// {
|
||||
// }
|
||||
// else
|
||||
// else
|
||||
{
|
||||
LL_WARNS("Plugin") << "Unknown " << message_class << " class message: " << message_name << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
/* virtual */
|
||||
void LLPluginClassMedia::pluginLaunchFailed()
|
||||
{
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
/* virtual */
|
||||
void LLPluginClassMedia::pluginDied()
|
||||
{
|
||||
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED);
|
||||
@@ -1116,7 +1141,7 @@ void LLPluginClassMedia::focus(bool focused)
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "focus");
|
||||
|
||||
message.setValueBoolean("focused", focused);
|
||||
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
@@ -1143,7 +1168,7 @@ void LLPluginClassMedia::clear_cookies()
|
||||
void LLPluginClassMedia::set_cookies(const std::string &cookies)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies");
|
||||
message.setValue("cookies", cookies);
|
||||
message.setValue("cookies", cookies);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
@@ -1176,7 +1201,7 @@ void LLPluginClassMedia::browse_reload(bool ignore_cache)
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_reload");
|
||||
|
||||
message.setValueBoolean("ignore_cache", ignore_cache);
|
||||
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
@@ -1300,7 +1325,7 @@ void LLPluginClassMedia::seek(float time)
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
|
||||
|
||||
message.setValueReal("time", time);
|
||||
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
@@ -1318,11 +1343,11 @@ void LLPluginClassMedia::setVolume(float volume)
|
||||
if(volume != mRequestedVolume)
|
||||
{
|
||||
mRequestedVolume = volume;
|
||||
|
||||
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_volume");
|
||||
|
||||
message.setValueReal("volume", volume);
|
||||
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
}
|
||||
@@ -1341,4 +1366,3 @@ void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history)
|
||||
|
||||
LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,8 @@ public:
|
||||
// Text may be unicode (utf8 encoded)
|
||||
bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data);
|
||||
|
||||
void setCookie(std::string uri, std::string name, std::string value, std::string domain, std::string path, bool httponly, bool secure);
|
||||
|
||||
void loadURI(const std::string &uri);
|
||||
|
||||
// Inherited from LLPluginProcessParentOwner
|
||||
@@ -154,7 +156,7 @@ public:
|
||||
bool canPaste() const { return mCanPaste; };
|
||||
|
||||
// These can be called before init(), and they will be queued and sent before the media init message.
|
||||
void setUserDataPath(const std::string &user_data_path);
|
||||
void setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_logs);
|
||||
void setLanguageCode(const std::string &language_code);
|
||||
void setPluginsEnabled(const bool enabled);
|
||||
void setJavascriptEnabled(const bool enabled);
|
||||
@@ -234,6 +236,10 @@ public:
|
||||
std::string getHoverText() const { return mHoverText; };
|
||||
std::string getHoverLink() const { return mHoverLink; };
|
||||
|
||||
// these are valid during MEDIA_EVENT_LINK_HOVERED
|
||||
std::string getFileDownloadFilename() const { return mFileDownloadFilename; }
|
||||
|
||||
|
||||
const std::string& getMediaName() const { return mMediaName; };
|
||||
std::string getMediaDescription() const { return mMediaDescription; };
|
||||
|
||||
@@ -373,6 +379,7 @@ protected:
|
||||
std::string mAuthRealm;
|
||||
std::string mHoverText;
|
||||
std::string mHoverLink;
|
||||
std::string mFileDownloadFilename;
|
||||
|
||||
/////////////////////////////////////////
|
||||
// media_time class
|
||||
|
||||
@@ -3,33 +3,26 @@
|
||||
* @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
|
||||
*
|
||||
* @cond
|
||||
* $LicenseInfo:firstyear=2008&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2008-2010, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlife.com/developers/opensource/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -71,6 +64,8 @@ public:
|
||||
|
||||
MEDIA_EVENT_AUTH_REQUEST, // The plugin wants to display an auth dialog
|
||||
|
||||
MEDIA_EVENT_FILE_DOWNLOAD, // the plugin wants to download a file
|
||||
|
||||
MEDIA_EVENT_DEBUG_MESSAGE, // plugin sending back debug information for host to process
|
||||
|
||||
MEDIA_EVENT_LINK_HOVERED // Got a "link hovered" event from the plugin
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
project(llqtwebkit)
|
||||
|
||||
include(00-Common)
|
||||
include(Qt4)
|
||||
|
||||
if(NOT WORD_SIZE EQUAL 32)
|
||||
if(WINDOWS)
|
||||
add_definitions(/FIXED:NO)
|
||||
else(WINDOWS)
|
||||
add_definitions(-fPIC)
|
||||
endif(WINDOWS)
|
||||
endif(NOT WORD_SIZE EQUAL 32)
|
||||
|
||||
include_directories(${QT_INCLUDES})
|
||||
|
||||
add_subdirectory(qtwebkit_cookiejar)
|
||||
include_directories(qtwebkit_cookiejar/src/)
|
||||
|
||||
set(llqtwebkit_SOURCE_FILES
|
||||
llembeddedbrowser.cpp
|
||||
llembeddedbrowserwindow.cpp
|
||||
lljsobject.cpp
|
||||
llnetworkaccessmanager.cpp
|
||||
llqtwebkit.cpp
|
||||
llstyle.cpp
|
||||
llwebpage.cpp
|
||||
llwebpageopenshim.cpp
|
||||
)
|
||||
|
||||
set(llqtwebkit_HEADER_FILES
|
||||
llembeddedbrowser.h
|
||||
llembeddedbrowser_p.h
|
||||
llembeddedbrowserwindow.h
|
||||
llembeddedbrowserwindow_p.h
|
||||
lljsobject.h
|
||||
llnetworkaccessmanager.h
|
||||
llqtwebkit.h
|
||||
llstyle.h
|
||||
llwebpage.h
|
||||
llwebpageopenshim.h
|
||||
pstdint.h
|
||||
)
|
||||
|
||||
set(llqtwebkit_UI_FILES
|
||||
passworddialog.ui
|
||||
)
|
||||
|
||||
set(llqtwebkit_LINK_LIBRARIES
|
||||
networkcookiejar
|
||||
)
|
||||
|
||||
QT4_WRAP_UI(llqtwebkit_UI_MOC ${llqtwebkit_UI_FILES})
|
||||
QT4_WRAP_CPP(llqtwebkit_HEADERS_MOC ${llqtwebkit_HEADER_FILES})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_library(llqtwebkit
|
||||
${llqtwebkit_SOURCE_FILES}
|
||||
${llqtwebkit_HEADERS_MOC}
|
||||
${llqtwebkit_UI_MOC}
|
||||
)
|
||||
|
||||
add_dependencies(llqtwebkit prepare)
|
||||
|
||||
target_link_libraries(llqtwebkit ${llqtwebkit_LINK_LIBRARIES})
|
||||
|
||||
add_dependencies(llqtwebkit
|
||||
networkcookiejar
|
||||
)
|
||||
@@ -1,14 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
|
||||
CONFIG += qtestlib
|
||||
QT += webkit opengl network
|
||||
|
||||
include(../../llmozlib2.pri)
|
||||
DEFINES += AUTOTEST
|
||||
|
||||
# Input
|
||||
SOURCES += tst_llembeddedbrowser.cpp
|
||||
|
||||
@@ -1,400 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <llembeddedbrowser.h>
|
||||
#include <llembeddedbrowserwindow.h>
|
||||
|
||||
class tst_LLEmbeddedBrowser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
private slots:
|
||||
void llembeddedbrowser_data();
|
||||
void llembeddedbrowser();
|
||||
|
||||
void clearAllCookies();
|
||||
void clearCache_data();
|
||||
void clearCache();
|
||||
void clearLastError_data();
|
||||
void clearLastError();
|
||||
void createBrowserWindow_data();
|
||||
void createBrowserWindow();
|
||||
void destroyBrowserWindow();
|
||||
void enableCookies_data();
|
||||
void enableCookies();
|
||||
void enablePlugins_data();
|
||||
void enablePlugins();
|
||||
void enableProxy_data();
|
||||
void enableProxy();
|
||||
void getGREVersion_data();
|
||||
void getGREVersion();
|
||||
void getInstance();
|
||||
void getLastError_data();
|
||||
void getLastError();
|
||||
void initBrowser_data();
|
||||
void initBrowser(); //change function init as initbrowser
|
||||
void reset();
|
||||
void setBrowserAgentId_data();
|
||||
void setBrowserAgentId();
|
||||
void setLastError_data();
|
||||
void setLastError();
|
||||
};
|
||||
|
||||
// Subclass that exposes the protected functions.
|
||||
class SubLLEmbeddedBrowser : public LLEmbeddedBrowser
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
// This will be called before the first test function is executed.
|
||||
// It is only called once.
|
||||
void tst_LLEmbeddedBrowser::initTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
// This will be called after the last test function is executed.
|
||||
// It is only called once.
|
||||
void tst_LLEmbeddedBrowser::cleanupTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
// This will be called before each test function is executed.
|
||||
void tst_LLEmbeddedBrowser::init()
|
||||
{
|
||||
}
|
||||
|
||||
// This will be called after every test function.
|
||||
void tst_LLEmbeddedBrowser::cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::llembeddedbrowser_data()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::llembeddedbrowser()
|
||||
{
|
||||
SubLLEmbeddedBrowser browser;
|
||||
QCOMPARE(browser.clearAllCookies(), false);
|
||||
QCOMPARE(browser.clearCache(), false);
|
||||
browser.clearLastError();
|
||||
QCOMPARE(browser.enableCookies(false), false);
|
||||
QCOMPARE(browser.enablePlugins(false), true);
|
||||
QCOMPARE(browser.enableProxy(false, std::string(""), -1), true);
|
||||
QCOMPARE(browser.getGREVersion(), std::string(QT_VERSION_STR));
|
||||
QVERIFY(browser.getInstance() != NULL);
|
||||
QCOMPARE(browser.getLastError(), 0);
|
||||
browser.setBrowserAgentId("uBrowser");
|
||||
browser.setLastError(-1);
|
||||
QCOMPARE(browser.reset(), true);
|
||||
browser.destroyBrowserWindow(0);
|
||||
browser.destroyBrowserWindow((LLEmbeddedBrowserWindow*)6);
|
||||
QCOMPARE(browser.getWindowCount(), 0);
|
||||
QCOMPARE(browser.init(std::string(""),std::string(""),std::string(""),0), true);
|
||||
}
|
||||
|
||||
// public bool clearAllCookies()
|
||||
void tst_LLEmbeddedBrowser::clearAllCookies()
|
||||
{
|
||||
SubLLEmbeddedBrowser browser;
|
||||
|
||||
QCOMPARE(browser.clearAllCookies(), false);
|
||||
browser.reset();
|
||||
QCOMPARE(browser.clearAllCookies(), true);
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::clearCache_data()
|
||||
{
|
||||
QTest::addColumn<bool>("clearCache");
|
||||
#if QT_VERSION < 0x040500
|
||||
QTest::newRow("QTVersion < 4.5") << false;
|
||||
#else
|
||||
QTest::newRow("QTVersion > 4.5") << true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// public bool clearCache()
|
||||
void tst_LLEmbeddedBrowser::clearCache()
|
||||
{
|
||||
QFETCH(bool, clearCache);
|
||||
|
||||
SubLLEmbeddedBrowser browser;
|
||||
browser.reset();
|
||||
QCOMPARE(browser.clearCache(), clearCache);
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::clearLastError_data()
|
||||
{
|
||||
QTest::addColumn<int>("lastError");
|
||||
QTest::newRow("1") << 1;
|
||||
}
|
||||
|
||||
// public void clearLastError()
|
||||
void tst_LLEmbeddedBrowser::clearLastError()
|
||||
{
|
||||
SubLLEmbeddedBrowser browser;
|
||||
QFETCH(int, lastError);
|
||||
|
||||
browser.setLastError(lastError);
|
||||
browser.clearLastError();
|
||||
QCOMPARE(browser.getLastError(), 0);
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::createBrowserWindow_data()
|
||||
{
|
||||
QTest::addColumn<int>("width");
|
||||
QTest::addColumn<int>("height");
|
||||
QTest::newRow("0,0") << 0 << 0;
|
||||
QTest::newRow("800,600") << 800 << 600;
|
||||
}
|
||||
|
||||
// public LLEmbeddedBrowserWindow* createBrowserWindow(int width, int height)
|
||||
void tst_LLEmbeddedBrowser::createBrowserWindow()
|
||||
{
|
||||
QFETCH(int, width);
|
||||
QFETCH(int, height);
|
||||
SubLLEmbeddedBrowser browser;
|
||||
|
||||
LLEmbeddedBrowserWindow *window = browser.createBrowserWindow(width, height);
|
||||
QVERIFY(window);
|
||||
QCOMPARE(browser.getLastError(), 0);
|
||||
QCOMPARE(browser.getWindowCount(), 1);
|
||||
QCOMPARE(window->getBrowserWidth(), (int16_t)width);
|
||||
QCOMPARE(window->getBrowserHeight(), (int16_t)height);
|
||||
}
|
||||
|
||||
// public bool destroyBrowserWindow(LLEmbeddedBrowserWindow* browser_window)
|
||||
void tst_LLEmbeddedBrowser::destroyBrowserWindow()
|
||||
{
|
||||
SubLLEmbeddedBrowser browser;
|
||||
browser.reset();
|
||||
LLEmbeddedBrowserWindow* browser_window = browser.createBrowserWindow(200, 100);
|
||||
if (browser_window)
|
||||
{
|
||||
QCOMPARE(browser.getWindowCount(), 1);
|
||||
browser.destroyBrowserWindow(browser_window);
|
||||
QCOMPARE(browser.getLastError(), 0);
|
||||
QCOMPARE(browser.getWindowCount(), 0);
|
||||
}
|
||||
|
||||
browser_window = browser.createBrowserWindow(800, 600);
|
||||
if (browser_window)
|
||||
{
|
||||
QCOMPARE(browser.getWindowCount(), 1);
|
||||
browser.destroyBrowserWindow(browser_window);
|
||||
QCOMPARE(browser.getLastError(), 0);
|
||||
QCOMPARE(browser.getWindowCount(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::enableCookies_data()
|
||||
{
|
||||
QTest::addColumn<bool>("enabled");
|
||||
QTest::addColumn<bool>("enableCookies");
|
||||
QTest::newRow("disable") << false << false;
|
||||
QTest::newRow("enable") << true << false;
|
||||
}
|
||||
|
||||
// public bool enableCookies(bool enabled)
|
||||
void tst_LLEmbeddedBrowser::enableCookies()
|
||||
{
|
||||
QFETCH(bool, enabled);
|
||||
QFETCH(bool, enableCookies);
|
||||
|
||||
SubLLEmbeddedBrowser browser;
|
||||
browser.reset();
|
||||
QCOMPARE(browser.enableCookies(enabled), enableCookies);
|
||||
// TODO check that cookies are not saved
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::enablePlugins_data()
|
||||
{
|
||||
QTest::addColumn<bool>("enabled");
|
||||
QTest::addColumn<bool>("enablePlugins");
|
||||
QTest::newRow("disable") << false << true;
|
||||
QTest::newRow("enable") << true << true;
|
||||
}
|
||||
|
||||
// public bool enablePlugins(bool enabled)
|
||||
void tst_LLEmbeddedBrowser::enablePlugins()
|
||||
{
|
||||
QFETCH(bool, enabled);
|
||||
QFETCH(bool, enablePlugins);
|
||||
|
||||
SubLLEmbeddedBrowser browser;
|
||||
browser.reset();
|
||||
QCOMPARE(browser.enablePlugins(enabled), enablePlugins);
|
||||
// TODO check that plugins work/do not work
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(std::string)
|
||||
void tst_LLEmbeddedBrowser::enableProxy_data()
|
||||
{
|
||||
QTest::addColumn<bool>("enabled");
|
||||
QTest::addColumn<std::string>("host_name");
|
||||
QTest::addColumn<int>("port");
|
||||
QTest::addColumn<bool>("enableProxy");
|
||||
QTest::newRow("null") << false << std::string() << 0 << true;
|
||||
QTest::newRow("valid") << true << std::string("wtfsurf.com") << 80 << true;
|
||||
}
|
||||
|
||||
// public bool enableProxy(bool enabled, std::string host_name, int port)
|
||||
void tst_LLEmbeddedBrowser::enableProxy()
|
||||
{
|
||||
QFETCH(bool, enabled);
|
||||
QFETCH(std::string, host_name);
|
||||
QFETCH(int, port);
|
||||
QFETCH(bool, enableProxy);
|
||||
|
||||
SubLLEmbeddedBrowser browser;
|
||||
browser.reset();
|
||||
QCOMPARE(browser.enableProxy(enabled, host_name, port), enableProxy);
|
||||
// TODO need some proxy servers to test this
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::getGREVersion_data()
|
||||
{
|
||||
QTest::addColumn<std::string>("getGREVersion");
|
||||
QTest::newRow("valid") << std::string(QT_VERSION_STR);
|
||||
}
|
||||
|
||||
// public std::string getGREVersion()
|
||||
void tst_LLEmbeddedBrowser::getGREVersion()
|
||||
{
|
||||
QFETCH(std::string, getGREVersion);
|
||||
|
||||
SubLLEmbeddedBrowser browser;
|
||||
browser.reset();
|
||||
QCOMPARE(browser.getGREVersion(), getGREVersion);
|
||||
}
|
||||
|
||||
// public static LLEmbeddedBrowser* getInstance()
|
||||
void tst_LLEmbeddedBrowser::getInstance()
|
||||
{
|
||||
SubLLEmbeddedBrowser browser;
|
||||
QVERIFY(browser.getInstance() != NULL);
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::getLastError_data()
|
||||
{
|
||||
QTest::addColumn<int>("error");
|
||||
QTest::newRow("0") << 0;
|
||||
QTest::newRow("-1") << -1;
|
||||
QTest::newRow("100") << 100;
|
||||
}
|
||||
|
||||
// public int getLastError()
|
||||
void tst_LLEmbeddedBrowser::getLastError()
|
||||
{
|
||||
QFETCH(int, error);
|
||||
SubLLEmbeddedBrowser browser;
|
||||
browser.setLastError(error);
|
||||
QCOMPARE(browser.getLastError(), error);
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::initBrowser_data()
|
||||
{
|
||||
QTest::addColumn<std::string>("application_directory");
|
||||
QTest::addColumn<std::string>("component_directory");
|
||||
QTest::addColumn<std::string>("profile_directory");
|
||||
QTest::addColumn<void *>("native_window_handleCount");
|
||||
QTest::addColumn<bool>("init");
|
||||
QTest::newRow("null") << std::string() << std::string() << std::string() << (void *)0 << true;
|
||||
QTest::newRow("valid") << std::string("/home/crystal/Settings/") << std::string() << std::string() << (void *)0 << true;
|
||||
}
|
||||
void tst_LLEmbeddedBrowser::initBrowser()
|
||||
{
|
||||
QFETCH(std::string, application_directory);
|
||||
QFETCH(std::string, component_directory);
|
||||
QFETCH(std::string, profile_directory);
|
||||
QFETCH(void *, native_window_handleCount);
|
||||
SubLLEmbeddedBrowser browser;
|
||||
browser.init(application_directory,component_directory,profile_directory,native_window_handleCount);
|
||||
QCOMPARE(browser.getLastError(), 0);
|
||||
}
|
||||
|
||||
// public bool reset()
|
||||
void tst_LLEmbeddedBrowser::reset()
|
||||
{
|
||||
SubLLEmbeddedBrowser browser;
|
||||
|
||||
browser.setLastError(100);
|
||||
QCOMPARE(browser.getLastError(), 100);
|
||||
QVERIFY(browser.reset());
|
||||
QCOMPARE(browser.getLastError(), 0);
|
||||
// TODO what should reset really do?
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::setBrowserAgentId_data()
|
||||
{
|
||||
QTest::addColumn<std::string>("id");
|
||||
QTest::newRow("null") << std::string();
|
||||
QTest::newRow("valid") << std::string("uBrowser");
|
||||
|
||||
}
|
||||
|
||||
// public void setBrowserAgentId(std::string id)
|
||||
void tst_LLEmbeddedBrowser::setBrowserAgentId()
|
||||
{
|
||||
QFETCH(std::string, id);
|
||||
|
||||
SubLLEmbeddedBrowser browser;
|
||||
browser.reset();
|
||||
browser.setBrowserAgentId(id);
|
||||
LLEmbeddedBrowserWindow *window = browser.createBrowserWindow(0, 0);
|
||||
Q_UNUSED(window);
|
||||
// TODO confirm that the page is actually sending the agent ID
|
||||
}
|
||||
|
||||
void tst_LLEmbeddedBrowser::setLastError_data()
|
||||
{
|
||||
QTest::addColumn<int>("error_number");
|
||||
QTest::newRow("0") << 0;
|
||||
QTest::newRow("-1") << -1;
|
||||
QTest::newRow("100") << 100;
|
||||
}
|
||||
|
||||
// public void setLastError(int error_number)
|
||||
void tst_LLEmbeddedBrowser::setLastError()
|
||||
{
|
||||
QFETCH(int, error_number);
|
||||
|
||||
SubLLEmbeddedBrowser browser;
|
||||
|
||||
browser.setLastError(error_number);
|
||||
QCOMPARE(browser.getLastError(), error_number);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_LLEmbeddedBrowser)
|
||||
#include "tst_llembeddedbrowser.moc"
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
|
||||
CONFIG += qtestlib
|
||||
QT += webkit opengl network
|
||||
|
||||
include(../../llmozlib2.pri)
|
||||
DEFINES += AUTOTEST
|
||||
|
||||
# Input
|
||||
SOURCES += tst_llembeddedbrowserwindow.cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,759 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include "llembeddedbrowser.h"
|
||||
|
||||
#include "llembeddedbrowser_p.h"
|
||||
#include "llembeddedbrowserwindow.h"
|
||||
#include "llnetworkaccessmanager.h"
|
||||
#include "llstyle.h"
|
||||
|
||||
#include <qvariant.h>
|
||||
#include <qwebsettings.h>
|
||||
#include <qnetworkproxy.h>
|
||||
#include <qfile.h>
|
||||
#include <qsslconfiguration.h>
|
||||
#include <qsslsocket.h>
|
||||
#include <qdesktopservices.h>
|
||||
#include <qdatetime.h>
|
||||
#include <iostream>
|
||||
|
||||
// singleton pattern - initialization
|
||||
LLEmbeddedBrowser* LLEmbeddedBrowser::sInstance = 0;
|
||||
|
||||
LLEmbeddedBrowserPrivate::LLEmbeddedBrowserPrivate()
|
||||
: mErrorNum(0)
|
||||
, mNativeWindowHandle(0)
|
||||
, mNetworkAccessManager(0)
|
||||
, mApplication(0)
|
||||
#if QT_VERSION >= 0x040500
|
||||
, mDiskCache(0)
|
||||
#endif
|
||||
, mNetworkCookieJar(0)
|
||||
, mHostLanguage( "en" )
|
||||
, mIgnoreSSLCertErrors(false)
|
||||
{
|
||||
if (!qApp)
|
||||
{
|
||||
static int argc = 0;
|
||||
static const char* argv[] = {""};
|
||||
QApplication::setAttribute(Qt::AA_MacPluginApplication);
|
||||
QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
|
||||
mApplication = new QApplication(argc, (char **)argv);
|
||||
mApplication->addLibraryPath(qApp->applicationDirPath());
|
||||
}
|
||||
qApp->setStyle(new LLStyle());
|
||||
mNetworkAccessManager = new LLNetworkAccessManager(this);
|
||||
#if LL_DARWIN
|
||||
// HACK: Qt installs CarbonEvent handlers that steal events from our main event loop.
|
||||
// This uninstalls them.
|
||||
// It's not clear whether calling this internal function is really a good idea. It's probably not.
|
||||
// It does, however, seem to fix at least one problem ( https://jira.secondlife.com/browse/MOZ-12 ).
|
||||
extern void qt_release_app_proc_handler();
|
||||
qt_release_app_proc_handler();
|
||||
|
||||
// This is defined and exported from qwidget_mac.mm.
|
||||
// Calling it with false should prevent qwidget from bringing its process to the foreground, such as when bringing up a popup menu.
|
||||
extern void qt_mac_set_raise_process(bool b);
|
||||
qt_mac_set_raise_process(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
LLEmbeddedBrowserPrivate::~LLEmbeddedBrowserPrivate()
|
||||
{
|
||||
delete mApplication;
|
||||
delete mNetworkAccessManager;
|
||||
delete mNetworkCookieJar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LLEmbeddedBrowser::LLEmbeddedBrowser()
|
||||
: d(new LLEmbeddedBrowserPrivate)
|
||||
, mPluginsEnabled( false )
|
||||
, mJavaScriptEnabled( false )
|
||||
, mCookiesEnabled( false )
|
||||
{
|
||||
}
|
||||
|
||||
LLEmbeddedBrowser::~LLEmbeddedBrowser()
|
||||
{
|
||||
if(d->mNetworkCookieJar)
|
||||
{
|
||||
d->mNetworkCookieJar->mBrowser = NULL;
|
||||
}
|
||||
|
||||
delete d;
|
||||
}
|
||||
|
||||
LLEmbeddedBrowser* LLEmbeddedBrowser::getInstance()
|
||||
{
|
||||
if (!sInstance)
|
||||
sInstance = new LLEmbeddedBrowser;
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setLastError(int error_number)
|
||||
{
|
||||
d->mErrorNum = error_number;
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::clearLastError()
|
||||
{
|
||||
d->mErrorNum = 0x0000;
|
||||
}
|
||||
|
||||
int LLEmbeddedBrowser::getLastError()
|
||||
{
|
||||
return d->mErrorNum;
|
||||
}
|
||||
|
||||
std::string LLEmbeddedBrowser::getGREVersion()
|
||||
{
|
||||
// take the string directly from Qt
|
||||
return std::string(QT_VERSION_STR);
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::init(std::string application_directory,
|
||||
std::string component_directory,
|
||||
std::string profile_directory,
|
||||
void* native_window_handle)
|
||||
{
|
||||
Q_UNUSED(application_directory);
|
||||
Q_UNUSED(component_directory);
|
||||
Q_UNUSED(native_window_handle);
|
||||
d->mStorageDirectory = QString::fromStdString(profile_directory);
|
||||
QWebSettings::setIconDatabasePath(d->mStorageDirectory);
|
||||
// The gif and jpeg libraries should be installed in component_directory/imageformats/
|
||||
QCoreApplication::addLibraryPath(QString::fromStdString(component_directory));
|
||||
|
||||
// turn on plugins by default
|
||||
enablePlugins( true );
|
||||
|
||||
// Until QtWebkit defaults to 16
|
||||
QWebSettings::globalSettings()->setFontSize(QWebSettings::DefaultFontSize, 16);
|
||||
QWebSettings::globalSettings()->setFontSize(QWebSettings::DefaultFixedFontSize, 16);
|
||||
|
||||
|
||||
QWebSettings::globalSettings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
|
||||
QWebSettings::globalSettings()->setOfflineStoragePath(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
|
||||
|
||||
// use default text encoding - not sure how this helps right now so commenting out until we
|
||||
// understand how to use it a little better.
|
||||
//QWebSettings::globalSettings()->setDefaultTextEncoding ( "" );
|
||||
|
||||
return reset();
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::reset()
|
||||
{
|
||||
foreach(LLEmbeddedBrowserWindow *window, d->windows)
|
||||
delete window;
|
||||
d->windows.clear();
|
||||
delete d->mNetworkAccessManager;
|
||||
d->mNetworkAccessManager = new LLNetworkAccessManager(d);
|
||||
#if QT_VERSION >= 0x040500
|
||||
d->mDiskCache = new QNetworkDiskCache(d->mNetworkAccessManager);
|
||||
d->mDiskCache->setCacheDirectory(d->mStorageDirectory + "/cache");
|
||||
if (QLatin1String(qVersion()) != QLatin1String("4.5.1"))
|
||||
d->mNetworkAccessManager->setCache(d->mDiskCache);
|
||||
#endif
|
||||
d->mNetworkCookieJar = new LLNetworkCookieJar(d->mNetworkAccessManager, this);
|
||||
d->mNetworkAccessManager->setCookieJar(d->mNetworkCookieJar);
|
||||
clearLastError();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::clearCache()
|
||||
{
|
||||
#if QT_VERSION >= 0x040500
|
||||
if (d->mDiskCache)
|
||||
{
|
||||
d->mDiskCache->clear();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::enableProxy(bool enabled, std::string host_name, int port)
|
||||
{
|
||||
QNetworkProxy proxy;
|
||||
if (enabled)
|
||||
{
|
||||
proxy.setType(QNetworkProxy::HttpProxy);
|
||||
QString q_host_name = QString::fromStdString(host_name);
|
||||
proxy.setHostName(q_host_name);
|
||||
proxy.setPort(port);
|
||||
}
|
||||
d->mNetworkAccessManager->setProxy(proxy);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::clearAllCookies()
|
||||
{
|
||||
if (!d->mNetworkCookieJar)
|
||||
return false;
|
||||
d->mNetworkCookieJar->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setCookies(const std::string &cookies)
|
||||
{
|
||||
if (d->mNetworkCookieJar)
|
||||
{
|
||||
d->mNetworkCookieJar->setCookiesFromRawForm(cookies);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLEmbeddedBrowser::getAllCookies()
|
||||
{
|
||||
std::string result;
|
||||
|
||||
if (d->mNetworkCookieJar)
|
||||
{
|
||||
result = d->mNetworkCookieJar->getAllCookiesInRawForm();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::enableCookies( bool enabled )
|
||||
{
|
||||
mCookiesEnabled = enabled;
|
||||
enableCookiesTransient( mCookiesEnabled );
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::enableCookiesTransient( bool enabled )
|
||||
{
|
||||
if ( d->mNetworkCookieJar )
|
||||
{
|
||||
d->mNetworkCookieJar->mAllowCookies = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::areCookiesEnabled()
|
||||
{
|
||||
return mCookiesEnabled;
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::enablePlugins( bool enabled )
|
||||
{
|
||||
mPluginsEnabled = enabled; // record state
|
||||
enablePluginsTransient( mPluginsEnabled );
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::enablePluginsTransient( bool enabled )
|
||||
{
|
||||
QWebSettings* default_settings = QWebSettings::globalSettings();
|
||||
default_settings->setAttribute( QWebSettings::PluginsEnabled, enabled );
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::arePluginsEnabled()
|
||||
{
|
||||
return mPluginsEnabled;
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::enableJavaScript( bool enabled )
|
||||
{
|
||||
mJavaScriptEnabled = enabled; // record state
|
||||
enableJavaScriptTransient( mJavaScriptEnabled );
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::enableJavaScriptTransient( bool enabled )
|
||||
{
|
||||
QWebSettings* default_settings = QWebSettings::globalSettings();
|
||||
default_settings->setAttribute( QWebSettings::JavascriptEnabled, enabled );
|
||||
default_settings->setAttribute( QWebSettings::JavascriptCanOpenWindows, enabled );
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::isJavaScriptEnabled()
|
||||
{
|
||||
return mJavaScriptEnabled;
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::showWebInspector(bool show)
|
||||
{
|
||||
QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, show);
|
||||
foreach (LLEmbeddedBrowserWindow* window, d->windows)
|
||||
{
|
||||
window->showWebInspector(show);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Sets a string that should be addded to the user agent to identify the application
|
||||
*/
|
||||
void LLEmbeddedBrowser::setBrowserAgentId(std::string id)
|
||||
{
|
||||
QCoreApplication::setApplicationName(QString::fromStdString(id));
|
||||
}
|
||||
|
||||
// updates value of 'hostLanguage' in JavaScript 'Navigator' obect that
|
||||
// embedded pages can query to see what language the host app is set to
|
||||
// IMPORTANT: call this before any windows are created - only gets passed
|
||||
// to LLWebPage when new window is created
|
||||
void LLEmbeddedBrowser::setHostLanguage( const std::string& host_language )
|
||||
{
|
||||
d->mHostLanguage = host_language;
|
||||
}
|
||||
|
||||
LLEmbeddedBrowserWindow* LLEmbeddedBrowser::createBrowserWindow(int width, int height, const std::string target)
|
||||
{
|
||||
LLEmbeddedBrowserWindow *newWin = new LLEmbeddedBrowserWindow();
|
||||
if (newWin)
|
||||
{
|
||||
newWin->setSize(width, height);
|
||||
newWin->setParent(this);
|
||||
newWin->setHostLanguage(d->mHostLanguage);
|
||||
clearLastError();
|
||||
d->windows.append(newWin);
|
||||
|
||||
if(!target.empty() && (target != "_blank"))
|
||||
{
|
||||
newWin->setTarget(target);
|
||||
}
|
||||
|
||||
return newWin;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::destroyBrowserWindow(LLEmbeddedBrowserWindow* browser_window)
|
||||
{
|
||||
// check if exists in windows list
|
||||
if (d->windows.removeOne(browser_window))
|
||||
{
|
||||
delete browser_window;
|
||||
clearLastError();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int LLEmbeddedBrowser::getWindowCount() const
|
||||
{
|
||||
return d->windows.size();
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::pump(int max_milliseconds)
|
||||
{
|
||||
#if 0
|
||||
// This USED to be necessary on the mac, but with Qt 4.6 it seems to cause trouble loading some pages,
|
||||
// and using processEvents() seems to work properly now.
|
||||
// Leaving this here in case these issues ever come back.
|
||||
|
||||
// On the Mac, calling processEvents hangs the viewer.
|
||||
// I'm not entirely sure this does everything we need, but it seems to work better, and allows things like animated gifs to work.
|
||||
qApp->sendPostedEvents();
|
||||
qApp->sendPostedEvents(0, QEvent::DeferredDelete);
|
||||
#else
|
||||
qApp->processEvents(QEventLoop::AllEvents, max_milliseconds);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::cookieChanged(const std::string &cookie, const std::string &url, bool dead)
|
||||
{
|
||||
foreach (LLEmbeddedBrowserWindow* window, d->windows)
|
||||
{
|
||||
window->cookieChanged(cookie, url, dead);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLEmbeddedBrowser::setCAFile(const std::string &ca_file)
|
||||
{
|
||||
bool result = false;
|
||||
//qDebug() << "LLEmbeddedBrowser::" << __FUNCTION__ << "attempting to read certs from file: " << QString::fromStdString(ca_file);
|
||||
|
||||
// Extract the list of certificates from the specified file
|
||||
QList<QSslCertificate> certs = QSslCertificate::fromPath(QString::fromStdString(ca_file));
|
||||
|
||||
if(!certs.isEmpty())
|
||||
{
|
||||
//qDebug() << "LLEmbeddedBrowser::" << __FUNCTION__ << "certs read: " << certs;
|
||||
|
||||
// Set the default CA cert for Qt's SSL implementation.
|
||||
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
|
||||
config.setCaCertificates(certs);
|
||||
QSslConfiguration::setDefaultConfiguration(config);
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLEmbeddedBrowser::addCAFile(const std::string &ca_file)
|
||||
{
|
||||
// Enabling this can help diagnose certificate verification issues.
|
||||
const bool cert_debugging_on = false;
|
||||
|
||||
if ( cert_debugging_on )
|
||||
{
|
||||
//qDebug() << "\n\nLLEmbeddedBrowser::" << __FUNCTION__ << " ------------------- (Before add)";
|
||||
QSslCertificate cert;
|
||||
foreach(cert, QSslSocket::defaultCaCertificates())
|
||||
{
|
||||
//qDebug() << cert.issuerInfo(QSslCertificate::CommonName) << " --- " << cert.subjectInfo(QSslCertificate::CommonName);
|
||||
}
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
//qDebug() << "LLEmbeddedBrowser::" << __FUNCTION__ << "attempting to read certs from file: " << QString::fromStdString(ca_file);
|
||||
|
||||
if ( cert_debugging_on )
|
||||
{
|
||||
//qDebug() << "\n\nLLEmbeddedBrowser::" << __FUNCTION__ << " ------------------- (From CA.pem)";
|
||||
QList<QSslCertificate> certs = QSslCertificate::fromPath(QString::fromStdString(ca_file));
|
||||
QSslCertificate cert;
|
||||
foreach(cert, certs)
|
||||
{
|
||||
//qDebug() << cert.issuerInfo(QSslCertificate::CommonName) << " --- " << cert.subjectInfo(QSslCertificate::CommonName);
|
||||
}
|
||||
}
|
||||
|
||||
result = QSslSocket::addDefaultCaCertificates(QString::fromStdString(ca_file));
|
||||
|
||||
if ( cert_debugging_on )
|
||||
{
|
||||
//qDebug() << "\n\nLLEmbeddedBrowser::" << __FUNCTION__ << " ------------------- (After add)";
|
||||
QSslCertificate cert;
|
||||
foreach(cert, QSslSocket::defaultCaCertificates())
|
||||
{
|
||||
//qDebug() << cert.issuerInfo(QSslCertificate::CommonName) << " --- " << cert.subjectInfo(QSslCertificate::CommonName);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setIgnoreSSLCertErrors(bool ignore)
|
||||
{
|
||||
d->mIgnoreSSLCertErrors = ignore;
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowser::getIgnoreSSLCertErrors()
|
||||
{
|
||||
return d->mIgnoreSSLCertErrors;
|
||||
}
|
||||
|
||||
const std::vector< std::string > LLEmbeddedBrowser::getInstalledCertsList()
|
||||
{
|
||||
std::vector< std::string > cert_list;
|
||||
|
||||
QSslCertificate cert;
|
||||
foreach(cert, QSslSocket::defaultCaCertificates())
|
||||
{
|
||||
QString cert_info="";
|
||||
|
||||
QString issuer_info="";
|
||||
issuer_info+="C=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::CountryName);
|
||||
issuer_info+=", ST=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::StateOrProvinceName);
|
||||
issuer_info+=", L=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::LocalityName);
|
||||
issuer_info+=", O=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::Organization);
|
||||
issuer_info+=", OU=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::OrganizationalUnitName);
|
||||
issuer_info+=", CN=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::CommonName);
|
||||
cert_info+=issuer_info;
|
||||
cert_info+="\n";
|
||||
|
||||
QString subject_info="";
|
||||
subject_info+="C=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::CountryName);
|
||||
subject_info+=", ST=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::StateOrProvinceName);
|
||||
subject_info+=", L=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::LocalityName);
|
||||
subject_info+=", O=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::Organization);
|
||||
subject_info+=", OU=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
|
||||
subject_info+=", CN=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::CommonName);
|
||||
cert_info+=subject_info;
|
||||
cert_info+="\n";
|
||||
|
||||
cert_info+="Not valid before: ";
|
||||
cert_info+=cert.effectiveDate().toString();
|
||||
cert_info+="\n";
|
||||
cert_info+="Not valid after: ";
|
||||
cert_info+=cert.expiryDate().toString();
|
||||
cert_info+="\n";
|
||||
|
||||
cert_list.push_back( llToStdString(cert_info) );
|
||||
}
|
||||
return cert_list;
|
||||
}
|
||||
|
||||
// Second Life viewer specific functions
|
||||
void LLEmbeddedBrowser::setSLObjectEnabled( bool enabled )
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->setSLObjectEnabled( enabled );
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setAgentLanguage( const std::string& agent_language )
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->setAgentLanguage( agent_language );
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setAgentRegion( const std::string& agent_region )
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->setAgentRegion( agent_region );
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setAgentLocation( double x, double y, double z )
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->setAgentLocation( x, y, z );
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setAgentGlobalLocation( double x, double y, double z )
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->setAgentGlobalLocation( x, y, z );
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setAgentOrientation( double angle )
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->setAgentOrientation( angle );
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setAgentMaturity( const std::string& agent_maturity )
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->setAgentMaturity( agent_maturity );
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::emitLocation()
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->emitLocation();
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::emitMaturity()
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->emitMaturity();
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::emitLanguage()
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->emitLanguage();
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::setPageZoomFactor( double factor )
|
||||
{
|
||||
foreach ( LLEmbeddedBrowserWindow* window, d->windows )
|
||||
{
|
||||
window->setPageZoomFactor( factor );
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::qtMessageHandler(QtMsgType type, const char *msg)
|
||||
{
|
||||
std::string msg_type("");
|
||||
switch (type)
|
||||
{
|
||||
case QtDebugMsg:
|
||||
msg_type="Debug";
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
msg_type="Warning";
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
msg_type="Critical";
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
msg_type="Fatal";
|
||||
break;
|
||||
};
|
||||
|
||||
foreach ( LLEmbeddedBrowserWindow* window, sInstance->d->windows )
|
||||
{
|
||||
|
||||
window->onQtDebugMessage( std::string( msg ), msg_type);
|
||||
}
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowser::enableQtMessageHandler( bool enable )
|
||||
{
|
||||
if ( enable )
|
||||
{
|
||||
qInstallMsgHandler( qtMessageHandler );
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove handler
|
||||
qInstallMsgHandler(0);
|
||||
};
|
||||
}
|
||||
|
||||
LLNetworkCookieJar::LLNetworkCookieJar(QObject* parent, LLEmbeddedBrowser *browser)
|
||||
: NetworkCookieJar(parent)
|
||||
, mAllowCookies(true)
|
||||
, mBrowser(browser)
|
||||
{
|
||||
}
|
||||
|
||||
LLNetworkCookieJar::~LLNetworkCookieJar()
|
||||
{
|
||||
}
|
||||
|
||||
QList<QNetworkCookie> LLNetworkCookieJar::cookiesForUrl(const QUrl& url) const
|
||||
{
|
||||
if (!mAllowCookies)
|
||||
return QList<QNetworkCookie>();
|
||||
return NetworkCookieJar::cookiesForUrl(url);
|
||||
}
|
||||
|
||||
bool LLNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookie_list, const QUrl& url)
|
||||
{
|
||||
if (!mAllowCookies)
|
||||
return false;
|
||||
return NetworkCookieJar::setCookiesFromUrl(cookie_list, url);
|
||||
}
|
||||
|
||||
void LLNetworkCookieJar::onCookieSetFromURL(const QNetworkCookie &cookie, const QUrl &url, bool already_dead)
|
||||
{
|
||||
// qDebug() << "LLNetworkCookieJar::" << __FUNCTION__ << (already_dead?"set dead cookie":"set cookie ") << cookie;
|
||||
|
||||
if(mBrowser)
|
||||
{
|
||||
QByteArray cookie_bytes = cookie.toRawForm(QNetworkCookie::Full);
|
||||
std::string cookie_string(cookie_bytes.data(), cookie_bytes.size());
|
||||
std::string url_string = llToStdString(url);
|
||||
mBrowser->cookieChanged(cookie_string, url_string, already_dead);
|
||||
}
|
||||
}
|
||||
|
||||
void LLNetworkCookieJar::clear()
|
||||
{
|
||||
clearCookies();
|
||||
}
|
||||
|
||||
void LLNetworkCookieJar::setCookiesFromRawForm(const std::string &cookie_string)
|
||||
{
|
||||
QByteArray cookie_bytearray(cookie_string.data(), cookie_string.size());
|
||||
QList<QNetworkCookie> cookie_list = QNetworkCookie::parseCookies(cookie_bytearray);
|
||||
setCookies(cookie_list);
|
||||
}
|
||||
|
||||
std::string LLNetworkCookieJar::getAllCookiesInRawForm()
|
||||
{
|
||||
std::string result;
|
||||
|
||||
QList<QNetworkCookie> cookie_list = allCookies();
|
||||
|
||||
foreach (const QNetworkCookie &cookie, cookie_list)
|
||||
{
|
||||
QByteArray raw_form = cookie.toRawForm(QNetworkCookie::Full);
|
||||
result.append(raw_form.data(), raw_form.size());
|
||||
result.append("\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#include "llembeddedbrowserwindow_p.h"
|
||||
#include <qnetworkreply.h>
|
||||
|
||||
QGraphicsWebView *LLEmbeddedBrowserPrivate::findView(QNetworkReply *reply)
|
||||
{
|
||||
for (int i = 0; i < windows.count(); ++i)
|
||||
if (windows[i]->d->mView->url() == reply->url())
|
||||
return windows[i]->d->mView;
|
||||
return windows[0]->d->mView;
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowserPrivate::authRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
// qDebug() << "LLEmbeddedBrowser::" << __FUNCTION__ << "requesting auth for url " << QString::fromStdString(in_url) << ", realm " << QString::fromStdString(in_realm);
|
||||
//
|
||||
// qDebug() << "LLEmbeddedBrowser::" << __FUNCTION__ << "window count is " << windows.count();
|
||||
|
||||
if(windows.count() > 1)
|
||||
{
|
||||
qDebug() << "LLEmbeddedBrowser::" << __FUNCTION__ << "WARNING: authRequest called with more than one window, using the first one";
|
||||
}
|
||||
|
||||
LLEmbeddedBrowserWindow* window = windows.first();
|
||||
|
||||
if(window)
|
||||
{
|
||||
result = window->authRequest(in_url, in_realm, out_username, out_password);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowserPrivate::certError(const std::string &in_url, const std::string &in_msg)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
LLEmbeddedBrowserWindow* window = windows.first();
|
||||
if(window)
|
||||
{
|
||||
result = window->certError(in_url, in_msg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLEMBEDDEDBROWSER_H
|
||||
#define LLEMBEDDEDBROWSER_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <QtDebug>
|
||||
|
||||
class LLEmbeddedBrowserWindow;
|
||||
class LLEmbeddedBrowserWindowObserver;
|
||||
|
||||
class LLEmbeddedBrowserPrivate;
|
||||
class LLEmbeddedBrowser
|
||||
{
|
||||
public:
|
||||
LLEmbeddedBrowser();
|
||||
virtual ~LLEmbeddedBrowser();
|
||||
|
||||
static LLEmbeddedBrowser* getInstance();
|
||||
|
||||
bool init(std::string application_directory,
|
||||
std::string component_directory,
|
||||
std::string profile_directory,
|
||||
void* native_window_handle);
|
||||
bool reset();
|
||||
bool clearCache();
|
||||
bool enableProxy(bool enabled, std::string host_name, int port);
|
||||
bool clearAllCookies();
|
||||
void setCookies(const std::string &cookies);
|
||||
std::string getAllCookies();
|
||||
|
||||
void enableCookies( bool enabled );
|
||||
void enableCookiesTransient( bool enabled );
|
||||
bool areCookiesEnabled();
|
||||
void enablePlugins( bool enabled );
|
||||
void enablePluginsTransient( bool enabled );
|
||||
bool arePluginsEnabled();
|
||||
void enableJavaScript( bool enabled );
|
||||
void enableJavaScriptTransient( bool enabled );
|
||||
bool isJavaScriptEnabled();
|
||||
|
||||
bool showWebInspector(bool show);
|
||||
std::string getGREVersion();
|
||||
void setBrowserAgentId(std::string id);
|
||||
void setHostLanguage( const std::string& host_language );
|
||||
LLEmbeddedBrowserWindow* createBrowserWindow(int width, int height, const std::string target);
|
||||
bool destroyBrowserWindow(LLEmbeddedBrowserWindow* browser_window);
|
||||
void setLastError(int error_number);
|
||||
void clearLastError();
|
||||
int getLastError();
|
||||
int getWindowCount() const;
|
||||
void pump(int max_milliseconds);
|
||||
void cookieChanged(const std::string &cookie, const std::string &url, bool dead);
|
||||
bool setCAFile(const std::string &ca_file);
|
||||
bool addCAFile(const std::string &ca_file);
|
||||
void setIgnoreSSLCertErrors(bool ignore);
|
||||
bool getIgnoreSSLCertErrors();
|
||||
const std::vector< std::string > getInstalledCertsList();
|
||||
|
||||
void enableQtMessageHandler( bool enable );
|
||||
|
||||
void setPageZoomFactor( double factor );
|
||||
|
||||
// Second Life specific functions
|
||||
void setSLObjectEnabled( bool enabled );
|
||||
void setAgentLanguage( const std::string& agent_language );
|
||||
void setAgentRegion( const std::string& agent_region );
|
||||
void setAgentLocation( double x, double y, double z );
|
||||
void setAgentGlobalLocation( double x, double y, double z );
|
||||
void setAgentOrientation( double angle );
|
||||
void setAgentMaturity( const std::string& agent_maturity );
|
||||
void emitLocation();
|
||||
void emitMaturity();
|
||||
void emitLanguage();
|
||||
|
||||
private:
|
||||
friend class LLEmbeddedBrowserWindow;
|
||||
friend class LLEmbeddedBrowserWindowPrivate;
|
||||
LLEmbeddedBrowserPrivate *d;
|
||||
bool mPluginsEnabled;
|
||||
bool mJavaScriptEnabled;
|
||||
bool mCookiesEnabled;
|
||||
|
||||
static void qtMessageHandler(QtMsgType type, const char *msg);
|
||||
|
||||
static LLEmbeddedBrowser* sInstance;
|
||||
};
|
||||
|
||||
#endif // LLEMBEDDEDBROWSER_H
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLEMBEDDEDBROWSER_P_H
|
||||
#define LLEMBEDDEDBROWSER_P_H
|
||||
|
||||
#include <qnetworkaccessmanager.h>
|
||||
#include <qapplication.h>
|
||||
#if QT_VERSION >= 0x040500
|
||||
#include <qnetworkdiskcache.h>
|
||||
#endif
|
||||
|
||||
#include "networkcookiejar.h"
|
||||
#include "llembeddedbrowser.h"
|
||||
|
||||
#include <qgraphicswebview.h>
|
||||
|
||||
class LLEmbeddedBrowser;
|
||||
class LLNetworkCookieJar : public NetworkCookieJar
|
||||
{
|
||||
public:
|
||||
LLNetworkCookieJar(QObject *parent, LLEmbeddedBrowser *browser);
|
||||
~LLNetworkCookieJar();
|
||||
|
||||
QList<QNetworkCookie> cookiesForUrl(const QUrl& url) const;
|
||||
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookie_list, const QUrl& url);
|
||||
|
||||
/*virtual*/ void onCookieSetFromURL(const QNetworkCookie &cookie, const QUrl &url, bool already_dead);
|
||||
|
||||
void clear();
|
||||
|
||||
void setCookiesFromRawForm(const std::string &cookie_string);
|
||||
std::string getAllCookiesInRawForm();
|
||||
|
||||
bool mAllowCookies;
|
||||
LLEmbeddedBrowser *mBrowser;
|
||||
};
|
||||
|
||||
class LLNetworkAccessManager;
|
||||
class LLEmbeddedBrowserPrivate
|
||||
{
|
||||
public:
|
||||
LLEmbeddedBrowserPrivate();
|
||||
~LLEmbeddedBrowserPrivate();
|
||||
|
||||
bool authRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password);
|
||||
bool certError(const std::string &in_url, const std::string &in_msg);
|
||||
|
||||
int mErrorNum;
|
||||
void* mNativeWindowHandle;
|
||||
LLNetworkAccessManager *mNetworkAccessManager;
|
||||
QApplication *mApplication;
|
||||
#if QT_VERSION >= 0x040500
|
||||
QNetworkDiskCache *mDiskCache;
|
||||
#endif
|
||||
LLNetworkCookieJar *mNetworkCookieJar;
|
||||
|
||||
QGraphicsWebView *findView(QNetworkReply *);
|
||||
|
||||
QString mStorageDirectory;
|
||||
QList<LLEmbeddedBrowserWindow*> windows;
|
||||
|
||||
std::string mHostLanguage;
|
||||
bool mIgnoreSSLCertErrors;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,185 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLEMBEDDEDBROWSERWINDOW_H
|
||||
#define LLEMBEDDEDBROWSERWINDOW_H
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#if defined _MSC_VER && _MSC_VER < 1600
|
||||
#include "pstdint.h"
|
||||
#else
|
||||
#include <stdint.h> // Use the C99 official header
|
||||
#endif
|
||||
|
||||
#include "llqtwebkit.h"
|
||||
|
||||
class LLEmbeddedBrowser;
|
||||
class LLWebPageOpenShim;
|
||||
class QWebPage;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// class for a "window" that holds a browser - there can be lots of these
|
||||
class LLEmbeddedBrowserWindowPrivate;
|
||||
class LLEmbeddedBrowserWindow
|
||||
{
|
||||
public:
|
||||
LLEmbeddedBrowserWindow();
|
||||
virtual ~LLEmbeddedBrowserWindow();
|
||||
|
||||
// housekeeping
|
||||
void setParent(LLEmbeddedBrowser* parent);
|
||||
bool setSize(int16_t width, int16_t height);
|
||||
void focusBrowser(bool focus_browser);
|
||||
void scrollByLines(int16_t lines);
|
||||
void setWindowId(int window_id);
|
||||
int getWindowId();
|
||||
void proxyWindowOpened(const std::string target, const std::string uuid);
|
||||
void proxyWindowClosed(const std::string uuid);
|
||||
|
||||
// random accessors
|
||||
int16_t getPercentComplete();
|
||||
std::string& getStatusMsg();
|
||||
std::string& getCurrentUri();
|
||||
|
||||
// memory buffer management
|
||||
unsigned char* grabWindow(int x, int y, int width, int height);
|
||||
bool flipWindow(bool flip);
|
||||
unsigned char* getPageBuffer();
|
||||
int16_t getBrowserWidth();
|
||||
int16_t getBrowserHeight();
|
||||
int16_t getBrowserDepth();
|
||||
int32_t getBrowserRowSpan();
|
||||
|
||||
// set background color that you see in between pages - default is white but sometimes useful to change
|
||||
void setBackgroundColor(const uint8_t red, const uint8_t green, const uint8_t blue);
|
||||
|
||||
// can turn off updates to a page - e.g. when it's hidden by your windowing system
|
||||
void setEnabled(bool enabledIn);
|
||||
|
||||
// navigation
|
||||
bool userAction(LLQtWebKit::EUserAction action);
|
||||
bool userActionIsEnabled(LLQtWebKit::EUserAction action);
|
||||
bool navigateTo(const std::string uri);
|
||||
|
||||
// javascript access/control
|
||||
std::string evaluateJavaScript(std::string script);
|
||||
|
||||
// redirection when you hit an error page
|
||||
void navigateErrorPage( int http_status_code );
|
||||
|
||||
// host language setting
|
||||
void setHostLanguage(const std::string host_language);
|
||||
|
||||
// mouse & keyboard events
|
||||
void mouseEvent(LLQtWebKit::EMouseEvent mouse_event, int16_t button, int16_t x, int16_t y, LLQtWebKit::EKeyboardModifier modifiers);
|
||||
void scrollWheelEvent(int16_t x, int16_t y, int16_t scroll_x, int16_t scroll_y, LLQtWebKit::EKeyboardModifier modifiers);
|
||||
void keyboardEvent(
|
||||
LLQtWebKit::EKeyEvent key_event,
|
||||
uint32_t key_code,
|
||||
const char *utf8_text,
|
||||
LLQtWebKit::EKeyboardModifier modifiers,
|
||||
uint32_t native_scan_code,
|
||||
uint32_t native_virtual_key,
|
||||
uint32_t native_modifiers);
|
||||
|
||||
// allow consumers of this class and to observe browser events
|
||||
bool addObserver(LLEmbeddedBrowserWindowObserver* observer);
|
||||
bool remObserver(LLEmbeddedBrowserWindowObserver* observer);
|
||||
int getObserverNumber();
|
||||
|
||||
// accessor/mutator for scheme that browser doesn't follow - e.g. secondlife.com://
|
||||
void setNoFollowScheme(std::string scheme);
|
||||
std::string getNoFollowScheme();
|
||||
|
||||
// prepend the current history with the given url
|
||||
void prependHistoryUrl(std::string url);
|
||||
// clear the URL history
|
||||
void clearHistory();
|
||||
std::string dumpHistory();
|
||||
|
||||
void cookieChanged(const std::string &cookie, const std::string &url, bool dead);
|
||||
|
||||
QWebPage *createWindow();
|
||||
|
||||
LLWebPageOpenShim *findShim(const std::string &uuid);
|
||||
void deleteShim(LLWebPageOpenShim *shim);
|
||||
void setTarget(const std::string &target);
|
||||
|
||||
std::string requestFilePicker();
|
||||
|
||||
void showWebInspector(bool enabled);
|
||||
|
||||
bool authRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password);
|
||||
bool certError(const std::string &in_url, const std::string &in_msg);
|
||||
|
||||
void onQtDebugMessage( const std::string& msg, const std::string& msg_type);
|
||||
|
||||
void enableLoadingOverlay(bool enable);
|
||||
|
||||
void setWhiteListRegex( const std::string& regex );
|
||||
|
||||
void setPageZoomFactor( double factor );
|
||||
|
||||
// Second Life specific functions
|
||||
void setSLObjectEnabled( bool enabled );
|
||||
void setAgentLanguage( const std::string& agent_language );
|
||||
void setAgentRegion( const std::string& agent_region );
|
||||
void setAgentLocation( double x, double y, double z );
|
||||
void setAgentGlobalLocation( double x, double y, double z );
|
||||
void setAgentOrientation( double angle );
|
||||
void setAgentMaturity( const std::string& agent_maturity );
|
||||
void emitLocation();
|
||||
void emitMaturity();
|
||||
void emitLanguage();
|
||||
|
||||
private:
|
||||
friend class LLWebPage;
|
||||
friend class LLWebPageOpenShim;
|
||||
friend class LLGraphicsScene;
|
||||
friend class LLWebView;
|
||||
friend class LLEmbeddedBrowserPrivate;
|
||||
LLEmbeddedBrowserWindowPrivate *d;
|
||||
bool mEnableLoadingOverlay;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// QString::toStdString converts to ascii, not utf8. Define our own versions that do utf8.
|
||||
|
||||
#ifdef QSTRING_H
|
||||
std::string llToStdString(const QString &s);
|
||||
#endif
|
||||
|
||||
#ifdef QBYTEARRAY_H
|
||||
std::string llToStdString(const QByteArray &bytes);
|
||||
#endif
|
||||
|
||||
#ifdef QURL_H
|
||||
std::string llToStdString(const QUrl &url);
|
||||
#endif
|
||||
|
||||
#endif // LLEMBEDEDDBROWSERWINDOW_H
|
||||
@@ -1,251 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLEMBEDDEDBROWSERWINDOW_P_H
|
||||
#define LLEMBEDDEDBROWSERWINDOW_P_H
|
||||
|
||||
#include "llwebpage.h"
|
||||
#include "llwebpageopenshim.h"
|
||||
|
||||
#include <qgraphicsscene.h>
|
||||
#include <qgraphicsview.h>
|
||||
#include <qwebview.h>
|
||||
#include <QWebInspector>
|
||||
#include <list>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// manages the process of storing and emitting events that the consumer
|
||||
// of the embedding class can observe
|
||||
template< class T >
|
||||
class LLEmbeddedBrowserWindowEmitter
|
||||
{
|
||||
public:
|
||||
LLEmbeddedBrowserWindowEmitter() { };
|
||||
~LLEmbeddedBrowserWindowEmitter() { };
|
||||
|
||||
typedef typename T::EventType EventType;
|
||||
typedef std::list< T* > ObserverContainer;
|
||||
typedef typename ObserverContainer::iterator iterator;
|
||||
typedef void(T::*observerMethod)(const EventType&);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool addObserver(T* observer)
|
||||
{
|
||||
if (! observer)
|
||||
return false;
|
||||
|
||||
if (std::find(observers.begin(), observers.end(), observer) != observers.end())
|
||||
return false;
|
||||
|
||||
observers.push_back(observer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool remObserver(T* observer)
|
||||
{
|
||||
if (! observer)
|
||||
return false;
|
||||
|
||||
observers.remove(observer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void update(observerMethod method, const EventType& msg)
|
||||
{
|
||||
typename std::list< T* >::iterator iter = observers.begin();
|
||||
|
||||
while(iter != observers.end())
|
||||
{
|
||||
((*iter)->*method)(msg);
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
int getObserverNumber()
|
||||
{
|
||||
return observers.size();
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return observers.begin();
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return observers.end();
|
||||
}
|
||||
|
||||
protected:
|
||||
ObserverContainer observers;
|
||||
};
|
||||
|
||||
#include "llqtwebkit.h"
|
||||
#include "llembeddedbrowserwindow.h"
|
||||
#include <qgraphicssceneevent.h>
|
||||
#include <qgraphicswebview.h>
|
||||
|
||||
class LLGraphicsScene : public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LLGraphicsScene();
|
||||
LLEmbeddedBrowserWindow *window;
|
||||
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) {
|
||||
QGraphicsScene::mouseMoveEvent(mouseEvent);
|
||||
mouseEvent->setAccepted(true);
|
||||
mouseEvent->setButtons(Qt::LeftButton);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void repaintRequestedSlot(const QList<QRectF> &);
|
||||
friend class LLEmbeddedBrowserWindow;
|
||||
};
|
||||
|
||||
|
||||
class LLWebView : public QGraphicsWebView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LLWebView(QGraphicsItem *parent = 0);
|
||||
LLEmbeddedBrowserWindow *window;
|
||||
|
||||
static QUrl guessUrlFromString(const QString &string);
|
||||
|
||||
int width() const { return boundingRect().width(); }
|
||||
int height() const { return boundingRect().height(); }
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event);
|
||||
|
||||
Qt::CursorShape currentShape;
|
||||
};
|
||||
|
||||
class LLEmbeddedBrowserWindowPrivate
|
||||
{
|
||||
public:
|
||||
LLEmbeddedBrowserWindowPrivate()
|
||||
: mParent(0)
|
||||
, mPage(0)
|
||||
, mView(0)
|
||||
, mGraphicsScene(0)
|
||||
, mGraphicsView(0)
|
||||
, mInspector(0)
|
||||
, mCurrentMouseButtonState(Qt::NoButton)
|
||||
, mPercentComplete(0)
|
||||
, mShowLoadingOverlay(false)
|
||||
, mTimeLoadStarted(0)
|
||||
, mStatusText("")
|
||||
, mTitle("")
|
||||
, mCurrentUri("")
|
||||
, mNoFollowScheme("secondlife")
|
||||
, mWindowId(-1)
|
||||
, mEnabled(true)
|
||||
, mFlipBitmap(false)
|
||||
, mPageBuffer(NULL)
|
||||
, mDirty(false)
|
||||
, mOpeningSelf(false)
|
||||
{
|
||||
}
|
||||
|
||||
~LLEmbeddedBrowserWindowPrivate()
|
||||
{
|
||||
while(!mProxyPages.empty())
|
||||
{
|
||||
ProxyList::iterator iter = mProxyPages.begin();
|
||||
(*iter)->window = 0;
|
||||
(*iter)->deleteLater();
|
||||
}
|
||||
|
||||
if(mGraphicsScene)
|
||||
{
|
||||
mGraphicsScene->window = 0;
|
||||
}
|
||||
if(mPage)
|
||||
{
|
||||
mPage->window = 0;
|
||||
}
|
||||
if(mView)
|
||||
{
|
||||
mView->deleteLater();
|
||||
}
|
||||
if(mGraphicsScene)
|
||||
{
|
||||
mGraphicsScene->deleteLater();
|
||||
}
|
||||
if(mGraphicsView)
|
||||
{
|
||||
mGraphicsView->viewport()->setParent(mGraphicsView);
|
||||
mGraphicsView->deleteLater();
|
||||
}
|
||||
if(mInspector)
|
||||
{
|
||||
mInspector->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
typedef LLEmbeddedBrowserWindowEmitter< LLEmbeddedBrowserWindowObserver> Emitter;
|
||||
Emitter mEventEmitter;
|
||||
QImage mImage;
|
||||
LLEmbeddedBrowser *mParent;
|
||||
LLWebPage *mPage;
|
||||
typedef std::list<LLWebPageOpenShim*> ProxyList;
|
||||
ProxyList mProxyPages;
|
||||
|
||||
LLWebView *mView;
|
||||
QWebInspector* mInspector;
|
||||
LLGraphicsScene *mGraphicsScene;
|
||||
QGraphicsView *mGraphicsView;
|
||||
Qt::MouseButtons mCurrentMouseButtonState;
|
||||
|
||||
int16_t mPercentComplete;
|
||||
bool mShowLoadingOverlay;
|
||||
time_t mTimeLoadStarted;
|
||||
std::string mStatusText;
|
||||
std::string mTitle;
|
||||
std::string mCurrentUri;
|
||||
QString mNoFollowScheme;
|
||||
int mWindowId;
|
||||
bool mEnabled;
|
||||
bool mFlipBitmap;
|
||||
unsigned char* mPageBuffer;
|
||||
QColor backgroundColor;
|
||||
bool mDirty;
|
||||
bool mOpeningSelf;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
#include "lljsobject.h"
|
||||
|
||||
LLJsObject::LLJsObject( QObject* parent ) :
|
||||
QObject( parent )
|
||||
{
|
||||
mEnabled = false;
|
||||
|
||||
mAgentLanguage = QString();
|
||||
mAgentMaturity = QString();
|
||||
mAgentRegion = QString();
|
||||
|
||||
mAgentLocation[ "x" ] = 0.0;
|
||||
mAgentLocation[ "y" ] = 0.0;
|
||||
mAgentLocation[ "z" ] = 0.0;
|
||||
|
||||
mAgentGlobalLocation[ "x" ] = 0.0;
|
||||
mAgentGlobalLocation[ "y" ] = 0.0;
|
||||
mAgentGlobalLocation[ "z" ] = 0.0;
|
||||
}
|
||||
|
||||
void LLJsObject::setSLObjectEnabled( bool enabled )
|
||||
{
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
bool LLJsObject::getSLObjectEnabled()
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
void LLJsObject::setAgentLanguage( const QString& agent_language )
|
||||
{
|
||||
if ( mEnabled )
|
||||
{
|
||||
mAgentLanguage = agent_language;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAgentLanguage = QString();
|
||||
}
|
||||
}
|
||||
|
||||
void LLJsObject::setAgentRegion( const QString& agent_region )
|
||||
{
|
||||
if ( mEnabled )
|
||||
{
|
||||
mAgentRegion = agent_region;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAgentRegion = QString();
|
||||
}
|
||||
}
|
||||
|
||||
void LLJsObject::setAgentMaturity( const QString& agent_maturity )
|
||||
{
|
||||
if ( mEnabled )
|
||||
{
|
||||
mAgentMaturity = agent_maturity;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAgentMaturity = QString();
|
||||
}
|
||||
}
|
||||
|
||||
void LLJsObject::setAgentLocation( const QVariantMap agent_location )
|
||||
{
|
||||
if ( mEnabled )
|
||||
{
|
||||
mAgentLocation = agent_location;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAgentLocation[ "x" ] = 0.0;
|
||||
mAgentLocation[ "y" ] = 0.0;
|
||||
mAgentLocation[ "z" ] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLJsObject::setAgentGlobalLocation( const QVariantMap agent_global_location )
|
||||
{
|
||||
if ( mEnabled )
|
||||
{
|
||||
mAgentGlobalLocation = agent_global_location;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAgentGlobalLocation[ "x" ] = 0.0;
|
||||
mAgentGlobalLocation[ "y" ] = 0.0;
|
||||
mAgentGlobalLocation[ "z" ] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLJsObject::setAgentOrientation( const double angle )
|
||||
{
|
||||
if ( mEnabled )
|
||||
{
|
||||
mAgentOrientation = angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAgentOrientation = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLJsObject::emitLocation()
|
||||
{
|
||||
QVariantMap agent_location;
|
||||
|
||||
agent_location[ "region" ] = mAgentRegion;
|
||||
agent_location[ "location" ] = mAgentLocation;
|
||||
agent_location[ "orientation" ] = mAgentOrientation;
|
||||
agent_location[ "globalLocation" ] = mAgentGlobalLocation;
|
||||
|
||||
emit getLocation( agent_location );
|
||||
}
|
||||
|
||||
void LLJsObject::emitMaturity()
|
||||
{
|
||||
emit getMaturity( mAgentMaturity );
|
||||
}
|
||||
|
||||
void LLJsObject::emitLanguage()
|
||||
{
|
||||
emit getLanguage( mAgentLanguage );
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLJSOBJECT_H
|
||||
#define LLJSOBJECT_H
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
class LLJsObject :
|
||||
public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LLJsObject( QObject* parent = 0 );
|
||||
|
||||
void setSLObjectEnabled( bool enabled );
|
||||
bool getSLObjectEnabled();
|
||||
|
||||
void setAgentLanguage( const QString& agent_language );
|
||||
void setAgentRegion( const QString& agent_region );
|
||||
void setAgentMaturity( const QString& agent_maturity );
|
||||
void setAgentLocation( const QVariantMap agent_location );
|
||||
void setAgentGlobalLocation( const QVariantMap agent_global_location );
|
||||
void setAgentOrientation( const double angle );
|
||||
|
||||
void emitLocation();
|
||||
void emitMaturity();
|
||||
void emitLanguage();
|
||||
|
||||
signals:
|
||||
void getLocation( const QVariantMap agent_location );
|
||||
void getMaturity( const QString agent_maturity );
|
||||
void getLanguage( const QString agent_language );
|
||||
|
||||
private:
|
||||
bool mEnabled;
|
||||
|
||||
QString mAgentLanguage;
|
||||
QString mAgentMaturity;
|
||||
QString mAgentRegion;
|
||||
QVariantMap mAgentLocation;
|
||||
QVariantMap mAgentGlobalLocation;
|
||||
double mAgentOrientation;
|
||||
};
|
||||
|
||||
#endif // LLJSOBJECT_H
|
||||
@@ -1,247 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include "llnetworkaccessmanager.h"
|
||||
|
||||
#include <qauthenticator.h>
|
||||
#include <qnetworkreply.h>
|
||||
#include <qtextdocument.h>
|
||||
#include <qgraphicsview.h>
|
||||
#include <qgraphicsscene.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qgraphicsproxywidget.h>
|
||||
#include <qdebug.h>
|
||||
#include <qsslconfiguration.h>
|
||||
|
||||
#include "llembeddedbrowserwindow.h"
|
||||
#include "llembeddedbrowser_p.h"
|
||||
|
||||
#include "ui_passworddialog.h"
|
||||
|
||||
|
||||
LLNetworkAccessManager::LLNetworkAccessManager(LLEmbeddedBrowserPrivate* browser,QObject* parent)
|
||||
: QNetworkAccessManager(parent)
|
||||
, mBrowser(browser)
|
||||
{
|
||||
connect(this, SIGNAL(finished(QNetworkReply*)),
|
||||
this, SLOT(finishLoading(QNetworkReply*)));
|
||||
connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)),
|
||||
this, SLOT(authenticationRequiredSlot(QNetworkReply*, QAuthenticator*)));
|
||||
connect(this, SIGNAL(sslErrors( QNetworkReply *, const QList<QSslError> &)),
|
||||
this, SLOT(sslErrorsSlot( QNetworkReply *, const QList<QSslError> & )));
|
||||
}
|
||||
|
||||
QNetworkReply *LLNetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request,
|
||||
QIODevice *outgoingData)
|
||||
{
|
||||
|
||||
// Create a local copy of the request we can modify.
|
||||
QNetworkRequest mutable_request(request);
|
||||
|
||||
// Set an Accept-Language header in the request, based on what the host has set through setHostLanguage.
|
||||
mutable_request.setRawHeader(QByteArray("Accept-Language"), QByteArray(mBrowser->mHostLanguage.c_str()));
|
||||
|
||||
// this is undefine'd in 4.7.1 and leads to caching issues - setting it here explicitly
|
||||
mutable_request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork);
|
||||
|
||||
if(op == GetOperation)
|
||||
{
|
||||
// GET requests should not have a Content-Type header, but it seems somebody somewhere is adding one.
|
||||
// This removes it.
|
||||
mutable_request.setRawHeader("Content-Type", QByteArray());
|
||||
}
|
||||
|
||||
// qDebug() << "headers for request:" << mutable_request.rawHeaderList();
|
||||
|
||||
// and pass this through to the parent implementation
|
||||
return QNetworkAccessManager::createRequest(op, mutable_request, outgoingData);
|
||||
}
|
||||
|
||||
void LLNetworkAccessManager::sslErrorsSlot(QNetworkReply* reply, const QList<QSslError>& errors)
|
||||
{
|
||||
// Enabling this can help diagnose certificate verification issues.
|
||||
const bool ssl_debugging_on = false;
|
||||
|
||||
// flag that indicates if the error that brought us here is one we care about or not
|
||||
bool valid_ssl_error = false;
|
||||
|
||||
foreach( const QSslError &error, errors )
|
||||
{
|
||||
if ( ssl_debugging_on )
|
||||
{
|
||||
qDebug() << "SSL error details are (" << (int)(error.error()) << ") - " << error.error();
|
||||
}
|
||||
|
||||
// SSL "error" codes we don't care about - if we get one of these, we want to continue
|
||||
if ( error.error() != QSslError::NoError
|
||||
// many more in src/network/ssl/qsslerror.h
|
||||
)
|
||||
{
|
||||
if ( ssl_debugging_on )
|
||||
{
|
||||
qDebug() << "Found valid SSL error - will not ignore";
|
||||
}
|
||||
|
||||
valid_ssl_error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ssl_debugging_on )
|
||||
{
|
||||
qDebug() << "Found invalid SSL error - will ignore and continue";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ssl_debugging_on )
|
||||
{
|
||||
qDebug() << "LLNetworkAccessManager" << __FUNCTION__ << "errors: " << errors
|
||||
<< ", peer certificate chain: ";
|
||||
|
||||
QSslCertificate cert;
|
||||
foreach(cert, reply->sslConfiguration().peerCertificateChain())
|
||||
{
|
||||
qDebug() << " cert: " << cert
|
||||
<< ", issuer = " << cert.issuerInfo(QSslCertificate::CommonName)
|
||||
<< ", subject = " << cert.subjectInfo(QSslCertificate::CommonName);
|
||||
}
|
||||
}
|
||||
|
||||
if ( valid_ssl_error )
|
||||
{
|
||||
std::string url = llToStdString(reply->url());
|
||||
QString err_msg="";
|
||||
foreach( const QSslError &error, errors )
|
||||
{
|
||||
err_msg+=error.errorString();
|
||||
err_msg+="\n";
|
||||
|
||||
QSslCertificate cert = error.certificate();
|
||||
|
||||
QString issuer_info="";
|
||||
issuer_info+="C=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::CountryName);
|
||||
issuer_info+=", ST=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::StateOrProvinceName);
|
||||
issuer_info+=", L=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::LocalityName);
|
||||
issuer_info+=", O=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::Organization);
|
||||
issuer_info+=", OU=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::OrganizationalUnitName);
|
||||
issuer_info+=", CN=";
|
||||
issuer_info+=cert.issuerInfo(QSslCertificate::CommonName);
|
||||
err_msg+=issuer_info;
|
||||
err_msg+="\n";
|
||||
|
||||
QString subject_info="";
|
||||
subject_info+="C=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::CountryName);
|
||||
subject_info+=", ST=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::StateOrProvinceName);
|
||||
subject_info+=", L=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::LocalityName);
|
||||
subject_info+=", O=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::Organization);
|
||||
subject_info+=", OU=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
|
||||
subject_info+=", CN=";
|
||||
subject_info+=cert.subjectInfo(QSslCertificate::CommonName);
|
||||
err_msg+=subject_info;
|
||||
err_msg+="\n";
|
||||
|
||||
err_msg+="Not valid before: ";
|
||||
err_msg+=cert.effectiveDate().toString();
|
||||
err_msg+="\n";
|
||||
err_msg+="Not valid after: ";
|
||||
err_msg+=cert.expiryDate().toString();
|
||||
err_msg+="\n";
|
||||
err_msg+="----------\n";
|
||||
}
|
||||
|
||||
if(mBrowser->certError(url, llToStdString(err_msg)))
|
||||
{
|
||||
// signal we should ignore and continue processing
|
||||
reply->ignoreSslErrors();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The user canceled, don't return yet so we can test ignore variable
|
||||
}
|
||||
}
|
||||
|
||||
// we the SSL error is invalid (in our opinion) or we explicitly ignore all SSL errors
|
||||
if ( valid_ssl_error == false || ( mBrowser && mBrowser->mIgnoreSSLCertErrors ) )
|
||||
{
|
||||
// signal we should ignore and continue processing
|
||||
reply->ignoreSslErrors();
|
||||
};
|
||||
}
|
||||
|
||||
void LLNetworkAccessManager::finishLoading(QNetworkReply* reply)
|
||||
{
|
||||
QVariant val = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute );
|
||||
int http_status_code = val.toInt();
|
||||
if ( http_status_code >=400 && http_status_code <=499 )
|
||||
{
|
||||
if (mBrowser)
|
||||
{
|
||||
std::string current_url = llToStdString(reply->url());
|
||||
foreach (LLEmbeddedBrowserWindow *window, mBrowser->windows)
|
||||
{
|
||||
if (window->getCurrentUri() == current_url)
|
||||
{
|
||||
window->navigateErrorPage( http_status_code );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tests if navigation request resulted in a cache hit - useful for testing so leaving here for the moment.
|
||||
//QVariant from_cache = reply->attribute( QNetworkRequest::SourceIsFromCacheAttribute );
|
||||
//QString url = QString(reply->url().toEncoded());
|
||||
//qDebug() << url << " --- from cache?" << fromCache.toBool() << "\n";
|
||||
}
|
||||
|
||||
void LLNetworkAccessManager:: authenticationRequiredSlot(QNetworkReply *reply, QAuthenticator *authenticator)
|
||||
{
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string url = llToStdString(reply->url());
|
||||
std::string realm = llToStdString(authenticator->realm());
|
||||
|
||||
if(mBrowser->authRequest(url, realm, username, password))
|
||||
{
|
||||
// Got credentials to try, attempt auth with them.
|
||||
authenticator->setUser(QString::fromStdString(username));
|
||||
authenticator->setPassword(QString::fromStdString(password));
|
||||
}
|
||||
else
|
||||
{
|
||||
// The user cancelled, don't attempt auth.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLNETWORKACCESSMANAGER_H
|
||||
#define LLNETWORKACCESSMANAGER_H
|
||||
|
||||
#include <qnetworkaccessmanager.h>
|
||||
#include <qsslerror.h>
|
||||
|
||||
#include "ui_passworddialog.h"
|
||||
|
||||
class QGraphicsProxyWidget;
|
||||
|
||||
class LLEmbeddedBrowserPrivate;
|
||||
class LLNetworkAccessManager: public QNetworkAccessManager
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LLNetworkAccessManager(LLEmbeddedBrowserPrivate* browser, QObject* parent = 0);
|
||||
|
||||
protected:
|
||||
virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request,
|
||||
QIODevice *outgoingData = 0);
|
||||
private slots:
|
||||
void finishLoading(QNetworkReply* reply);
|
||||
void authenticationRequiredSlot(QNetworkReply *reply, QAuthenticator *authenticator);
|
||||
void sslErrorsSlot(QNetworkReply* reply, const QList<QSslError>& errors);
|
||||
|
||||
private:
|
||||
LLEmbeddedBrowserPrivate* mBrowser;
|
||||
|
||||
};
|
||||
|
||||
#endif // LLNETWORKACCESSMANAGER_H
|
||||
|
||||
@@ -1,820 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <time.h>
|
||||
|
||||
#include "llqtwebkit.h"
|
||||
|
||||
#include "llembeddedbrowser.h"
|
||||
#include "llembeddedbrowserwindow.h"
|
||||
|
||||
LLQtWebKit* LLQtWebKit::sInstance = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
LLQtWebKit::LLQtWebKit() :
|
||||
mMaxBrowserWindows(16)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
LLQtWebKit* LLQtWebKit::getInstance()
|
||||
{
|
||||
if (! sInstance)
|
||||
{
|
||||
sInstance = new LLQtWebKit;
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
LLQtWebKit::~LLQtWebKit()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::init(std::string application_directory,
|
||||
std::string component_directory,
|
||||
std::string profile_directory,
|
||||
void* native_window_handle)
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->init(application_directory,
|
||||
component_directory,
|
||||
profile_directory,
|
||||
native_window_handle);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int LLQtWebKit::getLastError()
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->getLastError();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::reset()
|
||||
{
|
||||
mBrowserWindowMap.clear();
|
||||
return LLEmbeddedBrowser::getInstance()->reset();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::clearCache()
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->clearCache();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
std::string LLQtWebKit::getVersion()
|
||||
{
|
||||
const int majorVersion = 2;
|
||||
const int minorVersion = 2;
|
||||
|
||||
// number of hours since "time began" for this library - used to identify builds of same version
|
||||
const int magicNumber = static_cast< int >((time(NULL) / 3600L) - (321190L));
|
||||
|
||||
// return as a string for now - don't think we need to expose actual version numbers
|
||||
std::ostringstream codec;
|
||||
codec << std::setw(1) << std::setfill('0');
|
||||
codec << majorVersion << ".";
|
||||
codec << std::setw(2) << std::setfill('0');
|
||||
codec << minorVersion << ".";
|
||||
codec << std::setw(5) << std::setfill('0');
|
||||
codec << magicNumber;
|
||||
codec << " (QtWebKit version ";
|
||||
codec << LLEmbeddedBrowser::getInstance()->getGREVersion();
|
||||
codec << ")";
|
||||
|
||||
return codec.str();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::setBrowserAgentId(std::string id)
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setBrowserAgentId(id);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::enableProxy(bool enabled, std::string host_name, int port)
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->enableProxy(enabled, host_name, port);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::setHostLanguage(const std::string& host_language )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setHostLanguage(host_language);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int LLQtWebKit::createBrowserWindow(int width, int height, const std::string target)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = LLEmbeddedBrowser::getInstance()->createBrowserWindow(width, height, target);
|
||||
|
||||
if (browser_window)
|
||||
{
|
||||
// arbitrary limit so we don't exhaust system resources
|
||||
int id(0);
|
||||
while (++id < mMaxBrowserWindows)
|
||||
{
|
||||
std::pair< BrowserWindowMapIter, bool > result = mBrowserWindowMap.insert(std::make_pair(id, browser_window));
|
||||
|
||||
// find first place the insert succeeds and use that index as the id
|
||||
if (result.second)
|
||||
{
|
||||
browser_window->setWindowId(id);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::proxyWindowOpened(int browser_window_id, const std::string target, const std::string uuid)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->proxyWindowOpened(target, uuid);
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::proxyWindowClosed(int browser_window_id, const std::string uuid)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->proxyWindowClosed(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::destroyBrowserWindow(int browser_window_id)
|
||||
{
|
||||
// don't use the utility method here since we need the iteratorator to remove the entry from the map
|
||||
BrowserWindowMapIter iterator = mBrowserWindowMap.find(browser_window_id);
|
||||
LLEmbeddedBrowserWindow* browser_window = (*iterator).second;
|
||||
|
||||
if (browser_window)
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->destroyBrowserWindow(browser_window);
|
||||
}
|
||||
|
||||
mBrowserWindowMap.erase(iterator);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::setBackgroundColor(int browser_window_id, const int red, const int green, const int blue)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->setBackgroundColor(red, green, blue);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::setEnabled(int browser_window_id, bool enabled)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->setEnabled(enabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::setSize(int browser_window_id, int width, int height)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->setSize(width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::scrollByLines(int browser_window_id, int lines)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->scrollByLines(lines);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::addObserver(int browser_window_id, LLEmbeddedBrowserWindowObserver* subject)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->addObserver(subject);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::remObserver(int browser_window_id, LLEmbeddedBrowserWindowObserver* subject)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->remObserver(subject);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::navigateTo(int browser_window_id, const std::string uri)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->navigateTo(uri) ? true : false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::userAction(int browser_window_id, EUserAction action)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->userAction(action);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::userActionIsEnabled(int browser_window_id, EUserAction action)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->userActionIsEnabled(action);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
const unsigned char* LLQtWebKit::grabBrowserWindow(int browser_window_id)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->grabWindow(0, 0, browser_window->getBrowserWidth(), browser_window->getBrowserHeight());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
const unsigned char* LLQtWebKit::getBrowserWindowPixels(int browser_window_id)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->getPageBuffer();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::flipWindow(int browser_window_id, bool flip)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->flipWindow(flip);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int LLQtWebKit::getBrowserWidth(int browser_window_id)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->getBrowserWidth();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int LLQtWebKit::getBrowserHeight(int browser_window_id)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->getBrowserHeight();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int LLQtWebKit::getBrowserDepth(int browser_window_id)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->getBrowserDepth();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int LLQtWebKit::getBrowserRowSpan(int browser_window_id)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->getBrowserRowSpan();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::mouseEvent(int browser_window_id, EMouseEvent mouse_event, int button, int x, int y, EKeyboardModifier modifiers)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->mouseEvent(mouse_event, button, x, y, modifiers);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::scrollWheelEvent(int browser_window_id, int x, int y, int scroll_x, int scroll_y, EKeyboardModifier modifiers)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->scrollWheelEvent(x, y, scroll_x, scroll_y, modifiers);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::keyboardEvent(
|
||||
int browser_window_id,
|
||||
EKeyEvent key_event,
|
||||
uint32_t key_code,
|
||||
const char *utf8_text,
|
||||
EKeyboardModifier modifiers,
|
||||
uint32_t native_scan_code,
|
||||
uint32_t native_virtual_key,
|
||||
uint32_t native_modifiers)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->keyboardEvent(key_event, key_code, utf8_text, modifiers, native_scan_code, native_virtual_key, native_modifiers);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::focusBrowser(int browser_window_id, bool focus_browser)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->focusBrowser(focus_browser);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::setNoFollowScheme(int browser_window_id, std::string scheme)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->setNoFollowScheme(scheme);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
std::string LLQtWebKit::getNoFollowScheme(int browser_window_id)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->getNoFollowScheme();
|
||||
}
|
||||
|
||||
return ("");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::pump(int max_milliseconds)
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->pump(max_milliseconds);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::enableCookies(bool enabled)
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->enableCookies( enabled );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::clearAllCookies()
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->clearAllCookies();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::setCookies(const std::string &cookies)
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->setCookies(cookies);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
std::string LLQtWebKit::getAllCookies()
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->getAllCookies();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::enablePlugins(bool enabled)
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->enablePlugins(enabled);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::enableJavaScript(bool enabled)
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->enableJavaScript(enabled);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::showWebInspector(bool show)
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->showWebInspector(show);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
std::string LLQtWebKit::evaluateJavaScript(int browser_window_id, const std::string script)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->evaluateJavaScript(script);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::prependHistoryUrl(int browser_window_id, std::string url)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->prependHistoryUrl(url);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::clearHistory(int browser_window_id)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->clearHistory();
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLQtWebKit::dumpHistory(int browser_window_id)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
return browser_window->dumpHistory();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::setCAFile(const std::string &ca_file)
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->setCAFile(ca_file);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::addCAFile(const std::string &ca_file)
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->addCAFile(ca_file);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLQtWebKit::setIgnoreSSLCertErrors(bool ignore)
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setIgnoreSSLCertErrors(ignore);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool LLQtWebKit::getIgnoreSSLCertErrors()
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()-> getIgnoreSSLCertErrors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
const std::vector< std::string > LLQtWebKit::getInstalledCertsList()
|
||||
{
|
||||
return LLEmbeddedBrowser::getInstance()->getInstalledCertsList();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// utility method to get an LLEmbeddedBrowserWindow* from a window id (int)
|
||||
LLEmbeddedBrowserWindow* LLQtWebKit::getBrowserWindowFromWindowId(int browser_window_id)
|
||||
{
|
||||
BrowserWindowMapIter iterator = mBrowserWindowMap.find(browser_window_id);
|
||||
|
||||
if (iterator != mBrowserWindowMap.end())
|
||||
return (*iterator).second;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
LLEmbeddedBrowserWindowObserver::~LLEmbeddedBrowserWindowObserver()
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onCursorChanged(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onPageChanged(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onNavigateBegin(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onNavigateComplete(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onUpdateProgress(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onStatusTextChange(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onTitleChange(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onLocationChange(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onNavigateErrorPage(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onClickLinkHref(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onClickLinkNoFollow(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onCookieChanged(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
std::string LLEmbeddedBrowserWindowObserver::onRequestFilePicker(const EventType&)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onWindowCloseRequested(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onWindowGeometryChangeRequested(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowserWindowObserver::onAuthRequest(const std::string &, const std::string &, std::string &, std::string &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLEmbeddedBrowserWindowObserver::onCertError(const std::string &, const std::string &)
|
||||
{
|
||||
return false; // cancel and abort after cert error
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onQtDebugMessage( const std::string &, const std::string &)
|
||||
{
|
||||
}
|
||||
|
||||
void LLEmbeddedBrowserWindowObserver::onLinkHovered(const EventType&)
|
||||
{
|
||||
}
|
||||
|
||||
// set the regex used to determine if a page is trusted or not
|
||||
void LLQtWebKit::setWhiteListRegex( int browser_window_id, const std::string& regex )
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->setWhiteListRegex(regex);
|
||||
}
|
||||
}
|
||||
|
||||
// Second Life viewer specific functions
|
||||
void LLQtWebKit::setSLObjectEnabled( bool enabled )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setSLObjectEnabled( enabled );
|
||||
}
|
||||
|
||||
void LLQtWebKit::setAgentLanguage( const std::string& agent_language )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setAgentLanguage( agent_language );
|
||||
}
|
||||
|
||||
void LLQtWebKit::setAgentRegion( const std::string& agent_region )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setAgentRegion( agent_region );
|
||||
}
|
||||
|
||||
void LLQtWebKit::setAgentLocation( double x, double y, double z )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setAgentLocation( x, y, z );
|
||||
}
|
||||
|
||||
void LLQtWebKit::setAgentGlobalLocation( double x, double y, double z )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setAgentGlobalLocation( x, y, z );
|
||||
}
|
||||
|
||||
void LLQtWebKit::setAgentOrientation( double angle )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setAgentOrientation( angle );
|
||||
}
|
||||
|
||||
|
||||
void LLQtWebKit::setAgentMaturity( const std::string& agent_maturity )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setAgentMaturity( agent_maturity );
|
||||
}
|
||||
|
||||
void LLQtWebKit::emitLocation()
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->emitLocation();
|
||||
}
|
||||
|
||||
void LLQtWebKit::emitMaturity()
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->emitMaturity();
|
||||
}
|
||||
|
||||
void LLQtWebKit::emitLanguage()
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->emitLanguage();
|
||||
}
|
||||
|
||||
void LLQtWebKit::enableQtMessageHandler( bool enable )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->enableQtMessageHandler( enable );
|
||||
}
|
||||
|
||||
void LLQtWebKit::enableLoadingOverlay( int browser_window_id, bool enable)
|
||||
{
|
||||
LLEmbeddedBrowserWindow* browser_window = getBrowserWindowFromWindowId(browser_window_id);
|
||||
if (browser_window)
|
||||
{
|
||||
browser_window->enableLoadingOverlay( enable );
|
||||
}
|
||||
}
|
||||
|
||||
void LLQtWebKit::setPageZoomFactor( double factor )
|
||||
{
|
||||
LLEmbeddedBrowser::getInstance()->setPageZoomFactor( factor );
|
||||
}
|
||||
@@ -1,470 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLQTWEBKIT_H
|
||||
#define LLQTWEBKIT_H
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER < 1600
|
||||
// no pstdint.h in the client where this header is used
|
||||
typedef unsigned long uint32_t;
|
||||
#else
|
||||
#include <stdint.h> // Use the C99 official header
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class LLEmbeddedBrowser;
|
||||
class LLEmbeddedBrowserWindow;
|
||||
|
||||
// Use this to conditionalize code that depends on particular changes to the llqtwebkit API.
|
||||
// This can be useful for times when we're waiting for a rebuild on one platform or another.
|
||||
// When you bump this number, please note what the changes were in a comment below the #define,
|
||||
// and keep the existing comments as history.
|
||||
#define LLQTWEBKIT_API_VERSION 16
|
||||
// version 16:
|
||||
// Added LLQtWebKit::enableLoadingOverlay()
|
||||
// version 15:
|
||||
// Added LLQtWebKit::setPageZoomFactor()
|
||||
// version 14:
|
||||
// Added LLEmbeddedBrowserWindowObserver::onQtDebugMessage
|
||||
// version 13:
|
||||
// Added LLEmbeddedBrowserWindowObserver::onCertError
|
||||
// version 12:
|
||||
// Pass over value to indicate if host for current URL is trusted as per whitelist regex or not
|
||||
// version 11:
|
||||
// Added initial support for url/host whitelist via a regex
|
||||
// version 10:
|
||||
// Added initial support for creating and displaying the Qt Web Inspector
|
||||
// version 9:
|
||||
// Added initial support for exposing certain Second Life viewer/agent variables to JavaScript
|
||||
// version 8:
|
||||
// Removed calls to set/clear 404 redirects and made the API now emit an event that the
|
||||
// consumer can catch and decide what to do when an HTTP status code after navigate is 400-499
|
||||
// version 7:
|
||||
// Added LLEmbeddedBrowserWindowEvent::setNavigationType() && LLEmbeddedBrowserWindowEvent::getNavigationType()
|
||||
// Used to pass (and retrieve) the type of navigation event that caused a link to be activated.
|
||||
// version 6:
|
||||
// Added LLQtWebKit::addCAFile()
|
||||
// version 5:
|
||||
// Added LLEmbeddedBrowserWindowObserver::onLinkHovered
|
||||
// version 4:
|
||||
// Added LLEmbeddedBrowserWindowObserver::onAuthRequest
|
||||
// version 3:
|
||||
// Added setIgnoreSSLCertErrors and getIgnoreSSLCertErrors
|
||||
// version 2:
|
||||
// Changed the usage of the event parameters in onClickLinkHref and onClickLinkNoFollow events slightly.
|
||||
// The clicked URI for both should now be retrieved with getEventUri() instead of getStringValue().
|
||||
// The "target" string in onClickLinkHref is now retrieved with getStringValue() instead of getStringValue2().
|
||||
// The contents of getStringValue2() in the onClickLinkHref event is now a unique ID for the window proxy the click targets.
|
||||
// Removed the "link target type" concept, since it doesn't really belong here.
|
||||
// Removed most of the construtor variants in LLEmbeddedBrowserWindowEvent and added setters in their place.
|
||||
// Removed setCaretColor, since it's done nothing for some time now.
|
||||
// Added LLEmbeddedBrowserWindowObserver::onWindowGeometryChangeRequested
|
||||
// Added
|
||||
// version 1:
|
||||
// Added the LLQTWEBKIT_API_VERSION define.
|
||||
// Added LLEmbeddedBrowserWindowObserver::onWindowCloseRequested
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// data class that is passed with an event
|
||||
class LLEmbeddedBrowserWindowEvent
|
||||
{
|
||||
public:
|
||||
LLEmbeddedBrowserWindowEvent(int window_id) :
|
||||
mEventWindowId(window_id)
|
||||
{
|
||||
};
|
||||
|
||||
virtual ~LLEmbeddedBrowserWindowEvent() {}
|
||||
|
||||
void setEventUri(const std::string &uri) { mEventUri = uri; }
|
||||
void setNavigationType(const std::string &type) { mNavigationType = type; }
|
||||
void setTrustedHost(const bool trusted) { mTrustedHost = trusted; }
|
||||
void setIntValue(int val) { mIntVal = val; }
|
||||
void setStringValue(const std::string &val) { mStringVal = val; }
|
||||
void setStringValue2(const std::string &val) { mStringVal2 = val; }
|
||||
void setRectValue(int x, int y, int width, int height)
|
||||
{
|
||||
mXVal = x;
|
||||
mYVal = y;
|
||||
mWidthVal = width;
|
||||
mHeightVal = height;
|
||||
}
|
||||
|
||||
int getEventWindowId() const { return mEventWindowId; }
|
||||
std::string getEventUri() const { return mEventUri; }
|
||||
std::string getNavigationType() const { return mNavigationType; }
|
||||
bool getTrustedHost() const { return mTrustedHost; }
|
||||
int getIntValue() const { return mIntVal; };
|
||||
std::string getStringValue() const { return mStringVal; }
|
||||
std::string getStringValue2() const { return mStringVal2; }
|
||||
void getRectValue(int& x, int& y, int& width, int& height) const
|
||||
{
|
||||
x = mXVal;
|
||||
y = mYVal;
|
||||
width = mWidthVal;
|
||||
height = mHeightVal;
|
||||
};
|
||||
|
||||
private:
|
||||
int mEventWindowId;
|
||||
std::string mEventUri;
|
||||
std::string mNavigationType;
|
||||
bool mTrustedHost;
|
||||
int mIntVal;
|
||||
std::string mStringVal;
|
||||
std::string mStringVal2;
|
||||
int mXVal;
|
||||
int mYVal;
|
||||
int mWidthVal;
|
||||
int mHeightVal;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// derrive from this class and override these methods to observe these events
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
class LLEmbeddedBrowserWindowObserver
|
||||
{
|
||||
public:
|
||||
virtual ~LLEmbeddedBrowserWindowObserver();
|
||||
typedef LLEmbeddedBrowserWindowEvent EventType;
|
||||
|
||||
virtual void onCursorChanged(const EventType& event);
|
||||
virtual void onPageChanged(const EventType& event);
|
||||
virtual void onNavigateBegin(const EventType& event);
|
||||
virtual void onNavigateComplete(const EventType& event);
|
||||
virtual void onNavigateErrorPage(const EventType& event);
|
||||
virtual void onUpdateProgress(const EventType& event);
|
||||
virtual void onStatusTextChange(const EventType& event);
|
||||
virtual void onTitleChange(const EventType& event);
|
||||
virtual void onLocationChange(const EventType& event);
|
||||
virtual void onClickLinkHref(const EventType& event);
|
||||
virtual void onClickLinkNoFollow(const EventType& event);
|
||||
virtual void onCookieChanged(const EventType& event);
|
||||
// mStringVal will be the cookie in RFC 2109 string format
|
||||
// mEventUri will be the url that caused the cookie change
|
||||
// mIntVal will be true if the cookie is dead (i.e. being deleted), false otherwise
|
||||
virtual std::string onRequestFilePicker(const EventType& event);
|
||||
virtual void onWindowCloseRequested(const EventType& event);
|
||||
virtual void onWindowGeometryChangeRequested(const EventType& event);
|
||||
|
||||
// This should return true to attempt auth, or false to cancel.
|
||||
virtual bool onAuthRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password);
|
||||
|
||||
// This should return true to continue after cert error, or false to cancel and abort.
|
||||
virtual bool onCertError(const std::string &in_url, const std::string &in_msg);
|
||||
|
||||
virtual void onLinkHovered(const EventType& event);
|
||||
// mEventURI will be the link
|
||||
// mStringVal will be the title
|
||||
// mStringVal2 will be the text
|
||||
|
||||
// catch qDebug() messages from Qt and pipe them back to host application
|
||||
virtual void onQtDebugMessage( const std::string& msg, const std::string& msg_type);
|
||||
};
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// main library class
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
class LLQtWebKit
|
||||
{
|
||||
public:
|
||||
typedef enum e_cursor
|
||||
{
|
||||
C_ARROW,
|
||||
C_IBEAM,
|
||||
C_SPLITV,
|
||||
C_SPLITH,
|
||||
C_POINTINGHAND
|
||||
} ECursor;
|
||||
|
||||
typedef enum e_user_action
|
||||
{
|
||||
UA_EDIT_CUT,
|
||||
UA_EDIT_COPY,
|
||||
UA_EDIT_PASTE,
|
||||
UA_NAVIGATE_STOP,
|
||||
UA_NAVIGATE_BACK,
|
||||
UA_NAVIGATE_FORWARD,
|
||||
UA_NAVIGATE_RELOAD
|
||||
} EUserAction;
|
||||
|
||||
typedef enum e_key_event
|
||||
{
|
||||
KE_KEY_DOWN,
|
||||
KE_KEY_REPEAT,
|
||||
KE_KEY_UP
|
||||
}EKeyEvent;
|
||||
|
||||
typedef enum e_mouse_event
|
||||
{
|
||||
ME_MOUSE_MOVE,
|
||||
ME_MOUSE_DOWN,
|
||||
ME_MOUSE_UP,
|
||||
ME_MOUSE_DOUBLE_CLICK
|
||||
}EMouseEvent;
|
||||
|
||||
typedef enum e_mouse_button
|
||||
{
|
||||
MB_MOUSE_BUTTON_LEFT,
|
||||
MB_MOUSE_BUTTON_RIGHT,
|
||||
MB_MOUSE_BUTTON_MIDDLE,
|
||||
MB_MOUSE_BUTTON_EXTRA_1,
|
||||
MB_MOUSE_BUTTON_EXTRA_2,
|
||||
}EMouseButton;
|
||||
|
||||
typedef enum e_keyboard_modifier
|
||||
{
|
||||
KM_MODIFIER_NONE = 0x00,
|
||||
KM_MODIFIER_SHIFT = 0x01,
|
||||
KM_MODIFIER_CONTROL = 0x02,
|
||||
KM_MODIFIER_ALT = 0x04,
|
||||
KM_MODIFIER_META = 0x08
|
||||
}EKeyboardModifier;
|
||||
|
||||
virtual ~LLQtWebKit();
|
||||
|
||||
// singleton access
|
||||
static LLQtWebKit* getInstance();
|
||||
|
||||
// housekeeping
|
||||
bool init(std::string application_directory,
|
||||
std::string component_directory,
|
||||
std::string profile_directory,
|
||||
void* native_window_handle);
|
||||
bool reset();
|
||||
bool clearCache();
|
||||
int getLastError();
|
||||
std::string getVersion();
|
||||
void setBrowserAgentId(std::string id);
|
||||
bool enableProxy(bool enabled, std::string host_name, int port);
|
||||
|
||||
void enableCookies(bool enabled);
|
||||
bool clearAllCookies();
|
||||
|
||||
// The following two functions accept and return cookies in the same format that's used for the Set-Cookie: HTTP header
|
||||
// as defined in RFC 2109 ( http://www.ietf.org/rfc/rfc2109.txt ). The string should not contain the literal "Set-Cookie:",
|
||||
// just the cookie itself.
|
||||
// Multiple cookies within the string are separated by a newline character ('\n')
|
||||
void setCookies(const std::string &cookies);
|
||||
std::string getAllCookies();
|
||||
|
||||
void enablePlugins(bool enabled);
|
||||
void enableJavaScript(bool enabled);
|
||||
|
||||
// Web inspector - Firebug-esque debugger
|
||||
bool showWebInspector(bool show);
|
||||
|
||||
// updates value of 'hostLanguage' in JavaScript 'Navigator' obect that
|
||||
// embedded pages can query to see what language the host app is set to
|
||||
void setHostLanguage(const std::string& host_language);
|
||||
|
||||
// browser window - creation/deletion, mutation etc.
|
||||
int createBrowserWindow(int width, int height, const std::string target = std::string(""));
|
||||
void proxyWindowOpened(int browser_window_id, const std::string target, const std::string uuid);
|
||||
void proxyWindowClosed(int browser_window_id, const std::string uuid);
|
||||
bool destroyBrowserWindow(int browser_window_id);
|
||||
bool setSize(int browser_window_id, int width, int height);
|
||||
bool scrollByLines(int browser_window_id, int lines);
|
||||
bool setBackgroundColor(int browser_window_id, const int red, const int green, const int blue);
|
||||
bool setEnabled(int browser_window_id, bool enabled);
|
||||
|
||||
// add/remove yourself as an observer on browser events - see LLEmbeddedBrowserWindowObserver declaration
|
||||
bool addObserver(int browser_window_id, LLEmbeddedBrowserWindowObserver* subject);
|
||||
bool remObserver(int browser_window_id, LLEmbeddedBrowserWindowObserver* subject);
|
||||
|
||||
// navigation - self explanatory
|
||||
bool navigateTo(int browser_window_id, const std::string uri);
|
||||
bool userAction(int browser_window_id, EUserAction action);
|
||||
bool userActionIsEnabled(int browser_window_id, EUserAction action);
|
||||
|
||||
// javascript access/control
|
||||
std::string evaluateJavaScript(int browser_window_id, const std::string script);
|
||||
|
||||
// set/clear URL to redirect to when a 404 page is reached
|
||||
bool set404RedirectUrl(int browser_window_in, std::string redirect_url);
|
||||
bool clr404RedirectUrl(int browser_window_in);
|
||||
|
||||
// access to rendered bitmap data
|
||||
const unsigned char* grabBrowserWindow(int browser_window_id); // renders page to memory and returns pixels
|
||||
const unsigned char* getBrowserWindowPixels(int browser_window_id); // just returns pixels - no render
|
||||
bool flipWindow(int browser_window_id, bool flip); // optionally flip window (pixels) you get back
|
||||
int getBrowserWidth(int browser_window_id); // current browser width (can vary slightly after page is rendered)
|
||||
int getBrowserHeight(int browser_window_id); // current height
|
||||
int getBrowserDepth(int browser_window_id); // depth in bytes
|
||||
int getBrowserRowSpan(int browser_window_id); // width in pixels * depth in bytes
|
||||
|
||||
// mouse/keyboard interaction
|
||||
bool mouseEvent(int browser_window_id, EMouseEvent mouse_event, int button, int x, int y, EKeyboardModifier modifiers); // send a mouse event to a browser window at given XY in browser space
|
||||
bool scrollWheelEvent(int browser_window_id, int x, int y, int scroll_x, int scroll_y, EKeyboardModifier modifiers);
|
||||
bool keyboardEvent(
|
||||
int browser_window_id,
|
||||
EKeyEvent key_event,
|
||||
uint32_t key_code,
|
||||
const char *utf8_text,
|
||||
EKeyboardModifier modifiers,
|
||||
uint32_t native_scan_code = 0,
|
||||
uint32_t native_virtual_key = 0,
|
||||
uint32_t native_modifiers = 0);
|
||||
|
||||
bool focusBrowser(int browser_window_id, bool focus_browser); // set/remove focus to given browser window
|
||||
|
||||
// accessor/mutator for scheme that browser doesn't follow - e.g. secondlife.com://
|
||||
void setNoFollowScheme(int browser_window_id, std::string scheme);
|
||||
std::string getNoFollowScheme(int browser_window_id);
|
||||
|
||||
void pump(int max_milliseconds);
|
||||
|
||||
void prependHistoryUrl(int browser_window_id, std::string url);
|
||||
void clearHistory(int browser_window_id);
|
||||
std::string dumpHistory(int browser_window_id);
|
||||
|
||||
// Specify a path to a .pem file containing a list of CA certificates the browser should trust.
|
||||
// NOTE that this will replace the default list of root certs (not add to it).
|
||||
// If the file isn't found or doesn't contain any certs in the correct format, this call will have no effect and will return false.
|
||||
// NOTE: Using this function causes strange cert verification issues on the Mac.
|
||||
// Using addCAFile() instead seems to work better.
|
||||
bool setCAFile(const std::string &ca_file);
|
||||
|
||||
// This behaves similarly, but instead of replacing the entire list it appends additional trusted root certs to the current list.
|
||||
bool addCAFile(const std::string &ca_file);
|
||||
|
||||
// Set a flag causing all SSL cert errors to be ignored.
|
||||
// NOTE: this should only be used for testing, as it negates the security model of https.
|
||||
void setIgnoreSSLCertErrors(bool ignore);
|
||||
bool getIgnoreSSLCertErrors();
|
||||
|
||||
const std::vector< std::string > getInstalledCertsList();
|
||||
|
||||
void enableQtMessageHandler( bool enable );
|
||||
|
||||
void enableLoadingOverlay( int browser_window_id, bool enable);
|
||||
|
||||
// Copied from indra_constants.h.
|
||||
// The key_code argument to keyboardEvent should either be one of these or a 7-bit ascii character.
|
||||
enum keyCodes
|
||||
{
|
||||
// Leading zeroes ensure that these won't sign-extend when assigned to a larger type.
|
||||
KEY_RETURN = 0x0081,
|
||||
KEY_LEFT = 0x0082,
|
||||
KEY_RIGHT = 0x0083,
|
||||
KEY_UP = 0x0084,
|
||||
KEY_DOWN = 0x0085,
|
||||
KEY_ESCAPE = 0x0086,
|
||||
KEY_BACKSPACE = 0x0087,
|
||||
KEY_DELETE = 0x0088,
|
||||
KEY_SHIFT = 0x0089,
|
||||
KEY_CONTROL = 0x008A,
|
||||
KEY_ALT = 0x008B,
|
||||
KEY_HOME = 0x008C,
|
||||
KEY_END = 0x008D,
|
||||
KEY_PAGE_UP = 0x008E,
|
||||
KEY_PAGE_DOWN = 0x008F,
|
||||
KEY_HYPHEN = 0x0090,
|
||||
KEY_EQUALS = 0x0091,
|
||||
KEY_INSERT = 0x0092,
|
||||
KEY_CAPSLOCK = 0x0093,
|
||||
KEY_TAB = 0x0094,
|
||||
KEY_ADD = 0x0095,
|
||||
KEY_SUBTRACT = 0x0096,
|
||||
KEY_MULTIPLY = 0x0097,
|
||||
KEY_DIVIDE = 0x0098,
|
||||
KEY_F1 = 0x00A1,
|
||||
KEY_F2 = 0x00A2,
|
||||
KEY_F3 = 0x00A3,
|
||||
KEY_F4 = 0x00A4,
|
||||
KEY_F5 = 0x00A5,
|
||||
KEY_F6 = 0x00A6,
|
||||
KEY_F7 = 0x00A7,
|
||||
KEY_F8 = 0x00A8,
|
||||
KEY_F9 = 0x00A9,
|
||||
KEY_F10 = 0x00AA,
|
||||
KEY_F11 = 0x00AB,
|
||||
KEY_F12 = 0x00AC,
|
||||
|
||||
KEY_PAD_UP = 0x00C0,
|
||||
KEY_PAD_DOWN = 0x00C1,
|
||||
KEY_PAD_LEFT = 0x00C2,
|
||||
KEY_PAD_RIGHT = 0x00C3,
|
||||
KEY_PAD_HOME = 0x00C4,
|
||||
KEY_PAD_END = 0x00C5,
|
||||
KEY_PAD_PGUP = 0x00C6,
|
||||
KEY_PAD_PGDN = 0x00C7,
|
||||
KEY_PAD_CENTER = 0x00C8, // the 5 in the middle
|
||||
KEY_PAD_INS = 0x00C9,
|
||||
KEY_PAD_DEL = 0x00CA,
|
||||
KEY_PAD_RETURN = 0x00CB,
|
||||
KEY_PAD_ADD = 0x00CC,
|
||||
KEY_PAD_SUBTRACT = 0x00CD,
|
||||
KEY_PAD_MULTIPLY = 0x00CE,
|
||||
KEY_PAD_DIVIDE = 0x00CF,
|
||||
|
||||
KEY_NONE = 0x00FF // not sent from keyboard. For internal use only.
|
||||
};
|
||||
|
||||
// set the regex used to determine if a page is trusted or not
|
||||
void setWhiteListRegex( int browser_window_id, const std::string& regex );
|
||||
|
||||
// Second Life specific functions
|
||||
// (Note, this is a departure from the generic nature of this library)
|
||||
void setSLObjectEnabled( bool enabled ); // enable or disaable feature
|
||||
void setAgentLanguage( const std::string& agent_language ); // viewer language selected by agent
|
||||
void setAgentRegion( const std::string& agent_region ); // name of region where agent is located
|
||||
void setAgentLocation( double x, double y, double z ); // agent's x,y,z location within a region
|
||||
void setAgentGlobalLocation( double x, double y, double z ); // agent's x,y,z location within the current grid
|
||||
void setAgentOrientation( double angle ); // direction (0..359) agent is facing
|
||||
void setAgentMaturity( const std::string& agent_maturity ); // selected maturity level of agent
|
||||
void emitLocation();
|
||||
void emitMaturity();
|
||||
void emitLanguage();
|
||||
|
||||
// set the zoom factor for web pages ( can be less than 0.0)
|
||||
void setPageZoomFactor( double factor );
|
||||
|
||||
private:
|
||||
LLQtWebKit();
|
||||
LLEmbeddedBrowserWindow* getBrowserWindowFromWindowId(int browser_window_id);
|
||||
static LLQtWebKit* sInstance;
|
||||
const int mMaxBrowserWindows;
|
||||
typedef std::map< int, LLEmbeddedBrowserWindow* > BrowserWindowMap;
|
||||
typedef std::map< int, LLEmbeddedBrowserWindow* >::iterator BrowserWindowMapIter;
|
||||
BrowserWindowMap mBrowserWindowMap;
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
|
||||
#endif // LLQTWEBKIT_H
|
||||
@@ -1,47 +0,0 @@
|
||||
DEPENDPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
!mac {
|
||||
unix {
|
||||
DEFINES += LL_LINUX
|
||||
}
|
||||
}
|
||||
|
||||
mac {
|
||||
DEFINES += LL_OSX
|
||||
}
|
||||
|
||||
win32{
|
||||
DEFINES += _WINDOWS
|
||||
}
|
||||
|
||||
# Input
|
||||
HEADERS += llembeddedbrowser.h \
|
||||
llembeddedbrowser_p.h \
|
||||
llembeddedbrowserwindow.h \
|
||||
llembeddedbrowserwindow_p.h \
|
||||
llnetworkaccessmanager.h \
|
||||
llqtwebkit.h \
|
||||
llwebpage.h \
|
||||
llwebpageopenshim.h \
|
||||
llstyle.h \
|
||||
lljsobject.h
|
||||
|
||||
SOURCES += llembeddedbrowser.cpp \
|
||||
llembeddedbrowserwindow.cpp \
|
||||
llnetworkaccessmanager.cpp \
|
||||
llqtwebkit.cpp \
|
||||
llwebpage.cpp \
|
||||
llwebpageopenshim.cpp \
|
||||
llstyle.cpp \
|
||||
lljsobject.cpp
|
||||
|
||||
FORMS += passworddialog.ui
|
||||
|
||||
RCC_DIR = .rcc
|
||||
UI_DIR = .ui
|
||||
MOC_DIR = .moc
|
||||
OBJECTS_DIR = .obj
|
||||
|
||||
include(static.pri)
|
||||
include(qtwebkit_cookiejar/src/src.pri)
|
||||
@@ -1,18 +0,0 @@
|
||||
TEMPLATE = lib
|
||||
CONFIG += static staticlib # we always build as static lib whether Qt is static or not
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
|
||||
include(llqtwebkit.pri)
|
||||
|
||||
QT += webkit opengl network gui
|
||||
|
||||
win32:CONFIG(debug,debug|release) {
|
||||
TARGET = llqtwebkitd
|
||||
}
|
||||
|
||||
RCC_DIR = $$PWD/.rcc
|
||||
UI_DIR = $$PWD/.ui
|
||||
MOC_DIR = $$PWD/.moc
|
||||
OBJECTS_DIR = $$PWD/.obj
|
||||
@@ -1,79 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include "llstyle.h"
|
||||
|
||||
#include "llembeddedbrowserwindow_p.h"
|
||||
#include <qstyleoption.h>
|
||||
#include <qpainter.h>
|
||||
#include <qdebug.h>
|
||||
|
||||
LLStyle::LLStyle()
|
||||
: QPlastiqueStyle()
|
||||
{
|
||||
}
|
||||
|
||||
void LLStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
#ifdef Q_WS_MAC
|
||||
if (control == QStyle::CC_ScrollBar) {
|
||||
QStyleOptionSlider* opt = (QStyleOptionSlider*)option;
|
||||
const QPoint topLeft = opt->rect.topLeft();
|
||||
painter->translate(topLeft);
|
||||
opt->rect.moveTo(QPoint(0, 0));
|
||||
painter->fillRect(opt->rect, opt->palette.background());
|
||||
}
|
||||
#endif
|
||||
QPlastiqueStyle::drawComplexControl(control, option, painter, widget);
|
||||
}
|
||||
|
||||
void LLStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
switch(element)
|
||||
{
|
||||
case CE_ScrollBarAddLine:
|
||||
case CE_ScrollBarSubLine:
|
||||
// This fixes the "scrollbar arrows pointing the wrong way" bug.
|
||||
if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option))
|
||||
{
|
||||
// Make the State_Horizontal bit in the option's state field match its orientation field.
|
||||
QStyleOptionSlider localOption(*scrollBar);
|
||||
if(localOption.orientation == Qt::Horizontal)
|
||||
{
|
||||
localOption.state |= State_Horizontal;
|
||||
}
|
||||
else
|
||||
{
|
||||
localOption.state &= ~State_Horizontal;
|
||||
}
|
||||
QPlastiqueStyle::drawControl(element, &localOption, painter, widget);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QPlastiqueStyle::drawControl(element, option, painter, widget);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLSTYLE_H
|
||||
#define LLSTYLE_H
|
||||
|
||||
#include <qplastiquestyle.h>
|
||||
|
||||
class LLStyle : public QPlastiqueStyle
|
||||
{
|
||||
|
||||
public:
|
||||
explicit LLStyle();
|
||||
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
|
||||
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,536 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include "llwebpage.h"
|
||||
|
||||
#include <qnetworkrequest.h>
|
||||
#include <qwebframe.h>
|
||||
#include <qgraphicswebview.h>
|
||||
#include <qevent.h>
|
||||
#include <qdebug.h>
|
||||
#include <qmessagebox.h>
|
||||
#include <qwebelement.h>
|
||||
#include <qgraphicsproxywidget.h>
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "llqtwebkit.h"
|
||||
#include "llembeddedbrowser.h"
|
||||
#include "llembeddedbrowserwindow.h"
|
||||
#include "llembeddedbrowserwindow_p.h"
|
||||
#include "lljsobject.h"
|
||||
|
||||
LLWebPage::LLWebPage(QObject *parent)
|
||||
: QWebPage(parent)
|
||||
, window(0)
|
||||
, mHostLanguage( "en" )
|
||||
, mWhiteListRegex( "" )
|
||||
{
|
||||
mJsObject = new LLJsObject( parent );
|
||||
|
||||
connect(this, SIGNAL(loadProgress(int)),
|
||||
this, SLOT(loadProgressSlot(int)));
|
||||
connect(this, SIGNAL(linkHovered(const QString &, const QString &, const QString &)),
|
||||
this, SLOT(linkHoveredSlot(const QString &, const QString &, const QString &)));
|
||||
connect(this, SIGNAL(statusBarMessage(const QString &)),
|
||||
this, SLOT(statusBarMessageSlot(const QString &)));
|
||||
connect(mainFrame(), SIGNAL(urlChanged(const QUrl&)),
|
||||
this, SLOT(urlChangedSlot(const QUrl&)));
|
||||
connect(this, SIGNAL(loadStarted()),
|
||||
this, SLOT(loadStarted()));
|
||||
connect(this, SIGNAL(loadFinished(bool)),
|
||||
this, SLOT(loadFinished(bool)));
|
||||
connect(this, SIGNAL(windowCloseRequested()),
|
||||
this, SLOT(windowCloseRequested()));
|
||||
connect(this, SIGNAL(geometryChangeRequested(const QRect&)),
|
||||
this, SLOT(geometryChangeRequested(const QRect&)));
|
||||
connect(mainFrame(), SIGNAL(titleChanged(const QString&)),
|
||||
this, SLOT(titleChangedSlot(const QString&)));
|
||||
connect(mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
|
||||
this, SLOT(extendNavigatorObject()));
|
||||
}
|
||||
|
||||
LLWebPage::~LLWebPage()
|
||||
{
|
||||
delete mJsObject;
|
||||
}
|
||||
|
||||
void LLWebPage::loadProgressSlot(int progress)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
window->d->mPercentComplete = progress;
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setEventUri(window->getCurrentUri());
|
||||
event.setIntValue(progress);
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onUpdateProgress, event);
|
||||
|
||||
if ( progress >= 100 )
|
||||
window->d->mShowLoadingOverlay = false;
|
||||
|
||||
window->d->mDirty = true;
|
||||
window->grabWindow(0,0,webView->boundingRect().width(),webView->boundingRect().height());
|
||||
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onPageChanged, event);
|
||||
}
|
||||
|
||||
void LLWebPage::linkHoveredSlot(const QString &link, const QString &title, const QString &textContent)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setEventUri(llToStdString(link));
|
||||
event.setStringValue(llToStdString(title));
|
||||
event.setStringValue2(llToStdString(textContent));
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onLinkHovered, event);
|
||||
}
|
||||
|
||||
void LLWebPage::statusBarMessageSlot(const QString& text)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
window->d->mStatusText = llToStdString(text);
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setEventUri(window->getCurrentUri());
|
||||
event.setStringValue(window->d->mStatusText);
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onStatusTextChange, event);
|
||||
}
|
||||
|
||||
void LLWebPage::titleChangedSlot(const QString& text)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
window->d->mTitle = llToStdString(text);
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setEventUri(window->getCurrentUri());
|
||||
event.setStringValue(window->d->mTitle);
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onTitleChange, event);
|
||||
}
|
||||
|
||||
// set the regex used to determine if a page is trusted or not
|
||||
void LLWebPage::setWhiteListRegex( const std::string& regex )
|
||||
{
|
||||
mWhiteListRegex = regex;
|
||||
}
|
||||
|
||||
void LLWebPage::configureTrustedPage( bool is_trusted )
|
||||
{
|
||||
// action happens in browser window parent
|
||||
LLEmbeddedBrowser* parent_browser = 0;
|
||||
if ( window && window->d && window->d->mParent )
|
||||
{
|
||||
parent_browser = window->d->mParent;
|
||||
if ( parent_browser )
|
||||
{
|
||||
if ( is_trusted )
|
||||
{
|
||||
//qDebug() << "Whitelist passed - turning on";
|
||||
|
||||
// trusted so turn everything on
|
||||
parent_browser->enableJavaScriptTransient( true );
|
||||
parent_browser->enableCookiesTransient( true );
|
||||
parent_browser->enablePluginsTransient( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
//qDebug() << "Whitelist failed - reverting to default state";
|
||||
|
||||
// restore default state set by client
|
||||
parent_browser->enableJavaScript( parent_browser->isJavaScriptEnabled() );
|
||||
parent_browser->enableCookies( parent_browser->areCookiesEnabled() );
|
||||
parent_browser->enablePlugins( parent_browser->arePluginsEnabled() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLWebPage::checkRegex( const QUrl& url )
|
||||
{
|
||||
QRegExp reg_exp( QString::fromStdString( mWhiteListRegex ) );
|
||||
reg_exp.setCaseSensitivity( Qt::CaseInsensitive );
|
||||
reg_exp.setMinimal( true );
|
||||
|
||||
if ( reg_exp.exactMatch( url.host() ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void LLWebPage::checkWhiteList( const QUrl& url )
|
||||
{
|
||||
if ( mWhiteListRegex.length() )
|
||||
{
|
||||
if ( checkRegex( url ) )
|
||||
{
|
||||
configureTrustedPage( true ); // page is "trusted" - go ahead and configure it as such
|
||||
}
|
||||
else
|
||||
{
|
||||
configureTrustedPage( false ); // page is "NOT trusted" - go ahead and configure it as such
|
||||
}
|
||||
}
|
||||
else
|
||||
// no regex specified, don't do anything (i.e. don't change trust state)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void LLWebPage::urlChangedSlot(const QUrl& url)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
checkWhiteList( url );
|
||||
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setEventUri(window->getCurrentUri());
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onLocationChange, event);
|
||||
}
|
||||
|
||||
bool LLWebPage::event(QEvent *event)
|
||||
{
|
||||
bool result = QWebPage::event(event);
|
||||
|
||||
if (event->type() == QEvent::GraphicsSceneMousePress)
|
||||
currentPoint = ((QGraphicsSceneMouseEvent*)event)->pos().toPoint();
|
||||
else if(event->type() == QEvent::GraphicsSceneMouseRelease)
|
||||
currentPoint = QPoint();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool LLWebPage::acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, NavigationType type)
|
||||
{
|
||||
Q_UNUSED( frame );
|
||||
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
if (request.url().scheme() == window->d->mNoFollowScheme)
|
||||
{
|
||||
QString encodedUrl = request.url().toEncoded();
|
||||
// QUrl is turning foo:///home/bar into foo:/home/bar for some reason while Firefox does not
|
||||
// http://bugs.webkit.org/show_bug.cgi?id=24695
|
||||
if (!encodedUrl.startsWith(window->d->mNoFollowScheme + "://")) {
|
||||
encodedUrl = encodedUrl.mid(window->d->mNoFollowScheme.length() + 1);
|
||||
encodedUrl = window->d->mNoFollowScheme + "://" + encodedUrl;
|
||||
}
|
||||
std::string rawUri = llToStdString(encodedUrl);
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setEventUri(rawUri);
|
||||
|
||||
// pass over the navigation type as per this page: http://apidocs.meego.com/1.1/core/html/qt4/qwebpage.html#NavigationType-enum
|
||||
// pass as strings because telling everyone who needs to know about enums is too invasive.
|
||||
std::string nav_type("unknown");
|
||||
if (type == QWebPage::NavigationTypeLinkClicked) nav_type="clicked";
|
||||
else
|
||||
if (type == QWebPage::NavigationTypeFormSubmitted) nav_type="form_submited";
|
||||
else
|
||||
if (type == QWebPage::NavigationTypeBackOrForward) nav_type="back_forward";
|
||||
else
|
||||
if (type == QWebPage::NavigationTypeReload) nav_type="reloaded";
|
||||
else
|
||||
if (type == QWebPage::NavigationTypeFormResubmitted) nav_type="form_resubmited";
|
||||
event.setNavigationType(nav_type);
|
||||
|
||||
if ( mWhiteListRegex.length() )
|
||||
{
|
||||
if ( frame )
|
||||
{
|
||||
if ( checkRegex( frame->url() ) )
|
||||
{
|
||||
event.setTrustedHost( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
event.setTrustedHost( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
// no frame - no trust (TODO: when can this happen?)
|
||||
{
|
||||
event.setTrustedHost( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
// no regex is like switching it off and indicating everything is trusted
|
||||
{
|
||||
event.setTrustedHost( true );
|
||||
}
|
||||
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onClickLinkNoFollow, event);
|
||||
|
||||
//qDebug() << "LLWebPage::acceptNavigationRequest: sending onClickLinkNoFollow, NavigationType is " << type << ", url is " << QString::fromStdString(rawUri) ;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LLWebPage::loadStarted()
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
QUrl url( QString::fromStdString( window->getCurrentUri() ) );
|
||||
checkWhiteList( url );
|
||||
|
||||
window->d->mShowLoadingOverlay = true;
|
||||
|
||||
window->d->mTimeLoadStarted=time(NULL);
|
||||
|
||||
window->d->mDirty = true;
|
||||
window->grabWindow(0,0,webView->boundingRect().width(),webView->boundingRect().height());
|
||||
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setEventUri(window->getCurrentUri());
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onNavigateBegin, event);
|
||||
}
|
||||
|
||||
void LLWebPage::loadFinished(bool)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
window->d->mShowLoadingOverlay = false;
|
||||
|
||||
window->d->mDirty = true;
|
||||
window->grabWindow(0,0,webView->boundingRect().width(),webView->boundingRect().height());
|
||||
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setEventUri(window->getCurrentUri());
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onPageChanged, event);
|
||||
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onNavigateComplete, event);
|
||||
}
|
||||
|
||||
void LLWebPage::windowCloseRequested()
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onWindowCloseRequested, event);
|
||||
}
|
||||
|
||||
void LLWebPage::geometryChangeRequested(const QRect& geom)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
// empty UUID indicates this is targeting the main window
|
||||
// event.setStringValue(window->getUUID());
|
||||
event.setRectValue(geom.x(), geom.y(), geom.width(), geom.height());
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onWindowGeometryChangeRequested, event);
|
||||
}
|
||||
|
||||
QString LLWebPage::chooseFile(QWebFrame* parentFrame, const QString& suggestedFile)
|
||||
{
|
||||
Q_UNUSED(parentFrame);
|
||||
Q_UNUSED(suggestedFile);
|
||||
|
||||
return QString::fromStdString( window->requestFilePicker() );
|
||||
}
|
||||
|
||||
void LLWebPage::javaScriptAlert(QWebFrame* frame, const QString& msg)
|
||||
{
|
||||
Q_UNUSED(frame);
|
||||
QMessageBox *msgBox = new QMessageBox;
|
||||
msgBox->setWindowTitle(tr("JavaScript Alert - %1").arg(mainFrame()->url().host()));
|
||||
msgBox->setText(msg);
|
||||
msgBox->addButton(QMessageBox::Ok);
|
||||
|
||||
QGraphicsProxyWidget *proxy = webView->scene()->addWidget(msgBox);
|
||||
proxy->setWindowFlags(Qt::Window); // this makes the item a panel (and will make it get a window 'frame')
|
||||
proxy->setPanelModality(QGraphicsItem::SceneModal);
|
||||
proxy->setPos((webView->boundingRect().width() - msgBox->sizeHint().width())/2,
|
||||
(webView->boundingRect().height() - msgBox->sizeHint().height())/2);
|
||||
proxy->setActive(true); // make it the active item
|
||||
|
||||
connect(msgBox, SIGNAL(finished(int)), proxy, SLOT(deleteLater()));
|
||||
msgBox->show();
|
||||
|
||||
webView->scene()->setFocusItem(proxy);
|
||||
}
|
||||
|
||||
bool LLWebPage::javaScriptConfirm(QWebFrame* frame, const QString& msg)
|
||||
{
|
||||
Q_UNUSED(frame);
|
||||
Q_UNUSED(msg);
|
||||
qWarning() << "LLWebPage::" << __FUNCTION__ << "not implemented" << msg << "returning true";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLWebPage::javaScriptPrompt(QWebFrame* frame, const QString& msg, const QString& defaultValue, QString* result)
|
||||
{
|
||||
Q_UNUSED(frame);
|
||||
Q_UNUSED(msg);
|
||||
Q_UNUSED(defaultValue);
|
||||
Q_UNUSED(result);
|
||||
qWarning() << "LLWebPage::" << __FUNCTION__ << "not implemented" << msg << defaultValue << "returning false";
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLWebPage::extendNavigatorObject()
|
||||
{
|
||||
// legacy - will go away in the future
|
||||
QString q_host_language = QString::fromStdString( mHostLanguage );
|
||||
mainFrame()->evaluateJavaScript(QString("navigator.hostLanguage=\"%1\"").arg( q_host_language ));
|
||||
|
||||
// the new way
|
||||
if ( mJsObject )
|
||||
{
|
||||
bool enabled = mJsObject->getSLObjectEnabled();
|
||||
if ( enabled )
|
||||
{
|
||||
mainFrame()->addToJavaScriptWindowObject("slviewer", mJsObject );
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
QWebPage *LLWebPage::createWindow(WebWindowType type)
|
||||
{
|
||||
Q_UNUSED(type);
|
||||
QWebPage *result = NULL;
|
||||
|
||||
if(window)
|
||||
{
|
||||
result = window->createWindow();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void LLWebPage::setHostLanguage(const std::string& host_language)
|
||||
{
|
||||
mHostLanguage = host_language;
|
||||
}
|
||||
|
||||
bool LLWebPage::supportsExtension(QWebPage::Extension extension) const
|
||||
{
|
||||
if (extension == QWebPage::ErrorPageExtension)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLWebPage::extension(Extension, const ExtensionOption* option, ExtensionReturn* output)
|
||||
{
|
||||
const QWebPage::ErrorPageExtensionOption* info = static_cast<const QWebPage::ErrorPageExtensionOption*>(option);
|
||||
QWebPage::ErrorPageExtensionReturn* errorPage = static_cast<QWebPage::ErrorPageExtensionReturn*>(output);
|
||||
|
||||
errorPage->content = QString("<html><head><title>Failed loading page</title></head><body bgcolor=\"#ffe0e0\" text=\"#000000\"><h3><tt>%1</tt></h3></body></html>")
|
||||
.arg(info->errorString).toUtf8();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Second Life viewer specific functions
|
||||
void LLWebPage::setSLObjectEnabled( bool enabled )
|
||||
{
|
||||
if ( mJsObject )
|
||||
mJsObject->setSLObjectEnabled( enabled );
|
||||
}
|
||||
|
||||
void LLWebPage::setAgentLanguage( const std::string& agent_language )
|
||||
{
|
||||
if ( mJsObject )
|
||||
mJsObject->setAgentLanguage( QString::fromStdString( agent_language ) );
|
||||
}
|
||||
|
||||
void LLWebPage::setAgentRegion( const std::string& agent_region )
|
||||
{
|
||||
if ( mJsObject )
|
||||
mJsObject->setAgentRegion( QString::fromStdString( agent_region ) );
|
||||
}
|
||||
|
||||
void LLWebPage::setAgentLocation( double x, double y, double z )
|
||||
{
|
||||
if ( mJsObject )
|
||||
{
|
||||
QVariantMap location;
|
||||
location["x"] = x;
|
||||
location["y"] = y;
|
||||
location["z"] = z;
|
||||
mJsObject->setAgentLocation( location );
|
||||
}
|
||||
}
|
||||
|
||||
void LLWebPage::setAgentGlobalLocation( double x, double y, double z )
|
||||
{
|
||||
if ( mJsObject )
|
||||
{
|
||||
QVariantMap global_location;
|
||||
global_location["x"] = x;
|
||||
global_location["y"] = y;
|
||||
global_location["z"] = z;
|
||||
mJsObject->setAgentGlobalLocation( global_location );
|
||||
}
|
||||
}
|
||||
|
||||
void LLWebPage::setAgentOrientation( double angle )
|
||||
{
|
||||
if ( mJsObject )
|
||||
{
|
||||
mJsObject->setAgentOrientation( angle );
|
||||
}
|
||||
}
|
||||
|
||||
void LLWebPage::setAgentMaturity( const std::string& agent_maturity )
|
||||
{
|
||||
if ( mJsObject )
|
||||
mJsObject->setAgentMaturity( QString::fromStdString( agent_maturity ) );
|
||||
}
|
||||
|
||||
void LLWebPage::emitLocation()
|
||||
{
|
||||
if ( mJsObject )
|
||||
mJsObject->emitLocation();
|
||||
}
|
||||
|
||||
void LLWebPage::emitMaturity()
|
||||
{
|
||||
if ( mJsObject )
|
||||
mJsObject->emitMaturity();
|
||||
}
|
||||
|
||||
void LLWebPage::emitLanguage()
|
||||
{
|
||||
if ( mJsObject )
|
||||
mJsObject->emitLanguage();
|
||||
}
|
||||
|
||||
void LLWebPage::setPageZoomFactor( double factor )
|
||||
{
|
||||
if ( webView )
|
||||
{
|
||||
webView->setZoomFactor( factor );
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLWEBPAGE_H
|
||||
#define LLWEBPAGE_H
|
||||
|
||||
class QGraphicsWebView;
|
||||
#include <qwebpage.h>
|
||||
#include "llqtwebkit.h"
|
||||
|
||||
class LLEmbeddedBrowserWindow;
|
||||
class LLJsObject;
|
||||
|
||||
class LLWebPage : public QWebPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LLWebPage(QObject *parent = 0);
|
||||
~LLWebPage();
|
||||
|
||||
LLEmbeddedBrowserWindow *window;
|
||||
bool event(QEvent *event);
|
||||
|
||||
QGraphicsWebView *webView;
|
||||
|
||||
void setHostLanguage(const std::string& host_language);
|
||||
virtual bool supportsExtension(QWebPage::Extension extension) const;
|
||||
virtual bool extension(Extension extension, const ExtensionOption* option, ExtensionReturn* output);
|
||||
|
||||
// set the regex used to determine if a page is trusted or not
|
||||
void setWhiteListRegex( const std::string& regex );
|
||||
|
||||
// check the whitelist and update browser config as appropriate
|
||||
void checkWhiteList( const QUrl& url );
|
||||
|
||||
// code to change settings if page is known to be trusted goes here
|
||||
void configureTrustedPage( bool is_trusted );
|
||||
|
||||
// Second Life specific functions
|
||||
void setAgentRegion( const std::string& agent_region );
|
||||
void setAgentLocation( double x, double y, double z );
|
||||
void setAgentGlobalLocation( double x, double y, double z );
|
||||
void setAgentOrientation( double angle );
|
||||
void setSLObjectEnabled( bool enabled );
|
||||
void setAgentLanguage( const std::string& agent_language );
|
||||
void setAgentMaturity( const std::string& agent_maturity );
|
||||
void emitLocation();
|
||||
void emitMaturity();
|
||||
void emitLanguage();
|
||||
|
||||
void setPageZoomFactor( double factor );
|
||||
|
||||
protected:
|
||||
bool acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, NavigationType type);
|
||||
|
||||
public slots:
|
||||
void loadProgressSlot(int progress);
|
||||
void linkHoveredSlot(const QString &link, const QString &title, const QString &textContent);
|
||||
void statusBarMessageSlot(const QString &);
|
||||
void titleChangedSlot(const QString &);
|
||||
void urlChangedSlot(const QUrl& url);
|
||||
void loadStarted();
|
||||
void loadFinished(bool ok);
|
||||
void windowCloseRequested();
|
||||
void geometryChangeRequested(const QRect& geom);
|
||||
|
||||
private slots:
|
||||
void extendNavigatorObject();
|
||||
|
||||
protected:
|
||||
QString chooseFile(QWebFrame* parentFrame, const QString& suggestedFile);
|
||||
void javaScriptAlert(QWebFrame* frame, const QString& msg);
|
||||
bool javaScriptConfirm(QWebFrame* frame, const QString& msg);
|
||||
bool javaScriptPrompt(QWebFrame* frame, const QString& msg, const QString& defaultValue, QString* result);
|
||||
QWebPage *createWindow(WebWindowType type);
|
||||
|
||||
private:
|
||||
bool checkRegex( const QUrl& url );
|
||||
QPoint currentPoint;
|
||||
std::string mHostLanguage;
|
||||
std::string mWhiteListRegex;
|
||||
LLJsObject* mJsObject;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,176 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include "llwebpageopenshim.h"
|
||||
|
||||
#include <qnetworkrequest.h>
|
||||
#include <qwebframe.h>
|
||||
#include <qdebug.h>
|
||||
#include <quuid.h>
|
||||
|
||||
#include "llqtwebkit.h"
|
||||
#include "llembeddedbrowserwindow.h"
|
||||
#include "llembeddedbrowserwindow_p.h"
|
||||
|
||||
LLWebPageOpenShim::LLWebPageOpenShim(LLEmbeddedBrowserWindow *in_window, QObject *parent)
|
||||
: QWebPage(parent)
|
||||
, window(in_window)
|
||||
, mOpeningSelf(false)
|
||||
, mGeometryChangeRequested(false)
|
||||
, mHasSentUUID(false)
|
||||
{
|
||||
// qDebug() << "LLWebPageOpenShim created";
|
||||
|
||||
connect(this, SIGNAL(windowCloseRequested()),
|
||||
this, SLOT(windowCloseRequested()));
|
||||
connect(this, SIGNAL(geometryChangeRequested(const QRect&)),
|
||||
this, SLOT(geometryChangeRequested(const QRect&)));
|
||||
|
||||
// Create a unique UUID for this proxy
|
||||
mUUID = llToStdString(QUuid::createUuid().toString());
|
||||
|
||||
// mTarget starts out as the empty string, which is what we want.
|
||||
}
|
||||
|
||||
LLWebPageOpenShim::~LLWebPageOpenShim()
|
||||
{
|
||||
// qDebug() << "LLWebPageOpenShim destroyed";
|
||||
}
|
||||
|
||||
void LLWebPageOpenShim::windowCloseRequested()
|
||||
{
|
||||
// qDebug() << "LLWebPageOpenShim::windowCloseRequested";
|
||||
if(window)
|
||||
{
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setStringValue(mUUID);
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onWindowCloseRequested, event);
|
||||
}
|
||||
}
|
||||
|
||||
void LLWebPageOpenShim::geometryChangeRequested(const QRect& geom)
|
||||
{
|
||||
// qDebug() << "LLWebPageOpenShim::geometryChangeRequested: " << geom ;
|
||||
|
||||
// This seems to happen before acceptNavigationRequest is called. If this is the case, delay sending the message until afterwards.
|
||||
|
||||
if(window && mHasSentUUID)
|
||||
{
|
||||
LLEmbeddedBrowserWindowEvent event(window->getWindowId());
|
||||
event.setStringValue(mUUID);
|
||||
event.setRectValue(geom.x(), geom.y(), geom.width(), geom.height());
|
||||
window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onWindowGeometryChangeRequested, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
mGeometry = geom;
|
||||
mGeometryChangeRequested = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool LLWebPageOpenShim::matchesTarget(const std::string target)
|
||||
{
|
||||
return (target == mTarget);
|
||||
}
|
||||
|
||||
bool LLWebPageOpenShim::matchesUUID(const std::string uuid)
|
||||
{
|
||||
return (uuid == mUUID);
|
||||
}
|
||||
|
||||
void LLWebPageOpenShim::setProxy(const std::string &target, const std::string &uuid)
|
||||
{
|
||||
mTarget = target;
|
||||
mUUID = uuid;
|
||||
|
||||
mHasSentUUID = false;
|
||||
|
||||
mOpeningSelf = true;
|
||||
|
||||
mainFrame()->evaluateJavaScript(QString("window.open("", \"%1\");").arg( QString::fromStdString(target) ));
|
||||
}
|
||||
|
||||
bool LLWebPageOpenShim::acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, NavigationType type)
|
||||
{
|
||||
Q_UNUSED(type);
|
||||
if (!window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(mOpeningSelf)
|
||||
{
|
||||
qDebug() << "LLWebPageOpenShim::acceptNavigationRequest: reopening self to set target name.";
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
qDebug() << "LLWebPageOpenShim::acceptNavigationRequest called, NavigationType is " << type
|
||||
<< ", web frame is " << frame
|
||||
<< ", frame->page is " << frame->page()
|
||||
<< ", url is " << request.url()
|
||||
<< ", frame name is " << frame->frameName()
|
||||
;
|
||||
#endif
|
||||
|
||||
if (request.url().scheme() == QString("file"))
|
||||
{
|
||||
// For some reason, I'm seeing a spurious call to this function with a file:/// URL that points to the current working directory.
|
||||
// Ignoring file:/// URLs here isn't a perfect solution (since it could potentially break content in local HTML files),
|
||||
// but it's the best I could come up with for now.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// The name of the incoming frame has been set to the link target that was used when opening this window.
|
||||
std::string click_href = llToStdString(request.url());
|
||||
mTarget = llToStdString(frame->frameName());
|
||||
|
||||
// build event based on the data we have and emit it
|
||||
LLEmbeddedBrowserWindowEvent event( window->getWindowId());
|
||||
event.setEventUri(click_href);
|
||||
event.setStringValue(mTarget);
|
||||
event.setStringValue2(mUUID);
|
||||
|
||||
window->d->mEventEmitter.update( &LLEmbeddedBrowserWindowObserver::onClickLinkHref, event );
|
||||
|
||||
mHasSentUUID = true;
|
||||
|
||||
if(mGeometryChangeRequested)
|
||||
{
|
||||
geometryChangeRequested(mGeometry);
|
||||
mGeometryChangeRequested = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QWebPage *LLWebPageOpenShim::createWindow(WebWindowType type)
|
||||
{
|
||||
Q_UNUSED(type);
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef LLWEBPAGEOPENSHIM_H
|
||||
#define LLWEBPAGEOPENSHIM_H
|
||||
|
||||
#include <qwebpage.h>
|
||||
|
||||
class LLEmbeddedBrowserWindow;
|
||||
class LLWebPageOpenShim : public QWebPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LLWebPageOpenShim(LLEmbeddedBrowserWindow *in_window, QObject *parent = 0);
|
||||
~LLWebPageOpenShim();
|
||||
LLEmbeddedBrowserWindow *window;
|
||||
bool matchesTarget(const std::string target);
|
||||
bool matchesUUID(const std::string uuid);
|
||||
void setProxy(const std::string &target, const std::string &uuid);
|
||||
|
||||
public slots:
|
||||
void windowCloseRequested();
|
||||
void geometryChangeRequested(const QRect& geom);
|
||||
|
||||
protected:
|
||||
bool acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, NavigationType type);
|
||||
QWebPage *createWindow(WebWindowType type);
|
||||
|
||||
private:
|
||||
std::string mUUID;
|
||||
std::string mTarget;
|
||||
bool mOpeningSelf;
|
||||
bool mGeometryChangeRequested;
|
||||
bool mHasSentUUID;
|
||||
QRect mGeometry;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PasswordDialog</class>
|
||||
<widget class="QDialog" name="PasswordDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>394</width>
|
||||
<height>183</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>12</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="3">
|
||||
<widget class="QLabel" name="message">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="icon">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>32</horstretch>
|
||||
<verstretch>32</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>icon</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="userNameLabel">
|
||||
<property name="text">
|
||||
<string>User name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="userName"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="passwordLabel">
|
||||
<property name="text">
|
||||
<string>Password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="password">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>PasswordDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>PasswordDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -1,728 +0,0 @@
|
||||
/* A portable stdint.h
|
||||
****************************************************************************
|
||||
* BSD License:
|
||||
****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2005-2007 Paul Hsieh
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Version 0.1.10
|
||||
*
|
||||
* The ANSI C standard committee, for the C99 standard, specified the
|
||||
* inclusion of a new standard include file called stdint.h. This is
|
||||
* a very useful and long desired include file which contains several
|
||||
* very precise definitions for integer scalar types that is
|
||||
* critically important for making portable several classes of
|
||||
* applications including cryptography, hashing, variable length
|
||||
* integer libraries and so on. But for most developers its likely
|
||||
* useful just for programming sanity.
|
||||
*
|
||||
* The problem is that most compiler vendors have decided not to
|
||||
* implement the C99 standard, and the next C++ language standard
|
||||
* (which has a lot more mindshare these days) will be a long time in
|
||||
* coming and its unknown whether or not it will include stdint.h or
|
||||
* how much adoption it will have. Either way, it will be a long time
|
||||
* before all compilers come with a stdint.h and it also does nothing
|
||||
* for the extremely large number of compilers available today which
|
||||
* do not include this file, or anything comparable to it.
|
||||
*
|
||||
* So that's what this file is all about. Its an attempt to build a
|
||||
* single universal include file that works on as many platforms as
|
||||
* possible to deliver what stdint.h is supposed to. A few things
|
||||
* that should be noted about this file:
|
||||
*
|
||||
* 1) It is not guaranteed to be portable and/or present an identical
|
||||
* interface on all platforms. The extreme variability of the
|
||||
* ANSI C standard makes this an impossibility right from the
|
||||
* very get go. Its really only meant to be useful for the vast
|
||||
* majority of platforms that possess the capability of
|
||||
* implementing usefully and precisely defined, standard sized
|
||||
* integer scalars. Systems which are not intrinsically 2s
|
||||
* complement may produce invalid constants.
|
||||
*
|
||||
* 2) There is an unavoidable use of non-reserved symbols.
|
||||
*
|
||||
* 3) Other standard include files are invoked.
|
||||
*
|
||||
* 4) This file may come in conflict with future platforms that do
|
||||
* include stdint.h. The hope is that one or the other can be
|
||||
* used with no real difference.
|
||||
*
|
||||
* 5) In the current verison, if your platform can't represent
|
||||
* int32_t, int16_t and int8_t, it just dumps out with a compiler
|
||||
* error.
|
||||
*
|
||||
* 6) 64 bit integers may or may not be defined. Test for their
|
||||
* presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
|
||||
* Note that this is different from the C99 specification which
|
||||
* requires the existence of 64 bit support in the compiler. If
|
||||
* this is not defined for your platform, yet it is capable of
|
||||
* dealing with 64 bits then it is because this file has not yet
|
||||
* been extended to cover all of your system's capabilities.
|
||||
*
|
||||
* 7) (u)intptr_t may or may not be defined. Test for its presence
|
||||
* with the test: #ifdef PTRDIFF_MAX. If this is not defined
|
||||
* for your platform, then it is because this file has not yet
|
||||
* been extended to cover all of your system's capabilities, not
|
||||
* because its optional.
|
||||
*
|
||||
* 8) The following might not been defined even if your platform is
|
||||
* capable of defining it:
|
||||
*
|
||||
* WCHAR_MIN
|
||||
* WCHAR_MAX
|
||||
* (u)int64_t
|
||||
* PTRDIFF_MIN
|
||||
* PTRDIFF_MAX
|
||||
* (u)intptr_t
|
||||
*
|
||||
* 9) The following have not been defined:
|
||||
*
|
||||
* WINT_MIN
|
||||
* WINT_MAX
|
||||
*
|
||||
* 10) The criteria for defining (u)int_least(*)_t isn't clear,
|
||||
* except for systems which don't have a type that precisely
|
||||
* defined 8, 16, or 32 bit types (which this include file does
|
||||
* not support anyways). Default definitions have been given.
|
||||
*
|
||||
* 11) The criteria for defining (u)int_fast(*)_t isn't something I
|
||||
* would trust to any particular compiler vendor or the ANSI C
|
||||
* committee. It is well known that "compatible systems" are
|
||||
* commonly created that have very different performance
|
||||
* characteristics from the systems they are compatible with,
|
||||
* especially those whose vendors make both the compiler and the
|
||||
* system. Default definitions have been given, but its strongly
|
||||
* recommended that users never use these definitions for any
|
||||
* reason (they do *NOT* deliver any serious guarantee of
|
||||
* improved performance -- not in this file, nor any vendor's
|
||||
* stdint.h).
|
||||
*
|
||||
* 12) The following macros:
|
||||
*
|
||||
* PRINTF_INTMAX_MODIFIER
|
||||
* PRINTF_INT64_MODIFIER
|
||||
* PRINTF_INT32_MODIFIER
|
||||
* PRINTF_INT16_MODIFIER
|
||||
* PRINTF_LEAST64_MODIFIER
|
||||
* PRINTF_LEAST32_MODIFIER
|
||||
* PRINTF_LEAST16_MODIFIER
|
||||
* PRINTF_INTPTR_MODIFIER
|
||||
*
|
||||
* are strings which have been defined as the modifiers required
|
||||
* for the "d", "u" and "x" printf formats to correctly output
|
||||
* (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
|
||||
* (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
|
||||
* PRINTF_INTPTR_MODIFIER is not defined for some systems which
|
||||
* provide their own stdint.h. PRINTF_INT64_MODIFIER is not
|
||||
* defined if INT64_MAX is not defined. These are an extension
|
||||
* beyond what C99 specifies must be in stdint.h.
|
||||
*
|
||||
* In addition, the following macros are defined:
|
||||
*
|
||||
* PRINTF_INTMAX_HEX_WIDTH
|
||||
* PRINTF_INT64_HEX_WIDTH
|
||||
* PRINTF_INT32_HEX_WIDTH
|
||||
* PRINTF_INT16_HEX_WIDTH
|
||||
* PRINTF_INT8_HEX_WIDTH
|
||||
* PRINTF_INTMAX_DEC_WIDTH
|
||||
* PRINTF_INT64_DEC_WIDTH
|
||||
* PRINTF_INT32_DEC_WIDTH
|
||||
* PRINTF_INT16_DEC_WIDTH
|
||||
* PRINTF_INT8_DEC_WIDTH
|
||||
*
|
||||
* Which specifies the maximum number of characters required to
|
||||
* print the number of that type in either hexadecimal or decimal.
|
||||
* These are an extension beyond what C99 specifies must be in
|
||||
* stdint.h.
|
||||
*
|
||||
* Compilers tested (all with 0 warnings at their highest respective
|
||||
* settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
|
||||
* bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
|
||||
* .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
|
||||
*
|
||||
* This file should be considered a work in progress. Suggestions for
|
||||
* improvements, especially those which increase coverage are strongly
|
||||
* encouraged.
|
||||
*
|
||||
* Acknowledgements
|
||||
*
|
||||
* The following people have made significant contributions to the
|
||||
* development and testing of this file:
|
||||
*
|
||||
* Chris Howie
|
||||
* John Steele Scott
|
||||
* Dave Thorup
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
|
||||
/*
|
||||
* For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
|
||||
* do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
|
||||
*/
|
||||
|
||||
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) )) && !defined (_PSTDINT_H_INCLUDED)
|
||||
#include <stdint.h>
|
||||
#define _PSTDINT_H_INCLUDED
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER "l"
|
||||
# endif
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER "h"
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_MODIFIER
|
||||
# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
|
||||
# endif
|
||||
# ifndef PRINTF_INT64_HEX_WIDTH
|
||||
# define PRINTF_INT64_HEX_WIDTH "16"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_HEX_WIDTH
|
||||
# define PRINTF_INT32_HEX_WIDTH "8"
|
||||
# endif
|
||||
# ifndef PRINTF_INT16_HEX_WIDTH
|
||||
# define PRINTF_INT16_HEX_WIDTH "4"
|
||||
# endif
|
||||
# ifndef PRINTF_INT8_HEX_WIDTH
|
||||
# define PRINTF_INT8_HEX_WIDTH "2"
|
||||
# endif
|
||||
# ifndef PRINTF_INT64_DEC_WIDTH
|
||||
# define PRINTF_INT64_DEC_WIDTH "20"
|
||||
# endif
|
||||
# ifndef PRINTF_INT32_DEC_WIDTH
|
||||
# define PRINTF_INT32_DEC_WIDTH "10"
|
||||
# endif
|
||||
# ifndef PRINTF_INT16_DEC_WIDTH
|
||||
# define PRINTF_INT16_DEC_WIDTH "5"
|
||||
# endif
|
||||
# ifndef PRINTF_INT8_DEC_WIDTH
|
||||
# define PRINTF_INT8_DEC_WIDTH "3"
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_HEX_WIDTH
|
||||
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_DEC_WIDTH
|
||||
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Something really weird is going on with Open Watcom. Just pull some of
|
||||
* these duplicated definitions from Open Watcom's stdint.h file for now.
|
||||
*/
|
||||
|
||||
# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
|
||||
# if !defined (INT64_C)
|
||||
# define INT64_C(x) (x + (INT64_MAX - INT64_MAX))
|
||||
# endif
|
||||
# if !defined (UINT64_C)
|
||||
# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
|
||||
# endif
|
||||
# if !defined (INT32_C)
|
||||
# define INT32_C(x) (x + (INT32_MAX - INT32_MAX))
|
||||
# endif
|
||||
# if !defined (UINT32_C)
|
||||
# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX))
|
||||
# endif
|
||||
# if !defined (INT16_C)
|
||||
# define INT16_C(x) (x)
|
||||
# endif
|
||||
# if !defined (UINT16_C)
|
||||
# define UINT16_C(x) (x)
|
||||
# endif
|
||||
# if !defined (INT8_C)
|
||||
# define INT8_C(x) (x)
|
||||
# endif
|
||||
# if !defined (UINT8_C)
|
||||
# define UINT8_C(x) (x)
|
||||
# endif
|
||||
# if !defined (UINT64_MAX)
|
||||
# define UINT64_MAX 18446744073709551615ULL
|
||||
# endif
|
||||
# if !defined (INT64_MAX)
|
||||
# define INT64_MAX 9223372036854775807LL
|
||||
# endif
|
||||
# if !defined (UINT32_MAX)
|
||||
# define UINT32_MAX 4294967295UL
|
||||
# endif
|
||||
# if !defined (INT32_MAX)
|
||||
# define INT32_MAX 2147483647L
|
||||
# endif
|
||||
# if !defined (INTMAX_MAX)
|
||||
# define INTMAX_MAX INT64_MAX
|
||||
# endif
|
||||
# if !defined (INTMAX_MIN)
|
||||
# define INTMAX_MIN INT64_MIN
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef _PSTDINT_H_INCLUDED
|
||||
#define _PSTDINT_H_INCLUDED
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX (~(size_t)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Deduce the type assignments from limits.h under the assumption that
|
||||
* integer sizes in bits are powers of 2, and follow the ANSI
|
||||
* definitions.
|
||||
*/
|
||||
|
||||
#ifndef UINT8_MAX
|
||||
# define UINT8_MAX 0xff
|
||||
#endif
|
||||
#ifndef uint8_t
|
||||
# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
|
||||
typedef unsigned char uint8_t;
|
||||
# define UINT8_C(v) ((uint8_t) v)
|
||||
# else
|
||||
# error "Platform not supported"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INT8_MAX
|
||||
# define INT8_MAX 0x7f
|
||||
#endif
|
||||
#ifndef INT8_MIN
|
||||
# define INT8_MIN INT8_C(0x80)
|
||||
#endif
|
||||
#ifndef int8_t
|
||||
# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
|
||||
typedef signed char int8_t;
|
||||
# define INT8_C(v) ((int8_t) v)
|
||||
# else
|
||||
# error "Platform not supported"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef UINT16_MAX
|
||||
# define UINT16_MAX 0xffff
|
||||
#endif
|
||||
#ifndef uint16_t
|
||||
#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
|
||||
typedef unsigned int uint16_t;
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER ""
|
||||
# endif
|
||||
# define UINT16_C(v) ((uint16_t) (v))
|
||||
#elif (USHRT_MAX == UINT16_MAX)
|
||||
typedef unsigned short uint16_t;
|
||||
# define UINT16_C(v) ((uint16_t) (v))
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER "h"
|
||||
# endif
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MAX
|
||||
# define INT16_MAX 0x7fff
|
||||
#endif
|
||||
#ifndef INT16_MIN
|
||||
# define INT16_MIN INT16_C(0x8000)
|
||||
#endif
|
||||
#ifndef int16_t
|
||||
#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
|
||||
typedef signed int int16_t;
|
||||
# define INT16_C(v) ((int16_t) (v))
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER ""
|
||||
# endif
|
||||
#elif (SHRT_MAX == INT16_MAX)
|
||||
typedef signed short int16_t;
|
||||
# define INT16_C(v) ((int16_t) (v))
|
||||
# ifndef PRINTF_INT16_MODIFIER
|
||||
# define PRINTF_INT16_MODIFIER "h"
|
||||
# endif
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
# define UINT32_MAX (0xffffffffUL)
|
||||
#endif
|
||||
#ifndef uint32_t
|
||||
#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
|
||||
typedef unsigned long uint32_t;
|
||||
# define UINT32_C(v) v ## UL
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER "l"
|
||||
# endif
|
||||
#elif (UINT_MAX == UINT32_MAX)
|
||||
typedef unsigned int uint32_t;
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
# define UINT32_C(v) v ## U
|
||||
#elif (USHRT_MAX == UINT32_MAX)
|
||||
typedef unsigned short uint32_t;
|
||||
# define UINT32_C(v) ((unsigned short) (v))
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MAX
|
||||
# define INT32_MAX (0x7fffffffL)
|
||||
#endif
|
||||
#ifndef INT32_MIN
|
||||
# define INT32_MIN INT32_C(0x80000000)
|
||||
#endif
|
||||
#ifndef int32_t
|
||||
#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
|
||||
typedef signed long int32_t;
|
||||
# define INT32_C(v) v ## L
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER "l"
|
||||
# endif
|
||||
#elif (INT_MAX == INT32_MAX)
|
||||
typedef signed int int32_t;
|
||||
# define INT32_C(v) v
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
#elif (SHRT_MAX == INT32_MAX)
|
||||
typedef signed short int32_t;
|
||||
# define INT32_C(v) ((short) (v))
|
||||
# ifndef PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_INT32_MODIFIER ""
|
||||
# endif
|
||||
#else
|
||||
#error "Platform not supported"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The macro stdint_int64_defined is temporarily used to record
|
||||
* whether or not 64 integer support is available. It must be
|
||||
* defined for any 64 integer extensions for new platforms that are
|
||||
* added.
|
||||
*/
|
||||
|
||||
#undef stdint_int64_defined
|
||||
#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
|
||||
# if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S)
|
||||
# define stdint_int64_defined
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
# define UINT64_C(v) v ## ULL
|
||||
# define INT64_C(v) v ## LL
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined (stdint_int64_defined)
|
||||
# if defined(__GNUC__)
|
||||
# define stdint_int64_defined
|
||||
__extension__ typedef long long int64_t;
|
||||
__extension__ typedef unsigned long long uint64_t;
|
||||
# define UINT64_C(v) v ## ULL
|
||||
# define INT64_C(v) v ## LL
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
|
||||
# define stdint_int64_defined
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
# define UINT64_C(v) v ## ULL
|
||||
# define INT64_C(v) v ## LL
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "ll"
|
||||
# endif
|
||||
# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
|
||||
# define stdint_int64_defined
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# define UINT64_C(v) v ## UI64
|
||||
# define INT64_C(v) v ## I64
|
||||
# ifndef PRINTF_INT64_MODIFIER
|
||||
# define PRINTF_INT64_MODIFIER "I64"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined (LONG_LONG_MAX) && defined (INT64_C)
|
||||
# define LONG_LONG_MAX INT64_C (9223372036854775807)
|
||||
#endif
|
||||
#ifndef ULONG_LONG_MAX
|
||||
# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
|
||||
#endif
|
||||
|
||||
#if !defined (INT64_MAX) && defined (INT64_C)
|
||||
# define INT64_MAX INT64_C (9223372036854775807)
|
||||
#endif
|
||||
#if !defined (INT64_MIN) && defined (INT64_C)
|
||||
# define INT64_MIN INT64_C (-9223372036854775808)
|
||||
#endif
|
||||
#if !defined (UINT64_MAX) && defined (INT64_C)
|
||||
# define UINT64_MAX UINT64_C (18446744073709551615)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Width of hexadecimal for number field.
|
||||
*/
|
||||
|
||||
#ifndef PRINTF_INT64_HEX_WIDTH
|
||||
# define PRINTF_INT64_HEX_WIDTH "16"
|
||||
#endif
|
||||
#ifndef PRINTF_INT32_HEX_WIDTH
|
||||
# define PRINTF_INT32_HEX_WIDTH "8"
|
||||
#endif
|
||||
#ifndef PRINTF_INT16_HEX_WIDTH
|
||||
# define PRINTF_INT16_HEX_WIDTH "4"
|
||||
#endif
|
||||
#ifndef PRINTF_INT8_HEX_WIDTH
|
||||
# define PRINTF_INT8_HEX_WIDTH "2"
|
||||
#endif
|
||||
|
||||
#ifndef PRINTF_INT64_DEC_WIDTH
|
||||
# define PRINTF_INT64_DEC_WIDTH "20"
|
||||
#endif
|
||||
#ifndef PRINTF_INT32_DEC_WIDTH
|
||||
# define PRINTF_INT32_DEC_WIDTH "10"
|
||||
#endif
|
||||
#ifndef PRINTF_INT16_DEC_WIDTH
|
||||
# define PRINTF_INT16_DEC_WIDTH "5"
|
||||
#endif
|
||||
#ifndef PRINTF_INT8_DEC_WIDTH
|
||||
# define PRINTF_INT8_DEC_WIDTH "3"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ok, lets not worry about 128 bit integers for now. Moore's law says
|
||||
* we don't need to worry about that until about 2040 at which point
|
||||
* we'll have bigger things to worry about.
|
||||
*/
|
||||
|
||||
#ifdef stdint_int64_defined
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
# define INTMAX_MAX INT64_MAX
|
||||
# define INTMAX_MIN INT64_MIN
|
||||
# define UINTMAX_MAX UINT64_MAX
|
||||
# define UINTMAX_C(v) UINT64_C(v)
|
||||
# define INTMAX_C(v) INT64_C(v)
|
||||
# ifndef PRINTF_INTMAX_MODIFIER
|
||||
# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_HEX_WIDTH
|
||||
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_DEC_WIDTH
|
||||
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
|
||||
# endif
|
||||
#else
|
||||
typedef int32_t intmax_t;
|
||||
typedef uint32_t uintmax_t;
|
||||
# define INTMAX_MAX INT32_MAX
|
||||
# define UINTMAX_MAX UINT32_MAX
|
||||
# define UINTMAX_C(v) UINT32_C(v)
|
||||
# define INTMAX_C(v) INT32_C(v)
|
||||
# ifndef PRINTF_INTMAX_MODIFIER
|
||||
# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_HEX_WIDTH
|
||||
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
|
||||
# endif
|
||||
# ifndef PRINTF_INTMAX_DEC_WIDTH
|
||||
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Because this file currently only supports platforms which have
|
||||
* precise powers of 2 as bit sizes for the default integers, the
|
||||
* least definitions are all trivial. Its possible that a future
|
||||
* version of this file could have different definitions.
|
||||
*/
|
||||
|
||||
#ifndef stdint_least_defined
|
||||
typedef int8_t int_least8_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
|
||||
# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
|
||||
# define UINT_LEAST8_MAX UINT8_MAX
|
||||
# define INT_LEAST8_MAX INT8_MAX
|
||||
# define UINT_LEAST16_MAX UINT16_MAX
|
||||
# define INT_LEAST16_MAX INT16_MAX
|
||||
# define UINT_LEAST32_MAX UINT32_MAX
|
||||
# define INT_LEAST32_MAX INT32_MAX
|
||||
# define INT_LEAST8_MIN INT8_MIN
|
||||
# define INT_LEAST16_MIN INT16_MIN
|
||||
# define INT_LEAST32_MIN INT32_MIN
|
||||
# ifdef stdint_int64_defined
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
|
||||
# define UINT_LEAST64_MAX UINT64_MAX
|
||||
# define INT_LEAST64_MAX INT64_MAX
|
||||
# define INT_LEAST64_MIN INT64_MIN
|
||||
# endif
|
||||
#endif
|
||||
#undef stdint_least_defined
|
||||
|
||||
/*
|
||||
* The ANSI C committee pretending to know or specify anything about
|
||||
* performance is the epitome of misguided arrogance. The mandate of
|
||||
* this file is to *ONLY* ever support that absolute minimum
|
||||
* definition of the fast integer types, for compatibility purposes.
|
||||
* No extensions, and no attempt to suggest what may or may not be a
|
||||
* faster integer type will ever be made in this file. Developers are
|
||||
* warned to stay away from these types when using this or any other
|
||||
* stdint.h.
|
||||
*/
|
||||
|
||||
typedef int_least8_t int_fast8_t;
|
||||
typedef uint_least8_t uint_fast8_t;
|
||||
typedef int_least16_t int_fast16_t;
|
||||
typedef uint_least16_t uint_fast16_t;
|
||||
typedef int_least32_t int_fast32_t;
|
||||
typedef uint_least32_t uint_fast32_t;
|
||||
#define UINT_FAST8_MAX UINT_LEAST8_MAX
|
||||
#define INT_FAST8_MAX INT_LEAST8_MAX
|
||||
#define UINT_FAST16_MAX UINT_LEAST16_MAX
|
||||
#define INT_FAST16_MAX INT_LEAST16_MAX
|
||||
#define UINT_FAST32_MAX UINT_LEAST32_MAX
|
||||
#define INT_FAST32_MAX INT_LEAST32_MAX
|
||||
#define INT_FAST8_MIN INT_LEAST8_MIN
|
||||
#define INT_FAST16_MIN INT_LEAST16_MIN
|
||||
#define INT_FAST32_MIN INT_LEAST32_MIN
|
||||
#ifdef stdint_int64_defined
|
||||
typedef int_least64_t int_fast64_t;
|
||||
typedef uint_least64_t uint_fast64_t;
|
||||
# define UINT_FAST64_MAX UINT_LEAST64_MAX
|
||||
# define INT_FAST64_MAX INT_LEAST64_MAX
|
||||
# define INT_FAST64_MIN INT_LEAST64_MIN
|
||||
#endif
|
||||
|
||||
#undef stdint_int64_defined
|
||||
|
||||
/*
|
||||
* Whatever piecemeal, per compiler thing we can do about the wchar_t
|
||||
* type limits.
|
||||
*/
|
||||
|
||||
#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__)
|
||||
# include <wchar.h>
|
||||
# ifndef WCHAR_MIN
|
||||
# define WCHAR_MIN 0
|
||||
# endif
|
||||
# ifndef WCHAR_MAX
|
||||
# define WCHAR_MAX ((wchar_t)-1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Whatever piecemeal, per compiler/platform thing we can do about the
|
||||
* (u)intptr_t types and limits.
|
||||
*/
|
||||
|
||||
#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)
|
||||
# define STDINT_H_UINTPTR_T_DEFINED
|
||||
#endif
|
||||
|
||||
#ifndef STDINT_H_UINTPTR_T_DEFINED
|
||||
# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64)
|
||||
# define stdint_intptr_bits 64
|
||||
# elif defined (__WATCOMC__) || defined (__TURBOC__)
|
||||
# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
|
||||
# define stdint_intptr_bits 16
|
||||
# else
|
||||
# define stdint_intptr_bits 32
|
||||
# endif
|
||||
# elif defined (__i386__) || defined (_WIN32) || defined (WIN32)
|
||||
# define stdint_intptr_bits 32
|
||||
# elif defined (__INTEL_COMPILER)
|
||||
/* TODO -- what will Intel do about x86-64? */
|
||||
# endif
|
||||
|
||||
# ifdef stdint_intptr_bits
|
||||
# define stdint_intptr_glue3_i(a,b,c) a##b##c
|
||||
# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c)
|
||||
# ifndef PRINTF_INTPTR_MODIFIER
|
||||
# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
|
||||
# endif
|
||||
# ifndef PTRDIFF_MAX
|
||||
# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
|
||||
# endif
|
||||
# ifndef PTRDIFF_MIN
|
||||
# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
|
||||
# endif
|
||||
# ifndef UINTPTR_MAX
|
||||
# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
|
||||
# endif
|
||||
# ifndef INTPTR_MAX
|
||||
# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
|
||||
# endif
|
||||
# ifndef INTPTR_MIN
|
||||
# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
|
||||
# endif
|
||||
# ifndef INTPTR_C
|
||||
# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
|
||||
# endif
|
||||
# ifndef UINTPTR_C
|
||||
# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
|
||||
# endif
|
||||
typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
|
||||
typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t;
|
||||
# else
|
||||
/* TODO -- This following is likely wrong for some platforms, and does
|
||||
nothing for the definition of uintptr_t. */
|
||||
typedef ptrdiff_t intptr_t;
|
||||
# endif
|
||||
# define STDINT_H_UINTPTR_T_DEFINED
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assumes sig_atomic_t is signed and we have a 2s complement machine.
|
||||
*/
|
||||
|
||||
#ifndef SIG_ATOMIC_MAX
|
||||
# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,3 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
add_subdirectory(src)
|
||||
@@ -1,15 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
|
||||
win32: CONFIG += console
|
||||
mac:CONFIG -= app_bundle
|
||||
|
||||
CONFIG += qtestlib
|
||||
|
||||
include(../../src/src.pri)
|
||||
|
||||
# Input
|
||||
SOURCES += tst_trie.cpp
|
||||
HEADERS +=
|
||||
@@ -1,270 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <trie_p.h>
|
||||
|
||||
class tst_Trie : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
private slots:
|
||||
void trie_data();
|
||||
void trie();
|
||||
|
||||
void insert_data();
|
||||
void insert();
|
||||
void clear();
|
||||
void find_data();
|
||||
void find();
|
||||
void remove_data();
|
||||
void remove();
|
||||
void all();
|
||||
};
|
||||
|
||||
// Subclass that exposes the protected functions.
|
||||
class SubTrie : public Trie<int>
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
// This will be called before the first test function is executed.
|
||||
// It is only called once.
|
||||
void tst_Trie::initTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
// This will be called after the last test function is executed.
|
||||
// It is only called once.
|
||||
void tst_Trie::cleanupTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
// This will be called before each test function is executed.
|
||||
void tst_Trie::init()
|
||||
{
|
||||
}
|
||||
|
||||
// This will be called after every test function.
|
||||
void tst_Trie::cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_Trie::trie_data()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_Trie::trie()
|
||||
{
|
||||
SubTrie t;
|
||||
t.clear();
|
||||
QCOMPARE(t.find(QStringList()), QList<int>());
|
||||
QCOMPARE(t.remove(QStringList(), -1), false);
|
||||
QCOMPARE(t.all(), QList<int>());
|
||||
t.insert(QStringList(), -1);
|
||||
}
|
||||
|
||||
void tst_Trie::insert_data()
|
||||
{
|
||||
#if 0
|
||||
QTest::addColumn<QStringList>("key");
|
||||
QTest::addColumn<T>("value");
|
||||
QTest::newRow("null") << QStringList() << T();
|
||||
#endif
|
||||
}
|
||||
|
||||
// public void insert(QStringList const& key, T value)
|
||||
void tst_Trie::insert()
|
||||
{
|
||||
#if 0
|
||||
QFETCH(QStringList, key);
|
||||
QFETCH(T, value);
|
||||
|
||||
SubTrie<T> t>;
|
||||
|
||||
t>.insert(key, value);
|
||||
#endif
|
||||
QSKIP("Test is not implemented.", SkipAll);
|
||||
}
|
||||
|
||||
// public void clear()
|
||||
void tst_Trie::clear()
|
||||
{
|
||||
SubTrie t;
|
||||
t.insert(QStringList(), 0);
|
||||
t.clear();
|
||||
QCOMPARE(t.find(QStringList()), QList<int>());
|
||||
QCOMPARE(t.all(), QList<int>());
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QStringList)
|
||||
typedef QList<int> IntList;
|
||||
Q_DECLARE_METATYPE(IntList)
|
||||
void tst_Trie::find_data()
|
||||
{
|
||||
QTest::addColumn<QStringList>("keys");
|
||||
QTest::addColumn<IntList>("values");
|
||||
QTest::addColumn<QStringList>("find");
|
||||
QTest::addColumn<IntList>("found");
|
||||
|
||||
QTest::newRow("null") << QStringList() << IntList() << QStringList() << IntList();
|
||||
|
||||
QStringList wiki = (QStringList() << "t,e,a" << "i" << "t,e,n" << "i,n" << "i,n,n" << "t,o");
|
||||
IntList wikiNum = (IntList() << 3 << 11 << 12 << 5 << 9 << 7);
|
||||
|
||||
QTest::newRow("wikipedia-0")
|
||||
<< wiki
|
||||
<< wikiNum
|
||||
<< (QStringList() << "t")
|
||||
<< (IntList());
|
||||
|
||||
QTest::newRow("wikipedia-1")
|
||||
<< wiki
|
||||
<< wikiNum
|
||||
<< (QStringList() << "t" << "o")
|
||||
<< (IntList() << 7);
|
||||
|
||||
QTest::newRow("wikipedia-2")
|
||||
<< (wiki << "t,o")
|
||||
<< (wikiNum << 4)
|
||||
<< (QStringList() << "t" << "o")
|
||||
<< (IntList() << 7 << 4);
|
||||
|
||||
QTest::newRow("wikipedia-3")
|
||||
<< wiki
|
||||
<< wikiNum
|
||||
<< (QStringList() << "i" << "n" << "n")
|
||||
<< (IntList() << 9);
|
||||
|
||||
}
|
||||
|
||||
// public QList<T> const find(QStringList const& key)
|
||||
void tst_Trie::find()
|
||||
{
|
||||
QFETCH(QStringList, keys);
|
||||
QFETCH(IntList, values);
|
||||
QFETCH(QStringList, find);
|
||||
QFETCH(IntList, found);
|
||||
|
||||
SubTrie t;
|
||||
for (int i = 0; i < keys.count(); ++i)
|
||||
t.insert(keys[i].split(","), values[i]);
|
||||
QCOMPARE(t.all(), values);
|
||||
QCOMPARE(t.find(find), found);
|
||||
}
|
||||
|
||||
void tst_Trie::remove_data()
|
||||
{
|
||||
QTest::addColumn<QStringList>("keys");
|
||||
QTest::addColumn<IntList>("values");
|
||||
QTest::addColumn<QStringList>("removeKey");
|
||||
QTest::addColumn<int>("removeValue");
|
||||
QTest::addColumn<bool>("removed");
|
||||
|
||||
QTest::newRow("null") << QStringList() << IntList() << QStringList() << -1 << false;
|
||||
|
||||
QStringList wiki = (QStringList() << "t,e,a" << "i" << "t,e,n" << "i,n" << "i,n,n" << "t,o");
|
||||
IntList wikiNum = (IntList() << 3 << 11 << 12 << 5 << 9 << 7);
|
||||
|
||||
QTest::newRow("valid key-0")
|
||||
<< wiki
|
||||
<< wikiNum
|
||||
<< (QStringList() << "t")
|
||||
<< -1
|
||||
<< false;
|
||||
|
||||
QTest::newRow("valid key-1")
|
||||
<< wiki
|
||||
<< wikiNum
|
||||
<< (QStringList() << "t" << "o")
|
||||
<< -1
|
||||
<< false;
|
||||
|
||||
QTest::newRow("valid key-2")
|
||||
<< wiki
|
||||
<< wikiNum
|
||||
<< (QStringList() << "t" << "o" << "w")
|
||||
<< 2
|
||||
<< false;
|
||||
|
||||
QTest::newRow("valid key-3")
|
||||
<< wiki
|
||||
<< wikiNum
|
||||
<< (QStringList() << "t" << "o")
|
||||
<< 7
|
||||
<< true;
|
||||
|
||||
QTest::newRow("valid key-4")
|
||||
<< wiki
|
||||
<< wikiNum
|
||||
<< (QStringList() << "i" << "n")
|
||||
<< 3
|
||||
<< false;
|
||||
|
||||
QTest::newRow("valid key-5")
|
||||
<< wiki
|
||||
<< wikiNum
|
||||
<< (QStringList() << "i" << "n")
|
||||
<< 5
|
||||
<< true;
|
||||
|
||||
}
|
||||
|
||||
// public bool remove(QStringList const& key, T value)
|
||||
void tst_Trie::remove()
|
||||
{
|
||||
QFETCH(QStringList, keys);
|
||||
QFETCH(IntList, values);
|
||||
QFETCH(QStringList, removeKey);
|
||||
QFETCH(int, removeValue);
|
||||
QFETCH(bool, removed);
|
||||
|
||||
SubTrie t;
|
||||
for (int i = 0; i < keys.count(); ++i)
|
||||
t.insert(keys[i].split(","), values[i]);
|
||||
QCOMPARE(t.all(), values);
|
||||
QCOMPARE(t.remove(removeKey, removeValue), removed);
|
||||
if (removed)
|
||||
values.removeOne(removeValue);
|
||||
QCOMPARE(t.all(), values);
|
||||
}
|
||||
|
||||
void tst_Trie::all()
|
||||
{
|
||||
SubTrie t;
|
||||
// hmm everyone else tests this it seems
|
||||
QSKIP("Test is not implemented.", SkipAll);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_Trie)
|
||||
#include "tst_trie.moc"
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
|
||||
win32: CONFIG += console
|
||||
mac:CONFIG -= app_bundle
|
||||
|
||||
CONFIG += qtestlib
|
||||
|
||||
include(../../src/src.pri)
|
||||
#include(../../../dev/code/webweaver/src/iris.pri)
|
||||
#include(../../../dev/arora/src/src.pri)
|
||||
|
||||
# Input
|
||||
SOURCES += main.cpp
|
||||
HEADERS +=
|
||||
@@ -1,159 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtNetwork/QtNetwork>
|
||||
#include <networkcookiejar.h>
|
||||
|
||||
class CookieJarBenchmark: public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void setCookiesFromUrl();
|
||||
void cookiesForUrl();
|
||||
void player();
|
||||
|
||||
private:
|
||||
QNetworkCookieJar *getJar(bool populate = true);
|
||||
QList<QNetworkCookie> generateCookies(int size);
|
||||
};
|
||||
|
||||
QNetworkCookieJar *CookieJarBenchmark::getJar(bool populate)
|
||||
{
|
||||
QNetworkCookieJar *jar;
|
||||
if (qgetenv("JAR") == "CookieJar") {
|
||||
jar = new NetworkCookieJar(this);
|
||||
} else {
|
||||
jar = new QNetworkCookieJar(this);
|
||||
}
|
||||
if (!populate)
|
||||
return jar;
|
||||
|
||||
// pre populate
|
||||
for (int i = 0; i < 500; ++i) {
|
||||
QList<QNetworkCookie> cookies = generateCookies(1);
|
||||
QUrl url = QUrl(QString("http://%1").arg(cookies[0].domain()));
|
||||
jar->setCookiesFromUrl(cookies, url);
|
||||
}
|
||||
|
||||
return jar;
|
||||
}
|
||||
|
||||
QList<QNetworkCookie> CookieJarBenchmark::generateCookies(int size)
|
||||
{
|
||||
QList<QNetworkCookie> cookies;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
QNetworkCookie cookie;
|
||||
|
||||
QString tld;
|
||||
int c = qrand() % 3;
|
||||
if (c == 0) tld = "com";
|
||||
if (c == 1) tld = "net";
|
||||
if (c == 2) tld = "org";
|
||||
|
||||
QString mid;
|
||||
int size = qrand() % 6 + 3;
|
||||
while (mid.count() < size)
|
||||
mid += QString(QChar::fromAscii(qrand() % 26 + 65));
|
||||
|
||||
QString sub;
|
||||
c = qrand() % 3;
|
||||
if (c == 0) sub = ".";
|
||||
if (c == 1) sub = ".www.";
|
||||
if (c == 2) sub = ".foo";
|
||||
|
||||
cookie.setDomain(QString("%1%2.%3").arg(sub).arg(mid).arg(tld));
|
||||
cookie.setName("a");
|
||||
cookie.setValue("b");
|
||||
cookie.setPath("/");
|
||||
cookies.append(cookie);
|
||||
}
|
||||
return cookies;
|
||||
}
|
||||
|
||||
void CookieJarBenchmark::setCookiesFromUrl()
|
||||
{
|
||||
QNetworkCookieJar *jar = getJar();
|
||||
QList<QNetworkCookie> cookies = generateCookies(1);
|
||||
QUrl url = QUrl(QString("http://%1").arg(cookies[0].domain()));
|
||||
QBENCHMARK {
|
||||
jar->setCookiesFromUrl(cookies, url);
|
||||
}
|
||||
delete jar;
|
||||
}
|
||||
|
||||
void CookieJarBenchmark::cookiesForUrl()
|
||||
{
|
||||
QNetworkCookieJar *jar = getJar();
|
||||
QList<QNetworkCookie> cookies = generateCookies(1);
|
||||
cookies[0].setDomain("www.foo.tld");
|
||||
QUrl url = QUrl("http://www.foo.tld");
|
||||
//QUrl url = QUrl(QString("http://foo%1/").arg(cookies[0].domain()));
|
||||
jar->setCookiesFromUrl(cookies, url);
|
||||
//qDebug() << cookies << url;
|
||||
int c = 0;
|
||||
QBENCHMARK {
|
||||
c += jar->cookiesForUrl(url).count();
|
||||
}
|
||||
delete jar;
|
||||
}
|
||||
|
||||
// Grab the cookie.log file from the manualtest/browser directory
|
||||
void CookieJarBenchmark::player()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QFile file("cookie.log");
|
||||
file.open(QFile::ReadOnly);
|
||||
QDataStream stream(&file);
|
||||
QNetworkCookieJar *jar = getJar(false);
|
||||
while (!stream.atEnd()) {
|
||||
QString command;
|
||||
QUrl url;
|
||||
stream >> command;
|
||||
stream >> url;
|
||||
//qDebug() << command << url;
|
||||
if (command == "cookiesForUrl") {
|
||||
jar->cookiesForUrl(url);
|
||||
}
|
||||
if (command == "setCookiesFromUrl") {
|
||||
QByteArray data;
|
||||
stream >> data;
|
||||
QDataStream dstream(&data, QIODevice::ReadWrite);
|
||||
qint32 c;
|
||||
dstream >> c;
|
||||
QList<QNetworkCookie> cookies;
|
||||
for (int i = 0; i < c; ++i) {
|
||||
QByteArray text;
|
||||
dstream >> text;
|
||||
cookies += QNetworkCookie::parseCookies(text);
|
||||
}
|
||||
jar->setCookiesFromUrl(cookies, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(CookieJarBenchmark)
|
||||
#include "main.moc"
|
||||
@@ -1,11 +0,0 @@
|
||||
######################################################################
|
||||
# Automatically generated by qmake (2.01a) Wed Jan 7 13:19:00 2009
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
include(../../src/src.pri)
|
||||
# Input
|
||||
SOURCES += main.cpp
|
||||
@@ -1,85 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include <QtGui/QtGui>
|
||||
#include <QtWebKit/QtWebKit>
|
||||
#include <QtNetwork/QtNetwork>
|
||||
#include <networkcookiejar.h>
|
||||
|
||||
QFile file;
|
||||
QDataStream stream;
|
||||
|
||||
class CookieLog : public NetworkCookieJar {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CookieLog(QObject *parent = 0) : NetworkCookieJar(parent)
|
||||
{
|
||||
file.setFileName("cookie.log");
|
||||
file.open(QFile::WriteOnly);
|
||||
stream.setDevice(&file);
|
||||
};
|
||||
|
||||
virtual QList<QNetworkCookie> cookiesForUrl(const QUrl & url) const
|
||||
{
|
||||
stream << QString("cookiesForUrl") << url;
|
||||
QList<QNetworkCookie> cookies = NetworkCookieJar::cookiesForUrl(url);
|
||||
//stream << "#" << cookies;
|
||||
file.flush();
|
||||
return cookies;
|
||||
}
|
||||
|
||||
virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
|
||||
{
|
||||
QByteArray data;
|
||||
QDataStream dstream(&data, QIODevice::ReadWrite);
|
||||
qint32 c = cookieList.count();
|
||||
dstream << c;
|
||||
qDebug() << cookieList.count();
|
||||
for (int i = 0; i < c; ++i)
|
||||
dstream << cookieList[i].toRawForm();
|
||||
dstream.device()->close();
|
||||
stream << QString("setCookiesFromUrl") << url << data;// << cookieList;
|
||||
bool set = NetworkCookieJar::setCookiesFromUrl(cookieList, url);
|
||||
file.flush();
|
||||
return set;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main(int argc, char**argv) {
|
||||
QApplication application(argc, argv);
|
||||
QWebView view;
|
||||
QString url = "http://www.google.com";
|
||||
if (argc > 1)
|
||||
url = argv[1];
|
||||
view.load(QUrl(url));
|
||||
view.page()->networkAccessManager()->setCookieJar(new CookieLog());
|
||||
view.show();
|
||||
return application.exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
||||
@@ -1,12 +0,0 @@
|
||||
######################################################################
|
||||
# Automatically generated by qmake (2.01a) Wed Jan 7 13:19:00 2009
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
include(../../src/src.pri)
|
||||
DEFINES += QT_NO_CAST_FROM_ASCII QT_STRICT_ITERATOR
|
||||
# Input
|
||||
SOURCES += main.cpp
|
||||
@@ -1,100 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include <QtCore/QtCore>
|
||||
#include <trie_p.h>
|
||||
|
||||
QStringList generateKey() {
|
||||
QStringList key;
|
||||
int size = qrand() % 20 + 3;
|
||||
while (key.count() < size)
|
||||
key += QString(QChar::fromAscii(qrand() % 26 + 64));
|
||||
return key;
|
||||
}
|
||||
|
||||
void basicCheck() {
|
||||
QStringList list;
|
||||
list << QLatin1String("to") << QLatin1String("tea") << QLatin1String("ten") << QLatin1String("i") << QLatin1String("in") << QLatin1String("inn");
|
||||
Trie<int> trie;
|
||||
for (int i = 0; i < list.count(); ++i) {
|
||||
QString key = list[i];
|
||||
QStringList keyList;
|
||||
for (int j = 0; j < key.count(); ++j)
|
||||
keyList.append(QString(key[j]));
|
||||
trie.insert(keyList, i);
|
||||
}
|
||||
QByteArray data;
|
||||
{
|
||||
QDataStream stream(&data, QIODevice::ReadWrite);
|
||||
stream << trie;
|
||||
}
|
||||
Trie<int> trie2;
|
||||
{
|
||||
QDataStream stream(&data, QIODevice::ReadOnly);
|
||||
stream >> trie2;
|
||||
}
|
||||
for (int i = 0; i < list.count(); ++i) {
|
||||
QString key = list[i];
|
||||
QStringList keyList;
|
||||
for (int j = 0; j < key.count(); ++j)
|
||||
keyList.append(QString(key[j]));
|
||||
QList<int> x = trie2.find(keyList);
|
||||
qDebug() << x.count() << i << x[0] << i;
|
||||
qDebug() << trie2.remove(keyList, i);
|
||||
qDebug() << trie2.find(keyList).count();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Q_UNUSED(argc);
|
||||
Q_UNUSED(argv);
|
||||
|
||||
basicCheck();
|
||||
|
||||
QHash<QString, int> hash;
|
||||
Trie<int> t;
|
||||
while (hash.count() < 500) {
|
||||
qDebug() << hash.count();
|
||||
QStringList key = generateKey();
|
||||
int value = qrand() % 50000;
|
||||
hash[key.join(QLatin1String(","))] = value;
|
||||
t.insert(key, value);
|
||||
|
||||
QHashIterator<QString, int> i(hash);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (t.find(i.key().split(QLatin1Char(','))).count() == 0)
|
||||
qDebug() << i.key();
|
||||
Q_ASSERT(t.find(i.key().split(QLatin1Char(','))).count() > 0);
|
||||
if (qrand() % 500 == 0) {
|
||||
t.remove(i.key().split(QLatin1Char(',')), i.value());
|
||||
hash.remove(i.key());
|
||||
}
|
||||
//cout << i.key() << ": " << i.value() << endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
project(networkcookiejar)
|
||||
|
||||
set(networkcookiejar_SOURCE_FILES
|
||||
networkcookiejar.cpp
|
||||
)
|
||||
|
||||
set(networkcookiejar_HEADER_FILES
|
||||
networkcookiejar.h
|
||||
networkcookiejar_p.h
|
||||
trie_p.h
|
||||
twoleveldomains_p.h
|
||||
|
||||
)
|
||||
|
||||
QT4_WRAP_CPP(networkcookiejar_HEADERS_MOC ${networkcookiejar_HEADER_FILES})
|
||||
|
||||
add_library(networkcookiejar
|
||||
${networkcookiejar_SOURCE_FILES}
|
||||
${networkcookiejar_HEADERS_MOC}
|
||||
${networkcookiejar_UI_MOC}
|
||||
)
|
||||
|
||||
add_dependencies(networkcookiejar prepare)
|
||||
|
||||
target_link_libraries(networkcookiejar)
|
||||
@@ -1,444 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include "networkcookiejar.h"
|
||||
#include "networkcookiejar_p.h"
|
||||
#include "twoleveldomains_p.h"
|
||||
|
||||
//#define NETWORKCOOKIEJAR_DEBUG
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
// ^ Prevent being left on in a released product by accident
|
||||
// qDebug any cookies that are rejected for further inspection
|
||||
#define NETWORKCOOKIEJAR_LOGREJECTEDCOOKIES
|
||||
#include <qdebug.h>
|
||||
#endif
|
||||
|
||||
#include <qurl.h>
|
||||
#include <qdatetime.h>
|
||||
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
#include <qdebug.h>
|
||||
#endif
|
||||
|
||||
|
||||
NetworkCookieJar::NetworkCookieJar(QObject *parent)
|
||||
: QNetworkCookieJar(parent)
|
||||
{
|
||||
d = new NetworkCookieJarPrivate;
|
||||
}
|
||||
|
||||
NetworkCookieJar::~NetworkCookieJar()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
static QStringList splitHost(const QString &host) {
|
||||
QStringList parts = host.split(QLatin1Char('.'), QString::KeepEmptyParts);
|
||||
// Remove empty components that are on the start and end
|
||||
while (!parts.isEmpty() && parts.last().isEmpty())
|
||||
parts.removeLast();
|
||||
while (!parts.isEmpty() && parts.first().isEmpty())
|
||||
parts.removeFirst();
|
||||
return parts;
|
||||
}
|
||||
|
||||
inline static bool shorterPaths(const QNetworkCookie &c1, const QNetworkCookie &c2)
|
||||
{
|
||||
return c2.path().length() < c1.path().length();
|
||||
}
|
||||
|
||||
QList<QNetworkCookie> NetworkCookieJar::cookiesForUrl(const QUrl &url) const
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << url;
|
||||
#endif
|
||||
// Generate split host
|
||||
QString host = url.host();
|
||||
if (url.scheme().toLower() == QLatin1String("file"))
|
||||
host = QLatin1String("localhost");
|
||||
QStringList urlHost = splitHost(host);
|
||||
|
||||
// Get all the cookies for url
|
||||
QList<QNetworkCookie> cookies = d->tree.find(urlHost);
|
||||
if (urlHost.count() > 2) {
|
||||
int top = 2;
|
||||
if (d->matchesBlacklist(urlHost.last()))
|
||||
top = 3;
|
||||
|
||||
urlHost.removeFirst();
|
||||
while (urlHost.count() >= top) {
|
||||
cookies += d->tree.find(urlHost);
|
||||
urlHost.removeFirst();
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent doing anything expensive in the common case where
|
||||
// there are no cookies to check
|
||||
if (cookies.isEmpty())
|
||||
return cookies;
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime().toTimeSpec(Qt::UTC);
|
||||
const QString urlPath = d->urlPath(url);
|
||||
const bool isSecure = url.scheme().toLower() == QLatin1String("https");
|
||||
QList<QNetworkCookie>::iterator i = cookies.begin();
|
||||
for (; i != cookies.end();) {
|
||||
if (!d->matchingPath(*i, urlPath)) {
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << __FUNCTION__ << "Ignoring cookie, path does not match" << *i << urlPath;
|
||||
#endif
|
||||
i = cookies.erase(i);
|
||||
continue;
|
||||
}
|
||||
if (!isSecure && i->isSecure()) {
|
||||
i = cookies.erase(i);
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << __FUNCTION__ << "Ignoring cookie, security mismatch"
|
||||
<< *i << !isSecure;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if (!i->isSessionCookie() && now > i->expirationDate()) {
|
||||
// remove now (expensive short term) because there will
|
||||
// probably be many more cookiesForUrl calls for this host
|
||||
d->tree.remove(splitHost(i->domain()), *i);
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << __FUNCTION__ << "Ignoring cookie, expiration issue"
|
||||
<< *i << now;
|
||||
#endif
|
||||
i = cookies.erase(i);
|
||||
continue;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
// shorter paths should go first
|
||||
qSort(cookies.begin(), cookies.end(), shorterPaths);
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << "returning" << cookies.count();
|
||||
qDebug() << cookies;
|
||||
#endif
|
||||
return cookies;
|
||||
}
|
||||
|
||||
static const qint32 NetworkCookieJarMagic = 0xae;
|
||||
|
||||
QByteArray NetworkCookieJar::saveState () const
|
||||
{
|
||||
int version = 1;
|
||||
QByteArray data;
|
||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||
|
||||
stream << qint32(NetworkCookieJarMagic);
|
||||
stream << qint32(version);
|
||||
stream << d->tree;
|
||||
return data;
|
||||
}
|
||||
|
||||
bool NetworkCookieJar::restoreState(const QByteArray &state)
|
||||
{
|
||||
int version = 1;
|
||||
QByteArray sd = state;
|
||||
QDataStream stream(&sd, QIODevice::ReadOnly);
|
||||
if (stream.atEnd())
|
||||
return false;
|
||||
qint32 marker;
|
||||
qint32 v;
|
||||
stream >> marker;
|
||||
stream >> v;
|
||||
if (marker != NetworkCookieJarMagic || v != version)
|
||||
return false;
|
||||
stream >> d->tree;
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
d->tree.clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Remove any session cookies or cookies that have expired.
|
||||
*/
|
||||
void NetworkCookieJar::endSession()
|
||||
{
|
||||
const QList<QNetworkCookie> cookies = d->tree.all();
|
||||
QDateTime now = QDateTime::currentDateTime().toTimeSpec(Qt::UTC);
|
||||
QList<QNetworkCookie>::const_iterator i = cookies.constBegin();
|
||||
for (; i != cookies.constEnd();) {
|
||||
if (i->isSessionCookie()
|
||||
|| (!i->isSessionCookie() && now > i->expirationDate())) {
|
||||
d->tree.remove(splitHost(i->domain()), *i);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
static const int maxCookiePathLength = 1024;
|
||||
|
||||
bool NetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << url;
|
||||
qDebug() << cookieList;
|
||||
#endif
|
||||
QDateTime now = QDateTime::currentDateTime().toTimeSpec(Qt::UTC);
|
||||
bool changed = false;
|
||||
QString fullUrlPath = url.path();
|
||||
QString defaultPath = fullUrlPath.mid(0, fullUrlPath.lastIndexOf(QLatin1Char('/')) + 1);
|
||||
if (defaultPath.isEmpty())
|
||||
defaultPath = QLatin1Char('/');
|
||||
|
||||
QString urlPath = d->urlPath(url);
|
||||
foreach (QNetworkCookie cookie, cookieList) {
|
||||
if (cookie.path().length() > maxCookiePathLength)
|
||||
continue;
|
||||
|
||||
bool alreadyDead = !cookie.isSessionCookie() && cookie.expirationDate() < now;
|
||||
|
||||
if (cookie.path().isEmpty()) {
|
||||
cookie.setPath(defaultPath);
|
||||
}
|
||||
// Matching the behavior of Firefox, no path checking is done when setting cookies
|
||||
// Safari does something even odder, when that paths don't match it keeps
|
||||
// the cookie, but changes the paths to the default path
|
||||
#if 0
|
||||
else if (!d->matchingPath(cookie, urlPath)) {
|
||||
#ifdef NETWORKCOOKIEJAR_LOGREJECTEDCOOKIES
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__
|
||||
<< "Blocked cookie because: path doesn't match: " << cookie << url;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cookie.domain().isEmpty()) {
|
||||
QString host = url.host().toLower();
|
||||
if (host.isEmpty())
|
||||
continue;
|
||||
cookie.setDomain(host);
|
||||
} else if (!d->matchingDomain(cookie, url)) {
|
||||
#ifdef NETWORKCOOKIEJAR_LOGREJECTEDCOOKIES
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__
|
||||
<< "Blocked cookie because: domain doesn't match: " << cookie << url;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
// replace/remove existing cookies
|
||||
removeCookie(cookie);
|
||||
|
||||
// Notify derived class
|
||||
onCookieSetFromURL(cookie, url, alreadyDead);
|
||||
|
||||
if (alreadyDead)
|
||||
continue;
|
||||
|
||||
changed = true;
|
||||
d->tree.insert(splitHost(cookie.domain()), cookie);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
QList<QNetworkCookie> NetworkCookieJar::allCookies() const
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__;
|
||||
#endif
|
||||
return d->tree.all();
|
||||
}
|
||||
|
||||
void NetworkCookieJar::clearCookies()
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__;
|
||||
#endif
|
||||
d->tree.clear();
|
||||
}
|
||||
|
||||
void NetworkCookieJar::setCookies(const QList<QNetworkCookie> &cookieList)
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << cookieList.count();
|
||||
#endif
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime().toTimeSpec(Qt::UTC);
|
||||
|
||||
foreach (const QNetworkCookie &cookie, cookieList)
|
||||
{
|
||||
// If a matching cookie is already in the list, remove it.
|
||||
removeCookie(cookie);
|
||||
|
||||
if(!cookie.isSessionCookie() && cookie.expirationDate() < now)
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << "removing cookie: " << cookie;
|
||||
#endif
|
||||
// This cookie has expired -- don't re-add it
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << "adding cookie: " << cookie;
|
||||
#endif
|
||||
// this cookie has not expired -- save it
|
||||
d->tree.insert(splitHost(cookie.domain()), cookie);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkCookieJar::setAllCookies(const QList<QNetworkCookie> &cookieList)
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << cookieList.count();
|
||||
#endif
|
||||
clearCookies();
|
||||
setCookies(cookieList);
|
||||
}
|
||||
|
||||
void NetworkCookieJar::removeCookie(const QNetworkCookie &cookie)
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << "removing cookie: " << cookie;
|
||||
#endif
|
||||
|
||||
// If a cookie with the matching domain, path, and name exists in the cookiejar, remove it.
|
||||
QString domain = cookie.domain();
|
||||
Q_ASSERT(!domain.isEmpty());
|
||||
QStringList urlHost = splitHost(domain);
|
||||
|
||||
QList<QNetworkCookie> cookies = d->tree.find(urlHost);
|
||||
QList<QNetworkCookie>::const_iterator it = cookies.constBegin();
|
||||
for (; it != cookies.constEnd(); ++it)
|
||||
{
|
||||
if (cookie.name() == it->name() &&
|
||||
domain == it->domain() &&
|
||||
cookie.path() == it->path())
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << "found matching cookie: " << *it;
|
||||
#endif
|
||||
d->tree.remove(urlHost, *it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkCookieJar::dump()
|
||||
{
|
||||
#if defined(NETWORKCOOKIEJAR_DEBUG)
|
||||
qDebug() << "NetworkCookieJar::" << __FUNCTION__ << "dumping all cookies: ";
|
||||
QList<QNetworkCookie> cookies = allCookies();
|
||||
foreach (const QNetworkCookie &cookie, cookies)
|
||||
{
|
||||
qDebug() << " " << cookie;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QString NetworkCookieJarPrivate::urlPath(const QUrl &url) const
|
||||
{
|
||||
QString urlPath = url.path();
|
||||
if (!urlPath.endsWith(QLatin1Char('/')))
|
||||
urlPath += QLatin1Char('/');
|
||||
return urlPath;
|
||||
}
|
||||
|
||||
bool NetworkCookieJarPrivate::matchingPath(const QNetworkCookie &cookie, const QString &urlPath) const
|
||||
{
|
||||
QString cookiePath = cookie.path();
|
||||
if (!cookiePath.endsWith(QLatin1Char('/')))
|
||||
cookiePath += QLatin1Char('/');
|
||||
|
||||
return urlPath.startsWith(cookiePath);
|
||||
}
|
||||
|
||||
bool NetworkCookieJarPrivate::matchesBlacklist(const QString &string) const
|
||||
{
|
||||
if (!setSecondLevelDomain) {
|
||||
// Alternatively to save a little bit of ram we could just
|
||||
// use bsearch on twoLevelDomains in place
|
||||
for (int j = 0; twoLevelDomains[j]; ++j)
|
||||
secondLevelDomains += QLatin1String(twoLevelDomains[j]);
|
||||
setSecondLevelDomain = true;
|
||||
}
|
||||
QStringList::const_iterator i =
|
||||
qBinaryFind(secondLevelDomains.constBegin(), secondLevelDomains.constEnd(), string);
|
||||
return (i != secondLevelDomains.constEnd());
|
||||
}
|
||||
|
||||
bool NetworkCookieJarPrivate::matchingDomain(const QNetworkCookie &cookie, const QUrl &url) const
|
||||
{
|
||||
QString domain = cookie.domain().simplified().toLower();
|
||||
domain.remove(QLatin1Char(' '));
|
||||
QStringList parts = splitHost(domain);
|
||||
if (parts.isEmpty())
|
||||
return false;
|
||||
|
||||
// When there is only one part only file://localhost/ is accepted
|
||||
if (parts.count() == 1) {
|
||||
QString s = parts.first();
|
||||
if (parts.first() != QLatin1String("localhost"))
|
||||
return false;
|
||||
if (url.scheme().toLower() == QLatin1String("file"))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for blacklist
|
||||
if (parts.count() == 2 && matchesBlacklist(parts.last()))
|
||||
return false;
|
||||
|
||||
QStringList urlParts = url.host().toLower().split(QLatin1Char('.'), QString::SkipEmptyParts);
|
||||
if (urlParts.isEmpty())
|
||||
return false;
|
||||
while (urlParts.count() > parts.count())
|
||||
urlParts.removeFirst();
|
||||
|
||||
for (int j = 0; j < urlParts.count(); ++j) {
|
||||
if (urlParts.at(j) != parts.at(j)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetworkCookieJar::setSecondLevelDomains(const QStringList &secondLevelDomains)
|
||||
{
|
||||
d->setSecondLevelDomain = true;
|
||||
d->secondLevelDomains = secondLevelDomains;
|
||||
qSort(d->secondLevelDomains);
|
||||
}
|
||||
|
||||
|
||||
void NetworkCookieJar::onCookieSetFromURL(const QNetworkCookie &cookie, const QUrl &url, bool already_dead)
|
||||
{
|
||||
Q_UNUSED(cookie);
|
||||
Q_UNUSED(url);
|
||||
Q_UNUSED(already_dead);
|
||||
|
||||
// Derived classes can use this to track cookie changes.
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef NETWORKCOOKIEJAR_H
|
||||
#define NETWORKCOOKIEJAR_H
|
||||
|
||||
#include <qnetworkcookie.h>
|
||||
|
||||
class NetworkCookieJarPrivate;
|
||||
class NetworkCookieJar : public QNetworkCookieJar {
|
||||
Q_OBJECT
|
||||
public:
|
||||
NetworkCookieJar(QObject *parent = 0);
|
||||
~NetworkCookieJar();
|
||||
|
||||
virtual QList<QNetworkCookie> cookiesForUrl(const QUrl & url) const;
|
||||
virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
|
||||
|
||||
protected:
|
||||
QByteArray saveState() const;
|
||||
bool restoreState(const QByteArray &state);
|
||||
void endSession();
|
||||
|
||||
QList<QNetworkCookie> allCookies() const;
|
||||
void clearCookies();
|
||||
void setCookies(const QList<QNetworkCookie> &cookieList);
|
||||
void setAllCookies(const QList<QNetworkCookie> &cookieList);
|
||||
void removeCookie(const QNetworkCookie &cookie);
|
||||
void dump();
|
||||
void setSecondLevelDomains(const QStringList &secondLevelDomains);
|
||||
|
||||
virtual void onCookieSetFromURL(const QNetworkCookie &cookie, const QUrl &url, bool already_dead);
|
||||
|
||||
private:
|
||||
NetworkCookieJarPrivate *d;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef NETWORKCOOKIEJARPRIVATE_H
|
||||
#define NETWORKCOOKIEJARPRIVATE_H
|
||||
|
||||
#include "trie_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
QDataStream &operator<<(QDataStream &stream, const QNetworkCookie &cookie)
|
||||
{
|
||||
stream << cookie.toRawForm();
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &stream, QNetworkCookie &cookie)
|
||||
{
|
||||
QByteArray value;
|
||||
stream >> value;
|
||||
QList<QNetworkCookie> newCookies = QNetworkCookie::parseCookies(value);
|
||||
if (!newCookies.isEmpty())
|
||||
cookie = newCookies.first();
|
||||
return stream;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class NetworkCookieJarPrivate {
|
||||
public:
|
||||
NetworkCookieJarPrivate()
|
||||
: setSecondLevelDomain(false)
|
||||
{}
|
||||
|
||||
Trie<QNetworkCookie> tree;
|
||||
mutable bool setSecondLevelDomain;
|
||||
mutable QStringList secondLevelDomains;
|
||||
|
||||
bool matchesBlacklist(const QString &string) const;
|
||||
bool matchingDomain(const QNetworkCookie &cookie, const QUrl &url) const;
|
||||
QString urlPath(const QUrl &url) const;
|
||||
bool matchingPath(const QNetworkCookie &cookie, const QString &urlPath) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
|
||||
HEADERS += trie_p.h networkcookiejar.h twoleveldomains_p.h networkcookiejar_p.h
|
||||
SOURCES += networkcookiejar.cpp
|
||||
@@ -1,247 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef TRIE_H
|
||||
#define TRIE_H
|
||||
|
||||
//#define TRIE_DEBUG
|
||||
|
||||
#include <qstringlist.h>
|
||||
|
||||
#if defined(TRIE_DEBUG)
|
||||
#include <qdebug.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
A Trie tree (prefix tree) where the lookup takes m in the worst case.
|
||||
|
||||
The key is stored in *reverse* order
|
||||
|
||||
Example:
|
||||
Keys: x,a y,a
|
||||
|
||||
Trie:
|
||||
a
|
||||
| \
|
||||
x y
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
class Trie {
|
||||
public:
|
||||
Trie();
|
||||
~Trie();
|
||||
|
||||
void clear();
|
||||
void insert(const QStringList &key, const T &value);
|
||||
bool remove(const QStringList &key, const T &value);
|
||||
QList<T> find(const QStringList &key) const;
|
||||
QList<T> all() const;
|
||||
|
||||
inline bool contains(const QStringList &key) const;
|
||||
inline bool isEmpty() const { return children.isEmpty() && values.isEmpty(); }
|
||||
|
||||
private:
|
||||
const Trie<T>* walkTo(const QStringList &key) const;
|
||||
Trie<T>* walkTo(const QStringList &key, bool create = false);
|
||||
|
||||
template<class T1> friend QDataStream &operator<<(QDataStream &, const Trie<T1>&);
|
||||
template<class T1> friend QDataStream &operator>>(QDataStream &, Trie<T1>&);
|
||||
|
||||
QList<T> values;
|
||||
QStringList childrenKeys;
|
||||
QList<Trie<T> > children;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
Trie<T>::Trie() {
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Trie<T>::~Trie() {
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Trie<T>::clear() {
|
||||
#if defined(TRIE_DEBUG)
|
||||
qDebug() << "Trie::" << __FUNCTION__;
|
||||
#endif
|
||||
values.clear();
|
||||
childrenKeys.clear();
|
||||
children.clear();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool Trie<T>::contains(const QStringList &key) const {
|
||||
return walkTo(key);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Trie<T>::insert(const QStringList &key, const T &value) {
|
||||
#if defined(TRIE_DEBUG)
|
||||
qDebug() << "Trie::" << __FUNCTION__ << key << value;
|
||||
#endif
|
||||
Trie<T> *node = walkTo(key, true);
|
||||
if (node)
|
||||
node->values.append(value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool Trie<T>::remove(const QStringList &key, const T &value) {
|
||||
#if defined(TRIE_DEBUG)
|
||||
qDebug() << "Trie::" << __FUNCTION__ << key << value;
|
||||
#endif
|
||||
Trie<T> *node = walkTo(key, true);
|
||||
if (node) {
|
||||
bool removed = node->values.removeOne(value);
|
||||
if (!removed)
|
||||
return false;
|
||||
|
||||
// A faster implementation of removing nodes up the tree
|
||||
// can be created if profile shows this to be slow
|
||||
QStringList subKey = key;
|
||||
while (node->values.isEmpty()
|
||||
&& node->children.isEmpty()
|
||||
&& !subKey.isEmpty()) {
|
||||
QString currentLevelKey = subKey.first();
|
||||
QStringList parentKey = subKey.mid(1);
|
||||
Trie<T> *parent = walkTo(parentKey, false);
|
||||
Q_ASSERT(parent);
|
||||
QStringList::iterator iterator;
|
||||
iterator = qBinaryFind(parent->childrenKeys.begin(),
|
||||
parent->childrenKeys.end(),
|
||||
currentLevelKey);
|
||||
Q_ASSERT(iterator != parent->childrenKeys.end());
|
||||
int index = iterator - parent->childrenKeys.begin();
|
||||
parent->children.removeAt(index);
|
||||
parent->childrenKeys.removeAt(index);
|
||||
|
||||
node = parent;
|
||||
subKey = parentKey;
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
QList<T> Trie<T>::find(const QStringList &key) const {
|
||||
#if defined(TRIE_DEBUG)
|
||||
qDebug() << "Trie::" << __FUNCTION__ << key;
|
||||
#endif
|
||||
const Trie<T> *node = walkTo(key);
|
||||
if (node)
|
||||
return node->values;
|
||||
return QList<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
QList<T> Trie<T>::all() const {
|
||||
#if defined(TRIE_DEBUG)
|
||||
qDebug() << "Trie::" << __FUNCTION__;
|
||||
#endif
|
||||
QList<T> all = values;
|
||||
for (int i = 0; i < children.count(); ++i)
|
||||
all += children[i].all();
|
||||
return all;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
QDataStream &operator<<(QDataStream &out, const Trie<T>&trie) {
|
||||
out << trie.values;
|
||||
out << trie.childrenKeys;
|
||||
out << trie.children;
|
||||
Q_ASSERT(trie.childrenKeys.count() == trie.children.count());
|
||||
return out;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
QDataStream &operator>>(QDataStream &in, Trie<T> &trie) {
|
||||
trie.clear();
|
||||
if (in.status() != QDataStream::Ok)
|
||||
return in;
|
||||
in >> trie.values;
|
||||
in >> trie.childrenKeys;
|
||||
in >> trie.children;
|
||||
//Q_ASSERT(trie.childrenKeys.count() == trie.children.count());
|
||||
if (trie.childrenKeys.count() != trie.children.count())
|
||||
in.setStatus(QDataStream::ReadCorruptData);
|
||||
return in;
|
||||
}
|
||||
|
||||
// Very fast const walk
|
||||
template<class T>
|
||||
const Trie<T>* Trie<T>::walkTo(const QStringList &key) const {
|
||||
const Trie<T> *node = this;
|
||||
QStringList::const_iterator childIterator;
|
||||
QStringList::const_iterator begin, end;
|
||||
|
||||
int depth = key.count() - 1;
|
||||
while (depth >= 0) {
|
||||
const QString currentLevelKey = key.at(depth--);
|
||||
begin = node->childrenKeys.constBegin();
|
||||
end = node->childrenKeys.constEnd();
|
||||
childIterator = qBinaryFind(begin, end, currentLevelKey);
|
||||
if (childIterator == end)
|
||||
return 0;
|
||||
node = &node->children.at(childIterator - begin);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Trie<T>* Trie<T>::walkTo(const QStringList &key, bool create) {
|
||||
QStringList::iterator iterator;
|
||||
Trie<T> *node = this;
|
||||
QStringList::iterator begin, end;
|
||||
int depth = key.count() - 1;
|
||||
while (depth >= 0) {
|
||||
const QString currentLevelKey = key.at(depth--);
|
||||
begin = node->childrenKeys.begin();
|
||||
end = node->childrenKeys.end();
|
||||
iterator = qBinaryFind(begin, end, currentLevelKey);
|
||||
#if defined(TRIE_DEBUG)
|
||||
qDebug() << "\t" << node << key << currentLevelKey << node->childrenKeys;
|
||||
#endif
|
||||
int index = -1;
|
||||
if (iterator == end) {
|
||||
if (!create)
|
||||
return 0;
|
||||
iterator = qLowerBound(begin,
|
||||
end,
|
||||
currentLevelKey);
|
||||
index = iterator - begin;
|
||||
node->childrenKeys.insert(iterator, currentLevelKey);
|
||||
node->children.insert(index, Trie<T>());
|
||||
} else {
|
||||
index = iterator - begin;
|
||||
}
|
||||
Q_ASSERT(index >= 0 && index < node->children.count());
|
||||
node = &node->children[index];
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,92 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
// Updated from https://wiki.mozilla.org/TLD_List#External_Links
|
||||
// To set a custom list use NetworkCookieJar::setSecondLevelDomains()
|
||||
static const char *const twoLevelDomains[] = {
|
||||
"ao",
|
||||
"ar",
|
||||
"arpa",
|
||||
"bd",
|
||||
"bn",
|
||||
"br",
|
||||
"co",
|
||||
"cr",
|
||||
"cy",
|
||||
"do",
|
||||
"eg",
|
||||
"et",
|
||||
"fj",
|
||||
"fk",
|
||||
"gh",
|
||||
"gn",
|
||||
"gu",
|
||||
"id",
|
||||
"il",
|
||||
"jm",
|
||||
"ke",
|
||||
"kh",
|
||||
"ki",
|
||||
"kw",
|
||||
"kz",
|
||||
"lb",
|
||||
"lc",
|
||||
"lr",
|
||||
"ls",
|
||||
"ml",
|
||||
"mm",
|
||||
"mv",
|
||||
"mw",
|
||||
"mx",
|
||||
"my",
|
||||
"ng",
|
||||
"ni",
|
||||
"np",
|
||||
"nz",
|
||||
"om",
|
||||
"pa",
|
||||
"pe",
|
||||
"pg",
|
||||
"pw",
|
||||
"py",
|
||||
"qa",
|
||||
"sa",
|
||||
"sb",
|
||||
"sv",
|
||||
"sy",
|
||||
"th",
|
||||
"tn",
|
||||
"tz",
|
||||
"uk",
|
||||
"uy",
|
||||
"va",
|
||||
"ve",
|
||||
"ye",
|
||||
"yu",
|
||||
"za",
|
||||
"zm",
|
||||
"zw",
|
||||
0
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
# Detect if Qt is static or shared
|
||||
CONFIG(debug, debug|release) {
|
||||
win32:PRL = $$[QT_INSTALL_LIBS] QtGui.prl
|
||||
} else {
|
||||
win32:PRL = $$[QT_INSTALL_LIBS] QtGuid.prl
|
||||
}
|
||||
|
||||
unix:!mac: PRL = $$[QT_INSTALL_LIBS] libQtGui.prl
|
||||
mac: PRL = $$[QT_INSTALL_LIBS] QtGui.framework/QtGui.prl
|
||||
include($$join(PRL, "/"))
|
||||
|
||||
contains(QMAKE_PRL_CONFIG, static) {
|
||||
DEFINES += STATIC_QT
|
||||
QTPLUGIN += qgif
|
||||
} else {
|
||||
DEFINES += SHARED_QT
|
||||
}
|
||||
|
||||
@@ -1,269 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
#define FREEGLUT_STATIC
|
||||
|
||||
#include "zpr.h"
|
||||
#include "llqtwebkit.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <direct.h>
|
||||
#include <time.h>
|
||||
|
||||
bool gDebugMode = false;
|
||||
int gBrowserWindowId=-1;
|
||||
GLuint gBrowserTexture=-1;
|
||||
GLuint gCheckerTexture=-1;
|
||||
|
||||
// manually make part of the browser texture transparent - for testing - LLQtWebKit will handle this eventually
|
||||
void alphaize_browser_texture(unsigned char* texture_pixels)
|
||||
{
|
||||
const int texture_depth=4;
|
||||
|
||||
int texture_width = LLQtWebKit::getInstance()->getBrowserWidth(gBrowserWindowId);
|
||||
int texture_height = LLQtWebKit::getInstance()->getBrowserHeight(gBrowserWindowId);
|
||||
|
||||
const int num_squares=16;
|
||||
int sqr1_alpha=0xff;
|
||||
int sqr2_alpha=0x00;
|
||||
|
||||
for(int y1=0;y1<num_squares;++y1)
|
||||
{
|
||||
for(int x1=0;x1<num_squares;++x1)
|
||||
{
|
||||
int px_start=texture_width*x1/num_squares;
|
||||
int px_end=(texture_width*(x1+1))/num_squares;
|
||||
int py_start=texture_height*y1/num_squares;
|
||||
int py_end=(texture_height*(y1+1))/num_squares;
|
||||
|
||||
for(int y2=py_start;y2<py_end;++y2)
|
||||
{
|
||||
for(int x2=px_start;x2<px_end;++x2)
|
||||
{
|
||||
int rowspan=texture_width*texture_depth;
|
||||
|
||||
if((y1%2)^(x1%2))
|
||||
{
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+3]=sqr1_alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+3]=sqr2_alpha;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
void idle(void)
|
||||
{
|
||||
if(!gDebugMode)
|
||||
{
|
||||
LLQtWebKit::getInstance()->pump(200);
|
||||
LLQtWebKit::getInstance()->grabBrowserWindow( gBrowserWindowId );
|
||||
glutPostRedisplay();
|
||||
};
|
||||
}
|
||||
|
||||
void display(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gCheckerTexture);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.8f, -0.8f, -0.8f);
|
||||
glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.8f, 0.8f, -0.8f);
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.8f, 0.8f, -0.8f);
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.8f, -0.8f, -0.8f);
|
||||
glEnd();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gBrowserTexture);
|
||||
if(!gDebugMode)
|
||||
{
|
||||
const unsigned char* browser_pixels=LLQtWebKit::getInstance()->getBrowserWindowPixels(gBrowserWindowId);
|
||||
if(browser_pixels)
|
||||
{
|
||||
int texture_width = LLQtWebKit::getInstance()->getBrowserWidth(gBrowserWindowId);
|
||||
int texture_height = LLQtWebKit::getInstance()->getBrowserHeight(gBrowserWindowId);
|
||||
int texture_depth = 4;
|
||||
|
||||
unsigned char* texture_pixels = new unsigned char[texture_width*texture_height*texture_depth];
|
||||
memcpy(texture_pixels, browser_pixels, texture_width*texture_height*texture_depth);
|
||||
alphaize_browser_texture(texture_pixels);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
0, 0,
|
||||
texture_width, texture_height,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
texture_pixels);
|
||||
|
||||
delete [] texture_pixels;
|
||||
};
|
||||
};
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.8f, -0.8f, 0.8f);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.8f, -0.8f, 0.8f);
|
||||
glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.8f, 0.8f, 0.8f);
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.8f, 0.8f, 0.8f);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
GLuint make_rgba_texture(int texture_width, int texture_height)
|
||||
{
|
||||
const int texture_depth=4;
|
||||
|
||||
unsigned char* texture_pixels = new unsigned char[texture_width*texture_height*texture_depth];
|
||||
|
||||
const int num_squares=rand()%10+10;
|
||||
int sqr1_r=rand()%0xa0+0x20;
|
||||
int sqr1_g=rand()%0xa0+0x20;
|
||||
int sqr1_b=rand()%0xa0+0x20;
|
||||
int sqr1_alpha=0xff;
|
||||
|
||||
int sqr2_r=rand()%0xa0+0x20;
|
||||
int sqr2_g=rand()%0xa0+0x20;
|
||||
int sqr2_b=rand()%0xa0+0x20;
|
||||
int sqr2_alpha=0x00;
|
||||
|
||||
for(int y1=0;y1<num_squares;++y1)
|
||||
{
|
||||
for(int x1=0;x1<num_squares;++x1)
|
||||
{
|
||||
int px_start=texture_width*x1/num_squares;
|
||||
int px_end=(texture_width*(x1+1))/num_squares;
|
||||
int py_start=texture_height*y1/num_squares;
|
||||
int py_end=(texture_height*(y1+1))/num_squares;
|
||||
|
||||
for(int y2=py_start;y2<py_end;++y2)
|
||||
{
|
||||
for(int x2=px_start;x2<px_end;++x2)
|
||||
{
|
||||
int rowspan=texture_width*texture_depth;
|
||||
|
||||
if((y1%2)^(x1%2))
|
||||
{
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+0]=sqr1_r;
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+1]=sqr1_g;
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+2]=sqr1_b;
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+3]=sqr1_alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+0]=sqr2_r;
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+1]=sqr2_g;
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+2]=sqr2_b;
|
||||
texture_pixels[y2*rowspan+x2*texture_depth+3]=sqr2_alpha;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
GLuint texture_id;
|
||||
glGenTextures(1, &texture_id);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width, texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_pixels);
|
||||
|
||||
delete [] texture_pixels;
|
||||
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
srand((unsigned int)time(0));
|
||||
|
||||
const int browser_width=1024;
|
||||
const int browser_height=1024;
|
||||
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
|
||||
glutInitWindowPosition(80, 0);
|
||||
glutInitWindowSize(600,600);
|
||||
|
||||
glutCreateWindow("3D Web Pages in OpenGL");
|
||||
|
||||
glutDisplayFunc(display);
|
||||
glutIdleFunc(idle);
|
||||
|
||||
zprInit();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDepthFunc(GL_LESS);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
if(gDebugMode)
|
||||
{
|
||||
gBrowserTexture = make_rgba_texture(browser_width, browser_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
glGenTextures(1, &gBrowserTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, gBrowserTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, browser_width, browser_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
|
||||
|
||||
std::string working_dir=_getcwd(NULL, 1024);
|
||||
std::string app_dir("");
|
||||
std::string profile_dir=working_dir+"/profile";
|
||||
std::string cookie_path=profile_dir+"/cookies.txt";
|
||||
LLQtWebKit::getInstance()->init(std::string(), app_dir, profile_dir, GetDesktopWindow());
|
||||
|
||||
LLQtWebKit::getInstance()->enableJavaScript(true);
|
||||
LLQtWebKit::getInstance()->enableCookies(true);
|
||||
LLQtWebKit::getInstance()->enablePlugins(true);
|
||||
|
||||
const std::string start_url("http://news.google.com");
|
||||
//const std::string start_url("http://www.youtube.com/watch?v=4Z3r9X8OahA&feature=rbl_entertainment");
|
||||
gBrowserWindowId=LLQtWebKit::getInstance()->createBrowserWindow(browser_width, browser_height);
|
||||
LLQtWebKit::getInstance()->setSize(gBrowserWindowId, browser_width, browser_height);
|
||||
LLQtWebKit::getInstance()->flipWindow(gBrowserWindowId, true);
|
||||
LLQtWebKit::getInstance()->navigateTo(gBrowserWindowId, start_url);
|
||||
}
|
||||
|
||||
gCheckerTexture = make_rgba_texture( browser_width, browser_height);
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
INCLUDEPATH += ../../
|
||||
CONFIG -= app_bundle
|
||||
|
||||
QT += webkit opengl network
|
||||
|
||||
!mac {
|
||||
unix {
|
||||
DEFINES += LL_LINUX
|
||||
LIBS += -lglui -lglut
|
||||
LIBS += $$PWD/../../libllqtwebkit.a
|
||||
}
|
||||
}
|
||||
|
||||
mac {
|
||||
DEFINES += LL_OSX
|
||||
LIBS += -framework GLUT -framework OpenGL
|
||||
LIBS += $$PWD/libllqtwebkit.dylib
|
||||
}
|
||||
|
||||
win32 {
|
||||
DEFINES += _WINDOWS
|
||||
INCLUDEPATH += ../
|
||||
INCLUDEPATH += $$PWD/../../stage/packages/include
|
||||
DESTDIR=../build
|
||||
release {
|
||||
LIBS += $$PWD/../../Release/llqtwebkit.lib
|
||||
LIBS += $$PWD/../build/freeglut_static.lib
|
||||
LIBS += comdlg32.lib
|
||||
}
|
||||
}
|
||||
|
||||
include(../../static.pri)
|
||||
|
||||
SOURCES += 3dgl.cpp zpr.c
|
||||
@@ -1,429 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "zpr.h"
|
||||
|
||||
/* This code was originally C++ :-) */
|
||||
|
||||
#define bool int
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
static double _left = 0.0;
|
||||
static double _right = 0.0;
|
||||
static double _bottom = 0.0;
|
||||
static double _top = 0.0;
|
||||
static double _zNear = -10.0;
|
||||
static double _zFar = 10.0;
|
||||
|
||||
static int _mouseX = 0;
|
||||
static int _mouseY = 0;
|
||||
static bool _mouseLeft = false;
|
||||
static bool _mouseMiddle = false;
|
||||
static bool _mouseRight = false;
|
||||
|
||||
static double _dragPosX = 0.0;
|
||||
static double _dragPosY = 0.0;
|
||||
static double _dragPosZ = 0.0;
|
||||
|
||||
static double _matrix[16];
|
||||
static double _matrixInverse[16];
|
||||
|
||||
static double vlen(double x,double y,double z);
|
||||
static void pos(double *px,double *py,double *pz,const int x,const int y,const int *viewport);
|
||||
static void getMatrix();
|
||||
static void invertMatrix(const GLdouble *m, GLdouble *out );
|
||||
|
||||
static void zprReshape(int w,int h);
|
||||
static void zprMouse(int button, int state, int x, int y);
|
||||
static void zprMotion(int x, int y);
|
||||
|
||||
static void zprPick(GLdouble x, GLdouble y,GLdouble delX, GLdouble delY);
|
||||
|
||||
/* Configurable center point for zooming and rotation */
|
||||
|
||||
GLfloat zprReferencePoint[4] = { 0,0,0,0 };
|
||||
|
||||
void
|
||||
zprInit()
|
||||
{
|
||||
getMatrix();
|
||||
|
||||
glutReshapeFunc(zprReshape);
|
||||
glutMouseFunc(zprMouse);
|
||||
glutMotionFunc(zprMotion);
|
||||
}
|
||||
|
||||
static void
|
||||
zprReshape(int w,int h)
|
||||
{
|
||||
glViewport(0,0,w,h);
|
||||
|
||||
_top = 1.0;
|
||||
_bottom = -1.0;
|
||||
_left = -(double)w/(double)h;
|
||||
_right = -_left;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(_left,_right,_bottom,_top,_zNear,_zFar);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
static void
|
||||
zprMouse(int button, int state, int x, int y)
|
||||
{
|
||||
GLint viewport[4];
|
||||
|
||||
/* Do picking */
|
||||
if (state==GLUT_DOWN)
|
||||
zprPick(x,glutGet(GLUT_WINDOW_HEIGHT)-1-y,3,3);
|
||||
|
||||
_mouseX = x;
|
||||
_mouseY = y;
|
||||
|
||||
if (state==GLUT_UP)
|
||||
switch (button)
|
||||
{
|
||||
case GLUT_LEFT_BUTTON: _mouseLeft = false; break;
|
||||
case GLUT_MIDDLE_BUTTON: _mouseMiddle = false; break;
|
||||
case GLUT_RIGHT_BUTTON: _mouseRight = false; break;
|
||||
}
|
||||
else
|
||||
switch (button)
|
||||
{
|
||||
case GLUT_LEFT_BUTTON: _mouseLeft = true; break;
|
||||
case GLUT_MIDDLE_BUTTON: _mouseMiddle = true; break;
|
||||
case GLUT_RIGHT_BUTTON: _mouseRight = true; break;
|
||||
}
|
||||
|
||||
glGetIntegerv(GL_VIEWPORT,viewport);
|
||||
pos(&_dragPosX,&_dragPosY,&_dragPosZ,x,y,viewport);
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
static void
|
||||
zprMotion(int x, int y)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
const int dx = x - _mouseX;
|
||||
const int dy = y - _mouseY;
|
||||
|
||||
GLint viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT,viewport);
|
||||
|
||||
if (dx==0 && dy==0)
|
||||
return;
|
||||
|
||||
if (_mouseMiddle || (_mouseLeft && _mouseRight))
|
||||
{
|
||||
double s = exp((double)dy*0.01);
|
||||
|
||||
glTranslatef( zprReferencePoint[0], zprReferencePoint[1], zprReferencePoint[2]);
|
||||
glScalef(s,s,s);
|
||||
glTranslatef(-zprReferencePoint[0],-zprReferencePoint[1],-zprReferencePoint[2]);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
if (_mouseLeft)
|
||||
{
|
||||
double ax,ay,az;
|
||||
double bx,by,bz;
|
||||
double angle;
|
||||
|
||||
ax = dy;
|
||||
ay = dx;
|
||||
az = 0.0;
|
||||
angle = vlen(ax,ay,az)/(double)(viewport[2]+1)*180.0;
|
||||
|
||||
/* Use inverse matrix to determine local axis of rotation */
|
||||
|
||||
bx = _matrixInverse[0]*ax + _matrixInverse[4]*ay + _matrixInverse[8] *az;
|
||||
by = _matrixInverse[1]*ax + _matrixInverse[5]*ay + _matrixInverse[9] *az;
|
||||
bz = _matrixInverse[2]*ax + _matrixInverse[6]*ay + _matrixInverse[10]*az;
|
||||
|
||||
glTranslatef( zprReferencePoint[0], zprReferencePoint[1], zprReferencePoint[2]);
|
||||
glRotatef(angle,bx,by,bz);
|
||||
glTranslatef(-zprReferencePoint[0],-zprReferencePoint[1],-zprReferencePoint[2]);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
if (_mouseRight)
|
||||
{
|
||||
double px,py,pz;
|
||||
|
||||
pos(&px,&py,&pz,x,y,viewport);
|
||||
|
||||
glLoadIdentity();
|
||||
glTranslatef(px-_dragPosX,py-_dragPosY,pz-_dragPosZ);
|
||||
glMultMatrixd(_matrix);
|
||||
|
||||
_dragPosX = px;
|
||||
_dragPosY = py;
|
||||
_dragPosZ = pz;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
_mouseX = x;
|
||||
_mouseY = y;
|
||||
|
||||
if (changed)
|
||||
{
|
||||
getMatrix();
|
||||
glutPostRedisplay();
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* Utility functions
|
||||
*****************************************************************/
|
||||
|
||||
static double
|
||||
vlen(double x,double y,double z)
|
||||
{
|
||||
return sqrt(x*x+y*y+z*z);
|
||||
}
|
||||
|
||||
static void
|
||||
pos(double *px,double *py,double *pz,const int x,const int y,const int *viewport)
|
||||
{
|
||||
/*
|
||||
Use the ortho projection and viewport information
|
||||
to map from mouse co-ordinates back into world
|
||||
co-ordinates
|
||||
*/
|
||||
|
||||
*px = (double)(x-viewport[0])/(double)(viewport[2]);
|
||||
*py = (double)(y-viewport[1])/(double)(viewport[3]);
|
||||
|
||||
*px = _left + (*px)*(_right-_left);
|
||||
*py = _top + (*py)*(_bottom-_top);
|
||||
*pz = _zNear;
|
||||
}
|
||||
|
||||
static void
|
||||
getMatrix()
|
||||
{
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX,_matrix);
|
||||
invertMatrix(_matrix,_matrixInverse);
|
||||
}
|
||||
|
||||
/*
|
||||
* From Mesa-2.2\src\glu\project.c
|
||||
*
|
||||
* Compute the inverse of a 4x4 matrix. Contributed by scotter@lafn.org
|
||||
*/
|
||||
|
||||
static void
|
||||
invertMatrix(const GLdouble *m, GLdouble *out )
|
||||
{
|
||||
|
||||
/* NB. OpenGL Matrices are COLUMN major. */
|
||||
#define MAT(m,r,c) (m)[(c)*4+(r)]
|
||||
|
||||
/* Here's some shorthand converting standard (row,column) to index. */
|
||||
#define m11 MAT(m,0,0)
|
||||
#define m12 MAT(m,0,1)
|
||||
#define m13 MAT(m,0,2)
|
||||
#define m14 MAT(m,0,3)
|
||||
#define m21 MAT(m,1,0)
|
||||
#define m22 MAT(m,1,1)
|
||||
#define m23 MAT(m,1,2)
|
||||
#define m24 MAT(m,1,3)
|
||||
#define m31 MAT(m,2,0)
|
||||
#define m32 MAT(m,2,1)
|
||||
#define m33 MAT(m,2,2)
|
||||
#define m34 MAT(m,2,3)
|
||||
#define m41 MAT(m,3,0)
|
||||
#define m42 MAT(m,3,1)
|
||||
#define m43 MAT(m,3,2)
|
||||
#define m44 MAT(m,3,3)
|
||||
|
||||
GLdouble det;
|
||||
GLdouble d12, d13, d23, d24, d34, d41;
|
||||
GLdouble tmp[16]; /* Allow out == in. */
|
||||
|
||||
/* Inverse = adjoint / det. (See linear algebra texts.)*/
|
||||
|
||||
/* pre-compute 2x2 dets for last two rows when computing */
|
||||
/* cofactors of first two rows. */
|
||||
d12 = (m31*m42-m41*m32);
|
||||
d13 = (m31*m43-m41*m33);
|
||||
d23 = (m32*m43-m42*m33);
|
||||
d24 = (m32*m44-m42*m34);
|
||||
d34 = (m33*m44-m43*m34);
|
||||
d41 = (m34*m41-m44*m31);
|
||||
|
||||
tmp[0] = (m22 * d34 - m23 * d24 + m24 * d23);
|
||||
tmp[1] = -(m21 * d34 + m23 * d41 + m24 * d13);
|
||||
tmp[2] = (m21 * d24 + m22 * d41 + m24 * d12);
|
||||
tmp[3] = -(m21 * d23 - m22 * d13 + m23 * d12);
|
||||
|
||||
/* Compute determinant as early as possible using these cofactors. */
|
||||
det = m11 * tmp[0] + m12 * tmp[1] + m13 * tmp[2] + m14 * tmp[3];
|
||||
|
||||
/* Run singularity test. */
|
||||
if (det == 0.0) {
|
||||
/* printf("invert_matrix: Warning: Singular matrix.\n"); */
|
||||
/* memcpy(out,_identity,16*sizeof(double)); */
|
||||
}
|
||||
else {
|
||||
GLdouble invDet = 1.0 / det;
|
||||
/* Compute rest of inverse. */
|
||||
tmp[0] *= invDet;
|
||||
tmp[1] *= invDet;
|
||||
tmp[2] *= invDet;
|
||||
tmp[3] *= invDet;
|
||||
|
||||
tmp[4] = -(m12 * d34 - m13 * d24 + m14 * d23) * invDet;
|
||||
tmp[5] = (m11 * d34 + m13 * d41 + m14 * d13) * invDet;
|
||||
tmp[6] = -(m11 * d24 + m12 * d41 + m14 * d12) * invDet;
|
||||
tmp[7] = (m11 * d23 - m12 * d13 + m13 * d12) * invDet;
|
||||
|
||||
/* Pre-compute 2x2 dets for first two rows when computing */
|
||||
/* cofactors of last two rows. */
|
||||
d12 = m11*m22-m21*m12;
|
||||
d13 = m11*m23-m21*m13;
|
||||
d23 = m12*m23-m22*m13;
|
||||
d24 = m12*m24-m22*m14;
|
||||
d34 = m13*m24-m23*m14;
|
||||
d41 = m14*m21-m24*m11;
|
||||
|
||||
tmp[8] = (m42 * d34 - m43 * d24 + m44 * d23) * invDet;
|
||||
tmp[9] = -(m41 * d34 + m43 * d41 + m44 * d13) * invDet;
|
||||
tmp[10] = (m41 * d24 + m42 * d41 + m44 * d12) * invDet;
|
||||
tmp[11] = -(m41 * d23 - m42 * d13 + m43 * d12) * invDet;
|
||||
tmp[12] = -(m32 * d34 - m33 * d24 + m34 * d23) * invDet;
|
||||
tmp[13] = (m31 * d34 + m33 * d41 + m34 * d13) * invDet;
|
||||
tmp[14] = -(m31 * d24 + m32 * d41 + m34 * d12) * invDet;
|
||||
tmp[15] = (m31 * d23 - m32 * d13 + m33 * d12) * invDet;
|
||||
|
||||
memcpy(out, tmp, 16*sizeof(GLdouble));
|
||||
}
|
||||
|
||||
#undef m11
|
||||
#undef m12
|
||||
#undef m13
|
||||
#undef m14
|
||||
#undef m21
|
||||
#undef m22
|
||||
#undef m23
|
||||
#undef m24
|
||||
#undef m31
|
||||
#undef m32
|
||||
#undef m33
|
||||
#undef m34
|
||||
#undef m41
|
||||
#undef m42
|
||||
#undef m43
|
||||
#undef m44
|
||||
#undef MAT
|
||||
}
|
||||
|
||||
/***************************************** Picking ****************************************************/
|
||||
|
||||
static void (*selection)(void) = NULL;
|
||||
static void (*pick)(GLint name) = NULL;
|
||||
|
||||
void zprSelectionFunc(void (*f)(void))
|
||||
{
|
||||
selection = f;
|
||||
}
|
||||
|
||||
void zprPickFunc(void (*f)(GLint name))
|
||||
{
|
||||
pick = f;
|
||||
}
|
||||
|
||||
/* Draw in selection mode */
|
||||
|
||||
static void
|
||||
zprPick(GLdouble x, GLdouble y,GLdouble delX, GLdouble delY)
|
||||
{
|
||||
GLuint buffer[1024];
|
||||
const int bufferSize = sizeof(buffer)/sizeof(GLuint);
|
||||
|
||||
GLint viewport[4];
|
||||
GLdouble projection[16];
|
||||
|
||||
GLint hits;
|
||||
GLint i,j,k;
|
||||
|
||||
GLint min = -1;
|
||||
GLuint minZ = -1;
|
||||
|
||||
glSelectBuffer(bufferSize,buffer); /* Selection buffer for hit records */
|
||||
glRenderMode(GL_SELECT); /* OpenGL selection mode */
|
||||
glInitNames(); /* Clear OpenGL name stack */
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix(); /* Push current projection matrix */
|
||||
glGetIntegerv(GL_VIEWPORT,viewport); /* Get the current viewport size */
|
||||
glGetDoublev(GL_PROJECTION_MATRIX,projection); /* Get the projection matrix */
|
||||
glLoadIdentity(); /* Reset the projection matrix */
|
||||
gluPickMatrix(x,y,delX,delY,viewport); /* Set the picking matrix */
|
||||
glMultMatrixd(projection); /* Apply projection matrix */
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
if (selection)
|
||||
selection(); /* Draw the scene in selection mode */
|
||||
|
||||
hits = glRenderMode(GL_RENDER); /* Return to normal rendering mode */
|
||||
|
||||
/* Diagnostic output to stdout */
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (hits!=0)
|
||||
{
|
||||
printf("hits = %d\n",hits);
|
||||
|
||||
for (i=0,j=0; i<hits; i++)
|
||||
{
|
||||
printf("\tsize = %u, min = %u, max = %u : ",buffer[j],buffer[j+1],buffer[j+2]);
|
||||
for (k=0; k < (GLint) buffer[j]; k++)
|
||||
printf("%u ",buffer[j+3+k]);
|
||||
printf("\n");
|
||||
|
||||
j += 3 + buffer[j];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Determine the nearest hit */
|
||||
|
||||
if (hits)
|
||||
{
|
||||
for (i=0,j=0; i<hits; i++)
|
||||
{
|
||||
if (buffer[j+1]<minZ)
|
||||
{
|
||||
/* If name stack is empty, return -1 */
|
||||
/* If name stack is not empty, return top-most name */
|
||||
|
||||
if (buffer[j]==0)
|
||||
min = -1;
|
||||
else
|
||||
min = buffer[j+2+buffer[j]];
|
||||
|
||||
minZ = buffer[j+1];
|
||||
}
|
||||
|
||||
j += buffer[j] + 3;
|
||||
}
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix(); /* Restore projection matrix */
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
if (pick)
|
||||
pick(min); /* Pass pick event back to application */
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
#ifndef ZPR_H
|
||||
#define ZPR_H
|
||||
|
||||
/*
|
||||
* Zoom-pan-rotate mouse manipulation module for GLUT
|
||||
* Version 0.4, October 2003
|
||||
*
|
||||
* Nigel Stewart
|
||||
* School of Computer Science and Information Technology
|
||||
* RMIT University
|
||||
* nigels@cs.rmit.edu.au
|
||||
*
|
||||
* Instructions
|
||||
* ------------
|
||||
*
|
||||
* Call zprInit() immediately after your call to glutCreateWindow()
|
||||
*
|
||||
* The ZPR module handles glutReshapeFunc(), glutMouseFunc() and glutMotionFunc()
|
||||
* Applications should not bypass the ZPR handlers for reshape or mouse events.
|
||||
*
|
||||
* Mouse manipulation of the GLUT window via the modelview matrix:
|
||||
*
|
||||
* Left button -> rotate
|
||||
* Middle button -> zoom
|
||||
* Right button -> pan
|
||||
*
|
||||
* Picking is also provided via two configurable callbacks:
|
||||
*
|
||||
* void zprSelectionFunc(void (*f)(void))
|
||||
*
|
||||
* The draw function to be called in OpenGL selection
|
||||
* mode in response to a mouse-down button event.
|
||||
*
|
||||
* void zprPickFunc(void (*f)(GLint name))
|
||||
*
|
||||
* The callback function which will receive the
|
||||
* top-most item of the name stack of the closest selection
|
||||
* hit. If there is no selection hit, -1
|
||||
*
|
||||
* Limitations
|
||||
* -----------
|
||||
*
|
||||
* Works best with zprReferencePoint appropriately configured.
|
||||
* Works best with ortho projection.
|
||||
* You may need to use glEnable(GL_NORMALIZATION) for correct lighting.
|
||||
* Near and far clip planes are hard-coded.
|
||||
* Zooming and rotation is centered on the origin.
|
||||
* Only one window can use the callbacks at one time.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define FREEGLUT_STATIC
|
||||
|
||||
#include <GL/glut.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
/* Mouse Manipulation API */
|
||||
|
||||
void zprInit();
|
||||
|
||||
extern GLfloat zprReferencePoint[4];
|
||||
|
||||
/* Picking API (Optional) */
|
||||
|
||||
extern void zprSelectionFunc(void (*f)(void)); /* Selection-mode draw function */
|
||||
extern void zprPickFunc(void (*f)(GLint name)); /* Pick event handling function */
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,341 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#include <QtGui/QtGui>
|
||||
#include <llqtwebkit.h>
|
||||
|
||||
class WebPage : public QWidget, LLEmbeddedBrowserWindowObserver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void locationChanged(const QString &);
|
||||
void canGoBack(bool);
|
||||
void canGoForward(bool);
|
||||
|
||||
public:
|
||||
WebPage(QWidget *parent = 0);
|
||||
~WebPage();
|
||||
|
||||
void onCursorChanged(const EventType& event);
|
||||
void onPageChanged(const EventType& event);
|
||||
void onNavigateBegin(const EventType& event);
|
||||
void onNavigateComplete(const EventType& event);
|
||||
void onUpdateProgress(const EventType& event);
|
||||
void onStatusTextChange(const EventType& event);
|
||||
void onLocationChange(const EventType& event);
|
||||
void onClickLinkHref(const EventType& event);
|
||||
void onClickLinkNoFollow(const EventType& event);
|
||||
|
||||
public slots:
|
||||
void goBack();
|
||||
void goForward();
|
||||
void reload();
|
||||
void loadUrl(const QString &);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void mouseDoubleClickEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void keyReleaseEvent(QKeyEvent *event);
|
||||
private:
|
||||
void updateSLvariables();
|
||||
int mBrowserWindowId;
|
||||
};
|
||||
|
||||
WebPage::WebPage(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
std::string applicationDir = std::string();
|
||||
std::string componentDir = applicationDir;
|
||||
std::string profileDir = applicationDir + "\\" + "testGL_profile";
|
||||
LLQtWebKit::getInstance()->init(applicationDir, componentDir, profileDir, 0);
|
||||
|
||||
mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow(width(), height());
|
||||
|
||||
// observer events that LLQtWebKit emits
|
||||
LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this );
|
||||
|
||||
// append details to agent string
|
||||
LLQtWebKit::getInstance()->setBrowserAgentId("testqtapp");
|
||||
|
||||
// don't flip bitmap
|
||||
LLQtWebKit::getInstance()->flipWindow(mBrowserWindowId, false);
|
||||
|
||||
// test Second Life viewer specific functions
|
||||
LLQtWebKit::getInstance()->setSLObjectEnabled( true ); // true means feature is turned on
|
||||
LLQtWebKit::getInstance()->setAgentLanguage( "tst-en" ); // viewer language selected by agent
|
||||
LLQtWebKit::getInstance()->setAgentRegion( "QtTestAppRegion" ); // name of region where agent is located
|
||||
LLQtWebKit::getInstance()->setAgentLocation( 9.8, 7.6, 5.4 ); // agent's x,y,z location within a region
|
||||
LLQtWebKit::getInstance()->setAgentGlobalLocation( 119.8, 227.6, 335.4 ); // agent's x,y,z location within the grid
|
||||
LLQtWebKit::getInstance()->setAgentMaturity( "Very immature" ); // selected maturity level of agent
|
||||
LLQtWebKit::getInstance()->setAgentOrientation( (rand()%36000)/100.0f ); // direction avatar is facing
|
||||
LLQtWebKit::getInstance()->emitLocation();
|
||||
LLQtWebKit::getInstance()->emitLanguage();
|
||||
LLQtWebKit::getInstance()->emitMaturity();
|
||||
|
||||
// go to the "home page"
|
||||
LLQtWebKit::getInstance()->navigateTo(mBrowserWindowId, "http://callum-linden.s3.amazonaws.com/browsertest.html");
|
||||
}
|
||||
|
||||
WebPage::~WebPage()
|
||||
{
|
||||
// unhook observer
|
||||
LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this );
|
||||
|
||||
// clean up
|
||||
LLQtWebKit::getInstance()->reset();
|
||||
}
|
||||
|
||||
void WebPage::updateSLvariables()
|
||||
{
|
||||
// randomly update SL values to test
|
||||
LLQtWebKit::getInstance()->setAgentOrientation( (rand()%36000)/100.0f );
|
||||
LLQtWebKit::getInstance()->setAgentLocation( (rand()%25600)/100.0f, (rand()%25600)/100.0f, (rand()%25600)/100.0f );
|
||||
LLQtWebKit::getInstance()->setAgentGlobalLocation( (rand()%25600)/100.0f, (rand()%25600)/100.0f, (rand()%25600)/100.0f );
|
||||
|
||||
if ( rand() % 2 )
|
||||
LLQtWebKit::getInstance()->setAgentLanguage( "One language" );
|
||||
else
|
||||
LLQtWebKit::getInstance()->setAgentLanguage( "Another language" );
|
||||
|
||||
if ( rand() % 2 )
|
||||
LLQtWebKit::getInstance()->setAgentRegion( "Region Wibble" );
|
||||
else
|
||||
LLQtWebKit::getInstance()->setAgentRegion( "Region Flasm" );
|
||||
|
||||
if ( rand() % 2 )
|
||||
LLQtWebKit::getInstance()->setAgentMaturity( "Adults only" );
|
||||
else
|
||||
LLQtWebKit::getInstance()->setAgentMaturity( "Children only" );
|
||||
|
||||
LLQtWebKit::getInstance()->emitLocation();
|
||||
LLQtWebKit::getInstance()->emitLanguage();
|
||||
LLQtWebKit::getInstance()->emitMaturity();
|
||||
}
|
||||
|
||||
void WebPage::onCursorChanged(const EventType& event)
|
||||
{
|
||||
//qDebug() << __FUNCTION__ << QString::fromStdString(event.getEventUri());
|
||||
switch (event.getIntValue()) {
|
||||
case LLQtWebKit::C_ARROW: setCursor(QCursor(Qt::ArrowCursor)); break;
|
||||
case LLQtWebKit::C_IBEAM: setCursor(QCursor(Qt::IBeamCursor)); break;
|
||||
case LLQtWebKit::C_SPLITV: setCursor(QCursor(Qt::SplitHCursor)); break;
|
||||
case LLQtWebKit::C_SPLITH: setCursor(QCursor(Qt::SplitVCursor)); break;
|
||||
case LLQtWebKit::C_POINTINGHAND: setCursor(QCursor(Qt::PointingHandCursor)); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void WebPage::onPageChanged(const EventType& event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId );
|
||||
//qDebug() << __FUNCTION__ << QString::fromStdString(event.getEventUri());
|
||||
update();
|
||||
}
|
||||
|
||||
void WebPage::onNavigateBegin(const EventType& event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
//qDebug() << __FUNCTION__ << QString::fromStdString(event.getEventUri());
|
||||
}
|
||||
|
||||
void WebPage::onNavigateComplete(const EventType& event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
//qDebug() << __FUNCTION__ << QString::fromStdString(event.getEventUri());
|
||||
}
|
||||
|
||||
void WebPage::onUpdateProgress(const EventType& event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
void WebPage::onStatusTextChange(const EventType& event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
void WebPage::onLocationChange(const EventType& event)
|
||||
{
|
||||
//qDebug() << __FUNCTION__;
|
||||
emit locationChanged(QString::fromStdString(event.getEventUri()));
|
||||
//void canGoBack(bool);
|
||||
//void canGoForward(bool);
|
||||
}
|
||||
|
||||
void WebPage::onClickLinkHref(const EventType& event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
void WebPage::onClickLinkNoFollow(const EventType& event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
void WebPage::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
LLQtWebKit::getInstance()->setSize(mBrowserWindowId, event->size().width(), event->size().height());
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
||||
void WebPage::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
int width = LLQtWebKit::getInstance()->getBrowserWidth(mBrowserWindowId);
|
||||
int height = LLQtWebKit::getInstance()->getBrowserHeight(mBrowserWindowId);
|
||||
const unsigned char* pixels = LLQtWebKit::getInstance()->getBrowserWindowPixels(mBrowserWindowId);
|
||||
QImage image(pixels, width, height, QImage::Format_RGB32);
|
||||
image = image.rgbSwapped();
|
||||
QPainter painter(this);
|
||||
painter.drawImage(QPoint(0, 0), image);
|
||||
}
|
||||
|
||||
void WebPage::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId,
|
||||
LLQtWebKit::ME_MOUSE_DOUBLE_CLICK,
|
||||
LLQtWebKit::MB_MOUSE_BUTTON_LEFT,
|
||||
event->x(), event->y(),
|
||||
LLQtWebKit::KM_MODIFIER_NONE );
|
||||
}
|
||||
|
||||
void WebPage::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
updateSLvariables();
|
||||
|
||||
LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId,
|
||||
LLQtWebKit::ME_MOUSE_MOVE,
|
||||
LLQtWebKit::MB_MOUSE_BUTTON_LEFT,
|
||||
event->x(), event->y(),
|
||||
LLQtWebKit::KM_MODIFIER_NONE );
|
||||
}
|
||||
|
||||
void WebPage::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId,
|
||||
LLQtWebKit::ME_MOUSE_DOWN,
|
||||
LLQtWebKit::MB_MOUSE_BUTTON_LEFT,
|
||||
event->x(), event->y(),
|
||||
LLQtWebKit::KM_MODIFIER_NONE );
|
||||
}
|
||||
|
||||
void WebPage::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId,
|
||||
LLQtWebKit::ME_MOUSE_UP,
|
||||
LLQtWebKit::MB_MOUSE_BUTTON_LEFT,
|
||||
event->x(), event->y(),
|
||||
LLQtWebKit::KM_MODIFIER_NONE );
|
||||
|
||||
LLQtWebKit::getInstance()->focusBrowser(mBrowserWindowId, true);
|
||||
}
|
||||
|
||||
void WebPage::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
void WebPage::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
//LLQtWebKit::getInstance()->unicodeInput(mBrowserWindowId, event->text().at(0).unicode(),LLQtWebKit::KM_MODIFIER_NONE);
|
||||
}
|
||||
|
||||
void WebPage::goBack()
|
||||
{
|
||||
LLQtWebKit::getInstance()->userAction(mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK);
|
||||
}
|
||||
|
||||
void WebPage::goForward()
|
||||
{
|
||||
LLQtWebKit::getInstance()->userAction(mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD);
|
||||
}
|
||||
|
||||
void WebPage::reload()
|
||||
{
|
||||
LLQtWebKit::getInstance()->userAction(mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_RELOAD);
|
||||
}
|
||||
|
||||
void WebPage::loadUrl(const QString &url)
|
||||
{
|
||||
LLQtWebKit::getInstance()->navigateTo(mBrowserWindowId, url.toStdString());
|
||||
}
|
||||
|
||||
#include "ui_window.h"
|
||||
|
||||
class Window : public QDialog, public Ui_Dialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Window(QWidget *parent = 0);
|
||||
|
||||
public slots:
|
||||
void loadUrl();
|
||||
};
|
||||
|
||||
Window::Window(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
connect(webpage, SIGNAL(locationChanged(const QString &)),
|
||||
location, SLOT(setText(const QString &)));
|
||||
connect(webpage, SIGNAL(canGoBack(bool)),
|
||||
backButton, SLOT(setEnabled(bool)));
|
||||
connect(webpage, SIGNAL(canGoForward(bool)),
|
||||
forwardButton, SLOT(setEnabled(bool)));
|
||||
connect(backButton, SIGNAL(clicked()),
|
||||
webpage, SLOT(goBack()));
|
||||
connect(forwardButton, SIGNAL(clicked()),
|
||||
webpage, SLOT(goForward()));
|
||||
connect(reloadButton, SIGNAL(clicked()),
|
||||
webpage, SLOT(reload()));
|
||||
connect(location, SIGNAL(returnPressed()),
|
||||
this, SLOT(loadUrl()));
|
||||
}
|
||||
|
||||
void Window::loadUrl()
|
||||
{
|
||||
webpage->loadUrl(location->text());
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication application(argc, argv);
|
||||
Window window;
|
||||
window.show();
|
||||
return application.exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
||||
@@ -1,38 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
INCLUDEPATH += ../../
|
||||
CONFIG -= app_bundle
|
||||
|
||||
include(../../static.pri)
|
||||
|
||||
QT += webkit opengl network
|
||||
|
||||
unix {
|
||||
LIBS += $$PWD/../../libllqtwebkit.a
|
||||
}
|
||||
|
||||
!mac {
|
||||
unix {
|
||||
DEFINES += LL_LINUX
|
||||
}
|
||||
}
|
||||
|
||||
mac {
|
||||
DEFINES += LL_OSX
|
||||
}
|
||||
|
||||
|
||||
win32{
|
||||
DEFINES += _WINDOWS
|
||||
INCLUDEPATH += ../
|
||||
DESTDIR=../build
|
||||
release {
|
||||
LIBS += $$PWD/../../Release/llqtwebkit.lib
|
||||
}
|
||||
}
|
||||
|
||||
# Input
|
||||
SOURCES += main.cpp
|
||||
FORMS += window.ui
|
||||
@@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>766</width>
|
||||
<height>613</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="backButton">
|
||||
<property name="text">
|
||||
<string>←</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="forwardButton">
|
||||
<property name="text">
|
||||
<string>→</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="reloadButton">
|
||||
<property name="text">
|
||||
<string>↺</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="location"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="WebPage" name="webpage" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>WebPage</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">webpage.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,229 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef _WINDOWS
|
||||
extern "C" {
|
||||
#include <unistd.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <fstream>
|
||||
|
||||
#ifdef LL_OSX
|
||||
// I'm not sure why STATIC_QT is getting defined, but the Q_IMPORT_PLUGIN thing doesn't seem to be necessary on the mac.
|
||||
#undef STATIC_QT
|
||||
#endif
|
||||
|
||||
#ifdef STATIC_QT
|
||||
#include <QtPlugin>
|
||||
Q_IMPORT_PLUGIN(qgif)
|
||||
#endif
|
||||
|
||||
#include "llqtwebkit.h"
|
||||
|
||||
class sslTest :
|
||||
public LLEmbeddedBrowserWindowObserver
|
||||
{
|
||||
public:
|
||||
sslTest( std::string url, bool ignore_ca_file, bool ignore_ssl_errors ) :
|
||||
mBrowserWindowWidth( 512 ),
|
||||
mBrowserWindowHeight( 512 ),
|
||||
mBrowserWindowHandle( 0 ),
|
||||
mNavigateInProgress( true )
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
std::string cwd = std::string( _getcwd( NULL, 1024) );
|
||||
std::string profile_dir = cwd + "\\" + "ssltest_profile";
|
||||
void* native_window_handle = (void*)GetDesktopWindow();
|
||||
std::string ca_file_loc = cwd + "\\" + "CA.pem";
|
||||
#else
|
||||
std::string cwd = std::string( getcwd( NULL, 1024) );
|
||||
std::string profile_dir = cwd + "/" + "ssltest_profile";
|
||||
void* native_window_handle = 0;
|
||||
std::string ca_file_loc = cwd + "/" + "CA.pem";
|
||||
#endif
|
||||
std::cout << "ssltest> === begin ===" << std::endl;
|
||||
std::cout << "ssltest> current working dir is " << cwd << std::endl;
|
||||
std::cout << "ssltest> profiles dir location is " << profile_dir << std::endl;
|
||||
|
||||
LLQtWebKit::getInstance()->init( cwd, cwd, profile_dir, native_window_handle );
|
||||
|
||||
LLQtWebKit::getInstance()->enableJavaScript( true );
|
||||
LLQtWebKit::getInstance()->enablePlugins( true );
|
||||
|
||||
mBrowserWindowHandle = LLQtWebKit::getInstance()->createBrowserWindow( mBrowserWindowWidth, mBrowserWindowHeight );
|
||||
LLQtWebKit::getInstance()->setSize( mBrowserWindowHandle, mBrowserWindowWidth, mBrowserWindowHeight );
|
||||
|
||||
LLQtWebKit::getInstance()->addObserver( mBrowserWindowHandle, this );
|
||||
|
||||
if ( ! ignore_ca_file )
|
||||
{
|
||||
std::cout << "ssltest> Expected certificate authority file location is " << ca_file_loc << std::endl;
|
||||
LLQtWebKit::getInstance()->setCAFile( ca_file_loc.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ssltest> Not loading certificate authority file" << std::endl;
|
||||
};
|
||||
|
||||
if ( ignore_ssl_errors )
|
||||
{
|
||||
LLQtWebKit::getInstance()->setIgnoreSSLCertErrors( true );
|
||||
std::cout << "ssltest> Ignoring SSL errors " << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ssltest> Not ignoring SSL errors " << std::endl;
|
||||
};
|
||||
|
||||
LLQtWebKit::getInstance()->navigateTo( mBrowserWindowHandle, url );
|
||||
|
||||
std::cout << "ssltest> navigating to " << url << std::endl;
|
||||
};
|
||||
|
||||
bool idle( void )
|
||||
{
|
||||
LLQtWebKit::getInstance()->pump( 100 );
|
||||
|
||||
#if _WINDOWS
|
||||
MSG msg;
|
||||
while ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
|
||||
{
|
||||
GetMessage( &msg, NULL, 0, 0 );
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessage( &msg );
|
||||
};
|
||||
#endif
|
||||
return mNavigateInProgress;
|
||||
};
|
||||
|
||||
~sslTest()
|
||||
{
|
||||
LLQtWebKit::getInstance()->remObserver( mBrowserWindowHandle, this );
|
||||
LLQtWebKit::getInstance()->reset();
|
||||
std::cout << "ssltest> === end ===" << std::endl;
|
||||
};
|
||||
|
||||
void onNavigateBegin( const EventType& eventIn )
|
||||
{
|
||||
mNavigateInProgress = true;
|
||||
std::cout << "ssltest> Event: begin navigation to " << eventIn.getEventUri() << std::endl;
|
||||
};
|
||||
|
||||
void onNavigateComplete( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "ssltest> Event: end navigation to " << eventIn.getEventUri() << std::endl;
|
||||
mNavigateInProgress = false;
|
||||
};
|
||||
|
||||
void onUpdateProgress( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "ssltest> Event: progress value updated to " << eventIn.getIntValue() << std::endl;
|
||||
};
|
||||
|
||||
void onStatusTextChange( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "ssltest> Event: status updated to " << eventIn.getStringValue() << std::endl;
|
||||
};
|
||||
|
||||
void onTitleChange( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "ssltest> Event: title changed to " << eventIn.getStringValue() << std::endl;
|
||||
};
|
||||
|
||||
void onLocationChange( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "ssltest> Event: location changed to " << eventIn.getStringValue() << std::endl;
|
||||
};
|
||||
|
||||
bool onCertError(const std::string &in_url, const std::string &in_msg)
|
||||
{
|
||||
std::cout << "ssltest> Cert error triggered\n" << in_url << "\n" << in_msg << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
int mBrowserWindowWidth;
|
||||
int mBrowserWindowHeight;
|
||||
int mBrowserWindowHandle;
|
||||
bool mNavigateInProgress;
|
||||
};
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
bool ingore_ssl_errors = false;
|
||||
bool ignore_ca_file = false;
|
||||
|
||||
for( int i = 1; i < argc; ++i )
|
||||
{
|
||||
if ( std::string( argv[ i ] ) == "--help" )
|
||||
{
|
||||
std::cout << std::endl << "ssltest <url> [--ignoresslerrors] [--ignorecafile]" << std::endl;
|
||||
std::cout << "Looks for cert file CA.pem in the current working directory";
|
||||
|
||||
exit( 0 );
|
||||
};
|
||||
|
||||
if ( std::string( argv[ i ] ) == "--ignoresslerrors" )
|
||||
ingore_ssl_errors = true;
|
||||
|
||||
if ( std::string( argv[ i ] ) == "--ignorecafile" )
|
||||
ignore_ca_file = true;
|
||||
};
|
||||
|
||||
std::string url ( "https://my.secondlife.com/callum.linden" );
|
||||
for( int i = 1; i < argc; ++i )
|
||||
{
|
||||
if ( std::string( argv[ i ] ).substr( 0, 2 ) != "--" )
|
||||
{
|
||||
url = std::string( argv[ i ] );
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
std::cout << std::endl << " --------- sslTest application starting --------- " << std::endl;
|
||||
std::cout << "ssltest> URL specified is " << url << std::endl;
|
||||
|
||||
sslTest* app = new sslTest( url, ignore_ca_file, ingore_ssl_errors );
|
||||
|
||||
bool result = app->idle();
|
||||
while( result )
|
||||
{
|
||||
result = app->idle();
|
||||
};
|
||||
|
||||
delete app;
|
||||
|
||||
std::cout << " --------- sslTest application ending --------- " << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
INCLUDEPATH += ../../
|
||||
CONFIG -= app_bundle
|
||||
CONFIG += console
|
||||
|
||||
QT += webkit network
|
||||
|
||||
mac {
|
||||
DEFINES += LL_OSX
|
||||
LIBS += $$PWD/libllqtwebkit.dylib
|
||||
}
|
||||
|
||||
win32 {
|
||||
DEFINES += _WINDOWS
|
||||
INCLUDEPATH += ../
|
||||
DESTDIR=../build
|
||||
LIBS += user32.lib
|
||||
release {
|
||||
LIBS += $$PWD/../../Release/llqtwebkit.lib
|
||||
}
|
||||
}
|
||||
|
||||
include(../../static.pri)
|
||||
|
||||
SOURCES += ssltest.cpp
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,38 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
INCLUDEPATH += ../../
|
||||
CONFIG -= app_bundle
|
||||
|
||||
QT += webkit opengl network
|
||||
|
||||
!mac {
|
||||
unix {
|
||||
DEFINES += LL_LINUX
|
||||
LIBS += -lglui -lglut
|
||||
LIBS += $$PWD/../../libllqtwebkit.a
|
||||
}
|
||||
}
|
||||
|
||||
mac {
|
||||
DEFINES += LL_OSX
|
||||
LIBS += -framework GLUT -framework OpenGL
|
||||
LIBS += $$PWD/libllqtwebkit.dylib
|
||||
}
|
||||
|
||||
win32 {
|
||||
DEFINES += _WINDOWS
|
||||
INCLUDEPATH += ../
|
||||
INCLUDEPATH += $$PWD/../../stage/packages/include
|
||||
DESTDIR=../build
|
||||
release {
|
||||
LIBS += $$PWD/../../Release/llqtwebkit.lib
|
||||
LIBS += $$PWD/../build/freeglut_static.lib
|
||||
LIBS += comdlg32.lib
|
||||
}
|
||||
}
|
||||
|
||||
include(../../static.pri)
|
||||
|
||||
SOURCES += testgl.cpp
|
||||
@@ -1,292 +0,0 @@
|
||||
/* Copyright (c) 2006-2010, Linden Research, Inc.
|
||||
*
|
||||
* LLQtWebKit Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in GPL-license.txt in this distribution, or online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
*/
|
||||
|
||||
#ifndef _WINDOWS
|
||||
extern "C" {
|
||||
#include <unistd.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <iomanip>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
#ifdef LL_OSX
|
||||
// I'm not sure why STATIC_QT is getting defined, but the Q_IMPORT_PLUGIN thing doesn't seem to be necessary on the mac.
|
||||
#undef STATIC_QT
|
||||
#endif
|
||||
|
||||
#ifdef STATIC_QT
|
||||
#include <QtPlugin>
|
||||
Q_IMPORT_PLUGIN(qgif)
|
||||
#endif
|
||||
|
||||
#include "llqtwebkit.h"
|
||||
|
||||
class textMode :
|
||||
public LLEmbeddedBrowserWindowObserver
|
||||
{
|
||||
public:
|
||||
textMode( std::string url, bool ignore_ca_file, bool ignore_ssl_errors ) :
|
||||
mBrowserWindowWidth( 512 ),
|
||||
mBrowserWindowHeight( 512 ),
|
||||
mBrowserWindowHandle( 0 ),
|
||||
mNavigateInProgress( true ),
|
||||
mLogLine( "" )
|
||||
{
|
||||
|
||||
#ifdef _WINDOWS
|
||||
std::string cwd = std::string( _getcwd( NULL, 1024) );
|
||||
std::string profile_dir = cwd + "\\" + "textmode_profile";
|
||||
void* native_window_handle = (void*)GetDesktopWindow();
|
||||
std::string ca_file_loc = cwd + "\\" + "CA.pem";
|
||||
#else
|
||||
std::string cwd = std::string( getcwd( NULL, 1024) );
|
||||
std::string profile_dir = cwd + "/" + "textmode_profile";
|
||||
void* native_window_handle = 0;
|
||||
std::string ca_file_loc = cwd + "/" + "CA.pem";
|
||||
#endif
|
||||
mLogLine << "Current working dir is " << cwd << std::endl;
|
||||
mLogLine << "Profiles dir is " << profile_dir;
|
||||
writeLine( mLogLine.str() );
|
||||
|
||||
LLQtWebKit::getInstance()->init( cwd, cwd, profile_dir, native_window_handle );
|
||||
|
||||
LLQtWebKit::getInstance()->enableQtMessageHandler( true );
|
||||
|
||||
LLQtWebKit::getInstance()->enableJavaScript( true );
|
||||
LLQtWebKit::getInstance()->enablePlugins( true );
|
||||
|
||||
mBrowserWindowHandle = LLQtWebKit::getInstance()->createBrowserWindow( mBrowserWindowWidth, mBrowserWindowHeight );
|
||||
LLQtWebKit::getInstance()->setSize( mBrowserWindowHandle, mBrowserWindowWidth, mBrowserWindowHeight );
|
||||
|
||||
LLQtWebKit::getInstance()->addObserver( mBrowserWindowHandle, this );
|
||||
|
||||
if ( ! ignore_ca_file )
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "Expected certificate authority file location is " << ca_file_loc;
|
||||
writeLine( mLogLine.str() );
|
||||
LLQtWebKit::getInstance()->setCAFile( ca_file_loc.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "Not loading certificate authority file";
|
||||
writeLine( mLogLine.str() );
|
||||
};
|
||||
|
||||
if ( ignore_ssl_errors )
|
||||
{
|
||||
LLQtWebKit::getInstance()->setIgnoreSSLCertErrors( true );
|
||||
mLogLine.str("");
|
||||
mLogLine << "Ignoring SSL errors";
|
||||
writeLine( mLogLine.str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "Not ignoring SSL errors";
|
||||
writeLine( mLogLine.str() );
|
||||
};
|
||||
|
||||
mLogLine.str("");
|
||||
mLogLine << "Navigating to " << url;
|
||||
writeLine( mLogLine.str() );
|
||||
|
||||
LLQtWebKit::getInstance()->navigateTo( mBrowserWindowHandle, url );
|
||||
};
|
||||
|
||||
bool idle( void )
|
||||
{
|
||||
LLQtWebKit::getInstance()->pump( 100 );
|
||||
|
||||
#if _WINDOWS
|
||||
MSG msg;
|
||||
while ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
|
||||
{
|
||||
GetMessage( &msg, NULL, 0, 0 );
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessage( &msg );
|
||||
};
|
||||
#endif
|
||||
return mNavigateInProgress;
|
||||
};
|
||||
|
||||
~textMode()
|
||||
{
|
||||
LLQtWebKit::getInstance()->remObserver( mBrowserWindowHandle, this );
|
||||
LLQtWebKit::getInstance()->reset();
|
||||
};
|
||||
|
||||
void onNavigateBegin( const EventType& eventIn )
|
||||
{
|
||||
mNavigateInProgress = true;
|
||||
mLogLine.str("");
|
||||
mLogLine << "Event: Begin navigation to " << eventIn.getEventUri();
|
||||
writeLine( mLogLine.str() );
|
||||
};
|
||||
|
||||
void onNavigateComplete( const EventType& eventIn )
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "Event: End navigation to " << eventIn.getEventUri();
|
||||
writeLine( mLogLine.str() );
|
||||
mNavigateInProgress = false;
|
||||
};
|
||||
|
||||
void onUpdateProgress( const EventType& eventIn )
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "Event: progress value updated to " << eventIn.getIntValue();
|
||||
writeLine( mLogLine.str() );
|
||||
};
|
||||
|
||||
void onStatusTextChange( const EventType& eventIn )
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "Event: status updated to " << eventIn.getStringValue();
|
||||
writeLine( mLogLine.str() );
|
||||
};
|
||||
|
||||
void onTitleChange( const EventType& eventIn )
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "Event: title change to " << eventIn.getStringValue();
|
||||
writeLine( mLogLine.str() );
|
||||
};
|
||||
|
||||
void onLocationChange( const EventType& eventIn )
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "Event: location changed to " << eventIn.getStringValue();
|
||||
writeLine( mLogLine.str() );
|
||||
};
|
||||
|
||||
bool onCertError(const std::string &in_url, const std::string &in_msg)
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "Cert error triggered: " << std::endl << in_url << "\n" << in_msg;
|
||||
writeLine( mLogLine.str() );
|
||||
return true;
|
||||
}
|
||||
|
||||
void onCookieChanged(const EventType& event)
|
||||
{
|
||||
std::string url = event.getEventUri();
|
||||
std::string cookie = event.getStringValue();
|
||||
int dead = event.getIntValue();
|
||||
mLogLine.str("");
|
||||
if ( ! dead )
|
||||
mLogLine << "Cookie added:" << cookie;
|
||||
else
|
||||
mLogLine << "Cookie deleted:" << cookie;
|
||||
writeLine( mLogLine.str() );
|
||||
}
|
||||
|
||||
virtual void onQtDebugMessage( const std::string& msg, const std::string& msg_type)
|
||||
{
|
||||
mLogLine.str("");
|
||||
mLogLine << "QtDebugMsg (" << msg_type << "): " << msg.substr(msg.length() - 1);
|
||||
writeLine( mLogLine.str() );
|
||||
}
|
||||
|
||||
void writeLine( std::string line )
|
||||
{
|
||||
double elapsed_seconds = (double)clock() / (double)CLOCKS_PER_SEC;
|
||||
|
||||
std::cout << "[" << std::setprecision(7) << std::setw(3) << std::setfill('0') << elapsed_seconds << "] ";
|
||||
const int max_len = 140;
|
||||
if ( line.length() > max_len )
|
||||
{
|
||||
std::cout << line.substr(0, max_len);
|
||||
std::cout << "....";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << line;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
//std::cout << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
int mBrowserWindowWidth;
|
||||
int mBrowserWindowHeight;
|
||||
int mBrowserWindowHandle;
|
||||
bool mNavigateInProgress;
|
||||
std::ostringstream mLogLine;
|
||||
};
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
bool ingore_ssl_errors = false;
|
||||
bool ignore_ca_file = false;
|
||||
|
||||
for( int i = 1; i < argc; ++i )
|
||||
{
|
||||
if ( std::string( argv[ i ] ) == "--help" )
|
||||
{
|
||||
std::cout << std::endl << "textmode <url>" << std::endl;
|
||||
exit( 0 );
|
||||
};
|
||||
|
||||
if ( std::string( argv[ i ] ) == "--ignoresslerrors" )
|
||||
ingore_ssl_errors = true;
|
||||
|
||||
if ( std::string( argv[ i ] ) == "--ignorecafile" )
|
||||
ignore_ca_file = true;
|
||||
};
|
||||
|
||||
std::string url ( "https://my.secondlife.com/callum.linden" );
|
||||
for( int i = 1; i < argc; ++i )
|
||||
{
|
||||
if ( std::string( argv[ i ] ).substr( 0, 2 ) != "--" )
|
||||
{
|
||||
url = std::string( argv[ i ] );
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
textMode* app = new textMode( url, ignore_ca_file, ingore_ssl_errors );
|
||||
|
||||
bool result = app->idle();
|
||||
while( result )
|
||||
{
|
||||
result = app->idle();
|
||||
};
|
||||
|
||||
delete app;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
INCLUDEPATH += ../../
|
||||
CONFIG -= app_bundle
|
||||
CONFIG += console
|
||||
|
||||
QT += webkit network
|
||||
|
||||
mac {
|
||||
DEFINES += LL_OSX
|
||||
LIBS += $$PWD/libllqtwebkit.dylib
|
||||
}
|
||||
|
||||
win32 {
|
||||
DEFINES += _WINDOWS
|
||||
INCLUDEPATH += ../
|
||||
DESTDIR=../build
|
||||
LIBS += user32.lib
|
||||
release {
|
||||
LIBS += $$PWD/../../Release/llqtwebkit.lib
|
||||
}
|
||||
}
|
||||
|
||||
include(../../static.pri)
|
||||
|
||||
SOURCES += textmode.cpp
|
||||
@@ -1,6 +0,0 @@
|
||||
@echo off
|
||||
echo Setting up a Qt environment using 3p-qt HG repository
|
||||
set QTDIR=C:\Work\3p-llqtwebkit\stage
|
||||
set PATH=C:\Work\3p-llqtwebkit\stage\bin;%PATH%
|
||||
set QMAKESPEC=win32-msvc2010
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat"
|
||||
Binary file not shown.
@@ -46,12 +46,30 @@ BOOL LLFocusableElement::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLFocusableElement::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
bool LLFocusableElement::wantsKeyUpKeyDown() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//virtual
|
||||
bool LLFocusableElement::wantsReturnKey() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLFocusableElement::~LLFocusableElement()
|
||||
{
|
||||
|
||||
@@ -57,8 +57,17 @@ public:
|
||||
|
||||
// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
|
||||
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
|
||||
virtual BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent);
|
||||
virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
|
||||
|
||||
/**
|
||||
* If true this LLFocusableElement wants to receive KEYUP and KEYDOWN messages
|
||||
* even for normal character strokes.
|
||||
* Default implementation returns false.
|
||||
*/
|
||||
virtual bool wantsKeyUpKeyDown() const;
|
||||
virtual bool wantsReturnKey() const;
|
||||
|
||||
virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
|
||||
protected:
|
||||
virtual void onFocusReceived();
|
||||
|
||||
@@ -963,6 +963,38 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
||||
return handled;
|
||||
}
|
||||
|
||||
BOOL LLView::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
|
||||
if (getVisible() && getEnabled())
|
||||
{
|
||||
if (called_from_parent)
|
||||
{
|
||||
// Downward traversal
|
||||
handled = childrenHandleKeyUp(key, mask) != NULL;
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
// For event logging we don't care which widget handles it
|
||||
// So we capture the key at the end of this function once we know if it was handled
|
||||
handled = handleKeyUpHere(key, mask);
|
||||
if (handled)
|
||||
{
|
||||
LL_DEBUGS() << "Key handled by " << getName() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!handled && !called_from_parent && mParentView)
|
||||
{
|
||||
// Upward traversal
|
||||
handled = mParentView->handleKeyUp(key, mask, FALSE);
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
// Called from handleKey()
|
||||
// Handles key in this object. Checking parents and children happens in handleKey()
|
||||
BOOL LLView::handleKeyHere(KEY key, MASK mask)
|
||||
@@ -970,6 +1002,13 @@ BOOL LLView::handleKeyHere(KEY key, MASK mask)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Called from handleKey()
|
||||
// Handles key in this object. Checking parents and children happens in handleKey()
|
||||
BOOL LLView::handleKeyUpHere(KEY key, MASK mask)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
@@ -1095,6 +1134,12 @@ LLView* LLView::childrenHandleKey(KEY key, MASK mask)
|
||||
return childrenHandleCharEvent("Key", &LLView::handleKey, key, mask);
|
||||
}
|
||||
|
||||
// Called during downward traversal
|
||||
LLView* LLView::childrenHandleKeyUp(KEY key, MASK mask)
|
||||
{
|
||||
return childrenHandleCharEvent("Key Up", &LLView::handleKeyUp, key, mask);
|
||||
}
|
||||
|
||||
// Called during downward traversal
|
||||
LLView* LLView::childrenHandleUnicodeChar(llwchar uni_char)
|
||||
{
|
||||
|
||||
@@ -452,6 +452,7 @@ public:
|
||||
|
||||
// inherited from LLFocusableElement
|
||||
/* virtual */ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
|
||||
/* virtual */ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent);
|
||||
/* virtual */ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
|
||||
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
@@ -657,6 +658,7 @@ public:
|
||||
virtual void handleReshape(const LLRect& rect, bool by_user);
|
||||
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
virtual BOOL handleKeyUpHere(KEY key, MASK mask);
|
||||
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
|
||||
|
||||
|
||||
@@ -681,6 +683,7 @@ protected:
|
||||
void logMouseEvent();
|
||||
|
||||
LLView* childrenHandleKey(KEY key, MASK mask);
|
||||
LLView* childrenHandleKeyUp(KEY key, MASK mask);
|
||||
LLView* childrenHandleUnicodeChar(llwchar uni_char);
|
||||
LLView* childrenHandleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
BOOL drop,
|
||||
|
||||
@@ -261,7 +261,7 @@ void LLKeyboardWin32::scanKeyboard()
|
||||
// *TODO: I KNOW there must be a better way of
|
||||
// interrogating the key state than this, using async key
|
||||
// state can cause ALL kinds of bugs - Doug
|
||||
if (key < KEY_BUTTON0)
|
||||
if ((key < KEY_BUTTON0) && ((key < '0') || (key > '9')))
|
||||
{
|
||||
// ...under windows make sure the key actually still is down.
|
||||
// ...translate back to windows key
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "llgl.h"
|
||||
#include "llstring.h"
|
||||
#include "lldir.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llglslshader.h"
|
||||
|
||||
// System includes
|
||||
@@ -2105,6 +2106,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
|
||||
window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next
|
||||
window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
|
||||
window_imp->mKeyVirtualKey = w_param;
|
||||
window_imp->mRawMsg = u_msg;
|
||||
window_imp->mRawWParam = w_param;
|
||||
window_imp->mRawLParam = l_param;
|
||||
|
||||
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYDOWN");
|
||||
{
|
||||
@@ -2127,6 +2131,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
|
||||
{
|
||||
window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
|
||||
window_imp->mKeyVirtualKey = w_param;
|
||||
window_imp->mRawMsg = u_msg;
|
||||
window_imp->mRawWParam = w_param;
|
||||
window_imp->mRawLParam = l_param;
|
||||
|
||||
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP");
|
||||
LLFastTimer t2(FTM_KEYHANDLER);
|
||||
@@ -2214,6 +2221,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
|
||||
|
||||
case WM_CHAR:
|
||||
window_imp->mKeyCharCode = w_param;
|
||||
window_imp->mRawMsg = u_msg;
|
||||
window_imp->mRawWParam = w_param;
|
||||
window_imp->mRawLParam = l_param;
|
||||
|
||||
// Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need
|
||||
// to figure out how that works. - Doug
|
||||
@@ -3310,6 +3320,9 @@ LLSD LLWindowWin32::getNativeKeyData()
|
||||
|
||||
result["scan_code"] = (S32)mKeyScanCode;
|
||||
result["virtual_key"] = (S32)mKeyVirtualKey;
|
||||
result["msg"] = ll_sd_from_U32(mRawMsg);
|
||||
result["w_param"] = ll_sd_from_U32(mRawWParam);
|
||||
result["l_param"] = ll_sd_from_U32(mRawLParam);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ protected:
|
||||
HCURSOR loadColorCursor(LPCTSTR name);
|
||||
BOOL isValid();
|
||||
void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size);
|
||||
LLSD getNativeKeyData();
|
||||
virtual LLSD getNativeKeyData();
|
||||
|
||||
// Changes display resolution. Returns true if successful
|
||||
BOOL setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh);
|
||||
@@ -215,6 +215,9 @@ protected:
|
||||
U32 mKeyCharCode;
|
||||
U32 mKeyScanCode;
|
||||
U32 mKeyVirtualKey;
|
||||
U32 mRawMsg;
|
||||
U32 mRawWParam;
|
||||
U32 mRawLParam;
|
||||
|
||||
friend class LLWindowManager;
|
||||
};
|
||||
|
||||
@@ -70,6 +70,8 @@
|
||||
#include "lldxhardware.h"
|
||||
#endif
|
||||
|
||||
#include "cef/llceflib.h"
|
||||
|
||||
extern LLMemoryInfo gSysMemory;
|
||||
extern U32 gPacketsIn;
|
||||
|
||||
@@ -112,7 +114,7 @@ LLFloaterAbout::LLFloaterAbout()
|
||||
LLViewerTextEditor *credits_widget =
|
||||
getChild<LLViewerTextEditor>("credits_editor", true);
|
||||
|
||||
LLViewerTextEditor *licenses_widget =
|
||||
LLViewerTextEditor *licenses_widget =
|
||||
getChild<LLViewerTextEditor>("licenses_editor", true);
|
||||
|
||||
childSetAction("copy_btn", onAboutClickCopyToClipboard, this);
|
||||
@@ -271,17 +273,6 @@ LLFloaterAbout::LLFloaterAbout()
|
||||
// [/RLVa:KB]
|
||||
support.append("\n\n");
|
||||
|
||||
support.append("Viewer SSE Version: ");
|
||||
#if _M_IX86_FP > 0 //Windows
|
||||
support.append(llformat("SSE%i\n", _M_IX86_FP ));
|
||||
#elif defined(__SSE2__) //GCC
|
||||
support.append("SSE2\n");
|
||||
#elif defined(__SSE__) //GCC
|
||||
support.append("SSE\n");
|
||||
#else
|
||||
support.append("None\n");
|
||||
#endif
|
||||
|
||||
support.append("libcurl Version: ");
|
||||
support.append( LLCurl::getVersionString() );
|
||||
support.append("\n");
|
||||
@@ -296,16 +287,8 @@ LLFloaterAbout::LLFloaterAbout()
|
||||
support.append("\n");
|
||||
|
||||
// TODO: Implement media plugin version query
|
||||
|
||||
support.append("Qt Webkit Version: ");
|
||||
support.append(
|
||||
#if LL_LINUX && defined(__x86_64__)
|
||||
"4.8.6"
|
||||
#else
|
||||
"4.7.1"
|
||||
#endif
|
||||
);
|
||||
support.append(" (version number hard-coded)");
|
||||
support.append("LLCEFLib/CEF Version: ");
|
||||
support.append(LLCEFLIB_VERSION);
|
||||
support.append("\n");
|
||||
|
||||
if (gPacketsIn > 0)
|
||||
@@ -331,25 +314,25 @@ LLFloaterAbout::LLFloaterAbout()
|
||||
credits_widget->setTakesFocus(TRUE);
|
||||
credits_widget->setHandleEditKeysDirectly(TRUE);
|
||||
|
||||
// Get the Versions and Copyrights, created at build time
|
||||
std::string licenses_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "packages-info.txt");
|
||||
llifstream licenses_file;
|
||||
licenses_file.open(licenses_path); /* Flawfinder: ignore */
|
||||
if (licenses_file.is_open())
|
||||
{
|
||||
std::string license_line;
|
||||
licenses_widget->clear();
|
||||
while (std::getline(licenses_file, license_line))
|
||||
{
|
||||
licenses_widget->appendColoredText(license_line + "\n", FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor"));
|
||||
}
|
||||
licenses_file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
// this case will use the (out of date) hard coded value from the XUI
|
||||
LL_INFOS("AboutInit") << "Could not read licenses file at " << licenses_path << LL_ENDL;
|
||||
}
|
||||
// Get the Versions and Copyrights, created at build time
|
||||
std::string licenses_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "packages-info.txt");
|
||||
llifstream licenses_file;
|
||||
licenses_file.open(licenses_path); /* Flawfinder: ignore */
|
||||
if (licenses_file.is_open())
|
||||
{
|
||||
std::string license_line;
|
||||
licenses_widget->clear();
|
||||
while (std::getline(licenses_file, license_line))
|
||||
{
|
||||
licenses_widget->appendColoredText(license_line + "\n", FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor"));
|
||||
}
|
||||
licenses_file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
// this case will use the (out of date) hard coded value from the XUI
|
||||
LL_INFOS("AboutInit") << "Could not read licenses file at " << licenses_path << LL_ENDL;
|
||||
}
|
||||
licenses_widget->setCursorPos(0);
|
||||
licenses_widget->setEnabled(FALSE);
|
||||
licenses_widget->setTakesFocus(TRUE);
|
||||
|
||||
@@ -412,6 +412,23 @@ BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
BOOL LLMediaCtrl::handleKeyUpHere(KEY key, MASK mask)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (mMediaSource)
|
||||
{
|
||||
result = mMediaSource->handleKeyUpHere(key, mask);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
result = LLPanel::handleKeyUpHere(key, mask);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility )
|
||||
@@ -940,7 +957,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
|
||||
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MEDIA_EVENT_NAVIGATE_BEGIN:
|
||||
{
|
||||
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;
|
||||
@@ -995,21 +1012,23 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
|
||||
std::string target = self->getClickTarget();
|
||||
std::string uuid = self->getClickUUID();
|
||||
|
||||
LLNotification::Params notify_params("PopupAttempt");
|
||||
notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID);
|
||||
notify_params.functor(boost::bind(&LLMediaCtrl::onPopup, this, _1, _2));
|
||||
LLWeb::loadURL(url, target, std::string());
|
||||
|
||||
if (mTrusted)
|
||||
{
|
||||
LLNotifications::instance().forceResponse(notify_params, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotifications::instance().add(notify_params);
|
||||
}
|
||||
//LLNotification::Params notify_params("PopupAttempt");
|
||||
//notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID);
|
||||
//notify_params.functor(boost::bind(&LLMediaCtrl::onPopup, this, _1, _2));
|
||||
|
||||
//if (mTrusted)
|
||||
//{
|
||||
// LLNotifications::instance().forceResponse(notify_params, 0);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// LLNotifications::instance().add(notify_params);
|
||||
//}
|
||||
break;
|
||||
};
|
||||
|
||||
|
||||
case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
|
||||
{
|
||||
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL;
|
||||
@@ -1076,6 +1095,13 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
|
||||
};
|
||||
break;
|
||||
|
||||
case MEDIA_EVENT_FILE_DOWNLOAD:
|
||||
{
|
||||
//llinfos << "Media event - file download requested - filename is " << self->getFileDownloadFilename() << llendl;
|
||||
//LLNotificationsUtil::add("MediaFileDownloadUnsupported");
|
||||
};
|
||||
break;
|
||||
|
||||
case MEDIA_EVENT_DEBUG_MESSAGE:
|
||||
{
|
||||
LL_INFOS("media") << self->getDebugMessageText() << LL_ENDL;
|
||||
@@ -1142,6 +1168,16 @@ void LLMediaCtrl::setTrustedContent(bool trusted)
|
||||
}
|
||||
}
|
||||
|
||||
bool LLMediaCtrl::wantsKeyUpKeyDown() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLMediaCtrl::wantsReturnKey() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLXMLNodePtr LLMediaCtrl::getXML(bool save_children) const
|
||||
{
|
||||
|
||||
@@ -160,6 +160,7 @@ public:
|
||||
|
||||
// over-rides
|
||||
virtual BOOL handleKeyHere( KEY key, MASK mask);
|
||||
virtual BOOL handleKeyUpHere(KEY key, MASK mask);
|
||||
virtual void handleVisibilityChange ( BOOL new_visibility );
|
||||
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
|
||||
virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
@@ -178,6 +179,10 @@ public:
|
||||
|
||||
LLUUID getTextureID() {return mMediaTextureID;}
|
||||
|
||||
// The Browser windows want keyup and keydown events. Overridden from LLFocusableElement to return true.
|
||||
virtual bool wantsKeyUpKeyDown() const;
|
||||
virtual bool wantsReturnKey() const;
|
||||
|
||||
protected:
|
||||
void convertInputCoords(S32& x, S32& y);
|
||||
|
||||
|
||||
@@ -749,6 +749,11 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
LL_INFOS() << "LLToolPie handleDoubleClick (becoming mouseDown)" << LL_ENDL;
|
||||
}
|
||||
|
||||
if (handleMediaDblClick(mPick))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))
|
||||
{
|
||||
if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||
|
||||
@@ -879,56 +884,110 @@ static void handle_click_action_play()
|
||||
|
||||
bool LLToolPie::handleMediaClick(const LLPickInfo& pick)
|
||||
{
|
||||
//FIXME: how do we handle object in different parcel than us?
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
LLPointer<LLViewerObject> objectp = pick.getObject();
|
||||
//FIXME: how do we handle object in different parcel than us?
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
LLPointer<LLViewerObject> objectp = pick.getObject();
|
||||
|
||||
|
||||
if (!parcel ||
|
||||
objectp.isNull() ||
|
||||
pick.mObjectFace < 0 ||
|
||||
pick.mObjectFace >= objectp->getNumTEs())
|
||||
{
|
||||
LLViewerMediaFocus::getInstance()->clearFocus();
|
||||
if (!parcel ||
|
||||
objectp.isNull() ||
|
||||
pick.mObjectFace < 0 ||
|
||||
pick.mObjectFace >= objectp->getNumTEs())
|
||||
{
|
||||
LLViewerMediaFocus::getInstance()->clearFocus();
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Does this face have media?
|
||||
const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
|
||||
if(!tep)
|
||||
return false;
|
||||
// Does this face have media?
|
||||
const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
|
||||
if (!tep)
|
||||
return false;
|
||||
|
||||
LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
|
||||
if(!mep)
|
||||
return false;
|
||||
|
||||
viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
|
||||
LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
|
||||
if (!mep)
|
||||
return false;
|
||||
|
||||
if (gSavedSettings.getBOOL("MediaOnAPrimUI"))
|
||||
{
|
||||
if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull())
|
||||
{
|
||||
// It's okay to give this a null impl
|
||||
LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure keyboard focus is set to the media focus object.
|
||||
gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance());
|
||||
LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl();
|
||||
|
||||
media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE));
|
||||
mMediaMouseCaptureID = mep->getMediaID();
|
||||
setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture.
|
||||
}
|
||||
viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
|
||||
|
||||
return true;
|
||||
}
|
||||
if (gSavedSettings.getBOOL("MediaOnAPrimUI"))
|
||||
{
|
||||
if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull())
|
||||
{
|
||||
// It's okay to give this a null impl
|
||||
LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure keyboard focus is set to the media focus object.
|
||||
gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance());
|
||||
LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl();
|
||||
|
||||
LLViewerMediaFocus::getInstance()->clearFocus();
|
||||
media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE));
|
||||
mMediaMouseCaptureID = mep->getMediaID();
|
||||
setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture.
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
LLViewerMediaFocus::getInstance()->clearFocus();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLToolPie::handleMediaDblClick(const LLPickInfo& pick)
|
||||
{
|
||||
//FIXME: how do we handle object in different parcel than us?
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
LLPointer<LLViewerObject> objectp = pick.getObject();
|
||||
|
||||
|
||||
if (!parcel ||
|
||||
objectp.isNull() ||
|
||||
pick.mObjectFace < 0 ||
|
||||
pick.mObjectFace >= objectp->getNumTEs())
|
||||
{
|
||||
LLViewerMediaFocus::getInstance()->clearFocus();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Does this face have media?
|
||||
const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
|
||||
if (!tep)
|
||||
return false;
|
||||
|
||||
LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
|
||||
if (!mep)
|
||||
return false;
|
||||
|
||||
viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
|
||||
|
||||
if (gSavedSettings.getBOOL("MediaOnAPrimUI"))
|
||||
{
|
||||
if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull())
|
||||
{
|
||||
// It's okay to give this a null impl
|
||||
LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure keyboard focus is set to the media focus object.
|
||||
gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance());
|
||||
LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl();
|
||||
|
||||
media_impl->mouseDoubleClick(pick.mUVCoords, gKeyboard->currentMask(TRUE));
|
||||
mMediaMouseCaptureID = mep->getMediaID();
|
||||
setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture.
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LLViewerMediaFocus::getInstance()->clearFocus();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLToolPie::handleMediaHover(const LLPickInfo& pick)
|
||||
@@ -939,7 +998,7 @@ bool LLToolPie::handleMediaHover(const LLPickInfo& pick)
|
||||
|
||||
LLPointer<LLViewerObject> objectp = pick.getObject();
|
||||
|
||||
// Early out cases. Must clear media hover.
|
||||
// Early out cases. Must clear media hover.
|
||||
// did not hit an object or did not hit a valid face
|
||||
if ( objectp.isNull() ||
|
||||
pick.mObjectFace < 0 ||
|
||||
|
||||
@@ -89,6 +89,7 @@ private:
|
||||
ECursorType cursorFromObject(LLViewerObject* object);
|
||||
|
||||
bool handleMediaClick(const LLPickInfo& info);
|
||||
bool handleMediaDblClick(const LLPickInfo& info);
|
||||
bool handleMediaHover(const LLPickInfo& info);
|
||||
bool handleMediaMouseUp();
|
||||
|
||||
|
||||
@@ -706,7 +706,10 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL
|
||||
return mKeyHandledByUI[translated_key];
|
||||
}
|
||||
|
||||
|
||||
BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask)
|
||||
{
|
||||
return gViewerWindow->handleKeyUp(translated_key, translated_mask);
|
||||
}
|
||||
|
||||
BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name)
|
||||
{
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
LLViewerKeyboard();
|
||||
|
||||
BOOL handleKey(KEY key, MASK mask, BOOL repeated);
|
||||
BOOL handleKeyUp(KEY key, MASK mask);
|
||||
|
||||
S32 loadBindings(const std::string& filename); // returns number bound, 0 on error
|
||||
S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error
|
||||
|
||||
@@ -1832,7 +1832,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
|
||||
|
||||
// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
|
||||
// If a spare was already created before PluginAttachDebuggerToPlugins was set, don't use it.
|
||||
if((plugin_basename == "media_plugin_webkit") &&
|
||||
if ((plugin_basename == "media_plugin_cef") &&
|
||||
!gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))
|
||||
{
|
||||
media_source = LLViewerMedia::getSpareBrowserMediaSource();
|
||||
@@ -1853,20 +1853,26 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
|
||||
{
|
||||
std::string launcher_name = gDirUtilp->getLLPluginLauncher();
|
||||
std::string plugin_name = gDirUtilp->getLLPluginFilename(plugin_basename);
|
||||
std::string user_data_path = gDirUtilp->getOSUserAppDir();
|
||||
user_data_path += gDirUtilp->getDirDelimiter();
|
||||
|
||||
std::string user_data_path_cache = gDirUtilp->getCacheDir(false);
|
||||
user_data_path_cache += gDirUtilp->getDirDelimiter();
|
||||
|
||||
std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir();
|
||||
user_data_path_cookies += gDirUtilp->getDirDelimiter();
|
||||
|
||||
std::string user_data_path_logs = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
|
||||
|
||||
// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)
|
||||
// If the linden username returned is blank, that can only mean we are
|
||||
// at the login page displaying login Web page or Web browser test via Develop menu.
|
||||
// In this case we just use whatever gDirUtilp->getOSUserAppDir() gives us (this
|
||||
// is what we always used before this change)
|
||||
std::string linden_user_dir = gDirUtilp->getLindenUserDir(true);
|
||||
std::string linden_user_dir = gDirUtilp->getLindenUserDir();
|
||||
if ( ! linden_user_dir.empty() )
|
||||
{
|
||||
// gDirUtilp->getLindenUserDir() is whole path, not just Linden name
|
||||
user_data_path = linden_user_dir;
|
||||
user_data_path += gDirUtilp->getDirDelimiter();
|
||||
user_data_path_cookies = linden_user_dir;
|
||||
user_data_path_cookies += gDirUtilp->getDirDelimiter();
|
||||
};
|
||||
|
||||
// See if the plugin executable exists
|
||||
@@ -1883,7 +1889,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
|
||||
{
|
||||
media_source = new LLPluginClassMedia(owner);
|
||||
media_source->setSize(default_width, default_height);
|
||||
media_source->setUserDataPath(user_data_path);
|
||||
media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies, user_data_path_logs);
|
||||
media_source->setLanguageCode(LLUI::getLanguage());
|
||||
|
||||
// collect 'cookies enabled' setting from prefs and send to embedded browser
|
||||
@@ -1901,6 +1907,9 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
|
||||
bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
|
||||
media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled );
|
||||
|
||||
// need to set agent string here before instance created
|
||||
media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent());
|
||||
|
||||
media_source->setTarget(target);
|
||||
|
||||
const std::string plugin_dir = gDirUtilp->getLLPluginDir();
|
||||
@@ -2426,6 +2435,18 @@ void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords, MASK mask)
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerMediaImpl::mouseDoubleClick(const LLVector2& texture_coords, MASK mask)
|
||||
{
|
||||
LLPluginClassMedia* mMediaSource = getMediaPlugin();
|
||||
if (mMediaSource)
|
||||
{
|
||||
S32 x, y;
|
||||
scaleTextureCoords(texture_coords, &x, &y);
|
||||
|
||||
mouseDoubleClick(x, y, mask);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLViewerMediaImpl::mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button)
|
||||
{
|
||||
@@ -2779,7 +2800,7 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
|
||||
{
|
||||
// FIXME: THIS IS SO WRONG.
|
||||
// Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it...
|
||||
if( MASK_CONTROL & mask && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END)
|
||||
if (MASK_CONTROL & mask && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
@@ -2810,18 +2831,38 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
|
||||
|
||||
if(!result)
|
||||
{
|
||||
|
||||
LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
|
||||
|
||||
result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask, native_key_data);
|
||||
// Since the viewer internal event dispatching doesn't give us key-up events, simulate one here.
|
||||
(void)mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP ,key, mask, native_key_data);
|
||||
result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN, key, mask, native_key_data);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool LLViewerMediaImpl::handleKeyUpHere(KEY key, MASK mask)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
LLPluginClassMedia* mMediaSource = getMediaPlugin();
|
||||
|
||||
if (mMediaSource)
|
||||
{
|
||||
// FIXME: THIS IS SO WRONG.
|
||||
// Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it...
|
||||
if (MASK_CONTROL & mask && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
|
||||
result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP, key, mask, native_key_data);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)
|
||||
{
|
||||
@@ -3221,13 +3262,13 @@ bool LLViewerMediaImpl::isForcedUnloaded() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// If this media's class is not supposed to be shown, unload
|
||||
if (!shouldShowBasedOnClass())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3240,19 +3281,19 @@ bool LLViewerMediaImpl::isPlayable() const
|
||||
// All of the forced-unloaded criteria also imply not playable.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(hasMedia())
|
||||
{
|
||||
// Anything that's already playing is, by definition, playable.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if(!mMediaURL.empty())
|
||||
{
|
||||
// If something has navigated the instance, it's ready to be played.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -234,6 +234,7 @@ public:
|
||||
void mouseDown(const LLVector2& texture_coords, MASK mask, S32 button = 0);
|
||||
void mouseUp(const LLVector2& texture_coords, MASK mask, S32 button = 0);
|
||||
void mouseMove(const LLVector2& texture_coords, MASK mask);
|
||||
void mouseDoubleClick(const LLVector2& texture_coords, MASK mask);
|
||||
void mouseDoubleClick(S32 x,S32 y, MASK mask, S32 button = 0);
|
||||
void scrollWheel(S32 x, S32 y, MASK mask);
|
||||
void mouseCapture();
|
||||
@@ -247,6 +248,7 @@ public:
|
||||
void navigateInternal();
|
||||
void navigateStop();
|
||||
bool handleKeyHere(KEY key, MASK mask);
|
||||
bool handleKeyUpHere(KEY key, MASK mask);
|
||||
bool handleUnicodeCharHere(llwchar uni_char);
|
||||
bool canNavigateForward();
|
||||
bool canNavigateBack();
|
||||
@@ -257,6 +259,7 @@ public:
|
||||
void setHomeURL(const std::string& home_url, const std::string& mime_type = LLStringUtil::null) { mHomeURL = home_url; mHomeMimeType = mime_type;};
|
||||
void clearCache();
|
||||
void setPageZoomFactor( double factor );
|
||||
double getPageZoomFactor() {return mZoomFactor;}
|
||||
std::string getMimeType() { return mMimeType; }
|
||||
void scaleMouse(S32 *mouse_x, S32 *mouse_y);
|
||||
void scaleTextureCoords(const LLVector2& texture_coords, S32 *x, S32 *y);
|
||||
|
||||
@@ -351,6 +351,18 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL LLViewerMediaFocus::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
|
||||
{
|
||||
LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
|
||||
if (media_impl)
|
||||
{
|
||||
media_impl->handleKeyUpHere(key, mask);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL LLViewerMediaFocus::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
|
||||
{
|
||||
LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
|
||||
@@ -434,7 +446,6 @@ void LLViewerMediaFocus::update()
|
||||
{
|
||||
mMediaControls.get()->setMediaFace(NULL, 0, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,3 +614,13 @@ LLUUID LLViewerMediaFocus::getControlsMediaID()
|
||||
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
||||
bool LLViewerMediaFocus::wantsKeyUpKeyDown() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLViewerMediaFocus::wantsReturnKey() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
|
||||
/*virtual*/ bool getFocus();
|
||||
/*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
|
||||
/*virtual*/ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent);
|
||||
/*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
|
||||
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
|
||||
|
||||
@@ -87,6 +88,10 @@ public:
|
||||
// Return the ID of the media instance the controls are currently attached to (either focus or hover).
|
||||
LLUUID getControlsMediaID();
|
||||
|
||||
// The MoaP object wants keyup and keydown events. Overridden to return true.
|
||||
virtual bool wantsKeyUpKeyDown() const;
|
||||
virtual bool wantsReturnKey() const;
|
||||
|
||||
protected:
|
||||
/*virtual*/ void onFocusReceived();
|
||||
/*virtual*/ void onFocusLost();
|
||||
|
||||
@@ -1362,7 +1362,11 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
|
||||
// it's all entered/processed.
|
||||
if (key == KEY_RETURN && mask == MASK_NONE)
|
||||
{
|
||||
return FALSE;
|
||||
// RIDER: although, at times some of the controlls (in particular the CEF viewer
|
||||
// would like to know about the KEYDOWN for an enter key... so ask and pass it along.
|
||||
LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
|
||||
if (keyboard_focus && !keyboard_focus->wantsReturnKey())
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return gViewerKeyboard.handleKey(key, mask, repeated);
|
||||
@@ -1380,10 +1384,9 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
|
||||
tool_inspectp->keyUp(key, mask);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return gViewerKeyboard.handleKeyUp(key, mask);
|
||||
}
|
||||
|
||||
|
||||
void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
|
||||
{
|
||||
LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
|
||||
@@ -2681,6 +2684,46 @@ void LLViewerWindow::draw()
|
||||
#endif
|
||||
}
|
||||
|
||||
// Takes a single keyup event, usually when UI is visible
|
||||
BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
|
||||
{
|
||||
LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
|
||||
|
||||
if (keyboard_focus
|
||||
&& !(mask & (MASK_CONTROL | MASK_ALT))
|
||||
&& !gFocusMgr.getKeystrokesOnly())
|
||||
{
|
||||
// We have keyboard focus, and it's not an accelerator
|
||||
if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown())
|
||||
{
|
||||
return keyboard_focus->handleKeyUp(key, mask, FALSE);
|
||||
}
|
||||
else if (key < 0x80)
|
||||
{
|
||||
// Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
|
||||
return (gFocusMgr.getKeyboardFocus() != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (keyboard_focus)
|
||||
{
|
||||
if (keyboard_focus->handleKeyUp(key, mask, FALSE))
|
||||
{
|
||||
LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned true" << LL_ENDL;
|
||||
//LLViewerEventRecorder::instance().logKeyEvent(key, mask);
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned FALSE" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
// don't pass keys on to world when something in ui has focus
|
||||
return gFocusMgr.childHasKeyboardFocus(mRootView)
|
||||
|| LLMenuGL::getKeyboardMode()
|
||||
|| (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive());
|
||||
}
|
||||
|
||||
// Takes a single keydown event, usually when UI is visible
|
||||
BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
||||
{
|
||||
@@ -2699,7 +2742,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
||||
&& !gFocusMgr.getKeystrokesOnly())
|
||||
{
|
||||
// We have keyboard focus, and it's not an accelerator
|
||||
if (key < 0x80)
|
||||
if (gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->wantsKeyUpKeyDown())
|
||||
{
|
||||
return gFocusMgr.getKeyboardFocus()->handleKey(key, mask, FALSE );
|
||||
}
|
||||
else if (key < 0x80)
|
||||
{
|
||||
// Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
|
||||
return (gFocusMgr.getKeyboardFocus() != NULL);
|
||||
|
||||
@@ -292,6 +292,7 @@ public:
|
||||
void updateKeyboardFocus();
|
||||
|
||||
BOOL handleKey(KEY key, MASK mask);
|
||||
BOOL handleKeyUp(KEY key, MASK mask);
|
||||
void handleScrollWheel (S32 clicks);
|
||||
|
||||
// Hide normal UI when a logon fails, re-show everything when logon is attempted again
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
none
|
||||
</defaultwidget>
|
||||
<defaultimpl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</defaultimpl>
|
||||
<widgetset name="web">
|
||||
<label name="web_label">
|
||||
@@ -131,7 +131,7 @@
|
||||
none
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="audio/*">
|
||||
@@ -164,7 +164,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
|
||||
@@ -186,7 +186,7 @@
|
||||
web
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/ogg">
|
||||
@@ -208,7 +208,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/postscript">
|
||||
@@ -219,7 +219,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/rtf">
|
||||
@@ -230,7 +230,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/smil">
|
||||
@@ -241,7 +241,7 @@
|
||||
movie
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/xhtml+xml">
|
||||
@@ -252,7 +252,7 @@
|
||||
web
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/x-director">
|
||||
@@ -263,7 +263,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="audio/mid">
|
||||
@@ -318,7 +318,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="image/gif">
|
||||
@@ -329,7 +329,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="image/jpeg">
|
||||
@@ -340,7 +340,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="image/png">
|
||||
@@ -351,7 +351,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="image/svg+xml">
|
||||
@@ -362,7 +362,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="image/tiff">
|
||||
@@ -373,7 +373,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="text/html">
|
||||
@@ -384,7 +384,7 @@
|
||||
web
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="text/plain">
|
||||
@@ -395,7 +395,7 @@
|
||||
text
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="text/xml">
|
||||
@@ -406,7 +406,7 @@
|
||||
text
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="video/mpeg">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
none
|
||||
</defaultwidget>
|
||||
<defaultimpl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</defaultimpl>
|
||||
<widgetset name="web">
|
||||
<label name="web_label">
|
||||
@@ -120,7 +120,7 @@
|
||||
none
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="none/none">
|
||||
@@ -131,7 +131,7 @@
|
||||
none
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="audio/*">
|
||||
@@ -164,7 +164,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
|
||||
@@ -186,7 +186,7 @@
|
||||
web
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/ogg">
|
||||
@@ -208,7 +208,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/postscript">
|
||||
@@ -219,7 +219,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/rtf">
|
||||
@@ -230,7 +230,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/smil">
|
||||
@@ -241,7 +241,7 @@
|
||||
movie
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/xhtml+xml">
|
||||
@@ -252,7 +252,7 @@
|
||||
web
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="application/x-director">
|
||||
@@ -263,7 +263,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="audio/mid">
|
||||
@@ -318,7 +318,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="image/gif">
|
||||
@@ -329,7 +329,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="image/jpeg">
|
||||
@@ -340,7 +340,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="image/png">
|
||||
@@ -351,7 +351,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="image/svg+xml">
|
||||
@@ -362,7 +362,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="image/tiff">
|
||||
@@ -373,7 +373,7 @@
|
||||
image
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="text/html">
|
||||
@@ -384,7 +384,7 @@
|
||||
web
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="text/plain">
|
||||
@@ -395,7 +395,7 @@
|
||||
text
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype name="text/xml">
|
||||
@@ -406,7 +406,7 @@
|
||||
text
|
||||
</widgettype>
|
||||
<impl>
|
||||
media_plugin_webkit
|
||||
media_plugin_cef
|
||||
</impl>
|
||||
</mimetype>
|
||||
<mimetype menu="1" name="video/mpeg">
|
||||
|
||||
@@ -321,41 +321,103 @@ class WindowsManifest(ViewerManifest):
|
||||
self.path("media_plugin_quicktime.dll")
|
||||
self.end_prefix()
|
||||
|
||||
# Media plugins - WebKit/Qt
|
||||
if self.prefix(src='../plugins/webkit/%s' % self.args['configuration'], dst="llplugin"):
|
||||
self.path("media_plugin_webkit.dll")
|
||||
# Media plugins - CEF
|
||||
if self.prefix(src='../plugins/cef/%s' % self.args['configuration'], dst="llplugin"):
|
||||
self.path("media_plugin_cef.dll")
|
||||
self.end_prefix()
|
||||
|
||||
# For WebKit/Qt plugin runtimes
|
||||
if self.prefix(src=self.args['configuration']+"/llplugin", dst="llplugin"):
|
||||
self.path("libeay32.dll")
|
||||
self.path("qtcore4.dll")
|
||||
self.path("qtgui4.dll")
|
||||
self.path("qtnetwork4.dll")
|
||||
self.path("qtopengl4.dll")
|
||||
self.path("qtwebkit4.dll")
|
||||
self.path("qtxmlpatterns4.dll")
|
||||
self.path("ssleay32.dll")
|
||||
|
||||
# For WebKit/Qt plugin runtimes (image format plugins)
|
||||
if self.prefix(src="imageformats", dst="imageformats"):
|
||||
self.path("qgif4.dll")
|
||||
self.path("qico4.dll")
|
||||
self.path("qjpeg4.dll")
|
||||
self.path("qmng4.dll")
|
||||
self.path("qsvg4.dll")
|
||||
self.path("qtiff4.dll")
|
||||
self.end_prefix()
|
||||
|
||||
if self.prefix(src="codecs", dst="codecs"):
|
||||
self.path("qcncodecs4.dll")
|
||||
self.path("qjpcodecs4.dll")
|
||||
self.path("qkrcodecs4.dll")
|
||||
self.path("qtwcodecs4.dll")
|
||||
# CEF runtime files - debug
|
||||
if self.args['configuration'].lower() == 'debug':
|
||||
if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'debug'), dst="llplugin"):
|
||||
self.path("d3dcompiler_47.dll")
|
||||
self.path("libcef.dll")
|
||||
self.path("libEGL.dll")
|
||||
self.path("libGLESv2.dll")
|
||||
self.path("llceflib_host.exe")
|
||||
self.path("natives_blob.bin")
|
||||
self.path("snapshot_blob.bin")
|
||||
self.path("widevinecdmadapter.dll")
|
||||
self.path("wow_helper.exe")
|
||||
self.end_prefix()
|
||||
else:
|
||||
# CEF runtime files - not debug (release, relwithdebinfo etc.)
|
||||
if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"):
|
||||
self.path("d3dcompiler_47.dll")
|
||||
self.path("libcef.dll")
|
||||
self.path("libEGL.dll")
|
||||
self.path("libGLESv2.dll")
|
||||
self.path("llceflib_host.exe")
|
||||
self.path("natives_blob.bin")
|
||||
self.path("snapshot_blob.bin")
|
||||
self.path("widevinecdmadapter.dll")
|
||||
self.path("wow_helper.exe")
|
||||
self.end_prefix()
|
||||
|
||||
# CEF files common to all configurations
|
||||
if self.prefix(src=os.path.join(os.pardir, 'packages', 'resources'), dst="llplugin"):
|
||||
self.path("cef.pak")
|
||||
self.path("cef_100_percent.pak")
|
||||
self.path("cef_200_percent.pak")
|
||||
self.path("cef_extensions.pak")
|
||||
self.path("devtools_resources.pak")
|
||||
self.path("icudtl.dat")
|
||||
self.end_prefix()
|
||||
|
||||
if self.prefix(src=os.path.join(os.pardir, 'packages', 'resources', 'locales'), dst=os.path.join('llplugin', 'locales')):
|
||||
self.path("am.pak")
|
||||
self.path("ar.pak")
|
||||
self.path("bg.pak")
|
||||
self.path("bn.pak")
|
||||
self.path("ca.pak")
|
||||
self.path("cs.pak")
|
||||
self.path("da.pak")
|
||||
self.path("de.pak")
|
||||
self.path("el.pak")
|
||||
self.path("en-GB.pak")
|
||||
self.path("en-US.pak")
|
||||
self.path("es-419.pak")
|
||||
self.path("es.pak")
|
||||
self.path("et.pak")
|
||||
self.path("fa.pak")
|
||||
self.path("fi.pak")
|
||||
self.path("fil.pak")
|
||||
self.path("fr.pak")
|
||||
self.path("gu.pak")
|
||||
self.path("he.pak")
|
||||
self.path("hi.pak")
|
||||
self.path("hr.pak")
|
||||
self.path("hu.pak")
|
||||
self.path("id.pak")
|
||||
self.path("it.pak")
|
||||
self.path("ja.pak")
|
||||
self.path("kn.pak")
|
||||
self.path("ko.pak")
|
||||
self.path("lt.pak")
|
||||
self.path("lv.pak")
|
||||
self.path("ml.pak")
|
||||
self.path("mr.pak")
|
||||
self.path("ms.pak")
|
||||
self.path("nb.pak")
|
||||
self.path("nl.pak")
|
||||
self.path("pl.pak")
|
||||
self.path("pt-BR.pak")
|
||||
self.path("pt-PT.pak")
|
||||
self.path("ro.pak")
|
||||
self.path("ru.pak")
|
||||
self.path("sk.pak")
|
||||
self.path("sl.pak")
|
||||
self.path("sr.pak")
|
||||
self.path("sv.pak")
|
||||
self.path("sw.pak")
|
||||
self.path("ta.pak")
|
||||
self.path("te.pak")
|
||||
self.path("th.pak")
|
||||
self.path("tr.pak")
|
||||
self.path("uk.pak")
|
||||
self.path("vi.pak")
|
||||
self.path("zh-CN.pak")
|
||||
self.path("zh-TW.pak")
|
||||
self.end_prefix()
|
||||
|
||||
if not self.is_packaging_viewer():
|
||||
self.package_file = "copied_deps"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
add_subdirectory(base_basic)
|
||||
add_subdirectory(base_media)
|
||||
add_subdirectory(filepicker)
|
||||
add_subdirectory(webkit)
|
||||
add_subdirectory(cef)
|
||||
|
||||
if (LINUX)
|
||||
add_subdirectory(gstreamer010)
|
||||
|
||||
115
indra/plugins/cef/CMakeLists.txt
Normal file
115
indra/plugins/cef/CMakeLists.txt
Normal file
@@ -0,0 +1,115 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
project(media_plugin_cef)
|
||||
|
||||
include(00-Common)
|
||||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLPlugin)
|
||||
include(LLMath)
|
||||
include(LLRender)
|
||||
include(LLWindow)
|
||||
include(Linking)
|
||||
include(PluginAPI)
|
||||
include(MediaPluginBase)
|
||||
include(OpenGL)
|
||||
|
||||
include(CEFPlugin)
|
||||
|
||||
include_directories(
|
||||
${LLPLUGIN_INCLUDE_DIRS}
|
||||
${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
${LLIMAGE_INCLUDE_DIRS}
|
||||
${LLRENDER_INCLUDE_DIRS}
|
||||
${LLWINDOW_INCLUDE_DIRS}
|
||||
${CEF_INCLUDE_DIR}
|
||||
)
|
||||
include_directories(SYSTEM
|
||||
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
|
||||
### media_plugin_cef
|
||||
|
||||
if(NOT WORD_SIZE EQUAL 32)
|
||||
if(NOT WINDOWS) # not windows therefore gcc LINUX and DARWIN
|
||||
add_definitions(-fPIC)
|
||||
endif(NOT WINDOWS)
|
||||
endif(NOT WORD_SIZE EQUAL 32)
|
||||
|
||||
set(media_plugin_cef_SOURCE_FILES
|
||||
media_plugin_cef.cpp
|
||||
)
|
||||
|
||||
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"
|
||||
" 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_LINK_LIBRARIES
|
||||
${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_cef_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}
|
||||
)
|
||||
|
||||
add_dependencies(media_plugin_cef
|
||||
${LLPLUGIN_LIBRARIES}
|
||||
${MEDIA_PLUGIN_BASE_LIBRARIES}
|
||||
${LLCOMMON_LIBRARIES}
|
||||
)
|
||||
|
||||
target_link_libraries(media_plugin_cef
|
||||
${media_plugin_cef_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
if (WINDOWS)
|
||||
set_target_properties(
|
||||
media_plugin_cef
|
||||
PROPERTIES
|
||||
LINK_FLAGS "/MANIFEST:NO /NODEFAULTLIB:LIBCMT"
|
||||
LINK_FLAGS_DEBUG "/MANIFEST: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)
|
||||
@@ -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;
|
||||
@@ -35,9 +35,13 @@
|
||||
|
||||
#include "volume_catcher.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <QuickTime/QuickTime.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <list>
|
||||
|
||||
#if LL_DARWIN
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
struct VolumeCatcherStorage;
|
||||
|
||||
@@ -266,3 +270,6 @@ void VolumeCatcher::pump()
|
||||
// No periodic tasks are necessary for this implementation.
|
||||
}
|
||||
|
||||
#if LL_DARWIN
|
||||
#pragma GCC diagnostic warning "-Wdeprecated-declarations"
|
||||
#endif
|
||||
903
indra/plugins/cef/media_plugin_cef.cpp
Normal file
903
indra/plugins/cef/media_plugin_cef.cpp
Normal file
@@ -0,0 +1,903 @@
|
||||
/**
|
||||
* @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"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#pragma warning (disable : 4265)
|
||||
#endif
|
||||
|
||||
#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 <functional>
|
||||
#include "llceflib.h"
|
||||
#include "volume_catcher.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
class MediaPluginCEF :
|
||||
public MediaPluginBase
|
||||
{
|
||||
public:
|
||||
MediaPluginCEF(LLPluginInstance::sendMessageFunction send_message_function, LLPluginInstance* plugin_instance);
|
||||
~MediaPluginCEF();
|
||||
|
||||
/*virtual*/
|
||||
void receiveMessage(const char* message_string);
|
||||
|
||||
private:
|
||||
bool init();
|
||||
|
||||
void onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup);
|
||||
void onCustomSchemeURLCallback(std::string url);
|
||||
void onConsoleMessageCallback(std::string message, std::string source, int line);
|
||||
void onStatusMessageCallback(std::string value);
|
||||
void onTitleChangeCallback(std::string title);
|
||||
void onLoadStartCallback();
|
||||
void onRequestExitCallback();
|
||||
void onLoadEndCallback(int httpStatusCode);
|
||||
void onAddressChangeCallback(std::string url);
|
||||
void onNavigateURLCallback(std::string url, std::string target);
|
||||
bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
|
||||
void onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle);
|
||||
void onFileDownloadCallback(std::string filename);
|
||||
|
||||
void postDebugMessage(const std::string& msg);
|
||||
void authResponse(LLPluginMessage &message);
|
||||
|
||||
LLCEFLib::EKeyboardModifier decodeModifiers(std::string &modifiers);
|
||||
void deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers);
|
||||
void keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data);
|
||||
void unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data);
|
||||
|
||||
void checkEditState();
|
||||
void setVolume(F32 vol);
|
||||
|
||||
bool mEnableMediaPluginDebugging;
|
||||
std::string mHostLanguage;
|
||||
bool mCookiesEnabled;
|
||||
bool mPluginsEnabled;
|
||||
bool mJavascriptEnabled;
|
||||
std::string mUserAgentSubtring;
|
||||
std::string mAuthUsername;
|
||||
std::string mAuthPassword;
|
||||
bool mAuthOK;
|
||||
bool mCanCut;
|
||||
bool mCanCopy;
|
||||
bool mCanPaste;
|
||||
std::string mCachePath;
|
||||
std::string mCookiePath;
|
||||
std::string mLogFile;
|
||||
LLCEFLib* mLLCEFLib;
|
||||
|
||||
VolumeCatcher mVolumeCatcher;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction send_message_function, LLPluginInstance* plugin_instance) :
|
||||
MediaPluginBase(send_message_function, plugin_instance)
|
||||
{
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mDepth = 4;
|
||||
mPixels = 0;
|
||||
mEnableMediaPluginDebugging = false;
|
||||
mHostLanguage = "en";
|
||||
mCookiesEnabled = true;
|
||||
mPluginsEnabled = false;
|
||||
mJavascriptEnabled = true;
|
||||
mUserAgentSubtring = "";
|
||||
mAuthUsername = "";
|
||||
mAuthPassword = "";
|
||||
mAuthOK = false;
|
||||
mCanCut = false;
|
||||
mCanCopy = false;
|
||||
mCanPaste = false;
|
||||
mCachePath = "";
|
||||
mCookiePath = "";
|
||||
mLogFile = "";
|
||||
mLLCEFLib = new LLCEFLib();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
MediaPluginCEF::~MediaPluginCEF()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::postDebugMessage(const std::string& msg)
|
||||
{
|
||||
if (mEnableMediaPluginDebugging)
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "@Media Msg> " << msg;
|
||||
|
||||
LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message");
|
||||
debug_message.setValue("message_text", str.str());
|
||||
debug_message.setValue("message_level", "info");
|
||||
sendMessage(debug_message);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup)
|
||||
{
|
||||
if (mPixels && pixels)
|
||||
{
|
||||
if (is_popup)
|
||||
{
|
||||
for (int line = 0; line < height; ++line)
|
||||
{
|
||||
int inverted_y = mHeight - y - height;
|
||||
int src = line * width * mDepth;
|
||||
int dst = (inverted_y + line) * mWidth * mDepth + x * mDepth;
|
||||
|
||||
if (dst + width * mDepth < mWidth * mHeight * mDepth)
|
||||
{
|
||||
memcpy(mPixels + dst, pixels + src, width * mDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mWidth == width && mHeight == height)
|
||||
{
|
||||
memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
|
||||
}
|
||||
|
||||
}
|
||||
setDirty(0, 0, mWidth, mHeight);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line)
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "Console message: " << message << " in file(" << source << ") at line " << line;
|
||||
postDebugMessage(str.str());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onStatusMessageCallback(std::string value)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
|
||||
message.setValue("status", value);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onTitleChangeCallback(std::string title)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
|
||||
message.setValue("name", title);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onLoadStartCallback()
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
|
||||
//message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
|
||||
message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack());
|
||||
message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward());
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onRequestExitCallback()
|
||||
{
|
||||
mLLCEFLib->shutdown();
|
||||
|
||||
LLPluginMessage message("base", "goodbye");
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onLoadEndCallback(int httpStatusCode)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
|
||||
//message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
|
||||
message.setValueS32("result_code", httpStatusCode);
|
||||
message.setValueBoolean("history_back_available", mLLCEFLib->canGoBack());
|
||||
message.setValueBoolean("history_forward_available", mLLCEFLib->canGoForward());
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onAddressChangeCallback(std::string url)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
|
||||
message.setValue("uri", url);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onNavigateURLCallback(std::string url, std::string target)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
|
||||
message.setValue("uri", url);
|
||||
message.setValue("target", target);
|
||||
message.setValue("uuid", ""); // not used right now
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onCustomSchemeURLCallback(std::string url)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
|
||||
message.setValue("uri", url);
|
||||
message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password)
|
||||
{
|
||||
mAuthOK = false;
|
||||
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request");
|
||||
message.setValue("url", host);
|
||||
message.setValue("realm", realm);
|
||||
message.setValueBoolean("blocking_request", true);
|
||||
|
||||
// The "blocking_request" key in the message means this sendMessage call will block until a response is received.
|
||||
sendMessage(message);
|
||||
|
||||
if (mAuthOK)
|
||||
{
|
||||
username = mAuthUsername;
|
||||
password = mAuthPassword;
|
||||
}
|
||||
|
||||
return mAuthOK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::onFileDownloadCallback(const std::string filename)
|
||||
{
|
||||
mAuthOK = false;
|
||||
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
|
||||
message.setValue("filename", filename);
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void MediaPluginCEF::onCursorChangedCallback(LLCEFLib::ECursorType type, unsigned int handle)
|
||||
{
|
||||
std::string name = "";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LLCEFLib::CT_POINTER:
|
||||
name = "arrow";
|
||||
break;
|
||||
case LLCEFLib::CT_IBEAM:
|
||||
name = "ibeam";
|
||||
break;
|
||||
case LLCEFLib::CT_NORTHSOUTHRESIZE:
|
||||
name = "splitv";
|
||||
break;
|
||||
case LLCEFLib::CT_EASTWESTRESIZE:
|
||||
name = "splith";
|
||||
break;
|
||||
case LLCEFLib::CT_HAND:
|
||||
name = "hand";
|
||||
break;
|
||||
|
||||
default:
|
||||
LL_WARNS() << "Unknown cursor ID: " << (int)type << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed");
|
||||
message.setValue("name", name);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void MediaPluginCEF::authResponse(LLPluginMessage &message)
|
||||
{
|
||||
mAuthOK = message.getValueBoolean("ok");
|
||||
if (mAuthOK)
|
||||
{
|
||||
mAuthUsername = message.getValue("username");
|
||||
mAuthPassword = message.getValue("password");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
std::string generate_cef_locale(std::string in)
|
||||
{
|
||||
if (in == "en")
|
||||
in = "en-US";
|
||||
else if (in == "pt")
|
||||
in = "pt-BR";
|
||||
else if (in == "zh")
|
||||
in = "zh-CN";
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
void MediaPluginCEF::receiveMessage(const char* message_string)
|
||||
{
|
||||
// std::cerr << "MediaPluginCEF::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
|
||||
LLPluginMessage message_in;
|
||||
|
||||
if (message_in.parse(message_string) >= 0)
|
||||
{
|
||||
std::string message_class = message_in.getClass();
|
||||
std::string message_name = message_in.getName();
|
||||
if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
|
||||
{
|
||||
if (message_name == "init")
|
||||
{
|
||||
LLPluginMessage message("base", "init_response");
|
||||
LLSD versions = LLSD::emptyMap();
|
||||
versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
|
||||
versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
|
||||
versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
|
||||
message.setValueLLSD("versions", versions);
|
||||
|
||||
std::string plugin_version = "CEF plugin 1.1.3";
|
||||
message.setValue("plugin_version", plugin_version);
|
||||
sendMessage(message);
|
||||
}
|
||||
else if (message_name == "idle")
|
||||
{
|
||||
mLLCEFLib->update();
|
||||
|
||||
mVolumeCatcher.pump();
|
||||
// this seems bad but unless the state changes (it won't until we figure out
|
||||
// how to get CEF to tell us if copy/cut/paste is available) then this function
|
||||
// will return immediately
|
||||
checkEditState();
|
||||
}
|
||||
else if (message_name == "cleanup")
|
||||
{
|
||||
mLLCEFLib->requestExit();
|
||||
}
|
||||
else if (message_name == "shm_added")
|
||||
{
|
||||
SharedSegmentInfo info;
|
||||
info.mAddress = message_in.getValuePointer("address");
|
||||
info.mSize = (size_t)message_in.getValueS32("size");
|
||||
std::string name = message_in.getValue("name");
|
||||
|
||||
mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
|
||||
|
||||
}
|
||||
else if (message_name == "shm_remove")
|
||||
{
|
||||
std::string name = message_in.getValue("name");
|
||||
|
||||
SharedSegmentMap::iterator iter = mSharedSegments.find(name);
|
||||
if (iter != mSharedSegments.end())
|
||||
{
|
||||
if (mPixels == iter->second.mAddress)
|
||||
{
|
||||
mPixels = NULL;
|
||||
mTextureSegmentName.clear();
|
||||
}
|
||||
mSharedSegments.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
LLPluginMessage message("base", "shm_remove_response");
|
||||
message.setValue("name", name);
|
||||
sendMessage(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
|
||||
{
|
||||
if (message_name == "init")
|
||||
{
|
||||
// event callbacks from LLCefLib
|
||||
mLLCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6));
|
||||
mLLCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
|
||||
mLLCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
mLLCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
|
||||
mLLCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
|
||||
mLLCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));
|
||||
mLLCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1));
|
||||
mLLCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));
|
||||
mLLCEFLib->setOnNavigateURLCallback(std::bind(&MediaPluginCEF::onNavigateURLCallback, this, std::placeholders::_1, std::placeholders::_2));
|
||||
mLLCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
|
||||
mLLCEFLib->setOnFileDownloadCallback(std::bind(&MediaPluginCEF::onFileDownloadCallback, this, std::placeholders::_1));
|
||||
mLLCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1, std::placeholders::_2));
|
||||
mLLCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this));
|
||||
|
||||
LLCEFLib::LLCEFLibSettings settings;
|
||||
settings.initial_width = 1024;
|
||||
settings.initial_height = 1024;
|
||||
settings.plugins_enabled = mPluginsEnabled;
|
||||
settings.javascript_enabled = mJavascriptEnabled;
|
||||
settings.cookies_enabled = mCookiesEnabled;
|
||||
settings.cookie_store_path = mCookiePath;
|
||||
settings.cache_enabled = true;
|
||||
settings.cache_path = mCachePath;
|
||||
settings.locale = generate_cef_locale(mHostLanguage);
|
||||
settings.accept_language_list = mHostLanguage;
|
||||
settings.user_agent_substring = mLLCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
|
||||
settings.debug_output = mEnableMediaPluginDebugging;
|
||||
settings.log_file = mLogFile;
|
||||
|
||||
bool result = mLLCEFLib->init(settings);
|
||||
if (!result)
|
||||
{
|
||||
// if this fails, the media system in viewer will put up a message
|
||||
}
|
||||
|
||||
// Plugin gets to decide the texture parameters to use.
|
||||
mDepth = 4;
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
|
||||
message.setValueS32("default_width", 1024);
|
||||
message.setValueS32("default_height", 1024);
|
||||
message.setValueS32("depth", mDepth);
|
||||
message.setValueU32("internalformat", GL_RGB);
|
||||
message.setValueU32("format", GL_BGRA);
|
||||
message.setValueU32("type", GL_UNSIGNED_BYTE);
|
||||
message.setValueBoolean("coords_opengl", true);
|
||||
sendMessage(message);
|
||||
}
|
||||
else if (message_name == "set_user_data_path")
|
||||
{
|
||||
std::string user_data_path_cache = message_in.getValue("cache_path");
|
||||
std::string user_data_path_cookies = message_in.getValue("cookies_path");
|
||||
std::string user_data_path_logs = message_in.getValue("logs_path");
|
||||
mCachePath = user_data_path_cache + "cef_cache";
|
||||
mCookiePath = user_data_path_cookies + "cef_cookies";
|
||||
mLogFile = user_data_path_logs + "cef.log";
|
||||
}
|
||||
else if (message_name == "size_change")
|
||||
{
|
||||
std::string name = message_in.getValue("name");
|
||||
S32 width = message_in.getValueS32("width");
|
||||
S32 height = message_in.getValueS32("height");
|
||||
S32 texture_width = message_in.getValueS32("texture_width");
|
||||
S32 texture_height = message_in.getValueS32("texture_height");
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
// Find the shared memory region with this name
|
||||
SharedSegmentMap::iterator iter = mSharedSegments.find(name);
|
||||
if (iter != mSharedSegments.end())
|
||||
{
|
||||
mPixels = (unsigned char*)iter->second.mAddress;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
|
||||
mTextureWidth = texture_width;
|
||||
mTextureHeight = texture_height;
|
||||
};
|
||||
};
|
||||
|
||||
mLLCEFLib->setSize(mWidth, mHeight);
|
||||
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
|
||||
message.setValue("name", name);
|
||||
message.setValueS32("width", width);
|
||||
message.setValueS32("height", height);
|
||||
message.setValueS32("texture_width", texture_width);
|
||||
message.setValueS32("texture_height", texture_height);
|
||||
sendMessage(message);
|
||||
|
||||
}
|
||||
else if (message_name == "set_language_code")
|
||||
{
|
||||
mHostLanguage = message_in.getValue("language");
|
||||
}
|
||||
else if (message_name == "load_uri")
|
||||
{
|
||||
std::string uri = message_in.getValue("uri");
|
||||
mLLCEFLib->navigate(uri);
|
||||
}
|
||||
else if (message_name == "set_cookie")
|
||||
{
|
||||
std::string uri = message_in.getValue("uri");
|
||||
std::string name = message_in.getValue("name");
|
||||
std::string value = message_in.getValue("value");
|
||||
std::string domain = message_in.getValue("domain");
|
||||
std::string path = message_in.getValue("path");
|
||||
bool httponly = message_in.getValueBoolean("httponly");
|
||||
bool secure = message_in.getValueBoolean("secure");
|
||||
mLLCEFLib->setCookie(uri, name, value, domain, path, httponly, secure);
|
||||
}
|
||||
else if (message_name == "mouse_event")
|
||||
{
|
||||
std::string event = message_in.getValue("event");
|
||||
|
||||
S32 x = message_in.getValueS32("x");
|
||||
S32 y = message_in.getValueS32("y");
|
||||
|
||||
// only even send left mouse button events to LLCEFLib
|
||||
// (partially prompted by crash in OS X CEF when sending right button events)
|
||||
// we catch the right click in viewer and display our own context menu anyway
|
||||
S32 button = message_in.getValueS32("button");
|
||||
LLCEFLib::EMouseButton btn = LLCEFLib::MB_MOUSE_BUTTON_LEFT;
|
||||
|
||||
if (event == "down" && button == 0)
|
||||
{
|
||||
mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOWN, x, y);
|
||||
mLLCEFLib->setFocus(true);
|
||||
|
||||
std::stringstream str;
|
||||
str << "Mouse down at = " << x << ", " << y;
|
||||
postDebugMessage(str.str());
|
||||
}
|
||||
else if (event == "up" && button == 0)
|
||||
{
|
||||
mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_UP, x, y);
|
||||
|
||||
std::stringstream str;
|
||||
str << "Mouse up at = " << x << ", " << y;
|
||||
postDebugMessage(str.str());
|
||||
}
|
||||
else if (event == "double_click")
|
||||
{
|
||||
mLLCEFLib->mouseButton(btn, LLCEFLib::ME_MOUSE_DOUBLE_CLICK, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLLCEFLib->mouseMove(x, y);
|
||||
}
|
||||
}
|
||||
else if (message_name == "scroll_event")
|
||||
{
|
||||
S32 x = message_in.getValueS32("x");
|
||||
S32 y = message_in.getValueS32("y");
|
||||
const int scaling_factor = 40;
|
||||
y *= -scaling_factor;
|
||||
|
||||
mLLCEFLib->mouseWheel(x, y);
|
||||
}
|
||||
else if (message_name == "text_event")
|
||||
{
|
||||
std::string text = message_in.getValue("text");
|
||||
std::string modifiers = message_in.getValue("modifiers");
|
||||
LLSD native_key_data = message_in.getValueLLSD("native_key_data");
|
||||
|
||||
unicodeInput(text, decodeModifiers(modifiers), native_key_data);
|
||||
}
|
||||
else if (message_name == "key_event")
|
||||
{
|
||||
#if LL_DARWIN
|
||||
std::string event = message_in.getValue("event");
|
||||
S32 key = message_in.getValueS32("key");
|
||||
LLSD native_key_data = message_in.getValueLLSD("native_key_data");
|
||||
|
||||
#if 0
|
||||
if (event == "down")
|
||||
{
|
||||
//mLLCEFLib->keyPress(key, true);
|
||||
mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
|
||||
|
||||
}
|
||||
else if (event == "up")
|
||||
{
|
||||
//mLLCEFLib->keyPress(key, false);
|
||||
mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_UP, (uint32_t)key, 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
|
||||
}
|
||||
#else
|
||||
// Treat unknown events as key-up for safety.
|
||||
LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP;
|
||||
if (event == "down")
|
||||
{
|
||||
key_event = LLCEFLib::KE_KEY_DOWN;
|
||||
}
|
||||
else if (event == "repeat")
|
||||
{
|
||||
key_event = LLCEFLib::KE_KEY_REPEAT;
|
||||
}
|
||||
|
||||
keyEvent(key_event, key, LLCEFLib::KM_MODIFIER_NONE, native_key_data);
|
||||
|
||||
#endif
|
||||
#elif LL_WINDOWS
|
||||
std::string event = message_in.getValue("event");
|
||||
S32 key = message_in.getValueS32("key");
|
||||
std::string modifiers = message_in.getValue("modifiers");
|
||||
LLSD native_key_data = message_in.getValueLLSD("native_key_data");
|
||||
|
||||
// Treat unknown events as key-up for safety.
|
||||
LLCEFLib::EKeyEvent key_event = LLCEFLib::KE_KEY_UP;
|
||||
if (event == "down")
|
||||
{
|
||||
key_event = LLCEFLib::KE_KEY_DOWN;
|
||||
}
|
||||
else if (event == "repeat")
|
||||
{
|
||||
key_event = LLCEFLib::KE_KEY_REPEAT;
|
||||
}
|
||||
|
||||
keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
|
||||
#endif
|
||||
}
|
||||
else if (message_name == "enable_media_plugin_debugging")
|
||||
{
|
||||
mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
|
||||
}
|
||||
if (message_name == "auth_response")
|
||||
{
|
||||
authResponse(message_in);
|
||||
}
|
||||
if (message_name == "edit_cut")
|
||||
{
|
||||
mLLCEFLib->editCut();
|
||||
}
|
||||
if (message_name == "edit_copy")
|
||||
{
|
||||
mLLCEFLib->editCopy();
|
||||
}
|
||||
if (message_name == "edit_paste")
|
||||
{
|
||||
mLLCEFLib->editPaste();
|
||||
}
|
||||
}
|
||||
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
|
||||
{
|
||||
if (message_name == "set_page_zoom_factor")
|
||||
{
|
||||
F32 factor = (F32)message_in.getValueReal("factor");
|
||||
mLLCEFLib->setPageZoom(factor);
|
||||
}
|
||||
if (message_name == "browse_stop")
|
||||
{
|
||||
mLLCEFLib->stop();
|
||||
}
|
||||
else if (message_name == "browse_reload")
|
||||
{
|
||||
bool ignore_cache = true;
|
||||
mLLCEFLib->reload(ignore_cache);
|
||||
}
|
||||
else if (message_name == "browse_forward")
|
||||
{
|
||||
mLLCEFLib->goForward();
|
||||
}
|
||||
else if (message_name == "browse_back")
|
||||
{
|
||||
mLLCEFLib->goBack();
|
||||
}
|
||||
else if (message_name == "cookies_enabled")
|
||||
{
|
||||
mCookiesEnabled = message_in.getValueBoolean("enable");
|
||||
}
|
||||
else if (message_name == "set_user_agent")
|
||||
{
|
||||
mUserAgentSubtring = message_in.getValue("user_agent");
|
||||
}
|
||||
else if (message_name == "show_web_inspector")
|
||||
{
|
||||
mLLCEFLib->showDevTools(true);
|
||||
}
|
||||
else if (message_name == "plugins_enabled")
|
||||
{
|
||||
mPluginsEnabled = message_in.getValueBoolean("enable");
|
||||
}
|
||||
else if (message_name == "javascript_enabled")
|
||||
{
|
||||
mJavascriptEnabled = message_in.getValueBoolean("enable");
|
||||
}
|
||||
}
|
||||
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
|
||||
{
|
||||
if (message_name == "set_volume")
|
||||
{
|
||||
F32 volume = (F32)message_in.getValueReal("volume");
|
||||
setVolume(volume);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
LLCEFLib::EKeyboardModifier MediaPluginCEF::decodeModifiers(std::string &modifiers)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (modifiers.find("shift") != std::string::npos)
|
||||
result |= LLCEFLib::KM_MODIFIER_SHIFT;
|
||||
|
||||
if (modifiers.find("alt") != std::string::npos)
|
||||
result |= LLCEFLib::KM_MODIFIER_ALT;
|
||||
|
||||
if (modifiers.find("control") != std::string::npos)
|
||||
result |= LLCEFLib::KM_MODIFIER_CONTROL;
|
||||
|
||||
if (modifiers.find("meta") != std::string::npos)
|
||||
result |= LLCEFLib::KM_MODIFIER_META;
|
||||
|
||||
return (LLCEFLib::EKeyboardModifier)result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers)
|
||||
{
|
||||
native_scan_code = 0;
|
||||
native_virtual_key = 0;
|
||||
native_modifiers = 0;
|
||||
|
||||
if (native_key_data.isMap())
|
||||
{
|
||||
#if LL_DARWIN
|
||||
native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger());
|
||||
native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger());
|
||||
native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
|
||||
#elif LL_WINDOWS
|
||||
native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
|
||||
native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
|
||||
// TODO: I don't think we need to do anything with native modifiers here -- please verify
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers_x, LLSD native_key_data = LLSD::emptyMap())
|
||||
{
|
||||
#if LL_DARWIN
|
||||
|
||||
if (!native_key_data.has("event_type") ||
|
||||
!native_key_data.has("event_modifiers") ||
|
||||
!native_key_data.has("event_keycode") ||
|
||||
!native_key_data.has("event_isrepeat"))
|
||||
return;
|
||||
|
||||
uint32_t eventType = native_key_data["event_type"].asInteger();
|
||||
if (!eventType)
|
||||
return;
|
||||
uint32_t eventModifiers = native_key_data["event_modifiers"].asInteger();
|
||||
uint32_t eventKeycode = native_key_data["event_keycode"].asInteger();
|
||||
char eventChars = static_cast<char>(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger());
|
||||
char eventUChars = static_cast<char>(native_key_data["event_umodchars"].isUndefined() ? 0 : native_key_data["event_umodchars"].asInteger());
|
||||
bool eventIsRepeat = native_key_data["event_isrepeat"].asBoolean();
|
||||
|
||||
mLLCEFLib->keyboardEventOSX(eventType, eventModifiers, (eventChars) ? &eventChars : NULL,
|
||||
(eventUChars) ? &eventUChars : NULL, eventIsRepeat, eventKeycode);
|
||||
|
||||
#elif LL_WINDOWS
|
||||
U32 msg = ll_U32_from_sd(native_key_data["msg"]);
|
||||
U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
|
||||
U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
|
||||
|
||||
mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
|
||||
#endif
|
||||
};
|
||||
|
||||
void MediaPluginCEF::unicodeInput(const std::string &utf8str, LLCEFLib::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
|
||||
{
|
||||
#if LL_DARWIN
|
||||
//mLLCEFLib->keyPress(utf8str[0], true);
|
||||
//mLLCEFLib->keyboardEvent(LLCEFLib::KE_KEY_DOWN, (uint32_t)(utf8str[0]), 0, LLCEFLib::KM_MODIFIER_NONE, 0, 0, 0);
|
||||
if (!native_key_data.has("event_chars") || !native_key_data.has("event_umodchars") ||
|
||||
!native_key_data.has("event_keycode") || !native_key_data.has("event_modifiers"))
|
||||
return;
|
||||
uint32_t unicodeChar = native_key_data["event_chars"].asInteger();
|
||||
uint32_t unmodifiedChar = native_key_data["event_umodchars"].asInteger();
|
||||
uint32_t keyCode = native_key_data["event_keycode"].asInteger();
|
||||
uint32_t rawmodifiers = native_key_data["event_modifiers"].asInteger();
|
||||
|
||||
mLLCEFLib->injectUnicodeText(unicodeChar, unmodifiedChar, keyCode, rawmodifiers);
|
||||
|
||||
#elif LL_WINDOWS
|
||||
U32 msg = ll_U32_from_sd(native_key_data["msg"]);
|
||||
U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
|
||||
U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
|
||||
mLLCEFLib->nativeKeyboardEvent(msg, wparam, lparam);
|
||||
#endif
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginCEF::checkEditState()
|
||||
{
|
||||
bool can_cut = mLLCEFLib->editCanCut();
|
||||
bool can_copy = mLLCEFLib->editCanCopy();
|
||||
bool can_paste = mLLCEFLib->editCanPaste();
|
||||
|
||||
if ((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste))
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state");
|
||||
|
||||
if (can_cut != mCanCut)
|
||||
{
|
||||
mCanCut = can_cut;
|
||||
message.setValueBoolean("cut", can_cut);
|
||||
}
|
||||
|
||||
if (can_copy != mCanCopy)
|
||||
{
|
||||
mCanCopy = can_copy;
|
||||
message.setValueBoolean("copy", can_copy);
|
||||
}
|
||||
|
||||
if (can_paste != mCanPaste)
|
||||
{
|
||||
mCanPaste = can_paste;
|
||||
message.setValueBoolean("paste", can_paste);
|
||||
}
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaPluginCEF::setVolume(F32 vol)
|
||||
{
|
||||
mVolumeCatcher.setVolume(vol);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
bool MediaPluginCEF::init()
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
|
||||
message.setValue("name", "CEF Plugin");
|
||||
sendMessage(message);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int create_plugin(LLPluginInstance::sendMessageFunction send_message_function, LLPluginInstance* plugin_instance, BasicPluginBase** plugin_object)
|
||||
{
|
||||
*plugin_object = new MediaPluginCEF(send_message_function, plugin_instance);
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user