Fix up a couple of tiny merge conflicts after a merge with main

master
Callum Prentice 2023-02-13 14:12:59 -08:00
commit 422cd237df
263 changed files with 5675 additions and 4671 deletions

78
.github/labeler.yaml vendored Normal file
View File

@ -0,0 +1,78 @@
llappearance:
- indra/llappearance/**/*
llaudio:
- indra/llaudio/**/*
llcharacter:
- indra/llcharacter/**/*
llcommon:
- indra/llcommon/**/*
llcorehttp:
- indra/llcorehttp/**/*
llcrashlogger:
- indra/llcrashlogger/**/*
llfilesystem:
- indra/llfilesystem/**/*
llimage:
- indra/llimage/**/*
llimagej2coj:
- indra/llimagej2coj/**/*
llinventory:
- indra/llinventory/**/*
llkdu:
- indra/llkdu/**/*
llmath:
- indra/llmath/**/*
llmeshoptimizer:
- indra/llmeshoptimizer/**/*
llmessage:
- indra/llmessage/**/*
llplugin:
- indra/llplugin/**/*
llprimitive:
- indra/llprimitive/**/*
llrender:
- indra/llrender/**/*
llui:
- indra/llui/**/*
llwindow:
- indra/llwindow/**/*
llxml:
- indra/llxml/**/*
cmake:
- '**/*.cmake'
- '**/*/cmake/*'
- '**/CMakeLists.txt'
python:
- '**/*.py'
c/cpp:
- '**/*.c'
- '**/*.cpp'
- '**/*.cxx'
- '**/*.h'
- '**/*.hpp'
- '**/*.hxx'
- '**/*.i'
- '**/*.inl'
- '**/*.y'

25
.github/workflows/cla.yaml vendored Normal file
View File

@ -0,0 +1,25 @@
name: Check CLA
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened, closed, synchronize]
jobs:
cla:
name: Check CLA
runs-on: ubuntu-latest
steps:
- name: CLA Assistant
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
uses: secondlife-3p/contributor-assistant@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PERSONAL_ACCESS_TOKEN: ${{ secrets.SHARED_CLA_TOKEN }}
with:
branch: main
path-to-document: https://github.com/secondlife/cla/blob/master/CLA.md
path-to-signatures: signatures.json
remote-organization-name: secondlife
remote-repository-name: cla-signatures

15
.github/workflows/label.yaml vendored Normal file
View File

@ -0,0 +1,15 @@
name: Pull Request Labeler
on:
- pull_request_target
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
with:
configuration-path: .github/labeler.yaml
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -1,4 +1,8 @@
![Second Life Logo](doc/sl-logo.png)
<picture>
<source media="(prefers-color-scheme: dark)" srcset="doc/sl-logo-dark.png">
<source media="(prefers-color-scheme: light)" srcset="doc/sl-logo.png">
<img alt="Second Life Logo" src="doc/sl-logo.png">
</picture>
**[Second Life][] is a free 3D virtual world where users can create, connect and chat with others from around the
world.** This repository contains the source code for the official client.

View File

@ -52,9 +52,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>b6357ef3a0ec37877a5831820f25094e</string>
<string>178b16ee9ff67986c8c14413ee68218e</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80557/759704/apr_suite-1.4.5.558565-darwin64-558565.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107593/938535/apr_suite-1.4.5.576669-darwin64-576669.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -76,9 +76,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>cb48ac069440f6dcd564cfa9fd02a4c2</string>
<string>d2997cad03dbd0d70a060276b5671480</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80556/759710/apr_suite-1.4.5.558565-windows-558565.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107594/938548/apr_suite-1.4.5.576669-windows-576669.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -88,16 +88,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>646dc3828d9c39fb1e77c4eec44ed739</string>
<string>ec24f5945faa8f13807b83eeaeb994f8</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80555/759709/apr_suite-1.4.5.558565-windows64-558565.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107592/938547/apr_suite-1.4.5.576669-windows64-576669.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.4.5.558565</string>
<string>1.4.5.576669</string>
</map>
<key>boost</key>
<map>
@ -184,9 +184,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>ae90d19cdcddf539f6d0b41cab12f918</string>
<string>7b4aceaed511d44c4d1354b2162b59c7</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72773/702861/bugsplat-1.0.7.552580-darwin64-552580.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107398/936936/bugsplat-1.0.7.576560-darwin64-576560.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -196,9 +196,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f5936eceb6a33ff0f1cc31996a40f29c</string>
<string>53918c7c74b943cdc0bb90caf9657a84</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72774/702905/bugsplat-3.6.0.8.552580-windows-552580.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107400/936949/bugsplat-4.0.3.0.576560-windows-576560.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -208,16 +208,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>9cd940754e53e0670030b3da5ba8f373</string>
<string>19d6a55db101f02e7eb531daf3e8cfd1</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72775/702906/bugsplat-3.6.0.8.552580-windows64-552580.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107401/936948/bugsplat-.576560-windows64-576560.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>3.6.0.8.552580</string>
<string>4.0.3.0.576560</string>
</map>
<key>colladadom</key>
<map>
@ -602,9 +602,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>2c619c1bef969dc42b4f44a4651b314e</string>
<string>8de71c518c248d77f70f87ab5e9de732</string>
<key>url</key>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98369/869141/fmodstudio-2.02.06.570913-darwin64-570913.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/105828/925920/fmodstudio-2.02.06.575716-darwin64-575716.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -626,9 +626,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>875ccd8c1feec8ff03438d453371044b</string>
<string>2eea946ee7a572b748cec0c623ade3ef</string>
<key>url</key>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98371/869153/fmodstudio-2.02.06.570913-windows-570913.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/105830/925932/fmodstudio-2.02.06.575716-windows-575716.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -638,16 +638,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>5e402f4828741bce942e2ced318cd02a</string>
<string>483d6fd5d057b0a681bffef9b8b9d927</string>
<key>url</key>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98372/869154/fmodstudio-2.02.06.570913-windows64-570913.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/105829/925931/fmodstudio-2.02.06.575716-windows64-575716.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>2.02.06.570913</string>
<string>2.02.06.575716</string>
</map>
<key>fontconfig</key>
<map>
@ -1418,9 +1418,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>c1c9e32e21f3c34d91ed045b2ca91f24</string>
<string>7a0059748d0b8733f2f9ce434cf604b8</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87781/805801/libpng-1.6.8.563850-darwin64-563850.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107514/937867/libpng-1.6.38.576621-darwin64-576621.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -1442,9 +1442,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>642e9cf95c8ccd0eb34f6d7a40df585a</string>
<string>3112013186ad60b0fc270a398d4dd499</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87782/805831/libpng-1.6.8.563850-windows-563850.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107513/937823/libpng-1.6.38.576621-windows-576621.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1454,16 +1454,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>ce46aa0f171d97626c4a3940347cecd7</string>
<string>7c6bfcdb0d6162587cdbc436f595dd02</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87780/805832/libpng-1.6.8.563850-windows64-563850.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107512/937822/libpng-1.6.38.576621-windows64-576621.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.6.8.563850</string>
<string>1.6.38.576621</string>
</map>
<key>libuuid</key>
<map>
@ -2195,9 +2195,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>5abf2d9c0b250821c59cc60cd94fd8af</string>
<string>8114c6a7e499ea20d325db0de08ce30a</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54840/510064/openjpeg-1.5.1.538970-darwin64-538970.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105469/923024/openjpeg-2.5.0.575496-darwin64-575496.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -2219,9 +2219,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>222a406ecb4071a9cc9635353afa337e</string>
<string>edc9388870d951632a6d595792293e05</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54977/511775/openjpeg-1.5.1.538970-windows-538970.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105472/923036/openjpeg-2.5.0.575496-windows-575496.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -2231,16 +2231,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>5b5c80807fa8161f3480be3d89fe9516</string>
<string>b95f0732f2388ebb0ddf33d4a30e0ff1</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54974/511767/openjpeg-1.5.1.538970-windows64-538970.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105471/923037/openjpeg-2.5.0.575496-windows64-575496.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.5.1.538970</string>
<string>2.5.0.575496</string>
</map>
<key>openssl</key>
<map>
@ -2671,9 +2671,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>1dda5fb3bb649b0ab5a93f22df7cb11e</string>
<string>2e8d817e7837dd6f4284b13fa3f5c15e</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/96998/862110/viewer_manager-3.0.569958-darwin64-569958.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104765/917714/viewer_manager-3.0.575083-darwin64-575083.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -2683,9 +2683,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>30d1386d0a6883d898fc56757a789b8b</string>
<string>3efa80faaf537e39a77218cd6efa9409</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/97002/862130/viewer_manager-3.0.569958-windows-569958.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104766/917721/viewer_manager-3.0.575083-windows-575083.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -2696,7 +2696,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
<string>3.0.569958</string>
<string>3.0.575083</string>
</map>
<key>vlc-bin</key>
<map>
@ -2888,7 +2888,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>package_description</key>
<map>
<key>canonical_repo</key>
<string>https://bitbucket.org/lindenlab/viewer</string>
<string>https://github.com/secondlife/viewer</string>
<key>copyright</key>
<string>Copyright (c) 2020, Linden Research, Inc.</string>
<key>description</key>

502
doc/LGPL-license.txt Executable file
View File

@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 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.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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; either
version 2.1 of the License, or (at your option) any later version.
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
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -282,6 +282,8 @@ Beq Janus
SL-11300
SL-15709
SL-16021
SL-18592
SL-18637
Beth Walcher
Bezilon Kasei
Biancaluce Robbiani
@ -372,6 +374,7 @@ Charlie Sazaland
Chaser Zaks
BUG-225599
BUG-227485
SL-16874
Cherry Cheevers
ChickyBabes Zuzu
Chorazin Allen
@ -1380,6 +1383,7 @@ Sovereign Engineer
OPEN-343
SL-11625
BUG-229030
SL-14696
SL-14705
SL-14706
SL-14707
@ -1387,6 +1391,12 @@ Sovereign Engineer
SL-14732
SL-15096
SL-16127
SL-18249
SL-18394
SL-18412
SL-18497
SL-18525
SL-18534
SpacedOut Frye
VWR-34
VWR-45
@ -1649,6 +1659,8 @@ Zi Ree
VWR-25588
STORM-1790
STORM-1842
SL-18348
SL-18593
Zipherius Turas
VWR-76
VWR-77

BIN
doc/sl-logo-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -52,7 +52,7 @@ if(WINDOWS)
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(release_files
openjpeg.dll
openjp2.dll
libapr-1.dll
libaprutil-1.dll
libapriconv-1.dll
@ -220,7 +220,7 @@ elseif(LINUX)
libgobject-2.0.so
libhunspell-1.3.so.0.0.0
libopenal.so
libopenjpeg.so
libopenjp2.so
libuuid.so.16
libuuid.so.16.0.22
libfontconfig.so.1.8.0

View File

@ -14,9 +14,10 @@ FIND_PATH(OPENJPEG_INCLUDE_DIR openjpeg.h
/usr/local/include
/usr/include/openjpeg
/usr/include
include/openjpeg
)
SET(OPENJPEG_NAMES ${OPENJPEG_NAMES} openjpeg)
SET(OPENJPEG_NAMES ${OPENJPEG_NAMES} openjp2)
FIND_LIBRARY(OPENJPEG_LIBRARY
NAMES ${OPENJPEG_NAMES}
PATHS /usr/lib /usr/local/lib

View File

@ -8,15 +8,7 @@ if (USESYSTEMLIBS)
include(FindOpenJPEG)
else (USESYSTEMLIBS)
use_prebuilt_binary(openjpeg)
if(WINDOWS)
# Windows has differently named release and debug openjpeg(d) libs.
set(OPENJPEG_LIBRARIES
debug openjpegd
optimized openjpeg)
else(WINDOWS)
set(OPENJPEG_LIBRARIES openjpeg)
endif(WINDOWS)
set(OPENJPEG_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/openjpeg)
set(OPENJPEG_LIBRARIES openjp2)
set(OPENJPEG_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/openjpeg)
endif (USESYSTEMLIBS)

View File

@ -99,14 +99,14 @@ if (WINDOWS)
# Copy over OpenJPEG.dll
# *NOTE: On Windows with VS2005, only the first comment prints
set(OPENJPEG_RELEASE
"${ARCH_PREBUILT_DIRS_RELEASE}/openjpeg.dll")
"${ARCH_PREBUILT_DIRS_RELEASE}/openjp2.dll")
add_custom_command( TARGET llui_libtest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${OPENJPEG_RELEASE} ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Copying OpenJPEG DLLs to binary directory"
)
set(OPENJPEG_DEBUG
"${ARCH_PREBUILT_DIRS_DEBUG}/openjpegd.dll")
"${ARCH_PREBUILT_DIRS_DEBUG}/openjp2.dll")
add_custom_command( TARGET llui_libtest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${OPENJPEG_DEBUG} ${CMAKE_CURRENT_BINARY_DIR}

View File

@ -305,7 +305,12 @@ LLAvatarAppearance::~LLAvatarAppearance()
}
}
if (mRoot) mRoot->removeAllChildren();
if (mRoot)
{
mRoot->removeAllChildren();
delete mRoot;
mRoot = nullptr;
}
mJointMap.clear();
clearSkeleton();

View File

@ -76,6 +76,7 @@ LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject& lto) :
LLLocalTextureObject::~LLLocalTextureObject()
{
delete_and_clear(mTexLayers);
}
LLGLTexture* LLLocalTextureObject::getImage() const

View File

