Remove llqtwebkit, add cef

This commit is contained in:
Drake Arconis
2016-01-16 16:14:04 -05:00
parent 2a072bfc67
commit d219087950
108 changed files with 1783 additions and 15014 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,11 +0,0 @@
# -*- cmake -*-
if (STANDALONE)
set(LLQTWEBKIT_INCLUDE_DIR
${LIBS_OPEN_DIR}/llqtwebkit
)
set(LLQTWEBKIT_LIBRARY
llqtwebkit
)
endif (STANDALONE)

View File

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

View File

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

View File

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

View File

@@ -13,7 +13,6 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLQTWEBKIT_INCLUDE_DIR}
)
set(llplugin_SOURCE_FILES

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +0,0 @@
# -*- cmake -*-
add_subdirectory(src)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +0,0 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
HEADERS += trie_p.h networkcookiejar.h twoleveldomains_p.h networkcookiejar_p.h
SOURCES += networkcookiejar.cpp

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 */
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -89,6 +89,7 @@ public:
LLViewerKeyboard();
BOOL handleKey(KEY key, MASK mask, BOOL repeated);
BOOL handleKeyUp(KEY key, MASK mask);
S32 loadBindings(const std::string& filename); // returns number bound, 0 on error
S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error

View File

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

View File

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

View File

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

View File

@@ -56,6 +56,7 @@ public:
/*virtual*/ bool getFocus();
/*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
/*virtual*/ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent);
/*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
@@ -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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View 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