Initial llqtwebkit

This commit is contained in:
Drake Arconis
2012-09-08 02:01:25 -04:00
parent 86ad4aabf3
commit 9b358a1b39
72 changed files with 12876 additions and 30 deletions

View File

@@ -0,0 +1,114 @@
Linden Research, Inc. ("Linden Lab") Viewer FLOSS License Exception v0.5
The Linden Lab Exception for Free/Libre and Open Source Software-only
Applications Using Linden Lab Viewer Software (the "FLOSS Exception").
Exception Intent
Linden Lab is releasing the source code for certain software that
enables users to view or otherwise access the Second Life virtual
world environment (the "Viewer Software"), under version 2 of the GNU
General Public License (the "GPL"). The creation or distribution of
works based on the Program (as defined under the GPL) of the Viewer
Software may require the use of certain Free/Libre and Open Source
Software ("FLOSS") works that are subject to license agreements not
compatible with re-licensing under the GPL. Because we want to allow
the Viewer Software to be distributed with these FLOSS works, this
FLOSS Exception following exception applies subject to the terms and
conditions below.
Legal Terms and Conditions
As a special exception to the terms and conditions of version 2.0 of
the GPL:
You are free to distribute a work based on the Program that is formed
entirely from the Viewer Software (and any modifications thereof) and
one or more works that are independent and separate works not derived
from the Viewer Software, and are licensed under one or more of the
licenses listed below in section 1 (each, a "FLOSS Work") , as long
as:
A. You obey the GPL in all respects for the Viewer Software and any
work based on the Program, except for the FLOSS Works, for which
you must comply with B below,
B. all FLOSS Works,
i. are distributed subject to one of the FLOSS licenses
listed below, and
ii. the object code or executable form of the FLOSS Works are
accompanied by the complete corresponding
machine-readable source code for those FLOSS Works on the
same medium and under the same FLOSS license as the
corresponding object code or executable forms thereof,
and
C. any works that are aggregated with the Viewer Software or a work
based on the Program on a volume of a storage or distribution
medium in accordance with the GPL, and are not licensed under
the FLOSS licenses listed below, are independent and separate
works in themselves which are not derivatives of either the
Viewer Software, a work based on the Program or a FLOSS Work.
If the above conditions are not met, then the Viewer Software may only
be copied, modified, distributed or used under the terms and
conditions of the GPL or another valid licensing option from Linden
Lab.
1. FLOSS License List
License name Version(s)/Copyright Date
Academic Free License 2.0
Apache Software License 1.0/1.1/2.0
Apple Public Source License 2.0
Artistic license From Perl 5.8.0
BSD license "July 22 1999"
Common Development and
Distribution License (CDDL) 1.0
Common Public License 1.0
GNU Library or "Lesser" General
Public License (LGPL) 2.0/2.1
Jabber Open Source License 1.0
MIT License (As listed in file MIT-License.txt) -
Mozilla Public License (MPL) 1.0/1.1
Open Software License 2.0
OpenSSL license (with
original SSLeay license) "2003" ("1998")
PHP License 3.0
Python license (CNRI Python License) -
Python Software Foundation License 2.1.1
Sleepycat License "1999"
W3C License "2001"
X11 License "2001"
Zlib/libpng License -
Zope Public License 2.0
Due to the many variants of some of the above licenses, we require
that any variant of the above licenses be identical in substance to
the form approved by the Open Source Initiative and follow the 2003
version of the Free Software Foundation's Free Software Definition
(http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of the
Open Source Definition by the Open Source Initiative
(http://www.opensource.org/docs/definition.php).
2. Definitions
Terms used, but not defined, herein shall have the meaning provided in
the GPL.
3. Applicability
This FLOSS Exception applies to all Viewer Software files that contain
a notice placed by Linden Lab saying that the Viewer Software may be
distributed under the terms of this FLOSS Exception. If you create or
distribute a work which is a work based on the Program for the Viewer
Software and any other work licensed under the GPL, then this FLOSS
Exception is not available for that work; thus, you must remove the
FLOSS Exception notice from that work and comply with the GPL in all
respects, including by retaining all GPL notices. You may choose to
redistribute a copy of the Viewer Software exclusively under the terms
of the GPL by removing the FLOSS Exception notice from that copy of
the Viewer Software, provided that the copy has never been modified by
you or any third party.

339
LICENSES/GPL-license.txt Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -0,0 +1,36 @@
Source code
========
The license for the source code in this distribution should be clearly
marked on each source file. Unless otherwise specified, the source
code in this distribution ("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.
Logos and trademarks
==============
"Second Life" and "Linden Lab" are registered trademarks of Linden
Research, Inc. Other trademarks include (but are not limited to): the
names Linden and Linden Research, as well as the Linden Lab Hexagon
Design and the Second Life Hand Design logos.
Use of logos and trademarks are subject to the Linden Lab trademark
policy, available at:
http://secondlife.com/corporate/trademark/

View File

@@ -62,6 +62,10 @@ 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 (EXISTS ${LIBS_CLOSED_DIR}llkdu AND NOT STANDALONE)
add_subdirectory(${LIBS_CLOSED_PREFIX}llkdu)
endif (EXISTS ${LIBS_CLOSED_DIR}llkdu AND NOT STANDALONE)

View File

@@ -54,6 +54,7 @@ set(cmake_SOURCE_FILES
LLMessage.cmake
LLPlugin.cmake
LLPrimitive.cmake
LLQtWebkit.cmake
LLRender.cmake
LLScene.cmake
LLUI.cmake
@@ -70,6 +71,7 @@ set(cmake_SOURCE_FILES
PNG.cmake
Python.cmake
Prebuilt.cmake
Qt4.cmake
RunBuildTest.cmake
TemplateCheck.cmake
Tut.cmake

View File

@@ -1,9 +1,9 @@
# -*- cmake -*-
include(Prebuilt)
if(WORD_SIZE EQUAL 64)
set(DISABLE_TCMALLOC TRUE)
endif(WORD_SIZE EQUAL 64)
#if(WORD_SIZE EQUAL 64)
# set(DISABLE_TCMALLOC TRUE)
#endif(WORD_SIZE EQUAL 64)
if (STANDALONE)
include(FindGooglePerfTools)

View File

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

12
indra/cmake/Qt4.cmake Normal file
View File

@@ -0,0 +1,12 @@
# -*- 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,31 +1,10 @@
# -*- cmake -*-
include(Linking)
include(Prebuilt)
include(LLQtWebkit)
include(Qt4)
if (STANDALONE)
# The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny.
find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED)
include(${QT_USE_FILE})
set(QTDIR $ENV{QTDIR})
if (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
message(FATAL_ERROR "\"${QT_BINARY_DIR}\" is unequal \"${QTDIR}/bin\"; "
"Qt is found by looking for qmake in your PATH. "
"Please set your PATH such that 'qmake' is found in \$QTDIR/bin, "
"or unset QTDIR if the found Qt is correct.")
endif (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
find_package(LLQtWebkit REQUIRED QUIET)
# Add the plugins.
set(QT_PLUGIN_LIBRARIES)
foreach(qlibname qgif qjpeg)
find_library(QT_PLUGIN_${qlibname} ${qlibname} PATHS ${QT_PLUGINS_DIR}/imageformats NO_DEFAULT_PATH)
if (QT_PLUGIN_${qlibname})
list(APPEND QT_PLUGIN_LIBRARIES ${QT_PLUGIN_${qlibname}})
else (QT_PLUGIN_${qtlibname})
message(FATAL_ERROR "Could not find the Qt plugin ${qlibname} in \"${QT_PLUGINS_DIR}/imageformats\"!")
endif (QT_PLUGIN_${qlibname})
endforeach(qlibname)
# qjpeg depends on libjpeg
list(APPEND QT_PLUGIN_LIBRARIES jpeg)
set(WEBKITLIBPLUGIN OFF CACHE BOOL
"WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
else (STANDALONE)

View File

@@ -39,8 +39,6 @@
#include "llpluginclassmedia.h"
#include "llpluginmessageclasses.h"
#include "llqtwebkit.h"
static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256;
static int nextPowerOf2( int value )

View File

@@ -0,0 +1,70 @@
# -*- 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

@@ -0,0 +1,14 @@
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
CONFIG += qtestlib
QT += webkit opengl network
include(../../llmozlib2.pri)
DEFINES += AUTOTEST
# Input
SOURCES += tst_llembeddedbrowser.cpp

View File

@@ -0,0 +1,400 @@
/* 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

@@ -0,0 +1,14 @@
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
CONFIG += qtestlib
QT += webkit opengl network
include(../../llmozlib2.pri)
DEFINES += AUTOTEST
# Input
SOURCES += tst_llembeddedbrowserwindow.cpp

View File

@@ -0,0 +1,759 @@
/* 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

@@ -0,0 +1,115 @@
/* 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

@@ -0,0 +1,90 @@
/* 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

@@ -0,0 +1,185 @@
/* 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

@@ -0,0 +1,251 @@
/* 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

@@ -0,0 +1,153 @@
/* 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

@@ -0,0 +1,71 @@
/* 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

@@ -0,0 +1,247 @@
/* 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

@@ -0,0 +1,57 @@
/* 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

@@ -0,0 +1,820 @@
/* 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

@@ -0,0 +1,470 @@
/* 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

@@ -0,0 +1,47 @@
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

@@ -0,0 +1,18 @@
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

@@ -0,0 +1,79 @@
/* 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;
}
break;
}
QPlastiqueStyle::drawControl(element, option, painter, widget);
}

View File

@@ -0,0 +1,42 @@
/* 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

@@ -0,0 +1,536 @@
/* 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

@@ -0,0 +1,108 @@
/* 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

@@ -0,0 +1,176 @@
/* 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

@@ -0,0 +1,63 @@
/* 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

@@ -0,0 +1,137 @@
<?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>

728
indra/llqtwebkit/pstdint.h Normal file
View File

@@ -0,0 +1,728 @@
/* 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

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

View File

@@ -0,0 +1,15 @@
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

@@ -0,0 +1,270 @@
/* 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

@@ -0,0 +1,17 @@
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

@@ -0,0 +1,159 @@
/* 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

@@ -0,0 +1,11 @@
######################################################################
# 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

@@ -0,0 +1,85 @@
/* 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

@@ -0,0 +1,12 @@
######################################################################
# 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

@@ -0,0 +1,100 @@
/* 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

@@ -0,0 +1,27 @@
# -*- 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

@@ -0,0 +1,444 @@
/* 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

@@ -0,0 +1,61 @@
/* 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

@@ -0,0 +1,66 @@
/* 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

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

View File

@@ -0,0 +1,247 @@
/* 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

@@ -0,0 +1,92 @@
/* 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

@@ -0,0 +1,18 @@
# 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

@@ -0,0 +1,269 @@
/* 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

@@ -0,0 +1,38 @@
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

@@ -0,0 +1,429 @@
#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

@@ -0,0 +1,88 @@
#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

@@ -0,0 +1,341 @@
/* 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

@@ -0,0 +1,38 @@
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

@@ -0,0 +1,79 @@
<?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

@@ -0,0 +1,229 @@
/* 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

@@ -0,0 +1,28 @@
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

@@ -0,0 +1,38 @@
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

@@ -0,0 +1,292 @@
/* 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

@@ -0,0 +1,28 @@
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

@@ -0,0 +1,6 @@
@echo off
echo Setting up a Qt environment using 3p-qt HG repository
set QTDIR=C:\Work\3p-llqtwebkit\stage
set PATH=C:\Work\3p-llqtwebkit\stage\bin;%PATH%
set QMAKESPEC=win32-msvc2010
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat"

Binary file not shown.

View File

@@ -7,6 +7,7 @@ include(LLCommon)
include(LLImage)
include(LLPlugin)
include(LLMath)
include(LLQtWebkit)
include(LLRender)
include(LLWindow)
include(UI)

View File

@@ -161,7 +161,7 @@ private:
checkEditState();
if(mInitState == INIT_STATE_NAVIGATE_COMPLETE)
if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
{
if(!mInitialNavigateURL.empty())
{
@@ -284,7 +284,7 @@ private:
bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, mProfileDir, native_window_handle );
if ( result )
{
mInitState = INIT_STATE_INITIALIZED;
setInitState(INIT_STATE_INITIALIZED);
// debug spam sent to viewer and displayed in the log as usual
postDebugMessage( "browser initialized okay" );