@ -1229,7 +1229,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints)
{
BOOL old_version = FALSE;
mJointMotionList = new LLKeyframeMotion::JointMotionList;
std::unique_ptr<LLKeyframeMotion::JointMotionList> joint_motion_list(new LLKeyframeMotion::JointMotionList);
//-------------------------------------------------------------------------
// get base priority
@ -1272,16 +1272,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority;
joint_motion_list->mBasePriority = (LLJoint::JointPriority) temp_priority;
if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY)
if (joint_motion_list->mBasePriority >= LLJoint::ADDITIVE_PRIORITY)
{
mJointMotionList->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1);
mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority;
joint_motion_list->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1);
joint_motion_list->mMaxPriority = joint_motion_list->mBasePriority;
}
else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY)
else if (joint_motion_list->mBasePriority < LLJoint::USE_MOTION_PRIORITY)
{
LL_WARNS() << "bad animation base_priority " << mJointMotionList->mBasePriority
LL_WARNS() << "bad animation base_priority " << joint_motion_list->mBasePriority
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
@ -1289,15 +1289,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
//-------------------------------------------------------------------------
// get duration
//-------------------------------------------------------------------------
if (!dp.unpackF32(mJointMotionList->mDuration, "duration"))
if (!dp.unpackF32(joint_motion_list->mDuration, "duration"))
{
LL_WARNS() << "can't read duration"
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
if (mJointMotionList->mDuration > MAX_ANIM_DURATION ||
!llfinite(mJointMotionList->mDuration))
if (joint_motion_list->mDuration > MAX_ANIM_DURATION ||
!llfinite(joint_motion_list->mDuration))
{
LL_WARNS() << "invalid animation duration"
<< " for animation " << asset_id << LL_ENDL;
@ -1307,14 +1307,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
//-------------------------------------------------------------------------
// get emote (optional)
//-------------------------------------------------------------------------
if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name"))
if (!dp.unpackString(joint_motion_list->mEmoteName, "emote_name"))
{
LL_WARNS() << "can't read optional_emote_animation"
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
if(mJointMotionList->mEmoteName==mID.asString())
if(joint_motion_list->mEmoteName==mID.asString())
{
LL_WARNS() << "Malformed animation mEmoteName==mID"
<< " for animation " << asset_id << LL_ENDL;
@ -1324,23 +1324,23 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
//-------------------------------------------------------------------------
// get loop
//-------------------------------------------------------------------------
if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") ||
!llfinite(mJointMotionList->mLoopInPoint))
if (!dp.unpackF32(joint_motion_list->mLoopInPoint, "loop_in_point") ||
!llfinite(joint_motion_list->mLoopInPoint))
{
LL_WARNS() << "can't read loop point"
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") ||
!llfinite(mJointMotionList->mLoopOutPoint))
if (!dp.unpackF32(joint_motion_list->mLoopOutPoint, "loop_out_point") ||
!llfinite(joint_motion_list->mLoopOutPoint))
{
LL_WARNS() << "can't read loop point"
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
if (!dp.unpackS32(mJointMotionList->mLoop, "loop"))
if (!dp.unpackS32(joint_motion_list->mLoop, "loop"))
{
LL_WARNS() << "can't read loop"
<< " for animation " << asset_id << LL_ENDL;
@ -1353,22 +1353,22 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
if (female_land_anim == asset_id || formal_female_land_anim == asset_id)
{
LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL;
mJointMotionList->mLoop = FALSE;
joint_motion_list->mLoop = FALSE;
}
//-------------------------------------------------------------------------
// get easeIn and easeOut
//-------------------------------------------------------------------------
if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") ||
!llfinite(mJointMotionList->mEaseInDuration))
if (!dp.unpackF32(joint_motion_list->mEaseInDuration, "ease_in_duration") ||
!llfinite(joint_motion_list->mEaseInDuration))
{
LL_WARNS() << "can't read easeIn"
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") ||
!llfinite(mJointMotionList->mEaseOutDuration))
if (!dp.unpackF32(joint_motion_list->mEaseOutDuration, "ease_out_duration") ||
!llfinite(joint_motion_list->mEaseOutDuration))
{
LL_WARNS() << "can't read easeOut"
<< " for animation " << asset_id << LL_ENDL;
@ -1393,7 +1393,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
return FALSE;
}
mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word;
joint_motion_list->mHandPose = (LLHandMotion::eHandPose)word;
//-------------------------------------------------------------------------
// get number of joint motions
@ -1419,8 +1419,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
return FALSE;
}
mJointMotionList->mJointMotionArray.clear();
mJointMotionList->mJointMotionArray.reserve(num_motions);
joint_motion_list->mJointMotionArray.clear();
joint_motion_list->mJointMotionArray.reserve(num_motions);
mJointStates.clear();
mJointStates.reserve(num_motions);
@ -1431,7 +1431,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
for(U32 i=0; i<num_motions; ++i)
{
JointMotion* joint_motion = new JointMotion;
mJointMotionList->mJointMotionArray.push_back(joint_motion);
joint_motion_list->mJointMotionArray.push_back(joint_motion);
std::string joint_name;
if (!dp.unpackString(joint_name, "joint_name"))
@ -1503,9 +1503,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
joint_motion->mPriority = (LLJoint::JointPriority)joint_priority;
if (joint_priority != LLJoint::USE_MOTION_PRIORITY &&
joint_priority > mJointMotionList->mMaxPriority)
joint_priority > joint_motion_list->mMaxPriority)
{
mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority;
joint_motion_list->mMaxPriority = (LLJoint::JointPriority)joint_priority;
}
joint_state->setPriority((LLJoint::JointPriority)joint_priority);
@ -1556,9 +1556,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
return FALSE;
}
time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration);
time = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration);
if (time < 0 || time > mJointMotionList->mDuration)
if (time < 0 || time > joint_motion_list->mDuration)
{
LL_WARNS() << "invalid frame time"
<< " for animation " << asset_id << LL_ENDL;
@ -1571,38 +1571,57 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
LLVector3 rot_angles;
U16 x, y, z;
BOOL success = TRUE;
if (old_version)
{
success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite();
if (!dp.unpackVector3(rot_angles, "rot_angles"))
{
LL_WARNS() << "can't read rot_angles in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!rot_angles.isFinite())
{
LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
LLQuaternion::Order ro = StringToOrder("ZYX");
rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro);
}
else
{
success &= dp.unpackU16(x, "rot_angle_x");
success &= dp.unpackU16(y, "rot_angle_y");
success &= dp.unpackU16(z, "rot_angle_z");
if (!dp.unpackU16(x, "rot_angle_x"))
{
LL_WARNS() << "can't read rot_angle_x in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!dp.unpackU16(y, "rot_angle_y"))
{
LL_WARNS() << "can't read rot_angle_y in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!dp.unpackU16(z, "rot_angle_z"))
{
LL_WARNS() << "can't read rot_angle_z in rotation key (" << k << ")" << LL_ENDL;
return FALSE;
}
LLVector3 rot_vec;
rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f);
rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f);
rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f);
if(!rot_vec.isFinite())
{
LL_WARNS() << "non-finite angle in rotation key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
rot_key.mRotation.unpackFromVector3(rot_vec);
}
if( !(rot_key.mRotation.isFinite()) )
if(!rot_key.mRotation.isFinite())
{
LL_WARNS() << "non-finite angle in rotation key"
<< " for animation " << asset_id << LL_ENDL;
success = FALSE;
}
if (!success)
{
LL_WARNS() << "can't read rotation key (" << k << ")"
LL_WARNS() << "non-finite angle in rotation key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
@ -1655,14 +1674,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
return FALSE;
}
pos_key.mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration);
pos_key.mTime = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration);
}
BOOL success = TRUE;
if (old_version)
{
success = dp.unpackVector3(pos_key.mPosition, "pos");
if (!dp.unpackVector3(pos_key.mPosition, "pos"))
{
LL_WARNS() << "can't read pos in position key (" << k << ")" << LL_ENDL;
return FALSE;
}
//MAINT-6162
pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
@ -1674,25 +1695,30 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
U16 x, y, z;
success &= dp.unpackU16(x, "pos_x");
success &= dp.unpackU16(y, "pos_y");
success &= dp.unpackU16(z, "pos_z");
if (!dp.unpackU16(x, "pos_x"))
{
LL_WARNS() << "can't read pos_x in position key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!dp.unpackU16(y, "pos_y"))
{
LL_WARNS() << "can't read pos_y in position key (" << k << ")" << LL_ENDL;
return FALSE;
}
if (!dp.unpackU16(z, "pos_z"))
{
LL_WARNS() << "can't read pos_z in position key (" << k << ")" << LL_ENDL;
return FALSE;
}
pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
}
if( !(pos_key.mPosition.isFinite()) )
if(!pos_key.mPosition.isFinite())
{
LL_WARNS() << "non-finite position in key"
<< " for animation " << asset_id << LL_ENDL;
success = FALSE;
}
if (!success)
{
LL_WARNS() << "can't read position key (" << k << ")"
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
@ -1701,7 +1727,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
if (is_pelvis)
{
mJointMotionList->mPelvisBBox.addPoint(pos_key.mPosition);
joint_motion_list->mPelvisBBox.addPoint(pos_key.mPosition);
}
}
@ -1733,23 +1759,21 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
for(S32 i = 0; i < num_constraints; ++i)
{
// read in constraint data
JointConstraintSharedData* constraintp = new JointConstraintSharedData;
std::unique_ptr<JointConstraintSharedData> constraintp(new JointConstraintSharedData);
U8 byte = 0;
if (!dp.unpackU8(byte, "chain_length"))
{
LL_WARNS() << "can't read constraint chain length"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
constraintp->mChainLength = (S32) byte;
if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions())
if((U32)constraintp->mChainLength > joint_motion_list->getNumJointMotions())
{
LL_WARNS() << "invalid constraint chain length"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1757,7 +1781,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read constraint type"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1765,7 +1788,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "invalid constraint type"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
constraintp->mConstraintType = (EConstraintType)byte;
@ -1776,7 +1798,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read source volume name"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1787,7 +1808,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "not a valid source constraint volume " << str
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1795,7 +1815,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read constraint source offset"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1803,7 +1822,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "non-finite constraint source offset"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1811,7 +1829,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read target volume name"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1830,7 +1847,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "not a valid target constraint volume " << str
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
}
@ -1839,7 +1855,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read constraint target offset"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1847,7 +1862,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "non-finite constraint target offset"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1855,7 +1869,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read constraint target direction"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1863,7 +1876,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "non-finite constraint target direction"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1877,7 +1889,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read constraint ease in start time"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1885,7 +1896,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read constraint ease in stop time"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1893,7 +1903,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read constraint ease out start time"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
@ -1901,33 +1910,31 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "can't read constraint ease out stop time"
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
mJointMotionList->mConstraints.push_front(constraintp);
constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte
LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume);
// get joint to which this collision volume is attached
if (!joint)
{
return FALSE;
}
constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte
for (S32 i = 0; i < constraintp->mChainLength + 1; i++)
{
LLJoint* parent = joint->getParent();
if (!parent)
{
LL_WARNS() << "Joint with no parent: " << joint->getName()
<< " Emote: " << mJointMotionList->mEmoteName
<< " Emote: " << joint_motion_list->mEmoteName
<< " for animation " << asset_id << LL_ENDL;
return FALSE;
}
joint = parent;
constraintp->mJointStateIndices[i] = -1;
for (U32 j = 0; j < mJointMotionList->getNumJointMotions(); j++)
for (U32 j = 0; j < joint_motion_list->getNumJointMotions(); j++)
{
LLJoint* constraint_joint = getJoint(j);
@ -1948,14 +1955,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
{
LL_WARNS() << "No joint index for constraint " << i
<< " for animation " << asset_id << LL_ENDL;
delete constraintp;
return FALSE;
}
}
joint_motion_list->mConstraints.push_front(constraintp.release());
}
}
// *FIX: support cleanup of old keyframe data
mJointMotionList = joint_motion_list.release(); // release from unique_ptr to member;
LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList);
mAssetStatus = ASSET_LOADED;

View File

@ -108,7 +108,6 @@ set(llcommon_SOURCE_FILES
llsys.cpp
lltempredirect.cpp
llthread.cpp
llthreadlocalstorage.cpp
llthreadsafequeue.cpp
lltimer.cpp
lltrace.cpp

View File

@ -30,7 +30,6 @@
#include "llapr.h"
#include "llmutex.h"
#include "apr_dso.h"
#include "llthreadlocalstorage.h"
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
@ -54,7 +53,6 @@ void ll_init_apr()
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
}
LLThreadLocalPointerBase::initAllThreadLocalStorage();
gAPRInitialized = true;
}
@ -70,8 +68,6 @@ void ll_cleanup_apr()
LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL;
LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
if (gAPRPoolp)
{
apr_pool_destroy(gAPRPoolp);

View File

@ -288,25 +288,15 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
return name;
}
namespace
{
#if LL_WINDOWS
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name)
U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
{
// C++ exceptions were logged in toplevelTryWrapper, but not SEH
// log SEH exceptions here, to make sure it gets into bugsplat's
// report and because __try won't allow std::string operations
if (code != STATUS_MSC_EXCEPTION)
{
LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL;
}
// Handle bugsplat here, since GetExceptionInformation() can only be
// called from within filter for __except(filter), not from __except's {}
// Bugsplat should get all exceptions, C++ and SEH
LLApp::instance()->reportCrashToBugsplat(exception_infop);
// Only convert non C++ exceptions.
if (code == STATUS_MSC_EXCEPTION)
{
// C++ exception, go on
@ -319,28 +309,38 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,
}
}
void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable)
void sehandle(const LLCoros::callable_t& callable)
{
__try
{
LLCoros::toplevelTryWrapper(name, callable);
callable();
}
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
__except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
{
// convert to C++ styled exception for handlers other than bugsplat
// convert to C++ styled exception
// Note: it might be better to use _se_set_translator
// if you want exception to inherit full callstack
//
// in case of bugsplat this will get to exceptionTerminateHandler and
// looks like fiber will terminate application after that
char integer_string[512];
sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode());
sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
throw std::exception(integer_string);
}
}
#endif
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
#else // ! LL_WINDOWS
inline void sehandle(const LLCoros::callable_t& callable)
{
callable();
}
#endif // ! LL_WINDOWS
} // anonymous namespace
// Top-level wrapper around caller's coroutine callable.
// Normally we like to pass strings and such by const reference -- but in this
// case, we WANT to copy both the name and the callable to our local stack!
void LLCoros::toplevel(std::string name, callable_t callable)
{
// keep the CoroData on this top-level function's stack frame
CoroData corodata(name);
@ -350,12 +350,12 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
// run the code the caller actually wants in the coroutine
try
{
callable();
sehandle(callable);
}
catch (const Stop& exc)
{
LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
<< exc.what() << LL_ENDL;
<< exc.what() << LL_ENDL;
}
catch (const LLContinueError&)
{
@ -366,36 +366,14 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
}
catch (...)
{
#if LL_WINDOWS
// Any OTHER kind of uncaught exception will cause the viewer to
// crash, SEH handling should catch it and report to bugsplat.
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
// to not modify callstack
throw;
#else
// Stash any OTHER kind of uncaught exception in the rethrow() queue
// to be rethrown by the main fiber.
LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine "
<< name << LL_ENDL;
LLCoros::instance().saveException(name, std::current_exception());
#endif
}
}
// Top-level wrapper around caller's coroutine callable.
// Normally we like to pass strings and such by const reference -- but in this
// case, we WANT to copy both the name and the callable to our local stack!
void LLCoros::toplevel(std::string name, callable_t callable)
{
#if LL_WINDOWS
// Because SEH can's have unwinding, need to call a wrapper
// 'try' is inside SEH handling to not catch LLContinue
sehHandle(name, callable);
#else
toplevelTryWrapper(name, callable);
#endif
}
//static
void LLCoros::checkStop()
{

View File

@ -307,11 +307,7 @@ public:
private:
std::string generateDistinctName(const std::string& prefix) const;
void toplevelTryWrapper(const std::string& name, const callable_t& callable);
#if LL_WINDOWS
void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper
#endif
void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper
void toplevel(std::string name, callable_t callable);
struct CoroData;
static CoroData& get_CoroData(const std::string& caller);
void saveException(const std::string& name, std::exception_ptr exc);

View File

@ -943,7 +943,7 @@ namespace LLError
for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a)
{
const LLSD& entry = *a;
if (entry.isMap() && !entry.emptyMap())
if (entry.isMap() && entry.size() != 0)
{
ELevel level = decodeLevel(entry["level"]);

View File

@ -34,6 +34,9 @@
#include <iostream>
#include "apr_base64.h"
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
#else
@ -2128,7 +2131,9 @@ std::string zip_llsd(LLSD& data)
{ //copy result into output
if (strm.avail_out >= CHUNK)
{
free(output);
deflateEnd(&strm);
if(output)
free(output);
LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL;
return std::string();
}
@ -2151,7 +2156,9 @@ std::string zip_llsd(LLSD& data)
}
else
{
free(output);
deflateEnd(&strm);
if(output)
free(output);
LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL;
return std::string();
}
@ -2162,7 +2169,8 @@ std::string zip_llsd(LLSD& data)
std::string result((char*) output, size);
deflateEnd(&strm);
free(output);
if(output)
free(output);
return result;
}
@ -2172,53 +2180,66 @@ std::string zip_llsd(LLSD& data)
// and deserializes from that copy using LLSDSerialize
LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size)
{
U8* result = NULL;
llssize cur_size = 0;
z_stream strm;
const U32 CHUNK = 65536;
U8 *in = new(std::nothrow) U8[size];
std::unique_ptr<U8[]> in = std::unique_ptr<U8[]>(new(std::nothrow) U8[size]);
if (!in)
{
return ZR_MEM_ERROR;
}
is.read((char*) in, size);
is.read((char*) in.get(), size);
U8 out[CHUNK];
return unzip_llsd(data, in.get(), size);
}
LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32 size)
{
U8* result = NULL;
U32 cur_size = 0;
z_stream strm;
constexpr U32 CHUNK = 1024 * 512;
static thread_local std::unique_ptr<U8[]> out;
if (!out)
{
out = std::unique_ptr<U8[]>(new(std::nothrow) U8[CHUNK]);
}
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = size;
strm.next_in = in;
strm.next_in = const_cast<U8*>(in);
S32 ret = inflateInit(&strm);
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
strm.next_out = out.get();
ret = inflate(&strm, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR)
{
inflateEnd(&strm);
free(result);
delete [] in;
return ZR_DATA_ERROR;
}
switch (ret)
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
{
inflateEnd(&strm);
free(result);
return ZR_DATA_ERROR;
}
case Z_STREAM_ERROR:
case Z_BUF_ERROR:
{
inflateEnd(&strm);
free(result);
return ZR_BUFFER_ERROR;
}
case Z_MEM_ERROR:
{
inflateEnd(&strm);
free(result);
delete [] in;
return ZR_MEM_ERROR;
break;
}
}
U32 have = CHUNK-strm.avail_out;
@ -2231,17 +2252,15 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
{
free(result);
}
delete[] in;
return ZR_MEM_ERROR;
}
result = new_result;
memcpy(result+cur_size, out, have);
memcpy(result+cur_size, out.get(), have);
cur_size += have;
} while (ret == Z_OK);
} while (ret == Z_OK && ret != Z_STREAM_END);
inflateEnd(&strm);
delete [] in;
if (ret != Z_STREAM_END)
{
@ -2251,37 +2270,11 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
//result now points to the decompressed LLSD block
{
std::istringstream istr;
// Since we are using this for meshes, data we are dealing with tend to be large.
// So string can potentially fail to allocate, make sure this won't cause problems
try
{
std::string res_str((char*)result, cur_size);
char* result_ptr = strip_deprecated_header((char*)result, cur_size);
std::string deprecated_header("<? LLSD/Binary ?>");
if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
{
res_str = res_str.substr(deprecated_header.size() + 1, cur_size);
}
cur_size = res_str.size();
istr.str(res_str);
}
#ifdef LL_WINDOWS
catch (std::length_error)
{
free(result);
return ZR_SIZE_ERROR;
}
#endif
catch (std::bad_alloc&)
{
free(result);
return ZR_MEM_ERROR;
}
if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH))
boost::iostreams::stream<boost::iostreams::array_source> istrm(result_ptr, cur_size);
if (!LLSDSerialize::fromBinary(data, istrm, cur_size, UNZIP_LLSD_MAX_DEPTH))
{
free(result);
return ZR_PARSE_ERROR;
@ -2395,4 +2388,22 @@ U8* unzip_llsdNavMesh( bool& valid, size_t& outsize, std::istream& is, S32 size
return result;
}
char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size)
{
const char* deprecated_header = "<? LLSD/Binary ?>";
constexpr size_t deprecated_header_size = 17;
if (cur_size > deprecated_header_size
&& memcmp(in, deprecated_header, deprecated_header_size) == 0)
{
in = in + deprecated_header_size;
cur_size = cur_size - deprecated_header_size;
if (header_size)
{
*header_size = deprecated_header_size + 1;
}
}
return in;
}

