diff --git a/.gitignore b/.gitignore index 84a272544..f30ca2cc4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ /bin-release /indra/viewer-* /indra/newview/vivox-runtime/ +/indra/newview/dbghelp.dll /libraries/ /lib/ *.pyc diff --git a/LICENSES/FLOSS-exception.txt b/LICENSES/FLOSS-exception.txt new file mode 100644 index 000000000..483246685 --- /dev/null +++ b/LICENSES/FLOSS-exception.txt @@ -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. diff --git a/LICENSES/GPL-license.txt b/LICENSES/GPL-license.txt new file mode 100644 index 000000000..d511905c1 --- /dev/null +++ b/LICENSES/GPL-license.txt @@ -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. + + + Copyright (C) + + 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. + + , 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. diff --git a/LICENSES/LLQTWEBKIT_LICENSE.txt b/LICENSES/LLQTWEBKIT_LICENSE.txt new file mode 100644 index 000000000..405d89131 --- /dev/null +++ b/LICENSES/LLQTWEBKIT_LICENSE.txt @@ -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/ diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 9c358301b..43d185b4f 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -18,7 +18,7 @@ cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR) cmake_policy(SET CMP0003 OLD) set(ROOT_PROJECT_NAME "Singularity" CACHE STRING - "The root project/makefile/solution name. Defaults to SecondLife.") + "The root project/makefile/solution name. Defaults to Singularity.") project(${ROOT_PROJECT_NAME}) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") @@ -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) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 8347352d0..2bb5ba88f 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -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 diff --git a/indra/cmake/LLQtWebkit.cmake b/indra/cmake/LLQtWebkit.cmake new file mode 100644 index 000000000..cec7e22e9 --- /dev/null +++ b/indra/cmake/LLQtWebkit.cmake @@ -0,0 +1,11 @@ +# -*- cmake -*- + +if (STANDALONE) + set(LLQTWEBKIT_INCLUDE_DIR + ${LIBS_OPEN_DIR}/llqtwebkit + ) + + set(LLQTWEBKIT_LIBRARY + llqtwebkit + ) +endif (STANDALONE) diff --git a/indra/cmake/Qt4.cmake b/indra/cmake/Qt4.cmake new file mode 100644 index 000000000..37d2799a2 --- /dev/null +++ b/indra/cmake/Qt4.cmake @@ -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) diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake index e52492c38..275b840a0 100644 --- a/indra/cmake/ViewerMiscLibs.cmake +++ b/indra/cmake/ViewerMiscLibs.cmake @@ -19,8 +19,3 @@ else (NOT STANDALONE) endif(LINUX AND ${ARCH} STREQUAL "x86_64") set(STANDALONE ON) endif(NOT STANDALONE) - -if (WINDOWS) - use_prebuilt_binary(dbghelp) -endif (WINDOWS) - diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake index 6c8e60103..5d1036c6f 100644 --- a/indra/cmake/WebKitLibPlugin.cmake +++ b/indra/cmake/WebKitLibPlugin.cmake @@ -1,19 +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) set(WEBKITLIBPLUGIN OFF CACHE BOOL "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.") else (STANDALONE) @@ -46,7 +37,7 @@ elseif (DARWIN) ) elseif (LINUX) if (STANDALONE) - set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES}) + set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES} ${QT_PLUGIN_LIBRARIES}) else (STANDALONE) set(WEBKIT_PLUGIN_LIBRARIES llqtwebkit diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 6818be493..23d1fbeb3 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -193,21 +193,30 @@ void LLCharacter::requestStopMotion( LLMotion* motion) //----------------------------------------------------------------------------- // updateMotions() //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation"); +static LLFastTimer::DeclareTimer FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim"); +static LLFastTimer::DeclareTimer FTM_UPDATE_MOTIONS("Update Motions"); + void LLCharacter::updateMotions(e_update_t update_type) { if (update_type == HIDDEN_UPDATE) { + LLFastTimer t(FTM_UPDATE_HIDDEN_ANIMATION); mMotionController.updateMotionsMinimal(); } else { + LLFastTimer t(FTM_UPDATE_ANIMATION); // unpause if the number of outstanding pause requests has dropped to the initial one if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1) { mMotionController.unpauseAllMotions(); } bool force_update = (update_type == FORCE_UPDATE); - mMotionController.updateMotions(force_update); + { + LLFastTimer t(FTM_UPDATE_MOTIONS); + mMotionController.updateMotions(force_update); + } } } diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index d040a1a22..eecbd1823 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -547,6 +547,8 @@ void LLMotionController::updateIdleActiveMotions() //----------------------------------------------------------------------------- // updateMotionsByType() //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_MOTION_ON_UPDATE("Motion onUpdate"); + void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type) { BOOL update_result = TRUE; @@ -704,7 +706,10 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } // perform motion update - update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); + { + LLFastTimer t(FTM_MOTION_ON_UPDATE); + update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature); + } } //********************** diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index 97989030a..b292fad2a 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -22,13 +22,11 @@ include_directories( ) set(llimage_SOURCE_FILES - aes.cpp llimagebmp.cpp llimage.cpp llimagedxt.cpp llimagej2c.cpp llimagejpeg.cpp - llimagemetadatareader.cpp llimagepng.cpp llimagetga.cpp llimageworker.cpp @@ -37,13 +35,11 @@ set(llimage_SOURCE_FILES set(llimage_HEADER_FILES CMakeLists.txt - aes.h llimage.h llimagebmp.h llimagedxt.h llimagej2c.h llimagejpeg.h - llimagemetadatareader.h llimagepng.h llimagetga.h llimageworker.h diff --git a/indra/llimage/aes.cpp b/indra/llimage/aes.cpp deleted file mode 100644 index 2dc45ea35..000000000 --- a/indra/llimage/aes.cpp +++ /dev/null @@ -1,1380 +0,0 @@ - -//Rijndael.cpp - -#include -#include -#include -#include "aes.h" - -const int CRijndael::sm_alog[256] = -{ - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 -}; - -const int CRijndael::sm_log[256] = -{ - 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3, - 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 248, 105, 28, 193, - 125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166, 114, 154, 201, 9, 120, - 101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218, 142, - 150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, - 102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, - 126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186, - 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 167, 87, - 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232, - 44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160, - 127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183, - 204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, - 151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, - 83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171, - 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165, - 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 192, 247, 112, 7 -}; - -const char CRijndael::sm_S[256] = -{ - 99, 124, 119, 123, -14, 107, 111, -59, 48, 1, 103, 43, -2, -41, -85, 118, - -54, -126, -55, 125, -6, 89, 71, -16, -83, -44, -94, -81, -100, -92, 114, -64, - -73, -3, -109, 38, 54, 63, -9, -52, 52, -91, -27, -15, 113, -40, 49, 21, - 4, -57, 35, -61, 24, -106, 5, -102, 7, 18, -128, -30, -21, 39, -78, 117, - 9, -125, 44, 26, 27, 110, 90, -96, 82, 59, -42, -77, 41, -29, 47, -124, - 83, -47, 0, -19, 32, -4, -79, 91, 106, -53, -66, 57, 74, 76, 88, -49, - -48, -17, -86, -5, 67, 77, 51, -123, 69, -7, 2, 127, 80, 60, -97, -88, - 81, -93, 64, -113, -110, -99, 56, -11, -68, -74, -38, 33, 16, -1, -13, -46, - -51, 12, 19, -20, 95, -105, 68, 23, -60, -89, 126, 61, 100, 93, 25, 115, - 96, -127, 79, -36, 34, 42, -112, -120, 70, -18, -72, 20, -34, 94, 11, -37, - -32, 50, 58, 10, 73, 6, 36, 92, -62, -45, -84, 98, -111, -107, -28, 121, - -25, -56, 55, 109, -115, -43, 78, -87, 108, 86, -12, -22, 101, 122, -82, 8, - -70, 120, 37, 46, 28, -90, -76, -58, -24, -35, 116, 31, 75, -67, -117, -118, - 112, 62, -75, 102, 72, 3, -10, 14, 97, 53, 87, -71, -122, -63, 29, -98, - -31, -8, -104, 17, 105, -39, -114, -108, -101, 30, -121, -23, -50, 85, 40, -33, - -116, -95, -119, 13, -65, -26, 66, 104, 65, -103, 45, 15, -80, 84, -69, 22 -}; - -const char CRijndael::sm_Si[256] = -{ - 82, 9, 106, -43, 48, 54, -91, 56, -65, 64, -93, -98, -127, -13, -41, -5, - 124, -29, 57, -126, -101, 47, -1, -121, 52, -114, 67, 68, -60, -34, -23, -53, - 84, 123, -108, 50, -90, -62, 35, 61, -18, 76, -107, 11, 66, -6, -61, 78, - 8, 46, -95, 102, 40, -39, 36, -78, 118, 91, -94, 73, 109, -117, -47, 37, - 114, -8, -10, 100, -122, 104, -104, 22, -44, -92, 92, -52, 93, 101, -74, -110, - 108, 112, 72, 80, -3, -19, -71, -38, 94, 21, 70, 87, -89, -115, -99, -124, - -112, -40, -85, 0, -116, -68, -45, 10, -9, -28, 88, 5, -72, -77, 69, 6, - -48, 44, 30, -113, -54, 63, 15, 2, -63, -81, -67, 3, 1, 19, -118, 107, - 58, -111, 17, 65, 79, 103, -36, -22, -105, -14, -49, -50, -16, -76, -26, 115, - -106, -84, 116, 34, -25, -83, 53, -123, -30, -7, 55, -24, 28, 117, -33, 110, - 71, -15, 26, 113, 29, 41, -59, -119, 111, -73, 98, 14, -86, 24, -66, 27, - -4, 86, 62, 75, -58, -46, 121, 32, -102, -37, -64, -2, 120, -51, 90, -12, - 31, -35, -88, 51, -120, 7, -57, 49, -79, 18, 16, 89, 39, -128, -20, 95, - 96, 81, 127, -87, 25, -75, 74, 13, 45, -27, 122, -97, -109, -55, -100, -17, - -96, -32, 59, 77, -82, 42, -11, -80, -56, -21, -69, 60, -125, 83, -103, 97, - 23, 43, 4, 126, -70, 119, -42, 38, -31, 105, 20, 99, 85, 33, 12, 125 -}; - -const int CRijndael::sm_T1[256] = -{ - -966564955, -126059388, -294160487, -159679603, - -855539, -697603139, -563122255, -1849309868, - 1613770832, 33620227, -832084055, 1445669757, - -402719207, -1244145822, 1303096294, -327780710, - -1882535355, 528646813, -1983264448, -92439161, - -268764651, -1302767125, -1907931191, -68095989, - 1101901292, -1277897625, 1604494077, 1169141738, - 597466303, 1403299063, -462261610, -1681866661, - 1974974402, -503448292, 1033081774, 1277568618, - 1815492186, 2118074177, -168298750, -2083730353, - 1748251740, 1369810420, -773462732, -101584632, - -495881837, -1411852173, 1647391059, 706024767, - 134480908, -1782069422, 1176707941, -1648114850, - 806885416, 932615841, 168101135, 798661301, - 235341577, 605164086, 461406363, -538779075, - -840176858, 1311188841, 2142417613, -361400929, - 302582043, 495158174, 1479289972, 874125870, - 907746093, -596742478, -1269146898, 1537253627, - -1538108682, 1983593293, -1210657183, 2108928974, - 1378429307, -572267714, 1580150641, 327451799, - -1504488459, -1177431704, 0, -1041371860, - 1075847264, -469959649, 2041688520, -1235526675, - -731223362, -1916023994, 1740553945, 1916352843, - -1807070498, -1739830060, -1336387352, -2049978550, - -1143943061, -974131414, 1336584933, -302253290, - -2042412091, -1706209833, 1714631509, 293963156, - -1975171633, -369493744, 67240454, -25198719, - -1605349136, 2017213508, 631218106, 1269344483, - -1571728909, 1571005438, -2143272768, 93294474, - 1066570413, 563977660, 1882732616, -235539196, - 1673313503, 2008463041, -1344611723, 1109467491, - 537923632, -436207846, -34344178, -1076702611, - -2117218996, 403442708, 638784309, -1007883217, - -1101045791, 899127202, -2008791860, 773265209, - -1815821225, 1437050866, -58818942, 2050833735, - -932944724, -1168286233, 840505643, -428641387, - -1067425632, 427917720, -1638969391, -1545806721, - 1143087718, 1412049534, 999329963, 193497219, - -1941551414, -940642775, 1807268051, 672404540, - -1478566279, -1134666014, 369822493, -1378100362, - -606019525, 1681011286, 1949973070, 336202270, - -1840690725, 201721354, 1210328172, -1201906460, - -1614626211, -1110191250, 1135389935, -1000185178, - 965841320, 831886756, -739974089, -226920053, - -706222286, -1949775805, 1849112409, -630362697, - 26054028, -1311386268, -1672589614, 1235855840, - -663982924, -1403627782, -202050553, -806688219, - -899324497, -193299826, 1202630377, 268961816, - 1874508501, -260540280, 1243948399, 1546530418, - 941366308, 1470539505, 1941222599, -1748580783, - -873928669, -1579295364, -395021156, 1042226977, - -1773450275, 1639824860, 227249030, 260737669, - -529502064, 2084453954, 1907733956, -865704278, - -1874310952, 100860677, -134810111, 470683154, - -1033805405, 1781871967, -1370007559, 1773779408, - 394692241, -1715355304, 974986535, 664706745, - -639508168, -336005101, 731420851, 571543859, - -764843589, -1445340816, 126783113, 865375399, - 765172662, 1008606754, 361203602, -907417312, - -2016489911, -1437248001, 1344809080, -1512054918, - 59542671, 1503764984, 160008576, 437062935, - 1707065306, -672733647, -2076032314, -798463816, - -2109652541, 697932208, 1512910199, 504303377, - 2075177163, -1470868228, 1841019862, 739644986 -}; - -const int CRijndael::sm_T2[256] = -{ - -1513725085, -2064089988, -1712425097, -1913226373, - 234877682, -1110021269, -1310822545, 1418839493, - 1348481072, 50462977, -1446090905, 2102799147, - 434634494, 1656084439, -431117397, -1695779210, - 1167051466, -1658879358, 1082771913, -2013627011, - 368048890, -340633255, -913422521, 201060592, - -331240019, 1739838676, -44064094, -364531793, - -1088185188, -145513308, -1763413390, 1536934080, - -1032472649, 484572669, -1371696237, 1783375398, - 1517041206, 1098792767, 49674231, 1334037708, - 1550332980, -195975771, 886171109, 150598129, - -1813876367, 1940642008, 1398944049, 1059722517, - 201851908, 1385547719, 1699095331, 1587397571, - 674240536, -1590192490, 252314885, -1255171430, - 151914247, 908333586, -1692696448, 1038082786, - 651029483, 1766729511, -847269198, -1612024459, - 454166793, -1642232957, 1951935532, 775166490, - 758520603, -1294176658, -290170278, -77881184, - -157003182, 1299594043, 1639438038, -830622797, - 2068982057, 1054729187, 1901997871, -1760328572, - -173649069, 1757008337, 0, 750906861, - 1614815264, 535035132, -931548751, -306816165, - -1093375382, 1183697867, -647512386, 1265776953, - -560706998, -728216500, -391096232, 1250283471, - 1807470800, 717615087, -447763798, 384695291, - -981056701, -677753523, 1432761139, -1810791035, - -813021883, 283769337, 100925954, -2114027649, - -257929136, 1148730428, -1171939425, -481580888, - -207466159, -27417693, -1065336768, -1979347057, - -1388342638, -1138647651, 1215313976, 82966005, - -547111748, -1049119050, 1974459098, 1665278241, - 807407632, 451280895, 251524083, 1841287890, - 1283575245, 337120268, 891687699, 801369324, - -507617441, -1573546089, -863484860, 959321879, - 1469301956, -229267545, -2097381762, 1199193405, - -1396153244, -407216803, 724703513, -1780059277, - -1598005152, -1743158911, -778154161, 2141445340, - 1715741218, 2119445034, -1422159728, -2096396152, - -896776634, 700968686, -747915080, 1009259540, - 2041044702, -490971554, 487983883, 1991105499, - 1004265696, 1449407026, 1316239930, 504629770, - -611169975, 168560134, 1816667172, -457679780, - 1570751170, 1857934291, -280777556, -1497079198, - -1472622191, -1540254315, 936633572, -1947043463, - 852879335, 1133234376, 1500395319, -1210421907, - -1946055283, 1689376213, -761508274, -532043351, - -1260884884, -89369002, 133428468, 634383082, - -1345690267, -1896580486, -381178194, 403703816, - -714097990, -1997506440, 1867130149, 1918643758, - 607656988, -245913946, -948718412, 1368901318, - 600565992, 2090982877, -1662487436, 557719327, - -577352885, -597574211, -2045932661, -2062579062, - -1864339344, 1115438654, -999180875, -1429445018, - -661632952, 84280067, 33027830, 303828494, - -1547542175, 1600795957, -106014889, -798377543, - -1860729210, 1486471617, 658119965, -1188585826, - 953803233, 334231800, -1288988520, 857870609, - -1143838359, 1890179545, -1995993458, -1489791852, - -1238525029, 574365214, -1844082809, 550103529, - 1233637070, -5614251, 2018519080, 2057691103, - -1895592820, -128343647, -2146858615, 387583245, - -630865985, 836232934, -964410814, -1194301336, - -1014873791, -1339450983, 2002398509, 287182607, - -881086288, -56077228, -697451589, 975967766 -}; - -const int CRijndael::sm_T3[256] = -{ - 1671808611, 2089089148, 2006576759, 2072901243, - -233963534, 1807603307, 1873927791, -984313403, - 810573872, 16974337, 1739181671, 729634347, - -31856642, -681396777, -1410970197, 1989864566, - -901410870, -2103631998, -918517303, 2106063485, - -99225606, 1508618841, 1204391495, -267650064, - -1377025619, -731401260, -1560453214, -1343601233, - -1665195108, -1527295068, 1922491506, -1067738176, - -1211992649, -48438787, -1817297517, 644500518, - 911895606, 1061256767, -150800905, -867204148, - 878471220, -1510714971, -449523227, -251069967, - 1905517169, -663508008, 827548209, 356461077, - 67897348, -950889017, 593839651, -1017209405, - 405286936, -1767819370, 84871685, -1699401830, - 118033927, 305538066, -2137318528, -499261470, - -349778453, 661212711, -1295155278, 1973414517, - 152769033, -2086789757, 745822252, 439235610, - 455947803, 1857215598, 1525593178, -1594139744, - 1391895634, 994932283, -698239018, -1278313037, - 695947817, -482419229, 795958831, -2070473852, - 1408607827, -781665839, 0, -315833875, - 543178784, -65018884, -1312261711, 1542305371, - 1790891114, -884568629, -1093048386, 961245753, - 1256100938, 1289001036, 1491644504, -817199665, - -798245936, -282409489, -1427812438, -82383365, - 1137018435, 1305975373, 861234739, -2053893755, - 1171229253, -116332039, 33948674, 2139225727, - 1357946960, 1011120188, -1615190625, -1461498968, - 1374921297, -1543610973, 1086357568, -1886780017, - -1834139758, -1648615011, 944271416, -184225291, - -1126210628, -1228834890, -629821478, 560153121, - 271589392, -15014401, -217121293, -764559406, - -850624051, 202643468, 322250259, -332413972, - 1608629855, -1750977129, 1154254916, 389623319, - -1000893500, -1477290585, 2122513534, 1028094525, - 1689045092, 1575467613, 422261273, 1939203699, - 1621147744, -2120738431, 1339137615, -595614756, - 577127458, 712922154, -1867826288, -2004677752, - 1187679302, -299251730, -1194103880, 339486740, - -562452514, 1591917662, 186455563, -612979237, - -532948000, 844522546, 978220090, 169743370, - 1239126601, 101321734, 611076132, 1558493276, - -1034051646, -747717165, -1393605716, 1655096418, - -1851246191, -1784401515, -466103324, 2039214713, - -416098841, -935097400, 928607799, 1840765549, - -1920204403, -714821163, 1322425422, -1444918871, - 1823791212, 1459268694, -200805388, -366620694, - 1706019429, 2056189050, -1360443474, 135794696, - -1160417350, 2022240376, 628050469, 779246638, - 472135708, -1494132826, -1261997132, -967731258, - -400307224, -579034659, 1956440180, 522272287, - 1272813131, -1109630531, -1954148981, -1970991222, - 1888542832, 1044544574, -1245417035, 1722469478, - 1222152264, 50660867, -167643146, 236067854, - 1638122081, 895445557, 1475980887, -1177523783, - -2037311610, -1051158079, 489110045, -1632032866, - -516367903, -132912136, -1733088360, 288563729, - 1773916777, -646927911, -1903622258, -1800981612, - -1682559589, 505560094, -2020469369, -383727127, - -834041906, 1442818645, 678973480, -545610273, - -1936784500, -1577559647, -1988097655, 219617805, - -1076206145, -432941082, 1120306242, 1756942440, - 1103331905, -1716508263, 762796589, 252780047, - -1328841808, 1425844308, -1143575109, 372911126 -}; - -const int CRijndael::sm_T4[256] = -{ - 1667474886, 2088535288, 2004326894, 2071694838, - -219017729, 1802223062, 1869591006, -976923503, - 808472672, 16843522, 1734846926, 724270422, - -16901657, -673750347, -1414797747, 1987484396, - -892713585, -2105369313, -909557623, 2105378810, - -84273681, 1499065266, 1195886990, -252703749, - -1381110719, -724277325, -1566376609, -1347425723, - -1667449053, -1532692653, 1920112356, -1061135461, - -1212693899, -33743647, -1819038147, 640051788, - 909531756, 1061110142, -134806795, -859025533, - 875846760, -1515850671, -437963567, -235861767, - 1903268834, -656903253, 825316194, 353713962, - 67374088, -943238507, 589522246, -1010606435, - 404236336, -1768513225, 84217610, -1701137105, - 117901582, 303183396, -2139055333, -488489505, - -336910643, 656894286, -1296904833, 1970642922, - 151591698, -2088526307, 741110872, 437923380, - 454765878, 1852748508, 1515908788, -1600062629, - 1381168804, 993742198, -690593353, -1280061827, - 690584402, -471646499, 791638366, -2071685357, - 1398011302, -774805319, 0, -303223615, - 538992704, -50585629, -1313748871, 1532751286, - 1785380564, -875870579, -1094788761, 960056178, - 1246420628, 1280103576, 1482221744, -808498555, - -791647301, -269538619, -1431640753, -67430675, - 1128514950, 1296947098, 859002214, -2054843375, - 1162203018, -101117719, 33687044, 2139062782, - 1347481760, 1010582648, -1616922075, -1465326773, - 1364325282, -1549533603, 1077985408, -1886418427, - -1835881153, -1650607071, 943212656, -168491791, - -1128472733, -1229536905, -623217233, 555836226, - 269496352, -58651, -202174723, -757961281, - -842183551, 202118168, 320025894, -320065597, - 1600119230, -1751670219, 1145359496, 387397934, - -993765485, -1482165675, 2122220284, 1027426170, - 1684319432, 1566435258, 421079858, 1936954854, - 1616945344, -2122213351, 1330631070, -589529181, - 572679748, 707427924, -1869567173, -2004319477, - 1179044492, -286381625, -1195846805, 336870440, - -555845209, 1583276732, 185277718, -606374227, - -522175525, 842159716, 976899700, 168435220, - 1229577106, 101059084, 606366792, 1549591736, - -1027449441, -741118275, -1397952701, 1650632388, - -1852725191, -1785355215, -454805549, 2038008818, - -404278571, -926399605, 926374254, 1835907034, - -1920103423, -707435343, 1313788572, -1448484791, - 1819063512, 1448540844, -185333773, -353753649, - 1701162954, 2054852340, -1364268729, 134748176, - -1162160785, 2021165296, 623210314, 774795868, - 471606328, -1499008681, -1263220877, -960081513, - -387439669, -572687199, 1953799400, 522133822, - 1263263126, -1111630751, -1953790451, -1970633457, - 1886425312, 1044267644, -1246378895, 1718004428, - 1212733584, 50529542, -151649801, 235803164, - 1633788866, 892690282, 1465383342, -1179004823, - -2038001385, -1044293479, 488449850, -1633765081, - -505333543, -117959701, -1734823125, 286339874, - 1768537042, -640061271, -1903261433, -1802197197, - -1684294099, 505291324, -2021158379, -370597687, - -825341561, 1431699370, 673740880, -539002203, - -1936945405, -1583220647, -1987477495, 218961690, - -1077945755, -421121577, 1111672452, 1751693520, - 1094828930, -1717981143, 757954394, 252645662, - -1330590853, 1414855848, -1145317779, 370555436 -}; - -const int CRijndael::sm_T5[256] = -{ - 1374988112, 2118214995, 437757123, 975658646, - 1001089995, 530400753, -1392879445, 1273168787, - 540080725, -1384747530, -1999866223, -184398811, - 1340463100, -987051049, 641025152, -1251826801, - -558802359, 632953703, 1172967064, 1576976609, - -1020300030, -2125664238, -1924753501, 1809054150, - 59727847, 361929877, -1083344149, -1789765158, - -725712083, 1484005843, 1239443753, -1899378620, - 1975683434, -191989384, -1722270101, 666464733, - -1092530250, -259478249, -920605594, 2110667444, - 1675577880, -451268222, -1756286112, 1649639237, - -1318815776, -1150570876, -25059300, -116905068, - 1883793496, -1891238631, -1797362553, 1383856311, - -1418472669, 1917518562, -484470953, 1716890410, - -1293211641, 800440835, -2033878118, -751368027, - 807962610, 599762354, 33778362, -317291940, - -1966138325, -1485196142, -217582864, 1315562145, - 1708848333, 101039829, -785096161, -995688822, - 875451293, -1561111136, 92987698, -1527321739, - 193195065, 1080094634, 1584504582, -1116860335, - 1042385657, -1763899843, -583137874, 1306967366, - -1856729675, 1908694277, 67556463, 1615861247, - 429456164, -692196969, -1992277044, 1742315127, - -1326955843, 126454664, -417768648, 2043211483, - -1585706425, 2084704233, -125559095, 0, - 159417987, 841739592, 504459436, 1817866830, - -49348613, 260388950, 1034867998, 908933415, - 168810852, 1750902305, -1688513327, 607530554, - 202008497, -1822955761, -1259432238, 463180190, - -2134850225, 1641816226, 1517767529, 470948374, - -493635062, -1063245083, 1008918595, 303765277, - 235474187, -225720403, 766945465, 337553864, - 1475418501, -1351284916, -291906117, -1551933187, - -150919521, 1551037884, 1147550661, 1543208500, - -1958532746, -886847780, -1225917336, -1192955549, - -684598070, 1113818384, 328671808, -2067394272, - -2058738563, -759480840, -1359400431, -953573011, - 496906059, -592301837, 226906860, 2009195472, - 733156972, -1452230247, 294930682, 1206477858, - -1459843900, -1594867942, 1451044056, 573804783, - -2025238841, -650587711, -1932877058, -1730933962, - -1493859889, -1518674392, -625504730, 1068351396, - 742039012, 1350078989, 1784663195, 1417561698, - -158526526, -1864845080, 775550814, -2101104651, - -1621262146, 1775276924, 1876241833, -819653965, - -928212677, 270040487, -392404114, -616842373, - -853116919, 1851332852, -325404927, -2091935064, - -426414491, -1426069890, 566021896, -283776794, - -1159226407, 1248802510, -358676012, 699432150, - 832877231, 708780849, -962227152, 899835584, - 1951317047, -58537306, -527380304, 866637845, - -251357110, 1106041591, 2144161806, 395441711, - 1984812685, 1139781709, -861254316, -459930401, - -1630423581, 1282050075, -1054072904, 1181045119, - -1654724092, 25965917, -91786125, -83148498, - -1285087910, -1831087534, -384805325, 1842759443, - -1697160820, 933301370, 1509430414, -351060855, - -827774994, -1218328267, -518199827, 2051518780, - -1663901863, 1441952575, 404016761, 1942435775, - 1408749034, 1610459739, -549621996, 2017778566, - -894438527, -1184316354, 941896748, -1029488545, - 371049330, -1126030068, 675039627, -15887039, - 967311729, 135050206, -659233636, 1683407248, - 2076935265, -718096784, 1215061108, -793225406 -}; - -const int CRijndael::sm_T6[256] = -{ - 1347548327, 1400783205, -1021700188, -1774573730, - -885281941, -249586363, -1414727080, -1823743229, - 1428173050, -156404115, -1853305738, 636813900, - -61872681, -674944309, -2144979644, -1883938141, - 1239331162, 1730525723, -1740248562, -513933632, - 46346101, 310463728, -1551022441, -966011911, - -419197089, -1793748324, -339776134, -627748263, - 768917123, -749177823, 692707433, 1150208456, - 1786102409, 2029293177, 1805211710, -584599183, - -1229004465, 401639597, 1724457132, -1266823622, - 409198410, -2098914767, 1620529459, 1164071807, - -525245321, -2068091986, 486441376, -1795618773, - 1483753576, 428819965, -2020286868, -1219331080, - 598438867, -495826174, 1474502543, 711349675, - 129166120, 53458370, -1702443653, -1512884472, - -231724921, -1306280027, -1174273174, 1559041666, - 730517276, -1834518092, -252508174, -1588696606, - -848962828, -721025602, 533804130, -1966823682, - -1657524653, -1599933611, 839224033, 1973745387, - 957055980, -1438621457, 106852767, 1371368976, - -113368694, 1033297158, -1361232379, 1179510461, - -1248766835, 91341917, 1862534868, -10465259, - 605657339, -1747534359, -863420349, 2003294622, - -1112479678, -2012771957, 954669403, -612775698, - 1201765386, -377732593, -906460130, 0, - -2096529274, 1211247597, -1407315600, 1315723890, - -67301633, 1443857720, 507358933, 657861945, - 1678381017, 560487590, -778347692, 975451694, - -1324610969, 261314535, -759894378, -1642357871, - 1333838021, -1570644960, 1767536459, 370938394, - 182621114, -440360918, 1128014560, 487725847, - 185469197, -1376613433, -1188186456, -938205527, - -2057834215, 1286567175, -1141990947, -39616672, - -1611202266, -1134791947, -985373125, 878443390, - 1988838185, -590666810, 1756818940, 1673061617, - -891866660, 272786309, 1075025698, 545572369, - 2105887268, -120407235, 296679730, 1841768865, - 1260232239, -203640272, -334657966, -797457949, - 1814803222, -1716948807, -99511224, 575138148, - -995558260, 446754879, -665420500, -282971248, - -947435186, -1042728751, -24327518, 915985419, - -811141759, 681933534, 651868046, -1539330625, - -466863459, 223377554, -1687527476, 1649704518, - -1024029421, -393160520, 1580087799, -175979601, - -1096852096, 2087309459, -1452288723, -1278270190, - 1003007129, -1492117379, 1860738147, 2077965243, - 164439672, -194094824, 32283319, -1467789414, - 1709610350, 2125135846, 136428751, -420538904, - -642062437, -833982666, -722821367, -701910916, - -1355701070, 824852259, 818324884, -1070226842, - 930369212, -1493400886, -1327460144, 355706840, - 1257309336, -146674470, 243256656, 790073846, - -1921626666, 1296297904, 1422699085, -538667516, - -476130891, 457992840, -1195299809, 2135319889, - 77422314, 1560382517, 1945798516, 788204353, - 1521706781, 1385356242, 870912086, 325965383, - -1936009375, 2050466060, -1906706412, -1981082820, - -288446169, 901210569, -304014107, 1014646705, - 1503449823, 1062597235, 2031621326, -1082931401, - -363595827, 1533017514, 350174575, -2038938405, - -2117423117, 1052338372, 741876788, 1606591296, - 1914052035, 213705253, -1960297399, 1107234197, - 1899603969, -569897805, -1663519516, -1872472383, - 1635502980, 1893020342, 1950903388, 1120974935 -}; - -const int CRijndael::sm_T7[256] = -{ - -1487908364, 1699970625, -1530717673, 1586903591, - 1808481195, 1173430173, 1487645946, 59984867, - -95084496, 1844882806, 1989249228, 1277555970, - -671330331, -875051734, 1149249077, -1550863006, - 1514790577, 459744698, 244860394, -1058972162, - 1963115311, -267222708, -1750889146, -104436781, - 1608975247, -1667951214, 2062270317, 1507497298, - -2094148418, 567498868, 1764313568, -935031095, - -1989511742, 2037970062, 1047239000, 1910319033, - 1337376481, -1390940024, -1402549984, 984907214, - 1243112415, 830661914, 861968209, 2135253587, - 2011214180, -1367032981, -1608712575, 731183368, - 1750626376, -48656571, 1820824798, -122203525, - -752637069, 48394827, -1890065633, -1423284651, - 671593195, -1039978571, 2073724613, 145085239, - -2014171096, -1515052097, 1790575107, -2107839210, - 472615631, -1265457287, -219090169, -492745111, - -187865638, -1093335547, 1646252340, -24460122, - 1402811438, 1436590835, -516815478, -344611594, - -331805821, -274055072, -1626972559, 273792366, - -1963377119, 104699613, 95345982, -1119466010, - -1917480620, 1560637892, -730921978, 369057872, - -81520232, -375925059, 1137477952, -1636341799, - 1119727848, -1954019447, 1530455833, -287606328, - 172466556, 266959938, 516552836, 0, - -2038232704, -314035669, 1890328081, 1917742170, - -262898, 945164165, -719438418, 958871085, - -647755249, -1507760036, 1423022939, 775562294, - 1739656202, -418409641, -1764576018, -1851909221, - -984645440, 547512796, 1265195639, 437656594, - -1173691757, 719700128, -532464606, 387781147, - 218828297, -944901493, -1464259146, -1446505442, - 428169201, 122466165, -574886247, 1627235199, - 648017665, -172204942, 1002783846, 2117360635, - 695634755, -958608605, -60246291, -245122844, - -590686415, -2062531997, 574624663, 287343814, - 612205898, 1039717051, 840019705, -1586641111, - 793451934, 821288114, 1391201670, -472877119, - 376187827, -1181111952, 1224348052, 1679968233, - -1933268740, 1058709744, 752375421, -1863376333, - 1321699145, -775825096, -1560376118, 188127444, - -2117097739, -567761542, -1910056265, -1079754835, - -1645990854, -1844621192, -862229921, 1180849278, - 331544205, -1192718120, -144822727, -1342864701, - -2134991011, -1820562992, 766078933, 313773861, - -1724135252, 2108100632, 1668212892, -1149510853, - 2013908262, 418672217, -1224610662, -1700232369, - 1852171925, -427906305, -821550660, -387518699, - -1680229657, 919489135, 164948639, 2094410160, - -1297141340, 590424639, -1808742747, 1723872674, - -1137216434, -895026046, -793714544, -669699161, - -1739919100, -621329940, 1343127501, -164685935, - -695372211, -1337113617, 1297403050, 81781910, - -1243373871, -2011476886, 532201772, 1367295589, - -368796322, 895287692, 1953757831, 1093597963, - 492483431, -766340389, 1446242576, 1192455638, - 1636604631, 209336225, 344873464, 1015671571, - 669961897, -919226527, -437395172, -1321436601, - -547775278, 1933530610, -830924780, 935293895, - -840281097, -1436852227, 1863638845, -611944380, - -209597777, -1002522264, 875313188, 1080017571, - -1015933411, 621591778, 1233856572, -1790836979, - 24197544, -1277294580, -459482956, -1047501738, - -2073986101, -1234119374, 1551124588, 1463996600 -}; - -const int CRijndael::sm_T8[256] = -{ - -190361519, 1097159550, 396673818, 660510266, - -1418998981, -1656360673, -94852180, -486304949, - 821712160, 1986918061, -864644728, 38544885, - -438830001, 718002117, 893681702, 1654886325, - -1319482914, -1172609243, -368142267, -20913827, - 796197571, 1290801793, 1184342925, -738605461, - -1889540349, -1835231979, 1836772287, 1381620373, - -1098699308, 1948373848, -529979063, -909622130, - -1031181707, -1904641804, 1480485785, -1183720153, - -514869570, -2001922064, 548169417, -835013507, - -548792221, 439452389, 1362321559, 1400849762, - 1685577905, 1806599355, -2120213250, 137073913, - 1214797936, 1174215055, -563312748, 2079897426, - 1943217067, 1258480242, 529487843, 1437280870, - -349698126, -1245576401, -981755258, 923313619, - 679998000, -1079659997, 57326082, 377642221, - -820237430, 2041877159, 133361907, 1776460110, - -621490843, 96392454, 878845905, -1493267772, - 777231668, -212492126, -1964953083, -152341084, - -2081670901, 1626319424, 1906247262, 1846563261, - 562755902, -586793578, 1040559837, -423803315, - 1418573201, -1000536719, 114585348, 1343618912, - -1728371687, -1108764714, 1078185097, -643926169, - -398279248, -1987344377, 425408743, -923870343, - 2081048481, 1108339068, -2078357000, 0, - -2138668279, 736970802, 292596766, 1517440620, - 251657213, -2059905521, -1361764803, 758720310, - 265905162, 1554391400, 1532285339, 908999204, - 174567692, 1474760595, -292105548, -1684955621, - -1060810880, -601841055, 2001430874, 303699484, - -1816524062, -1607801408, 585122620, 454499602, - 151849742, -1949848078, -1230456531, 514443284, - -249985705, 1963412655, -1713521682, 2137062819, - 19308535, 1928707164, 1715193156, -75615141, - 1126790795, 600235211, -302225226, -453942344, - 836553431, 1669664834, -1759363053, -971956092, - 1243905413, -1153566510, -114159186, 698445255, - -1641067747, -1305414692, -2041385971, -1042034569, - -1290376149, 1891211689, -1807156719, -379313593, - -57883480, -264299872, 2100090966, 865136418, - 1229899655, 953270745, -895287668, -737462632, - -176042074, 2061379749, -1215420710, -1379949505, - 983426092, 2022837584, 1607244650, 2118541908, - -1928084746, -658970480, 972512814, -1011878526, - 1568718495, -795640727, -718427793, 621982671, - -1399243832, 410887952, -1671205144, 1002142683, - 645401037, 1494807662, -1699282452, 1335535747, - -1787927066, -1671510, -1127282655, 367585007, - -409216582, 1865862730, -1626745622, -1333995991, - -1531793615, 1059270954, -1517014842, -1570324427, - 1320957812, -2100648196, -1865371424, -1479011021, - 77089521, -321194175, -850391425, -1846137065, - 1305906550, -273658557, -1437772596, -1778065436, - -776608866, 1787304780, 740276417, 1699839814, - 1592394909, -1942659839, -2022411270, 188821243, - 1729977011, -606973294, 274084841, -699985043, - -681472870, -1593017801, -132870567, 322734571, - -1457000754, 1640576439, 484830689, 1202797690, - -757114468, -227328171, 349075736, -952647821, - -137500077, -39167137, 1030690015, 1155237496, - -1342996022, 1757691577, 607398968, -1556062270, - 499347990, -500888388, 1011452712, 227885567, - -1476300487, 213114376, -1260086056, 1455525988, - -880516741, 850817237, 1817998408, -1202240816 -}; - -const int CRijndael::sm_U1[256] = -{ - 0, 235474187, 470948374, 303765277, - 941896748, 908933415, 607530554, 708780849, - 1883793496, 2118214995, 1817866830, 1649639237, - 1215061108, 1181045119, 1417561698, 1517767529, - -527380304, -291906117, -58537306, -225720403, - -659233636, -692196969, -995688822, -894438527, - -1864845080, -1630423581, -1932877058, -2101104651, - -1459843900, -1493859889, -1259432238, -1159226407, - -616842373, -718096784, -953573011, -920605594, - -484470953, -317291940, -15887039, -251357110, - -1418472669, -1518674392, -1218328267, -1184316354, - -1822955761, -1654724092, -1891238631, -2125664238, - 1001089995, 899835584, 666464733, 699432150, - 59727847, 226906860, 530400753, 294930682, - 1273168787, 1172967064, 1475418501, 1509430414, - 1942435775, 2110667444, 1876241833, 1641816226, - -1384747530, -1551933187, -1318815776, -1083344149, - -1789765158, -1688513327, -1992277044, -2025238841, - -583137874, -751368027, -1054072904, -819653965, - -451268222, -351060855, -116905068, -150919521, - 1306967366, 1139781709, 1374988112, 1610459739, - 1975683434, 2076935265, 1775276924, 1742315127, - 1034867998, 866637845, 566021896, 800440835, - 92987698, 193195065, 429456164, 395441711, - 1984812685, 2017778566, 1784663195, 1683407248, - 1315562145, 1080094634, 1383856311, 1551037884, - 101039829, 135050206, 437757123, 337553864, - 1042385657, 807962610, 573804783, 742039012, - -1763899843, -1730933962, -1966138325, -2067394272, - -1359400431, -1594867942, -1293211641, -1126030068, - -426414491, -392404114, -91786125, -191989384, - -558802359, -793225406, -1029488545, -861254316, - 1106041591, 1340463100, 1576976609, 1408749034, - 2043211483, 2009195472, 1708848333, 1809054150, - 832877231, 1068351396, 766945465, 599762354, - 159417987, 126454664, 361929877, 463180190, - -1585706425, -1351284916, -1116860335, -1285087910, - -1722270101, -1756286112, -2058738563, -1958532746, - -785096161, -549621996, -853116919, -1020300030, - -384805325, -417768648, -184398811, -83148498, - -1697160820, -1797362553, -2033878118, -1999866223, - -1561111136, -1392879445, -1092530250, -1326955843, - -358676012, -459930401, -158526526, -125559095, - -759480840, -592301837, -827774994, -1063245083, - 2051518780, 1951317047, 1716890410, 1750902305, - 1113818384, 1282050075, 1584504582, 1350078989, - 168810852, 67556463, 371049330, 404016761, - 841739592, 1008918595, 775550814, 540080725, - -325404927, -493635062, -259478249, -25059300, - -725712083, -625504730, -928212677, -962227152, - -1663901863, -1831087534, -2134850225, -1899378620, - -1527321739, -1426069890, -1192955549, -1225917336, - 202008497, 33778362, 270040487, 504459436, - 875451293, 975658646, 675039627, 641025152, - 2084704233, 1917518562, 1615861247, 1851332852, - 1147550661, 1248802510, 1484005843, 1451044056, - 933301370, 967311729, 733156972, 632953703, - 260388950, 25965917, 328671808, 496906059, - 1206477858, 1239443753, 1543208500, 1441952575, - 2144161806, 1908694277, 1675577880, 1842759443, - -684598070, -650587711, -886847780, -987051049, - -283776794, -518199827, -217582864, -49348613, - -1485196142, -1452230247, -1150570876, -1251826801, - -1621262146, -1856729675, -2091935064, -1924753501 -}; - -const int CRijndael::sm_U2[256] = -{ - 0, 185469197, 370938394, 487725847, - 741876788, 657861945, 975451694, 824852259, - 1483753576, 1400783205, 1315723890, 1164071807, - 1950903388, 2135319889, 1649704518, 1767536459, - -1327460144, -1141990947, -1493400886, -1376613433, - -1663519516, -1747534359, -1966823682, -2117423117, - -393160520, -476130891, -24327518, -175979601, - -995558260, -811141759, -759894378, -642062437, - 2077965243, 1893020342, 1841768865, 1724457132, - 1474502543, 1559041666, 1107234197, 1257309336, - 598438867, 681933534, 901210569, 1052338372, - 261314535, 77422314, 428819965, 310463728, - -885281941, -1070226842, -584599183, -701910916, - -419197089, -334657966, -249586363, -99511224, - -1823743229, -1740248562, -2057834215, -1906706412, - -1082931401, -1266823622, -1452288723, -1570644960, - -156404115, -39616672, -525245321, -339776134, - -627748263, -778347692, -863420349, -947435186, - -1361232379, -1512884472, -1195299809, -1278270190, - -2098914767, -1981082820, -1795618773, -1611202266, - 1179510461, 1296297904, 1347548327, 1533017514, - 1786102409, 1635502980, 2087309459, 2003294622, - 507358933, 355706840, 136428751, 53458370, - 839224033, 957055980, 605657339, 790073846, - -1921626666, -2038938405, -1687527476, -1872472383, - -1588696606, -1438621457, -1219331080, -1134791947, - -721025602, -569897805, -1021700188, -938205527, - -113368694, -231724921, -282971248, -466863459, - 1033297158, 915985419, 730517276, 545572369, - 296679730, 446754879, 129166120, 213705253, - 1709610350, 1860738147, 1945798516, 2029293177, - 1239331162, 1120974935, 1606591296, 1422699085, - -146674470, -61872681, -513933632, -363595827, - -612775698, -797457949, -848962828, -966011911, - -1355701070, -1539330625, -1188186456, -1306280027, - -2096529274, -2012771957, -1793748324, -1642357871, - 1201765386, 1286567175, 1371368976, 1521706781, - 1805211710, 1620529459, 2105887268, 1988838185, - 533804130, 350174575, 164439672, 46346101, - 870912086, 954669403, 636813900, 788204353, - -1936009375, -2020286868, -1702443653, -1853305738, - -1599933611, -1414727080, -1229004465, -1112479678, - -722821367, -538667516, -1024029421, -906460130, - -120407235, -203640272, -288446169, -440360918, - 1014646705, 930369212, 711349675, 560487590, - 272786309, 457992840, 106852767, 223377554, - 1678381017, 1862534868, 1914052035, 2031621326, - 1211247597, 1128014560, 1580087799, 1428173050, - 32283319, 182621114, 401639597, 486441376, - 768917123, 651868046, 1003007129, 818324884, - 1503449823, 1385356242, 1333838021, 1150208456, - 1973745387, 2125135846, 1673061617, 1756818940, - -1324610969, -1174273174, -1492117379, -1407315600, - -1657524653, -1774573730, -1960297399, -2144979644, - -377732593, -495826174, -10465259, -194094824, - -985373125, -833982666, -749177823, -665420500, - 2050466060, 1899603969, 1814803222, 1730525723, - 1443857720, 1560382517, 1075025698, 1260232239, - 575138148, 692707433, 878443390, 1062597235, - 243256656, 91341917, 409198410, 325965383, - -891866660, -1042728751, -590666810, -674944309, - -420538904, -304014107, -252508174, -67301633, - -1834518092, -1716948807, -2068091986, -1883938141, - -1096852096, -1248766835, -1467789414, -1551022441, -}; - -const int CRijndael::sm_U3[256] = -{ - 0, 218828297, 437656594, 387781147, - 875313188, 958871085, 775562294, 590424639, - 1750626376, 1699970625, 1917742170, 2135253587, - 1551124588, 1367295589, 1180849278, 1265195639, - -793714544, -574886247, -895026046, -944901493, - -459482956, -375925059, -24460122, -209597777, - -1192718120, -1243373871, -1560376118, -1342864701, - -1933268740, -2117097739, -1764576018, -1680229657, - -1149510853, -1234119374, -1586641111, -1402549984, - -1890065633, -2107839210, -1790836979, -1739919100, - -752637069, -567761542, -919226527, -1002522264, - -418409641, -368796322, -48656571, -267222708, - 1808481195, 1723872674, 1910319033, 2094410160, - 1608975247, 1391201670, 1173430173, 1224348052, - 59984867, 244860394, 428169201, 344873464, - 935293895, 984907214, 766078933, 547512796, - 1844882806, 1627235199, 2011214180, 2062270317, - 1507497298, 1423022939, 1137477952, 1321699145, - 95345982, 145085239, 532201772, 313773861, - 830661914, 1015671571, 731183368, 648017665, - -1119466010, -1337113617, -1487908364, -1436852227, - -1989511742, -2073986101, -1820562992, -1636341799, - -719438418, -669699161, -821550660, -1039978571, - -516815478, -331805821, -81520232, -164685935, - -695372211, -611944380, -862229921, -1047501738, - -492745111, -274055072, -122203525, -172204942, - -1093335547, -1277294580, -1530717673, -1446505442, - -1963377119, -2014171096, -1863376333, -1645990854, - 104699613, 188127444, 472615631, 287343814, - 840019705, 1058709744, 671593195, 621591778, - 1852171925, 1668212892, 1953757831, 2037970062, - 1514790577, 1463996600, 1080017571, 1297403050, - -621329940, -671330331, -1058972162, -840281097, - -287606328, -472877119, -187865638, -104436781, - -1297141340, -1079754835, -1464259146, -1515052097, - -2038232704, -1954019447, -1667951214, -1851909221, - 172466556, 122466165, 273792366, 492483431, - 1047239000, 861968209, 612205898, 695634755, - 1646252340, 1863638845, 2013908262, 1963115311, - 1446242576, 1530455833, 1277555970, 1093597963, - 1636604631, 1820824798, 2073724613, 1989249228, - 1436590835, 1487645946, 1337376481, 1119727848, - 164948639, 81781910, 331544205, 516552836, - 1039717051, 821288114, 669961897, 719700128, - -1321436601, -1137216434, -1423284651, -1507760036, - -2062531997, -2011476886, -1626972559, -1844621192, - -647755249, -730921978, -1015933411, -830924780, - -314035669, -532464606, -144822727, -95084496, - -1224610662, -1173691757, -1390940024, -1608712575, - -2094148418, -1910056265, -1724135252, -1808742747, - -547775278, -766340389, -984645440, -935031095, - -344611594, -427906305, -245122844, -60246291, - 1739656202, 1790575107, 2108100632, 1890328081, - 1402811438, 1586903591, 1233856572, 1149249077, - 266959938, 48394827, 369057872, 418672217, - 1002783846, 919489135, 567498868, 752375421, - 209336225, 24197544, 376187827, 459744698, - 945164165, 895287692, 574624663, 793451934, - 1679968233, 1764313568, 2117360635, 1933530610, - 1343127501, 1560637892, 1243112415, 1192455638, - -590686415, -775825096, -958608605, -875051734, - -387518699, -437395172, -219090169, -262898, - -1265457287, -1181111952, -1367032981, -1550863006, - -2134991011, -1917480620, -1700232369, -1750889146 -}; - -const int CRijndael::sm_U4[256] = -{ - 0, 151849742, 303699484, 454499602, - 607398968, 758720310, 908999204, 1059270954, - 1214797936, 1097159550, 1517440620, 1400849762, - 1817998408, 1699839814, 2118541908, 2001430874, - -1865371424, -1713521682, -2100648196, -1949848078, - -1260086056, -1108764714, -1493267772, -1342996022, - -658970480, -776608866, -895287668, -1011878526, - -57883480, -176042074, -292105548, -409216582, - 1002142683, 850817237, 698445255, 548169417, - 529487843, 377642221, 227885567, 77089521, - 1943217067, 2061379749, 1640576439, 1757691577, - 1474760595, 1592394909, 1174215055, 1290801793, - -1418998981, -1570324427, -1183720153, -1333995991, - -1889540349, -2041385971, -1656360673, -1807156719, - -486304949, -368142267, -249985705, -132870567, - -952647821, -835013507, -718427793, -601841055, - 1986918061, 2137062819, 1685577905, 1836772287, - 1381620373, 1532285339, 1078185097, 1229899655, - 1040559837, 923313619, 740276417, 621982671, - 439452389, 322734571, 137073913, 19308535, - -423803315, -273658557, -190361519, -39167137, - -1031181707, -880516741, -795640727, -643926169, - -1361764803, -1479011021, -1127282655, -1245576401, - -1964953083, -2081670901, -1728371687, -1846137065, - 1305906550, 1155237496, 1607244650, 1455525988, - 1776460110, 1626319424, 2079897426, 1928707164, - 96392454, 213114376, 396673818, 514443284, - 562755902, 679998000, 865136418, 983426092, - -586793578, -737462632, -820237430, -971956092, - -114159186, -264299872, -349698126, -500888388, - -1787927066, -1671205144, -2022411270, -1904641804, - -1319482914, -1202240816, -1556062270, -1437772596, - -321194175, -438830001, -20913827, -137500077, - -923870343, -1042034569, -621490843, -738605461, - -1531793615, -1379949505, -1230456531, -1079659997, - -2138668279, -1987344377, -1835231979, -1684955621, - 2081048481, 1963412655, 1846563261, 1729977011, - 1480485785, 1362321559, 1243905413, 1126790795, - 878845905, 1030690015, 645401037, 796197571, - 274084841, 425408743, 38544885, 188821243, - -681472870, -563312748, -981755258, -864644728, - -212492126, -94852180, -514869570, -398279248, - -1626745622, -1778065436, -1928084746, -2078357000, - -1153566510, -1305414692, -1457000754, -1607801408, - 1202797690, 1320957812, 1437280870, 1554391400, - 1669664834, 1787304780, 1906247262, 2022837584, - 265905162, 114585348, 499347990, 349075736, - 736970802, 585122620, 972512814, 821712160, - -1699282452, -1816524062, -2001922064, -2120213250, - -1098699308, -1215420710, -1399243832, -1517014842, - -757114468, -606973294, -1060810880, -909622130, - -152341084, -1671510, -453942344, -302225226, - 174567692, 57326082, 410887952, 292596766, - 777231668, 660510266, 1011452712, 893681702, - 1108339068, 1258480242, 1343618912, 1494807662, - 1715193156, 1865862730, 1948373848, 2100090966, - -1593017801, -1476300487, -1290376149, -1172609243, - -2059905521, -1942659839, -1759363053, -1641067747, - -379313593, -529979063, -75615141, -227328171, - -850391425, -1000536719, -548792221, -699985043, - 836553431, 953270745, 600235211, 718002117, - 367585007, 484830689, 133361907, 251657213, - 2041877159, 1891211689, 1806599355, 1654886325, - 1568718495, 1418573201, 1335535747, 1184342925 -}; - -const char CRijndael::sm_rcon[30] = -{ - 1, 2, 4, 8, 16, 32, - 64, -128, 27, 54, 108, -40, - -85, 77, -102, 47, 94, -68, - 99, -58, -105, 53, 106, -44, - -77, 125, -6, -17, -59, -111 -}; - -const int CRijndael::sm_shifts[3][4][2] = -{ - { {0, 0}, {1, 3}, {2, 2}, {3, 1} }, - { {0, 0}, {1, 5}, {2, 4}, {3, 3} }, - { {0, 0}, {1, 7}, {3, 5}, {4, 4} } -}; - -//Error Messages -char const* CRijndael::sm_szErrorMsg1 = "Object not Initialized"; -char const* CRijndael::sm_szErrorMsg2 = "Data not multiple of Block Size"; - -//Null chain -char const* CRijndael::sm_chain0 = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; - -//CONSTRUCTOR -CRijndael::CRijndael() : m_bKeyInit(false) -{ -} - -//DESTRUCTOR -CRijndael::~CRijndael() -{ -} - -//Expand a user-supplied key material into a session key. -// key - The 128/192/256-bit user-key to use. -// chain - initial chain block for CBC and CFB modes. -// keylength - 16, 24 or 32 bytes -// blockSize - The block size in bytes of this Rijndael (16, 24 or 32 bytes). -void CRijndael::MakeKey(char const* key, char const* chain, int keylength, int blockSize) -{ - if(NULL == key) - throw std::string("Empty key"); - if(!(16==keylength || 24==keylength || 32==keylength)) - throw std::string("Incorrect key length"); - if(!(16==blockSize || 24==blockSize || 32==blockSize)) - throw std::string("Incorrect block length"); - m_keylength = keylength; - m_blockSize = blockSize; - //Initialize the chain - memcpy(m_chain0, chain, m_blockSize); - memcpy(m_chain, chain, m_blockSize); - //Calculate Number of Rounds - switch(m_keylength) - { - case 16: - m_iROUNDS = (m_blockSize == 16) ? 10 : (m_blockSize == 24 ? 12 : 14); - break; - - case 24: - m_iROUNDS = (m_blockSize != 32) ? 12 : 14; - break; - - default: // 32 bytes = 256 bits - m_iROUNDS = 14; - } - int BC = m_blockSize / 4; - int i, j; - for(i=0; i<=m_iROUNDS; i++) - { - for(j=0; j> 16) & 0xFF] & 0xFF) << 24 ^ - (sm_S[(tt >> 8) & 0xFF] & 0xFF) << 16 ^ - (sm_S[ tt & 0xFF] & 0xFF) << 8 ^ - (sm_S[(tt >> 24) & 0xFF] & 0xFF) ^ - (sm_rcon[rconpointer++] & 0xFF) << 24; - if(KC != 8) - for(i=1, j=0; i> 8) & 0xFF] & 0xFF) << 8 ^ - (sm_S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ - (sm_S[(tt >> 24) & 0xFF] & 0xFF) << 24; - for(j = KC/2, i=j+1; i> 24) & 0xFF] ^ - sm_U2[(tt >> 16) & 0xFF] ^ - sm_U3[(tt >> 8) & 0xFF] ^ - sm_U4[tt & 0xFF]; - } - m_bKeyInit = true; -} - -//Convenience method to encrypt exactly one block of plaintext, assuming -//Rijndael's default block size (128-bit). -// in - The plaintext -// result - The ciphertext generated from a plaintext using the key -void CRijndael::DefEncryptBlock(char const* in, char* result) -{ - if(false==m_bKeyInit) - throw std::string(sm_szErrorMsg1); - int* Ker = m_Ke[0]; - int t0 = ((unsigned char)*(in++) << 24); - t0 |= ((unsigned char)*(in++) << 16); - t0 |= ((unsigned char)*(in++) << 8); - (t0 |= (unsigned char)*(in++)) ^= Ker[0]; - int t1 = ((unsigned char)*(in++) << 24); - t1 |= ((unsigned char)*(in++) << 16); - t1 |= ((unsigned char)*(in++) << 8); - (t1 |= (unsigned char)*(in++)) ^= Ker[1]; - int t2 = ((unsigned char)*(in++) << 24); - t2 |= ((unsigned char)*(in++) << 16); - t2 |= ((unsigned char)*(in++) << 8); - (t2 |= (unsigned char)*(in++)) ^= Ker[2]; - int t3 = ((unsigned char)*(in++) << 24); - t3 |= ((unsigned char)*(in++) << 16); - t3 |= ((unsigned char)*(in++) << 8); - (t3 |= (unsigned char)*(in++)) ^= Ker[3]; - int a0, a1, a2, a3; - //Apply Round Transforms - for (int r = 1; r < m_iROUNDS; r++) - { - Ker = m_Ke[r]; - a0 = (sm_T1[(t0 >> 24) & 0xFF] ^ - sm_T2[(t1 >> 16) & 0xFF] ^ - sm_T3[(t2 >> 8) & 0xFF] ^ - sm_T4[t3 & 0xFF]) ^ Ker[0]; - a1 = (sm_T1[(t1 >> 24) & 0xFF] ^ - sm_T2[(t2 >> 16) & 0xFF] ^ - sm_T3[(t3 >> 8) & 0xFF] ^ - sm_T4[t0 & 0xFF]) ^ Ker[1]; - a2 = (sm_T1[(t2 >> 24) & 0xFF] ^ - sm_T2[(t3 >> 16) & 0xFF] ^ - sm_T3[(t0 >> 8) & 0xFF] ^ - sm_T4[t1 & 0xFF]) ^ Ker[2]; - a3 = (sm_T1[(t3 >> 24) & 0xFF] ^ - sm_T2[(t0 >> 16) & 0xFF] ^ - sm_T3[(t1 >> 8) & 0xFF] ^ - sm_T4[t2 & 0xFF]) ^ Ker[3]; - t0 = a0; - t1 = a1; - t2 = a2; - t3 = a3; - } - //Last Round is special - Ker = m_Ke[m_iROUNDS]; - int tt = Ker[0]; - result[0] = sm_S[(t0 >> 24) & 0xFF] ^ (tt >> 24); - result[1] = sm_S[(t1 >> 16) & 0xFF] ^ (tt >> 16); - result[2] = sm_S[(t2 >> 8) & 0xFF] ^ (tt >> 8); - result[3] = sm_S[t3 & 0xFF] ^ tt; - tt = Ker[1]; - result[4] = sm_S[(t1 >> 24) & 0xFF] ^ (tt >> 24); - result[5] = sm_S[(t2 >> 16) & 0xFF] ^ (tt >> 16); - result[6] = sm_S[(t3 >> 8) & 0xFF] ^ (tt >> 8); - result[7] = sm_S[t0 & 0xFF] ^ tt; - tt = Ker[2]; - result[8] = sm_S[(t2 >> 24) & 0xFF] ^ (tt >> 24); - result[9] = sm_S[(t3 >> 16) & 0xFF] ^ (tt >> 16); - result[10] = sm_S[(t0 >> 8) & 0xFF] ^ (tt >> 8); - result[11] = sm_S[t1 & 0xFF] ^ tt; - tt = Ker[3]; - result[12] = sm_S[(t3 >> 24) & 0xFF] ^ (tt >> 24); - result[13] = sm_S[(t0 >> 16) & 0xFF] ^ (tt >> 16); - result[14] = sm_S[(t1 >> 8) & 0xFF] ^ (tt >> 8); - result[15] = sm_S[t2 & 0xFF] ^ tt; -} - -//Convenience method to decrypt exactly one block of plaintext, assuming -//Rijndael's default block size (128-bit). -// in - The ciphertext. -// result - The plaintext generated from a ciphertext using the session key. -void CRijndael::DefDecryptBlock(char const* in, char* result) -{ - if(false==m_bKeyInit) - throw std::string(sm_szErrorMsg1); - int* Kdr = m_Kd[0]; - int t0 = ((unsigned char)*(in++) << 24); - t0 = t0 | ((unsigned char)*(in++) << 16); - t0 |= ((unsigned char)*(in++) << 8); - (t0 |= (unsigned char)*(in++)) ^= Kdr[0]; - int t1 = ((unsigned char)*(in++) << 24); - t1 |= ((unsigned char)*(in++) << 16); - t1 |= ((unsigned char)*(in++) << 8); - (t1 |= (unsigned char)*(in++)) ^= Kdr[1]; - int t2 = ((unsigned char)*(in++) << 24); - t2 |= ((unsigned char)*(in++) << 16); - t2 |= ((unsigned char)*(in++) << 8); - (t2 |= (unsigned char)*(in++)) ^= Kdr[2]; - int t3 = ((unsigned char)*(in++) << 24); - t3 |= ((unsigned char)*(in++) << 16); - t3 |= ((unsigned char)*(in++) << 8); - (t3 |= (unsigned char)*(in++)) ^= Kdr[3]; - int a0, a1, a2, a3; - for(int r = 1; r < m_iROUNDS; r++) // apply round transforms - { - Kdr = m_Kd[r]; - a0 = (sm_T5[(t0 >> 24) & 0xFF] ^ - sm_T6[(t3 >> 16) & 0xFF] ^ - sm_T7[(t2 >> 8) & 0xFF] ^ - sm_T8[ t1 & 0xFF] ) ^ Kdr[0]; - a1 = (sm_T5[(t1 >> 24) & 0xFF] ^ - sm_T6[(t0 >> 16) & 0xFF] ^ - sm_T7[(t3 >> 8) & 0xFF] ^ - sm_T8[ t2 & 0xFF] ) ^ Kdr[1]; - a2 = (sm_T5[(t2 >> 24) & 0xFF] ^ - sm_T6[(t1 >> 16) & 0xFF] ^ - sm_T7[(t0 >> 8) & 0xFF] ^ - sm_T8[ t3 & 0xFF] ) ^ Kdr[2]; - a3 = (sm_T5[(t3 >> 24) & 0xFF] ^ - sm_T6[(t2 >> 16) & 0xFF] ^ - sm_T7[(t1 >> 8) & 0xFF] ^ - sm_T8[ t0 & 0xFF] ) ^ Kdr[3]; - t0 = a0; - t1 = a1; - t2 = a2; - t3 = a3; - } - //Last Round is special - Kdr = m_Kd[m_iROUNDS]; - int tt = Kdr[0]; - result[ 0] = sm_Si[(t0 >> 24) & 0xFF] ^ (tt >> 24); - result[ 1] = sm_Si[(t3 >> 16) & 0xFF] ^ (tt >> 16); - result[ 2] = sm_Si[(t2 >> 8) & 0xFF] ^ (tt >> 8); - result[ 3] = sm_Si[ t1 & 0xFF] ^ tt; - tt = Kdr[1]; - result[ 4] = sm_Si[(t1 >> 24) & 0xFF] ^ (tt >> 24); - result[ 5] = sm_Si[(t0 >> 16) & 0xFF] ^ (tt >> 16); - result[ 6] = sm_Si[(t3 >> 8) & 0xFF] ^ (tt >> 8); - result[ 7] = sm_Si[ t2 & 0xFF] ^ tt; - tt = Kdr[2]; - result[ 8] = sm_Si[(t2 >> 24) & 0xFF] ^ (tt >> 24); - result[ 9] = sm_Si[(t1 >> 16) & 0xFF] ^ (tt >> 16); - result[10] = sm_Si[(t0 >> 8) & 0xFF] ^ (tt >> 8); - result[11] = sm_Si[ t3 & 0xFF] ^ tt; - tt = Kdr[3]; - result[12] = sm_Si[(t3 >> 24) & 0xFF] ^ (tt >> 24); - result[13] = sm_Si[(t2 >> 16) & 0xFF] ^ (tt >> 16); - result[14] = sm_Si[(t1 >> 8) & 0xFF] ^ (tt >> 8); - result[15] = sm_Si[ t0 & 0xFF] ^ tt; -} - -//Encrypt exactly one block of plaintext. -// in - The plaintext. -// result - The ciphertext generated from a plaintext using the key. -void CRijndael::EncryptBlock(char const* in, char* result) -{ - if(false==m_bKeyInit) - throw std::string(sm_szErrorMsg1); - if(DEFAULT_BLOCK_SIZE == m_blockSize) - { - DefEncryptBlock(in, result); - return; - } - int BC = m_blockSize / 4; - int SC = (BC == 4) ? 0 : (BC == 6 ? 1 : 2); - int s1 = sm_shifts[SC][1][0]; - int s2 = sm_shifts[SC][2][0]; - int s3 = sm_shifts[SC][3][0]; - //Temporary Work Arrays - int i; - int tt; - int* pi = t; - for(i=0; i> 24) & 0xFF] ^ - sm_T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^ - sm_T3[(t[(i + s2) % BC] >> 8) & 0xFF] ^ - sm_T4[ t[(i + s3) % BC] & 0xFF] ) ^ m_Ke[r][i]; - memcpy(t, a, 4*BC); - } - int j; - //Last Round is Special - for(i=0,j=0; i> 24) & 0xFF] ^ (tt >> 24); - result[j++] = sm_S[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16); - result[j++] = sm_S[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8); - result[j++] = sm_S[ t[(i + s3) % BC] & 0xFF] ^ tt; - } -} - -//Decrypt exactly one block of ciphertext. -// in - The ciphertext. -// result - The plaintext generated from a ciphertext using the session key. -void CRijndael::DecryptBlock(char const* in, char* result) -{ - if(false==m_bKeyInit) - throw std::string(sm_szErrorMsg1); - if(DEFAULT_BLOCK_SIZE == m_blockSize) - { - DefDecryptBlock(in, result); - return; - } - int BC = m_blockSize / 4; - int SC = BC == 4 ? 0 : (BC == 6 ? 1 : 2); - int s1 = sm_shifts[SC][1][1]; - int s2 = sm_shifts[SC][2][1]; - int s3 = sm_shifts[SC][3][1]; - //Temporary Work Arrays - int i; - int tt; - int* pi = t; - for(i=0; i> 24) & 0xFF] ^ - sm_T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^ - sm_T7[(t[(i + s2) % BC] >> 8) & 0xFF] ^ - sm_T8[ t[(i + s3) % BC] & 0xFF]) ^ m_Kd[r][i]; - memcpy(t, a, 4*BC); - } - int j; - //Last Round is Special - for(i=0,j=0; i> 24) & 0xFF] ^ (tt >> 24); - result[j++] = sm_Si[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16); - result[j++] = sm_Si[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8); - result[j++] = sm_Si[ t[(i + s3) % BC] & 0xFF] ^ tt; - } -} - -void CRijndael::Encrypt(char const* in, char* result, size_t n, int iMode) -{ - if(false==m_bKeyInit) - throw std::string(sm_szErrorMsg1); - //n should be > 0 and multiple of m_blockSize - if(0==n || n%m_blockSize!=0) - throw std::string(sm_szErrorMsg2); - int i; - char const* pin; - char* presult; - if(CBC == iMode) //CBC mode, using the Chain - { - for(i=0,pin=in,presult=result; i<(int)n/m_blockSize; i++) - { - Xor(m_chain, pin); - EncryptBlock(m_chain, presult); - memcpy(m_chain, presult, m_blockSize); - pin += m_blockSize; - presult += m_blockSize; - } - } - else if(CFB == iMode) //CFB mode, using the Chain - { - for(i=0,pin=in,presult=result; i<(int)n/m_blockSize; i++) - { - EncryptBlock(m_chain, presult); - Xor(presult, pin); - memcpy(m_chain, presult, m_blockSize); - pin += m_blockSize; - presult += m_blockSize; - } - } - else //ECB mode, not using the Chain - { - for(i=0,pin=in,presult=result; i<(int)n/m_blockSize; i++) - { - EncryptBlock(pin, presult); - pin += m_blockSize; - presult += m_blockSize; - } - } -} - -void CRijndael::Decrypt(char const* in, char* result, size_t n, int iMode) -{ - if(false==m_bKeyInit) - throw std::string(sm_szErrorMsg1); - //n should be > 0 and multiple of m_blockSize - if(0==n || n%m_blockSize!=0) - throw std::string(sm_szErrorMsg2); - int i; - char const* pin; - char* presult; - if(CBC == iMode) //CBC mode, using the Chain - { - for(i=0,pin=in,presult=result; i<(int)n/m_blockSize; i++) - { - DecryptBlock(pin, presult); - Xor(presult, m_chain); - memcpy(m_chain, pin, m_blockSize); - pin += m_blockSize; - presult += m_blockSize; - } - } - else if(CFB == iMode) //CFB mode, using the Chain, not using Decrypt() - { - for(i=0,pin=in,presult=result; i<(int)n/m_blockSize; i++) - { - EncryptBlock(m_chain, presult); - //memcpy(presult, pin, m_blockSize); - Xor(presult, pin); - memcpy(m_chain, pin, m_blockSize); - pin += m_blockSize; - presult += m_blockSize; - } - } - else //ECB mode, not using the Chain - { - for(i=0,pin=in,presult=result; i<(int)n/m_blockSize; i++) - { - DecryptBlock(pin, presult); - pin += m_blockSize; - presult += m_blockSize; - } - } -} diff --git a/indra/llimage/aes.h b/indra/llimage/aes.h deleted file mode 100644 index 37e4aa5a8..000000000 --- a/indra/llimage/aes.h +++ /dev/null @@ -1,190 +0,0 @@ - -//Rijndael.h - -#ifndef __RIJNDAEL_H__ -#define __RIJNDAEL_H__ - -#include -#include -#include - -using namespace std; - -//Rijndael (pronounced Reindaal) is a block cipher, designed by Joan Daemen and Vincent Rijmen as a candidate algorithm for the AES. -//The cipher has a variable block length and key length. The authors currently specify how to use keys with a length -//of 128, 192, or 256 bits to encrypt blocks with al length of 128, 192 or 256 bits (all nine combinations of -//key length and block length are possible). Both block length and key length can be extended very easily to -// multiples of 32 bits. -//Rijndael can be implemented very efficiently on a wide range of processors and in hardware. -//This implementation is based on the Java Implementation used with the Cryptix toolkit found at: -//http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael.zip -//Java code authors: Raif S. Naffah, Paulo S. L. M. Barreto -//This Implementation was tested against KAT test published by the authors of the method and the -//results were identical. -class CRijndael -{ -public: - //Operation Modes - //The Electronic Code Book (ECB), Cipher Block Chaining (CBC) and Cipher Feedback Block (CFB) modes - //are implemented. - //In ECB mode if the same block is encrypted twice with the same key, the resulting - //ciphertext blocks are the same. - //In CBC Mode a ciphertext block is obtained by first xoring the - //plaintext block with the previous ciphertext block, and encrypting the resulting value. - //In CFB mode a ciphertext block is obtained by encrypting the previous ciphertext block - //and xoring the resulting value with the plaintext. - enum { ECB=0, CBC=1, CFB=2 }; - -private: - enum { DEFAULT_BLOCK_SIZE=16 }; - enum { MAX_BLOCK_SIZE=32, MAX_ROUNDS=14, MAX_KC=8, MAX_BC=8 }; - - //Auxiliary Functions - //Multiply two elements of GF(2^m) - static int Mul(int a, int b) - { - return (a != 0 && b != 0) ? sm_alog[(sm_log[a & 0xFF] + sm_log[b & 0xFF]) % 255] : 0; - } - - //Convenience method used in generating Transposition Boxes - static int Mul4(int a, char b[]) - { - if(a == 0) - return 0; - a = sm_log[a & 0xFF]; - int a0 = (b[0] != 0) ? sm_alog[(a + sm_log[b[0] & 0xFF]) % 255] & 0xFF : 0; - int a1 = (b[1] != 0) ? sm_alog[(a + sm_log[b[1] & 0xFF]) % 255] & 0xFF : 0; - int a2 = (b[2] != 0) ? sm_alog[(a + sm_log[b[2] & 0xFF]) % 255] & 0xFF : 0; - int a3 = (b[3] != 0) ? sm_alog[(a + sm_log[b[3] & 0xFF]) % 255] & 0xFF : 0; - return a0 << 24 | a1 << 16 | a2 << 8 | a3; - } - -public: - //CONSTRUCTOR - CRijndael(); - - //DESTRUCTOR - virtual ~CRijndael(); - - //Expand a user-supplied key material into a session key. - // key - The 128/192/256-bit user-key to use. - // chain - initial chain block for CBC and CFB modes. - // keylength - 16, 24 or 32 bytes - // blockSize - The block size in bytes of this Rijndael (16, 24 or 32 bytes). - void MakeKey(char const* key, char const* chain, int keylength=DEFAULT_BLOCK_SIZE, int blockSize=DEFAULT_BLOCK_SIZE); - -private: - //Auxiliary Function - void Xor(char* buff, char const* chain) - { - if(false==m_bKeyInit) - throw std::string(sm_szErrorMsg1); - for(int i=0; i -#include "linden_common.h" -#include "llimagemetadatareader.h" -#include "aes.h" -//#include "llapr.h" -//#include "llerror.h" -const unsigned char EMKDU_AES_KEY[] = {0x01,0x00,0x81,0x07,0x63,0x78,0xB6,0xFE,0x6E,0x3F,0xB0,0x12,0xCC,0x65,0x66,0xC1, -0x81,0x96,0xAC,0xC1,0x3B,0x66,0x0B,0xF7}; -//#define COMMENT_DEBUGG1ING -LLJ2cParser::LLJ2cParser(U8* data,int data_size) -{ - if(data && data_size) - { - mData.resize(data_size); - memcpy(&(mData[0]), data, data_size); - //std::copy(data,data+data_size,mData.begin()); - } - mIter = mData.begin(); -} - -U8 LLJ2cParser::nextChar() -{ - U8 rtn = 0x00; - if(mIter != mData.end()) - { - rtn = (*mIter); - mIter++; - } - return rtn; -} - -std::vector LLJ2cParser::nextCharArray(int len) -{ - std::vector array; - if(len > 0) - { - array.resize(len); - for(S32 i = 0; i < len; i++) - { - array[i] = nextChar(); - } - } - return array; -} - -std::vector LLJ2cParser::GetNextComment() -{ - std::vector content; - while (mIter != mData.end()) - { - U8 marker = nextChar(); - if (marker == 0xff) - { - U8 marker_type = nextChar(); - if (marker_type == 0x4f) - { - continue; - } - if (marker_type == 0x90) - { - //llinfos << "FOUND 0x90" << llendl; - break; //return empty vector - } - - if (marker_type == 0x64) - { - //llinfos << "FOUND 0x64 COMMENT SECTION" << llendl; - S32 len = ((S32)nextChar())*256 + (S32)nextChar(); - if (len > 3) content = nextCharArray(len - 2); - return content; - } - } - } - content.clear(); //return empty vector by clear anything there - return content; -} - -//flow of control in this method is shit, gotta fix this... possibly return a vector or map instead of a string -HG - -/* - Notes: - - For anyone debugging this method, if a comment is not being decoded properly and you know encryption is being used, - the easiest thing to do is to create an LLAPRFile handle inside this method and write the contents of data to a file. - Normally the comment is going to be up near the header, just have a look at it in a hex editor. - - It's generally going to be a string of 130 bytes preceeded by a null. -*/ - -//static -unsigned int LLImageMetaDataReader::ExtractEncodedComment(U8* data,int data_size, std::string& output) -{ - LLJ2cParser parser = LLJ2cParser(data,data_size); - - std::string decodedComment; - - //not supported yet, but why the hell not? - unsigned int result = ENC_NONE; - - while(1) - { - std::vector comment = parser.GetNextComment(); - if (comment.empty()) break; //exit loop - - if (comment[1] == 0x00 && comment.size() == 130) - { - bool xorComment = true; - //llinfos << "FOUND PAYLOAD" << llendl; - std::vector payload(128); - S32 i; - memcpy(&(payload[0]), &(comment[2]), 128); - //std::copy(comment.begin()+2,comment.end(),payload.begin()); - //lets check xorComment Cipher first - if (payload[2] == payload[127]) - { - // emkdu.dll - for (i = 4; i < 128; i += 4) - { - payload[i] ^= payload[3]; - payload[i + 1] ^= payload[1]; - payload[i + 2] ^= payload[0]; - payload[i + 3] ^= payload[2]; - } - result = ENC_EMKDU_V1; - } - else if (payload[3] == payload[127]) - { - // emkdu.dll or onyxkdu.dll - for (i = 4; i < 128; i += 4) - { - payload[i] ^= payload[2]; - payload[i + 1] ^= payload[0]; - payload[i + 2] ^= payload[1]; - payload[i + 3] ^= payload[3]; - } - result = ENC_ONYXKDU; - } - else - { - xorComment = false; - } - if(!xorComment) - { - //this is terrible i know - std::vector decrypted(129); - CRijndael aes; - try - { - aes.MakeKey(reinterpret_cast(EMKDU_AES_KEY),"", 24, 16); - } catch(std::string error) - { - llinfos << error << llendl; - } - try - { - int numBlocks = 8; - char* datain = (char*)&(payload[0]); - char* dataout = (char*)&(decrypted[0]); - char buffer[64]; - memset(buffer,0,sizeof(buffer)); - aes.DecryptBlock(datain,dataout); // do first block - for (int pos = 0; pos < 16; ++pos) - *dataout++ ^= buffer[pos]; - datain += 16; - numBlocks--; - - while (numBlocks) - { - aes.DecryptBlock(datain,dataout); // do next block - for (int pos = 0; pos < 16; ++pos) - *dataout++ ^= *(datain-16+pos); - datain += 16; - --numBlocks; - } - } catch(std::string error) - { - llinfos << error << llendl; - } - //payload.clear(); - //memcpy(&(payload[0]),&(dataout[0]),dataout.size()); - for (i = 0 ; i < 128; ++i) - { - if (decrypted[i] == 0) break; - } - if(i == 0) continue; - if(decodedComment.length() > 0) - decodedComment.append(", "); - - //the way it's being done now, you can only specify the encryption type for the last comment. - //need to switch to a map or a vector for output. - result = ENC_EMKDU_V2; - decodedComment.append(decrypted.begin(),decrypted.begin()+i); - } - else - { - for (i = 4 ; i < 128; ++i) - { - if (payload[i] == 0) break; - } - if(i < 4) continue; - if(decodedComment.length() > 0) - decodedComment.append(", "); - - decodedComment.append(payload.begin()+4,payload.begin()+i); - } - //llinfos << "FOUND COMMENT: " << result << llendl; - } - } - //end of loop - output = decodedComment; - return result; -} -// diff --git a/indra/llimage/llimagemetadatareader.h b/indra/llimage/llimagemetadatareader.h deleted file mode 100644 index b72c43e80..000000000 --- a/indra/llimage/llimagemetadatareader.h +++ /dev/null @@ -1,32 +0,0 @@ -// -#ifndef LL_LLIMAGEMETADATAREADER_H -#define LL_LLIMAGEMETADATAREADER_H -#include "stdtypes.h" -#include -#include -#include - -//encryption types -#define ENC_NONE 0 -#define ENC_ONYXKDU 1 -#define ENC_EMKDU_V1 2 -#define ENC_EMKDU_V2 4 - -class LLJ2cParser -{ -public: - LLJ2cParser(U8* data,int data_size); - std::vector GetNextComment(); - std::vector mData; -private: - U8 nextChar(); - std::vector nextCharArray(int len); - std::vector::iterator mIter; -}; -class LLImageMetaDataReader -{ -public: - static unsigned int ExtractEncodedComment(U8* data,int data_size, std::string& output); -}; -#endif -// diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 584abdf89..c168f7a89 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -12,8 +12,7 @@ include_directories( set(llmath_SOURCE_FILES llbbox.cpp llbboxlocal.cpp - llcalc.cpp - llcalcparser.cpp + llcalc.cpp llcamera.cpp llcoordframe.cpp llline.cpp @@ -48,8 +47,8 @@ set(llmath_HEADER_FILES coordframe.h llbbox.h llbboxlocal.h - llcalc.h - llcalcparser.h + llcalc.h + llcalcparser.h llcamera.h llcoord.h llcoordframe.h diff --git a/indra/llmath/llcalc.cpp b/indra/llmath/llcalc.cpp index 597d0815f..331e363e7 100644 --- a/indra/llmath/llcalc.cpp +++ b/indra/llmath/llcalc.cpp @@ -1,9 +1,26 @@ /* * LLCalc.cpp - * SecondLife - * - * Created by Aimee Walton on 28/09/2008. - * Copyright 2008 Aimee Walton. + * Copyright 2008 Aimee Walton. + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2008, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ * */ @@ -11,59 +28,61 @@ #include "llcalc.h" -#include "llcalcparser.h" #include "llmath.h" +#include "llcalcparser.h" // Variable names for use in the build floater -const char* LLCalc::X_POS = "PX"; -const char* LLCalc::Y_POS = "PY"; -const char* LLCalc::Z_POS = "PZ"; -const char* LLCalc::X_SCALE = "SX"; -const char* LLCalc::Y_SCALE = "SY"; -const char* LLCalc::Z_SCALE = "SZ"; -const char* LLCalc::X_ROT = "RX"; -const char* LLCalc::Y_ROT = "RY"; -const char* LLCalc::Z_ROT = "RZ"; -const char* LLCalc::HOLLOW = "HLW"; -const char* LLCalc::CUT_BEGIN = "CB"; -const char* LLCalc::CUT_END = "CE"; -const char* LLCalc::PATH_BEGIN = "PB"; -const char* LLCalc::PATH_END = "PE"; -const char* LLCalc::TWIST_BEGIN = "TB"; -const char* LLCalc::TWIST_END = "TE"; -const char* LLCalc::X_SHEAR = "SHX"; -const char* LLCalc::Y_SHEAR = "SHY"; -const char* LLCalc::X_TAPER = "TPX"; -const char* LLCalc::Y_TAPER = "TPY"; -const char* LLCalc::RADIUS_OFFSET = "ROF"; -const char* LLCalc::REVOLUTIONS = "REV"; -const char* LLCalc::SKEW = "SKW"; -const char* LLCalc::X_HOLE = "HLX"; -const char* LLCalc::Y_HOLE = "HLY"; -const char* LLCalc::TEX_U_SCALE = "TSU"; -const char* LLCalc::TEX_V_SCALE = "TSV"; -const char* LLCalc::TEX_U_OFFSET = "TOU"; -const char* LLCalc::TEX_V_OFFSET = "TOV"; -const char* LLCalc::TEX_ROTATION = "TROT"; -const char* LLCalc::TEX_TRANSPARENCY = "TRNS"; -const char* LLCalc::TEX_GLOW = "GLOW"; - +// must be lower case for parser definition +// case-insensitive for actual parsing +const char* LLCalc::X_POS = "px"; +const char* LLCalc::Y_POS = "py"; +const char* LLCalc::Z_POS = "pz"; +const char* LLCalc::X_SCALE = "sx"; +const char* LLCalc::Y_SCALE = "sy"; +const char* LLCalc::Z_SCALE = "sz"; +const char* LLCalc::X_ROT = "rx"; +const char* LLCalc::Y_ROT = "ry"; +const char* LLCalc::Z_ROT = "rz"; +const char* LLCalc::HOLLOW = "hlw"; +const char* LLCalc::CUT_BEGIN = "cb"; +const char* LLCalc::CUT_END = "ce"; +const char* LLCalc::PATH_BEGIN = "pb"; +const char* LLCalc::PATH_END = "pe"; +const char* LLCalc::TWIST_BEGIN = "tb"; +const char* LLCalc::TWIST_END = "te"; +const char* LLCalc::X_SHEAR = "shx"; +const char* LLCalc::Y_SHEAR = "shy"; +const char* LLCalc::X_TAPER = "tpx"; +const char* LLCalc::Y_TAPER = "tpy"; +const char* LLCalc::RADIUS_OFFSET = "rof"; +const char* LLCalc::REVOLUTIONS = "rev"; +const char* LLCalc::SKEW = "skw"; +const char* LLCalc::X_HOLE = "hlx"; +const char* LLCalc::Y_HOLE = "hly"; +const char* LLCalc::TEX_U_SCALE = "tsu"; +const char* LLCalc::TEX_V_SCALE = "tsv"; +const char* LLCalc::TEX_U_OFFSET = "tou"; +const char* LLCalc::TEX_V_OFFSET = "tov"; +const char* LLCalc::TEX_ROTATION = "trot"; +const char* LLCalc::TEX_TRANSPARENCY = "trns"; +const char* LLCalc::TEX_GLOW = "glow"; LLCalc* LLCalc::sInstance = NULL; +//TODO: Make this a static global class LLCalc::LLCalc() : mLastErrorPos(0) { // Init table of constants - mConstants["PI"] = F_PI; - mConstants["TWO_PI"] = F_TWO_PI; - mConstants["PI_BY_TWO"] = F_PI_BY_TWO; - mConstants["SQRT_TWO_PI"] = F_SQRT_TWO_PI; - mConstants["SQRT2"] = F_SQRT2; - mConstants["SQRT3"] = F_SQRT3; - mConstants["DEG_TO_RAD"] = DEG_TO_RAD; - mConstants["RAD_TO_DEG"] = RAD_TO_DEG; - mConstants["GRAVITY"] = GRAVITY; + /*setVar("PI", F_PI); + setVar("TWO_PI", F_TWO_PI); + setVar("PI_BY_TWO", F_PI_BY_TWO); + setVar("SQRT_TWO_PI", F_SQRT_TWO_PI); + setVar("SQRT2", F_SQRT2); + setVar("SQRT3", F_SQRT3); + setVar("DEG_TO_RAD", DEG_TO_RAD); + setVar("RAD_TO_DEG", RAD_TO_DEG); + setVar("GRAVITY", GRAVITY);*/ } LLCalc::~LLCalc() @@ -80,7 +99,7 @@ void LLCalc::cleanUp() //static LLCalc* LLCalc::getInstance() { - if (!sInstance) sInstance = new LLCalc(); + if (!sInstance) sInstance = new LLCalc(); return sInstance; } @@ -99,47 +118,35 @@ void LLCalc::clearAllVariables() mVariables.clear(); } -/* -void LLCalc::updateVariables(LLSD& vars) -{ - LLSD::map_iterator cIt = vars.beginMap(); - for(; cIt != vars.endMap(); cIt++) - { - setVar(cIt->first, (F32)(LLSD::Real)cIt->second); - } -} -*/ - bool LLCalc::evalString(const std::string& expression, F32& result) { - std::string expr_upper = expression; - LLStringUtil::toUpper(expr_upper); - - LLCalcParser calc(result, &mConstants, &mVariables); - mLastErrorPos = 0; - std::string::iterator start = expr_upper.begin(); - parse_info info; - - try + std::string::const_iterator itr = expression.begin(); + expression::grammar calc; + calc.constant.add + ("pi", F_PI) + ("two_pi", F_TWO_PI) + ("pi_by_two", F_PI_BY_TWO) + ("sqrt_two_pi", F_SQRT_TWO_PI) + ("sqrt2", F_SQRT2) + ("sqrt3", F_SQRT3) + ("deg_to_rad", DEG_TO_RAD) + ("rad_to_deg", RAD_TO_DEG) + ("gravity", GRAVITY) + ; + for(calc_map_t::const_iterator iter = mVariables.begin(); + iter != mVariables.end(); + ++iter) { - info = parse(start, expr_upper.end(), calc, space_p); - lldebugs << "Math expression: " << expression << " = " << result << llendl; + calc.constant.add(iter->first, iter->second); } - catch(parser_error &e) + + if (!expression::parse(itr, expression.end(), calc, result) || itr != expression.end()) { - mLastErrorPos = e.where - expr_upper.begin(); - - llinfos << "Calc parser exception: " << e.descriptor << " at " << mLastErrorPos << " in expression: " << expression << llendl; - return false; - } - - if (!info.full) - { - mLastErrorPos = info.stop - expr_upper.begin(); + mLastErrorPos = itr - expression.begin(); llinfos << "Unhandled syntax error at " << mLastErrorPos << " in expression: " << expression << llendl; return false; } - + lldebugs << "Math expression: " << expression << " = " << result << llendl; return true; } diff --git a/indra/llmath/llcalc.h b/indra/llmath/llcalc.h index 886e0bc8f..8c71569f4 100644 --- a/indra/llmath/llcalc.h +++ b/indra/llmath/llcalc.h @@ -1,9 +1,26 @@ /* * LLCalc.h - * SecondLife - * - * Created by Aimee Walton on 28/09/2008. * Copyright 2008 Aimee Walton. + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2008, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ * */ @@ -69,13 +86,8 @@ public: private: std::string::size_type mLastErrorPos; - calc_map_t mConstants; calc_map_t mVariables; - - // *TODO: Add support for storing user defined variables, and stored functions. - // Will need UI work, and a means to save them between sessions. -// calc_map_t* mUserVariables; - + // "There shall be only one" static LLCalc* sInstance; }; diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h index e0ad27026..0fcd38064 100644 --- a/indra/llmath/llcalcparser.h +++ b/indra/llmath/llcalcparser.h @@ -27,165 +27,207 @@ #ifndef LL_CALCPARSER_H #define LL_CALCPARSER_H -#include -#include -#include -#include -#include -#include -using namespace boost::spirit::classic; +#include +#if !defined(SPIRIT_VERSION) || SPIRIT_VERSION < 0x2010 +#error "At least Spirit version 2.1 required" +#endif -#include "llcalc.h" -#include "llmath.h" +// Add this in if we want boost math constants. +//#include +#include +#include -struct LLCalcParser : grammar +namespace expression { + + +//TODO: If we can find a better way to do this with boost::pheonix::bind lets do it +namespace { // anonymous + +template +T min_glue(T a, T b) { - LLCalcParser(F32& result, LLCalc::calc_map_t* constants, LLCalc::calc_map_t* vars) : - mResult(result), mConstants(constants), mVariables(vars) {}; - - struct value_closure : closure - { - member1 value; - }; - - template - struct definition - { - // Rule declarations - rule statement, identifier; - rule expression, term, - power, - unary_expr, - factor, - unary_func, - binary_func, - group; + return std::min(a, b); +} - // start() should return the starting symbol - rule const& start() const { return statement; } - - definition(LLCalcParser const& self) +template +T max_glue(T a, T b) +{ + return std::max(a, b); +} + +struct lazy_pow_ +{ + template + struct result { typedef X type; }; + + template + X operator()(X x, Y y) const + { + return std::pow(x, y); + } +}; + +struct lazy_ufunc_ +{ + template + struct result { typedef A1 type; }; + + template + A1 operator()(F f, A1 a1) const + { + return f(a1); + } +}; + +struct lazy_bfunc_ +{ + template + struct result { typedef A1 type; }; + + template + A1 operator()(F f, A1 a1, A2 a2) const + { + return f(a1, a2); + } +}; + +} // end namespace anonymous + +template +struct grammar + : boost::spirit::qi::grammar< + Iterator, FPT(), boost::spirit::ascii::space_type + > +{ + + // symbol table for constants + // to be added by the actual calculator + struct constant_ + : boost::spirit::qi::symbols< + typename std::iterator_traits::value_type, + FPT + > + { + constant_() { - using namespace phoenix; - - assertion assert_domain("Domain error"); -// assertion assert_symbol("Unknown symbol"); - assertion assert_syntax("Syntax error"); - - identifier = - lexeme_d[(alpha_p | '_') >> *(alnum_p | '_')] - ; - - group = - '(' >> expression[group.value = arg1] >> assert_syntax(ch_p(')')) - ; - - unary_func = - ((str_p("SIN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sin)(self,arg1)]) | - (str_p("COS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_cos)(self,arg1)]) | - (str_p("TAN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_tan)(self,arg1)]) | - (str_p("ASIN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_asin)(self,arg1)]) | - (str_p("ACOS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_acos)(self,arg1)]) | - (str_p("ATAN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_atan)(self,arg1)]) | - (str_p("SQRT") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sqrt)(self,arg1)]) | - (str_p("LOG") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_log)(self,arg1)]) | - (str_p("EXP") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_exp)(self,arg1)]) | - (str_p("ABS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_fabs)(self,arg1)]) | - (str_p("FLR") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_floor)(self,arg1)]) | - (str_p("CEIL") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_ceil)(self,arg1)]) - ) >> assert_syntax(ch_p(')')) - ; - - binary_func = - ((str_p("ATAN2") >> '(' >> expression[binary_func.value = arg1] >> ',' >> - expression[binary_func.value = bind(&LLCalcParser::_atan2)(self, binary_func.value, arg1)]) | - (str_p("MIN") >> '(' >> expression[binary_func.value = arg1] >> ',' >> - expression[binary_func.value = bind(&LLCalcParser::_min)(self, binary_func.value, arg1)]) | - (str_p("MAX") >> '(' >> expression[binary_func.value = arg1] >> ',' >> - expression[binary_func.value = bind(&LLCalcParser::_max)(self, binary_func.value, arg1)]) - ) >> assert_syntax(ch_p(')')) - ; - - // *TODO: Localisation of the decimal point? - // Problem, LLLineEditor::postvalidateFloat accepts a comma when appropriate - // for the current locale. However to do that here could clash with using - // the comma as a separator when passing arguments to functions. - factor = - (ureal_p[factor.value = arg1] | - group[factor.value = arg1] | - unary_func[factor.value = arg1] | - binary_func[factor.value = arg1] | - // Lookup throws an Unknown Symbol error if it is unknown, while this works fine, - // would be "neater" to handle symbol lookup from here with an assertive parser. -// constants_p[factor.value = arg1]| - identifier[factor.value = bind(&LLCalcParser::lookup)(self, arg1, arg2)] - ) >> - // Detect and throw math errors. - assert_domain(eps_p(bind(&LLCalcParser::checkNaN)(self, factor.value))) - ; - - unary_expr = - !ch_p('+') >> factor[unary_expr.value = arg1] | - '-' >> factor[unary_expr.value = -arg1] - ; - - power = - unary_expr[power.value = arg1] >> - *('^' >> assert_syntax(unary_expr[power.value = bind(&powf)(power.value, arg1)])) - ; - - term = - power[term.value = arg1] >> - *(('*' >> assert_syntax(power[term.value *= arg1])) | - ('/' >> assert_syntax(power[term.value /= arg1])) | - ('%' >> assert_syntax(power[term.value = bind(&fmodf)(term.value, arg1)])) - ) - ; - - expression = - assert_syntax(term[expression.value = arg1]) >> - *(('+' >> assert_syntax(term[expression.value += arg1])) | - ('-' >> assert_syntax(term[expression.value -= arg1])) - ) - ; - - statement = - !ch_p('=') >> ( expression )[var(self.mResult) = arg1] >> (end_p) + } + } constant; + + // symbol table for unary functions like "abs" + struct ufunc_ + : boost::spirit::qi::symbols< + typename std::iterator_traits::value_type, + FPT (*)(FPT) + > + { + ufunc_() + { + this->add + ("abs" , (FPT (*)(FPT)) std::abs ) + ("acos" , (FPT (*)(FPT)) std::acos ) + ("asin" , (FPT (*)(FPT)) std::asin ) + ("atan" , (FPT (*)(FPT)) std::atan ) + ("ceil" , (FPT (*)(FPT)) std::ceil ) + ("cos" , (FPT (*)(FPT)) std::cos ) + ("cosh" , (FPT (*)(FPT)) std::cosh ) + ("exp" , (FPT (*)(FPT)) std::exp ) + ("floor" , (FPT (*)(FPT)) std::floor) + ("log" , (FPT (*)(FPT)) std::log ) + ("log10" , (FPT (*)(FPT)) std::log10) + ("sin" , (FPT (*)(FPT)) std::sin ) + ("sinh" , (FPT (*)(FPT)) std::sinh ) + ("sqrt" , (FPT (*)(FPT)) std::sqrt ) + ("tan" , (FPT (*)(FPT)) std::tan ) + ("tanh" , (FPT (*)(FPT)) std::tanh ) ; } - }; - -private: - // Member functions for semantic actions - F32 lookup(const std::string::iterator&, const std::string::iterator&) const; - F32 _min(const F32& a, const F32& b) const { return llmin(a, b); } - F32 _max(const F32& a, const F32& b) const { return llmax(a, b); } - - bool checkNaN(const F32& a) const { return !llisnan(a); } - - //FIX* non ambigious function fix making SIN() work for calc -Cryogenic Blitz - F32 _sin(const F32& a) const { return sin(DEG_TO_RAD * a); } - F32 _cos(const F32& a) const { return cos(DEG_TO_RAD * a); } - F32 _tan(const F32& a) const { return tan(DEG_TO_RAD * a); } - F32 _asin(const F32& a) const { return asin(a * RAD_TO_DEG); } - F32 _acos(const F32& a) const { return acos(a * RAD_TO_DEG); } - F32 _atan(const F32& a) const { return atan(a * RAD_TO_DEG); } - F32 _sqrt(const F32& a) const { return sqrt(a); } - F32 _log(const F32& a) const { return log(a); } - F32 _exp(const F32& a) const { return exp(a); } - F32 _fabs(const F32& a) const { return fabs(a); } - F32 _floor(const F32& a) const { return (F32)llfloor(a); } - F32 _ceil(const F32& a) const { return llceil(a); } + } ufunc; - F32 _atan2(const F32& a,const F32& b) const { return atan2(a,b); } - - - - LLCalc::calc_map_t* mConstants; - LLCalc::calc_map_t* mVariables; -// LLCalc::calc_map_t* mUserVariables; - - F32& mResult; + // symbol table for binary functions like "pow" + struct bfunc_ + : boost::spirit::qi::symbols< + typename std::iterator_traits::value_type, + FPT (*)(FPT, FPT) + > + { + bfunc_() + { + using boost::bind; + this->add + ("pow" , (FPT (*)(FPT, FPT)) std::pow ) + ("atan2", (FPT (*)(FPT, FPT)) std::atan2) + ("min" , (FPT (*)(FPT, FPT)) min_glue) + ("max" , (FPT (*)(FPT, FPT)) max_glue) + ; + } + } bfunc; + + boost::spirit::qi::rule< + Iterator, FPT(), boost::spirit::ascii::space_type + > expression, term, factor, primary; + + grammar() : grammar::base_type(expression) + { + using boost::spirit::qi::real_parser; + using boost::spirit::qi::real_policies; + real_parser > real; + + using boost::spirit::qi::_1; + using boost::spirit::qi::_2; + using boost::spirit::qi::_3; + using boost::spirit::qi::no_case; + using boost::spirit::qi::_val; + + boost::phoenix::function lazy_pow; + boost::phoenix::function lazy_ufunc; + boost::phoenix::function lazy_bfunc; + + expression = + term [_val = _1] + >> *( ('+' >> term [_val += _1]) + | ('-' >> term [_val -= _1]) + ) + ; + + term = + factor [_val = _1] + >> *( ('*' >> factor [_val *= _1]) + | ('/' >> factor [_val /= _1]) + ) + ; + + factor = + primary [_val = _1] + >> *( ("**" >> factor [_val = lazy_pow(_val, _1)]) + ) + ; + + primary = + real [_val = _1] + | '(' >> expression [_val = _1] >> ')' + | ('-' >> primary [_val = -_1]) + | ('+' >> primary [_val = _1]) + | (no_case[ufunc] >> '(' >> expression >> ')') + [_val = lazy_ufunc(_1, _2)] + | (no_case[bfunc] >> '(' >> expression >> ',' + >> expression >> ')') + [_val = lazy_bfunc(_1, _2, _3)] + | no_case[constant] [_val = _1] + ; + + } }; + +template +bool parse(Iterator &iter, + Iterator end, + const grammar &g, + FPT &result) +{ + return boost::spirit::qi::phrase_parse( + iter, end, g, boost::spirit::ascii::space, result); +} + +} // end namespace expression #endif // LL_CALCPARSER_H diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index 1add51a09..f0a74e71b 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -839,6 +839,8 @@ P(iamHereVoice); P2(inventoryModelFetchDescendentsResponder, transfer_300s); P(inventoryModelFetchItemResponder); P(lcl_responder); +P(MPImportGetResponder); +P(MPImportPostResponder); P(mapLayerResponder); P(mediaTypeResponder); P(meshDecompositionResponder); diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index c71515496..064b12da1 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -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 ) diff --git a/indra/llqtwebkit/CMakeLists.txt b/indra/llqtwebkit/CMakeLists.txt new file mode 100644 index 000000000..6fbf5e960 --- /dev/null +++ b/indra/llqtwebkit/CMakeLists.txt @@ -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 +) diff --git a/indra/llqtwebkit/autotests/llembeddedbrowser/llembeddedbrowser.pro b/indra/llqtwebkit/autotests/llembeddedbrowser/llembeddedbrowser.pro new file mode 100644 index 000000000..02ecce5a2 --- /dev/null +++ b/indra/llqtwebkit/autotests/llembeddedbrowser/llembeddedbrowser.pro @@ -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 + diff --git a/indra/llqtwebkit/autotests/llembeddedbrowser/tst_llembeddedbrowser.cpp b/indra/llqtwebkit/autotests/llembeddedbrowser/tst_llembeddedbrowser.cpp new file mode 100644 index 000000000..a59cc9e19 --- /dev/null +++ b/indra/llqtwebkit/autotests/llembeddedbrowser/tst_llembeddedbrowser.cpp @@ -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 +#include +#include + +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("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("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("width"); + QTest::addColumn("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("enabled"); + QTest::addColumn("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("enabled"); + QTest::addColumn("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("enabled"); + QTest::addColumn("host_name"); + QTest::addColumn("port"); + QTest::addColumn("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("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("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("application_directory"); + QTest::addColumn("component_directory"); + QTest::addColumn("profile_directory"); + QTest::addColumn("native_window_handleCount"); + QTest::addColumn("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("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("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" + diff --git a/indra/llqtwebkit/autotests/llembeddedbrowserwindow/llembeddedbrowserwindow.pro b/indra/llqtwebkit/autotests/llembeddedbrowserwindow/llembeddedbrowserwindow.pro new file mode 100644 index 000000000..a89f50065 --- /dev/null +++ b/indra/llqtwebkit/autotests/llembeddedbrowserwindow/llembeddedbrowserwindow.pro @@ -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 + diff --git a/indra/llqtwebkit/autotests/llembeddedbrowserwindow/tst_llembeddedbrowserwindow.cpp b/indra/llqtwebkit/autotests/llembeddedbrowserwindow/tst_llembeddedbrowserwindow.cpp new file mode 100644 index 000000000..4c365d371 --- /dev/null +++ b/indra/llqtwebkit/autotests/llembeddedbrowserwindow/tst_llembeddedbrowserwindow.cpp @@ -0,0 +1,1027 @@ +/* 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 + +#include "llembeddedbrowserwindow.h" +#include "llembeddedbrowser.h" + +#ifndef QTRY_COMPARE + +#define __TRY_TIMEOUT__ 10000 +#define __TRY_STEP__ 50 + +#define __QTRY(__expression__, __functionToCall__) \ + do { \ + int __i = 0; \ + while (!(__expression__) && __i < __TRY_TIMEOUT__) { \ + QTest::qWait(__TRY_STEP__); \ + __i += __TRY_STEP__; \ + } \ + __functionToCall__; \ + } while(0) + +#define QTRY_COMPARE(__expression__, __expected__) \ + __QTRY((__expression__ == __expected__), QCOMPARE(__expression__, __expected__)); + +#define QTRY_VERIFY(__expression__) \ + __QTRY(__expression__, QVERIFY(__expression__)); + +#endif // QTRY_COMPARE + +class tst_LLEmbeddedBrowserWindow : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void llembeddedbrowserwindow_data(); + void llembeddedbrowserwindow(); + + void addObserver_data(); + void addObserver(); + void canNavigateBack_data(); + void canNavigateBack(); + void canNavigateForward_data(); + void canNavigateForward(); + void evaluateJavascript_data(); + void evaluateJavascript(); + void flipWindow_data(); + void flipWindow(); + void focusBrowser_data(); + void focusBrowser(); + void getBrowserDepth_data(); + void getBrowserDepth(); + void getBrowserHeight_data(); + void getBrowserHeight(); + void getBrowserRowSpan_data(); + void getBrowserRowSpan(); + void getBrowserWidth_data(); + void getBrowserWidth(); + void getClickLinkHref_data(); + void getClickLinkHref(); + void getClickLinkTarget_data(); + void getClickLinkTarget(); + void getCurrentUri_data(); + void getCurrentUri(); + void getNoFollowScheme_data(); + void getNoFollowScheme(); + void getPageBuffer_data(); + void getPageBuffer(); + void getPercentComplete_data(); + void getPercentComplete(); + void getStatusMsg_data(); + void getStatusMsg(); + void getWindowId_data(); + void getWindowId(); + void grabWindow_data(); + void grabWindow(); + void keyPress_data(); + void keyPress(); + void mouseDown_data(); + void mouseDown(); + void mouseLeftDoubleClick_data(); + void mouseLeftDoubleClick(); + void mouseMove_data(); + void mouseMove(); + void mouseUp_data(); + void mouseUp(); + void navigateBack_data(); + void navigateBack(); + void navigateForward_data(); + void navigateForward(); + void navigateReload_data(); + void navigateReload(); + void navigateStop_data(); + void navigateStop(); + void navigateTo_data(); + void navigateTo(); + void remObserver_data(); + void remObserver(); + void scrollByLines_data(); + void scrollByLines(); + void setBackgroundColor_data(); + void setBackgroundColor(); + void setCaretColor_data(); + void setCaretColor(); + void setEnabled_data(); + void setEnabled(); + void setNoFollowScheme_data(); + void setNoFollowScheme(); + void setParent_data(); + void setParent(); + void setSize_data(); + void setSize(); + void setWindowId_data(); + void setWindowId(); + void unicodeInput_data(); + void unicodeInput(); +}; + +// Subclass that exposes the protected functions. +class SubLLEmbeddedBrowserWindow : public LLEmbeddedBrowserWindow +{ +public: + +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_LLEmbeddedBrowserWindow::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_LLEmbeddedBrowserWindow::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_LLEmbeddedBrowserWindow::init() +{ +} + +// This will be called after every test function. +void tst_LLEmbeddedBrowserWindow::cleanup() +{ +} + +void tst_LLEmbeddedBrowserWindow::llembeddedbrowserwindow_data() +{ +} + +void tst_LLEmbeddedBrowserWindow::llembeddedbrowserwindow() +{ + SubLLEmbeddedBrowserWindow window; + QCOMPARE(window.addObserver((LLEmbeddedBrowserWindowObserver*)0), false); + QCOMPARE(window.canNavigateBack(), false); + QCOMPARE(window.canNavigateForward(), false); + QCOMPARE(window.evaluateJavascript(std::string()), std::string()); + QCOMPARE(window.flipWindow(false), true); + window.focusBrowser(false); + QCOMPARE(window.getBrowserDepth(), (int16_t)4); + QCOMPARE(window.getBrowserHeight(), (int16_t)0); + QCOMPARE(window.getBrowserRowSpan(), (int32_t)0); + QCOMPARE(window.getBrowserWidth(), (int16_t)0); + QCOMPARE(window.getClickLinkHref(), std::string()); + QCOMPARE(window.getClickLinkTarget(), std::string()); + QCOMPARE(window.getCurrentUri(), std::string()); + QCOMPARE(window.getNoFollowScheme(), std::string("secondlife")); + QCOMPARE(window.getPageBuffer(), (unsigned char*)0); + QCOMPARE(window.getPercentComplete(), (int16_t)0); + QCOMPARE(window.getStatusMsg(), std::string()); + QCOMPARE(window.getWindowId(), -1); + QCOMPARE(window.grabWindow(-1, -1, -1, -1), (unsigned char*)0); + window.keyPress(0); + window.mouseDown(0, 0); + window.mouseLeftDoubleClick(0, 0); + window.mouseMove(0, 0); + window.mouseUp(0, 0); + window.navigateBack(); + window.navigateForward(); + window.navigateReload(); + window.navigateStop(); + QCOMPARE(window.navigateTo(std::string()), true); + QCOMPARE(window.remObserver((LLEmbeddedBrowserWindowObserver*)0), false); + window.scrollByLines(0); + window.setBackgroundColor(0, 0, 0); + window.setCaretColor(0, 0, 0); + window.setEnabled(false); + window.setNoFollowScheme(std::string()); + window.setParent((LLEmbeddedBrowser*)0); + QCOMPARE(window.setSize(0, 0), true); + window.setWindowId(-1); + window.unicodeInput((uint32_t)0); +} + +void tst_LLEmbeddedBrowserWindow::addObserver_data() +{ +#if 0 + QTest::addColumn("observerCount"); + QTest::addColumn("addObserver"); + QTest::newRow("null") << 0 << false; +#endif +} + +// public bool addObserver(LLEmbeddedBrowserWindowObserver* observer) +void tst_LLEmbeddedBrowserWindow::addObserver() +{ +#if 0 + QFETCH(int, observerCount); + QFETCH(bool, addObserver); + + SubLLEmbeddedBrowserWindow window; + + QCOMPARE(window.addObserver(observer), addObserver); +#endif + QSKIP("Test is same with remObserver.", SkipAll); +} + +void tst_LLEmbeddedBrowserWindow::canNavigateBack_data() +{ +#if 0 + QTest::addColumn("canNavigateBack"); + QTest::newRow("true") << true; + QTest::newRow("false") << false; +#endif +} + +// public bool canNavigateBack() +void tst_LLEmbeddedBrowserWindow::canNavigateBack() +{ + //QFETCH(bool, canNavigateForward); + + SubLLEmbeddedBrowserWindow window; + window.setSize(800,600); + window.setParent(new LLEmbeddedBrowser()); + QCOMPARE(window.canNavigateForward(), false); + window.navigateTo(std::string("http://www.google.com")); + QTest::qWait(__TRY_TIMEOUT__); + QCOMPARE(window.canNavigateBack(), false); + window.navigateTo(std::string("http://www.cnn.com")); + QTest::qWait(__TRY_TIMEOUT__); + QCOMPARE(window.canNavigateBack(), true); + window.navigateBack(); + QTRY_COMPARE(window.canNavigateForward(), true); + window.navigateForward(); + QTRY_COMPARE(window.canNavigateBack(), true); +} + +void tst_LLEmbeddedBrowserWindow::canNavigateForward_data() +{ +#if 0 + QTest::addColumn("canNavigateForward"); + QTest::newRow("true") << true; + QTest::newRow("false") << false; +#endif +} + +// public bool canNavigateForward() +void tst_LLEmbeddedBrowserWindow::canNavigateForward() +{ + QSKIP("Test is same with canNavigateBack().", SkipAll); +} + +Q_DECLARE_METATYPE(std::string) +void tst_LLEmbeddedBrowserWindow::evaluateJavascript_data() +{ + QTest::addColumn("script"); + QTest::addColumn("evaluateJavascript"); + QTest::newRow("null") << std::string() << std::string(); + //QTest::newRow("valid") << std::string("alert(\"hey!\")") << std::string("alert(\"hey!\")"); +} + +// public std::string evaluateJavascript(std::string script) +void tst_LLEmbeddedBrowserWindow::evaluateJavascript() +{ + QFETCH(std::string, script); + QFETCH(std::string, evaluateJavascript); + + SubLLEmbeddedBrowserWindow window; + + window.evaluateJavascript(script); +} + +void tst_LLEmbeddedBrowserWindow::flipWindow_data() +{ + QTest::addColumn("flip"); + QTest::addColumn("flipWindow"); + QTest::newRow("false") << false << true; + QTest::newRow("true") << true << true; +} + +// public bool flipWindow(bool flip) +void tst_LLEmbeddedBrowserWindow::flipWindow() +{ + QFETCH(bool, flip); + QFETCH(bool, flipWindow); + + SubLLEmbeddedBrowserWindow window; + + QCOMPARE(window.flipWindow(flip), flipWindow); +} + +void tst_LLEmbeddedBrowserWindow::focusBrowser_data() +{ + QTest::addColumn("focus_browser"); + QTest::newRow("true") << true; + QTest::newRow("false") << false; +} + +// public void focusBrowser(bool focus_browser) +void tst_LLEmbeddedBrowserWindow::focusBrowser() +{ + QFETCH(bool, focus_browser); + + SubLLEmbeddedBrowserWindow window; + window.focusBrowser(focus_browser); +} + +Q_DECLARE_METATYPE(int16_t) +void tst_LLEmbeddedBrowserWindow::getBrowserDepth_data() +{ +#if 0 + QTest::addColumn("getBrowserDepth"); + QTest::newRow("null") << int16_t(); +#endif +} + +// public int16_t getBrowserDepth() +void tst_LLEmbeddedBrowserWindow::getBrowserDepth() +{ + //QFETCH(int16_t, getBrowserDepth); + + SubLLEmbeddedBrowserWindow window; + + QCOMPARE(window.getBrowserDepth(), int16_t(4)); +} + +void tst_LLEmbeddedBrowserWindow::getBrowserHeight_data() +{ +#if 0 + QTest::addColumn("getBrowserHeight"); + QTest::newRow("null") << int16_t(); +#endif +} + +// public int16_t getBrowserHeight() +void tst_LLEmbeddedBrowserWindow::getBrowserHeight() +{ +#if 0 + QFETCH(int16_t, getBrowserHeight); + + SubLLEmbeddedBrowserWindow window; + + QCOMPARE(window.getBrowserHeight(), getBrowserHeight); +#endif + QSKIP("Test is same with setSize().", SkipAll); +} + +Q_DECLARE_METATYPE(int32_t) +void tst_LLEmbeddedBrowserWindow::getBrowserRowSpan_data() +{ +#if 0 + QTest::addColumn("getBrowserRowSpan"); + QTest::newRow("null") << int32_t(); +#endif +} + +// public int32_t getBrowserRowSpan() +void tst_LLEmbeddedBrowserWindow::getBrowserRowSpan() +{ +#if 0 + SubLLEmbeddedBrowserWindow window; + window.setSize(0, 0); + + QCOMPARE(window.getBrowserWidth(), int16_t(0)); + QCOMPARE(window.getBrowserRowSpan(), int32_t(0)); + window.setSize(100, 100); + + QCOMPARE(window.getBrowserWidth(), int16_t(100)); + QCOMPARE(window.getBrowserRowSpan(), int32_t(400)); +#endif + QSKIP("Test is same with setSize().", SkipAll); +} + +void tst_LLEmbeddedBrowserWindow::getBrowserWidth_data() +{ +#if 0 + QTest::addColumn("getBrowserWidth"); + QTest::newRow("null") << int16_t(); +#endif +} + +// public int16_t getBrowserWidth() +void tst_LLEmbeddedBrowserWindow::getBrowserWidth() +{ +#if 0 + //QFETCH(int16_t, getBrowserWidth); + + SubLLEmbeddedBrowserWindow window; + window.setSize(0, 0); + + QCOMPARE(window.getBrowserWidth(), int16_t(0)); + QCOMPARE(window.getBrowserHeight(), int16_t(0)); + window.setSize(100, 100); + + QCOMPARE(window.getBrowserWidth(), int16_t(100)); + QCOMPARE(window.getBrowserHeight(), int16_t(100)); +#endif + QSKIP("Test is same with setSize().", SkipAll); +} + +//Q_DECLARE_METATYPE(std::string const) +void tst_LLEmbeddedBrowserWindow::getClickLinkHref_data() +{ +#if 0 + QTest::addColumn("getClickLinkHref"); + QTest::newRow("null") << std::string const(); +#endif +} + +// public std::string const getClickLinkHref() +void tst_LLEmbeddedBrowserWindow::getClickLinkHref() +{ + //QFETCH(std::string const, getClickLinkHref); + + SubLLEmbeddedBrowserWindow window; + + window.getClickLinkHref(); +} + +void tst_LLEmbeddedBrowserWindow::getClickLinkTarget_data() +{ +#if 0 + QTest::addColumn("getClickLinkTarget"); + QTest::newRow("null") << std::string const(); +#endif +} + +// public std::string const getClickLinkTarget() +void tst_LLEmbeddedBrowserWindow::getClickLinkTarget() +{ + //QFETCH(std::string const, getClickLinkTarget); + + SubLLEmbeddedBrowserWindow window; + + window.getClickLinkTarget(); +} + +void tst_LLEmbeddedBrowserWindow::getCurrentUri_data() +{ +#if 0 + QTest::addColumn("getCurrentUri"); + QTest::newRow("null") << std::string const(); +#endif +} + +// public std::string const getCurrentUri() +void tst_LLEmbeddedBrowserWindow::getCurrentUri() +{ + //QFETCH(std::string const, getCurrentUri); + + SubLLEmbeddedBrowserWindow window; + window.navigateTo(std::string("http://www.google.ca/")); + QTRY_COMPARE(QString::fromStdString(window.getCurrentUri()), QString::fromStdString(std::string("http://www.google.ca/"))); +} + +void tst_LLEmbeddedBrowserWindow::getNoFollowScheme_data() +{ +#if 0 + QTest::addColumn("getNoFollowScheme"); + QTest::newRow("FTP") << std::string("FTP"); +#endif +} + +// public std::string getNoFollowScheme() +void tst_LLEmbeddedBrowserWindow::getNoFollowScheme() +{ + //QFETCH(std::string, getNoFollowScheme); + + SubLLEmbeddedBrowserWindow window; + window.setNoFollowScheme("FTP://www.google.com"); + + QCOMPARE(window.getNoFollowScheme(), std::string("FTP")); +} + +//Q_DECLARE_METATYPE(unsigned char*) +void tst_LLEmbeddedBrowserWindow::getPageBuffer_data() +{ +#if 0 + QTest::addColumn("getPageBuffer"); + QTest::newRow("null") << unsigned char*(); +#endif +} + +// public unsigned char* getPageBuffer() +void tst_LLEmbeddedBrowserWindow::getPageBuffer() +{ + //QFETCH(unsigned char*, getPageBuffer); + + SubLLEmbeddedBrowserWindow window; + window.setSize(100,100); + window.grabWindow(0, 0, 100, 100); + + QVERIFY(window.getPageBuffer() != NULL); +} + +//Q_DECLARE_METATYPE(int16_t const) +void tst_LLEmbeddedBrowserWindow::getPercentComplete_data() +{ +#if 0 + QTest::addColumn("getPercentComplete"); + QTest::newRow("null") << int16_t const(); +#endif +} + +// public int16_t const getPercentComplete() +void tst_LLEmbeddedBrowserWindow::getPercentComplete() +{ + //QFETCH(int16_t const, getPercentComplete); + SubLLEmbeddedBrowserWindow window; + window.navigateTo(std::string("http://www.google.com")); + QTest::qWait(1000); + QVERIFY(window.getPercentComplete() > 0); +} + +void tst_LLEmbeddedBrowserWindow::getStatusMsg_data() +{ +#if 0 + QTest::addColumn("getStatusMsg"); + QTest::newRow("null") << std::string const(); +#endif +} + +// public std::string const getStatusMsg() +void tst_LLEmbeddedBrowserWindow::getStatusMsg() +{ + //QFETCH(std::string const, getStatusMsg); + + SubLLEmbeddedBrowserWindow window; + window.navigateTo(std::string("http://www.google.com")); + QTest::qWait(1000); + window.navigateStop(); + window.navigateTo(std::string("http://www.yahoo.com")); + // Seems status msg will always be null during navigating. + //QTRY_VERIFY(QString::fromStdString(window.getStatusMsg())!= NULL); + QSKIP("Status msg will always be null during navigating", SkipAll); +} + +void tst_LLEmbeddedBrowserWindow::getWindowId_data() +{ +#if 0 + QTest::addColumn("getWindowId"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +#endif +} + +// public int getWindowId() +void tst_LLEmbeddedBrowserWindow::getWindowId() +{ + //QFETCH(int, getWindowId); + + SubLLEmbeddedBrowserWindow window; + window.setWindowId(0); + QCOMPARE(window.getWindowId(), 0); + window.setWindowId(100); + QCOMPARE(window.getWindowId(), 100); +} + +void tst_LLEmbeddedBrowserWindow::grabWindow_data() +{ +#if 0 + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::addColumn("grabWindow"); + QTest::newRow("null") << 0 << 0 << 0 << 0 << 0; +#endif +} + +// public unsigned char* grabWindow(int x, int y, int width, int height) +void tst_LLEmbeddedBrowserWindow::grabWindow() +{ + QSKIP("Test is same with getPageBuffer().", SkipAll); +} + +void tst_LLEmbeddedBrowserWindow::keyPress_data() +{ + QTest::addColumn("key_code"); + QTest::newRow("null") << int16_t(0); + QTest::newRow("valid") << int16_t(0x0E); +} + +// public void keyPress(int16_t key_code) +void tst_LLEmbeddedBrowserWindow::keyPress() +{ + QFETCH(int16_t, key_code); + + SubLLEmbeddedBrowserWindow window; + window.keyPress(key_code); +} + +void tst_LLEmbeddedBrowserWindow::mouseDown_data() +{ + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::newRow("0") << int16_t(0) << int16_t(0); + QTest::newRow("bignumber") << int16_t(100000) << int16_t(100000); + QTest::newRow("valid") << int16_t(100) << int16_t(100); +} + +// public void mouseDown(int16_t x, int16_t y) +void tst_LLEmbeddedBrowserWindow::mouseDown() +{ + QFETCH(int16_t, x); + QFETCH(int16_t, y); + + SubLLEmbeddedBrowserWindow window; + window.mouseDown(x, y); +} + +void tst_LLEmbeddedBrowserWindow::mouseLeftDoubleClick_data() +{ + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::newRow("0") << int16_t(0) << int16_t(0); + QTest::newRow("bignumber") << int16_t(100000) << int16_t(100000); + QTest::newRow("valid") << int16_t(100) << int16_t(100); +} + +// public void mouseLeftDoubleClick(int16_t x, int16_t y) +void tst_LLEmbeddedBrowserWindow::mouseLeftDoubleClick() +{ + QFETCH(int16_t, x); + QFETCH(int16_t, y); + + SubLLEmbeddedBrowserWindow window; + window.mouseLeftDoubleClick(x, y); +} + +void tst_LLEmbeddedBrowserWindow::mouseMove_data() +{ + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::newRow("0") << int16_t(0) << int16_t(0); + QTest::newRow("bignumber") << int16_t(100000) << int16_t(100000); + QTest::newRow("valid") << int16_t(100) << int16_t(100); +} + +// public void mouseMove(int16_t x, int16_t y) +void tst_LLEmbeddedBrowserWindow::mouseMove() +{ + QFETCH(int16_t, x); + QFETCH(int16_t, y); + + SubLLEmbeddedBrowserWindow window; + window.mouseMove(x, y); +} + +void tst_LLEmbeddedBrowserWindow::mouseUp_data() +{ + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::newRow("0") << int16_t(0) << int16_t(0); + QTest::newRow("bignumber") << int16_t(100000) << int16_t(100000); + QTest::newRow("valid") << int16_t(100) << int16_t(100); +} + +// public void mouseUp(int16_t x, int16_t y) +void tst_LLEmbeddedBrowserWindow::mouseUp() +{ + QFETCH(int16_t, x); + QFETCH(int16_t, y); + + SubLLEmbeddedBrowserWindow window; + window.mouseUp(x, y); +} + +void tst_LLEmbeddedBrowserWindow::navigateBack_data() +{ +#if 0 + QTest::addColumn("foo"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +#endif +} + +// public void navigateBack() +void tst_LLEmbeddedBrowserWindow::navigateBack() +{ + //QFETCH(int, foo); + + SubLLEmbeddedBrowserWindow window; + window.navigateTo(std::string("http://www.google.ca/")); + QTest::qWait(__TRY_TIMEOUT__); + QCOMPARE(window.canNavigateForward(), false); + window.navigateTo(std::string("http://www.yahoo.com/")); + QTest::qWait(__TRY_TIMEOUT__); + QCOMPARE(window.canNavigateBack(), true); + window.navigateBack(); + QTRY_COMPARE(QString::fromStdString((window.getCurrentUri())), QString("http://www.google.ca/")); + window.navigateBack(); + QTRY_COMPARE(QString::fromStdString((window.getCurrentUri())), QString("http://www.google.ca/")); +} + +void tst_LLEmbeddedBrowserWindow::navigateForward_data() +{ +#if 0 + QTest::addColumn("foo"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +#endif +} + +// public void navigateForward() +void tst_LLEmbeddedBrowserWindow::navigateForward() +{ + // QFETCH(int, foo); + SubLLEmbeddedBrowserWindow window; + window.navigateTo(std::string("http://www.google.ca/")); + QTest::qWait(__TRY_TIMEOUT__); + QCOMPARE(window.canNavigateForward(), false); + window.navigateTo(std::string("http://www.yahoo.ca/")); + QTest::qWait(__TRY_TIMEOUT__); + QCOMPARE(window.canNavigateBack(), true); + window.navigateBack(); + QTRY_COMPARE(QString::fromStdString((window.getCurrentUri())), QString("http://www.google.ca/")); + window.navigateForward(); + QTRY_COMPARE(QString::fromStdString((window.getCurrentUri())), QString("http://ca.yahoo.com/")); + window.navigateForward(); + QTRY_COMPARE(QString::fromStdString((window.getCurrentUri())), QString("http://ca.yahoo.com/")); +} + +void tst_LLEmbeddedBrowserWindow::navigateReload_data() +{ +#if 0 + QTest::addColumn("foo"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +#endif +} + +// public void navigateReload() +void tst_LLEmbeddedBrowserWindow::navigateReload() +{ + SubLLEmbeddedBrowserWindow window; + + window.navigateTo(std::string("http://www.google.ca/")); + QTest::qWait(__TRY_TIMEOUT__); + window.navigateReload(); + QTRY_COMPARE(QString::fromStdString((window.getCurrentUri())), QString("http://www.google.ca/")); +} + +void tst_LLEmbeddedBrowserWindow::navigateStop_data() +{ +#if 0 + QTest::addColumn("foo"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +#endif +} + +// public void navigateStop() +void tst_LLEmbeddedBrowserWindow::navigateStop() +{ + SubLLEmbeddedBrowserWindow window; + window.navigateTo("www.google.com"); + window.navigateStop(); +} + +void tst_LLEmbeddedBrowserWindow::navigateTo_data() +{ + QTest::addColumn("uri"); + QTest::addColumn("navigateTo"); + QTest::newRow("null") << std::string() << std::string(); + QTest::newRow("valid") << std::string("http://www.google.ca/") << std::string("http://www.google.ca/"); +} + +// public bool navigateTo(std::string const uri) +void tst_LLEmbeddedBrowserWindow::navigateTo() +{ + QSKIP("Test is same with navigateBack(), navigateForward().", SkipAll); +} + +void tst_LLEmbeddedBrowserWindow::remObserver_data() +{ +#if 0 + QTest::addColumn("observerCount"); + QTest::addColumn("remObserver"); + QTest::newRow("null") << 0 << false; +#endif +} + +// public bool remObserver(LLEmbeddedBrowserWindowObserver* observer) +void tst_LLEmbeddedBrowserWindow::remObserver() +{ +// QFETCH(int, observerCount); +// QFETCH(bool, remObserver); + + SubLLEmbeddedBrowserWindow window; + LLEmbeddedBrowserWindowObserver* observer = new LLEmbeddedBrowserWindowObserver(); + window.addObserver(observer); + QCOMPARE(window.getObserverNumber(), 1); + window.remObserver(observer); + QCOMPARE(window.getObserverNumber(), 0); +} + +void tst_LLEmbeddedBrowserWindow::scrollByLines_data() +{ + QTest::addColumn("lines"); + QTest::newRow("null") << int16_t(0); + QTest::addColumn("lines"); + QTest::newRow("100") << int16_t(100); +} + +// public void scrollByLines(int16_t lines) +void tst_LLEmbeddedBrowserWindow::scrollByLines() +{ + QFETCH(int16_t, lines); + + SubLLEmbeddedBrowserWindow window; + + window.scrollByLines(lines); +} + +Q_DECLARE_METATYPE(uint8_t) +void tst_LLEmbeddedBrowserWindow::setBackgroundColor_data() +{ + QTest::addColumn("red"); + QTest::addColumn("green"); + QTest::addColumn("blue"); + QTest::newRow("black") << uint8_t(0) << uint8_t(0) << uint8_t(0); + QTest::newRow("red") << uint8_t(255) << uint8_t(0) << uint8_t(0); + QTest::newRow("green") << uint8_t(0) << uint8_t(255) << uint8_t(0); + QTest::newRow("blue") << uint8_t(0) << uint8_t(0) << uint8_t(255); +} + +// public void setBackgroundColor(uint8_t const red, uint8_t const green, uint8_t const blue) +void tst_LLEmbeddedBrowserWindow::setBackgroundColor() +{ + QFETCH(uint8_t, red); + QFETCH(uint8_t, green); + QFETCH(uint8_t, blue); + + SubLLEmbeddedBrowserWindow window; + + window.setBackgroundColor(red, green, blue); +} + +void tst_LLEmbeddedBrowserWindow::setCaretColor_data() +{ + QTest::addColumn("red"); + QTest::addColumn("green"); + QTest::addColumn("blue"); + QTest::newRow("black") << uint8_t(0) << uint8_t(0) << uint8_t(0); + QTest::newRow("red") << uint8_t(255) << uint8_t(0) << uint8_t(0); + QTest::newRow("green") << uint8_t(0) << uint8_t(255) << uint8_t(0); + QTest::newRow("blue") << uint8_t(0) << uint8_t(0) << uint8_t(255); +} + +// public void setCaretColor(uint8_t const red, uint8_t const green, uint8_t const blue) +void tst_LLEmbeddedBrowserWindow::setCaretColor() +{ + QFETCH(uint8_t, red); + QFETCH(uint8_t, green); + QFETCH(uint8_t, blue); + + SubLLEmbeddedBrowserWindow window; + + window.setCaretColor(red, green, blue); +} + +void tst_LLEmbeddedBrowserWindow::setEnabled_data() +{ + QTest::addColumn("enabledIn"); + QTest::newRow("true") << true; + QTest::newRow("false") << false; +} + +// public void setEnabled(bool enabledIn) +void tst_LLEmbeddedBrowserWindow::setEnabled() +{ + QFETCH(bool, enabledIn); + + SubLLEmbeddedBrowserWindow window; + + window.setEnabled(enabledIn); +} + +void tst_LLEmbeddedBrowserWindow::setNoFollowScheme_data() +{ + QTest::addColumn("scheme"); + QTest::addColumn("result"); + QTest::newRow("null") << std::string() << std::string(); + QTest::newRow("valid") << std::string("ftp://www.google.com") << std::string("ftp");; +} + +// public void setNoFollowScheme(std::string scheme) +void tst_LLEmbeddedBrowserWindow::setNoFollowScheme() +{ + QFETCH(std::string, scheme); + QFETCH(std::string, result); + + SubLLEmbeddedBrowserWindow window; + + window.setNoFollowScheme(scheme); + QCOMPARE(window.getNoFollowScheme(), result); +} + +void tst_LLEmbeddedBrowserWindow::setParent_data() +{ +#if 0 + QTest::addColumn("parentCount"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +#endif +} + +// public void setParent(LLEmbeddedBrowser* parent) +void tst_LLEmbeddedBrowserWindow::setParent() +{ +#if 0 + QFETCH(int, parentCount); + + SubLLEmbeddedBrowserWindow window; + LLEmbeddedBrowser* parent = new LLEmbeddedBrowser(); + + window.setParent(parent); +#endif + QSKIP("Has been tested before.", SkipAll); +} + +void tst_LLEmbeddedBrowserWindow::setSize_data() +{ + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::addColumn("setSize"); + QTest::newRow("null") << int16_t(0) << int16_t(0) << true; + QTest::newRow("valid") << int16_t(100) << int16_t(200) << true; +} + +// public bool setSize(int16_t width, int16_t height) +void tst_LLEmbeddedBrowserWindow::setSize() +{ + QFETCH(int16_t, width); + QFETCH(int16_t, height); + QFETCH(bool, setSize); + + SubLLEmbeddedBrowserWindow window; + QCOMPARE(window.setSize(width, height), setSize); + window.grabWindow(0, 0, 800, 600); + + QCOMPARE(window.getBrowserWidth(), width); + QCOMPARE(window.getBrowserHeight(), height); + QCOMPARE(window.getBrowserRowSpan(), (int32_t)width * 4); +} + +void tst_LLEmbeddedBrowserWindow::setWindowId_data() +{ + QTest::addColumn("window_id"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; + QTest::newRow("100") << 100; +} + +// public void setWindowId(int window_id) +void tst_LLEmbeddedBrowserWindow::setWindowId() +{ + QFETCH(int, window_id); + + SubLLEmbeddedBrowserWindow window; + + window.setWindowId(window_id); + QCOMPARE(window.getWindowId(), window_id); +} + +Q_DECLARE_METATYPE(uint32_t) +void tst_LLEmbeddedBrowserWindow::unicodeInput_data() +{ + QTest::addColumn("unicode_char"); + QTest::newRow("null") << uint32_t(); + QTest::newRow("valid") << uint32_t(54); +} + +// public void unicodeInput(uint32_t unicode_char) +void tst_LLEmbeddedBrowserWindow::unicodeInput() +{ + QFETCH(uint32_t, unicode_char); + + SubLLEmbeddedBrowserWindow window; + + window.unicodeInput(unicode_char); +} + +QTEST_MAIN(tst_LLEmbeddedBrowserWindow) +#include "tst_llembeddedbrowserwindow.moc" + diff --git a/indra/llqtwebkit/llembeddedbrowser.cpp b/indra/llqtwebkit/llembeddedbrowser.cpp new file mode 100644 index 000000000..f38019b9b --- /dev/null +++ b/indra/llqtwebkit/llembeddedbrowser.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +// 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 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 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 LLNetworkCookieJar::cookiesForUrl(const QUrl& url) const +{ + if (!mAllowCookies) + return QList(); + return NetworkCookieJar::cookiesForUrl(url); +} + +bool LLNetworkCookieJar::setCookiesFromUrl(const QList &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 cookie_list = QNetworkCookie::parseCookies(cookie_bytearray); + setCookies(cookie_list); +} + +std::string LLNetworkCookieJar::getAllCookiesInRawForm() +{ + std::string result; + + QList 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 + +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; +} diff --git a/indra/llqtwebkit/llembeddedbrowser.h b/indra/llqtwebkit/llembeddedbrowser.h new file mode 100644 index 000000000..c21a6b063 --- /dev/null +++ b/indra/llqtwebkit/llembeddedbrowser.h @@ -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 +#include +#include +#include + +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 + diff --git a/indra/llqtwebkit/llembeddedbrowser_p.h b/indra/llqtwebkit/llembeddedbrowser_p.h new file mode 100644 index 000000000..9f9f9cd02 --- /dev/null +++ b/indra/llqtwebkit/llembeddedbrowser_p.h @@ -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 +#include +#if QT_VERSION >= 0x040500 +#include +#endif + +#include "networkcookiejar.h" +#include "llembeddedbrowser.h" + +#include + +class LLEmbeddedBrowser; +class LLNetworkCookieJar : public NetworkCookieJar +{ +public: + LLNetworkCookieJar(QObject *parent, LLEmbeddedBrowser *browser); + ~LLNetworkCookieJar(); + + QList cookiesForUrl(const QUrl& url) const; + bool setCookiesFromUrl(const QList &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 windows; + + std::string mHostLanguage; + bool mIgnoreSSLCertErrors; +}; + +#endif + diff --git a/indra/llqtwebkit/llembeddedbrowserwindow.cpp b/indra/llqtwebkit/llembeddedbrowserwindow.cpp new file mode 100644 index 000000000..c990d5567 --- /dev/null +++ b/indra/llqtwebkit/llembeddedbrowserwindow.cpp @@ -0,0 +1,1136 @@ +/* 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "llembeddedbrowserwindow.h" +#include "llembeddedbrowserwindow_p.h" + +#include "llembeddedbrowser.h" +#include "llembeddedbrowser_p.h" +#include "llnetworkaccessmanager.h" + +#ifdef STATIC_QT + #include + // Enable gif and jpeg plugins, since web pages look pretty bleak without gifs or jpegs. + // Qt 4.7 uses the system gif and jpeg libraries by default, so this is no longer necessary. +// Q_IMPORT_PLUGIN(qgif) +// Q_IMPORT_PLUGIN(qjpeg) +#ifndef LL_LINUX + // Qt also has its own translators for CJK text encodings we need to pull in. + Q_IMPORT_PLUGIN(qcncodecs) + Q_IMPORT_PLUGIN(qjpcodecs) + Q_IMPORT_PLUGIN(qkrcodecs) + Q_IMPORT_PLUGIN(qtwcodecs) +#endif +#endif + +//#define LLEMBEDDEDBROWSER_DEBUG 1 + +#ifdef LLEMBEDDEDBROWSER_DEBUG +#include +#endif + +#if LL_DARWIN || defined(STATIC_QT) + // Don't define qt_sendSpontaneousEvent on the mac -- it causes a multiply-defined symbol. + extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); +#else + #include + bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event) + { + return QCoreApplication::sendSpontaneousEvent(receiver, event); + } +#endif + +LLEmbeddedBrowserWindow::LLEmbeddedBrowserWindow() +{ + d = new LLEmbeddedBrowserWindowPrivate(); + + d->mPage = new LLWebPage; + d->mInspector = new QWebInspector; + d->mInspector->setPage(d->mPage); + d->mPage->window = this; + d->mView = new LLWebView; + d->mPage->webView = d->mView; + d->mView->window = this; + d->mView->setPage(d->mPage); + d->mGraphicsScene = new LLGraphicsScene; + d->mGraphicsScene->window = this; + d->mGraphicsView = new QGraphicsView; + d->mGraphicsScene->addItem(d->mView); + d->mGraphicsView->setScene(d->mGraphicsScene); + d->mGraphicsScene->setStickyFocus(true); + d->mGraphicsView->viewport()->setParent(0); + + mEnableLoadingOverlay = false; +} + +LLEmbeddedBrowserWindow::~LLEmbeddedBrowserWindow() +{ + delete d; +} + +void LLEmbeddedBrowserWindow::setParent(LLEmbeddedBrowser* parent) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << parent; +#endif + d->mParent = parent; + if (parent) + { + d->mPage->setNetworkAccessManager(parent->d->mNetworkAccessManager); + } else + { + d->mPage->setNetworkAccessManager(0); + } +} + +void LLEmbeddedBrowserWindow::showWebInspector(bool show) +{ + if ( d ) + { + if ( d->mInspector ) + { + d->mInspector->setVisible( show ); + } + } +} + +void LLEmbeddedBrowserWindow::enableLoadingOverlay(bool enable) +{ + mEnableLoadingOverlay = enable; +} + +// change the background color that gets used between pages (usually white) +void LLEmbeddedBrowserWindow::setBackgroundColor(const uint8_t red, const uint8_t green, const uint8_t blue) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << red << green << blue; +#endif + d->backgroundColor = QColor(red, green, blue); +} + +// +void LLEmbeddedBrowserWindow::setEnabled(bool enabled) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << enabled; +#endif + d->mEnabled = enabled; +} + +// allow consumers of this class to observe events - add themselves as an observer +bool LLEmbeddedBrowserWindow::addObserver(LLEmbeddedBrowserWindowObserver* observer) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << observer; +#endif + return d->mEventEmitter.addObserver(observer); +} + +// allow consumers of this class to observe events - remove themselves as an observer +bool LLEmbeddedBrowserWindow::remObserver(LLEmbeddedBrowserWindowObserver* observer) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << observer; +#endif + return d->mEventEmitter.remObserver(observer); +} + +int LLEmbeddedBrowserWindow::getObserverNumber() +{ + return d->mEventEmitter.getObserverNumber(); +} + +// used by observers of this class to get the current URI +std::string& LLEmbeddedBrowserWindow::getCurrentUri() +{ + d->mCurrentUri = llToStdString(d->mPage->mainFrame()->url()); + return d->mCurrentUri; +} + +// utility method that is used by observers to retrieve data after an event +int16_t LLEmbeddedBrowserWindow::getPercentComplete() +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__; +#endif + return d->mPercentComplete; +} + +// utility method that is used by observers to retrieve data after an event +std::string& LLEmbeddedBrowserWindow::getStatusMsg() +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__; +#endif + return d->mStatusText; +} + +// render a page into memory and grab the window +unsigned char* LLEmbeddedBrowserWindow::grabWindow(int x, int y, int width, int height) +{ +#if LLEMBEDDEDBROWSER_DEBUG > 10 + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << x << y << width << height; +#endif + // only grab the window if it's enabled + if (!d->mEnabled) + return 0; + + if (!d->mDirty) + return d->mPageBuffer; + + Q_ASSERT(d->mImage.size() == d->mView->size()); + if (!d->mPage->mainFrame()->url().isValid()) + { + d->mImage.fill(d->backgroundColor.value()); + } else + { + QPainter painter(&d->mImage); + + QRectF r(x, y, width, height); + QRect g(0, 0, d->mView->width(), d->mView->height()); + d->mGraphicsView->render(&painter, r, g); + + d->mDirty = false; + + const bool spinner_enabled = false; + if ( spinner_enabled ) + { + const time_t seconds_before_show_overlay = 1; + + if ( mEnableLoadingOverlay && + d->mShowLoadingOverlay && + time(NULL) - d->mTimeLoadStarted >= seconds_before_show_overlay ) + { + painter.setRenderHint(QPainter::Antialiasing);; + + QBrush brush; + QPen pen; + + int size = width; + if ( height < width ) + size = height; + + const int symbol_translucency = 64; // 0=fully trans, 255=opaque + const int symbol_proportion_of_sceen = 8; // (1/8) + const int symbol_diameter = size/(symbol_proportion_of_sceen); + const int symbol_start_line = symbol_diameter*2/3; + const int symbol_end_line = symbol_diameter; + const int symbol_num_segments = 20; + const int symbol_line_width = size/60; + if ( size < 4 ) size = 4; + + QColor background_color(QColor(128,128,128,symbol_translucency)); + brush.setColor(background_color); + brush.setStyle(Qt::SolidPattern); + pen.setColor(background_color); + painter.setPen(pen); + painter.setBrush(brush); + painter.drawRect(0,0,width, height); + + painter.translate(QPoint(width/2, height/2)); + + static int offset=0; + painter.rotate(((qreal)(offset++%(symbol_num_segments))/(qreal)symbol_num_segments)*360.0f); + + for ( int count=0; countmDirty = true; // force dirty so updates happen frequently during load + } + } + + painter.end(); + if (d->mFlipBitmap) + { + d->mImage = d->mImage.mirrored(); + } + d->mImage = d->mImage.rgbSwapped(); + } + + d->mPageBuffer = d->mImage.bits(); + + return d->mPageBuffer; +} + +// return the buffer that contains the rendered page +unsigned char* LLEmbeddedBrowserWindow::getPageBuffer() +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__; +#endif + return d->mPageBuffer; +} + +int16_t LLEmbeddedBrowserWindow::getBrowserWidth() +{ +#if LLEMBEDDEDBROWSER_DEBUG > 10 + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__; +#endif + return d->mImage.width(); +} + +int16_t LLEmbeddedBrowserWindow::getBrowserHeight() +{ +#if LLEMBEDDEDBROWSER_DEBUG > 10 + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__; +#endif + return d->mImage.height(); +} + +int16_t LLEmbeddedBrowserWindow::getBrowserDepth() +{ +#if LLEMBEDDEDBROWSER_DEBUG > 10 + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__; +#endif + return 4; +} + +int32_t LLEmbeddedBrowserWindow::getBrowserRowSpan() +{ +#if LLEMBEDDEDBROWSER_DEBUG > 10 + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__; +#endif + return 4 * getBrowserWidth(); +} + +bool LLEmbeddedBrowserWindow::navigateTo(const std::string uri) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << QString::fromStdString(uri); +#endif + QUrl url = QUrl::fromUserInput(QString::fromStdString(uri)); + + d->mPage->triggerAction(QWebPage::Stop); + d->mPage->mainFrame()->setUrl(url); + d->mPage->mainFrame()->load(url); + return true; +} + +bool LLEmbeddedBrowserWindow::userAction(LLQtWebKit::EUserAction action) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << action; +#endif + bool result = true; + + switch(action) + { + case LLQtWebKit::UA_EDIT_CUT: + d->mPage->triggerAction(QWebPage::Cut); + break; + case LLQtWebKit::UA_EDIT_COPY: + d->mPage->triggerAction(QWebPage::Copy); + break; + case LLQtWebKit::UA_EDIT_PASTE: + d->mPage->triggerAction(QWebPage::Paste); + break; + case LLQtWebKit::UA_NAVIGATE_STOP: + d->mPage->triggerAction(QWebPage::Stop); + break; + case LLQtWebKit::UA_NAVIGATE_BACK: + d->mPage->triggerAction(QWebPage::Back); + break; + case LLQtWebKit::UA_NAVIGATE_FORWARD: + d->mPage->triggerAction(QWebPage::Forward); + break; + case LLQtWebKit::UA_NAVIGATE_RELOAD: + d->mPage->triggerAction(QWebPage::ReloadAndBypassCache); + break; + default: + result = false; + break; + } + + return result; +} + +bool LLEmbeddedBrowserWindow::userActionIsEnabled(LLQtWebKit::EUserAction action) +{ +#if LLEMBEDDEDBROWSER_DEBUG > 10 + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << action; +#endif + + bool result; + + switch(action) + { + case LLQtWebKit::UA_EDIT_CUT: + result = d->mPage->action(QWebPage::Cut)->isEnabled(); + break; + case LLQtWebKit::UA_EDIT_COPY: + result = d->mPage->action(QWebPage::Copy)->isEnabled(); + break; + case LLQtWebKit::UA_EDIT_PASTE: + result = d->mPage->action(QWebPage::Paste)->isEnabled(); + break; + case LLQtWebKit::UA_NAVIGATE_STOP: + result = true; + break; + case LLQtWebKit::UA_NAVIGATE_BACK: + result = d->mPage->history()->canGoBack(); + break; + case LLQtWebKit::UA_NAVIGATE_FORWARD: + result = d->mPage->history()->canGoForward(); + break; + case LLQtWebKit::UA_NAVIGATE_RELOAD: + result = true; + break; + default: + result = false; + break; + } + return result; +} + +// set the size of the browser window +bool LLEmbeddedBrowserWindow::setSize(int16_t width, int16_t height) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << width << height; +#endif + d->mPageBuffer = NULL; + d->mImage = QImage(QSize(width, height), QImage::Format_RGB32); + d->mGraphicsView->resize(width, height); + d->mView->resize(width, height); + d->mImage.fill(d->backgroundColor.rgb()); + return true; +} + +bool LLEmbeddedBrowserWindow::flipWindow(bool flip) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << flip; +#endif + d->mFlipBitmap = flip; + return true; +} + +static Qt::KeyboardModifiers convert_modifiers(LLQtWebKit::EKeyboardModifier modifiers) +{ + Qt::KeyboardModifiers result = Qt::NoModifier; + + if(modifiers & LLQtWebKit::KM_MODIFIER_SHIFT) + result |= Qt::ShiftModifier; + + if(modifiers & LLQtWebKit::KM_MODIFIER_CONTROL) + result |= Qt::ControlModifier; + + if(modifiers & LLQtWebKit::KM_MODIFIER_ALT) + result |= Qt::AltModifier; + + if(modifiers & LLQtWebKit::KM_MODIFIER_META) + result |= Qt::MetaModifier; + + return result; +} + +static Qt::MouseButton qt_button_from_button_number(int button) +{ + Qt::MouseButton result; + + switch(button) + { + default: result = Qt::NoButton; break; + case 0: result = Qt::LeftButton; break; + case 1: result = Qt::RightButton; break; + case 2: result = Qt::MidButton; break; + case 3: result = Qt::XButton1; break; + case 4: result = Qt::XButton2; break; + } + + return result; +} + +static QEvent::Type event_from_mouse_event(LLQtWebKit::EMouseEvent mouse_event) +{ + QEvent::Type result; + + switch(mouse_event) + { + default: + result = QEvent::None; + break; + + case LLQtWebKit::ME_MOUSE_MOVE: + result = QEvent::MouseMove; + break; + + case LLQtWebKit::ME_MOUSE_DOWN: + result = QEvent::MouseButtonPress; + break; + + case LLQtWebKit::ME_MOUSE_UP: + result = QEvent::MouseButtonRelease; + break; + + case LLQtWebKit::ME_MOUSE_DOUBLE_CLICK: + result = QEvent::MouseButtonDblClick; + break; + } + + return result; +} + +static QEvent::Type event_from_keyboard_event(LLQtWebKit::EKeyEvent keyboard_event) +{ + QEvent::Type result; + + switch(keyboard_event) + { + default: + result = QEvent::None; + break; + + case LLQtWebKit::KE_KEY_DOWN: + case LLQtWebKit::KE_KEY_REPEAT: + result = QEvent::KeyPress; + break; + + case LLQtWebKit::KE_KEY_UP: + result = QEvent::KeyRelease; + break; + } + + return result; +} + +void LLEmbeddedBrowserWindow::mouseEvent(LLQtWebKit::EMouseEvent mouse_event, int16_t button, int16_t x, int16_t y, LLQtWebKit::EKeyboardModifier modifiers) +{ +#if LLEMBEDDEDBROWSER_DEBUG > 10 + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << x << y; +#endif + + QEvent::Type type = event_from_mouse_event(mouse_event); + Qt::MouseButton qt_button = qt_button_from_button_number(button); + Qt::KeyboardModifiers qt_modifiers = convert_modifiers(modifiers); + + if(type == QEvent::MouseMove) + { + // Mouse move events should always use "no button". + qt_button = Qt::NoButton; + } + + // FIXME: should the current button state be updated before or after constructing the event? + switch(type) + { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonDblClick: + d->mCurrentMouseButtonState |= qt_button; + break; + + case QEvent::MouseButtonRelease: + d->mCurrentMouseButtonState &= ~qt_button; + break; + + default: + break; + } + + QMouseEvent event(type, QPoint(x, y), qt_button, d->mCurrentMouseButtonState, qt_modifiers); + + qt_sendSpontaneousEvent(d->mGraphicsView->viewport(), &event); +} + +void LLEmbeddedBrowserWindow::scrollWheelEvent(int16_t x, int16_t y, int16_t scroll_x, int16_t scroll_y, LLQtWebKit::EKeyboardModifier modifiers) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << x << y; +#endif + + Qt::KeyboardModifiers qt_modifiers = convert_modifiers(modifiers); + + if(scroll_y != 0) + { + QWheelEvent event(QPoint(x, y), scroll_y, d->mCurrentMouseButtonState, qt_modifiers, Qt::Vertical); + qApp->sendEvent(d->mGraphicsView->viewport(), &event); + } + + if(scroll_x != 0) + { + QWheelEvent event(QPoint(x, y), scroll_x, d->mCurrentMouseButtonState, qt_modifiers, Qt::Horizontal); + qApp->sendEvent(d->mGraphicsView->viewport(), &event); + } +} + + +// utility methods to set an error message so something else can look at it +void LLEmbeddedBrowserWindow::scrollByLines(int16_t lines) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << lines; +#endif + int currentScrollValue = d->mPage->mainFrame()->scrollBarValue(Qt::Vertical); + d->mPage->mainFrame()->setScrollBarValue(Qt::Vertical, currentScrollValue + lines); +} + +// Send a keyboard event with native event data. +void LLEmbeddedBrowserWindow::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) +{ + QEvent::Type type = event_from_keyboard_event(key_event); + Qt::KeyboardModifiers qt_modifiers = convert_modifiers(modifiers); + bool auto_repeat = (key_event == LLQtWebKit::KE_KEY_REPEAT); + QString text = QString::fromUtf8(utf8_text); + + Qt::Key key = Qt::Key_unknown; + + switch (key_code) + { + case LLQtWebKit::KEY_RETURN: key = Qt::Key_Return; break; + case LLQtWebKit::KEY_LEFT: key = Qt::Key_Left; break; + case LLQtWebKit::KEY_RIGHT: key = Qt::Key_Right; break; + case LLQtWebKit::KEY_UP: key = Qt::Key_Up; break; + case LLQtWebKit::KEY_DOWN: key = Qt::Key_Down; break; + case LLQtWebKit::KEY_ESCAPE: key = Qt::Key_Escape; break; + case LLQtWebKit::KEY_BACKSPACE: key = Qt::Key_Backspace; break; + case LLQtWebKit::KEY_DELETE: key = Qt::Key_Delete; break; + case LLQtWebKit::KEY_SHIFT: key = Qt::Key_Shift; break; + case LLQtWebKit::KEY_CONTROL: key = Qt::Key_Control; break; + case LLQtWebKit::KEY_ALT: key = Qt::Key_Alt; break; + case LLQtWebKit::KEY_HOME: key = Qt::Key_Home; break; + case LLQtWebKit::KEY_END: key = Qt::Key_End; break; + case LLQtWebKit::KEY_PAGE_UP: key = Qt::Key_PageUp; break; + case LLQtWebKit::KEY_PAGE_DOWN: key = Qt::Key_PageDown; break; + case LLQtWebKit::KEY_HYPHEN: key = Qt::Key_hyphen; break; + case LLQtWebKit::KEY_EQUALS: key = Qt::Key_Equal; break; + case LLQtWebKit::KEY_INSERT: key = Qt::Key_Insert; break; + case LLQtWebKit::KEY_CAPSLOCK: key = Qt::Key_CapsLock; break; + case LLQtWebKit::KEY_TAB: key = Qt::Key_Tab; break; + case LLQtWebKit::KEY_ADD: key = Qt::Key_Plus; break; + case LLQtWebKit::KEY_SUBTRACT: key = Qt::Key_Minus; break; + case LLQtWebKit::KEY_MULTIPLY: key = Qt::Key_Asterisk; break; + case LLQtWebKit::KEY_DIVIDE: key = Qt::Key_Slash; break; + case LLQtWebKit::KEY_F1: key = Qt::Key_F1; break; + case LLQtWebKit::KEY_F2: key = Qt::Key_F2; break; + case LLQtWebKit::KEY_F3: key = Qt::Key_F3; break; + case LLQtWebKit::KEY_F4: key = Qt::Key_F4; break; + case LLQtWebKit::KEY_F5: key = Qt::Key_F5; break; + case LLQtWebKit::KEY_F6: key = Qt::Key_F6; break; + case LLQtWebKit::KEY_F7: key = Qt::Key_F7; break; + case LLQtWebKit::KEY_F8: key = Qt::Key_F8; break; + case LLQtWebKit::KEY_F9: key = Qt::Key_F9; break; + case LLQtWebKit::KEY_F10: key = Qt::Key_F10; break; + case LLQtWebKit::KEY_F11: key = Qt::Key_F11; break; + case LLQtWebKit::KEY_F12: key = Qt::Key_F12; break; + + case LLQtWebKit::KEY_PAD_UP: key = Qt::Key_Up; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_DOWN: key = Qt::Key_Down; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_LEFT: key = Qt::Key_Left; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_RIGHT: key = Qt::Key_Right; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_HOME: key = Qt::Key_Home; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_END: key = Qt::Key_End; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_PGUP: key = Qt::Key_PageUp; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_PGDN: key = Qt::Key_PageDown; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_CENTER: key = Qt::Key_5; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_INS: key = Qt::Key_Insert; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_DEL: key = Qt::Key_Delete; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_RETURN: key = Qt::Key_Enter; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_ADD: key = Qt::Key_Plus; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_SUBTRACT: key = Qt::Key_Minus; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_MULTIPLY: key = Qt::Key_Asterisk; qt_modifiers |= Qt::KeypadModifier; break; + case LLQtWebKit::KEY_PAD_DIVIDE: key = Qt::Key_Slash; qt_modifiers |= Qt::KeypadModifier; break; + + case LLQtWebKit::KEY_NONE: key = Qt::Key_unknown; break; + + default: + key = (Qt::Key)toupper(key_code); + break; + } + + + QKeyEvent *event = + QKeyEvent::createExtendedKeyEvent( + type, + key, + qt_modifiers, + native_scan_code, + native_virtual_key, + native_modifiers, + text, + auto_repeat, + text.count()); + + qApp->sendEvent(d->mGraphicsScene, event); + + delete event; +} + + +// give focus to the browser so that input keyboard events work +void LLEmbeddedBrowserWindow::focusBrowser(bool focus_browser) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << focus_browser; +#endif + QEvent ev(QEvent::WindowActivate); + qApp->sendEvent(d->mGraphicsScene, &ev); + + QEvent ev2(QEvent::ActivationChange); + qApp->sendEvent(d->mGraphicsScene, &ev2); + + QFocusEvent event(focus_browser ? QEvent::FocusIn : QEvent::FocusOut, Qt::ActiveWindowFocusReason); + qApp->sendEvent(d->mPage, &event); +} + +void LLEmbeddedBrowserWindow::setWindowId(int window_id) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << window_id; +#endif + d->mWindowId = window_id; +} + +int LLEmbeddedBrowserWindow::getWindowId() +{ + return d->mWindowId; +} + +void LLEmbeddedBrowserWindow::proxyWindowOpened(const std::string target, const std::string uuid) +{ + LLWebPageOpenShim *shim = findShim(uuid); + if(!shim) + { + // We don't already have a shim with this uuid -- create one. + shim = new LLWebPageOpenShim(this, d->mPage); + d->mProxyPages.push_back(shim); + +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow::proxyWindowOpened: page list size is " << d->mProxyPages.size(); +#endif + } + + shim->setProxy(target, uuid); +} + +void LLEmbeddedBrowserWindow::proxyWindowClosed(const std::string uuid) +{ + LLWebPageOpenShim *shim = findShim(uuid); + if(shim) + { + deleteShim(shim); + } +} + +std::string LLEmbeddedBrowserWindow::evaluateJavaScript(std::string script) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << QString::fromStdString(script); +#endif + QString q_script = QString::fromStdString(script); + QString result = d->mPage->mainFrame()->evaluateJavaScript(q_script).toString(); + return llToStdString(result); +} + +void LLEmbeddedBrowserWindow::setHostLanguage(const std::string host_language) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << QString::fromStdString(host_language); +#endif + if ( d ) + if ( d->mPage ) + d->mPage->setHostLanguage( host_language ); +} + +void LLEmbeddedBrowserWindow::navigateErrorPage( int http_status_code ) +{ + LLEmbeddedBrowserWindowEvent event(getWindowId()); + event.setIntValue( http_status_code ); + + d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onNavigateErrorPage, event); +} + +void LLEmbeddedBrowserWindow::setNoFollowScheme(std::string scheme) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__ << QString::fromStdString(scheme); +#endif + d->mNoFollowScheme = QString::fromStdString(scheme); + // The scheme part of the url is what is before '://' + d->mNoFollowScheme = d->mNoFollowScheme.mid(0, d->mNoFollowScheme.indexOf("://")); +} + +std::string LLEmbeddedBrowserWindow::getNoFollowScheme() +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow" << __FUNCTION__; +#endif + return llToStdString(d->mNoFollowScheme); +} + +void LLEmbeddedBrowserWindow::prependHistoryUrl(std::string url) +{ +#ifdef WEBHISTORYPATCH + // *HACK: we only have a URL here, we set a "" title and "current time" as + // last visited time. + d->mPage->history()->prependItem(QString::fromStdString(url), + QString::fromAscii(""), + QDateTime::currentDateTime()); +#else + Q_UNUSED(url); +#endif +} + +void LLEmbeddedBrowserWindow::clearHistory() +{ + d->mPage->history()->clear(); +} + +std::string LLEmbeddedBrowserWindow::dumpHistory() +{ + std::ostringstream oss; + const QList &items = d->mPage->history()->backItems(9999); + oss << "cur: " << d->mPage->history()->currentItemIndex() << ":" + << d->mPage->history()->currentItem().url().toString().toAscii().data() << "\n"; + for (int i=0; i< items.count(); i++) { + oss << items[i].url().toString().toAscii().data() << "\n"; + } + return oss.str(); +} + +void LLEmbeddedBrowserWindow::cookieChanged(const std::string &cookie, const std::string &url, bool dead) +{ + LLEmbeddedBrowserWindowEvent event(getWindowId()); + event.setEventUri(url); + event.setStringValue(cookie); + event.setIntValue((int)dead); + + d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onCookieChanged, event); +} + +QWebPage *LLEmbeddedBrowserWindow::createWindow() +{ + QWebPage *result = NULL; + if(d->mOpeningSelf) + { + // Special case: opening self to set target, etc. +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow::createWindow: opening self to set target name. "; +#endif + result = d->mPage; + d->mOpeningSelf = false; + } + else + { + LLWebPageOpenShim *shim = new LLWebPageOpenShim(this, d->mPage); + d->mProxyPages.push_back(shim); + result = shim; + +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow::createWindow: page list size is " << d->mProxyPages.size(); +#endif + } + + return result; +} + +LLWebPageOpenShim *LLEmbeddedBrowserWindow::findShim(const std::string &uuid) +{ + LLEmbeddedBrowserWindowPrivate::ProxyList::iterator iter; + for(iter = d->mProxyPages.begin(); iter != d->mProxyPages.end(); iter++) + { + if((*iter)->matchesUUID(uuid)) + return *iter; + } + + return NULL; +} + +void LLEmbeddedBrowserWindow::deleteShim(LLWebPageOpenShim *shim) +{ + shim->window = 0; + shim->deleteLater(); + d->mProxyPages.remove(shim); + +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow::deleteShim: page list size is " << d->mProxyPages.size(); +#endif +} + +void LLEmbeddedBrowserWindow::setTarget(const std::string &target) +{ +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow::setTarget: setting target to " << QString::fromStdString(target); +#endif + + d->mOpeningSelf = true; + + std::stringstream s; + s << "window.open(\"\",\"" << target << "\");"; + + evaluateJavaScript(s.str()); +} + +std::string LLEmbeddedBrowserWindow::requestFilePicker() +{ + std::string filename_chosen; + + LLEmbeddedBrowserWindowEvent event(getWindowId()); + event.setEventUri(getCurrentUri()); + event.setStringValue("*.png;*.jpg"); + + // If there's at least one observer registered, call it with the event. + LLEmbeddedBrowserWindowPrivate::Emitter::iterator i = d->mEventEmitter.begin(); + if(i != d->mEventEmitter.end()) + { + filename_chosen = (*i)->onRequestFilePicker(event); + } + + return filename_chosen; +} + +bool LLEmbeddedBrowserWindow::authRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password) +{ + bool result = false; + +#ifdef LLEMBEDDEDBROWSER_DEBUG + qDebug() << "LLEmbeddedBrowserWindow::authRequest: requesting auth for url " << QString::fromStdString(in_url) << ", realm " << QString::fromStdString(in_realm); +#endif + + // If there's at least one observer registered, send it the auth request. + LLEmbeddedBrowserWindowPrivate::Emitter::iterator i = d->mEventEmitter.begin(); + if(i != d->mEventEmitter.end()) + { + result = (*i)->onAuthRequest(in_url, in_realm, out_username, out_password); + } + + return result; +} + +bool LLEmbeddedBrowserWindow::certError(const std::string &in_url, const std::string &in_msg) +{ + bool result = false; + + // If there's at least one observer registered, send it the auth request. + LLEmbeddedBrowserWindowPrivate::Emitter::iterator i = d->mEventEmitter.begin(); + if(i != d->mEventEmitter.end()) + { + result = (*i)->onCertError(in_url, in_msg); + } + + return result; +} + +void LLEmbeddedBrowserWindow::onQtDebugMessage( const std::string& msg, const std::string& msg_type) +{ + // If there's at least one observer registered, send it the auth request. + LLEmbeddedBrowserWindowPrivate::Emitter::iterator i = d->mEventEmitter.begin(); + if(i != d->mEventEmitter.end()) + { + (*i)->onQtDebugMessage(msg, msg_type); + } +} + +void LLEmbeddedBrowserWindow::setWhiteListRegex( const std::string& regex ) +{ + if ( d ) + if ( d->mPage ) + d->mPage->setWhiteListRegex( regex ); +} + +// Second Life viewer specific functions +void LLEmbeddedBrowserWindow::setSLObjectEnabled( bool enabled ) +{ + if ( d ) + if ( d->mPage ) + d->mPage->setSLObjectEnabled( enabled ); +} + +void LLEmbeddedBrowserWindow::setAgentLanguage( const std::string& agent_language ) +{ + if ( d ) + if ( d->mPage ) + d->mPage->setAgentLanguage( agent_language ); +} + +void LLEmbeddedBrowserWindow::setAgentRegion( const std::string& agent_region ) +{ + if ( d ) + if ( d->mPage ) + d->mPage->setAgentRegion( agent_region ); +} + +void LLEmbeddedBrowserWindow::setAgentLocation( double x, double y, double z ) +{ + if ( d ) + if ( d->mPage ) + d->mPage->setAgentLocation( x, y, z ); +} + +void LLEmbeddedBrowserWindow::setAgentGlobalLocation( double x, double y, double z ) +{ + if ( d ) + if ( d->mPage ) + d->mPage->setAgentGlobalLocation( x, y, z ); +} + +void LLEmbeddedBrowserWindow::setAgentOrientation( double angle ) +{ + if ( d ) + if ( d->mPage ) + d->mPage->setAgentOrientation( angle ); +} + +void LLEmbeddedBrowserWindow::setAgentMaturity( const std::string& agent_maturity ) +{ + if ( d ) + if ( d->mPage ) + d->mPage->setAgentMaturity( agent_maturity ); +} + +void LLEmbeddedBrowserWindow::emitLocation() +{ + if ( d ) + if ( d->mPage ) + d->mPage->emitLocation(); +} + +void LLEmbeddedBrowserWindow::emitMaturity() +{ + if ( d ) + if ( d->mPage ) + d->mPage->emitMaturity(); +} + +void LLEmbeddedBrowserWindow::emitLanguage() +{ + if ( d ) + if ( d->mPage ) + d->mPage->emitLanguage(); +} + +void LLEmbeddedBrowserWindow::setPageZoomFactor( double factor ) +{ + if ( d ) + if ( d->mPage ) + d->mPage->setPageZoomFactor( factor ); +} + +LLGraphicsScene::LLGraphicsScene() + : QGraphicsScene() + , window(0) +{ + connect(this, SIGNAL(changed(const QList &)), + this, SLOT(repaintRequestedSlot(const QList &))); +} + +void LLGraphicsScene::repaintRequestedSlot(const QList ®ions) +{ + if (!window) + return; + window->d->mDirty = true; + for (int i = 0; i < regions.count(); ++i) + { + LLEmbeddedBrowserWindowEvent event(window->getWindowId()); + event.setEventUri(window->getCurrentUri()); + event.setRectValue(regions[i].x(), regions[i].y(), regions[i].width(), regions[i].height()); + + window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onPageChanged, event); + } +} + +#include +#include +LLWebView::LLWebView(QGraphicsItem *parent) + : QGraphicsWebView(parent) + , window(0) +{ +} + +bool LLWebView::event(QEvent* event) +{ + if (window && event->type() == QEvent::CursorChange) { + QCursor cursor = this->cursor(); + if (currentShape != cursor.shape()) { + currentShape = cursor.shape(); + LLQtWebKit::ECursor llcursor; + switch(currentShape) + { + case Qt::ArrowCursor: + llcursor = LLQtWebKit::C_ARROW; + break; + case Qt::PointingHandCursor: + llcursor = LLQtWebKit::C_POINTINGHAND; + break; + case Qt::IBeamCursor: + llcursor = LLQtWebKit::C_IBEAM; + break; + case Qt::SplitVCursor: + llcursor = LLQtWebKit::C_SPLITV; + break; + case Qt::SplitHCursor: + llcursor = LLQtWebKit::C_SPLITH; + break; + default: + qWarning() << "Unhandled cursor shape:" << currentShape; + llcursor = LLQtWebKit::C_ARROW; + } + + LLEmbeddedBrowserWindowEvent event(window->getWindowId()); + event.setEventUri(window->getCurrentUri()); + event.setIntValue((int)llcursor); + window->d->mEventEmitter.update(&LLEmbeddedBrowserWindowObserver::onCursorChanged, event); + } + + return true; + } + return QGraphicsWebView::event(event); +} + + +std::string llToStdString(const QString &s) +{ + return llToStdString(s.toUtf8()); +} + +std::string llToStdString(const QByteArray &bytes) +{ + return std::string(bytes.constData(), bytes.size()); +} + +std::string llToStdString(const QUrl &url) +{ + return llToStdString(url.toEncoded()); +} diff --git a/indra/llqtwebkit/llembeddedbrowserwindow.h b/indra/llqtwebkit/llembeddedbrowserwindow.h new file mode 100644 index 000000000..0c8080c15 --- /dev/null +++ b/indra/llqtwebkit/llembeddedbrowserwindow.h @@ -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 +#include +#include +#if defined _MSC_VER && _MSC_VER < 1600 +#include "pstdint.h" +#else +#include // 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 diff --git a/indra/llqtwebkit/llembeddedbrowserwindow_p.h b/indra/llqtwebkit/llembeddedbrowserwindow_p.h new file mode 100644 index 000000000..27b36d947 --- /dev/null +++ b/indra/llqtwebkit/llembeddedbrowserwindow_p.h @@ -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 +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// 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 +#include + +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 &); + 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 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 + diff --git a/indra/llqtwebkit/lljsobject.cpp b/indra/llqtwebkit/lljsobject.cpp new file mode 100644 index 000000000..f5abfa702 --- /dev/null +++ b/indra/llqtwebkit/lljsobject.cpp @@ -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 +#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 ); +} diff --git a/indra/llqtwebkit/lljsobject.h b/indra/llqtwebkit/lljsobject.h new file mode 100644 index 000000000..806a8a8a1 --- /dev/null +++ b/indra/llqtwebkit/lljsobject.h @@ -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 +#include +#include + +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 diff --git a/indra/llqtwebkit/llnetworkaccessmanager.cpp b/indra/llqtwebkit/llnetworkaccessmanager.cpp new file mode 100644 index 000000000..2a51f1340 --- /dev/null +++ b/indra/llqtwebkit/llnetworkaccessmanager.cpp @@ -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 +#include "llnetworkaccessmanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 &)), + this, SLOT(sslErrorsSlot( QNetworkReply *, const QList & ))); +} + +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& 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. + } +} + diff --git a/indra/llqtwebkit/llnetworkaccessmanager.h b/indra/llqtwebkit/llnetworkaccessmanager.h new file mode 100644 index 000000000..478b679aa --- /dev/null +++ b/indra/llqtwebkit/llnetworkaccessmanager.h @@ -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 +#include + +#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& errors); + +private: + LLEmbeddedBrowserPrivate* mBrowser; + +}; + +#endif // LLNETWORKACCESSMANAGER_H + diff --git a/indra/llqtwebkit/llqtwebkit.cpp b/indra/llqtwebkit/llqtwebkit.cpp new file mode 100644 index 000000000..2be066d11 --- /dev/null +++ b/indra/llqtwebkit/llqtwebkit.cpp @@ -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 +#include +#include +#include + +#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 ); +} diff --git a/indra/llqtwebkit/llqtwebkit.h b/indra/llqtwebkit/llqtwebkit.h new file mode 100644 index 000000000..8e7ebd390 --- /dev/null +++ b/indra/llqtwebkit/llqtwebkit.h @@ -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 // Use the C99 official header +#endif + +#include +#include +#include + +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 diff --git a/indra/llqtwebkit/llqtwebkit.pri b/indra/llqtwebkit/llqtwebkit.pri new file mode 100644 index 000000000..4f85aa423 --- /dev/null +++ b/indra/llqtwebkit/llqtwebkit.pri @@ -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) diff --git a/indra/llqtwebkit/llqtwebkit.pro b/indra/llqtwebkit/llqtwebkit.pro new file mode 100644 index 000000000..b6ff077bd --- /dev/null +++ b/indra/llqtwebkit/llqtwebkit.pro @@ -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 diff --git a/indra/llqtwebkit/llstyle.cpp b/indra/llqtwebkit/llstyle.cpp new file mode 100644 index 000000000..ecd2b3eb8 --- /dev/null +++ b/indra/llqtwebkit/llstyle.cpp @@ -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 +#include +#include + +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(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); +} diff --git a/indra/llqtwebkit/llstyle.h b/indra/llqtwebkit/llstyle.h new file mode 100644 index 000000000..77c09b3bb --- /dev/null +++ b/indra/llqtwebkit/llstyle.h @@ -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 + +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 + diff --git a/indra/llqtwebkit/llwebpage.cpp b/indra/llqtwebkit/llwebpage.cpp new file mode 100644 index 000000000..113c0c186 --- /dev/null +++ b/indra/llqtwebkit/llwebpage.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include + +#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(option); + QWebPage::ErrorPageExtensionReturn* errorPage = static_cast(output); + + errorPage->content = QString("Failed loading page

%1

") + .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 ); + } +} \ No newline at end of file diff --git a/indra/llqtwebkit/llwebpage.h b/indra/llqtwebkit/llwebpage.h new file mode 100644 index 000000000..1a882254f --- /dev/null +++ b/indra/llqtwebkit/llwebpage.h @@ -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 +#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 diff --git a/indra/llqtwebkit/llwebpageopenshim.cpp b/indra/llqtwebkit/llwebpageopenshim.cpp new file mode 100644 index 000000000..af9627907 --- /dev/null +++ b/indra/llqtwebkit/llwebpageopenshim.cpp @@ -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 +#include +#include +#include + +#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; +} diff --git a/indra/llqtwebkit/llwebpageopenshim.h b/indra/llqtwebkit/llwebpageopenshim.h new file mode 100644 index 000000000..322f832ce --- /dev/null +++ b/indra/llqtwebkit/llwebpageopenshim.h @@ -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 + +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 + diff --git a/indra/llqtwebkit/passworddialog.ui b/indra/llqtwebkit/passworddialog.ui new file mode 100644 index 000000000..033514eff --- /dev/null +++ b/indra/llqtwebkit/passworddialog.ui @@ -0,0 +1,137 @@ + + + PasswordDialog + + + + 0 + 0 + 394 + 183 + + + + Dialog + + + + + + Qt::Vertical + + + + 20 + 12 + + + + + + + + + + + true + + + + + + + + 32 + 32 + + + + icon + + + + + + + Qt::Vertical + + + + 20 + 13 + + + + + + + + User name: + + + + + + + + + + Password: + + + + + + + QLineEdit::Password + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + PasswordDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PasswordDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/indra/llqtwebkit/pstdint.h b/indra/llqtwebkit/pstdint.h new file mode 100644 index 000000000..b36f63db3 --- /dev/null +++ b/indra/llqtwebkit/pstdint.h @@ -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 +#include +#include + +/* + * 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 +#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 +# 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 diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/CMakeLists.txt b/indra/llqtwebkit/qtwebkit_cookiejar/CMakeLists.txt new file mode 100644 index 000000000..635765c83 --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/CMakeLists.txt @@ -0,0 +1,3 @@ +# -*- cmake -*- + +add_subdirectory(src) diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/autotest/trie/trie.pro b/indra/llqtwebkit/qtwebkit_cookiejar/autotest/trie/trie.pro new file mode 100644 index 000000000..c031e1971 --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/autotest/trie/trie.pro @@ -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 += diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/autotest/trie/tst_trie.cpp b/indra/llqtwebkit/qtwebkit_cookiejar/autotest/trie/tst_trie.cpp new file mode 100644 index 000000000..e4bdc6d4e --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/autotest/trie/tst_trie.cpp @@ -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 +#include + +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 +{ +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()); + QCOMPARE(t.remove(QStringList(), -1), false); + QCOMPARE(t.all(), QList()); + t.insert(QStringList(), -1); +} + +void tst_Trie::insert_data() +{ +#if 0 + QTest::addColumn("key"); + QTest::addColumn("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>.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()); + QCOMPARE(t.all(), QList()); +} + +Q_DECLARE_METATYPE(QStringList) +typedef QList IntList; +Q_DECLARE_METATYPE(IntList) +void tst_Trie::find_data() +{ + QTest::addColumn("keys"); + QTest::addColumn("values"); + QTest::addColumn("find"); + QTest::addColumn("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 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("keys"); + QTest::addColumn("values"); + QTest::addColumn("removeKey"); + QTest::addColumn("removeValue"); + QTest::addColumn("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" + diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/benchmark/networkcookiejar/cookiejar.pro b/indra/llqtwebkit/qtwebkit_cookiejar/benchmark/networkcookiejar/cookiejar.pro new file mode 100644 index 000000000..350fbc0f6 --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/benchmark/networkcookiejar/cookiejar.pro @@ -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 += diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/benchmark/networkcookiejar/main.cpp b/indra/llqtwebkit/qtwebkit_cookiejar/benchmark/networkcookiejar/main.cpp new file mode 100644 index 000000000..863d6b0be --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/benchmark/networkcookiejar/main.cpp @@ -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 +#include +#include + +class CookieJarBenchmark: public QObject { + Q_OBJECT + +private slots: + void setCookiesFromUrl(); + void cookiesForUrl(); + void player(); + +private: + QNetworkCookieJar *getJar(bool populate = true); + QList 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 cookies = generateCookies(1); + QUrl url = QUrl(QString("http://%1").arg(cookies[0].domain())); + jar->setCookiesFromUrl(cookies, url); + } + + return jar; +} + +QList CookieJarBenchmark::generateCookies(int size) +{ + QList 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 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 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 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" diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/browser/browser.pro b/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/browser/browser.pro new file mode 100644 index 000000000..a363bbefc --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/browser/browser.pro @@ -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 diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/browser/main.cpp b/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/browser/main.cpp new file mode 100644 index 000000000..6d21759fc --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/browser/main.cpp @@ -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 +#include +#include +#include + +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 cookiesForUrl(const QUrl & url) const + { + stream << QString("cookiesForUrl") << url; + QList cookies = NetworkCookieJar::cookiesForUrl(url); + //stream << "#" << cookies; + file.flush(); + return cookies; + } + + virtual bool setCookiesFromUrl(const QList &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" diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/fuzz/fuzz.pro b/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/fuzz/fuzz.pro new file mode 100644 index 000000000..0ad65f1bf --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/fuzz/fuzz.pro @@ -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 diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/fuzz/main.cpp b/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/fuzz/main.cpp new file mode 100644 index 000000000..28c79a1c2 --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/manualtest/fuzz/main.cpp @@ -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 +#include + +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 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 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 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 hash; + Trie 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 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; +} + diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/src/CMakeLists.txt b/indra/llqtwebkit/qtwebkit_cookiejar/src/CMakeLists.txt new file mode 100644 index 000000000..20bacf3eb --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/src/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/src/networkcookiejar.cpp b/indra/llqtwebkit/qtwebkit_cookiejar/src/networkcookiejar.cpp new file mode 100644 index 000000000..274d9e1c1 --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/src/networkcookiejar.cpp @@ -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 +#endif + +#include +#include + +#if defined(NETWORKCOOKIEJAR_DEBUG) +#include +#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 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 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::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 cookies = d->tree.all(); + QDateTime now = QDateTime::currentDateTime().toTimeSpec(Qt::UTC); + QList::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 &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 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 &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 &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 cookies = d->tree.find(urlHost); + QList::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 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. +} diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/src/networkcookiejar.h b/indra/llqtwebkit/qtwebkit_cookiejar/src/networkcookiejar.h new file mode 100644 index 000000000..86b14fa16 --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/src/networkcookiejar.h @@ -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 + +class NetworkCookieJarPrivate; +class NetworkCookieJar : public QNetworkCookieJar { + Q_OBJECT +public: + NetworkCookieJar(QObject *parent = 0); + ~NetworkCookieJar(); + + virtual QList cookiesForUrl(const QUrl & url) const; + virtual bool setCookiesFromUrl(const QList &cookieList, const QUrl &url); + +protected: + QByteArray saveState() const; + bool restoreState(const QByteArray &state); + void endSession(); + + QList allCookies() const; + void clearCookies(); + void setCookies(const QList &cookieList); + void setAllCookies(const QList &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 + diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/src/networkcookiejar_p.h b/indra/llqtwebkit/qtwebkit_cookiejar/src/networkcookiejar_p.h new file mode 100644 index 000000000..d8f22cfce --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/src/networkcookiejar_p.h @@ -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 newCookies = QNetworkCookie::parseCookies(value); + if (!newCookies.isEmpty()) + cookie = newCookies.first(); + return stream; +} +QT_END_NAMESPACE + +class NetworkCookieJarPrivate { +public: + NetworkCookieJarPrivate() + : setSecondLevelDomain(false) + {} + + Trie 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 + diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/src/src.pri b/indra/llqtwebkit/qtwebkit_cookiejar/src/src.pri new file mode 100644 index 000000000..78ac273a1 --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/src/src.pri @@ -0,0 +1,5 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += trie_p.h networkcookiejar.h twoleveldomains_p.h networkcookiejar_p.h +SOURCES += networkcookiejar.cpp diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/src/trie_p.h b/indra/llqtwebkit/qtwebkit_cookiejar/src/trie_p.h new file mode 100644 index 000000000..a4959a198 --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/src/trie_p.h @@ -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 + +#if defined(TRIE_DEBUG) +#include +#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 Trie { +public: + Trie(); + ~Trie(); + + void clear(); + void insert(const QStringList &key, const T &value); + bool remove(const QStringList &key, const T &value); + QList find(const QStringList &key) const; + QList all() const; + + inline bool contains(const QStringList &key) const; + inline bool isEmpty() const { return children.isEmpty() && values.isEmpty(); } + +private: + const Trie* walkTo(const QStringList &key) const; + Trie* walkTo(const QStringList &key, bool create = false); + + template friend QDataStream &operator<<(QDataStream &, const Trie&); + template friend QDataStream &operator>>(QDataStream &, Trie&); + + QList values; + QStringList childrenKeys; + QList > children; +}; + +template +Trie::Trie() { +} + +template +Trie::~Trie() { +} + +template +void Trie::clear() { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__; +#endif + values.clear(); + childrenKeys.clear(); + children.clear(); +} + +template +bool Trie::contains(const QStringList &key) const { + return walkTo(key); +} + +template +void Trie::insert(const QStringList &key, const T &value) { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__ << key << value; +#endif + Trie *node = walkTo(key, true); + if (node) + node->values.append(value); +} + +template +bool Trie::remove(const QStringList &key, const T &value) { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__ << key << value; +#endif + Trie *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 *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 +QList Trie::find(const QStringList &key) const { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__ << key; +#endif + const Trie *node = walkTo(key); + if (node) + return node->values; + return QList(); +} + +template +QList Trie::all() const { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__; +#endif + QList all = values; + for (int i = 0; i < children.count(); ++i) + all += children[i].all(); + return all; +} + +template +QDataStream &operator<<(QDataStream &out, const Trie&trie) { + out << trie.values; + out << trie.childrenKeys; + out << trie.children; + Q_ASSERT(trie.childrenKeys.count() == trie.children.count()); + return out; +} + +template +QDataStream &operator>>(QDataStream &in, Trie &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 +const Trie* Trie::walkTo(const QStringList &key) const { + const Trie *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 +Trie* Trie::walkTo(const QStringList &key, bool create) { + QStringList::iterator iterator; + Trie *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()); + } else { + index = iterator - begin; + } + Q_ASSERT(index >= 0 && index < node->children.count()); + node = &node->children[index]; + } + return node; +} + +#endif diff --git a/indra/llqtwebkit/qtwebkit_cookiejar/src/twoleveldomains_p.h b/indra/llqtwebkit/qtwebkit_cookiejar/src/twoleveldomains_p.h new file mode 100644 index 000000000..e4c046cb6 --- /dev/null +++ b/indra/llqtwebkit/qtwebkit_cookiejar/src/twoleveldomains_p.h @@ -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 +}; diff --git a/indra/llqtwebkit/static.pri b/indra/llqtwebkit/static.pri new file mode 100644 index 000000000..8c282347d --- /dev/null +++ b/indra/llqtwebkit/static.pri @@ -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 +} + diff --git a/indra/llqtwebkit/tests/3dgl/3dgl.cpp b/indra/llqtwebkit/tests/3dgl/3dgl.cpp new file mode 100644 index 000000000..c07c5d89c --- /dev/null +++ b/indra/llqtwebkit/tests/3dgl/3dgl.cpp @@ -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 +#include +#include +#include + +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;y1pump(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;y1init(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; +} diff --git a/indra/llqtwebkit/tests/3dgl/3dgl.pro b/indra/llqtwebkit/tests/3dgl/3dgl.pro new file mode 100644 index 000000000..6285128ef --- /dev/null +++ b/indra/llqtwebkit/tests/3dgl/3dgl.pro @@ -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 diff --git a/indra/llqtwebkit/tests/3dgl/zpr.c b/indra/llqtwebkit/tests/3dgl/zpr.c new file mode 100644 index 000000000..65373efc5 --- /dev/null +++ b/indra/llqtwebkit/tests/3dgl/zpr.c @@ -0,0 +1,429 @@ +#include +#include +#include +#include + +#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 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 +#endif + +#define FREEGLUT_STATIC + +#include + +#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 diff --git a/indra/llqtwebkit/tests/qttestapp/main.cpp b/indra/llqtwebkit/tests/qttestapp/main.cpp new file mode 100644 index 000000000..3ab3a9c17 --- /dev/null +++ b/indra/llqtwebkit/tests/qttestapp/main.cpp @@ -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 +#include + +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" diff --git a/indra/llqtwebkit/tests/qttestapp/qttestapp.pro b/indra/llqtwebkit/tests/qttestapp/qttestapp.pro new file mode 100644 index 000000000..5a0ca33cf --- /dev/null +++ b/indra/llqtwebkit/tests/qttestapp/qttestapp.pro @@ -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 diff --git a/indra/llqtwebkit/tests/qttestapp/webpage.h b/indra/llqtwebkit/tests/qttestapp/webpage.h new file mode 100644 index 000000000..e69de29bb diff --git a/indra/llqtwebkit/tests/qttestapp/window.ui b/indra/llqtwebkit/tests/qttestapp/window.ui new file mode 100644 index 000000000..6125821cc --- /dev/null +++ b/indra/llqtwebkit/tests/qttestapp/window.ui @@ -0,0 +1,79 @@ + + + Dialog + + + + 0 + 0 + 766 + 613 + + + + Dialog + + + + 0 + + + + + 6 + + + 6 + + + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + + + + + WebPage + QWidget +
webpage.h
+ 1 +
+
+ + +
diff --git a/indra/llqtwebkit/tests/ssltest/ssltest.cpp b/indra/llqtwebkit/tests/ssltest/ssltest.cpp new file mode 100644 index 000000000..fcbf80314 --- /dev/null +++ b/indra/llqtwebkit/tests/ssltest/ssltest.cpp @@ -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 +} +#endif + +#ifdef _WINDOWS +#include +#include +#endif + +#include +#include +#include + +#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 +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 [--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; +} diff --git a/indra/llqtwebkit/tests/ssltest/ssltest.pro b/indra/llqtwebkit/tests/ssltest/ssltest.pro new file mode 100644 index 000000000..981e35211 --- /dev/null +++ b/indra/llqtwebkit/tests/ssltest/ssltest.pro @@ -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 diff --git a/indra/llqtwebkit/tests/testgl/testgl.cpp b/indra/llqtwebkit/tests/testgl/testgl.cpp new file mode 100644 index 000000000..6dfb11a72 --- /dev/null +++ b/indra/llqtwebkit/tests/testgl/testgl.cpp @@ -0,0 +1,1002 @@ +/* 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 +} +#endif + +#ifdef _WINDOWS +#include +#include // file choser dialog +#include // for local file access +#endif + +#include +#include +#include +#include +#include + +#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 +Q_IMPORT_PLUGIN(qgif) +#endif + +#ifdef LL_OSX +#include +#include +#else +#define FREEGLUT_STATIC +#include "GL/glut.h" +#endif +#include "llqtwebkit.h" + +#ifdef _WINDOWS + #define PATH_SEPARATOR "\\" +#else + #define PATH_SEPARATOR "/" +#endif + + +//////////////////////////////////////////////////////////////////////////////// +// +std::string chooseFileName() +{ +#ifdef _WINDOWS + OPENFILENAMEA ofn ; + static char szFile[_MAX_PATH] ; + + ZeroMemory( &ofn , sizeof( ofn) ); + ofn.lStructSize = sizeof ( ofn ); + ofn.hwndOwner = NULL ; + ofn.lpstrFile = szFile ; + ofn.lpstrFile[0] = '\0'; + ofn.nMaxFile = sizeof( szFile ); + ofn.lpstrFilter = "All\0*.*\0Images\0*.jpg;*.png\0"; + ofn.nFilterIndex =1; + ofn.lpstrFileTitle = NULL ; + ofn.nMaxFileTitle = 0 ; + ofn.lpstrInitialDir=NULL ; + ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ; + + GetOpenFileNameA( &ofn ); + + return ofn.lpstrFile; +#else + return ""; +#endif +} + +//////////////////////////////////////////////////////////////////////////////// +// Implementation of the test app - implemented as a class and derrives from +// the observer so we can catch events emitted by LLQtWebKit +// +class testGL : + public LLEmbeddedBrowserWindowObserver +{ + public: + testGL() : + mAppWindowWidth( 800 ), // dimensions of the app window - can be anything + mAppWindowHeight( 900 ), + mBrowserWindowWidth( mAppWindowWidth ), // dimensions of the embedded browser - can be anything + mBrowserWindowHeight( mAppWindowHeight ), // but looks best when it's the same as the app window + mAppTextureWidth( -1 ), // dimensions of the texture that the browser is rendered into + mAppTextureHeight( -1 ), // calculated at initialization + mAppTexture( 0 ), + mBrowserWindowId( 0 ), + mAppWindowName( "testGL" ), + mCwd(), + mHomeUrl(), + mNeedsUpdate( true ) // flag to indicate if browser texture needs an update + { +#ifdef _WINDOWS // to remove warning on Windows + mCwd = _getcwd(NULL, 1024); +#else + mCwd = getcwd(NULL, 1024); +#endif + mHomeUrl = "http://callum-linden.s3.amazonaws.com/browsertest.html"; + std::cout << "LLQtWebKit version: " << LLQtWebKit::getInstance()->getVersion() << std::endl; + + std::cout << "Current working directory is " << mCwd << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void init( const std::string argv0, const std::string argv1 ) + { + // OpenGL initialization + glClearColor( 0.0f, 0.0f, 0.0f, 0.5f); + glEnable( GL_COLOR_MATERIAL ); + glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); + glEnable( GL_TEXTURE_2D ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + glEnable( GL_CULL_FACE ); + + // calculate texture size required (next power of two above browser window size + for ( mAppTextureWidth = 1; mAppTextureWidth < mBrowserWindowWidth; mAppTextureWidth <<= 1 ) + { + }; + + for ( mAppTextureHeight = 1; mAppTextureHeight < mBrowserWindowHeight; mAppTextureHeight <<= 1 ) + { + }; + + // create the texture used to display the browser data + glGenTextures( 1, &mAppTexture ); + glBindTexture( GL_TEXTURE_2D, mAppTexture ); + 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_RGB, + mAppTextureWidth, mAppTextureHeight, + 0, GL_RGB, GL_UNSIGNED_BYTE, 0 ); + + // create a single browser window and set things up. + mProfileDir = mCwd + PATH_SEPARATOR + "testGL_profile"; + std::cout << "Profiles dir location is " << mProfileDir << std::endl; + + mCookiePath = mProfileDir + PATH_SEPARATOR + "cookies.txt"; + std::cout << "Cookies.txt file location is " << mCookiePath << std::endl; + + LLQtWebKit::getInstance()->init( mApplicationDir, mApplicationDir, mProfileDir, getNativeWindowHandle() ); + + LLQtWebKit::getInstance()->enableQtMessageHandler( false ); + + // set host language test (in reality, string will be language code passed into client) + // IMPORTANT: must be called before createBrowserWindow(...) + LLQtWebKit::getInstance()->setHostLanguage( "EN-AB-CD-EF" ); + + // set up features + LLQtWebKit::getInstance()->enableJavaScript( true ); + LLQtWebKit::getInstance()->enableCookies( true ); + LLQtWebKit::getInstance()->enablePlugins( true ); + + // make a browser window + mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mBrowserWindowWidth, mBrowserWindowHeight ); + + // tell LLQtWebKit about the size of the browser window + LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mBrowserWindowWidth, mBrowserWindowHeight ); + + // observer events that LLQtWebKit emits + LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this ); + + // append details to agent string + LLQtWebKit::getInstance()->setBrowserAgentId( mAppWindowName ); + + // don't flip bitmap + LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, false ); + + // only "trust" pages whose host match this regex + LLQtWebKit::getInstance()->setWhiteListRegex( mBrowserWindowId, "^([^.]+\\.)*amazonaws\\.com$" ); + + LLQtWebKit::getInstance()->enableLoadingOverlay( mBrowserWindowId, true ); + + // Attempt to read cookies from the cookie file and send them to llqtwebkit. + { + std::ifstream cookie_file(mCookiePath.c_str(), std::ios_base::in); + std::string cookies; + + while(cookie_file.good() && !cookie_file.eof()) + { + std::string tmp; + std::getline(cookie_file, tmp); + cookies += tmp; + cookies += "\n"; + } + + if(!cookies.empty()) + { + LLQtWebKit::getInstance()->setCookies(cookies); + } + } + + #if 0 + const std::vector before=LLQtWebKit::getInstance()->getInstalledCertsList(); + std::cout << "Certs before CA.pem load: " << before.size() << " items" << std::endl; + for(int i=0;isetCAFile( ca_pem_file_loc.c_str() ); + std::cout << "Expected CA.pem file location is " << ca_pem_file_loc << std::endl; + + #if 0 + const std::vector after=LLQtWebKit::getInstance()->getInstalledCertsList(); + std::cout << "Certs after CA.pem load: " << after.size() << " items" << std::endl; + for(int i=0;isetSLObjectEnabled( true ); // true means the feature is turned on + LLQtWebKit::getInstance()->setAgentLanguage( "tst-en" ); // viewer language selected by agent + LLQtWebKit::getInstance()->setAgentRegion( "TestGL region" ); // 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( 1234.5, 6789.0, 3456.7 ); // agent's x,y,z location within a region + LLQtWebKit::getInstance()->setAgentOrientation( 175.69 ); // direction (0..359) agent is facing + LLQtWebKit::getInstance()->setAgentMaturity( "Very immature" ); // selected maturity level of agent + + // go to the "home page" or URL passed in via command line + if ( ! argv1.empty() ) + LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, argv1 ); + else + LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, mHomeUrl ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void reset( void ) + { + // Get cookies from this instance + std::string cookies = LLQtWebKit::getInstance()->getAllCookies(); + + // Dump cookies to stdout +// std::cout << "Cookies:" << std::endl; +// std::cout << cookies; + + // and save them to cookies.txt in the profile directory + { + std::ofstream cookie_file(mCookiePath.c_str(), std::ios_base::out|std::ios_base::trunc); + + if(cookie_file.good()) + { + cookie_file << cookies; + } + + cookie_file.close(); + } + + // unhook observer + LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this ); + + // clean up + LLQtWebKit::getInstance()->reset(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void reshape( int widthIn, int heightIn ) + { + if ( heightIn == 0 ) + heightIn = 1; + + LLQtWebKit::getInstance()->setSize(mBrowserWindowId, widthIn, heightIn ); + mNeedsUpdate = true; + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + + glViewport( 0, 0, widthIn, heightIn ); + glOrtho( 0.0f, widthIn, heightIn, 0.0f, -1.0f, 1.0f ); + + // we use these elsewhere so save + mAppWindowWidth = widthIn; + mAppWindowHeight = heightIn; + mBrowserWindowWidth = widthIn; + mBrowserWindowHeight = heightIn; + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + mNeedsUpdate = true; + idle(); + + glutPostRedisplay(); + }; + + void updateSLvariables() + { + if ( rand() % 2 ) + LLQtWebKit::getInstance()->setAgentRegion( "Region Wibble" ); + else + LLQtWebKit::getInstance()->setAgentRegion( "Region Flasm" ); + LLQtWebKit::getInstance()->setAgentLocation( (rand()%25600)/100.0f, (rand()%25600)/100.0f, (rand()%25600)/100.0f ); + LLQtWebKit::getInstance()->setAgentGlobalLocation( (rand()%25600)/10.0f, (rand()%25600)/10.0f, (rand()%25600)/10.0f ); + LLQtWebKit::getInstance()->setAgentOrientation( (rand()%3600)/10.0f ); + LLQtWebKit::getInstance()->emitLocation(); + + if ( rand() % 2 ) + LLQtWebKit::getInstance()->setAgentLanguage( "One language" ); + else + LLQtWebKit::getInstance()->setAgentLanguage( "Another language" ); + LLQtWebKit::getInstance()->emitLanguage(); + + if ( rand() % 2 ) + LLQtWebKit::getInstance()->setAgentMaturity( "Adults only" ); + else + LLQtWebKit::getInstance()->setAgentMaturity( "Children only" ); + LLQtWebKit::getInstance()->emitMaturity(); + } + + //////////////////////////////////////////////////////////////////////////////// + // + void idle() + { + static time_t starttime = time( NULL ); + if ( time( NULL ) - starttime ) + { + updateSLvariables(); + time( &starttime ); + }; + + LLQtWebKit::getInstance()->pump(100); + + // onPageChanged event sets this + if ( mNeedsUpdate ) + // grab a page but don't reset 'needs update' flag until we've written it to the texture in display() + LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId ); + + // lots of updates for smooth motion + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void display() + { + // clear screen + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glLoadIdentity(); + + // use the browser texture + glBindTexture( GL_TEXTURE_2D, mAppTexture ); + + // valid window ? + if ( mBrowserWindowId ) + { + // needs to be updated? + if ( mNeedsUpdate ) + { + // grab the page + const unsigned char* pixels = LLQtWebKit::getInstance()->getBrowserWindowPixels( mBrowserWindowId ); + if ( pixels ) + { + // write them into the texture + glTexSubImage2D( GL_TEXTURE_2D, 0, + 0, 0, + // because sometimes the rowspan != width * bytes per pixel (mBrowserWindowWidth) + LLQtWebKit::getInstance()->getBrowserRowSpan( mBrowserWindowId ) / LLQtWebKit::getInstance()->getBrowserDepth( mBrowserWindowId ), + mBrowserWindowHeight, +#ifdef _WINDOWS + LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId ) == 3 ? GL_RGBA : GL_RGBA, +#elif defined(__APPLE__) + GL_RGBA, +#elif defined(LL_LINUX) + GL_RGBA, +#endif + GL_UNSIGNED_BYTE, + pixels ); + }; + + // flag as already updated + mNeedsUpdate = false; + }; + }; + + // scale the texture so that it fits the screen + GLfloat textureScaleX = ( GLfloat )mBrowserWindowWidth / ( GLfloat )mAppTextureWidth; + GLfloat textureScaleY = ( GLfloat )mBrowserWindowHeight / ( GLfloat )mAppTextureHeight; + + // draw the single quad full screen (orthographic) + glMatrixMode( GL_TEXTURE ); + glPushMatrix(); + glScalef( textureScaleX, textureScaleY, 1.0f ); + + glEnable( GL_TEXTURE_2D ); + glColor3f( 1.0f, 1.0f, 1.0f ); + glBegin( GL_QUADS ); + glTexCoord2f( 1.0f, 0.0f ); + glVertex2d( mAppWindowWidth, 0 ); + + glTexCoord2f( 0.0f, 0.0f ); + glVertex2d( 0, 0 ); + + glTexCoord2f( 0.0f, 1.0f ); + glVertex2d( 0, mAppWindowHeight ); + + glTexCoord2f( 1.0f, 1.0f ); + glVertex2d( mAppWindowWidth, mAppWindowHeight ); + glEnd(); + + glMatrixMode( GL_TEXTURE ); + glPopMatrix(); + + glutSwapBuffers(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // convert a GLUT keyboard modifier to an LLQtWebKit one + // (only valid in mouse and keyboard callbacks + LLQtWebKit::EKeyboardModifier getLLQtWebKitKeyboardModifierCode() + { + int result = LLQtWebKit::KM_MODIFIER_NONE; + + int modifiers = glutGetModifiers(); + + if ( GLUT_ACTIVE_SHIFT & modifiers ) + { + result |= LLQtWebKit::KM_MODIFIER_SHIFT; + } + + if ( GLUT_ACTIVE_CTRL & modifiers ) + result |= LLQtWebKit::KM_MODIFIER_CONTROL; + + if ( GLUT_ACTIVE_ALT & modifiers ) + result |= LLQtWebKit::KM_MODIFIER_ALT; + + return (LLQtWebKit::EKeyboardModifier)result; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseButton( int button, int state, int xIn, int yIn ) + { + // texture is scaled to fit the screen so we scale mouse coords in the same way + xIn = ( xIn * mBrowserWindowWidth ) / mAppWindowWidth; + yIn = ( yIn * mBrowserWindowHeight ) / mAppWindowHeight; + + if ( button == GLUT_LEFT_BUTTON ) + { + if ( state == GLUT_DOWN ) + { + // send event to LLQtWebKit + LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId, + LLQtWebKit::ME_MOUSE_DOWN, + LLQtWebKit::MB_MOUSE_BUTTON_LEFT, + xIn, yIn, + getLLQtWebKitKeyboardModifierCode() ); + } + else + if ( state == GLUT_UP ) + { + // send event to LLQtWebKit + LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId, + LLQtWebKit::ME_MOUSE_UP, + LLQtWebKit::MB_MOUSE_BUTTON_LEFT, + xIn, yIn, + getLLQtWebKitKeyboardModifierCode() ); + + + // this seems better than sending focus on mouse down (still need to improve this) + LLQtWebKit::getInstance()->focusBrowser( mBrowserWindowId, true ); + }; + }; + + // force a GLUT update + glutPostRedisplay(); + } + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseMove( int xIn , int yIn ) + { + // texture is scaled to fit the screen so we scale mouse coords in the same way + xIn = ( xIn * mBrowserWindowWidth ) / mAppWindowWidth; + yIn = ( yIn * mBrowserWindowHeight ) / mAppWindowHeight; + + // send event to LLQtWebKit + LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId, + LLQtWebKit::ME_MOUSE_MOVE, + LLQtWebKit::MB_MOUSE_BUTTON_LEFT, + xIn, yIn, + LLQtWebKit::KM_MODIFIER_NONE ); + + + // force a GLUT update + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyboard( unsigned char keyIn, bool isDown) + { + // ESC key exits + if ( keyIn == 27 ) + { + reset(); + + exit( 0 ); + }; + + // Translate some keys + switch(keyIn) + { + case 127: + // Turn delete char into backspace + keyIn = LLQtWebKit::KEY_BACKSPACE; + break; + case '\r': + case '\n': + // Turn CR and NL into enter key + keyIn = LLQtWebKit::KEY_RETURN; + break; + + case '\t': + keyIn = LLQtWebKit::KEY_TAB; + break; + + default: + break; + } + + // control-H goes home + if ( keyIn == 8 ) + { + LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, mHomeUrl ); + } + // control-B navigates back + else if ( keyIn == 2 ) + { + LLQtWebKit::getInstance()->userAction(mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK); + } + // control-F navigates forward + else if ( keyIn == 6 ) + { + LLQtWebKit::getInstance()->userAction(mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD); + } + // control-R reloads + else if ( keyIn == 18 ) + { + LLQtWebKit::getInstance()->userAction(mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_RELOAD ); + } + // control-I toggles inspector + else if ( keyIn == 23 ) + { + LLQtWebKit::getInstance()->showWebInspector( true ); + } + else if ( keyIn == '1' ) + { + if ( getLLQtWebKitKeyboardModifierCode() == LLQtWebKit::KM_MODIFIER_CONTROL ) + { + LLQtWebKit::getInstance()->setPageZoomFactor( 1.0 ); + } + } + else if ( keyIn == '2' ) + { + if ( getLLQtWebKitKeyboardModifierCode() == LLQtWebKit::KM_MODIFIER_CONTROL ) + { + LLQtWebKit::getInstance()->setPageZoomFactor( 2.0 ); + } + } + + char text[2]; + if(keyIn < 0x80) + { + text[0] = (char)keyIn; + } + else + { + text[0] = 0; + } + + text[1] = 0; + + std::cerr << "key " << (isDown?"down ":"up ") << (int)keyIn << ", modifiers = " << (int)getLLQtWebKitKeyboardModifierCode() << std::endl; + + // send event to LLQtWebKit + LLQtWebKit::getInstance()->keyboardEvent(mBrowserWindowId, isDown?LLQtWebKit::KE_KEY_DOWN:LLQtWebKit::KE_KEY_UP, keyIn, text, getLLQtWebKitKeyboardModifierCode() ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyboardSpecial( int specialIn, bool isDown) + { + uint32_t key = LLQtWebKit::KEY_NONE; + + switch(specialIn) + { + case GLUT_KEY_F1: key = LLQtWebKit::KEY_F1; break; + case GLUT_KEY_F2: key = LLQtWebKit::KEY_F2; break; + case GLUT_KEY_F3: key = LLQtWebKit::KEY_F3; break; + case GLUT_KEY_F4: key = LLQtWebKit::KEY_F4; break; + case GLUT_KEY_F5: key = LLQtWebKit::KEY_F5; break; + case GLUT_KEY_F6: key = LLQtWebKit::KEY_F6; break; + case GLUT_KEY_F7: key = LLQtWebKit::KEY_F7; break; + case GLUT_KEY_F8: key = LLQtWebKit::KEY_F8; break; + case GLUT_KEY_F9: key = LLQtWebKit::KEY_F9; break; + case GLUT_KEY_F10: key = LLQtWebKit::KEY_F10; break; + case GLUT_KEY_F11: key = LLQtWebKit::KEY_F11; break; + case GLUT_KEY_F12: key = LLQtWebKit::KEY_F12; break; + case GLUT_KEY_LEFT: key = LLQtWebKit::KEY_LEFT; break; + case GLUT_KEY_UP: key = LLQtWebKit::KEY_UP; break; + case GLUT_KEY_RIGHT: key = LLQtWebKit::KEY_RIGHT; break; + case GLUT_KEY_DOWN: key = LLQtWebKit::KEY_DOWN; break; + case GLUT_KEY_PAGE_UP: key = LLQtWebKit::KEY_PAGE_UP; break; + case GLUT_KEY_PAGE_DOWN: key = LLQtWebKit::KEY_PAGE_DOWN;break; + case GLUT_KEY_HOME: key = LLQtWebKit::KEY_HOME; break; + case GLUT_KEY_END: key = LLQtWebKit::KEY_END; break; + case GLUT_KEY_INSERT: key = LLQtWebKit::KEY_INSERT; break; + + default: + break; + } + + if(key != LLQtWebKit::KEY_NONE) + { + keyboard(key, isDown); + } + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onPageChanged( const EventType& /*eventIn*/ ) + { + // flag that an update is required - page grab happens in idle() so we don't stall + mNeedsUpdate = true; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onNavigateBegin( const EventType& eventIn ) + { + std::cout << "Event: begin navigation to " << eventIn.getEventUri() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onNavigateComplete( const EventType& eventIn ) + { + std::cout << "Event: end navigation to " << eventIn.getEventUri() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onUpdateProgress( const EventType& eventIn ) + { + std::cout << "Event: progress value updated to " << eventIn.getIntValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onStatusTextChange( const EventType& eventIn ) + { + std::cout << "Event: status updated to " << eventIn.getStringValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onTitleChange( const EventType& eventIn ) + { + std::cout << "Event: title changed to " << eventIn.getStringValue() << std::endl; + glutSetWindowTitle( eventIn.getStringValue().c_str() ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onLocationChange( const EventType& eventIn ) + { + std::cout << "Event: location changed to " << eventIn.getStringValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onClickLinkHref( const EventType& eventIn ) + { + std::string uuid = eventIn.getStringValue2(); + + std::cout << "Event: clicked on link:" << std::endl; + std::cout << " URL:" << eventIn.getEventUri() << std::endl; + std::cout << " target:" << eventIn.getStringValue() << std::endl; + std::cout << " UUID:" << uuid << std::endl; + std::cout << std::endl; + + // Since we never actually open the window, send a "proxy window closed" back to webkit to keep it from leaking. + LLQtWebKit::getInstance()->proxyWindowClosed(mBrowserWindowId, uuid); + }; + + // virtual + void onClickLinkNoFollow(const EventType& eventIn) + { + std::cout << "Clink link no-follow --" << std::endl; + std::cout << " URL:" << eventIn.getEventUri() << std::endl; + std::cout << " type:" << eventIn.getNavigationType() << std::endl; + std::cout << " trusted:" << eventIn.getTrustedHost() << std::endl; + } + + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onCookieChanged( const EventType& eventIn ) + { + int dead = eventIn.getIntValue(); + std::cout << (dead?"deleting cookie: ":"setting cookie: ") << eventIn.getStringValue() << std::endl; + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + std::string onRequestFilePicker( const EventType& ) + { + std::string fn = chooseFileName(); + return fn; + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + bool onAuthRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password) + { + std::cout << "Auth request, url = " << in_url << ", realm = " << in_realm << std::endl; + out_username = ""; // replace these temporarily with site username/password as required. + out_password = ""; + return false; + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + bool onCertError(const std::string &in_url, const std::string &in_msg) + { + std::cout << "Cert error, url = " << in_url << ", message = " << in_msg << std::endl; + return false; // cancel (return true to ignore errors and continue) + } + + virtual void onQtDebugMessage( const std::string& msg, const std::string& msg_type) + { + std::cout << "QtDebugMsg [" << msg_type << "]> " << msg << std::endl; + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onLinkHovered( const EventType& eventIn ) + { + std::cout + << "Link hovered, link = " << eventIn.getEventUri() + << ", title = " << eventIn.getStringValue() + << ", text = " << eventIn.getStringValue2() + << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onWindowCloseRequested( const EventType& ) + { + std::cout << "Event: window close requested" << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onNavigateErrorPage( const EventType& event ) + { + std::cout << "Error page hit with code of " << event.getIntValue() << " - navigating to another URL" << std::endl; + LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "http://bestbuy.com" ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onWindowGeometryChangeRequested( const EventType& eventIn) + { + int x, y, width, height; + eventIn.getRectValue(x, y, width, height); + + std::cout << "Event: window geometry change requested" << std::endl; + std::cout << " uuid: " << eventIn.getStringValue() << std::endl; + std::cout << " location: (" << x << ", " << y << ")" << std::endl; + std::cout << " size: (" << width << ", " << height << ")" << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + int getAppWindowWidth() + { + return mAppWindowWidth; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + int getAppWindowHeight() + { + return mAppWindowHeight; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + std::string getAppWindowName() + { + return mAppWindowName; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void* getNativeWindowHandle() + { + // My implementation of the embedded browser needs a native window handle + // Can't get this via GLUT so had to use this hack + #ifdef _WINDOWS + return FindWindow( NULL, (LPCWSTR)mAppWindowName.c_str() ); + #else + #ifdef LL_OSX + // not needed on osx + return 0; + #else + //#error "You will need an implementation of this method" + return 0; + #endif + #endif + }; + + private: + int mAppWindowWidth; + int mAppWindowHeight; + int mBrowserWindowWidth; + int mBrowserWindowHeight; + int mAppTextureWidth; + int mAppTextureHeight; + GLuint mAppTexture; + int mBrowserWindowId; + std::string mAppWindowName; + std::string mHomeUrl; + std::string mCwd; + bool mNeedsUpdate; + std::string mApplicationDir; + std::string mProfileDir; + std::string mCookiePath; +}; + +testGL* theApp; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutReshape( int widthIn, int heightIn ) +{ + if ( theApp ) + theApp->reshape( widthIn, heightIn ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutDisplay() +{ + if ( theApp ) + theApp->display(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutIdle() +{ + if ( theApp ) + theApp->idle(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutKeyboard( unsigned char keyIn, int /*xIn*/, int /*yIn*/ ) +{ + if ( theApp ) + { + theApp->keyboard( keyIn, true ); + } +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutKeyboardUp( unsigned char keyIn, int /*xIn*/, int /*yIn*/ ) +{ + if ( theApp ) + { + theApp->keyboard( keyIn, false ); + } +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutSpecial( int specialIn, int /*xIn*/, int /*yIn*/ ) +{ + if ( theApp ) + { + theApp->keyboardSpecial( specialIn, true ); + } +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutSpecialUp( int specialIn, int /*xIn*/, int /*yIn*/ ) +{ + if ( theApp ) + { + theApp->keyboardSpecial( specialIn, false ); + } +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseMove( int xIn , int yIn ) +{ + if ( theApp ) + theApp->mouseMove( xIn, yIn ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseButton( int buttonIn, int stateIn, int xIn, int yIn ) +{ + if ( theApp ) + theApp->mouseButton( buttonIn, stateIn, xIn, yIn ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +int main( int argc, char* argv[] ) +{ + glutInit( &argc, argv ); + glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB ); + + // implementation in a class so we can observer events + // means we need this painful GLUT <--> class shim... + theApp = new testGL; + + if ( theApp ) + { + glutInitWindowPosition( 80, 0 ); + glutInitWindowSize( theApp->getAppWindowWidth(), theApp->getAppWindowHeight() ); + + glutCreateWindow( theApp->getAppWindowName().c_str() ); + + std::string url = ""; + if ( 2 == argc ) + url = std::string( argv[ 1 ] ); + + theApp->init( std::string( argv[ 0 ] ), url ); + + glutKeyboardFunc( glutKeyboard ); + glutKeyboardUpFunc( glutKeyboardUp ); + glutSpecialFunc( glutSpecial ); + glutSpecialUpFunc( glutSpecialUp ); + + glutMouseFunc( glutMouseButton ); + glutPassiveMotionFunc( glutMouseMove ); + glutMotionFunc( glutMouseMove ); + + glutDisplayFunc( glutDisplay ); + glutReshapeFunc( glutReshape ); + + glutIdleFunc( glutIdle ); + + glutMainLoop(); + + std::cout << "glutMainLoop returned" << std::endl; + + delete theApp; + }; + + return 0; +} diff --git a/indra/llqtwebkit/tests/testgl/testgl.pro b/indra/llqtwebkit/tests/testgl/testgl.pro new file mode 100644 index 000000000..42692d68d --- /dev/null +++ b/indra/llqtwebkit/tests/testgl/testgl.pro @@ -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 diff --git a/indra/llqtwebkit/tests/textmode/textmode.cpp b/indra/llqtwebkit/tests/textmode/textmode.cpp new file mode 100644 index 000000000..019fba902 --- /dev/null +++ b/indra/llqtwebkit/tests/textmode/textmode.cpp @@ -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 +} +#endif + +#ifdef _WINDOWS +#include +#include +#endif + +#include +#include +#include +#include +#include +#include + +#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 +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 " << 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; +} diff --git a/indra/llqtwebkit/tests/textmode/textmode.pro b/indra/llqtwebkit/tests/textmode/textmode.pro new file mode 100644 index 000000000..d41e1ea68 --- /dev/null +++ b/indra/llqtwebkit/tests/textmode/textmode.pro @@ -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 diff --git a/indra/llqtwebkit/win32/3p-qt-vars.bat b/indra/llqtwebkit/win32/3p-qt-vars.bat new file mode 100644 index 000000000..5ea118848 --- /dev/null +++ b/indra/llqtwebkit/win32/3p-qt-vars.bat @@ -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" diff --git a/indra/llqtwebkit/win32/Qt Command Prompt (3p-qt).lnk b/indra/llqtwebkit/win32/Qt Command Prompt (3p-qt).lnk new file mode 100644 index 000000000..460a9e9cf Binary files /dev/null and b/indra/llqtwebkit/win32/Qt Command Prompt (3p-qt).lnk differ diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 210ea7167..03eddae8d 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -290,9 +290,11 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) //---------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_STATS("Image Stats"); // static void LLImageGL::updateStats(F32 current_time) { + LLFastTimer t(FTM_IMAGE_UPDATE_STATS); sLastFrameTime = current_time; sBoundTextureMemoryInBytes = sCurBoundTextureMemory; sCurBoundTextureMemory = 0; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index acc842818..926ae374d 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -2443,7 +2443,6 @@ BOOL LLLineEditor::evaluateFloat() { bool success = false; std::string expr = getText(); - LLStringUtil::toUpper(expr); // user deleted the contents, nothing to evaluate -- MC if (expr.empty()) diff --git a/indra/llui/lltrans.cpp b/indra/llui/lltrans.cpp index f7988c965..13721aa40 100644 --- a/indra/llui/lltrans.cpp +++ b/indra/llui/lltrans.cpp @@ -92,9 +92,15 @@ bool LLTrans::parseStrings(const std::string& xml_filename, const std::setgetRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; + if (!viewp->visibleAndContains(local_x, local_y)) + { + continue; + } + // Here we've found the first (frontmost) visible child at this level + // containing the specified point. Is the caller asking us to drill + // down and return the innermost leaf child at this point, or just the + // top-level child? + if (recur) + { + LLView* leaf(viewp->childFromPoint(local_x, local_y, recur)); + // Maybe viewp is already a leaf LLView, or maybe it has children + // but this particular (x, y) point falls between them. If the + // recursive call returns non-NULL, great, use that; else just use + // viewp. + return leaf? leaf : viewp; + } + return viewp; + + } + return 0; +} + BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent) { BOOL handled = FALSE; @@ -1507,7 +1540,7 @@ BOOL LLView::hasChild(const std::string& childname, BOOL recurse) const //----------------------------------------------------------------------------- // getChildView() //----------------------------------------------------------------------------- -static LLFastTimer::DeclareTimer FTM_FIND_VIEWS("Find Views"); +static LLFastTimer::DeclareTimer FTM_FIND_VIEWS("Find Widgets"); LLView* LLView::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const { diff --git a/indra/llui/llview.h b/indra/llui/llview.h index ee2ad2d3e..a742b2c56 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -394,11 +394,9 @@ public: void setShape(const LLRect& new_rect, bool by_user = false); virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0); virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0); - virtual BOOL canSnapTo(const LLView* other_view); - virtual void setSnappedTo(const LLView* snap_view); - + // inherited from LLFocusableElement /* virtual */ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); /* virtual */ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); @@ -478,6 +476,7 @@ public: /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); // Display mToolTipMsg if no child handles it. + /*virtual*/ const std::string& getName() const; /*virtual*/ void onMouseCaptureLost(); /*virtual*/ BOOL hasMouseCapture(); @@ -485,6 +484,8 @@ public: /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; + virtual LLView* childFromPoint(S32 x, S32 y, bool recur=false); + template T* findChild(const std::string& name) { return getChild(name,true,false); diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 0f93fea47..68bb663a3 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1914,7 +1914,7 @@ void LLWindowSDL::gatherInput() mIsMinimized = (!event.active.gain); mCallbacks->handleActivate(this, !mIsMinimized); - llinfos << "SDL deiconification state switched to " << BOOL(event.active.gain) << llendl; + lldebugs << "SDL deiconification state switched to " << BOOL(event.active.gain) << llendl; } else { diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4c18a6a83..3ef620b2b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -10,9 +10,10 @@ include(ELFIO) if(FMODEX) include(FMODEX) set(FMOD OFF) -else(FMODEX) - include(FMOD) endif(FMODEX) +if(FMOD) + include(FMOD) +endif(FMOD) include(OPENAL) include(FindOpenGL) include(Hunspell) @@ -224,6 +225,7 @@ set(viewer_SOURCE_FILES llfloaternotificationsconsole.cpp llfloaterobjectiminfo.cpp llfloateropenobject.cpp + llfloateroutbox.cpp llfloaterparcel.cpp llfloaterpermissionsmgr.cpp llfloaterperms.cpp @@ -304,6 +306,7 @@ set(viewer_SOURCE_FILES llmanipscale.cpp llmaniptranslate.cpp llmapresponders.cpp + llmarketplacefunctions.cpp llmarketplacenotifications.cpp llmediactrl.cpp llmediaremotectrl.cpp @@ -356,6 +359,7 @@ set(viewer_SOURCE_FILES llpanellandoptions.cpp llpanellogin.cpp llpanelmaininventory.cpp + llpanelmarketplaceoutboxinventory.cpp llpanelmediahud.cpp llpanelmorph.cpp llpanelmsgs.cpp @@ -725,6 +729,7 @@ set(viewer_HEADER_FILES llfloaternotificationsconsole.h llfloaterobjectiminfo.h llfloateropenobject.h + llfloateroutbox.h llfloaterparcel.h llfloaterpermissionsmgr.h llfloaterperms.h @@ -805,6 +810,7 @@ set(viewer_HEADER_FILES llmanipscale.h llmaniptranslate.h llmapresponders.h + llmarketplacefunctions.h llmarketplacenotifications.h llmediactrl.h llmediaremotectrl.h @@ -857,6 +863,7 @@ set(viewer_HEADER_FILES llpanellandoptions.h llpanellogin.h llpanelmaininventory.h + llpanelmarketplaceoutboxinventory.h llpanelmediahud.h llpanelmorph.h llpanelmsgs.h @@ -1270,8 +1277,6 @@ if (WINDOWS) if (INTEL_MEMOPS_LIBRARY) list(APPEND viewer_LIBRARIES ${INTEL_MEMOPS_LIBRARY}) endif (INTEL_MEMOPS_LIBRARY) - - use_prebuilt_binary(dbghelp) endif (WINDOWS) # Add the xui files. This is handy for searching for xui elements @@ -1369,13 +1374,10 @@ if (FMOD OR FMODEX) set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMOD") endif (FMOD) - if (DARWIN) - if(FMOD) + if (DARWIN AND FMOD) set(fmodwrapper_SOURCE_FILES fmodwrapper.cpp) add_library(fmodwrapper SHARED ${fmodwrapper_SOURCE_FILES}) - if (FMOD) - set(fmodwrapper_needed_LIBRARIES ${FMOD_LIBRARY} ${CARBON_LIBRARY}) - endif (FMOD) + set(fmodwrapper_needed_LIBRARIES ${FMOD_LIBRARY} ${CARBON_LIBRARY}) set_target_properties( fmodwrapper PROPERTIES @@ -1385,11 +1387,7 @@ if (FMOD OR FMODEX) ) set(FMODWRAPPER_LIBRARY fmodwrapper) target_link_libraries(fmodwrapper ${fmodwrapper_needed_LIBRARIES}) - endif(FMOD) - if(FMODEX) - set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY}) - endif(FMODEX) - else (DARWIN) + else (DARWIN AND FMOD) # fmodwrapper unnecessary on linux or windows, for fmod and fmodex if (FMODEX) set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY}) @@ -1397,7 +1395,7 @@ if (FMOD OR FMODEX) if (FMOD) set(FMODWRAPPER_LIBRARY ${FMOD_LIBRARY}) endif (FMOD) - endif (DARWIN) + endif (DARWIN AND FMOD) endif (FMOD OR FMODEX) set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") @@ -1433,9 +1431,9 @@ set(PACKAGE ${PACKAGE_DEFAULT} CACHE BOOL if (WINDOWS) if(MSVC10) set(release_flags "/MAPRelease/${VIEWER_BINARY_NAME}.map") - else() + else(MSVC10) set(release_flags "/MAP:Release/${VIEWER_BINARY_NAME}.map") - endif() + endif(MSVC10) if (FMOD) if(MANIFEST_LIBRARIES) diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 6bed5a829..7e35949ed 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -1,21 +1,79 @@ - help + + agenturi desc - display this help message - - short - h + URL of agent host to connect to in Agent Domain. + count + 1 + map-to + CmdLineAgentURI - port + autologin + + desc + log in as last saved user + map-to + AutoLogin + + + channel count 1 map-to - UserConnectionPort + VersionChannelName + + + console + + count + 1 + map-to + ShowConsoleWindow + + + cooperative + + desc + Yield some idle time to local host. + count + 1 + map-to + YieldTime + + + crashonstartup + + desc + Crashes on startup. For QA use. + map-to + CrashOnStartup + + + debugsession + + desc + Run as if RenderDebugGL is TRUE, but log errors until end of session. + map-to + DebugSession + + + debugviews + + map-to + DebugViews + + + disablecrashlogger + + desc + Disables the crash logger and lets the OS handle crashes + map-to + DisableCrashLogger drop @@ -26,20 +84,12 @@ PacketDropPercentage - inbw + god - count - 1 + desc + Log in a god if you have god access. map-to - InBandwidth - - - outbw - - count - 1 - map-to - OutBandwidth + ConnectAsGod grid @@ -52,6 +102,69 @@ CmdLineGridChoice
+ help + + desc + display this help message + + short + h + + + helperuri + + desc + helper web CGI prefix to use + count + 1 + map-to + CmdLineHelperURI + + + ignorepixeldepth + + desc + Ignore pixel depth settings. + map-to + IgnorePixelDepth + + + inbw + + count + 1 + map-to + InBandwidth + + + logfile + + count + 1 + map-to + UserLogFile + + + login + + desc + 3 tokens: first, last and password + count + 3 + map-to + UserLoginInfo + + + loginpage + + desc + Login authentication page to use. + count + 1 + map-to + LoginPage + + loginuri desc @@ -64,60 +177,12 @@ CmdLineLoginURI - helperuri + multiple desc - helper web CGI prefix to use - count - 1 + Allow multiple viewers. map-to - CmdLineHelperURI - - - debugviews - - map-to - DebugViews - - - skin - - desc - ui/branding skin folder to use - count - 1 - map-to - SkinFolder - - - autologin - - desc - log in as last saved user - map-to - AutoLogin - - - quitafter - - count - 1 - map-to - QuitAfterSeconds - - - - debugsession - - desc - Run as if RenderDebugGL is TRUE, but log errors until end of session. - map-to - DebugSession - - rotate - - map-to - RotateRight + AllowMultipleViewers noaudio @@ -126,10 +191,18 @@ NoAudio
- nosound + noinvlib + + desc + Do not request the inventory library. + map-to + NoInventoryLibrary + + + nopreload map-to - NoAudio + NoPreload noprobe @@ -144,10 +217,40 @@ NoQuickTime - nopreload + nosound map-to - NoPreload + NoAudio + + + no-verify-ssl-cert + + map-to + NoVerifySSLCert + + + novoice + + desc + Disable voice. + map-to + CmdLineDisableVoice + + + outbw + + count + 1 + map-to + OutBandwidth + + + port + + count + 1 + map-to + UserConnectionPort purge @@ -158,41 +261,50 @@ PurgeCacheOnNextStartup - noinvlib + qa desc - Do not request the inventory library. + Activated debugging menu in Advanced Settings. map-to - NoInventoryLibrary + QAMode - logfile + quitafter count 1 map-to - UserLogFile + QuitAfterSeconds - setdefault + regionuri desc - specify the value of a particular - configuration variable which can be - overridden by settings.xml - + URL of region to connect to through Agent Domain. count - 2 - + 1 + map-to + CmdLineRegionURI + + + rotate + + map-to + RotateRight + + + safe + + desc + Reset preferences, run in safe mode. + map-to + SafeMode set desc - specify the value of a particular - configuration variable that - overrides all other settings - + specify the value of a particular configuration variable that overrides all other settings. count 2 compose @@ -200,6 +312,15 @@ + setdefault + + desc + specify the value of a particular configuration variable which can be overridden by settings.xml. + count + 2 + + + settings desc @@ -209,65 +330,14 @@ - login + skin desc - 3 tokens: first, last and password - count - 3 - map-to - UserLoginInfo - - - god - - desc - Log in a god if you have god access. - map-to - ConnectAsGod - - - console - + ui/branding skin folder to use count 1 map-to - ShowConsoleWindow - - - safe - - desc - Reset preferences, run in safe mode. - map-to - SafeMode - - - multiple - - desc - Allow multiple viewers. - map-to - AllowMultipleViewers - - - novoice - - desc - Disable voice. - map-to - CmdLineDisableVoice - - - url - - desc - Startup location - count - 1 - last_option - true - + SkinFolder slurl @@ -283,92 +353,15 @@ - regionuri + url desc - URL of region to connect to through Agent Domain. + Startup location count 1 - map-to - CmdLineRegionURI + last_option + true + - - - agenturi - - desc - URL of agent host to connect to in Agent Domain. - count - 1 - map-to - CmdLineAgentURI - - - ignorepixeldepth - - desc - Ignore pixel depth settings. - map-to - IgnorePixelDepth - - - cooperative - - desc - Yield some idle time to local host. - count - 1 - map-to - YieldTime - - - no-verify-ssl-cert - - map-to - NoVerifySSLCert - - - channel - - count - 1 - map-to - VersionChannelName - - - loginpage - - desc - Login authentication page to use. - count - 1 - map-to - LoginPage - - - qa - - desc - Activated debugging menu in Advanced Settings. - map-to - QAMode - - - crashonstartup - - desc - Crashes on startup. For QA use. - map-to - CrashOnStartup - - - disablecrashlogger - - desc - Disables the crash logger and lets the OS handle crashes - map-to - DisableCrashLogger - - diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index bc2023902..7e5a991c7 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -682,6 +682,18 @@ Value 0 + LiruSensibleARC + + Comment + Use the old-style way to calculate Avatar Render Cost. +Found in Advanced->Rendering->Info Displays + Persist + 1 + Type + Boolean + Value + 1 + ResetFocusOnSelfClick Comment diff --git a/indra/newview/app_settings/windlight/skies/%5BEUPHORIA%5D%20smoky%20blue%20sky%20%253A%20reverse.xml b/indra/newview/app_settings/windlight/skies/%5BEUPHORIA%5D%20smoky%20blue%20sky%20%253A%20reverse.xml new file mode 100755 index 000000000..4d50f8091 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/%5BEUPHORIA%5D%20smoky%20blue%20sky%20%253A%20reverse.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.8300000429153442 + 1.8300000429153442 + 1.8300000429153442 + 0.61000001430511475 + + blue_density + + 0.21899415552616119 + 0.40148928761482239 + 0.68000000715255737 + 0.34000000357627869 + + blue_horizon + + 0 + 0.10838708281517029 + 0.14000000059604645 + 0.070000000298023224 + + cloud_color + + 0 + 0 + 0 + 0 + + cloud_pos_density1 + + 0.14000000059604645 + 0.62000000476837158 + 0.99999999999999767 + 1 + + cloud_pos_density2 + + 0.48999997973442078 + 0.19999998807907104 + 0.125 + 1 + + cloud_scale + + 0.43999999761581421 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.199999853917745 + 10.010999722693327 + + cloud_shadow + + 0.29999998211860657 + 0 + 0 + 1 + + density_multiplier + + 0.00015999999595806003 + 0 + 0 + 1 + + distance_multiplier + + 10.800000190734863 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 0.94999998807907104 + 0 + 0 + 1 + + glow + + 4.9999999403953552 + 0.0010000000616982377 + -0.47999998693999579 + 1 + + haze_density + + 0.94999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.25999999046325684 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.96692299842834473 + -0.25506836175918579 + 0 + + max_y + + 1128 + 0 + 0 + 1 + + preset_num + 28 + star_brightness + 0 + sun_angle + 1.8287147283554077 + sunlight_color + + 0.65999996662139893 + 0.78157895803451538 + 0.89999997615814209 + 0.29999998211860657 + + + diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20Dark.xml b/indra/newview/app_settings/windlight/skies/Ambient%20Dark.xml new file mode 100644 index 000000000..20aa5ba44 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Ambient%20Dark.xml @@ -0,0 +1,141 @@ + + + ambient + + 0 + 0 + 0 + 0 + + blue_density + + 0 + 0 + 0 + 0 + + blue_horizon + + 0 + 0 + 0 + 0 + + cloud_color + + 0 + 0 + 0 + 0 + + cloud_pos_density1 + + 0.5 + 0.5 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 11.539999961853027 + 10.01099967956543 + + cloud_shadow + + 0 + 0 + 0 + 1 + + density_multiplier + + 0.00042999998549930751 + 0 + 0 + 1 + + distance_multiplier + + 8.1000003814697266 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 20 + 0.0010000000474974513 + -0 + 1 + + haze_density + + 0.079999998211860657 + 0 + 0 + 1 + + haze_horizon + + 0 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + -0 + 0.89100658893585205 + 0.45399042963981628 + 0 + + max_y + + 718.70001220703125 + 0 + 0 + 1 + + preset_num + 23 + star_brightness + 0 + sun_angle + 1.0995575189590454 + sunlight_color + + 0 + 0 + 0 + 0 + + + diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20Grey.xml b/indra/newview/app_settings/windlight/skies/Ambient%20Grey.xml new file mode 100644 index 000000000..6949d336b --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Ambient%20Grey.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.9499999284744263 + 1.9499999284744263 + 1.9499999284744263 + 0.64999997615814209 + + blue_density + + 0 + 0 + 0 + 0 + + blue_horizon + + 0 + 0 + 0 + 0 + + cloud_color + + 0 + 0 + 0 + 0 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 0.99999999999999289 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.4199999868869746 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.069999694824219 + 11.050000190734863 + + cloud_shadow + + 0 + 0 + 0 + 1 + + density_multiplier + + 0.00089999998454004526 + 0 + 0 + 1 + + distance_multiplier + + 0.80000001192093606 + 0 + 0 + 1 + + east_angle + 4.7123889923095703 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 0.029999999329447746 + 0 + 0 + 1 + + haze_horizon + + 0 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + -0.99144464731216431 + 0.13052797317504883 + -1.182285913614578e-008 + 0 + + max_y + + 4000 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 3.0106911659240723 + sunlight_color + + 0 + 0 + 0 + 0 + + + diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20White.xml b/indra/newview/app_settings/windlight/skies/Ambient%20White.xml new file mode 100644 index 000000000..c30c1db26 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Ambient%20White.xml @@ -0,0 +1,141 @@ + + + ambient + + 3 + 3 + 3 + 1 + + blue_density + + 0 + 0 + 0 + 0 + + blue_horizon + + 0 + 0 + 0 + 0 + + cloud_color + + 0 + 0 + 0 + 0 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 0.99999999999999289 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.4199999868869746 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.069999694824219 + 11.050000190734863 + + cloud_shadow + + 0 + 0 + 0 + 1 + + density_multiplier + + 0.00089999998454004526 + 0 + 0 + 1 + + distance_multiplier + + 0.80000001192093606 + 0 + 0 + 1 + + east_angle + 4.7123889923095703 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 0.029999999329447746 + 0 + 0 + 1 + + haze_horizon + + 0 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + -0.99144464731216431 + 0.13052797317504883 + -1.182285913614578e-008 + 0 + + max_y + + 4000 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 3.0106911659240723 + sunlight_color + + 0 + 0 + 0 + 0 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Dark%20Red%20sky.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Dark%20Red%20sky.xml new file mode 100644 index 000000000..f3005fbea --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Dark%20Red%20sky.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.3079376220703125 + 0.31744983792304993 + 0.4186248779296875 + 0.1395416259765625 + + blue_density + + 0.078125 + 0.078125 + 0.078125 + 0.0390625 + + blue_horizon + + 0.1856689453125 + 0.2917042076587677 + 0.3768310546875 + 0.18841552734375 + + cloud_color + + 0.2981414794921875 + 0.0065460205078125 + 0.081723079085350037 + 0.2981414794921875 + + cloud_pos_density1 + + 0.68000000715255737 + 0.5 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.18000000715255737 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.47999998927116394 + 0 + 0 + 1 + + density_multiplier + + 0 + 0 + 0 + 1 + + distance_multiplier + + 0 + 0 + 0 + 1 + + east_angle + 0.25132742524147034 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.0199999809265137 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.33000001311302185 + 1 + + haze_density + + 0.57999998331069946 + 0 + 0 + 1 + + haze_horizon + + 0 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.22304299473762512 + 0.44229033589363098 + -0.86869502067565918 + 0 + + max_y + + 880 + 0 + 0 + 1 + + preset_num + 21 + star_brightness + 0 + sun_angle + 2.6834418773651123 + sunlight_color + + 1.56097412109375 + 1.4059410095214844 + 1.34527587890625 + 0.52032470703125 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Darkness.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Darkness.xml new file mode 100644 index 000000000..c4495ce55 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Darkness.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.21000002324581146 + 0.21000002324581146 + 0.21000002324581146 + 0.070000007748603821 + + blue_density + + 0.51999998092651367 + 0.51999998092651367 + 0.51999998092651367 + 0.25999999046325684 + + blue_horizon + + 0.296875 + 0.296875 + 0.296875 + 0.1484375 + + cloud_color + + 0.69140625 + 0.69140625 + 0.69140625 + 0.69140625 + + cloud_pos_density1 + + 0.57999998331069946 + 0.44999998807907104 + 0.91999995708465576 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.649999618530273 + 10.359999656677246 + + cloud_shadow + + 0.47999998927116394 + 0 + 0 + 1 + + density_multiplier + + 0.00014000000373926014 + 0 + 0 + 1 + + distance_multiplier + + 11.5 + 0 + 0 + 1 + + east_angle + 3.958406925201416 + enable_cloud_scroll + + 0 + 0 + + gamma + + 1.0499999523162842 + 0 + 0 + 1 + + glow + + 20 + 0.0010000000474974513 + -0 + 1 + + haze_density + + 0.55000001192092896 + 0 + 0 + 1 + + haze_horizon + + 0.099999994039535522 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + -0.5154578685760498 + 0.70710796117782593 + 0.48404696583747864 + 0 + + max_y + + 886 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 2 + sun_angle + 2.3561928272247314 + sunlight_color + + 0.87000000476837158 + 0.87000000476837158 + 0.87000000476837158 + 0.28999999165534973 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Dusty.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Dusty.xml new file mode 100644 index 000000000..b3a4a13c9 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Dusty.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.291046142578125 + 0.42025142908096313 + 0.505828857421875 + 0.168609619140625 + + blue_density + + 0.15999999642372131 + 0.15999999642372131 + 0.15999999642372131 + 0.079999998211860657 + + blue_horizon + + 0.19999998807907104 + 0.19999998807907104 + 0.19999998807907104 + 0.099999994039535522 + + cloud_color + + 0.61395263671875 + 0.50241565704345703 + 0.48760986328125 + 0.61395263671875 + + cloud_pos_density1 + + 0.52999997138977051 + 0.45999997854232788 + 0.070000000298023224 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.039999999105930328 + 1 + + cloud_scale + + 0.15999999642372131 + 0 + 0 + 1 + + cloud_scroll_rate + + 20 + 20 + + cloud_shadow + + 0.68000000715255737 + 0 + 0 + 1 + + density_multiplier + + 0.00015999999595806003 + 0 + 0 + 1 + + distance_multiplier + + 12.199999809265137 + 0 + 0 + 1 + + east_angle + 5.026547908782959 + enable_cloud_scroll + + 0 + 0 + + gamma + + 1.2200000286102295 + 0 + 0 + 1 + + glow + + 0.19999980926513672 + 0.0010000000474974513 + -0 + 1 + + haze_density + + 4 + 0 + 0 + 1 + + haze_horizon + + 0.17999999225139618 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + -0.93278193473815918 + 0.19509218633174896 + -0.30307888984680176 + 0 + + max_y + + 347 + 0 + 0 + 1 + + preset_num + 18 + star_brightness + 0 + sun_angle + 2.9452412128448486 + sunlight_color + + 0.91124993562698364 + 0.61839842796325684 + 0.52875006198883057 + 0.30374997854232788 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Light%20Explosion%20II.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Light%20Explosion%20II.xml new file mode 100644 index 000000000..24a192b95 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Light%20Explosion%20II.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.6568816900253296 + 1.5270273685455322 + 1.4837433099746704 + 0.55229389667510986 + + blue_density + + 1.1843417882919312 + 1.3887529373168945 + 1.4597588777542114 + 0.72987943887710571 + + blue_horizon + + 0.468017578125 + 0.62104421854019165 + 0.641357421875 + 0.3206787109375 + + cloud_color + + 0.0234222412109375 + 0.018011331558227539 + 0.0156402587890625 + 0.0234222412109375 + + cloud_pos_density1 + + 0.39999997615814209 + 0.81000000238418579 + 0.10999999940395355 + 1 + + cloud_pos_density2 + + 0.56000000238418579 + 1 + 0 + 1 + + cloud_scale + + 0.08999999612569809 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.6499996185302734 + 10.01099967956543 + + cloud_shadow + + 0.5 + 0 + 0 + 1 + + density_multiplier + + 0.00017999998817685992 + 0 + 0 + 1 + + distance_multiplier + + 2 + 0 + 0 + 1 + + east_angle + 1.2566369771957397 + enable_cloud_scroll + + 0 + 0 + + gamma + + 1.6299999952316284 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.39999997615814209 + 1 + + haze_density + + 1.2300000190734863 + 0 + 0 + 1 + + haze_horizon + + 0 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.57896542549133301 + 0.79335421323776245 + -0.18811732530593872 + 0 + + max_y + + 293 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 2.2252933979034424 + sunlight_color + + 1.62725830078125 + 1.8157768249511719 + 1.98211669921875 + 0.66070556640625 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Light%20Explosion%20III.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Light%20Explosion%20III.xml new file mode 100644 index 000000000..ba2df9e6e --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Light%20Explosion%20III.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.89040267467498779 + 1.0580335855484009 + 1.4399999380111694 + 0.47999998927116394 + + blue_density + + 0.43015211820602417 + 0.44939243793487549 + 0.51507484912872314 + 0.25753742456436157 + + blue_horizon + + 0.15130999684333801 + 0.30000001192092896 + 0.35131001472473145 + 1 + + cloud_color + + 0.21396400034427643 + 0.21396400034427643 + 0.21396400034427643 + 1 + + cloud_pos_density1 + + 0.099999994039535522 + 0.09771379828453064 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.079754598438739777 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.644780158996582 + 10.423800468444824 + + cloud_shadow + + 0.45999997854232788 + 0 + 0 + 1 + + density_multiplier + + 0.00015800200344529003 + 0 + 0 + 1 + + distance_multiplier + + 1 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 0 + 0 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.33000001311302185 + 1 + + haze_density + + 1.2300000190734863 + 0 + 0 + 1 + + haze_horizon + + 0.17999999225139618 + 0.13210900127887726 + 0.13210900127887726 + 1 + + lightnorm + + -0 + 0.99785882234573364 + 0.06540437787771225 + 0 + + max_y + + 600 + 0 + 0 + 1 + + preset_num + 3 + star_brightness + 0 + sun_angle + 1.5053452253341675 + sunlight_color + + 3 + 3 + 3 + 1 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Light%20Explosion.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Light%20Explosion.xml new file mode 100644 index 000000000..0c318b6ed --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Light%20Explosion.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.31640625 + 0.31640625 + 0.31640625 + 0.10546875 + + blue_density + + 0.40625 + 0.59642577171325684 + 0.63374996185302734 + 0.31687498092651367 + + blue_horizon + + 0.296875 + 0.296875 + 0.296875 + 0.1484375 + + cloud_color + + 0 + 0 + 0 + 0 + + cloud_pos_density1 + + 0.57999998331069946 + 0.44999998807907104 + 0.91999995708465576 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.15999999642372131 + 1 + + cloud_scale + + 0.5899999737739563 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.649999618530273 + 10.359999656677246 + + cloud_shadow + + 0.32999998331069946 + 0 + 0 + 1 + + density_multiplier + + 0.00016999999934341758 + 0 + 0 + 1 + + distance_multiplier + + 31.30000114440918 + 0 + 0 + 1 + + east_angle + 2.4504423141479492 + enable_cloud_scroll + + 0 + 0 + + gamma + + 1.0499999523162842 + 0 + 0 + 1 + + glow + + 0.19999980926513672 + 0.0010000000474974513 + -2.5 + 1 + + haze_density + + 0 + 0 + 0 + 1 + + haze_horizon + + 0 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.59898221492767334 + 0.34202155470848083 + 0.72404521703720093 + 0 + + max_y + + 827 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 2.7925252914428711 + sunlight_color + + 0.77144533395767212 + 0.86230051517486572 + 0.9685547947883606 + 0.32285159826278687 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Optimal%20Skin%20%28no%20shadows%29.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Optimal%20Skin%20%28no%20shadows%29.xml new file mode 100644 index 000000000..3ca73ade7 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Optimal%20Skin%20%28no%20shadows%29.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.7898764610290527 + 1.7999999523162842 + 1.7999999523162842 + 0.59999996423721313 + + blue_density + + 0.17840505994550426 + 0.41624023325357484 + 0.78666704491092787 + 0.79331876337528229 + + blue_horizon + + 0.23695440116756572 + 0.30749256375219147 + 0.38000917434692383 + 0.77331733703613281 + + cloud_color + + 0.28744032449850465 + 0.28744032449850465 + 0.28744032449850465 + 0.80331945419311523 + + cloud_pos_density1 + + 1 + 1 + 0.92000281969717435 + 1 + + cloud_pos_density2 + + 0.29999998211860657 + 0.29999998211860657 + 0.125 + 1 + + cloud_scale + + 0.4199999912582939 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.399593049491159 + 10.010999738700775 + + cloud_shadow + + 0.39999997615814209 + 0 + 0 + 1 + + density_multiplier + + 0.0003666600819003385 + 0 + 0 + 1 + + distance_multiplier + + 0.93332862854003906 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000491261485 + -0.47999999284769501 + 1 + + haze_density + + 0.69999999205299446 + 0 + 0 + 1 + + haze_horizon + + 0.17000070333489248 + 0.1991559977192594 + 0.1991559977192594 + 1 + + lightnorm + + 0 + 0.3070400059223175 + -0.95169663429260254 + 0 + + max_y + + 910.02454853057861 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 2.8295114040374756 + sunlight_color + + 0.29243719577789307 + 0.29459795355796814 + 0.29999998211860657 + 0.099999994039535522 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Realistic%20ambient.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Realistic%20ambient.xml new file mode 100644 index 000000000..506d8ae2c --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Realistic%20ambient.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.73828125 + 0.63248288631439209 + 0.61171871423721313 + 0.24609375 + + blue_density + + 1.0170860290527344 + 1.015869140625 + 1.171630859375 + 0.5858154296875 + + blue_horizon + + 0.287109375 + 0.39328005909919739 + 0.478515625 + 0.2392578125 + + cloud_color + + 0.50999999046325684 + 0.50999999046325684 + 0.50999999046325684 + 0.50999999046325684 + + cloud_pos_density1 + + 0.34999999403953552 + 0.31000000238418579 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.099999994039535522 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.35999998450279236 + 0 + 0 + 1 + + density_multiplier + + 0.00026000000070780516 + 0 + 0 + 1 + + distance_multiplier + + 6.0999999046325684 + 0 + 0 + 1 + + east_angle + 0.62831848859786987 + enable_cloud_scroll + + 0 + 0 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 8.2000017166137695 + 0.0010000000474974513 + -0.19999998807907104 + 1 + + haze_density + + 1.7799999713897705 + 0 + 0 + 1 + + haze_horizon + + 0.23999999463558197 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.47401577234268188 + 0.59131073951721191 + -0.65242677927017212 + 0 + + max_y + + 720 + 0 + 0 + 1 + + preset_num + 21 + star_brightness + 0 + sun_angle + 2.5089094638824463 + sunlight_color + + 1.677886962890625 + 1.646484375 + 1.728515625 + 0.576171875 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Red%20moments.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Red%20moments.xml new file mode 100644 index 000000000..cd7ba4933 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Red%20moments.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.73851561546325684 + 0.65285521745681763 + 0.64148437976837158 + 0.24617186188697815 + + blue_density + + 0.83835935592651367 + 1.0087707042694092 + 1.1216405630111694 + 0.56082028150558472 + + blue_horizon + + 0.387725830078125 + 0.24486541748046875 + 0.159149169921875 + 0.1938629150390625 + + cloud_color + + 0.9296875 + 0.9296875 + 0.9296875 + 0.9296875 + + cloud_pos_density1 + + 0.47999998927116394 + 0.5 + 1 + 1 + + cloud_pos_density2 + + 0.53999996185302734 + 0.4699999988079071 + 0.059999998658895493 + 1 + + cloud_scale + + 0.3099999725818634 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.29999998211860657 + 0 + 0 + 1 + + density_multiplier + + 0.00026999998954124749 + 0 + 0 + 1 + + distance_multiplier + + 0 + 0 + 0 + 1 + + east_angle + 2.6389377117156982 + enable_cloud_scroll + + 0 + 0 + + gamma + + 0.74000000953674316 + 0 + 0 + 1 + + glow + + 5.5999994277954102 + 0.0010000000474974513 + -0.29999998211860657 + 1 + + haze_density + + 1.8899999856948853 + 0 + 0 + 1 + + haze_horizon + + 0.26999998092651367 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.44095441699028015 + 0.40274816751480103 + 0.80209296941757202 + 0 + + max_y + + 752 + 0 + 0 + 1 + + preset_num + 21 + star_brightness + 0 + sun_angle + 2.7270753383636475 + sunlight_color + + 1.4399999380111694 + 1.4399999380111694 + 1.4399999380111694 + 0.47999998927116394 + + + diff --git a/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Tan%20Skin.xml b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Tan%20Skin.xml new file mode 100644 index 000000000..3ac14b91a --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Annan%20Adored%20Tan%20Skin.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.53460693359375 + 1.2169990539550781 + 1.18414306640625 + 0.51153564453125 + + blue_density + + 1.5458984375 + 1.520721435546875 + 1.5166015625 + 0.77294921875 + + blue_horizon + + 0.5263671875 + 0.2863616943359375 + 0.2392578125 + 0.26318359375 + + cloud_color + + 0.50999999046325684 + 0.50999999046325684 + 0.50999999046325684 + 0.50999999046325684 + + cloud_pos_density1 + + 0.34999999403953552 + 0.31000000238418579 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.099999994039535522 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.35999998450279236 + 0 + 0 + 1 + + density_multiplier + + 0.0002899999963119626 + 0 + 0 + 1 + + distance_multiplier + + 0 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 0 + 0 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 20 + 0.0010000000474974513 + -2.1499998569488525 + 1 + + haze_density + + 0 + 0 + 0 + 1 + + haze_horizon + + 0.23999999463558197 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.5735776424407959 + -0.81915122270584106 + 0 + + max_y + + 560 + 0 + 0 + 1 + + preset_num + 21 + star_brightness + 0 + sun_angle + 2.5307259559631348 + sunlight_color + + 0.9609375 + 0.9609375 + 0.9609375 + 0.3203125 + + + diff --git a/indra/newview/app_settings/windlight/skies/Gwen%27s%20Light.xml b/indra/newview/app_settings/windlight/skies/Gwen%27s%20Light.xml new file mode 100644 index 000000000..beaa7bba2 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Gwen%27s%20Light.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.2274205684661865 + 1.220489501953125 + 2.107635498046875 + 0.702545166015625 + + blue_density + + 0.625 + 0.625 + 0.625 + 0.3125 + + blue_horizon + + 0.025146491825580597 + 0.099853508174419403 + 0.050827037543058395 + 0.049926754087209702 + + cloud_color + + 0.54396075010299683 + 0.1728515625 + 0.8818359375 + 0.8818359375 + + cloud_pos_density1 + + 0.70999997854232788 + 0.53047597408294678 + 0.32999998331069946 + 1 + + cloud_pos_density2 + + 0.29999998211860657 + 0.29999998211860657 + 0.25 + 1 + + cloud_scale + + 0.25999999046325684 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.069999694824219 + 9.7899999618530273 + + cloud_shadow + + 0.43999999761581421 + 0 + 0 + 1 + + density_multiplier + + 0.00069000001531094313 + 0 + 0 + 1 + + distance_multiplier + + 10 + 0 + 0 + 1 + + east_angle + 2.3876104354858398 + enable_cloud_scroll + + 1 + 1 + + gamma + + 2 + 0 + 0 + 1 + + glow + + 1.6000008583068848 + 0.0010000000474974513 + -1.1999999284744263 + 1 + + haze_density + + 0.59999996423721313 + 0 + 0 + 1 + + haze_horizon + + 0.35999998450279236 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.56918007135391235 + 0.55557030439376831 + 0.60611522197723389 + 1 + + max_y + + 1493 + 0 + 0 + 1 + + preset_num + 2 + star_brightness + 2 + sun_angle + 5.6941366195678711 + sunlight_color + + 2.1550192832946777 + 1.8917083740234375 + 2.4442291259765625 + 0.8147430419921875 + + + diff --git a/indra/newview/app_settings/windlight/skies/Oceane%27s%20Body%20Designs.xml b/indra/newview/app_settings/windlight/skies/Oceane%27s%20Body%20Designs.xml new file mode 100644 index 000000000..1fec5b8af --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Oceane%27s%20Body%20Designs.xml @@ -0,0 +1,141 @@ + + + ambient + + 2.03999996185302734375 + 1.94999992847442626953125 + 1.83000004291534423828125 + 2.03999996185302734375 + + blue_density + + 0.63999998569488525390625 + 1.17999994754791259765625 + 2 + 2 + + blue_horizon + + 0.2199999988079071044921875 + 0.2199999988079071044921875 + 0.319999992847442626953125 + 0.319999992847442626953125 + + cloud_color + + 0.2261587334555770212318748 + 0.2261587334555770212318748 + 0.2261587334555770212318748 + 0.9999848079680475620989455 + + cloud_pos_density1 + + 0.884190976619720458984375 + 0.53047597408294677734375 + 0.8800030851365363560034893 + 1 + + cloud_pos_density2 + + 0.384193003177642822265625 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.4199999868869781494140625 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49939242953405482694507 + 10.0109996795654296875 + + cloud_shadow + + 0.1599999964237213134765625 + 0 + 0 + 1 + + density_multiplier + + 0.0001799999881768599152565002 + 0 + 0 + 1 + + distance_multiplier + + 2 + 0 + 0 + 1 + + east_angle + 1.00530970096588134765625 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.2200000286102294921875 + 0 + 0 + 1 + + glow + + 5 + 0.001000000047497451305389404 + -0.449999988079071044921875 + 1 + + haze_density + + 0.680000007152557373046875 + 0 + 0 + 1 + + haze_horizon + + 0.08999999612569808959960938 + 0.1991560012102127075195312 + 0.1991560012102127075195312 + 1 + + lightnorm + + -0.8443279266357421875 + 0 + 0.535826742649078369140625 + 0 + + max_y + + 188 + 0 + 0 + 1 + + preset_num + 2 + star_brightness + 0 + sun_angle + 0 + sunlight_color + + 2.5799999237060546875 + 2.5799999237060546875 + 2.610000133514404296875 + 2.610000133514404296875 + + + diff --git a/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20clean.xml b/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20clean.xml new file mode 100644 index 000000000..82dd68d2d --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20clean.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.89999997615814209 + 0.89999997615814209 + 0.89999997615814209 + 0.29999998211860657 + + blue_density + + 0.36974793672561646 + 0.38095235824584961 + 0.39999997615814209 + 0.19999998807907104 + + blue_horizon + + 0 + 0.042857140302658081 + 0.059999998658895493 + 0.029999999329447746 + + cloud_color + + 0.039999999105930328 + 0.056000009179115295 + 0.079999998211860657 + 0.079999998211860657 + + cloud_pos_density1 + + 0.40999999642372131 + 0.23999999463558197 + 0.099999994039535522 + 1 + + cloud_pos_density2 + + 0.32999998331069946 + 0.45999997854232788 + 0.11999999731779099 + 1 + + cloud_scale + + 0.25 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.7100000381469727 + 10.590000152587891 + + cloud_shadow + + 0.35999998450279236 + 0 + 0 + 1 + + density_multiplier + + 0.00014999999257270247 + 0 + 0 + 1 + + distance_multiplier + + 0 + 0 + 0 + 1 + + east_angle + 0.9424777626991272 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.5 + 0 + 0 + 1 + + glow + + 20 + 0.0010000000474974513 + -0 + 1 + + haze_density + + 0.48999997973442078 + 0 + 0 + 1 + + haze_horizon + + 0.049999997019767761 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.30724778771400452 + 0.92507719993591309 + -0.22322858870029449 + 0 + + max_y + + 188 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 1.9603538513183594 + sunlight_color + + 0.14999999105930328 + 0.14999999105930328 + 0.14999999105930328 + 0.049999997019767761 + + + diff --git a/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20extreme.xml b/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20extreme.xml new file mode 100644 index 000000000..938d710f0 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20extreme.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.89999997615814209 + 0.89999997615814209 + 0.89999997615814209 + 0.29999998211860657 + + blue_density + + 0.36974793672561646 + 0.38095235824584961 + 0.39999997615814209 + 0.19999998807907104 + + blue_horizon + + 0 + 0.042857140302658081 + 0.059999998658895493 + 0.029999999329447746 + + cloud_color + + 0.039999999105930328 + 0.056000009179115295 + 0.079999998211860657 + 0.079999998211860657 + + cloud_pos_density1 + + 0.40999999642372131 + 0.23999999463558197 + 0.099999994039535522 + 1 + + cloud_pos_density2 + + 0.32999998331069946 + 0.45999997854232788 + 0.11999999731779099 + 1 + + cloud_scale + + 0.25 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.7100000381469727 + 10.590000152587891 + + cloud_shadow + + 0.35999998450279236 + 0 + 0 + 1 + + density_multiplier + + 0.0003499999875202775 + 0 + 0 + 1 + + distance_multiplier + + 60.0 + 0 + 0 + 1 + + east_angle + 0.9424777626991272 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.5 + 0 + 0 + 1 + + glow + + 20 + 0.0010000000474974513 + -0 + 1 + + haze_density + + 0.48999997973442078 + 0 + 0 + 1 + + haze_horizon + + 0.049999997019767761 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.30724778771400452 + 0.92507719993591309 + -0.22322858870029449 + 0 + + max_y + + 188 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 1.9603538513183594 + sunlight_color + + 0.14999999105930328 + 0.14999999105930328 + 0.14999999105930328 + 0.049999997019767761 + + + diff --git a/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20hard.xml b/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20hard.xml new file mode 100644 index 000000000..f41ede37f --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20hard.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.89999997615814209 + 0.89999997615814209 + 0.89999997615814209 + 0.29999998211860657 + + blue_density + + 0.36974793672561646 + 0.38095235824584961 + 0.39999997615814209 + 0.19999998807907104 + + blue_horizon + + 0 + 0.042857140302658081 + 0.059999998658895493 + 0.029999999329447746 + + cloud_color + + 0.039999999105930328 + 0.056000009179115295 + 0.079999998211860657 + 0.079999998211860657 + + cloud_pos_density1 + + 0.40999999642372131 + 0.23999999463558197 + 0.099999994039535522 + 1 + + cloud_pos_density2 + + 0.32999998331069946 + 0.45999997854232788 + 0.11999999731779099 + 1 + + cloud_scale + + 0.25 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.7100000381469727 + 10.590000152587891 + + cloud_shadow + + 0.35999998450279236 + 0 + 0 + 1 + + density_multiplier + + 0.00025000001187436283 + 0 + 0 + 1 + + distance_multiplier + + 40.0 + 0 + 0 + 1 + + east_angle + 0.9424777626991272 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.5 + 0 + 0 + 1 + + glow + + 20 + 0.0010000000474974513 + -0 + 1 + + haze_density + + 0.48999997973442078 + 0 + 0 + 1 + + haze_horizon + + 0.049999997019767761 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.30724778771400452 + 0.92507719993591309 + -0.22322858870029449 + 0 + + max_y + + 188 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 1.9603538513183594 + sunlight_color + + 0.14999999105930328 + 0.14999999105930328 + 0.14999999105930328 + 0.049999997019767761 + + + diff --git a/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20soft.xml b/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20soft.xml new file mode 100644 index 000000000..d15c8d009 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/Tron%20Legacy%20soft.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.89999997615814209 + 0.89999997615814209 + 0.89999997615814209 + 0.29999998211860657 + + blue_density + + 0.36974793672561646 + 0.38095235824584961 + 0.39999997615814209 + 0.19999998807907104 + + blue_horizon + + 0 + 0.042857140302658081 + 0.059999998658895493 + 0.029999999329447746 + + cloud_color + + 0.039999999105930328 + 0.056000009179115295 + 0.079999998211860657 + 0.079999998211860657 + + cloud_pos_density1 + + 0.40999999642372131 + 0.23999999463558197 + 0.099999994039535522 + 1 + + cloud_pos_density2 + + 0.32999998331069946 + 0.45999997854232788 + 0.11999999731779099 + 1 + + cloud_scale + + 0.25 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.7100000381469727 + 10.590000152587891 + + cloud_shadow + + 0.35999998450279236 + 0 + 0 + 1 + + density_multiplier + + 0.00014999999257270247 + 0 + 0 + 1 + + distance_multiplier + + 20.0 + 0 + 0 + 1 + + east_angle + 0.9424777626991272 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.5 + 0 + 0 + 1 + + glow + + 20 + 0.0010000000474974513 + -0 + 1 + + haze_density + + 0.48999997973442078 + 0 + 0 + 1 + + haze_horizon + + 0.049999997019767761 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.30724778771400452 + 0.92507719993591309 + -0.22322858870029449 + 0 + + max_y + + 188 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 1.9603538513183594 + sunlight_color + + 0.14999999105930328 + 0.14999999105930328 + 0.14999999105930328 + 0.049999997019767761 + + + diff --git a/indra/newview/app_settings/windlight/skies/wastelands.xml b/indra/newview/app_settings/windlight/skies/wastelands.xml index 313111fbb..33ae9e562 100644 --- a/indra/newview/app_settings/windlight/skies/wastelands.xml +++ b/indra/newview/app_settings/windlight/skies/wastelands.xml @@ -2,7 +2,7 @@ ambient - 0.29999998211860657 + 0.29999998211860657 0.17999999225139618 0 0.29999998211860657 diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index 2d490f8e8..f937571c3 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -86,11 +86,18 @@ LLPrefsAscentChat::LLPrefsAscentChat() LLUUID itemid = (LLUUID)gSavedPerAccountSettings.getString("AscentInstantMessageResponseItemData"); LLViewerInventoryItem* item = gInventory.getItem(itemid); - if (item) childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlySetTo") + LLTrans::getString(":") + " " +item->getName()); - else if (itemid.isNull()) childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlyNotSet")); - else childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlySetTo") + " " + LLTrans::getString("AnItemNotOnThisAccount")); + if (item) + { + LLStringUtil::format_map_t args; + args["[ITEM]"] = item->getName(); + childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlySetTo", args)); + } + else if (itemid.isNull()) + childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlyNotSet")); + else + childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlySetToAnItemNotOnThisAccount")); } - else childSetValue("im_give_disp_rect_txt", LLTrans::getString("NotLoggedIn")); + else childSetValue("im_give_disp_rect_txt", LLTrans::getString("NotLoggedIn")); childSetCommitCallback("im_response", onCommitAutoResponse, this); @@ -98,6 +105,7 @@ LLPrefsAscentChat::LLPrefsAscentChat() childSetCommitCallback("reset_antispam", onCommitResetAS, this); childSetCommitCallback("enable_as", onCommitEnableAS, this); childSetCommitCallback("antispam_checkbox", onCommitDialogBlock, this); + childSetCommitCallback("Group Invites", onCommitDialogBlock, this); childSetCommitCallback("KeywordsOn", onCommitKeywords, this); childSetCommitCallback("KeywordsList", onCommitKeywords, this); @@ -242,7 +250,9 @@ void LLPrefsAscentChat::onCommitAutoResponse(LLUICtrl* ctrl, void* user_data) void LLPrefsAscentChat::SinguIMResponseItemDrop(LLViewerInventoryItem* item) { gSavedPerAccountSettings.setString("AscentInstantMessageResponseItemData", item->getUUID().asString()); - sInst->childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlySetTo") + LLTrans::getString(":") + " " +item->getName()); + LLStringUtil::format_map_t args; + args["[ITEM]"] = item->getName(); + sInst->childSetValue("im_give_disp_rect_txt", LLTrans::getString("CurrentlySetTo", args)); } //static @@ -269,15 +279,19 @@ void LLPrefsAscentChat::onCommitEnableAS(LLUICtrl* ctrl, void* user_data) void LLPrefsAscentChat::onCommitDialogBlock(LLUICtrl* ctrl, void* user_data) { LLPrefsAscentChat* self = (LLPrefsAscentChat*)user_data; + self->childSetEnabled("Group Fee Invites", !self->childGetValue("antispam_checkbox").asBoolean() && !self->childGetValue("Group Invites").asBoolean()); bool enabled = ctrl->getValue().asBoolean(); - self->childSetEnabled("Block All Dialogs From", !enabled); - self->childSetEnabled("Alerts", !enabled); - self->childSetEnabled("Friendship Offers", !enabled); - self->childSetEnabled("Group Invites", !enabled); - self->childSetEnabled("Group Notices", !enabled); - self->childSetEnabled("Item Offers", !enabled); - self->childSetEnabled("Scripts", !enabled); - self->childSetEnabled("Teleport Offers", !enabled); + if (ctrl->getName() == "antispam_checkbox") + { + self->childSetEnabled("Block All Dialogs From", !enabled); + self->childSetEnabled("Alerts", !enabled); + self->childSetEnabled("Friendship Offers", !enabled); + self->childSetEnabled("Group Invites", !enabled); + self->childSetEnabled("Group Notices", !enabled); + self->childSetEnabled("Item Offers", !enabled); + self->childSetEnabled("Scripts", !enabled); + self->childSetEnabled("Teleport Offers", !enabled); + } } //static @@ -434,6 +448,7 @@ void LLPrefsAscentChat::refresh() childSetEnabled("Alerts", !mBlockDialogSpam); childSetEnabled("Friendship Offers", !mBlockDialogSpam); childSetEnabled("Group Invites", !mBlockDialogSpam); + childSetEnabled("Group Fee Invites", !mBlockDialogSpam && !mBlockGroupInviteSpam); childSetEnabled("Group Notices", !mBlockDialogSpam); childSetEnabled("Item Offers", !mBlockDialogSpam); childSetEnabled("Scripts", !mBlockDialogSpam); diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index 64f423dec..8b90011f2 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -103,11 +103,18 @@ LLPrefsAscentSys::LLPrefsAscentSys() LLUUID itemid = (LLUUID)gSavedPerAccountSettings.getString("EmeraldBuildPrefs_Item"); LLViewerInventoryItem* item = gInventory.getItem(itemid); - if (item) childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlySetTo") + LLTrans::getString(":") + "\n" +item->getName()); - else if (itemid.isNull()) childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlyNotSet")); - else childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlySetTo") + "\n" + LLTrans::getString("AnItemNotOnThisAccount")); + if (item) + { + LLStringUtil::format_map_t args; + args["[ITEM]"] = item->getName(); + childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlySetTo", args)); + } + else if (itemid.isNull()) + childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlyNotSet")); + else + childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlySetToAnItemNotOnThisAccount")); } - else childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("NotLoggedIn")); + else childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("NotLoggedIn")); refreshValues(); refresh(); @@ -245,10 +252,13 @@ void LLPrefsAscentSys::onCommitTexturePicker(LLUICtrl* ctrl, void* userdata) if(image_ctrl) gSavedSettings.setString("EmeraldBuildPrefs_Texture", image_ctrl->getImageAssetID().asString()); } +//static void LLPrefsAscentSys::SinguBuildItemDrop(LLViewerInventoryItem* item) { gSavedPerAccountSettings.setString("EmeraldBuildPrefs_Item", item->getUUID().asString()); - sInst->childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlySetTo") + LLTrans::getString(":") + "\n" + item->getName()); + LLStringUtil::format_map_t args; + args["[ITEM]"] = item->getName(); + sInst->childSetValue("build_item_add_disp_rect_txt", LLTrans::getString("CurrentlySetTo", args)); } void LLPrefsAscentSys::refreshValues() diff --git a/indra/newview/build_win32_appConfig.py b/indra/newview/build_win32_appConfig.py index 44b63afce..cb1df6580 100644 --- a/indra/newview/build_win32_appConfig.py +++ b/indra/newview/build_win32_appConfig.py @@ -2,9 +2,9 @@ # @brief Create the windows app.config file to redirect crt linkage. # # $LicenseInfo:firstyear=2009&license=viewergpl$ -# +# # Copyright (c) 2009, Linden Research, Inc. -# +# # Second Life Viewer Source Code # The source code in this file ("Source Code") is provided by Linden Lab # to you under the terms of the GNU General Public License, version 2.0 @@ -12,17 +12,17 @@ # ("Other License"), formally executed by you and Linden Lab. Terms of # the GPL can be found in doc/GPL-license.txt in this distribution, or # online at http://secondlifegrid.net/programs/open_source/licensing/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 doc/FLOSS-exception.txt in this software distribution, or # online at # http://secondlifegrid.net/programs/open_source/licensing/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. @@ -35,23 +35,23 @@ def main(): src_manifest_name = sys.argv[1] src_config_name = sys.argv[2] dst_config_name = sys.argv[3] - + manifest_dom = parse(src_manifest_name) node = manifest_dom.getElementsByTagName('assemblyIdentity')[0] manifest_assm_ver = node.getAttribute('version') - + config_dom = parse(src_config_name) node = config_dom.getElementsByTagName('bindingRedirect')[0] node.setAttribute('newVersion', manifest_assm_ver) - src_old_ver=re.match('([^-]*-).*', node.getAttribute('oldVersion')).group(1) + src_old_ver=re.match('([^-]*-).*', node.getAttribute('oldVersion')).group(1) node.setAttribute('oldVersion', src_old_ver + manifest_assm_ver) comment = config_dom.createComment("This file is automatically generated by the build. see indra/newview/build_win32_appConfig.py") config_dom.insertBefore(comment, config_dom.childNodes[0]) - + f = open(dst_config_name, 'w') config_dom.writexml(f) f.close() - + return 0 if __name__ == "__main__": diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index a0051de59..5f416241c 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -210,7 +210,24 @@ bool stort_calls(const std::pair& left, const std::pair sAscentCmdLine(gSavedSettings, "AscentCmdLine"); + static LLCachedControl sAscentCmdLinePos(gSavedSettings, "AscentCmdLinePos"); + static LLCachedControl sAscentCmdLineDrawDistance(gSavedSettings, "AscentCmdLineDrawDistance"); + static LLCachedControl sAscentCmdTeleportToCam(gSavedSettings, "AscentCmdTeleportToCam"); + static LLCachedControl sAscentCmdLineKeyToName(gSavedSettings, "AscentCmdLineKeyToName"); + static LLCachedControl sAscentCmdLineOfferTp(gSavedSettings, "AscentCmdLineOfferTp"); + static LLCachedControl sAscentCmdLineGround(gSavedSettings, "AscentCmdLineGround"); + static LLCachedControl sAscentCmdLineHeight(gSavedSettings, "AscentCmdLineHeight"); + static LLCachedControl sAscentCmdLineTeleportHome(gSavedSettings, "AscentCmdLineTeleportHome"); + static LLCachedControl sAscentCmdLineRezPlatform(gSavedSettings, "AscentCmdLineRezPlatform"); + static LLCachedControl sAscentCmdLineMapTo(gSavedSettings, "AscentCmdLineMapTo"); + static LLCachedControl sAscentCmdLineMapToKeepPos(gSavedSettings, "AscentMapToKeepPos"); + static LLCachedControl sAscentCmdLineCalc(gSavedSettings, "AscentCmdLineCalc"); + static LLCachedControl sAscentCmdLineTP2(gSavedSettings, "AscentCmdLineTP2"); + static LLCachedControl sSinguCmdLineClearChat(gSavedSettings, "SinguCmdLineAway"); + static LLCachedControl sAscentCmdLineClearChat(gSavedSettings, "AscentCmdLineClearChat"); + + if(sAscentCmdLine) { std::istringstream i(revised_text); std::string command; @@ -218,7 +235,7 @@ bool cmd_line_chat(std::string revised_text, EChatType type) command = utf8str_tolower(command); if(command != "") { - if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLinePos"))) + if(command == utf8str_tolower(sAscentCmdLinePos)) { F32 x,y,z; if (i >> x) @@ -241,74 +258,73 @@ bool cmd_line_chat(std::string revised_text, EChatType type) } } } - else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineDrawDistance"))) + else if(command == utf8str_tolower(sAscentCmdLineDrawDistance)) { - int drawDist; - if(i >> drawDist) - { - gSavedSettings.setF32("RenderFarClip", drawDist); - gAgentCamera.mDrawDistance=drawDist; - char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ - snprintf(buffer,sizeof(buffer),"Draw distance set to: %dm",drawDist); + int drawDist; + if(i >> drawDist) + { + gSavedSettings.setF32("RenderFarClip", drawDist); + gAgentCamera.mDrawDistance=drawDist; + char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ + snprintf(buffer,sizeof(buffer),"Draw distance set to: %dm",drawDist); cmdline_printchat(std::string(buffer)); return false; - } + } } - else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdTeleportToCam"))) - { + else if(command == utf8str_tolower(sAscentCmdTeleportToCam)) + { gAgent.teleportViaLocation(gAgentCamera.getCameraPositionGlobal()); return false; - } - else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineKeyToName"))) - { - LLUUID targetKey; - if(i >> targetKey) - { - std::string object_name; - gCacheName->getFullName(targetKey, object_name); - char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ - snprintf(buffer,sizeof(buffer),"%s: (%s)",targetKey.asString().c_str(), object_name.c_str()); + } + else if(command == utf8str_tolower(sAscentCmdLineKeyToName)) + { + LLUUID targetKey; + if(i >> targetKey) + { + std::string object_name; + gCacheName->getFullName(targetKey, object_name); + char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ + snprintf(buffer,sizeof(buffer),"%s: (%s)",targetKey.asString().c_str(), object_name.c_str()); cmdline_printchat(std::string(buffer)); - } + } return false; - } - else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineOfferTp"))) - { - std::string avatarKey; + } + else if(command == utf8str_tolower(sAscentCmdLineOfferTp)) + { + std::string avatarKey; // llinfos << "CMD DEBUG 0 " << command << " " << avatarName << llendl; - if(i >> avatarKey) - { + if(i >> avatarKey) + { // llinfos << "CMD DEBUG 0 afterif " << command << " " << avatarName << llendl; - LLUUID tempUUID; - if(LLUUID::parseUUID(avatarKey, &tempUUID)) - { - char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ - LLDynamicArray ids; - ids.push_back(tempUUID); - std::string tpMsg="Join me!"; - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_StartLure); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_Info); - msg->addU8Fast(_PREHASH_LureType, (U8)0); + LLUUID tempUUID; + if(LLUUID::parseUUID(avatarKey, &tempUUID)) + { + char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ + LLDynamicArray ids; + ids.push_back(tempUUID); + std::string tpMsg="Join me!"; + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_StartLure); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_Info); + msg->addU8Fast(_PREHASH_LureType, (U8)0); - msg->addStringFast(_PREHASH_Message, tpMsg); - for(LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) - { - msg->nextBlockFast(_PREHASH_TargetData); - msg->addUUIDFast(_PREHASH_TargetID, *itr); - } - gAgent.sendReliableMessage(); - snprintf(buffer,sizeof(buffer),"Offered TP to key %s",tempUUID.asString().c_str()); + msg->addStringFast(_PREHASH_Message, tpMsg); + for(LLDynamicArray::iterator itr = ids.begin(); itr != ids.end(); ++itr) + { + msg->nextBlockFast(_PREHASH_TargetData); + msg->addUUIDFast(_PREHASH_TargetID, *itr); + } + gAgent.sendReliableMessage(); + snprintf(buffer,sizeof(buffer),"Offered TP to key %s",tempUUID.asString().c_str()); cmdline_printchat(std::string(buffer)); return false; - } - } - } - - else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineGround"))) + } + } + } + else if(command == utf8str_tolower(sAscentCmdLineGround)) { LLVector3 agentPos = gAgent.getPositionAgent(); U64 agentRegion = gAgent.getRegion()->getHandle(); @@ -317,7 +333,8 @@ bool cmd_line_chat(std::string revised_text, EChatType type) pos_global += LLVector3d((F64)targetPos.mV[0],(F64)targetPos.mV[1],(F64)targetPos.mV[2]); gAgent.teleportViaLocation(pos_global); return false; - }else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineHeight"))) + } + else if(command == utf8str_tolower(sAscentCmdLineHeight)) { F32 z; if(i >> z) @@ -330,17 +347,20 @@ bool cmd_line_chat(std::string revised_text, EChatType type) gAgent.teleportViaLocation(pos_global); return false; } - }else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineTeleportHome"))) + } + else if(command == utf8str_tolower(sAscentCmdLineTeleportHome)) { gAgent.teleportHome(); return false; - }else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineRezPlatform"))) - { + } + else if(command == utf8str_tolower(sAscentCmdLineRezPlatform)) + { F32 width; if (i >> width) cmdline_rezplat(false, width); else cmdline_rezplat(); return false; - }else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineMapTo"))) + } + else if(command == utf8str_tolower(sAscentCmdLineMapTo)) { if (revised_text.length() > command.length() + 1) //Typing this command with no argument was causing a crash. -Madgeek { @@ -351,7 +371,7 @@ bool cmd_line_chat(std::string revised_text, EChatType type) std::string region_name = LLWeb::escapeURL(revised_text.substr(command.length()+1)); std::string url; - if(!gSavedSettings.getBOOL("AscentMapToKeepPos")) + if(!sAscentCmdLineMapToKeepPos) { agent_x = 128; agent_y = 128; @@ -362,7 +382,8 @@ bool cmd_line_chat(std::string revised_text, EChatType type) LLURLDispatcher::dispatch(url, NULL, true); } return false; - }else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineCalc")))//Cryogenic Blitz + } + else if(command == utf8str_tolower(sAscentCmdLineCalc))//Cryogenic Blitz { bool success; F32 result = 0.f; @@ -391,7 +412,8 @@ bool cmd_line_chat(std::string revised_text, EChatType type) cmdline_printchat(out); return false; } - }else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineTP2"))) + } + else if(command == utf8str_tolower(sAscentCmdLineTP2)) { if (revised_text.length() > command.length() + 1) //Typing this command with no argument was causing a crash. -Madgeek { @@ -399,11 +421,13 @@ bool cmd_line_chat(std::string revised_text, EChatType type) cmdline_tp2name(name); } return false; - }else if(command == utf8str_tolower(gSavedSettings.getString("SinguCmdLineAway"))) + } + else if(command == utf8str_tolower(sSinguCmdLineClearChat)) { handle_fake_away_status(NULL); return false; - }else if(command == "typingstop") + } + else if(command == "typingstop") { std::string text; if(i >> text) @@ -411,7 +435,7 @@ bool cmd_line_chat(std::string revised_text, EChatType type) gChatBar->sendChatFromViewer(text, CHAT_TYPE_STOP, FALSE); } } - else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineClearChat"))) + else if(command == utf8str_tolower(sAscentCmdLineClearChat)) { LLFloaterChat* chat = LLFloaterChat::getInstance(LLSD()); if(chat) @@ -422,7 +446,8 @@ bool cmd_line_chat(std::string revised_text, EChatType type) history_editor_with_mute->clear(); return false; } - }else if(command == "invrepair") + } + else if(command == "invrepair") { invrepair(); } @@ -513,55 +538,61 @@ void cmdline_tp2name(std::string target) void cmdline_rezplat(bool use_saved_value, F32 visual_radius) //cmdline_rezplat() will still work... just will use the saved value { - LLVector3 agentPos = gAgent.getPositionAgent()+(gAgent.getVelocity()*(F32)0.333); - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ObjectAdd); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU8Fast(_PREHASH_PCode, LL_PCODE_VOLUME); - msg->addU8Fast(_PREHASH_Material, LL_MCODE_METAL); + LLVector3 agentPos = gAgent.getPositionAgent()+(gAgent.getVelocity()*(F32)0.333); + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ObjectAdd); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU8Fast(_PREHASH_PCode, LL_PCODE_VOLUME); + msg->addU8Fast(_PREHASH_Material, LL_MCODE_METAL); - if(agentPos.mV[2] > 4096.0)msg->addU32Fast(_PREHASH_AddFlags, FLAGS_CREATE_SELECTED); - else msg->addU32Fast(_PREHASH_AddFlags, 0); + if(agentPos.mV[2] > 4096.0) + msg->addU32Fast(_PREHASH_AddFlags, FLAGS_CREATE_SELECTED); + else + msg->addU32Fast(_PREHASH_AddFlags, 0); - LLVolumeParams volume_params; + LLVolumeParams volume_params; - volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE_33 ); - volume_params.setRatio ( 2, 2 ); - volume_params.setShear ( 0, 0 ); - volume_params.setTaper(2.0f,2.0f); - volume_params.setTaperX(0.f); - volume_params.setTaperY(0.f); + volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE_33 ); + volume_params.setRatio( 2, 2 ); + volume_params.setShear( 0, 0 ); + volume_params.setTaper(2.0f,2.0f); + volume_params.setTaperX(0.f); + volume_params.setTaperY(0.f); - LLVolumeMessage::packVolumeParams(&volume_params, msg); - LLVector3 rezpos = agentPos - LLVector3(0.0f,0.0f,2.5f); - LLQuaternion rotation; - rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); + LLVolumeMessage::packVolumeParams(&volume_params, msg); + LLVector3 rezpos = agentPos - LLVector3(0.0f,0.0f,2.5f); + LLQuaternion rotation; + rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); + + if (use_saved_value) + { + visual_radius = gSavedSettings.getF32("AscentPlatformSize"); + } - if (use_saved_value) visual_radius = gSavedSettings.getF32("AscentPlatformSize"); F32 realsize = visual_radius / 3.0f; if (realsize < 0.01f) realsize = 0.01f; else if (realsize > 10.0f) realsize = 10.0f; - msg->addVector3Fast(_PREHASH_Scale, LLVector3(0.01f,realsize,realsize) ); - msg->addQuatFast(_PREHASH_Rotation, rotation ); - msg->addVector3Fast(_PREHASH_RayStart, rezpos ); - msg->addVector3Fast(_PREHASH_RayEnd, rezpos ); - msg->addU8Fast(_PREHASH_BypassRaycast, (U8)1 ); - msg->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE ); - msg->addU8Fast(_PREHASH_State, 0); - msg->addUUIDFast(_PREHASH_RayTargetID, LLUUID::null ); - msg->sendReliable(gAgent.getRegionHost()); + msg->addVector3Fast(_PREHASH_Scale, LLVector3(0.01f,realsize,realsize) ); + msg->addQuatFast(_PREHASH_Rotation, rotation ); + msg->addVector3Fast(_PREHASH_RayStart, rezpos ); + msg->addVector3Fast(_PREHASH_RayEnd, rezpos ); + msg->addU8Fast(_PREHASH_BypassRaycast, (U8)1 ); + msg->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE ); + msg->addU8Fast(_PREHASH_State, 0); + msg->addUUIDFast(_PREHASH_RayTargetID, LLUUID::null ); + msg->sendReliable(gAgent.getRegionHost()); } void cmdline_printchat(std::string message) { - LLChat chat; - chat.mText = message; + LLChat chat; + chat.mText = message; chat.mSourceType = CHAT_SOURCE_SYSTEM; - LLFloaterChat::addChat(chat, FALSE, FALSE); + LLFloaterChat::addChat(chat, FALSE, FALSE); } diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif new file mode 100644 index 000000000..ba6f30fa0 Binary files /dev/null and b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif differ diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tif new file mode 100644 index 000000000..830d5692f Binary files /dev/null and b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tif differ diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tif new file mode 100644 index 000000000..e05284214 Binary files /dev/null and b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tif differ diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tif new file mode 100644 index 000000000..c4822adf6 Binary files /dev/null and b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tif differ diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif new file mode 100644 index 000000000..5166af6e0 Binary files /dev/null and b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif differ diff --git a/indra/newview/floaterao.cpp b/indra/newview/floaterao.cpp index ec3fac0e5..f7bdf090f 100644 --- a/indra/newview/floaterao.cpp +++ b/indra/newview/floaterao.cpp @@ -331,7 +331,9 @@ BOOL LLFloaterAO::postBuild() LLViewerInventoryItem* itemimport = gInventory.getItem(itemidimport); if(itemimport) { - childSetValue("ao_nc_text", LLTrans::getString("CurrentlySetTo") + LLTrans::getString(":") + " " +itemimport->getName()); + LLStringUtil::format_map_t args; + args["[ITEM]"] = itemimport->getName(); + childSetValue("ao_nc_text", LLTrans::getString("CurrentlySetTo", args)); } else if(itemidimport.isNull()) { @@ -339,7 +341,7 @@ BOOL LLFloaterAO::postBuild() } else { - childSetValue("ao_nc_text", LLTrans::getString("CurrentlySetTo") + " " + LLTrans::getString("AnItemNotOnThisAccount")); + childSetValue("ao_nc_text", LLTrans::getString("CurrentlySetToAnItemNotOnThisAccount")); } } else @@ -795,7 +797,9 @@ void LLFloaterAO::setCurrentStandId(const LLUUID& id) void LLFloaterAO::AOItemDrop(LLViewerInventoryItem* item) { gSavedPerAccountSettings.setString("AOConfigNotecardID", item->getUUID().asString()); - sInstance->childSetValue("ao_nc_text", LLTrans::getString("CurrentlySetTo") + LLTrans::getString(":") + " " +item->getName()); + LLStringUtil::format_map_t args; + args["[ITEM]"] = item->getName(); + sInstance->childSetValue("ao_nc_text", LLTrans::getString("CurrentlySetTo", args)); } LLUUID LLFloaterAO::GetAnimID(const LLUUID& id) diff --git a/indra/newview/linux_tools/handle_secondlifeprotocol.sh b/indra/newview/linux_tools/handle_secondlifeprotocol.sh index b7314ad64..4ff3e2637 100755 --- a/indra/newview/linux_tools/handle_secondlifeprotocol.sh +++ b/indra/newview/linux_tools/handle_secondlifeprotocol.sh @@ -13,5 +13,5 @@ fi RUN_PATH=`dirname "$0" || echo .` cd "${RUN_PATH}" -exec ./snowglobe -url \'"${URL}"\' +exec ./singularity -url \'"${URL}"\' diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 30415e458..4cb74f011 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1845,13 +1845,6 @@ U8 LLAgent::getRenderState() //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -static const LLFloaterView::skip_list_t& get_skip_list() -{ - static LLFloaterView::skip_list_t skip_list; - skip_list.insert(LLFloaterMap::getInstance()); - return skip_list; -} - //----------------------------------------------------------------------------- // endAnimationUpdateUI() //----------------------------------------------------------------------------- @@ -1884,8 +1877,11 @@ void LLAgent::endAnimationUpdateUI() // Only pop if we have pushed... if (TRUE == mViewsPushed) { + LLFloaterView::skip_list_t skip_list; + skip_list.insert(LLFloaterMap::getInstance()); + + gFloaterView->popVisibleAll(skip_list); mViewsPushed = FALSE; - gFloaterView->popVisibleAll(get_skip_list()); } gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); @@ -1962,6 +1958,7 @@ void LLAgent::endAnimationUpdateUI() // hide menus gMenuBarView->setVisible(FALSE); gStatusBar->setVisibleForMouselook(false); + LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(FALSE); // clear out camera lag effect @@ -1978,7 +1975,12 @@ void LLAgent::endAnimationUpdateUI() { (*mMouselookModeInSignal)(); } - gFloaterView->pushVisibleAll(FALSE, get_skip_list()); + + // hide all floaters except the mini map + + LLFloaterView::skip_list_t skip_list; + skip_list.insert(LLFloaterMap::getInstance()); + gFloaterView->pushVisibleAll(FALSE, skip_list); if( gMorphView ) { @@ -3488,9 +3490,9 @@ bool LLAgent::teleportCore(bool is_local) // yet if the teleport will succeed. Look in // process_teleport_location_reply - // close the map and find panels so we can see our destination + // close the map panel so we can see our destination. + // we don't close search floater, see EXT-5840. LLFloaterWorldMap::hide(NULL); - LLFloaterDirectory::hide(NULL); // hide land floater too - it'll be out of date LLFloaterLand::hideInstance(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5913aae9c..af0e54551 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -51,7 +51,7 @@ #include "llagentwearables.h" #include "llwindow.h" #include "llviewerstats.h" -//#include "llmarketplacefunctions.h" +#include "llmarketplacefunctions.h" #include "llmarketplacenotifications.h" #include "llmd5.h" #include "llmeshrepository.h" @@ -318,10 +318,10 @@ BOOL gLogoutInProgress = FALSE; // Internal globals... that should be removed. static std::string gArgs; -const std::string MARKER_FILE_NAME("SecondLife.exec_marker"); -const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker"); -const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker"); -const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker"); +const std::string MARKER_FILE_NAME("Singularity.exec_marker"); +const std::string ERROR_MARKER_FILE_NAME("Singularity.error_marker"); +const std::string LLERROR_MARKER_FILE_NAME("Singularity.llerror_marker"); +const std::string LOGOUT_MARKER_FILE_NAME("Singularity.logout_marker"); static BOOL gDoDisconnect = FALSE; // //static BOOL gBusyDisconnect = FALSE; @@ -1033,6 +1033,8 @@ void LLAppViewer::checkMemory() static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages"); static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep"); +static LLFastTimer::DeclareTimer FTM_YIELD("Yield"); + static LLFastTimer::DeclareTimer FTM_TEXTURE_CACHE("Texture Cache"); static LLFastTimer::DeclareTimer FTM_DECODE("Image Decode"); static LLFastTimer::DeclareTimer FTM_VFS("VFS Thread"); @@ -1100,7 +1102,7 @@ bool LLAppViewer::mainLoop() LLFastTimer t2(FTM_MESSAGES); gViewerWindow->getWindow()->processMiscNativeEvents(); } - + pingMainloopTimeout("Main:GatherInput"); if (gViewerWindow) @@ -1223,6 +1225,7 @@ bool LLAppViewer::mainLoop() // yield some time to the os based on command line option if(mYieldTime >= 0) { + LLFastTimer t(FTM_YIELD); ms_sleep(mYieldTime); } @@ -1887,15 +1890,15 @@ bool LLAppViewer::initLogging() // Remove the last ".old" log file. std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - "SecondLife.old"); + "Singularity.old"); LLFile::remove(old_log_file); // Rename current log file to ".old" std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - "SecondLife.log"); + "Singularity.log"); LLFile::rename(log_file, old_log_file); - // Set the log file to SecondLife.log + // Set the log file to Singularity.log LLError::logToFile(log_file); @@ -2949,10 +2952,10 @@ void LLAppViewer::initMarkerFile() LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL; //We've got 4 things to test for here - // - Other Process Running (SecondLife.exec_marker present, locked) - // - Freeze (SecondLife.exec_marker present, not locked) - // - LLError Crash (SecondLife.llerror_marker present) - // - Other Crash (SecondLife.error_marker present) + // - Other Process Running (Singularity.exec_marker present, locked) + // - Freeze (Singularity.exec_marker present, not locked) + // - LLError Crash (Singularity.llerror_marker present) + // - Other Crash (Singularity.error_marker present) // These checks should also remove these files for the last 2 cases if they currently exist //LLError/Error checks. Only one of these should ever happen at a time. @@ -4118,7 +4121,7 @@ void LLAppViewer::idle() LLViewerMediaFocus::getInstance()->update(); // Update marketplace - //LLMarketplaceInventoryImporter::update(); + LLMarketplaceInventoryImporter::update(); LLMarketplaceInventoryNotifications::update(); // objects and camera should be in sync, do LOD calculations now diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 3e818faa4..e74bacaa8 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -99,7 +99,6 @@ S32 AVATAR_OFFSET_TEX0 = 32; S32 AVATAR_OFFSET_TEX1 = 40; S32 AVATAR_VERTEX_BYTES = 48; - BOOL gAvatarEmbossBumpMap = FALSE; static BOOL sRenderingSkinned = FALSE; S32 normal_channel = -1; @@ -1040,9 +1039,12 @@ void LLDrawPoolAvatar::endDeferredSkinned() gGL.getTexUnit(0)->activate(); } +static LLFastTimer::DeclareTimer FTM_RENDER_AVATARS("renderAvatars"); void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) { + LLFastTimer t(FTM_RENDER_AVATARS); + if (pass == -1) { for (S32 i = 1; i < getNumPasses(); i++) @@ -1546,8 +1548,12 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar) renderRigged(avatar, RIGGED_DEFERRED_BUMP); } +static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO"); + void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) { + LLFastTimer t(FTM_RIGGED_VBO); + //update rigged vertex buffers for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type) { diff --git a/indra/newview/llfloateravatarinfo.h b/indra/newview/llfloateravatarinfo.h index 6e608e9e4..4df618d5e 100644 --- a/indra/newview/llfloateravatarinfo.h +++ b/indra/newview/llfloateravatarinfo.h @@ -47,7 +47,6 @@ class LLAvatarName; class LLButton; class LLCheckBoxCtrl; -class LLDropTarget; class LLInventoryItem; class LLLineEditor; class LLMessageSystem; diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 6d25b887c..c214f3480 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -84,54 +84,55 @@ typedef enum e_radar_alert_type void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool entering) { static LLCachedControl radar_chat_alerts(gSavedSettings, "RadarChatAlerts"); + if (!radar_chat_alerts) return; static LLCachedControl radar_alert_sim(gSavedSettings, "RadarAlertSim"); static LLCachedControl radar_alert_draw(gSavedSettings, "RadarAlertDraw"); static LLCachedControl radar_alert_shout_range(gSavedSettings, "RadarAlertShoutRange"); static LLCachedControl radar_alert_chat_range(gSavedSettings, "RadarAlertChatRange"); static LLCachedControl radar_chat_keys(gSavedSettings, "RadarChatKeys"); - if (radar_chat_alerts) + LLFloaterAvatarList* self = LLFloaterAvatarList::getInstance(); + LLStringUtil::format_map_t args; + switch(type) { + case ALERT_TYPE_SIM: + if (radar_alert_sim) + { + args["[RANGE]"] = self->getString("the_sim"); + } + break; + + case ALERT_TYPE_DRAW: + if (radar_alert_draw) + { + args["[RANGE]"] = self->getString("draw_distance"); + } + break; + + case ALERT_TYPE_SHOUTRANGE: + if (radar_alert_shout_range) + { + args["[RANGE]"] = self->getString("shout_range"); + } + break; + + case ALERT_TYPE_CHATRANGE: + if (radar_alert_chat_range) + { + args["[RANGE]"] = self->getString("chat_range"); + } + break; + } + if (args.find("[RANGE]") != args.end()) + { + args["[NAME]"] = name; + args["[ACTION]"] = self->getString(entering ? "has_entered" : "has_left"); LLChat chat; - LLFloaterAvatarList* self = LLFloaterAvatarList::getInstance(); - std::string message = name + " " + self->getString(entering ? "has_entered" : "has_left") + " "; - switch(type) - { - case ALERT_TYPE_SIM: - if (radar_alert_sim) - { - chat.mText = message + self->getString("the_sim") + "."; - } - break; - - case ALERT_TYPE_DRAW: - if (radar_alert_draw) - { - chat.mText = message + self->getString("draw_distance") + "."; - } - break; - - case ALERT_TYPE_SHOUTRANGE: - if (radar_alert_shout_range) - { - chat.mText = message + self->getString("shout_range") + "."; - } - break; - - case ALERT_TYPE_CHATRANGE: - if (radar_alert_chat_range) - { - chat.mText = message + self->getString("chat_range") + "."; - } - break; - } - if (chat.mText != "") - { - chat.mFromName = name; - chat.mURL = llformat("secondlife:///app/agent/%s/about",key.asString().c_str()); - chat.mSourceType = CHAT_SOURCE_SYSTEM; - LLFloaterChat::addChat(chat); - } + chat.mText = self->getString("template", args); + chat.mFromName = name; + chat.mURL = llformat("secondlife:///app/agent/%s/about",key.asString().c_str()); + chat.mSourceType = CHAT_SOURCE_SYSTEM; + LLFloaterChat::addChat(chat); } } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index ac3e2f7cc..3d1a4452f 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1613,7 +1613,7 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo // check for no results if (0 == self->mOwnerList->getItemCount()) { - self->mOwnerList->addCommentText(LLTrans::getString("None_found")); + self->mOwnerList->addCommentText(LLTrans::getString("NoneFound")); } else { diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp new file mode 100644 index 000000000..67e6b45c9 --- /dev/null +++ b/indra/newview/llfloateroutbox.cpp @@ -0,0 +1,591 @@ +/** + * @file llfloateroutbox.cpp + * @brief Implementation of the merchant outbox window + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloateroutbox.h" + +#include "llfolderview.h" +#include "llinventorybridge.h" +#include "llinventorymodelbackgroundfetch.h" +#include "llinventoryobserver.h" +#include "llinventorypanel.h" +#include "llmarketplacefunctions.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "lltextbox.h" +#include "lltexteditor.h" +//#include "lltransientfloatermgr.h" +#include "lltrans.h" +#include "llviewernetwork.h" +//#include "llwindowshade.h" + +#define USE_WINDOWSHADE_DIALOGS 0 + + +///---------------------------------------------------------------------------- +/// LLOutboxNotification class +///---------------------------------------------------------------------------- + +class LLOutboxNotification +{ +public: + bool processNotification(const LLSD& notify) + { + LLFloaterOutbox* outbox_floater = LLFloaterOutbox::getInstance(); + + outbox_floater->showNotification(notify); + + return false; + } +}; + +///---------------------------------------------------------------------------- +/// LLOutboxAddedObserver helper class +///---------------------------------------------------------------------------- + +class LLOutboxAddedObserver : public LLInventoryCategoryAddedObserver +{ +public: + LLOutboxAddedObserver(LLFloaterOutbox * outboxFloater) + : LLInventoryCategoryAddedObserver() + , mOutboxFloater(outboxFloater) + { + } + + void done() + { + for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it) + { + LLViewerInventoryCategory* added_category = *it; + + LLFolderType::EType added_category_type = added_category->getPreferredType(); + + if (added_category_type == LLFolderType::FT_OUTBOX) + { + mOutboxFloater->setupOutbox(added_category->getUUID()); + } + } + } + +private: + LLFloaterOutbox * mOutboxFloater; +}; + +///---------------------------------------------------------------------------- +/// LLFloaterOutbox +///---------------------------------------------------------------------------- + +LLFloaterOutbox::LLFloaterOutbox(const LLSD& key) + : LLFloater(key) + , mCategoriesObserver(NULL) + , mCategoryAddedObserver(NULL) + , mImportBusy(false) + , mImportButton(NULL) + , mInventoryFolderCountText(NULL) + , mInventoryImportInProgress(NULL) + , mInventoryPlaceholder(NULL) + , mInventoryText(NULL) + , mInventoryTitle(NULL) + , mOutboxId(LLUUID::null) + , mOutboxInventoryPanel(NULL) + , mOutboxItemCount(0) + , mOutboxTopLevelDropZone(NULL) +// , mWindowShade(NULL) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_merchant_outbox.xml"); + +} + +LLFloaterOutbox::~LLFloaterOutbox() +{ + if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) + { + gInventory.removeObserver(mCategoriesObserver); + } + delete mCategoriesObserver; + + if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver)) + { + gInventory.removeObserver(mCategoryAddedObserver); + } + delete mCategoryAddedObserver; +} + +BOOL LLFloaterOutbox::postBuild() +{ + mInventoryFolderCountText = getChild("outbox_folder_count"); + mInventoryImportInProgress = getChild("import_progress_indicator"); + mInventoryPlaceholder = getChild("outbox_inventory_placeholder_panel"); + mInventoryText = mInventoryPlaceholder->getChild("outbox_inventory_placeholder_text"); + // For some reason, adding style doesn't work unless this is true. + mInventoryText->setParseHTML(TRUE); + + mInventoryTitle = mInventoryPlaceholder->getChild("outbox_inventory_placeholder_title"); + + mImportButton = getChild("outbox_import_btn"); + mImportButton->setCommitCallback(boost::bind(&LLFloaterOutbox::onImportButtonClicked, this)); + + mOutboxTopLevelDropZone = getChild("outbox_generic_drag_target"); + + LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterOutbox::onFocusReceived, this)); + + return TRUE; +} + +void LLFloaterOutbox::onClose(bool app_quitting) +{ +/* + if (mWindowShade) + { + delete mWindowShade; + + mWindowShade = NULL; + } +*/ + setVisible(FALSE); + //destroy(); //Don't because outbox should be persistent. +} + +void LLFloaterOutbox::onOpen() +{ + // + // Look for an outbox and set up the inventory API + // + + if (mOutboxId.isNull()) + { + const bool do_not_create_folder = false; + const bool do_not_find_in_library = false; + + const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library); + + if (outbox_id.isNull()) + { + // Observe category creation to catch outbox creation + mCategoryAddedObserver = new LLOutboxAddedObserver(this); + gInventory.addObserver(mCategoryAddedObserver); + } + else + { + setupOutbox(outbox_id); + } + } + + updateView(); + + // + // Trigger fetch of outbox contents + // + + fetchOutboxContents(); +} + +void LLFloaterOutbox::onFocusReceived() +{ + fetchOutboxContents(); +} + +void LLFloaterOutbox::fetchOutboxContents() +{ + if (mOutboxId.notNull()) + { + LLInventoryModelBackgroundFetch::instance().start(mOutboxId); + } +} + +void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId) +{ + llassert(outboxId.notNull()); + llassert(mOutboxId.isNull()); + llassert(mCategoriesObserver == NULL); + + mOutboxId = outboxId; + + // No longer need to observe new category creation + if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver)) + { + gInventory.removeObserver(mCategoryAddedObserver); + delete mCategoryAddedObserver; + mCategoryAddedObserver = NULL; + } + + // Create observer for outbox modifications + mCategoriesObserver = new LLInventoryCategoriesObserver(); + gInventory.addObserver(mCategoriesObserver); + + mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this)); + + // + // Set up the outbox inventory view + // + + mOutboxInventoryPanel = getChild("panel_outbox_inventory"); + + llassert(mOutboxInventoryPanel); + + // Reshape the inventory to the proper size + LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect(); + mOutboxInventoryPanel->setShape(inventory_placeholder_rect); + + // Set the sort order newest to oldest + mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME); + mOutboxInventoryPanel->getFilter()->markDefault(); + + fetchOutboxContents(); + + // + // Initialize the marketplace import API + // + + LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance(); + + importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2)); + importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1)); + importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2)); + importer.initialize(); +} + +void LLFloaterOutbox::setStatusString(const std::string& statusString) +{ + llassert(mInventoryFolderCountText != NULL); + + mInventoryFolderCountText->setText(statusString); +} + +void LLFloaterOutbox::updateFolderCount() +{ + S32 item_count = 0; + + if (mOutboxId.notNull()) + { + LLInventoryModel::cat_array_t * cats; + LLInventoryModel::item_array_t * items; + gInventory.getDirectDescendentsOf(mOutboxId, cats, items); + + item_count = cats->count() + items->count(); + } + + mOutboxItemCount = item_count; + + if (!mImportBusy) + { + updateFolderCountStatus(); + } +} + +void LLFloaterOutbox::updateFolderCountStatus() +{ + if (mOutboxInventoryPanel) + { + switch (mOutboxItemCount) + { + case 0: setStatusString(getString("OutboxFolderCount0")); break; + case 1: setStatusString(getString("OutboxFolderCount1")); break; + default: + { + std::string item_count_str = llformat("%d", mOutboxItemCount); + + LLStringUtil::format_map_t args; + args["[NUM]"] = item_count_str; + + setStatusString(getString("OutboxFolderCountN", args)); + break; + } + } + } + + mImportButton->setEnabled(mOutboxItemCount > 0); +} + +void LLFloaterOutbox::updateView() +{ + //updateView() is called twice the first time. + updateFolderCount(); + + if (mOutboxItemCount > 0) + { + mOutboxInventoryPanel->setVisible(TRUE); + mInventoryPlaceholder->setVisible(FALSE); + } + else + { + if (mOutboxInventoryPanel) + { + mOutboxInventoryPanel->setVisible(FALSE); + } + + mInventoryPlaceholder->setVisible(TRUE); + + std::string outbox_text; + std::string outbox_title; + std::string outbox_tooltip; + + const LLSD& subs = getMarketplaceStringSubstitutions(); + + // Text styles for marketplace hyperlinks + std::string subs_link; + std::string subs_text; + + if (mOutboxId.notNull()) + { + outbox_text = LLTrans::getString("InventoryOutboxNoItems"); + subs_link = "[MARKETPLACE_DASHBOARD_URL]"; + subs_text = " " + LLTrans::getString("InventoryOutboxNoItemsSubs"); + outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle"); + outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip"); + } + else + { + outbox_text = LLTrans::getString("InventoryOutboxNotMerchant"); + subs_link = "[MARKETPLACE_CREATE_STORE_URL]"; + subs_text = " " + LLTrans::getString("InventoryOutboxNotMerchantSubs"); + outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle"); + outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip"); + } + + mInventoryText->clear(); + mInventoryText->appendColoredText(outbox_text, false, false, gColors.getColor("TextFgReadOnlyColor")); + LLStringUtil::format(subs_link, subs); + LLStyleSP subs_link_style(new LLStyle); + subs_link_style->setLinkHREF(subs_link); + subs_link_style->setColor(gSavedSettings.getColor4("HTMLLinkColor")); + mInventoryText->appendStyledText(subs_text, false, false, subs_link_style); + mInventoryTitle->setValue(outbox_title); + mInventoryPlaceholder->getParent()->setToolTip(outbox_tooltip); + } +} + +bool isAccepted(EAcceptance accept) +{ + return (accept >= ACCEPT_YES_COPY_SINGLE); +} + +BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + if ((mOutboxInventoryPanel == NULL) || + //(mWindowShade && mWindowShade->isShown()) || + LLMarketplaceInventoryImporter::getInstance()->isImportInProgress()) + { + return FALSE; + } + + LLView * handled_view = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + BOOL handled = (handled_view != NULL); + + // Determine if the mouse is inside the inventory panel itself or just within the floater + bool pointInInventoryPanel = false; + bool pointInInventoryPanelChild = false; + LLFolderView * root_folder = mOutboxInventoryPanel->getRootFolder(); + if (mOutboxInventoryPanel->getVisible()) + { + S32 inv_x, inv_y; + localPointToOtherView(x, y, &inv_x, &inv_y, mOutboxInventoryPanel); + + pointInInventoryPanel = mOutboxInventoryPanel->getRect().pointInRect(inv_x, inv_y); + + LLView * inventory_panel_child_at_point = mOutboxInventoryPanel->childFromPoint(inv_x, inv_y, true); + pointInInventoryPanelChild = (inventory_panel_child_at_point != root_folder); + } + + // Pass all drag and drop for this floater to the outbox inventory control + if (!handled || !isAccepted(*accept)) + { + // Handle the drag and drop directly to the root of the outbox if we're not in the inventory panel + // (otherwise the inventory panel itself will handle the drag and drop operation, without any override) + if (!pointInInventoryPanel) + { + handled = root_folder->handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + } + + mOutboxTopLevelDropZone->setBackgroundVisible(handled && !drop && isAccepted(*accept)); + } + else + { + mOutboxTopLevelDropZone->setBackgroundVisible(!pointInInventoryPanelChild); + } + + return handled; +} + +BOOL LLFloaterOutbox::handleHover(S32 x, S32 y, MASK mask) +{ + mOutboxTopLevelDropZone->setBackgroundVisible(FALSE); + + return LLFloater::handleHover(x, y, mask); +} +/* +void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask) +{ + mOutboxTopLevelDropZone->setBackgroundVisible(FALSE); + + LLFloater::onMouseLeave(x, y, mask); +} +*/ +void LLFloaterOutbox::onImportButtonClicked() +{ + mOutboxInventoryPanel->clearSelection(); + + mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport(); +} + +void LLFloaterOutbox::onOutboxChanged() +{ + llassert(!mOutboxId.isNull()); + + if (mOutboxInventoryPanel) + { + mOutboxInventoryPanel->requestSort(); + } + + fetchOutboxContents(); + + updateView(); +} + +void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content) +{ + if (status == MarketplaceErrorCodes::IMPORT_DONE) + { + LLNotificationsUtil::add("OutboxImportComplete"); + } + else if (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) + { + const LLSD& subs = getMarketplaceStringSubstitutions(); + + LLNotificationsUtil::add("OutboxImportHadErrors", subs); + } + else + { + char status_string[16]; + sprintf(status_string, "%d", status); + + LLSD subs; + subs["[ERROR_CODE]"] = status_string; + + LLNotificationsUtil::add("OutboxImportFailed", subs); + } + + updateView(); +} + +void LLFloaterOutbox::importStatusChanged(bool inProgress) +{ + if (inProgress) + { + if (mImportBusy) + { + setStatusString(getString("OutboxImporting")); + } + else + { + setStatusString(getString("OutboxInitializing")); + } + + mImportBusy = true; + mImportButton->setEnabled(false); + mInventoryImportInProgress->setVisible(true); + } + else + { + mImportBusy = false; + mImportButton->setEnabled(mOutboxItemCount > 0); + mInventoryImportInProgress->setVisible(false); + } + + updateView(); +} + +void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content) +{ + if (status != MarketplaceErrorCodes::IMPORT_DONE) + { + char status_string[16]; + sprintf(status_string, "%d", status); + + LLSD subs; + subs["[ERROR_CODE]"] = status_string; + + LLNotificationsUtil::add("OutboxInitFailed", subs); + } + + updateView(); +} + +void LLFloaterOutbox::showNotification(const LLSD& notify) +{ + LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); + + if (!notification) + { + llerrs << "Unable to find outbox notification!" << notify.asString() << llendl; + + return; + } + +#if USE_WINDOWSHADE_DIALOGS + + if (mWindowShade) + { + delete mWindowShade; + } + + LLRect floater_rect = getLocalRect(); + floater_rect.mTop -= getHeaderHeight(); + floater_rect.stretch(-5, 0); + + LLWindowShade::Params params; + params.name = "notification_shade"; + params.rect = floater_rect; + params.follows.flags = FOLLOWS_ALL; + params.modal = true; + params.can_close = false; + params.shade_color = LLColor4::white % 0.25f; + params.text_color = LLColor4::white; + + mWindowShade = LLUICtrlFactory::create(params); + + addChild(mWindowShade); + mWindowShade->show(notification); + +#else //USE_WINDOWSHADE_DIALOGS +/* + LLNotificationsUI::LLEventHandler * handler = + LLNotificationsUI::LLNotificationManager::instance().getHandlerForNotification("alertmodal"); + + LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast(handler); + llassert(sys_handler); + + sys_handler->processNotification(notify); +*/ + LLNotifications::instance().add(notification); +#endif //USE_WINDOWSHADE_DIALOGS +} + diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h new file mode 100644 index 000000000..92f301416 --- /dev/null +++ b/indra/newview/llfloateroutbox.h @@ -0,0 +1,115 @@ +/** + * @file llfloateroutbox.h + * @brief LLFloaterOutbox + * class definition + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATEROUTBOX_H +#define LL_LLFLOATEROUTBOX_H + +#include "llfloater.h" +#include "llfoldertype.h" +#include "llnotificationptr.h" + + +class LLButton; +class LLInventoryCategoriesObserver; +class LLInventoryCategoryAddedObserver; +class LLInventoryPanel; +class LLLoadingIndicator; +class LLNotification; +class LLTextBox; +class LLTextEditor; +class LLView; +//class LLWindowShade; + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFloaterOutbox +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFloaterOutbox : public LLFloater, public LLFloaterSingleton +{ +public: + LLFloaterOutbox(const LLSD& key); + ~LLFloaterOutbox(); + + void setupOutbox(const LLUUID& outboxId); + + // virtuals + BOOL postBuild(); + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + void showNotification(const LLSD& notify); + + BOOL handleHover(S32 x, S32 y, MASK mask); +// void onMouseLeave(S32 x, S32 y, MASK mask); + +protected: + void fetchOutboxContents(); + + void importReportResults(U32 status, const LLSD& content); + void importStatusChanged(bool inProgress); + void initializationReportError(U32 status, const LLSD& content); + + void onClose(bool app_quitting); + void onOpen(); + + void onFocusReceived(); + + void onImportButtonClicked(); + void onOutboxChanged(); + + void setStatusString(const std::string& statusString); + + void updateFolderCount(); + void updateFolderCountStatus(); + void updateView(); + +private: + LLInventoryCategoriesObserver * mCategoriesObserver; + LLInventoryCategoryAddedObserver * mCategoryAddedObserver; + + bool mImportBusy; + LLButton * mImportButton; + + LLTextBox * mInventoryFolderCountText; + LLView * mInventoryImportInProgress; + LLView * mInventoryPlaceholder; + LLTextEditor * mInventoryText; + LLTextBox * mInventoryTitle; + + LLUUID mOutboxId; + LLInventoryPanel * mOutboxInventoryPanel; + U32 mOutboxItemCount; + LLPanel * mOutboxTopLevelDropZone; + + //LLWindowShade * mWindowShade; +}; + +#endif // LL_LLFLOATEROUTBOX_H diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 5de9bf503..9952eadd3 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -32,19 +32,19 @@ #include "llviewerprecompiledheaders.h" -#include - // self include #include "llfloaterreporter.h" +#include + // linden library includes #include "llassetstorage.h" #include "llcachename.h" #include "llfontgl.h" #include "llgl.h" // for renderer +#include "llimagej2c.h" #include "llinventory.h" #include "llnotificationsutil.h" -#include "llimagej2c.h" #include "llstring.h" #include "llsys.h" #include "sgversion.h" @@ -86,6 +86,8 @@ #include "llassetuploadresponders.h" +#include "lltrans.h" + // #include "llviewercontrol.h" // @@ -397,6 +399,7 @@ void LLFloaterReporter::callbackAvatarID(const std::vector& names, }; } + // static void LLFloaterReporter::onClickSend(void *userdata) { @@ -443,7 +446,7 @@ void LLFloaterReporter::onClickSend(void *userdata) } } - LLUploadDialog::modalUploadDialog("Uploading...\n\nReport"); + LLUploadDialog::modalUploadDialog(LLTrans::getString("uploading_abuse_report")); // *TODO don't upload image if checkbox isn't checked std::string url = gAgent.getRegion()->getCapability("SendUserReport"); std::string sshot_url = gAgent.getRegion()->getCapability("SendUserReportWithScreenshot"); @@ -584,7 +587,7 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id) } -// static +// static LLFloaterReporter* LLFloaterReporter::getReporter(EReportType report_type) { LLFloaterReporter *self = NULL; @@ -947,7 +950,7 @@ void LLFloaterReporter::takeScreenshot() { texture->setImageAssetID(mResourceDatap->mAssetInfo.mUuid); texture->setDefaultImageAssetID(mResourceDatap->mAssetInfo.mUuid); - texture->setCaption(std::string("Screenshot")); + texture->setCaption(getString("Screenshot")); } } diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index f4cc7c30e..dfb82dada 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -46,6 +46,7 @@ #include "llviewerparcelmgr.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" +#include "lltrans.h" #include "hippogridmanager.h" @@ -471,7 +472,7 @@ void LLFloaterSellLandUI::doSellLand(void *userdata) // Do a confirmation S32 sale_price = self->childGetValue("price"); S32 area = parcel->getArea(); - std::string authorizedBuyerName = "Anyone"; + std::string authorizedBuyerName = LLTrans::getString("Anyone"); bool sell_to_anyone = true; if ("user" == self->childGetValue("sell_to").asString()) { diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 3c59b36fe..575957476 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -1053,7 +1053,7 @@ void LLFolderViewItem::draw() && root_is_loading && mShowLoadStatus)) { - std::string load_string = " ( Loading... ) "; + std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) "; font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE); diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index b922f7710..926fdb8d1 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -36,6 +36,7 @@ #include "llagentdata.h" #include "llagentui.h" #include "llagentwearables.h" +#include "llfloaterchat.h" //for addChatHistory #include "llfloatertools.h" // for gFloaterTool #include "llhudeffecttrail.h" #include "llhudmanager.h" @@ -159,7 +160,7 @@ bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item) return acceptable; } -// Static +// static bool LLGiveInventory::isInventoryGroupGiveAcceptable(const LLInventoryItem* item) { if(!item) return false; @@ -286,7 +287,7 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, { LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id); } - else + else { LLSD args; args["COUNT"] = llformat("%d",giveable.countNoCopy()); @@ -305,6 +306,8 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, //static void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id) { + // compute id of possible IM session with agent that has "to_agent" id + LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, to_agent); // If this item was given by drag-and-drop into an IM panel, log this action in the IM panel chat. LLSD args; args["user_id"] = to_agent; @@ -312,6 +315,22 @@ void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im { gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args); } + // If this item was given by drag-and-drop on avatar while IM panel was open, log this action in the IM panel chat. + else if (gIMMgr->isIMSessionOpen(session_id)) + { + gIMMgr->addSystemMessage(session_id, "inventory_item_offered", args); + } + // If this item was given by drag-and-drop on avatar while IM panel wasn't open, log this action to IM history. + else + { + std::string full_name; + if (gCacheName->getFullName(to_agent, full_name)) + { + LLChat chat(LLTrans::getString("inventory_item_offered_to") + " " + full_name); + chat.mSourceType = CHAT_SOURCE_SYSTEM; + LLFloaterChat::addChatHistory(chat); + } + } } // static @@ -380,7 +399,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, NO_TIMESTAMP, bucket, BUCKET_SIZE); - gAgent.sendReliableMessage(); + gAgent.sendReliableMessage(); // if (gSavedSettings.getBOOL("BroadcastViewerEffects")) { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index e2f6144fb..b9d07da6d 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llinventorybridge.cpp * @brief Implementation of the Inventory-Folder-View-Bridge classes. * @@ -34,49 +34,47 @@ #include // for std::pair<> -#include "llinventorypanel.h" #include "llinventorybridge.h" -#include "llinventorydefines.h" -#include "llinventoryfunctions.h" -#include "llinventoryicon.h" -#include "llinventorymodelbackgroundfetch.h" - -#include "lltrans.h" #include "message.h" -#include "llagent.h" -#include "llagentwearables.h" -#include "llappearancemgr.h" -#include "llattachmentsmgr.h" -#include "llagentcamera.h" -#include "llcallingcard.h" #include "llcheckboxctrl.h" // for radio buttons #include "llradiogroup.h" #include "llspinctrl.h" #include "lltextbox.h" #include "llui.h" -#include "llviewerfoldertype.h" +#include "lluictrlfactory.h" -#include "llviewercontrol.h" +#include "llagent.h" +#include "llagentcamera.h" +#include "llagentwearables.h" +#include "llappearancemgr.h" +#include "llattachmentsmgr.h" +#include "llcallingcard.h" #include "llfirstuse.h" #include "llfloateravatarinfo.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" #include "llfloaterinventory.h" +#include "llfloateropenobject.h" #include "llfloaterproperties.h" - #include "llfloaterworldmap.h" #include "llfocusmgr.h" #include "llfolderview.h" #include "llgesturemgr.h" #include "llgiveinventory.h" #include "lliconctrl.h" -#include "llinventorymodel.h" +#include "llimview.h" #include "llinventoryclipboard.h" +#include "llinventorydefines.h" +#include "llinventoryfunctions.h" +#include "llinventoryicon.h" +#include "llinventorymodel.h" +#include "llinventorymodelbackgroundfetch.h" +#include "llinventorypanel.h" #include "lllineeditor.h" +#include "llmarketplacefunctions.h" #include "llmenugl.h" -//#include "llmarketplacefunctions.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llpreviewanim.h" @@ -87,27 +85,25 @@ #include "llpreviewsound.h" #include "llpreviewtexture.h" #include "llresmgr.h" +#include "llselectmgr.h" #include "llscrollcontainer.h" -#include "llimview.h" -#include "llviewerassettype.h" -#include "llfoldertype.h" #include "lltooldraganddrop.h" - -#include "llviewertexturelist.h" +#include "lltabcontainer.h" +#include "lltrans.h" +#include "llviewerassettype.h" +#include "llviewercontrol.h" +#include "llviewerfoldertype.h" #include "llviewerinventory.h" - +#include "llviewermessage.h" #include "llviewerobjectlist.h" - +#include "llviewerregion.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llvoavatar.h" +#include "llfoldertype.h" #include "llwearable.h" #include "llwearablelist.h" -#include "llviewermessage.h" -#include "llviewerregion.h" -#include "lltabcontainer.h" -#include "lluictrlfactory.h" -#include "llselectmgr.h" -#include "llfloateropenobject.h" + // #include "llappviewer.h" // System Folders #include "llfloateranimpreview.h" // for reuploads @@ -133,7 +129,7 @@ // Marketplace outbox current disabled #define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 1 -#define ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU 0 +#define ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU 1 #define BLOCK_WORN_ITEMS_IN_OUTBOX 1 bool InventoryLinksEnabled() @@ -270,7 +266,7 @@ LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, const std::string& LLInvFVBridge::getName() const { - LLInventoryObject* obj = getInventoryObject(); + const LLInventoryObject* obj = getInventoryObject(); if(obj) { return obj->getName(); @@ -354,7 +350,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray& batc S32 count = batch.count(); S32 i,j; for(i = 0; i < count; ++i) - { + { bridge = (LLInvFVBridge*)(batch.get(i)); if(!bridge || !bridge->isItemRemovable()) continue; item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID()); @@ -367,7 +363,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray& batc } } for(i = 0; i < count; ++i) - { + { bridge = (LLInvFVBridge*)(batch.get(i)); if(!bridge || !bridge->isItemRemovable()) continue; cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID()); @@ -778,7 +774,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } - // Don't allow items to be pasted directly into the COF. + // Don't allow items to be pasted directly into the COF or the inbox/outbox if (!isCOFFolder() && !isInboxFolder() && !isOutboxFolder()) { items.push_back(std::string("Paste")); @@ -861,7 +857,7 @@ void LLInvFVBridge::addTrashContextMenuOptions(menuentry_vec_t &items, items.push_back(std::string("Purge Item")); if (!isItemRemovable()) { - disabled_items.push_back(std::string("Purge Item")); + disabled_items.push_back(std::string("Purge Item")); } items.push_back(std::string("Restore Item")); } @@ -945,7 +941,7 @@ BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { return FALSE; } - + *id = obj->getUUID(); //object_ids.put(obj->getUUID()); @@ -1148,8 +1144,8 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, new_listener = new LLItemBridge(inventory, root, uuid); break; - case LLAssetType::AT_OBJECT: - if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT) + case LLAssetType::AT_OBJECT: + if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT) || inv_type == LLInventoryType::IT_TEXTURE ) //There's an abundance of objects in inv that have texture (0) as their inv type, right out of unpack. //May have been bug either in an old client, or server version. Either way... it causes a lot of spam over something ultimately harmless. { @@ -1242,7 +1238,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) { LLInventoryCategory* cat = model->getCategory(uuid); - if(cat) + if (cat) { model->purgeDescendentsOf(uuid); model->notifyObservers(); @@ -1311,10 +1307,10 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const bool can_list = true; // Do not allow listing while import is in progress - /*if (LLMarketplaceInventoryImporter::instanceExists()) + if (LLMarketplaceInventoryImporter::instanceExists()) { can_list = !LLMarketplaceInventoryImporter::instance().isImportInProgress(); - }*/ + } const LLInventoryObject* obj = getInventoryObject(); can_list &= (obj != NULL); @@ -2861,10 +2857,11 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) { llinfos << "Send to marketplace action!" << llendl; - LLInventoryCategory * cat = gInventory.getCategory(mUUID); + /*LLInventoryCategory * cat = gInventory.getCategory(mUUID); if (!cat) return; - send_to_marketplace(cat); + send_to_marketplace(cat);*/ + LLMarketplaceInventoryImporter::instance().triggerImport(); } #endif // ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU } @@ -3028,13 +3025,55 @@ void LLFolderBridge::pasteFromClipboard() if(model && isClipboardPasteable()) { const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); + const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); - - const LLUUID parent_id(mUUID); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); LLDynamicArray objects; LLInventoryClipboard::instance().retrieve(objects); + + if (move_is_into_outbox) + { + LLFolderViewItem * outbox_itemp = mRoot->getItemByID(mUUID); + + if (outbox_itemp) + { + //LLToolDragAndDrop::instance().setCargoCount(objects.size()); + + BOOL can_list = TRUE; + + for (LLDynamicArray::const_iterator iter = objects.begin(); + (iter != objects.end()) && (can_list == TRUE); + ++iter) + { + const LLUUID& item_id = (*iter); + LLInventoryItem *item = model->getItem(item_id); + + if (item) + { + MASK mask = 0x0; + BOOL drop = FALSE; + EDragAndDropType cargo_type = LLViewerAssetType::lookupDragAndDropType(item->getActualType()); + void * cargo_data = (void *) item; + //std::string tooltip_msg; + + can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data/*, tooltip_msg*/); + } + } + + //LLToolDragAndDrop::instance().resetCargoCount(); + + if (can_list == FALSE) + { + // Notify user of failure somehow -- play error sound? modal dialog? + return; + } + } + } + + const LLUUID parent_id(mUUID); + for (LLDynamicArray::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) @@ -5106,6 +5145,7 @@ std::string LLObjectBridge::getLabelSuffix() const { return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn"); } + bool unsupportedPoint = false; //Unsupported points are given special names, translate them as they're named, not later. std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID); if (attachment_point_name == LLStringUtil::null) // Error condition, invalid attach point { @@ -5116,13 +5156,14 @@ std::string LLObjectBridge::getLabelSuffix() const { if((*iter).second.first == mUUID) { - attachment_point_name = llformat("unsupported point %d)", (*iter).first); + attachment_point_name = llformat((LLTrans::getString("unsupported point")+" %d)").c_str(), (*iter).first); } } + unsupportedPoint = attachment_point_name != "Invalid Attachment"; } // e.g. "(worn on ...)" / "(attached to ...)" LLStringUtil::format_map_t args; - args["[ATTACHMENT_POINT]"] = attachment_point_name; + args["[ATTACHMENT_POINT]"] = unsupportedPoint ? attachment_point_name : LLTrans::getString(attachment_point_name); if(gRlvAttachmentLocks.canDetach(getItem())) return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 14c2de40f..06153ad72 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -45,6 +45,7 @@ #include "llappviewer.h" //#include "llfirstuse.h" #include "llfloaterinventory.h" +#include "llfloateroutbox.h" #include "llfocusmgr.h" #include "llfolderview.h" #include "llgesturemgr.h" @@ -430,7 +431,7 @@ void show_item_profile(const LLUUID& item_uuid) void open_outbox() { - //LLFloaterReg::showInstance("outbox"); + LLFloaterOutbox::showInstance(); } LLUUID create_folder_in_outbox_for_item(LLInventoryItem* item, const LLUUID& destFolderId, S32 operation_id) diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 0f6fa9e78..2fcdd59f2 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -44,6 +44,7 @@ #include "llscrollcontainer.h" #include "llviewerassettype.h" #include "llpanelmaininventory.h" +#include "llpanelmarketplaceoutboxinventory.h" #include "llsdserialize.h" @@ -130,6 +131,7 @@ void LLInvPanelComplObserver::done() LLInventoryPanel::LLInventoryPanel(const std::string& name, const std::string& sort_order_setting, + const std::string& start_folder, const LLRect& rect, LLInventoryModel* inventory, BOOL allow_multi_select, @@ -140,6 +142,7 @@ LLInventoryPanel::LLInventoryPanel(const std::string& name, mFolderRoot(NULL), mScroller(NULL), mSortOrderSetting(sort_order_setting), + mStartFolder(start_folder), mInventory(inventory), mAllowMultiSelect(allow_multi_select), mViewsInitialized(false), @@ -154,12 +157,38 @@ LLInventoryPanel::LLInventoryPanel(const std::string& name, void LLInventoryPanel::buildFolderView() { + // Determine the root folder in case specified, and + // build the views starting with that folder. + + //std::string start_folder_name(params.start_folder()); + + const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolder); + + LLUUID root_id; + + if ("LIBRARY" == mStartFolder) + { + root_id = gInventory.getLibraryRootFolderID(); + } + else + { + root_id = (preferred_type != LLFolderType::FT_NONE) + ? gInventory.findCategoryUUIDForType(preferred_type, false, false) + : LLUUID::null; + } + + if ((root_id == LLUUID::null) && !mStartFolder.empty()) + { + llwarns << "No category found that matches start_folder: " << mStartFolder << llendl; + root_id = LLUUID::generateNewID(); + } + LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, LLAssetType::AT_CATEGORY, LLInventoryType::IT_CATEGORY, this, NULL, - LLUUID::null); + root_id); mFolderRoot = createFolderView(new_listener, true/*params.use_label_suffix()*/); } @@ -247,6 +276,7 @@ class LLInventoryRecentItemsPanel : public LLInventoryPanel public: LLInventoryRecentItemsPanel(const std::string& name, const std::string& sort_order_setting, + const std::string& start_folder, const LLRect& rect, LLInventoryModel* inventory, BOOL allow_multi_select, @@ -270,12 +300,19 @@ LLView* LLInventoryPanel::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac std::string sort_order(INHERIT_SORT_ORDER); node->getAttributeString("sort_order", sort_order); - if(name != "Recent Items") - panel = new LLInventoryPanel(name, sort_order, + std::string start_folder; + node->getAttributeString("start_folder", start_folder); + + if(name == "Recent Items") + panel = new LLInventoryRecentItemsPanel(name, sort_order, start_folder, + rect, &gInventory, + allow_multi_select, parent); + else if(name == "panel_outbox_inventory") + panel = new LLOutboxInventoryPanel(name, sort_order, start_folder, rect, &gInventory, allow_multi_select, parent); else - panel = new LLInventoryRecentItemsPanel(name, sort_order, + panel = new LLInventoryPanel(name, sort_order, start_folder, rect, &gInventory, allow_multi_select, parent); @@ -1058,11 +1095,12 @@ static const LLRecentInventoryBridgeBuilder RECENT_ITEMS_BUILDER; LLInventoryRecentItemsPanel:: LLInventoryRecentItemsPanel(const std::string& name, const std::string& sort_order_setting, + const std::string& start_folder, const LLRect& rect, LLInventoryModel* inventory, BOOL allow_multi_select, - LLView *parent_view) : - LLInventoryPanel(name, sort_order_setting,rect,inventory,allow_multi_select,parent_view) + LLView *parent_view) : + LLInventoryPanel(name, sort_order_setting, start_folder,rect,inventory,allow_multi_select,parent_view) { mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER; } diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 4a2953f7f..330e8d3d2 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -69,6 +69,7 @@ class LLInventoryPanel : public LLPanel protected: LLInventoryPanel(const std::string& name, const std::string& sort_order_setting, + const std::string& start_folder, const LLRect& rect, LLInventoryModel* inventory, BOOL allow_multi_select, @@ -188,6 +189,7 @@ public: void requestSort(); private: + const std::string mStartFolder; const std::string mSortOrderSetting; //-------------------------------------------------------------------- diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp new file mode 100644 index 000000000..545ad927b --- /dev/null +++ b/indra/newview/llmarketplacefunctions.cpp @@ -0,0 +1,490 @@ +/** + * @file llmarketplacefunctions.cpp + * @brief Implementation of assorted functions related to the marketplace + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llmarketplacefunctions.h" + +#include "llagent.h" +#include "llhttpclient.h" +#include "lltimer.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "llviewermedia.h" +#include "llviewernetwork.h" +#include "hippogridmanager.h" + +// +// Helpers +// + +static std::string getMarketplaceDomain() +{ + std::string domain = "secondlife.com"; + if (gHippoGridManager->getCurrentGrid()->isSecondLife()) + { + if (!LLViewerLogin::getInstance()->isInProductionGrid()) + { + domain = "secondlife.aditi.lindenlab.com"; + } + } + else + { + // TODO: Find out if OpenSim, and Avination adopted any outbox stuffs, if so code HippoGridManager for this + // Aurora grid has not. + // For now, reset domain on other grids, so we don't harass LL web services. + domain = ""; //gHippoGridManager->getCurrentGrid()->getMarketPlaceDomain(); + } + + return domain; +} + +static std::string getMarketplaceURL(const std::string& urlStringName) +{ + LLStringUtil::format_map_t domain_arg; + domain_arg["[MARKETPLACE_DOMAIN_NAME]"] = getMarketplaceDomain(); + + std::string marketplace_url = LLTrans::getString(urlStringName, domain_arg); + + return marketplace_url; +} + +LLSD getMarketplaceStringSubstitutions() +{ + std::string marketplace_url = getMarketplaceURL("MarketplaceURL"); + std::string marketplace_url_create = getMarketplaceURL("MarketplaceURL_CreateStore"); + std::string marketplace_url_dashboard = getMarketplaceURL("MarketplaceURL_Dashboard"); + std::string marketplace_url_imports = getMarketplaceURL("MarketplaceURL_Imports"); + std::string marketplace_url_info = getMarketplaceURL("MarketplaceURL_LearnMore"); + + LLSD marketplace_sub_map; + + marketplace_sub_map["[MARKETPLACE_URL]"] = marketplace_url; + marketplace_sub_map["[MARKETPLACE_CREATE_STORE_URL]"] = marketplace_url_create; + marketplace_sub_map["[MARKETPLACE_LEARN_MORE_URL]"] = marketplace_url_info; + marketplace_sub_map["[MARKETPLACE_DASHBOARD_URL]"] = marketplace_url_dashboard; + marketplace_sub_map["[MARKETPLACE_IMPORTS_URL]"] = marketplace_url_imports; + + return marketplace_sub_map; +} + +class AIHTTPTimeoutPolicy; +extern AIHTTPTimeoutPolicy MPImportGetResponder_timeout; +extern AIHTTPTimeoutPolicy MPImportPostResponder_timeout; + +namespace LLMarketplaceImport +{ + // Basic interface for this namespace + + + bool hasSessionCookie(); + bool inProgress(); + bool resultPending(); + U32 getResultStatus(); + const LLSD& getResults(); + + bool establishMarketplaceSessionCookie(); + bool pollStatus(); + bool triggerImport(); + + // Internal state variables + + static std::string sMarketplaceCookie = ""; + static LLSD sImportId = LLSD::emptyMap(); + static bool sImportInProgress = false; + static bool sImportPostPending = false; + static bool sImportGetPending = false; + static U32 sImportResultStatus = 0; + static LLSD sImportResults = LLSD::emptyMap(); + + static LLTimer slmGetTimer; + static LLTimer slmPostTimer; + + // Responders + + class LLImportPostResponder : public LLHTTPClient::ResponderWithCompleted + { + public: + AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return MPImportPostResponder_timeout; } + + void completed(U32 status, const std::string& reason, const LLSD& content) + { + slmPostTimer.stop(); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST status: " << status << llendl; + llinfos << " SLM POST reason: " << reason << llendl; + llinfos << " SLM POST content: " << content.asString() << llendl; + + llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl; + } + + if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) || + (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || + (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) + { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl; + } + + sMarketplaceCookie.clear(); + } + + sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE); + sImportPostPending = false; + sImportResultStatus = status; + sImportId = content; + } + }; + + class LLImportGetResponder : public LLHTTPClient::ResponderWithCompleted + { + public: + AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return MPImportGetResponder_timeout; } + + bool needsHeaders(void) const { return true; } + + void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers) + { + std::string set_cookie_string; + if (headers.getFirstValue("set-cookie", set_cookie_string) && !set_cookie_string.empty()) + { + sMarketplaceCookie = set_cookie_string; + } + } + + void completed(U32 status, const std::string& reason, const LLSD& content) + { + slmGetTimer.stop(); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET status: " << status << llendl; + llinfos << " SLM GET reason: " << reason << llendl; + llinfos << " SLM GET content: " << content.asString() << llendl; + + llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl; + } + + if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || + (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) + { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl; + } + + sMarketplaceCookie.clear(); + } + + sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING); + sImportGetPending = false; + sImportResultStatus = status; + sImportResults = content; + } + }; + + // Basic API + + bool hasSessionCookie() + { + return !sMarketplaceCookie.empty(); + } + + bool inProgress() + { + return sImportInProgress; + } + + bool resultPending() + { + return (sImportPostPending || sImportGetPending); + } + + U32 getResultStatus() + { + return sImportResultStatus; + } + + const LLSD& getResults() + { + return sImportResults; + } + + static std::string getInventoryImportURL() + { + std::string url = getMarketplaceURL("MarketplaceURL"); + + url += "api/1/"; + url += gAgent.getID().getString(); + url += "/inventory/import/"; + + return url; + } + + bool establishMarketplaceSessionCookie() + { + if (hasSessionCookie()) + { + return false; + } + + sImportInProgress = true; + sImportGetPending = true; + + std::string url = getInventoryImportURL(); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET: " << url << llendl; + } + + slmGetTimer.start(); + AIHTTPHeaders headers = LLViewerMedia::getHeaders(); + LLHTTPClient::get(url, new LLImportGetResponder(), headers); + + return true; + } + + bool pollStatus() + { + if (!hasSessionCookie()) + { + return false; + } + + sImportGetPending = true; + + std::string url = getInventoryImportURL(); + + url += sImportId.asString(); + + // Make the headers for the post + AIHTTPHeaders headers; + headers.addHeader("Accept", "*/*"); + headers.addHeader("Cookie", sMarketplaceCookie); + headers.addHeader("Content-Type", "application/llsd+xml"); + headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET: " << url << llendl; + } + + slmGetTimer.start(); + LLHTTPClient::get(url, new LLImportGetResponder(), headers); + + return true; + } + + bool triggerImport() + { + if (!hasSessionCookie()) + { + return false; + } + + sImportId = LLSD::emptyMap(); + sImportInProgress = true; + sImportPostPending = true; + sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING; + sImportResults = LLSD::emptyMap(); + + std::string url = getInventoryImportURL(); + + // Make the headers for the post + AIHTTPHeaders headers; + headers.addHeader("Accept", "*/*"); + headers.addHeader("Connection", "Keep-Alive"); + headers.addHeader("Cookie", sMarketplaceCookie); + headers.addHeader("Content-Type", "application/xml"); + headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST: " << url << llendl; + } + + slmPostTimer.start(); + LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers); + + return true; + } +} + + +// +// Interface class +// + +static const F32 MARKET_IMPORTER_UPDATE_FREQUENCY = 300.0f; //1.0f; + +//static +void LLMarketplaceInventoryImporter::update() +{ + if (instanceExists()) + { + static LLTimer update_timer; + if (update_timer.hasExpired()) + { + LLMarketplaceInventoryImporter::instance().updateImport(); + update_timer.setTimerExpirySec(MARKET_IMPORTER_UPDATE_FREQUENCY); + } + } +} + +LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter() + : mAutoTriggerImport(false) + , mImportInProgress(false) + , mInitialized(false) + , mErrorInitSignal(NULL) + , mStatusChangedSignal(NULL) + , mStatusReportSignal(NULL) +{ +} + +boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb) +{ + if (mErrorInitSignal == NULL) + { + mErrorInitSignal = new status_report_signal_t(); + } + + return mErrorInitSignal->connect(cb); +} + +boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb) +{ + if (mStatusChangedSignal == NULL) + { + mStatusChangedSignal = new status_changed_signal_t(); + } + + return mStatusChangedSignal->connect(cb); +} + +boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb) +{ + if (mStatusReportSignal == NULL) + { + mStatusReportSignal = new status_report_signal_t(); + } + + return mStatusReportSignal->connect(cb); +} + +void LLMarketplaceInventoryImporter::initialize() +{ + llassert(!mInitialized); + + if (!LLMarketplaceImport::hasSessionCookie()) + { + LLMarketplaceImport::establishMarketplaceSessionCookie(); + } +} + +void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport() +{ + mInitialized = false; + + initialize(); + + mAutoTriggerImport = true; +} + +bool LLMarketplaceInventoryImporter::triggerImport() +{ + const bool import_triggered = LLMarketplaceImport::triggerImport(); + + if (!import_triggered) + { + reinitializeAndTriggerImport(); + } + + return import_triggered; +} + +void LLMarketplaceInventoryImporter::updateImport() +{ + const bool in_progress = LLMarketplaceImport::inProgress(); + + if (in_progress && !LLMarketplaceImport::resultPending()) + { + const bool polling_status = LLMarketplaceImport::pollStatus(); + + if (!polling_status) + { + reinitializeAndTriggerImport(); + } + } + + if (mImportInProgress != in_progress) + { + mImportInProgress = in_progress; + + // If we are no longer in progress + if (!mImportInProgress) + { + if (mInitialized) + { + // Report results + if (mStatusReportSignal) + { + (*mStatusReportSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + } + } + else + { + // Look for results success + mInitialized = LLMarketplaceImport::hasSessionCookie(); + + if (mInitialized) + { + // Follow up with auto trigger of import + if (mAutoTriggerImport) + { + mAutoTriggerImport = false; + + mImportInProgress = triggerImport(); + } + } + else if (mErrorInitSignal) + { + (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + } + } + } + + // Make sure we trigger the status change with the final state (in case of auto trigger after initialize) + if (mStatusChangedSignal) + { + (*mStatusChangedSignal)(mImportInProgress); + } + } +} + diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h new file mode 100644 index 000000000..4c4e07903 --- /dev/null +++ b/indra/newview/llmarketplacefunctions.h @@ -0,0 +1,94 @@ +/** + * @file llmarketplacefunctions.h + * @brief Miscellaneous marketplace-related functions and classes + * class definition + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLMARKETPLACEFUNCTIONS_H +#define LL_LLMARKETPLACEFUNCTIONS_H + + +#include +#include +#include + +#include "llsingleton.h" +#include "llstring.h" + + +LLSD getMarketplaceStringSubstitutions(); + + +namespace MarketplaceErrorCodes +{ + enum eCode + { + IMPORT_DONE = 200, + IMPORT_PROCESSING = 202, + IMPORT_REDIRECT = 302, + IMPORT_AUTHENTICATION_ERROR = 401, + IMPORT_DONE_WITH_ERRORS = 409, + IMPORT_JOB_FAILED = 410, + IMPORT_JOB_TIMEOUT = 499, + }; +} + + +class LLMarketplaceInventoryImporter + : public LLSingleton +{ +public: + static void update(); + + LLMarketplaceInventoryImporter(); + + typedef boost::signals2::signal status_changed_signal_t; + typedef boost::signals2::signal status_report_signal_t; + + boost::signals2::connection setInitializationErrorCallback(const status_report_signal_t::slot_type& cb); + boost::signals2::connection setStatusChangedCallback(const status_changed_signal_t::slot_type& cb); + boost::signals2::connection setStatusReportCallback(const status_report_signal_t::slot_type& cb); + + void initialize(); + bool triggerImport(); + bool isImportInProgress() const { return mImportInProgress; } + +protected: + void reinitializeAndTriggerImport(); + void updateImport(); + +private: + bool mAutoTriggerImport; + bool mImportInProgress; + bool mInitialized; + + status_report_signal_t * mErrorInitSignal; + status_changed_signal_t * mStatusChangedSignal; + status_report_signal_t * mStatusReportSignal; +}; + + + +#endif // LL_LLMARKETPLACEFUNCTIONS_H + diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp new file mode 100644 index 000000000..7800eb791 --- /dev/null +++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp @@ -0,0 +1,149 @@ +/** + * @file llpanelmarketplaceoutboxinventory.cpp + * @brief LLOutboxInventoryPanel class definition + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelmarketplaceoutboxinventory.h" + +//#include "llfolderview.h" +//#include "llfoldervieweventlistener.h" +#include "llinventorybridge.h" +//#include "llinventoryfunctions.h" +#include "lltrans.h" +//#include "llviewerfoldertype.h" + + +// +// statics +// + +static LLRegisterWidget r1("outbox_inventory_panel"); +//static LLRegisterWidget r2("outbox_folder_view_folder"); + +// +// LLOutboxInventoryPanel Implementation +// + +LLOutboxInventoryPanel::LLOutboxInventoryPanel(const std::string& name, + const std::string& sort_order_setting, + const std::string& start_folder, + const LLRect& rect, + LLInventoryModel* inventory, + BOOL allow_multi_select, + LLView* parent_view) + : LLInventoryPanel(name, sort_order_setting, start_folder, rect, inventory, allow_multi_select, parent_view) +{ +} + +LLOutboxInventoryPanel::~LLOutboxInventoryPanel() +{ +} + +// virtual +void LLOutboxInventoryPanel::buildFolderView(/*const LLInventoryPanel::Params& params*/) +{ + // Determine the root folder in case specified, and + // build the views starting with that folder. + + LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); + + if (root_id == LLUUID::null) + { + llwarns << "Outbox inventory panel has no root folder!" << llendl; + root_id = LLUUID::generateNewID(); + } + + LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, + LLAssetType::AT_CATEGORY, + LLInventoryType::IT_CATEGORY, + this, + NULL, + root_id); + + mFolderRoot = createFolderView(new_listener, true/*params.use_label_suffix()*/); +} + +LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge) +{ + return new LLOutboxFolderViewFolder( + bridge->getDisplayName(), + bridge->getIcon(), + bridge->getOpenIcon(), + LLUI::getUIImage("inv_link_overlay.tga"), + mFolderRoot, + bridge); +} + +LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge) +{ + return new LLOutboxFolderViewItem( + bridge->getDisplayName(), + bridge->getIcon(), + bridge->getOpenIcon(), + LLUI::getUIImage("inv_link_overlay.tga"), + bridge->getCreationDate(), + mFolderRoot, + bridge); +} + +// +// LLOutboxFolderViewFolder Implementation +// + +LLOutboxFolderViewFolder::LLOutboxFolderViewFolder(const std::string& name, LLUIImagePtr icon, + LLUIImagePtr icon_open, + LLUIImagePtr icon_link, + LLFolderView* root, + LLFolderViewEventListener* listener) + : LLFolderViewFolder(name, icon, icon_open, icon_link, root, listener) +{ +} + +// +// LLOutboxFolderViewItem Implementation +// + +LLOutboxFolderViewItem::LLOutboxFolderViewItem(const std::string& name, LLUIImagePtr icon, + LLUIImagePtr icon_open, + LLUIImagePtr icon_overlay, + S32 creation_date, + LLFolderView* root, + LLFolderViewEventListener* listener) + : LLFolderViewItem(name, icon, icon_open, icon_overlay, creation_date, root, listener) +{ +} + +BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + return TRUE; +} + +void LLOutboxFolderViewItem::openItem() +{ + // Intentionally do nothing to block attaching items from the outbox +} + +// eof diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.h b/indra/newview/llpanelmarketplaceoutboxinventory.h new file mode 100644 index 000000000..0eee7ed9e --- /dev/null +++ b/indra/newview/llpanelmarketplaceoutboxinventory.h @@ -0,0 +1,74 @@ +/** + * @file llpanelmarketplaceoutboxinventory.h + * @brief LLOutboxInventoryPanel class declaration + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_OUTBOXINVENTORYPANEL_H +#define LL_OUTBOXINVENTORYPANEL_H + + +#include "llinventorypanel.h" +#include "llfolderviewitem.h" + + +class LLOutboxInventoryPanel : public LLInventoryPanel +{ +public: + LLOutboxInventoryPanel(const std::string& name, + const std::string& sort_order_setting, + const std::string& start_folder, + const LLRect& rect, + LLInventoryModel* inventory, + BOOL allow_multi_select, + LLView *parent_view = NULL); + ~LLOutboxInventoryPanel(); + + // virtual + void buildFolderView(/*const LLInventoryPanel::Params& params*/); + + // virtual + LLFolderViewFolder * createFolderViewFolder(LLInvFVBridge * bridge); + LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge); +}; + + +class LLOutboxFolderViewFolder : public LLFolderViewFolder +{ +public: + LLOutboxFolderViewFolder(const std::string& name, LLUIImagePtr icon, LLUIImagePtr icon_open, LLUIImagePtr icon_link, LLFolderView* root, LLFolderViewEventListener* listener); +}; + + +class LLOutboxFolderViewItem : public LLFolderViewItem +{ +public: + LLOutboxFolderViewItem(const std::string& name, LLUIImagePtr icon, LLUIImagePtr icon_open, LLUIImagePtr icon_overlay, S32 creation_date, LLFolderView* root, LLFolderViewEventListener* listener); + + // virtual + BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + void openItem(); +}; + + +#endif //LL_OUTBOXINVENTORYPANEL_H diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index d7b342b25..1265ed7c7 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -1912,8 +1912,12 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) //----------------------------------------------------------------------------- // apply() //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion"); + void LLPolySkeletalDistortion::apply( ESex avatar_sex ) { + LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY); + F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight(); LLJoint* joint; diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp index b43837e89..cfbe6907c 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/newview/llpolymorph.cpp @@ -781,6 +781,8 @@ F32 LLPolyMorphTarget::getMaxDistortion() //----------------------------------------------------------------------------- // apply() //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_APPLY_MORPH_TARGET("Apply Morph"); + void LLPolyMorphTarget::apply( ESex avatar_sex ) { if (!mMorphData || mNumMorphMasksPending > 0) @@ -788,6 +790,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) return; } + LLFastTimer t(FTM_APPLY_MORPH_TARGET); + mLastSex = avatar_sex; // Check for NaN condition (NaN is detected if a variable doesn't equal itself. diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 3447341f6..d39061bb4 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -358,7 +358,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dUpdateInventoryCategory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_GESTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dActivateGesture, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); @@ -1710,6 +1710,12 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( //} // + const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + if(gInventory.isObjectDescendentOf(item->getUUID(), outbox_id)) + { + return ACCEPT_NO; + } + // [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) { @@ -1739,7 +1745,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( else { // rez_attachment(item, 0); -// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-08 (Catznip-2.2.0a) | Added: Catznip-2.2.0a +// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a // Make this behave consistent with dad3dWearItem rez_attachment(item, 0, !(mask & MASK_CONTROL)); // [/SL:KB] @@ -2068,7 +2074,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem( if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY) { // it's in the agent inventory - LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) { return ACCEPT_NO; @@ -2118,7 +2124,7 @@ EAcceptance LLToolDragAndDrop::dad3dActivateGesture( if(mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY) { // it's in the agent inventory - LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) { return ACCEPT_NO; @@ -2191,7 +2197,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory( if(drop) { - BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE ); + BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE ); LLAppearanceMgr::instance().wearInventoryCategory(category, false, append); } return ACCEPT_YES_MULTI; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 675ae0fec..bc7c88e2b 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -631,13 +631,13 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom } -LLSD LLViewerMedia::getHeaders() +AIHTTPHeaders LLViewerMedia::getHeaders() { - LLSD headers = LLSD::emptyMap(); - headers["Accept"] = "*/*"; - headers["Content-Type"] = "application/xml"; - headers["Cookie"] = sOpenIDCookie; - headers["User-Agent"] = getCurrentUserAgent(); + AIHTTPHeaders headers; + headers.addHeader("Accept", "*/*"); + headers.addHeader("Content-Type", "application/xml"); + headers.addHeader("Cookie", sOpenIDCookie); + headers.addHeader("User-Agent", getCurrentUserAgent()); return headers; } diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index f33b3f13a..0c9e4e77f 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -46,6 +46,7 @@ class LLUUID; class LLSD; class LLViewerTexture; class LLPluginCookieStore; +class AIHTTPHeaders; typedef LLPointer viewer_media_t; @@ -95,7 +96,7 @@ class LLViewerMedia static void openIDSetup(const std::string &openid_url, const std::string &openid_token); static void openIDCookieResponse(const std::string &cookie); - static LLSD getHeaders(); + static AIHTTPHeaders getHeaders(); private: static void setOpenIDCookie(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8963af86c..9d93b6970 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -139,6 +139,7 @@ #include "llfloatermute.h" #include "llfloateropenobject.h" +#include "llfloateroutbox.h" #include "llfloaterpermissionsmgr.h" #include "llfloaterperms.h" #include "llfloaterpostprocess.h" @@ -6539,6 +6540,10 @@ class LLShowFloater : public view_listener_t { LLFloaterPerms::toggleInstance(LLSD()); } + else if (floater_name == "outbox") + { + LLFloaterOutbox::toggleInstance(LLSD()); + } return true; } }; @@ -6613,6 +6618,10 @@ class LLFloaterVisible : public view_listener_t if (!instn) new_value = false; else new_value = instn->getVisible(); } + else if (floater_name == "outbox") + { + new_value = LLFloaterOutbox::instanceVisible(LLSD()); + } gMenuHolder->findControl(control_name)->setValue(new_value); return true; } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index ae1fd1bdd..a53805fe8 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1510,6 +1510,10 @@ void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id) mPendingPhysicsFlags.erase(object_id); } +static LLFastTimer::DeclareTimer FTM_SHIFT_OBJECTS("Shift Objects"); +static LLFastTimer::DeclareTimer FTM_PIPELINE_SHIFT("Pipeline Shift"); +static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift"); + void LLViewerObjectList::shiftObjects(const LLVector3 &offset) { // This is called when we shift our origin when we cross region boundaries... @@ -1521,6 +1525,8 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) return; } + LLFastTimer t(FTM_SHIFT_OBJECTS); + LLViewerObject *objectp; for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { @@ -1537,8 +1543,15 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) } } - gPipeline.shiftObjects(offset); - LLWorld::getInstance()->shiftRegions(offset); + { + LLFastTimer t(FTM_PIPELINE_SHIFT); + gPipeline.shiftObjects(offset); + } + + { + LLFastTimer t(FTM_REGION_SHIFT); + LLWorld::getInstance()->shiftRegions(offset); + } } void LLViewerObjectList::repartitionObjects() @@ -2073,8 +2086,8 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) llinfos << "Agent: " << objectp->getPositionAgent() << llendl; addDebugBeacon(objectp->getPositionAgent(),""); #endif - gPipeline.markMoved(objectp->mDrawable); - objectp->setChanged(LLXform::MOVED | LLXform::SILHOUETTE); + gPipeline.markMoved(objectp->mDrawable); + objectp->setChanged(LLXform::MOVED | LLXform::SILHOUETTE); // Flag the object as no longer orphaned childp->mOrphaned = FALSE; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 67b1b2b10..19bd366b4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -39,7 +39,6 @@ #include "llaudioengine.h" #include "noise.h" -#include "llsdserialize.h" #include "raytrace.h" #include "llagent.h" // Get state values from here @@ -54,12 +53,10 @@ #include "lldriverparam.h" #include "lleditingmotion.h" #include "llemote.h" - #include "llfirstuse.h" #include "llfloaterchat.h" #include "llfloaterinventory.h" #include "llheadrotmotion.h" - #include "llhudeffecttrail.h" #include "llhudmanager.h" #include "llinventorybridge.h" @@ -101,6 +98,7 @@ #include "llanimstatelabels.h" #include "lltrans.h" #include "llappearancemgr.h" + #include "llgesturemgr.h" //needed to trigger the voice gesticulations #include "llvoiceclient.h" #include "llvoicevisualizer.h" // Ventrella @@ -110,11 +108,8 @@ #include "floaterao.h" #include "llsdutil.h" -// #include "llfloaterexploreanimations.h" -#include "llimagemetadatareader.h" #include "aihttptimeoutpolicy.h" -// #include "llavatarname.h" @@ -6939,7 +6934,7 @@ U32 LLVOAvatar::getNumAttachments() const iter != mAttachmentPoints.end(); ++iter) { - LLViewerJointAttachment *attachment_pt = (*iter).second; + const LLViewerJointAttachment *attachment_pt = (*iter).second; num_attachments += attachment_pt->getNumObjects(); } return num_attachments; @@ -9512,132 +9507,177 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d void LLVOAvatar::idleUpdateRenderCost() { - static const U32 ARC_BODY_PART_COST = 200; - static const U32 ARC_LIMIT = 20000; - - static std::set all_textures; - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES)) - { //set debug text to attachment geometry bytes here so render cost will override - setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea)); - } - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) { return; } - U32 cost = 0; - LLVOVolume::texture_cost_t textures; + F32 red, green; - for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) + static LLCachedControl UseOldARC(gSavedSettings, "LiruSensibleARC", true); + if(UseOldARC) { - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); - ETextureIndex tex_index = baked_dict->mTextureIndex; - if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT))) - { - if (isTextureVisible(tex_index)) - { - cost +=ARC_BODY_PART_COST; - } - } - } + U32 shame = 1; + std::set textures; - for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) + attachment_map_t::const_iterator iter; + for (iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) { - const LLViewerObject* attached_object = (*attachment_iter); - if (attached_object && !attached_object->isHUDAttachment()) + LLViewerJointAttachment* attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - textures.clear(); - const LLDrawable* drawable = attached_object->mDrawable; - if (drawable) + const LLViewerObject* object = (*attachment_iter); + if (object && !object->isHUDAttachment()) { - const LLVOVolume* volume = drawable->getVOVolume(); - if (volume) + LLDrawable* drawable = object->mDrawable; + if (drawable) { - cost += volume->getRenderCost(textures); - - const_child_list_t children = volume->getChildren(); - for (const_child_list_t::const_iterator child_iter = children.begin(); - child_iter != children.end(); - ++child_iter) + shame += 10; + LLVOVolume* volume = drawable->getVOVolume(); + if (volume) { - LLViewerObject* child_obj = *child_iter; - LLVOVolume *child = dynamic_cast( child_obj ); - if (child) - { - cost += child->getRenderCost(textures); - } - } - - for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) - { - // add the cost of each individual texture in the linkset - cost += iter->second; + shame += calc_shame(volume, textures); } } } } } + shame += textures.size() * 5; + + setDebugText(llformat("%d", shame)); + green = 1.f-llclamp(((F32) shame-1024.f)/1024.f, 0.f, 1.f); + red = llmin((F32) shame/1024.f, 1.f); } - - - - // Diagnostic output to identify all avatar-related textures. - // Does not affect rendering cost calculation. - // Could be wrapped in a debug option if output becomes problematic. - if (isSelf()) + else { - // print any attachment textures we didn't already know about. - for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) + static const U32 ARC_BODY_PART_COST = 200; + static const U32 ARC_LIMIT = 20000; + + static std::set all_textures; + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES)) + { //set debug text to attachment geometry bytes here so render cost will override + setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea)); + } + + U32 cost = 0; + LLVOVolume::texture_cost_t textures; + + for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { - LLUUID image_id = it->first; - if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) - continue; - if (all_textures.find(image_id) == all_textures.end()) + const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); + ETextureIndex tex_index = baked_dict->mTextureIndex; + if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT))) { - // attachment texture not previously seen. - llinfos << "attachment_texture: " << image_id.asString() << llendl; - all_textures.insert(image_id); + if (isTextureVisible(tex_index)) + { + cost +=ARC_BODY_PART_COST; + } } } - // print any avatar textures we didn't already know about - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); - ++iter) + + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) { - const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; - // TODO: MULTI-WEARABLE: handle multiple textures for self - const LLViewerTexture* te_image = getImage(iter->first,0); - if (!te_image) - continue; - LLUUID image_id = te_image->getID(); - if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) - continue; - if (all_textures.find(image_id) == all_textures.end()) + LLViewerJointAttachment* attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl; - all_textures.insert(image_id); + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isHUDAttachment()) + { + textures.clear(); + const LLDrawable* drawable = attached_object->mDrawable; + if (drawable) + { + const LLVOVolume* volume = drawable->getVOVolume(); + if (volume) + { + cost += volume->getRenderCost(textures); + + const_child_list_t children = volume->getChildren(); + for (const_child_list_t::const_iterator child_iter = children.begin(); + child_iter != children.end(); + ++child_iter) + { + LLViewerObject* child_obj = *child_iter; + LLVOVolume *child = dynamic_cast( child_obj ); + if (child) + { + cost += child->getRenderCost(textures); + } + } + + for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) + { + // add the cost of each individual texture in the linkset + cost += iter->second; + } + } + } + } + } + + } + + + + // Diagnostic output to identify all avatar-related textures. + // Does not affect rendering cost calculation. + // Could be wrapped in a debug option if output becomes problematic. + if (isSelf()) + { + // print any attachment textures we didn't already know about. + for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) + { + LLUUID image_id = it->first; + if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) + continue; + if (all_textures.find(image_id) == all_textures.end()) + { + // attachment texture not previously seen. + llinfos << "attachment_texture: " << image_id.asString() << llendl; + all_textures.insert(image_id); + } + } + + // print any avatar textures we didn't already know about + for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); + iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + ++iter) + { + const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + // TODO: MULTI-WEARABLE: handle multiple textures for self + const LLViewerTexture* te_image = getImage(iter->first,0); + if (!te_image) + continue; + LLUUID image_id = te_image->getID(); + if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) + continue; + if (all_textures.find(image_id) == all_textures.end()) + { + llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl; + all_textures.insert(image_id); + } } } + + + std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); + setDebugText(llformat("%s %d", viz_string.c_str(), cost)); + mVisualComplexity = cost; + green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f); + red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f); } - - - std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); - setDebugText(llformat("%s %d", viz_string.c_str(), cost)); - mVisualComplexity = cost; - F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f); - F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f); mText->setColor(LLColor4(red,green,0,1)); } diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 9e9b0c8a3..66c40fbb6 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -330,6 +330,7 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) return TRUE ; } + if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime())) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index f8c1f84a7..99f528dc8 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -167,6 +167,7 @@ void LLVOPartGroup::freeVBSlot(S32 idx) *sVBSlotCursor = idx; } } + LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : LLAlphaObject(id, pcode, regionp), mViewerPartGroupp(NULL) @@ -181,7 +182,6 @@ LLVOPartGroup::~LLVOPartGroup() { } - BOOL LLVOPartGroup::isActive() const { return FALSE; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 416834eee..de657beed 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -352,7 +352,6 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) cloud_pos_density1 = LLColor3(); cloud_pos_density2 = LLColor3(); - mInitialized = FALSE; mbCanSelect = FALSE; mUpdateTimer.reset(); @@ -409,7 +408,6 @@ LLVOSky::~LLVOSky() mCubeMap = NULL; } - void LLVOSky::init() { const F32 haze_int = color_intens(mHaze.calcSigSca(0)); @@ -1250,6 +1248,7 @@ void LLVOSky::createDummyVertexBuffer() } static LLFastTimer::DeclareTimer FTM_RENDER_FAKE_VBO_UPDATE("Fake VBO Update"); + void LLVOSky::updateDummyVertexBuffer() { if(!LLVertexBuffer::sEnableVBOs) @@ -1491,6 +1490,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons } llassert(facep->getVertexBuffer()->getNumIndices() == 6); + index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp); if (-1 == index_offset) diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index e50c11ced..c765371c6 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -894,7 +894,6 @@ void LLVOTree::updateMesh() S32 stop_depth = 0; F32 alpha = 1.0; - U32 vert_count = 0; U32 index_count = 0; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 05e033392..6f085d6cc 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -140,6 +140,7 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline) } static LLFastTimer::DeclareTimer FTM_UPDATE_WATER("Update Water"); + BOOL LLVOWater::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(FTM_UPDATE_WATER); @@ -213,6 +214,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) { //bump edge patches down 10 cm to prevent aliasing along edges z_fudge = -0.1f; } + for (y = 0; y < size; y++) { for (x = 0; x < size; x++) diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index e9a03fee8..492bfe174 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -354,6 +354,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) llinfos << "WL Skydome strips in " << strips_segments << " batches." << llendl; mStripsVerts.resize(strips_segments, NULL); + LLTimer timer; timer.start(); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index a265b3613..c195b2777 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -181,8 +181,8 @@ LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) U32 iindex = 0; U32 jindex = 0; from_region_handle(region_handle, &iindex, &jindex); - S32 x = (S32)(iindex/mWidth); - S32 y = (S32)(jindex/mWidth); + S32 x = (S32)(iindex/mWidth); + S32 y = (S32)(jindex/mWidth); llinfos << "Adding new region (" << x << ":" << y << ")" << llendl; llinfos << "Host: " << host << llendl; @@ -606,13 +606,13 @@ void LLWorld::updateVisibilities() { F32 cur_far_clip = LLViewerCamera::getInstance()->getFar(); - // Go through the culled list and check for visible regions + // Go through the culled list and check for visible regions (region is visible if land is visible) for (region_list_t::iterator iter = mCulledRegionList.begin(); iter != mCulledRegionList.end(); ) { region_list_t::iterator curiter = iter++; LLViewerRegion* regionp = *curiter; - + LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN); if (part) { @@ -623,8 +623,8 @@ void LLWorld::updateVisibilities() mVisibleRegionList.push_back(regionp); } } - } - + } + // Update all of the visible regions for (region_list_t::iterator iter = mVisibleRegionList.begin(); iter != mVisibleRegionList.end(); ) @@ -636,7 +636,7 @@ void LLWorld::updateVisibilities() continue; } - LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN); + LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN); if (part) { LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); @@ -1254,9 +1254,11 @@ void LLWorld::disconnectRegions() } } +static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim"); void process_enable_simulator(LLMessageSystem *msg, void **user_data) { + LLFastTimer t(FTM_ENABLE_SIMULATOR); // enable the appropriate circuit for this simulator and // add its values into the gSimulator structure U64 handle; @@ -1415,15 +1417,13 @@ void send_agent_resume() static LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin) { - LLVector3d pos_global(region_origin); - LLVector3d pos_local; + LLVector3d pos_local; - pos_local.mdV[VZ] = (compact_local & 0xFFU) * 4; - pos_local.mdV[VY] = (compact_local >> 8) & 0xFFU; - pos_local.mdV[VX] = (compact_local >> 16) & 0xFFU; + pos_local.mdV[VZ] = (compact_local & 0xFFU) * 4; + pos_local.mdV[VY] = (compact_local >> 8) & 0xFFU; + pos_local.mdV[VX] = (compact_local >> 16) & 0xFFU; - pos_global += pos_local; - return pos_global; + return region_origin + pos_local; } void LLWorld::getAvatars(std::vector* avatar_ids, std::vector* positions, const LLVector3d& relative_to, F32 radius) const @@ -1478,7 +1478,7 @@ void LLWorld::getAvatars(std::vector* avatar_ids, std::vectormMapAvatarIDs.get(i); // if this avatar doesn't already exist in the list, add it - if(uuid.notNull() && avatar_ids!=NULL && std::find(avatar_ids->begin(), avatar_ids->end(), uuid) == avatar_ids->end()) + if(uuid.notNull() && avatar_ids != NULL && std::find(avatar_ids->begin(), avatar_ids->end(), uuid) == avatar_ids->end()) { if(positions != NULL) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d2004a187..867370945 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -110,7 +110,7 @@ #include "llspatialpartition.h" #include "llmutelist.h" -// [RLVa:KB] +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] @@ -185,8 +185,13 @@ LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump"); LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright"); LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow"); LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update"); +LLFastTimer::DeclareTimer FTM_PIPELINE_CREATE("Pipeline Create"); LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool"); LLFastTimer::DeclareTimer FTM_POOLS("Pools"); +LLFastTimer::DeclareTimer FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)"); +LLFastTimer::DeclareTimer FTM_DEFERRED_POOLS("Pools (Deferred)"); +LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)"); +LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLS("Pools (Post)"); LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO"); LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State"); LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline"); @@ -1474,7 +1479,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) void LLPipeline::createObjects(F32 max_dtime) { - LLFastTimer ftm(FTM_GEO_UPDATE); + LLFastTimer ftm(FTM_PIPELINE_CREATE); LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS); LLTimer update_timer; @@ -2311,14 +2316,19 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) static LLFastTimer::DeclareTimer FTM_SEED_VBO_POOLS("Seed VBO Pool"); +static LLFastTimer::DeclareTimer FTM_UPDATE_GL("Update GL"); + void LLPipeline::updateGL() { - while (!LLGLUpdate::sGLQ.empty()) { - LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); - glu->updateGL(); - glu->mInQ = FALSE; - LLGLUpdate::sGLQ.pop_front(); + LLFastTimer t(FTM_UPDATE_GL); + while (!LLGLUpdate::sGLQ.empty()) + { + LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); + glu->updateGL(); + glu->mInQ = FALSE; + LLGLUpdate::sGLQ.pop_front(); + } } /*{ //seed VBO Pools @@ -2327,11 +2337,14 @@ void LLPipeline::updateGL() }*/ } +static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups"); + void LLPipeline::rebuildPriorityGroups() { + LLFastTimer t(FTM_REBUILD_PRIORITY_GROUPS); LLTimer update_timer; LLMemType mt(LLMemType::MTYPE_PIPELINE); - + assertInitialized(); gMeshRepo.notifyLoadedMeshes(); @@ -2350,7 +2363,9 @@ void LLPipeline::rebuildPriorityGroups() mGroupQ1Locked = false; } - + +static LLFastTimer::DeclareTimer FTM_REBUILD_GROUPS("Rebuild Groups"); + void LLPipeline::rebuildGroups() { if (mGroupQ2.empty()) @@ -2358,6 +2373,7 @@ void LLPipeline::rebuildGroups() return; } + LLFastTimer t(FTM_REBUILD_GROUPS); mGroupQ2Locked = true; // Iterate through some drawables on the non-priority build queue S32 size = (S32) mGroupQ2.size(); @@ -2614,6 +2630,10 @@ void LLPipeline::markShift(LLDrawable *drawablep) } } +static LLFastTimer::DeclareTimer FTM_SHIFT_DRAWABLE("Shift Drawable"); +static LLFastTimer::DeclareTimer FTM_SHIFT_OCTREE("Shift Octree"); +static LLFastTimer::DeclareTimer FTM_SHIFT_HUD("Shift HUD"); + void LLPipeline::shiftObjects(const LLVector3 &offset) { LLMemType mt(LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS); @@ -2626,35 +2646,44 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) LLVector4a offseta; offseta.load3(offset.mV); - for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); - iter != mShiftList.end(); iter++) { - LLDrawable *drawablep = *iter; - if (drawablep->isDead()) + LLFastTimer t(FTM_SHIFT_DRAWABLE); + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); + iter != mShiftList.end(); iter++) { - continue; - } - drawablep->shiftPos(offseta); - drawablep->clearState(LLDrawable::ON_SHIFT_LIST); - } - mShiftList.resize(0); - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) + LLDrawable *drawablep = *iter; + if (drawablep->isDead()) { - part->shift(offseta); + continue; + } + drawablep->shiftPos(offseta); + drawablep->clearState(LLDrawable::ON_SHIFT_LIST); + } + mShiftList.resize(0); + } + + { + LLFastTimer t(FTM_SHIFT_OCTREE); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->shift(offseta); + } } } } - LLHUDText::shiftAll(offset); - LLHUDNameTag::shiftAll(offset); + { + LLFastTimer t(FTM_SHIFT_HUD); + LLHUDText::shiftAll(offset); + LLHUDNameTag::shiftAll(offset); + } display_update_camera(); } @@ -2687,8 +2716,10 @@ void LLPipeline::markPartitionMove(LLDrawable* drawable) } } +static LLFastTimer::DeclareTimer FTM_PROCESS_PARTITIONQ("PartitionQ"); void LLPipeline::processPartitionQ() { + LLFastTimer t(FTM_PROCESS_PARTITIONQ); for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) { LLDrawable* drawable = *iter; @@ -3231,7 +3262,7 @@ void LLPipeline::postSort(LLCamera& camera) rebuildPriorityGroups(); llpushcallstacks ; - + //build render map for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { @@ -3852,7 +3883,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) LLMemType mt_rgd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED); LLFastTimer t(FTM_RENDER_GEOMETRY); - LLFastTimer t2(FTM_POOLS); + LLFastTimer t2(FTM_DEFERRED_POOLS); LLGLEnable cull(GL_CULL_FACE); @@ -3895,7 +3926,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) { - LLFastTimer t(FTM_POOLRENDER); + LLFastTimer t(FTM_DEFERRED_POOLRENDER); gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); @@ -3950,7 +3981,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) void LLPipeline::renderGeomPostDeferred(LLCamera& camera) { LLMemType mt_rgpd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF); - LLFastTimer t(FTM_POOLS); + LLFastTimer t(FTM_POST_DEFERRED_POOLS); U32 cur_type = 0; LLGLEnable cull(GL_CULL_FACE); @@ -3985,7 +4016,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) { - LLFastTimer t(FTM_POOLRENDER); + LLFastTimer t(FTM_POST_DEFERRED_POOLRENDER); gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); @@ -4401,8 +4432,7 @@ void LLPipeline::renderDebug() gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); gGL.end(); - } - + } } /*gGL.flush(); @@ -4530,8 +4560,11 @@ void LLPipeline::renderDebug() } } +static LLFastTimer::DeclareTimer FTM_REBUILD_POOLS("Rebuild Pools"); + void LLPipeline::rebuildPools() { + LLFastTimer t(FTM_REBUILD_POOLS); LLMemType mt(LLMemType::MTYPE_PIPELINE_REBUILD_POOLS); assertInitialized(); @@ -6129,13 +6162,16 @@ void LLPipeline::resetVertexBuffers() { mResetVertexBuffers = true; } +static LLFastTimer::DeclareTimer FTM_RESET_VB("Reset VB"); + void LLPipeline::doResetVertexBuffers() { if (!mResetVertexBuffers) { return; } - + + LLFastTimer t(FTM_RESET_VB); mResetVertexBuffers = false; mCubeVB = NULL; @@ -6634,7 +6670,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); blur_constant /= 1000.f; //convert to meters for shader F32 magnification = focal_length/(subject_distance-focal_length); - + { //build diffuse+bloom+CoF mDeferredLight.bindTarget(); shader = &gDeferredCoFProgram; @@ -7241,7 +7277,7 @@ void LLPipeline::renderDeferredLighting() static const LLCachedControl RenderShadowBlurDistFactor("RenderShadowBlurDistFactor",.1f); static const LLCachedControl RenderDeferredAtmospheric("RenderDeferredAtmospheric",false); static const LLCachedControl RenderLocalLights("RenderLocalLights",false); - + { LLFastTimer ftm(FTM_RENDER_DEFERRED); @@ -7501,7 +7537,7 @@ void LLPipeline::renderDeferredLighting() } mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - + LLGLDepthTest depth(GL_TRUE, GL_FALSE); for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) { @@ -7547,7 +7583,7 @@ void LLPipeline::renderDeferredLighting() } sVisibleLightCount++; - + if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || camera->getOrigin().mV[0] < c[0] - s - 0.2f || camera->getOrigin().mV[1] > c[1] + s + 0.2f || @@ -8043,14 +8079,14 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.setColorMask(true, false); mWaterRef.getViewport(gGLViewport); - + stop_glerror(); gGL.pushMatrix(); mat.set_scale(glh::vec3f(1,1,-1)); mat.set_translate(glh::vec3f(0,0,height*2.f)); - + glh::matrix4f current = glh_get_current_modelview(); mat = current * mat; @@ -8070,7 +8106,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glCullFace(GL_FRONT); static LLCullResult ref_result; - + if (LLDrawPoolWater::sNeedsReflectionUpdate) { //initial sky pass (no user clip plane) @@ -8103,10 +8139,10 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) #endif if (detail < 3) { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); if (detail < 2) { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); } } } @@ -8382,7 +8418,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gDeferredShadowAlphaMaskProgram.bind(); gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f); gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); - + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | @@ -8596,6 +8632,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector } +static LLFastTimer::DeclareTimer FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); void LLPipeline::generateSunShadow(LLCamera& camera) { @@ -8614,6 +8651,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) return; } + LLFastTimer t(FTM_GEN_SUN_SHADOW); + BOOL skip_avatar_update = FALSE; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) { @@ -9375,6 +9414,12 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu } } +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_SETUP("Impostor Setup"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_BACKGROUND("Impostor Background"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_ALLOCATE("Impostor Allocate"); +static LLFastTimer::DeclareTimer FTM_IMPOSTOR_RESIZE("Impostor Resize"); + void LLPipeline::generateImpostor(LLVOAvatar* avatar) { LLMemType mt_gi(LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR); @@ -9430,22 +9475,26 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) sImpostorRender = TRUE; LLViewerCamera* viewer_camera = LLViewerCamera::getInstance(); - markVisible(avatar->mDrawable, *viewer_camera); - LLVOAvatar::sUseImpostors = FALSE; - LLVOAvatar::attachment_map_t::iterator iter; - for (iter = avatar->mAttachmentPoints.begin(); - iter != avatar->mAttachmentPoints.end(); - ++iter) { - LLViewerJointAttachment *attachment = iter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) + LLFastTimer t(FTM_IMPOSTOR_MARK_VISIBLE); + markVisible(avatar->mDrawable, *viewer_camera); + LLVOAvatar::sUseImpostors = FALSE; + + LLVOAvatar::attachment_map_t::iterator iter; + for (iter = avatar->mAttachmentPoints.begin(); + iter != avatar->mAttachmentPoints.end(); + ++iter) { - if (LLViewerObject* attached_object = (*attachment_iter)) + LLViewerJointAttachment *attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) { - markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + if (LLViewerObject* attached_object = (*attachment_iter)) + { + markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + } } } } @@ -9458,6 +9507,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) U32 resX = 0; { + LLFastTimer t(FTM_IMPOSTOR_SETUP); const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); @@ -9512,6 +9562,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (!avatar->mImpostor.isComplete()) { + LLFastTimer t(FTM_IMPOSTOR_ALLOCATE); avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); if (LLPipeline::sRenderDeferred) @@ -9526,6 +9577,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) { + LLFastTimer t(FTM_IMPOSTOR_RESIZE); avatar->mImpostor.resize(resX,resY,GL_RGBA); } @@ -9547,6 +9599,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) } { //create alpha mask based on depth buffer (grey out if muted) + LLFastTimer t(FTM_IMPOSTOR_BACKGROUND); if (LLPipeline::sRenderDeferred) { GLuint buff = GL_COLOR_ATTACHMENT0; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 6dd80b5b1..e5ed58ca1 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -168,7 +168,7 @@ public: void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); void markPartitionMove(LLDrawable* drawablep); void markMeshDirty(LLSpatialGroup* group); - + //get the object between start and end that's closest to start. LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, BOOL pick_transparent, diff --git a/indra/newview/res-sdl/lltoolpathfinding.BMP b/indra/newview/res-sdl/lltoolpathfinding.BMP new file mode 100644 index 000000000..a567951b7 Binary files /dev/null and b/indra/newview/res-sdl/lltoolpathfinding.BMP differ diff --git a/indra/newview/res-sdl/lltoolpathfindingpathend.BMP b/indra/newview/res-sdl/lltoolpathfindingpathend.BMP new file mode 100644 index 000000000..aacea8237 Binary files /dev/null and b/indra/newview/res-sdl/lltoolpathfindingpathend.BMP differ diff --git a/indra/newview/res-sdl/lltoolpathfindingpathendadd.BMP b/indra/newview/res-sdl/lltoolpathfindingpathendadd.BMP new file mode 100644 index 000000000..fa19f3f10 Binary files /dev/null and b/indra/newview/res-sdl/lltoolpathfindingpathendadd.BMP differ diff --git a/indra/newview/res-sdl/lltoolpathfindingpathstart.BMP b/indra/newview/res-sdl/lltoolpathfindingpathstart.BMP new file mode 100644 index 000000000..912b7f931 Binary files /dev/null and b/indra/newview/res-sdl/lltoolpathfindingpathstart.BMP differ diff --git a/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP b/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP new file mode 100644 index 000000000..4e8999ae0 Binary files /dev/null and b/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP differ diff --git a/indra/newview/res-sdl/toolbuy.BMP b/indra/newview/res-sdl/toolbuy.BMP index a00bdb2c5..07e927372 100644 Binary files a/indra/newview/res-sdl/toolbuy.BMP and b/indra/newview/res-sdl/toolbuy.BMP differ diff --git a/indra/newview/res-sdl/toolbuy_old.BMP b/indra/newview/res-sdl/toolbuy_old.BMP new file mode 100644 index 000000000..a00bdb2c5 Binary files /dev/null and b/indra/newview/res-sdl/toolbuy_old.BMP differ diff --git a/indra/newview/res-sdl/toolopen.BMP b/indra/newview/res-sdl/toolopen.BMP index 93c7e44b2..5b8797930 100644 Binary files a/indra/newview/res-sdl/toolopen.BMP and b/indra/newview/res-sdl/toolopen.BMP differ diff --git a/indra/newview/res-sdl/toolopen_old.BMP b/indra/newview/res-sdl/toolopen_old.BMP new file mode 100644 index 000000000..93c7e44b2 Binary files /dev/null and b/indra/newview/res-sdl/toolopen_old.BMP differ diff --git a/indra/newview/res-sdl/toolsit.BMP b/indra/newview/res-sdl/toolsit.BMP index ca911ece7..8ce59ae97 100644 Binary files a/indra/newview/res-sdl/toolsit.BMP and b/indra/newview/res-sdl/toolsit.BMP differ diff --git a/indra/newview/res-sdl/toolsit_old.BMP b/indra/newview/res-sdl/toolsit_old.BMP new file mode 100644 index 000000000..ca911ece7 Binary files /dev/null and b/indra/newview/res-sdl/toolsit_old.BMP differ diff --git a/indra/newview/res/lltoolpathfinding.cur b/indra/newview/res/lltoolpathfinding.cur new file mode 100644 index 000000000..2aba2daa4 Binary files /dev/null and b/indra/newview/res/lltoolpathfinding.cur differ diff --git a/indra/newview/res/lltoolpathfindingpathend.cur b/indra/newview/res/lltoolpathfindingpathend.cur new file mode 100644 index 000000000..e951a6956 Binary files /dev/null and b/indra/newview/res/lltoolpathfindingpathend.cur differ diff --git a/indra/newview/res/lltoolpathfindingpathendadd.cur b/indra/newview/res/lltoolpathfindingpathendadd.cur new file mode 100644 index 000000000..0bf3201b2 Binary files /dev/null and b/indra/newview/res/lltoolpathfindingpathendadd.cur differ diff --git a/indra/newview/res/lltoolpathfindingpathstart.cur b/indra/newview/res/lltoolpathfindingpathstart.cur new file mode 100644 index 000000000..fecc71699 Binary files /dev/null and b/indra/newview/res/lltoolpathfindingpathstart.cur differ diff --git a/indra/newview/res/lltoolpathfindingpathstartadd.cur b/indra/newview/res/lltoolpathfindingpathstartadd.cur new file mode 100644 index 000000000..45e23e516 Binary files /dev/null and b/indra/newview/res/lltoolpathfindingpathstartadd.cur differ diff --git a/indra/newview/skins/default/xui/en-us/floater_chatterbox.xml b/indra/newview/skins/default/xui/en-us/floater_chatterbox.xml index 3dfa2110f..31d7358d4 100644 --- a/indra/newview/skins/default/xui/en-us/floater_chatterbox.xml +++ b/indra/newview/skins/default/xui/en-us/floater_chatterbox.xml @@ -5,9 +5,9 @@ - + mouse_opaque="false" name="chatterbox_tab_container" width="391"/> + diff --git a/indra/newview/skins/default/xui/en-us/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/en-us/floater_merchant_outbox.xml new file mode 100644 index 000000000..e6ff5213b --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/floater_merchant_outbox.xml @@ -0,0 +1,146 @@ + + + No folders + 1 folder + [NUM] folders + Sending folders... + Initializing... + + + + Loading... + + + + + + + + Drag items here to create folders + + + +