View File

@ -858,14 +858,20 @@ public:
ZR_SIZE_ERROR,
ZR_DATA_ERROR,
ZR_PARSE_ERROR,
ZR_BUFFER_ERROR,
ZR_VERSION_ERROR
} EZipRresult;
// return OK or reason for failure
static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size);
static EZipRresult unzip_llsd(LLSD& data, const U8* in, S32 size);
};
//dirty little zip functions -- yell at davep
LL_COMMON_API std::string zip_llsd(LLSD& data);
LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, size_t& outsize,std::istream& is, S32 size);
LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size);
// returns a pointer to the array or past the array if the deprecated header exists
LL_COMMON_API char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size = nullptr);
#endif // LL_LLSDSERIALIZE_H

View File

@ -1,115 +0,0 @@
/**
* @file llthreadlocalstorage.cpp
* @author Richard
* @date 2013-1-11
* @brief implementation of thread local storage utility classes
*
* $LicenseInfo:firstyear=2013&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 "linden_common.h"
#include "llthreadlocalstorage.h"
#include "llapr.h"
//
//LLThreadLocalPointerBase
//
bool LLThreadLocalPointerBase::sInitialized = false;
void LLThreadLocalPointerBase::set( void* value )
{
llassert(sInitialized && mThreadKey);
apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to set thread local data" << LL_ENDL;
}
}
void* LLThreadLocalPointerBase::get() const
{
// llassert(sInitialized);
void* ptr;
apr_status_t result =
apr_threadkey_private_get(&ptr, mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to get thread local data" << LL_ENDL;
}
return ptr;
}
void LLThreadLocalPointerBase::initStorage( )
{
apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL;
}
}
void LLThreadLocalPointerBase::destroyStorage()
{
if (sInitialized)
{
if (mThreadKey)
{
apr_status_t result = apr_threadkey_private_delete(mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to delete thread local data" << LL_ENDL;
}
}
}
}
//static
void LLThreadLocalPointerBase::initAllThreadLocalStorage()
{
if (!sInitialized)
{
for (auto& base : instance_snapshot())
{
base.initStorage();
}
sInitialized = true;
}
}
//static
void LLThreadLocalPointerBase::destroyAllThreadLocalStorage()
{
if (sInitialized)
{
//for (auto& base : instance_snapshot())
//{
// base.destroyStorage();
//}
sInitialized = false;
}
}

View File

@ -30,100 +30,6 @@
#include "llinstancetracker.h"
class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
{
public:
LLThreadLocalPointerBase()
: mThreadKey(NULL)
{
if (sInitialized)
{
initStorage();
}
}
LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other)
: mThreadKey(NULL)
{
if (sInitialized)
{
initStorage();
}
}
~LLThreadLocalPointerBase()
{
destroyStorage();
}
static void initAllThreadLocalStorage();
static void destroyAllThreadLocalStorage();
protected:
void set(void* value);
void* get() const;
void initStorage();
void destroyStorage();
protected:
struct apr_threadkey_t* mThreadKey;
static bool sInitialized;
};
template <typename T>
class LLThreadLocalPointer : public LLThreadLocalPointerBase
{
public:
LLThreadLocalPointer()
{}
explicit LLThreadLocalPointer(T* value)
{
set(value);
}
LLThreadLocalPointer(const LLThreadLocalPointer<T>& other)
: LLThreadLocalPointerBase(other)
{
set(other.get());
}
LL_FORCE_INLINE T* get() const
{
return (T*)LLThreadLocalPointerBase::get();
}
T* operator -> () const
{
return (T*)get();
}
T& operator*() const
{
return *(T*)get();
}
LLThreadLocalPointer<T>& operator = (T* value)
{
set((void*)value);
return *this;
}
bool operator ==(const T* other) const
{
if (!sInitialized) return false;
return get() == other;
}
bool isNull() const { return !sInitialized || get() == NULL; }
bool notNull() const { return sInitialized && get() != NULL; }
};
template<typename DERIVED_TYPE>
class LLThreadLocalSingletonPointer
{
@ -139,10 +45,10 @@ public:
}
private:
static LL_THREAD_LOCAL DERIVED_TYPE* sInstance;
static thread_local DERIVED_TYPE* sInstance;
};
template<typename DERIVED_TYPE>
LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
#endif // LL_LLTHREADLOCALSTORAGE_H

View File

@ -40,7 +40,7 @@ StatBase::StatBase( const char* name, const char* description )
mDescription(description ? description : "")
{
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLTrace::get_thread_recorder().notNull())
if (LLTrace::get_thread_recorder() != NULL)
{
LL_ERRS() << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << LL_ENDL;
}

View File

@ -93,7 +93,7 @@ void AccumulatorBufferGroup::makeCurrent()
mStackTimers.makeCurrent();
mMemStats.makeCurrent();
ThreadRecorder* thread_recorder = get_thread_recorder().get();
ThreadRecorder* thread_recorder = get_thread_recorder();
AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
// update stacktimer parent pointers
for (size_t i = 0, end_i = mStackTimers.size(); i < end_i; i++)

View File

@ -95,7 +95,7 @@ Recording::~Recording()
// allow recording destruction without thread recorder running,
// otherwise thread shutdown could crash if a recording outlives the thread recorder
// besides, recording construction and destruction is fine without a recorder...just don't attempt to start one
if (isStarted() && LLTrace::get_thread_recorder().notNull())
if (isStarted() && LLTrace::get_thread_recorder() != NULL)
{
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
}
@ -112,9 +112,9 @@ void Recording::update()
// must have
llassert(mActiveBuffers != NULL
&& LLTrace::get_thread_recorder().notNull());
&& LLTrace::get_thread_recorder() != NULL);
if(!mActiveBuffers->isCurrent())
if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
{
AccumulatorBufferGroup* buffers = mBuffers.write();
LLTrace::get_thread_recorder()->deactivate(buffers);
@ -144,7 +144,7 @@ void Recording::handleStart()
mSamplingTimer.reset();
mBuffers.setStayUnique(true);
// must have thread recorder running on this thread
llassert(LLTrace::get_thread_recorder().notNull());
llassert(LLTrace::get_thread_recorder() != NULL);
mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write());
#endif
}
@ -155,7 +155,7 @@ void Recording::handleStop()
#if LL_TRACE_ENABLED
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
// must have thread recorder running on this thread
llassert(LLTrace::get_thread_recorder().notNull());
llassert(LLTrace::get_thread_recorder() != NULL);
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
mActiveBuffers = NULL;
mBuffers.setStayUnique(false);
@ -1182,8 +1182,8 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth
PeriodicRecording& get_frame_recording()
{
static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));
return *sRecording;
static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
return sRecording;
}
}

View File

@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder()
return sMasterThreadRecorder;
}
LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr()
ThreadRecorder*& get_thread_recorder_ptr()
{
static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder;
static thread_local ThreadRecorder* s_thread_recorder;
return s_thread_recorder;
}
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder()
ThreadRecorder* get_thread_recorder()
{
return get_thread_recorder_ptr();
}

View File

@ -32,7 +32,6 @@
#include "llmutex.h"
#include "lltraceaccumulators.h"
#include "llthreadlocalstorage.h"
namespace LLTrace
{
@ -92,7 +91,7 @@ namespace LLTrace
};
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder();
ThreadRecorder* get_thread_recorder();
void set_thread_recorder(ThreadRecorder*);
void set_master_thread_recorder(ThreadRecorder*);

View File

@ -1009,36 +1009,6 @@ LLUUID::LLUUID()
return !(word[0] | word[1] | word[2] | word[3]);
}
// Copy constructor
LLUUID::LLUUID(const LLUUID& rhs)
{
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
tmp[0] = rhstmp[0];
tmp[1] = rhstmp[1];
tmp[2] = rhstmp[2];
tmp[3] = rhstmp[3];
}
LLUUID::~LLUUID()
{
}
// Assignment
LLUUID& LLUUID::operator=(const LLUUID& rhs)
{
// No need to check the case where this==&rhs. The branch is slower than the write.
U32 *tmp = (U32 *)mData;
U32 *rhstmp = (U32 *)rhs.mData;
tmp[0] = rhstmp[0];
tmp[1] = rhstmp[1];
tmp[2] = rhstmp[2];
tmp[3] = rhstmp[3];
return *this;
}
LLUUID::LLUUID(const char *in_string)
{
if (!in_string || in_string[0] == 0)

View File

@ -55,10 +55,7 @@ public:
LLUUID();
explicit LLUUID(const char *in_string); // Convert from string.
explicit LLUUID(const std::string& in_string); // Convert from string.
LLUUID(const LLUUID &in);
LLUUID &operator=(const LLUUID &rhs);
~LLUUID();
~LLUUID() = default;
//
// MANIPULATORS
@ -131,6 +128,9 @@ public:
U8 mData[UUID_BYTES];
};
static_assert(std::is_trivially_copyable<LLUUID>::value, "LLUUID must be trivial copy");
static_assert(std::is_trivially_move_assignable<LLUUID>::value, "LLUUID must be trivial move");
static_assert(std::is_standard_layout<LLUUID>::value, "LLUUID must be a standard layout type");
typedef std::vector<LLUUID> uuid_vec_t;
typedef std::set<LLUUID> uuid_set_t;

View File

@ -248,7 +248,7 @@ namespace LL
TimePoint until = TimePoint::clock::now() + std::chrono::hours(24);
pop_result popped = tryPopUntil_(lock, until, tt);
if (popped == POPPED)
return std::move(tt);
return tt;
// DONE: throw, just as super::pop() does
if (popped == DONE)

View File

@ -66,16 +66,16 @@ LLDir_Mac::LLDir_Mac()
const std::string secondLifeString = "SecondLife";
std::string *executablepathstr = getSystemExecutableFolder();
std::string executablepathstr = getSystemExecutableFolder();
//NOTE: LLINFOS/LLERRS will not output to log here. The streams are not initialized.
if (executablepathstr)
if (!executablepathstr.empty())
{
// mExecutablePathAndName
mExecutablePathAndName = *executablepathstr;
mExecutablePathAndName = executablepathstr;
boost::filesystem::path executablepath(*executablepathstr);
boost::filesystem::path executablepath(executablepathstr);
# ifndef BOOST_SYSTEM_NO_DEPRECATED
#endif
@ -83,8 +83,8 @@ LLDir_Mac::LLDir_Mac()
mExecutableDir = executablepath.parent_path().string();
// mAppRODataDir
std::string *resourcepath = getSystemResourceFolder();
mAppRODataDir = *resourcepath;
std::string resourcepath = getSystemResourceFolder();
mAppRODataDir = resourcepath;
// *NOTE: When running in a dev tree, use the copy of
// skins in indra/newview/ rather than in the application bundle. This
@ -110,11 +110,11 @@ LLDir_Mac::LLDir_Mac()
}
// mOSUserDir
std::string *appdir = getSystemApplicationSupportFolder();
std::string appdir = getSystemApplicationSupportFolder();
std::string rootdir;
//Create root directory
if (CreateDirectory(*appdir, secondLifeString, &rootdir))
if (CreateDirectory(appdir, secondLifeString, &rootdir))
{
// Save the full path to the folder
@ -128,12 +128,10 @@ LLDir_Mac::LLDir_Mac()
}
//mOSCacheDir
std::string *cachedir = getSystemCacheFolder();
if (cachedir)
std::string cachedir = getSystemCacheFolder();
if (!cachedir.empty())
{
mOSCacheDir = *cachedir;
mOSCacheDir = cachedir;
//TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away.
CreateDirectory(mOSCacheDir, secondLifeString, NULL);
}
@ -143,12 +141,10 @@ LLDir_Mac::LLDir_Mac()
// mTempDir
//Aura 120920 boost::filesystem::temp_directory_path() not yet implemented on mac. :(
std::string *tmpdir = getSystemTempFolder();
if (tmpdir)
std::string tmpdir = getSystemTempFolder();
if (!tmpdir.empty())
{
CreateDirectory(*tmpdir, secondLifeString, &mTempDir);
if (tmpdir) delete tmpdir;
CreateDirectory(tmpdir, secondLifeString, &mTempDir);
}
mWorkingDir = getCurPath();

View File

@ -33,11 +33,11 @@
#include <iostream>
std::string* getSystemTempFolder();
std::string* getSystemCacheFolder();
std::string* getSystemApplicationSupportFolder();
std::string* getSystemResourceFolder();
std::string* getSystemExecutableFolder();
std::string getSystemTempFolder();
std::string getSystemCacheFolder();
std::string getSystemApplicationSupportFolder();
std::string getSystemResourceFolder();
std::string getSystemExecutableFolder();
#endif // LL_LLDIR_UTILS_OBJC_H

View File

@ -30,75 +30,75 @@
#include "lldir_utils_objc.h"
#import <Cocoa/Cocoa.h>
std::string* getSystemTempFolder()
std::string getSystemTempFolder()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString * tempDir = NSTemporaryDirectory();
if (tempDir == nil)
tempDir = @"/tmp";
std::string *result = ( new std::string([tempDir UTF8String]) );
[pool release];
std::string result;
@autoreleasepool {
NSString * tempDir = NSTemporaryDirectory();
if (tempDir == nil)
tempDir = @"/tmp";
result = std::string([tempDir UTF8String]);
}
return result;
}
//findSystemDirectory scoped exclusively to this file.
std::string* findSystemDirectory(NSSearchPathDirectory searchPathDirectory,
std::string findSystemDirectory(NSSearchPathDirectory searchPathDirectory,
NSSearchPathDomainMask domainMask)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
std::string *result = nil;
NSString *path = nil;
// Search for the path
NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory,
domainMask,
YES);
if ([paths count])
{
path = [paths objectAtIndex:0];
//HACK: Always attempt to create directory, ignore errors.
NSError *error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
std::string result;
@autoreleasepool {
NSString *path = nil;
result = new std::string([path UTF8String]);
// Search for the path
NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory,
domainMask,
YES);
if ([paths count])
{
path = [paths objectAtIndex:0];
//HACK: Always attempt to create directory, ignore errors.
NSError *error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
result = std::string([path UTF8String]);
}
}
[pool release];
return result;
}
std::string* getSystemExecutableFolder()
std::string getSystemExecutableFolder()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *bundlePath = [[NSBundle mainBundle] executablePath];
std::string *result = (new std::string([bundlePath UTF8String]));
[pool release];
std::string result;
@autoreleasepool {
NSString *bundlePath = [[NSBundle mainBundle] executablePath];
result = std::string([bundlePath UTF8String]);
}
return result;
}
std::string* getSystemResourceFolder()
std::string getSystemResourceFolder()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
std::string *result = (new std::string([bundlePath UTF8String]));
[pool release];
std::string result;
@autoreleasepool {
NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
result = std::string([bundlePath UTF8String]);
}
return result;
}
std::string* getSystemCacheFolder()
std::string getSystemCacheFolder()
{
return findSystemDirectory (NSCachesDirectory,
NSUserDomainMask);
}
std::string* getSystemApplicationSupportFolder()
std::string getSystemApplicationSupportFolder()
{
return findSystemDirectory (NSApplicationSupportDirectory,
NSUserDomainMask);

View File

@ -257,12 +257,7 @@ void LLPngWrapper::normalizeImage()
png_set_strip_16(mReadPngPtr);
}
#if LL_DARWIN
const F64 SCREEN_GAMMA = 1.8;
#else
const F64 SCREEN_GAMMA = 2.2;
#endif
if (png_get_gAMA(mReadPngPtr, mReadInfoPtr, &mGamma))
{
png_set_gamma(mReadPngPtr, SCREEN_GAMMA, mGamma);

File diff suppressed because it is too large Load Diff

View File

@ -2386,7 +2386,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
return false;
}
return unpackVolumeFacesInternal(mdl);
}
bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size)
{
//input data is now pointing at a zlib compressed block of LLSD
//decompress block
LLSD mdl;
U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size);
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
return false;
}
return unpackVolumeFacesInternal(mdl);
}
bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
{
{
U32 face_count = mdl.size();
@ -5013,6 +5031,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
{
U16 index = mIndices[i];
if (index >= mNumVertices)
{
// invalid index
// replace with a valid index to avoid crashes
index = mNumVertices - 1;
mIndices[i] = index;
// Needs better logging
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL;
}
LLVolumeFace::VertexData cv;
getVertexData(index, cv);
@ -5385,6 +5414,17 @@ bool LLVolumeFace::cacheOptimize()
U16 idx = mIndices[i];
U32 tri_idx = i / 3;
if (idx >= mNumVertices)
{
// invalid index
// replace with a valid index to avoid crashes
idx = mNumVertices - 1;
mIndices[i] = idx;
// Needs better logging
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL;
}
vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx]));
vertex_data[idx].mIdx = idx;
triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]);

View File

@ -1101,8 +1101,12 @@ protected:
BOOL generate();
void createVolumeFaces();
public:
virtual bool unpackVolumeFaces(std::istream& is, S32 size);
bool unpackVolumeFaces(std::istream& is, S32 size);
bool unpackVolumeFaces(U8* in_data, S32 size);
private:
bool unpackVolumeFacesInternal(const LLSD& mdl);
public:
virtual void setMeshAssetLoaded(BOOL loaded);
virtual BOOL isMeshAssetLoaded();

View File

@ -116,9 +116,8 @@ BOOL LLDataPacker::packFixed(const F32 value, const char *name,
BOOL LLDataPacker::unpackFixed(F32 &value, const char *name,
const BOOL is_signed, const U32 int_bits, const U32 frac_bits)
{
//BOOL success = TRUE;
BOOL success = TRUE;
//LL_INFOS() << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << LL_ENDL;
BOOL ok = FALSE;
S32 unsigned_bits = int_bits + frac_bits;
S32 total_bits = unsigned_bits;
@ -134,19 +133,19 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name,
if (total_bits <= 8)
{
U8 fixed_8;
ok = unpackU8(fixed_8, name);
success = unpackU8(fixed_8, name);
fixed_val = (F32)fixed_8;
}
else if (total_bits <= 16)
{
U16 fixed_16;
ok = unpackU16(fixed_16, name);
success = unpackU16(fixed_16, name);
fixed_val = (F32)fixed_16;
}
else if (total_bits <= 31)
{
U32 fixed_32;
ok = unpackU32(fixed_32, name);
success = unpackU32(fixed_32, name);
fixed_val = (F32)fixed_32;
}
else
@ -164,7 +163,7 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name,
}
value = fixed_val;
//LL_INFOS() << "Value: " << value << LL_ENDL;
return ok;
return success;
}
BOOL LLDataPacker::unpackU16s(U16 *values, S32 count, const char *name)
@ -238,37 +237,43 @@ BOOL LLDataPacker::unpackUUIDs(LLUUID *values, S32 count, const char *name)
BOOL LLDataPackerBinaryBuffer::packString(const std::string& value, const char *name)
{
BOOL success = TRUE;
S32 length = value.length()+1;
success &= verifyLength(length, name);
if (!verifyLength(length, name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length);
}
mCurBufferp += length;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackString(std::string& value, const char *name)
{
BOOL success = TRUE;
S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/
success &= verifyLength(length, name);
if (!verifyLength(length, name))
{
return FALSE;
}
value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen()
mCurBufferp += length;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(size + 4, name);
if (!verifyLength(size + 4, name))
{
return FALSE;
}
if (mWriteEnabled)
{
@ -280,102 +285,117 @@ BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const c
htolememcpy(mCurBufferp, value, MVT_VARIABLE, size);
}
mCurBufferp += size;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(4, name);
htolememcpy(&size, mCurBufferp, MVT_S32, 4);
mCurBufferp += 4;
success &= verifyLength(size, name);
if (success)
{
htolememcpy(value, mCurBufferp, MVT_VARIABLE, size);
mCurBufferp += size;
}
else
if (!verifyLength(4, name))
{
LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL;
success = FALSE;
return FALSE;
}
return success;
htolememcpy(&size, mCurBufferp, MVT_S32, 4);
mCurBufferp += 4;
if (!verifyLength(size, name))
{
LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL;
return FALSE;
}
htolememcpy(value, mCurBufferp, MVT_VARIABLE, size);
mCurBufferp += size;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(size, name);
if (!verifyLength(size, name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, value, MVT_VARIABLE, size);
}
mCurBufferp += size;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(size, name);
if (!verifyLength(size, name))
{
return FALSE;
}
htolememcpy(value, mCurBufferp, MVT_VARIABLE, size);
mCurBufferp += size;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(U8), name);
if (!verifyLength(sizeof(U8), name))
{
return FALSE;
}
if (mWriteEnabled)
{
*mCurBufferp = value;
}
mCurBufferp++;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(U8), name);
if (!verifyLength(sizeof(U8), name))
{
return FALSE;
}
value = *mCurBufferp;
mCurBufferp++;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(U16), name);
if (!verifyLength(sizeof(U16), name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, &value, MVT_U16, 2);
}
mCurBufferp += 2;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(U16), name);
if (!verifyLength(sizeof(U16), name))
{
return FALSE;
}
htolememcpy(&value, mCurBufferp, MVT_U16, 2);
mCurBufferp += 2;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packS16(const S16 value, const char *name)
@ -404,134 +424,156 @@ BOOL LLDataPackerBinaryBuffer::unpackS16(S16 &value, const char *name)
BOOL LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(U32), name);
if (!verifyLength(sizeof(U32), name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, &value, MVT_U32, 4);
}
mCurBufferp += 4;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(U32), name);
if (!verifyLength(sizeof(U32), name))
{
return FALSE;
}
htolememcpy(&value, mCurBufferp, MVT_U32, 4);
mCurBufferp += 4;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(S32), name);
if (!verifyLength(sizeof(S32), name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, &value, MVT_S32, 4);
}
mCurBufferp += 4;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(S32), name);
if(!verifyLength(sizeof(S32), name))
{
return FALSE;
}
htolememcpy(&value, mCurBufferp, MVT_S32, 4);
mCurBufferp += 4;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(F32), name);
if (!verifyLength(sizeof(F32), name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, &value, MVT_F32, 4);
}
mCurBufferp += 4;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(sizeof(F32), name);
if (!verifyLength(sizeof(F32), name))
{
return FALSE;
}
htolememcpy(&value, mCurBufferp, MVT_F32, 4);
mCurBufferp += 4;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(16, name);
if (!verifyLength(16, name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16);
}
mCurBufferp += 16;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(16, name);
if (!verifyLength(16, name))
{
return FALSE;
}
htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
mCurBufferp += 16;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(4, name);
if (!verifyLength(4, name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4);
}
mCurBufferp += 4;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(4, name);
if (!verifyLength(4, name))
{
return FALSE;
}
htolememcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4);
mCurBufferp += 4;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(8, name);
if (!verifyLength(8, name))
{
return FALSE;
}
if (mWriteEnabled)
{
@ -539,92 +581,106 @@ BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *n
htolememcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4);
}
mCurBufferp += 8;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(8, name);
if (!verifyLength(8, name))
{
return FALSE;
}
htolememcpy(&value.mV[0], mCurBufferp, MVT_F32, 4);
htolememcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4);
mCurBufferp += 8;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(12, name);
if (!verifyLength(12, name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, value.mV, MVT_LLVector3, 12);
}
mCurBufferp += 12;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(12, name);
if (!verifyLength(12, name))
{
return FALSE;
}
htolememcpy(value.mV, mCurBufferp, MVT_LLVector3, 12);
mCurBufferp += 12;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(16, name);
if (!verifyLength(16, name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16);
}
mCurBufferp += 16;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(16, name);
if (!verifyLength(16, name))
{
return FALSE;
}
htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16);
mCurBufferp += 16;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(16, name);
if (!verifyLength(16, name))
{
return FALSE;
}
if (mWriteEnabled)
{
htolememcpy(mCurBufferp, value.mData, MVT_LLUUID, 16);
}
mCurBufferp += 16;
return success;
return TRUE;
}
BOOL LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name)
{
BOOL success = TRUE;
success &= verifyLength(16, name);
if (!verifyLength(16, name))
{
return FALSE;
}
htolememcpy(value.mData, mCurBufferp, MVT_LLUUID, 16);
mCurBufferp += 16;
return success;
return TRUE;
}
const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a)
@ -698,15 +754,13 @@ BOOL LLDataPackerAsciiBuffer::packString(const std::string& value, const char *n
BOOL LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name)
{
BOOL success = TRUE;
char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/
BOOL res = getValueStr(name, valuestr, DP_BUFSIZE); // NULL terminated
if (!res) //
if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated
{
return FALSE;
}
value = valuestr;
return success;
return TRUE;
}

View File

@ -666,7 +666,6 @@ char const* const _PREHASH_GroupRolesCount = LLMessageStringTable::getInstance()
char const* const _PREHASH_SimulatorBlock = LLMessageStringTable::getInstance()->getString("SimulatorBlock");
char const* const _PREHASH_GroupID = LLMessageStringTable::getInstance()->getString("GroupID");
char const* const _PREHASH_AgentVel = LLMessageStringTable::getInstance()->getString("AgentVel");
char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage");
char const* const _PREHASH_NetStats = LLMessageStringTable::getInstance()->getString("NetStats");
char const* const _PREHASH_AgentPos = LLMessageStringTable::getInstance()->getString("AgentPos");
char const* const _PREHASH_AgentSit = LLMessageStringTable::getInstance()->getString("AgentSit");
@ -1047,7 +1046,6 @@ char const* const _PREHASH_SortOrder = LLMessageStringTable::getInstance()->getS
char const* const _PREHASH_Hunter = LLMessageStringTable::getInstance()->getString("Hunter");
char const* const _PREHASH_SunAngVelocity = LLMessageStringTable::getInstance()->getString("SunAngVelocity");
char const* const _PREHASH_BinaryBucket = LLMessageStringTable::getInstance()->getString("BinaryBucket");
char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket");
char const* const _PREHASH_StartGroupProposal = LLMessageStringTable::getInstance()->getString("StartGroupProposal");
char const* const _PREHASH_EnergyLevel = LLMessageStringTable::getInstance()->getString("EnergyLevel");
char const* const _PREHASH_PriceForListing = LLMessageStringTable::getInstance()->getString("PriceForListing");
@ -1236,7 +1234,6 @@ char const* const _PREHASH_ForceScriptControlRelease = LLMessageStringTable::get
char const* const _PREHASH_ParcelRelease = LLMessageStringTable::getInstance()->getString("ParcelRelease");
char const* const _PREHASH_VFileType = LLMessageStringTable::getInstance()->getString("VFileType");
char const* const _PREHASH_EjectGroupMemberReply = LLMessageStringTable::getInstance()->getString("EjectGroupMemberReply");
char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData");
char const* const _PREHASH_SimulatorViewerTimeMessage = LLMessageStringTable::getInstance()->getString("SimulatorViewerTimeMessage");
char const* const _PREHASH_Rotation = LLMessageStringTable::getInstance()->getString("Rotation");
char const* const _PREHASH_Selection = LLMessageStringTable::getInstance()->getString("Selection");

View File

@ -666,7 +666,6 @@ extern char const* const _PREHASH_GroupRolesCount;
extern char const* const _PREHASH_SimulatorBlock;
extern char const* const _PREHASH_GroupID;
extern char const* const _PREHASH_AgentVel;
extern char const* const _PREHASH_RequestImage;
extern char const* const _PREHASH_NetStats;
extern char const* const _PREHASH_AgentPos;
extern char const* const _PREHASH_AgentSit;
@ -1047,7 +1046,6 @@ extern char const* const _PREHASH_SortOrder;
extern char const* const _PREHASH_Hunter;
extern char const* const _PREHASH_SunAngVelocity;
extern char const* const _PREHASH_BinaryBucket;
extern char const* const _PREHASH_ImagePacket;
extern char const* const _PREHASH_StartGroupProposal;
extern char const* const _PREHASH_EnergyLevel;
extern char const* const _PREHASH_PriceForListing;

View File

@ -92,7 +92,7 @@ namespace tut
Sync sync;
int foo = 0;
LLCoprocedureManager::instance().initializePool("PoolName");
LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName",
LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName",
[&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) {
sync.bump();
foo = 1;

View File

@ -330,7 +330,10 @@ LLModel::EModelStatus load_face_from_dom_triangles(
// VFExtents change
face.mExtents[0].set(v[0], v[1], v[2]);
face.mExtents[1].set(v[0], v[1], v[2]);
point_map.clear();
verts.clear();
indices.clear();
point_map.clear();
}
}

View File

@ -1386,6 +1386,16 @@ LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin):
fromLLSD(skin);
}
LLMeshSkinInfo::LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& skin) :
mMeshID(mesh_id),
mPelvisOffset(0.0),
mLockScaleIfJointPosition(false),
mInvalidJointsScrubbed(false),
mJointNumsInitialized(false)
{
fromLLSD(skin);
}
void LLMeshSkinInfo::fromLLSD(LLSD& skin)
{
if (skin.has("joint_names"))

View File

@ -41,12 +41,13 @@ class domMesh;
#define MAX_MODEL_FACES 8
LL_ALIGN_PREFIX(16)
class LLMeshSkinInfo
class LLMeshSkinInfo : public LLRefCount
{
LL_ALIGN_NEW
public:
LLMeshSkinInfo();
LLMeshSkinInfo(LLSD& data);
LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data);
void fromLLSD(LLSD& data);
LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
void updateHash();
@ -57,6 +58,8 @@ public:
mutable std::vector<S32> mJointNums;
typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t;
matrix_list_t mInvBindMatrix;
// bones/joints position overrides
matrix_list_t mAlternateBindMatrix;
LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);

View File

@ -38,7 +38,8 @@ typedef enum e_chat_source_type
CHAT_SOURCE_AGENT = 1,
CHAT_SOURCE_OBJECT = 2,
CHAT_SOURCE_TELEPORT = 3,
CHAT_SOURCE_UNKNOWN = 4
CHAT_SOURCE_UNKNOWN = 4,
CHAT_SOURCE_REGION = 5,
} EChatSourceType;
typedef enum e_chat_type

View File

@ -203,11 +203,9 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
// it will work fine in case of decrease of space, but if we get more space or text
// becomes longer, label will fail to grow so reinit label's dimentions.
static LLUICachedControl<S32> llcheckboxctrl_hpad("UICheckboxctrlHPad", 0);
LLRect label_rect = mLabel->getRect();
S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad;
label_rect.mRight = label_rect.mLeft + new_width;
mLabel->setRect(label_rect);
S32 new_width = rect.getWidth() - label_rect.mLeft;
mLabel->reshape(new_width, label_rect.getHeight(), TRUE);
S32 label_top = label_rect.mTop;
mLabel->reshapeToFitText(TRUE);

View File

@ -505,6 +505,17 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
}
};
LLFlatListView::~LLFlatListView()
{
for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it)
{
mItemsPanel->removeChild((*it)->first);
(*it)->first->die();
delete *it;
}
mItemPairs.clear();
}
// virtual
void LLFlatListView::draw()
{

View File

@ -299,6 +299,7 @@ public:
virtual S32 notify(const LLSD& info) ;
virtual ~LLFlatListView();
protected:
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */

View File

@ -163,6 +163,7 @@ LLFolderView::LLFolderView(const Params& p)
: LLFolderViewFolder(p),
mScrollContainer( NULL ),
mPopupMenuHandle(),
mMenuFileName(p.options_menu),
mAllowMultiSelect(p.allow_multiselect),
mAllowDrag(p.allow_drag),
mShowEmptyMessage(p.show_empty_message),
@ -182,6 +183,7 @@ LLFolderView::LLFolderView(const Params& p)
mMinWidth(0),
mDragAndDropThisFrame(FALSE),
mCallbackRegistrar(NULL),
mEnableRegistrar(NULL),
mUseEllipses(p.use_ellipses),
mDraggingOverItem(NULL),
mStatusTextBox(NULL),
@ -244,17 +246,6 @@ LLFolderView::LLFolderView(const Params& p)
mStatusTextBox->setFollowsTop();
addChild(mStatusTextBox);
// make the popup menu available
llassert(LLMenuGL::sMenuContainer != NULL);
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (!menu)
{
menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
}
menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
mPopupMenuHandle = menu->getHandle();
mViewModelItem->openItem();
mAreChildrenInited = true; // root folder is a special case due to not being loaded normally, assume that it's inited.
@ -276,6 +267,7 @@ LLFolderView::~LLFolderView( void )
mStatusTextBox = NULL;
if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
mPopupMenuHandle.markDead();
mAutoOpenItems.removeAllNodes();
clearSelection();
@ -1438,22 +1430,56 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
S32 count = mSelectedItems.size();
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
LLMenuGL* menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
if (!menu)
{
if (mCallbackRegistrar)
{
mCallbackRegistrar->pushScope();
}
if (mEnableRegistrar)
{
mEnableRegistrar->pushScope();
}
llassert(LLMenuGL::sMenuContainer != NULL);
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(mMenuFileName, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (!menu)
{
menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
}
menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
mPopupMenuHandle = menu->getHandle();
if (mEnableRegistrar)
{
mEnableRegistrar->popScope();
}
if (mCallbackRegistrar)
{
mCallbackRegistrar->popScope();
}
}
bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected();
if ((handled
&& ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible
&& menu ) &&
if (menu && (handled
&& ( count > 0 && (hasVisibleChildren()) )) && // show menu only if selected items are visible
!hide_folder_menu)
{
if (mCallbackRegistrar)
{
mCallbackRegistrar->pushScope();
}
if (mEnableRegistrar)
{
mEnableRegistrar->pushScope();
}
updateMenuOptions(menu);
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
if (mEnableRegistrar)
{
mEnableRegistrar->popScope();
}
if (mCallbackRegistrar)
{
mCallbackRegistrar->popScope();
@ -1531,7 +1557,7 @@ void LLFolderView::deleteAllChildren()
{
closeRenamer();
if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
mPopupMenuHandle = LLHandle<LLView>();
mPopupMenuHandle.markDead();
mScrollContainer = NULL;
mRenameItem = NULL;
mRenamer = NULL;

View File

@ -235,6 +235,7 @@ public:
bool showItemLinkOverlays() { return mShowItemLinkOverlays; }
void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
void setEnableRegistrar(LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* registrar) { mEnableRegistrar = registrar; }
LLPanel* getParentPanel() { return mParentPanel.get(); }
// DEBUG only
@ -272,6 +273,7 @@ protected:
protected:
LLHandle<LLView> mPopupMenuHandle;
std::string mMenuFileName;
selected_items_t mSelectedItems;
bool mKeyboardSelection,
@ -327,6 +329,7 @@ protected:
LLFolderViewItem* mDraggingOverItem; // See EXT-719
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* mEnableRegistrar;
public:
static F32 sAutoOpenTime;

View File

@ -172,7 +172,7 @@ public:
virtual BOOL removeItem() = 0;
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
virtual BOOL isItemCopyable() const = 0;
virtual bool isItemCopyable(bool can_copy_as_link = true) const = 0;
virtual BOOL copyToClipboard() const = 0;
virtual BOOL cutToClipboard() = 0;
virtual bool isCutToClipboard() { return false; };
@ -419,21 +419,15 @@ public:
mFilter(filter)
{}
virtual ~LLFolderViewModel()
{
delete mSorter;
mSorter = NULL;
delete mFilter;
mFilter = NULL;
}
virtual ~LLFolderViewModel() {}
virtual SortType& getSorter() { return *mSorter; }
virtual const SortType& getSorter() const { return *mSorter; }
virtual void setSorter(const SortType& sorter) { mSorter = new SortType(sorter); requestSortAll(); }
virtual void setSorter(const SortType& sorter) { mSorter.reset(new SortType(sorter)); requestSortAll(); }
virtual FilterType& getFilter() { return *mFilter; }
virtual const FilterType& getFilter() const { return *mFilter; }
virtual void setFilter(const FilterType& filter) { mFilter = new FilterType(filter); }
virtual void setFilter(const FilterType& filter) { mFilter.reset(new FilterType(filter)); }
// By default, we assume the content is available. If a network fetch mechanism is implemented for the model,
// this method needs to be overloaded and return the relevant fetch status.
@ -471,8 +465,8 @@ public:
}
protected:
SortType* mSorter;
FilterType* mFilter;
std::unique_ptr<SortType> mSorter;
std::unique_ptr<FilterType> mFilter;
};
#endif // LLFOLDERVIEWMODEL_H

View File

@ -209,13 +209,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
setPrevalidateInput(p.prevalidate_input_callback());
setPrevalidate(p.prevalidate_callback());
llassert(LLMenuGL::sMenuContainer != NULL);
LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>
("menu_text_editor.xml",
LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
setContextMenu(menu);
}
LLLineEditor::~LLLineEditor()
@ -1567,7 +1560,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
KEY_SHIFT != key &&
KEY_CONTROL != key &&
KEY_ALT != key &&
KEY_CAPSLOCK )
KEY_CAPSLOCK != key)
{
deselect();
}
@ -2637,6 +2630,15 @@ LLWString LLLineEditor::getConvertedText() const
void LLLineEditor::showContextMenu(S32 x, S32 y)
{
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if (!menu)
{
llassert(LLMenuGL::sMenuContainer != NULL);
menu = LLUICtrlFactory::createFromFile<LLContextMenu>
("menu_text_editor.xml",
LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
setContextMenu(menu);
}
if (menu)
{

View File

@ -4087,25 +4087,39 @@ void LLTearOffMenu::closeTearOff()
}
LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p)
: LLMenuItemGL(p),
mBranch( p.branch()->getHandle() )
: LLMenuItemGL(p)
{
mBranch.get()->hide();
mBranch.get()->setParentMenuItem(this);
LLContextMenu* branch = static_cast<LLContextMenu*>(p.branch);
if (branch)
{
mBranch = branch->getHandle();
branch->hide();
branch->setParentMenuItem(this);
}
}
LLContextMenuBranch::~LLContextMenuBranch()
{
if (mBranch.get())
{
mBranch.get()->die();
}
}
// called to rebuild the draw label
void LLContextMenuBranch::buildDrawLabel( void )
{
auto menu = getBranch();
if (menu)
{
// default enablement is this -- if any of the subitems are
// enabled, this item is enabled. JC
U32 sub_count = mBranch.get()->getItemCount();
U32 sub_count = menu->getItemCount();
U32 i;
BOOL any_enabled = FALSE;
for (i = 0; i < sub_count; i++)
{
LLMenuItemGL* item = mBranch.get()->getItem(i);
LLMenuItemGL* item = menu->getItem(i);
item->buildDrawLabel();
if (item->getEnabled() && !item->getDrawTextDisabled() )
{
@ -4127,13 +4141,17 @@ void LLContextMenuBranch::buildDrawLabel( void )
void LLContextMenuBranch::showSubMenu()
{
LLMenuItemGL* menu_item = mBranch.get()->getParentMenuItem();
if (menu_item != NULL && menu_item->getVisible())
auto menu = getBranch();
if(menu)
{
S32 center_x;
S32 center_y;
localPointToScreen(getRect().getWidth(), getRect().getHeight() , &center_x, &center_y);
mBranch.get()->show(center_x, center_y);
LLMenuItemGL* menu_item = menu->getParentMenuItem();
if (menu_item != NULL && menu_item->getVisible())
{
S32 center_x;
S32 center_y;
localPointToScreen(getRect().getWidth(), getRect().getHeight(), &center_x, &center_y);
menu->show(center_x, center_y);
}
}
}
@ -4147,13 +4165,17 @@ void LLContextMenuBranch::setHighlight( BOOL highlight )
{
if (highlight == getHighlight()) return;
LLMenuItemGL::setHighlight(highlight);
if( highlight )
auto menu = getBranch();
if (menu)
{
showSubMenu();
}
else
{
mBranch.get()->hide();
if (highlight)
{
showSubMenu();
}
else
{
menu->hide();
}
}
}

View File

@ -745,8 +745,7 @@ public:
LLContextMenuBranch(const Params&);
virtual ~LLContextMenuBranch()
{}
virtual ~LLContextMenuBranch();
// called to rebuild the draw label
virtual void buildDrawLabel( void );

View File

@ -92,7 +92,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
mMouseDownSignal(NULL),
mMouseUpSignal(NULL)
{
mValue.emptyMap();
mValue = LLSD::emptyMap();
mCurSlider = LLStringUtil::null;
if (mOrientation == HORIZONTAL)

View File

@ -196,7 +196,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mHighlightedItem(-1),
mBorder(NULL),
mSortCallback(NULL),
mPopupMenu(NULL),
mCommentTextView(NULL),
mNumDynamicWidthColumns(0),
mTotalStaticColumnWidth(0),
@ -348,6 +347,13 @@ LLScrollListCtrl::~LLScrollListCtrl()
mItemList.clear();
clearColumns(); //clears columns and deletes headers
delete mIsFriendSignal;
auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
}
@ -1307,14 +1313,14 @@ LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, BOO
}
BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive)
BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive, S32 column)
{
return selectItemByPrefix(utf8str_to_wstring(target), case_sensitive);
return selectItemByPrefix(utf8str_to_wstring(target), case_sensitive, column);
}
// Selects first enabled item that has a name where the name's first part matched the target string.
// Returns false if item not found.
BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive)
BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive, S32 column)
{
BOOL found = FALSE;
@ -1329,7 +1335,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
{
LLScrollListItem* item = *iter;
// Only select enabled items with matching names
LLScrollListCell* cellp = item->getColumn(getSearchColumn());
LLScrollListCell* cellp = item->getColumn(column == -1 ? getSearchColumn() : column);
BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE;
if (select)
{
@ -1352,7 +1358,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
LLScrollListItem* item = *iter;
// Only select enabled items with matching names
LLScrollListCell* cellp = item->getColumn(getSearchColumn());
LLScrollListCell* cellp = item->getColumn(column == -1 ? getSearchColumn() : column);
if (!cellp)
{
continue;
@ -1997,17 +2003,23 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
// create the context menu from the XUI file and display it
std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml";
delete mPopupMenu;
llassert(LLMenuGL::sMenuContainer != NULL);
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (mPopupMenu)
auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
llassert(LLMenuGL::sMenuContainer != NULL);
menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
if (mIsFriendSignal)
{
bool isFriend = *(*mIsFriendSignal)(uuid);
LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend");
LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend");
LLView* addFriendButton = menu->getChild<LLView>("add_friend");
LLView* removeFriendButton = menu->getChild<LLView>("remove_friend");
if (addFriendButton && removeFriendButton)
{
@ -2016,8 +2028,8 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
}
}
mPopupMenu->show(x, y);
LLMenuGL::showPopup(this, mPopupMenu, x, y);
menu->show(x, y);
LLMenuGL::showPopup(this, menu, x, y);
return TRUE;
}
}
@ -3395,3 +3407,42 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien
}
return mIsFriendSignal->connect(cb);
}
bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str)
{
if (filter_str == "" || filter_str == " ")
{
clearHighlightedItems();
return false;
}
bool res = false;
setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red));
std::string filter_str_lc(filter_str);
LLStringUtil::toLower(filter_str_lc);
std::vector<LLScrollListItem*> data = getAllData();
std::vector<LLScrollListItem*>::iterator iter = data.begin();
while (iter != data.end())
{
LLScrollListCell* cell = (*iter)->getColumn(0);
if (cell)
{
std::string value = cell->getValue().asString();
LLStringUtil::toLower(value);
if (value.find(filter_str_lc) == std::string::npos)
{
(*iter)->setHighlighted(false);
}
else
{
(*iter)->setHighlighted(true);
res = true;
}
}
iter++;
}
return res;
}

View File

@ -261,8 +261,8 @@ public:
virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD());
BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); // FALSE if item not found
BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE);
BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE);
BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE, S32 column = -1);
BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE, S32 column = -1);
LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );
const std::string getSelectedItemLabel(S32 column = 0) const;
LLSD getSelectedValue();
@ -419,6 +419,8 @@ public:
void setNeedsSort(bool val = true) { mSorted = !val; }
void dirtyColumns(); // some operation has potentially affected column layout or ordering
bool highlightMatchingItems(const std::string& filter_str);
boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
{
if (!mSortCallback) mSortCallback = new sort_signal_t();
@ -526,7 +528,7 @@ private:
S32 mHighlightedItem;
class LLViewBorder* mBorder;
LLContextMenu *mPopupMenu;
LLHandle<LLContextMenu> mPopupMenuHandle;
LLView *mCommentTextView;

View File

@ -101,7 +101,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
// Spin buttons
LLButton::Params up_button_params(p.up_button);
up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height);
up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
// Click callback starts within the button and ends within the button,
// but LLSpinCtrl handles the action continuosly so subsribers needs to
// be informed about click ending even if outside view, use 'up' instead
up_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
up_button_params.commit_on_capture_lost = true;
@ -110,7 +113,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
LLButton::Params down_button_params(p.down_button);
down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height);
down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.commit_on_capture_lost = true;
mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params);

View File

@ -1442,6 +1442,11 @@ void LLTabContainer::selectLastTab()
void LLTabContainer::selectNextTab()
{
if (mTabList.size() == 0)
{
return;
}
BOOL tab_has_focus = FALSE;
if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus())
{

View File

@ -273,6 +273,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
LLTextBase::~LLTextBase()
{
mSegments.clear();
LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
delete mURLClickSignal;
delete mIsFriendSignal;
delete mIsObjectBlockedSignal;
@ -355,95 +361,113 @@ void LLTextBase::onValueChange(S32 start, S32 end)
{
}
std::vector<LLRect> LLTextBase::getSelctionRects()
{
// Nor supposed to be called without selection
llassert(hasSelection());
llassert(!mLineInfoList.empty());
std::vector<LLRect> selection_rects;
S32 selection_left = llmin(mSelectionStart, mSelectionEnd);
S32 selection_right = llmax(mSelectionStart, mSelectionEnd);
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
// binary search for line that starts before top of visible buffer
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
bool done = false;
// Find the coordinates of the selected area
for (; line_iter != end_iter && !done; ++line_iter)
{
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
// Use F32 otherwise a string of multiple segments
// will accumulate a large error
F32 left_precise = line_iter->mRect.mLeft;
F32 right_precise = line_iter->mRect.mLeft;
for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
{
LLTextSegmentPtr segmentp = *segment_iter;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
if (segment_line_start > segment_line_end) break;
F32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if (selection_left >= segment_line_start)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
left_precise += segment_width;
}
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
right_precise += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
right_precise += segment_width;
break;
}
}
LLRect selection_rect;
selection_rect.mLeft = left_precise;
selection_rect.mRight = right_precise;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
selection_rects.push_back(selection_rect);
}
}
return selection_rects;
}
// Draws the black box behind the selected text
void LLTextBase::drawSelectionBackground()
{
// Draw selection even if we don't have keyboard focus for search/replace
if( hasSelection() && !mLineInfoList.empty())
{
std::vector<LLRect> selection_rects;
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
// binary search for line that starts before top of visible buffer
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
bool done = false;
// Find the coordinates of the selected area
for (;line_iter != end_iter && !done; ++line_iter)
{
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
LLRect selection_rect;
selection_rect.mLeft = line_iter->mRect.mLeft;
selection_rect.mRight = line_iter->mRect.mLeft;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
{
LLTextSegmentPtr segmentp = *segment_iter;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
if (segment_line_start > segment_line_end) break;
S32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if(selection_left >= segment_line_start)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mLeft += segment_width;
}
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
break;
}
}
selection_rects.push_back(selection_rect);
}
}
// Draw selection even if we don't have keyboard focus for search/replace
if (hasSelection() && !mLineInfoList.empty())
{
std::vector<LLRect> selection_rects = getSelctionRects();
// Draw the selection box (we're using a box instead of reversing the colors on the selected text).
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
const LLColor4& color = mSelectedBGColor;
F32 alpha = hasFocus() ? 0.7f : 0.3f;
alpha *= getDrawContext().mAlpha;
LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha);
LLRect content_display_rect = getVisibleDocumentRect();
for (std::vector<LLRect>::iterator rect_it = selection_rects.begin();
rect_it != selection_rects.end();
@ -2551,7 +2575,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
}
S32 pos = getLength();
S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft;
F32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft;
segment_set_t::iterator line_seg_iter;
S32 line_seg_offset;
@ -2563,8 +2587,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
S32 segment_line_start = segmentp->getStart() + line_seg_offset;
S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd) - segment_line_start;
S32 text_width, text_height;
bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height);
F32 text_width;
S32 text_height;
bool newline = segmentp->getDimensionsF32(line_seg_offset, segment_line_length, text_width, text_height);
if(newline)
{
@ -2584,8 +2609,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
S32 offset;
if (!segmentp->canEdit())
{
S32 segment_width, segment_height;
segmentp->getDimensions(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height);
F32 segment_width;
S32 segment_height;
segmentp->getDimensionsF32(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height);
if (round && local_x - start_x > segment_width / 2)
{
offset = segment_line_length;
@ -2632,17 +2658,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
return LLRect();
}
LLRect doc_rect;
// clamp pos to valid values
pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1);
line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare());
doc_rect.mLeft = line_iter->mRect.mLeft;
doc_rect.mBottom = line_iter->mRect.mBottom;
doc_rect.mTop = line_iter->mRect.mTop;
segment_set_t::iterator line_seg_iter;
S32 line_seg_offset;
segment_set_t::iterator cursor_seg_iter;
@ -2650,6 +2670,8 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset);
getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset);
F32 doc_left_precise = line_iter->mRect.mLeft;
while(line_seg_iter != mSegments.end())
{
const LLTextSegmentPtr segmentp = *line_seg_iter;
@ -2657,18 +2679,20 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
if (line_seg_iter == cursor_seg_iter)
{
// cursor advanced to right based on difference in offset of cursor to start of line
S32 segment_width, segment_height;
segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
doc_rect.mLeft += segment_width;
F32 segment_width;
S32 segment_height;
segmentp->getDimensionsF32(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
doc_left_precise += segment_width;
break;
}
else
{
// add remainder of current text segment to cursor position
S32 segment_width, segment_height;
segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
doc_rect.mLeft += segment_width;
F32 segment_width;
S32 segment_height;
segmentp->getDimensionsF32(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
doc_left_precise += segment_width;
// offset will be 0 for all segments after the first
line_seg_offset = 0;
// go to next text segment on this line
@ -2676,6 +2700,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
}
}
LLRect doc_rect;
doc_rect.mLeft = doc_left_precise;
doc_rect.mBottom = line_iter->mRect.mBottom;
doc_rect.mTop = line_iter->mRect.mTop;
// set rect to 0 width
doc_rect.mRight = doc_rect.mLeft;

View File

@ -638,6 +638,8 @@ protected:
return mLabel.getString() + getToolTip();
}
std::vector<LLRect> getSelctionRects();
protected:
// text segmentation and flow
segment_set_t mSegments;

View File

@ -257,7 +257,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
mMouseDownY(0),
mTabsToNextField(p.ignore_tab),
mPrevalidateFunc(p.prevalidate_callback()),
mContextMenu(NULL),
mShowContextMenu(p.show_context_menu),
mEnableTooltipPaste(p.enable_tooltip_paste),
mPassDelete(FALSE),
@ -301,8 +300,13 @@ LLTextEditor::~LLTextEditor()
// Scrollbar is deleted by LLView
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
mUndoStack.clear();
// context menu is owned by menu holder, not us
//delete mContextMenu;
// Mark the menu as dead or its retained in memory till shutdown.
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if(menu)
{
menu->die();
mContextMenuHandle.markDead();
}
}
////////////////////////////////////////////////////////////
@ -2051,12 +2055,19 @@ void LLTextEditor::setEnabled(BOOL enabled)
void LLTextEditor::showContextMenu(S32 x, S32 y)
{
if (!mContextMenu)
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if (!menu)
{
llassert(LLMenuGL::sMenuContainer != NULL);
mContextMenu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_text_editor.xml",
menu = LLUICtrlFactory::createFromFile<LLContextMenu>("menu_text_editor.xml",
LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
if(!menu)
{
LL_WARNS() << "Failed to create menu for LLTextEditor: " << getName() << LL_ENDL;
return;
}
mContextMenuHandle = menu->getHandle();
}
// Route menu to this class
@ -2102,11 +2113,11 @@ void LLTextEditor::showContextMenu(S32 x, S32 y)
}
}
mContextMenu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
mContextMenu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
mContextMenu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
mContextMenu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
mContextMenu->show(screen_x, screen_y, this);
menu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
menu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
menu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
menu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
menu->show(screen_x, screen_y, this);
}

View File

@ -329,7 +329,7 @@ private:
keystroke_signal_t mKeystrokeSignal;
LLTextValidate::validate_func_t mPrevalidateFunc;
LLContextMenu* mContextMenu;
LLHandle<LLContextMenu> mContextMenuHandle;
}; // end class LLTextEditor
// Build time optimization, generate once in .cpp file

View File

@ -127,7 +127,12 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
LLToolBar::~LLToolBar()
{
delete mPopupMenuHandle.get();
auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
delete mButtonAddSignal;
delete mButtonEnterSignal;
delete mButtonLeaveSignal;

View File

@ -1098,7 +1098,7 @@ LLSD LLDXHardware::getDisplayInfo()
}
LCleanup:
if (ret.emptyMap())
if (!ret.isMap() || (ret.size() == 0))
{
LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL;
}

View File

@ -495,7 +495,12 @@ attributedStringInfo getSegments(NSAttributedString *str)
// e.g. OS Window for upload something or Input Window...
// mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit)
mModifiers = [theEvent modifierFlags];
unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
NSString *str_no_modifiers = [theEvent charactersIgnoringModifiers];
unichar ch = 0;
if (str_no_modifiers.length)
{
ch = [str_no_modifiers characterAtIndex:0];
}
bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, ch);
if (acceptsText &&

View File

@ -83,7 +83,7 @@ int createNSApp(int argc, const char **argv);
void setupCocoa();
bool pasteBoardAvailable();
bool copyToPBoard(const unsigned short *str, unsigned int len);
const unsigned short *copyFromPBoard();
unsigned short *copyFromPBoard();
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
short releaseImageCursor(CursorRef ref);
short setImageCursor(CursorRef ref);

View File

@ -49,14 +49,12 @@ void setupCocoa()
if(!inited)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
// when init'ing the Cocoa App window.
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
[pool release];
@autoreleasepool {
// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
// when init'ing the Cocoa App window.
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
}
inited = true;
}
@ -64,13 +62,13 @@ void setupCocoa()
bool copyToPBoard(const unsigned short *str, unsigned int len)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
[pboard clearContents];
NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil];
[pool release];
return [pboard writeObjects:contentsToPaste];
@autoreleasepool {
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
[pboard clearContents];
NSArray *contentsToPaste = [[[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil] autorelease];
return [pboard writeObjects:contentsToPaste];
}
}
bool pasteBoardAvailable()
@ -79,39 +77,39 @@ bool pasteBoardAvailable()
return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
}
const unsigned short *copyFromPBoard()
unsigned short *copyFromPBoard()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
NSString *str = NULL;
BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
if (ok)
{
NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
str = [objToPaste objectAtIndex:0];
}
unichar* temp = (unichar*)calloc([str length]+1, sizeof(unichar));
[str getCharacters:temp];
[pool release];
return temp;
@autoreleasepool {
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
NSString *str = NULL;
BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
if (ok)
{
NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
str = [objToPaste objectAtIndex:0];
}
NSUInteger str_len = [str length];
unichar* temp = (unichar*)calloc(str_len+1, sizeof(unichar));
[str getCharacters:temp range:NSMakeRange(0, str_len)];
return temp;
}
}
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
NSCursor *cursor =
[[[NSCursor alloc]
initWithImage:
[[[NSImage alloc] initWithContentsOfFile:
[NSString stringWithUTF8String:fullpath]
]autorelease]
hotSpot:NSMakePoint(hotspotX, hotspotY)
]retain];
[pool release];
NSCursor *cursor = nil;
@autoreleasepool {
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
cursor =
[[[NSCursor alloc]
initWithImage:
[[[NSImage alloc] initWithContentsOfFile:
[NSString stringWithUTF8String:fullpath]
] autorelease]
hotSpot:NSMakePoint(hotspotX, hotspotY)
] retain];
}
return (CursorRef)cursor;
}
@ -178,10 +176,10 @@ OSErr releaseImageCursor(CursorRef ref)
{
if( ref != NULL )
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSCursor *cursor = (NSCursor*)ref;
[cursor release];
[pool release];
@autoreleasepool {
NSCursor *cursor = (NSCursor*)ref;
[cursor autorelease];
}
}
else
{
@ -195,10 +193,10 @@ OSErr setImageCursor(CursorRef ref)
{
if( ref != NULL )
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSCursor *cursor = (NSCursor*)ref;
[cursor set];
[pool release];
@autoreleasepool {
NSCursor *cursor = (NSCursor*)ref;
[cursor set];
}
}
else
{
@ -419,24 +417,26 @@ void requestUserAttention()
long showAlert(std::string text, std::string title, int type)
{
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
[alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
if (type == 0)
{
[alert addButtonWithTitle:@"Okay"];
} else if (type == 1)
{
[alert addButtonWithTitle:@"Okay"];
[alert addButtonWithTitle:@"Cancel"];
} else if (type == 2)
{
[alert addButtonWithTitle:@"Yes"];
[alert addButtonWithTitle:@"No"];
long ret = 0;
@autoreleasepool {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
[alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
if (type == 0)
{
[alert addButtonWithTitle:@"Okay"];
} else if (type == 1)
{
[alert addButtonWithTitle:@"Okay"];
[alert addButtonWithTitle:@"Cancel"];
} else if (type == 2)
{
[alert addButtonWithTitle:@"Yes"];
[alert addButtonWithTitle:@"No"];
}
ret = [alert runModal];
}
long ret = [alert runModal];
[alert dealloc];
if (ret == NSAlertFirstButtonReturn)
{

View File

@ -668,11 +668,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
if (cgl_err != kCGLNoError )
{
LL_DEBUGS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL;
LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL;
}
else
{
LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
}
}
makeFirstResponder(mWindow, mGLView);
@ -1246,8 +1246,11 @@ BOOL LLWindowMacOSX::isClipboardTextAvailable()
}
BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst)
{
llutf16string str(copyFromPBoard());
{
unsigned short* pboard_data = copyFromPBoard(); // must free returned data
llutf16string str(pboard_data);
free(pboard_data);
dst = utf16str_to_wstring(str);
if (dst != L"")
{
@ -1280,7 +1283,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r
{
if (!mSupportedResolutions)
{
CFArrayRef modes = CGDisplayAvailableModes(mDisplay);
CFArrayRef modes = CGDisplayCopyAllDisplayModes(mDisplay, nullptr);
if(modes != NULL)
{
@ -1319,6 +1322,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r
}
}
}
CFRelease(modes);
}
}

View File

@ -228,6 +228,7 @@ protected:
BOOL mLanguageTextInputAllowed;
LLPreeditor* mPreeditor;
public:
static BOOL sUseMultGL;
friend class LLWindowManager;

View File

@ -3067,18 +3067,54 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
{
LLMutexLock lock(&window_imp->mRawMouseMutex);
S32 speed;
const S32 DEFAULT_SPEED(10);
SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
if (speed == DEFAULT_SPEED)
bool absolute_coordinates = (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE);
if (absolute_coordinates)
{
window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
static S32 prev_absolute_x = 0;
static S32 prev_absolute_y = 0;
S32 absolute_x;
S32 absolute_y;
if ((raw->data.mouse.usFlags & 0x10) == 0x10) // touch screen? touch? Not defined in header
{
// touch screen spams (0,0) coordinates in a number of situations
// (0,0) might need to be filtered
absolute_x = raw->data.mouse.lLastX;
absolute_y = raw->data.mouse.lLastY;
}
else
{
bool v_desktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) == MOUSE_VIRTUAL_DESKTOP;
S32 width = GetSystemMetrics(v_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
S32 height = GetSystemMetrics(v_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
absolute_x = (raw->data.mouse.lLastX / 65535.0f) * width;
absolute_y = (raw->data.mouse.lLastY / 65535.0f) * height;
}
window_imp->mRawMouseDelta.mX += absolute_x - prev_absolute_x;
window_imp->mRawMouseDelta.mY -= absolute_y - prev_absolute_y;
prev_absolute_x = absolute_x;
prev_absolute_y = absolute_y;
}
else
{
window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
S32 speed;
const S32 DEFAULT_SPEED(10);
SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
if (speed == DEFAULT_SPEED)
{
window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
}
else
{
window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
}
}
}
}
@ -4215,7 +4251,10 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes)
if (needs_update)
{
mPreeditor->resetPreedit();
if (preedit_string.length() != 0 || result_string.length() != 0)
{
mPreeditor->resetPreedit();
}
if (result_string.length() > 0)
{

View File

@ -287,9 +287,9 @@ set(viewer_SOURCE_FILES
llfloaternotificationsconsole.cpp
llfloaternotificationstabbed.cpp
llfloateroutfitphotopreview.cpp
llfloateroutfitsnapshot.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
llfloatersimpleoutfitsnapshot.cpp
llfloaterpathfindingcharacters.cpp
llfloaterpathfindingconsole.cpp
llfloaterpathfindinglinksets.cpp
@ -929,9 +929,9 @@ set(viewer_HEADER_FILES
llfloaternotificationsconsole.h
llfloaternotificationstabbed.h
llfloateroutfitphotopreview.h
llfloateroutfitsnapshot.h
llfloaterobjectweights.h
llfloateropenobject.h
llfloatersimpleoutfitsnapshot.h
llfloaterpathfindingcharacters.h
llfloaterpathfindingconsole.h
llfloaterpathfindinglinksets.h
@ -1825,9 +1825,9 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/Release/libcollada14dom22.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libcollada14dom22.dll
${SHARED_LIB_STAGING_DIR}/Debug/libcollada14dom22-d.dll
${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll
${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll
${SHARED_LIB_STAGING_DIR}/Release/openjp2.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjp2.dll
${SHARED_LIB_STAGING_DIR}/Debug/openjp2.dll
${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll

View File

@ -1 +1 @@
6.6.8
6.6.10

View File

@ -4747,7 +4747,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
<string>https://search.[GRID]/viewer/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
</map>
<key>GuidebookURL</key>
<map>
@ -14634,6 +14634,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>MediaSoundsEarLocation</key>
<map>
<key>Comment</key>
<string>Location of the virtual ear for media and sounds</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>VoiceHost</key>
<map>
<key>Comment</key>
@ -16876,5 +16887,16 @@
<key>Value</key>
<string></string>
</map>
<key>DebugSettingsHideDefault</key>
<map>
<key>Comment</key>
<string>Show non-default settings only in Debug Settings list</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
</map>
</llsd>

View File

@ -202,7 +202,7 @@ VARYING vec2 vary_texcoord2;
uniform float env_intensity;
uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
#ifdef HAS_ALPHA_MASK
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
uniform float minimum_alpha;
#endif
@ -227,12 +227,11 @@ void main()
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
diffcol.rgb *= vertex_color.rgb;
#ifdef HAS_ALPHA_MASK
#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND
if (diffcol.a*vertex_color.a < minimum_alpha)
#else
if (diffcol.a < minimum_alpha)
#endif
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
// Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
float bias = 0.001953125; // 1/512, or half an 8-bit quantization (SL-18637)
if (diffcol.a < minimum_alpha-bias)
{
discard;
}

View File

@ -25,6 +25,17 @@
/*[EXTRA_CODE_HERE]*/
// Inputs
VARYING vec4 vary_HazeColor;
VARYING float vary_LightNormPosDot;
uniform sampler2D rainbow_map;
uniform sampler2D halo_map;
uniform float moisture_level;
uniform float droplet_radius;
uniform float ice_level;
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@ -35,11 +46,34 @@ out vec4 frag_data[3];
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
VARYING vec4 vary_HazeColor;
vec3 rainbow(float d)
{
// 'Interesting' values of d are -0.75 .. -0.825, i.e. when view vec nearly opposite of sun vec
// Rainbox tex is mapped with REPEAT, so -.75 as tex coord is same as 0.25. -0.825 -> 0.175. etc.
// SL-13629
// Unfortunately the texture is inverted, so we need to invert the y coord, but keep the 'interesting'
// part within the same 0.175..0.250 range, i.e. d = (1 - d) - 1.575
d = clamp(-0.575 - d, 0.0, 1.0);
// With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
// So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
// space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
float interior_coord = max(0.0, d - 0.25) * 4.2857;
d = clamp(d, 0.0, 0.25) + interior_coord;
float rad = (droplet_radius - 5.0f) / 1024.0f;
return pow(texture2D(rainbow_map, vec2(rad+0.5, d)).rgb, vec3(1.8)) * moisture_level;
}
vec3 halo22(float d)
{
d = clamp(d, 0.1, 1.0);
float v = sqrt(clamp(1 - (d * d), 0, 1));
return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
}
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light);
vec3 srgb_to_linear(vec3 c);
void main()
{
@ -48,14 +82,18 @@ void main()
// the fragment) if the sky wouldn't show up because the clouds
// are fully opaque.
vec4 color;
color = vary_HazeColor;
vec4 color = vary_HazeColor;
float rel_pos_lightnorm = vary_LightNormPosDot;
float optic_d = rel_pos_lightnorm;
vec3 halo_22 = halo22(optic_d);
color.rgb += rainbow(optic_d);
color.rgb += halo_22;
color.rgb *= 2.;
color.rgb = scaleSoftClip(color.rgb);
/// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, 0.0);
// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, 1.0);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog

View File

@ -33,6 +33,7 @@ ATTRIBUTE vec3 position;
// Output parameters
VARYING vec4 vary_HazeColor;
VARYING float vary_LightNormPosDot;
// Inputs
uniform vec3 camPosLocal;
@ -72,27 +73,29 @@ void main()
vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
// Adj position vector to clamp altitude
if (rel_pos.y > 0)
if (rel_pos.y > 0.)
{
rel_pos *= (max_y / rel_pos.y);
}
if (rel_pos.y < 0)
if (rel_pos.y < 0.)
{
rel_pos *= (-32000. / rel_pos.y);
}
// Can normalize then
vec3 rel_pos_norm = normalize(rel_pos);
// Normalized
vec3 rel_pos_norm = normalize(rel_pos);
float rel_pos_len = length(rel_pos);
float rel_pos_len = length(rel_pos);
// Grab this value and pass to frag shader for rainbows
float rel_pos_lightnorm_dot = dot(rel_pos_norm, lightnorm.xyz);
vary_LightNormPosDot = rel_pos_lightnorm_dot;
// Initialize temp variables
vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
vec4 light_atten;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
@ -112,7 +115,7 @@ void main()
combined_haze = exp(-combined_haze * density_dist);
// Compute haze glow
float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
float haze_glow = 1.0 - rel_pos_lightnorm_dot;
// haze_glow is 0 at the sun and increases away from sun
haze_glow = max(haze_glow, .001);
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
@ -123,30 +126,30 @@ void main()
// Add "minimum anti-solar illumination"
// For sun, add to glow. For moon, remove glow entirely. SL-13768
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
vec4 color =
(blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
// Haze color above cloud
vec4 color = (blue_horizon * blue_weight * (sunlight + ambient_color)
+ (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
// Final atmosphere additive
color *= (1. - combined_haze);
// Increase ambient when there are more clouds
vec4 tmpAmbient = ambient_color;
tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
vec4 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
vec4 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
+ (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient));
// Attenuate cloud color by atmosphere
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
// At horizon, blend high altitude sky color towards the darker color below the clouds
color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));
color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
// Haze color above cloud
vary_HazeColor = color;

View File

@ -1,199 +0,0 @@
/**
* @file class2/deferred/skyF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, 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$
*/
uniform mat4 modelview_projection_matrix;
// SKY ////////////////////////////////////////////////////////////////////////
// The vertex shader for creating the atmospheric sky
///////////////////////////////////////////////////////////////////////////////
// Inputs
uniform vec3 camPosLocal;
uniform vec4 lightnorm;
uniform vec4 sunlight_color;
uniform vec4 moonlight_color;
uniform int sun_up_factor;
uniform vec4 ambient_color;
uniform vec4 blue_horizon;
uniform vec4 blue_density;
uniform float haze_horizon;
uniform float haze_density;
uniform float cloud_shadow;
uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
uniform float sun_moon_glow_factor;
uniform vec4 cloud_color;
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
#define frag_data gl_FragData
#endif
VARYING vec3 pos;
/////////////////////////////////////////////////////////////////////////
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
uniform sampler2D rainbow_map;
uniform sampler2D halo_map;
uniform float moisture_level;
uniform float droplet_radius;
uniform float ice_level;
vec3 rainbow(float d)
{
// d is the dot product of view and sun directions, so ranging -1.0..1.0
// 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec
// Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175.
// SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted.
// Rather than replace the texture, we mirror and translate the y tc to keep the colors within the
// interesting range, but in reversed order: i.e. d = (1 - d) - 1.575
d = clamp(-0.575 - d, 0.0, 1.0);
// With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
// So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
// space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
float interior_coord = max(0.0, d - 0.25) * 4.2857;
d = clamp(d, 0.0, 0.25) + interior_coord;
float rad = (droplet_radius - 5.0f) / 1024.0f;
return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
}
vec3 halo22(float d)
{
d = clamp(d, 0.1, 1.0);
float v = sqrt(clamp(1 - (d * d), 0, 1));
return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
}
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light);
void main()
{
// World / view / projection
// Get relative position (offset why?)
vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0);
// Adj position vector to clamp altitude
if (rel_pos.y > 0.)
{
rel_pos *= (max_y / rel_pos.y);
}
if (rel_pos.y < 0.)
{
rel_pos *= (-32000. / rel_pos.y);
}
// Normalized
vec3 rel_pos_norm = normalize(rel_pos);
float rel_pos_len = length(rel_pos);
// Initialize temp variables
vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
vec4 blue_weight = blue_density / combined_haze;
vec4 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y);
sunlight *= exp(-light_atten * off_axis);
// Distance
float density_dist = rel_pos_len * density_multiplier;
// Transparency (-> combined_haze)
// ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
// compiler gets confused.
combined_haze = exp(-combined_haze * density_dist);
// Compute haze glow
float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
haze_glow = 1. - haze_glow;
// haze_glow is 0 at the sun and increases away from sun
haze_glow = max(haze_glow, .001);
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
haze_glow *= glow.x;
// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
haze_glow = pow(haze_glow, glow.z);
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
// Add "minimum anti-solar illumination"
// For sun, add to glow. For moon, remove glow entirely. SL-13768
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
// Haze color above cloud
vec4 color = blue_horizon * blue_weight * (sunlight + ambient_color)
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color);
// Final atmosphere additive
color *= (1. - combined_haze);
// Increase ambient when there are more clouds
// TODO 9/20: DJH what does this do? max(0,(1-ambient)) will change the color
vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
vec4 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient)
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient);
// Attenuate cloud color by atmosphere
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
// At horizon, blend high altitude sky color towards the darker color below the clouds
color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
float optic_d = dot(rel_pos_norm, lightnorm.xyz);
vec3 halo_22 = halo22(optic_d);
color.rgb += rainbow(optic_d);
color.rgb += halo_22;
color.rgb *= 2.;
color.rgb = scaleSoftClip(color.rgb);
// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, 1.0);
frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0);
frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0); // 1.0 in norm.w masks off fog
}

View File

@ -1,42 +0,0 @@
/**
* @file WLSkyV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, 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$
*/
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
// SKY ////////////////////////////////////////////////////////////////////////
// The vertex shader for creating the atmospheric sky
///////////////////////////////////////////////////////////////////////////////
VARYING vec3 pos;
void main()
{
// World / view / projection
pos = position.xyz;
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
}

View File

@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
RenderDelayVBUpdate 1 0

View File

@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
RenderDelayVBUpdate 1 0
@ -80,7 +79,6 @@ RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
RenderAvatarMaxComplexity 1 25000
RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
@ -111,7 +109,6 @@ RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
RenderAvatarMaxComplexity 1 35000
RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
@ -141,7 +138,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
@ -171,7 +167,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -201,7 +196,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -231,7 +225,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -261,7 +254,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -290,7 +282,6 @@ RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -367,7 +358,6 @@ RenderCompressTextures 1 0
// No Pixel Shaders available
//
list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
@ -380,7 +370,6 @@ RenderShadowDetail 0 0
// No Vertex Shaders available
//
list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
@ -402,7 +391,6 @@ RenderVBOMappingDisable 1 1
list safe
RenderAnisotropic 1 0
RenderAvatarCloth 0 0
RenderAvatarVP 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
RenderObjectBump 0 0
@ -597,7 +585,6 @@ Disregard128DefaultDrawDistance 1 0
// on various ATI chipsets on drivers before 8.2
list ATIOldDriver
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
// Avoid driver crashes with some features on Linux with old ATI drivers
UseOcclusion 0 0

View File

@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
RenderDelayVBUpdate 1 0

View File

@ -96,11 +96,7 @@ void LLAccountingCostManager::accountingCostCoro(std::string url,
LLSD dataToPost = LLSD::emptyMap();
dataToPost[keystr.c_str()] = objectList;
LLAccountingCostObserver* observer = observerHandle.get();
LLUUID transactionId = observer->getTransactionID();
observer = NULL;
LLAccountingCostObserver* observer = NULL;
LLSD results = httpAdapter->postAndSuspend(httpRequest, url, dataToPost);

View File

@ -2912,9 +2912,11 @@ void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferr
bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure)
{
std::string url;
url = getRegion()->getCapability(capName);
if (!getRegion())
{
return false;
}
std::string url = getRegion()->getCapability(capName);
if (url.empty())
{

View File

@ -46,6 +46,7 @@
- (void)dealloc
{
[currentInputLanguage release];
[super dealloc];
}
@ -199,12 +200,14 @@
- (bool) romanScript
{
// How to add support for new languages with the input window:
// Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.)
NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil];
if ([nonRomanScript containsObject:currentInputLanguage])
{
return false;
@autoreleasepool {
// How to add support for new languages with the input window:
// Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.)
NSArray* nonRomanScript = @[@"ja", @"ko", @"zh-Hant", @"zh-Hans"];
if ([nonRomanScript containsObject:currentInputLanguage])
{
return false;
}
}
return true;

View File

@ -3987,7 +3987,7 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo
// existence of AIS as an indicator the fix is present. Does
// not actually use AIS to create the category.
inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel);
LLUUID folder_id = gInventory.createNewCategory(
gInventory.createNewCategory(
parent_id,
LLFolderType::FT_OUTFIT,
new_folder_name,

View File

@ -135,6 +135,10 @@
#include "vlc/libvlc_version.h"
#endif // LL_LINUX
#if LL_DARWIN
#include "llwindowmacosx.h"
#endif
// Third party library includes
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
@ -209,7 +213,7 @@
#include "llcommandlineparser.h"
#include "llfloatermemleak.h"
#include "llfloaterreg.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llfloatersnapshot.h"
#include "llsidepanelinventory.h"
#include "llatmosphere.h"
@ -560,6 +564,7 @@ static void settings_to_globals()
LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));
#if LL_DARWIN
LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL");
gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
#endif
}
@ -1275,7 +1280,6 @@ bool LLAppViewer::init()
//LLSimpleton creations
LLEnvironment::createInstance();
LLEnvironment::getInstance()->initSingleton();
LLWorld::createInstance();
LLSelectMgr::createInstance();
LLViewerCamera::createInstance();
@ -1521,7 +1525,7 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
LLFloaterSimpleOutfitSnapshot::update();
gGLActive = FALSE;
}
}
@ -1725,7 +1729,8 @@ bool LLAppViewer::cleanup()
{
if (!isSecondInstance())
{
LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv");
LLSceneMonitor::instance().dumpToFile(dump_path);
}
LLSceneMonitor::deleteSingleton();
}

View File

@ -102,7 +102,7 @@ LLVector3d LLAudioSourceVO::getPosGlobal() const
bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const
{
static LLCachedControl<S32> ear_mode(gSavedSettings, "VoiceEarLocation", 0);
static LLCachedControl<S32> ear_mode(gSavedSettings, "MediaSoundsEarLocation", 0);
LLVector3d pos_ear;
@ -113,9 +113,6 @@ bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cu
break;
case 1: // avatar
case 2:
// voice support 'mixed' in '2' case with agent's position and camera's rotations
// but it is not defined in settings and uses camera as default
pos_ear = gAgent.getPositionGlobal();
break;

View File

@ -364,11 +364,10 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
}
}
// static
// Called every frame - send render weight requests to every region
void LLAvatarRenderInfoAccountant::idle()
{
if (mRenderInfoScanTimer.hasExpired())
if (mRenderInfoScanTimer.hasExpired() && !LLApp::isExiting())
{
LL_DEBUGS("AvatarRenderInfo") << "Scanning regions for render info updates"
<< LL_ENDL;

View File

@ -41,7 +41,7 @@ class LLBuyCurrencyHTMLHandler :
{
public:
// requests will be throttled from a non-trusted browser
LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_ALLOW ) {}
LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_THROTTLE) {}
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{

View File

@ -650,8 +650,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
{
if(mBuddyInfo.find(agent_id) != mBuddyInfo.end())
{
if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
&& !gAgent.isDoNotDisturb())
if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS))
{
LLSD args;
args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString();
@ -719,11 +718,12 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
// we were tracking someone who went offline
deleteTrackingData();
}
}
if(chat_notify)
{
// Look up the name of this agent for the notification
LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload));
if(chat_notify)
{
// Look up the name of this agent for the notification
LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload));
}
}
mModifyMask |= LLFriendObserver::ONLINE;

View File

@ -141,6 +141,18 @@ public:
{
mAvatarNameCacheConnection.disconnect();
}
auto menu = mPopupMenuHandleAvatar.get();
if (menu)
{
menu->die();
mPopupMenuHandleAvatar.markDead();
}
menu = mPopupMenuHandleObject.get();
if (menu)
{
menu->die();
mPopupMenuHandleObject.markDead();
}
}
BOOL handleMouseUp(S32 x, S32 y, MASK mask)
@ -567,36 +579,6 @@ public:
BOOL postBuild()
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2));
registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2));
registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandleAvatar = menu->getHandle();
}
else
{
LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL;
}
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandleObject = menu->getHandle();
}
else
{
LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL;
}
setDoubleClickCallback(boost::bind(&LLChatHistoryHeader::showInspector, this));
setMouseEnterCallback(boost::bind(&LLChatHistoryHeader::showInfoCtrl, this));
@ -650,7 +632,7 @@ public:
void showInspector()
{
if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) return;
if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) return;
if (mSourceType == CHAT_SOURCE_OBJECT)
{
@ -798,6 +780,7 @@ public:
icon->setValue(LLSD("OBJECT_Icon"));
break;
case CHAT_SOURCE_SYSTEM:
case CHAT_SOURCE_REGION:
icon->setValue(LLSD("SL_Logo"));
break;
case CHAT_SOURCE_TELEPORT:
@ -883,13 +866,53 @@ protected:
void showObjectContextMenu(S32 x,S32 y)
{
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleObject.get();
if(menu)
if (!menu)
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandleObject = menu->getHandle();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
}
else
{
LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL;
}
}
else
{
LLMenuGL::showPopup(this, menu, x, y);
}
}
void showAvatarContextMenu(S32 x,S32 y)
{
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleAvatar.get();
if (!menu)
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2));
registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2));
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandleAvatar = menu->getHandle();
}
else
{
LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL;
}
}
if(menu)
{
@ -947,7 +970,7 @@ protected:
void showInfoCtrl()
{
const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType;
const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType;
if (isVisible)
{
const LLRect sticky_rect = mUserNameTextBox->getRect();
@ -1081,10 +1104,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
LLSD LLChatHistory::getValue() const
{
LLSD* text=new LLSD();
text->assign(mEditor->getText());
return *text;
return LLSD(mEditor->getText());
}
LLChatHistory::~LLChatHistory()
@ -1343,7 +1363,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params);
prependNewLineState = false;
}
else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION)
{
LLStyle::Params link_params(body_message_params);
link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));

View File

@ -67,7 +67,6 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)
, mMaxDisplayedCount(p.max_displayed_count)
, mIsNewMessagesState(false)
, mFlashToLitTimer(NULL)
, mContextMenu(NULL)
{
LLButton::Params button_params = p.button;
mButton = LLUICtrlFactory::create<LLButton>(button_params);
@ -79,6 +78,12 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)
LLSysWellChiclet::~LLSysWellChiclet()
{
mFlashToLitTimer->unset();
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if (menu)
{
menu->die();
mContextMenuHandle.markDead();
}
}
void LLSysWellChiclet::setCounter(S32 counter)
@ -145,14 +150,16 @@ void LLSysWellChiclet::updateWidget(bool is_window_empty)
// virtual
BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if(!mContextMenu)
LLContextMenu* menu_avatar = mContextMenuHandle.get();
if(!menu_avatar)
{
createMenu();
menu_avatar = mContextMenuHandle.get();
}
if (mContextMenu)
if (menu_avatar)
{
mContextMenu->show(x, y);
LLMenuGL::showPopup(this, mContextMenu, x, y);
menu_avatar->show(x, y);
LLMenuGL::showPopup(this, menu_avatar, x, y);
}
return TRUE;
}
@ -192,7 +199,7 @@ bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data)
void LLNotificationChiclet::createMenu()
{
if(mContextMenu)
if(mContextMenuHandle.get())
{
LL_WARNS() << "Menu already exists" << LL_ENDL;
return;
@ -207,10 +214,14 @@ void LLNotificationChiclet::createMenu()
boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2));
llassert(LLMenuGL::sMenuContainer != NULL);
mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
("menu_notification_well_button.xml",
LLMenuGL::sMenuContainer,
LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mContextMenuHandle = menu->getHandle();
}
}
/*virtual*/
@ -309,10 +320,19 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p)
, mDefaultWidth(p.rect().getWidth())
, mNewMessagesIcon(NULL)
, mChicletButton(NULL)
, mPopupMenu(NULL)
{
}
LLIMChiclet::~LLIMChiclet()
{
auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
}
/* virtual*/
BOOL LLIMChiclet::postBuild()
{
@ -364,16 +384,18 @@ void LLIMChiclet::setToggleState(bool toggle)
BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if(!mPopupMenu)
auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
if(!menu)
{
createPopupMenu();
menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
}
if (mPopupMenu)
if (menu)
{
updateMenuItems();
mPopupMenu->arrangeAndClear();
LLMenuGL::showPopup(this, mPopupMenu, x, y);
menu->arrangeAndClear();
LLMenuGL::showPopup(this, menu, x, y);
}
return TRUE;
@ -381,15 +403,16 @@ BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
void LLIMChiclet::hidePopupMenu()
{
if (mPopupMenu)
auto menu = mPopupMenuHandle.get();
if (menu)
{
mPopupMenu->setVisible(FALSE);
menu->setVisible(FALSE);
}
}
bool LLIMChiclet::canCreateMenu()
{
if(mPopupMenu)
if(mPopupMenuHandle.get())
{
LL_WARNS() << "Menu already exists" << LL_ENDL;
return false;
@ -1107,8 +1130,13 @@ void LLScriptChiclet::createPopupMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("ScriptChiclet.Action", boost::bind(&LLScriptChiclet::onMenuItemClicked, this, _2));
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
("menu_script_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
}
}
//////////////////////////////////////////////////////////////////////////
@ -1185,8 +1213,12 @@ void LLInvOfferChiclet::createPopupMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("InvOfferChiclet.Action", boost::bind(&LLInvOfferChiclet::onMenuItemClicked, this, _2));
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
("menu_inv_offer_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
}
}
// EOF

View File

@ -252,7 +252,7 @@ public:
{};
virtual ~LLIMChiclet() {};
virtual ~LLIMChiclet();
/**
* It is used for default setting up of chicklet:click handler, etc.
@ -325,7 +325,7 @@ protected:
bool canCreateMenu();
LLMenuGL* mPopupMenu;
LLHandle<LLUICtrl> mPopupMenuHandle;
bool mShowSpeaker;
bool mCounterEnabled;
@ -519,7 +519,7 @@ protected:
bool mIsNewMessagesState;
LLFlashTimer* mFlashToLitTimer;
LLContextMenu* mContextMenu;
LLHandle<LLContextMenu> mContextMenuHandle;
};
class LLNotificationChiclet : public LLSysWellChiclet

View File

@ -39,6 +39,7 @@
#define THROTTLE_PERIOD 5 // required seconds between throttled commands
static LLCommandDispatcherListener sCommandDispatcherListener;
const std::string LLCommandHandler::NAV_TYPE_CLICKED = "clicked";
//---------------------------------------------------------------------------
// Underlying registry for command handlers, not directly accessible.
@ -64,6 +65,9 @@ public:
bool trusted_browser);
private:
void notifySlurlBlocked();
void notifySlurlThrottled();
friend LLSD LLCommandDispatcher::enumerate();
std::map<std::string, LLCommandHandlerInfo> mMap;
};
@ -96,8 +100,6 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
const std::string& nav_type,
bool trusted_browser)
{
static bool slurl_blocked = false;
static bool slurl_throttled = false;
static F64 last_throttle_time = 0.0;
F64 cur_time = 0.0;
std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd);
@ -115,44 +117,45 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
// block request from external browser, but report as
// "handled" because it was well formatted.
LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_blocked)
{
if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
{
// Note: commands can arrive before we initialize everything we need for Notification.
LLNotificationsUtil::add("BlockedSLURL");
}
slurl_blocked = true;
}
notifySlurlBlocked();
return true;
case LLCommandHandler::UNTRUSTED_CLICK_ONLY:
if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED
&& info.mHandler->canHandleUntrusted(params, query_map, web, nav_type))
{
break;
}
LL_WARNS_ONCE("SLURL") << "Blocked SLURL click-only command " << cmd << " from untrusted browser" << LL_ENDL;
notifySlurlBlocked();
return true;
case LLCommandHandler::UNTRUSTED_THROTTLE:
// if users actually click on a link, we don't need to throttle it
// (throttling mechanism is used to prevent an avalanche of clicks via
// javascript
if ( nav_type == "clicked" )
{
break;
}
//skip initial request from external browser before STATE_BROWSER_INIT
if (LLStartUp::getStartupState() == STATE_FIRST)
{
return true;
}
if (!info.mHandler->canHandleUntrusted(params, query_map, web, nav_type))
{
LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
notifySlurlBlocked();
return true;
}
// if users actually click on a link, we don't need to throttle it
// (throttling mechanism is used to prevent an avalanche of clicks via
// javascript
if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED)
{
break;
}
cur_time = LLTimer::getElapsedSeconds();
if (cur_time < last_throttle_time + THROTTLE_PERIOD)
{
// block request from external browser if it happened
// within THROTTLE_PERIOD seconds of the last command
LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_throttled)
{
if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
{
LLNotificationsUtil::add("ThrottledSLURL");
}
slurl_throttled = true;
}
notifySlurlThrottled();
return true;
}
last_throttle_time = cur_time;
@ -163,6 +166,34 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
return info.mHandler->handle(params, query_map, web);
}
void LLCommandHandlerRegistry::notifySlurlBlocked()
{
static bool slurl_blocked = false;
if (!slurl_blocked)
{
if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
{
// Note: commands can arrive before we initialize everything we need for Notification.
LLNotificationsUtil::add("BlockedSLURL");
}
slurl_blocked = true;
}
}
void LLCommandHandlerRegistry::notifySlurlThrottled()
{
static bool slurl_throttled = false;
if (!slurl_throttled)
{
if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
{
// Note: commands can arrive before we initialize everything we need for Notification.
LLNotificationsUtil::add("ThrottledSLURL");
}
slurl_throttled = true;
}
}
//---------------------------------------------------------------------------
// Automatic registration of commands, runs before main()
//---------------------------------------------------------------------------
@ -230,6 +261,7 @@ symbol_info symbols[] =
{
ent(LLCommandHandler::UNTRUSTED_ALLOW), // allow commands from untrusted browsers
ent(LLCommandHandler::UNTRUSTED_BLOCK), // ignore commands from untrusted browsers
ent(LLCommandHandler::UNTRUSTED_CLICK_ONLY), // allow untrusted, but only if clicked
ent(LLCommandHandler::UNTRUSTED_THROTTLE) // allow untrusted, but only a few per min.
};

View File

@ -65,9 +65,12 @@ public:
{
UNTRUSTED_ALLOW, // allow commands from untrusted browsers
UNTRUSTED_BLOCK, // ignore commands from untrusted browsers
UNTRUSTED_CLICK_ONLY, // allow untrusted, but only if clicked
UNTRUSTED_THROTTLE // allow untrusted, but only a few per min.
};
static const std::string NAV_TYPE_CLICKED;
LLCommandHandler(const char* command, EUntrustedAccess untrusted_access);
// Automatically registers object to get called when
// command is executed. All commands can be processed
@ -76,6 +79,13 @@ public:
virtual ~LLCommandHandler();
virtual bool canHandleUntrusted(
const LLSD& params,
const LLSD& query_map,
LLMediaCtrl* web,
const std::string& nav_type)
{ return true; }
virtual bool handle(const LLSD& params,
const LLSD& query_map,
LLMediaCtrl* web) = 0;

View File

@ -87,7 +87,7 @@ public:
virtual BOOL removeItem() { return FALSE; }
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
virtual void move( LLFolderViewModelItem* parent_listener ) { }
virtual BOOL isItemCopyable() const { return FALSE; }
virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; }
virtual BOOL copyToClipboard() const { return FALSE; }
virtual BOOL cutToClipboard() { return FALSE; }
virtual BOOL isClipboardPasteable() const { return FALSE; }

Some files were not shown because too many files have changed in this diff Show More