aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--avatar_lad.xml11454
-rw-r--r--linden/doc/contributions.txt5
-rw-r--r--linden/etc/message.xml20
-rw-r--r--linden/indra/cmake/Boost.cmake4
-rw-r--r--linden/indra/cmake/GStreamer010Plugin.cmake26
-rw-r--r--linden/indra/llaudio/llaudioengine.cpp79
-rw-r--r--linden/indra/llaudio/llaudioengine.h21
-rw-r--r--linden/indra/llaudio/llstreamingaudio.h3
-rw-r--r--linden/indra/llcharacter/llcharacter.cpp4
-rw-r--r--linden/indra/llcharacter/llcharacter.h14
-rw-r--r--linden/indra/llcharacter/llvisualparam.cpp4
-rw-r--r--linden/indra/llcharacter/llvisualparam.h7
-rw-r--r--linden/indra/llcommon/CMakeLists.txt6
-rw-r--r--linden/indra/llcommon/aiaprpool.cpp198
-rw-r--r--linden/indra/llcommon/aiaprpool.h240
-rw-r--r--linden/indra/llcommon/aithreadsafe.h463
-rw-r--r--linden/indra/llcommon/llapp.cpp5
-rw-r--r--linden/indra/llcommon/llapr.cpp299
-rw-r--r--linden/indra/llcommon/llapr.h74
-rw-r--r--linden/indra/llcommon/llavatarname.cpp150
-rw-r--r--linden/indra/llcommon/llavatarname.h105
-rw-r--r--linden/indra/llcommon/llcommon.cpp13
-rw-r--r--linden/indra/llcommon/llcommon.h2
-rw-r--r--linden/indra/llcommon/llerror.cpp5
-rw-r--r--linden/indra/llcommon/llfile.cpp2
-rw-r--r--linden/indra/llcommon/llfindlocale.cpp2
-rw-r--r--linden/indra/llcommon/llfixedbuffer.cpp3
-rw-r--r--linden/indra/llcommon/llmemory.cpp2
-rw-r--r--linden/indra/llcommon/llprocesslauncher.h2
-rw-r--r--linden/indra/llcommon/llscopedvolatileaprpool.h58
-rw-r--r--linden/indra/llcommon/llthread.cpp117
-rw-r--r--linden/indra/llcommon/llthread.h184
-rw-r--r--linden/indra/llcommon/llworkerthread.cpp3
-rw-r--r--linden/indra/llcommon/llworkerthread.h2
-rwxr-xr-xlinden/indra/llcrashlogger/llcrashlogger.cpp3
-rw-r--r--linden/indra/llimage/llimage.cpp2
-rw-r--r--linden/indra/llimage/llimagej2c.cpp15
-rw-r--r--linden/indra/llimage/llimageworker.cpp7
-rw-r--r--linden/indra/llimage/llimageworker.h2
-rw-r--r--linden/indra/llmath/llvolumemgr.cpp4
-rw-r--r--linden/indra/llmessage/CMakeLists.txt2
-rw-r--r--linden/indra/llmessage/llares.cpp17
-rw-r--r--linden/indra/llmessage/llavatarnamecache.cpp859
-rw-r--r--linden/indra/llmessage/llavatarnamecache.h105
-rw-r--r--linden/indra/llmessage/llcachename.h2
-rw-r--r--linden/indra/llmessage/llcurl.cpp2
-rw-r--r--linden/indra/llmessage/lliohttpserver.cpp10
-rw-r--r--linden/indra/llmessage/lliohttpserver.h2
-rw-r--r--linden/indra/llmessage/lliosocket.cpp99
-rw-r--r--linden/indra/llmessage/lliosocket.h33
-rw-r--r--linden/indra/llmessage/llmail.cpp17
-rw-r--r--linden/indra/llmessage/llmail.h4
-rw-r--r--linden/indra/llmessage/llpartdata.cpp90
-rw-r--r--linden/indra/llmessage/llpartdata.h3
-rw-r--r--linden/indra/llmessage/llpumpio.cpp74
-rw-r--r--linden/indra/llmessage/llpumpio.h31
-rw-r--r--linden/indra/llmessage/llurlrequest.cpp25
-rw-r--r--linden/indra/llmessage/message.cpp17
-rwxr-xr-xlinden/indra/llplugin/llpluginclassmedia.cpp34
-rwxr-xr-xlinden/indra/llplugin/llplugininstance.cpp29
-rwxr-xr-xlinden/indra/llplugin/llpluginmessagepipe.cpp28
-rwxr-xr-xlinden/indra/llplugin/llpluginprocesschild.cpp58
-rwxr-xr-xlinden/indra/llplugin/llpluginprocessparent.cpp123
-rwxr-xr-xlinden/indra/llplugin/llpluginprocessparent.h2
-rwxr-xr-xlinden/indra/llplugin/llpluginsharedmemory.cpp11
-rwxr-xr-xlinden/indra/llplugin/llpluginsharedmemory.h3
-rwxr-xr-xlinden/indra/llplugin/slplugin/slplugin.cpp6
-rwxr-xr-xlinden/indra/llvfs/llpidlock.h2
-rw-r--r--linden/indra/llvfs/llvfs.cpp2
-rw-r--r--linden/indra/llwindow/GL/glh_extensions.h2
-rwxr-xr-xlinden/indra/media_plugins/CMakeLists.txt10
-rw-r--r--linden/indra/media_plugins/gstreamer010/CMakeLists.txt6
-rwxr-xr-xlinden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h2
-rwxr-xr-xlinden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp165
-rw-r--r--linden/indra/media_plugins/webkit/linux_volume_catcher.cpp14
-rw-r--r--linden/indra/media_plugins/webkit/windows_volume_catcher.cpp2
-rw-r--r--linden/indra/newview/CMakeLists.txt30
-rw-r--r--linden/indra/newview/app_settings/cloud.xml88
-rw-r--r--linden/indra/newview/app_settings/logcontrol.xml10
-rw-r--r--linden/indra/newview/app_settings/settings.xml47
-rw-r--r--linden/indra/newview/chatbar_as_cmdline.cpp4
-rw-r--r--linden/indra/newview/kokuastreamingaudio.cpp129
-rw-r--r--linden/indra/newview/kokuastreamingaudio.h71
-rw-r--r--linden/indra/newview/llagent.cpp2
-rw-r--r--linden/indra/newview/llappviewer.cpp156
-rw-r--r--linden/indra/newview/llappviewer.h1
-rw-r--r--linden/indra/newview/llappviewerlinux.cpp1
-rw-r--r--linden/indra/newview/llappviewermacosx.cpp1
-rw-r--r--linden/indra/newview/llappviewerwin32.cpp25
-rw-r--r--linden/indra/newview/llcallingcard.cpp50
-rw-r--r--linden/indra/newview/llcallingcard.h3
-rw-r--r--linden/indra/newview/llfilepicker.cpp2
-rw-r--r--linden/indra/newview/llfirstuse.cpp28
-rw-r--r--linden/indra/newview/llfirstuse.h3
-rw-r--r--linden/indra/newview/llfloateractivespeakers.cpp7
-rw-r--r--linden/indra/newview/llfloateractivespeakers.h3
-rw-r--r--linden/indra/newview/llfloateravatarinfo.cpp10
-rw-r--r--linden/indra/newview/llfloateravatarinfo.h4
-rw-r--r--linden/indra/newview/llfloaterchatterbox.cpp3
-rw-r--r--linden/indra/newview/llfloatercustomize.cpp8
-rw-r--r--linden/indra/newview/llfloaterdirectory.cpp4
-rw-r--r--linden/indra/newview/llfloaterdisplayname.cpp224
-rw-r--r--linden/indra/newview/llfloaterdisplayname.h48
-rw-r--r--linden/indra/newview/llfloaterfriends.cpp75
-rw-r--r--linden/indra/newview/llfloaternewim.cpp20
-rw-r--r--linden/indra/newview/llfloatertools.cpp4
-rw-r--r--linden/indra/newview/llhoverview.cpp21
-rw-r--r--linden/indra/newview/llimpanel.cpp66
-rw-r--r--linden/indra/newview/llimpanel.h6
-rw-r--r--linden/indra/newview/llmanipscale.cpp2
-rw-r--r--linden/indra/newview/llnamelistctrl.cpp46
-rw-r--r--linden/indra/newview/llnamelistctrl.h5
-rw-r--r--linden/indra/newview/llnetmap.cpp25
-rw-r--r--linden/indra/newview/lloverlaybar.cpp13
-rw-r--r--linden/indra/newview/llpanelavatar.cpp53
-rw-r--r--linden/indra/newview/llpanelavatar.h8
-rw-r--r--linden/indra/newview/llpaneldirfind.cpp8
-rw-r--r--linden/indra/newview/llpanelgeneral.cpp5
-rw-r--r--linden/indra/newview/llpanelgeneral.h3
-rw-r--r--linden/indra/newview/llpanelgroupgeneral.cpp21
-rw-r--r--linden/indra/newview/llstartup.cpp75
-rw-r--r--linden/indra/newview/llstartup.h4
-rw-r--r--linden/indra/newview/lltexlayer.cpp24
-rw-r--r--linden/indra/newview/lltexturecache.cpp5
-rw-r--r--linden/indra/newview/lltexturecache.h3
-rw-r--r--linden/indra/newview/lltexturefetch.cpp3
-rw-r--r--linden/indra/newview/lltoolpie.cpp7
-rw-r--r--linden/indra/newview/llvieweraudio.cpp125
-rw-r--r--linden/indra/newview/llviewercontrol.cpp38
-rw-r--r--linden/indra/newview/llviewerdisplayname.cpp208
-rw-r--r--linden/indra/newview/llviewerdisplayname.h53
-rw-r--r--linden/indra/newview/llviewermedia.cpp4
-rw-r--r--linden/indra/newview/llviewermedia_streamingaudio.cpp10
-rw-r--r--linden/indra/newview/llviewermedia_streamingaudio.h2
-rw-r--r--linden/indra/newview/llviewermenu.cpp32
-rwxr-xr-xlinden/indra/newview/llviewermessage.cpp27
-rw-r--r--linden/indra/newview/llviewerobject.cpp2
-rw-r--r--linden/indra/newview/llviewerparcelmgr.cpp18
-rw-r--r--linden/indra/newview/llviewerprecompiledheaders.h2
-rw-r--r--linden/indra/newview/llviewerregion.cpp17
-rw-r--r--linden/indra/newview/llviewerregion.h6
-rw-r--r--linden/indra/newview/llvoavatar.cpp186
-rw-r--r--linden/indra/newview/llvoavatar.h7
-rw-r--r--linden/indra/newview/llvoiceclient.cpp2
-rw-r--r--linden/indra/newview/llwatchdog.cpp4
-rw-r--r--linden/indra/newview/llwearable.cpp14
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_customize.xml6
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_display_name.xml42
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_new_im.xml5
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml4
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml15
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml22
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/notifications.xml104
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/panel_avatar.xml5
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml147
-rw-r--r--linden/indra/test/lltemplatemessagebuilder_tut.cpp2
-rw-r--r--linden/indra/test/message_tut.cpp2
-rw-r--r--linden/indra/test/test.cpp16
-rw-r--r--linden/indra/test_apps/llplugintest/demo_plugin.cpp2
-rw-r--r--linden/indra/test_apps/llplugintest/llmediaplugintest.cpp3
-rw-r--r--linden/indra/win_crash_logger/StdAfx.h2
-rw-r--r--linden/indra/win_crash_logger/llcrashloggerwindows.h2
-rw-r--r--linden/indra/win_updater/updater.cpp2
-rwxr-xr-xlinden/install.xml11
164 files changed, 16689 insertions, 1424 deletions
diff --git a/avatar_lad.xml b/avatar_lad.xml
new file mode 100644
index 0000000..245b393
--- /dev/null
+++ b/avatar_lad.xml
@@ -0,0 +1,11454 @@
1<?xml version="1.0" encoding="us-ascii" standalone="yes"?>
2<linden_avatar
3 version="1.0"
4 wearable_definition_version="22">
5 <!-- The wearable_definition_version is checked during asset upload. -->
6 <!-- If you increment it, check indra/lib/python/indra/assetutil.py. -->
7 <skeleton
8 file_name="avatar_skeleton.xml">
9 <attachment_point
10 id="1"
11 group="6"
12 pie_slice="2"
13 name="Chest"
14 joint="mChest"
15 position="0.15 0 -0.1"
16 rotation="0 90 90"
17 visible_in_first_person="true" />
18
19 <attachment_point
20 id="2"
21 group="2"
22 pie_slice="2"
23 name="Skull"
24 joint="mHead"
25 position="0 0 0.15"
26 rotation="0 0 90"
27 visible_in_first_person="false" />
28
29 <attachment_point
30 id="3"
31 group="3"
32 pie_slice="3"
33 name="Left Shoulder"
34 joint="mCollarLeft"
35 position="0 0 0.08"
36 rotation="0 0 0"
37 visible_in_first_person="true" />
38
39 <attachment_point
40 id="4"
41 group="1"
42 pie_slice="1"
43 name="Right Shoulder"
44 joint="mCollarRight"
45 position="0 0 0.08"
46 rotation="0 0 0"
47 visible_in_first_person="true"/>
48
49 <attachment_point
50 id="5"
51 group="4"
52 name="Left Hand"
53 joint="mWristLeft"
54 position="0 0.08 -0.02"
55 rotation="0 0 0"
56 visible_in_first_person="true"
57 max_attachment_offset="1.5" />
58
59 <attachment_point
60 id="6"
61 group="0"
62 name="Right Hand"
63 joint="mWristRight"
64 position="0 -0.08 -0.02"
65 rotation="0 0 0"
66 visible_in_first_person="true"
67 max_attachment_offset="1.5" />
68
69 <attachment_point
70 id="7"
71 group="5"
72 pie_slice="6"
73 name="Left Foot"
74 joint="mFootLeft"
75 position="0 0.0 0.0"
76 rotation="0 0 0"
77 visible_in_first_person="true"/>
78
79 <attachment_point
80 id="8"
81 group="7"
82 pie_slice="6"
83 name="Right Foot"
84 joint="mFootRight"
85 position="0 0.0 0.0"
86 rotation="0 0 0"
87 visible_in_first_person="true"/>
88
89 <attachment_point
90 id="9"
91 group="6"
92 pie_slice="7"
93 name="Spine"
94 joint="mChest"
95 position="-0.15 0 -0.1"
96 rotation="0 -90 90"
97 visible_in_first_person="true" />
98
99 <attachment_point
100 id="10"
101 group="6"
102 pie_slice="6"
103 name="Pelvis"
104 joint="mPelvis"
105 position="0 0 -0.15"
106 rotation="0 0 0"
107 visible_in_first_person="true" />
108
109 <attachment_point
110 id="11"
111 group="2"
112 pie_slice="6"
113 name="Mouth"
114 joint="mHead"
115 position="0.12 0 0.001"
116 rotation="0 0 0"
117 visible_in_first_person="false"/>
118
119 <attachment_point
120 id="12"
121 group="2"
122 pie_slice="7"
123 name="Chin"
124 joint="mHead"
125 position="0.12 0 -0.04"
126 rotation="0 0 0"
127 visible_in_first_person="false" />
128
129 <attachment_point
130 id="13"
131 group="2"
132 pie_slice="4"
133 name="Left Ear"
134 joint="mHead"
135 position="0.015 0.08 0.017"
136 rotation="0 0 0"
137 visible_in_first_person="false" />
138
139 <attachment_point
140 id="14"
141 group="2"
142 pie_slice="0"
143 name="Right Ear"
144 joint="mHead"
145 position="0.015 -0.08 0.017"
146 rotation="0 0 0"
147 visible_in_first_person="false" />
148
149 <attachment_point
150 id="15"
151 group="2"
152 pie_slice="3"
153 name="Left Eyeball"
154 joint="mEyeLeft"
155 position="0 0 0"
156 rotation="0 0 0"
157 visible_in_first_person="false"/>
158
159 <attachment_point
160 id="16"
161 group="2"
162 pie_slice="1"
163 name="Right Eyeball"
164 joint="mEyeRight"
165 position="0 0 0"
166 rotation="0 0 0"
167 visible_in_first_person="false" />
168
169 <attachment_point
170 id="17"
171 group="2"
172 pie_slice="5"
173 name="Nose"
174 joint="mHead"
175 position="0.1 0 0.05"
176 rotation="0 0 0"
177 visible_in_first_person="false"/>
178
179 <attachment_point
180 id="18"
181 group="1"
182 pie_slice="0"
183 name="R Upper Arm"
184 joint="mShoulderRight"
185 position="0.01 -0.13 0.01"
186 rotation="0 0 0"
187 visible_in_first_person="true" />
188
189 <attachment_point
190 id="19"
191 group="1"
192 pie_slice="7"
193 name="R Forearm"
194 joint="mElbowRight"
195 position="0 -0.12 0"
196 rotation="0 0 0"
197 visible_in_first_person="true"/>
198
199 <attachment_point
200 id="20"
201 group="3"
202 pie_slice="4"
203 name="L Upper Arm"
204 joint="mShoulderLeft"
205 position="0.01 0.15 -0.01"
206 rotation="0 0 0"
207 visible_in_first_person="true" />
208
209 <attachment_point
210 id="21"
211 group="3"
212 pie_slice="5"
213 name="L Forearm"
214 joint="mElbowLeft"
215 position="0 0.113 0"
216 rotation="0 0 0"
217 visible_in_first_person="true" />
218
219 <attachment_point
220 id="22"
221 group="7"
222 pie_slice="1"
223 name="Right Hip"
224 joint="mHipRight"
225 position="0 0 0"
226 rotation="0 0 0"
227 visible_in_first_person="true" />
228
229 <attachment_point
230 id="23"
231 group="7"
232 pie_slice="0"
233 name="R Upper Leg"
234 joint="mHipRight"
235 position="-0.017 0.041 -0.310"
236 rotation="0 0 0"
237 visible_in_first_person="true" />
238
239 <attachment_point
240 id="24"
241 group="7"
242 pie_slice="7"
243 name="R Lower Leg"
244 joint="mKneeRight"
245 position="-0.044 -0.007 -0.262"
246 rotation="0 0 0"
247 visible_in_first_person="true" />
248
249 <attachment_point
250 id="25"
251 group="5"
252 pie_slice="3"
253 name="Left Hip"
254 joint="mHipLeft"
255 position="0 0 0"
256 rotation="0 0 0"
257 visible_in_first_person="true" />
258
259 <attachment_point
260 id="26"
261 group="5"
262 pie_slice="4"
263 name="L Upper Leg"
264 joint="mHipLeft"
265 position="-0.019 -0.034 -0.310"
266 rotation="0 0 0"
267 visible_in_first_person="true"/>
268
269 <attachment_point
270 id="27"
271 group="5"
272 pie_slice="5"
273 name="L Lower Leg"
274 joint="mKneeLeft"
275 position="-0.044 -0.007 -0.261"
276 rotation="0 0 0"
277 visible_in_first_person="true" />
278
279 <attachment_point
280 id="28"
281 group="6"
282 pie_slice="5"
283 name="Stomach"
284 joint="mPelvis"
285 position="0.092 0.0 0.088"
286 rotation="0 0 0"
287 visible_in_first_person="true" />
288
289 <attachment_point
290 id="29"
291 group="6"
292 pie_slice="3"
293 name="Left Pec"
294 joint="mTorso"
295 position="0.104 0.082 0.247"
296 rotation="0 0 0"
297 visible_in_first_person="true" />
298
299 <attachment_point
300 id="30"
301 group="6"
302 pie_slice="1"
303 name="Right Pec"
304 joint="mTorso"
305 position="0.104 -0.082 0.247"
306 rotation="0 0 0"
307 visible_in_first_person="true" />
308
309 <attachment_point
310 id="31"
311 group="8"
312 name="Center 2"
313 joint="mScreen"
314 position="0 0 0"
315 rotation="0 0 0"
316 hud="true"
317 max_attachment_offset="2.0"
318 visible_in_first_person="true" />
319
320 <attachment_point
321 id="32"
322 group="8"
323 name="Top Right"
324 joint="mScreen"
325 position="0 -0.5 0.5"
326 rotation="0 0 0"
327 hud="true"
328 max_attachment_offset="2.0"
329 visible_in_first_person="true" />
330
331 <attachment_point
332 id="33"
333 group="8"
334 name="Top"
335 joint="mScreen"
336 position="0 0 0.5"
337 rotation="0 0 0"
338 hud="true"
339 max_attachment_offset="2.0"
340 visible_in_first_person="true" />
341
342 <attachment_point
343 id="34"
344 group="8"
345 name="Top Left"
346 joint="mScreen"
347 position="0 0.5 0.5"
348 rotation="0 0 0"
349 hud="true"
350 max_attachment_offset="2.0"
351 visible_in_first_person="true" />
352
353 <attachment_point
354 id="35"
355 group="8"
356 name="Center"
357 joint="mScreen"
358 position="0 0 0"
359 rotation="0 0 0"
360 hud="true"
361 max_attachment_offset="2.0"
362 visible_in_first_person="true" />
363
364 <attachment_point
365 id="36"
366 group="8"
367 name="Bottom Left"
368 joint="mScreen"
369 position="0 0.5 -0.5"
370 rotation="0 0 0"
371 hud="true"
372 max_attachment_offset="2.0"
373 visible_in_first_person="true" />
374
375 <attachment_point
376 id="37"
377 group="8"
378 name="Bottom"
379 joint="mScreen"
380 position="0 0 -0.5"
381 rotation="0 0 0"
382 hud="true"
383 max_attachment_offset="2.0"
384 visible_in_first_person="true" />
385
386 <attachment_point
387 id="38"
388 group="8"
389 name="Bottom Right"
390 joint="mScreen"
391 position="0 -0.5 -0.5"
392 rotation="0 0 0"
393 hud="true"
394 max_attachment_offset="2.0"
395 visible_in_first_person="true" />
396
397 <attachment_point
398 id="39"
399 group="6"
400 pie_slice="2"
401 name="Chest 2"
402 joint="mChest"
403 position="0.15 0 -0.1"
404 rotation="0 90 90"
405 visible_in_first_person="true" />
406
407 <attachment_point
408 id="40"
409 group="2"
410 pie_slice="2"
411 name="Skull 2"
412 joint="mHead"
413 position="0 0 0.15"
414 rotation="0 0 90"
415 visible_in_first_person="false" />
416
417 <attachment_point
418 id="41"
419 group="3"
420 pie_slice="3"
421 name="Left Shoulder 2"
422 joint="mCollarLeft"
423 position="0 0 0.08"
424 rotation="0 0 0"
425 visible_in_first_person="true" />
426
427 <attachment_point
428 id="42"
429 group="1"
430 pie_slice="1"
431 name="Right Shoulder 2"
432 joint="mCollarRight"
433 position="0 0 0.08"
434 rotation="0 0 0"
435 visible_in_first_person="true"/>
436
437 <attachment_point
438 id="43"
439 group="4"
440 name="Left Hand 2"
441 joint="mWristLeft"
442 position="0 0.08 -0.02"
443 rotation="0 0 0"
444 visible_in_first_person="true"
445 max_attachment_offset="1.5" />
446
447 <attachment_point
448 id="44"
449 group="0"
450 name="Right Hand 2"
451 joint="mWristRight"
452 position="0 -0.08 -0.02"
453 rotation="0 0 0"
454 visible_in_first_person="true"
455 max_attachment_offset="1.5" />
456
457 <attachment_point
458 id="45"
459 group="5"
460 pie_slice="6"
461 name="Left Foot 2"
462 joint="mFootLeft"
463 position="0 0.0 0.0"
464 rotation="0 0 0"
465 visible_in_first_person="true"/>
466
467 <attachment_point
468 id="46"
469 group="7"
470 pie_slice="6"
471 name="Right Foot 2"
472 joint="mFootRight"
473 position="0 0.0 0.0"
474 rotation="0 0 0"
475 visible_in_first_person="true"/>
476
477 <attachment_point
478 id="47"
479 group="6"
480 pie_slice="7"
481 name="Spine 2"
482 joint="mChest"
483 position="-0.15 0 -0.1"
484 rotation="0 -90 90"
485 visible_in_first_person="true" />
486
487 <attachment_point
488 id="48"
489 group="6"
490 pie_slice="6"
491 name="Pelvis 2"
492 joint="mPelvis"
493 position="0 0 -0.15"
494 rotation="0 0 0"
495 visible_in_first_person="true" />
496
497 <attachment_point
498 id="49"
499 group="2"
500 pie_slice="6"
501 name="Mouth 2"
502 joint="mHead"
503 position="0.12 0 0.001"
504 rotation="0 0 0"
505 visible_in_first_person="false"/>
506
507 <attachment_point
508 id="50"
509 group="2"
510 pie_slice="7"
511 name="Chin 2"
512 joint="mHead"
513 position="0.12 0 -0.04"
514 rotation="0 0 0"
515 visible_in_first_person="false" />
516
517 <attachment_point
518 id="51"
519 group="2"
520 pie_slice="4"
521 name="Left Ear 2"
522 joint="mHead"
523 position="0.015 0.08 0.017"
524 rotation="0 0 0"
525 visible_in_first_person="false" />
526
527 <attachment_point
528 id="52"
529 group="2"
530 pie_slice="0"
531 name="Right Ear 2"
532 joint="mHead"
533 position="0.015 -0.08 0.017"
534 rotation="0 0 0"
535 visible_in_first_person="false" />
536
537 <attachment_point
538 id="53"
539 group="2"
540 pie_slice="3"
541 name="Left Eyeball 2"
542 joint="mEyeLeft"
543 position="0 0 0"
544 rotation="0 0 0"
545 visible_in_first_person="false"/>
546
547 <attachment_point
548 id="54"
549 group="2"
550 pie_slice="1"
551 name="Right Eyeball 2"
552 joint="mEyeRight"
553 position="0 0 0"
554 rotation="0 0 0"
555 visible_in_first_person="false" />
556
557 <attachment_point
558 id="55"
559 group="2"
560 pie_slice="5"
561 name="Nose 2"
562 joint="mHead"
563 position="0.1 0 0.05"
564 rotation="0 0 0"
565 visible_in_first_person="false"/>
566
567 <attachment_point
568 id="56"
569 group="1"
570 pie_slice="0"
571 name="R Upper Arm 2"
572 joint="mShoulderRight"
573 position="0.01 -0.13 0.01"
574 rotation="0 0 0"
575 visible_in_first_person="true" />
576
577 <attachment_point
578 id="57"
579 group="1"
580 pie_slice="7"
581 name="R Forearm 2"
582 joint="mElbowRight"
583 position="0 -0.12 0"
584 rotation="0 0 0"
585 visible_in_first_person="true"/>
586
587 <attachment_point
588 id="58"
589 group="3"
590 pie_slice="4"
591 name="L Upper Arm 2"
592 joint="mShoulderLeft"
593 position="0.01 0.15 -0.01"
594 rotation="0 0 0"
595 visible_in_first_person="true" />
596
597 <attachment_point
598 id="59"
599 group="3"
600 pie_slice="5"
601 name="L Forearm 2"
602 joint="mElbowLeft"
603 position="0 0.113 0"
604 rotation="0 0 0"
605 visible_in_first_person="true" />
606
607 <attachment_point
608 id="60"
609 group="7"
610 pie_slice="1"
611 name="Right Hip 2"
612 joint="mHipRight"
613 position="0 0 0"
614 rotation="0 0 0"
615 visible_in_first_person="true" />
616
617 <attachment_point
618 id="61"
619 group="7"
620 pie_slice="0"
621 name="R Upper Leg 2"
622 joint="mHipRight"
623 position="-0.017 0.041 -0.310"
624 rotation="0 0 0"
625 visible_in_first_person="true" />
626
627 <attachment_point
628 id="62"
629 group="7"
630 pie_slice="7"
631 name="R Lower Leg 2"
632 joint="mKneeRight"
633 position="-0.044 -0.007 -0.262"
634 rotation="0 0 0"
635 visible_in_first_person="true" />
636
637 <attachment_point
638 id="63"
639 group="5"
640 pie_slice="3"
641 name="Left Hip 2"
642 joint="mHipLeft"
643 position="0 0 0"
644 rotation="0 0 0"
645 visible_in_first_person="true" />
646
647 <attachment_point
648 id="64"
649 group="5"
650 pie_slice="4"
651 name="L Upper Leg 2"
652 joint="mHipLeft"
653 position="-0.019 -0.034 -0.310"
654 rotation="0 0 0"
655 visible_in_first_person="true"/>
656
657 <attachment_point
658 id="65"
659 group="5"
660 pie_slice="5"
661 name="L Lower Leg 2"
662 joint="mKneeLeft"
663 position="-0.044 -0.007 -0.261"
664 rotation="0 0 0"
665 visible_in_first_person="true" />
666
667 <attachment_point
668 id="66"
669 group="6"
670 pie_slice="5"
671 name="Stomach 2"
672 joint="mPelvis"
673 position="0.092 0.0 0.088"
674 rotation="0 0 0"
675 visible_in_first_person="true" />
676
677 <attachment_point
678 id="67"
679 group="6"
680 pie_slice="3"
681 name="Left Pec 2"
682 joint="mTorso"
683 position="0.104 0.082 0.247"
684 rotation="0 0 0"
685 visible_in_first_person="true" />
686
687 <attachment_point
688 id="68"
689 group="6"
690 pie_slice="1"
691 name="Right Pec 2"
692 joint="mTorso"
693 position="0.104 -0.082 0.247"
694 rotation="0 0 0"
695 visible_in_first_person="true" />
696
697 <param
698 id="32"
699 group="1"
700 wearable="shape"
701 name="Male_Skeleton"
702 label_min="Female"
703 label_max="Male"
704 value_min="0"
705 value_max="1">
706 <param_skeleton>
707 <bone name="mNeck" scale="0 0 .2" />
708 <bone name="mCollarLeft" scale="0 .4 0" />
709 <bone name="mCollarRight" scale="0 .4 0" />
710 <bone name="mShoulderLeft" scale="0 .35 0" />
711 <bone name="mShoulderRight" scale="0 .35 0" />
712 <bone name="mElbowLeft" scale="0 .1 0" />
713 <bone name="mElbowRight" scale="0 .1 0" />
714 <bone name="mChest" scale=".05 .05 .05" />
715 <bone name="mTorso" scale="0 0 .05" />
716 <bone name="mPelvis" scale="0 0 0" />
717 <bone name="mHipLeft" scale=".05 .05 0" />
718 <bone name="mHipRight" scale=".05 .05 0" />
719 <bone name="mKneeLeft" scale=".05 .05 .1" />
720 <bone name="mKneeRight" scale=".05 .05 .1" />
721 </param_skeleton>
722 </param>
723
724 <param
725 id="33"
726 group="0"
727 name="Height"
728 label="Height"
729 wearable="shape"
730 edit_group="shape_body"
731 edit_group_order="1"
732 label_min="Short"
733 label_max="Tall"
734 show_simple="true"
735 value_min="-2.3"
736 value_max="2"
737 camera_distance="2.2">
738 <param_skeleton>
739 <bone name="mNeck" scale="0 0 .02" />
740 <bone name="mCollarLeft" scale="0 0 0" />
741 <bone name="mCollarRight" scale="0 0 0" />
742 <bone name="mShoulderLeft" scale="0 0.08 0" />
743 <bone name="mShoulderRight" scale="0 0.08 0" />
744 <bone name="mElbowLeft" scale="0 0.06 0" />
745 <bone name="mElbowRight" scale="0 0.06 0" />
746 <bone name="mChest" scale="0 0 0.05" />
747 <bone name="mTorso" scale="0 0 0.05" />
748 <bone name="mPelvis" scale="0 0 0" />
749 <bone name="mHipLeft" scale="0 0 0.1" />
750 <bone name="mHipRight" scale="0 0 0.1" />
751 <bone name="mKneeLeft" scale="0 0 0.1" />
752 <bone name="mKneeRight" scale="0 0 0.1" />
753 </param_skeleton>
754 </param>
755
756 <param
757 id="34"
758 group="0"
759 name="Thickness"
760 label="Body Thickness"
761 wearable="shape"
762 edit_group="shape_body"
763 edit_group_order="2"
764 label_min="Body Thin"
765 label_max="Body Thick"
766 show_simple="true"
767 value_min="-0.7"
768 value_max="1.5"
769 camera_distance="1.8">
770 <param_skeleton>
771 <bone name="mNeck" scale="0.1 0.1 0" />
772 <bone name="mCollarLeft" scale="0 0.2 0" />
773 <bone name="mCollarRight" scale="0 0.2 0" />
774 <bone name="mShoulderLeft" scale="0.1 0 0.1" />
775 <bone name="mShoulderRight" scale="0.1 0 0.1" />
776 <bone name="mElbowLeft" scale="0.1 0 0.1" />
777 <bone name="mElbowRight" scale="0.1 0 0.1" />
778 <bone name="mChest" scale="0.1 0.1 0" />
779 <bone name="mTorso" scale="0.1 0.1 0" />
780 <bone name="mPelvis" scale="0.1 0.1 0" />
781 <bone name="mHipLeft" scale="0.13 0.13 0" />
782 <bone name="mHipRight" scale="0.13 0.13 0" />
783 <bone name="mKneeLeft" scale="0.12 0.12 0" />
784 <bone name="mKneeRight" scale="0.12 0.12 0" />
785 </param_skeleton>
786 </param>
787
788 <param
789 id="36"
790 group="0"
791 name="Shoulders"
792 label="Shoulders"
793 wearable="shape"
794 edit_group="shape_torso"
795 edit_group_order="4"
796 label_min="Narrow"
797 label_max="Broad"
798 show_simple="true"
799 value_min="-1.8"
800 value_max="1.4"
801 value_default="-0.5"
802 camera_elevation=".1"
803 camera_distance="1.2"
804 camera_angle="0">
805 <param_skeleton>
806 <bone name="mNeck" scale="0.01 0.03 0" />
807 <bone name="mCollarLeft" scale="0 0 0" offset="0 .02 0" />
808 <bone name="mCollarRight" scale="0 0 0" offset="0 -.02 0" />
809 <bone name="mChest" scale="0.02 0.08 0" />
810 </param_skeleton>
811 </param>
812
813 <param
814 id="37"
815 group="0"
816 name="Hip Width"
817 label="Hip Width"
818 wearable="shape"
819 edit_group="shape_legs"
820 edit_group_order="3"
821 label_min="Narrow"
822 label_max="Wide"
823 show_simple="true"
824 value_min="-3.2"
825 value_max="2.8"
826 camera_distance="1.8">
827 <param_skeleton>
828 <bone name="mPelvis" scale="0 0.1 0" />
829 <bone name="mHipLeft" scale="0 0 0" offset="0 .004 0" />
830 <bone name="mHipRight" scale="0 0 0" offset="0 -.004 0" />
831 </param_skeleton>
832 </param>
833
834 <param
835 id="842"
836 group="0"
837 name="Hip Length"
838 wearable="shape"
839 edit_group="shape_legs"
840 edit_group_order="3.2"
841 label_min="Short hips"
842 label_max="Long Hips"
843 value_min="-1"
844 value_max="1"
845 camera_distance="1.8">
846 <param_skeleton>
847 <bone name="mPelvis" scale="0 0 0.3" />
848 </param_skeleton>
849 </param>
850
851 <param
852 id="38"
853 group="0"
854 name="Torso Length"
855 wearable="shape"
856 edit_group="shape_torso"
857 edit_group_order="11"
858 label_min="Short Torso"
859 label_max="Long Torso"
860 value_min="-1"
861 value_max="1"
862 camera_distance="1.8">
863 <param_skeleton>
864 <bone name="mTorso" scale="0 0 .3" />
865 <bone name="mPelvis" scale="0 0 .1" />
866 <bone name="mHipLeft" scale="0 0 -.1" />
867 <bone name="mHipRight" scale="0 0 -.1" />
868 <bone name="mKneeRight" scale="0 0 -.05" />
869 <bone name="mKneeLeft" scale="0 0 -.05" />
870 </param_skeleton>
871 </param>
872
873 <param
874 id="195"
875 group="1"
876 name="EyeBone_Spread"
877 wearable="shape"
878 edit_group="shape_eyes"
879 label_min="Eyes Together"
880 label_max="Eyes Spread"
881 value_min="-1"
882 value_max="1">
883 <param_skeleton>
884 <bone name="mEyeLeft" scale="0 0 0" offset="0 .009 0" />
885 <bone name="mEyeRight" scale="0 0 0" offset="0 -.009 0" />
886 </param_skeleton>
887 </param>
888
889 <param
890 id="661"
891 group="1"
892 name="EyeBone_Head_Shear"
893 wearable="shape"
894 edit_group="shape_eyes"
895 label_min="Eyes Shear Left Up"
896 label_max="Eyes Shear Right Up"
897 value_min="-2"
898 value_max="2">
899 <param_skeleton>
900 <bone name="mEyeLeft" scale="0 0 0" offset="0 0 .004" />
901 <bone name="mEyeRight" scale="0 0 0" offset="0 0 -.004" />
902 </param_skeleton>
903 </param>
904
905 <param
906 id="772"
907 group="1"
908 name="EyeBone_Head_Elongate"
909 wearable="shape"
910 edit_group="shape_eyes"
911 label_min="Eyes Short Head"
912 label_max="Eyes Long Head"
913 value_min="-1"
914 value_max="1">
915 <param_skeleton>
916 <bone name="mEyeLeft" scale="0 0 0" offset=".016 0 0" />
917 <bone name="mEyeRight" scale="0 0 0" offset=".016 0 0" />
918 </param_skeleton>
919 </param>
920
921 <param
922 id="768"
923 group="1"
924 name="EyeBone_Bug"
925 wearable="shape"
926 edit_group="shape_eyes"
927 label_min="Eyes Sunken"
928 label_max="Eyes Bugged"
929 value_min="-2"
930 value_max="2">
931 <param_skeleton>
932 <bone name="mEyeLeft" scale="0 0 0" offset=".005 0 0" />
933 <bone name="mEyeRight" scale="0 0 0" offset=".005 0 0" />
934 </param_skeleton>
935 </param>
936
937 <param
938 id="655"
939 group="1"
940 name="Head Size"
941 label="Head Size"
942 wearable="shape"
943 edit_group="shape_head"
944 label_min="Small Head"
945 label_max="Big Head"
946 show_simple="true"
947 value_min="-.25"
948 value_max=".10">
949 <param_skeleton>
950 <bone name="mSkull" scale="1 1 1" offset="0 0 0.1" />
951 <bone name="mHead" scale="1 1 1" offset="0 0 0" />
952 <bone name="mEyeLeft" scale="1 1 1" offset="0 0 0" />
953 <bone name="mEyeRight" scale="1 1 1" offset="0 0 0" />
954 </param_skeleton>
955 </param>
956
957 <param
958 id="197"
959 group="1"
960 wearable="shoes"
961 name="Shoe_Heels"
962 edit_group="shoes"
963 label_min="No Heels"
964 label_max="High Heels"
965 value_min="0"
966 value_max="1">
967 <param_skeleton>
968 <bone name="mFootRight" scale="0 0 0" offset="0 0 -.08" />
969 <bone name="mFootLeft" scale="0 0 0" offset="0 0 -.08" />
970 </param_skeleton>
971 </param>
972
973 <param
974 id="502"
975 group="1"
976 wearable="shoes"
977 name="Shoe_Platform"
978 edit_group="shoes"
979 label_min="No Heels"
980 label_max="High Heels"
981 value_min="0"
982 value_max="1">
983 <param_skeleton>
984 <bone name="mFootRight" scale="0 0 0" offset="0 0 -.07" />
985 <bone name="mFootLeft" scale="0 0 0" offset="0 0 -.07" />
986 </param_skeleton>
987 </param>
988
989 <param
990 id="675"
991 group="0"
992 name="Hand Size"
993 wearable="shape"
994 edit_group="shape_torso"
995 edit_group_order="10"
996 label_min="Small Hands"
997 label_max="Large Hands"
998 value_min="-.3"
999 value_max=".3"
1000 camera_elevation=".1"
1001 camera_distance="1.4"
1002 camera_angle="0">
1003 <param_skeleton>
1004 <bone name="mWristRight" scale="1 1 1" offset="0 0 0" />
1005 <bone name="mWristLeft" scale="1 1 1" offset="0 0 0" />
1006 </param_skeleton>
1007 </param>
1008
1009 <param
1010 id="683"
1011 group="0"
1012 name="Neck Thickness"
1013 wearable="shape"
1014 edit_group="shape_torso"
1015 edit_group_order="2"
1016 label_min="Skinny Neck"
1017 label_max="Thick Neck"
1018 value_min="-.4"
1019 value_max=".2"
1020 value_default="-.15"
1021 camera_elevation=".3"
1022 camera_distance=".8"
1023 camera_angle="15">
1024 <param_skeleton>
1025 <bone name="mNeck" scale="1 1 0" offset="0 0 0" />
1026 </param_skeleton>
1027 </param>
1028
1029 <param
1030 id="689"
1031 group="1"
1032 wearable="shape"
1033 name="EyeBone_Big_Eyes"
1034 edit_group="shape_eyes"
1035 label_min="Eyes Back"
1036 label_max="Eyes Forward"
1037 value_min="-1"
1038 value_max="1">
1039 <param_skeleton>
1040 <bone name="mEyeLeft" scale="0 0 0" offset="-.005 0 0" />
1041 <bone name="mEyeRight" scale="0 0 0" offset="-.005 0 0" />
1042 </param_skeleton>
1043 </param>
1044
1045 <param
1046 id="692"
1047 group="0"
1048 name="Leg Length"
1049 wearable="shape"
1050 edit_group="shape_legs"
1051 edit_group_order="2"
1052 label_min="Short Legs"
1053 label_max="Long Legs"
1054 value_min="-1"
1055 value_max="1"
1056 camera_distance="2.5">
1057 <param_skeleton>
1058 <bone name="mHipLeft" scale="0 0 .2" />
1059 <bone name="mHipRight" scale="0 0 .2" />
1060 <bone name="mKneeRight" scale="0 0 .2" />
1061 <bone name="mKneeLeft" scale="0 0 .2" />
1062 </param_skeleton>
1063 </param>
1064
1065 <param
1066 id="693"
1067 group="0"
1068 name="Arm Length"
1069 wearable="shape"
1070 edit_group="shape_torso"
1071 edit_group_order="9"
1072 label_min="Short Arms"
1073 label_max="Long arms"
1074 value_min="-1"
1075 value_max="1"
1076 value_default=".6"
1077 camera_distance="1.5">
1078 <param_skeleton>
1079 <bone name="mShoulderLeft" scale="0 .2 0" />
1080 <bone name="mShoulderRight" scale="0 .2 0" />
1081 <bone name="mElbowRight" scale="0 .3 0" />
1082 <bone name="mElbowLeft" scale="0 .3 0" />
1083 </param_skeleton>
1084 </param>
1085
1086 <param
1087 id="756"
1088 group="0"
1089 name="Neck Length"
1090 wearable="shape"
1091 edit_group="shape_torso"
1092 edit_group_order="3"
1093 label_min="Short Neck"
1094 label_max="Long Neck"
1095 value_min="-1"
1096 value_max="1"
1097 value_default="0"
1098 camera_elevation=".3"
1099 camera_distance=".8"
1100 camera_angle="15">
1101 <param_skeleton>
1102 <bone name="mNeck" scale="0 0 .5" />
1103 </param_skeleton>
1104 </param>
1105 </skeleton>
1106
1107 <mesh
1108 type="hairMesh"
1109 lod="0"
1110 file_name="avatar_hair.llm"
1111 min_pixel_width="320">
1112<!-- begin morph targets -->
1113 <param
1114 id="180"
1115 group="1"
1116 name="Hair_Volume"
1117 label="Hair Volume"
1118 show_simple="true"
1119 wearable="hair"
1120 clothing_morph="true"
1121 edit_group="hair_style"
1122 label_min="Less"
1123 label_max="More"
1124 value_min="0"
1125 value_max="1.3"
1126 camera_elevation=".1"
1127 camera_distance=".5"
1128 camera_angle="20">
1129 <param_morph />
1130 </param>
1131
1132 <param
1133 id="761"
1134 group="1"
1135 name="Hair_Volume_Small"
1136 label="Hair Volume"
1137 show_simple="true"
1138 wearable="hair"
1139 edit_group="hair_style"
1140 label_min="Less"
1141 label_max="More"
1142 value_min="0"
1143 value_max="1.3"
1144 camera_elevation=".1"
1145 camera_distance=".5"
1146 camera_angle="20">
1147 <param_morph />
1148 </param>
1149
1150 <param
1151 id="181"
1152 group="0"
1153 name="Hair_Big_Front"
1154 label="Big Hair Front"
1155 wearable="hair"
1156 edit_group="hair_style"
1157 edit_group_order="5"
1158 label_min="Less"
1159 label_max="More"
1160 value_min="-1"
1161 value_max="1"
1162 value_default="0.14"
1163 camera_elevation=".1"
1164 camera_distance=".5"
1165 camera_angle="90">
1166 <param_morph />
1167 </param>
1168
1169 <param
1170 id="182"
1171 group="0"
1172 name="Hair_Big_Top"
1173 label="Big Hair Top"
1174 wearable="hair"
1175 edit_group="hair_style"
1176 edit_group_order="6"
1177 label_min="Less"
1178 label_max="More"
1179 value_min="-1"
1180 value_max="1"
1181 value_default=".7"
1182 camera_elevation=".1"
1183 camera_distance=".5"
1184 camera_angle="90">
1185 <param_morph />
1186 </param>
1187
1188 <param
1189 id="183"
1190 group="0"
1191 name="Hair_Big_Back"
1192 clothing_morph="true"
1193 label="Big Hair Back"
1194 wearable="hair"
1195 edit_group="hair_style"
1196 edit_group_order="7"
1197 label_min="Less"
1198 label_max="More"
1199 value_min="-1"
1200 value_max="1"
1201 value_default="0.05"
1202 camera_elevation=".1"
1203 camera_distance=".7"
1204 camera_angle="90">
1205 <param_morph />
1206 </param>
1207
1208 <param
1209 id="184"
1210 group="0"
1211 name="Hair_Spiked"
1212 label="Spiked Hair"
1213 show_simple="true"
1214 wearable="hair"
1215 clothing_morph="true"
1216 edit_group="hair_style"
1217 edit_group_order="15"
1218 label_min="No Spikes"
1219 label_max="Big Spikes"
1220 value_min="0"
1221 value_max="1"
1222 camera_elevation=".1"
1223 camera_distance=".5"
1224 camera_angle="20">
1225 <param_morph />
1226 </param>
1227
1228 <param
1229 id="140"
1230 group="0"
1231 name="Hair_Part_Middle"
1232 label="Middle Part"
1233 wearable="hair"
1234 edit_group="hair_style"
1235 edit_group_order="17"
1236 label_min="No Part"
1237 label_max="Part"
1238 value_min="0"
1239 value_max="2"
1240 camera_elevation=".1"
1241 camera_distance=".5"
1242 camera_angle="0">
1243 <param_morph />
1244 </param>
1245
1246 <param
1247 id="141"
1248 group="0"
1249 name="Hair_Part_Right"
1250 label="Right Part"
1251 wearable="hair"
1252 edit_group="hair_style"
1253 edit_group_order="18"
1254 label_min="No Part"
1255 label_max="Part"
1256 value_min="0"
1257 value_max="2"
1258 camera_elevation=".1"
1259 camera_distance=".5"
1260 camera_angle="0">
1261 <param_morph />
1262 </param>
1263
1264 <param
1265 id="142"
1266 group="0"
1267 name="Hair_Part_Left"
1268 label="Left Part"
1269 wearable="hair"
1270 edit_group="hair_style"
1271 edit_group_order="19"
1272 label_min="No Part"
1273 label_max="Part"
1274 value_min="0"
1275 value_max="2"
1276 camera_elevation=".1"
1277 camera_distance=".5"
1278 camera_angle="0">
1279 <param_morph />
1280 </param>
1281
1282 <param
1283 id="143"
1284 group="0"
1285 name="Hair_Sides_Full"
1286 label="Full Hair Sides"
1287 show_simple="true"
1288 wearable="hair"
1289 edit_group="hair_style"
1290 edit_group_order="11"
1291 label_min="Mowhawk"
1292 label_max="Full Sides"
1293 value_min="-4"
1294 value_max="1.5"
1295 value_default="0.125"
1296 camera_elevation=".1"
1297 camera_distance=".5"
1298 camera_angle="20">
1299 <param_morph />
1300 </param>
1301
1302 <param
1303 id="144"
1304 group="1"
1305 name="Bangs_Front_Up"
1306 label="Front Bangs Up"
1307 wearable="hair"
1308 edit_group="hair_style"
1309 label_min="Bangs"
1310 label_max="Bangs Up"
1311 value_min="0"
1312 value_max="1"
1313 camera_elevation=".1"
1314 camera_distance=".5"
1315 camera_angle="20">
1316 <param_morph />
1317 </param>
1318
1319 <param
1320 id="145"
1321 group="1"
1322 clothing_morph="true"
1323 name="Bangs_Front_Down"
1324 label="Front Bangs Down"
1325 wearable="hair"
1326 edit_group="hair_style"
1327 label_min="Bangs"
1328 label_max="Bangs Down"
1329 value_min="0"
1330 value_max="5"
1331 camera_elevation=".1"
1332 camera_distance=".5"
1333 camera_angle="20">
1334 <param_morph />
1335 </param>
1336
1337 <param
1338 id="146"
1339 group="1"
1340 name="Bangs_Sides_Up"
1341 label="Side Bangs Up"
1342 wearable="hair"
1343 edit_group="hair_style"
1344 label_min="Side Bangs"
1345 label_max="Side Bangs Up"
1346 value_min="0"
1347 value_max="1"
1348 camera_elevation=".1"
1349 camera_distance=".5"
1350 camera_angle="20">
1351 <param_morph />
1352 </param>
1353
1354 <param
1355 id="147"
1356 group="1"
1357 clothing_morph="true"
1358 name="Bangs_Sides_Down"
1359 label="Side Bangs Down"
1360 wearable="hair"
1361 edit_group="hair_style"
1362 label_min="Side Bangs"
1363 label_max="Side Bangs Down"
1364 value_min="0"
1365 value_max="2"
1366 camera_elevation=".1"
1367 camera_distance=".5"
1368 camera_angle="20">
1369 <param_morph />
1370 </param>
1371
1372 <param
1373 id="148"
1374 group="1"
1375 name="Bangs_Back_Up"
1376 label="Back Bangs Up"
1377 wearable="hair"
1378 edit_group="hair_style"
1379 label_min="Back Bangs"
1380 label_max="Back Bangs Up"
1381 value_min="0"
1382 value_max="1"
1383 camera_elevation=".1"
1384 camera_distance=".5"
1385 camera_angle="150">
1386 <param_morph />
1387 </param>
1388
1389 <param
1390 id="149"
1391 group="1"
1392 name="Bangs_Back_Down"
1393 label="Back Bangs Down"
1394 clothing_morph="true"
1395 wearable="hair"
1396 edit_group="hair_style"
1397 label_min="Back Bangs"
1398 label_max="Back Bangs Down"
1399 value_min="0"
1400 value_max="2"
1401 camera_elevation=".1"
1402 camera_distance=".5"
1403 camera_angle="150">
1404 <param_morph />
1405 </param>
1406
1407 <param
1408 id="171"
1409 group="1"
1410 name="Hair_Front_Down"
1411 label="Front Hair Down"
1412 wearable="hair"
1413 edit_group="hair_style"
1414 label_min="Front Hair"
1415 label_max="Front Hair Down"
1416 value_min="0"
1417 value_max="1"
1418 camera_elevation=".1"
1419 camera_distance=".5"
1420 camera_angle="20">
1421 <param_morph />
1422 </param>
1423
1424 <param
1425 id="172"
1426 group="1"
1427 name="Hair_Front_Up"
1428 label="Front Hair Up"
1429 wearable="hair"
1430 edit_group="hair_style"
1431 label_min="Front Hair"
1432 label_max="Front Hair Up"
1433 value_min="0"
1434 value_max="1"
1435 camera_elevation=".1"
1436 camera_distance=".5"
1437 camera_angle="20">
1438 <param_morph />
1439 </param>
1440
1441 <param
1442 id="173"
1443 group="1"
1444 name="Hair_Sides_Down"
1445 label="Sides Hair Down"
1446 wearable="hair"
1447 edit_group="hair_style"
1448 label_min="Sides Hair"
1449 label_max="Sides Hair Down"
1450 value_min="0"
1451 value_max="1"
1452 camera_elevation=".1"
1453 camera_distance=".5"
1454 camera_angle="20">
1455 <param_morph />
1456 </param>
1457
1458 <param
1459 id="174"
1460 group="1"
1461 name="Hair_Sides_Up"
1462 label="Sides Hair Up"
1463 wearable="hair"
1464 edit_group="hair_style"
1465 label_min="Sides Hair"
1466 label_max="Sides Hair Up"
1467 value_min="0"
1468 value_max="1"
1469 camera_elevation=".1"
1470 camera_distance=".5"
1471 camera_angle="20">
1472 <param_morph />
1473 </param>
1474
1475 <param
1476 id="175"
1477 group="1"
1478 name="Hair_Back_Down"
1479 label="Back Hair Down"
1480 clothing_morph="true"
1481 wearable="hair"
1482 edit_group="hair_style"
1483 label_min="Back Hair"
1484 label_max="Back Hair Down"
1485 value_min="0"
1486 value_max="3"
1487 camera_elevation=".1"
1488 camera_distance=".5"
1489 camera_angle="150">
1490 <param_morph />
1491 </param>
1492
1493 <param
1494 id="176"
1495 group="1"
1496 name="Hair_Back_Up"
1497 label="Back Hair Up"
1498 wearable="hair"
1499 edit_group="hair_style"
1500 label_min="Back Hair"
1501 label_max="Back Hair Up"
1502 value_min="0"
1503 value_max="1"
1504 camera_elevation=".1"
1505 camera_distance=".5"
1506 camera_angle="150">
1507 <param_morph />
1508 </param>
1509
1510 <param
1511 id="177"
1512 group="0"
1513 name="Hair_Rumpled"
1514 label="Rumpled Hair"
1515 show_simple="true"
1516 wearable="hair"
1517 clothing_morph="true"
1518 edit_group="hair_style"
1519 edit_group_order="14.5"
1520 label_min="Smooth Hair"
1521 label_max="Rumpled Hair"
1522 value_min="0"
1523 value_max="1"
1524 camera_elevation=".1"
1525 camera_distance=".5"
1526 camera_angle="20">
1527 <param_morph />
1528 </param>
1529
1530 <param
1531 id="178"
1532 group="1"
1533 name="Hair_Swept_Back"
1534 label="Swept Back Hair"
1535 wearable="hair"
1536 edit_group="hair_style"
1537 label_min="NotHair"
1538 label_max="Swept Back"
1539 value_min="0"
1540 value_max="1"
1541 camera_elevation=".1"
1542 camera_distance=".5"
1543 camera_angle="90">
1544 <param_morph />
1545 </param>
1546
1547 <param
1548 id="179"
1549 group="1"
1550 name="Hair_Swept_Forward"
1551 label="Swept Forward Hair"
1552 wearable="hair"
1553 edit_group="hair_style"
1554 label_min="Hair"
1555 label_max="Swept Forward"
1556 value_min="0"
1557 value_max="1"
1558 camera_elevation=".1"
1559 camera_distance=".5"
1560 camera_angle="90">
1561 <param_morph />
1562 </param>
1563
1564 <param
1565 id="190"
1566 group="1"
1567 name="Hair_Tilt_Right"
1568 label="Hair Tilted Right"
1569 wearable="hair"
1570 edit_group="hair_style"
1571 label_min="Hair"
1572 label_max="Tilt Right"
1573 value_min="0"
1574 value_max="1"
1575 camera_elevation=".1"
1576 camera_distance=".5"
1577 camera_angle="0">
1578 <param_morph />
1579 </param>
1580
1581 <param
1582 id="191"
1583 group="1"
1584 name="Hair_Tilt_Left"
1585 label="Hair Tilted Left"
1586 wearable="hair"
1587 edit_group="hair_style"
1588 label_min="Hair"
1589 label_max="Tilt Left"
1590 value_min="0"
1591 value_max="1"
1592 camera_elevation=".1"
1593 camera_distance=".5"
1594 camera_angle="0">
1595 <param_morph />
1596 </param>
1597
1598 <param
1599 id="192"
1600 group="0"
1601 name="Bangs_Part_Middle"
1602 label="Part Bangs"
1603 wearable="hair"
1604 edit_group="hair_style"
1605 edit_group_order="20"
1606 label_min="No Part"
1607 label_max="Part Bangs"
1608 value_min="0"
1609 value_max="1"
1610 camera_elevation=".1"
1611 camera_distance=".5"
1612 camera_angle="0">
1613 <param_morph />
1614 </param>
1615
1616 <param
1617 id="640"
1618 group="1"
1619 name="Hair_Egg_Head"
1620 wearable="hair"
1621 edit_group="hair_style"
1622 value_min="-1.3"
1623 value_max="1">
1624 <param_morph />
1625 </param>
1626
1627 <param
1628 id="641"
1629 group="1"
1630 name="Hair_Squash_Stretch_Head"
1631 wearable="hair"
1632 edit_group="hair_style"
1633 value_min="-.5"
1634 value_max="1">
1635 <param_morph />
1636 </param>
1637
1638 <param
1639 id="642"
1640 group="1"
1641 name="Hair_Square_Head"
1642 wearable="hair"
1643 edit_group="hair_style"
1644 value_min="0"
1645 value_max="1">
1646 <param_morph />
1647 </param>
1648
1649 <param
1650 id="643"
1651 group="1"
1652 name="Hair_Round_Head"
1653 wearable="hair"
1654 edit_group="hair_style"
1655 value_min="0"
1656 value_max="1">
1657 <param_morph />
1658 </param>
1659
1660 <param
1661 id="644"
1662 group="1"
1663 name="Hair_Forehead_Round"
1664 wearable="hair"
1665 edit_group="hair_style"
1666 value_min="0"
1667 value_max="1">
1668 <param_morph />
1669 </param>
1670
1671 <param
1672 id="645"
1673 group="1"
1674 name="Hair_Forehead_Slant"
1675 wearable="hair"
1676 edit_group="hair_style"
1677 value_min="0"
1678 value_max="1">
1679 <param_morph />
1680 </param>
1681
1682 <param
1683 id="774"
1684 group="1"
1685 name="Shear_Head_Hair"
1686 wearable="hair"
1687 edit_group="hair_style"
1688 value_min="-2"
1689 value_max="2">
1690 <param_morph />
1691 </param>
1692
1693 <param
1694 id="771"
1695 group="1"
1696 name="Elongate_Head_Hair"
1697 wearable="hair"
1698 edit_group="hair_style"
1699 value_min="-1"
1700 value_max="1">
1701 <param_morph />
1702 </param>
1703
1704 <param
1705 id="674"
1706 group="0"
1707 name="Hair_Shear_Back"
1708 wearable="hair"
1709 edit_group="hair_style"
1710 edit_group_order="12"
1711 label="Shear Back"
1712 label_min="Full Back"
1713 label_max="Sheared Back"
1714 value_min="-1"
1715 value_max="2"
1716 value_default="-0.3"
1717 camera_elevation=".1"
1718 camera_distance=".5"
1719 camera_angle="100">
1720 <param_morph />
1721 </param>
1722
1723 <param
1724 id="762"
1725 group="0"
1726 name="Hair_Shear_Front"
1727 wearable="hair"
1728 edit_group="hair_style"
1729 edit_group_order="11.8"
1730 label="Shear Front"
1731 show_simple="true"
1732 label_min="Full Front"
1733 label_max="Sheared Front"
1734 value_min="0"
1735 value_max="3"
1736 camera_elevation=".1"
1737 camera_distance=".5"
1738 camera_angle="30">
1739 <param_morph />
1740 </param>
1741
1742 <param
1743 id="754"
1744 group="0"
1745 name="Hair_Taper_Back"
1746 wearable="hair"
1747 edit_group="hair_style"
1748 edit_group_order="14"
1749 label="Taper Back"
1750 label_min="Wide Back"
1751 label_max="Narrow Back"
1752 value_min="-1"
1753 value_max="2"
1754 value_default="0"
1755 camera_elevation=".1"
1756 camera_distance=".5"
1757 camera_angle="160">
1758 <param_morph />
1759 </param>
1760
1761 <param
1762 id="755"
1763 group="0"
1764 name="Hair_Taper_Front"
1765 wearable="hair"
1766 edit_group="hair_style"
1767 edit_group_order="13"
1768 label="Taper Front"
1769 label_min="Wide Front"
1770 label_max="Narrow Front"
1771 value_min="-1.5"
1772 value_max="1.5"
1773 value_default="0.05"
1774 camera_elevation=".1"
1775 camera_distance=".5"
1776 camera_angle="20">
1777 <param_morph />
1778 </param>
1779
1780 <param
1781 id="782"
1782 group="1"
1783 clothing_morph="true"
1784 name="Hair_Pigtails_Short"
1785 wearable="hair"
1786 edit_group="hair_style"
1787 value_min="0"
1788 value_max="1">
1789 <param_morph />
1790 </param>
1791
1792 <param
1793 id="783"
1794 group="1"
1795 clothing_morph="true"
1796 name="Hair_Pigtails_Med"
1797 wearable="hair"
1798 edit_group="hair_style"
1799 value_min="0"
1800 value_max="1">
1801 <param_morph />
1802 </param>
1803
1804 <param
1805 id="790"
1806 group="1"
1807 clothing_morph="true"
1808 name="Hair_Pigtails_Medlong"
1809 wearable="hair"
1810 edit_group="hair_style"
1811 value_min="0"
1812 value_max="1">
1813 <param_morph />
1814 </param>
1815
1816 <param
1817 id="784"
1818 group="1"
1819 clothing_morph="true"
1820 name="Hair_Pigtails_Long"
1821 wearable="hair"
1822 edit_group="hair_style"
1823 value_min="0"
1824 value_max="1">
1825 <param_morph />
1826 </param>
1827
1828 <param
1829 id="786"
1830 group="1"
1831 name="Hair_Ponytail_Short"
1832 wearable="hair"
1833 edit_group="hair_style"
1834 value_min="0"
1835 value_max="1">
1836 <param_morph />
1837 </param>
1838
1839 <param
1840 id="787"
1841 group="1"
1842 name="Hair_Ponytail_Med"
1843 wearable="hair"
1844 edit_group="hair_style"
1845 value_min="0"
1846 value_max="1">
1847 <param_morph />
1848 </param>
1849
1850 <param
1851 id="788"
1852 group="1"
1853 name="Hair_Ponytail_Long"
1854 clothing_morph="true"
1855 wearable="hair"
1856 edit_group="hair_style"
1857 value_min="0"
1858 value_max="1">
1859 <param_morph />
1860 </param>
1861
1862<!-- #end morph targets -->
1863 </mesh>
1864
1865 <mesh
1866 type="hairMesh"
1867 lod="1"
1868 file_name="avatar_hair_1.llm"
1869 min_pixel_width="160"
1870 reference="avatar_hair.llm">
1871 </mesh>
1872
1873 <mesh
1874 type="hairMesh"
1875 lod="2"
1876 file_name="avatar_hair_2.llm"
1877 min_pixel_width="80"
1878 reference="avatar_hair.llm">
1879 </mesh>
1880
1881 <mesh
1882 type="hairMesh"
1883 lod="3"
1884 file_name="avatar_hair_3.llm"
1885 min_pixel_width="40"
1886 reference="avatar_hair.llm">
1887 </mesh>
1888
1889 <mesh
1890 type="hairMesh"
1891 lod="4"
1892 file_name="avatar_hair_4.llm"
1893 min_pixel_width="20"
1894 reference="avatar_hair.llm">
1895 </mesh>
1896
1897 <mesh
1898 type="hairMesh"
1899 lod="5"
1900 file_name="avatar_hair_5.llm"
1901 min_pixel_width="0"
1902 reference="avatar_hair.llm">
1903 </mesh>
1904
1905 <mesh
1906 type="headMesh"
1907 lod="0"
1908 file_name="avatar_head.llm"
1909 min_pixel_width="320">
1910<!--
1911 begin morph targets
1912 #############
1913 tweakable morphs
1914 #############
1915 -->
1916 <param
1917 id="1"
1918 group="0"
1919 name="Big_Brow"
1920 label="Brow Size"
1921 wearable="shape"
1922 edit_group="shape_head"
1923 edit_group_order="7"
1924 label_min="Small"
1925 label_max="Large"
1926 value_min="-.3"
1927 value_max="2"
1928 camera_elevation=".1"
1929 camera_distance=".4"
1930 camera_angle="45">
1931 <param_morph />
1932 </param>
1933
1934 <param
1935 id="2"
1936 group="0"
1937 name="Nose_Big_Out"
1938 label="Nose Size"
1939 wearable="shape"
1940 edit_group="shape_nose"
1941 edit_group_order="1"
1942 label_min="Small"
1943 label_max="Large"
1944 show_simple="true"
1945 value_min="-0.8"
1946 value_max="2.5"
1947 camera_elevation=".1"
1948 camera_distance=".35"
1949 camera_angle="50">
1950 <param_morph />
1951 </param>
1952
1953 <param
1954 id="4"
1955 group="0"
1956 name="Broad_Nostrils"
1957 label="Nostril Width"
1958 wearable="shape"
1959 edit_group="shape_nose"
1960 edit_group_order="3"
1961 label_min="Narrow"
1962 label_max="Broad"
1963 value_min="-.5"
1964 value_max="1"
1965 camera_elevation=".1"
1966 camera_distance=".3"
1967 camera_angle="-20">
1968 <param_morph />
1969 </param>
1970
1971 <param
1972 id="759"
1973 group="0"
1974 name="Low_Septum_Nose"
1975 label="Nostril Division"
1976 wearable="shape"
1977 edit_group="shape_nose"
1978 edit_group_order="3.5"
1979 label_min="High"
1980 label_max="Low"
1981 value_min="-1"
1982 value_max="1.5"
1983 value_default="0.5"
1984 camera_elevation=".1"
1985 camera_distance=".3"
1986 camera_angle="-20">
1987 <param_morph />
1988 </param>
1989
1990 <param
1991 id="517"
1992 group="0"
1993 name="Wide_Nose"
1994 label="Nose Width"
1995 wearable="shape"
1996 edit_group="shape_nose"
1997 edit_group_order="2"
1998 label_min="Narrow"
1999 label_max="Wide"
2000 show_simple="true"
2001 value_min="-.5"
2002 value_max="1"
2003 camera_elevation=".1"
2004 camera_distance=".3"
2005 camera_angle="-20">
2006 <param_morph />
2007 </param>
2008
2009 <param
2010 id="5"
2011 group="0"
2012 name="Cleft_Chin"
2013 label="Chin Cleft"
2014 wearable="shape"
2015 edit_group="shape_chin"
2016 edit_group_order="6"
2017 label_min="Round"
2018 label_max="Cleft"
2019 value_min="-.1"
2020 value_max="1"
2021 camera_elevation="0"
2022 camera_distance=".28"
2023 camera_angle="-20">
2024 <param_morph />
2025 </param>
2026
2027 <param
2028 id="6"
2029 group="0"
2030 name="Bulbous_Nose_Tip"
2031 label="Nose Tip Shape"
2032 wearable="shape"
2033 edit_group="shape_nose"
2034 edit_group_order="8"
2035 label_min="Pointy"
2036 label_max="Bulbous"
2037 value_min="-.3"
2038 value_max="1"
2039 camera_elevation=".1"
2040 camera_distance=".35"
2041 camera_angle="15">
2042 <param_morph />
2043 </param>
2044
2045 <param
2046 id="7"
2047 group="0"
2048 name="Weak_Chin"
2049 label="Chin Angle"
2050 wearable="shape"
2051 edit_group="shape_chin"
2052 edit_group_order="1"
2053 label_min="Chin Out"
2054 label_max="Chin In"
2055 value_min="-.5"
2056 value_max=".5"
2057 camera_elevation=".1"
2058 camera_distance=".4"
2059 camera_angle="45">
2060 <param_morph />
2061 </param>
2062
2063 <param
2064 id="8"
2065 group="0"
2066 name="Double_Chin"
2067 label="Chin-Neck"
2068 wearable="shape"
2069 edit_group="shape_chin"
2070 edit_group_order="8"
2071 label_min="Tight Chin"
2072 label_max="Double Chin"
2073 value_min="-.5"
2074 value_max="1.5"
2075 camera_elevation="-.1"
2076 camera_distance=".3"
2077 camera_angle="60">
2078 <param_morph />
2079 </param>
2080
2081 <param
2082 id="10"
2083 group="0"
2084 name="Sunken_Cheeks"
2085 label="Lower Cheeks"
2086 wearable="shape"
2087 edit_group="shape_head"
2088 edit_group_order="9"
2089 label_min="Well-Fed"
2090 label_max="Sunken"
2091 show_simple="true"
2092 value_min="-1.5"
2093 value_max="3"
2094 camera_elevation=".1"
2095 camera_distance=".4"
2096 camera_angle="5">
2097 <param_morph />
2098 </param>
2099
2100 <param
2101 id="11"
2102 group="0"
2103 name="Noble_Nose_Bridge"
2104 label="Upper Bridge"
2105 wearable="shape"
2106 edit_group="shape_nose"
2107 edit_group_order="5"
2108 label_min="Low"
2109 label_max="High"
2110 value_min="-.5"
2111 value_max="1.5"
2112 camera_elevation=".1"
2113 camera_distance=".35"
2114 camera_angle="70">
2115 <param_morph />
2116 </param>
2117
2118 <param
2119 id="758"
2120 group="0"
2121 name="Lower_Bridge_Nose"
2122 label="Lower Bridge"
2123 wearable="shape"
2124 edit_group="shape_nose"
2125 edit_group_order="5.5"
2126 label_min="Low"
2127 label_max="High"
2128 value_min="-1.5"
2129 value_max="1.5"
2130 camera_elevation=".1"
2131 camera_distance=".35"
2132 camera_angle="70">
2133 <param_morph />
2134 </param>
2135
2136 <param
2137 id="12"
2138 group="0"
2139 name="Jowls"
2140 wearable="shape"
2141 edit_group="shape_chin"
2142 edit_group_order="5"
2143 label_min="Less"
2144 label_max="More"
2145 value_min="-.5"
2146 value_max="2.5"
2147 camera_elevation=".1"
2148 camera_distance=".4"
2149 camera_angle="0">
2150 <param_morph />
2151 </param>
2152
2153 <param
2154 id="13"
2155 group="0"
2156 name="Cleft_Chin_Upper"
2157 label="Upper Chin Cleft"
2158 wearable="shape"
2159 edit_group="shape_chin"
2160 edit_group_order="7"
2161 label_min="Round"
2162 label_max="Cleft"
2163 value_min="0"
2164 value_max="1.5"
2165 camera_elevation="0"
2166 camera_distance=".28"
2167 camera_angle="-20">
2168 <param_morph />
2169 </param>
2170
2171 <param
2172 id="14"
2173 group="0"
2174 name="High_Cheek_Bones"
2175 label="Cheek Bones"
2176 wearable="shape"
2177 edit_group="shape_head"
2178 edit_group_order="10"
2179 label_min="Low"
2180 label_max="High"
2181 value_min="-.5"
2182 value_max="1"
2183 camera_elevation=".1"
2184 camera_distance=".3"
2185 camera_angle="-20">
2186 <param_morph />
2187 </param>
2188
2189 <param
2190 id="15"
2191 group="0"
2192 name="Ears_Out"
2193 label="Ear Angle"
2194 wearable="shape"
2195 edit_group="shape_ears"
2196 edit_group_order="2"
2197 label_min="In"
2198 label_max="Out"
2199 value_min="-.5"
2200 value_max="1.5"
2201 camera_elevation=".1"
2202 camera_distance=".3"
2203 camera_angle="-20">
2204 <param_morph />
2205 </param>
2206
2207<!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
2208 <param
2209 id="870"
2210 group="1"
2211 name="Pointy_Eyebrows"
2212 label="Eyebrow Points"
2213 wearable="hair"
2214 edit_group="hair_eyebrows"
2215 edit_group_order="4"
2216 label_min="Smooth"
2217 label_max="Pointy"
2218 value_min="-.5"
2219 value_max="1"
2220 camera_elevation=".1"
2221 camera_distance=".3">
2222 <param_morph />
2223 </param>
2224
2225 <param
2226 id="17"
2227 group="0"
2228 name="Square_Jaw"
2229 label="Jaw Shape"
2230 wearable="shape"
2231 edit_group="shape_chin"
2232 edit_group_order="2"
2233 label_min="Pointy"
2234 label_max="Square"
2235 value_min="-.5"
2236 value_max="1"
2237 camera_distance=".3"
2238 camera_elevation=".04"
2239 camera_angle="-20">
2240 <param_morph />
2241 </param>
2242
2243 <param
2244 id="18"
2245 group="0"
2246 name="Puffy_Upper_Cheeks"
2247 label="Upper Cheeks"
2248 wearable="shape"
2249 edit_group="shape_head"
2250 edit_group_order="8"
2251 label_min="Thin"
2252 label_max="Puffy"
2253 value_min="-1.5"
2254 value_max="2.5"
2255 camera_elevation=".1"
2256 camera_distance=".3"
2257 camera_angle="-20">
2258 <param_morph />
2259 </param>
2260
2261 <param
2262 id="19"
2263 group="0"
2264 name="Upturned_Nose_Tip"
2265 label="Nose Tip Angle"
2266 wearable="shape"
2267 edit_group="shape_nose"
2268 edit_group_order="7"
2269 label_min="Downturned"
2270 label_max="Upturned"
2271 value_min="-1.5"
2272 value_max="1"
2273 camera_elevation=".1"
2274 camera_distance=".35"
2275 camera_angle="15">
2276 <param_morph />
2277 </param>
2278
2279 <param
2280 id="20"
2281 group="0"
2282 name="Bulbous_Nose"
2283 label="Nose Thickness"
2284 wearable="shape"
2285 edit_group="shape_nose"
2286 edit_group_order="4"
2287 label_min="Thin Nose"
2288 label_max="Bulbous Nose"
2289 show_simple="true"
2290 value_min="-.5"
2291 value_max="1.5"
2292 camera_elevation=".1"
2293 camera_distance=".3">
2294 <param_morph />
2295 </param>
2296
2297 <param
2298 id="21"
2299 group="0"
2300 name="Upper_Eyelid_Fold"
2301 label="Upper Eyelid Fold"
2302 wearable="shape"
2303 edit_group="shape_eyes"
2304 edit_group_order="5"
2305 label_min="Uncreased"
2306 label_max="Creased"
2307 value_min="-0.2"
2308 value_max="1.3"
2309 camera_elevation=".1"
2310 camera_distance=".35">
2311 <param_morph />
2312 </param>
2313
2314 <param
2315 id="22"
2316 group="0"
2317 name="Attached_Earlobes"
2318 label="Attached Earlobes"
2319 wearable="shape"
2320 edit_group="shape_ears"
2321 edit_group_order="3"
2322 label_min="Unattached"
2323 label_max="Attached"
2324 value_min="0"
2325 value_max="1"
2326 camera_elevation=".1"
2327 camera_distance=".3"
2328 camera_angle="45">
2329 <param_morph />
2330 </param>
2331
2332 <param
2333 id="23"
2334 group="0"
2335 name="Baggy_Eyes"
2336 label="Eye Bags"
2337 wearable="shape"
2338 edit_group="shape_eyes"
2339 edit_group_order="6"
2340 label_min="Smooth"
2341 label_max="Baggy"
2342 value_min="-.5"
2343 value_max="1.5"
2344 camera_elevation=".1"
2345 camera_distance=".35">
2346 <param_morph />
2347 </param>
2348
2349 <param
2350 id="765"
2351 group="0"
2352 name="Puffy_Lower_Lids"
2353 label="Puffy Eyelids"
2354 wearable="shape"
2355 edit_group="shape_eyes"
2356 edit_group_order="6.1"
2357 label_min="Flat"
2358 label_max="Puffy"
2359 value_min="-.3"
2360 value_max="2.5"
2361 camera_elevation=".1"
2362 camera_distance=".35">
2363 <param_morph />
2364 </param>
2365
2366 <param
2367 id="24"
2368 group="0"
2369 name="Wide_Eyes"
2370 label="Eye Opening"
2371 wearable="shape"
2372 edit_group="shape_eyes"
2373 edit_group_order="1.1"
2374 label_min="Narrow"
2375 label_max="Wide"
2376 value_min="-1.5"
2377 value_max="2"
2378 show_simple="true"
2379 camera_elevation=".1"
2380 camera_distance=".35">
2381 <param_morph />
2382 </param>
2383
2384 <param
2385 id="25"
2386 group="0"
2387 name="Wide_Lip_Cleft"
2388 label="Lip Cleft"
2389 wearable="shape"
2390 edit_group="shape_mouth"
2391 edit_group_order="6"
2392 label_min="Narrow"
2393 label_max="Wide"
2394 value_min="-.8"
2395 value_max="1.5"
2396 camera_elevation="0"
2397 camera_distance=".28">
2398 <param_morph />
2399 </param>
2400
2401 <param
2402 id="764"
2403 group="0"
2404 name="Lip_Cleft_Deep"
2405 label="Lip Cleft Depth"
2406 wearable="shape"
2407 edit_group="shape_mouth"
2408 edit_group_order="5.8"
2409 label_min="Shallow"
2410 label_max="Deep"
2411 value_min="-.5"
2412 value_max="1.2"
2413 camera_elevation="0"
2414 camera_distance=".28">
2415 <param_morph />
2416 </param>
2417
2418 <param
2419 id="26"
2420 group="1"
2421 wearable="shape"
2422 name="Lips_Thin"
2423 edit_group="driven"
2424 value_min="0"
2425 value_max=".7">
2426 <param_morph />
2427 </param>
2428
2429 <param
2430 id="27"
2431 group="0"
2432 name="Wide_Nose_Bridge"
2433 label="Bridge Width"
2434 wearable="shape"
2435 edit_group="shape_nose"
2436 edit_group_order="6"
2437 label_min="Narrow"
2438 label_max="Wide"
2439 value_min="-1.3"
2440 value_max="1.2"
2441 camera_elevation=".1"
2442 camera_distance=".3"
2443 camera_angle="-20">
2444 <param_morph />
2445 </param>
2446
2447 <param
2448 id="28"
2449 group="1"
2450 name="Lips_Fat"
2451 wearable="shape"
2452 edit_group="driven"
2453 value_min="0"
2454 value_max="2">
2455 <param_morph />
2456 </param>
2457
2458 <param
2459 id="29"
2460 group="1"
2461 name="Wide_Upper_Lip"
2462 wearable="shape"
2463 edit_group="driven"
2464 value_min="-.7"
2465 value_max="1.3">
2466 <param_morph />
2467 </param>
2468
2469 <param
2470 id="30"
2471 group="1"
2472 name="Wide_Lower_Lip"
2473 wearable="shape"
2474 edit_group="driven"
2475 value_min="-.7"
2476 value_max="1.3">
2477 <param_morph />
2478 </param>
2479
2480<!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
2481 <param
2482 id="872"
2483 group="1"
2484 name="Arced_Eyebrows"
2485 label="Eyebrow Arc"
2486 wearable="hair"
2487 edit_group="hair_eyebrows"
2488 edit_group_order="3"
2489 label_min="Flat"
2490 label_max="Arced"
2491 value_min="0"
2492 value_max="1">
2493 <param_morph />
2494 </param>
2495
2496<!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1-->
2497 <param
2498 id="871"
2499 group="1"
2500 name="Lower_Eyebrows"
2501 label="Eyebrow Height"
2502 show_simple="true"
2503 wearable="hair"
2504 edit_group="hair_eyebrows"
2505 edit_group_order="2.5"
2506 label_min="Higher"
2507 label_max="Lower"
2508 value_min="-2"
2509 value_max="2">
2510 <param_morph />
2511 </param>
2512
2513 <param
2514 id="35"
2515 group="0"
2516 name="Big_Ears"
2517 label="Ear Size"
2518 wearable="shape"
2519 edit_group="shape_ears"
2520 edit_group_order="1"
2521 label_min="Small"
2522 label_max="Large"
2523 value_min="-1"
2524 value_max="2"
2525 camera_elevation=".1"
2526 camera_distance=".3"
2527 camera_angle="45">
2528 <param_morph />
2529 </param>
2530
2531 <param
2532 id="796"
2533 group="0"
2534 name="Pointy_Ears"
2535 label="Ear Tips"
2536 wearable="shape"
2537 edit_group="shape_ears"
2538 edit_group_order="4"
2539 label_min="Flat"
2540 label_max="Pointy"
2541 value_min="-.4"
2542 value_max="3"
2543 camera_elevation=".1"
2544 camera_distance=".3"
2545 camera_angle="45">
2546 <param_morph />
2547 </param>
2548
2549 <param
2550 id="185"
2551 group="0"
2552 name="Deep_Chin"
2553 label="Chin Depth"
2554 wearable="shape"
2555 edit_group="shape_chin"
2556 edit_group_order="3"
2557 label_min="Shallow"
2558 label_max="Deep"
2559 value_min="-1"
2560 value_max="1"
2561 camera_elevation=".1"
2562 camera_distance=".4"
2563 camera_angle="30">
2564 <param_morph />
2565 </param>
2566
2567 <param
2568 id="186"
2569 group="1"
2570 name="Egg_Head"
2571 label="Egg Head"
2572 wearable="shape"
2573 edit_group="shape_head"
2574 label_min="Chin Heavy"
2575 label_max="Forehead Heavy"
2576 value_min="-1.3"
2577 value_max="1"
2578 camera_elevation=".1"
2579 camera_distance=".5"
2580 camera_angle="20">
2581 <param_morph />
2582 </param>
2583
2584 <param
2585 id="187"
2586 group="1"
2587 name="Squash_Stretch_Head"
2588 label="Squash/Stretch Head"
2589 wearable="shape"
2590 edit_group="shape_head"
2591 label_min="Squash Head"
2592 label_max="Stretch Head"
2593 value_min="-.5"
2594 value_max="1"
2595 camera_elevation=".1"
2596 camera_distance=".5"
2597 camera_angle="20">
2598 <param_morph>
2599 <volume_morph
2600 name="HEAD"
2601 scale="-0.008 -0.006 0.015"/>
2602 </param_morph>
2603 </param>
2604
2605 <param
2606 id="188"
2607 group="1"
2608 name="Square_Head"
2609 wearable="shape"
2610 label_min="Less Square"
2611 label_max="More Square"
2612 value_min="0"
2613 value_max=".7"
2614 camera_elevation=".1"
2615 camera_distance=".5"
2616 camera_angle="20">
2617 <param_morph />
2618 </param>
2619
2620 <param
2621 id="189"
2622 group="1"
2623 wearable="shape"
2624 name="Round_Head"
2625 label_min="Less Round"
2626 label_max="More Round"
2627 value_min="0"
2628 value_max="1"
2629 camera_elevation=".1"
2630 camera_distance=".5"
2631 camera_angle="20">
2632 <param_morph />
2633 </param>
2634
2635 <param
2636 id="194"
2637 group="1"
2638 name="Eye_Spread"
2639 wearable="shape"
2640 edit_group="shape_eyes"
2641 label_min="Eyes Together"
2642 label_max="Eyes Spread"
2643 value_min="-2"
2644 value_max="2">
2645 <param_morph />
2646 </param>
2647
2648 <param
2649 id="400"
2650 sex="male"
2651 group="1"
2652 name="Displace_Hair_Facial"
2653 label="Hair Thickess"
2654 wearable="hair"
2655 edit_group="hair_facial"
2656 label_min="Cropped Hair"
2657 label_max="Bushy Hair"
2658 value_min="0"
2659 value_max="2">
2660 <param_morph />
2661 </param>
2662
2663 <param
2664 id="506"
2665 group="0"
2666 name="Mouth_Height"
2667 wearable="shape"
2668 label="Mouth Position"
2669 show_simple="true"
2670 edit_group="shape_mouth"
2671 edit_group_order="4"
2672 label_min="High"
2673 label_max="Low"
2674 value_min="-2"
2675 value_max="2"
2676 camera_distance=".3"
2677 camera_elevation=".04">
2678 <param_morph />
2679 </param>
2680
2681 <param
2682 id="633"
2683 group="1"
2684 name="Fat_Head"
2685 label="Fat Head"
2686 wearable="shape"
2687 edit_group="shape_body"
2688 label_min="Skinny"
2689 label_max="Fat"
2690 value_min="0"
2691 value_max="1"
2692 camera_elevation=".3">
2693 <param_morph/>
2694 </param>
2695
2696 <param
2697 id="630"
2698 group="1"
2699 name="Forehead_Round"
2700 label="Round Forehead"
2701 wearable="shape"
2702 label_min="Less"
2703 label_max="More"
2704 value_min="0"
2705 value_max="1">
2706 <param_morph />
2707 </param>
2708
2709 <param
2710 id="631"
2711 group="1"
2712 name="Forehead_Slant"
2713 label="Slanted Forehead"
2714 wearable="shape"
2715 label_min="Less"
2716 label_max="More"
2717 value_min="0"
2718 value_max="1">
2719 <param_morph />
2720 </param>
2721
2722 <param
2723 id="650"
2724 group="0"
2725 name="Eyelid_Corner_Up"
2726 label="Outer Eye Corner"
2727 wearable="shape"
2728 edit_group="shape_eyes"
2729 edit_group_order="4"
2730 label_min="Corner Down"
2731 label_max="Corner Up"
2732 value_min="-1.3"
2733 value_max="1.2"
2734 camera_elevation=".1"
2735 camera_distance=".30">
2736 <param_morph />
2737 </param>
2738
2739 <param
2740 id="880"
2741 group="0"
2742 name="Eyelid_Inner_Corner_Up"
2743 label="Inner Eye Corner"
2744 wearable="shape"
2745 edit_group="shape_eyes"
2746 edit_group_order="4.2"
2747 label_min="Corner Down"
2748 label_max="Corner Up"
2749 value_min="-1.3"
2750 value_max="1.2"
2751 camera_elevation=".1"
2752 camera_distance=".30">
2753 <param_morph />
2754 </param>
2755
2756 <param
2757 id="653"
2758 group="0"
2759 name="Tall_Lips"
2760 wearable="shape"
2761 label="Lip Fullness"
2762 show_simple="true"
2763 edit_group="shape_mouth"
2764 edit_group_order="2"
2765 label_min="Less Full"
2766 label_max="More Full"
2767 value_min="-1"
2768 value_max="2"
2769 camera_distance=".3"
2770 camera_elevation=".04">
2771 <param_morph />
2772 </param>
2773
2774 <param
2775 id="656"
2776 group="0"
2777 name="Crooked_Nose"
2778 wearable="shape"
2779 label="Crooked Nose"
2780 edit_group="shape_nose"
2781 edit_group_order="9"
2782 label_min="Nose Left"
2783 label_max="Nose Right"
2784 value_min="-2"
2785 value_max="2"
2786 camera_distance=".3"
2787 camera_elevation=".04"
2788 camera_angle="-20">
2789 <param_morph />
2790 </param>
2791
2792 <param
2793 id="657"
2794 group="1"
2795 name="Smile_Mouth"
2796 wearable="shape"
2797 label="Mouth Corner"
2798 edit_group="shape_mouth"
2799 label_min="Corner Normal"
2800 label_max="Corner Up"
2801 value_min="0"
2802 value_max="1.4"
2803 camera_distance=".3"
2804 camera_elevation=".04">
2805 <param_morph />
2806 </param>
2807
2808 <param
2809 id="658"
2810 group="1"
2811 name="Frown_Mouth"
2812 wearable="shape"
2813 label="Mouth Corner"
2814 edit_group="shape_mouth"
2815 label_min="Corner Normal"
2816 label_max="Corner Down"
2817 value_min="0"
2818 value_max="1.2"
2819 camera_distance=".3"
2820 camera_elevation=".04">
2821 <param_morph />
2822 </param>
2823
2824 <param
2825 id="797"
2826 group="1"
2827 name="Fat_Upper_Lip"
2828 wearable="shape"
2829 label="Fat Upper Lip"
2830 edit_group="shape_mouth"
2831 label_min="Normal Upper"
2832 label_max="Fat Upper"
2833 value_min="0"
2834 value_max="1.5"
2835 camera_distance=".3"
2836 camera_elevation=".04">
2837 <param_morph />
2838 </param>
2839
2840 <param
2841 id="798"
2842 group="1"
2843 name="Fat_Lower_Lip"
2844 wearable="shape"
2845 label="Fat Lower Lip"
2846 edit_group="shape_mouth"
2847 label_min="Normal Lower"
2848 label_max="Fat Lower"
2849 value_min="0"
2850 value_max="1.5"
2851 camera_distance=".3"
2852 camera_elevation=".04">
2853 <param_morph />
2854 </param>
2855
2856 <param
2857 id="660"
2858 group="1"
2859 name="Shear_Head"
2860 wearable="shape"
2861 label="Shear Face"
2862 edit_group="shape_head"
2863 label_min="Shear Left"
2864 label_max="Shear Right"
2865 value_min="-2"
2866 value_max="2"
2867 value_default="0"
2868 camera_distance=".5"
2869 camera_elevation=".04">
2870 <param_morph />
2871 </param>
2872
2873 <param
2874 id="770"
2875 group="1"
2876 name="Elongate_Head"
2877 wearable="shape"
2878 label="Shear Face"
2879 edit_group="shape_head"
2880 label_min="Flat Head"
2881 label_max="Long Head"
2882 value_min="-1"
2883 value_max="1"
2884 value_default="0"
2885 camera_distance=".5"
2886 camera_elevation=".04">
2887 <param_morph>
2888 <volume_morph
2889 name="HEAD"
2890 scale="0.02 0.0 0.0"/>
2891 </param_morph>
2892 </param>
2893
2894 <param
2895 id="663"
2896 group="0"
2897 name="Shift_Mouth"
2898 wearable="shape"
2899 label="Shift Mouth"
2900 edit_group="shape_mouth"
2901 edit_group_order="7"
2902 label_min="Shift Left"
2903 label_max="Shift Right"
2904 value_min="-2"
2905 value_max="2"
2906 value_default="0"
2907 camera_distance=".35"
2908 camera_elevation=".04"
2909 camera_angle="-20">
2910 <param_morph />
2911 </param>
2912
2913 <param
2914 id="664"
2915 group="0"
2916 name="Pop_Eye"
2917 wearable="shape"
2918 label="Eye Pop"
2919 edit_group="shape_eyes"
2920 edit_group_order="8"
2921 label_min="Pop Right Eye"
2922 label_max="Pop Left Eye"
2923 value_min="-1.3"
2924 value_max="1.3"
2925 value_default="0"
2926 camera_elevation=".1"
2927 camera_distance=".35">
2928 <param_morph />
2929 </param>
2930
2931 <param
2932 id="760"
2933 group="0"
2934 name="Jaw_Angle"
2935 wearable="shape"
2936 label="Jaw Angle"
2937 edit_group="shape_chin"
2938 edit_group_order="3.5"
2939 label_min="Low Jaw"
2940 label_max="High Jaw"
2941 value_min="-1.2"
2942 value_max="2"
2943 value_default="0"
2944 camera_distance=".5"
2945 camera_elevation=".04"
2946 camera_angle="70">
2947 <param_morph />
2948 </param>
2949
2950 <param
2951 id="665"
2952 group="0"
2953 name="Jaw_Jut"
2954 wearable="shape"
2955 label="Jaw Jut"
2956 edit_group="shape_chin"
2957 edit_group_order="4"
2958 label_min="Overbite"
2959 label_max="Underbite"
2960 value_min="-2"
2961 value_max="2"
2962 value_default="0"
2963 camera_distance=".5"
2964 camera_elevation=".04"
2965 camera_angle="70">
2966 <param_morph />
2967 </param>
2968
2969 <param
2970 id="686"
2971 group="1"
2972 name="Head_Eyes_Big"
2973 wearable="shape"
2974 label="Eye Size"
2975 edit_group="shape_eyes"
2976 label_min="Beady Eyes"
2977 label_max="Anime Eyes"
2978 show_simple="true"
2979 value_min="-2"
2980 value_max="2"
2981 value_default="0">
2982 <param_morph />
2983 </param>
2984
2985 <param
2986 id="767"
2987 group="1"
2988 name="Bug_Eyed_Head"
2989 wearable="shape"
2990 label="Eye Depth"
2991 edit_group="shape_eyes"
2992 edit_group_order="4.5"
2993 label_min="Sunken Eyes"
2994 label_max="Bug Eyes"
2995 value_min="-2"
2996 value_max="2"
2997 value_default="0">
2998 <param_morph />
2999 </param>
3000
3001<!--
3002 #Fat_Lips = Fat_Lips 34 1 0 1
3003 #Wide_Lips = Wide_Lips 35 1 0 1
3004 #Wide_Nose = Wide_Nose 36 1 0 1
3005 -->
3006<!--
3007 ##############
3008 # Facial Expression morphs
3009 ##############
3010 -->
3011 <param
3012 id="300"
3013 group="1"
3014 name="Express_Closed_Mouth"
3015 value_default="1"
3016 value_min="0"
3017 value_max="1">
3018 <param_morph />
3019 </param>
3020
3021 <param
3022 id="301"
3023 group="1"
3024 name="Express_Tongue_Out"
3025 value_min="0"
3026 value_max="1">
3027 <param_morph />
3028 </param>
3029
3030 <param
3031 id="302"
3032 group="1"
3033 name="Express_Surprise_Emote"
3034 value_min="0"
3035 value_max="1">
3036 <param_morph />
3037 </param>
3038
3039 <param
3040 id="303"
3041 group="1"
3042 name="Express_Wink_Emote"
3043 value_min="0"
3044 value_max="1">
3045 <param_morph />
3046 </param>
3047
3048 <param
3049 id="304"
3050 group="1"
3051 name="Express_Embarrassed_Emote"
3052 value_min="0"
3053 value_max="1">
3054 <param_morph />
3055 </param>
3056
3057 <param
3058 id="305"
3059 group="1"
3060 name="Express_Shrug_Emote"
3061 value_min="0"
3062 value_max="1">
3063 <param_morph />
3064 </param>
3065
3066 <param
3067 id="306"
3068 group="1"
3069 name="Express_Kiss"
3070 value_min="0"
3071 value_max="1">
3072 <param_morph />
3073 </param>
3074
3075 <param
3076 id="307"
3077 group="1"
3078 name="Express_Bored_Emote"
3079 value_min="0"
3080 value_max="1">
3081 <param_morph />
3082 </param>
3083
3084 <param
3085 id="308"
3086 group="1"
3087 name="Express_Repulsed_Emote"
3088 value_min="0"
3089 value_max="1">
3090 <param_morph />
3091 </param>
3092
3093 <param
3094 id="309"
3095 group="1"
3096 name="Express_Disdain"
3097 value_min="0"
3098 value_max="1">
3099 <param_morph />
3100 </param>
3101
3102 <param
3103 id="310"
3104 group="1"
3105 name="Express_Afraid_Emote"
3106 value_min="0"
3107 value_max="1">
3108 <param_morph />
3109 </param>
3110
3111 <param
3112 id="311"
3113 group="1"
3114 name="Express_Worry_Emote"
3115 value_min="0"
3116 value_max="1">
3117 <param_morph />
3118 </param>
3119
3120 <param
3121 id="312"
3122 group="1"
3123 name="Express_Cry_Emote"
3124 value_min="0"
3125 value_max="1">
3126 <param_morph />
3127 </param>
3128
3129 <param
3130 id="313"
3131 group="1"
3132 name="Express_Sad_Emote"
3133 value_min="0"
3134 value_max="1">
3135 <param_morph />
3136 </param>
3137
3138 <param
3139 id="314"
3140 group="1"
3141 name="Express_Anger_Emote"
3142 value_min="0"
3143 value_max="1">
3144 <param_morph />
3145 </param>
3146
3147 <param
3148 id="315"
3149 group="1"
3150 name="Express_Frown"
3151 value_min="0"
3152 value_max="1">
3153 <param_morph />
3154 </param>
3155
3156 <param
3157 id="316"
3158 group="1"
3159 name="Express_Laugh_Emote"
3160 value_min="0"
3161 value_max="1">
3162 <param_morph />
3163 </param>
3164
3165 <param
3166 id="317"
3167 group="1"
3168 name="Express_Toothsmile"
3169 value_min="0"
3170 value_max="1">
3171 <param_morph />
3172 </param>
3173
3174 <param
3175 id="318"
3176 group="1"
3177 name="Express_Smile"
3178 value_min="0"
3179 value_max="1">
3180 <param_morph />
3181 </param>
3182
3183 <param
3184 id="632"
3185 group="1"
3186 name="Express_Open_Mouth"
3187 value_min="0"
3188 value_max="1">
3189 <param_morph />
3190 </param>
3191
3192<!--
3193 ##############
3194 # Lipsync morphs
3195 ##############
3196 -->
3197
3198 <param
3199 id="70"
3200 group="1"
3201 name="Lipsync_Aah"
3202 value_min="0"
3203 value_max="1">
3204 <param_morph />
3205 </param>
3206
3207 <param
3208 id="71"
3209 group="1"
3210 name="Lipsync_Ooh"
3211 value_min="0"
3212 value_max="1">
3213 <param_morph />
3214 </param>
3215
3216<!--
3217 ##############
3218 # other morphs (not user controlled)
3219 ##############
3220 -->
3221 <param
3222 id="40"
3223 group="1"
3224 name="Male_Head"
3225 value_min="0"
3226 value_max="1">
3227 <param_morph />
3228 </param>
3229
3230 <param
3231 id="41"
3232 group="1"
3233 name="Old"
3234 value_min="0"
3235 value_max="1">
3236 <param_morph />
3237 </param>
3238
3239<!--
3240 ##############
3241 # animatable morphs
3242 ##############
3243 -->
3244 <param
3245 id="51"
3246 group="1"
3247 name="Furrowed_Eyebrows"
3248 value_min="0"
3249 value_max="1">
3250 <param_morph />
3251 </param>
3252
3253 <param
3254 id="53"
3255 group="1"
3256 name="Surprised_Eyebrows"
3257 value_min="0"
3258 value_max="1">
3259 <param_morph />
3260 </param>
3261
3262 <param
3263 id="54"
3264 group="1"
3265 name="Worried_Eyebrows"
3266 value_min="0"
3267 value_max="1">
3268 <param_morph />
3269 </param>
3270
3271 <param
3272 id="55"
3273 group="1"
3274 name="Frown_Mouth"
3275 value_min="0"
3276 value_max="1">
3277 <param_morph />
3278 </param>
3279
3280 <param
3281 id="57"
3282 group="1"
3283 name="Smile_Mouth"
3284 value_min="0"
3285 value_max="1">
3286 <param_morph />
3287 </param>
3288
3289 <param
3290 id="58"
3291 group="1"
3292 name="Blink_Left"
3293 value_min="0"
3294 value_max="1">
3295 <param_morph />
3296 </param>
3297
3298 <param
3299 id="59"
3300 group="1"
3301 name="Blink_Right"
3302 value_min="0"
3303 value_max="1">
3304 <param_morph />
3305 </param>
3306
3307<!--
3308 #end morph targets
3309 -->
3310 </mesh>
3311
3312 <mesh
3313 type="headMesh"
3314 lod="1"
3315 file_name="avatar_head_1.llm"
3316 min_pixel_width="160"
3317 reference="avatar_head.llm">
3318 </mesh>
3319
3320 <mesh
3321 type="headMesh"
3322 lod="2"
3323 file_name="avatar_head_2.llm"
3324 min_pixel_width="80"
3325 reference="avatar_head.llm">
3326 </mesh>
3327
3328 <mesh
3329 type="headMesh"
3330 lod="3"
3331 file_name="avatar_head_3.llm"
3332 min_pixel_width="40"
3333 reference="avatar_head.llm">
3334 </mesh>
3335
3336 <mesh
3337 type="headMesh"
3338 lod="4"
3339 file_name="avatar_head_4.llm"
3340 min_pixel_width="0"
3341 reference="avatar_head.llm">
3342 </mesh>
3343
3344 <mesh
3345 type="eyelashMesh"
3346 lod="0"
3347 file_name="avatar_eyelashes.llm"
3348 min_pixel_width="320">
3349 <param
3350 shared="1"
3351 id="660"
3352 group="1"
3353 name="Shear_Head"
3354 wearable="shape"
3355 label="Shear Face"
3356 edit_group="shape_head"
3357 label_min="Shear Left"
3358 label_max="Shear Right"
3359 value_min="-2"
3360 value_max="2"
3361 value_default="0"
3362 camera_distance=".5"
3363 camera_elevation=".04">
3364 <param_morph />
3365 </param>
3366
3367 <param
3368 shared="1"
3369 id="770"
3370 group="1"
3371 name="Elongate_Head"
3372 wearable="shape"
3373 label="Shear Face"
3374 edit_group="shape_head"
3375 label_min="Flat Head"
3376 label_max="Long Head"
3377 value_min="-1"
3378 value_max="1"
3379 value_default="0"
3380 camera_distance=".5"
3381 camera_elevation=".04">
3382 <param_morph />
3383 </param>
3384
3385 <param
3386 shared="1"
3387 id="664"
3388 group="0"
3389 name="Pop_Eye"
3390 wearable="shape"
3391 label="Eye Pop"
3392 edit_group="shape_eyes"
3393 edit_group_order="8"
3394 label_min="Pop Right Eye"
3395 label_max="Pop Left Eye"
3396 value_min="-2"
3397 value_max="2"
3398 value_default="0"
3399 camera_distance=".5"
3400 camera_elevation=".04"
3401 camera_angle="-20">
3402 <param_morph />
3403 </param>
3404
3405 <param
3406 shared="1"
3407 id="21"
3408 group="0"
3409 name="Upper_Eyelid_Fold"
3410 label="Upper Eyelid Fold"
3411 wearable="shape"
3412 edit_group="shape_eyes"
3413 label_min="Uncreased"
3414 label_max="Creased"
3415 value_min="-0.2"
3416 value_max="1.3"
3417 camera_elevation=".1"
3418 camera_distance=".35">
3419 <param_morph />
3420 </param>
3421
3422 <param
3423 shared="1"
3424 id="24"
3425 group="0"
3426 name="Wide_Eyes"
3427 label="Eye Opening"
3428 wearable="shape"
3429 edit_group="shape_eyes"
3430 label_min="Narrow"
3431 label_max="Wide"
3432 show_simple="true"
3433 value_min="-1.5"
3434 value_max="2"
3435 camera_elevation=".1"
3436 camera_distance=".3">
3437 <param_morph />
3438 </param>
3439
3440 <param
3441 shared="1"
3442 id="186"
3443 group="1"
3444 name="Egg_Head"
3445 label="Egg Head"
3446 wearable="shape"
3447 edit_group="shape_head"
3448 label_min="Chin Heavy"
3449 label_max="Forehead Heavy"
3450 value_min="-1.3"
3451 value_max="1"
3452 camera_elevation=".1"
3453 camera_distance=".5"
3454 camera_angle="20">
3455 <param_morph />
3456 </param>
3457
3458 <param
3459 shared="1"
3460 id="187"
3461 group="1"
3462 name="Squash_Stretch_Head"
3463 label="Squash/Stretch Head"
3464 wearable="shape"
3465 edit_group="shape_head"
3466 label_min="Squash Head"
3467 label_max="Stretch Head"
3468 value_min="-.5"
3469 value_max="1"
3470 camera_elevation=".1"
3471 camera_distance=".5"
3472 camera_angle="20">
3473 <param_morph />
3474 </param>
3475
3476 <param
3477 shared="1"
3478 id="194"
3479 group="1"
3480 name="Eye_Spread"
3481 edit_group="shape_eyes"
3482 label_min="Eyes Together"
3483 label_max="Eyes Spread"
3484 value_min="-2"
3485 value_max="2">
3486 <param_morph />
3487 </param>
3488
3489 <param
3490 id="518"
3491 group="0"
3492 name="Eyelashes_Long"
3493 wearable="shape"
3494 label="Eyelash Length"
3495 edit_group="shape_eyes"
3496 edit_group_order="7"
3497 label_min="Short"
3498 label_max="Long"
3499 value_min="-.3"
3500 value_max="1.5"
3501 camera_elevation=".1"
3502 camera_distance=".30"
3503 camera_angle="-20">
3504 <param_morph />
3505 </param>
3506
3507 <param
3508 shared="1"
3509 id="650"
3510 group="0"
3511 name="Eyelid_Corner_Up"
3512 label="Outer Eye Corner"
3513 wearable="shape"
3514 edit_group="shape_eyes"
3515 label_min="Corner Down"
3516 label_max="Corner Up"
3517 value_min="-1.3"
3518 value_max="1.2"
3519 camera_elevation=".1"
3520 camera_distance=".3">
3521 <param_morph />
3522 </param>
3523
3524 <param
3525 shared="1"
3526 id="880"
3527 group="0"
3528 name="Eyelid_Inner_Corner_Up"
3529 label="Inner Eye Corner"
3530 wearable="shape"
3531 edit_group="shape_eyes"
3532 label_min="Corner Down"
3533 label_max="Corner Up"
3534 value_min="-1.3"
3535 value_max="1.2"
3536 camera_elevation=".1"
3537 camera_distance=".3">
3538 <param_morph />
3539 </param>
3540
3541 <param
3542 shared="1"
3543 id="686"
3544 group="1"
3545 name="Head_Eyes_Big"
3546 wearable="shape"
3547 label="Eye Size"
3548 edit_group="shape_eyes"
3549 label_min="Beady Eyes"
3550 label_max="Anime Eyes"
3551 value_min="-2"
3552 value_max="2"
3553 show_simple="true"
3554 value_default="0">
3555 <param_morph />
3556 </param>
3557
3558 <param
3559 shared="1"
3560 id="767"
3561 group="1"
3562 name="Bug_Eyed_Head"
3563 wearable="shape"
3564 label="Eye Depth"
3565 edit_group="shape_eyes"
3566 edit_group_order="4.5"
3567 label_min="Sunken Eyes"
3568 label_max="Bug Eyes"
3569 value_min="-2"
3570 value_max="2"
3571 value_default="0">
3572 <param_morph />
3573 </param>
3574
3575<!--
3576 ##############
3577 # Facial Expression morphs
3578 ##############
3579 -->
3580 <param
3581 shared="1"
3582 id="301"
3583 group="1"
3584 name="Express_Tongue_Out"
3585 value_min="0"
3586 value_max="1">
3587 <param_morph />
3588 </param>
3589
3590 <param
3591 shared="1"
3592 id="302"
3593 group="1"
3594 name="Express_Surprise_Emote"
3595 value_min="0"
3596 value_max="1">
3597 <param_morph />
3598 </param>
3599
3600 <param
3601 shared="1"
3602 id="303"
3603 group="1"
3604 name="Express_Wink_Emote"
3605 value_min="0"
3606 value_max="1">
3607 <param_morph />
3608 </param>
3609
3610 <param
3611 shared="1"
3612 id="304"
3613 group="1"
3614 name="Express_Embarrassed_Emote"
3615 value_min="0"
3616 value_max="1">
3617 <param_morph />
3618 </param>
3619
3620 <param
3621 shared="1"
3622 id="305"
3623 group="1"
3624 name="Express_Shrug_Emote"
3625 value_min="0"
3626 value_max="1">
3627 <param_morph />
3628 </param>
3629
3630 <param
3631 shared="1"
3632 id="306"
3633 group="1"
3634 name="Express_Kiss"
3635 value_min="0"
3636 value_max="1">
3637 <param_morph />
3638 </param>
3639
3640 <param
3641 shared="1"
3642 id="307"
3643 group="1"
3644 name="Express_Bored_Emote"
3645 value_min="0"
3646 value_max="1">
3647 <param_morph />
3648 </param>
3649
3650 <param
3651 shared="1"
3652 id="308"
3653 group="1"
3654 name="Express_Repulsed_Emote"
3655 value_min="0"
3656 value_max="1">
3657 <param_morph />
3658 </param>
3659
3660 <param
3661 shared="1"
3662 id="309"
3663 group="1"
3664 name="Express_Disdain"
3665 value_min="0"
3666 value_max="1">
3667 <param_morph />
3668 </param>
3669
3670 <param
3671 shared="1"
3672 id="310"
3673 group="1"
3674 name="Express_Afraid_Emote"
3675 value_min="0"
3676 value_max="1">
3677 <param_morph />
3678 </param>
3679
3680 <param
3681 shared="1"
3682 id="312"
3683 group="1"
3684 name="Express_Cry_Emote"
3685 value_min="0"
3686 value_max="1">
3687 <param_morph />
3688 </param>
3689
3690 <param
3691 shared="1"
3692 id="313"
3693 group="1"
3694 name="Express_Sad_Emote"
3695 value_min="0"
3696 value_max="1">
3697 <param_morph />
3698 </param>
3699
3700 <param
3701 shared="1"
3702 id="314"
3703 group="1"
3704 name="Express_Anger_Emote"
3705 value_min="0"
3706 value_max="1">
3707 <param_morph />
3708 </param>
3709
3710 <param
3711 shared="1"
3712 id="315"
3713 group="1"
3714 name="Express_Frown"
3715 value_min="0"
3716 value_max="1">
3717 <param_morph />
3718 </param>
3719
3720 <param
3721 shared="1"
3722 id="316"
3723 group="1"
3724 name="Express_Laugh_Emote"
3725 value_min="0"
3726 value_max="1">
3727 <param_morph />
3728 </param>
3729
3730 <param
3731 shared="1"
3732 id="317"
3733 group="1"
3734 name="Express_Toothsmile"
3735 value_min="0"
3736 value_max="1">
3737 <param_morph />
3738 </param>
3739
3740 <param
3741 shared="1"
3742 id="318"
3743 group="1"
3744 name="Express_Smile"
3745 value_min="0"
3746 value_max="1">
3747 <param_morph />
3748 </param>
3749
3750<!--
3751 ##############
3752 # other morphs (not user controlled)
3753 ##############
3754 -->
3755 <param
3756 shared="1"
3757 id="41"
3758 group="1"
3759 name="Old"
3760 value_min="0"
3761 value_max="1">
3762 <param_morph />
3763 </param>
3764
3765<!--
3766 ##############
3767 # animatable morphs
3768 ##############
3769 -->
3770 <param
3771 shared="1"
3772 id="58"
3773 group="1"
3774 name="Blink_Left"
3775 value_min="0"
3776 value_max="1">
3777 <param_morph />
3778 </param>
3779
3780 <param
3781 shared="1"
3782 id="59"
3783 group="1"
3784 name="Blink_Right"
3785 value_min="0"
3786 value_max="1">
3787 <param_morph />
3788 </param>
3789 </mesh>
3790
3791<!--
3792 #headMesh2 =
3793 #headMesh3 =
3794 -->
3795 <mesh
3796 type="upperBodyMesh"
3797 lod="0"
3798 file_name="avatar_upper_body.llm"
3799 min_pixel_width="320">
3800<!--
3801 #begin morph targets
3802 #############
3803 # tweakable morphs
3804 #############
3805 -->
3806 <param
3807 id="104"
3808 group="1"
3809 name="Big_Belly_Torso"
3810 value_min="0"
3811 value_max="1">
3812 <param_morph>
3813 <volume_morph
3814 name="BELLY"
3815 scale="0.075 0.04 0.03"
3816 pos="0.07 0 -0.07"/>
3817 </param_morph>
3818 </param>
3819
3820 <param
3821 id="626"
3822 sex="female"
3823 group="1"
3824 name="Big_Chest"
3825 label="Chest Size"
3826 wearable="shape"
3827 edit_group="shape_torso"
3828 label_min="Small"
3829 label_max="Large"
3830 value_min="0"
3831 value_max="1"
3832 camera_elevation=".1"
3833 camera_distance="1"
3834 camera_angle="15">
3835 <param_morph />
3836 </param>
3837
3838 <param
3839 id="627"
3840 sex="female"
3841 group="1"
3842 name="Small_Chest"
3843 label="Chest Size"
3844 wearable="shape"
3845 edit_group="shape_torso"
3846 label_min="Large"
3847 label_max="Small"
3848 value_min="0"
3849 value_max="1"
3850 camera_elevation="0"
3851 camera_distance=".28">
3852 <param_morph />
3853 </param>
3854
3855 <param
3856 id="843"
3857 sex="female"
3858 group="1"
3859 name="No_Chest"
3860 label="Chest Size"
3861 wearable="shape"
3862 edit_group="shape_torso"
3863 label_min="Some"
3864 label_max="None"
3865 value_min="0"
3866 value_max="1"
3867 camera_elevation="0"
3868 camera_distance=".28">
3869 <param_morph />
3870 </param>
3871
3872 <param
3873 id="106"
3874 group="1"
3875 name="Muscular_Torso"
3876 label="Torso Muscles"
3877 show_simple="true"
3878 wearable="shape"
3879 edit_group="shape_torso"
3880 label_min="Regular"
3881 label_max="Muscular"
3882 value_min="0"
3883 value_max="1.4"
3884 camera_elevation=".3"
3885 camera_distance="1.2">
3886 <param_morph>
3887 <volume_morph
3888 name="L_CLAVICLE"
3889 scale="0.02 0.0 0.005"
3890 pos="0.0 0 0.005"/>
3891 <volume_morph
3892 name="L_UPPER_ARM"
3893 scale="0.015 0.0 0.005"
3894 pos="0.015 0 0"/>
3895 <volume_morph
3896 name="L_LOWER_ARM"
3897 scale="0.005 0.0 0.005"
3898 pos="0.005 0 0"/>
3899 <volume_morph
3900 name="R_CLAVICLE"
3901 scale="0.02 0.0 0.005"
3902 pos="0.0 0 0.005"/>
3903 <volume_morph
3904 name="R_UPPER_ARM"
3905 scale="0.015 0.0 0.005"
3906 pos="0.015 0 0"/>
3907 <volume_morph
3908 name="R_LOWER_ARM"
3909 scale="0.005 0.0 0.005"
3910 pos="0.005 0 0"/>
3911 </param_morph>
3912 </param>
3913
3914 <param
3915 id="648"
3916 group="1"
3917 sex="female"
3918 name="Scrawny_Torso"
3919 label="Torso Muscles"
3920 show_simple="true"
3921 wearable="shape"
3922 edit_group="shape_torso"
3923 label_min="Regular"
3924 label_max="Scrawny"
3925 value_min="0"
3926 value_max="1.3"
3927 camera_elevation=".3"
3928 camera_distance="1.2">
3929 <param_morph>
3930 <volume_morph
3931 name="BELLY"
3932 scale="0.0 -0.01 0.0"
3933 pos="0.0 0.0 0"/>
3934 <volume_morph
3935 name="CHEST"
3936 scale="-0.01 -0.01 0.0"
3937 pos="0.01 0.0 0"/>
3938 <volume_morph
3939 name="L_CLAVICLE"
3940 scale="0.0 -0.03 -0.005"
3941 pos="0.0 0 -0.005"/>
3942 <volume_morph
3943 name="L_UPPER_ARM"
3944 scale="-0.01 -0.01 -0.02"
3945 pos="0 0 0"/>
3946 <volume_morph
3947 name="L_LOWER_ARM"
3948 scale="-0.005 0.0 -0.01"
3949 pos="-0.005 0 0"/>
3950 <volume_morph
3951 name="R_CLAVICLE"
3952 scale="0.0 -0.03 -0.005"
3953 pos="0.0 0 -0.005"/>
3954 <volume_morph
3955 name="R_UPPER_ARM"
3956 scale="-0.01 -0.01 -0.02"
3957 pos="0 0 0"/>
3958 <volume_morph
3959 name="R_LOWER_ARM"
3960 scale="-0.005 0.0 -0.01"
3961 pos="-0.005 0 0"/>
3962 </param_morph>
3963 </param>
3964
3965 <param
3966 id="677"
3967 group="1"
3968 sex="male"
3969 name="Scrawny_Torso_Male"
3970 label="Torso Scrawny"
3971 wearable="shape"
3972 edit_group="shape_torso"
3973 label_min="Regular"
3974 label_max="Scrawny"
3975 value_min="0"
3976 value_max="1.3"
3977 camera_elevation=".3"
3978 camera_distance="1.2">
3979 <param_morph>
3980 <volume_morph
3981 name="BELLY"
3982 scale="-0.01 -0.01 0.0"
3983 pos="0.01 0.0 0"/>
3984 <volume_morph
3985 name="CHEST"
3986 scale="-0.02 -0.02 0.0"
3987 pos="0.01 0.0 0"/>
3988 <volume_morph
3989 name="L_CLAVICLE"
3990 scale="0.0 -0.03 -0.005"
3991 pos="0.0 0 -0.005"/>
3992 <volume_morph
3993 name="L_UPPER_ARM"
3994 scale="-0.01 -0.01 -0.02"
3995 pos="0 0 0"/>
3996 <volume_morph
3997 name="L_LOWER_ARM"
3998 scale="-0.005 0.0 -0.01"
3999 pos="-0.005 0 0"/>
4000 <volume_morph
4001 name="R_CLAVICLE"
4002 scale="0.0 -0.03 -0.005"
4003 pos="0.0 0 -0.005"/>
4004 <volume_morph
4005 name="R_UPPER_ARM"
4006 scale="-0.01 -0.01 -0.02"
4007 pos="0 0 0"/>
4008 <volume_morph
4009 name="R_LOWER_ARM"
4010 scale="-0.005 0.0 -0.01"
4011 pos="-0.005 0 0"/>
4012 </param_morph>
4013 </param>
4014
4015 <param
4016 id="634"
4017 group="1"
4018 name="Fat_Torso"
4019 label="Fat Torso"
4020 wearable="shape"
4021 edit_group="shape_body"
4022 label_min="skinny"
4023 label_max="fat"
4024 value_min="0"
4025 value_max="1"
4026 camera_elevation=".3">
4027 <param_morph>
4028 <volume_morph
4029 name="CHEST"
4030 scale="0.02 0.03 0.03"
4031 pos="0 0 -0.03"/>
4032 <volume_morph
4033 name="BELLY"
4034 scale="0.09 0.08 0.07"
4035 pos="0 0 -0.05"/>
4036 <volume_morph
4037 name="L_CLAVICLE"
4038 scale="0.0 0.0 0.015"/>
4039 <volume_morph
4040 name="L_UPPER_ARM"
4041 scale="0.02 0.0 0.02"
4042 pos="0.0 0.0 -0.02"/>
4043 <volume_morph
4044 name="L_LOWER_ARM"
4045 scale="0.01 0.0 0.01"
4046 pos="0.0 0.0 -0.01"/>
4047 <volume_morph
4048 name="R_CLAVICLE"
4049 scale="0.0 0.0 0.015"/>
4050 <volume_morph
4051 name="R_UPPER_ARM"
4052 scale="0.02 0.0 0.02"
4053 pos="0.0 0.0 -0.02"/>
4054 <volume_morph
4055 name="R_LOWER_ARM"
4056 scale="0.01 0.0 0.01"
4057 pos="0.0 0.0 -0.01"/>
4058 <volume_morph
4059 name="NECK"
4060 scale="0.015 0.01 0.0"/>
4061 <volume_morph
4062 name="HEAD"
4063 scale="0.0 0.0 0.01"
4064 pos="0 0 -0.01"/>
4065 </param_morph>
4066
4067 </param>
4068
4069 <param
4070 id="507"
4071 group="0"
4072 sex="female"
4073 name="Breast_Gravity"
4074 label="Breast Buoyancy"
4075 wearable="shape"
4076 edit_group="shape_torso"
4077 edit_group_order="7"
4078 label_min="Less Gravity"
4079 label_max="More Gravity"
4080 value_default="0"
4081 value_min="-1.5"
4082 value_max="2"
4083 camera_elevation=".3"
4084 camera_distance=".8">
4085 <param_morph />
4086 </param>
4087
4088 <param
4089 id="628"
4090 group="1"
4091 name="Displace_Loose_Upperbody"
4092 label="Shirt Fit"
4093 wearable="shirt"
4094 edit_group="driven"
4095 clothing_morph="true"
4096 value_min="0"
4097 value_max="1"
4098 value_default="0">
4099 <param_morph />
4100 </param>
4101
4102 <param
4103 id="840"
4104 group="0"
4105 name="Shirtsleeve_flair"
4106 label="Sleeve Looseness"
4107 show_simple="true"
4108 wearable="shirt"
4109 edit_group="shirt"
4110 edit_group_order="6"
4111 clothing_morph="true"
4112 label_min="Tight Sleeves"
4113 label_max="Loose Sleeves"
4114 value_min="0"
4115 value_max="1.5"
4116 camera_distance="1.8"
4117 camera_angle="30"
4118 camera_elevation="-.3">
4119 <param_morph />
4120 </param>
4121
4122 <param
4123 id="855"
4124 group="1"
4125 name="Love_Handles"
4126 value_default="0"
4127 value_min="-1"
4128 value_max="2">
4129 <param_morph>
4130 <volume_morph
4131 name="BELLY"
4132 scale="0.0 0.02 0.0"/>
4133 </param_morph>
4134 </param>
4135
4136 <param
4137 id="684"
4138 group="0"
4139 sex="female"
4140 name="Breast_Female_Cleavage"
4141 label="Breast Cleavage"
4142 wearable="shape"
4143 edit_group="shape_torso"
4144 edit_group_order="8"
4145 label_min="Separate"
4146 label_max="Join"
4147 value_default="0"
4148 value_min="-.3"
4149 value_max="1.3"
4150 camera_elevation=".3"
4151 camera_distance=".8">
4152 <param_morph />
4153 </param>
4154
4155 <param
4156 id="685"
4157 group="0"
4158 sex="male"
4159 name="Chest_Male_No_Pecs"
4160 label="Pectorals"
4161 wearable="shape"
4162 edit_group="shape_torso"
4163 edit_group_order="5"
4164 label_min="Big Pectorals"
4165 label_max="Sunken Chest"
4166 value_default="0"
4167 value_min="-.5"
4168 value_max="1.1"
4169 camera_elevation=".3"
4170 camera_distance="1.2">
4171 <param_morph />
4172 </param>
4173
4174<!-- ############# #
4175 other morphs (not user controlled)
4176 ############# -->
4177 <param
4178 id="100"
4179 group="1"
4180 name="Male_Torso"
4181 label_min="Male_Torso"
4182 value_min="0"
4183 value_max="1">
4184 <param_morph>
4185 <volume_morph
4186 name="CHEST"
4187 scale="0.03 0.04 0.02"
4188 pos="-0.03 0 -0.01"/>
4189 <volume_morph
4190 name="BELLY"
4191 scale="0.03 0.03 0.0"
4192 pos="-0.03 0 0.02"/>
4193 <volume_morph
4194 name="L_CLAVICLE"
4195 scale="0.02 0.0 0.01"
4196 pos="-0.02 0 0"/>
4197 <volume_morph
4198 name="L_UPPER_ARM"
4199 scale="0.01 0.0 0.01"
4200 pos="0.0 0.0 -0.01"/>
4201 <volume_morph
4202 name="L_LOWER_ARM"
4203 scale="0.005 0.0 0.005"
4204 pos="0.0 0.0 -0.005"/>
4205 <volume_morph
4206 name="R_CLAVICLE"
4207 scale="0.02 0.0 0.01"
4208 pos="-0.02 0 0"/>
4209 <volume_morph
4210 name="R_UPPER_ARM"
4211 scale="0.01 0.0 0.01"
4212 pos="0.0 0.0 -0.01"/>
4213 <volume_morph
4214 name="R_LOWER_ARM"
4215 scale="0.005 0.0 0.005"
4216 pos="0.0 0.0 -0.005"/>
4217 <volume_morph
4218 name="NECK"
4219 scale="0.015 0.01 0.0"/>
4220 <volume_morph
4221 name="HEAD"
4222 scale="0.0 0.0 0.01"
4223 pos="0 0 -0.01"/>
4224 </param_morph>
4225 </param>
4226
4227<!--
4228 ##############
4229 # animatable morphs
4230 ##############
4231 -->
4232 <param
4233 id="101"
4234 group="1"
4235 name="Hands_Relaxed"
4236 value_min="0"
4237 value_max="1">
4238 <param_morph />
4239 </param>
4240
4241 <param
4242 id="102"
4243 group="1"
4244 name="Hands_Point"
4245 value_min="0"
4246 value_max="1">
4247 <param_morph />
4248 </param>
4249
4250 <param
4251 id="103"
4252 group="1"
4253 name="Hands_Fist"
4254 value_min="0"
4255 value_max="1">
4256 <param_morph />
4257 </param>
4258
4259 <param
4260 id="666"
4261 group="1"
4262 name="Hands_Relaxed_L"
4263 value_min="0"
4264 value_max="1">
4265 <param_morph />
4266 </param>
4267
4268 <param
4269 id="667"
4270 group="1"
4271 name="Hands_Point_L"
4272 value_min="0"
4273 value_max="1">
4274 <param_morph />
4275 </param>
4276
4277 <param
4278 id="668"
4279 group="1"
4280 name="Hands_Fist_L"
4281 value_min="0"
4282 value_max="1">
4283 <param_morph />
4284 </param>
4285
4286 <param
4287 id="669"
4288 group="1"
4289 name="Hands_Relaxed_R"
4290 value_min="0"
4291 value_max="1">
4292 <param_morph />
4293 </param>
4294
4295 <param
4296 id="670"
4297 group="1"
4298 name="Hands_Point_R"
4299 value_min="0"
4300 value_max="1">
4301 <param_morph />
4302 </param>
4303
4304 <param
4305 id="671"
4306 group="1"
4307 name="Hands_Fist_R"
4308 value_min="0"
4309 value_max="1">
4310 <param_morph />
4311 </param>
4312
4313 <param
4314 id="672"
4315 group="1"
4316 name="Hands_Typing"
4317 value_min="0"
4318 value_max="1">
4319 <param_morph />
4320 </param>
4321
4322 <param
4323 id="766"
4324 group="1"
4325 name="Hands_Salute_R"
4326 value_min="0"
4327 value_max="1">
4328 <param_morph />
4329 </param>
4330
4331 <param
4332 id="791"
4333 group="1"
4334 name="Hands_Peace_R"
4335 value_min="0"
4336 value_max="1">
4337 <param_morph />
4338 </param>
4339
4340 <param
4341 id="792"
4342 group="1"
4343 name="Hands_Spread_R"
4344 value_min="0"
4345 value_max="1">
4346 <param_morph />
4347 </param>
4348
4349<!--
4350 #end morph targets
4351 -->
4352 </mesh>
4353
4354 <mesh
4355 type="upperBodyMesh"
4356 lod="1"
4357 file_name="avatar_upper_body_1.llm"
4358 min_pixel_width="160"
4359 reference="avatar_upper_body.llm">
4360 </mesh>
4361
4362 <mesh
4363 type="upperBodyMesh"
4364 lod="2"
4365 file_name="avatar_upper_body_2.llm"
4366 min_pixel_width="80"
4367 reference="avatar_upper_body.llm">
4368 </mesh>
4369
4370 <mesh
4371 type="upperBodyMesh"
4372 lod="3"
4373 file_name="avatar_upper_body_3.llm"
4374 min_pixel_width="40"
4375 reference="avatar_upper_body.llm">
4376 </mesh>
4377
4378 <mesh
4379 type="upperBodyMesh"
4380 lod="4"
4381 file_name="avatar_upper_body_4.llm"
4382 min_pixel_width="0"
4383 reference="avatar_upper_body.llm">
4384 </mesh>
4385
4386<!--
4387 #upperBodyMesh2 =
4388 #upperBodyMesh3 =
4389 -->
4390 <mesh
4391 type="lowerBodyMesh"
4392 lod="0"
4393 file_name="avatar_lower_body.llm"
4394 min_pixel_width="320">
4395<!--
4396 #begin morph targets
4397 #############
4398 # tweakable morphs
4399 #############
4400 -->
4401 <param
4402 id="156"
4403 group="1"
4404 name="Big_Belly_Legs"
4405 value_min="0"
4406 value_max="1">
4407 <param_morph />
4408 </param>
4409
4410 <param
4411 id="151"
4412 group="1"
4413 name="Big_Butt_Legs"
4414 label="Butt Size"
4415 wearable="shape"
4416 edit_group="shape_legs"
4417 label_min="Regular"
4418 label_max="Large"
4419 value_min="0"
4420 value_max="1">
4421 <param_morph>
4422 <volume_morph
4423 name="PELVIS"
4424 scale="0.03 0.0 0.02"
4425 pos="-0.03 0 -0.025"/>
4426 </param_morph>
4427 </param>
4428
4429 <param
4430 id="794"
4431 group="1"
4432 name="Small_Butt"
4433 label="Butt Size"
4434 wearable="shape"
4435 edit_group="shape_legs"
4436 label_min="Regular"
4437 label_max="Small"
4438 value_min="0"
4439 value_max="1">
4440 <param_morph>
4441 <volume_morph
4442 name="PELVIS"
4443 scale="-0.01 0.0 0.0"
4444 pos="0.01 0 0.0"/>
4445 </param_morph>
4446 </param>
4447
4448 <param
4449 id="152"
4450 group="1"
4451 name="Muscular_Legs"
4452 label="Leg Muscles"
4453 show_simple="true"
4454 wearable="shape"
4455 edit_group="shape_legs"
4456 label_min="Regular Muscles"
4457 label_max="More Muscles"
4458 value_min="0"
4459 value_max="1.5"
4460 camera_distance="1.3"
4461 camera_elevation="-.5">
4462 <param_morph>
4463 <volume_morph
4464 name="L_UPPER_LEG"
4465 scale="0.015 0.015 0.0"
4466 pos="0.0 0 0.0"/>
4467 <volume_morph
4468 name="L_LOWER_LEG"
4469 scale="0.01 0.01 0.0"
4470 pos="0.0 0 0.0"/>
4471 <volume_morph
4472 name="R_UPPER_LEG"
4473 scale="0.015 0.015 0.0"
4474 pos="0.0 0 0.0"/>
4475 <volume_morph
4476 name="R_LOWER_LEG"
4477 scale="0.01 0.01 0.0"
4478 pos="0.0 0 0.0"/>
4479 </param_morph>
4480 </param>
4481
4482 <param
4483 id="651"
4484 group="1"
4485 name="Scrawny_Legs"
4486 label="Scrawny Leg"
4487 wearable="shape"
4488 edit_group="shape_legs"
4489 label_min="Regular Muscles"
4490 label_max="Less Muscles"
4491 value_min="0"
4492 value_max="1.5"
4493 camera_distance="1.3"
4494 camera_elevation="-.5">
4495 <param_morph>
4496 <volume_morph
4497 name="L_UPPER_LEG"
4498 scale="-0.03 -0.03 0.0"
4499 pos="0.0 0 0.0"/>
4500 <volume_morph
4501 name="L_LOWER_LEG"
4502 scale="-0.015 -0.015 0.0"
4503 pos="0.0 0 0.0"/>
4504 <volume_morph
4505 name="R_UPPER_LEG"
4506 scale="-0.03 -0.03 0.0"
4507 pos="0.0 0 0.0"/>
4508 <volume_morph
4509 name="R_LOWER_LEG"
4510 scale="-0.015 -0.015 0.0"
4511 pos="0.0 0 0.0"/>
4512 </param_morph>
4513 </param>
4514
4515 <param
4516 id="853"
4517 group="1"
4518 name="Bowed_Legs"
4519 label="Knee Angle"
4520 wearable="shape"
4521 value_min="-1"
4522 value_max="1">
4523 <param_morph>
4524 <volume_morph
4525 name="L_UPPER_LEG"
4526 pos="0.0 0.03 0.0"/>
4527 <volume_morph
4528 name="L_LOWER_LEG"
4529 pos="0.0 0.03 0.0"/>
4530 <volume_morph
4531 name="R_UPPER_LEG"
4532 pos="0.0 -0.03 0.0"/>
4533 <volume_morph
4534 name="R_LOWER_LEG"
4535 pos="0.0 -0.03 0.0"/>
4536 </param_morph>
4537 </param>
4538
4539 <param
4540 id="500"
4541 group="1"
4542 name="Shoe_Heel_Height"
4543 label="Heel Height"
4544 wearable="shoes"
4545 edit_group="shoes"
4546 label_min="Low Heels"
4547 label_max="High Heels"
4548 value_min="0"
4549 value_max="1"
4550 camera_distance="1.5"
4551 camera_elevation="-.5">
4552 <param_morph />
4553 </param>
4554
4555 <param
4556 id="501"
4557 group="1"
4558 name="Shoe_Platform_Height"
4559 label="Platform Height"
4560 wearable="shoes"
4561 edit_group="shoes"
4562 label_min="Low Platforms"
4563 label_max="High Platforms"
4564 value_min="0"
4565 value_max="1"
4566 camera_distance="1.5"
4567 camera_elevation="-.5">
4568 <param_morph />
4569 </param>
4570
4571 <param
4572 id="508"
4573 group="0"
4574 name="Shoe_Platform_Width"
4575 label="Platform Width"
4576 wearable="shoes"
4577 edit_group="shoes"
4578 edit_group_order="7"
4579 label_min="Narrow"
4580 label_max="Wide"
4581 value_min="-1"
4582 value_max="2"
4583 camera_angle="15"
4584 camera_distance="1.5"
4585 camera_elevation="-1">
4586 <param_morph />
4587 </param>
4588
4589 <param
4590 id="509"
4591 group="1"
4592 name="Shoe_Heel_Point"
4593 label="Heel Shape"
4594 wearable="shoes"
4595 edit_group="shoes"
4596 label_min="Default Heels"
4597 label_max="Pointy Heels"
4598 value_min="0"
4599 value_max="1"
4600 camera_distance="1.3"
4601 camera_elevation="-.5">
4602 <param_morph />
4603 </param>
4604
4605 <param
4606 id="510"
4607 group="1"
4608 name="Shoe_Heel_Thick"
4609 label="Heel Shape"
4610 wearable="shoes"
4611 edit_group="shoes"
4612 label_min="default Heels"
4613 label_max="Thick Heels"
4614 value_min="0"
4615 value_max="1"
4616 camera_distance="1.3"
4617 camera_elevation="-.5">
4618 <param_morph />
4619 </param>
4620
4621 <param
4622 id="511"
4623 group="1"
4624 name="Shoe_Toe_Point"
4625 label="Toe Shape"
4626 wearable="shoes"
4627 edit_group="shoes"
4628 label_min="Default Toe"
4629 label_max="Pointy Toe"
4630 value_min="0"
4631 value_max="1"
4632 camera_distance="1.3"
4633 camera_elevation="-.5">
4634 <param_morph />
4635 </param>
4636
4637 <param
4638 id="512"
4639 group="1"
4640 name="Shoe_Toe_Square"
4641 label="Toe Shape"
4642 wearable="shoes"
4643 edit_group="shoes"
4644 label_min="Default Toe"
4645 label_max="Square Toe"
4646 value_min="0"
4647 value_max="1"
4648 camera_distance="1.5"
4649 camera_elevation="-.5">
4650 <param_morph />
4651 </param>
4652
4653 <param
4654 id="654"
4655 group="0"
4656 name="Shoe_Toe_Thick"
4657 label="Toe Thickness"
4658 wearable="shoes"
4659 edit_group="shoes"
4660 edit_group_order="5"
4661 label_min="Flat Toe"
4662 label_max="Thick Toe"
4663 value_min="0"
4664 value_max="2"
4665 camera_angle="15"
4666 camera_distance="1.5"
4667 camera_elevation="-1">
4668 <param_morph />
4669 </param>
4670
4671 <param
4672 id="515"
4673 group="0"
4674 name="Foot_Size"
4675 label="Foot Size"
4676 wearable="shape"
4677 edit_group="shape_legs"
4678 edit_group_order="6"
4679 label_min="Small"
4680 label_max="Big"
4681 value_min="-1"
4682 value_max="3"
4683 camera_angle="45"
4684 camera_distance="1.1"
4685 camera_elevation="-1">
4686 <param_morph>
4687 <volume_morph
4688 name="L_FOOT"
4689 scale="0.02 0.01 0.0"
4690 pos="0.01 0 0"/>
4691 <volume_morph
4692 name="R_FOOT"
4693 scale="0.02 0.01 0.0"
4694 pos="0.01 0 0"/>
4695 </param_morph>
4696 </param>
4697
4698 <param
4699 id="516"
4700 group="1"
4701 name="Displace_Loose_Lowerbody"
4702 label="Pants Fit"
4703 wearable="pants"
4704 edit_group="driven"
4705 clothing_morph="true"
4706 value_min="0"
4707 value_max="1"
4708 value_default="0">
4709 <param_morph />
4710 </param>
4711
4712 <param
4713 id="625"
4714 group="0"
4715 name="Leg_Pantflair"
4716 label="Cuff Flare"
4717 show_simple="true"
4718 wearable="pants"
4719 edit_group="pants"
4720 edit_group_order="3"
4721 clothing_morph="true"
4722 label_min="Tight Cuffs"
4723 label_max="Flared Cuffs"
4724 value_min="0"
4725 value_max="1.5"
4726 camera_distance="1.8"
4727 camera_angle="30"
4728 camera_elevation="-.3">
4729 <param_morph />
4730 </param>
4731
4732 <param
4733 id="793"
4734 group="1"
4735 name="Leg_Longcuffs"
4736 label="Longcuffs"
4737 wearable="pants"
4738 edit_group="driven"
4739 clothing_morph="true"
4740 value_min="0"
4741 value_max="3"
4742 value_default="0">
4743 <param_morph />
4744 </param>
4745
4746 <param
4747 id="638"
4748 group="0"
4749 name="Low_Crotch"
4750 label="Pants Crotch"
4751 wearable="pants"
4752 clothing_morph="true"
4753 edit_group="pants"
4754 edit_group_order="4"
4755 label_min="High and Tight"
4756 label_max="Low and Loose"
4757 value_min="0"
4758 value_max="1.3"
4759 camera_distance="1.2"
4760 camera_angle="-20"
4761 camera_elevation="-.3">
4762 <param_morph />
4763 </param>
4764
4765 <param
4766 id="635"
4767 group="1"
4768 name="Fat_Legs"
4769 label="Fat Torso"
4770 wearable="shape"
4771 edit_group="shape_body"
4772 label_min="skinny"
4773 label_max="fat"
4774 value_min="0"
4775 value_max="1">
4776 <param_morph>
4777 <volume_morph
4778 name="PELVIS"
4779 scale="0.03 0.06 0.0"/>
4780 <volume_morph
4781 name="R_UPPER_LEG"
4782 scale="0.02 0.02 0.0"
4783 pos="0.0 -0.02 0.0"/>
4784 <volume_morph
4785 name="R_LOWER_LEG"
4786 scale="0.01 0.01 0.0"/>
4787 <volume_morph
4788 name="L_UPPER_LEG"
4789 scale="0.02 0.02 0.0"
4790 pos="0.0 0.02 0.0"/>
4791 <volume_morph
4792 name="L_LOWER_LEG"
4793 scale="0.01 0.01 0.0"/>
4794 </param_morph>
4795 </param>
4796
4797 <param
4798 id="854"
4799 group="1"
4800 name="Saddlebags"
4801 value_min="-.5"
4802 value_max="3">
4803 <param_morph>
4804 <volume_morph
4805 name="PELVIS"
4806 scale="0.0 0.025 0.0"/>
4807 </param_morph>
4808
4809 </param>
4810
4811 <param
4812 id="879"
4813 group="0"
4814 sex="male"
4815 name="Male_Package"
4816 label="Package"
4817 wearable="shape"
4818 edit_group="shape_legs"
4819 edit_group_order="4.6"
4820 label_min="Coin Purse"
4821 label_max="Duffle Bag"
4822 value_default="0"
4823 value_min="-.5"
4824 value_max="2"
4825 camera_angle="60"
4826 camera_distance=".6">
4827 <param_morph />
4828 </param>
4829
4830<!--
4831 #############
4832 # other morphs (not user controlled)
4833 #############
4834 -->
4835 <param
4836 id="153"
4837 group="1"
4838 name="Male_Legs"
4839 value_min="0"
4840 value_max="1">
4841 <param_morph />
4842 </param>
4843
4844<!--
4845 #end morph targets
4846 -->
4847 </mesh>
4848
4849 <mesh
4850 type="lowerBodyMesh"
4851 lod="1"
4852 file_name="avatar_lower_body_1.llm"
4853 min_pixel_width="160"
4854 reference="avatar_lower_body.llm">
4855 </mesh>
4856
4857 <mesh
4858 type="lowerBodyMesh"
4859 lod="2"
4860 file_name="avatar_lower_body_2.llm"
4861 min_pixel_width="80"
4862 reference="avatar_lower_body.llm">
4863 </mesh>
4864
4865 <mesh
4866 type="lowerBodyMesh"
4867 lod="3"
4868 file_name="avatar_lower_body_3.llm"
4869 min_pixel_width="40"
4870 reference="avatar_lower_body.llm">
4871 </mesh>
4872
4873 <mesh
4874 type="lowerBodyMesh"
4875 lod="4"
4876 file_name="avatar_lower_body_4.llm"
4877 min_pixel_width="0"
4878 reference="avatar_lower_body.llm">
4879 </mesh>
4880
4881<!--
4882 #lowerBodyMesh2 =
4883 #lowerBodyMesh3 =
4884 -->
4885<!--
4886 #eyeLidLeftMesh =
4887 -->
4888 <mesh
4889 type="eyeBallLeftMesh"
4890 lod="0"
4891 file_name="avatar_eye.llm"
4892 min_pixel_width="320">
4893<!-- begin morph_params -->
4894 <param
4895 id="679"
4896 group="1"
4897 name="Eyeball_Size"
4898 label="Eyeball Size"
4899 wearable="shape"
4900 edit_group="shape_eyes"
4901 label_min="small eye"
4902 label_max="big eye"
4903 value_min="-.25"
4904 value_max=".10">
4905 <param_morph />
4906 </param>
4907
4908 <param
4909 id="687"
4910 group="1"
4911 name="Eyeball_Size"
4912 label="Big Eyeball"
4913 wearable="shape"
4914 edit_group="shape_eyes"
4915 label_min="small eye"
4916 label_max="big eye"
4917 value_min="-.25"
4918 value_max=".25">
4919 <param_morph />
4920 </param>
4921 </mesh>
4922
4923 <mesh
4924 type="eyeBallLeftMesh"
4925 lod="1"
4926 file_name="avatar_eye_1.llm"
4927 min_pixel_width="80">
4928<!-- begin morph_params -->
4929 <param
4930 id="694"
4931 group="1"
4932 name="Eyeball_Size"
4933 label="Eyeball Size"
4934 wearable="shape"
4935 edit_group="shape_eyes"
4936 label_min="small eye"
4937 label_max="big eye"
4938 value_min="-.25"
4939 value_max=".10">
4940 <param_morph />
4941 </param>
4942
4943 <param
4944 id="695"
4945 group="1"
4946 name="Eyeball_Size"
4947 label="Big Eyeball"
4948 wearable="shape"
4949 edit_group="shape_eyes"
4950 label_min="small eye"
4951 label_max="big eye"
4952 value_min="-.25"
4953 value_max=".25">
4954 <param_morph />
4955 </param>
4956 </mesh>
4957
4958<!--
4959 #eyeLidRightMesh =
4960 -->
4961 <mesh
4962 type="eyeBallRightMesh"
4963 lod="0"
4964 file_name="avatar_eye.llm"
4965 min_pixel_width="320">
4966<!-- begin morph_params -->
4967 <param
4968 id="680"
4969 group="1"
4970 name="Eyeball_Size"
4971 label="Eyeball Size"
4972 wearable="shape"
4973 label_min="small eye"
4974 label_max="big eye"
4975 value_min="-.25"
4976 value_max=".10">
4977 <param_morph />
4978 </param>
4979
4980 <param
4981 id="688"
4982 group="1"
4983 name="Eyeball_Size"
4984 label="Big Eyeball"
4985 wearable="shape"
4986 label_min="small eye"
4987 label_max="big eye"
4988 value_min="-.25"
4989 value_max=".25">
4990 <param_morph />
4991 </param>
4992 </mesh>
4993
4994 <mesh
4995 type="eyeBallRightMesh"
4996 lod="1"
4997 file_name="avatar_eye_1.llm"
4998 min_pixel_width="80">
4999<!-- begin morph_params -->
5000 <param
5001 id="681"
5002 group="1"
5003 name="Eyeball_Size"
5004 label="Eyeball Size"
5005 wearable="shape"
5006 edit_group="shape_eyes"
5007 label_min="small eye"
5008 label_max="big eye"
5009 value_min="-.25"
5010 value_max=".10">
5011 <param_morph />
5012 </param>
5013
5014 <param
5015 id="691"
5016 group="1"
5017 name="Eyeball_Size"
5018 label="Big Eyeball"
5019 wearable="shape"
5020 edit_group="shape_eyes"
5021 label_min="small eye"
5022 label_max="big eye"
5023 value_min="-.25"
5024 value_max=".25">
5025 <param_morph />
5026 </param>
5027 </mesh>
5028
5029 <mesh
5030 type="skirtMesh"
5031 lod="0"
5032 file_name="avatar_skirt.llm"
5033 min_pixel_width="320">
5034 <param
5035 id="845"
5036 group="1"
5037 name="skirt_poofy"
5038 label="poofy skirt"
5039 clothing_morph="true"
5040 wearable="skirt"
5041 edit_group="skirt"
5042 label_min="less poofy"
5043 label_max="more poofy"
5044 value_min="0"
5045 value_max="1.5">
5046 <param_morph />
5047 </param>
5048
5049 <param
5050 id="846"
5051 group="1"
5052 name="skirt_loose"
5053 label="loose skirt"
5054 clothing_morph="true"
5055 wearable="skirt"
5056 edit_group="skirt"
5057 label_min="form fitting"
5058 label_max="loose"
5059 value_min="0"
5060 value_max="1">
5061 <param_morph />
5062 </param>
5063
5064 <param
5065 id="866"
5066 group="1"
5067 name="skirt_tight"
5068 label="tight skirt"
5069 clothing_morph="true"
5070 wearable="skirt"
5071 edit_group="skirt"
5072 label_min="form fitting"
5073 label_max="loose"
5074 value_min="0"
5075 value_max="1">
5076 <param_morph />
5077 </param>
5078
5079 <param
5080 id="867"
5081 group="1"
5082 name="skirt_smallbutt"
5083 label="tight skirt"
5084 clothing_morph="false"
5085 wearable="skirt"
5086 edit_group="skirt"
5087 label_min="form fitting"
5088 label_max="loose"
5089 value_min="0"
5090 value_max="1">
5091 <param_morph />
5092 </param>
5093
5094 <param
5095 id="848"
5096 group="0"
5097 name="skirt_bustle"
5098 label="bustle skirt"
5099 clothing_morph="true"
5100 wearable="skirt"
5101 edit_group_order="3"
5102 edit_group="skirt"
5103 label_min="no bustle"
5104 label_max="more bustle"
5105 value_min="0"
5106 value_max="2"
5107 value_default=".2"
5108 camera_angle="100"
5109 camera_distance="1.3"
5110 camera_elevation="-.5">
5111 <param_morph />
5112 </param>
5113
5114 <param
5115 id="847"
5116 group="1"
5117 name="skirt_bowlegs"
5118 label="legs skirt"
5119 wearable="skirt"
5120 value_min="-1"
5121 value_max="1"
5122 value_default="0">
5123 <param_morph />
5124 </param>
5125
5126 <param
5127 id="852"
5128 group="1"
5129 name="skirt_bigbutt"
5130 label="bigbutt skirt"
5131 label_min="less"
5132 label_max="more"
5133 value_min="0"
5134 value_max="1">
5135 <param_morph />
5136 </param>
5137
5138 <param
5139 id="849"
5140 group="1"
5141 name="skirt_belly"
5142 label="big belly skirt"
5143 value_min="0"
5144 value_max="1">
5145 <param_morph />
5146 </param>
5147
5148 <param
5149 id="850"
5150 group="1"
5151 name="skirt_saddlebags"
5152 value_min="-.5"
5153 value_max="3">
5154 <param_morph />
5155 </param>
5156
5157 <param
5158 id="851"
5159 group="1"
5160 name="skirt_chubby"
5161 label_min="less"
5162 label_max="more"
5163 value_min="0"
5164 value_max="1"
5165 value_default="0">
5166 <param_morph />
5167 </param>
5168
5169 <param
5170 id="856"
5171 group="1"
5172 name="skirt_lovehandles"
5173 label_min="less"
5174 label_max="more"
5175 value_min="-1"
5176 value_max="2"
5177 value_default="0">
5178 <param_morph />
5179 </param>
5180
5181<!--
5182 #############
5183 # other morphs (not user controlled)
5184 #############
5185 -->
5186 <param
5187 id="857"
5188 group="1"
5189 name="skirt_male"
5190 value_min="0"
5191 value_max="1">
5192 <param_morph />
5193 </param>
5194 </mesh>
5195
5196 <mesh
5197 type="skirtMesh"
5198 lod="1"
5199 file_name="avatar_skirt_1.llm"
5200 min_pixel_width="160"
5201 reference="avatar_skirt.llm">
5202 </mesh>
5203
5204 <mesh
5205 type="skirtMesh"
5206 lod="2"
5207 file_name="avatar_skirt_2.llm"
5208 min_pixel_width="80"
5209 reference="avatar_skirt.llm">
5210 </mesh>
5211
5212 <mesh
5213 type="skirtMesh"
5214 lod="3"
5215 file_name="avatar_skirt_3.llm"
5216 min_pixel_width="40"
5217 reference="avatar_skirt.llm">
5218 </mesh>
5219
5220 <mesh
5221 type="skirtMesh"
5222 lod="4"
5223 file_name="avatar_skirt_4.llm"
5224 min_pixel_width="0"
5225 reference="avatar_skirt.llm">
5226 </mesh>
5227
5228<!-- =========================================================== -->
5229 <global_color
5230 name="skin_color">
5231 <param
5232 id="111"
5233 group="0"
5234 wearable="skin"
5235 edit_group="skin_color"
5236 edit_group_order="1"
5237 name="Pigment"
5238 show_simple="true"
5239 label_min="Light"
5240 label_max="Dark"
5241 value_min="0"
5242 value_max="1"
5243 value_default=".5">
5244 <param_color>
5245 <value
5246 color="252, 215, 200, 255" />
5247
5248 <value
5249 color="240, 177, 112, 255" />
5250
5251 <value
5252 color="90, 40, 16, 255" />
5253
5254 <value
5255 color="29, 9, 6, 255" />
5256 </param_color>
5257 </param>
5258
5259 <param
5260 id="110"
5261 group="0"
5262 wearable="skin"
5263 edit_group="skin_color"
5264 edit_group_order="2"
5265 name="Red Skin"
5266 label="Ruddiness"
5267 label_min="Pale"
5268 label_max="Ruddy"
5269 value_min="0"
5270 value_max="0.1">
5271 <param_color
5272 operation="blend">
5273 <value
5274 color="218, 41, 37, 255" />
5275 </param_color>
5276 </param>
5277
5278 <param
5279 id="108"
5280 group="0"
5281 wearable="skin"
5282 edit_group="skin_color"
5283 edit_group_order="3"
5284 name="Rainbow Color"
5285 show_simple="true"
5286 label_min="None"
5287 label_max="Wild"
5288 value_min="0"
5289 value_max="1"
5290 camera_elevation=".1"
5291 camera_distance=".5">
5292 <param_color>
5293 <value
5294 color=" 0, 0, 0, 255" />
5295
5296 <value
5297 color="255, 0, 255, 255" />
5298
5299 <value
5300 color="255, 0, 0, 255" />
5301
5302 <value
5303 color="255, 255, 0, 255" />
5304
5305 <value
5306 color=" 0, 255, 0, 255" />
5307
5308 <value
5309 color=" 0, 255, 255, 255" />
5310
5311 <value
5312 color=" 0, 0, 255, 255" />
5313
5314 <value
5315 color="255, 0, 255, 255" />
5316 </param_color>
5317 </param>
5318 </global_color>
5319
5320<!-- =========================================================== -->
5321 <global_color
5322 name="hair_color">
5323 <param
5324 id="114"
5325 group="0"
5326 wearable="hair"
5327 edit_group="hair_color"
5328 edit_group_order="3"
5329 name="Blonde Hair"
5330 show_simple="true"
5331 label_min="Black"
5332 label_max="Blonde"
5333 value_min="0"
5334 value_max="1"
5335 value_default=".5"
5336 camera_elevation=".1"
5337 camera_distance=".5">
5338 <param_color>
5339 <value
5340 color="0, 0, 0, 255" />
5341
5342 <value
5343 color="22, 6, 6, 255" />
5344
5345 <value
5346 color="29, 9, 6, 255" />
5347
5348 <value
5349 color="45, 21, 11, 255" />
5350
5351 <value
5352 color="78, 39, 11, 255" />
5353
5354 <value
5355 color="90, 53, 16, 255" />
5356
5357 <value
5358 color="136, 92, 21, 255" />
5359
5360 <value
5361 color="150, 106, 33, 255" />
5362
5363 <value
5364 color="198, 156, 74, 255" />
5365
5366 <value
5367 color="233, 192, 103, 255" />
5368
5369 <value
5370 color="238, 205, 136, 255" />
5371 </param_color>
5372 </param>
5373
5374 <param
5375 id="113"
5376 group="0"
5377 wearable="hair"
5378 edit_group="hair_color"
5379 edit_group_order="4"
5380 name="Red Hair"
5381 show_simple="true"
5382 label_min="No Red"
5383 label_max="Very Red"
5384 value_min="0"
5385 value_max="1"
5386 camera_elevation=".1"
5387 camera_distance=".5">
5388 <param_color>
5389 <value
5390 color="0, 0, 0, 255" />
5391
5392 <value
5393 color="118, 47, 19, 255" />
5394 </param_color>
5395 </param>
5396
5397 <param
5398 id="115"
5399 group="0"
5400 wearable="hair"
5401 edit_group="hair_color"
5402 edit_group_order="1"
5403 name="White Hair"
5404 show_simple="true"
5405 label_min="No White"
5406 label_max="All White"
5407 value_min="0"
5408 value_max="1"
5409 camera_elevation=".1"
5410 camera_distance=".5">
5411 <param_color>
5412 <value
5413 color="0, 0, 0, 255" />
5414
5415 <value
5416 color="255, 255, 255, 255" />
5417 </param_color>
5418 </param>
5419
5420 <param
5421 id="112"
5422 group="0"
5423 wearable="hair"
5424 edit_group="hair_color"
5425 edit_group_order="2"
5426 name="Rainbow Color"
5427 show_simple="true"
5428 label_min="None"
5429 label_max="Wild"
5430 value_min="0"
5431 value_max="1"
5432 camera_elevation=".1"
5433 camera_distance=".5">
5434 <param_color>
5435 <value
5436 color=" 0, 0, 0, 255" />
5437
5438 <value
5439 color="255, 0, 255, 255" />
5440
5441 <value
5442 color="255, 0, 0, 255" />
5443
5444 <value
5445 color="255, 255, 0, 255" />
5446
5447 <value
5448 color=" 0, 255, 0, 255" />
5449
5450 <value
5451 color=" 0, 255, 255, 255" />
5452
5453 <value
5454 color=" 0, 0, 255, 255" />
5455
5456 <value
5457 color="255, 0, 255, 255" />
5458 </param_color>
5459 </param>
5460 </global_color>
5461
5462<!-- =========================================================== -->
5463 <global_color
5464 name="eye_color">
5465 <param
5466 id="99"
5467 group="0"
5468 wearable="eyes"
5469 edit_group="eyes"
5470 edit_group_order="1"
5471 name="Eye Color"
5472 show_simple="true"
5473 label_min="Natural"
5474 label_max="Unnatural"
5475 value_min="0"
5476 value_max="1"
5477 value_default="0"
5478 camera_elevation=".1"
5479 camera_distance=".3">
5480<!-- default to natural brown eyes-->
5481 <param_color>
5482 <value
5483 color="50, 25, 5, 255" />
5484
5485<!-- natural dark brown eyes-->
5486 <value
5487 color="109, 55, 15, 255" />
5488
5489<!-- natural brown eyes-->
5490 <value
5491 color="150, 93, 49, 255" />
5492
5493<!-- natural light brown eyes-->
5494 <value
5495 color="152, 118, 25, 255" />
5496
5497<!--natural hazel eyes-->
5498 <value
5499 color="95, 179, 107, 255" />
5500
5501<!--natural green eyes-->
5502 <value
5503 color="87, 192, 191, 255" />
5504
5505<!--natural aqua eyes-->
5506 <value
5507 color="95, 172, 179, 255" />
5508
5509<!--natural blue eyes-->
5510 <value
5511 color="128, 128, 128, 255" />
5512
5513<!--natural grey eyes-->
5514 <value
5515 color="0, 0, 0, 255" />
5516
5517<!--black eyes-->
5518 <value
5519 color="255, 255, 0, 255" />
5520
5521<!--bright yellow eyes-->
5522 <value
5523 color=" 0, 255, 0, 255" />
5524
5525<!-- bright green eyes-->
5526 <value
5527 color=" 0, 255, 255, 255" />
5528
5529<!-- bright cyan eyes-->
5530 <value
5531 color=" 0, 0, 255, 255" />
5532
5533<!--bright blue eyes-->
5534 <value
5535 color="255, 0, 255, 255" />
5536
5537<!-- bright violet eyes-->
5538 <value
5539 color="255, 0, 0, 255" />
5540
5541<!--bright red eyes-->
5542 </param_color>
5543 </param>
5544
5545 <param
5546 id="98"
5547 group="0"
5548 wearable="eyes"
5549 edit_group="eyes"
5550 edit_group_order="2"
5551 name="Eye Lightness"
5552 show_simple="true"
5553 label_min="Darker"
5554 label_max="Lighter"
5555 value_min="0"
5556 value_max="1"
5557 camera_elevation=".1"
5558 camera_distance=".3">
5559 <param_color>
5560 <value
5561 color="0, 0, 0, 0" />
5562
5563 <value
5564 color="255, 255, 255, 255" />
5565 </param_color>
5566 </param>
5567 </global_color>
5568
5569<!-- =========================================================== -->
5570 <layer_set
5571 body_region="hair"
5572 width="512"
5573 height="512"
5574 clear_alpha="false">
5575 <layer
5576 name="base"
5577 global_color="hair_color"
5578 write_all_channels="true">
5579 <texture
5580 local_texture="hair_grain" />
5581 </layer>
5582
5583 <layer
5584 name="hair texture alpha layer"
5585 visibility_mask="TRUE">
5586 <texture
5587 local_texture="hair_grain" />
5588 </layer>
5589
5590 <layer
5591 name="hair alpha"
5592 visibility_mask="TRUE">
5593 <texture
5594 local_texture="hair_alpha" />
5595 </layer>
5596 </layer_set>
5597 <!-- =========================================================== -->
5598
5599 <layer_set
5600 body_region="head"
5601 width="512"
5602 height="512">
5603 <layer
5604 name="head bump base"
5605 fixed_color = "128,128,128,255"
5606 render_pass="bump">
5607 </layer>
5608
5609 <layer
5610 name="head bump definition"
5611 render_pass="bump">
5612
5613 <texture
5614 tga_file="bump_head_base.tga"
5615 file_is_mask="FALSE"/>
5616
5617 <param
5618 id="873"
5619 group="1"
5620 wearable="skin"
5621 edit_group="driven"
5622 edit_group_order="12"
5623 name="Bump base"
5624 value_min="0"
5625 value_max="1">
5626 <param_alpha
5627 domain="0" />
5628 </param>
5629 </layer>
5630
5631 <layer
5632 name="base"
5633 global_color="skin_color">
5634 <texture
5635 tga_file="head_skingrain.tga" />
5636 </layer>
5637
5638 <layer
5639 name="headcolor">
5640 <texture
5641 tga_file="head_color.tga" />
5642 </layer>
5643
5644 <layer
5645 name="shadow">
5646 <texture
5647 tga_file="head_shading_alpha.tga"
5648 file_is_mask="TRUE" />
5649
5650 <param
5651 id="158"
5652 group="1"
5653 wearable="skin"
5654 name="Shading"
5655 value_min="0"
5656 value_max="1">
5657 <param_color>
5658 <value
5659 color="0, 0, 0, 0" />
5660
5661 <value
5662 color="0, 0, 0, 128" />
5663 </param_color>
5664 </param>
5665 </layer>
5666
5667 <layer
5668 name="highlight">
5669 <texture
5670 tga_file="head_highlights_alpha.tga"
5671 file_is_mask="TRUE" />
5672
5673
5674 <param
5675 id="159"
5676 group="1"
5677 name="Shading"
5678 wearable="skin"
5679 value_min="0"
5680 value_max="1">
5681 <param_color>
5682 <value
5683 color="255, 255, 255, 0" />
5684
5685
5686 <value
5687 color="255, 255, 255, 64" />
5688 </param_color>
5689 </param>
5690 </layer>
5691 <layer
5692 name="rosyface">
5693 <texture
5694 tga_file="rosyface_alpha.tga"
5695 file_is_mask="true" />
5696
5697 <param
5698 id="116"
5699 group="0"
5700 wearable="skin"
5701 edit_group="skin_facedetail"
5702 edit_group_order="4"
5703 name="Rosy Complexion"
5704 label_min="Less Rosy"
5705 label_max="More Rosy"
5706 value_min="0"
5707 value_max="1"
5708 camera_distance=".3"
5709 camera_elevation=".07">
5710 <param_color>
5711 <value
5712 color="198, 71, 71, 0" />
5713
5714 <value
5715 color="198, 71, 71, 255" />
5716 </param_color>
5717 </param>
5718 </layer>
5719
5720 <layer
5721 name="lips">
5722 <texture
5723 tga_file="lips_mask.tga"
5724 file_is_mask="true" />
5725
5726 <param
5727 id="117"
5728 group="0"
5729 wearable="skin"
5730 edit_group="skin_facedetail"
5731 edit_group_order="5"
5732 name="Lip Pinkness"
5733 label_min="Darker"
5734 label_max="Pinker"
5735 value_min="0"
5736 value_max="1"
5737 camera_distance=".25">
5738 <param_color>
5739 <value
5740 color="220, 115, 115, 0" />
5741
5742 <value
5743 color="220, 115, 115, 128" />
5744 </param_color>
5745 </param>
5746 </layer>
5747
5748 <layer
5749 name="wrinkles_shading"
5750 render_pass="bump"
5751 fixed_color="0,0,0,100">
5752 <param
5753 id="118"
5754 group="1"
5755 wearable="skin"
5756 name="Wrinkles"
5757 value_min="0"
5758 value_max="1">
5759 <param_alpha
5760 tga_file="bump_face_wrinkles.tga"
5761 skip_if_zero="true"
5762 domain="0.3" />
5763 </param>
5764 </layer>
5765
5766<!--<layer
5767 name="wrinkles_highlights"
5768 fixed_color="255,255,255,64">
5769 <param
5770 id="128"
5771 group="1"
5772 name="Wrinkles"
5773 value_min="0"
5774 value_max="1">
5775 <param_alpha
5776 tga_file="head_wrinkles_highlights_alpha.tga"
5777 skip_if_zero="true"
5778 domain="0.3" />
5779 </param>
5780 </layer>-->
5781 <layer
5782 name="freckles"
5783 fixed_color="120,47,20,128">
5784 <param
5785 id="165"
5786 group="0"
5787 wearable="skin"
5788 edit_group="skin_facedetail"
5789 edit_group_order="2"
5790 name="Freckles"
5791 label_min="Less"
5792 label_max="More"
5793 value_min="0"
5794 value_max="1"
5795 camera_distance=".3"
5796 camera_elevation=".07">
5797 <param_alpha
5798 tga_file="freckles_alpha.tga"
5799 skip_if_zero="true"
5800 domain="0.5" />
5801 </param>
5802 </layer>
5803 <layer
5804 name="eyebrowsbump"
5805 render_pass="bump">
5806 <texture
5807 tga_file="head_hair.tga"
5808 file_is_mask="false" />
5809
5810 <param
5811 id="1000"
5812 group="1"
5813 wearable="hair"
5814 edit_group="driven"
5815 name="Eyebrow Size Bump"
5816 value_min="0"
5817 value_max="1">
5818 <param_alpha
5819 tga_file="eyebrows_alpha.tga"
5820 domain="0.1" />
5821 </param>
5822
5823 <param
5824 id="1002"
5825 group="1"
5826 wearable="hair"
5827 edit_group="driven"
5828 name="Eyebrow Density Bump"
5829 value_min="0"
5830 value_max="1">
5831 <param_color>
5832 <value
5833 color="255,255,255,0" />
5834
5835 <value
5836 color="255,255,255,255" />
5837 </param_color>
5838 </param>
5839 </layer>
5840
5841 <layer
5842 name="eyebrows"
5843 global_color="hair_color">
5844 <texture
5845 tga_file="head_hair.tga"
5846 file_is_mask="false" />
5847
5848 <param
5849 id="1001"
5850 group="1"
5851 wearable="hair"
5852 edit_group="hair_eyebrows"
5853 name="Eyebrow Size"
5854 show_simple="true"
5855 value_min="0"
5856 value_max="1"
5857 value_default="0.5">
5858 <param_alpha
5859 tga_file="eyebrows_alpha.tga"
5860 domain="0.1" />
5861 </param>
5862
5863 <param
5864 id="1003"
5865 group="1"
5866 edit_group="driven"
5867 name="Eyebrow Density"
5868 value_min="0"
5869 value_max="1">
5870 <param_color
5871 operation="multiply">
5872 <value
5873 color="255,255,255,0" />
5874
5875 <value
5876 color="255,255,255,255" />
5877 </param_color>
5878 </param>
5879 </layer>
5880
5881 <layer
5882 name="lipstick">
5883 <param
5884 id="700"
5885 group="0"
5886 wearable="skin"
5887 edit_group="skin_makeup"
5888 edit_group_order="2"
5889 name="Lipstick Color"
5890 label_min="Pink"
5891 label_max="Black"
5892 value_min="0"
5893 value_max="1"
5894 value_default=".25"
5895 camera_distance=".25">
5896 <param_color>
5897 <value
5898 color="245,161,177,200" />
5899
5900 <value
5901 color="216,37,67,200" />
5902
5903 <value
5904 color="178,48,76,200" />
5905
5906 <value
5907 color="68,0,11,200" />
5908
5909 <value
5910 color="252,207,184,200" />
5911
5912 <value
5913 color="241,136,106,200" />
5914
5915 <value
5916 color="208,110,85,200" />
5917
5918 <value
5919 color="106,28,18,200" />
5920
5921 <value
5922 color="58,26,49,200" />
5923
5924 <value
5925 color="14,14,14,200" />
5926 </param_color>
5927 </param>
5928
5929 <param
5930 id="701"
5931 group="0"
5932 wearable="skin"
5933 edit_group="skin_makeup"
5934 edit_group_order="1"
5935 name="Lipstick"
5936 label_min="No Lipstick"
5937 label_max="More Lipstick"
5938 value_min="0"
5939 value_max=".9"
5940 value_default="0.0"
5941 camera_distance=".25">
5942 <param_alpha
5943 tga_file="lipstick_alpha.tga"
5944 skip_if_zero="true"
5945 domain="0.05" />
5946 </param>
5947 </layer>
5948
5949 <layer
5950 name="lipgloss"
5951 fixed_color="255,255,255,190">
5952 <param
5953 id="702"
5954 name="Lipgloss"
5955 label_min="No Lipgloss"
5956 label_max="Glossy"
5957 wearable="skin"
5958 edit_group="skin_makeup"
5959 edit_group_order="3"
5960 group="0"
5961 value_min="0"
5962 value_max="1"
5963 camera_distance=".25">
5964 <param_alpha
5965 tga_file="lipgloss_alpha.tga"
5966 skip_if_zero="true"
5967 domain="0.2" />
5968 </param>
5969 </layer>
5970
5971 <layer
5972 name="blush">
5973 <param
5974 id="704"
5975 group="0"
5976 wearable="skin"
5977 edit_group="skin_makeup"
5978 edit_group_order="4"
5979 name="Blush"
5980 label_min="No Blush"
5981 label_max="More Blush"
5982 value_min="0"
5983 value_max=".9"
5984 value_default="0"
5985 camera_distance=".3"
5986 camera_elevation=".07"
5987 camera_angle="20">
5988 <param_alpha
5989 tga_file="blush_alpha.tga"
5990 skip_if_zero="true"
5991 domain="0.3" />
5992 </param>
5993
5994 <param
5995 id="705"
5996 group="0"
5997 wearable="skin"
5998 edit_group="skin_makeup"
5999 edit_group_order="5"
6000 name="Blush Color"
6001 label_min="Pink"
6002 label_max="Orange"
6003 value_min="0"
6004 value_max="1"
6005 value_default=".5"
6006 camera_distance=".3"
6007 camera_elevation=".07"
6008 camera_angle="20">
6009 <param_color>
6010 <value
6011 color="253,162,193,200" />
6012
6013 <value
6014 color="247,131,152,200" />
6015
6016 <value
6017 color="213,122,140,200" />
6018
6019 <value
6020 color="253,152,144,200" />
6021
6022 <value
6023 color="236,138,103,200" />
6024
6025 <value
6026 color="195,128,122,200" />
6027
6028 <value
6029 color="148,103,100,200" />
6030
6031 <value
6032 color="168,95,62,200" />
6033 </param_color>
6034 </param>
6035
6036 <param
6037 id="711"
6038 group="0"
6039 wearable="skin"
6040 edit_group="skin_makeup"
6041 edit_group_order="6"
6042 name="Blush Opacity"
6043 label_min="Clear"
6044 label_max="Opaque"
6045 value_min="0"
6046 value_max="1"
6047 value_default=".5"
6048 camera_distance=".3"
6049 camera_elevation=".07"
6050 camera_angle="20">
6051 <param_color
6052 operation="multiply">
6053 <value
6054 color="255,255,255,0" />
6055
6056 <value
6057 color="255,255,255,255" />
6058 </param_color>
6059 </param>
6060 </layer>
6061
6062 <layer
6063 name="Outer Eye Shadow">
6064 <param
6065 id="708"
6066 group="0"
6067 wearable="skin"
6068 edit_group="skin_makeup"
6069 edit_group_order="11"
6070 name="Out Shdw Color"
6071 label_min="Light"
6072 label_max="Dark"
6073 value_min="0"
6074 value_max="1"
6075 camera_distance=".3"
6076 camera_elevation=".14">
6077 <param_color>
6078 <value
6079 color="252,247,246,255" />
6080
6081 <value
6082 color="255,206,206,255" />
6083
6084 <value
6085 color="233,135,149,255" />
6086
6087 <value
6088 color="220,168,192,255" />
6089
6090 <value
6091 color="228,203,232,255" />
6092
6093 <value
6094 color="255,234,195,255" />
6095
6096 <value
6097 color="230,157,101,255" />
6098
6099 <value
6100 color="255,147,86,255" />
6101
6102 <value
6103 color="228,110,89,255" />
6104
6105 <value
6106 color="228,150,120,255" />
6107
6108 <value
6109 color="223,227,213,255" />
6110
6111 <value
6112 color="96,116,87,255" />
6113
6114 <value
6115 color="88,143,107,255" />
6116
6117 <value
6118 color="194,231,223,255" />
6119
6120 <value
6121 color="207,227,234,255" />
6122
6123 <value
6124 color="41,171,212,255" />
6125
6126 <value
6127 color="180,137,130,255" />
6128
6129 <value
6130 color="173,125,105,255" />
6131
6132 <value
6133 color="144,95,98,255" />
6134
6135 <value
6136 color="115,70,77,255" />
6137
6138 <value
6139 color="155,78,47,255" />
6140
6141 <value
6142 color="239,239,239,255" />
6143
6144 <value
6145 color="194,194,194,255" />
6146
6147 <value
6148 color="120,120,120,255" />
6149
6150 <value
6151 color="10,10,10,255" />
6152 </param_color>
6153 </param>
6154
6155 <param
6156 id="706"
6157 group="0"
6158 wearable="skin"
6159 edit_group="skin_makeup"
6160 edit_group_order="12"
6161 name="Out Shdw Opacity"
6162 label_min="Clear"
6163 label_max="Opaque"
6164 value_min=".2"
6165 value_max="1"
6166 value_default=".6"
6167 camera_distance=".3"
6168 camera_elevation=".14">
6169 <param_color
6170 operation="multiply">
6171 <value
6172 color="255,255,255,0" />
6173
6174 <value
6175 color="255,255,255,255" />
6176 </param_color>
6177 </param>
6178
6179 <param
6180 id="707"
6181 group="0"
6182 wearable="skin"
6183 edit_group="skin_makeup"
6184 edit_group_order="10"
6185 name="Outer Shadow"
6186 label_min="No Eyeshadow"
6187 label_max="More Eyeshadow"
6188 value_min="0"
6189 value_max=".7"
6190 camera_distance=".3"
6191 camera_elevation=".14">
6192 <param_alpha
6193 tga_file="eyeshadow_outer_alpha.tga"
6194 skip_if_zero="true"
6195 domain="0.05" />
6196 </param>
6197 </layer>
6198
6199 <layer
6200 name="Inner Eye Shadow">
6201 <param
6202 id="712"
6203 group="0"
6204 wearable="skin"
6205 edit_group="skin_makeup"
6206 edit_group_order="8"
6207 name="In Shdw Color"
6208 label_min="Light"
6209 label_max="Dark"
6210 value_min="0"
6211 value_max="1"
6212 camera_distance=".3"
6213 camera_elevation=".14">
6214 <param_color>
6215 <value
6216 color="252,247,246,255" />
6217
6218 <value
6219 color="255,206,206,255" />
6220
6221 <value
6222 color="233,135,149,255" />
6223
6224 <value
6225 color="220,168,192,255" />
6226
6227 <value
6228 color="228,203,232,255" />
6229
6230 <value
6231 color="255,234,195,255" />
6232
6233 <value
6234 color="230,157,101,255" />
6235
6236 <value
6237 color="255,147,86,255" />
6238
6239 <value
6240 color="228,110,89,255" />
6241
6242 <value
6243 color="228,150,120,255" />
6244
6245 <value
6246 color="223,227,213,255" />
6247
6248 <value
6249 color="96,116,87,255" />
6250
6251 <value
6252 color="88,143,107,255" />
6253
6254 <value
6255 color="194,231,223,255" />
6256
6257 <value
6258 color="207,227,234,255" />
6259
6260 <value
6261 color="41,171,212,255" />
6262
6263 <value
6264 color="180,137,130,255" />
6265
6266 <value
6267 color="173,125,105,255" />
6268
6269 <value
6270 color="144,95,98,255" />
6271
6272 <value
6273 color="115,70,77,255" />
6274
6275 <value
6276 color="155,78,47,255" />
6277
6278 <value
6279 color="239,239,239,255" />
6280
6281 <value
6282 color="194,194,194,255" />
6283
6284 <value
6285 color="120,120,120,255" />
6286
6287 <value
6288 color="10,10,10,255" />
6289 </param_color>
6290 </param>
6291
6292 <param
6293 id="713"
6294 group="0"
6295 wearable="skin"
6296 edit_group="skin_makeup"
6297 edit_group_order="9"
6298 name="In Shdw Opacity"
6299 label_min="Clear"
6300 label_max="Opaque"
6301 value_min=".2"
6302 value_max="1"
6303 value_default=".7"
6304 camera_distance=".3"
6305 camera_elevation=".14">
6306 <param_color
6307 operation="multiply">
6308 <value
6309 color="255,255,255,0" />
6310
6311 <value
6312 color="255,255,255,255" />
6313 </param_color>
6314 </param>
6315
6316 <param
6317 id="709"
6318 group="0"
6319 wearable="skin"
6320 edit_group="skin_makeup"
6321 edit_group_order="7"
6322 name="Inner Shadow"
6323 label_min="No Eyeshadow"
6324 label_max="More Eyeshadow"
6325 value_min="0"
6326 value_max="1"
6327 value_default="0"
6328 camera_distance=".3"
6329 camera_elevation=".14">
6330 <param_alpha
6331 tga_file="eyeshadow_inner_alpha.tga"
6332 skip_if_zero="true"
6333 domain="0.2" />
6334 </param>
6335 </layer>
6336
6337 <layer
6338 name="eyeliner"
6339 fixed_color="0,0,0,200">
6340 <param
6341 id="703"
6342 group="0"
6343 wearable="skin"
6344 edit_group="skin_makeup"
6345 edit_group_order="13"
6346 name="Eyeliner"
6347 label_min="No Eyeliner"
6348 label_max="Full Eyeliner"
6349 value_min="0"
6350 value_max="1"
6351 value_default="0.0"
6352 camera_distance=".3"
6353 camera_elevation=".14">
6354 <param_alpha
6355 tga_file="eyeliner_alpha.tga"
6356 skip_if_zero="true"
6357 domain="0.1" />
6358 </param>
6359
6360 <param
6361 id="714"
6362 group="0"
6363 wearable="skin"
6364 edit_group="skin_makeup"
6365 edit_group_order="14"
6366 name="Eyeliner Color"
6367 label_min="Dark Green"
6368 label_max="Black"
6369 value_min="0"
6370 value_max="1"
6371 camera_distance=".3"
6372 camera_elevation=".14">
6373 <param_color>
6374 <value
6375 color="24,98,40,250" />
6376
6377<!-- dark green -->
6378 <value
6379 color="9,100,127,250" />
6380
6381<!-- lt.aqua blue -->
6382 <value
6383 color="61,93,134,250" />
6384
6385<!-- aqua -->
6386 <value
6387 color="70,29,27,250" />
6388
6389<!-- dark brown -->
6390 <value
6391 color="115,75,65,250" />
6392
6393<!-- lt. brown blue -->
6394 <value
6395 color="100,100,100,250" />
6396
6397<!-- grey -->
6398 <value
6399 color="91,80,74,250" />
6400
6401<!-- grey/brown -->
6402 <value
6403 color="112,42,76,250" />
6404
6405<!-- plum -->
6406 <value
6407 color="14,14,14,250" />
6408
6409<!-- black -->
6410 </param_color>
6411 </param>
6412 </layer>
6413
6414 <layer
6415 name="facialhair bump"
6416 render_pass="bump">
6417 <texture
6418 tga_file="head_hair.tga"
6419 file_is_mask="false" />
6420
6421 <param
6422 id="1004"
6423 sex="male"
6424 group="1"
6425 wearable="hair"
6426 edit_group="driven"
6427 name="Sideburns bump"
6428 value_min="0"
6429 value_max="1">
6430 <param_alpha
6431 tga_file="facehair_sideburns_alpha.tga"
6432 skip_if_zero="true"
6433 domain="0.05" />
6434 </param>
6435
6436 <param
6437 id="1006"
6438 sex="male"
6439 group="1"
6440 wearable="hair"
6441 edit_group="driven"
6442 name="Moustache bump"
6443 value_min="0"
6444 value_max="1">
6445 <param_alpha
6446 tga_file="facehair_moustache_alpha.tga"
6447 skip_if_zero="true"
6448 domain="0.05" />
6449 </param>
6450
6451 <param
6452 id="1008"
6453 sex="male"
6454 group="1"
6455 wearable="hair"
6456 edit_group="driven"
6457 name="Soulpatch bump"
6458 value_min="0"
6459 value_max="1">
6460 <param_alpha
6461 tga_file="facehair_soulpatch_alpha.tga"
6462 skip_if_zero="true"
6463 domain="0.1" />
6464 </param>
6465
6466 <param
6467 id="1010"
6468 sex="male"
6469 group="1"
6470 edit_group="driven"
6471 wearable="hair"
6472 name="Chin Curtains bump"
6473 value_min="0"
6474 value_max="1">
6475 <param_alpha
6476 tga_file="facehair_chincurtains_alpha.tga"
6477 skip_if_zero="true"
6478 domain="0.03" />
6479 </param>
6480
6481 <param
6482 id="1012"
6483 group="1"
6484 sex="male"
6485 wearable="hair"
6486 edit_group="driven"
6487 name="5 O'Clock Shadow bump"
6488 value_min="0"
6489 value_max="1">
6490 <param_color>
6491 <value
6492 color="255,255,255,255" />
6493
6494 <value
6495 color="255,255,255,0" />
6496 </param_color>
6497 </param>
6498 </layer>
6499
6500 <layer
6501 name="facialhair"
6502 global_color="hair_color">
6503 <morph_mask
6504 morph_name="Displace_Hair_Facial" />
6505
6506 <texture
6507 tga_file="head_hair.tga"
6508 file_is_mask="false" />
6509
6510 <param
6511 id="1005"
6512 sex="male"
6513 group="1"
6514 edit_group="driven"
6515 name="Sideburns"
6516 value_min="0"
6517 value_max="1">
6518 <param_alpha
6519 tga_file="facehair_sideburns_alpha.tga"
6520 skip_if_zero="true"
6521 domain="0.05" />
6522 </param>
6523
6524 <param
6525 id="1007"
6526 sex="male"
6527 group="1"
6528 edit_group="driven"
6529 name="Moustache"
6530 value_min="0"
6531 value_max="1">
6532 <param_alpha
6533 tga_file="facehair_moustache_alpha.tga"
6534 skip_if_zero="true"
6535 domain="0.05" />
6536 </param>
6537
6538 <param
6539 id="1009"
6540 sex="male"
6541 group="1"
6542 edit_group="driven"
6543 name="Soulpatch"
6544 value_min="0"
6545 value_max="1">
6546 <param_alpha
6547 tga_file="facehair_soulpatch_alpha.tga"
6548 skip_if_zero="true"
6549 domain="0.1" />
6550 </param>
6551
6552 <param
6553 id="1011"
6554 sex="male"
6555 group="1"
6556 edit_group="driven"
6557 name="Chin Curtains"
6558 value_min="0"
6559 value_max="1">
6560 <param_alpha
6561 tga_file="facehair_chincurtains_alpha.tga"
6562 skip_if_zero="true"
6563 domain="0.03" />
6564 </param>
6565
6566 <param
6567 id="751"
6568 group="1"
6569 wearable="hair"
6570 sex="male"
6571 edit_group="hair_facial"
6572 name="5 O'Clock Shadow"
6573 label_min="Dense hair"
6574 label_max="Shadow hair"
6575 value_min="0"
6576 value_max="1"
6577 value_default="0.7"
6578 camera_elevation=".1"
6579 camera_distance=".3">
6580 <param_color
6581 operation="multiply">
6582 <value
6583 color="255,255,255,255" />
6584
6585 <value
6586 color="255,255,255,30" />
6587 </param_color>
6588 </param>
6589 </layer>
6590
6591 <layer
6592 name="head_bodypaint">
6593 <texture
6594 local_texture="head_bodypaint" />
6595 </layer>
6596 <layer
6597 name="eyelash alpha"
6598 visibility_mask="TRUE">
6599 <texture
6600 tga_file="head_alpha.tga"
6601 file_is_mask="TRUE" />
6602 </layer>
6603 <layer
6604 name="head alpha"
6605 visibility_mask="TRUE">
6606 <texture
6607 local_texture="head_alpha" />
6608 </layer>
6609 <layer
6610 name="head_tattoo">
6611 <texture local_texture="head_tattoo" />
6612 <param id="1062" group="1" edit_group="colorpicker_driven" wearable="tattoo"
6613 name="tattoo_head_red" value_min="0" value_max="1" value_default="1">
6614 <param_color>
6615 <value color="0, 0, 0, 255" />
6616 <value color="255, 0, 0, 255" />
6617 </param_color>
6618 </param>
6619
6620 <param id="1063" group="1" edit_group="colorpicker_driven" wearable="tattoo"
6621 name="tattoo_head_green" value_min="0" value_max="1" value_default="1">
6622 <param_color>
6623 <value color="0, 0, 0, 255" />
6624 <value color="0, 255, 0, 255" />
6625 </param_color>
6626 </param>
6627
6628 <param id="1064" group="1" edit_group="colorpicker_driven" wearable="tattoo"
6629 name="tattoo_head_blue" value_min="0" value_max="1" value_default="1">
6630 <param_color>
6631 <value color="0, 0, 0, 255" />
6632 <value color="0, 0, 255, 255" />
6633 </param_color>
6634 </param>
6635 </layer>
6636</layer_set>
6637
6638<!-- =========================================================== -->
6639 <layer_set
6640 body_region="upper_body"
6641 width="512"
6642 height="512">
6643 <layer
6644 name="base_upperbody bump"
6645 render_pass="bump"
6646 fixed_color="128,128,128,255">
6647 </layer>
6648 <layer
6649 name="upperbody bump definition"
6650 render_pass="bump">
6651 <texture
6652 tga_file="bump_upperbody_base.tga"
6653 file_is_mask="FALSE"/>
6654
6655 <param
6656 id="874"
6657 group="1"
6658 wearable="skin"
6659 edit_group="driven"
6660 edit_group_order="20"
6661 name="Bump upperdef"
6662 value_min="0"
6663 value_max="1">
6664 <param_alpha
6665 domain="0" />
6666 </param>
6667 </layer>
6668
6669 <layer
6670 name="base"
6671 global_color="skin_color">
6672 <texture
6673 tga_file="body_skingrain.tga" />
6674 </layer>
6675
6676 <layer
6677 name="nipples">
6678 <texture
6679 tga_file="upperbody_color.tga" />
6680 </layer>
6681
6682 <layer
6683 name="shadow">
6684 <texture
6685 tga_file="upperbody_shading_alpha.tga"
6686 file_is_mask="TRUE" />
6687
6688 <param
6689 id="125"
6690 group="1"
6691 name="Shading"
6692 wearable="skin"
6693 value_min="0"
6694 value_max="1">
6695 <param_color>
6696 <value
6697 color="0, 0, 0, 0" />
6698
6699 <value
6700 color="0, 0, 0, 128" />
6701 </param_color>
6702 </param>
6703 </layer>
6704
6705 <layer
6706 name="highlight">
6707 <texture
6708 tga_file="upperbody_highlights_alpha.tga"
6709 file_is_mask="TRUE" />
6710
6711 <param
6712 id="126"
6713 group="1"
6714 wearable="skin"
6715 name="Shading"
6716 value_min="0"
6717 value_max="1">
6718 <param_color>
6719 <value
6720 color="255, 255, 255, 0" />
6721
6722 <value
6723 color="255, 255, 255, 64" />
6724 </param_color>
6725 </param>
6726 </layer>
6727
6728 <layer
6729 name="upper_bodypaint">
6730 <texture
6731 local_texture="upper_bodypaint" />
6732 </layer>
6733
6734 <layer
6735 name="freckles upper"
6736 fixed_color="120,47,20,128">
6737 <param
6738 id="776"
6739 group="1"
6740 name="freckles upper"
6741 wearable="skin"
6742 value_min="0"
6743 value_max="1">
6744 <param_alpha
6745 tga_file="upperbodyfreckles_alpha.tga"
6746 skip_if_zero="true"
6747 domain="0.6" />
6748 </param>
6749 </layer>
6750
6751 <layer name="upper_tattoo">
6752 <texture local_texture="upper_tattoo" />
6753 <param id="1065" group="1" edit_group="colorpicker_driven" wearable="tattoo"
6754 name="tattoo_upper_red" value_min="0" value_max="1" value_default="1">
6755 <param_color>
6756 <value color="0, 0, 0, 255" />
6757 <value color="255, 0, 0, 255" />
6758 </param_color>
6759 </param>
6760
6761 <param id="1066" group="1" edit_group="colorpicker_driven" wearable="tattoo"
6762 name="tattoo_upper_green" value_min="0" value_max="1" value_default="1">
6763 <param_color>
6764 <value color="0, 0, 0, 255" />
6765 <value color="0, 255, 0, 255" />
6766 </param_color>
6767 </param>
6768
6769 <param id="1067" group="1" edit_group="colorpicker_driven" wearable="tattoo"
6770 name="tattoo_upper_blue" value_min="0" value_max="1" value_default="1">
6771 <param_color>
6772 <value color="0, 0, 0, 255" />
6773 <value color="0, 0, 255, 255" />
6774 </param_color>
6775 </param>
6776 </layer>
6777
6778 <layer
6779 name="upper_undershirt bump"
6780 render_pass="bump"
6781 fixed_color="128,128,128,255">
6782 <texture
6783 local_texture="upper_undershirt"
6784 local_texture_alpha_only="true" />
6785
6786 <param
6787 id="1043"
6788 group="1"
6789 wearable="undershirt"
6790 edit_group="driven"
6791 name="Sleeve Length bump"
6792 value_min=".01"
6793 value_max="1"
6794 value_default=".4">
6795 <param_alpha
6796 tga_file="shirt_sleeve_alpha.tga"
6797 multiply_blend="false"
6798 domain="0.01" />
6799 </param>
6800
6801 <param
6802 id="1045"
6803 group="1"
6804 wearable="undershirt"
6805 edit_group="undershirt"
6806 edit_group_order="2"
6807 name="Bottom bump"
6808 value_min="0"
6809 value_max="1"
6810 value_default=".8">
6811 <param_alpha
6812 tga_file="shirt_bottom_alpha.tga"
6813 multiply_blend="true"
6814 domain="0.05" />
6815 </param>
6816
6817 <param
6818 id="1047"
6819 group="1"
6820 wearable="undershirt"
6821 edit_group="driven"
6822 name="Collar Front bump"
6823 value_min="0"
6824 value_max="1"
6825 value_default=".8">
6826 <param_alpha
6827 tga_file="shirt_collar_alpha.tga"
6828 multiply_blend="true"
6829 domain="0.05" />
6830 </param>
6831
6832 <param
6833 id="1049"
6834 group="1"
6835 wearable="undershirt"
6836 edit_group="driven"
6837 name="Collar Back bump"
6838 value_min="0"
6839 value_max="1"
6840 value_default=".8">
6841 <param_alpha
6842 tga_file="shirt_collar_back_alpha.tga"
6843 multiply_blend="true"
6844 domain="0.05" />
6845 </param>
6846 </layer>
6847
6848 <layer
6849 name="upper_undershirt">
6850 <texture
6851 local_texture="upper_undershirt" />
6852
6853 <param
6854 id="821"
6855 group="0"
6856 wearable="undershirt"
6857 edit_group="colorpicker"
6858 name="undershirt_red"
6859 value_min="0"
6860 value_max="1"
6861 value_default="1">
6862 <param_color>
6863 <value
6864 color="0, 0, 0, 255" />
6865
6866 <value
6867 color="255, 0, 0, 255" />
6868 </param_color>
6869 </param>
6870
6871 <param
6872 id="822"
6873 group="0"
6874 wearable="undershirt"
6875 edit_group="colorpicker"
6876 name="undershirt_green"
6877 value_min="0"
6878 value_max="1"
6879 value_default="1">
6880 <param_color>
6881 <value
6882 color="0, 0, 0, 255" />
6883
6884 <value
6885 color="0, 255, 0, 255" />
6886 </param_color>
6887 </param>
6888
6889 <param
6890 id="823"
6891 group="0"
6892 wearable="undershirt"
6893 edit_group="colorpicker"
6894 name="undershirt_blue"
6895 value_min="0"
6896 value_max="1"
6897 value_default="1">
6898 <param_color>
6899 <value
6900 color="0, 0, 0, 255" />
6901
6902 <value
6903 color="0, 0, 255, 255" />
6904 </param_color>
6905 </param>
6906
6907 <param
6908 id="1042"
6909 group="1"
6910 wearable="undershirt"
6911 edit_group="driven"
6912 name="Sleeve Length"
6913 value_min=".01"
6914 value_max="1"
6915 value_default=".4">
6916 <param_alpha
6917 tga_file="shirt_sleeve_alpha.tga"
6918 multiply_blend="false"
6919 domain="0.01" />
6920 </param>
6921
6922 <param
6923 id="1044"
6924 group="1"
6925 wearable="undershirt"
6926 edit_group="driven"
6927 name="Bottom"
6928 value_min="0"
6929 value_max="1"
6930 value_default=".8">
6931 <param_alpha
6932 tga_file="shirt_bottom_alpha.tga"
6933 multiply_blend="true"
6934 domain="0.05" />
6935 </param>
6936
6937 <param
6938 id="1046"
6939 group="1"
6940 wearable="undershirt"
6941 edit_group="driven"
6942 name="Collar Front"
6943 value_min="0"
6944 value_max="1"
6945 value_default=".8">
6946 <param_alpha
6947 tga_file="shirt_collar_alpha.tga"
6948 multiply_blend="true"
6949 domain="0.05" />
6950 </param>
6951
6952 <param
6953 id="1048"
6954 group="1"
6955 wearable="undershirt"
6956 edit_group="driven"
6957 name="Collar Back"
6958 label_min="Low"
6959 label_max="High"
6960 value_min="0"
6961 value_max="1"
6962 value_default=".8">
6963 <param_alpha
6964 tga_file="shirt_collar_back_alpha.tga"
6965 multiply_blend="true"
6966 domain="0.05" />
6967 </param>
6968 </layer>
6969
6970 <layer
6971 name="Nail Polish">
6972 <param
6973 id="710"
6974 group="0"
6975 wearable="skin"
6976 edit_group="skin_makeup"
6977 edit_group_order="15"
6978 name="Nail Polish"
6979 label_min="No Polish"
6980 label_max="Painted Nails"
6981 value_min="0"
6982 value_max="1"
6983 value_default="0.0"
6984 camera_distance="1.6"
6985 camera_elevation="-.4"
6986 camera_angle="70">
6987 <param_alpha
6988 tga_file="nailpolish_alpha.tga"
6989 skip_if_zero="true"
6990 domain="0.1" />
6991 </param>
6992
6993 <param
6994 id="715"
6995 group="0"
6996 wearable="skin"
6997 edit_group="skin_makeup"
6998 edit_group_order="16"
6999 name="Nail Polish Color"
7000 label_min="Pink"
7001 label_max="Black"
7002 value_min="0"
7003 value_max="1"
7004 camera_distance="1.6"
7005 camera_elevation="-.4"
7006 camera_angle="70">
7007 <param_color>
7008 <value
7009 color="255,187,200,255" />
7010
7011 <value
7012 color="194,102,127,255" />
7013
7014 <value
7015 color="227,34,99,255" />
7016
7017 <value
7018 color="168,41,60,255" />
7019
7020 <value
7021 color="97,28,59,255" />
7022
7023 <value
7024 color="234,115,93,255" />
7025
7026 <value
7027 color="142,58,47,255" />
7028
7029 <value
7030 color="114,30,46,255" />
7031
7032 <value
7033 color="14,14,14,255" />
7034 </param_color>
7035 </param>
7036 </layer>
7037
7038 <layer
7039 name="upper_gloves bump"
7040 render_pass="bump"
7041 fixed_color="128,128,128,255">
7042 <texture
7043 local_texture="upper_gloves"
7044 local_texture_alpha_only="true" />
7045
7046 <param
7047 id="1059"
7048 group="1"
7049 wearable="gloves"
7050 edit_group="driven"
7051 name="Glove Length bump"
7052 value_min=".01"
7053 value_max="1"
7054 value_default=".8">
7055 <param_alpha
7056 tga_file="glove_length_alpha.tga"
7057 domain="0.01" />
7058 </param>
7059
7060 <param
7061 id="1061"
7062 group="1"
7063 wearable="gloves"
7064 edit_group="driven"
7065 name="Glove Fingers bump"
7066 value_min=".01"
7067 value_max="1"
7068 value_default="1">
7069 <param_alpha
7070 tga_file="gloves_fingers_alpha.tga"
7071 multiply_blend="true"
7072 domain="0.01" />
7073 </param>
7074 </layer>
7075
7076 <layer
7077 name="upper_gloves">
7078 <texture
7079 local_texture="upper_gloves" />
7080
7081 <param
7082 id="827"
7083 group="0"
7084 wearable="gloves"
7085 edit_group="colorpicker"
7086 name="gloves_red"
7087 value_min="0"
7088 value_max="1"
7089 value_default="1">
7090 <param_color>
7091 <value
7092 color="0, 0, 0, 255" />
7093
7094 <value
7095 color="255, 0, 0, 255" />
7096 </param_color>
7097 </param>
7098
7099 <param
7100 id="829"
7101 group="0"
7102 wearable="gloves"
7103 edit_group="colorpicker"
7104 name="gloves_green"
7105 value_min="0"
7106 value_max="1"
7107 value_default="1">
7108 <param_color>
7109 <value
7110 color="0, 0, 0, 255" />
7111
7112 <value
7113 color="0, 255, 0, 255" />
7114 </param_color>
7115 </param>
7116
7117 <param
7118 id="830"
7119 group="0"
7120 wearable="gloves"
7121 edit_group="colorpicker"
7122 name="gloves_blue"
7123 value_min="0"
7124 value_max="1"
7125 value_default="1">
7126 <param_color>
7127 <value
7128 color="0, 0, 0, 255" />
7129
7130 <value
7131 color="0, 0, 255, 255" />
7132 </param_color>
7133 </param>
7134
7135 <param
7136 id="1058"
7137 group="1"
7138 wearable="gloves"
7139 edit_group="driven"
7140 name="Glove Length"
7141 value_min=".01"
7142 value_max="1"
7143 value_default=".8">
7144 <param_alpha
7145 tga_file="glove_length_alpha.tga"
7146 domain="0.01" />
7147 </param>
7148
7149 <param
7150 id="1060"
7151 group="1"
7152 wearable="gloves"
7153 edit_group="driven"
7154 name="Glove Fingers"
7155 value_min=".01"
7156 value_max="1"
7157 value_default="1">
7158 <param_alpha
7159 tga_file="gloves_fingers_alpha.tga"
7160 multiply_blend="true"
7161 domain="0.01" />
7162 </param>
7163 </layer>
7164
7165 <layer
7166 name="upper_clothes_shadow">
7167 <texture
7168 local_texture="upper_shirt" />
7169
7170 <param
7171 id="899"
7172 group="1"
7173 edit_group="driven"
7174 wearable="shirt"
7175 name="Upper Clothes Shading"
7176 value_min="0"
7177 value_max="1"
7178 value_default="0">
7179 <param_color>
7180 <value
7181 color="0, 0, 0, 0" />
7182
7183 <value
7184 color="0, 0, 0, 80" />
7185 </param_color>
7186 </param>
7187
7188 <param
7189 id="900"
7190 group="1"
7191 wearable="shirt"
7192 edit_group="driven"
7193 name="Sleeve Length Shadow"
7194 value_min="0.02"
7195 value_max=".87"
7196 value_default="0.02">
7197 <param_alpha
7198 multiply_blend="false"
7199 tga_file="shirt_sleeve_alpha.tga"
7200 skip_if_zero="true"
7201 domain="0.03" />
7202 </param>
7203
7204 <param
7205 id="901"
7206 group="1"
7207 wearable="shirt"
7208 edit_group="driven"
7209 name="Shirt Shadow Bottom"
7210 value_min="0.02"
7211 value_max="1">
7212 <param_alpha
7213 multiply_blend="true"
7214 tga_file="shirt_bottom_alpha.tga"
7215 skip_if_zero="true"
7216 domain="0.05" />
7217 </param>
7218
7219 <param
7220 id="902"
7221 group="1"
7222 wearable="shirt"
7223 edit_group="driven"
7224 name="Collar Front Shadow Height"
7225 value_min="0.02"
7226 value_max="1">
7227 <param_alpha
7228 multiply_blend="true"
7229 tga_file="shirt_collar_alpha.tga"
7230 skip_if_zero="true"
7231 domain="0.02" />
7232 </param>
7233
7234 <param
7235 id="903"
7236 group="1"
7237 wearable="shirt"
7238 edit_group="driven"
7239 name="Collar Back Shadow Height"
7240 value_min="0.02"
7241 value_max="1">
7242 <param_alpha
7243 multiply_blend="true"
7244 tga_file="shirt_collar_back_alpha.tga"
7245 skip_if_zero="true"
7246 domain="0.02" />
7247 </param>
7248 </layer>
7249
7250 <layer
7251 name="upper_shirt base bump"
7252 render_pass="bump"
7253 fixed_color="128,128,128,255">
7254 <texture
7255 local_texture="upper_shirt"
7256 local_texture_alpha_only="true" />
7257
7258 <param
7259 id="1029"
7260 group="1"
7261 wearable="shirt"
7262 edit_group="driven"
7263 name="Sleeve Length Cloth"
7264 value_min="0"
7265 value_max="0.85">
7266 <param_alpha
7267 multiply_blend="false"
7268 tga_file="shirt_sleeve_alpha.tga"
7269 domain="0.01" />
7270 </param>
7271
7272 <param
7273 id="1030"
7274 group="1"
7275 wearable="shirt"
7276 edit_group="driven"
7277 name="Shirt Bottom Cloth"
7278 value_min="0"
7279 value_max="1">
7280 <param_alpha
7281 multiply_blend="true"
7282 tga_file="shirt_bottom_alpha.tga"
7283 domain="0.05" />
7284 </param>
7285
7286 <param
7287 id="1031"
7288 group="1"
7289 wearable="shirt"
7290 edit_group="driven"
7291 name="Collar Front Height Cloth"
7292 value_min="0"
7293 value_max="1">
7294 <param_alpha
7295 multiply_blend="true"
7296 tga_file="shirt_collar_alpha.tga"
7297 domain="0.05" />
7298 </param>
7299
7300 <param
7301 id="1032"
7302 group="1"
7303 wearable="shirt"
7304 edit_group="driven"
7305 name="Collar Back Height Cloth"
7306 value_min="0"
7307 value_max="1">
7308 <param_alpha
7309 multiply_blend="true"
7310 tga_file="shirt_collar_back_alpha.tga"
7311 domain="0.05" />
7312 </param>
7313 </layer>
7314
7315 <layer
7316 name="upper_clothes bump"
7317 render_pass="bump">
7318 <texture
7319 tga_file="bump_shirt_wrinkles.tga" />
7320
7321 <texture
7322 local_texture="upper_shirt"
7323 local_texture_alpha_only="true" />
7324
7325 <param
7326 id="868"
7327 group="0"
7328 wearable="shirt"
7329 edit_group="shirt"
7330 edit_group_order="8"
7331 name="Shirt Wrinkles"
7332 value_min="0"
7333 value_max="1"
7334 value_default="0">
7335 <param_color>
7336 <value
7337 color="255, 255, 255, 0" />
7338
7339 <value
7340 color="255, 255, 255, 255" />
7341 </param_color>
7342 </param>
7343
7344 <param
7345 id="1013"
7346 group="1"
7347 wearable="shirt"
7348 edit_group="driven"
7349 name="Sleeve Length Cloth"
7350 value_min="0"
7351 value_max="0.85">
7352 <param_alpha
7353 multiply_blend="false"
7354 tga_file="shirt_sleeve_alpha.tga"
7355 domain="0.01" />
7356 </param>
7357
7358 <param
7359 id="1014"
7360 group="1"
7361 wearable="shirt"
7362 edit_group="driven"
7363 name="Shirt Bottom Cloth"
7364 value_min="0"
7365 value_max="1">
7366 <param_alpha
7367 multiply_blend="true"
7368 tga_file="shirt_bottom_alpha.tga"
7369 domain="0.05" />
7370 </param>
7371
7372 <param
7373 id="1015"
7374 group="1"
7375 wearable="shirt"
7376 edit_group="driven"
7377 name="Collar Front Height Cloth"
7378 value_min="0"
7379 value_max="1">
7380 <param_alpha
7381 multiply_blend="true"
7382 tga_file="shirt_collar_alpha.tga"
7383 domain="0.05" />
7384 </param>
7385
7386 <param
7387 id="1016"
7388 group="1"
7389 wearable="shirt"
7390 edit_group="driven"
7391 name="Collar Back Height Cloth"
7392 value_min="0"
7393 value_max="1">
7394 <param_alpha
7395 multiply_blend="true"
7396 tga_file="shirt_collar_back_alpha.tga"
7397 domain="0.05" />
7398 </param>
7399 </layer>
7400
7401 <layer
7402 name="upper_clothes">
7403 <texture
7404 local_texture="upper_shirt" />
7405
7406 <morph_mask
7407 morph_name="Displace_Loose_Upperbody" />
7408
7409 <morph_mask
7410 morph_name="Shirtsleeve_flair" />
7411
7412 <param
7413 id="803"
7414 group="0"
7415 wearable="shirt"
7416 edit_group="colorpicker"
7417 name="shirt_red"
7418 value_min="0"
7419 value_max="1"
7420 value_default="1">
7421 <param_color>
7422 <value
7423 color="0, 0, 0, 255" />
7424
7425 <value
7426 color="255, 0, 0, 255" />
7427 </param_color>
7428 </param>
7429
7430 <param
7431 id="804"
7432 group="0"
7433 wearable="shirt"
7434 edit_group="colorpicker"
7435 name="shirt_green"
7436 value_min="0"
7437 value_max="1"
7438 value_default="1">
7439 <param_color>
7440 <value
7441 color="0, 0, 0, 255" />
7442
7443 <value
7444 color="0, 255, 0, 255" />
7445 </param_color>
7446 </param>
7447
7448 <param
7449 id="805"
7450 group="0"
7451 wearable="shirt"
7452 edit_group="colorpicker"
7453 name="shirt_blue"
7454 value_min="0"
7455 value_max="1"
7456 value_default="1">
7457 <param_color>
7458 <value
7459 color="0, 0, 0, 255" />
7460
7461 <value
7462 color="0, 0, 255, 255" />
7463 </param_color>
7464 </param>
7465
7466 <param
7467 id="600"
7468 group="1"
7469 wearable="shirt"
7470 edit_group="driven"
7471 name="Sleeve Length Cloth"
7472 value_min="0"
7473 value_max="0.85"
7474 value_default=".7">
7475 <param_alpha
7476 multiply_blend="false"
7477 tga_file="shirt_sleeve_alpha.tga"
7478 domain="0.01" />
7479 </param>
7480
7481 <param
7482 id="601"
7483 group="1"
7484 wearable="shirt"
7485 edit_group="driven"
7486 name="Shirt Bottom Cloth"
7487 value_min="0"
7488 value_max="1"
7489 value_default=".8">
7490 <param_alpha
7491 multiply_blend="true"
7492 tga_file="shirt_bottom_alpha.tga"
7493 domain="0.05" />
7494 </param>
7495
7496 <param
7497 id="602"
7498 group="1"
7499 wearable="shirt"
7500 edit_group="driven"
7501 name="Collar Front Height Cloth"
7502 value_min="0"
7503 value_max="1"
7504 value_default=".8">
7505 <param_alpha
7506 multiply_blend="true"
7507 tga_file="shirt_collar_alpha.tga"
7508 domain="0.05" />
7509 </param>
7510
7511 <param
7512 id="778"
7513 group="1"
7514 wearable="shirt"
7515 edit_group="driven"
7516 name="Collar Back Height Cloth"
7517 value_min="0"
7518 value_max="1"
7519 value_default=".8">
7520 <param_alpha
7521 multiply_blend="true"
7522 tga_file="shirt_collar_back_alpha.tga"
7523 domain="0.05" />
7524 </param>
7525 </layer>
7526
7527 <layer
7528 name="upper_jacket base bump"
7529 render_pass="bump"
7530 fixed_color="128,128,128,255">
7531 <texture
7532 local_texture="upper_jacket"
7533 local_texture_alpha_only="true" />
7534
7535 <param
7536 id="1039"
7537 group="1"
7538 wearable="jacket"
7539 edit_group="driven"
7540 edit_group_order="1"
7541 name="Jacket Sleeve Length bump"
7542 value_min="0"
7543 value_max="1">
7544 <param_alpha
7545 multiply_blend="false"
7546 tga_file="shirt_sleeve_alpha.tga"
7547 domain="0.01" />
7548 </param>
7549
7550 <param
7551 id="1040"
7552 group="1"
7553 wearable="jacket"
7554 edit_group="driven"
7555 name="Jacket Collar Front bump"
7556 value_min="0"
7557 value_max="1">
7558 <param_alpha
7559 multiply_blend="true"
7560 tga_file="shirt_collar_alpha.tga"
7561 domain="0.05" />
7562 </param>
7563
7564 <param
7565 id="1041"
7566 group="1"
7567 wearable="jacket"
7568 edit_group="driven"
7569 edit_group_order="3.5"
7570 name="Jacket Collar Back bump"
7571 value_min="0"
7572 value_max="1">
7573 <param_alpha
7574 multiply_blend="true"
7575 tga_file="shirt_collar_back_alpha.tga"
7576 domain="0.05" />
7577 </param>
7578
7579 <param
7580 id="1037"
7581 group="1"
7582 wearable="jacket"
7583 edit_group="driven"
7584 name="jacket bottom length upper bump"
7585 value_min="0"
7586 value_max="1">
7587 <param_alpha
7588 multiply_blend="true"
7589 tga_file="jacket_length_upper_alpha.tga"
7590 domain="0.01" />
7591 </param>
7592
7593 <param
7594 id="1038"
7595 group="1"
7596 wearable="jacket"
7597 edit_group="driven"
7598 name="jacket open upper bump"
7599 value_min="0"
7600 value_max="1">
7601 <param_alpha
7602 multiply_blend="true"
7603 tga_file="jacket_open_upper_alpha.tga"
7604 domain="0.01" />
7605 </param>
7606 </layer>
7607
7608 <layer
7609 name="upper_jacket bump"
7610 render_pass="bump">
7611 <texture
7612 tga_file="bump_shirt_wrinkles.tga" />
7613
7614 <texture
7615 local_texture="upper_jacket"
7616 local_texture_alpha_only="true" />
7617
7618 <param
7619 id="875"
7620 group="1"
7621 wearable="jacket"
7622 name="jacket upper Wrinkles"
7623 value_min="0"
7624 value_max="1"
7625 value_default="0">
7626 <param_color>
7627 <value
7628 color="255, 255, 255, 0" />
7629
7630 <value
7631 color="255, 255, 255, 255" />
7632 </param_color>
7633 </param>
7634
7635 <param
7636 id="1019"
7637 group="1"
7638 wearable="jacket"
7639 edit_group="driven"
7640 edit_group_order="1"
7641 name="Jacket Sleeve Length bump"
7642 value_min="0"
7643 value_max="1">
7644 <param_alpha
7645 multiply_blend="false"
7646 tga_file="shirt_sleeve_alpha.tga"
7647 domain="0.01" />
7648 </param>
7649
7650 <param
7651 id="1021"
7652 group="1"
7653 wearable="jacket"
7654 edit_group="driven"
7655 name="Jacket Collar Front bump"
7656 value_min="0"
7657 value_max="1">
7658 <param_alpha
7659 multiply_blend="true"
7660 tga_file="shirt_collar_alpha.tga"
7661 domain="0.05" />
7662 </param>
7663
7664 <param
7665 id="1023"
7666 group="1"
7667 wearable="jacket"
7668 edit_group="driven"
7669 edit_group_order="3.5"
7670 name="Jacket Collar Back bump"
7671 value_min="0"
7672 value_max="1">
7673 <param_alpha
7674 multiply_blend="true"
7675 tga_file="shirt_collar_back_alpha.tga"
7676 domain="0.05" />
7677 </param>
7678
7679 <param
7680 id="1025"
7681 group="1"
7682 wearable="jacket"
7683 edit_group="driven"
7684 name="jacket bottom length upper bump"
7685 value_min="0"
7686 value_max="1">
7687 <param_alpha
7688 multiply_blend="true"
7689 tga_file="jacket_length_upper_alpha.tga"
7690 domain="0.01" />
7691 </param>
7692
7693 <param
7694 id="1026"
7695 group="1"
7696 wearable="jacket"
7697 edit_group="driven"
7698 name="jacket open upper bump"
7699 value_min="0"
7700 value_max="1">
7701 <param_alpha
7702 multiply_blend="true"
7703 tga_file="jacket_open_upper_alpha.tga"
7704 domain="0.01" />
7705 </param>
7706 </layer>
7707
7708 <layer
7709 name="upper_jacket">
7710 <texture
7711 local_texture="upper_jacket" />
7712
7713 <param
7714 id="831"
7715 group="1"
7716 edit_group="colorpicker_driven"
7717 wearable="jacket"
7718 name="upper_jacket_red"
7719 value_min="0"
7720 value_max="1"
7721 value_default="1">
7722 <param_color>
7723 <value
7724 color="0, 0, 0, 255" />
7725
7726 <value
7727 color="255, 0, 0, 255" />
7728 </param_color>
7729 </param>
7730
7731 <param
7732 id="832"
7733 group="1"
7734 edit_group="colorpicker_driven"
7735 wearable="jacket"
7736 name="upper_jacket_green"
7737 value_min="0"
7738 value_max="1"
7739 value_default="1">
7740 <param_color>
7741 <value
7742 color="0, 0, 0, 255" />
7743
7744 <value
7745 color="0, 255, 0, 255" />
7746 </param_color>
7747 </param>
7748
7749 <param
7750 id="833"
7751 group="1"
7752 edit_group="colorpicker_driven"
7753 wearable="jacket"
7754 name="upper_jacket_blue"
7755 value_min="0"
7756 value_max="1"
7757 value_default="1">
7758 <param_color>
7759 <value
7760 color="0, 0, 0, 255" />
7761
7762 <value
7763 color="0, 0, 255, 255" />
7764 </param_color>
7765 </param>
7766
7767 <param
7768 id="1020"
7769 group="1"
7770 edit_group="driven"
7771 name="jacket Sleeve Length"
7772 value_min="0"
7773 value_max="1">
7774 <param_alpha
7775 multiply_blend="false"
7776 tga_file="shirt_sleeve_alpha.tga"
7777 domain="0.01" />
7778 </param>
7779
7780 <param
7781 id="1022"
7782 group="1"
7783 edit_group="driven"
7784 name="jacket Collar Front"
7785 value_min="0"
7786 value_max="1">
7787 <param_alpha
7788 multiply_blend="true"
7789 tga_file="shirt_collar_alpha.tga"
7790 domain="0.05" />
7791 </param>
7792
7793 <param
7794 id="1024"
7795 group="1"
7796 edit_group="driven"
7797 edit_group_order="3.5"
7798 name="jacket Collar Back"
7799 value_min="0"
7800 value_max="1">
7801 <param_alpha
7802 multiply_blend="true"
7803 tga_file="shirt_collar_back_alpha.tga"
7804 domain="0.05" />
7805 </param>
7806
7807 <param
7808 id="620"
7809 group="1"
7810 wearable="jacket"
7811 edit_group="jacket"
7812 name="bottom length upper"
7813 label_min="hi cut"
7814 label_max="low cut"
7815 value_min="0"
7816 value_max="1"
7817 value_default=".8"
7818 camera_distance="1.2"
7819 camera_angle="30"
7820 camera_elevation=".2">
7821 <param_alpha
7822 multiply_blend="true"
7823 tga_file="jacket_length_upper_alpha.tga"
7824 domain="0.01" />
7825 </param>
7826
7827 <param
7828 id="622"
7829 group="1"
7830 wearable="jacket"
7831 edit_group="jacket"
7832 name="open upper"
7833 label_min="closed"
7834 label_max="open"
7835 value_min="0"
7836 value_max="1"
7837 value_default=".8"
7838 camera_distance="1.2"
7839 camera_angle="30"
7840 camera_elevation=".2">
7841 <param_alpha
7842 multiply_blend="true"
7843 tga_file="jacket_open_upper_alpha.tga"
7844 domain="0.01" />
7845 </param>
7846 </layer>
7847
7848 <layer
7849 name="upper alpha"
7850 visibility_mask="TRUE">
7851 <texture
7852 local_texture="upper_alpha" />
7853 </layer>
7854
7855 </layer_set>
7856
7857<!-- =========================================================== -->
7858 <layer_set
7859 body_region="lower_body"
7860 width="512"
7861 height="512">
7862 <layer
7863 name="lower body bump base"
7864 fixed_color = "128,128,128,255"
7865 render_pass="bump">
7866 </layer>
7867 <layer
7868 name="base_lowerbody bump"
7869 render_pass="bump">
7870 <texture
7871 tga_file="bump_lowerbody_base.tga"
7872 file_is_mask="FALSE" />
7873
7874 <param
7875 id="878"
7876 group="1"
7877 wearable="skin"
7878 edit_group="driven"
7879 edit_group_order="20"
7880 name="Bump upperdef"
7881 value_min="0"
7882 value_max="1">
7883 <param_alpha
7884 domain="0" />
7885 </param>
7886 </layer>
7887
7888 <layer
7889 name="base"
7890 global_color="skin_color">
7891 <texture
7892 tga_file="body_skingrain.tga" />
7893 </layer>
7894
7895 <layer
7896 name="shadow">
7897 <texture
7898 tga_file="lowerbody_shading_alpha.tga"
7899 file_is_mask="TRUE" />
7900
7901 <param
7902 id="160"
7903 group="1"
7904 name="Shading"
7905 wearable="pants"
7906 value_min="0"
7907 value_max="1">
7908 <param_color>
7909 <value
7910 color="0, 0, 0, 0" />
7911
7912 <value
7913 color="0, 0, 0, 128" />
7914 </param_color>
7915 </param>
7916 </layer>
7917
7918 <layer
7919 name="highlight">
7920 <texture
7921 tga_file="lowerbody_highlights_alpha.tga"
7922 file_is_mask="TRUE" />
7923
7924 <param
7925 id="161"
7926 group="1"
7927 name="Shading"
7928 wearable="skin"
7929 value_min="0"
7930 value_max="1">
7931 <param_color>
7932 <value
7933 color="255, 255, 255, 0" />
7934
7935 <value
7936 color="255, 255, 255, 64" />
7937 </param_color>
7938 </param>
7939 </layer>
7940
7941 <layer
7942 name="toenails">
7943 <texture
7944 tga_file="lowerbody_color.tga" />
7945 </layer>
7946
7947 <layer
7948 name="lower_bodypaint">
7949 <texture
7950 local_texture="lower_bodypaint" />
7951 </layer>
7952
7953 <layer
7954 name="freckles lower"
7955 fixed_color="120,47,20,128">
7956 <param
7957 id="777"
7958 group="1"
7959 name="freckles lower"
7960 wearable="skin"
7961 value_min="0"
7962 value_max="1">
7963 <param_alpha
7964 tga_file="bodyfreckles_alpha.tga"
7965 skip_if_zero="true"
7966 domain="0.6" />
7967 </param>
7968 </layer>
7969
7970 <layer
7971 name="lower_tattoo">
7972 <texture local_texture="lower_tattoo" />
7973 <param id="1068" group="1" edit_group="colorpicker_driven" wearable="tattoo"
7974 name="tattoo_lower_red" value_min="0" value_max="1" value_default="1">
7975 <param_color>
7976 <value color="0, 0, 0, 255" />
7977 <value color="255, 0, 0, 255" />
7978 </param_color>
7979 </param>
7980
7981 <param id="1069" group="1" edit_group="colorpicker_driven" wearable="tattoo"
7982 name="tattoo_lower_green" value_min="0" value_max="1" value_default="1">
7983 <param_color>
7984 <value color="0, 0, 0, 255" />
7985 <value color="0, 255, 0, 255" />
7986 </param_color>
7987 </param>
7988
7989 <param id="1070" group="1" edit_group="colorpicker_driven" wearable="tattoo"
7990 name="tattoo_lower_blue" value_min="0" value_max="1" value_default="1">
7991 <param_color>
7992 <value color="0, 0, 0, 255" />
7993 <value color="0, 0, 255, 255" />
7994 </param_color>
7995 </param>
7996 </layer>
7997
7998 <layer
7999 name="lower_underpants bump"
8000 render_pass="bump"
8001 fixed_color="128,128,128,255">
8002 <texture
8003 local_texture="lower_underpants"
8004 local_texture_alpha_only="true" />
8005
8006 <param
8007 id="1055"
8008 group="1"
8009 wearable="underpants"
8010 edit_group="underpants"
8011 name="Pants Length"
8012 value_min="0"
8013 value_max="1"
8014 value_default=".3">
8015 <param_alpha
8016 tga_file="pants_length_alpha.tga"
8017 domain="0.01" />
8018 </param>
8019
8020 <param
8021 id="1057"
8022 group="1"
8023 wearable="underpants"
8024 edit_group="underpants"
8025 name="Pants Waist"
8026 value_min="0"
8027 value_max="1"
8028 value_default=".8">
8029 <param_alpha
8030 tga_file="pants_waist_alpha.tga"
8031 domain="0.05" />
8032 </param>
8033 </layer>
8034
8035 <layer
8036 name="lower_underpants">
8037 <texture
8038 local_texture="lower_underpants" />
8039
8040 <param
8041 id="824"
8042 group="0"
8043 wearable="underpants"
8044 edit_group="colorpicker"
8045 name="underpants_red"
8046 value_min="0"
8047 value_max="1"
8048 value_default="1">
8049 <param_color>
8050 <value
8051 color="0, 0, 0, 255" />
8052
8053 <value
8054 color="255, 0, 0, 255" />
8055 </param_color>
8056 </param>
8057
8058 <param
8059 id="825"
8060 group="0"
8061 wearable="underpants"
8062 edit_group="colorpicker"
8063 name="underpants_green"
8064 value_min="0"
8065 value_max="1"
8066 value_default="1">
8067 <param_color>
8068 <value
8069 color="0, 0, 0, 255" />
8070
8071 <value
8072 color="0, 255, 0, 255" />
8073 </param_color>
8074 </param>
8075
8076 <param
8077 id="826"
8078 group="0"
8079 wearable="underpants"
8080 edit_group="colorpicker"
8081 name="underpants_blue"
8082 value_min="0"
8083 value_max="1"
8084 value_default="1">
8085 <param_color>
8086 <value
8087 color="0, 0, 0, 255" />
8088
8089 <value
8090 color="0, 0, 255, 255" />
8091 </param_color>
8092 </param>
8093
8094 <param
8095 id="1054"
8096 group="1"
8097 wearable="underpants"
8098 edit_group="driven"
8099 name="Pants Length"
8100 value_min="0"
8101 value_max="1"
8102 value_default=".3"
8103 camera_distance="1.2"
8104 camera_angle="30"
8105 camera_elevation="-.3">
8106 <param_alpha
8107 tga_file="pants_length_alpha.tga"
8108 domain="0.01" />
8109 </param>
8110
8111 <param
8112 id="1056"
8113 group="1"
8114 wearable="underpants"
8115 edit_group="driven"
8116 name="Pants Waist"
8117 value_min="0"
8118 value_max="1"
8119 value_default=".8">
8120 <param_alpha
8121 tga_file="pants_waist_alpha.tga"
8122 domain="0.05" />
8123 </param>
8124 </layer>
8125
8126 <layer
8127 name="lower_socks bump"
8128 render_pass="bump"
8129 fixed_color="128,128,128,255">
8130 <texture
8131 local_texture="lower_socks"
8132 local_texture_alpha_only="true" />
8133
8134 <param
8135 id="1051"
8136 group="1"
8137 wearable="socks"
8138 edit_group="driven"
8139 name="Socks Length bump"
8140 value_min="0"
8141 value_max="1"
8142 value_default="0.35">
8143 <param_alpha
8144 tga_file="shoe_height_alpha.tga"
8145 domain="0.01" />
8146 </param>
8147 </layer>
8148
8149 <layer
8150 name="lower_socks">
8151 <texture
8152 local_texture="lower_socks" />
8153
8154 <param
8155 id="818"
8156 group="0"
8157 wearable="socks"
8158 edit_group="colorpicker"
8159 name="socks_red"
8160 value_min="0"
8161 value_max="1"
8162 value_default="1">
8163 <param_color>
8164 <value
8165 color="0, 0, 0, 255" />
8166
8167 <value
8168 color="255, 0, 0, 255" />
8169 </param_color>
8170 </param>
8171
8172 <param
8173 id="819"
8174 group="0"
8175 wearable="socks"
8176 edit_group="colorpicker"
8177 name="socks_green"
8178 value_min="0"
8179 value_max="1"
8180 value_default="1">
8181 <param_color>
8182 <value
8183 color="0, 0, 0, 255" />
8184
8185 <value
8186 color="0, 255, 0, 255" />
8187 </param_color>
8188 </param>
8189
8190 <param
8191 id="820"
8192 group="0"
8193 wearable="socks"
8194 edit_group="colorpicker"
8195 name="socks_blue"
8196 value_min="0"
8197 value_max="1"
8198 value_default="1">
8199 <param_color>
8200 <value
8201 color="0, 0, 0, 255" />
8202
8203 <value
8204 color="0, 0, 255, 255" />
8205 </param_color>
8206 </param>
8207
8208 <param
8209 id="1050"
8210 group="1"
8211 wearable="socks"
8212 edit_group="driven"
8213 name="Socks Length bump"
8214 value_min="0"
8215 value_max="1"
8216 value_default="0.35">
8217 <param_alpha
8218 tga_file="shoe_height_alpha.tga"
8219 domain="0.01" />
8220 </param>
8221 </layer>
8222
8223 <layer
8224 name="lower_shoes bump"
8225 render_pass="bump"
8226 fixed_color="128,128,128,255">
8227 <texture
8228 local_texture="lower_shoes"
8229 local_texture_alpha_only="true" />
8230
8231 <param
8232 id="1053"
8233 group="1"
8234 wearable="shoes"
8235 edit_group="driven"
8236 name="Shoe Height bump"
8237 value_min="0"
8238 value_max="1"
8239 value_default="0.1">
8240 <param_alpha
8241 tga_file="shoe_height_alpha.tga"
8242 domain="0.01" />
8243 </param>
8244 </layer>
8245
8246 <layer
8247 name="lower_shoes">
8248 <texture
8249 local_texture="lower_shoes" />
8250
8251 <param
8252 id="812"
8253 group="0"
8254 wearable="shoes"
8255 edit_group="colorpicker"
8256 name="shoes_red"
8257 value_min="0"
8258 value_max="1"
8259 value_default="1">
8260 <param_color>
8261 <value
8262 color="0, 0, 0, 255" />
8263
8264 <value
8265 color="255, 0, 0, 255" />
8266 </param_color>
8267 </param>
8268
8269 <param
8270 id="813"
8271 group="0"
8272 wearable="shoes"
8273 edit_group="colorpicker"
8274 name="shoes_green"
8275 value_min="0"
8276 value_max="1"
8277 value_default="1">
8278 <param_color>
8279 <value
8280 color="0, 0, 0, 255" />
8281
8282 <value
8283 color="0, 255, 0, 255" />
8284 </param_color>
8285 </param>
8286
8287 <param
8288 id="817"
8289 group="0"
8290 wearable="shoes"
8291 edit_group="colorpicker"
8292 name="shoes_blue"
8293 value_min="0"
8294 value_max="1"
8295 value_default="1">
8296 <param_color>
8297 <value
8298 color="0, 0, 0, 255" />
8299
8300 <value
8301 color="0, 0, 255, 255" />
8302 </param_color>
8303 </param>
8304
8305 <param
8306 id="1052"
8307 group="1"
8308 wearable="shoes"
8309 edit_group="driven"
8310 name="Shoe Height"
8311 value_min="0"
8312 value_max="1"
8313 value_default="0.1">
8314 <param_alpha
8315 tga_file="shoe_height_alpha.tga"
8316 domain="0.01" />
8317 </param>
8318 </layer>
8319
8320 <layer
8321 name="lower_clothes_shadow">
8322 <texture
8323 local_texture="lower_pants" />
8324
8325 <param
8326 id="913"
8327 group="1"
8328 edit_group="driven"
8329 wearable="pants"
8330 name="Lower Clothes Shading"
8331 value_min="0"
8332 value_max="1"
8333 value_default="0">
8334 <param_color>
8335 <value
8336 color="0, 0, 0, 0" />
8337
8338 <value
8339 color="0, 0, 0, 80" />
8340 </param_color>
8341 </param>
8342
8343 <param
8344 id="914"
8345 group="1"
8346 edit_group="driven"
8347 wearable="pants"
8348 name="Waist Height Shadow"
8349 value_min="0.02"
8350 value_max="1">
8351 <param_alpha
8352 tga_file="pants_waist_alpha.tga"
8353 skip_if_zero="true"
8354 domain="0.04" />
8355 </param>
8356
8357 <param
8358 id="915"
8359 group="1"
8360 edit_group="driven"
8361 wearable="pants"
8362 name="Pants Length Shadow"
8363 value_min="0.02"
8364 value_max="1">
8365 <param_alpha
8366 tga_file="pants_length_alpha.tga"
8367 skip_if_zero="true"
8368 domain="0.03" />
8369 </param>
8370 </layer>
8371
8372 <layer
8373 name="lower_pants base bump"
8374 render_pass="bump"
8375 fixed_color="128,128,128,255">
8376 <texture
8377 local_texture="lower_pants"
8378 local_texture_alpha_only="true" />
8379
8380 <param
8381 id="1035"
8382 group="1"
8383 edit_group="driven"
8384 wearable="pants"
8385 name="Waist Height Cloth"
8386 value_min="0"
8387 value_max="1">
8388 <param_alpha
8389 tga_file="pants_waist_alpha.tga"
8390 domain="0.05" />
8391 </param>
8392
8393 <param
8394 id="1036"
8395 group="1"
8396 edit_group="driven"
8397 wearable="pants"
8398 name="Pants Length Cloth"
8399 value_min="0"
8400 value_max="1">
8401 <param_alpha
8402 tga_file="pants_length_alpha.tga"
8403 domain="0.01" />
8404 </param>
8405 </layer>
8406
8407 <layer
8408 name="lower_pants bump"
8409 render_pass="bump">
8410 <texture
8411 tga_file="bump_pants_wrinkles.tga" />
8412
8413 <texture
8414 local_texture="lower_pants"
8415 local_texture_alpha_only="true" />
8416
8417 <param
8418 id="869"
8419 group="0"
8420 wearable="pants"
8421 edit_group="pants"
8422 edit_group_order="6"
8423 name="Pants Wrinkles"
8424 value_min="0"
8425 value_max="1"
8426 value_default="0">
8427 <param_color>
8428 <value
8429 color="255, 255, 255, 0" />
8430
8431 <value
8432 color="255, 255, 255, 255" />
8433 </param_color>
8434 </param>
8435
8436 <param
8437 id="1017"
8438 group="1"
8439 edit_group="driven"
8440 wearable="pants"
8441 name="Waist Height Cloth"
8442 value_min="0"
8443 value_max="1">
8444 <param_alpha
8445 tga_file="pants_waist_alpha.tga"
8446 domain="0.05" />
8447 </param>
8448
8449 <param
8450 id="1018"
8451 group="1"
8452 edit_group="driven"
8453 wearable="pants"
8454 name="Pants Length Cloth"
8455 value_min="0"
8456 value_max="1">
8457 <param_alpha
8458 tga_file="pants_length_alpha.tga"
8459 domain="0.01" />
8460 </param>
8461 </layer>
8462
8463 <layer
8464 name="lower_pants">
8465 <texture
8466 local_texture="lower_pants" />
8467
8468 <morph_mask
8469 morph_name="Displace_Loose_Lowerbody" />
8470
8471 <morph_mask
8472 morph_name="Leg_Pantflair" />
8473
8474 <morph_mask
8475 morph_name="Low_Crotch" />
8476
8477 <morph_mask
8478 morph_name="Leg_Longcuffs" />
8479
8480 <param
8481 id="806"
8482 group="0"
8483 wearable="pants"
8484 edit_group="colorpicker"
8485 name="pants_red"
8486 value_min="0"
8487 value_max="1"
8488 value_default="1">
8489 <param_color>
8490 <value
8491 color="0, 0, 0, 255" />
8492
8493 <value
8494 color="255, 0, 0, 255" />
8495 </param_color>
8496 </param>
8497
8498 <param
8499 id="807"
8500 group="0"
8501 wearable="pants"
8502 edit_group="colorpicker"
8503 name="pants_green"
8504 value_min="0"
8505 value_max="1"
8506 value_default="1">
8507 <param_color>
8508 <value
8509 color="0, 0, 0, 255" />
8510
8511 <value
8512 color="0, 255, 0, 255" />
8513 </param_color>
8514 </param>
8515
8516 <param
8517 id="808"
8518 group="0"
8519 wearable="pants"
8520 edit_group="colorpicker"
8521 name="pants_blue"
8522 value_min="0"
8523 value_max="1"
8524 value_default="1">
8525 <param_color>
8526 <value
8527 color="0, 0, 0, 255" />
8528
8529 <value
8530 color="0, 0, 255, 255" />
8531 </param_color>
8532 </param>
8533
8534 <param
8535 id="614"
8536 group="1"
8537 edit_group="driven"
8538 wearable="pants"
8539 name="Waist Height Cloth"
8540 value_min="0"
8541 value_max="1"
8542 value_default=".8">
8543 <param_alpha
8544 tga_file="pants_waist_alpha.tga"
8545 domain="0.05" />
8546 </param>
8547
8548 <param
8549 id="615"
8550 group="1"
8551 edit_group="driven"
8552 wearable="pants"
8553 name="Pants Length Cloth"
8554 value_min="0"
8555 value_max="1"
8556 value_default=".8">
8557 <param_alpha
8558 tga_file="pants_length_alpha.tga"
8559 domain="0.01" />
8560 </param>
8561 </layer>
8562
8563 <layer
8564 name="lower_jacket base bump"
8565 render_pass="bump"
8566 fixed_color="128,128,128,255">
8567 <texture
8568 local_texture="lower_jacket"
8569 local_texture_alpha_only="true" />
8570
8571 <param
8572 id="1033"
8573 group="1"
8574 wearable="jacket"
8575 edit_group="driven"
8576 name="jacket bottom length lower bump"
8577 value_min="0"
8578 value_max="1">
8579 <param_alpha
8580 multiply_blend="false"
8581 tga_file="jacket_length_lower_alpha.tga"
8582 domain="0.01" />
8583 </param>
8584
8585 <param
8586 id="1034"
8587 group="1"
8588 wearable="jacket"
8589 edit_group="driven"
8590 name="jacket open lower bump"
8591 value_min="0"
8592 value_max="1">
8593 <param_alpha
8594 multiply_blend="true"
8595 tga_file="jacket_open_lower_alpha.tga"
8596 domain="0.01" />
8597 </param>
8598 </layer>
8599
8600 <layer
8601 name="lower_jacket bump"
8602 render_pass="bump">
8603 <texture
8604 tga_file="bump_pants_wrinkles.tga" />
8605
8606 <texture
8607 local_texture="lower_jacket"
8608 local_texture_alpha_only="true" />
8609
8610 <param
8611 id="876"
8612 group="1"
8613 wearable="jacket"
8614 name="jacket upper Wrinkles"
8615 value_min="0"
8616 value_max="1"
8617 value_default="0">
8618 <param_color>
8619 <value
8620 color="255, 255, 255, 0" />
8621
8622 <value
8623 color="255, 255, 255, 255" />
8624 </param_color>
8625 </param>
8626
8627 <param
8628 id="1027"
8629 group="1"
8630 wearable="jacket"
8631 edit_group="driven"
8632 name="jacket bottom length lower bump"
8633 value_min="0"
8634 value_max="1">
8635 <param_alpha
8636 multiply_blend="false"
8637 tga_file="jacket_length_lower_alpha.tga"
8638 domain="0.01" />
8639 </param>
8640
8641 <param
8642 id="1028"
8643 group="1"
8644 wearable="jacket"
8645 edit_group="driven"
8646 name="jacket open lower bump"
8647 value_min="0"
8648 value_max="1">
8649 <param_alpha
8650 multiply_blend="true"
8651 tga_file="jacket_open_lower_alpha.tga"
8652 domain="0.01" />
8653 </param>
8654 </layer>
8655
8656 <layer
8657 name="lower_jacket">
8658 <texture
8659 local_texture="lower_jacket" />
8660
8661 <param
8662 id="809"
8663 group="1"
8664 edit_group="colorpicker_driven"
8665 wearable="jacket"
8666 name="lower_jacket_red"
8667 value_min="0"
8668 value_max="1"
8669 value_default="1">
8670 <param_color>
8671 <value
8672 color="0, 0, 0, 255" />
8673
8674 <value
8675 color="255, 0, 0, 255" />
8676 </param_color>
8677 </param>
8678
8679 <param
8680 id="810"
8681 group="1"
8682 edit_group="colorpicker_driven"
8683 wearable="jacket"
8684 name="lower_jacket_green"
8685 value_min="0"
8686 value_max="1"
8687 value_default="1">
8688 <param_color>
8689 <value
8690 color="0, 0, 0, 255" />
8691
8692 <value
8693 color="0, 255, 0, 255" />
8694 </param_color>
8695 </param>
8696
8697 <param
8698 id="811"
8699 group="1"
8700 edit_group="colorpicker_driven"
8701 wearable="jacket"
8702 name="lower_jacket_blue"
8703 value_min="0"
8704 value_max="1"
8705 value_default="1">
8706 <param_color>
8707 <value
8708 color="0, 0, 0, 255" />
8709
8710 <value
8711 color="0, 0, 255, 255" />
8712 </param_color>
8713 </param>
8714
8715 <param
8716 id="621"
8717 group="1"
8718 wearable="jacket"
8719 edit_group="jacket"
8720 name="bottom length lower"
8721 label_min="hi cut"
8722 label_max="low cut"
8723 value_min="0"
8724 value_max="1"
8725 value_default=".8"
8726 camera_distance="1.2"
8727 camera_angle="30"
8728 camera_elevation=".2">
8729 <param_alpha
8730 multiply_blend="false"
8731 tga_file="jacket_length_lower_alpha.tga"
8732 domain="0.01" />
8733 </param>
8734
8735 <param
8736 id="623"
8737 group="1"
8738 wearable="jacket"
8739 edit_group="jacket"
8740 name="open lower"
8741 label_min="open"
8742 label_max="closed"
8743 value_min="0"
8744 value_max="1"
8745 value_default=".8"
8746 camera_distance="1.2"
8747 camera_angle="30"
8748 camera_elevation=".2">
8749 <param_alpha
8750 multiply_blend="true"
8751 tga_file="jacket_open_lower_alpha.tga"
8752 domain="0.01" />
8753 </param>
8754 </layer>
8755
8756 <layer
8757 name="lower alpha"
8758 visibility_mask="TRUE">
8759 <texture
8760 local_texture="lower_alpha" />
8761 </layer>
8762
8763 </layer_set>
8764
8765<!-- =========================================================== -->
8766 <layer_set
8767 body_region="eyes"
8768 width="128"
8769 height="128">
8770 <layer
8771 name="whites">
8772 <texture
8773 tga_file="eyewhite.tga" />
8774 </layer>
8775
8776 <layer
8777 name="iris"
8778 global_color="eye_color">
8779 <texture
8780 local_texture="eyes_iris" />
8781 </layer>
8782
8783 <layer
8784 name="eyes alpha"
8785 visibility_mask="TRUE">
8786 <texture
8787 local_texture="eyes_alpha" />
8788 </layer>
8789
8790 </layer_set>
8791
8792<!-- =========================================================== -->
8793 <layer_set
8794 body_region="skirt"
8795 width="512"
8796 height="512"
8797 clear_alpha="false">
8798 <layer
8799 name="skirt_fabric"
8800 write_all_channels="true">
8801 <texture
8802 local_texture="skirt" />
8803
8804 <param
8805 id="921"
8806 group="0"
8807 wearable="skirt"
8808 edit_group="colorpicker"
8809 name="skirt_red"
8810 value_min="0"
8811 value_max="1"
8812 value_default="1">
8813 <param_color>
8814 <value
8815 color="0, 0, 0, 255" />
8816
8817 <value
8818 color="255, 0, 0, 255" />
8819 </param_color>
8820 </param>
8821
8822 <param
8823 id="922"
8824 group="0"
8825 wearable="skirt"
8826 edit_group="colorpicker"
8827 name="skirt_green"
8828 value_min="0"
8829 value_max="1"
8830 value_default="1">
8831 <param_color>
8832 <value
8833 color="0, 0, 0, 255" />
8834
8835 <value
8836 color="0, 255, 0, 255" />
8837 </param_color>
8838 </param>
8839
8840 <param
8841 id="923"
8842 group="0"
8843 wearable="skirt"
8844 edit_group="colorpicker"
8845 name="skirt_blue"
8846 value_min="0"
8847 value_max="1"
8848 value_default="1">
8849 <param_color>
8850 <value
8851 color="0, 0, 0, 255" />
8852
8853 <value
8854 color="0, 0, 255, 255" />
8855 </param_color>
8856 </param>
8857 </layer>
8858
8859 <layer
8860 name="skirt_fabric_alpha">
8861 <param
8862 id="858"
8863 group="0"
8864 wearable="skirt"
8865 edit_group="skirt"
8866 edit_group_order="1"
8867 name="Skirt Length"
8868 show_simple="true"
8869 label_min="Short"
8870 label_max="Long"
8871 value_min=".01"
8872 value_max="1"
8873 value_default=".4"
8874 simple_percent_min="40"
8875 simple_percent_max="100"
8876 camera_distance="1.3"
8877 camera_elevation="-.5"
8878 camera_angle="30">
8879 <param_alpha
8880 tga_file="skirt_length_alpha.tga"
8881 domain="0"
8882 multiply_blend="true" />
8883 </param>
8884
8885 <param
8886 id="859"
8887 group="0"
8888 wearable="skirt"
8889 edit_group="skirt"
8890 edit_group_order="4"
8891 name="Slit Front"
8892 label_min="Open Front"
8893 label_max="Closed Front"
8894 value_min="0"
8895 value_max="1"
8896 value_default="1"
8897 camera_distance="1.3"
8898 camera_elevation="-.5"
8899 camera_angle="30">
8900 <param_alpha
8901 tga_file="skirt_slit_front_alpha.tga"
8902 multiply_blend="true"
8903 domain="0" />
8904 </param>
8905
8906 <param
8907 id="860"
8908 group="0"
8909 wearable="skirt"
8910 edit_group="skirt"
8911 edit_group_order="5"
8912 name="Slit Back"
8913 label_min="Open Back"
8914 label_max="Closed Back"
8915 value_min="0"
8916 value_max="1"
8917 value_default="1"
8918 camera_distance="1.3"
8919 camera_elevation="-.5"
8920 camera_angle="160">
8921 <param_alpha
8922 tga_file="skirt_slit_back_alpha.tga"
8923 multiply_blend="true"
8924 domain="0" />
8925 </param>
8926
8927 <param
8928 id="861"
8929 group="0"
8930 wearable="skirt"
8931 edit_group="skirt"
8932 edit_group_order="6"
8933 name="Slit Left"
8934 label_min="Open Left"
8935 label_max="Closed Left"
8936 value_min="0"
8937 value_max="1"
8938 value_default="1"
8939 camera_distance="1.3"
8940 camera_elevation="-.5"
8941 camera_angle="30">
8942 <param_alpha
8943 tga_file="skirt_slit_left_alpha.tga"
8944 multiply_blend="true"
8945 domain="0" />
8946 </param>
8947
8948 <param
8949 id="862"
8950 group="0"
8951 wearable="skirt"
8952 edit_group="skirt"
8953 edit_group_order="7"
8954 name="Slit Right"
8955 label_min="Open Right"
8956 label_max="Closed Right"
8957 value_min="0"
8958 value_max="1"
8959 value_default="1"
8960 camera_distance="1.3"
8961 camera_elevation="-.5"
8962 camera_angle="-30">
8963 <param_alpha
8964 tga_file="skirt_slit_right_alpha.tga"
8965 multiply_blend="true"
8966 domain="0" />
8967 </param>
8968 </layer>
8969 </layer_set>
8970
8971<!-- =========================================================== -->
8972 <driver_parameters>
8973 <param
8974 id="828"
8975 group="0"
8976 name="Loose Upper Clothing"
8977 label="Shirt Fit"
8978 show_simple="true"
8979 wearable="shirt"
8980 edit_group="shirt"
8981 edit_group_order="4"
8982 label_min="Tight Shirt"
8983 label_max="Loose Shirt"
8984 value_min="0"
8985 value_max="1"
8986 camera_distance="1.2"
8987 camera_angle="30"
8988 camera_elevation=".2">
8989 <param_driver>
8990 <driven
8991 id="628" />
8992
8993 <driven
8994 id="899"
8995 min1="0.1"
8996 max1="0.5"
8997 max2="1"
8998 min2="1" />
8999 </param_driver>
9000 </param>
9001
9002 <param
9003 id="816"
9004 group="0"
9005 name="Loose Lower Clothing"
9006 label="Pants Fit"
9007 show_simple="true"
9008 wearable="pants"
9009 edit_group="pants"
9010 edit_group_order="2.5"
9011 label_min="Tight Pants"
9012 label_max="Loose Pants"
9013 value_min="0"
9014 value_max="1"
9015 camera_distance="1.8"
9016 camera_angle="30"
9017 camera_elevation="-.3">
9018 <param_driver>
9019 <driven
9020 id="516" />
9021
9022 <driven
9023 id="913"
9024 min1="0.1"
9025 max1="0.5"
9026 max2="1"
9027 min2="1" />
9028 </param_driver>
9029 </param>
9030
9031 <param
9032 id="814"
9033 group="0"
9034 wearable="pants"
9035 edit_group="pants"
9036 edit_group_order="2"
9037 name="Waist Height"
9038 label_min="Low"
9039 label_max="High"
9040 value_min="0"
9041 value_max="1"
9042 value_default="1"
9043 camera_distance="1.2"
9044 camera_angle="30"
9045 camera_elevation="-.3">
9046 <param_driver>
9047 <driven
9048 id="614" />
9049
9050 <driven
9051 id="1017" />
9052
9053 <driven
9054 id="1033" />
9055
9056 <driven
9057 id="914"
9058 min1="0"
9059 max1=".98"
9060 max2="1"
9061 min2="1" />
9062 </param_driver>
9063 </param>
9064
9065 <param
9066 id="815"
9067 group="0"
9068 wearable="pants"
9069 edit_group="pants"
9070 edit_group_order="1"
9071 name="Pants Length"
9072 show_simple="true"
9073 label_min="Short"
9074 label_max="Long"
9075 value_min="0"
9076 value_max="1"
9077 value_default=".8"
9078 simple_percent_min="20"
9079 simple_percent_max="100"
9080 camera_distance="1.8"
9081 camera_angle="30"
9082 camera_elevation="-.3">
9083 <param_driver>
9084 <driven
9085 id="615"
9086 min1="0"
9087 max1=".9"
9088 max2="1"
9089 min2="1" />
9090
9091 <driven
9092 id="1018"
9093 min1="0"
9094 max1=".9"
9095 max2="1"
9096 min2="1" />
9097
9098 <driven
9099 id="1036"
9100 min1="0"
9101 max1=".9"
9102 max2="1"
9103 min2="1" />
9104
9105 <driven
9106 id="793"
9107 min1=".9"
9108 max1="1"
9109 max2="1"
9110 min2="1" />
9111
9112 <driven
9113 id="915"
9114 min1="0"
9115 max1=".882"
9116 max2="1"
9117 min2="1" />
9118 </param_driver>
9119 </param>
9120
9121 <param
9122 id="800"
9123 group="0"
9124 wearable="shirt"
9125 edit_group="shirt"
9126 edit_group_order="1"
9127 name="Sleeve Length"
9128 show_simple="true"
9129 label_min="Short"
9130 label_max="Long"
9131 value_min="0"
9132 value_max="1"
9133 value_default=".89"
9134 simple_percent_min="15"
9135 simple_percent_max="100"
9136 camera_distance="1.2"
9137 camera_angle="30"
9138 camera_elevation=".2">
9139 <param_driver>
9140 <driven
9141 id="600" />
9142
9143 <driven
9144 id="1013" />
9145
9146 <driven
9147 id="1029" />
9148
9149 <driven
9150 id="900"
9151 min1="0"
9152 max1="1"
9153 max2="1"
9154 min2="1" />
9155 </param_driver>
9156 </param>
9157
9158 <param
9159 id="801"
9160 group="0"
9161 wearable="shirt"
9162 edit_group="shirt"
9163 edit_group_order="2"
9164 name="Shirt Bottom"
9165 label_min="Short"
9166 label_max="Long"
9167 value_min="0"
9168 value_max="1"
9169 value_default="1"
9170 camera_distance="1.2"
9171 camera_angle="30"
9172 camera_elevation=".2">
9173 <param_driver>
9174 <driven
9175 id="601" />
9176
9177 <driven
9178 id="1014" />
9179
9180 <driven
9181 id="1030" />
9182
9183 <driven
9184 id="901"
9185 min1="0"
9186 max1=".98"
9187 max2="1"
9188 min2="1" />
9189 </param_driver>
9190 </param>
9191
9192 <param
9193 id="802"
9194 group="0"
9195 wearable="shirt"
9196 edit_group="shirt"
9197 edit_group_order="3"
9198 name="Collar Front"
9199 show_simple="true"
9200 label_min="Low"
9201 label_max="High"
9202 value_min="0"
9203 value_max="1"
9204 value_default=".78"
9205 simple_percent_min="40"
9206 simple_percent_max="100"
9207 camera_distance="1.2"
9208 camera_angle="15"
9209 camera_elevation=".2">
9210 <param_driver>
9211 <driven
9212 id="602" />
9213
9214 <driven
9215 id="1015" />
9216
9217 <driven
9218 id="1031" />
9219
9220 <driven
9221 id="902"
9222 min1="0"
9223 max1=".98"
9224 max2="1"
9225 min2="1" />
9226 </param_driver>
9227 </param>
9228
9229 <param
9230 id="781"
9231 group="0"
9232 wearable="shirt"
9233 edit_group="shirt"
9234 edit_group_order="3.1"
9235 name="Collar Back"
9236 label_min="Low"
9237 label_max="High"
9238 value_min="0"
9239 value_max="1"
9240 value_default=".78"
9241 camera_distance="1.2"
9242 camera_angle="195"
9243 camera_elevation=".2">
9244 <param_driver>
9245 <driven
9246 id="778" />
9247
9248 <driven
9249 id="1016" />
9250
9251 <driven
9252 id="1032" />
9253
9254 <driven
9255 id="903"
9256 min1="0"
9257 max1=".98"
9258 max2="1"
9259 min2="1" />
9260 </param_driver>
9261 </param>
9262
9263 <param
9264 id="150"
9265 group="0"
9266 wearable="skin"
9267 edit_group="skin_bodydetail"
9268 name="Body Definition"
9269 label_min="Less"
9270 label_max="More"
9271 value_min="0"
9272 value_max="1"
9273 value_default="0"
9274 camera_distance="1.4"
9275 camera_elevation="-.2">
9276 <param_driver>
9277 <driven
9278 id="125" />
9279
9280 <driven
9281 id="126" />
9282
9283 <driven
9284 id="160" />
9285
9286 <driven
9287 id="161" />
9288
9289 <driven
9290 id="874" />
9291
9292 <driven
9293 id="878" />
9294
9295 </param_driver>
9296 </param>
9297
9298 <param
9299 id="775"
9300 group="0"
9301 wearable="skin"
9302 edit_group="skin_bodydetail"
9303 name="Body Freckles"
9304 label_min="Less Freckles"
9305 label_max="More Freckles"
9306 value_min="0"
9307 value_max="1"
9308 value_default="0"
9309 camera_distance="1.4"
9310 camera_elevation="-.2">
9311 <param_driver>
9312 <driven
9313 id="776" />
9314
9315 <driven
9316 id="777" />
9317 </param_driver>
9318 </param>
9319
9320 <param
9321 id="162"
9322 group="0"
9323 wearable="skin"
9324 edit_group="skin_facedetail"
9325 edit_group_order="1"
9326 name="Facial Definition"
9327 label_min="Less"
9328 label_max="More"
9329 value_min="0"
9330 value_max="1"
9331 camera_distance=".3"
9332 camera_elevation=".07"
9333 value_default="0">
9334 <param_driver>
9335 <driven
9336 id="158" />
9337
9338 <driven
9339 id="159" />
9340
9341 <driven
9342 id="873" />
9343 </param_driver>
9344 </param>
9345
9346 <param
9347 id="163"
9348 group="0"
9349 wearable="skin"
9350 edit_group="skin_facedetail"
9351 edit_group_order="3"
9352 name="wrinkles"
9353 label_min="Less"
9354 label_max="More"
9355 value_min="0"
9356 value_max="1"
9357 camera_distance=".3"
9358 camera_elevation=".07"
9359 value_default="0">
9360 <param_driver>
9361<!--<driven
9362 id="128" />-->
9363 <driven
9364 id="118" />
9365 </param_driver>
9366 </param>
9367
9368 <param
9369 id="505"
9370 group="0"
9371 wearable="shape"
9372 edit_group="shape_mouth"
9373 edit_group_order="3"
9374 name="Lip Thickness"
9375 label_min="Thin Lips"
9376 label_max="Fat Lips"
9377 value_min="0"
9378 value_max="1"
9379 value_default=".5"
9380 camera_distance=".3"
9381 camera_elevation=".04"
9382 camera_angle="20">
9383 <param_driver>
9384 <driven
9385 id="26"
9386 min1="0"
9387 max1="0"
9388 max2="0"
9389 min2=".5" />
9390
9391 <driven
9392 id="28"
9393 min1=".5"
9394 max1="1"
9395 max2="1"
9396 min2="1" />
9397 </param_driver>
9398 </param>
9399
9400 <param
9401 id="799"
9402 group="0"
9403 wearable="shape"
9404 edit_group="shape_mouth"
9405 edit_group_order="3.2"
9406 name="Lip Ratio"
9407 label="Lip Ratio"
9408 show_simple="true"
9409 label_min="More Upper Lip"
9410 label_max="More Lower Lip"
9411 value_min="0"
9412 value_max="1"
9413 value_default=".5"
9414 camera_distance=".3"
9415 camera_elevation=".04"
9416 camera_angle="20">
9417 <param_driver>
9418 <driven
9419 id="797"
9420 min1="0"
9421 max1="0"
9422 max2="0"
9423 min2=".5" />
9424
9425 <driven
9426 id="798"
9427 min1=".5"
9428 max1="1"
9429 max2="1"
9430 min2="1" />
9431 </param_driver>
9432 </param>
9433
9434 <param
9435 id="155"
9436 group="0"
9437 wearable="shape"
9438 edit_group="shape_mouth"
9439 edit_group_order="1"
9440 name="Lip Width"
9441 label="Lip Width"
9442 label_min="Narrow Lips"
9443 label_max="Wide Lips"
9444 show_simple="true"
9445 value_min="-0.9"
9446 value_max="1.3"
9447 camera_distance=".3"
9448 camera_elevation=".04"
9449 value_default="0">
9450 <param_driver>
9451 <driven
9452 id="29" />
9453
9454 <driven
9455 id="30" />
9456 </param_driver>
9457 </param>
9458
9459 <param
9460 id="196"
9461 group="0"
9462 wearable="shape"
9463 edit_group="shape_eyes"
9464 edit_group_order="2"
9465 name="Eye Spacing"
9466 label="Eye Spacing"
9467 label_min="Close Set Eyes"
9468 label_max="Far Set Eyes"
9469 show_simple="true"
9470 value_min="-2"
9471 value_max="1"
9472 value_default="0"
9473 camera_elevation=".1"
9474 camera_distance=".35"
9475 camera_angle="5">
9476 <param_driver>
9477 <driven
9478 id="194" />
9479
9480 <driven
9481 id="195" />
9482 </param_driver>
9483 </param>
9484
9485 <param
9486 id="769"
9487 group="0"
9488 wearable="shape"
9489 edit_group="shape_eyes"
9490 edit_group_order="4.5"
9491 name="Eye Depth"
9492 label_min="Sunken Eyes"
9493 label_max="Bugged Eyes"
9494 value_min="0"
9495 value_max="1"
9496 value_default=".5"
9497 camera_elevation=".1"
9498 camera_distance=".3"
9499 camera_angle="75">
9500 <param_driver>
9501 <driven
9502 id="767" />
9503
9504 <driven
9505 id="768" />
9506 </param_driver>
9507 </param>
9508
9509 <param
9510 id="198"
9511 group="0"
9512 wearable="shoes"
9513 edit_group="shoes"
9514 edit_group_order="2"
9515 name="Heel Height"
9516 label_min="Low Heels"
9517 label_max="High Heels"
9518 value_min="0"
9519 value_max="1"
9520 value_default="0"
9521 camera_angle="45"
9522 camera_distance=".8"
9523 camera_elevation="-1">
9524 <param_driver>
9525 <driven
9526 id="197" />
9527
9528 <driven
9529 id="500" />
9530 </param_driver>
9531 </param>
9532
9533 <param
9534 id="513"
9535 group="0"
9536 wearable="shoes"
9537 edit_group="shoes"
9538 edit_group_order="3"
9539 name="Heel Shape"
9540 label_min="Pointy Heels"
9541 label_max="Thick Heels"
9542 value_min="0"
9543 value_max="1"
9544 value_default=".5"
9545 camera_angle="45"
9546 camera_distance="1.5"
9547 camera_elevation="-1">
9548 <param_driver>
9549 <driven
9550 id="509"
9551 min1="0"
9552 max1="0"
9553 max2="0"
9554 min2=".5" />
9555
9556 <driven
9557 id="510"
9558 min1=".5"
9559 max1="1"
9560 max2="1"
9561 min2="1" />
9562 </param_driver>
9563 </param>
9564
9565 <param
9566 id="514"
9567 group="0"
9568 wearable="shoes"
9569 edit_group="shoes"
9570 edit_group_order="4"
9571 name="Toe Shape"
9572 label_min="Pointy"
9573 label_max="Square"
9574 value_min="0"
9575 value_max="1"
9576 value_default=".5"
9577 camera_angle="5"
9578 camera_distance=".8"
9579 camera_elevation="-.8">
9580 <param_driver>
9581 <driven
9582 id="511"
9583 min1="0"
9584 max1="0"
9585 max2="0"
9586 min2=".5" />
9587
9588 <driven
9589 id="512"
9590 min1=".5"
9591 max1="1"
9592 max2="1"
9593 min2="1" />
9594 </param_driver>
9595 </param>
9596
9597 <param
9598 id="503"
9599 group="0"
9600 wearable="shoes"
9601 edit_group="shoes"
9602 edit_group_order="6"
9603 name="Platform Height"
9604 label_min="Low Platforms"
9605 label_max="High Platforms"
9606 value_min="0"
9607 value_max="1"
9608 value_default="0"
9609 camera_angle="45"
9610 camera_distance=".5"
9611 camera_elevation="-1">
9612 <param_driver>
9613 <driven
9614 id="501" />
9615
9616 <driven
9617 id="502" />
9618 </param_driver>
9619 </param>
9620
9621 <param
9622 id="193"
9623 group="0"
9624 wearable="shape"
9625 edit_group="shape_head"
9626 edit_group_order="3"
9627 name="Head Shape"
9628 label="Head Shape"
9629 label_min="More Square"
9630 label_max="More Round"
9631 show_simple="true"
9632 value_min="0"
9633 value_max="1"
9634 value_default=".5"
9635 camera_elevation=".1"
9636 camera_distance=".5"
9637 camera_angle="20">
9638 <param_driver>
9639 <driven
9640 id="188"
9641 min1="0"
9642 max1="0"
9643 max2="0"
9644 min2=".5" />
9645
9646 <driven
9647 id="642"
9648 min1="0"
9649 max1="0"
9650 max2="0"
9651 min2=".5" />
9652
9653 <driven
9654 id="189"
9655 min1=".5"
9656 max1="1"
9657 max2="1"
9658 min2="1" />
9659
9660 <driven
9661 id="643"
9662 min1=".5"
9663 max1="1"
9664 max2="1"
9665 min2="1" />
9666 </param_driver>
9667 </param>
9668
9669 <param
9670 id="157"
9671 group="0"
9672 wearable="shape"
9673 edit_group="shape_torso"
9674 edit_group_order="13"
9675 name="Belly Size"
9676 label_min="Small"
9677 label_max="Big"
9678 value_min="0"
9679 value_max="1"
9680 value_default="0"
9681 camera_distance="1.4"
9682 camera_angle="30"
9683 camera_elevation=".2">
9684 <param_driver>
9685 <driven
9686 id="104" />
9687
9688 <driven
9689 id="156" />
9690
9691 <driven
9692 id="849" />
9693 </param_driver>
9694 </param>
9695
9696 <param
9697 id="637"
9698 group="0"
9699 wearable="shape"
9700 edit_group="shape_body"
9701 edit_group_order="3"
9702 name="Body Fat"
9703 label_min="Less Body Fat"
9704 label_max="More Body Fat"
9705 value_min="0"
9706 value_max="1"
9707 value_default="0"
9708 camera_distance="1.8">
9709 <param_driver>
9710 <driven
9711 id="633" />
9712
9713 <driven
9714 id="634" />
9715
9716 <driven
9717 id="635" />
9718
9719 <driven
9720 id="851" />
9721 </param_driver>
9722 </param>
9723
9724 <param
9725 id="130"
9726 group="0"
9727 wearable="hair"
9728 edit_group="hair_style"
9729 edit_group_order="8"
9730 name="Front Fringe"
9731 label_min="Short"
9732 label_max="Long"
9733 value_min="0"
9734 value_max="1"
9735 value_default=".45"
9736 camera_elevation=".1"
9737 camera_distance=".5"
9738 camera_angle="20">
9739 <param_driver>
9740 <driven
9741 id="144"
9742 min1="0"
9743 max1="0"
9744 max2="0"
9745 min2=".5" />
9746
9747 <driven
9748 id="145"
9749 min1=".5"
9750 max1="1"
9751 max2="1"
9752 min2="1" />
9753 </param_driver>
9754 </param>
9755
9756 <param
9757 id="131"
9758 group="0"
9759 wearable="hair"
9760 edit_group="hair_style"
9761 edit_group_order="9"
9762 name="Side Fringe"
9763 label_min="Short"
9764 label_max="Long"
9765 value_min="0"
9766 value_max="1"
9767 value_default=".5"
9768 camera_elevation=".1"
9769 camera_distance=".5"
9770 camera_angle="90">
9771 <param_driver>
9772 <driven
9773 id="146"
9774 min1="0"
9775 max1="0"
9776 max2="0"
9777 min2=".5" />
9778
9779 <driven
9780 id="147"
9781 min1=".5"
9782 max1="1"
9783 max2="1"
9784 min2="1" />
9785 </param_driver>
9786 </param>
9787
9788 <param
9789 id="132"
9790 group="0"
9791 wearable="hair"
9792 edit_group="hair_style"
9793 edit_group_order="10"
9794 name="Back Fringe"
9795 label_min="Short"
9796 label_max="Long"
9797 value_min="0"
9798 value_max="1"
9799 value_default=".39"
9800 camera_elevation=".1"
9801 camera_distance=".5"
9802 camera_angle="160">
9803 <param_driver>
9804 <driven
9805 id="148"
9806 min1="0"
9807 max1="0"
9808 max2="0"
9809 min2=".5" />
9810
9811 <driven
9812 id="149"
9813 min1=".5"
9814 max1="1"
9815 max2="1"
9816 min2="1" />
9817 </param_driver>
9818 </param>
9819
9820 <param
9821 id="133"
9822 group="0"
9823 wearable="hair"
9824 edit_group="hair_style"
9825 edit_group_order="2"
9826 name="Hair Front"
9827 label_min="Short"
9828 label_max="Long"
9829 value_min="0"
9830 value_max="1"
9831 value_default=".25"
9832 camera_elevation=".1"
9833 camera_distance=".5"
9834 camera_angle="20">
9835 <param_driver>
9836 <driven
9837 id="172"
9838 min1="0"
9839 max1="0"
9840 max2="0"
9841 min2=".5" />
9842
9843 <driven
9844 id="171"
9845 min1=".5"
9846 max1="1"
9847 max2="1"
9848 min2="1" />
9849 </param_driver>
9850 </param>
9851
9852 <param
9853 id="134"
9854 group="0"
9855 wearable="hair"
9856 edit_group="hair_style"
9857 edit_group_order="3"
9858 name="Hair Sides"
9859 label_min="Short"
9860 label_max="Long"
9861 value_min="0"
9862 value_max="1"
9863 value_default=".5"
9864 camera_elevation=".1"
9865 camera_distance=".5"
9866 camera_angle="90">
9867 <param_driver>
9868 <driven
9869 id="174"
9870 min1="0"
9871 max1="0"
9872 max2="0"
9873 min2=".5" />
9874
9875 <driven
9876 id="173"
9877 min1=".5"
9878 max1="1"
9879 max2="1"
9880 min2="1" />
9881 </param_driver>
9882 </param>
9883
9884 <param
9885 id="135"
9886 group="0"
9887 wearable="hair"
9888 edit_group="hair_style"
9889 edit_group_order="4"
9890 name="Hair Back"
9891 show_simple="true"
9892 label_min="Short"
9893 label_max="Long"
9894 value_min="0"
9895 value_max="1"
9896 value_default=".55"
9897 camera_elevation="-.1"
9898 camera_distance=".8"
9899 camera_angle="160">
9900 <param_driver>
9901 <driven
9902 id="176"
9903 min1="0"
9904 max1="0"
9905 max2="0"
9906 min2=".5" />
9907
9908 <driven
9909 id="175"
9910 min1=".5"
9911 max1="1"
9912 max2="1"
9913 min2="1" />
9914 </param_driver>
9915 </param>
9916
9917 <param
9918 id="136"
9919 group="0"
9920 wearable="hair"
9921 edit_group="hair_style"
9922 edit_group_order="11.5"
9923 name="Hair Sweep"
9924 label_min="Sweep Forward"
9925 label_max="Sweep Back"
9926 value_min="0"
9927 value_max="1"
9928 value_default=".5"
9929 camera_elevation=".1"
9930 camera_distance=".5"
9931 camera_angle="90">
9932 <param_driver>
9933 <driven
9934 id="179"
9935 min1="0"
9936 max1="0"
9937 max2="0"
9938 min2=".5" />
9939
9940 <driven
9941 id="178"
9942 min1=".5"
9943 max1="1"
9944 max2="1"
9945 min2="1" />
9946 </param_driver>
9947 </param>
9948
9949 <param
9950 id="137"
9951 group="0"
9952 wearable="hair"
9953 edit_group="hair_style"
9954 edit_group_order="16"
9955 name="Hair Tilt"
9956 label_min="Left"
9957 label_max="Right"
9958 value_min="0"
9959 value_max="1"
9960 value_default=".5"
9961 camera_elevation=".1"
9962 camera_distance=".5"
9963 camera_angle="0">
9964 <param_driver>
9965 <driven
9966 id="190"
9967 min1="0"
9968 max1="0"
9969 max2="0"
9970 min2=".5" />
9971
9972 <driven
9973 id="191"
9974 min1=".5"
9975 max1="1"
9976 max2="1"
9977 min2="1" />
9978 </param_driver>
9979 </param>
9980
9981 <param
9982 id="608"
9983 group="0"
9984 wearable="jacket"
9985 edit_group="jacket"
9986 edit_group_order="2"
9987 name="bottom length lower"
9988 label="Jacket Length"
9989 label_min="Short"
9990 label_max="Long"
9991 value_min="0"
9992 value_max="1"
9993 value_default=".8"
9994 camera_distance="1.4"
9995 camera_angle="30"
9996 camera_elevation=".2">
9997 <param_driver>
9998 <driven
9999 id="620" />
10000
10001 <driven
10002 id="1025" />
10003
10004 <driven
10005 id="1037" />
10006
10007 <driven
10008 id="621" />
10009
10010 <driven
10011 id="1027" />
10012
10013 <driven
10014 id="1033" />
10015 </param_driver>
10016 </param>
10017
10018 <param
10019 id="609"
10020 group="0"
10021 wearable="jacket"
10022 edit_group="jacket"
10023 edit_group_order="4"
10024 name="open jacket"
10025 label="Open Front"
10026 label_min="Open"
10027 label_max="Closed"
10028 value_min="0"
10029 value_max="1"
10030 value_default=".2"
10031 camera_distance="1.4"
10032 camera_angle="30"
10033 camera_elevation=".2">
10034 <param_driver>
10035 <driven
10036 id="622" />
10037
10038 <driven
10039 id="1026" />
10040
10041 <driven
10042 id="1038" />
10043
10044 <driven
10045 id="623" />
10046
10047 <driven
10048 id="1028" />
10049
10050 <driven
10051 id="1034" />
10052 </param_driver>
10053 </param>
10054
10055 <param
10056 id="105"
10057 group="0"
10058 sex="female"
10059 wearable="shape"
10060 edit_group="shape_torso"
10061 edit_group_order="6"
10062 name="Breast Size"
10063 label_min="Small"
10064 label_max="Large"
10065 value_min="0"
10066 value_max="1"
10067 value_default=".5"
10068 camera_elevation=".3"
10069 camera_distance="1.2"
10070 camera_angle="30">
10071 <param_driver>
10072 <driven
10073 id="843"
10074 min1="0"
10075 max1="0"
10076 max2="0"
10077 min2=".01" />
10078
10079 <driven
10080 id="627"
10081 min1="0"
10082 max1="0.01"
10083 max2="0.01"
10084 min2=".5" />
10085
10086 <driven
10087 id="626"
10088 min1=".5"
10089 max1="1"
10090 max2="1"
10091 min2="1" />
10092 </param_driver>
10093 </param>
10094
10095 <param
10096 id="629"
10097 group="0"
10098 wearable="shape"
10099 edit_group="shape_head"
10100 edit_group_order="6"
10101 name="Forehead Angle"
10102 label_min="More Vertical"
10103 label_max="More Sloped"
10104 value_min="0"
10105 value_max="1"
10106 value_default=".5"
10107 camera_elevation=".1"
10108 camera_distance=".5"
10109 camera_angle="70">
10110 <param_driver>
10111 <driven
10112 id="630"
10113 min1="0"
10114 max1="0"
10115 max2="0"
10116 min2=".5" />
10117
10118 <driven
10119 id="644"
10120 min1="0"
10121 max1="0"
10122 max2="0"
10123 min2=".5" />
10124
10125 <driven
10126 id="631"
10127 min1=".5"
10128 max1="1"
10129 max2="1"
10130 min2="1" />
10131
10132 <driven
10133 id="645"
10134 min1=".5"
10135 max1="1"
10136 max2="1"
10137 min2="1" />
10138 </param_driver>
10139 </param>
10140
10141 <param
10142 id="646"
10143 group="0"
10144 name="Egg_Head"
10145 label="Egg Head"
10146 wearable="shape"
10147 edit_group="shape_head"
10148 edit_group_order="4"
10149 label_min="Chin Heavy"
10150 label_max="Forehead Heavy"
10151 show_simple="true"
10152 value_min="-1.3"
10153 value_max="1"
10154 value_default="0"
10155 camera_elevation=".1"
10156 camera_distance=".5"
10157 camera_angle="20">
10158 <param_driver>
10159 <driven
10160 id="640" />
10161
10162 <driven
10163 id="186" />
10164 </param_driver>
10165 </param>
10166
10167 <param
10168 id="647"
10169 group="0"
10170 name="Squash_Stretch_Head"
10171 label="Head Stretch"
10172 wearable="shape"
10173 edit_group="shape_head"
10174 edit_group_order="2"
10175 show_simple="true"
10176 label_min="Squash Head"
10177 label_max="Stretch Head"
10178 value_min="-0.5"
10179 value_max="1"
10180 value_default="0"
10181 camera_elevation=".1"
10182 camera_distance=".5"
10183 camera_angle="20">
10184 <param_driver>
10185 <driven
10186 id="641" />
10187
10188 <driven
10189 id="187" />
10190 </param_driver>
10191 </param>
10192
10193 <param
10194 id="649"
10195 group="0"
10196 sex="female"
10197 wearable="shape"
10198 edit_group="shape_torso"
10199 edit_group_order="1.1"
10200 name="Torso Muscles"
10201 label="Torso Muscles"
10202 show_simple="true"
10203 label_min="Less Muscular"
10204 label_max="More Muscular"
10205 value_min="0"
10206 value_max="1"
10207 value_default=".5"
10208 camera_elevation=".1"
10209 camera_distance="1"
10210 camera_angle="15">
10211 <param_driver>
10212 <driven
10213 id="648"
10214 min1="0"
10215 max1="0"
10216 max2="0"
10217 min2=".5" />
10218
10219 <driven
10220 id="106"
10221 min1=".5"
10222 max1="1"
10223 max2="1"
10224 min2="1" />
10225 </param_driver>
10226 </param>
10227
10228 <param
10229 id="678"
10230 group="0"
10231 sex="male"
10232 wearable="shape"
10233 edit_group="shape_torso"
10234 edit_group_order="1"
10235 name="Torso Muscles"
10236 show_simple="true"
10237 label_min="Less Muscular"
10238 label_max="More Muscular"
10239 value_min="0"
10240 value_max="1"
10241 value_default=".5"
10242 camera_elevation=".1"
10243 camera_distance="1.2"
10244 camera_angle="0">
10245 <param_driver>
10246 <driven
10247 id="677"
10248 min1="0"
10249 max1="0"
10250 max2="0"
10251 min2=".5" />
10252
10253 <driven
10254 id="106"
10255 min1=".5"
10256 max1="1"
10257 max2="1"
10258 min2="1" />
10259 </param_driver>
10260 </param>
10261
10262 <param
10263 id="652"
10264 group="0"
10265 wearable="shape"
10266 edit_group="shape_legs"
10267 edit_group_order="1"
10268 name="Leg Muscles"
10269 label_min="Less Muscular"
10270 label_max="More Muscular"
10271 show_simple="true"
10272 value_min="0"
10273 value_max="1"
10274 value_default=".5"
10275 camera_distance="1.3"
10276 camera_elevation="-.5"
10277 camera_angle="15">
10278 <param_driver>
10279 <driven
10280 id="651"
10281 min1="0"
10282 max1="0"
10283 max2="0"
10284 min2=".5" />
10285
10286 <driven
10287 id="152"
10288 min1=".5"
10289 max1="1"
10290 max2="1"
10291 min2="1" />
10292 </param_driver>
10293 </param>
10294
10295 <param
10296 id="80"
10297 name="male"
10298 group="0"
10299 edit_group="dummy"
10300 wearable="shape"
10301 value_min="0"
10302 value_max="1">
10303 <param_driver>
10304 <driven
10305 id="32" />
10306
10307 <driven
10308 id="153" />
10309
10310 <driven
10311 id="40" />
10312
10313 <driven
10314 id="100" />
10315
10316 <driven
10317 id="857" />
10318 </param_driver>
10319 </param>
10320
10321 <param
10322 id="659"
10323 group="0"
10324 wearable="shape"
10325 edit_group="shape_mouth"
10326 edit_group_order="5"
10327 name="Mouth Corner"
10328 label_min="Corner Down"
10329 label_max="Corner Up"
10330 value_min="0"
10331 value_max="1"
10332 value_default=".5"
10333 camera_elevation="0"
10334 camera_distance=".28">
10335 <param_driver>
10336 <driven
10337 id="658"
10338 min1="0"
10339 max1="0"
10340 max2="0"
10341 min2=".5" />
10342
10343 <driven
10344 id="657"
10345 min1=".5"
10346 max1="1"
10347 max2="1"
10348 min2="1" />
10349 </param_driver>
10350 </param>
10351
10352 <param
10353 id="662"
10354 group="0"
10355 wearable="shape"
10356 edit_group="shape_head"
10357 edit_group_order="5"
10358 name="Face Shear"
10359 label_min="Shear Right Up"
10360 label_max="Shear Left Up"
10361 value_min="0"
10362 value_max="1"
10363 value_default=".5"
10364 camera_elevation=".1"
10365 camera_distance=".5">
10366 <param_driver>
10367 <driven
10368 id="660" />
10369
10370 <driven
10371 id="661" />
10372
10373 <driven
10374 id="774" />
10375 </param_driver>
10376 </param>
10377
10378 <param
10379 id="773"
10380 group="0"
10381 wearable="shape"
10382 edit_group="shape_head"
10383 edit_group_order="4.5"
10384 name="Head Length"
10385 label_min="Flat Head"
10386 label_max="Long Head"
10387 value_min="0"
10388 value_max="1"
10389 value_default=".5"
10390 camera_elevation=".1"
10391 camera_distance=".5"
10392 camera_angle="75">
10393 <param_driver>
10394 <driven
10395 id="770" />
10396
10397 <driven
10398 id="771" />
10399
10400 <driven
10401 id="772" />
10402 </param_driver>
10403 </param>
10404
10405 <param
10406 id="682"
10407 group="0"
10408 wearable="shape"
10409 edit_group="shape_head"
10410 edit_group_order="1"
10411 name="Head Size"
10412 label="Head Size"
10413 label_min="Small Head"
10414 label_max="Big Head"
10415 show_simple="true"
10416 value_min="0"
10417 value_max="1"
10418 value_default=".5"
10419 camera_elevation=".1"
10420 camera_distance=".5">
10421 <param_driver>
10422 <driven
10423 id="679" />
10424
10425 <driven
10426 id="694" />
10427
10428 <driven
10429 id="680" />
10430
10431 <driven
10432 id="681" />
10433
10434 <driven
10435 id="655" />
10436 </param_driver>
10437 </param>
10438
10439 <param
10440 id="690"
10441 group="0"
10442 wearable="shape"
10443 edit_group="shape_eyes"
10444 edit_group_order="1"
10445 name="Eye Size"
10446 label="Eye Size"
10447 label_min="Beady Eyes"
10448 label_max="Anime Eyes"
10449 value_min="0"
10450 value_max="1"
10451 value_default=".5"
10452 show_simple="true"
10453 camera_elevation=".1"
10454 camera_distance=".35">
10455 <param_driver>
10456 <driven
10457 id="686" />
10458
10459 <driven
10460 id="687" />
10461
10462 <driven
10463 id="695" />
10464
10465 <driven
10466 id="688" />
10467
10468 <driven
10469 id="691" />
10470
10471 <driven
10472 id="689" />
10473 </param_driver>
10474 </param>
10475
10476 <param
10477 id="752"
10478 group="0"
10479 sex="male"
10480 wearable="hair"
10481 edit_group="hair_facial"
10482 edit_group_order="1"
10483 name="Hair Thickness"
10484 label_min="5 O'Clock Shadow"
10485 label_max="Bushy Hair"
10486 value_min="0"
10487 value_max="1"
10488 value_default=".5"
10489 camera_elevation="0"
10490 camera_distance=".28">
10491 <param_driver>
10492 <driven
10493 id="751"
10494 min1="0"
10495 max1="0"
10496 max2="0"
10497 min2=".2" />
10498
10499 <driven
10500 id="1012"
10501 min1="0"
10502 max1="0"
10503 max2=".2"
10504 min2=".6" />
10505
10506 <driven
10507 id="400"
10508 min1=".2"
10509 max1="1"
10510 max2="1"
10511 min2="1" />
10512 </param_driver>
10513 </param>
10514
10515 <param
10516 id="763"
10517 group="0"
10518 wearable="hair"
10519 edit_group="hair_style"
10520 edit_group_order="1"
10521 name="Hair Volume"
10522 show_simple="true"
10523 label_min="Less Volume"
10524 label_max="More Volume"
10525 value_min="0"
10526 value_max="1"
10527 value_default=".55"
10528 camera_elevation=".1"
10529 camera_distance=".5"
10530 camera_angle="20">
10531 <param_driver>
10532 <driven
10533 id="761"
10534 min1="0"
10535 max1="0"
10536 max2="0"
10537 min2=".5" />
10538
10539 <driven
10540 id="180"
10541 min1=".5"
10542 max1="1"
10543 max2="1"
10544 min2="1" />
10545 </param_driver>
10546 </param>
10547
10548 <param
10549 id="834"
10550 group="0"
10551 wearable="jacket"
10552 edit_group="colorpicker"
10553 name="jacket_red"
10554 value_min="0"
10555 value_max="1"
10556 value_default="1">
10557 <param_driver>
10558 <driven
10559 id="809"
10560 min1="0"
10561 max1="1"
10562 max2="1"
10563 min2="1" />
10564
10565 <driven
10566 id="831"
10567 min1="0"
10568 max1="1"
10569 max2="1"
10570 min2="1" />
10571 </param_driver>
10572 </param>
10573
10574 <param
10575 id="835"
10576 group="0"
10577 wearable="jacket"
10578 edit_group="colorpicker"
10579 name="jacket_green"
10580 value_min="0"
10581 value_max="1"
10582 value_default="1">
10583 <param_driver>
10584 <driven
10585 id="810"
10586 min1="0"
10587 max1="1"
10588 max2="1"
10589 min2="1" />
10590
10591 <driven
10592 id="832"
10593 min1="0"
10594 max1="1"
10595 max2="1"
10596 min2="1" />
10597 </param_driver>
10598 </param>
10599
10600 <param
10601 id="836"
10602 group="0"
10603 wearable="jacket"
10604 edit_group="colorpicker"
10605 name="jacket_blue"
10606 value_min="0"
10607 value_max="1"
10608 value_default="1">
10609 <param_driver>
10610 <driven
10611 id="811"
10612 min1="0"
10613 max1="1"
10614 max2="1"
10615 min2="1" />
10616
10617 <driven
10618 id="833"
10619 min1="0"
10620 max1="1"
10621 max2="1"
10622 min2="1" />
10623 </param_driver>
10624 </param>
10625
10626 <param
10627 id="785"
10628 group="0"
10629 wearable="hair"
10630 edit_group="hair_style"
10631 edit_group_order="14.6"
10632 name="Pigtails"
10633 show_simple="true"
10634 label_min="Short Pigtails"
10635 label_max="Long Pigtails"
10636 value_min="0"
10637 value_max="1"
10638 value_default="0"
10639 camera_elevation=".1"
10640 camera_distance=".5"
10641 camera_angle="15">
10642 <param_driver>
10643 <driven
10644 id="782"
10645 min1="0"
10646 max1=".10"
10647 max2=".10"
10648 min2=".5" />
10649
10650 <driven
10651 id="783"
10652 min1=".10"
10653 max1=".5"
10654 max2=".5"
10655 min2=".75" />
10656
10657 <driven
10658 id="790"
10659 min1=".5"
10660 max1=".75"
10661 max2=".75"
10662 min2="1" />
10663
10664 <driven
10665 id="784"
10666 min1=".75"
10667 max1="1"
10668 max2="1"
10669 min2="1" />
10670 </param_driver>
10671 </param>
10672
10673 <param
10674 id="789"
10675 group="0"
10676 wearable="hair"
10677 edit_group="hair_style"
10678 edit_group_order="14.7"
10679 name="Ponytail"
10680 label_min="Short Ponytail"
10681 label_max="Long Ponytail"
10682 value_min="0"
10683 value_max="1"
10684 value_default="0"
10685 camera_elevation=".1"
10686 camera_distance=".5"
10687 camera_angle="180">
10688 <param_driver>
10689 <driven
10690 id="786"
10691 min1="0"
10692 max1=".10"
10693 max2=".10"
10694 min2=".66" />
10695
10696 <driven
10697 id="787"
10698 min1=".10"
10699 max1=".66"
10700 max2=".66"
10701 min2="1" />
10702
10703 <driven
10704 id="788"
10705 min1=".66"
10706 max1="1"
10707 max2="1"
10708 min2="1" />
10709 </param_driver>
10710 </param>
10711
10712 <param
10713 id="795"
10714 group="0"
10715 name="Butt Size"
10716 label="Butt Size"
10717 wearable="shape"
10718 edit_group="shape_legs"
10719 edit_group_order="4"
10720 label_min="Flat Butt"
10721 label_max="Big Butt"
10722 value_min="0"
10723 value_max="1"
10724 value_default=".25"
10725 camera_angle="180"
10726 camera_distance=".6">
10727 <param_driver>
10728 <driven
10729 id="867"
10730 min1="0"
10731 max1="0"
10732 max2="0"
10733 min2=".3" />
10734
10735 <driven
10736 id="794"
10737 min1="0"
10738 max1="0"
10739 max2="0"
10740 min2=".3" />
10741
10742 <driven
10743 id="151"
10744 min1=".3"
10745 max1="1"
10746 max2="1"
10747 min2="1" />
10748
10749 <driven
10750 id="852"
10751 min1=".3"
10752 max1="1"
10753 max2="1"
10754 min2="1" />
10755 </param_driver>
10756 </param>
10757
10758 <param
10759 id="841"
10760 group="0"
10761 name="Bowed_Legs"
10762 label="Knee Angle"
10763 wearable="shape"
10764 edit_group_order="5.5"
10765 edit_group="shape_legs"
10766 label_min="Knock Kneed"
10767 label_max="Bow Legged"
10768 value_min="-1"
10769 value_max="1"
10770 value_default="0"
10771 camera_distance="1.3"
10772 camera_elevation="-.5">
10773 <param_driver>
10774 <driven
10775 id="853" />
10776
10777 <driven
10778 id="847" />
10779 </param_driver>
10780 </param>
10781
10782 <param
10783 id="753"
10784 group="0"
10785 name="Saddlebags"
10786 label="Saddle Bags"
10787 wearable="shape"
10788 edit_group="shape_legs"
10789 edit_group_order="5"
10790 label_min="Less Saddle"
10791 label_max="More Saddle"
10792 value_min="-0.5"
10793 value_max="3"
10794 value_default="0"
10795 camera_angle="0"
10796 camera_distance="1.2">
10797 <param_driver>
10798 <driven
10799 id="850" />
10800
10801 <driven
10802 id="854" />
10803 </param_driver>
10804 </param>
10805
10806 <param
10807 id="676"
10808 group="0"
10809 name="Love_Handles"
10810 label="Love Handles"
10811 wearable="shape"
10812 edit_group="shape_torso"
10813 edit_group_order="12"
10814 label_min="Less Love"
10815 label_max="More Love"
10816 value_min="-1"
10817 value_max="2"
10818 value_default="0"
10819 camera_elevation=".3"
10820 camera_distance=".9">
10821 <param_driver>
10822 <driven
10823 id="855" />
10824
10825 <driven
10826 id="856" />
10827 </param_driver>
10828 </param>
10829
10830 <param
10831 id="863"
10832 group="0"
10833 name="skirt_looseness"
10834 label="Skirt Fit"
10835 show_simple="true"
10836 clothing_morph="true"
10837 wearable="skirt"
10838 edit_group_order="2"
10839 edit_group="skirt"
10840 label_min="Tight Skirt"
10841 label_max="Poofy Skirt"
10842 value_min="0"
10843 value_max="1"
10844 value_default=".333"
10845 camera_distance="1.3"
10846 camera_elevation="-.5">
10847 <param_driver>
10848 <driven
10849 id="866"
10850 min1="0"
10851 max1="0"
10852 max2="0"
10853 min2=".2" />
10854
10855 <driven
10856 id="846"
10857 min1="0"
10858 max1=".5"
10859 max2=".5"
10860 min2="1" />
10861
10862 <driven
10863 id="845"
10864 min1=".5"
10865 max1="1"
10866 max2="1"
10867 min2="1" />
10868 </param_driver>
10869 </param>
10870
10871 <param
10872 id="119"
10873 group="0"
10874 wearable="hair"
10875 edit_group="hair_eyebrows"
10876 edit_group_order="1"
10877 name="Eyebrow Size"
10878 show_simple="true"
10879 label_min="Thin Eyebrows"
10880 label_max="Bushy Eyebrows"
10881 value_min="0"
10882 value_max="1"
10883 value_default="0.5"
10884 camera_elevation=".1"
10885 camera_distance=".3">
10886 <param_driver>
10887 <driven
10888 id="1000" />
10889
10890 <driven
10891 id="1001" />
10892 </param_driver>
10893 </param>
10894
10895 <param
10896 id="750"
10897 group="0"
10898 wearable="hair"
10899 edit_group="hair_eyebrows"
10900 edit_group_order="2"
10901 name="Eyebrow Density"
10902 label_min="Sparse"
10903 label_max="Dense"
10904 value_min="0"
10905 value_max="1"
10906 value_default="0.7"
10907 camera_elevation=".1"
10908 camera_distance=".3">
10909 <param_driver>
10910 <driven
10911 id="1002" />
10912
10913 <driven
10914 id="1003" />
10915 </param_driver>
10916 </param>
10917
10918 <param
10919 id="166"
10920 sex="male"
10921 group="0"
10922 wearable="hair"
10923 edit_group="hair_facial"
10924 edit_group_order="2"
10925 name="Sideburns"
10926 show_simple="true"
10927 label_min="Short Sideburns"
10928 label_max="Mutton Chops"
10929 value_min="0"
10930 value_max="1"
10931 value_default="0.0"
10932 camera_elevation=".1"
10933 camera_distance=".3"
10934 camera_angle="30">
10935 <param_driver>
10936 <driven
10937 id="1004" />
10938
10939 <driven
10940 id="1005" />
10941 </param_driver>
10942 </param>
10943
10944 <param
10945 id="167"
10946 sex="male"
10947 group="0"
10948 wearable="hair"
10949 edit_group="hair_facial"
10950 edit_group_order="3"
10951 name="Moustache"
10952 show_simple="true"
10953 label_min="Chaplin"
10954 label_max="Handlebars"
10955 value_min="0"
10956 value_max="1"
10957 value_default="0.0"
10958 camera_elevation=".1"
10959 camera_distance=".3"
10960 camera_angle="30">
10961 <param_driver>
10962 <driven
10963 id="1006" />
10964
10965 <driven
10966 id="1007" />
10967 </param_driver>
10968 </param>
10969
10970 <param
10971 id="168"
10972 sex="male"
10973 group="0"
10974 wearable="hair"
10975 edit_group="hair_facial"
10976 edit_group_order="5"
10977 name="Soulpatch"
10978 show_simple="true"
10979 label_min="Less soul"
10980 label_max="More soul"
10981 value_min="0"
10982 value_max="1"
10983 value_default="0.0"
10984 camera_elevation="-.1"
10985 camera_distance=".3"
10986 camera_angle="0">
10987 <param_driver>
10988 <driven
10989 id="1008" />
10990
10991 <driven
10992 id="1009" />
10993 </param_driver>
10994 </param>
10995
10996 <param
10997 id="169"
10998 sex="male"
10999 group="0"
11000 wearable="hair"
11001 edit_group="hair_facial"
11002 edit_group_order="4"
11003 name="Chin Curtains"
11004 show_simple="true"
11005 label_min="Less Curtains"
11006 label_max="More Curtains"
11007 value_min="0"
11008 value_max="1"
11009 value_default="0.0"
11010 camera_elevation="-.1"
11011 camera_distance=".3"
11012 camera_angle="45">
11013 <param_driver>
11014 <driven
11015 id="1010" />
11016
11017 <driven
11018 id="1011" />
11019 </param_driver>
11020 </param>
11021
11022 <param
11023 id="606"
11024 group="0"
11025 wearable="jacket"
11026 edit_group="jacket"
11027 edit_group_order="1"
11028 name="Sleeve Length"
11029 label_min="Short"
11030 label_max="Long"
11031 value_min="0"
11032 value_max="1"
11033 value_default=".8"
11034 camera_distance="1.2"
11035 camera_angle="30"
11036 camera_elevation=".2">
11037 <param_driver>
11038 <driven
11039 id="1019" />
11040
11041 <driven
11042 id="1039" />
11043
11044 <driven
11045 id="1020" />
11046 </param_driver>
11047 </param>
11048
11049 <param
11050 id="607"
11051 group="0"
11052 wearable="jacket"
11053 edit_group="jacket"
11054 edit_group_order="3"
11055 name="Collar Front"
11056 label_min="Low"
11057 label_max="High"
11058 value_min="0"
11059 value_max="1"
11060 value_default=".8"
11061 camera_distance="1.2"
11062 camera_angle="15"
11063 camera_elevation=".2">
11064 <param_driver>
11065 <driven
11066 id="1021" />
11067
11068 <driven
11069 id="1040" />
11070
11071 <driven
11072 id="1022" />
11073 </param_driver>
11074 </param>
11075
11076 <param
11077 id="780"
11078 group="0"
11079 wearable="jacket"
11080 edit_group="jacket"
11081 edit_group_order="3.5"
11082 name="Collar Back"
11083 label_min="Low"
11084 label_max="High"
11085 value_min="0"
11086 value_max="1"
11087 value_default=".8"
11088 camera_distance="1.2"
11089 camera_angle="195"
11090 camera_elevation=".2">
11091 <param_driver>
11092 <driven
11093 id="1023" />
11094
11095 <driven
11096 id="1041" />
11097
11098 <driven
11099 id="1024" />
11100 </param_driver>
11101 </param>
11102
11103 <param
11104 id="603"
11105 group="0"
11106 wearable="undershirt"
11107 edit_group="undershirt"
11108 edit_group_order="1"
11109 name="Sleeve Length"
11110 label_min="Short"
11111 label_max="Long"
11112 value_min=".01"
11113 value_max="1"
11114 value_default=".4"
11115 camera_distance="1.2"
11116 camera_angle="30"
11117 camera_elevation=".2">
11118 <param_driver>
11119 <driven
11120 id="1042" />
11121
11122 <driven
11123 id="1043" />
11124 </param_driver>
11125 </param>
11126
11127 <param
11128 id="604"
11129 group="0"
11130 wearable="undershirt"
11131 edit_group="undershirt"
11132 edit_group_order="2"
11133 name="Bottom"
11134 label_min="Short"
11135 label_max="Long"
11136 value_min="0"
11137 value_max="1"
11138 value_default=".85"
11139 camera_distance="1.2"
11140 camera_angle="30"
11141 camera_elevation=".2">
11142 <param_driver>
11143 <driven
11144 id="1044" />
11145
11146 <driven
11147 id="1045" />
11148 </param_driver>
11149 </param>
11150
11151 <param
11152 id="605"
11153 group="0"
11154 wearable="undershirt"
11155 edit_group="undershirt"
11156 edit_group_order="3"
11157 name="Collar Front"
11158 label_min="Low"
11159 label_max="High"
11160 value_min="0"
11161 value_max="1"
11162 value_default=".84"
11163 camera_distance=".8"
11164 camera_angle="15"
11165 camera_elevation=".2">
11166 <param_driver>
11167 <driven
11168 id="1046" />
11169
11170 <driven
11171 id="1047" />
11172 </param_driver>
11173 </param>
11174
11175 <param
11176 id="779"
11177 group="0"
11178 wearable="undershirt"
11179 edit_group="undershirt"
11180 edit_group_order="4"
11181 name="Collar Back"
11182 label_min="Low"
11183 label_max="High"
11184 value_min="0"
11185 value_max="1"
11186 value_default=".84"
11187 camera_distance=".8"
11188 camera_angle="195"
11189 camera_elevation=".2">
11190 <param_driver>
11191 <driven
11192 id="1048" />
11193
11194 <driven
11195 id="1049" />
11196 </param_driver>
11197 </param>
11198
11199 <param
11200 id="617"
11201 group="0"
11202 wearable="socks"
11203 edit_group="socks"
11204 name="Socks Length"
11205 label_min="Short"
11206 label_max="Long"
11207 value_min="0"
11208 value_max="1"
11209 value_default="0.35"
11210 camera_distance=".95"
11211 camera_angle="30"
11212 camera_elevation="-.75">
11213 <param_driver>
11214 <driven
11215 id="1050" />
11216
11217 <driven
11218 id="1051" />
11219 </param_driver>
11220 </param>
11221
11222 <param
11223 id="616"
11224 group="0"
11225 wearable="shoes"
11226 edit_group="shoes"
11227 edit_group_order="1"
11228 name="Shoe Height"
11229 label_min="Short"
11230 label_max="Tall"
11231 value_min="0"
11232 value_max="1"
11233 value_default="0.1"
11234 camera_distance="1.2"
11235 camera_angle="30"
11236 camera_elevation="-.75">
11237 <param_driver>
11238 <driven
11239 id="1052" />
11240
11241 <driven
11242 id="1053" />
11243 </param_driver>
11244 </param>
11245
11246 <param
11247 id="619"
11248 group="0"
11249 wearable="underpants"
11250 edit_group="underpants"
11251 name="Pants Length"
11252 label_min="Short"
11253 label_max="Long"
11254 value_min="0"
11255 value_max="1"
11256 value_default=".3"
11257 camera_distance="1.2"
11258 camera_angle="30"
11259 camera_elevation="-.3">
11260 <param_driver>
11261 <driven
11262 id="1054" />
11263
11264 <driven
11265 id="1055" />
11266 </param_driver>
11267 </param>
11268
11269 <param
11270 id="624"
11271 group="0"
11272 wearable="underpants"
11273 edit_group="underpants"
11274 name="Pants Waist"
11275 label_min="Low"
11276 label_max="High"
11277 value_min="0"
11278 value_max="1"
11279 value_default=".8"
11280 camera_distance="1.2"
11281 camera_angle="30"
11282 camera_elevation="-.3">
11283 <param_driver>
11284 <driven
11285 id="1056" />
11286
11287 <driven
11288 id="1057" />
11289 </param_driver>
11290 </param>
11291
11292 <param
11293 id="93"
11294 group="0"
11295 wearable="gloves"
11296 edit_group="gloves"
11297 name="Glove Length"
11298 label_min="Short"
11299 label_max="Long"
11300 value_min=".01"
11301 value_max="1"
11302 value_default=".8"
11303 camera_distance="1.2"
11304 camera_angle="30"
11305 camera_elevation=".2">
11306 <param_driver>
11307 <driven
11308 id="1058" />
11309
11310 <driven
11311 id="1059" />
11312 </param_driver>
11313 </param>
11314
11315 <param
11316 id="844"
11317 group="0"
11318 wearable="gloves"
11319 edit_group="gloves"
11320 name="Glove Fingers"
11321 label_min="Fingerless"
11322 label_max="Fingers"
11323 value_min=".01"
11324 value_max="1"
11325 value_default="1"
11326 camera_distance="1.2"
11327 camera_angle="30"
11328 camera_elevation=".2">
11329 <param_driver>
11330 <driven
11331 id="1060" />
11332
11333 <driven
11334 id="1061" />
11335 </param_driver>
11336 </param>
11337
11338<!--Pointy eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
11339 <param
11340 id="16"
11341 group="0"
11342 name="Pointy_Eyebrows"
11343 label="Eyebrow Points"
11344 wearable="hair"
11345 edit_group="hair_eyebrows"
11346 edit_group_order="4"
11347 label_min="Smooth"
11348 label_max="Pointy"
11349 value_min="-.5"
11350 value_max="3"
11351 camera_elevation=".1"
11352 camera_distance=".3">
11353 <param_driver>
11354 <driven
11355 id="870" />
11356 </param_driver>
11357 </param>
11358
11359<!--Lower eyebrows became a driver/driven param with new min value for backwards compatibility between 1.0 and 1.1-->
11360 <param
11361 id="757"
11362 group="0"
11363 name="Lower_Eyebrows"
11364 label="Eyebrow Height"
11365 show_simple="true"
11366 wearable="hair"
11367 edit_group="hair_eyebrows"
11368 edit_group_order="2.5"
11369 label_min="Higher"
11370 label_max="Lower"
11371 value_min="-4"
11372 value_max="2"
11373 value_default="-1"
11374 camera_elevation=".1"
11375 camera_distance=".3">
11376 <param_driver>
11377 <driven
11378 id="871" />
11379 </param_driver>
11380 </param>
11381
11382<!--Arced eyebrows became a driver/driven param with new max value for backwards compatibility between 1.0 and 1.1-->
11383 <param
11384 id="31"
11385 group="0"
11386 name="Arced_Eyebrows"
11387 label="Eyebrow Arc"
11388 wearable="hair"
11389 edit_group="hair_eyebrows"
11390 edit_group_order="3"
11391 label_min="Flat"
11392 label_max="Arced"
11393 value_min="0"
11394 value_max="2"
11395 value_default=".5"
11396 camera_elevation=".1"
11397 camera_distance=".3">
11398 <param_driver>
11399 <driven
11400 id="872" />
11401 </param_driver>
11402 </param>
11403
11404 <param
11405 id="877"
11406 group="0"
11407 name="Jacket Wrinkles"
11408 label="Jacket Wrinkles"
11409 wearable="jacket"
11410 edit_group="jacket"
11411 edit_group_order="20"
11412 label_min="No Wrinkles"
11413 label_max="Wrinkles"
11414 value_min="0"
11415 value_max="1"
11416 value_default="0"
11417 camera_elevation=".1"
11418 camera_distance=".3">
11419 <param_driver>
11420 <driven
11421 id="875" />
11422
11423 <driven
11424 id="876" />
11425 </param_driver>
11426 </param>
11427 <param id="1071" group="2" wearable="tattoo" edit_group="colorpicker" name="tattoo_red"
11428 value_min="0" value_max="1" value_default="1">
11429 <param_driver>
11430 <driven id="1062" min1="0" max1="1" max2="1" min2="1" />
11431 <driven id="1065" min1="0" max1="1" max2="1" min2="1" />
11432 <driven id="1068" min1="0" max1="1" max2="1" min2="1" />
11433 </param_driver>
11434 </param>
11435 <param id="1072" group="2" wearable="tattoo" edit_group="colorpicker" name="tattoo_green"
11436 value_min="0" value_max="1" value_default="1">
11437 <param_driver>
11438 <driven id="1063" min1="0" max1="1" max2="1" min2="1" />
11439 <driven id="1066" min1="0" max1="1" max2="1" min2="1" />
11440 <driven id="1069" min1="0" max1="1" max2="1" min2="1" />
11441 </param_driver>
11442 </param>
11443 <param id="1073" group="2" wearable="tattoo" edit_group="colorpicker" name="tattoo_blue"
11444 value_min="0" value_max="1" value_default="1">
11445 <param_driver>
11446 <driven id="1064" min1="0" max1="1" max2="1" min2="1" />
11447 <driven id="1067" min1="0" max1="1" max2="1" min2="1" />
11448 <driven id="1070" min1="0" max1="1" max2="1" min2="1" />
11449 </param_driver>
11450 </param>
11451
11452 </driver_parameters>
11453</linden_avatar>
11454
diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt
index 41f896f..d18b5ba 100644
--- a/linden/doc/contributions.txt
+++ b/linden/doc/contributions.txt
@@ -80,6 +80,7 @@ Aleric Inglewood
80 IMP-578 80 IMP-578
81 IMP-579 81 IMP-579
82 IMP-581 82 IMP-581
83 IMP-590
83 IMP-592 84 IMP-592
84 IMP-595 85 IMP-595
85 IMP-660 86 IMP-660
@@ -91,6 +92,8 @@ Aleric Inglewood
91 IMP-670 92 IMP-670
92 IMP-688 93 IMP-688
93 IMP-692 94 IMP-692
95 IMP-701
96 IMP-712
94Alissa Sabre 97Alissa Sabre
95 VWR-81 98 VWR-81
96 VWR-83 99 VWR-83
@@ -339,6 +342,8 @@ Khyota Wulluf
339Kunnis Basiat 342Kunnis Basiat
340 VWR-82 343 VWR-82
341 VWR-102 344 VWR-102
345Lance Corrimal
346 SNOW-717
342Lisa Lowe 347Lisa Lowe
343 CT-218 348 CT-218
344 CT-219 349 CT-219
diff --git a/linden/etc/message.xml b/linden/etc/message.xml
index 0fdf364..8d34dd8 100644
--- a/linden/etc/message.xml
+++ b/linden/etc/message.xml
@@ -386,7 +386,17 @@
386 <boolean>true</boolean> 386 <boolean>true</boolean>
387 </map> 387 </map>
388 388
389 <key>ParcelVoiceInfo</key> 389 <!-- Server to client -->
390 <key>DisplayNameUpdate</key>
391 <map>
392 <key>flavor</key>
393 <string>llsd</string>
394 <key>trusted-sender</key>
395 <boolean>true</boolean>
396 </map>
397
398
399 <key>ParcelVoiceInfo</key>
390 <map> 400 <map>
391 <key>flavor</key> 401 <key>flavor</key>
392 <string>llsd</string> 402 <string>llsd</string>
@@ -442,6 +452,14 @@
442 <boolean>true</boolean> 452 <boolean>true</boolean>
443 </map> 453 </map>
444 454
455 <key>SetDisplayNameReply</key>
456 <map>
457 <key>flavor</key>
458 <string>llsd</string>
459 <key>trusted-sender</key>
460 <boolean>true</boolean>
461 </map>
462
445 <key>DirLandReply</key> 463 <key>DirLandReply</key>
446 <map> 464 <map>
447 <key>flavor</key> 465 <key>flavor</key>
diff --git a/linden/indra/cmake/Boost.cmake b/linden/indra/cmake/Boost.cmake
index 7741615..665a162 100644
--- a/linden/indra/cmake/Boost.cmake
+++ b/linden/indra/cmake/Boost.cmake
@@ -14,7 +14,7 @@ else (STANDALONE)
14 set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) 14 set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
15 15
16 if (WINDOWS) 16 if (WINDOWS)
17 set(BOOST_VERSION 1_36) 17 set(BOOST_VERSION 1_39)
18 if (MSVC80) 18 if (MSVC80)
19 set(BOOST_PROGRAM_OPTIONS_LIBRARY 19 set(BOOST_PROGRAM_OPTIONS_LIBRARY
20 optimized libboost_program_options-vc80-mt-${BOOST_VERSION} 20 optimized libboost_program_options-vc80-mt-${BOOST_VERSION}
@@ -25,6 +25,8 @@ else (STANDALONE)
25 set(BOOST_SIGNALS_LIBRARY 25 set(BOOST_SIGNALS_LIBRARY
26 optimized libboost_signals-vc80-mt-${BOOST_VERSION} 26 optimized libboost_signals-vc80-mt-${BOOST_VERSION}
27 debug libboost_signals-vc80-mt-gd-${BOOST_VERSION}) 27 debug libboost_signals-vc80-mt-gd-${BOOST_VERSION})
28 # Default support for VS2008 was lost in the move from 1.36 to 1.39.
29 # Remove this comment when this is fixed -- MC
28 elseif (MSVC90) 30 elseif (MSVC90)
29 set(BOOST_PROGRAM_OPTIONS_LIBRARY 31 set(BOOST_PROGRAM_OPTIONS_LIBRARY
30 optimized libboost_program_options-vc90-mt-${BOOST_VERSION} 32 optimized libboost_program_options-vc90-mt-${BOOST_VERSION}
diff --git a/linden/indra/cmake/GStreamer010Plugin.cmake b/linden/indra/cmake/GStreamer010Plugin.cmake
index 90ed35c..ec9b828 100644
--- a/linden/indra/cmake/GStreamer010Plugin.cmake
+++ b/linden/indra/cmake/GStreamer010Plugin.cmake
@@ -15,11 +15,19 @@ else (STANDALONE)
15 use_prebuilt_binary(gstreamer) 15 use_prebuilt_binary(gstreamer)
16 set(GSTREAMER010_FOUND ON FORCE BOOL) 16 set(GSTREAMER010_FOUND ON FORCE BOOL)
17 set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL) 17 set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL)
18 set(GSTREAMER010_INCLUDE_DIRS 18 if (WINDOWS)
19 ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gstreamer-0.10 19 set(GSTREAMER010_INCLUDE_DIRS
20 ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0 20 ${LIBS_PREBUILT_DIR}/include/gstreamer-0.10
21 ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2 21 ${LIBS_PREBUILT_DIR}/include/glib
22 ) 22 ${LIBS_PREBUILT_DIR}/include/libxml2
23 )
24 else (WINDOWS)
25 set(GSTREAMER010_INCLUDE_DIRS
26 ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gstreamer-0.10
27 ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0
28 ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2
29 )
30 endif (WINDOWS)
23 31
24endif (STANDALONE) 32endif (STANDALONE)
25 33
@@ -27,10 +35,10 @@ if (WINDOWS)
27 # We don't need to explicitly link against gstreamer itself, because 35 # We don't need to explicitly link against gstreamer itself, because
28 # LLMediaImplGStreamer probes for the system's copy at runtime. 36 # LLMediaImplGStreamer probes for the system's copy at runtime.
29 set(GSTREAMER010_LIBRARIES 37 set(GSTREAMER010_LIBRARIES
30 libgstvideo 38 gstaudio-0.10.lib
31 libgstaudio 39 gstbase-0.10.lib
32 libgstbase-0.10 40 gstreamer-0.10.lib
33 libgstreamer-0.10 41 gstvideo-0.10.lib
34 gobject-2.0 42 gobject-2.0
35 gmodule-2.0 43 gmodule-2.0
36 gthread-2.0 44 gthread-2.0
diff --git a/linden/indra/llaudio/llaudioengine.cpp b/linden/indra/llaudio/llaudioengine.cpp
index bed791a..6b0003a 100644
--- a/linden/indra/llaudio/llaudioengine.cpp
+++ b/linden/indra/llaudio/llaudioengine.cpp
@@ -36,7 +36,6 @@
36#include "linden_common.h" 36#include "linden_common.h"
37 37
38#include "llaudioengine.h" 38#include "llaudioengine.h"
39#include "llstreamingaudio.h"
40 39
41#include "llerror.h" 40#include "llerror.h"
42#include "llmath.h" 41#include "llmath.h"
@@ -48,7 +47,6 @@
48#include "llaudiodecodemgr.h" 47#include "llaudiodecodemgr.h"
49#include "llassetstorage.h" 48#include "llassetstorage.h"
50 49
51
52// necessary for grabbing sounds from sim (implemented in viewer) 50// necessary for grabbing sounds from sim (implemented in viewer)
53extern void request_sound(const LLUUID &sound_guid); 51extern void request_sound(const LLUUID &sound_guid);
54 52
@@ -70,16 +68,6 @@ LLAudioEngine::~LLAudioEngine()
70{ 68{
71} 69}
72 70
73LLStreamingAudioInterface* LLAudioEngine::getStreamingAudioImpl()
74{
75 return mStreamingAudioImpl;
76}
77
78void LLAudioEngine::setStreamingAudioImpl(LLStreamingAudioInterface *impl)
79{
80 mStreamingAudioImpl = impl;
81}
82
83void LLAudioEngine::setDefaults() 71void LLAudioEngine::setDefaults()
84{ 72{
85 mMaxWindGain = 1.f; 73 mMaxWindGain = 1.f;
@@ -108,8 +96,6 @@ void LLAudioEngine::setDefaults()
108 mInternalGain = 0.f; 96 mInternalGain = 0.f;
109 mNextWindUpdate = 0.f; 97 mNextWindUpdate = 0.f;
110 98
111 mStreamingAudioImpl = NULL;
112
113 for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++) 99 for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++)
114 mSecondaryGain[i] = 1.0f; 100 mSecondaryGain[i] = 1.0f;
115} 101}
@@ -174,62 +160,6 @@ void LLAudioEngine::shutdown()
174 } 160 }
175} 161}
176 162
177
178// virtual
179void LLAudioEngine::startInternetStream(const std::string& url)
180{
181 if (mStreamingAudioImpl)
182 mStreamingAudioImpl->start(url);
183}
184
185
186// virtual
187void LLAudioEngine::stopInternetStream()
188{
189 if (mStreamingAudioImpl)
190 mStreamingAudioImpl->stop();
191}
192
193// virtual
194void LLAudioEngine::pauseInternetStream(int pause)
195{
196 if (mStreamingAudioImpl)
197 mStreamingAudioImpl->pause(pause);
198}
199
200// virtual
201void LLAudioEngine::updateInternetStream()
202{
203 if (mStreamingAudioImpl)
204 mStreamingAudioImpl->update();
205}
206
207// virtual
208int LLAudioEngine::isInternetStreamPlaying()
209{
210 if (mStreamingAudioImpl)
211 return mStreamingAudioImpl->isPlaying();
212
213 return 0; // Stopped
214}
215
216
217// virtual
218void LLAudioEngine::setInternetStreamGain(F32 vol)
219{
220 if (mStreamingAudioImpl)
221 mStreamingAudioImpl->setGain(vol);
222}
223
224// virtual
225std::string LLAudioEngine::getInternetStreamURL()
226{
227 if (mStreamingAudioImpl)
228 return mStreamingAudioImpl->getURL();
229 else return std::string();
230}
231
232
233void LLAudioEngine::updateChannels() 163void LLAudioEngine::updateChannels()
234{ 164{
235 S32 i; 165 S32 i;
@@ -512,7 +442,6 @@ void LLAudioEngine::idle(F32 max_decode_time)
512 // or request new data. 442 // or request new data.
513 startNextTransfer(); 443 startNextTransfer();
514 444
515 updateInternetStream();
516} 445}
517 446
518 447
@@ -754,14 +683,6 @@ F32 LLAudioEngine::getSecondaryGain(S32 type)
754 return mSecondaryGain[type]; 683 return mSecondaryGain[type];
755} 684}
756 685
757F32 LLAudioEngine::getInternetStreamGain()
758{
759 if (mStreamingAudioImpl)
760 return mStreamingAudioImpl->getGain();
761 else
762 return 1.0f;
763}
764
765void LLAudioEngine::setMaxWindGain(F32 gain) 686void LLAudioEngine::setMaxWindGain(F32 gain)
766{ 687{
767 mMaxWindGain = gain; 688 mMaxWindGain = gain;
diff --git a/linden/indra/llaudio/llaudioengine.h b/linden/indra/llaudio/llaudioengine.h
index a1b240e..7237ce2 100644
--- a/linden/indra/llaudio/llaudioengine.h
+++ b/linden/indra/llaudio/llaudioengine.h
@@ -71,8 +71,6 @@ class LLAudioData;
71class LLAudioChannel; 71class LLAudioChannel;
72class LLAudioChannelOpenAL; 72class LLAudioChannelOpenAL;
73class LLAudioBuffer; 73class LLAudioBuffer;
74class LLStreamingAudioInterface;
75
76 74
77// 75//
78// LLAudioEngine definition 76// LLAudioEngine definition
@@ -119,16 +117,13 @@ public:
119 // stops playing new sounds. 117 // stops playing new sounds.
120 void setMuted(bool muted); 118 void setMuted(bool muted);
121 bool getMuted() const { return mMuted; } 119 bool getMuted() const { return mMuted; }
122#ifdef USE_PLUGIN_MEDIA 120
123 LLPluginClassMedia* initializeMedia(const std::string& media_type);
124#endif
125 F32 getMasterGain(); 121 F32 getMasterGain();
126 void setMasterGain(F32 gain); 122 void setMasterGain(F32 gain);
127 123
128 F32 getSecondaryGain(S32 type); 124 F32 getSecondaryGain(S32 type);
129 void setSecondaryGain(S32 type, F32 gain); 125 void setSecondaryGain(S32 type, F32 gain);
130 126
131 F32 getInternetStreamGain();
132 127
133 virtual void setDopplerFactor(F32 factor); 128 virtual void setDopplerFactor(F32 factor);
134 virtual F32 getDopplerFactor(); 129 virtual F32 getDopplerFactor();
@@ -150,19 +145,6 @@ public:
150 LLAudioSource *findAudioSource(const LLUUID &source_id); 145 LLAudioSource *findAudioSource(const LLUUID &source_id);
151 LLAudioData *getAudioData(const LLUUID &audio_uuid); 146 LLAudioData *getAudioData(const LLUUID &audio_uuid);
152 147
153 // Internet stream implementation manipulation
154 LLStreamingAudioInterface *getStreamingAudioImpl();
155 void setStreamingAudioImpl(LLStreamingAudioInterface *impl);
156 // Internet stream methods - these will call down into the *mStreamingAudioImpl if it exists
157 void startInternetStream(const std::string& url);
158 void stopInternetStream();
159 void pauseInternetStream(int pause);
160 void updateInternetStream(); // expected to be called often
161 int isInternetStreamPlaying();
162 // use a value from 0.0 to 1.0, inclusive
163 void setInternetStreamGain(F32 vol);
164 std::string getInternetStreamURL();
165
166 // For debugging usage 148 // For debugging usage
167 virtual LLVector3 getListenerPos(); 149 virtual LLVector3 getListenerPos();
168 150
@@ -247,7 +229,6 @@ protected:
247 229
248private: 230private:
249 void setDefaults(); 231 void setDefaults();
250 LLStreamingAudioInterface *mStreamingAudioImpl;
251}; 232};
252 233
253 234
diff --git a/linden/indra/llaudio/llstreamingaudio.h b/linden/indra/llaudio/llstreamingaudio.h
index aa89e6a..f5d5334 100644
--- a/linden/indra/llaudio/llstreamingaudio.h
+++ b/linden/indra/llaudio/llstreamingaudio.h
@@ -36,7 +36,7 @@
36 36
37#include "stdtypes.h" // from llcommon 37#include "stdtypes.h" // from llcommon
38 38
39// Entirely abstract. Based exactly on the historic API. 39// Entirely abstract. Based on the historic API.
40class LLStreamingAudioInterface 40class LLStreamingAudioInterface
41{ 41{
42 public: 42 public:
@@ -51,6 +51,7 @@ class LLStreamingAudioInterface
51 virtual void setGain(F32 vol) = 0; 51 virtual void setGain(F32 vol) = 0;
52 virtual F32 getGain() = 0; 52 virtual F32 getGain() = 0;
53 virtual std::string getURL() = 0; 53 virtual std::string getURL() = 0;
54 virtual std::string getVersion() = 0;
54}; 55};
55 56
56#endif // LL_STREAMINGAUDIO_H 57#endif // LL_STREAMINGAUDIO_H
diff --git a/linden/indra/llcharacter/llcharacter.cpp b/linden/indra/llcharacter/llcharacter.cpp
index 46ac326..72cef83 100644
--- a/linden/indra/llcharacter/llcharacter.cpp
+++ b/linden/indra/llcharacter/llcharacter.cpp
@@ -379,7 +379,7 @@ void LLCharacter::clearVisualParamWeights()
379 param; 379 param;
380 param = getNextVisualParam()) 380 param = getNextVisualParam())
381 { 381 {
382 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) 382 if (param->isTweakable())
383 { 383 {
384 param->setWeight( param->getDefaultWeight(), FALSE ); 384 param->setWeight( param->getDefaultWeight(), FALSE );
385 } 385 }
@@ -395,7 +395,7 @@ BOOL LLCharacter::visualParamWeightsAreDefault()
395 param; 395 param;
396 param = getNextVisualParam()) 396 param = getNextVisualParam())
397 { 397 {
398 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) 398 if (param->isTweakable())
399 { 399 {
400 if (param->getWeight() != param->getDefaultWeight()) 400 if (param->getWeight() != param->getDefaultWeight())
401 return false; 401 return false;
diff --git a/linden/indra/llcharacter/llcharacter.h b/linden/indra/llcharacter/llcharacter.h
index d91124b..7630760 100644
--- a/linden/indra/llcharacter/llcharacter.h
+++ b/linden/indra/llcharacter/llcharacter.h
@@ -231,6 +231,20 @@ public:
231 return (mCurIterator++)->second; 231 return (mCurIterator++)->second;
232 } 232 }
233 233
234 S32 getVisualParamCountInGroup(EVisualParamGroup group)
235 {
236 S32 rtn = 0;
237 VisualParamIndexMap_t::iterator iter;
238 for (iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
239 {
240 if (iter->second->getGroup() == group)
241 {
242 rtn++;
243 }
244 }
245 return rtn;
246 }
247
234 LLVisualParam* getVisualParam(S32 id) 248 LLVisualParam* getVisualParam(S32 id)
235 { 249 {
236 VisualParamIndexMap_t::iterator iter = mVisualParamIndexMap.find(id); 250 VisualParamIndexMap_t::iterator iter = mVisualParamIndexMap.find(id);
diff --git a/linden/indra/llcharacter/llvisualparam.cpp b/linden/indra/llcharacter/llvisualparam.cpp
index d7a144e..9579ff8 100644
--- a/linden/indra/llcharacter/llvisualparam.cpp
+++ b/linden/indra/llcharacter/llvisualparam.cpp
@@ -238,7 +238,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL set_by_user)
238{ 238{
239 if (mInfo) 239 if (mInfo)
240 { 240 {
241 if (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) 241 if (isTweakable())
242 { 242 {
243 mTargetWeight = llclamp(target_value, mInfo->mMinWeight, mInfo->mMaxWeight); 243 mTargetWeight = llclamp(target_value, mInfo->mMinWeight, mInfo->mMaxWeight);
244 } 244 }
@@ -282,7 +282,7 @@ void LLVisualParam::animate( F32 delta, BOOL set_by_user )
282//----------------------------------------------------------------------------- 282//-----------------------------------------------------------------------------
283void LLVisualParam::stopAnimating(BOOL set_by_user) 283void LLVisualParam::stopAnimating(BOOL set_by_user)
284{ 284{
285 if (mIsAnimating && getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) 285 if (mIsAnimating && isTweakable())
286 { 286 {
287 mIsAnimating = FALSE; 287 mIsAnimating = FALSE;
288 setWeight(mTargetWeight, set_by_user); 288 setWeight(mTargetWeight, set_by_user);
diff --git a/linden/indra/llcharacter/llvisualparam.h b/linden/indra/llcharacter/llvisualparam.h
index 3a0c1bb..d8dff8c 100644
--- a/linden/indra/llcharacter/llvisualparam.h
+++ b/linden/indra/llcharacter/llvisualparam.h
@@ -51,6 +51,7 @@ enum EVisualParamGroup
51{ 51{
52 VISUAL_PARAM_GROUP_TWEAKABLE, 52 VISUAL_PARAM_GROUP_TWEAKABLE,
53 VISUAL_PARAM_GROUP_ANIMATABLE, 53 VISUAL_PARAM_GROUP_ANIMATABLE,
54 VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT,
54 NUM_VISUAL_PARAM_GROUPS 55 NUM_VISUAL_PARAM_GROUPS
55}; 56};
56 57
@@ -124,7 +125,7 @@ public:
124 void setMaxDisplayName(const std::string& s) { mInfo->mMaxName = s; } 125 void setMaxDisplayName(const std::string& s) { mInfo->mMaxName = s; }
125 void setMinDisplayName(const std::string& s) { mInfo->mMinName = s; } 126 void setMinDisplayName(const std::string& s) { mInfo->mMinName = s; }
126 127
127 EVisualParamGroup getGroup() { return mInfo->mGroup; } 128 EVisualParamGroup getGroup() const { return mInfo->mGroup; }
128 F32 getMinWeight() { return mInfo->mMinWeight; } 129 F32 getMinWeight() { return mInfo->mMinWeight; }
129 F32 getMaxWeight() { return mInfo->mMaxWeight; } 130 F32 getMaxWeight() { return mInfo->mMaxWeight; }
130 F32 getDefaultWeight() { return mInfo->mDefaultWeight; } 131 F32 getDefaultWeight() { return mInfo->mDefaultWeight; }
@@ -133,7 +134,8 @@ public:
133 F32 getWeight() { return mIsAnimating ? mTargetWeight : mCurWeight; } 134 F32 getWeight() { return mIsAnimating ? mTargetWeight : mCurWeight; }
134 F32 getCurrentWeight() { return mCurWeight; } 135 F32 getCurrentWeight() { return mCurWeight; }
135 F32 getLastWeight() { return mLastWeight; } 136 F32 getLastWeight() { return mLastWeight; }
136 BOOL isAnimating() { return mIsAnimating; } 137 BOOL isAnimating() { return mIsAnimating; }
138 BOOL isTweakable() { return (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) || (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT); }
137 139
138 LLVisualParam* getNextParam() { return mNext; } 140 LLVisualParam* getNextParam() { return mNext; }
139 void setNextParam( LLVisualParam *next ); 141 void setNextParam( LLVisualParam *next );
@@ -141,6 +143,7 @@ public:
141 virtual void setAnimating(BOOL is_animating) { mIsAnimating = is_animating; } 143 virtual void setAnimating(BOOL is_animating) { mIsAnimating = is_animating; }
142 BOOL getAnimating() { return mIsAnimating; } 144 BOOL getAnimating() { return mIsAnimating; }
143 145
146
144protected: 147protected:
145 F32 mCurWeight; // current weight 148 F32 mCurWeight; // current weight
146 F32 mLastWeight; // last weight 149 F32 mLastWeight; // last weight
diff --git a/linden/indra/llcommon/CMakeLists.txt b/linden/indra/llcommon/CMakeLists.txt
index ff1d548..ed04ca6 100644
--- a/linden/indra/llcommon/CMakeLists.txt
+++ b/linden/indra/llcommon/CMakeLists.txt
@@ -13,11 +13,13 @@ include_directories(
13 ) 13 )
14 14
15set(llcommon_SOURCE_FILES 15set(llcommon_SOURCE_FILES
16 aiaprpool.cpp
16 imageids.cpp 17 imageids.cpp
17 indra_constants.cpp 18 indra_constants.cpp
18 llapp.cpp 19 llapp.cpp
19 llapr.cpp 20 llapr.cpp
20 llassettype.cpp 21 llassettype.cpp
22 llavatarname.cpp
21 llbase32.cpp 23 llbase32.cpp
22 llbase64.cpp 24 llbase64.cpp
23 llcommon.cpp 25 llcommon.cpp
@@ -74,6 +76,8 @@ set(llcommon_SOURCE_FILES
74set(llcommon_HEADER_FILES 76set(llcommon_HEADER_FILES
75 CMakeLists.txt 77 CMakeLists.txt
76 78
79 aiaprpool.h
80 aithreadsafe.h
77 bitpack.h 81 bitpack.h
78 ctype_workaround.h 82 ctype_workaround.h
79 doublelinkedlist.h 83 doublelinkedlist.h
@@ -87,6 +91,7 @@ set(llcommon_HEADER_FILES
87 llassettype.h 91 llassettype.h
88 llassoclist.h 92 llassoclist.h
89 llavatarconstants.h 93 llavatarconstants.h
94 llavatarname.h
90 llbase32.h 95 llbase32.h
91 llbase64.h 96 llbase64.h
92 llboost.h 97 llboost.h
@@ -147,6 +152,7 @@ set(llcommon_HEADER_FILES
147 llqueuedthread.h 152 llqueuedthread.h
148 llrand.h 153 llrand.h
149 llrun.h 154 llrun.h
155 llscopedvolatileaprpool.h
150 llsd.h 156 llsd.h
151 llsdserialize.h 157 llsdserialize.h
152 llsdserialize_xml.h 158 llsdserialize_xml.h
diff --git a/linden/indra/llcommon/aiaprpool.cpp b/linden/indra/llcommon/aiaprpool.cpp
new file mode 100644
index 0000000..d3748e9
--- /dev/null
+++ b/linden/indra/llcommon/aiaprpool.cpp
@@ -0,0 +1,198 @@
1/**
2 * @file aiaprpool.cpp
3 *
4 * Copyright (c) 2010, Aleric Inglewood.
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * There are special exceptions to the terms and conditions of the GPL as
20 * it is applied to this Source Code. View the full text of the exception
21 * in the file doc/FLOSS-exception.txt in this software distribution.
22 *
23 * CHANGELOG
24 * and additional copyright holders.
25 *
26 * 04/04/2010
27 * - Initial version, written by Aleric Inglewood @ SL
28 *
29 * 10/11/2010
30 * - Changed filename, class names and license to a more
31 * company-neutral format.
32 * - Added APR_HAS_THREADS #if's to allow creation and destruction
33 * of subpools by threads other than the parent pool owner.
34 */
35
36#include "linden_common.h"
37
38#include "llerror.h"
39#include "aiaprpool.h"
40#include "llthread.h"
41
42// Create a subpool from parent.
43void AIAPRPool::create(AIAPRPool& parent)
44{
45 llassert(!mPool); // Must be non-initialized.
46 mParent = &parent;
47 if (!mParent) // Using the default parameter?
48 {
49 // By default use the root pool of the current thread.
50 mParent = &AIThreadLocalData::tldata().mRootPool;
51 }
52 llassert(mParent->mPool); // Parent must be initialized.
53#if APR_HAS_THREADS
54 // As per the documentation of APR (ie http://apr.apache.org/docs/apr/1.4/apr__pools_8h.html):
55 //
56 // Note that most operations on pools are not thread-safe: a single pool should only be
57 // accessed by a single thread at any given time. The one exception to this rule is creating
58 // a subpool of a given pool: one or more threads can safely create subpools at the same
59 // time that another thread accesses the parent pool.
60 //
61 // In other words, it's safe for any thread to create a (sub)pool, independent of who
62 // owns the parent pool.
63 mOwner = apr_os_thread_current();
64#else
65 mOwner = mParent->mOwner;
66 llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
67#endif
68 apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool);
69 llassert_always(apr_pool_create_status == APR_SUCCESS);
70 llassert(mPool); // Initialized.
71 apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null);
72}
73
74// Destroy the (sub)pool, if any.
75void AIAPRPool::destroy(void)
76{
77 // Only do anything if we are not already (being) destroyed.
78 if (mPool)
79 {
80#if !APR_HAS_THREADS
81 // If we are a root pool, then every thread may destruct us: in that case
82 // we have to assume that no other thread will use this pool concurrently,
83 // of course. Otherwise, if we are a subpool, only the thread that owns
84 // the parent may destruct us, since that is the pool that is still alive,
85 // possibly being used by others and being altered here.
86 llassert(!mParent || apr_os_thread_equal(mParent->mOwner, apr_os_thread_current()));
87#endif
88 apr_pool_t* pool = mPool;
89 mPool = NULL; // Mark that we are BEING destructed.
90 apr_pool_cleanup_kill(pool, this, &s_plain_cleanup);
91 apr_pool_destroy(pool);
92 }
93}
94
95bool AIAPRPool::parent_is_being_destructed(void)
96{
97 return mParent && (!mParent->mPool || mParent->parent_is_being_destructed());
98}
99
100AIAPRInitialization::AIAPRInitialization(void)
101{
102 static bool apr_initialized = false;
103
104 if (!apr_initialized)
105 {
106 apr_initialize();
107 }
108
109 apr_initialized = true;
110}
111
112bool AIAPRRootPool::sCountInitialized = false;
113apr_uint32_t volatile AIAPRRootPool::sCount;
114
115extern apr_thread_mutex_t* gLogMutexp;
116extern apr_thread_mutex_t* gCallStacksLogMutexp;
117
118AIAPRRootPool::AIAPRRootPool(void) : AIAPRInitialization(), AIAPRPool(0)
119{
120 // sCountInitialized don't need locking because when we get here there is still only a single thread.
121 if (!sCountInitialized)
122 {
123 // Initialize the logging mutex
124 apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool);
125 apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool);
126
127 apr_status_t status = apr_atomic_init(mPool);
128 llassert_always(status == APR_SUCCESS);
129 apr_atomic_set32(&sCount, 1); // Set to 1 to account for the global root pool.
130 sCountInitialized = true;
131
132 // Initialize thread-local APR pool support.
133 // Because this recursively calls AIAPRRootPool::AIAPRRootPool(void)
134 // it must be done last, so that sCount is already initialized.
135 AIThreadLocalData::init();
136 }
137 apr_atomic_inc32(&sCount);
138}
139
140AIAPRRootPool::~AIAPRRootPool()
141{
142 if (!apr_atomic_dec32(&sCount))
143 {
144 // The last pool was destructed. Cleanup remainder of APR.
145 LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
146
147 if (gLogMutexp)
148 {
149 // Clean up the logging mutex
150
151 // All other threads NEED to be done before we clean up APR, so this is okay.
152 apr_thread_mutex_destroy(gLogMutexp);
153 gLogMutexp = NULL;
154 }
155 if (gCallStacksLogMutexp)
156 {
157 // Clean up the logging mutex
158
159 // All other threads NEED to be done before we clean up APR, so this is okay.
160 apr_thread_mutex_destroy(gCallStacksLogMutexp);
161 gCallStacksLogMutexp = NULL;
162 }
163
164 // Must destroy ALL, and therefore this last AIAPRRootPool, before terminating APR.
165 static_cast<AIAPRRootPool*>(this)->destroy();
166
167 apr_terminate();
168 }
169}
170
171//static
172AIAPRRootPool& AIAPRRootPool::get(void)
173{
174 static AIAPRRootPool global_APRpool(0); // This is what used to be gAPRPoolp.
175 return global_APRpool;
176}
177
178void AIVolatileAPRPool::clearVolatileAPRPool()
179{
180 llassert_always(mNumActiveRef > 0);
181 if (--mNumActiveRef == 0)
182 {
183 if (isOld())
184 {
185 destroy();
186 mNumTotalRef = 0 ;
187 }
188 else
189 {
190 // This does not actually free the memory,
191 // it just allows the pool to re-use this memory for the next allocation.
192 clear();
193 }
194 }
195
196 // Paranoia check if the pool is jammed.
197 llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
198}
diff --git a/linden/indra/llcommon/aiaprpool.h b/linden/indra/llcommon/aiaprpool.h
new file mode 100644
index 0000000..ac523a9
--- /dev/null
+++ b/linden/indra/llcommon/aiaprpool.h
@@ -0,0 +1,240 @@
1/**
2 * @file aiaprpool.h
3 * @brief Implementation of AIAPRPool.
4 *
5 * Copyright (c) 2010, Aleric Inglewood.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * There are special exceptions to the terms and conditions of the GPL as
21 * it is applied to this Source Code. View the full text of the exception
22 * in the file doc/FLOSS-exception.txt in this software distribution.
23 *
24 * CHANGELOG
25 * and additional copyright holders.
26 *
27 * 04/04/2010
28 * - Initial version, written by Aleric Inglewood @ SL
29 *
30 * 10/11/2010
31 * - Changed filename, class names and license to a more
32 * company-neutral format.
33 * - Added APR_HAS_THREADS #if's to allow creation and destruction
34 * of subpools by threads other than the parent pool owner.
35 */
36
37#ifndef AIAPRPOOL_H
38#define AIAPRPOOL_H
39
40#ifdef LL_WINDOWS
41//#include <ws2tcpip.h>
42# define WIN32_LEAN_AND_MEAN
43# include <winsock2.h> // Needed before including apr_portable.h
44#endif
45
46#include "apr_portable.h"
47#include "apr_pools.h"
48#include "llerror.h"
49
50extern void ll_init_apr();
51
52/**
53 * @brief A wrapper around the APR memory pool API.
54 *
55 * Usage of this class should be restricted to passing it to libapr-1 function calls that need it.
56 *
57 */
58class LL_COMMON_API AIAPRPool
59{
60protected:
61 apr_pool_t* mPool; //!< Pointer to the underlaying pool. NULL if not initialized.
62 AIAPRPool* mParent; //!< Pointer to the parent pool, if any. Only valid when mPool is non-zero.
63 apr_os_thread_t mOwner; //!< The thread that owns this memory pool. Only valid when mPool is non-zero.
64
65public:
66 //! Construct an uninitialized (destructed) pool.
67 AIAPRPool(void) : mPool(NULL) { }
68
69 //! Construct a subpool from an existing pool.
70 // This is not a copy-constructor, this class doesn't have one!
71 AIAPRPool(AIAPRPool& parent) : mPool(NULL) { create(parent); }
72
73 //! Destruct the memory pool (free all of it's subpools and allocated memory).
74 ~AIAPRPool() { destroy(); }
75
76protected:
77 // Create a pool that is allocated from the Operating System. Only used by AIAPRRootPool.
78 AIAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current())
79 {
80 apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL);
81 llassert_always(apr_pool_create_status == APR_SUCCESS);
82 llassert(mPool);
83 apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null);
84 }
85
86public:
87 //! Create a subpool from parent. May only be called for an uninitialized/destroyed pool.
88 // The default parameter causes the root pool of the current thread to be used.
89 void create(AIAPRPool& parent = *static_cast<AIAPRPool*>(NULL));
90
91 //! Destroy the (sub)pool, if any.
92 void destroy(void);
93
94 // Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool.
95 typedef apr_pool_t* const AIAPRPool::* const bool_type;
96 //! Return true if the pool is initialized.
97 operator bool_type() const { return mPool ? &AIAPRPool::mPool : 0; }
98
99 // Painful, but we have to either provide access to this, or wrap
100 // every APR function call that needs a apr_pool_t* to be passed.
101 // NEVER destroy a pool that is returned by this function!
102 apr_pool_t* operator()(void) const
103 {
104 llassert(mPool);
105 llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
106 return mPool;
107 }
108
109 // Free all memory without destructing the pool.
110 void clear(void)
111 {
112 llassert(mPool);
113 llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
114 apr_pool_clear(mPool);
115 }
116
117// These methods would make this class 'complete' (as wrapper around the libapr
118// pool functions), but we don't use memory pools in the viewer (only when
119// we are forced to pass one to a libapr call), so don't define them in order
120// not to encourage people to use them.
121#if 0
122 void* palloc(size_t size)
123 {
124 llassert(mPool);
125 llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
126 return apr_palloc(mPool, size);
127 }
128 void* pcalloc(size_t size)
129 {
130 llassert(mPool);
131 llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
132 return apr_pcalloc(mPool, size);
133 }
134#endif
135
136private:
137 bool parent_is_being_destructed(void);
138 static apr_status_t s_plain_cleanup(void* userdata) { return static_cast<AIAPRPool*>(userdata)->plain_cleanup(); }
139
140 apr_status_t plain_cleanup(void)
141 {
142 if (mPool && // We are not being destructed,
143 parent_is_being_destructed()) // but our parent is.
144 // This means the pool is being destructed recursively by libapr
145 // because one of it's parents is being destructed.
146 {
147 mPool = NULL; // Stop destroy() from destructing the pool again.
148 }
149 return APR_SUCCESS;
150 }
151};
152
153class AIAPRInitialization
154{
155public:
156 AIAPRInitialization(void);
157};
158
159/**
160 * @brief Root memory pool (allocates memory from the operating system).
161 *
162 * This class should only be used by AIThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase
163 * (and LLMutexRootPool when APR_HAS_THREADS isn't defined).
164 */
165class LL_COMMON_API AIAPRRootPool : public AIAPRInitialization, public AIAPRPool
166{
167private:
168 friend class AIThreadLocalData;
169 friend class AIThreadSafeSimpleDCRootPool_pbase;
170#if !APR_HAS_THREADS
171 friend class LLMutexRootPool;
172#endif
173 //! Construct a root memory pool.
174 // Should only be used by AIThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase.
175 AIAPRRootPool(void);
176 ~AIAPRRootPool();
177
178private:
179 // Keep track of how many root pools exist and when the last one is destructed.
180 static bool sCountInitialized;
181 static apr_uint32_t volatile sCount;
182
183public:
184 // Return a global root pool that is independent of AIThreadLocalData.
185 // Normally you should not use this. Only use for early initialization
186 // (before main) and deinitialization (after main).
187 static AIAPRRootPool& get(void);
188
189#if APR_POOL_DEBUG
190 void grab_ownership(void)
191 {
192 // You need a patched libapr to use this.
193 // See http://web.archiveorange.com/archive/v/5XO9y2zoxUOMt6Gmi1OI
194 apr_pool_owner_set(mPool);
195 }
196#endif
197
198private:
199 // Used for constructing the Special Global Root Pool (returned by AIAPRRootPool::get).
200 // It is the same as the default constructor but omits to increment sCount. As a result,
201 // we must be sure that at least one other AIAPRRootPool is created before termination
202 // of the application (which is the case: we create one AIAPRRootPool per thread).
203 AIAPRRootPool(int) : AIAPRInitialization(), AIAPRPool(0) { }
204};
205
206//! Volatile memory pool
207//
208// 'Volatile' APR memory pool which normally only clears memory,
209// and does not destroy the pool (the same pool is reused) for
210// greater efficiency. However, as a safe guard the apr pool
211// is destructed every FULL_VOLATILE_APR_POOL uses to allow
212// the system memory to be allocated more efficiently and not
213// get scattered through RAM.
214//
215class LL_COMMON_API AIVolatileAPRPool : protected AIAPRPool
216{
217public:
218 AIVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { }
219
220 apr_pool_t* getVolatileAPRPool(void)
221 {
222 if (!mPool) create();
223 ++mNumActiveRef;
224 ++mNumTotalRef;
225 return AIAPRPool::operator()();
226 }
227 void clearVolatileAPRPool(void);
228
229 bool isOld(void) const { return mNumTotalRef > FULL_VOLATILE_APR_POOL; }
230 bool isUnused() const { return mNumActiveRef == 0; }
231
232private:
233 S32 mNumActiveRef; // Number of active uses of the pool.
234 S32 mNumTotalRef; // Number of total uses of the pool since last creation.
235
236 // Maximum number of references to AIVolatileAPRPool until the pool is recreated.
237 static S32 const FULL_VOLATILE_APR_POOL = 1024;
238};
239
240#endif // AIAPRPOOL_H
diff --git a/linden/indra/llcommon/aithreadsafe.h b/linden/indra/llcommon/aithreadsafe.h
new file mode 100644
index 0000000..e1b93ba
--- /dev/null
+++ b/linden/indra/llcommon/aithreadsafe.h
@@ -0,0 +1,463 @@
1/**
2 * @file aithreadsafe.h
3 * @brief Implementation of AIThreadSafe, AIReadAccessConst, AIReadAccess and AIWriteAccess.
4 *
5 * CHANGELOG
6 * and additional copyright holders.
7 *
8 * 31/03/2010
9 * Initial version, written by Aleric Inglewood @ SL
10 */
11
12#ifndef AITHREADSAFE_H
13#define AITHREADSAFE_H
14
15#include <new>
16
17#include "llthread.h"
18#include "llerror.h"
19
20template<typename T> struct AIReadAccessConst;
21template<typename T> struct AIReadAccess;
22template<typename T> struct AIWriteAccess;
23template<typename T> struct AIAccess;
24
25template<typename T>
26class AIThreadSafeBits
27{
28private:
29 // AIThreadSafe is a wrapper around an instance of T.
30 // Because T might not have a default constructor, it is constructed
31 // 'in place', with placement new, in the memory reserved here.
32 //
33 // Make sure that the memory that T will be placed in is properly
34 // aligned by using an array of long's.
35 long mMemory[(sizeof(T) + sizeof(long) - 1) / sizeof(long)];
36
37public:
38 // The wrapped objects are constructed in-place with placement new *outside*
39 // of this object (by AITHREADSAFE macro(s) or derived classes).
40 // However, we are responsible for the destruction of the wrapped object.
41 ~AIThreadSafeBits() { ptr()->~T(); }
42
43 // Only for use by AITHREADSAFE, see below.
44 void* memory() const { return const_cast<long*>(&mMemory[0]); }
45
46protected:
47 // Accessors.
48 T const* ptr() const { return reinterpret_cast<T const*>(mMemory); }
49 T* ptr() { return reinterpret_cast<T*>(mMemory); }
50};
51
52/**
53 * @brief A wrapper class for objects that need to be accessed by more than one thread, allowing concurrent readers.
54 *
55 * Use AITHREADSAFE to define instances of any type, and use AIReadAccessConst,
56 * AIReadAccess and AIWriteAccess to get access to the instance.
57 *
58 * For example,
59 *
60 * <code>
61 * class Foo { public: Foo(int, int); };
62 *
63 * AITHREADSAFE(Foo, foo, (2, 3));
64 *
65 * AIReadAccess<Foo> foo_r(foo);
66 * // Use foo_r-> for read access.
67 *
68 * AIWriteAccess<Foo> foo_w(foo);
69 * // Use foo_w-> for write access.
70 * </code>
71 *
72 * If <code>foo</code> is constant, you have to use <code>AIReadAccessConst<Foo></code>.
73 *
74 * It is possible to pass access objects to a function that
75 * downgrades the access, for example:
76 *
77 * <code>
78 * void readfunc(AIReadAccess const& access);
79 *
80 * AIWriteAccess<Foo> foo_w(foo);
81 * readfunc(foo_w); // readfunc will perform read access to foo_w.
82 * </code>
83 *
84 * If <code>AIReadAccess</code> is non-const, you can upgrade the access by creating
85 * an <code>AIWriteAccess</code> object from it. For example:
86 *
87 * <code>
88 * AIWriteAccess<Foo> foo_w(foo_r);
89 * </code>
90 *
91 * This API is Robust(tm). If you try anything that could result in problems,
92 * it simply won't compile. The only mistake you can still easily make is
93 * to obtain write access to an object when it is not needed, or to unlock
94 * an object in between accesses while the state of the object should be
95 * preserved. For example:
96 *
97 * <code>
98 * // This resets foo to point to the first file and then returns that.
99 * std::string filename = AIWriteAccess<Foo>(foo)->get_first_filename();
100 *
101 * // WRONG! The state between calling get_first_filename and get_next_filename should be preserved!
102 *
103 * AIWriteAccess<Foo> foo_w(foo); // Wrong. The code below only needs read-access.
104 * while (!filename.empty())
105 * {
106 * something(filename);
107 * filename = foo_w->next_filename();
108 * }
109 * </code>
110 *
111 * Correct would be
112 *
113 * <code>
114 * AIReadAccess<Foo> foo_r(foo);
115 * std::string filename = AIWriteAccess<Foo>(foo_r)->get_first_filename();
116 * while (!filename.empty())
117 * {
118 * something(filename);
119 * filename = foo_r->next_filename();
120 * }
121 * </code>
122 *
123 */
124template<typename T>
125class AIThreadSafe : public AIThreadSafeBits<T>
126{
127protected:
128 // Only these may access the object (through ptr()).
129 friend struct AIReadAccessConst<T>;
130 friend struct AIReadAccess<T>;
131 friend struct AIWriteAccess<T>;
132
133 // Locking control.
134 AIRWLock mRWLock;
135
136 // For use by AIThreadSafeDC
137 AIThreadSafe(void) { }
138 AIThreadSafe(AIAPRPool& parent) : mRWLock(parent) { }
139
140public:
141 // Only for use by AITHREADSAFE, see below.
142 AIThreadSafe(T* object) { llassert(object == AIThreadSafeBits<T>::ptr()); }
143};
144
145/**
146 * @brief Instantiate an static, global or local object of a given type wrapped in AIThreadSafe, using an arbitrary constructor.
147 *
148 * For example, instead of doing
149 *
150 * <code>
151 * Foo foo(x, y);
152 * static Bar bar;
153 * </code>
154 *
155 * One can instantiate a thread-safe instance with
156 *
157 * <code>
158 * AITHREADSAFE(Foo, foo, (x, y));
159 * static AITHREADSAFE(Bar, bar, );
160 * </code>
161 *
162 * Note: This macro does not allow to allocate such object on the heap.
163 * If that is needed, have a look at AIThreadSafeDC.
164 */
165#define AITHREADSAFE(type, var, paramlist) AIThreadSafe<type> var(new (var.memory()) type paramlist)
166
167/**
168 * @brief A wrapper class for objects that need to be accessed by more than one thread.
169 *
170 * This class is the same as an AIThreadSafe wrapper, except that it can only
171 * be used for default constructed objects.
172 *
173 * For example, instead of
174 *
175 * <code>
176 * Foo foo;
177 * </code>
178 *
179 * One would use
180 *
181 * <code>
182 * AIThreadSafeDC<Foo> foo;
183 * </code>
184 *
185 * The advantage over AITHREADSAFE is that this object can be allocated with
186 * new on the heap. For example:
187 *
188 * <code>
189 * AIThreadSafeDC<Foo>* ptr = new AIThreadSafeDC<Foo>;
190 * </code>
191 *
192 * which is not possible with AITHREADSAFE.
193 */
194template<typename T>
195class AIThreadSafeDC : public AIThreadSafe<T>
196{
197public:
198 // Construct a wrapper around a default constructed object.
199 AIThreadSafeDC(void) { new (AIThreadSafe<T>::ptr()) T; }
200};
201
202/**
203 * @brief Read lock object and provide read access.
204 */
205template<typename T>
206struct AIReadAccessConst
207{
208 //! Internal enum for the lock-type of the AI*Access object.
209 enum state_type
210 {
211 readlocked, //!< A AIReadAccessConst or AIReadAccess.
212 read2writelocked, //!< A AIWriteAccess constructed from a AIReadAccess.
213 writelocked, //!< A AIWriteAccess constructed from a AIThreadSafe.
214 write2writelocked //!< A AIWriteAccess constructed from (the AIReadAccess base class of) a AIWriteAccess.
215 };
216
217 //! Construct a AIReadAccessConst from a constant AIThreadSafe.
218 AIReadAccessConst(AIThreadSafe<T> const& wrapper)
219 : mWrapper(const_cast<AIThreadSafe<T>&>(wrapper)),
220 mState(readlocked)
221 {
222 mWrapper.mRWLock.rdlock();
223 }
224
225 //! Destruct the AI*Access object.
226 // These should never be dynamically allocated, so there is no need to make this virtual.
227 ~AIReadAccessConst()
228 {
229 if (mState == readlocked)
230 mWrapper.mRWLock.rdunlock();
231 else if (mState == writelocked)
232 mWrapper.mRWLock.wrunlock();
233 else if (mState == read2writelocked)
234 mWrapper.mRWLock.wr2rdlock();
235 }
236
237 //! Access the underlaying object for read access.
238 T const* operator->() const { return mWrapper.ptr(); }
239
240 //! Access the underlaying object for read access.
241 T const& operator*() const { return *mWrapper.ptr(); }
242
243protected:
244 //! Constructor used by AIReadAccess.
245 AIReadAccessConst(AIThreadSafe<T>& wrapper, state_type state)
246 : mWrapper(wrapper), mState(state) { }
247
248 AIThreadSafe<T>& mWrapper; //!< Reference to the object that we provide access to.
249 state_type const mState; //!< The lock state that mWrapper is in.
250
251private:
252 // Disallow copy constructing directly.
253 AIReadAccessConst(AIReadAccessConst const&);
254};
255
256/**
257 * @brief Read lock object and provide read access, with possible promotion to write access.
258 */
259template<typename T>
260struct AIReadAccess : public AIReadAccessConst<T>
261{
262 typedef typename AIReadAccessConst<T>::state_type state_type;
263 using AIReadAccessConst<T>::readlocked;
264
265 //! Construct a AIReadAccess from a non-constant AIThreadSafe.
266 AIReadAccess(AIThreadSafe<T>& wrapper) : AIReadAccessConst<T>(wrapper, readlocked) { this->mWrapper.mRWLock.rdlock(); }
267
268protected:
269 //! Constructor used by AIWriteAccess.
270 AIReadAccess(AIThreadSafe<T>& wrapper, state_type state) : AIReadAccessConst<T>(wrapper, state) { }
271
272 friend class AIWriteAccess<T>;
273};
274
275/**
276 * @brief Write lock object and provide read/write access.
277 */
278template<typename T>
279struct AIWriteAccess : public AIReadAccess<T>
280{
281 using AIReadAccessConst<T>::readlocked;
282 using AIReadAccessConst<T>::read2writelocked;
283 using AIReadAccessConst<T>::writelocked;
284 using AIReadAccessConst<T>::write2writelocked;
285
286 //! Construct a AIWriteAccess from a non-constant AIThreadSafe.
287 AIWriteAccess(AIThreadSafe<T>& wrapper) : AIReadAccess<T>(wrapper, writelocked) { this->mWrapper.mRWLock.wrlock();}
288
289 //! Promote read access to write access.
290 explicit AIWriteAccess(AIReadAccess<T>& access)
291 : AIReadAccess<T>(access.mWrapper, (access.mState == readlocked) ? read2writelocked : write2writelocked)
292 {
293 if (this->mState == read2writelocked)
294 {
295 this->mWrapper.mRWLock.rd2wrlock();
296 }
297 }
298
299 //! Access the underlaying object for (read and) write access.
300 T* operator->() const { return this->mWrapper.ptr(); }
301
302 //! Access the underlaying object for (read and) write access.
303 T& operator*() const { return *this->mWrapper.ptr(); }
304};
305
306/**
307 * @brief A wrapper class for objects that need to be accessed by more than one thread.
308 *
309 * Use AITHREADSAFESIMPLE to define instances of any type, and use AIAccess
310 * to get access to the instance.
311 *
312 * For example,
313 *
314 * <code>
315 * class Foo { public: Foo(int, int); };
316 *
317 * AITHREADSAFESIMPLE(Foo, foo, (2, 3));
318 *
319 * AIAccess<Foo> foo_w(foo);
320 * // Use foo_w-> for read and write access.
321 *
322 * See also AIThreadSafe
323 */
324template<typename T>
325class AIThreadSafeSimple : public AIThreadSafeBits<T>
326{
327protected:
328 // Only this one may access the object (through ptr()).
329 friend struct AIAccess<T>;
330
331 // Locking control.
332 LLMutex mMutex;
333
334 // For use by AIThreadSafeSimpleDC
335 AIThreadSafeSimple(void) { }
336 AIThreadSafeSimple(AIAPRPool& parent) : mMutex(parent) { }
337
338public:
339 // Only for use by AITHREADSAFESIMPLE, see below.
340 AIThreadSafeSimple(T* object) { llassert(object == AIThreadSafeBits<T>::ptr()); }
341};
342
343/**
344 * @brief Instantiate an static, global or local object of a given type wrapped in AIThreadSafeSimple, using an arbitrary constructor.
345 *
346 * For example, instead of doing
347 *
348 * <code>
349 * Foo foo(x, y);
350 * static Bar bar;
351 * </code>
352 *
353 * One can instantiate a thread-safe instance with
354 *
355 * <code>
356 * AITHREADSAFESIMPLE(Foo, foo, (x, y));
357 * static AITHREADSAFESIMPLE(Bar, bar, );
358 * </code>
359 *
360 * Note: This macro does not allow to allocate such object on the heap.
361 * If that is needed, have a look at AIThreadSafeSimpleDC.
362 */
363#define AITHREADSAFESIMPLE(type, var, paramlist) AIThreadSafeSimple<type> var(new (var.memory()) type paramlist)
364
365/**
366 * @brief A wrapper class for objects that need to be accessed by more than one thread.
367 *
368 * This class is the same as an AIThreadSafeSimple wrapper, except that it can only
369 * be used for default constructed objects.
370 *
371 * For example, instead of
372 *
373 * <code>
374 * Foo foo;
375 * </code>
376 *
377 * One would use
378 *
379 * <code>
380 * AIThreadSafeSimpleDC<Foo> foo;
381 * </code>
382 *
383 * The advantage over AITHREADSAFESIMPLE is that this object can be allocated with
384 * new on the heap. For example:
385 *
386 * <code>
387 * AIThreadSafeSimpleDC<Foo>* ptr = new AIThreadSafeSimpleDC<Foo>;
388 * </code>
389 *
390 * which is not possible with AITHREADSAFESIMPLE.
391 */
392template<typename T>
393class AIThreadSafeSimpleDC : public AIThreadSafeSimple<T>
394{
395public:
396 // Construct a wrapper around a default constructed object.
397 AIThreadSafeSimpleDC(void) { new (AIThreadSafeSimple<T>::ptr()) T; }
398
399protected:
400 // For use by AIThreadSafeSimpleDCRootPool
401 AIThreadSafeSimpleDC(AIAPRPool& parent) : AIThreadSafeSimple<T>(parent) { new (AIThreadSafeSimple<T>::ptr()) T; }
402};
403
404// Helper class for AIThreadSafeSimpleDCRootPool to assure initialization of
405// the root pool before constructing AIThreadSafeSimpleDC.
406class AIThreadSafeSimpleDCRootPool_pbase
407{
408protected:
409 AIAPRRootPool mRootPool;
410
411private:
412 template<typename T> friend class AIThreadSafeSimpleDCRootPool;
413 AIThreadSafeSimpleDCRootPool_pbase(void) { }
414};
415
416/**
417 * @brief A wrapper class for objects that need to be accessed by more than one thread.
418 *
419 * The same as AIThreadSafeSimpleDC except that this class creates its own AIAPRRootPool
420 * for the internally used mutexes and condition, instead of using the current threads
421 * root pool. The advantage of this is that it can be used for objects that need to
422 * be accessed from the destructors of global objects (after main). The disadvantage
423 * is that it's less efficient to use your own root pool, therefore it's use should be
424 * restricted to those cases where it is absolutely necessary.
425 */
426template<typename T>
427class AIThreadSafeSimpleDCRootPool : private AIThreadSafeSimpleDCRootPool_pbase, public AIThreadSafeSimpleDC<T>
428{
429public:
430 // Construct a wrapper around a default constructed object, using memory allocated
431 // from the operating system for the internal APR objects (mutexes and conditional),
432 // as opposed to allocated from the current threads root pool.
433 AIThreadSafeSimpleDCRootPool(void) :
434 AIThreadSafeSimpleDCRootPool_pbase(),
435 AIThreadSafeSimpleDC<T>(mRootPool) { }
436};
437
438/**
439 * @brief Write lock object and provide read/write access.
440 */
441template<typename T>
442struct AIAccess
443{
444 //! Construct a AIAccess from a non-constant AIThreadSafeSimple.
445 AIAccess(AIThreadSafeSimple<T>& wrapper) : mWrapper(wrapper) { this->mWrapper.mMutex.lock(); }
446
447 //! Access the underlaying object for (read and) write access.
448 T* operator->() const { return this->mWrapper.ptr(); }
449
450 //! Access the underlaying object for (read and) write access.
451 T& operator*() const { return *this->mWrapper.ptr(); }
452
453 ~AIAccess() { this->mWrapper.mMutex.unlock(); }
454
455protected:
456 AIThreadSafeSimple<T>& mWrapper; //!< Reference to the object that we provide access to.
457
458private:
459 // Disallow copy constructing directly.
460 AIAccess(AIAccess const&);
461};
462
463#endif
diff --git a/linden/indra/llcommon/llapp.cpp b/linden/indra/llcommon/llapp.cpp
index e269f59..eedc503 100644
--- a/linden/indra/llcommon/llapp.cpp
+++ b/linden/indra/llcommon/llapp.cpp
@@ -119,13 +119,8 @@ void LLApp::commonCtor()
119 mOptions.append(sd); 119 mOptions.append(sd);
120 } 120 }
121 121
122 // Make sure we clean up APR when we exit
123 // Don't need to do this if we're cleaning up APR in the destructor
124 //atexit(ll_cleanup_apr);
125
126 // Set the application to this instance. 122 // Set the application to this instance.
127 sApplication = this; 123 sApplication = this;
128
129} 124}
130 125
131LLApp::LLApp(LLErrorThread *error_thread) : 126LLApp::LLApp(LLErrorThread *error_thread) :
diff --git a/linden/indra/llcommon/llapr.cpp b/linden/indra/llcommon/llapr.cpp
index 7e3a26c..a013d9c 100644
--- a/linden/indra/llcommon/llapr.cpp
+++ b/linden/indra/llcommon/llapr.cpp
@@ -34,220 +34,7 @@
34 34
35#include "linden_common.h" 35#include "linden_common.h"
36#include "llapr.h" 36#include "llapr.h"
37 37#include "llscopedvolatileaprpool.h"
38apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
39apr_thread_mutex_t *gLogMutexp = NULL;
40apr_thread_mutex_t *gCallStacksLogMutexp = NULL;
41
42const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
43
44void ll_init_apr()
45{
46 if (!gAPRPoolp)
47 {
48 // Initialize APR and create the global pool
49 apr_initialize();
50 apr_pool_create(&gAPRPoolp, NULL);
51
52 // Initialize the logging mutex
53 apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
54 apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
55
56 // Initialize thread-local APR pool support.
57 LLVolatileAPRPool::initLocalAPRFilePool();
58 }
59}
60
61
62void ll_cleanup_apr()
63{
64 LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
65
66 if (gLogMutexp)
67 {
68 // Clean up the logging mutex
69
70 // All other threads NEED to be done before we clean up APR, so this is okay.
71 apr_thread_mutex_destroy(gLogMutexp);
72 gLogMutexp = NULL;
73 }
74 if (gCallStacksLogMutexp)
75 {
76 // Clean up the logging mutex
77
78 // All other threads NEED to be done before we clean up APR, so this is okay.
79 apr_thread_mutex_destroy(gCallStacksLogMutexp);
80 gCallStacksLogMutexp = NULL;
81 }
82 if (gAPRPoolp)
83 {
84 apr_pool_destroy(gAPRPoolp);
85 gAPRPoolp = NULL;
86 }
87 apr_terminate();
88}
89
90//
91//
92//LLAPRPool
93//
94LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
95{
96 mParent = parent ;
97 mReleasePoolFlag = releasePoolFlag ;
98 mMaxSize = size ;
99 mPool = NULL ;
100
101 createAPRPool() ;
102}
103
104LLAPRPool::~LLAPRPool()
105{
106 releaseAPRPool() ;
107}
108
109void LLAPRPool::createAPRPool()
110{
111 if(mPool)
112 {
113 return ;
114 }
115
116 mStatus = apr_pool_create(&mPool, mParent);
117 ll_apr_warn_status(mStatus) ;
118
119 if(mMaxSize > 0) //size is the number of blocks (which is usually 4K), NOT bytes.
120 {
121 apr_allocator_t *allocator = apr_pool_allocator_get(mPool);
122 if (allocator)
123 {
124 apr_allocator_max_free_set(allocator, mMaxSize) ;
125 }
126 }
127}
128
129void LLAPRPool::releaseAPRPool()
130{
131 if(!mPool)
132 {
133 return ;
134 }
135
136 if(!mParent || mReleasePoolFlag)
137 {
138 apr_pool_destroy(mPool) ;
139 mPool = NULL ;
140 }
141}
142
143apr_pool_t* LLAPRPool::getAPRPool()
144{
145 if(!mPool)
146 {
147 createAPRPool() ;
148 }
149
150 return mPool ;
151}
152LLVolatileAPRPool::LLVolatileAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
153 : LLAPRPool(parent, size, releasePoolFlag)
154{
155 mNumActiveRef = 0 ;
156 mNumTotalRef = 0 ;
157}
158
159apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
160{
161 mNumTotalRef++ ;
162 mNumActiveRef++ ;
163 return getAPRPool() ;
164}
165
166void LLVolatileAPRPool::clearVolatileAPRPool()
167{
168 if(mNumActiveRef > 0)
169 {
170 mNumActiveRef--;
171 if(mNumActiveRef < 1)
172 {
173 if(isFull())
174 {
175 mNumTotalRef = 0 ;
176
177 //destroy the apr_pool.
178 releaseAPRPool() ;
179 }
180 else
181 {
182 //This does not actually free the memory,
183 //it just allows the pool to re-use this memory for the next allocation.
184 apr_pool_clear(mPool) ;
185 }
186 }
187 }
188 else
189 {
190 llassert_always(mNumActiveRef > 0) ;
191 }
192
193 //paranoia check if the pool is jammed.
194 //will remove the check before going to release.
195 llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
196}
197
198BOOL LLVolatileAPRPool::isFull()
199{
200 return mNumTotalRef > FULL_VOLATILE_APR_POOL ;
201}
202
203#ifdef SHOW_ASSERT
204// This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread.
205static void* gIsMainThread;
206bool is_main_thread() { return gIsMainThread == LLVolatileAPRPool::getLocalAPRFilePool(); }
207#endif
208
209// The thread private handle to access the LocalAPRFilePool.
210apr_threadkey_t* LLVolatileAPRPool::sLocalAPRFilePoolKey;
211
212// This should be called exactly once, before the first call to createLocalAPRFilePool.
213// static
214void LLVolatileAPRPool::initLocalAPRFilePool()
215{
216 apr_status_t status = apr_threadkey_private_create(&sLocalAPRFilePoolKey, &destroyLocalAPRFilePool, gAPRPoolp);
217 ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the
218 // total number of keys per process {PTHREAD_KEYS_MAX}
219 // has been exceeded.
220 // Create the thread-local pool for the main thread (this function is called by the main thread).
221 createLocalAPRFilePool();
222#ifdef SHOW_ASSERT
223 gIsMainThread = getLocalAPRFilePool();
224#endif
225}
226
227// This should be called once for every thread, before it uses getLocalAPRFilePool.
228// static
229void LLVolatileAPRPool::createLocalAPRFilePool()
230{
231 void* thread_local_data = new LLVolatileAPRPool;
232 apr_status_t status = apr_threadkey_private_set(thread_local_data, sLocalAPRFilePoolKey);
233 llassert_always(status == APR_SUCCESS);
234}
235
236// This is called once for every thread when the thread is destructed.
237// static
238void LLVolatileAPRPool::destroyLocalAPRFilePool(void* thread_local_data)
239{
240 delete reinterpret_cast<LLVolatileAPRPool*>(thread_local_data);
241}
242
243// static
244LLVolatileAPRPool* LLVolatileAPRPool::getLocalAPRFilePool()
245{
246 void* thread_local_data;
247 apr_status_t status = apr_threadkey_private_get(&thread_local_data, sLocalAPRFilePoolKey);
248 llassert_always(status == APR_SUCCESS);
249 return reinterpret_cast<LLVolatileAPRPool*>(thread_local_data);
250}
251 38
252//--------------------------------------------------------------------- 39//---------------------------------------------------------------------
253// 40//
@@ -310,13 +97,15 @@ void ll_apr_assert_status(apr_status_t status)
310// 97//
311LLAPRFile::LLAPRFile() 98LLAPRFile::LLAPRFile()
312 : mFile(NULL), 99 : mFile(NULL),
313 mCurrentFilePoolp(NULL) 100 mVolatileFilePoolp(NULL),
101 mRegularFilePoolp(NULL)
314{ 102{
315} 103}
316 104
317LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, access_t access_type) 105LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, access_t access_type)
318 : mFile(NULL), 106 : mFile(NULL),
319 mCurrentFilePoolp(NULL) 107 mVolatileFilePoolp(NULL),
108 mRegularFilePoolp(NULL)
320{ 109{
321 open(filename, flags, access_type); 110 open(filename, flags, access_type);
322} 111}
@@ -335,10 +124,16 @@ apr_status_t LLAPRFile::close()
335 mFile = NULL ; 124 mFile = NULL ;
336 } 125 }
337 126
338 if(mCurrentFilePoolp) 127 if (mVolatileFilePoolp)
339 { 128 {
340 mCurrentFilePoolp->clearVolatileAPRPool() ; 129 mVolatileFilePoolp->clearVolatileAPRPool() ;
341 mCurrentFilePoolp = NULL ; 130 mVolatileFilePoolp = NULL ;
131 }
132
133 if (mRegularFilePoolp)
134 {
135 delete mRegularFilePoolp;
136 mRegularFilePoolp = NULL;
342 } 137 }
343 138
344 return ret ; 139 return ret ;
@@ -347,25 +142,28 @@ apr_status_t LLAPRFile::close()
347apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep) 142apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep)
348{ 143{
349 llassert_always(!mFile); 144 llassert_always(!mFile);
350 llassert_always(!mCurrentFilePoolp); 145 llassert_always(!mVolatileFilePoolp && !mRegularFilePoolp);
351 146
352 // Access the pool and increment it's reference count. 147 apr_status_t status;
353 // The reference count of LLVolatileAPRPool objects will be decremented
354 // again in LLAPRFile::close by calling mCurrentFilePoolp->clearVolatileAPRPool().
355 apr_pool_t* pool;
356 if (access_type == local)
357 {
358 // Use a "volatile" thread-local pool.
359 mCurrentFilePoolp = LLVolatileAPRPool::getLocalAPRFilePool();
360 pool = mCurrentFilePoolp->getVolatileAPRPool();
361 }
362 else
363 { 148 {
364 llassert(is_main_thread()); 149 apr_pool_t* apr_file_open_pool;
365 pool = gAPRPoolp; 150 if (access_type == local)
151 {
152 // Use a "volatile" thread-local pool.
153 mVolatileFilePoolp = &AIThreadLocalData::tldata().mVolatileAPRPool;
154 // Access the pool and increment it's reference count.
155 // The reference count of AIVolatileAPRPool objects will be decremented
156 // again in LLAPRFile::close by calling mVolatileFilePoolp->clearVolatileAPRPool().
157 apr_file_open_pool = mVolatileFilePoolp->getVolatileAPRPool();
158 }
159 else
160 {
161 mRegularFilePoolp = new AIAPRPool(AIThreadLocalData::tldata().mRootPool);
162 apr_file_open_pool = (*mRegularFilePoolp)();
163 }
164 status = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, apr_file_open_pool);
366 } 165 }
367 apr_status_t s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, pool); 166 if (status != APR_SUCCESS || !mFile)
368 if (s != APR_SUCCESS || !mFile)
369 { 167 {
370 mFile = NULL ; 168 mFile = NULL ;
371 close() ; 169 close() ;
@@ -373,7 +171,7 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc
373 { 171 {
374 *sizep = 0; 172 *sizep = 0;
375 } 173 }
376 return s; 174 return status;
377 } 175 }
378 176
379 if (sizep) 177 if (sizep)
@@ -390,7 +188,7 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc
390 *sizep = file_size; 188 *sizep = file_size;
391 } 189 }
392 190
393 return s; 191 return status;
394} 192}
395 193
396// File I/O 194// File I/O
@@ -440,17 +238,6 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset)
440//static components of LLAPRFile 238//static components of LLAPRFile
441// 239//
442 240
443// Used in the static functions below.
444class LLScopedVolatileAPRFilePool {
445private:
446 LLVolatileAPRPool* mPool;
447 apr_pool_t* apr_pool;
448public:
449 LLScopedVolatileAPRFilePool() : mPool(LLVolatileAPRPool::getLocalAPRFilePool()), apr_pool(mPool->getVolatileAPRPool()) { }
450 ~LLScopedVolatileAPRFilePool() { mPool->clearVolatileAPRPool(); }
451 operator apr_pool_t*() const { return apr_pool; }
452};
453
454//static 241//static
455S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) 242S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
456{ 243{
@@ -487,7 +274,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
487S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) 274S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes)
488{ 275{
489 apr_file_t* file_handle; 276 apr_file_t* file_handle;
490 LLScopedVolatileAPRFilePool pool; 277 LLScopedVolatileAPRPool pool;
491 apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool); 278 apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool);
492 if (s != APR_SUCCESS || !file_handle) 279 if (s != APR_SUCCESS || !file_handle)
493 { 280 {
@@ -539,7 +326,7 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
539 } 326 }
540 327
541 apr_file_t* file_handle; 328 apr_file_t* file_handle;
542 LLScopedVolatileAPRFilePool pool; 329 LLScopedVolatileAPRPool pool;
543 apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); 330 apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool);
544 if (s != APR_SUCCESS || !file_handle) 331 if (s != APR_SUCCESS || !file_handle)
545 { 332 {
@@ -584,7 +371,7 @@ bool LLAPRFile::remove(const std::string& filename)
584{ 371{
585 apr_status_t s; 372 apr_status_t s;
586 373
587 LLScopedVolatileAPRFilePool pool; 374 LLScopedVolatileAPRPool pool;
588 s = apr_file_remove(filename.c_str(), pool); 375 s = apr_file_remove(filename.c_str(), pool);
589 376
590 if (s != APR_SUCCESS) 377 if (s != APR_SUCCESS)
@@ -601,7 +388,7 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname)
601{ 388{
602 apr_status_t s; 389 apr_status_t s;
603 390
604 LLScopedVolatileAPRFilePool pool; 391 LLScopedVolatileAPRPool pool;
605 s = apr_file_rename(filename.c_str(), newname.c_str(), pool); 392 s = apr_file_rename(filename.c_str(), newname.c_str(), pool);
606 393
607 if (s != APR_SUCCESS) 394 if (s != APR_SUCCESS)
@@ -619,7 +406,7 @@ bool LLAPRFile::isExist(const std::string& filename, apr_int32_t flags)
619 apr_file_t* file_handle; 406 apr_file_t* file_handle;
620 apr_status_t s; 407 apr_status_t s;
621 408
622 LLScopedVolatileAPRFilePool pool; 409 LLScopedVolatileAPRPool pool;
623 s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); 410 s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool);
624 411
625 if (s != APR_SUCCESS || !file_handle) 412 if (s != APR_SUCCESS || !file_handle)
@@ -640,7 +427,7 @@ S32 LLAPRFile::size(const std::string& filename)
640 apr_finfo_t info; 427 apr_finfo_t info;
641 apr_status_t s; 428 apr_status_t s;
642 429
643 LLScopedVolatileAPRFilePool pool; 430 LLScopedVolatileAPRPool pool;
644 s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool); 431 s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool);
645 432
646 if (s != APR_SUCCESS || !file_handle) 433 if (s != APR_SUCCESS || !file_handle)
@@ -669,7 +456,7 @@ bool LLAPRFile::makeDir(const std::string& dirname)
669{ 456{
670 apr_status_t s; 457 apr_status_t s;
671 458
672 LLScopedVolatileAPRFilePool pool; 459 LLScopedVolatileAPRPool pool;
673 s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool); 460 s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool);
674 461
675 if (s != APR_SUCCESS) 462 if (s != APR_SUCCESS)
@@ -686,7 +473,7 @@ bool LLAPRFile::removeDir(const std::string& dirname)
686{ 473{
687 apr_status_t s; 474 apr_status_t s;
688 475
689 LLScopedVolatileAPRFilePool pool; 476 LLScopedVolatileAPRPool pool;
690 s = apr_file_remove(dirname.c_str(), pool); 477 s = apr_file_remove(dirname.c_str(), pool);
691 478
692 if (s != APR_SUCCESS) 479 if (s != APR_SUCCESS)
diff --git a/linden/indra/llcommon/llapr.h b/linden/indra/llcommon/llapr.h
index 2aed515..ded15f5 100644
--- a/linden/indra/llcommon/llapr.h
+++ b/linden/indra/llcommon/llapr.h
@@ -48,73 +48,8 @@
48#include "apr_atomic.h" 48#include "apr_atomic.h"
49#include "llstring.h" 49#include "llstring.h"
50 50
51extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp; 51class AIAPRPool;
52 52class AIVolatileAPRPool;
53/**
54 * @brief initialize the common apr constructs -- apr itself, the
55 * global pool, and a mutex.
56 */
57void LL_COMMON_API ll_init_apr();
58
59/**
60 * @brief Cleanup those common apr constructs.
61 */
62void LL_COMMON_API ll_cleanup_apr();
63
64//
65//LL apr_pool
66//manage apr_pool_t, destroy allocated apr_pool in the destruction function.
67//
68class LL_COMMON_API LLAPRPool
69{
70public:
71 LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ;
72 ~LLAPRPool() ;
73
74 apr_pool_t* getAPRPool() ;
75 apr_status_t getStatus() {return mStatus ; }
76
77protected:
78 void releaseAPRPool() ;
79 void createAPRPool() ;
80
81protected:
82 apr_pool_t* mPool ; //pointing to an apr_pool
83 apr_pool_t* mParent ; //parent pool
84 apr_size_t mMaxSize ; //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work.
85 apr_status_t mStatus ; //status when creating the pool
86 BOOL mReleasePoolFlag ; //if set, mPool is destroyed when LLAPRPool is deleted. default value is true.
87};
88
89//
90//volatile LL apr_pool
91//which clears memory automatically.
92//so it can not hold static data or data after memory is cleared
93//
94class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool
95{
96public:
97 LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE);
98 ~LLVolatileAPRPool(){}
99
100 apr_pool_t* getVolatileAPRPool() ;
101
102 void clearVolatileAPRPool() ;
103
104 BOOL isFull() ;
105 BOOL isEmpty() {return !mNumActiveRef ;}
106
107 static void initLocalAPRFilePool();
108 static void createLocalAPRFilePool();
109 static void destroyLocalAPRFilePool(void* thread_local_data);
110 static LLVolatileAPRPool* getLocalAPRFilePool();
111
112private:
113 S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
114 S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating.
115
116 static apr_threadkey_t* sLocalAPRFilePoolKey;
117} ;
118 53
119/** 54/**
120 * @class LLScopedLock 55 * @class LLScopedLock
@@ -205,7 +140,8 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable
205 // make this non copyable since a copy closes the file 140 // make this non copyable since a copy closes the file
206private: 141private:
207 apr_file_t* mFile ; 142 apr_file_t* mFile ;
208 LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool. 143 AIVolatileAPRPool* mVolatileFilePoolp; // (Thread local) APR pool currently in use.
144 AIAPRPool* mRegularFilePoolp; // ...or a regular pool.
209 145
210public: 146public:
211 enum access_t { 147 enum access_t {
@@ -260,6 +196,4 @@ bool LL_COMMON_API ll_apr_warn_status(apr_status_t status);
260 196
261void LL_COMMON_API ll_apr_assert_status(apr_status_t status); 197void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
262 198
263extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool
264
265#endif // LL_LLAPR_H 199#endif // LL_LLAPR_H
diff --git a/linden/indra/llcommon/llavatarname.cpp b/linden/indra/llcommon/llavatarname.cpp
new file mode 100644
index 0000000..ebe8c88
--- /dev/null
+++ b/linden/indra/llcommon/llavatarname.cpp
@@ -0,0 +1,150 @@
1/**
2 * @file llavatarname.cpp
3 * @brief Represents name-related data for an avatar, such as the
4 * username/SLID ("bobsmith123" or "james.linden") and the display
5 * name ("James Cook")
6 *
7 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
8 * Second Life Viewer Source Code
9 * Copyright (C) 2010, Linden Research, Inc.
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation;
14 * version 2.1 of the License only.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
26 * $/LicenseInfo$
27 */
28#include "linden_common.h"
29
30#include "llavatarname.h"
31
32#include "lldate.h"
33#include "llsd.h"
34
35bool LLAvatarName::sOmitResidentAsLastName = false;
36
37// Store these in pre-built std::strings to avoid memory allocations in
38// LLSD map lookups
39static const std::string USERNAME("username");
40static const std::string DISPLAY_NAME("display_name");
41static const std::string LEGACY_FIRST_NAME("legacy_first_name");
42static const std::string LEGACY_LAST_NAME("legacy_last_name");
43static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default");
44static const std::string DISPLAY_NAME_EXPIRES("display_name_expires");
45static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update");
46
47LLAvatarName::LLAvatarName()
48: mUsername(),
49 mDisplayName(),
50 mLegacyFirstName(),
51 mLegacyLastName(),
52 mIsDisplayNameDefault(false),
53 mIsDummy(false),
54 mExpires(F64_MAX),
55 mNextUpdate(0.0)
56{ }
57
58bool LLAvatarName::operator<(const LLAvatarName& rhs) const
59{
60 if (mUsername == rhs.mUsername)
61 return mDisplayName < rhs.mDisplayName;
62 else
63 return mUsername < rhs.mUsername;
64}
65
66LLSD LLAvatarName::asLLSD() const
67{
68 LLSD sd;
69 sd[USERNAME] = mUsername;
70 sd[DISPLAY_NAME] = mDisplayName;
71 sd[LEGACY_FIRST_NAME] = mLegacyFirstName;
72 sd[LEGACY_LAST_NAME] = mLegacyLastName;
73 sd[IS_DISPLAY_NAME_DEFAULT] = mIsDisplayNameDefault;
74 sd[DISPLAY_NAME_EXPIRES] = LLDate(mExpires);
75 sd[DISPLAY_NAME_NEXT_UPDATE] = LLDate(mNextUpdate);
76 return sd;
77}
78
79void LLAvatarName::fromLLSD(const LLSD& sd)
80{
81 mUsername = sd[USERNAME].asString();
82 mDisplayName = sd[DISPLAY_NAME].asString();
83 mLegacyFirstName = sd[LEGACY_FIRST_NAME].asString();
84 mLegacyLastName = sd[LEGACY_LAST_NAME].asString();
85 mIsDisplayNameDefault = sd[IS_DISPLAY_NAME_DEFAULT].asBoolean();
86 LLDate expires = sd[DISPLAY_NAME_EXPIRES];
87 mExpires = expires.secondsSinceEpoch();
88 LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE];
89 mNextUpdate = next_update.secondsSinceEpoch();
90}
91
92std::string LLAvatarName::getCompleteName() const
93{
94 std::string name;
95 if (!mUsername.empty())
96 {
97 name = mDisplayName + " (" + mUsername + ")";
98 }
99 else
100 {
101 // ...display names are off, legacy name is in mDisplayName
102 name = mDisplayName;
103 }
104 return name;
105}
106
107std::string LLAvatarName::getLegacyName() const
108{
109 std::string name;
110 name.reserve(mLegacyFirstName.size() + 1 + mLegacyLastName.size());
111 name = mLegacyFirstName;
112 if (!sOmitResidentAsLastName || mLegacyLastName != "Resident")
113 {
114 name += " ";
115 name += mLegacyLastName;
116 }
117 return name;
118}
119
120std::string LLAvatarName::getNames(bool linefeed) const
121{
122 std::string name;
123
124 if (mUsername.empty())
125 {
126 // ...display names are off, legacy name is in mDisplayName
127 name = mDisplayName;
128 if (sOmitResidentAsLastName)
129 {
130 LLStringUtil::replaceString(name, " Resident", "");
131 }
132 }
133 else
134 {
135 name = getLegacyName();
136 if (name != mDisplayName)
137 {
138 if (linefeed)
139 {
140 name = mDisplayName + "\n[" + name + "]";
141 }
142 else
143 {
144 name = mDisplayName + " [" + name + "]";
145 }
146 }
147 }
148
149 return name;
150}
diff --git a/linden/indra/llcommon/llavatarname.h b/linden/indra/llcommon/llavatarname.h
new file mode 100644
index 0000000..3b6c6ea
--- /dev/null
+++ b/linden/indra/llcommon/llavatarname.h
@@ -0,0 +1,105 @@
1/**
2 * @file llavatarname.h
3 * @brief Represents name-related data for an avatar, such as the
4 * username/SLID ("bobsmith123" or "james.linden") and the display
5 * name ("James Cook")
6 *
7 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
8 * Second Life Viewer Source Code
9 * Copyright (C) 2010, Linden Research, Inc.
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation;
14 * version 2.1 of the License only.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
26 * $/LicenseInfo$
27 */
28#ifndef LLAVATARNAME_H
29#define LLAVATARNAME_H
30
31#include <string>
32
33class LLSD;
34
35class LL_COMMON_API LLAvatarName
36{
37public:
38 LLAvatarName();
39
40 bool operator<(const LLAvatarName& rhs) const;
41
42 LLSD asLLSD() const;
43
44 void fromLLSD(const LLSD& sd);
45
46 // For normal names, returns "James Linden (james.linden)"
47 // When display names are disabled returns just "James Linden"
48 std::string getCompleteName() const;
49
50 // For normal names, returns "Whatever Display Name (John Doe)" when
51 // display name and legacy name are different, or just "John Doe"
52 // when they are equal or when display names are disabled.
53 // When linefeed == true, the space between the display name and
54 // the opening parenthesis for the legacy name is replaced with a
55 // line feed.
56 std::string getNames(bool linefeed = false) const;
57
58 // Returns "James Linden" or "bobsmith123 Resident" for backwards
59 // compatibility with systems like voice and muting
60 std::string getLegacyName() const;
61
62 // "bobsmith123" or "james.linden", US-ASCII only
63 std::string mUsername;
64
65 // "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode
66 // Contains data whether or not user has explicitly set
67 // a display name; may duplicate their username.
68 std::string mDisplayName;
69
70 // For "James Linden", "James"
71 // For "bobsmith123", "bobsmith123"
72 // Used to communicate with legacy systems like voice and muting which
73 // rely on old-style names.
74 std::string mLegacyFirstName;
75
76 // For "James Linden", "Linden"
77 // For "bobsmith123", "Resident"
78 // see above for rationale
79 std::string mLegacyLastName;
80
81 // If true, both display name and SLID were generated from
82 // a legacy first and last name, like "James Linden (james.linden)"
83 bool mIsDisplayNameDefault;
84
85 // Under error conditions, we may insert "dummy" records with
86 // names equal to legacy name into caches as placeholders.
87 // These can be shown in UI, but are not serialized.
88 bool mIsDummy;
89
90 // Names can change, so need to keep track of when name was
91 // last checked.
92 // Unix time-from-epoch seconds for efficiency
93 F64 mExpires;
94
95 // You can only change your name every N hours, so record
96 // when the next update is allowed
97 // Unix time-from-epoch seconds
98 F64 mNextUpdate;
99
100 // true to prevent the displaying of "Resident" as a last name
101 // in legacy names
102 static bool sOmitResidentAsLastName;
103};
104
105#endif
diff --git a/linden/indra/llcommon/llcommon.cpp b/linden/indra/llcommon/llcommon.cpp
index 2cbb718..298dd46 100644
--- a/linden/indra/llcommon/llcommon.cpp
+++ b/linden/indra/llcommon/llcommon.cpp
@@ -35,17 +35,9 @@
35#include "llthread.h" 35#include "llthread.h"
36 36
37//static 37//static
38BOOL LLCommon::sAprInitialized = FALSE;
39
40//static
41void LLCommon::initClass() 38void LLCommon::initClass()
42{ 39{
43 LLMemory::initClass(); 40 LLMemory::initClass();
44 if (!sAprInitialized)
45 {
46 ll_init_apr();
47 sAprInitialized = TRUE;
48 }
49 LLTimer::initClass(); 41 LLTimer::initClass();
50 LLThreadSafeRefCount::initThreadSafeRefCount(); 42 LLThreadSafeRefCount::initThreadSafeRefCount();
51// LLWorkerThread::initClass(); 43// LLWorkerThread::initClass();
@@ -59,10 +51,5 @@ void LLCommon::cleanupClass()
59// LLWorkerThread::cleanupClass(); 51// LLWorkerThread::cleanupClass();
60 LLThreadSafeRefCount::cleanupThreadSafeRefCount(); 52 LLThreadSafeRefCount::cleanupThreadSafeRefCount();
61 LLTimer::cleanupClass(); 53 LLTimer::cleanupClass();
62 if (sAprInitialized)
63 {
64 ll_cleanup_apr();
65 sAprInitialized = FALSE;
66 }
67 LLMemory::cleanupClass(); 54 LLMemory::cleanupClass();
68} 55}
diff --git a/linden/indra/llcommon/llcommon.h b/linden/indra/llcommon/llcommon.h
index 851d4ac..300ebe2 100644
--- a/linden/indra/llcommon/llcommon.h
+++ b/linden/indra/llcommon/llcommon.h
@@ -43,8 +43,6 @@ class LL_COMMON_API LLCommon
43public: 43public:
44 static void initClass(); 44 static void initClass();
45 static void cleanupClass(); 45 static void cleanupClass();
46private:
47 static BOOL sAprInitialized;
48}; 46};
49 47
50#endif 48#endif
diff --git a/linden/indra/llcommon/llerror.cpp b/linden/indra/llcommon/llerror.cpp
index edc570f..a9587c6 100644
--- a/linden/indra/llcommon/llerror.cpp
+++ b/linden/indra/llcommon/llerror.cpp
@@ -46,6 +46,8 @@
46# include <unistd.h> 46# include <unistd.h>
47#endif // !LL_WINDOWS 47#endif // !LL_WINDOWS
48#if LL_WINDOWS 48#if LL_WINDOWS
49# define WIN32_LEAN_AND_MEAN
50# include <winsock2.h>
49# include <windows.h> 51# include <windows.h>
50#endif // LL_WINDOWS 52#endif // LL_WINDOWS
51#include <vector> 53#include <vector>
@@ -871,6 +873,9 @@ You get:
871 873
872*/ 874*/
873 875
876apr_thread_mutex_t* gLogMutexp;
877apr_thread_mutex_t* gCallStacksLogMutexp;
878
874namespace { 879namespace {
875 bool checkLevelMap(const LevelMap& map, const std::string& key, 880 bool checkLevelMap(const LevelMap& map, const std::string& key,
876 LLError::ELevel& level) 881 LLError::ELevel& level)
diff --git a/linden/indra/llcommon/llfile.cpp b/linden/indra/llcommon/llfile.cpp
index 2a76f7f..6b68630 100644
--- a/linden/indra/llcommon/llfile.cpp
+++ b/linden/indra/llcommon/llfile.cpp
@@ -34,6 +34,8 @@
34 */ 34 */
35 35
36#if LL_WINDOWS 36#if LL_WINDOWS
37# define WIN32_LEAN_AND_MEAN
38# include <winsock2.h>
37#include <windows.h> 39#include <windows.h>
38#endif 40#endif
39 41
diff --git a/linden/indra/llcommon/llfindlocale.cpp b/linden/indra/llcommon/llfindlocale.cpp
index 505f5c5..71675af 100644
--- a/linden/indra/llcommon/llfindlocale.cpp
+++ b/linden/indra/llcommon/llfindlocale.cpp
@@ -39,6 +39,8 @@
39#include <ctype.h> 39#include <ctype.h>
40 40
41#ifdef WIN32 41#ifdef WIN32
42# define WIN32_LEAN_AND_MEAN
43# include <winsock2.h>
42#include <windows.h> 44#include <windows.h>
43#include <winnt.h> 45#include <winnt.h>
44#endif 46#endif
diff --git a/linden/indra/llcommon/llfixedbuffer.cpp b/linden/indra/llcommon/llfixedbuffer.cpp
index e9d6029..37a12ad 100644
--- a/linden/indra/llcommon/llfixedbuffer.cpp
+++ b/linden/indra/llcommon/llfixedbuffer.cpp
@@ -33,9 +33,8 @@
33#include "llfixedbuffer.h" 33#include "llfixedbuffer.h"
34 34
35LLFixedBuffer::LLFixedBuffer(const U32 max_lines) 35LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
36 : mMutex(NULL) 36 : mMaxLines(max_lines)
37{ 37{
38 mMaxLines = max_lines;
39 mTimer.reset(); 38 mTimer.reset();
40} 39}
41 40
diff --git a/linden/indra/llcommon/llmemory.cpp b/linden/indra/llcommon/llmemory.cpp
index 74004b0..2b01442 100644
--- a/linden/indra/llcommon/llmemory.cpp
+++ b/linden/indra/llcommon/llmemory.cpp
@@ -33,6 +33,8 @@
33#include "linden_common.h" 33#include "linden_common.h"
34 34
35#if defined(LL_WINDOWS) 35#if defined(LL_WINDOWS)
36# define WIN32_LEAN_AND_MEAN
37# include <winsock2.h>
36# include <windows.h> 38# include <windows.h>
37# include <psapi.h> 39# include <psapi.h>
38#elif defined(LL_DARWIN) 40#elif defined(LL_DARWIN)
diff --git a/linden/indra/llcommon/llprocesslauncher.h b/linden/indra/llcommon/llprocesslauncher.h
index b72be27..9833a13 100644
--- a/linden/indra/llcommon/llprocesslauncher.h
+++ b/linden/indra/llcommon/llprocesslauncher.h
@@ -34,6 +34,8 @@
34#define LL_LLPROCESSLAUNCHER_H 34#define LL_LLPROCESSLAUNCHER_H
35 35
36#if LL_WINDOWS 36#if LL_WINDOWS
37# define WIN32_LEAN_AND_MEAN
38# include <winsock2.h>
37#include <windows.h> 39#include <windows.h>
38#endif 40#endif
39 41
diff --git a/linden/indra/llcommon/llscopedvolatileaprpool.h b/linden/indra/llcommon/llscopedvolatileaprpool.h
new file mode 100644
index 0000000..724dc7f
--- /dev/null
+++ b/linden/indra/llcommon/llscopedvolatileaprpool.h
@@ -0,0 +1,58 @@
1/**
2 * @file llscopedvolatileaprpool.h
3 * @brief Implementation of LLScopedVolatileAPRPool
4 *
5 * $LicenseInfo:firstyear=2010&license=viewergpl$
6 *
7 * Copyright (c) 2010, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 *
23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations.
26 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE.
30 * $/LicenseInfo$
31 */
32
33#ifndef LL_LLSCOPEDVOLATILEAPRPOOL_H
34#define LL_LLSCOPEDVOLATILEAPRPOOL_H
35
36#include "llthread.h"
37
38//! Scoped volatile memory pool.
39//
40// As the AIVolatileAPRPool should never keep allocations very
41// long, it's most common use is for allocations with a lifetime
42// equal to it's scope.
43//
44// This is a convenience class that makes just a little easier to type.
45//
46class LLScopedVolatileAPRPool
47{
48private:
49 AIVolatileAPRPool& mPool;
50 apr_pool_t* mScopedAPRpool;
51public:
52 LLScopedVolatileAPRPool() : mPool(AIThreadLocalData::tldata().mVolatileAPRPool), mScopedAPRpool(mPool.getVolatileAPRPool()) { }
53 ~LLScopedVolatileAPRPool() { mPool.clearVolatileAPRPool(); }
54 // Only use this to pass the pointer to a libapr-1 function that requires it.
55 operator apr_pool_t*() const { return mScopedAPRpool; }
56};
57
58#endif
diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp
index 692d6c4..f7732cb 100644
--- a/linden/indra/llcommon/llthread.cpp
+++ b/linden/indra/llcommon/llthread.cpp
@@ -72,8 +72,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
72 // Set thread state to running 72 // Set thread state to running
73 threadp->mStatus = RUNNING; 73 threadp->mStatus = RUNNING;
74 74
75 // Create a thread local APRFile pool. 75 // Create a thread local data.
76 LLVolatileAPRPool::createLocalAPRFilePool(); 76 AIThreadLocalData::create(threadp);
77 77
78 // Run the user supplied function 78 // Run the user supplied function
79 threadp->run(); 79 threadp->run();
@@ -87,24 +87,14 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
87} 87}
88 88
89 89
90LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : 90LLThread::LLThread(std::string const& name) :
91 mPaused(false), 91 mPaused(false),
92 mName(name), 92 mName(name),
93 mAPRThreadp(NULL), 93 mAPRThreadp(NULL),
94 mStatus(STOPPED) 94 mStatus(STOPPED),
95 mThreadLocalData(NULL)
95{ 96{
96 // Thread creation probably CAN be paranoid about APR being initialized, if necessary 97 mRunCondition = new LLCondition;
97 if (poolp)
98 {
99 mIsLocalPool = false;
100 mAPRPoolp = poolp;
101 }
102 else
103 {
104 mIsLocalPool = true;
105 apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
106 }
107 mRunCondition = new LLCondition(mAPRPoolp);
108} 98}
109 99
110 100
@@ -147,24 +137,18 @@ void LLThread::shutdown()
147 if (!isStopped()) 137 if (!isStopped())
148 { 138 {
149 // This thread just wouldn't stop, even though we gave it time 139 // This thread just wouldn't stop, even though we gave it time
150 llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl; 140 llwarns << "LLThread::shutdown() exiting thread before clean exit!" << llendl;
151 return; 141 return;
152 } 142 }
153 mAPRThreadp = NULL; 143 mAPRThreadp = NULL;
154 } 144 }
155 145
156 delete mRunCondition; 146 delete mRunCondition;
157
158 if (mIsLocalPool)
159 {
160 apr_pool_destroy(mAPRPoolp);
161 }
162} 147}
163 148
164
165void LLThread::start() 149void LLThread::start()
166{ 150{
167 apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp); 151 apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool());
168 152
169 // We won't bother joining 153 // We won't bother joining
170 apr_thread_detach(mAPRThreadp); 154 apr_thread_detach(mAPRThreadp);
@@ -265,38 +249,72 @@ void LLThread::wakeLocked()
265 } 249 }
266} 250}
267 251
268//============================================================================ 252#ifdef SHOW_ASSERT
253// This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread.
254static apr_os_thread_t main_thread_id;
255bool is_main_thread() { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); }
256#endif
269 257
270LLMutex::LLMutex(apr_pool_t *poolp) : 258// The thread private handle to access the AIThreadLocalData instance.
271 mAPRMutexp(NULL) 259apr_threadkey_t* AIThreadLocalData::sThreadLocalDataKey;
260
261//static
262void AIThreadLocalData::init(void)
272{ 263{
273 //if (poolp) 264 // Only do this once.
274 //{ 265 if (sThreadLocalDataKey)
275 // mIsLocalPool = false;
276 // mAPRPoolp = poolp;
277 //}
278 //else
279 { 266 {
280 mIsLocalPool = true; 267 return;
281 apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
282 } 268 }
283 apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); 269
270 apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &AIThreadLocalData::destroy, AIAPRRootPool::get()());
271 ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the
272 // total number of keys per process {PTHREAD_KEYS_MAX}
273 // has been exceeded.
274
275 // Create the thread-local data for the main thread (this function is called by the main thread).
276 AIThreadLocalData::create(NULL);
277
278#ifdef SHOW_ASSERT
279 // This function is called by the main thread.
280 main_thread_id = apr_os_thread_current();
281#endif
284} 282}
285 283
286LLMutex::~LLMutex() 284// This is called once for every thread when the thread is destructed.
285//static
286void AIThreadLocalData::destroy(void* thread_local_data)
287{ 287{
288#if _DEBUG 288 delete reinterpret_cast<AIThreadLocalData*>(thread_local_data);
289 llassert(!isLocked()); // better not be locked! 289}
290#endif 290
291 apr_thread_mutex_destroy(mAPRMutexp); 291//static
292 mAPRMutexp = NULL; 292void AIThreadLocalData::create(LLThread* threadp)
293 if (mIsLocalPool) 293{
294 AIThreadLocalData* new_tld = new AIThreadLocalData;
295 if (threadp)
294 { 296 {
295 apr_pool_destroy(mAPRPoolp); 297 threadp->mThreadLocalData = new_tld;
296 } 298 }
299 apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey);
300 llassert_always(status == APR_SUCCESS);
297} 301}
298 302
299bool LLMutex::isLocked() 303//static
304AIThreadLocalData& AIThreadLocalData::tldata(void)
305{
306 if (!sThreadLocalDataKey)
307 AIThreadLocalData::init();
308
309 void* data;
310 apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey);
311 llassert_always(status == APR_SUCCESS);
312 return *static_cast<AIThreadLocalData*>(data);
313}
314
315//============================================================================
316
317bool LLMutexBase::isLocked()
300{ 318{
301 if (!tryLock()) 319 if (!tryLock())
302 { 320 {
@@ -308,12 +326,9 @@ bool LLMutex::isLocked()
308 326
309//============================================================================ 327//============================================================================
310 328
311LLCondition::LLCondition(apr_pool_t *poolp) : 329LLCondition::LLCondition(AIAPRPool& parent) : LLMutex(parent)
312 LLMutex(poolp)
313{ 330{
314 // base class (LLMutex) has already ensured that mAPRPoolp is set up. 331 apr_thread_cond_create(&mAPRCondp, mPool());
315
316 apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
317} 332}
318 333
319LLCondition::~LLCondition() 334LLCondition::~LLCondition()
@@ -349,7 +364,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount()
349{ 364{
350 if (!sMutex) 365 if (!sMutex)
351 { 366 {
352 sMutex = new LLMutex(0); 367 sMutex = new LLMutex;
353 } 368 }
354} 369}
355 370
diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h
index 98d64ef..1e982cc 100644
--- a/linden/indra/llcommon/llthread.h
+++ b/linden/indra/llcommon/llthread.h
@@ -38,11 +38,28 @@
38#include "llmemory.h" 38#include "llmemory.h"
39 39
40#include "apr_thread_cond.h" 40#include "apr_thread_cond.h"
41#include "aiaprpool.h"
41 42
42class LLThread; 43class LLThread;
43class LLMutex; 44class LLMutex;
44class LLCondition; 45class LLCondition;
45 46
47class LL_COMMON_API AIThreadLocalData
48{
49private:
50 static apr_threadkey_t* sThreadLocalDataKey;
51
52public:
53 // Thread-local memory pool.
54 AIAPRRootPool mRootPool;
55 AIVolatileAPRPool mVolatileAPRPool;
56
57 static void init(void);
58 static void destroy(void* thread_local_data);
59 static void create(LLThread* pthread);
60 static AIThreadLocalData& tldata(void);
61};
62
46class LL_COMMON_API LLThread 63class LL_COMMON_API LLThread
47{ 64{
48public: 65public:
@@ -53,7 +70,7 @@ public:
53 QUITTING= 2 // Someone wants this thread to quit 70 QUITTING= 2 // Someone wants this thread to quit
54 } EThreadStatus; 71 } EThreadStatus;
55 72
56 LLThread(const std::string& name, apr_pool_t *poolp = NULL); 73 LLThread(std::string const& name);
57 virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state. 74 virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state.
58 virtual void shutdown(); // stops the thread 75 virtual void shutdown(); // stops the thread
59 76
@@ -82,7 +99,8 @@ public:
82 // this kicks off the apr thread 99 // this kicks off the apr thread
83 void start(void); 100 void start(void);
84 101
85 apr_pool_t *getAPRPool() { return mAPRPoolp; } 102 // Return thread-local data for the current thread.
103 static AIThreadLocalData& tldata(void) { return AIThreadLocalData::tldata(); }
86 104
87private: 105private:
88 bool mPaused; 106 bool mPaused;
@@ -95,10 +113,11 @@ protected:
95 LLCondition* mRunCondition; 113 LLCondition* mRunCondition;
96 114
97 apr_thread_t *mAPRThreadp; 115 apr_thread_t *mAPRThreadp;
98 apr_pool_t *mAPRPoolp;
99 bool mIsLocalPool;
100 EThreadStatus mStatus; 116 EThreadStatus mStatus;
101 117
118 friend void AIThreadLocalData::create(LLThread* threadp);
119 AIThreadLocalData* mThreadLocalData;
120
102 void setQuitting(); 121 void setQuitting();
103 122
104 // virtual function overridden by subclass -- this will be called when the thread runs 123 // virtual function overridden by subclass -- this will be called when the thread runs
@@ -125,12 +144,9 @@ protected:
125 144
126//============================================================================ 145//============================================================================
127 146
128class LL_COMMON_API LLMutex 147class LL_COMMON_API LLMutexBase
129{ 148{
130public: 149public:
131 LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex
132 ~LLMutex();
133
134 void lock() { apr_thread_mutex_lock(mAPRMutexp); } 150 void lock() { apr_thread_mutex_lock(mAPRMutexp); }
135 void unlock() { apr_thread_mutex_unlock(mAPRMutexp); } 151 void unlock() { apr_thread_mutex_unlock(mAPRMutexp); }
136 // Returns true if lock was obtained successfully. 152 // Returns true if lock was obtained successfully.
@@ -139,16 +155,60 @@ public:
139 bool isLocked(); // non-blocking, but does do a lock/unlock so not free 155 bool isLocked(); // non-blocking, but does do a lock/unlock so not free
140 156
141protected: 157protected:
142 apr_thread_mutex_t *mAPRMutexp; 158 // mAPRMutexp is initialized and uninitialized in the derived class.
143 apr_pool_t *mAPRPoolp; 159 apr_thread_mutex_t* mAPRMutexp;
144 bool mIsLocalPool; 160};
161
162class LL_COMMON_API LLMutex : public LLMutexBase
163{
164public:
165 LLMutex(AIAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent)
166 {
167 apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mPool());
168 }
169 ~LLMutex()
170 {
171 llassert(!isLocked()); // better not be locked!
172 apr_thread_mutex_destroy(mAPRMutexp);
173 mAPRMutexp = NULL;
174 }
175
176protected:
177 AIAPRPool mPool;
145}; 178};
146 179
180#if APR_HAS_THREADS
181// No need to use a root pool in this case.
182typedef LLMutex LLMutexRootPool;
183#else // APR_HAS_THREADS
184class LL_COMMON_API LLMutexRootPool : public LLMutexBase
185{
186public:
187 LLMutexRootPool(void)
188 {
189 apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mRootPool());
190 }
191 ~LLMutexRootPool()
192 {
193#if APR_POOL_DEBUG
194 // It is allowed to destruct root pools from a different thread.
195 mRootPool.grab_ownership();
196#endif
197 llassert(!isLocked()); // better not be locked!
198 apr_thread_mutex_destroy(mAPRMutexp);
199 mAPRMutexp = NULL;
200 }
201
202protected:
203 AIAPRRootPool mRootPool;
204};
205#endif // APR_HAS_THREADS
206
147// Actually a condition/mutex pair (since each condition needs to be associated with a mutex). 207// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
148class LL_COMMON_API LLCondition : public LLMutex 208class LL_COMMON_API LLCondition : public LLMutex
149{ 209{
150public: 210public:
151 LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. 211 LLCondition(AIAPRPool& parent = LLThread::tldata().mRootPool);
152 ~LLCondition(); 212 ~LLCondition();
153 213
154 void wait(); // blocks 214 void wait(); // blocks
@@ -162,7 +222,7 @@ protected:
162class LL_COMMON_API LLMutexLock 222class LL_COMMON_API LLMutexLock
163{ 223{
164public: 224public:
165 LLMutexLock(LLMutex* mutex) 225 LLMutexLock(LLMutexBase* mutex)
166 { 226 {
167 mMutex = mutex; 227 mMutex = mutex;
168 mMutex->lock(); 228 mMutex->lock();
@@ -172,7 +232,102 @@ public:
172 mMutex->unlock(); 232 mMutex->unlock();
173 } 233 }
174private: 234private:
175 LLMutex* mMutex; 235 LLMutexBase* mMutex;
236};
237
238class AIRWLock
239{
240public:
241 AIRWLock(AIAPRPool& parent = LLThread::tldata().mRootPool) :
242 mWriterWaitingMutex(parent), mNoHoldersCondition(parent), mHoldersCount(0), mWriterIsWaiting(false) { }
243
244private:
245 LLMutex mWriterWaitingMutex; //!< This mutex is locked while some writer is waiting for access.
246 LLCondition mNoHoldersCondition; //!< Access control for mHoldersCount. Condition true when there are no more holders.
247 int mHoldersCount; //!< Number of readers or -1 if a writer locked this object.
248 // This is volatile because we read it outside the critical area of mWriterWaitingMutex, at [1].
249 // That means that other threads can change it while we are already in the (inlined) function rdlock.
250 // Without volatile, the following assembly would fail:
251 // register x = mWriterIsWaiting;
252 // /* some thread changes mWriterIsWaiting */
253 // if (x ...
254 // However, because the function is fuzzy to begin with (we don't mind that this race
255 // condition exists) it would work fine without volatile. So, basically it's just here
256 // out of principle ;). -- Aleric
257 bool volatile mWriterIsWaiting; //!< True when there is a writer waiting for write access.
258
259public:
260 void rdlock(bool high_priority = false)
261 {
262 // Give a writer a higher priority (kinda fuzzy).
263 if (mWriterIsWaiting && !high_priority) // [1] If there is a writer interested,
264 {
265 mWriterWaitingMutex.lock(); // [2] then give it precedence and wait here.
266 // If we get here then the writer got it's access; mHoldersCount == -1.
267 mWriterWaitingMutex.unlock();
268 }
269 mNoHoldersCondition.lock(); // [3] Get exclusive access to mHoldersCount.
270 while (mHoldersCount == -1) // [4]
271 {
272 mNoHoldersCondition.wait(); // [5] Wait till mHoldersCount is (or just was) 0.
273 }
274 ++mHoldersCount; // One more reader.
275 mNoHoldersCondition.unlock(); // Release lock on mHoldersCount.
276 }
277 void rdunlock(void)
278 {
279 mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount.
280 if (--mHoldersCount == 0) // Was this the last reader?
281 {
282 mNoHoldersCondition.signal(); // Tell waiting threads, see [5], [6] and [7].
283 }
284 mNoHoldersCondition.unlock(); // Release lock on mHoldersCount.
285 }
286 void wrlock(void)
287 {
288 mWriterWaitingMutex.lock(); // Block new readers, see [2],
289 mWriterIsWaiting = true; // from this moment on, see [1].
290 mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount.
291 while (mHoldersCount != 0) // Other readers or writers have this lock?
292 {
293 mNoHoldersCondition.wait(); // [6] Wait till mHoldersCount is (or just was) 0.
294 }
295 mWriterIsWaiting = false; // Stop checking the lock for new readers, see [1].
296 mWriterWaitingMutex.unlock(); // Release blocked readers, they will still hang at [3].
297 mHoldersCount = -1; // We are a writer now (will cause a hang at [5], see [4]).
298 mNoHoldersCondition.unlock(); // Release lock on mHolders (readers go from [3] to [5]).
299 }
300 void wrunlock(void)
301 {
302 mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount.
303 mHoldersCount = 0; // We have no writer anymore.
304 mNoHoldersCondition.signal(); // Tell waiting threads, see [5], [6] and [7].
305 mNoHoldersCondition.unlock(); // Release lock on mHoldersCount.
306 }
307 void rd2wrlock(void)
308 {
309 mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. Blocks new readers at [3].
310 if (--mHoldersCount > 0) // Any other reads left?
311 {
312 mWriterWaitingMutex.lock(); // Block new readers, see [2],
313 mWriterIsWaiting = true; // from this moment on, see [1].
314 while (mHoldersCount != 0) // Other readers (still) have this lock?
315 {
316 mNoHoldersCondition.wait(); // [7] Wait till mHoldersCount is (or just was) 0.
317 }
318 mWriterIsWaiting = false; // Stop checking the lock for new readers, see [1].
319 mWriterWaitingMutex.unlock(); // Release blocked readers, they will still hang at [3].
320 }
321 mHoldersCount = -1; // We are a writer now (will cause a hang at [5], see [4]).
322 mNoHoldersCondition.unlock(); // Release lock on mHolders (readers go from [3] to [5]).
323 }
324 void wr2rdlock(void)
325 {
326 mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount.
327 mHoldersCount = 1; // Turn writer into a reader.
328 mNoHoldersCondition.signal(); // Tell waiting readers, see [5].
329 mNoHoldersCondition.unlock(); // Release lock on mHoldersCount.
330 }
176}; 331};
177 332
178//============================================================================ 333//============================================================================
@@ -187,7 +342,6 @@ void LLThread::unlockData()
187 mRunCondition->unlock(); 342 mRunCondition->unlock();
188} 343}
189 344
190
191//============================================================================ 345//============================================================================
192 346
193// see llmemory.h for LLPointer<> definition 347// see llmemory.h for LLPointer<> definition
diff --git a/linden/indra/llcommon/llworkerthread.cpp b/linden/indra/llcommon/llworkerthread.cpp
index 8195e1c..e238a89 100644
--- a/linden/indra/llcommon/llworkerthread.cpp
+++ b/linden/indra/llcommon/llworkerthread.cpp
@@ -43,7 +43,7 @@
43LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) : 43LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) :
44 LLQueuedThread(name, threaded) 44 LLQueuedThread(name, threaded)
45{ 45{
46 mDeleteMutex = new LLMutex(NULL); 46 mDeleteMutex = new LLMutex;
47} 47}
48 48
49LLWorkerThread::~LLWorkerThread() 49LLWorkerThread::~LLWorkerThread()
@@ -183,7 +183,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
183 : mWorkerThread(workerthread), 183 : mWorkerThread(workerthread),
184 mWorkerClassName(name), 184 mWorkerClassName(name),
185 mRequestHandle(LLWorkerThread::nullHandle()), 185 mRequestHandle(LLWorkerThread::nullHandle()),
186 mMutex(NULL),
187 mWorkFlags(0) 186 mWorkFlags(0)
188{ 187{
189 if (!mWorkerThread) 188 if (!mWorkerThread)
diff --git a/linden/indra/llcommon/llworkerthread.h b/linden/indra/llcommon/llworkerthread.h
index 33d4c40..8e0dd8a 100644
--- a/linden/indra/llcommon/llworkerthread.h
+++ b/linden/indra/llcommon/llworkerthread.h
@@ -194,7 +194,7 @@ protected:
194 U32 mRequestPriority; // last priority set 194 U32 mRequestPriority; // last priority set
195 195
196private: 196private:
197 LLMutex mMutex; 197 LLMutexRootPool mMutex; // Use LLMutexRootPool since this object is created and destructed by multiple threads.
198 LLAtomicU32 mWorkFlags; 198 LLAtomicU32 mWorkFlags;
199}; 199};
200 200
diff --git a/linden/indra/llcrashlogger/llcrashlogger.cpp b/linden/indra/llcrashlogger/llcrashlogger.cpp
index d25be55..b6afbc6 100755
--- a/linden/indra/llcrashlogger/llcrashlogger.cpp
+++ b/linden/indra/llcrashlogger/llcrashlogger.cpp
@@ -387,8 +387,7 @@ bool LLCrashLogger::init()
387 return false; 387 return false;
388 } 388 }
389 389
390 gServicePump = new LLPumpIO(gAPRPoolp); 390 gServicePump = new LLPumpIO;
391 gServicePump->prime(gAPRPoolp);
392 LLHTTPClient::setPump(*gServicePump); 391 LLHTTPClient::setPump(*gServicePump);
393 392
394 //If we've opened the crash logger, assume we can delete the marker file if it exists 393 //If we've opened the crash logger, assume we can delete the marker file if it exists
diff --git a/linden/indra/llimage/llimage.cpp b/linden/indra/llimage/llimage.cpp
index 776c481..e933750 100644
--- a/linden/indra/llimage/llimage.cpp
+++ b/linden/indra/llimage/llimage.cpp
@@ -57,7 +57,7 @@ LLMutex* LLImage::sMutex = NULL;
57//static 57//static
58void LLImage::initClass(const bool& useDSO) 58void LLImage::initClass(const bool& useDSO)
59{ 59{
60 sMutex = new LLMutex(NULL); 60 sMutex = new LLMutex;
61 if (useDSO) 61 if (useDSO)
62 { 62 {
63 LLImageJ2C::openDSO(); 63 LLImageJ2C::openDSO();
diff --git a/linden/indra/llimage/llimagej2c.cpp b/linden/indra/llimage/llimagej2c.cpp
index b99ebff..9e88bcd 100644
--- a/linden/indra/llimage/llimagej2c.cpp
+++ b/linden/indra/llimage/llimagej2c.cpp
@@ -46,7 +46,7 @@ typedef const char* (*EngineInfoLLImageJ2CFunction)();
46CreateLLImageJ2CFunction j2cimpl_create_func; 46CreateLLImageJ2CFunction j2cimpl_create_func;
47DestroyLLImageJ2CFunction j2cimpl_destroy_func; 47DestroyLLImageJ2CFunction j2cimpl_destroy_func;
48EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func; 48EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func;
49apr_pool_t *j2cimpl_dso_memory_pool; 49AIAPRPool j2cimpl_dso_memory_pool;
50apr_dso_handle_t *j2cimpl_dso_handle; 50apr_dso_handle_t *j2cimpl_dso_handle;
51 51
52//Declare the prototype for theses functions here, their functionality 52//Declare the prototype for theses functions here, their functionality
@@ -81,13 +81,12 @@ void LLImageJ2C::openDSO()
81 gDirUtilp->getExecutableDir()); 81 gDirUtilp->getExecutableDir());
82 82
83 j2cimpl_dso_handle = NULL; 83 j2cimpl_dso_handle = NULL;
84 j2cimpl_dso_memory_pool = NULL; 84 j2cimpl_dso_memory_pool.create();
85 85
86 //attempt to load the shared library 86 //attempt to load the shared library
87 apr_pool_create(&j2cimpl_dso_memory_pool, NULL);
88 rv = apr_dso_load(&j2cimpl_dso_handle, 87 rv = apr_dso_load(&j2cimpl_dso_handle,
89 dso_path.c_str(), 88 dso_path.c_str(),
90 j2cimpl_dso_memory_pool); 89 j2cimpl_dso_memory_pool());
91 90
92 //now, check for success 91 //now, check for success
93 if ( rv == APR_SUCCESS ) 92 if ( rv == APR_SUCCESS )
@@ -151,11 +150,7 @@ void LLImageJ2C::openDSO()
151 j2cimpl_dso_handle = NULL; 150 j2cimpl_dso_handle = NULL;
152 } 151 }
153 152
154 if ( j2cimpl_dso_memory_pool ) 153 j2cimpl_dso_memory_pool.destroy();
155 {
156 apr_pool_destroy(j2cimpl_dso_memory_pool);
157 j2cimpl_dso_memory_pool = NULL;
158 }
159 } 154 }
160} 155}
161 156
@@ -163,7 +158,7 @@ void LLImageJ2C::openDSO()
163void LLImageJ2C::closeDSO() 158void LLImageJ2C::closeDSO()
164{ 159{
165 if ( j2cimpl_dso_handle ) apr_dso_unload(j2cimpl_dso_handle); 160 if ( j2cimpl_dso_handle ) apr_dso_unload(j2cimpl_dso_handle);
166 if (j2cimpl_dso_memory_pool) apr_pool_destroy(j2cimpl_dso_memory_pool); 161 j2cimpl_dso_memory_pool.destroy();
167} 162}
168 163
169//static 164//static
diff --git a/linden/indra/llimage/llimageworker.cpp b/linden/indra/llimage/llimageworker.cpp
index 558a968..dc989e5 100644
--- a/linden/indra/llimage/llimageworker.cpp
+++ b/linden/indra/llimage/llimageworker.cpp
@@ -41,14 +41,13 @@
41LLImageDecodeThread::LLImageDecodeThread(bool threaded) 41LLImageDecodeThread::LLImageDecodeThread(bool threaded)
42 : LLQueuedThread("imagedecode", threaded) 42 : LLQueuedThread("imagedecode", threaded)
43{ 43{
44 mCreationMutex = new LLMutex(getAPRPool());
45} 44}
46 45
47// MAIN THREAD 46// MAIN THREAD
48// virtual 47// virtual
49S32 LLImageDecodeThread::update(U32 max_time_ms) 48S32 LLImageDecodeThread::update(U32 max_time_ms)
50{ 49{
51 LLMutexLock lock(mCreationMutex); 50 LLMutexLock lock(&mCreationMutex);
52 for (creation_list_t::iterator iter = mCreationList.begin(); 51 for (creation_list_t::iterator iter = mCreationList.begin();
53 iter != mCreationList.end(); ++iter) 52 iter != mCreationList.end(); ++iter)
54 { 53 {
@@ -71,7 +70,7 @@ S32 LLImageDecodeThread::update(U32 max_time_ms)
71LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, 70LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
72 U32 priority, S32 discard, BOOL needs_aux, Responder* responder) 71 U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
73{ 72{
74 LLMutexLock lock(mCreationMutex); 73 LLMutexLock lock(&mCreationMutex);
75 handle_t handle = generateHandle(); 74 handle_t handle = generateHandle();
76 mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder)); 75 mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
77 return handle; 76 return handle;
@@ -81,7 +80,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted*
81// Returns the size of the mutex guarded list as an indication of sanity 80// Returns the size of the mutex guarded list as an indication of sanity
82S32 LLImageDecodeThread::tut_size() 81S32 LLImageDecodeThread::tut_size()
83{ 82{
84 LLMutexLock lock(mCreationMutex); 83 LLMutexLock lock(&mCreationMutex);
85 S32 res = mCreationList.size(); 84 S32 res = mCreationList.size();
86 return res; 85 return res;
87} 86}
diff --git a/linden/indra/llimage/llimageworker.h b/linden/indra/llimage/llimageworker.h
index 0260206..fa2a8fa 100644
--- a/linden/indra/llimage/llimageworker.h
+++ b/linden/indra/llimage/llimageworker.h
@@ -101,7 +101,7 @@ private:
101 }; 101 };
102 typedef std::list<creation_info> creation_list_t; 102 typedef std::list<creation_info> creation_list_t;
103 creation_list_t mCreationList; 103 creation_list_t mCreationList;
104 LLMutex* mCreationMutex; 104 LLMutex mCreationMutex;
105}; 105};
106 106
107#endif 107#endif
diff --git a/linden/indra/llmath/llvolumemgr.cpp b/linden/indra/llmath/llvolumemgr.cpp
index 53641fc..8bfebcb 100644
--- a/linden/indra/llmath/llvolumemgr.cpp
+++ b/linden/indra/llmath/llvolumemgr.cpp
@@ -55,7 +55,7 @@ LLVolumeMgr::LLVolumeMgr()
55{ 55{
56 // the LLMutex magic interferes with easy unit testing, 56 // the LLMutex magic interferes with easy unit testing,
57 // so you now must manually call useMutex() to use it 57 // so you now must manually call useMutex() to use it
58 //mDataMutex = new LLMutex(gAPRPoolp); 58 //mDataMutex = new LLMutex;
59} 59}
60 60
61LLVolumeMgr::~LLVolumeMgr() 61LLVolumeMgr::~LLVolumeMgr()
@@ -222,7 +222,7 @@ void LLVolumeMgr::useMutex()
222{ 222{
223 if (!mDataMutex) 223 if (!mDataMutex)
224 { 224 {
225 mDataMutex = new LLMutex(gAPRPoolp); 225 mDataMutex = new LLMutex;
226 } 226 }
227} 227}
228 228
diff --git a/linden/indra/llmessage/CMakeLists.txt b/linden/indra/llmessage/CMakeLists.txt
index a5e4249..9965191 100644
--- a/linden/indra/llmessage/CMakeLists.txt
+++ b/linden/indra/llmessage/CMakeLists.txt
@@ -22,6 +22,7 @@ include_directories(
22set(llmessage_SOURCE_FILES 22set(llmessage_SOURCE_FILES
23 llares.cpp 23 llares.cpp
24 llassetstorage.cpp 24 llassetstorage.cpp
25 llavatarnamecache.cpp
25 llblowfishcipher.cpp 26 llblowfishcipher.cpp
26 llbuffer.cpp 27 llbuffer.cpp
27 llbufferstream.cpp 28 llbufferstream.cpp
@@ -105,6 +106,7 @@ set(llmessage_HEADER_FILES
105 106
106 llares.h 107 llares.h
107 llassetstorage.h 108 llassetstorage.h
109 llavatarnamecache.h
108 llblowfishcipher.h 110 llblowfishcipher.h
109 llbuffer.h 111 llbuffer.h
110 llbufferstream.h 112 llbufferstream.h
diff --git a/linden/indra/llmessage/llares.cpp b/linden/indra/llmessage/llares.cpp
index fe37fe8..5a6794e 100644
--- a/linden/indra/llmessage/llares.cpp
+++ b/linden/indra/llmessage/llares.cpp
@@ -43,6 +43,7 @@
43 43
44#include "llapr.h" 44#include "llapr.h"
45#include "llares.h" 45#include "llares.h"
46#include "llscopedvolatileaprpool.h"
46 47
47#if defined(LL_WINDOWS) 48#if defined(LL_WINDOWS)
48# define ns_c_in 1 49# define ns_c_in 1
@@ -463,11 +464,6 @@ void LLAres::search(const std::string &query, LLResType type,
463 464
464bool LLAres::process(U64 timeout) 465bool LLAres::process(U64 timeout)
465{ 466{
466 if (!gAPRPoolp)
467 {
468 ll_init_apr();
469 }
470
471 int socks[ARES_GETSOCK_MAXNUM]; 467 int socks[ARES_GETSOCK_MAXNUM];
472 apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM]; 468 apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];
473 apr_int32_t nsds = 0; 469 apr_int32_t nsds = 0;
@@ -481,10 +477,7 @@ bool LLAres::process(U64 timeout)
481 return nsds > 0; 477 return nsds > 0;
482 } 478 }
483 479
484 apr_status_t status; 480 LLScopedVolatileAPRPool scoped_pool;
485 LLAPRPool pool;
486 status = pool.getStatus() ;
487 ll_apr_assert_status(status);
488 481
489 for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++) 482 for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
490 { 483 {
@@ -501,7 +494,7 @@ bool LLAres::process(U64 timeout)
501 494
502 apr_socket_t *aprSock = NULL; 495 apr_socket_t *aprSock = NULL;
503 496
504 status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool()); 497 apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool);
505 if (status != APR_SUCCESS) 498 if (status != APR_SUCCESS)
506 { 499 {
507 ll_apr_warn_status(status); 500 ll_apr_warn_status(status);
@@ -510,7 +503,7 @@ bool LLAres::process(U64 timeout)
510 503
511 aprFds[nactive].desc.s = aprSock; 504 aprFds[nactive].desc.s = aprSock;
512 aprFds[nactive].desc_type = APR_POLL_SOCKET; 505 aprFds[nactive].desc_type = APR_POLL_SOCKET;
513 aprFds[nactive].p = pool.getAPRPool(); 506 aprFds[nactive].p = scoped_pool;
514 aprFds[nactive].rtnevents = 0; 507 aprFds[nactive].rtnevents = 0;
515 aprFds[nactive].client_data = &socks[i]; 508 aprFds[nactive].client_data = &socks[i];
516 509
@@ -519,7 +512,7 @@ bool LLAres::process(U64 timeout)
519 512
520 if (nactive > 0) 513 if (nactive > 0)
521 { 514 {
522 status = apr_poll(aprFds, nactive, &nsds, timeout); 515 apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout);
523 516
524 if (status != APR_SUCCESS && status != APR_TIMEUP) 517 if (status != APR_SUCCESS && status != APR_TIMEUP)
525 { 518 {
diff --git a/linden/indra/llmessage/llavatarnamecache.cpp b/linden/indra/llmessage/llavatarnamecache.cpp
new file mode 100644
index 0000000..180274e
--- /dev/null
+++ b/linden/indra/llmessage/llavatarnamecache.cpp
@@ -0,0 +1,859 @@
1/**
2 * @file llavatarnamecache.cpp
3 * @brief Provides lookup of avatar SLIDs ("bobsmith123") and display names
4 * ("James Cook") from avatar UUIDs.
5 *
6 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
7 * Second Life Viewer Source Code
8 * Copyright (C) 2010, Linden Research, Inc.
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation;
13 * version 2.1 of the License only.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *
24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
25 * $/LicenseInfo$
26 */
27#include "linden_common.h"
28
29#include "llavatarnamecache.h"
30
31#include "llcachename.h" // we wrap this system
32#include "llframetimer.h"
33#include "llhttpclient.h"
34#include "llsd.h"
35#include "llsdserialize.h"
36
37#include <boost/tokenizer.hpp>
38
39#include <map>
40#include <set>
41
42namespace LLAvatarNameCache
43{
44 use_display_name_signal_t mUseDisplayNamesSignal;
45
46 // Manual override for display names: 0 = legacy names,
47 // 1 = display name and legacy name, 2 = display name (legacy if absent)
48 U32 sUseDisplayNames = 0;
49
50 // Cache starts in a paused state until we can determine if the
51 // current region supports display names.
52 bool sRunning = false;
53
54 // Base lookup URL for name service.
55 // On simulator, loaded from indra.xml
56 // On viewer, usually a simulator capability (at People API team's request)
57 // Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
58 std::string sNameLookupURL;
59
60 // accumulated agent IDs for next query against service
61 typedef std::set<LLUUID> ask_queue_t;
62 ask_queue_t sAskQueue;
63
64 // agent IDs that have been requested, but with no reply
65 // maps agent ID to frame time request was made
66 typedef std::map<LLUUID, F64> pending_queue_t;
67 pending_queue_t sPendingQueue;
68
69 // Callbacks to fire when we received a name.
70 // May have multiple callbacks for a single ID, which are
71 // represented as multiple slots bound to the signal.
72 // Avoid copying signals via pointers.
73 typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
74 signal_map_t sSignalMap;
75
76 // names we know about
77 typedef std::map<LLUUID, LLAvatarName> cache_t;
78 cache_t sCache;
79
80 // Send bulk lookup requests a few times a second at most
81 // only need per-frame timing resolution
82 LLFrameTimer sRequestTimer;
83
84 // Periodically clean out expired entries from the cache
85 //LLFrameTimer sEraseExpiredTimer;
86
87 //-----------------------------------------------------------------------
88 // Internal methods
89 //-----------------------------------------------------------------------
90
91 // Handle name response off network.
92 // Optionally skip adding to cache, used when this is a fallback to the
93 // legacy name system.
94 void processName(const LLUUID& agent_id,
95 const LLAvatarName& av_name,
96 bool add_to_cache);
97
98 void requestNamesViaCapability();
99
100 // Legacy name system callback
101 void legacyNameCallback(const LLUUID& agent_id,
102 const std::string& first, const std::string& last,
103 BOOL is_group, void* data);
104
105 void requestNamesViaLegacy();
106
107 // Fill in an LLAvatarName with the legacy name data
108 void buildLegacyName(const std::string& full_name,
109 LLAvatarName* av_name);
110
111 // Do a single callback to a given slot
112 void fireSignal(const LLUUID& agent_id,
113 const callback_slot_t& slot,
114 const LLAvatarName& av_name);
115
116 // Is a request in-flight over the network?
117 bool isRequestPending(const LLUUID& agent_id);
118
119 // Erase expired names from cache
120 void eraseExpired();
121
122 bool expirationFromCacheControl(LLSD headers, F64 *expires);
123}
124
125/* Sample response:
126<?xml version="1.0"?>
127<llsd>
128 <map>
129 <key>agents</key>
130 <array>
131 <map>
132 <key>display_name_next_update</key>
133 <date>2010-04-16T21:34:02+00:00Z</date>
134 <key>display_name_expires</key>
135 <date>2010-04-16T21:32:26.142178+00:00Z</date>
136 <key>display_name</key>
137 <string>MickBot390 LLQABot</string>
138 <key>sl_id</key>
139 <string>mickbot390.llqabot</string>
140 <key>id</key>
141 <string>0012809d-7d2d-4c24-9609-af1230a37715</string>
142 <key>is_display_name_default</key>
143 <boolean>false</boolean>
144 </map>
145 <map>
146 <key>display_name_next_update</key>
147 <date>2010-04-16T21:34:02+00:00Z</date>
148 <key>display_name_expires</key>
149 <date>2010-04-16T21:32:26.142178+00:00Z</date>
150 <key>display_name</key>
151 <string>Bjork Gudmundsdottir</string>
152 <key>sl_id</key>
153 <string>sardonyx.linden</string>
154 <key>id</key>
155 <string>3941037e-78ab-45f0-b421-bd6e77c1804d</string>
156 <key>is_display_name_default</key>
157 <boolean>true</boolean>
158 </map>
159 </array>
160 </map>
161</llsd>
162*/
163
164class LLAvatarNameResponder : public LLHTTPClient::Responder
165{
166private:
167 // need to store agent ids that are part of this request in case of
168 // an error, so we can flag them as unavailable
169 std::vector<LLUUID> mAgentIDs;
170
171 // Need the headers to look up Expires: and Retry-After:
172 LLSD mHeaders;
173
174public:
175 LLAvatarNameResponder(const std::vector<LLUUID>& agent_ids)
176 : mAgentIDs(agent_ids),
177 mHeaders()
178 { }
179
180 /*virtual*/ void completedHeader(U32 status, const std::string& reason,
181 const LLSD& headers)
182 {
183 mHeaders = headers;
184 }
185
186 /*virtual*/ void result(const LLSD& content)
187 {
188 // Pull expiration out of headers if available
189 F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(mHeaders);
190
191 LLSD agents = content["agents"];
192 LLSD::array_const_iterator it;
193 for (it = agents.beginArray(); it != agents.endArray(); ++it)
194 {
195 const LLSD& row = *it;
196 LLUUID agent_id = row["id"].asUUID();
197
198 LLAvatarName av_name;
199 av_name.fromLLSD(row);
200
201 // Use expiration time from header
202 av_name.mExpires = expires;
203
204 // Some avatars don't have explicit display names set
205 if (av_name.mDisplayName.empty())
206 {
207 av_name.mDisplayName = av_name.mUsername;
208 }
209
210 // cache it and fire signals
211 LLAvatarNameCache::processName(agent_id, av_name, true);
212 }
213
214 // Same logic as error response case
215 LLSD unresolved_agents = content["bad_ids"];
216 if (unresolved_agents.size() > 0)
217 {
218 std::string first, last;
219 LLAvatarName av_name;
220 av_name.mIsDisplayNameDefault = false;
221 av_name.mIsDummy = true;
222 av_name.mExpires = expires;
223
224 for (it = unresolved_agents.beginArray(); it != unresolved_agents.endArray(); ++it)
225 {
226 const LLUUID& agent_id = *it;
227 gCacheName->getName(agent_id, first, last);
228 av_name.mLegacyFirstName = first;
229 av_name.mLegacyLastName = last;
230 av_name.mDisplayName = first;
231 if (last == "Resident")
232 {
233 av_name.mDisplayName = first;
234 av_name.mUsername = first;
235 }
236 else
237 {
238 av_name.mDisplayName = first + " " + last;
239 av_name.mUsername = first + "." + last;
240 }
241 LLStringUtil::toLower(av_name.mUsername);
242 // cache it and fire signals
243 LLAvatarNameCache::processName(agent_id, av_name, true);
244 }
245 }
246 }
247
248 /*virtual*/ void error(U32 status, const std::string& reason)
249 {
250 // We're going to construct a dummy record and cache it for a while,
251 // either briefly for a 503 Service Unavailable, or longer for other
252 // errors.
253 F64 retry_timestamp = errorRetryTimestamp(status);
254
255 std::string first, last;
256 LLAvatarName av_name;
257 av_name.mIsDisplayNameDefault = false;
258 av_name.mIsDummy = true;
259 av_name.mExpires = retry_timestamp;
260
261 // Add dummy records for all agent IDs in this request
262 std::vector<LLUUID>::const_iterator it;
263 for (it = mAgentIDs.begin(); it != mAgentIDs.end(); ++it)
264 {
265 const LLUUID& agent_id = *it;
266 gCacheName->getName(agent_id, first, last);
267 av_name.mLegacyFirstName = first;
268 av_name.mLegacyLastName = last;
269 av_name.mDisplayName = first;
270 if (last == "Resident")
271 {
272 av_name.mDisplayName = first;
273 av_name.mUsername = first;
274 }
275 else
276 {
277 av_name.mDisplayName = first + " " + last;
278 av_name.mUsername = first + "." + last;
279 }
280 LLStringUtil::toLower(av_name.mUsername);
281 // cache it and fire signals
282 LLAvatarNameCache::processName(agent_id, av_name, true);
283 }
284 }
285
286 // Return time to retry a request that generated an error, based on
287 // error type and headers. Return value is seconds-since-epoch.
288 F64 errorRetryTimestamp(S32 status)
289 {
290 F64 now = LLFrameTimer::getTotalSeconds();
291
292 // Retry-After takes priority
293 LLSD retry_after = mHeaders["retry-after"];
294 if (retry_after.isDefined())
295 {
296 // We only support the delta-seconds type
297 S32 delta_seconds = retry_after.asInteger();
298 if (delta_seconds > 0)
299 {
300 // ...valid delta-seconds
301 return now + F64(delta_seconds);
302 }
303 }
304
305 // If no Retry-After, look for Cache-Control max-age
306 F64 expires = 0.0;
307 if (LLAvatarNameCache::expirationFromCacheControl(mHeaders, &expires))
308 {
309 return expires;
310 }
311
312 // No information in header, make a guess
313 if (status == 503)
314 {
315 // ...service unavailable, retry soon
316 const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
317 return now + SERVICE_UNAVAILABLE_DELAY;
318 }
319 else
320 {
321 // ...other unexpected error
322 const F64 DEFAULT_DELAY = 3600.0; // 1 hour
323 return now + DEFAULT_DELAY;
324 }
325 }
326};
327
328void LLAvatarNameCache::processName(const LLUUID& agent_id,
329 const LLAvatarName& av_name,
330 bool add_to_cache)
331{
332 if (add_to_cache)
333 {
334 sCache[agent_id] = av_name;
335 }
336
337 sPendingQueue.erase(agent_id);
338
339 // signal everyone waiting on this name
340 signal_map_t::iterator sig_it = sSignalMap.find(agent_id);
341 if (sig_it != sSignalMap.end())
342 {
343 callback_signal_t* signal = sig_it->second;
344 (*signal)(agent_id, av_name);
345
346 sSignalMap.erase(agent_id);
347
348 delete signal;
349 signal = NULL;
350 }
351}
352
353void LLAvatarNameCache::requestNamesViaCapability()
354{
355 F64 now = LLFrameTimer::getTotalSeconds();
356
357 // URL format is like:
358 // http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0
359 //
360 // Apache can handle URLs of 4096 chars, but let's be conservative
361 const U32 NAME_URL_MAX = 4096;
362 const U32 NAME_URL_SEND_THRESHOLD = 3000;
363 std::string url;
364 url.reserve(NAME_URL_MAX);
365
366 std::vector<LLUUID> agent_ids;
367 agent_ids.reserve(128);
368
369 ask_queue_t::const_iterator it = sAskQueue.begin();
370 for ( ; it != sAskQueue.end(); ++it)
371 {
372 const LLUUID& agent_id = *it;
373
374 if (url.empty())
375 {
376 // ...starting new request
377 url += sNameLookupURL;
378 url += "?ids=";
379 }
380 else
381 {
382 // ...continuing existing request
383 url += "&ids=";
384 }
385 url += agent_id.asString();
386 agent_ids.push_back(agent_id);
387
388 // mark request as pending
389 sPendingQueue[agent_id] = now;
390
391 if (url.size() > NAME_URL_SEND_THRESHOLD)
392 {
393 //llinfos << "requestNames " << url << llendl;
394 LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
395 url.clear();
396 agent_ids.clear();
397 }
398 }
399
400 if (!url.empty())
401 {
402 //llinfos << "requestNames " << url << llendl;
403 LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
404 url.clear();
405 agent_ids.clear();
406 }
407
408 // We've moved all asks to the pending request queue
409 sAskQueue.clear();
410}
411
412void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
413 const std::string& first, const std::string& last,
414 BOOL is_group, void* data)
415{
416 std::string full_name = first + " " + last;
417 // Construct a dummy record for this name. By convention, SLID is blank
418 // Never expires, but not written to disk, so lasts until end of session.
419 LLAvatarName av_name;
420 buildLegacyName(full_name, &av_name);
421
422 // Don't add to cache, the data already exists in the legacy name system
423 // cache and we don't want or need duplicate storage, because keeping the
424 // two copies in sync is complex.
425 processName(agent_id, av_name, false);
426}
427
428void LLAvatarNameCache::requestNamesViaLegacy()
429{
430 F64 now = LLFrameTimer::getTotalSeconds();
431 std::string full_name;
432 ask_queue_t::const_iterator it = sAskQueue.begin();
433 for (; it != sAskQueue.end(); ++it)
434 {
435 const LLUUID& agent_id = *it;
436
437 // Mark as pending first, just in case the callback is immediately
438 // invoked below. This should never happen in practice.
439 sPendingQueue[agent_id] = now;
440
441 gCacheName->get(agent_id, false, legacyNameCallback);
442 }
443
444 // We've either answered immediately or moved all asks to the
445 // pending queue
446 sAskQueue.clear();
447}
448
449void LLAvatarNameCache::initClass(bool running)
450{
451 sRunning = running;
452}
453
454void LLAvatarNameCache::cleanupClass()
455{
456}
457
458void LLAvatarNameCache::importFile(std::istream& istr)
459{
460 LLSD data;
461 S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
462 if (parse_count < 1) return;
463
464 // by convention LLSD storage is a map
465 // we only store one entry in the map
466 LLSD agents = data["agents"];
467
468 LLUUID agent_id;
469 LLAvatarName av_name;
470 LLSD::map_const_iterator it = agents.beginMap();
471 for ( ; it != agents.endMap(); ++it)
472 {
473 agent_id.set(it->first);
474 av_name.fromLLSD( it->second );
475 sCache[agent_id] = av_name;
476 }
477 // entries may have expired since we last ran the viewer, just
478 // clean them out now
479 eraseExpired();
480 llinfos << "loaded " << sCache.size() << llendl;
481}
482
483void LLAvatarNameCache::exportFile(std::ostream& ostr)
484{
485 LLSD agents;
486 cache_t::const_iterator it = sCache.begin();
487 for ( ; it != sCache.end(); ++it)
488 {
489 const LLUUID& agent_id = it->first;
490 const LLAvatarName& av_name = it->second;
491 if (!av_name.mIsDummy)
492 {
493 // key must be a string
494 agents[agent_id.asString()] = av_name.asLLSD();
495 }
496 }
497 LLSD data;
498 data["agents"] = agents;
499 LLSDSerialize::toPrettyXML(data, ostr);
500}
501
502void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url)
503{
504 sNameLookupURL = name_lookup_url;
505}
506
507bool LLAvatarNameCache::hasNameLookupURL()
508{
509 return !sNameLookupURL.empty();
510}
511
512void LLAvatarNameCache::idle()
513{
514 // By convention, start running at first idle() call
515 sRunning = true;
516
517 // *TODO: Possibly re-enabled this based on People API load measurements
518 // 100 ms is the threshold for "user speed" operations, so we can
519 // stall for about that long to batch up requests.
520 //const F32 SECS_BETWEEN_REQUESTS = 0.1f;
521 //if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS))
522 //{
523 // return;
524 //}
525
526 // Must be large relative to above
527
528 // No longer deleting expired entries, just re-requesting in the get
529 // this way first synchronous get call on an expired entry won't return
530 // legacy name. LF
531
532 //const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
533 //if (sEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
534 //{
535 // eraseExpired();
536 //}
537
538 if (sAskQueue.empty())
539 {
540 return;
541 }
542
543 if (useDisplayNames())
544 {
545 requestNamesViaCapability();
546 }
547 else
548 {
549 // ...fall back to legacy name cache system
550 requestNamesViaLegacy();
551 }
552}
553
554bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)
555{
556 const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
557 F64 now = LLFrameTimer::getTotalSeconds();
558 F64 expire_time = now - PENDING_TIMEOUT_SECS;
559
560 pending_queue_t::const_iterator it = sPendingQueue.find(agent_id);
561 if (it != sPendingQueue.end())
562 {
563 bool request_expired = (it->second < expire_time);
564 return !request_expired;
565 }
566 return false;
567}
568
569void LLAvatarNameCache::eraseExpired()
570{
571 F64 now = LLFrameTimer::getTotalSeconds();
572 cache_t::iterator it = sCache.begin();
573 while (it != sCache.end())
574 {
575 cache_t::iterator cur = it;
576 ++it;
577 const LLAvatarName& av_name = cur->second;
578 if (av_name.mExpires < now)
579 {
580 sCache.erase(cur);
581 }
582 }
583}
584
585void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
586 LLAvatarName* av_name)
587{
588 llassert(av_name);
589 av_name->mUsername = "";
590 av_name->mDisplayName = full_name;
591 av_name->mIsDisplayNameDefault = true;
592 av_name->mIsDummy = true;
593 av_name->mExpires = F64_MAX;
594}
595
596// fills in av_name if it has it in the cache, even if expired (can check expiry time)
597// returns bool specifying if av_name was filled, false otherwise
598bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
599{
600 if (sRunning)
601 {
602 // ...only do immediate lookups when cache is running
603 if (useDisplayNames())
604 {
605 // ...use display names cache
606 std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
607 if (it != sCache.end())
608 {
609 *av_name = it->second;
610
611 // re-request name if entry is expired
612 if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
613 {
614 if (!isRequestPending(agent_id))
615 {
616 sAskQueue.insert(agent_id);
617 }
618 }
619
620 return true;
621 }
622 }
623 else
624 {
625 // ...use legacy names cache
626 std::string full_name;
627 if (gCacheName->getFullName(agent_id, full_name))
628 {
629 buildLegacyName(full_name, av_name);
630 return true;
631 }
632 }
633 }
634
635 if (!isRequestPending(agent_id))
636 {
637 sAskQueue.insert(agent_id);
638 }
639
640 return false;
641}
642
643void LLAvatarNameCache::fireSignal(const LLUUID& agent_id,
644 const callback_slot_t& slot,
645 const LLAvatarName& av_name)
646{
647 callback_signal_t signal;
648 signal.connect(slot);
649 signal(agent_id, av_name);
650}
651
652void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
653{
654 if (sRunning)
655 {
656 // ...only do immediate lookups when cache is running
657 if (useDisplayNames())
658 {
659 // ...use new cache
660 std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
661 if (it != sCache.end())
662 {
663 const LLAvatarName& av_name = it->second;
664
665 if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
666 {
667 // ...name already exists in cache, fire callback now
668 fireSignal(agent_id, slot, av_name);
669
670 return;
671 }
672 }
673 }
674 else
675 {
676 // ...use old name system
677 std::string full_name;
678 if (gCacheName->getFullName(agent_id, full_name))
679 {
680 LLAvatarName av_name;
681 buildLegacyName(full_name, &av_name);
682 fireSignal(agent_id, slot, av_name);
683 return;
684 }
685 }
686 }
687
688 // schedule a request
689 if (!isRequestPending(agent_id))
690 {
691 sAskQueue.insert(agent_id);
692 }
693
694 // always store additional callback, even if request is pending
695 signal_map_t::iterator sig_it = sSignalMap.find(agent_id);
696 if (sig_it == sSignalMap.end())
697 {
698 // ...new callback for this id
699 callback_signal_t* signal = new callback_signal_t();
700 signal->connect(slot);
701 sSignalMap[agent_id] = signal;
702 }
703 else
704 {
705 // ...existing callback, bind additional slot
706 callback_signal_t* signal = sig_it->second;
707 signal->connect(slot);
708 }
709}
710
711
712void LLAvatarNameCache::setUseDisplayNames(U32 use)
713{
714 if (use != sUseDisplayNames)
715 {
716 if (use > 2)
717 {
718 sUseDisplayNames = 2;
719 }
720 else
721 {
722 sUseDisplayNames = use;
723 }
724 // flush our cache
725 sCache.clear();
726
727 mUseDisplayNamesSignal();
728 }
729}
730
731U32 LLAvatarNameCache::useDisplayNames()
732{
733 // Must be both manually set on and able to look up names.
734 if (sNameLookupURL.empty())
735 {
736 return 0;
737 }
738 else
739 {
740 return sUseDisplayNames;
741 }
742}
743
744void LLAvatarNameCache::erase(const LLUUID& agent_id)
745{
746 sCache.erase(agent_id);
747}
748
749void LLAvatarNameCache::fetch(const LLUUID& agent_id)
750{
751 // re-request, even if request is already pending
752 sAskQueue.insert(agent_id);
753}
754
755void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name)
756{
757 // *TODO: update timestamp if zero?
758 sCache[agent_id] = av_name;
759}
760
761F64 LLAvatarNameCache::nameExpirationFromHeaders(LLSD headers)
762{
763 F64 expires = 0.0;
764 if (expirationFromCacheControl(headers, &expires))
765 {
766 return expires;
767 }
768 else
769 {
770 // With no expiration info, default to an hour
771 const F64 DEFAULT_EXPIRES = 60.0 * 60.0;
772 F64 now = LLFrameTimer::getTotalSeconds();
773 return now + DEFAULT_EXPIRES;
774 }
775}
776
777bool LLAvatarNameCache::expirationFromCacheControl(LLSD headers, F64 *expires)
778{
779 // Allow the header to override the default
780 LLSD cache_control_header = headers["cache-control"];
781 if (cache_control_header.isDefined())
782 {
783 S32 max_age = 0;
784 std::string cache_control = cache_control_header.asString();
785 if (max_age_from_cache_control(cache_control, &max_age))
786 {
787 F64 now = LLFrameTimer::getTotalSeconds();
788 *expires = now + (F64)max_age;
789 return true;
790 }
791 }
792 return false;
793}
794
795
796void LLAvatarNameCache::addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb)
797{
798 mUseDisplayNamesSignal.connect(cb);
799}
800
801
802static const std::string MAX_AGE("max-age");
803static const boost::char_separator<char> EQUALS_SEPARATOR("=");
804static const boost::char_separator<char> COMMA_SEPARATOR(",");
805
806bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age)
807{
808 // Split the string on "," to get a list of directives
809 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
810 tokenizer directives(cache_control, COMMA_SEPARATOR);
811
812 tokenizer::iterator token_it = directives.begin();
813 for ( ; token_it != directives.end(); ++token_it)
814 {
815 // Tokens may have leading or trailing whitespace
816 std::string token = *token_it;
817 LLStringUtil::trim(token);
818
819 if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0)
820 {
821 // ...this token starts with max-age, so let's chop it up by "="
822 tokenizer subtokens(token, EQUALS_SEPARATOR);
823 tokenizer::iterator subtoken_it = subtokens.begin();
824
825 // Must have a token
826 if (subtoken_it == subtokens.end()) return false;
827 std::string subtoken = *subtoken_it;
828
829 // Must exactly equal "max-age"
830 LLStringUtil::trim(subtoken);
831 if (subtoken != MAX_AGE) return false;
832
833 // Must have another token
834 ++subtoken_it;
835 if (subtoken_it == subtokens.end()) return false;
836 subtoken = *subtoken_it;
837
838 // Must be a valid integer
839 // *NOTE: atoi() returns 0 for invalid values, so we have to
840 // check the string first.
841 // *TODO: Do servers ever send "0000" for zero? We don't handle it
842 LLStringUtil::trim(subtoken);
843 if (subtoken == "0")
844 {
845 *max_age = 0;
846 return true;
847 }
848 S32 val = atoi( subtoken.c_str() );
849 if (val > 0 && val < S32_MAX)
850 {
851 *max_age = val;
852 return true;
853 }
854 return false;
855 }
856 }
857 return false;
858}
859
diff --git a/linden/indra/llmessage/llavatarnamecache.h b/linden/indra/llmessage/llavatarnamecache.h
new file mode 100644
index 0000000..a2519cd
--- /dev/null
+++ b/linden/indra/llmessage/llavatarnamecache.h
@@ -0,0 +1,105 @@
1/**
2 * @file llavatarnamecache.h
3 * @brief Provides lookup of avatar SLIDs ("bobsmith123") and display names
4 * ("James Cook") from avatar UUIDs.
5 *
6 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
7 * Second Life Viewer Source Code
8 * Copyright (C) 2010, Linden Research, Inc.
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation;
13 * version 2.1 of the License only.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *
24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
25 * $/LicenseInfo$
26 */
27
28#ifndef LLAVATARNAMECACHE_H
29#define LLAVATARNAMECACHE_H
30
31#include "llavatarname.h" // for convenience
32
33#include <boost/signals2.hpp>
34
35// We have display names support (this is for use by patches)
36#define LL_DISPLAY_NAMES
37
38class LLSD;
39class LLUUID;
40
41namespace LLAvatarNameCache
42{
43
44 typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
45
46 // Until the cache is set running, immediate lookups will fail and
47 // async lookups will be queued. This allows us to block requests
48 // until we know if the first region supports display names.
49 void initClass(bool running);
50 void cleanupClass();
51
52 void importFile(std::istream& istr);
53 void exportFile(std::ostream& ostr);
54
55 // On the viewer, usually a simulator capabilitity
56 // If empty, name cache will fall back to using legacy name
57 // lookup system
58 void setNameLookupURL(const std::string& name_lookup_url);
59
60 // Do we have a valid lookup URL, hence are we trying to use the
61 // new display name lookup system?
62 bool hasNameLookupURL();
63
64 // Periodically makes a batch request for display names not already in
65 // cache. Call once per frame.
66 void idle();
67
68 // If name is in cache, returns true and fills in provided LLAvatarName
69 // otherwise returns false
70 bool get(const LLUUID& agent_id, LLAvatarName *av_name);
71
72 // Callback types for get() below
73 typedef boost::signals2::signal<
74 void (const LLUUID& agent_id, const LLAvatarName& av_name)>
75 callback_signal_t;
76 typedef callback_signal_t::slot_type callback_slot_t;
77
78 // Fetches name information and calls callback.
79 // If name information is in cache, callback will be called immediately.
80 void get(const LLUUID& agent_id, callback_slot_t slot);
81
82 void setUseDisplayNames(U32 use);
83 U32 useDisplayNames();
84
85 void erase(const LLUUID& agent_id);
86
87 // Force a re-fetch of the most recent data, but keep the current
88 // data in cache
89 void fetch(const LLUUID& agent_id);
90
91 void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
92
93 // Compute name expiration time from HTTP Cache-Control header,
94 // or return default value, in seconds from epoch.
95 F64 nameExpirationFromHeaders(LLSD headers);
96
97 void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
98}
99
100// Parse a cache-control header to get the max-age delta-seconds.
101// Returns true if header has max-age param and it parses correctly.
102// Exported here to ease unit testing.
103bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age);
104
105#endif
diff --git a/linden/indra/llmessage/llcachename.h b/linden/indra/llmessage/llcachename.h
index 2757b86..cb3cc1f 100644
--- a/linden/indra/llmessage/llcachename.h
+++ b/linden/indra/llmessage/llcachename.h
@@ -33,6 +33,8 @@
33#ifndef LL_LLCACHENAME_H 33#ifndef LL_LLCACHENAME_H
34#define LL_LLCACHENAME_H 34#define LL_LLCACHENAME_H
35 35
36#include "llavatarnamecache.h" // for convenience
37
36class LLMessageSystem; 38class LLMessageSystem;
37class LLHost; 39class LLHost;
38class LLUUID; 40class LLUUID;
diff --git a/linden/indra/llmessage/llcurl.cpp b/linden/indra/llmessage/llcurl.cpp
index 202332c..9ecfee4 100644
--- a/linden/indra/llmessage/llcurl.cpp
+++ b/linden/indra/llmessage/llcurl.cpp
@@ -1020,7 +1020,7 @@ void LLCurl::initClass()
1020 S32 mutex_count = CRYPTO_num_locks(); 1020 S32 mutex_count = CRYPTO_num_locks();
1021 for (S32 i=0; i<mutex_count; i++) 1021 for (S32 i=0; i<mutex_count; i++)
1022 { 1022 {
1023 sSSLMutex.push_back(new LLMutex(NULL)); 1023 sSSLMutex.push_back(new LLMutex);
1024 } 1024 }
1025 CRYPTO_set_id_callback(&LLCurl::ssl_thread_id); 1025 CRYPTO_set_id_callback(&LLCurl::ssl_thread_id);
1026 CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback); 1026 CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback);
diff --git a/linden/indra/llmessage/lliohttpserver.cpp b/linden/indra/llmessage/lliohttpserver.cpp
index 83dfa94..8ad052b 100644
--- a/linden/indra/llmessage/lliohttpserver.cpp
+++ b/linden/indra/llmessage/lliohttpserver.cpp
@@ -948,13 +948,9 @@ private:
948 948
949 949
950// static 950// static
951LLHTTPNode& LLIOHTTPServer::create( 951LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port)
952 apr_pool_t* pool, LLPumpIO& pump, U16 port)
953{ 952{
954 LLSocket::ptr_t socket = LLSocket::create( 953 LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP, port);
955 pool,
956 LLSocket::STREAM_TCP,
957 port);
958 if(!socket) 954 if(!socket)
959 { 955 {
960 llerrs << "Unable to initialize socket" << llendl; 956 llerrs << "Unable to initialize socket" << llendl;
@@ -963,7 +959,7 @@ LLHTTPNode& LLIOHTTPServer::create(
963 LLHTTPResponseFactory* factory = new LLHTTPResponseFactory; 959 LLHTTPResponseFactory* factory = new LLHTTPResponseFactory;
964 boost::shared_ptr<LLChainIOFactory> factory_ptr(factory); 960 boost::shared_ptr<LLChainIOFactory> factory_ptr(factory);
965 961
966 LLIOServerSocket* server = new LLIOServerSocket(pool, socket, factory_ptr); 962 LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr);
967 963
968 LLPumpIO::chain_t chain; 964 LLPumpIO::chain_t chain;
969 chain.push_back(LLIOPipe::ptr_t(server)); 965 chain.push_back(LLIOPipe::ptr_t(server));
diff --git a/linden/indra/llmessage/lliohttpserver.h b/linden/indra/llmessage/lliohttpserver.h
index d1c9bdd..d2a8e2a 100644
--- a/linden/indra/llmessage/lliohttpserver.h
+++ b/linden/indra/llmessage/lliohttpserver.h
@@ -57,7 +57,7 @@ class LLIOHTTPServer
57public: 57public:
58 typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data); 58 typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data);
59 59
60 static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port); 60 static LLHTTPNode& create(LLPumpIO& pump, U16 port);
61 /**< Creates an HTTP wire server on the pump for the given TCP port. 61 /**< Creates an HTTP wire server on the pump for the given TCP port.
62 * 62 *
63 * Returns the root node of the new server. Add LLHTTPNode instances 63 * Returns the root node of the new server. Add LLHTTPNode instances
diff --git a/linden/indra/llmessage/lliosocket.cpp b/linden/indra/llmessage/lliosocket.cpp
index 7ec577c..686c037 100644
--- a/linden/indra/llmessage/lliosocket.cpp
+++ b/linden/indra/llmessage/lliosocket.cpp
@@ -41,6 +41,7 @@
41#include "llhost.h" 41#include "llhost.h"
42#include "llmemtype.h" 42#include "llmemtype.h"
43#include "llpumpio.h" 43#include "llpumpio.h"
44#include "llthread.h"
44 45
45// 46//
46// constants 47// constants
@@ -104,51 +105,31 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock)
104/// 105///
105 106
106// static 107// static
107LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) 108LLSocket::ptr_t LLSocket::create(EType type, U16 port)
108{ 109{
109 LLMemType m1(LLMemType::MTYPE_IO_TCP); 110 LLMemType m1(LLMemType::MTYPE_IO_TCP);
110 LLSocket::ptr_t rv;
111 apr_socket_t* socket = NULL;
112 apr_pool_t* new_pool = NULL;
113 apr_status_t status = APR_EGENERAL; 111 apr_status_t status = APR_EGENERAL;
114 112 LLSocket::ptr_t rv(new LLSocket);
115 // create a pool for the socket
116 status = apr_pool_create(&new_pool, pool);
117 if(ll_apr_warn_status(status))
118 {
119 if(new_pool) apr_pool_destroy(new_pool);
120 return rv;
121 }
122 113
123 if(STREAM_TCP == type) 114 if(STREAM_TCP == type)
124 { 115 {
125 status = apr_socket_create( 116 status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool());
126 &socket,
127 APR_INET,
128 SOCK_STREAM,
129 APR_PROTO_TCP,
130 new_pool);
131 } 117 }
132 else if(DATAGRAM_UDP == type) 118 else if(DATAGRAM_UDP == type)
133 { 119 {
134 status = apr_socket_create( 120 status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool());
135 &socket,
136 APR_INET,
137 SOCK_DGRAM,
138 APR_PROTO_UDP,
139 new_pool);
140 } 121 }
141 else 122 else
142 { 123 {
143 if(new_pool) apr_pool_destroy(new_pool); 124 rv.reset();
144 return rv; 125 return rv;
145 } 126 }
146 if(ll_apr_warn_status(status)) 127 if(ll_apr_warn_status(status))
147 { 128 {
148 if(new_pool) apr_pool_destroy(new_pool); 129 rv->mSocket = NULL;
130 rv.reset();
149 return rv; 131 return rv;
150 } 132 }
151 rv = ptr_t(new LLSocket(socket, new_pool));
152 if(port > 0) 133 if(port > 0)
153 { 134 {
154 apr_sockaddr_t* sa = NULL; 135 apr_sockaddr_t* sa = NULL;
@@ -158,7 +139,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
158 APR_UNSPEC, 139 APR_UNSPEC,
159 port, 140 port,
160 0, 141 0,
161 new_pool); 142 rv->mPool());
162 if(ll_apr_warn_status(status)) 143 if(ll_apr_warn_status(status))
163 { 144 {
164 rv.reset(); 145 rv.reset();
@@ -166,8 +147,8 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
166 } 147 }
167 // This allows us to reuse the address on quick down/up. This 148 // This allows us to reuse the address on quick down/up. This
168 // is unlikely to create problems. 149 // is unlikely to create problems.
169 ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); 150 ll_apr_warn_status(apr_socket_opt_set(rv->mSocket, APR_SO_REUSEADDR, 1));
170 status = apr_socket_bind(socket, sa); 151 status = apr_socket_bind(rv->mSocket, sa);
171 if(ll_apr_warn_status(status)) 152 if(ll_apr_warn_status(status))
172 { 153 {
173 rv.reset(); 154 rv.reset();
@@ -181,7 +162,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
181 // to keep a queue of incoming connections for ACCEPT. 162 // to keep a queue of incoming connections for ACCEPT.
182 lldebugs << "Setting listen state for socket." << llendl; 163 lldebugs << "Setting listen state for socket." << llendl;
183 status = apr_socket_listen( 164 status = apr_socket_listen(
184 socket, 165 rv->mSocket,
185 LL_DEFAULT_LISTEN_BACKLOG); 166 LL_DEFAULT_LISTEN_BACKLOG);
186 if(ll_apr_warn_status(status)) 167 if(ll_apr_warn_status(status))
187 { 168 {
@@ -202,21 +183,28 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
202} 183}
203 184
204// static 185// static
205LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool) 186LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket)
206{ 187{
207 LLMemType m1(LLMemType::MTYPE_IO_TCP); 188 LLMemType m1(LLMemType::MTYPE_IO_TCP);
208 LLSocket::ptr_t rv; 189 if (!listen_socket->getSocket())
209 if(!socket) 190 {
191 status = APR_ENOSOCKET;
192 return LLSocket::ptr_t();
193 }
194 LLSocket::ptr_t rv(new LLSocket);
195 lldebugs << "accepting socket" << llendl;
196 status = apr_socket_accept(&rv->mSocket, listen_socket->getSocket(), rv->mPool());
197 if (status != APR_SUCCESS)
210 { 198 {
199 rv->mSocket = NULL;
200 rv.reset();
211 return rv; 201 return rv;
212 } 202 }
213 rv = ptr_t(new LLSocket(socket, pool));
214 rv->mPort = PORT_EPHEMERAL; 203 rv->mPort = PORT_EPHEMERAL;
215 rv->setOptions(); 204 rv->setOptions();
216 return rv; 205 return rv;
217} 206}
218 207
219
220bool LLSocket::blockingConnect(const LLHost& host) 208bool LLSocket::blockingConnect(const LLHost& host)
221{ 209{
222 if(!mSocket) return false; 210 if(!mSocket) return false;
@@ -229,7 +217,7 @@ bool LLSocket::blockingConnect(const LLHost& host)
229 APR_UNSPEC, 217 APR_UNSPEC,
230 host.getPort(), 218 host.getPort(),
231 0, 219 0,
232 mPool))) 220 mPool())))
233 { 221 {
234 return false; 222 return false;
235 } 223 }
@@ -240,13 +228,11 @@ bool LLSocket::blockingConnect(const LLHost& host)
240 return true; 228 return true;
241} 229}
242 230
243LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) : 231LLSocket::LLSocket() :
244 mSocket(socket), 232 mSocket(NULL),
245 mPool(pool), 233 mPool(LLThread::tldata().mRootPool),
246 mPort(PORT_INVALID) 234 mPort(PORT_INVALID)
247{ 235{
248 ll_debug_socket("Constructing wholely formed socket", mSocket);
249 LLMemType m1(LLMemType::MTYPE_IO_TCP);
250} 236}
251 237
252LLSocket::~LLSocket() 238LLSocket::~LLSocket()
@@ -258,10 +244,6 @@ LLSocket::~LLSocket()
258 ll_debug_socket("Destroying socket", mSocket); 244 ll_debug_socket("Destroying socket", mSocket);
259 apr_socket_close(mSocket); 245 apr_socket_close(mSocket);
260 } 246 }
261 if(mPool)
262 {
263 apr_pool_destroy(mPool);
264 }
265} 247}
266 248
267void LLSocket::setOptions() 249void LLSocket::setOptions()
@@ -522,10 +504,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
522/// 504///
523 505
524LLIOServerSocket::LLIOServerSocket( 506LLIOServerSocket::LLIOServerSocket(
525 apr_pool_t* pool,
526 LLIOServerSocket::socket_t listener, 507 LLIOServerSocket::socket_t listener,
527 factory_t factory) : 508 factory_t factory) :
528 mPool(pool),
529 mListenSocket(listener), 509 mListenSocket(listener),
530 mReactor(factory), 510 mReactor(factory),
531 mInitialized(false), 511 mInitialized(false),
@@ -585,21 +565,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
585 lldebugs << "accepting socket" << llendl; 565 lldebugs << "accepting socket" << llendl;
586 566
587 PUMP_DEBUG; 567 PUMP_DEBUG;
588 apr_pool_t* new_pool = NULL; 568 apr_status_t status;
589 apr_status_t status = apr_pool_create(&new_pool, mPool); 569 LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket));
590 apr_socket_t* socket = NULL;
591 status = apr_socket_accept(
592 &socket,
593 mListenSocket->getSocket(),
594 new_pool);
595 LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool));
596 //EStatus rv = STATUS_ERROR; 570 //EStatus rv = STATUS_ERROR;
597 if(llsocket) 571 if(llsocket && status == APR_SUCCESS)
598 { 572 {
599 PUMP_DEBUG; 573 PUMP_DEBUG;
600 574
601 apr_sockaddr_t* remote_addr; 575 apr_sockaddr_t* remote_addr;
602 apr_socket_addr_get(&remote_addr, APR_REMOTE, socket); 576 apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket());
603 577
604 char* remote_host_string; 578 char* remote_host_string;
605 apr_sockaddr_ip_get(&remote_host_string, remote_addr); 579 apr_sockaddr_ip_get(&remote_host_string, remote_addr);
@@ -614,7 +588,6 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
614 { 588 {
615 chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); 589 chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));
616 pump->addChain(chain, mResponseTimeout); 590 pump->addChain(chain, mResponseTimeout);
617 status = STATUS_OK;
618 } 591 }
619 else 592 else
620 { 593 {
@@ -623,7 +596,8 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
623 } 596 }
624 else 597 else
625 { 598 {
626 llwarns << "Unable to create linden socket." << llendl; 599 char buf[256];
600 llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl;
627 } 601 }
628 602
629 PUMP_DEBUG; 603 PUMP_DEBUG;
@@ -636,11 +610,10 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
636#if 0 610#if 0
637LLIODataSocket::LLIODataSocket( 611LLIODataSocket::LLIODataSocket(
638 U16 suggested_port, 612 U16 suggested_port,
639 U16 start_discovery_port, 613 U16 start_discovery_port) :
640 apr_pool_t* pool) :
641 mSocket(NULL) 614 mSocket(NULL)
642{ 615{
643 if(!pool || (PORT_INVALID == suggested_port)) return; 616 if(PORT_INVALID == suggested_port) return;
644 if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return; 617 if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return;
645 apr_sockaddr_t* sa = NULL; 618 apr_sockaddr_t* sa = NULL;
646 if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return; 619 if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return;
diff --git a/linden/indra/llmessage/lliosocket.h b/linden/indra/llmessage/lliosocket.h
index ec09ad8..5ad75e9 100644
--- a/linden/indra/llmessage/lliosocket.h
+++ b/linden/indra/llmessage/lliosocket.h
@@ -44,7 +44,6 @@
44 */ 44 */
45 45
46#include "lliopipe.h" 46#include "lliopipe.h"
47#include "apr_pools.h"
48#include "apr_network_io.h" 47#include "apr_network_io.h"
49#include "llchainio.h" 48#include "llchainio.h"
50 49
@@ -94,34 +93,22 @@ public:
94 * socket. If you intend the socket to be known to external 93 * socket. If you intend the socket to be known to external
95 * clients without prior port notification, do not use 94 * clients without prior port notification, do not use
96 * PORT_EPHEMERAL. 95 * PORT_EPHEMERAL.
97 * @param pool The apr pool to use. A child pool will be created
98 * and associated with the socket.
99 * @param type The type of socket to create 96 * @param type The type of socket to create
100 * @param port The port for the socket 97 * @param port The port for the socket
101 * @return A valid socket shared pointer if the call worked. 98 * @return A valid socket shared pointer if the call worked.
102 */ 99 */
103 static ptr_t create( 100 static ptr_t create(
104 apr_pool_t* pool,
105 EType type, 101 EType type,
106 U16 port = PORT_EPHEMERAL); 102 U16 port = PORT_EPHEMERAL);
107 103
108 /** 104 /**
109 * @brief Create a LLSocket when you already have an apr socket. 105 * @brief Create a LLSocket by accepting a connection from a listen socket.
110 * 106 *
111 * This method assumes an ephemeral port. This is typically used 107 * @param status Output. Status of the accept if a valid listen socket was passed.
112 * by calls which spawn a socket such as a call to 108 * @param listen_socket The listen socket to use.
113 * <code>accept()</code> as in the server socket. This call should
114 * not fail if you have a valid apr socket.
115 * Because of the nature of how accept() works, you are expected
116 * to create a new pool for the socket, use that pool for the
117 * accept, and pass it in here where it will be bound with the
118 * socket and destroyed at the same time.
119 * @param socket The apr socket to use
120 * @param pool The pool used to create the socket. *NOTE: The pool
121 * passed in will be DESTROYED.
122 * @return A valid socket shared pointer if the call worked. 109 * @return A valid socket shared pointer if the call worked.
123 */ 110 */
124 static ptr_t create(apr_socket_t* socket, apr_pool_t* pool); 111 static ptr_t create(apr_status_t& status, ptr_t& listen_socket);
125 112
126 /** 113 /**
127 * @brief Perform a blocking connect to a host. Do not use in production. 114 * @brief Perform a blocking connect to a host. Do not use in production.
@@ -156,7 +143,7 @@ protected:
156 * @brief Protected constructor since should only make sockets 143 * @brief Protected constructor since should only make sockets
157 * with one of the two <code>create()</code> calls. 144 * with one of the two <code>create()</code> calls.
158 */ 145 */
159 LLSocket(apr_socket_t* socket, apr_pool_t* pool); 146 LLSocket(void);
160 147
161 /** 148 /**
162 * @brief Set default socket options. 149 * @brief Set default socket options.
@@ -173,8 +160,8 @@ protected:
173 // The apr socket. 160 // The apr socket.
174 apr_socket_t* mSocket; 161 apr_socket_t* mSocket;
175 162
176 // our memory pool 163 // Our memory pool.
177 apr_pool_t* mPool; 164 AIAPRPool mPool;
178 165
179 // The port if we know it. 166 // The port if we know it.
180 U16 mPort; 167 U16 mPort;
@@ -299,7 +286,7 @@ class LLIOServerSocket : public LLIOPipe
299public: 286public:
300 typedef LLSocket::ptr_t socket_t; 287 typedef LLSocket::ptr_t socket_t;
301 typedef boost::shared_ptr<LLChainIOFactory> factory_t; 288 typedef boost::shared_ptr<LLChainIOFactory> factory_t;
302 LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor); 289 LLIOServerSocket(socket_t listener, factory_t reactor);
303 virtual ~LLIOServerSocket(); 290 virtual ~LLIOServerSocket();
304 291
305 /** 292 /**
@@ -331,7 +318,6 @@ protected:
331 //@} 318 //@}
332 319
333protected: 320protected:
334 apr_pool_t* mPool;
335 socket_t mListenSocket; 321 socket_t mListenSocket;
336 factory_t mReactor; 322 factory_t mReactor;
337 bool mInitialized; 323 bool mInitialized;
@@ -365,8 +351,7 @@ public:
365 */ 351 */
366 LLIODataSocket( 352 LLIODataSocket(
367 U16 suggested_port, 353 U16 suggested_port,
368 U16 start_discovery_port, 354 U16 start_discovery_port);
369 apr_pool_t* pool);
370 virtual ~LLIODataSocket(); 355 virtual ~LLIODataSocket();
371 356
372protected: 357protected:
diff --git a/linden/indra/llmessage/llmail.cpp b/linden/indra/llmessage/llmail.cpp
index d52ff6c..8850e29 100644
--- a/linden/indra/llmessage/llmail.cpp
+++ b/linden/indra/llmessage/llmail.cpp
@@ -56,6 +56,7 @@
56#include "llstring.h" 56#include "llstring.h"
57#include "lluuid.h" 57#include "lluuid.h"
58#include "net.h" 58#include "net.h"
59#include "aiaprpool.h"
59 60
60// 61//
61// constants 62// constants
@@ -63,7 +64,7 @@
63const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096; 64const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;
64 65
65static bool gMailEnabled = true; 66static bool gMailEnabled = true;
66static apr_pool_t* gMailPool; 67static AIAPRPool gMailPool;
67static apr_sockaddr_t* gSockAddr; 68static apr_sockaddr_t* gSockAddr;
68static apr_socket_t* gMailSocket; 69static apr_socket_t* gMailSocket;
69 70
@@ -88,7 +89,7 @@ bool connect_smtp()
88 gSockAddr->sa.sin.sin_family, 89 gSockAddr->sa.sin.sin_family,
89 SOCK_STREAM, 90 SOCK_STREAM,
90 APR_PROTO_TCP, 91 APR_PROTO_TCP,
91 gMailPool); 92 gMailPool());
92 if(ll_apr_warn_status(status)) return false; 93 if(ll_apr_warn_status(status)) return false;
93 status = apr_socket_connect(gMailSocket, gSockAddr); 94 status = apr_socket_connect(gMailSocket, gSockAddr);
94 if(ll_apr_warn_status(status)) 95 if(ll_apr_warn_status(status))
@@ -145,19 +146,19 @@ BOOL LLMail::send(
145} 146}
146 147
147// static 148// static
148void LLMail::init(const std::string& hostname, apr_pool_t* pool) 149void LLMail::init(const std::string& hostname)
149{ 150{
150 gMailSocket = NULL; 151 gMailSocket = NULL;
151 if(hostname.empty() || !pool) 152 if (hostname.empty())
152 { 153 {
153 gMailPool = NULL;
154 gSockAddr = NULL; 154 gSockAddr = NULL;
155 gMailPool.destroy();
155 } 156 }
156 else 157 else
157 { 158 {
158 gMailPool = pool; 159 gMailPool.create();
159 160
160 // collect all the information into a socaddr sturcture. the 161 // Collect all the information into a sockaddr structure. the
161 // documentation is a bit unclear, but I either have to 162 // documentation is a bit unclear, but I either have to
162 // specify APR_UNSPEC or not specify any flags. I am not sure 163 // specify APR_UNSPEC or not specify any flags. I am not sure
163 // which option is better. 164 // which option is better.
@@ -167,7 +168,7 @@ void LLMail::init(const std::string& hostname, apr_pool_t* pool)
167 APR_UNSPEC, 168 APR_UNSPEC,
168 25, 169 25,
169 APR_IPV4_ADDR_OK, 170 APR_IPV4_ADDR_OK,
170 gMailPool); 171 gMailPool());
171 ll_apr_warn_status(status); 172 ll_apr_warn_status(status);
172 } 173 }
173} 174}
diff --git a/linden/indra/llmessage/llmail.h b/linden/indra/llmessage/llmail.h
index 7effb84..7026d93 100644
--- a/linden/indra/llmessage/llmail.h
+++ b/linden/indra/llmessage/llmail.h
@@ -33,15 +33,13 @@
33#ifndef LL_LLMAIL_H 33#ifndef LL_LLMAIL_H
34#define LL_LLMAIL_H 34#define LL_LLMAIL_H
35 35
36typedef struct apr_pool_t apr_pool_t;
37
38#include "llsd.h" 36#include "llsd.h"
39 37
40class LLMail 38class LLMail
41{ 39{
42public: 40public:
43 // if hostname is NULL, then the host is resolved as 'mail' 41 // if hostname is NULL, then the host is resolved as 'mail'
44 static void init(const std::string& hostname, apr_pool_t* pool); 42 static void init(const std::string& hostname);
45 43
46 // Allow all email transmission to be disabled/enabled. 44 // Allow all email transmission to be disabled/enabled.
47 static void enable(bool mail_enabled); 45 static void enable(bool mail_enabled);
diff --git a/linden/indra/llmessage/llpartdata.cpp b/linden/indra/llmessage/llpartdata.cpp
index 485bc6a..a2811ab 100644
--- a/linden/indra/llmessage/llpartdata.cpp
+++ b/linden/indra/llmessage/llpartdata.cpp
@@ -347,3 +347,93 @@ void LLPartSysData::setPartAccel(const LLVector3 &accel)
347 mPartAccel.mV[VY] = llclamp(accel.mV[VY], -100.f, 100.f); 347 mPartAccel.mV[VY] = llclamp(accel.mV[VY], -100.f, 100.f);
348 mPartAccel.mV[VZ] = llclamp(accel.mV[VZ], -100.f, 100.f); 348 mPartAccel.mV[VZ] = llclamp(accel.mV[VZ], -100.f, 100.f);
349} 349}
350
351LLSD LLPartSysData::asLLSD() const
352{
353 LLSD sd = LLSD();
354
355 sd["LL_PART_INTERP_COLOR_MASK"] = (LLPartData::LL_PART_INTERP_COLOR_MASK & mPartData.mFlags) ? 1 : 0;
356 sd["LL_PART_INTERP_SCALE_MASK"] = (LLPartData::LL_PART_INTERP_SCALE_MASK & mPartData.mFlags) ? 1 : 0;
357 sd["LL_PART_BOUNCE_MASK"] = (LLPartData::LL_PART_BOUNCE_MASK & mPartData.mFlags) ? 1 : 0;
358 sd["LL_PART_WIND_MASK"] = (LLPartData::LL_PART_WIND_MASK & mPartData.mFlags) ? 1 : 0;
359 sd["LL_PART_FOLLOW_SRC_MASK"] = (LLPartData::LL_PART_FOLLOW_SRC_MASK & mPartData.mFlags) ? 1 : 0;
360 sd["LL_PART_FOLLOW_VELOCITY_MASK"] = (LLPartData::LL_PART_FOLLOW_VELOCITY_MASK & mPartData.mFlags) ? 1 : 0;
361 sd["LL_PART_TARGET_POS_MASK"] = (LLPartData::LL_PART_TARGET_POS_MASK & mPartData.mFlags) ? 1 : 0;
362 sd["LL_PART_TARGET_LINEAR_MASK"] = (LLPartData::LL_PART_TARGET_LINEAR_MASK & mPartData.mFlags) ? 1 : 0;
363 sd["LL_PART_EMISSIVE_MASK"] = (LLPartData::LL_PART_EMISSIVE_MASK & mPartData.mFlags) ? 1 : 0;
364 sd["LL_PART_BEAM_MASK"] = (LLPartData::LL_PART_BEAM_MASK & mPartData.mFlags) ? 1 : 0;
365
366 sd["SourceMaxage"] = mPartData.mMaxAge;
367 sd["Startcolor"] = ll_sd_from_color4(mPartData.mStartColor);
368 sd["Endcolor"] = ll_sd_from_color4(mPartData.mEndColor);
369 sd["Startscale"] = ll_sd_from_vector2(mPartData.mStartScale);
370 sd["Endscale"] = ll_sd_from_vector2(mPartData.mEndScale);
371
372 sd["ParticleMaxAge"] = mMaxAge;
373 sd["ParticleStartAge"] = mStartAge;
374
375
376 sd["LL_PART_SRC_PATTERN_DROP"] = ( mPattern & LL_PART_SRC_PATTERN_DROP) ? 1 : 0;
377 sd["LL_PART_SRC_PATTERN_EXPLODE"] = ( mPattern & LL_PART_SRC_PATTERN_EXPLODE) ? 1 : 0;
378 sd["LL_PART_SRC_PATTERN_ANGLE"] = ( mPattern & LL_PART_SRC_PATTERN_ANGLE) ? 1 : 0;
379 sd["LL_PART_SRC_PATTERN_ANGLE_CONE"] = ( mPattern & LL_PART_SRC_PATTERN_ANGLE_CONE) ? 1 : 0 ;
380 sd["LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY"] = ( mPattern & LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY) ? 1 : 0;
381
382 sd["InnerAngle"] = mInnerAngle;
383 sd["OuterAngle"] = mOuterAngle;
384 sd["AngularVelocity"] = ll_sd_from_vector3(mAngularVelocity);
385 sd["BurstRate"] = mBurstRate;
386 sd["BurstPartCount"] = mBurstPartCount;
387 sd["BurstSpeedMin"] = mBurstSpeedMin;
388 sd["BurstSpeedMax"] = mBurstSpeedMax;
389 sd["BurstRadius"] = mBurstRadius;
390 sd["PartImageID"] = mPartImageID.asString();
391 sd["TargetId"] = mTargetUUID.asString();
392 return sd;
393}
394
395bool LLPartSysData::fromLLSD(LLSD& sd)
396{
397 mPartData.mFlags = 0;
398 if (sd["LL_PART_INTERP_COLOR_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_INTERP_COLOR_MASK;
399 if (sd["LL_PART_INTERP_SCALE_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_INTERP_SCALE_MASK;
400 if (sd["LL_PART_BOUNCE_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_BOUNCE_MASK;
401 if (sd["LL_PART_WIND_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_WIND_MASK;
402 if (sd["LL_PART_FOLLOW_SRC_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_FOLLOW_SRC_MASK;
403 if (sd["LL_PART_FOLLOW_VELOCITY_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_FOLLOW_VELOCITY_MASK;
404 if (sd["LL_PART_TARGET_POS_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_TARGET_POS_MASK;
405 if (sd["LL_PART_TARGET_LINEAR_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_TARGET_LINEAR_MASK;
406 if (sd["LL_PART_EMISSIVE_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_EMISSIVE_MASK;
407 if (sd["LL_PART_BEAM_MASK"]) mPartData.mFlags |= LLPartData::LL_PART_BEAM_MASK;
408
409 mPartData.mMaxAge = (F32)sd["SourceMaxage"].asReal();
410 mPartData.mStartColor = ll_color4_from_sd(sd["Startcolor"]);
411 mPartData.mEndColor = ll_color4_from_sd(sd["Endcolor"]);
412 mPartData.mStartScale = ll_vector2_from_sd(sd["Startscale"]);
413 mPartData.mEndScale = ll_vector2_from_sd(sd["Endscale"]);
414
415 mMaxAge = (F32)sd["ParticleMaxAge"].asReal();
416 mStartAge = (F32)sd["ParticleStartAge"].asReal();
417
418 mPattern = 0;
419 if (sd["LL_PART_SRC_PATTERN_DROP"]) mPattern |= LL_PART_SRC_PATTERN_DROP;
420 if (sd["LL_PART_SRC_PATTERN_EXPLODE"]) mPattern |= LL_PART_SRC_PATTERN_EXPLODE;
421 if (sd["LL_PART_SRC_PATTERN_ANGLE"]) mPattern |= LL_PART_SRC_PATTERN_ANGLE;
422 if (sd["LL_PART_SRC_PATTERN_ANGLE_CONE"]) mPattern |= LL_PART_SRC_PATTERN_ANGLE_CONE;
423 if (sd["LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY"]) mPattern |= LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY;
424
425 mInnerAngle = (F32)sd["InnerAngle"].asReal();
426 mOuterAngle = (F32)sd["OuterAngle"].asReal();
427 mAngularVelocity = ll_vector3_from_sd(sd["AngularVelocity"]);
428 mBurstRate = (F32)sd["BurstRate"].asReal();
429 int burst_part_count = sd["BurstPartCount"];
430 mBurstPartCount = (U8)burst_part_count;
431 mBurstSpeedMin = (F32)sd["BurstSpeedMin"].asReal();
432 mBurstSpeedMax = (F32)sd["BurstSpeedMax"].asReal();
433 mBurstRadius = (F32)sd["BurstRadius"].asReal();
434
435 mPartImageID = LLUUID(sd[("PartImageID")].asString());
436 mTargetUUID = LLUUID(sd["TargetId"].asString());
437
438 return true;
439} \ No newline at end of file
diff --git a/linden/indra/llmessage/llpartdata.h b/linden/indra/llmessage/llpartdata.h
index 6dcb311..b7efa95 100644
--- a/linden/indra/llmessage/llpartdata.h
+++ b/linden/indra/llmessage/llpartdata.h
@@ -158,6 +158,9 @@ public:
158 BOOL unpackBlock(const S32 block_num); 158 BOOL unpackBlock(const S32 block_num);
159 BOOL packBlock(); 159 BOOL packBlock();
160 160
161 LLSD asLLSD() const;
162 bool fromLLSD(LLSD& sd);
163
161 static BOOL packNull(); 164 static BOOL packNull();
162 static BOOL isNullPS(const S32 block_num); // Returns FALSE if this is a "NULL" particle system (i.e. no system) 165 static BOOL isNullPS(const S32 block_num); // Returns FALSE if this is a "NULL" particle system (i.e. no system)
163 166
diff --git a/linden/indra/llmessage/llpumpio.cpp b/linden/indra/llmessage/llpumpio.cpp
index 8ef2b16..6f10c6b 100644
--- a/linden/indra/llmessage/llpumpio.cpp
+++ b/linden/indra/llmessage/llpumpio.cpp
@@ -43,6 +43,7 @@
43#include "llmemtype.h" 43#include "llmemtype.h"
44#include "llstl.h" 44#include "llstl.h"
45#include "llstat.h" 45#include "llstat.h"
46#include "llthread.h"
46#include "llfasttimer.h" 47#include "llfasttimer.h"
47 48
48// These should not be enabled in production, but they can be 49// These should not be enabled in production, but they can be
@@ -169,14 +170,12 @@ struct ll_delete_apr_pollset_fd_client_data
169/** 170/**
170 * LLPumpIO 171 * LLPumpIO
171 */ 172 */
172LLPumpIO::LLPumpIO(apr_pool_t* pool) : 173LLPumpIO::LLPumpIO(void) :
173 mState(LLPumpIO::NORMAL), 174 mState(LLPumpIO::NORMAL),
174 mRebuildPollset(false), 175 mRebuildPollset(false),
175 mPollset(NULL), 176 mPollset(NULL),
176 mPollsetClientID(0), 177 mPollsetClientID(0),
177 mNextLock(0), 178 mNextLock(0),
178 mPool(NULL),
179 mCurrentPool(NULL),
180 mCurrentPoolReallocCount(0), 179 mCurrentPoolReallocCount(0),
181 mChainsMutex(NULL), 180 mChainsMutex(NULL),
182 mCallbackMutex(NULL), 181 mCallbackMutex(NULL),
@@ -185,21 +184,24 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) :
185 mCurrentChain = mRunningChains.end(); 184 mCurrentChain = mRunningChains.end();
186 185
187 LLMemType m1(LLMemType::MTYPE_IO_PUMP); 186 LLMemType m1(LLMemType::MTYPE_IO_PUMP);
188 initialize(pool); 187 initialize();
189} 188}
190 189
191LLPumpIO::~LLPumpIO() 190LLPumpIO::~LLPumpIO()
192{ 191{
193 LLMemType m1(LLMemType::MTYPE_IO_PUMP); 192 LLMemType m1(LLMemType::MTYPE_IO_PUMP);
194 cleanup(); 193#if LL_THREADS_APR
195} 194 if (mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
196 195 if (mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
197bool LLPumpIO::prime(apr_pool_t* pool) 196#endif
198{ 197 mChainsMutex = NULL;
199 LLMemType m1(LLMemType::MTYPE_IO_PUMP); 198 mCallbackMutex = NULL;
200 cleanup(); 199 if(mPollset)
201 initialize(pool); 200 {
202 return ((pool == NULL) ? false : true); 201// lldebugs << "cleaning up pollset" << llendl;
202 apr_pollset_destroy(mPollset);
203 mPollset = NULL;
204 }
203} 205}
204 206
205bool LLPumpIO::addChain(const chain_t& chain, F32 timeout) 207bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
@@ -359,8 +361,7 @@ bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll)
359 { 361 {
360 // each fd needs a pool to work with, so if one was 362 // each fd needs a pool to work with, so if one was
361 // not specified, use this pool. 363 // not specified, use this pool.
362 // *FIX: Should it always be this pool? 364 value.second.p = (*mCurrentChain).mDescriptorsPool->operator()();
363 value.second.p = mPool;
364 } 365 }
365 value.second.client_data = new S32(++mPollsetClientID); 366 value.second.client_data = new S32(++mPollsetClientID);
366 (*mCurrentChain).mDescriptors.push_back(value); 367 (*mCurrentChain).mDescriptors.push_back(value);
@@ -827,39 +828,15 @@ void LLPumpIO::control(LLPumpIO::EControl op)
827 } 828 }
828} 829}
829 830
830void LLPumpIO::initialize(apr_pool_t* pool) 831void LLPumpIO::initialize(void)
831{ 832{
832 LLMemType m1(LLMemType::MTYPE_IO_PUMP); 833 LLMemType m1(LLMemType::MTYPE_IO_PUMP);
833 if(!pool) return; 834 mPool.create();
834#if LL_THREADS_APR 835#if LL_THREADS_APR
835 // SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly. 836 // SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
836 apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool); 837 apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
837 apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool); 838 apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
838#endif
839 mPool = pool;
840}
841
842void LLPumpIO::cleanup()
843{
844 LLMemType m1(LLMemType::MTYPE_IO_PUMP);
845#if LL_THREADS_APR
846 if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
847 if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
848#endif 839#endif
849 mChainsMutex = NULL;
850 mCallbackMutex = NULL;
851 if(mPollset)
852 {
853// lldebugs << "cleaning up pollset" << llendl;
854 apr_pollset_destroy(mPollset);
855 mPollset = NULL;
856 }
857 if(mCurrentPool)
858 {
859 apr_pool_destroy(mCurrentPool);
860 mCurrentPool = NULL;
861 }
862 mPool = NULL;
863} 840}
864 841
865void LLPumpIO::rebuildPollset() 842void LLPumpIO::rebuildPollset()
@@ -887,21 +864,19 @@ void LLPumpIO::rebuildPollset()
887 if(mCurrentPool 864 if(mCurrentPool
888 && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT))) 865 && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT)))
889 { 866 {
890 apr_pool_destroy(mCurrentPool); 867 mCurrentPool.destroy();
891 mCurrentPool = NULL;
892 mCurrentPoolReallocCount = 0; 868 mCurrentPoolReallocCount = 0;
893 } 869 }
894 if(!mCurrentPool) 870 if(!mCurrentPool)
895 { 871 {
896 apr_status_t status = apr_pool_create(&mCurrentPool, mPool); 872 mCurrentPool.create(mPool);
897 (void)ll_apr_warn_status(status);
898 } 873 }
899 874
900 // add all of the file descriptors 875 // add all of the file descriptors
901 run_it = mRunningChains.begin(); 876 run_it = mRunningChains.begin();
902 LLChainInfo::conditionals_t::iterator fd_it; 877 LLChainInfo::conditionals_t::iterator fd_it;
903 LLChainInfo::conditionals_t::iterator fd_end; 878 LLChainInfo::conditionals_t::iterator fd_end;
904 apr_pollset_create(&mPollset, size, mCurrentPool, 0); 879 apr_pollset_create(&mPollset, size, mCurrentPool(), 0);
905 for(; run_it != run_end; ++run_it) 880 for(; run_it != run_end; ++run_it)
906 { 881 {
907 fd_it = (*run_it).mDescriptors.begin(); 882 fd_it = (*run_it).mDescriptors.begin();
@@ -1159,7 +1134,8 @@ bool LLPumpIO::handleChainError(
1159LLPumpIO::LLChainInfo::LLChainInfo() : 1134LLPumpIO::LLChainInfo::LLChainInfo() :
1160 mInit(false), 1135 mInit(false),
1161 mLock(0), 1136 mLock(0),
1162 mEOS(false) 1137 mEOS(false),
1138 mDescriptorsPool(new AIAPRPool(LLThread::tldata().mRootPool))
1163{ 1139{
1164 LLMemType m1(LLMemType::MTYPE_IO_PUMP); 1140 LLMemType m1(LLMemType::MTYPE_IO_PUMP);
1165 mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS); 1141 mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
diff --git a/linden/indra/llmessage/llpumpio.h b/linden/indra/llmessage/llpumpio.h
index fc0bfab..2666be0 100644
--- a/linden/indra/llmessage/llpumpio.h
+++ b/linden/indra/llmessage/llpumpio.h
@@ -36,11 +36,12 @@
36#define LL_LLPUMPIO_H 36#define LL_LLPUMPIO_H
37 37
38#include <set> 38#include <set>
39#include <boost/shared_ptr.hpp>
39#if LL_LINUX // needed for PATH_MAX in APR. 40#if LL_LINUX // needed for PATH_MAX in APR.
40#include <sys/param.h> 41#include <sys/param.h>
41#endif 42#endif
42 43
43#include "apr_pools.h" 44#include "aiaprpool.h"
44#include "llbuffer.h" 45#include "llbuffer.h"
45#include "llframetimer.h" 46#include "llframetimer.h"
46#include "lliopipe.h" 47#include "lliopipe.h"
@@ -64,9 +65,8 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS;
64 * <code>pump()</code> on a thread used for IO and call 65 * <code>pump()</code> on a thread used for IO and call
65 * <code>respond()</code> on a thread that is expected to do higher 66 * <code>respond()</code> on a thread that is expected to do higher
66 * level processing. You can call almost any other method from any 67 * level processing. You can call almost any other method from any
67 * thread - see notes for each method for details. In order for the 68 * thread - see notes for each method for details.
68 * threading abstraction to work, you need to call <code>prime()</code> 69 *
69 * with a valid apr pool.
70 * A pump instance manages much of the state for the pipe, including 70 * A pump instance manages much of the state for the pipe, including
71 * the list of pipes in the chain, the channel for each element in the 71 * the list of pipes in the chain, the channel for each element in the
72 * chain, the buffer, and if any pipe has marked the stream or process 72 * chain, the buffer, and if any pipe has marked the stream or process
@@ -85,7 +85,7 @@ public:
85 /** 85 /**
86 * @brief Constructor. 86 * @brief Constructor.
87 */ 87 */
88 LLPumpIO(apr_pool_t* pool); 88 LLPumpIO(void);
89 89
90 /** 90 /**
91 * @brief Destructor. 91 * @brief Destructor.
@@ -93,17 +93,6 @@ public:
93 ~LLPumpIO(); 93 ~LLPumpIO();
94 94
95 /** 95 /**
96 * @brief Prepare this pump for usage.
97 *
98 * If you fail to call this method prior to use, the pump will
99 * try to work, but will not come with any thread locking
100 * mechanisms.
101 * @param pool The apr pool to use.
102 * @return Returns true if the pump is primed.
103 */
104 bool prime(apr_pool_t* pool);
105
106 /**
107 * @brief Typedef for having a chain of pipes. 96 * @brief Typedef for having a chain of pipes.
108 */ 97 */
109 typedef std::vector<LLIOPipe::ptr_t> chain_t; 98 typedef std::vector<LLIOPipe::ptr_t> chain_t;
@@ -374,6 +363,7 @@ protected:
374 typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t; 363 typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t;
375 typedef std::vector<pipe_conditional_t> conditionals_t; 364 typedef std::vector<pipe_conditional_t> conditionals_t;
376 conditionals_t mDescriptors; 365 conditionals_t mDescriptors;
366 boost::shared_ptr<AIAPRPool> mDescriptorsPool;
377 }; 367 };
378 368
379 // All the running chains & info 369 // All the running chains & info
@@ -392,9 +382,9 @@ protected:
392 callbacks_t mPendingCallbacks; 382 callbacks_t mPendingCallbacks;
393 callbacks_t mCallbacks; 383 callbacks_t mCallbacks;
394 384
395 // memory allocator for pollsets & mutexes. 385 // Memory pool for pollsets & mutexes.
396 apr_pool_t* mPool; 386 AIAPRPool mPool;
397 apr_pool_t* mCurrentPool; 387 AIAPRPool mCurrentPool;
398 S32 mCurrentPoolReallocCount; 388 S32 mCurrentPoolReallocCount;
399 389
400#if LL_THREADS_APR 390#if LL_THREADS_APR
@@ -406,8 +396,7 @@ protected:
406#endif 396#endif
407 397
408protected: 398protected:
409 void initialize(apr_pool_t* pool); 399 void initialize();
410 void cleanup();
411 400
412 /** 401 /**
413 * @brief Given the internal state of the chains, rebuild the pollset 402 * @brief Given the internal state of the chains, rebuild the pollset
diff --git a/linden/indra/llmessage/llurlrequest.cpp b/linden/indra/llmessage/llurlrequest.cpp
index 46e976f..87f0116 100644
--- a/linden/indra/llmessage/llurlrequest.cpp
+++ b/linden/indra/llmessage/llurlrequest.cpp
@@ -45,6 +45,7 @@
45#include "llstring.h" 45#include "llstring.h"
46#include "apr_env.h" 46#include "apr_env.h"
47#include "llapr.h" 47#include "llapr.h"
48#include "llscopedvolatileaprpool.h"
48static const U32 HTTP_STATUS_PIPE_ERROR = 499; 49static const U32 HTTP_STATUS_PIPE_ERROR = 499;
49 50
50/** 51/**
@@ -161,27 +162,31 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback)
161// is called with use_proxy = FALSE 162// is called with use_proxy = FALSE
162void LLURLRequest::useProxy(bool use_proxy) 163void LLURLRequest::useProxy(bool use_proxy)
163{ 164{
164 static char *env_proxy; 165 static std::string env_proxy;
165 166
166 if (use_proxy && (env_proxy == NULL)) 167 if (use_proxy && env_proxy.empty())
167 { 168 {
168 apr_status_t status; 169 char* env_proxy_str;
169 LLAPRPool pool; 170 LLScopedVolatileAPRPool scoped_pool;
170 status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool()); 171 apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool);
171 if (status != APR_SUCCESS) 172 if (status != APR_SUCCESS)
172 { 173 {
173 status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool()); 174 status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool);
174 } 175 }
175 if (status != APR_SUCCESS) 176 if (status != APR_SUCCESS)
176 { 177 {
177 use_proxy = FALSE; 178 use_proxy = false;
178 } 179 }
180 else
181 {
182 // env_proxy_str is stored in the scoped_pool, so we have to make a copy.
183 env_proxy = env_proxy_str;
184 }
179 } 185 }
180 186
187 lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = \"" << env_proxy << "\"" << llendl;
181 188
182 lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl; 189 if (use_proxy)
183
184 if (env_proxy && use_proxy)
185 { 190 {
186 mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy); 191 mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
187 } 192 }
diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp
index 7e8aff1..53036bc 100644
--- a/linden/indra/llmessage/message.cpp
+++ b/linden/indra/llmessage/message.cpp
@@ -103,8 +103,10 @@ std::string get_shared_secret();
103class LLMessagePollInfo 103class LLMessagePollInfo
104{ 104{
105public: 105public:
106 LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { }
106 apr_socket_t *mAPRSocketp; 107 apr_socket_t *mAPRSocketp;
107 apr_pollfd_t mPollFD; 108 apr_pollfd_t mPollFD;
109 AIAPRPool mPool;
108}; 110};
109 111
110namespace 112namespace
@@ -291,20 +293,13 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,
291 } 293 }
292// LL_DEBUGS("Messaging") << << "*** port: " << mPort << llendl; 294// LL_DEBUGS("Messaging") << << "*** port: " << mPort << llendl;
293 295
294 // 296 mPollInfop = new LLMessagePollInfo;
295 // Create the data structure that we can poll on 297
296 //
297 if (!gAPRPoolp)
298 {
299 LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl;
300 ll_init_apr();
301 }
302 apr_socket_t *aprSocketp = NULL; 298 apr_socket_t *aprSocketp = NULL;
303 apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp); 299 apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool());
304 300
305 mPollInfop = new LLMessagePollInfo;
306 mPollInfop->mAPRSocketp = aprSocketp; 301 mPollInfop->mAPRSocketp = aprSocketp;
307 mPollInfop->mPollFD.p = gAPRPoolp; 302 mPollInfop->mPollFD.p = mPollInfop->mPool();
308 mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET; 303 mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET;
309 mPollInfop->mPollFD.reqevents = APR_POLLIN; 304 mPollInfop->mPollFD.reqevents = APR_POLLIN;
310 mPollInfop->mPollFD.rtnevents = 0; 305 mPollInfop->mPollFD.rtnevents = 0;
diff --git a/linden/indra/llplugin/llpluginclassmedia.cpp b/linden/indra/llplugin/llpluginclassmedia.cpp
index 85241be..5a81c46 100755
--- a/linden/indra/llplugin/llpluginclassmedia.cpp
+++ b/linden/indra/llplugin/llpluginclassmedia.cpp
@@ -72,10 +72,10 @@ LLPluginClassMedia::~LLPluginClassMedia()
72} 72}
73 73
74bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug) 74bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug)
75{ 75{
76 LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL; 76 LL_DEBUGS("PluginClassMedia") << "launcher: " << launcher_filename << LL_ENDL;
77 LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL; 77 LL_DEBUGS("PluginClassMedia") << "plugin: " << plugin_filename << LL_ENDL;
78 78
79 mPlugin = new LLPluginProcessParent(this); 79 mPlugin = new LLPluginProcessParent(this);
80 mPlugin->setSleepTime(mSleepTime); 80 mPlugin->setSleepTime(mSleepTime);
81 81
@@ -198,7 +198,7 @@ void LLPluginClassMedia::idle(void)
198 } 198 }
199 else 199 else
200 { 200 {
201 LL_WARNS("Plugin") << "Unable to pad texture width, padding size " << mPadding << "is not a multiple of pixel size " << mRequestedTextureDepth << LL_ENDL; 201 LL_WARNS("PluginClassMedia") << "Unable to pad texture width, padding size " << mPadding << "is not a multiple of pixel size " << mRequestedTextureDepth << LL_ENDL;
202 } 202 }
203 } 203 }
204 } 204 }
@@ -256,11 +256,11 @@ void LLPluginClassMedia::idle(void)
256 message.setValueReal("background_b", mBackgroundColor.mV[VZ]); 256 message.setValueReal("background_b", mBackgroundColor.mV[VZ]);
257 message.setValueReal("background_a", mBackgroundColor.mV[VW]); 257 message.setValueReal("background_a", mBackgroundColor.mV[VW]);
258 mPlugin->sendMessage(message); // DO NOT just use sendMessage() here -- we want this to jump ahead of the queue. 258 mPlugin->sendMessage(message); // DO NOT just use sendMessage() here -- we want this to jump ahead of the queue.
259 259
260 LL_DEBUGS("Plugin") << "Sending size_change" << LL_ENDL; 260 LL_DEBUGS("PluginClassMedia") << "Sending size_change" << LL_ENDL;
261 } 261 }
262 } 262 }
263 263
264 if(mPlugin && mPlugin->isRunning()) 264 if(mPlugin && mPlugin->isRunning())
265 { 265 {
266 // Send queued messages 266 // Send queued messages
@@ -777,7 +777,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
777 mDirtyRect.unionWith(newDirtyRect); 777 mDirtyRect.unionWith(newDirtyRect);
778 } 778 }
779 779
780 LL_DEBUGS("Plugin") << "adjusted incoming rect is: (" 780 LL_DEBUGS("PluginClassMedia") << "adjusted incoming rect is: ("
781 << newDirtyRect.mLeft << ", " 781 << newDirtyRect.mLeft << ", "
782 << newDirtyRect.mTop << ", " 782 << newDirtyRect.mTop << ", "
783 << newDirtyRect.mRight << ", " 783 << newDirtyRect.mRight << ", "
@@ -841,9 +841,9 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
841 else if(message_name == "media_status") 841 else if(message_name == "media_status")
842 { 842 {
843 std::string status = message.getValue("status"); 843 std::string status = message.getValue("status");
844 844
845 LL_DEBUGS("Plugin") << "Status changed to: " << status << LL_ENDL; 845 LL_DEBUGS("PluginClassMedia") << "Status changed to: " << status << LL_ENDL;
846 846
847 if(status == "loading") 847 if(status == "loading")
848 { 848 {
849 mStatus = LLPluginClassMediaOwner::MEDIA_LOADING; 849 mStatus = LLPluginClassMediaOwner::MEDIA_LOADING;
@@ -933,7 +933,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
933 } 933 }
934 else 934 else
935 { 935 {
936 LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; 936 LL_WARNS("PluginClassMedia") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
937 } 937 }
938 } 938 }
939 else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) 939 else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
@@ -990,7 +990,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
990 } 990 }
991 else 991 else
992 { 992 {
993 LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; 993 LL_WARNS("PluginClassMedia") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
994 } 994 }
995 } 995 }
996 else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) 996 else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
@@ -1001,9 +1001,9 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
1001// if(message_name == "message_name") 1001// if(message_name == "message_name")
1002// { 1002// {
1003// } 1003// }
1004// else 1004// else
1005 { 1005 {
1006 LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; 1006 LL_WARNS("PluginClassMedia") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
1007 } 1007 }
1008 } 1008 }
1009 1009
@@ -1230,6 +1230,6 @@ void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history)
1230 message.setValueLLSD("history", url_history); 1230 message.setValueLLSD("history", url_history);
1231 sendMessage(message); 1231 sendMessage(message);
1232 1232
1233 LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL; 1233 LL_DEBUGS("PluginClassMedia") << "Sending history" << LL_ENDL;
1234} 1234}
1235 1235
diff --git a/linden/indra/llplugin/llplugininstance.cpp b/linden/indra/llplugin/llplugininstance.cpp
index b822b9e..67457f2 100755
--- a/linden/indra/llplugin/llplugininstance.cpp
+++ b/linden/indra/llplugin/llplugininstance.cpp
@@ -36,8 +36,7 @@
36#include "linden_common.h" 36#include "linden_common.h"
37 37
38#include "llplugininstance.h" 38#include "llplugininstance.h"
39 39#include "aiaprpool.h"
40#include "llapr.h"
41 40
42/** Virtual destructor. */ 41/** Virtual destructor. */
43LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener() 42LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener()
@@ -86,16 +85,16 @@ int LLPluginInstance::load(std::string &plugin_file)
86 85
87 int result = apr_dso_load(&mDSOHandle, 86 int result = apr_dso_load(&mDSOHandle,
88 plugin_file.c_str(), 87 plugin_file.c_str(),
89 gAPRPoolp); 88 AIAPRRootPool::get()());
90 if(result != APR_SUCCESS) 89 if(result != APR_SUCCESS)
91 { 90 {
92 char buf[1024]; 91 char buf[1024];
93 apr_dso_error(mDSOHandle, buf, sizeof(buf)); 92 apr_dso_error(mDSOHandle, buf, sizeof(buf));
94 93
95 LL_WARNS("Plugin") << "apr_dso_load of " << plugin_file << " failed with error " << result << " , additional info string: " << buf << LL_ENDL; 94 LL_WARNS("PluginInstance") << "apr_dso_load of " << plugin_file << " failed with error " << result << " , additional info string: " << buf << LL_ENDL;
96 95
97 } 96 }
98 97
99 if(result == APR_SUCCESS) 98 if(result == APR_SUCCESS)
100 { 99 {
101 result = apr_dso_sym((apr_dso_handle_sym_t*)&init_function, 100 result = apr_dso_sym((apr_dso_handle_sym_t*)&init_function,
@@ -104,20 +103,20 @@ int LLPluginInstance::load(std::string &plugin_file)
104 103
105 if(result != APR_SUCCESS) 104 if(result != APR_SUCCESS)
106 { 105 {
107 LL_WARNS("Plugin") << "apr_dso_sym failed with error " << result << LL_ENDL; 106 LL_WARNS("PluginInstance") << "apr_dso_sym failed with error " << result << LL_ENDL;
108 } 107 }
109 } 108 }
110 109
111 if(result == APR_SUCCESS) 110 if(result == APR_SUCCESS)
112 { 111 {
113 result = init_function(staticReceiveMessage, (void*)this, &mPluginSendMessageFunction, &mPluginUserData); 112 result = init_function(staticReceiveMessage, (void*)this, &mPluginSendMessageFunction, &mPluginUserData);
114 113
115 if(result != APR_SUCCESS) 114 if(result != APR_SUCCESS)
116 { 115 {
117 LL_WARNS("Plugin") << "call to init function failed with error " << result << LL_ENDL; 116 LL_WARNS("PluginInstance") << "call to init function failed with error " << result << LL_ENDL;
118 } 117 }
119 } 118 }
120 119
121 return (int)result; 120 return (int)result;
122} 121}
123 122
@@ -130,12 +129,12 @@ void LLPluginInstance::sendMessage(const std::string &message)
130{ 129{
131 if(mPluginSendMessageFunction) 130 if(mPluginSendMessageFunction)
132 { 131 {
133 LL_DEBUGS("Plugin") << "sending message to plugin: \"" << message << "\"" << LL_ENDL; 132 LL_DEBUGS("PluginInstance") << "sending message to plugin: \"" << message << "\"" << LL_ENDL;
134 mPluginSendMessageFunction(message.c_str(), &mPluginUserData); 133 mPluginSendMessageFunction(message.c_str(), &mPluginUserData);
135 } 134 }
136 else 135 else
137 { 136 {
138 LL_WARNS("Plugin") << "dropping message: \"" << message << "\"" << LL_ENDL; 137 LL_WARNS("PluginInstance") << "dropping message: \"" << message << "\"" << LL_ENDL;
139 } 138 }
140} 139}
141 140
@@ -165,11 +164,11 @@ void LLPluginInstance::receiveMessage(const char *message_string)
165{ 164{
166 if(mOwner) 165 if(mOwner)
167 { 166 {
168 LL_DEBUGS("Plugin") << "processing incoming message: \"" << message_string << "\"" << LL_ENDL; 167 LL_DEBUGS("PluginInstance") << "processing incoming message: \"" << message_string << "\"" << LL_ENDL;
169 mOwner->receivePluginMessage(message_string); 168 mOwner->receivePluginMessage(message_string);
170 } 169 }
171 else 170 else
172 { 171 {
173 LL_WARNS("Plugin") << "dropping incoming message: \"" << message_string << "\"" << LL_ENDL; 172 LL_WARNS("PluginInstance") << "dropping incoming message: \"" << message_string << "\"" << LL_ENDL;
174 } 173 }
175} 174}
diff --git a/linden/indra/llplugin/llpluginmessagepipe.cpp b/linden/indra/llplugin/llpluginmessagepipe.cpp
index 8168b32..ac3a902 100755
--- a/linden/indra/llplugin/llpluginmessagepipe.cpp
+++ b/linden/indra/llplugin/llpluginmessagepipe.cpp
@@ -82,10 +82,10 @@ bool LLPluginMessagePipeOwner::writeMessageRaw(const std::string &message)
82 } 82 }
83 else 83 else
84 { 84 {
85 LL_WARNS("Plugin") << "dropping message: " << message << LL_ENDL; 85 LL_WARNS("PluginPipe") << "dropping message: " << message << LL_ENDL;
86 result = false; 86 result = false;
87 } 87 }
88 88
89 return result; 89 return result;
90} 90}
91 91
@@ -99,8 +99,6 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
99} 99}
100 100
101LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket): 101LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
102 mInputMutex(gAPRPoolp),
103 mOutputMutex(gAPRPoolp),
104 mOwner(owner), 102 mOwner(owner),
105 mSocket(socket) 103 mSocket(socket)
106{ 104{
@@ -179,18 +177,18 @@ bool LLPluginMessagePipe::pumpOutput()
179 { 177 {
180 // write any outgoing messages 178 // write any outgoing messages
181 size = (apr_size_t)mOutput.size(); 179 size = (apr_size_t)mOutput.size();
182 180
183 setSocketTimeout(0); 181 setSocketTimeout(0);
184 182
185// LL_INFOS("Plugin") << "before apr_socket_send, size = " << size << LL_ENDL; 183// LL_INFOS("PluginPipe") << "before apr_socket_send, size = " << size << LL_ENDL;
186 184
187 status = apr_socket_send( 185 status = apr_socket_send(
188 mSocket->getSocket(), 186 mSocket->getSocket(),
189 (const char*)mOutput.data(), 187 (const char*)mOutput.data(),
190 &size); 188 &size);
191 189
192// LL_INFOS("Plugin") << "after apr_socket_send, size = " << size << LL_ENDL; 190// LL_INFOS("PluginPipe") << "after apr_socket_send, size = " << size << LL_ENDL;
193 191
194 if(status == APR_SUCCESS) 192 if(status == APR_SUCCESS)
195 { 193 {
196 // success 194 // success
@@ -277,15 +275,15 @@ bool LLPluginMessagePipe::pumpInput(F64 timeout)
277 { 275 {
278 size = request_size; 276 size = request_size;
279 277
280// LL_INFOS("Plugin") << "before apr_socket_recv, size = " << size << LL_ENDL; 278// LL_INFOS("PluginPipe") << "before apr_socket_recv, size = " << size << LL_ENDL;
281 279
282 status = apr_socket_recv( 280 status = apr_socket_recv(
283 mSocket->getSocket(), 281 mSocket->getSocket(),
284 input_buf, 282 input_buf,
285 &size); 283 &size);
286 284
287// LL_INFOS("Plugin") << "after apr_socket_recv, size = " << size << LL_ENDL; 285// LL_INFOS("PluginPipe") << "after apr_socket_recv, size = " << size << LL_ENDL;
288 286
289 if(size > 0) 287 if(size > 0)
290 { 288 {
291 LLMutexLock lock(&mInputMutex); 289 LLMutexLock lock(&mInputMutex);
@@ -379,7 +377,7 @@ void LLPluginMessagePipe::processInput(void)
379 } 377 }
380 else 378 else
381 { 379 {
382 LL_WARNS("Plugin") << "!mOwner" << LL_ENDL; 380 LL_WARNS("PluginPipe") << "!mOwner" << LL_ENDL;
383 } 381 }
384 } 382 }
385 mInputMutex.unlock(); 383 mInputMutex.unlock();
diff --git a/linden/indra/llplugin/llpluginprocesschild.cpp b/linden/indra/llplugin/llpluginprocesschild.cpp
index 8dbf2b3..a1291c0 100755
--- a/linden/indra/llplugin/llpluginprocesschild.cpp
+++ b/linden/indra/llplugin/llpluginprocesschild.cpp
@@ -47,7 +47,7 @@ LLPluginProcessChild::LLPluginProcessChild()
47{ 47{
48 mState = STATE_UNINITIALIZED; 48 mState = STATE_UNINITIALIZED;
49 mInstance = NULL; 49 mInstance = NULL;
50 mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); 50 mSocket = LLSocket::create(LLSocket::STREAM_TCP);
51 mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz 51 mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz
52 mCPUElapsed = 0.0f; 52 mCPUElapsed = 0.0f;
53 mBlockingRequest = false; 53 mBlockingRequest = false;
@@ -94,18 +94,18 @@ void LLPluginProcessChild::idle(void)
94 } 94 }
95 else if(mSocketError != APR_SUCCESS) 95 else if(mSocketError != APR_SUCCESS)
96 { 96 {
97 LL_INFOS("Plugin") << "message pipe is in error state (" << mSocketError << "), moving to STATE_ERROR"<< LL_ENDL; 97 LL_INFOS("PluginChild") << "message pipe is in error state (" << mSocketError << "), moving to STATE_ERROR"<< LL_ENDL;
98 setState(STATE_ERROR); 98 setState(STATE_ERROR);
99 } 99 }
100 100
101 if((mState > STATE_INITIALIZED) && (mMessagePipe == NULL)) 101 if((mState > STATE_INITIALIZED) && (mMessagePipe == NULL))
102 { 102 {
103 // The pipe has been closed -- we're done. 103 // The pipe has been closed -- we're done.
104 // TODO: This could be slightly more subtle, but I'm not sure it needs to be. 104 // TODO: This could be slightly more subtle, but I'm not sure it needs to be.
105 LL_INFOS("Plugin") << "message pipe went away, moving to STATE_ERROR"<< LL_ENDL; 105 LL_INFOS("PluginChild") << "message pipe went away, moving to STATE_ERROR"<< LL_ENDL;
106 setState(STATE_ERROR); 106 setState(STATE_ERROR);
107 } 107 }
108 108
109 // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). 109 // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState().
110 // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return. 110 // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return.
111 // When in doubt, don't do it. 111 // When in doubt, don't do it.
@@ -291,17 +291,17 @@ void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
291 if (mInstance) 291 if (mInstance)
292 { 292 {
293 std::string buffer = message.generate(); 293 std::string buffer = message.generate();
294 294
295 LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL; 295 LL_DEBUGS("PluginChild") << "Sending to plugin: " << buffer << LL_ENDL;
296 LLTimer elapsed; 296 LLTimer elapsed;
297 297
298 mInstance->sendMessage(buffer); 298 mInstance->sendMessage(buffer);
299 299
300 mCPUElapsed += elapsed.getElapsedTimeF64(); 300 mCPUElapsed += elapsed.getElapsedTimeF64();
301 } 301 }
302 else 302 else
303 { 303 {
304 LL_WARNS("Plugin") << "mInstance == NULL" << LL_ENDL; 304 LL_WARNS("PluginChild") << "mInstance == NULL" << LL_ENDL;
305 } 305 }
306} 306}
307 307
@@ -309,7 +309,7 @@ void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message)
309{ 309{
310 std::string buffer = message.generate(); 310 std::string buffer = message.generate();
311 311
312 LL_DEBUGS("Plugin") << "Sending to parent: " << buffer << LL_ENDL; 312 LL_DEBUGS("PluginChild") << "Sending to parent: " << buffer << LL_ENDL;
313 313
314 writeMessageRaw(buffer); 314 writeMessageRaw(buffer);
315} 315}
@@ -318,7 +318,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
318{ 318{
319 // Incoming message from the TCP Socket 319 // Incoming message from the TCP Socket
320 320
321 LL_DEBUGS("Plugin") << "Received from parent: " << message << LL_ENDL; 321 LL_DEBUGS("PluginChild") << "Received from parent: " << message << LL_ENDL;
322 322
323 // Decode this message 323 // Decode this message
324 LLPluginMessage parsed; 324 LLPluginMessage parsed;
@@ -365,7 +365,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
365 if(iter != mSharedMemoryRegions.end()) 365 if(iter != mSharedMemoryRegions.end())
366 { 366 {
367 // Need to remove the old region first 367 // Need to remove the old region first
368 LL_WARNS("Plugin") << "Adding a duplicate shared memory segment!" << LL_ENDL; 368 LL_WARNS("PluginChild") << "Adding a duplicate shared memory segment!" << LL_ENDL;
369 } 369 }
370 else 370 else
371 { 371 {
@@ -392,7 +392,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
392 } 392 }
393 else 393 else
394 { 394 {
395 LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL; 395 LL_WARNS("PluginChild") << "Couldn't create a shared memory segment!" << LL_ENDL;
396 delete region; 396 delete region;
397 } 397 }
398 } 398 }
@@ -411,7 +411,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
411 } 411 }
412 else 412 else
413 { 413 {
414 LL_WARNS("Plugin") << "shm_remove for unknown memory segment!" << LL_ENDL; 414 LL_WARNS("PluginChild") << "shm_remove for unknown memory segment!" << LL_ENDL;
415 } 415 }
416 } 416 }
417 else if(message_name == "sleep_time") 417 else if(message_name == "sleep_time")
@@ -421,12 +421,12 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
421 else if(message_name == "crash") 421 else if(message_name == "crash")
422 { 422 {
423 // Crash the plugin 423 // Crash the plugin
424 LL_ERRS("Plugin") << "Plugin crash requested." << LL_ENDL; 424 LL_ERRS("PluginChild") << "Plugin crash requested." << LL_ENDL;
425 } 425 }
426 else if(message_name == "hang") 426 else if(message_name == "hang")
427 { 427 {
428 // Hang the plugin 428 // Hang the plugin
429 LL_WARNS("Plugin") << "Plugin hang requested." << LL_ENDL; 429 LL_WARNS("PluginChild") << "Plugin hang requested." << LL_ENDL;
430 while(1) 430 while(1)
431 { 431 {
432 // wheeeeeeeee...... 432 // wheeeeeeeee......
@@ -434,7 +434,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
434 } 434 }
435 else 435 else
436 { 436 {
437 LL_WARNS("Plugin") << "Unknown internal message from parent: " << message_name << LL_ENDL; 437 LL_WARNS("PluginChild") << "Unknown internal message from parent: " << message_name << LL_ENDL;
438 } 438 }
439 } 439 }
440 } 440 }
@@ -449,17 +449,17 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
449 } 449 }
450} 450}
451 451
452/* virtual */ 452/* virtual */
453void LLPluginProcessChild::receivePluginMessage(const std::string &message) 453void LLPluginProcessChild::receivePluginMessage(const std::string &message)
454{ 454{
455 LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL; 455 LL_DEBUGS("PluginChild") << "Received from plugin: " << message << LL_ENDL;
456 456
457 if(mBlockingRequest) 457 if(mBlockingRequest)
458 { 458 {
459 // 459 //
460 LL_ERRS("Plugin") << "Can't send a message while already waiting on a blocking request -- aborting!" << LL_ENDL; 460 LL_ERRS("PluginChild") << "Can't send a message while already waiting on a blocking request -- aborting!" << LL_ENDL;
461 } 461 }
462 462
463 // Incoming message from the plugin instance 463 // Incoming message from the plugin instance
464 bool passMessage = true; 464 bool passMessage = true;
465 465
@@ -523,18 +523,18 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
523 } 523 }
524 else 524 else
525 { 525 {
526 LL_WARNS("Plugin") << "shm_remove_response for unknown memory segment!" << LL_ENDL; 526 LL_WARNS("PluginChild") << "shm_remove_response for unknown memory segment!" << LL_ENDL;
527 } 527 }
528 } 528 }
529 } 529 }
530 } 530 }
531 531
532 if(passMessage) 532 if(passMessage)
533 { 533 {
534 LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL; 534 LL_DEBUGS("PluginChild") << "Passing through to parent: " << message << LL_ENDL;
535 writeMessageRaw(message); 535 writeMessageRaw(message);
536 } 536 }
537 537
538 while(mBlockingRequest) 538 while(mBlockingRequest)
539 { 539 {
540 // The plugin wants to block and wait for a response to this message. 540 // The plugin wants to block and wait for a response to this message.
@@ -552,8 +552,8 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
552 552
553void LLPluginProcessChild::setState(EState state) 553void LLPluginProcessChild::setState(EState state)
554{ 554{
555 LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL; 555 LL_DEBUGS("PluginChild") << "setting state to " << state << LL_ENDL;
556 mState = state; 556 mState = state;
557}; 557};
558 558
559void LLPluginProcessChild::deliverQueuedMessages() 559void LLPluginProcessChild::deliverQueuedMessages()
diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp
index 8fd18ef..5a66279 100755
--- a/linden/indra/llplugin/llpluginprocessparent.cpp
+++ b/linden/indra/llplugin/llpluginprocessparent.cpp
@@ -49,6 +49,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
49 49
50bool LLPluginProcessParent::sUseReadThread = false; 50bool LLPluginProcessParent::sUseReadThread = false;
51apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; 51apr_pollset_t *LLPluginProcessParent::sPollSet = NULL;
52AIAPRPool LLPluginProcessParent::sPollSetPool;
52bool LLPluginProcessParent::sPollsetNeedsRebuild = false; 53bool LLPluginProcessParent::sPollsetNeedsRebuild = false;
53LLMutex *LLPluginProcessParent::sInstancesMutex; 54LLMutex *LLPluginProcessParent::sInstancesMutex;
54std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances; 55std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances;
@@ -59,7 +60,7 @@ class LLPluginProcessParentPollThread: public LLThread
59{ 60{
60public: 61public:
61 LLPluginProcessParentPollThread() : 62 LLPluginProcessParentPollThread() :
62 LLThread("LLPluginProcessParentPollThread", gAPRPoolp) 63 LLThread("LLPluginProcessParentPollThread")
63 { 64 {
64 } 65 }
65protected: 66protected:
@@ -84,12 +85,11 @@ protected:
84 85
85}; 86};
86 87
87LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): 88LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
88 mIncomingQueueMutex(gAPRPoolp)
89{ 89{
90 if(!sInstancesMutex) 90 if(!sInstancesMutex)
91 { 91 {
92 sInstancesMutex = new LLMutex(gAPRPoolp); 92 sInstancesMutex = new LLMutex;
93 } 93 }
94 94
95 mOwner = owner; 95 mOwner = owner;
@@ -102,6 +102,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
102 mBlocked = false; 102 mBlocked = false;
103 mPolledInput = false; 103 mPolledInput = false;
104 mPollFD.client_data = NULL; 104 mPollFD.client_data = NULL;
105 mPollFDPool.create();
105 106
106 mPluginLaunchTimeout = 60.0f; 107 mPluginLaunchTimeout = 60.0f;
107 mPluginLockupTimeout = 15.0f; 108 mPluginLockupTimeout = 15.0f;
@@ -119,7 +120,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
119 120
120LLPluginProcessParent::~LLPluginProcessParent() 121LLPluginProcessParent::~LLPluginProcessParent()
121{ 122{
122 LL_DEBUGS("Plugin") << "destructor" << LL_ENDL; 123 LL_DEBUGS("PluginParent") << "destructor" << LL_ENDL;
123 124
124 // Remove from the global list before beginning destruction. 125 // Remove from the global list before beginning destruction.
125 { 126 {
@@ -177,44 +178,28 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
177bool LLPluginProcessParent::accept() 178bool LLPluginProcessParent::accept()
178{ 179{
179 bool result = false; 180 bool result = false;
180
181 apr_status_t status = APR_EGENERAL; 181 apr_status_t status = APR_EGENERAL;
182 apr_socket_t *new_socket = NULL;
183
184 status = apr_socket_accept(
185 &new_socket,
186 mListenSocket->getSocket(),
187 gAPRPoolp);
188 182
183 mSocket = LLSocket::create(status, mListenSocket);
189 184
190 if(status == APR_SUCCESS) 185 if(status == APR_SUCCESS)
191 { 186 {
192// llinfos << "SUCCESS" << llendl; 187// llinfos << "SUCCESS" << llendl;
193 // Success. Create a message pipe on the new socket 188 // Success. Create a message pipe on the new socket
194
195 // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor!
196 apr_pool_t* new_pool = NULL;
197 status = apr_pool_create(&new_pool, gAPRPoolp);
198
199 mSocket = LLSocket::create(new_socket, new_pool);
200 new LLPluginMessagePipe(this, mSocket); 189 new LLPluginMessagePipe(this, mSocket);
201 190
202 result = true; 191 result = true;
203 } 192 }
204 else if(APR_STATUS_IS_EAGAIN(status))
205 {
206// llinfos << "EAGAIN" << llendl;
207
208 // No incoming connections. This is not an error.
209 status = APR_SUCCESS;
210 }
211 else 193 else
212 { 194 {
213// llinfos << "Error:" << llendl; 195 mSocket.reset();
214 ll_apr_warn_status(status); 196 // EAGAIN means "No incoming connections". This is not an error.
215 197 if (!APR_STATUS_IS_EAGAIN(status))
216 // Some other error. 198 {
217 errorState(); 199 // Some other error.
200 ll_apr_warn_status(status);
201 errorState();
202 }
218 } 203 }
219 204
220 return result; 205 return result;
@@ -264,10 +249,10 @@ void LLPluginProcessParent::idle(void)
264 else if(mSocketError != APR_SUCCESS) 249 else if(mSocketError != APR_SUCCESS)
265 { 250 {
266 // The socket is in an error state -- the plugin is gone. 251 // The socket is in an error state -- the plugin is gone.
267 LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; 252 LL_WARNS("PluginParent") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL;
268 errorState(); 253 errorState();
269 } 254 }
270 } 255 }
271 256
272 // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). 257 // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState().
273 // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return. 258 // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return.
@@ -283,7 +268,7 @@ void LLPluginProcessParent::idle(void)
283 268
284 apr_status_t status = APR_SUCCESS; 269 apr_status_t status = APR_SUCCESS;
285 apr_sockaddr_t* addr = NULL; 270 apr_sockaddr_t* addr = NULL;
286 mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); 271 mListenSocket = LLSocket::create(LLSocket::STREAM_TCP);
287 mBoundPort = 0; 272 mBoundPort = 0;
288 273
289 // This code is based on parts of LLSocket::create() in lliosocket.cpp. 274 // This code is based on parts of LLSocket::create() in lliosocket.cpp.
@@ -294,7 +279,7 @@ void LLPluginProcessParent::idle(void)
294 APR_INET, 279 APR_INET,
295 0, // port 0 = ephemeral ("find me a port") 280 0, // port 0 = ephemeral ("find me a port")
296 0, 281 0,
297 gAPRPoolp); 282 AIAPRRootPool::get()());
298 283
299 if(ll_apr_warn_status(status)) 284 if(ll_apr_warn_status(status))
300 { 285 {
@@ -327,15 +312,15 @@ void LLPluginProcessParent::idle(void)
327 312
328 if(mBoundPort == 0) 313 if(mBoundPort == 0)
329 { 314 {
330 LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL; 315 LL_WARNS("PluginParent") << "Bound port number unknown, bailing out." << LL_ENDL;
331 316
332 killSockets(); 317 killSockets();
333 errorState(); 318 errorState();
334 break; 319 break;
335 } 320 }
336 } 321 }
337 322
338 LL_DEBUGS("Plugin") << "Bound tcp socket to port: " << addr->port << LL_ENDL; 323 LL_DEBUGS("PluginParent") << "Bound tcp socket to port: " << addr->port << LL_ENDL;
339 324
340 // Make the listen socket non-blocking 325 // Make the listen socket non-blocking
341 status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1); 326 status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1);
@@ -458,8 +443,8 @@ void LLPluginProcessParent::idle(void)
458 break; 443 break;
459 444
460 case STATE_HELLO: 445 case STATE_HELLO:
461 LL_DEBUGS("Plugin") << "received hello message" << LL_ENDL; 446 LL_DEBUGS("PluginParent") << "received hello message" << LL_ENDL;
462 447
463 // Send the message to load the plugin 448 // Send the message to load the plugin
464 { 449 {
465 LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); 450 LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin");
@@ -492,7 +477,7 @@ void LLPluginProcessParent::idle(void)
492 } 477 }
493 else if(pluginLockedUp()) 478 else if(pluginLockedUp())
494 { 479 {
495 LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << LL_ENDL; 480 LL_WARNS("PluginParent") << "timeout in exiting state, bailing out" << LL_ENDL;
496 errorState(); 481 errorState();
497 } 482 }
498 break; 483 break;
@@ -589,11 +574,11 @@ void LLPluginProcessParent::sendMessage(const LLPluginMessage &message)
589 // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked. 574 // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked.
590 mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); 575 mHeartbeat.setTimerExpirySec(mPluginLockupTimeout);
591 } 576 }
592 577
593 std::string buffer = message.generate(); 578 std::string buffer = message.generate();
594 LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL; 579 LL_DEBUGS("PluginParent") << "Sending: " << buffer << LL_ENDL;
595 writeMessageRaw(buffer); 580 writeMessageRaw(buffer);
596 581
597 // Try to send message immediately. 582 // Try to send message immediately.
598 if(mMessagePipe) 583 if(mMessagePipe)
599 { 584 {
@@ -617,7 +602,8 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe)
617 if(message_pipe != NULL) 602 if(message_pipe != NULL)
618 { 603 {
619 // Set up the apr_pollfd_t 604 // Set up the apr_pollfd_t
620 mPollFD.p = gAPRPoolp; 605
606 mPollFD.p = mPollFDPool();
621 mPollFD.desc_type = APR_POLL_SOCKET; 607 mPollFD.desc_type = APR_POLL_SOCKET;
622 mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; 608 mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP;
623 mPollFD.rtnevents = 0; 609 mPollFD.rtnevents = 0;
@@ -664,6 +650,7 @@ void LLPluginProcessParent::updatePollset()
664 // delete the existing pollset. 650 // delete the existing pollset.
665 apr_pollset_destroy(sPollSet); 651 apr_pollset_destroy(sPollSet);
666 sPollSet = NULL; 652 sPollSet = NULL;
653 sPollSetPool.destroy();
667 } 654 }
668 655
669 std::list<LLPluginProcessParent*>::iterator iter; 656 std::list<LLPluginProcessParent*>::iterator iter;
@@ -686,12 +673,14 @@ void LLPluginProcessParent::updatePollset()
686 { 673 {
687#ifdef APR_POLLSET_NOCOPY 674#ifdef APR_POLLSET_NOCOPY
688 // The pollset doesn't exist yet. Create it now. 675 // The pollset doesn't exist yet. Create it now.
689 apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY); 676 sPollSetPool.create();
677 apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY);
690 if(status != APR_SUCCESS) 678 if(status != APR_SUCCESS)
691 { 679 {
692#endif // APR_POLLSET_NOCOPY 680#endif // APR_POLLSET_NOCOPY
693 LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; 681 LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL;
694 sPollSet = NULL; 682 sPollSet = NULL;
683 sPollSetPool.destroy();
695#ifdef APR_POLLSET_NOCOPY 684#ifdef APR_POLLSET_NOCOPY
696 } 685 }
697 else 686 else
@@ -851,8 +840,8 @@ void LLPluginProcessParent::servicePoll()
851 840
852void LLPluginProcessParent::receiveMessageRaw(const std::string &message) 841void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
853{ 842{
854 LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL; 843 LL_DEBUGS("PluginParent") << "Received: " << message << LL_ENDL;
855 844
856 LLPluginMessage parsed; 845 LLPluginMessage parsed;
857 if(parsed.parse(message) != -1) 846 if(parsed.parse(message) != -1)
858 { 847 {
@@ -918,19 +907,19 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
918 } 907 }
919 else 908 else
920 { 909 {
921 LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL; 910 LL_WARNS("PluginParent") << "received hello message in wrong state -- bailing out" << LL_ENDL;
922 errorState(); 911 errorState();
923 } 912 }
924 913
925 } 914 }
926 else if(message_name == "load_plugin_response") 915 else if(message_name == "load_plugin_response")
927 { 916 {
928 if(mState == STATE_LOADING) 917 if(mState == STATE_LOADING)
929 { 918 {
930 // Plugin has been loaded. 919 // Plugin has been loaded.
931 920
932 mPluginVersionString = message.getValue("plugin_version"); 921 mPluginVersionString = message.getValue("plugin_version");
933 LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL; 922 LL_INFOS("PluginParent") << "plugin version string: " << mPluginVersionString << LL_ENDL;
934 923
935 // Check which message classes/versions the plugin supports. 924 // Check which message classes/versions the plugin supports.
936 // TODO: check against current versions 925 // TODO: check against current versions
@@ -939,9 +928,9 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
939 LLSD::map_iterator iter; 928 LLSD::map_iterator iter;
940 for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++) 929 for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++)
941 { 930 {
942 LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL; 931 LL_INFOS("PluginParent") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL;
943 } 932 }
944 933
945 // Send initial sleep time 934 // Send initial sleep time
946 setSleepTime(mSleepTime, true); 935 setSleepTime(mSleepTime, true);
947 936
@@ -949,7 +938,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
949 } 938 }
950 else 939 else
951 { 940 {
952 LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL; 941 LL_WARNS("PluginParent") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL;
953 errorState(); 942 errorState();
954 } 943 }
955 } 944 }
@@ -960,8 +949,8 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
960 949
961 mCPUUsage = message.getValueReal("cpu_usage"); 950 mCPUUsage = message.getValueReal("cpu_usage");
962 951
963 LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL; 952 LL_DEBUGS("PluginSpam") << "cpu usage reported as " << mCPUUsage << LL_ENDL;
964 953
965 } 954 }
966 else if(message_name == "shm_add_response") 955 else if(message_name == "shm_add_response")
967 { 956 {
@@ -983,7 +972,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
983 } 972 }
984 else 973 else
985 { 974 {
986 LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL; 975 LL_WARNS("PluginParent") << "Unknown internal message from child: " << message_name << LL_ENDL;
987 } 976 }
988 } 977 }
989 else 978 else
@@ -1015,7 +1004,7 @@ std::string LLPluginProcessParent::addSharedMemory(size_t size)
1015 } 1004 }
1016 else 1005 else
1017 { 1006 {
1018 LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL; 1007 LL_WARNS("PluginParent") << "Couldn't create a shared memory segment!" << LL_ENDL;
1019 1008
1020 // Don't leak 1009 // Don't leak
1021 delete region; 1010 delete region;
@@ -1037,7 +1026,7 @@ void LLPluginProcessParent::removeSharedMemory(const std::string &name)
1037 } 1026 }
1038 else 1027 else
1039 { 1028 {
1040 LL_WARNS("Plugin") << "Request to remove an unknown shared memory segment." << LL_ENDL; 1029 LL_WARNS("PluginParent") << "Request to remove an unknown shared memory segment." << LL_ENDL;
1041 } 1030 }
1042} 1031}
1043size_t LLPluginProcessParent::getSharedMemorySize(const std::string &name) 1032size_t LLPluginProcessParent::getSharedMemorySize(const std::string &name)
@@ -1084,25 +1073,25 @@ std::string LLPluginProcessParent::getPluginVersion(void)
1084 1073
1085void LLPluginProcessParent::setState(EState state) 1074void LLPluginProcessParent::setState(EState state)
1086{ 1075{
1087 LL_DEBUGS("Plugin") << "setting state to " << stateToString(state) << LL_ENDL; 1076 LL_DEBUGS("PluginParent") << "setting state to " << stateToString(state) << LL_ENDL;
1088 mState = state; 1077 mState = state;
1089}; 1078};
1090 1079
1091bool LLPluginProcessParent::pluginLockedUpOrQuit() 1080bool LLPluginProcessParent::pluginLockedUpOrQuit()
1092{ 1081{
1093 bool result = false; 1082 bool result = false;
1094 1083
1095 if(!mProcess.isRunning()) 1084 if(!mProcess.isRunning())
1096 { 1085 {
1097 LL_WARNS("Plugin") << "child exited" << LL_ENDL; 1086 LL_WARNS("PluginParent") << "child exited" << LL_ENDL;
1098 result = true; 1087 result = true;
1099 } 1088 }
1100 else if(pluginLockedUp()) 1089 else if(pluginLockedUp())
1101 { 1090 {
1102 LL_WARNS("Plugin") << "timeout" << LL_ENDL; 1091 LL_WARNS("PluginParent") << "timeout" << LL_ENDL;
1103 result = true; 1092 result = true;
1104 } 1093 }
1105 1094
1106 return result; 1095 return result;
1107} 1096}
1108 1097
diff --git a/linden/indra/llplugin/llpluginprocessparent.h b/linden/indra/llplugin/llpluginprocessparent.h
index 95f5f70..bba3643 100755
--- a/linden/indra/llplugin/llpluginprocessparent.h
+++ b/linden/indra/llplugin/llpluginprocessparent.h
@@ -186,7 +186,9 @@ private:
186 186
187 static bool sUseReadThread; 187 static bool sUseReadThread;
188 apr_pollfd_t mPollFD; 188 apr_pollfd_t mPollFD;
189 AIAPRPool mPollFDPool;
189 static apr_pollset_t *sPollSet; 190 static apr_pollset_t *sPollSet;
191 static AIAPRPool sPollSetPool;
190 static bool sPollsetNeedsRebuild; 192 static bool sPollsetNeedsRebuild;
191 static LLMutex *sInstancesMutex; 193 static LLMutex *sInstancesMutex;
192 static std::list<LLPluginProcessParent*> sInstances; 194 static std::list<LLPluginProcessParent*> sInstances;
diff --git a/linden/indra/llplugin/llpluginsharedmemory.cpp b/linden/indra/llplugin/llpluginsharedmemory.cpp
index e8a411a..6becb8d 100755
--- a/linden/indra/llplugin/llpluginsharedmemory.cpp
+++ b/linden/indra/llplugin/llpluginsharedmemory.cpp
@@ -84,6 +84,8 @@
84 #include <sys/mman.h> 84 #include <sys/mman.h>
85 #include <errno.h> 85 #include <errno.h>
86#elif USE_WIN32_SHARED_MEMORY 86#elif USE_WIN32_SHARED_MEMORY
87# define WIN32_LEAN_AND_MEAN
88# include <winsock2.h>
87#include <windows.h> 89#include <windows.h>
88#endif // USE_APR_SHARED_MEMORY 90#endif // USE_APR_SHARED_MEMORY
89 91
@@ -201,7 +203,8 @@ bool LLPluginSharedMemory::create(size_t size)
201 mName += createName(); 203 mName += createName();
202 mSize = size; 204 mSize = size;
203 205
204 apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp ); 206 mPool.create();
207 apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), mPool());
205 208
206 if(ll_apr_warn_status(status)) 209 if(ll_apr_warn_status(status))
207 { 210 {
@@ -224,7 +227,7 @@ bool LLPluginSharedMemory::destroy(void)
224 } 227 }
225 mImpl->mAprSharedMemory = NULL; 228 mImpl->mAprSharedMemory = NULL;
226 } 229 }
227 230 mPool.destroy();
228 return true; 231 return true;
229} 232}
230 233
@@ -233,7 +236,8 @@ bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
233 mName = name; 236 mName = name;
234 mSize = size; 237 mSize = size;
235 238
236 apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp ); 239 mPool.create();
240 apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), mPool() );
237 241
238 if(ll_apr_warn_status(status)) 242 if(ll_apr_warn_status(status))
239 { 243 {
@@ -255,6 +259,7 @@ bool LLPluginSharedMemory::detach(void)
255 } 259 }
256 mImpl->mAprSharedMemory = NULL; 260 mImpl->mAprSharedMemory = NULL;
257 } 261 }
262 mPool.destroy();
258 263
259 return true; 264 return true;
260} 265}
diff --git a/linden/indra/llplugin/llpluginsharedmemory.h b/linden/indra/llplugin/llpluginsharedmemory.h
index 081d311..669a3e4 100755
--- a/linden/indra/llplugin/llpluginsharedmemory.h
+++ b/linden/indra/llplugin/llpluginsharedmemory.h
@@ -35,6 +35,8 @@
35#ifndef LL_LLPLUGINSHAREDMEMORY_H 35#ifndef LL_LLPLUGINSHAREDMEMORY_H
36#define LL_LLPLUGINSHAREDMEMORY_H 36#define LL_LLPLUGINSHAREDMEMORY_H
37 37
38#include "aiaprpool.h"
39
38class LLPluginSharedMemoryPlatformImpl; 40class LLPluginSharedMemoryPlatformImpl;
39 41
40/** 42/**
@@ -115,6 +117,7 @@ private:
115 bool close(void); 117 bool close(void);
116 bool unlink(void); 118 bool unlink(void);
117 119
120 AIAPRPool mPool;
118 std::string mName; 121 std::string mName;
119 size_t mSize; 122 size_t mSize;
120 void *mMappedAddress; 123 void *mMappedAddress;
diff --git a/linden/indra/llplugin/slplugin/slplugin.cpp b/linden/indra/llplugin/slplugin/slplugin.cpp
index 64c087b..878577b 100755
--- a/linden/indra/llplugin/slplugin/slplugin.cpp
+++ b/linden/indra/llplugin/slplugin/slplugin.cpp
@@ -78,6 +78,8 @@ static void crash_handler(int sig)
78#endif 78#endif
79 79
80#if LL_WINDOWS 80#if LL_WINDOWS
81# define WIN32_LEAN_AND_MEAN
82# include <winsock2.h>
81#include <windows.h> 83#include <windows.h>
82//////////////////////////////////////////////////////////////////////////////// 84////////////////////////////////////////////////////////////////////////////////
83// Our exception handler - will probably just exit and the host application 85// Our exception handler - will probably just exit and the host application
@@ -183,8 +185,6 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
183int main(int argc, char **argv) 185int main(int argc, char **argv)
184#endif 186#endif
185{ 187{
186 ll_init_apr();
187
188 // Set up llerror logging 188 // Set up llerror logging
189 { 189 {
190 LLError::initForApplication("."); 190 LLError::initForApplication(".");
@@ -400,8 +400,6 @@ int main(int argc, char **argv)
400 400
401 delete plugin; 401 delete plugin;
402 402
403 ll_cleanup_apr();
404
405 return 0; 403 return 0;
406} 404}
407 405
diff --git a/linden/indra/llvfs/llpidlock.h b/linden/indra/llvfs/llpidlock.h
index efcfd91..6103599 100755
--- a/linden/indra/llvfs/llpidlock.h
+++ b/linden/indra/llvfs/llpidlock.h
@@ -39,6 +39,8 @@ class LLFrameTimer;
39 39
40#if LL_WINDOWS //For windows platform. 40#if LL_WINDOWS //For windows platform.
41 41
42# define WIN32_LEAN_AND_MEAN
43# include <winsock2.h>
42#include <windows.h> 44#include <windows.h>
43 45
44#else //Everyone Else 46#else //Everyone Else
diff --git a/linden/indra/llvfs/llvfs.cpp b/linden/indra/llvfs/llvfs.cpp
index dea8c9c..654dfa1 100644
--- a/linden/indra/llvfs/llvfs.cpp
+++ b/linden/indra/llvfs/llvfs.cpp
@@ -237,7 +237,7 @@ const S32 LLVFSFileBlock::SERIAL_SIZE = 34;
237LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash) 237LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)
238: mRemoveAfterCrash(remove_after_crash) 238: mRemoveAfterCrash(remove_after_crash)
239{ 239{
240 mDataMutex = new LLMutex(0); 240 mDataMutex = new LLMutex;
241 241
242 S32 i; 242 S32 i;
243 for (i = 0; i < VFSLOCK_COUNT; i++) 243 for (i = 0; i < VFSLOCK_COUNT; i++)
diff --git a/linden/indra/llwindow/GL/glh_extensions.h b/linden/indra/llwindow/GL/glh_extensions.h
index b936b5d..5b149c9 100644
--- a/linden/indra/llwindow/GL/glh_extensions.h
+++ b/linden/indra/llwindow/GL/glh_extensions.h
@@ -17,6 +17,8 @@
17#include <stdio.h> 17#include <stdio.h>
18 18
19#ifdef _WIN32 19#ifdef _WIN32
20# define WIN32_LEAN_AND_MEAN
21# include <winsock2.h>
20# include <windows.h> 22# include <windows.h>
21#endif 23#endif
22 24
diff --git a/linden/indra/media_plugins/CMakeLists.txt b/linden/indra/media_plugins/CMakeLists.txt
index a4c6b18..7c224b4 100755
--- a/linden/indra/media_plugins/CMakeLists.txt
+++ b/linden/indra/media_plugins/CMakeLists.txt
@@ -8,8 +8,14 @@ if (LINUX)
8 add_subdirectory(gstreamer010) 8 add_subdirectory(gstreamer010)
9endif (LINUX) 9endif (LINUX)
10 10
11if (WINDOWS OR DARWIN) 11# We use gstreamer for audio, quicktime for media on win-- MC
12if (WINDOWS)
13 add_subdirectory(gstreamer010)
14 add_subdirectory(quicktime)
15endif (WINDOWS)
16
17if (DARWIN)
12 add_subdirectory(quicktime) 18 add_subdirectory(quicktime)
13endif (WINDOWS OR DARWIN) 19endif (DARWIN)
14 20
15add_subdirectory(example) 21add_subdirectory(example)
diff --git a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt
index 4401e64..e405dc6 100644
--- a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -36,9 +36,15 @@ set(media_plugin_gstreamer010_SOURCE_FILES
36 ) 36 )
37 37
38set(media_plugin_gstreamer010_HEADER_FILES 38set(media_plugin_gstreamer010_HEADER_FILES
39 llmediaimplgstreamer.h
39 llmediaimplgstreamervidplug.h 40 llmediaimplgstreamervidplug.h
40 llmediaimplgstreamertriviallogging.h 41 llmediaimplgstreamertriviallogging.h
41 ) 42 )
43
44set_source_files_properties(${media_plugin_gstreamer010_HEADER_FILES}
45 PROPERTIES HEADER_FILE_ONLY TRUE)
46
47list(APPEND media_plugin_gstreamer010_SOURCE_FILES ${media_plugin_gstreamer010_HEADER_FILES})
42 48
43add_library(media_plugin_gstreamer010 49add_library(media_plugin_gstreamer010
44 SHARED 50 SHARED
diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
index bb90aa1..7917232 100755
--- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
+++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
@@ -41,7 +41,7 @@
41///////////////////////////////////////////////////////////////////////// 41/////////////////////////////////////////////////////////////////////////
42// Debug/Info/Warning macros. 42// Debug/Info/Warning macros.
43#if LL_WINDOWS 43#if LL_WINDOWS
44#include <process.h> 44#include <windows.h>
45#define LL_GETPID GetCurrentProcessId 45#define LL_GETPID GetCurrentProcessId
46#else 46#else
47#include <sys/types.h> 47#include <sys/types.h>
diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
index ed6d920..7e2833a 100755
--- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
+++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
@@ -83,6 +83,9 @@ public:
83 gboolean processGSTEvents(GstBus *bus, 83 gboolean processGSTEvents(GstBus *bus,
84 GstMessage *message); 84 GstMessage *message);
85 85
86 // basic log file writing
87 static bool writeToLog(char* str, ...);
88
86private: 89private:
87 std::string getVersion(); 90 std::string getVersion();
88 bool navigateTo( const std::string urlIn ); 91 bool navigateTo( const std::string urlIn );
@@ -178,8 +181,7 @@ MediaPluginGStreamer010::MediaPluginGStreamer010(
178 mVideoSink ( NULL ), 181 mVideoSink ( NULL ),
179 mCommand ( COMMAND_NONE ) 182 mCommand ( COMMAND_NONE )
180{ 183{
181 std::ostringstream str; 184 writeToLog("MediaPluginGStreamer010 PID=%u", U32(LL_GETPID()));
182 INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(LL_GETPID()));
183} 185}
184 186
185/////////////////////////////////////////////////////////////////////////////// 187///////////////////////////////////////////////////////////////////////////////
@@ -199,6 +201,29 @@ static char* get_gst_state_name(GstState state)
199} 201}
200#endif // LL_GST_REPORT_STATE_CHANGES 202#endif // LL_GST_REPORT_STATE_CHANGES
201 203
204// static
205bool MediaPluginGStreamer010::writeToLog(char* str, ...)
206{
207 LLFILE* fp = LLFile::fopen("media_plugin_gstreamer010.log", "a");
208
209 if (!fp)
210 {
211 return false;
212 }
213
214 time_t timeptr = time(NULL);
215 struct tm* ltime = localtime(&timeptr);
216 fprintf(fp, "[%d:%d:%d] ", ltime->tm_hour, ltime->tm_min, ltime->tm_sec);
217 va_list arglist;
218 va_start(arglist, str);
219 vfprintf(fp, str, arglist);
220 va_end(arglist);
221 fprintf(fp, " \n");
222 fclose(fp);
223
224 return true;
225}
226
202gboolean 227gboolean
203MediaPluginGStreamer010::processGSTEvents(GstBus *bus, 228MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
204 GstMessage *message) 229 GstMessage *message)
@@ -206,17 +231,12 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
206 if (!message) 231 if (!message)
207 return TRUE; // shield against GStreamer bug 232 return TRUE; // shield against GStreamer bug
208 233
234 // TODO: grok 'duration' message type
209 if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && 235 if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
210 GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) 236 GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING &&
237 GST_MESSAGE_TYPE(message) != GST_MESSAGE_TAG)
211 { 238 {
212 DEBUGMSG("Got GST message type: %s", 239 writeToLog("Got GST message type: %s", GST_MESSAGE_TYPE_NAME (message));
213 GST_MESSAGE_TYPE_NAME (message));
214 }
215 else
216 {
217 // TODO: grok 'duration' message type
218 DEBUGMSG("Got GST message type: %s",
219 GST_MESSAGE_TYPE_NAME (message));
220 } 240 }
221 241
222 switch (GST_MESSAGE_TYPE (message)) 242 switch (GST_MESSAGE_TYPE (message))
@@ -226,7 +246,7 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
226 // NEEDS GST 0.10.11+ and America discovered by C.Columbus 246 // NEEDS GST 0.10.11+ and America discovered by C.Columbus
227 gint percent = 0; 247 gint percent = 0;
228 gst_message_parse_buffering(message, &percent); 248 gst_message_parse_buffering(message, &percent);
229 DEBUGMSG("GST buffering: %d%%", percent); 249 writeToLog("GST buffering: %d%%", percent);
230 250
231 break; 251 break;
232 } 252 }
@@ -240,7 +260,7 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
240 &pending_state); 260 &pending_state);
241 #ifdef LL_GST_REPORT_STATE_CHANGES 261 #ifdef LL_GST_REPORT_STATE_CHANGES
242 // not generally very useful, and rather spammy. 262 // not generally very useful, and rather spammy.
243 DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", 263 writeToLog("state change (old,<new>,pending): %s,<%s>,%s",
244 get_gst_state_name(old_state), 264 get_gst_state_name(old_state),
245 get_gst_state_name(new_state), 265 get_gst_state_name(new_state),
246 get_gst_state_name(pending_state)); 266 get_gst_state_name(pending_state));
@@ -270,7 +290,7 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
270 gchar *debug = NULL; 290 gchar *debug = NULL;
271 291
272 gst_message_parse_error (message, &err, &debug); 292 gst_message_parse_error (message, &err, &debug);
273 WARNMSG("GST error: %s", err?err->message:"(unknown)"); 293 writeToLog("GST error: %s", err?err->message:"(unknown)");
274 if (err) 294 if (err)
275 g_error_free (err); 295 g_error_free (err);
276 g_free (debug); 296 g_free (debug);
@@ -287,7 +307,7 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
287 gchar *debug = NULL; 307 gchar *debug = NULL;
288 308
289 gst_message_parse_info (message, &err, &debug); 309 gst_message_parse_info (message, &err, &debug);
290 INFOMSG("GST info: %s", err?err->message:"(unknown)"); 310 writeToLog("GST info: %s", err?err->message:"(unknown)");
291 if (err) 311 if (err)
292 g_error_free (err); 312 g_error_free (err);
293 g_free (debug); 313 g_free (debug);
@@ -300,7 +320,7 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
300 gchar *debug = NULL; 320 gchar *debug = NULL;
301 321
302 gst_message_parse_warning (message, &err, &debug); 322 gst_message_parse_warning (message, &err, &debug);
303 WARNMSG("GST warning: %s", err?err->message:"(unknown)"); 323 writeToLog("GST warning: %s", err?err->message:"(unknown)");
304 if (err) 324 if (err)
305 g_error_free (err); 325 g_error_free (err);
306 g_free (debug); 326 g_free (debug);
@@ -317,7 +337,7 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
317 337
318 if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) ) 338 if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) )
319 { 339 {
320 //WARMING("Title: %s", title); 340 //writeToLog("Title: %s", title);
321 std::string newtitle(title); 341 std::string newtitle(title);
322 gst_tag_list_free(new_tags); 342 gst_tag_list_free(new_tags);
323 343
@@ -336,10 +356,10 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
336 case GST_MESSAGE_EOS: 356 case GST_MESSAGE_EOS:
337 { 357 {
338 /* end-of-stream */ 358 /* end-of-stream */
339 DEBUGMSG("GST end-of-stream."); 359 writeToLog("GST end-of-stream.");
340 if (mIsLooping) 360 if (mIsLooping)
341 { 361 {
342 DEBUGMSG("looping media..."); 362 //writeToLog("looping media...");
343 double eos_pos_sec = 0.0F; 363 double eos_pos_sec = 0.0F;
344 bool got_eos_position = getTimePos(eos_pos_sec); 364 bool got_eos_position = getTimePos(eos_pos_sec);
345 365
@@ -348,7 +368,7 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
348 // if we know that the movie is really short, don't 368 // if we know that the movie is really short, don't
349 // loop it else it can easily become a time-hog 369 // loop it else it can easily become a time-hog
350 // because of GStreamer spin-up overhead 370 // because of GStreamer spin-up overhead
351 DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); 371 writeToLog("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec);
352 // inject a COMMAND_PAUSE 372 // inject a COMMAND_PAUSE
353 mCommand = COMMAND_PAUSE; 373 mCommand = COMMAND_PAUSE;
354 } 374 }
@@ -367,7 +387,7 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
367 else 387 else
368 #endif // LLGST_LOOP_BY_SEEKING 388 #endif // LLGST_LOOP_BY_SEEKING
369 { // use clumsy stop-start to loop 389 { // use clumsy stop-start to loop
370 DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); 390 writeToLog("didn't loop by rewinding - stopping and starting instead...");
371 stop(); 391 stop();
372 play(1.0); 392 play(1.0);
373 } 393 }
@@ -413,7 +433,7 @@ MediaPluginGStreamer010::navigateTo ( const std::string urlIn )
413 433
414 setStatus(STATUS_LOADING); 434 setStatus(STATUS_LOADING);
415 435
416 DEBUGMSG("Setting media URI: %s", urlIn.c_str()); 436 writeToLog("Setting media URI: %s", urlIn.c_str());
417 437
418 mSeekWanted = false; 438 mSeekWanted = false;
419 439
@@ -441,13 +461,13 @@ MediaPluginGStreamer010::update(int milliseconds)
441 if (!mDoneInit) 461 if (!mDoneInit)
442 return false; // error 462 return false; // error
443 463
444 DEBUGMSG("updating media..."); 464 //writeToLog("updating media...");
445 465
446 // sanity check 466 // sanity check
447 if (NULL == mPump || 467 if (NULL == mPump ||
448 NULL == mPlaybin) 468 NULL == mPlaybin)
449 { 469 {
450 DEBUGMSG("dead media..."); 470 writeToLog("dead media...");
451 return false; 471 return false;
452 } 472 }
453 473
@@ -477,7 +497,7 @@ MediaPluginGStreamer010::update(int milliseconds)
477 GST_OBJECT_LOCK(mVideoSink); 497 GST_OBJECT_LOCK(mVideoSink);
478 if (mVideoSink->retained_frame_ready) 498 if (mVideoSink->retained_frame_ready)
479 { 499 {
480 DEBUGMSG("NEW FRAME READY"); 500 writeToLog("NEW FRAME READY");
481 501
482 if (mVideoSink->retained_frame_width != mCurrentWidth || 502 if (mVideoSink->retained_frame_width != mCurrentWidth ||
483 mVideoSink->retained_frame_height != mCurrentHeight) 503 mVideoSink->retained_frame_height != mCurrentHeight)
@@ -508,7 +528,7 @@ MediaPluginGStreamer010::update(int milliseconds)
508 GST_OBJECT_UNLOCK(mVideoSink); 528 GST_OBJECT_UNLOCK(mVideoSink);
509 529
510 mCurrentRowbytes = neww * newd; 530 mCurrentRowbytes = neww * newd;
511 DEBUGMSG("video container resized to %dx%d", 531 writeToLog("video container resized to %dx%d",
512 neww, newh); 532 neww, newh);
513 533
514 mDepth = newd; 534 mDepth = newd;
@@ -536,7 +556,7 @@ MediaPluginGStreamer010::update(int milliseconds)
536 } 556 }
537 557
538 GST_OBJECT_UNLOCK(mVideoSink); 558 GST_OBJECT_UNLOCK(mVideoSink);
539 DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST"); 559 writeToLog("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST");
540 560
541 setDirty(0,0,mCurrentWidth,mCurrentHeight); 561 setDirty(0,0,mCurrentWidth,mCurrentHeight);
542 } 562 }
@@ -547,7 +567,7 @@ MediaPluginGStreamer010::update(int milliseconds)
547 567
548 GST_OBJECT_UNLOCK(mVideoSink); 568 GST_OBJECT_UNLOCK(mVideoSink);
549 569
550 DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize"); 570 writeToLog("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize");
551 } 571 }
552 572
553 return true; 573 return true;
@@ -586,7 +606,7 @@ MediaPluginGStreamer010::mouseMove( int x, int y )
586bool 606bool
587MediaPluginGStreamer010::pause() 607MediaPluginGStreamer010::pause()
588{ 608{
589 DEBUGMSG("pausing media..."); 609 writeToLog("pausing media...");
590 // todo: error-check this? 610 // todo: error-check this?
591 gst_element_set_state(mPlaybin, GST_STATE_PAUSED); 611 gst_element_set_state(mPlaybin, GST_STATE_PAUSED);
592 return true; 612 return true;
@@ -595,7 +615,7 @@ MediaPluginGStreamer010::pause()
595bool 615bool
596MediaPluginGStreamer010::stop() 616MediaPluginGStreamer010::stop()
597{ 617{
598 DEBUGMSG("stopping media..."); 618 writeToLog("stopping media...");
599 // todo: error-check this? 619 // todo: error-check this?
600 gst_element_set_state(mPlaybin, GST_STATE_READY); 620 gst_element_set_state(mPlaybin, GST_STATE_READY);
601 return true; 621 return true;
@@ -605,8 +625,7 @@ bool
605MediaPluginGStreamer010::play(double rate) 625MediaPluginGStreamer010::play(double rate)
606{ 626{
607 // NOTE: we don't actually support non-natural rate. 627 // NOTE: we don't actually support non-natural rate.
608 628 writeToLog("playing media... rate=%f", rate);
609 DEBUGMSG("playing media... rate=%f", rate);
610 // todo: error-check this? 629 // todo: error-check this?
611 gst_element_set_state(mPlaybin, GST_STATE_PLAYING); 630 gst_element_set_state(mPlaybin, GST_STATE_PLAYING);
612 return true; 631 return true;
@@ -643,7 +662,7 @@ MediaPluginGStreamer010::seek(double time_sec)
643 GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), 662 GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND),
644 GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); 663 GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
645 } 664 }
646 DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d", 665 writeToLog("MEDIA SEEK REQUEST to %f sec result was %d",
647 float(time_sec), int(success)); 666 float(time_sec), int(success));
648 return success; 667 return success;
649} 668}
@@ -697,7 +716,7 @@ MediaPluginGStreamer010::load()
697 716
698 setStatus(STATUS_LOADING); 717 setStatus(STATUS_LOADING);
699 718
700 DEBUGMSG("setting up media..."); 719 writeToLog("setting up media...");
701 720
702 mIsLooping = false; 721 mIsLooping = false;
703 mVolume = (float) 0.1234567; // minor hack to force an initial volume update 722 mVolume = (float) 0.1234567; // minor hack to force an initial volume update
@@ -736,7 +755,7 @@ MediaPluginGStreamer010::load()
736 GST_SLVIDEO(gst_element_factory_make ("private-slvideo", "slvideo")); 755 GST_SLVIDEO(gst_element_factory_make ("private-slvideo", "slvideo"));
737 if (!mVideoSink) 756 if (!mVideoSink)
738 { 757 {
739 WARNMSG("Could not instantiate private-slvideo element."); 758 writeToLog("Could not instantiate private-slvideo element.");
740 // todo: cleanup. 759 // todo: cleanup.
741 setStatus(STATUS_ERROR); 760 setStatus(STATUS_ERROR);
742 return false; // error 761 return false; // error
@@ -755,7 +774,7 @@ MediaPluginGStreamer010::unload ()
755 if (!mDoneInit) 774 if (!mDoneInit)
756 return false; // error 775 return false; // error
757 776
758 DEBUGMSG("unloading media..."); 777 writeToLog("unloading media...");
759 778
760 // stop getting callbacks for this bus 779 // stop getting callbacks for this bus
761 g_source_remove(mBusWatchID); 780 g_source_remove(mBusWatchID);
@@ -813,7 +832,7 @@ MediaPluginGStreamer010::startup()
813 "libgstvideo-0.10.so.0") ) 832 "libgstvideo-0.10.so.0") )
814#endif 833#endif
815 { 834 {
816 WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); 835 writeToLog("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled.");
817 return false; 836 return false;
818 } 837 }
819*/ 838*/
@@ -823,7 +842,7 @@ MediaPluginGStreamer010::startup()
823// } 842// }
824// else 843// else
825// { 844// {
826// WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); 845// writeToLog("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught.");
827// } 846// }
828/* 847/*
829#if LL_LINUX 848#if LL_LINUX
@@ -866,12 +885,12 @@ MediaPluginGStreamer010::startup()
866 { 885 {
867 if (err) 886 if (err)
868 { 887 {
869 WARNMSG("GST init failed: %s", err->message); 888 writeToLog("GST init failed: %s", err->message);
870 g_error_free(err); 889 g_error_free(err);
871 } 890 }
872 else 891 else
873 { 892 {
874 WARNMSG("GST init failed for unspecified reason."); 893 writeToLog("GST init failed for unspecified reason.");
875 } 894 }
876 return false; 895 return false;
877 } 896 }
@@ -882,22 +901,22 @@ MediaPluginGStreamer010::startup()
882 901
883 // Init our custom plugins - only really need do this once. 902 // Init our custom plugins - only really need do this once.
884 gst_slvideo_init_class(); 903 gst_slvideo_init_class();
885/* 904
886 // List the plugins GStreamer can find 905 // List the plugins GStreamer can find
887 LL_DEBUGS("MediaImpl") << "Found GStreamer plugins:" << LL_ENDL; 906 writeToLog("Found GStreamer plugins:");
888 GList *list; 907 GList *list;
889 GstRegistry *registry = gst_registry_get_default(); 908 GstRegistry *registry = gst_registry_get_default();
890 std::string loaded = ""; 909 std::string loaded = "No";
891 for (list = gst_registry_get_plugin_list(registry); 910 for (list = gst_registry_get_plugin_list(registry);
892 list != NULL; 911 list != NULL;
893 list = g_list_next(list)) 912 list = g_list_next(list))
894 { 913 {
895 GstPlugin *list_plugin = (GstPlugin *)list->data; 914 GstPlugin *list_plugin = (GstPlugin *)list->data;
896 (bool)gst_plugin_is_loaded(list_plugin) ? loaded = "Yes" : loaded = "No"; 915 if (gst_plugin_is_loaded(list_plugin)) loaded = "Yes";
897 LL_DEBUGS("MediaImpl") << gst_plugin_get_name(list_plugin) << ", loaded? " << loaded << LL_ENDL; 916 writeToLog("%s, loaded? %s", gst_plugin_get_name(list_plugin), loaded.c_str());
898 } 917 }
899 gst_plugin_list_free(list); 918 gst_plugin_list_free(list);
900*/ 919
901 mDoneInit = true; 920 mDoneInit = true;
902 } 921 }
903 922
@@ -941,11 +960,11 @@ void MediaPluginGStreamer010::set_gst_plugin_path()
941 960
942 if( imp_dir == "" ) 961 if( imp_dir == "" )
943 { 962 {
944 WARNMSG("Could not get application directory, not setting GST_PLUGIN_PATH."); 963 writeToLog("Could not get application directory, not setting GST_PLUGIN_PATH.");
945 return; 964 return;
946 } 965 }
947 966
948 DEBUGMSG("Imprudence is installed at %s", imp_dir); 967 writeToLog("Imprudence is installed at %s", imp_dir.c_str());
949 968
950 // ":" on Mac and 'Nix, ";" on Windows 969 // ":" on Mac and 'Nix, ";" on Windows
951 std::string separator = G_SEARCHPATH_SEPARATOR_S; 970 std::string separator = G_SEARCHPATH_SEPARATOR_S;
@@ -955,7 +974,7 @@ void MediaPluginGStreamer010::set_gst_plugin_path()
955 char *old_path = getenv("GST_PLUGIN_PATH"); 974 char *old_path = getenv("GST_PLUGIN_PATH");
956 if(old_path == NULL) 975 if(old_path == NULL)
957 { 976 {
958 DEBUGMSG("Did not find user-set GST_PLUGIN_PATH."); 977 writeToLog("Did not find user-set GST_PLUGIN_PATH.");
959 } 978 }
960 else 979 else
961 { 980 {
@@ -986,11 +1005,11 @@ void MediaPluginGStreamer010::set_gst_plugin_path()
986 1005
987 if( put_result == -1 ) 1006 if( put_result == -1 )
988 { 1007 {
989 WARNMSG("Setting GST_PLUGIN_PATH failed!"); 1008 writeToLog("Setting GST_PLUGIN_PATH failed!");
990 } 1009 }
991 else 1010 else
992 { 1011 {
993 DEBUGMSG("GST_PLUGIN_PATH set to %s", getenv("GST_PLUGIN_PATH")); 1012 writeToLog("GST_PLUGIN_PATH set to %s", getenv("GST_PLUGIN_PATH"));
994 } 1013 }
995 1014
996 // Don't load system plugins. We only want to use ours, to avoid conflicts. 1015 // Don't load system plugins. We only want to use ours, to avoid conflicts.
@@ -1002,7 +1021,7 @@ void MediaPluginGStreamer010::set_gst_plugin_path()
1002 1021
1003 if( put_result == -1 ) 1022 if( put_result == -1 )
1004 { 1023 {
1005 WARNMSG("Setting GST_PLUGIN_SYSTEM_PATH=\"\" failed!"); 1024 writeToLog("Setting GST_PLUGIN_SYSTEM_PATH=\"\" failed!");
1006 } 1025 }
1007 1026
1008#endif // LL_WINDOWS || LL_DARWIN 1027#endif // LL_WINDOWS || LL_DARWIN
@@ -1020,7 +1039,7 @@ MediaPluginGStreamer010::sizeChanged()
1020 { 1039 {
1021 mNaturalWidth = mCurrentWidth; 1040 mNaturalWidth = mCurrentWidth;
1022 mNaturalHeight = mCurrentHeight; 1041 mNaturalHeight = mCurrentHeight;
1023 DEBUGMSG("Media NATURAL size better detected as %dx%d", 1042 writeToLog("Media NATURAL size better detected as %dx%d",
1024 mNaturalWidth, mNaturalHeight); 1043 mNaturalWidth, mNaturalHeight);
1025 } 1044 }
1026 1045
@@ -1035,7 +1054,7 @@ MediaPluginGStreamer010::sizeChanged()
1035 message.setValue("name", mTextureSegmentName); 1054 message.setValue("name", mTextureSegmentName);
1036 message.setValueS32("width", mNaturalWidth); 1055 message.setValueS32("width", mNaturalWidth);
1037 message.setValueS32("height", mNaturalHeight); 1056 message.setValueS32("height", mNaturalHeight);
1038 DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); 1057 writeToLog("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight);
1039 sendMessage(message); 1058 sendMessage(message);
1040 } 1059 }
1041} 1060}
@@ -1058,11 +1077,11 @@ MediaPluginGStreamer010::closedown()
1058 1077
1059MediaPluginGStreamer010::~MediaPluginGStreamer010() 1078MediaPluginGStreamer010::~MediaPluginGStreamer010()
1060{ 1079{
1061 DEBUGMSG("MediaPluginGStreamer010 destructor"); 1080 //writeToLog("MediaPluginGStreamer010 destructor");
1062 1081
1063 closedown(); 1082 closedown();
1064 1083
1065 DEBUGMSG("GStreamer010 closing down"); 1084 writeToLog("GStreamer010 closing down");
1066} 1085}
1067 1086
1068 1087
@@ -1085,7 +1104,7 @@ MediaPluginGStreamer010::getVersion()
1085 1104
1086void MediaPluginGStreamer010::receiveMessage(const char *message_string) 1105void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1087{ 1106{
1088 //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl; 1107 //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"";
1089 1108
1090 LLPluginMessage message_in; 1109 LLPluginMessage message_in;
1091 1110
@@ -1106,11 +1125,11 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1106 1125
1107 if ( load() ) 1126 if ( load() )
1108 { 1127 {
1109 DEBUGMSG("GStreamer010 media instance set up"); 1128 writeToLog("GStreamer010 media instance set up");
1110 } 1129 }
1111 else 1130 else
1112 { 1131 {
1113 WARNMSG("GStreamer010 media instance failed to set up"); 1132 writeToLog("GStreamer010 media instance failed to set up");
1114 } 1133 }
1115 1134
1116 message.setValue("plugin_version", getVersion()); 1135 message.setValue("plugin_version", getVersion());
@@ -1137,7 +1156,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1137 std::string name = message_in.getValue("name"); 1156 std::string name = message_in.getValue("name");
1138 1157
1139 std::ostringstream str; 1158 std::ostringstream str;
1140 INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress); 1159 writeToLog("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress);
1141 1160
1142 mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); 1161 mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
1143 } 1162 }
@@ -1145,7 +1164,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1145 { 1164 {
1146 std::string name = message_in.getValue("name"); 1165 std::string name = message_in.getValue("name");
1147 1166
1148 DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str()); 1167 writeToLog("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str());
1149 1168
1150 SharedSegmentMap::iterator iter = mSharedSegments.find(name); 1169 SharedSegmentMap::iterator iter = mSharedSegments.find(name);
1151 if(iter != mSharedSegments.end()) 1170 if(iter != mSharedSegments.end())
@@ -1163,7 +1182,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1163 } 1182 }
1164 else 1183 else
1165 { 1184 {
1166 WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!"); 1185 writeToLog("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!");
1167 } 1186 }
1168 1187
1169 // Send the response so it can be cleaned up. 1188 // Send the response so it can be cleaned up.
@@ -1174,7 +1193,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1174 else 1193 else
1175 { 1194 {
1176 std::ostringstream str; 1195 std::ostringstream str;
1177 INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str()); 1196 writeToLog("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str());
1178 } 1197 }
1179 } 1198 }
1180 else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) 1199 else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
@@ -1217,7 +1236,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1217 S32 texture_height = message_in.getValueS32("texture_height"); 1236 S32 texture_height = message_in.getValueS32("texture_height");
1218 1237
1219 std::ostringstream str; 1238 std::ostringstream str;
1220 INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height); 1239 writeToLog("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height);
1221 1240
1222 LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); 1241 LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
1223 message.setValue("name", name); 1242 message.setValue("name", name);
@@ -1233,8 +1252,8 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1233 SharedSegmentMap::iterator iter = mSharedSegments.find(name); 1252 SharedSegmentMap::iterator iter = mSharedSegments.find(name);
1234 if(iter != mSharedSegments.end()) 1253 if(iter != mSharedSegments.end())
1235 { 1254 {
1236 INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height); 1255 writeToLog("*** Got size change with matching shm, new size is %d x %d", width, height);
1237 INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height); 1256 writeToLog("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height);
1238 1257
1239 mPixels = (unsigned char*)iter->second.mAddress; 1258 mPixels = (unsigned char*)iter->second.mAddress;
1240 mTextureSegmentName = name; 1259 mTextureSegmentName = name;
@@ -1244,7 +1263,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1244 if (texture_width > 1 || 1263 if (texture_width > 1 ||
1245 texture_height > 1) // not a dummy size from the app, a real explicit forced size 1264 texture_height > 1) // not a dummy size from the app, a real explicit forced size
1246 { 1265 {
1247 INFOMSG("**** = REAL RESIZE REQUEST FROM APP"); 1266 writeToLog("**** = REAL RESIZE REQUEST FROM APP");
1248 1267
1249 GST_OBJECT_LOCK(mVideoSink); 1268 GST_OBJECT_LOCK(mVideoSink);
1250 mVideoSink->resize_forced_always = true; 1269 mVideoSink->resize_forced_always = true;
@@ -1326,13 +1345,23 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
1326 } 1345 }
1327 else 1346 else
1328 { 1347 {
1329 INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str()); 1348 writeToLog("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str());
1330 } 1349 }
1331 } 1350 }
1332} 1351}
1333 1352
1334int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) 1353int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
1335{ 1354{
1355 // init log file
1356 LLFILE* fp = LLFile::fopen("media_plugin_gstreamer010.log", "w");
1357 if (fp)
1358 {
1359 time_t timeptr = time(NULL);
1360 fprintf(fp, "%s", asctime(localtime(&timeptr)));
1361 fprintf(fp, "<--- Begin media_plugin_gstreamer010 initialization --->\n");
1362 fclose(fp);
1363 }
1364
1336 if (MediaPluginGStreamer010::startup()) 1365 if (MediaPluginGStreamer010::startup())
1337 { 1366 {
1338 MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data); 1367 MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data);
diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp
index c4c4181..cc3836e 100644
--- a/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp
+++ b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp
@@ -58,7 +58,7 @@ extern "C" {
58#include <pulse/subscribe.h> 58#include <pulse/subscribe.h>
59#include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken. 59#include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken.
60 60
61#include "apr_pools.h" 61#include "aiaprpool.h"
62#include "apr_dso.h" 62#include "apr_dso.h"
63} 63}
64 64
@@ -74,7 +74,7 @@ extern "C" {
74#undef LL_PA_SYM 74#undef LL_PA_SYM
75 75
76static bool sSymsGrabbed = false; 76static bool sSymsGrabbed = false;
77static apr_pool_t *sSymPADSOMemoryPool = NULL; 77static AIAPRPool sSymPADSOMemoryPool;
78static apr_dso_handle_t *sSymPADSOHandleG = NULL; 78static apr_dso_handle_t *sSymPADSOHandleG = NULL;
79 79
80bool grab_pa_syms(std::string pulse_dso_name) 80bool grab_pa_syms(std::string pulse_dso_name)
@@ -93,11 +93,11 @@ bool grab_pa_syms(std::string pulse_dso_name)
93#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0) 93#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0)
94 94
95 //attempt to load the shared library 95 //attempt to load the shared library
96 apr_pool_create(&sSymPADSOMemoryPool, NULL); 96 sSymPADSOMemoryPool.create();
97 97
98 if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle, 98 if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle,
99 pulse_dso_name.c_str(), 99 pulse_dso_name.c_str(),
100 sSymPADSOMemoryPool) )) 100 sSymPADSOMemoryPool()) ))
101 { 101 {
102 INFOMSG("Found DSO: %s", pulse_dso_name.c_str()); 102 INFOMSG("Found DSO: %s", pulse_dso_name.c_str());
103 103
@@ -140,11 +140,7 @@ void ungrab_pa_syms()
140 sSymPADSOHandleG = NULL; 140 sSymPADSOHandleG = NULL;
141 } 141 }
142 142
143 if ( sSymPADSOMemoryPool ) 143 sSymPADSOMemoryPool.destroy();
144 {
145 apr_pool_destroy(sSymPADSOMemoryPool);
146 sSymPADSOMemoryPool = NULL;
147 }
148 144
149 // NULL-out all of the symbols we'd grabbed 145 // NULL-out all of the symbols we'd grabbed
150#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0) 146#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0)
diff --git a/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp b/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp
index f1afea7..64f70c4 100644
--- a/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp
+++ b/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp
@@ -34,6 +34,8 @@
34 */ 34 */
35 35
36#include "volume_catcher.h" 36#include "volume_catcher.h"
37# define WIN32_LEAN_AND_MEAN
38# include <winsock2.h>
37#include <windows.h> 39#include <windows.h>
38#include "llmemory.h" 40#include "llmemory.h"
39class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl> 41class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl>
diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt
index e6c1767..dedced0 100644
--- a/linden/indra/newview/CMakeLists.txt
+++ b/linden/indra/newview/CMakeLists.txt
@@ -88,6 +88,7 @@ set(viewer_SOURCE_FILES
88 impprefsfonts.cpp 88 impprefsfonts.cpp
89 jcfloater_animation_list.cpp 89 jcfloater_animation_list.cpp
90 jcfloaterareasearch.cpp 90 jcfloaterareasearch.cpp
91 kokuastreamingaudio.cpp
91 kowopenregionsettings.cpp 92 kowopenregionsettings.cpp
92 lightshare.cpp 93 lightshare.cpp
93 llagent.cpp 94 llagent.cpp
@@ -172,6 +173,7 @@ set(viewer_SOURCE_FILES
172 llfloatercustomize.cpp 173 llfloatercustomize.cpp
173 llfloaterdaycycle.cpp 174 llfloaterdaycycle.cpp
174 llfloaterdirectory.cpp 175 llfloaterdirectory.cpp
176 llfloaterdisplayname.cpp
175 llfloatereditui.cpp 177 llfloatereditui.cpp
176 llfloaterenvsettings.cpp 178 llfloaterenvsettings.cpp
177 llfloaterevent.cpp 179 llfloaterevent.cpp
@@ -409,6 +411,7 @@ set(viewer_SOURCE_FILES
409 llviewercamera.cpp 411 llviewercamera.cpp
410 llviewercontrol.cpp 412 llviewercontrol.cpp
411 llviewerdisplay.cpp 413 llviewerdisplay.cpp
414 llviewerdisplayname.cpp
412 llviewergenericmessage.cpp 415 llviewergenericmessage.cpp
413 llviewergesture.cpp 416 llviewergesture.cpp
414 llviewerimage.cpp 417 llviewerimage.cpp
@@ -541,6 +544,7 @@ set(viewer_HEADER_FILES
541 impprefsfonts.h 544 impprefsfonts.h
542 jcfloater_animation_list.h 545 jcfloater_animation_list.h
543 jcfloaterareasearch.h 546 jcfloaterareasearch.h
547 kokuastreamingaudio.h
544 lightshare.h 548 lightshare.h
545 lggautocorrectfloater.h 549 lggautocorrectfloater.h
546 lggautocorrect.h 550 lggautocorrect.h
@@ -630,6 +634,7 @@ set(viewer_HEADER_FILES
630 llfloatercustomize.h 634 llfloatercustomize.h
631 llfloaterdaycycle.h 635 llfloaterdaycycle.h
632 llfloaterdirectory.h 636 llfloaterdirectory.h
637 llfloaterdisplayname.h
633 llfloatereditui.h 638 llfloatereditui.h
634 llfloaterenvsettings.h 639 llfloaterenvsettings.h
635 llfloaterevent.h 640 llfloaterevent.h
@@ -871,6 +876,7 @@ set(viewer_HEADER_FILES
871 llviewercamera.h 876 llviewercamera.h
872 llviewercontrol.h 877 llviewercontrol.h
873 llviewerdisplay.h 878 llviewerdisplay.h
879 llviewerdisplayname.h
874 llviewergenericmessage.h 880 llviewergenericmessage.h
875 llviewergesture.h 881 llviewergesture.h
876 llviewerimage.h 882 llviewerimage.h
@@ -1367,7 +1373,7 @@ if (WINDOWS)
1367 DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py 1373 DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
1368 ) 1374 )
1369 1375
1370 add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) # Removed media_plugin_gstreamer010 1376 add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit media_plugin_gstreamer010)
1371 1377
1372 if (PACKAGE) 1378 if (PACKAGE)
1373 add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat) 1379 add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat)
@@ -1583,17 +1589,17 @@ if (WINDOWS)
1583 COMMENT "Copying WebKit Plugin to the runtime folder." 1589 COMMENT "Copying WebKit Plugin to the runtime folder."
1584 ) 1590 )
1585 1591
1586 #get_target_property(BUILT_GSTREAMER_PLUGIN media_plugin_gstreamer010 LOCATION) 1592 get_target_property(BUILT_GSTREAMER_PLUGIN media_plugin_gstreamer010 LOCATION)
1587 # add_custom_command( 1593 add_custom_command(
1588 # TARGET ${VIEWER_BINARY_NAME} POST_BUILD 1594 TARGET ${VIEWER_BINARY_NAME} POST_BUILD
1589 # COMMAND ${CMAKE_COMMAND} 1595 COMMAND ${CMAKE_COMMAND}
1590 # ARGS 1596 ARGS
1591 # -E 1597 -E
1592 # copy_if_different 1598 copy_if_different
1593 # ${BUILT_GSTREAMER_PLUGIN} 1599 ${BUILT_GSTREAMER_PLUGIN}
1594 # ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin 1600 ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin
1595 # COMMENT "Copying Gstreamer Plugin to the runtime folder." 1601 COMMENT "Copying Gstreamer Plugin to the runtime folder."
1596 # ) 1602 )
1597 1603
1598 get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION) 1604 get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION)
1599 add_custom_command( 1605 add_custom_command(
diff --git a/linden/indra/newview/app_settings/cloud.xml b/linden/indra/newview/app_settings/cloud.xml
new file mode 100644
index 0000000..ff9492b
--- /dev/null
+++ b/linden/indra/newview/app_settings/cloud.xml
@@ -0,0 +1,88 @@
1<llsd>
2 <map>
3 <key>AngularVelocity</key>
4 <array>
5 <real>0</real>
6 <real>0</real>
7 <real>0</real>
8 </array>
9 <key>BurstPartCount</key>
10 <integer>1</integer>
11 <key>BurstRadius</key>
12 <real>0.3</real>
13 <key>BurstRate</key>
14 <real>0.02</real>
15 <key>BurstSpeedMax</key>
16 <real>1</real>
17 <key>Endcolor</key>
18 <array>
19 <real>0.75</real>
20 <real>0.47</real>
21 <real>0.81</real>
22 <real>0</real>
23 </array>
24 <key>Endscale</key>
25 <array>
26 <real>0.02</real>
27 <real>0.02</real>
28 </array>
29 <key>InnerAngle</key>
30 <real>3.1415927410125732421875</real>
31 <key>LL_PART_BEAM_MASK</key>
32 <integer>0</integer>
33 <key>LL_PART_BOUNCE_MASK</key>
34 <integer>0</integer>
35 <key>LL_PART_EMISSIVE_MASK</key>
36 <integer>1</integer>
37 <key>LL_PART_FOLLOW_SRC_MASK</key>
38 <integer>0</integer>
39 <key>LL_PART_FOLLOW_VELOCITY_MASK</key>
40 <integer>0</integer>
41 <key>LL_PART_INTERP_COLOR_MASK</key>
42 <integer>1</integer>
43 <key>LL_PART_INTERP_SCALE_MASK</key>
44 <integer>1</integer>
45 <key>LL_PART_SRC_PATTERN_ANGLE</key>
46 <integer>0</integer>
47 <key>LL_PART_SRC_PATTERN_ANGLE_CONE</key>
48 <integer>1</integer>
49 <key>LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY</key>
50 <integer>0</integer>
51 <key>LL_PART_SRC_PATTERN_DROP</key>
52 <integer>0</integer>
53 <key>LL_PART_SRC_PATTERN_EXPLODE</key>
54 <integer>0</integer>
55 <key>LL_PART_TARGET_LINEAR_MASK</key>
56 <integer>0</integer>
57 <key>LL_PART_TARGET_POS_MASK</key>
58 <integer>1</integer>
59 <key>LL_PART_WIND_MASK</key>
60 <integer>0</integer>
61 <key>OuterAngle</key>
62 <real>0</real>
63 <key>PartImageID</key>
64 <string>0000000000000-0000-0000-000000000000</string>
65 <key>ParticleMaxAge</key>
66 <real>0</real>
67 <key>ParticleStartAge</key>
68 <real>0</real>
69 <key>SourceMaxage</key>
70 <real>4</real>
71 <key>Startcolor</key>
72 <array>
73 <real>0.9</real>
74 <real>0.0</real>
75 <real>0.8</real>
76 <real>0.7</real>
77 </array>
78 <key>Startscale</key>
79 <array>
80 <real>0.8</real>
81 <real>0.8</real>
82 </array>
83 <key>TargetId</key>
84 <string>00000000-0000-0000-0000-000000000000</string>
85 <key>BurstSpeedMin</key>
86 <real>0.1</real>
87 </map>
88</llsd>
diff --git a/linden/indra/newview/app_settings/logcontrol.xml b/linden/indra/newview/app_settings/logcontrol.xml
index c94fc51..cdc837d 100644
--- a/linden/indra/newview/app_settings/logcontrol.xml
+++ b/linden/indra/newview/app_settings/logcontrol.xml
@@ -66,7 +66,15 @@
66 66
67 <!--<string>Messaging</string>--> 67 <!--<string>Messaging</string>-->
68 <!--<string>Notifications</string>--> 68 <!--<string>Notifications</string>-->
69 <!--<string>Plugin</string>--> 69 <string>Plugin</string>
70 <string>PluginClassMedia</string>
71 <string>PluginInstance</string>
72 <string>PluginPipe</string>
73 <string>PluginChild</string>
74 <!--<string>PluginSpam</string>-->
75 <string>PluginParent</string>
76 <string>PluginViewerMedia</string>
77
70 <!--<string>Radar</string>--> 78 <!--<string>Radar</string>-->
71 <!--<string>ShaderLoading</string>--> 79 <!--<string>ShaderLoading</string>-->
72 80
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml
index 4c822bf..2d9d810 100644
--- a/linden/indra/newview/app_settings/settings.xml
+++ b/linden/indra/newview/app_settings/settings.xml
@@ -419,6 +419,42 @@
419 <key>Value</key> 419 <key>Value</key>
420 <integer>0</integer> 420 <integer>0</integer>
421 </map> 421 </map>
422
423 <!-- Display Names -->
424 <key>DisplayNamesUsage</key>
425 <map>
426 <key>Comment</key>
427 <string>Usage type for display names: 0 = Legacy name only, 1 = display name only (legacy name when absent), 2 = Display name with legacy name</string>
428 <key>Persist</key>
429 <integer>1</integer>
430 <key>Type</key>
431 <string>U32</string>
432 <key>Value</key>
433 <integer>2</integer>
434 </map>
435 <key>OmitResidentAsLastName</key>
436 <map>
437 <key>Comment</key>
438 <string>Do not display "Resident" as the last name for new residents in their legacy name</string>
439 <key>Persist</key>
440 <integer>1</integer>
441 <key>Type</key>
442 <string>Boolean</string>
443 <key>Value</key>
444 <integer>1</integer>
445 </map>
446 <key>LegacyNamesForFriends</key>
447 <map>
448 <key>Comment</key>
449 <string>When TRUE, forces the use of the legacy names for the friends list and online notifications</string>
450 <key>Persist</key>
451 <integer>1</integer>
452 <key>Type</key>
453 <string>Boolean</string>
454 <key>Value</key>
455 <integer>1</integer>
456 </map>
457
422 <key>EmeraldTemporaryUpload</key> 458 <key>EmeraldTemporaryUpload</key>
423 <map> 459 <map>
424 <key>Comment</key> 460 <key>Comment</key>
@@ -1330,6 +1366,17 @@
1330 <key>Value</key> 1366 <key>Value</key>
1331 <integer>1</integer> 1367 <integer>1</integer>
1332 </map> 1368 </map>
1369 <key>WarnFirstPrivacy</key>
1370 <map>
1371 <key>Comment</key>
1372 <string>Enables FirstPrivacy warning on login</string>
1373 <key>Persist</key>
1374 <integer>1</integer>
1375 <key>Type</key>
1376 <string>Boolean</string>
1377 <key>Value</key>
1378 <integer>1</integer>
1379 </map>
1333 <key>WarnFirstVoiceLicense</key> 1380 <key>WarnFirstVoiceLicense</key>
1334 <map> 1381 <map>
1335 <key>Comment</key> 1382 <key>Comment</key>
diff --git a/linden/indra/newview/chatbar_as_cmdline.cpp b/linden/indra/newview/chatbar_as_cmdline.cpp
index 0593091..b5a7e8c 100644
--- a/linden/indra/newview/chatbar_as_cmdline.cpp
+++ b/linden/indra/newview/chatbar_as_cmdline.cpp
@@ -69,7 +69,7 @@
69#include "llviewerparcelmgr.h" 69#include "llviewerparcelmgr.h"
70#include "llviewerparcelmedia.h" 70#include "llviewerparcelmedia.h"
71#include "llparcel.h" 71#include "llparcel.h"
72#include "llaudioengine.h" 72#include "kokuastreamingaudio.h"
73#include "llviewerparcelmediaautoplay.h" 73#include "llviewerparcelmediaautoplay.h"
74#include "lloverlaybar.h" 74#include "lloverlaybar.h"
75#include "lggautocorrectfloater.h" 75#include "lggautocorrectfloater.h"
@@ -367,7 +367,7 @@ bool cmd_line_chat(std::string revised_text, EChatType type)
367 { 367 {
368 gOverlayBar->toggleMusicPlay(gOverlayBar); 368 gOverlayBar->toggleMusicPlay(gOverlayBar);
369 } 369 }
370 gAudiop->startInternetStream(status); 370 gAudioStream->startInternetStream(status);
371 return false; 371 return false;
372 } 372 }
373 } 373 }
diff --git a/linden/indra/newview/kokuastreamingaudio.cpp b/linden/indra/newview/kokuastreamingaudio.cpp
new file mode 100644
index 0000000..ed606db
--- /dev/null
+++ b/linden/indra/newview/kokuastreamingaudio.cpp
@@ -0,0 +1,129 @@
1 /**
2 * @file kokuastreamingaudio.cpp
3 * @brief Definition of KOKUAStreamingAudio base class for streaming audio support
4 *
5 * $LicenseInfo:firstyear=2011&license=viewergpl$
6 * Kokua Viewer Source Code
7 * Copyright (C) 2011, Armin.Weatherwax (at) googlemail.com
8 * for the Kokua Viewer Team, in special for our Imprudence Viewer.
9 *
10 * The source code in this file ("Source Code") is provided by the author
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in this
13 * distribution, or online at
14 * http://secondlifegrid.net/programs/open_source/licensing/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at
20 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * THIS SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 *
30 * $/LicenseInfo$
31 */
32
33#include "kokuastreamingaudio.h"
34#include "llstreamingaudio.h"
35
36
37KOKUAStreamingAudio* gAudioStream = NULL;
38
39KOKUAStreamingAudio::KOKUAStreamingAudio(LLStreamingAudioInterface *impl) :
40mStreamingAudioImpl (impl)
41{
42
43}
44
45KOKUAStreamingAudio::~KOKUAStreamingAudio()
46{
47 if (mStreamingAudioImpl)
48 {
49 delete mStreamingAudioImpl;
50 mStreamingAudioImpl = NULL;
51 }
52}
53
54LLStreamingAudioInterface* KOKUAStreamingAudio::getStreamingAudioImpl()
55{
56 return mStreamingAudioImpl;
57}
58
59// void KOKUAStreamingAudio::setStreamingAudioImpl(LLStreamingAudioInterface *impl)
60// {
61// mStreamingAudioImpl = impl;
62// }
63
64// virtual
65void KOKUAStreamingAudio::startInternetStream(const std::string& url)
66{
67 if (mStreamingAudioImpl)
68 mStreamingAudioImpl->start(url);
69}
70
71// virtual
72void KOKUAStreamingAudio::stopInternetStream()
73{
74 if (mStreamingAudioImpl)
75 mStreamingAudioImpl->stop();
76}
77
78// virtual
79void KOKUAStreamingAudio::pauseInternetStream(int pause)
80{
81 if (mStreamingAudioImpl)
82 mStreamingAudioImpl->pause(pause);
83}
84
85// virtual
86void KOKUAStreamingAudio::updateInternetStream()
87{
88 if (mStreamingAudioImpl)
89 mStreamingAudioImpl->update();
90}
91
92// virtual
93KOKUAStreamingAudio::KOKUAAudioPlayState KOKUAStreamingAudio::isInternetStreamPlaying()
94{
95 if (mStreamingAudioImpl)
96 return (KOKUAStreamingAudio::KOKUAAudioPlayState) mStreamingAudioImpl->isPlaying();
97
98 return KOKUAStreamingAudio::AUDIO_STOPPED; // Stopped
99}
100
101// virtual
102void KOKUAStreamingAudio::setInternetStreamGain(F32 vol)
103{
104 if (mStreamingAudioImpl)
105 mStreamingAudioImpl->setGain(vol);
106}
107
108F32 KOKUAStreamingAudio::getInternetStreamGain()
109{
110 if (mStreamingAudioImpl)
111 return mStreamingAudioImpl->getGain();
112 else
113 return 1.0f;
114}
115
116// virtual
117std::string KOKUAStreamingAudio::getInternetStreamURL()
118{
119 if (mStreamingAudioImpl)
120 return mStreamingAudioImpl->getURL();
121 else return std::string();
122}
123
124std::string KOKUAStreamingAudio::getVersion()
125{
126 if (mStreamingAudioImpl)
127 return mStreamingAudioImpl->getVersion();
128 else return std::string();
129} \ No newline at end of file
diff --git a/linden/indra/newview/kokuastreamingaudio.h b/linden/indra/newview/kokuastreamingaudio.h
new file mode 100644
index 0000000..eb49f25
--- /dev/null
+++ b/linden/indra/newview/kokuastreamingaudio.h
@@ -0,0 +1,71 @@
1/**
2 * @file kokuastreamingaudio.h
3 * @brief Definition of KOKUAStreamingAudio base class for streaming audio support
4 *
5 * $LicenseInfo:firstyear=2011&license=viewergpl$
6 * Kokua Viewer Source Code
7 * Copyright (C) 2011, Armin.Weatherwax (at) googlemail.com
8 * for the Kokua Viewer Team.
9 *
10 * The source code in this file ("Source Code") is provided by the author
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in this
13 * distribution, or online at
14 * http://secondlifegrid.net/programs/open_source/licensing/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at
20 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * THIS SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 *
30 * $/LicenseInfo$
31 */
32#ifndef KOKUA_STREAMINGAUDIO_H
33#define KOKUA_STREAMINGAUDIO_H
34
35#include "linden_common.h"
36
37class LLStreamingAudioInterface;
38
39class KOKUAStreamingAudio
40{
41public:
42 enum KOKUAAudioPlayState
43 {
44 // isInternetStreamPlaying() returns an *int*, with
45 // 0 = stopped, 1 = playing, 2 = paused.
46 AUDIO_STOPPED = 0,
47 AUDIO_PLAYING = 1,
48 AUDIO_PAUSED = 2
49 };
50
51 KOKUAStreamingAudio(LLStreamingAudioInterface *impl);
52 virtual ~KOKUAStreamingAudio();
53
54 LLStreamingAudioInterface *getStreamingAudioImpl();
55// void setStreamingAudioImpl(LLStreamingAudioInterface *impl);
56 void startInternetStream(const std::string& url);
57 void stopInternetStream();
58 void pauseInternetStream(int pause);
59 void updateInternetStream();
60 KOKUAAudioPlayState isInternetStreamPlaying();
61 void setInternetStreamGain(F32 vol);
62 F32 getInternetStreamGain();
63 std::string getInternetStreamURL();
64 std::string getVersion();
65private:
66 LLStreamingAudioInterface *mStreamingAudioImpl;
67};
68
69extern KOKUAStreamingAudio* gAudioStream;
70
71#endif
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp
index 5a1700a..515d588 100644
--- a/linden/indra/newview/llagent.cpp
+++ b/linden/indra/newview/llagent.cpp
@@ -7488,7 +7488,7 @@ void LLAgent::sendAgentSetAppearance()
7488 param; 7488 param;
7489 param = (LLViewerVisualParam*)mAvatarObject->getNextVisualParam()) 7489 param = (LLViewerVisualParam*)mAvatarObject->getNextVisualParam())
7490 { 7490 {
7491 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) 7491 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) // do not transmit params of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
7492 { 7492 {
7493 msg->nextBlockFast(_PREHASH_VisualParam ); 7493 msg->nextBlockFast(_PREHASH_VisualParam );
7494 7494
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp
index 8aea221..6b98c8e 100644
--- a/linden/indra/newview/llappviewer.cpp
+++ b/linden/indra/newview/llappviewer.cpp
@@ -104,6 +104,7 @@
104#include "llassetstorage.h" 104#include "llassetstorage.h"
105#include "llpolymesh.h" 105#include "llpolymesh.h"
106#include "llcachename.h" 106#include "llcachename.h"
107#include "kokuastreamingaudio.h"
107#include "llaudioengine.h" 108#include "llaudioengine.h"
108#include "llstreamingaudio.h" 109#include "llstreamingaudio.h"
109#include "llviewermenu.h" 110#include "llviewermenu.h"
@@ -920,7 +921,7 @@ bool LLAppViewer::mainLoop()
920 //------------------------------------------- 921 //-------------------------------------------
921 922
922 // Create IO Pump to use for HTTP Requests. 923 // Create IO Pump to use for HTTP Requests.
923 gServicePump = new LLPumpIO(gAPRPoolp); 924 gServicePump = new LLPumpIO;
924 LLHTTPClient::setPump(*gServicePump); 925 LLHTTPClient::setPump(*gServicePump);
925 LLCurl::setCAFile(gDirUtilp->getCAFile()); 926 LLCurl::setCAFile(gDirUtilp->getCAFile());
926 927
@@ -1258,6 +1259,7 @@ bool LLAppViewer::cleanup()
1258 1259
1259 LLPolyMesh::freeAllMeshes(); 1260 LLPolyMesh::freeAllMeshes();
1260 1261
1262 LLAvatarNameCache::cleanupClass();
1261 delete gCacheName; 1263 delete gCacheName;
1262 gCacheName = NULL; 1264 gCacheName = NULL;
1263 1265
@@ -1278,14 +1280,16 @@ bool LLAppViewer::cleanup()
1278 1280
1279 llinfos << "Global stuff deleted" << llendflush; 1281 llinfos << "Global stuff deleted" << llendflush;
1280 1282
1281 if (gAudiop) 1283 if (gAudioStream)
1282 { 1284 {
1283 // shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem. 1285 // shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem.
1284 1286
1285 LLStreamingAudioInterface *sai = gAudiop->getStreamingAudioImpl(); 1287 delete gAudioStream;
1286 delete sai; 1288 gAudioStream = NULL;
1287 gAudiop->setStreamingAudioImpl(NULL); 1289 }
1288 1290
1291 if (gAudiop)
1292 {
1289 // shut down the audio subsystem 1293 // shut down the audio subsystem
1290 1294
1291 bool want_longname = false; 1295 bool want_longname = false;
@@ -1642,19 +1646,38 @@ bool LLAppViewer::initLogging()
1642 LLError::initForApplication( 1646 LLError::initForApplication(
1643 gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); 1647 gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
1644 LLError::setFatalFunction(errorCallback); 1648 LLError::setFatalFunction(errorCallback);
1645
1646 // Remove the last ".old" log file.
1647 std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
1648 "Imprudence.old");
1649 LLFile::remove(old_log_file);
1650 1649
1651 // Rename current log file to ".old" 1650 std::string log_name = "Imprudence.log";
1652 std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
1653 "Imprudence.log");
1654 LLFile::rename(log_file, old_log_file);
1655 1651
1656 // Set the log file to Imprudence.log 1652 const int MAX_ROTATION = 5;
1653 for(int i = MAX_ROTATION; 0 < i; i--)
1654 {
1655 std::ostringstream current;
1656 current << ".";
1657 current << i;
1658
1659 std::ostringstream previous;
1660 if( 1 < i )
1661 {
1662 previous << ".";
1663 previous << i-1;
1664 }
1665
1666 std::string current_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
1667 log_name + current.str());
1668 std::string previous_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
1669 log_name + previous.str());
1657 1670
1671 if (MAX_ROTATION == i)
1672 {
1673 LLFile::remove(current_log_file);
1674 }
1675
1676 LLFile::rename(previous_log_file, current_log_file);
1677 }
1678
1679 // Set the log file to Imprudence.log
1680 std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, log_name);
1658 LLError::logToFile(log_file); 1681 LLError::logToFile(log_file);
1659 1682
1660 // *FIX:Mani no error handling here! 1683 // *FIX:Mani no error handling here!
@@ -1861,6 +1884,7 @@ bool LLAppViewer::initConfiguration()
1861 LLFirstUse::addConfigVariable("FirstVoice"); 1884 LLFirstUse::addConfigVariable("FirstVoice");
1862 LLFirstUse::addConfigVariable("FirstMedia"); 1885 LLFirstUse::addConfigVariable("FirstMedia");
1863 LLFirstUse::addConfigVariable("FirstLoginScreen"); 1886 LLFirstUse::addConfigVariable("FirstLoginScreen");
1887 LLFirstUse::addConfigVariable("FirstPrivacy");
1864 1888
1865// [RLVa:KB] - Checked: RLVa-1.0.3a (2009-09-10) | Added: RLVa-1.0.3a 1889// [RLVa:KB] - Checked: RLVa-1.0.3a (2009-09-10) | Added: RLVa-1.0.3a
1866 //LLFirstUse::addConfigVariable(RLV_SETTING_FIRSTUSE_DETACH); 1890 //LLFirstUse::addConfigVariable(RLV_SETTING_FIRSTUSE_DETACH);
@@ -3296,6 +3320,14 @@ void LLAppViewer::saveFinalSnapshot()
3296 3320
3297void LLAppViewer::loadNameCache() 3321void LLAppViewer::loadNameCache()
3298{ 3322{
3323 // display names cache
3324 std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
3325 llifstream name_cache_stream(filename);
3326 if (name_cache_stream.is_open())
3327 {
3328 LLAvatarNameCache::importFile(name_cache_stream);
3329 }
3330
3299 if (!gCacheName) return; 3331 if (!gCacheName) return;
3300 3332
3301 std::string name_cache; 3333 std::string name_cache;
@@ -3318,6 +3350,14 @@ void LLAppViewer::loadNameCache()
3318 3350
3319void LLAppViewer::saveNameCache() 3351void LLAppViewer::saveNameCache()
3320{ 3352{
3353 // display names cache
3354 std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
3355 llofstream name_cache_stream(filename);
3356 if (name_cache_stream.is_open())
3357 {
3358 LLAvatarNameCache::exportFile(name_cache_stream);
3359 }
3360
3321 if (!gCacheName) return; 3361 if (!gCacheName) return;
3322 3362
3323 std::string name_cache; 3363 std::string name_cache;
@@ -3469,18 +3509,22 @@ void LLAppViewer::idle()
3469 // Initialize the viewer_stats_timer with an already elapsed time 3509 // Initialize the viewer_stats_timer with an already elapsed time
3470 // of SEND_STATS_PERIOD so that the initial stats report will 3510 // of SEND_STATS_PERIOD so that the initial stats report will
3471 // be sent immediately. 3511 // be sent immediately.
3472 static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD); 3512 if(!gDisconnected && gHippoGridManager->getConnectedGrid()->isSecondLife())
3473 reset_statistics();
3474
3475 // Update session stats every large chunk of time
3476 // *FIX: (???) SAMANTHA
3477 /* or don't! part of a larger effort to waste less CPU cycles. -Patrick Sapinski (Sunday, November 29, 2009)
3478 if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
3479 { 3513 {
3480 llinfos << "Transmitting sessions stats" << llendl; 3514 static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD);
3481 send_stats(); 3515 reset_statistics();
3482 viewer_stats_timer.reset(); 3516
3483 } */ 3517 // Update session stats every large chunk of time
3518 // *FIX: (???) SAMANTHA
3519
3520 /* or don't! part of a larger effort to waste less CPU cycles. -Patrick Sapinski (Sunday, November 29, 2009)*/
3521 if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD )
3522 {
3523 llinfos << "Transmitting sessions stats" << llendl;
3524 send_stats();
3525 viewer_stats_timer.reset();
3526 }
3527 }
3484 3528
3485 // Print the object debugging stats 3529 // Print the object debugging stats
3486 static LLFrameTimer object_debug_timer; 3530 static LLFrameTimer object_debug_timer;
@@ -3518,6 +3562,8 @@ void LLAppViewer::idle()
3518 // floating throughout the various object lists. 3562 // floating throughout the various object lists.
3519 // 3563 //
3520 3564
3565 idleNameCache();
3566
3521 gFrameStats.start(LLFrameStats::IDLE_NETWORK); 3567 gFrameStats.start(LLFrameStats::IDLE_NETWORK);
3522 stop_glerror(); 3568 stop_glerror();
3523 idleNetwork(); 3569 idleNetwork();
@@ -3732,6 +3778,10 @@ void LLAppViewer::idle()
3732 const F32 max_audio_decode_time = 0.002f; // 2 ms decode time 3778 const F32 max_audio_decode_time = 0.002f; // 2 ms decode time
3733 gAudiop->idle(max_audio_decode_time); 3779 gAudiop->idle(max_audio_decode_time);
3734 } 3780 }
3781
3782 // update streaming audio
3783 if (gAudioStream)
3784 gAudioStream->updateInternetStream();
3735 } 3785 }
3736 3786
3737 3787
@@ -3895,6 +3945,60 @@ void LLAppViewer::sendLogoutRequest()
3895 } 3945 }
3896} 3946}
3897 3947
3948void LLAppViewer::idleNameCache()
3949{
3950 // Neither old nor new name cache can function before agent has a region
3951 LLViewerRegion* region = gAgent.getRegion();
3952 if (!region) return;
3953
3954 // deal with any queued name requests and replies.
3955 gCacheName->processPending();
3956
3957 // Can't run the new cache until we have the list of capabilities
3958 // for the agent region, and can therefore decide whether to use
3959 // display names or fall back to the old name system.
3960 if (!region->capabilitiesReceived()) return;
3961
3962 // Agent may have moved to a different region, so need to update cap URL
3963 // for name lookups. Can't do this in the cap grant code, as caps are
3964 // granted to neighbor regions before the main agent gets there. Can't
3965 // do it in the move-into-region code because cap not guaranteed to be
3966 // granted yet, for example on teleport.
3967 bool had_capability = LLAvatarNameCache::hasNameLookupURL();
3968 std::string name_lookup_url;
3969 name_lookup_url.reserve(128); // avoid a memory allocation below
3970 name_lookup_url = region->getCapability("GetDisplayNames");
3971 bool have_capability = !name_lookup_url.empty();
3972 if (have_capability)
3973 {
3974 // we have support for display names, use it
3975 U32 url_size = name_lookup_url.size();
3976 // capabilities require URLs with slashes before query params:
3977 // https://<host>:<port>/cap/<uuid>/?ids=<blah>
3978 // but the caps are granted like:
3979 // https://<host>:<port>/cap/<uuid>
3980 if (url_size > 0 && name_lookup_url[url_size-1] != '/')
3981 {
3982 name_lookup_url += '/';
3983 }
3984 LLAvatarNameCache::setNameLookupURL(name_lookup_url);
3985 }
3986 else
3987 {
3988 // Display names not available on this region
3989 LLAvatarNameCache::setNameLookupURL( std::string() );
3990 }
3991
3992 // Error recovery - did we change state?
3993 if (had_capability != have_capability)
3994 {
3995 // name tags are persistant on screen, so make sure they refresh
3996 LLVOAvatar::invalidateNameTags();
3997 }
3998
3999 LLAvatarNameCache::idle();
4000}
4001
3898// 4002//
3899// Handle messages, and all message related stuff 4003// Handle messages, and all message related stuff
3900// 4004//
diff --git a/linden/indra/newview/llappviewer.h b/linden/indra/newview/llappviewer.h
index 7b3230a..42c49de 100644
--- a/linden/indra/newview/llappviewer.h
+++ b/linden/indra/newview/llappviewer.h
@@ -192,6 +192,7 @@ private:
192 192
193 void idle(); 193 void idle();
194 void idleShutdown(); 194 void idleShutdown();
195 void idleNameCache();
195 void idleNetwork(); 196 void idleNetwork();
196 197
197 void sendLogoutRequest(); 198 void sendLogoutRequest();
diff --git a/linden/indra/newview/llappviewerlinux.cpp b/linden/indra/newview/llappviewerlinux.cpp
index 307f925..88ddf7e 100644
--- a/linden/indra/newview/llappviewerlinux.cpp
+++ b/linden/indra/newview/llappviewerlinux.cpp
@@ -129,6 +129,7 @@ int main( int argc, char **argv )
129 } 129 }
130 delete viewer_app_ptr; 130 delete viewer_app_ptr;
131 viewer_app_ptr = NULL; 131 viewer_app_ptr = NULL;
132
132 return 0; 133 return 0;
133} 134}
134 135
diff --git a/linden/indra/newview/llappviewermacosx.cpp b/linden/indra/newview/llappviewermacosx.cpp
index 91de066..d81b6e3 100644
--- a/linden/indra/newview/llappviewermacosx.cpp
+++ b/linden/indra/newview/llappviewermacosx.cpp
@@ -119,6 +119,7 @@ int main( int argc, char **argv )
119 } 119 }
120 delete viewer_app_ptr; 120 delete viewer_app_ptr;
121 viewer_app_ptr = NULL; 121 viewer_app_ptr = NULL;
122
122 return 0; 123 return 0;
123} 124}
124 125
diff --git a/linden/indra/newview/llappviewerwin32.cpp b/linden/indra/newview/llappviewerwin32.cpp
index 0d5b884..1f042bd 100644
--- a/linden/indra/newview/llappviewerwin32.cpp
+++ b/linden/indra/newview/llappviewerwin32.cpp
@@ -78,31 +78,6 @@ extern "C" {
78#endif 78#endif
79#endif 79#endif
80 80
81// Force Imprudence to link against the correct boost libraries -- McCabe
82#if defined(_MSC_VER)
83#if _MSC_VER >= 1500
84#ifdef LL_DEBUG
85#pragma comment( lib, "libboost_signals-vc90-mt-gd-1_36.lib" )
86#pragma comment( lib, "libboost_regex-vc90-mt-gd-1_36.lib" )
87#pragma comment( lib, "libboost_program_options-vc90-mt-gd-1_36.lib" )
88#else
89#pragma comment( lib, "libboost_signals-vc90-mt-1_36.lib" )
90#pragma comment( lib, "libboost_regex-vc90-mt-1_36.lib" )
91#pragma comment( lib, "libboost_program_options-vc90-mt-1_36.lib" )
92#endif
93#elif _MSC_VER >= 1400
94#ifdef LL_DEBUG
95#pragma comment( lib, "libboost_signals-vc80-mt-gd-1_36.lib" )
96#pragma comment( lib, "libboost_regex-vc80-mt-gd-1_36.lib" )
97#pragma comment( lib, "libboost_program_options-vc80-mt-gd-1_36.lib" )
98#else
99#pragma comment( lib, "libboost_signals-vc80-mt-1_36.lib" )
100#pragma comment( lib, "libboost_regex-vc80-mt-1_36.lib" )
101#pragma comment( lib, "libboost_program_options-vc80-mt-1_36.lib" )
102#endif
103#endif
104#endif
105
106const std::string LLAppViewerWin32::sWindowClass = "Imprudence"; 81const std::string LLAppViewerWin32::sWindowClass = "Imprudence";
107 82
108LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop) 83LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop)
diff --git a/linden/indra/newview/llcallingcard.cpp b/linden/indra/newview/llcallingcard.cpp
index 15be0eb..f1328be 100644
--- a/linden/indra/newview/llcallingcard.cpp
+++ b/linden/indra/newview/llcallingcard.cpp
@@ -613,6 +613,25 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
613 LLSD args; 613 LLSD args;
614 if(gCacheName->getName(agent_id, first, last)) 614 if(gCacheName->getName(agent_id, first, last))
615 { 615 {
616 if (LLAvatarNameCache::useDisplayNames() && !gSavedSettings.getBOOL("LegacyNamesForFriends"))
617 {
618 LLAvatarName avatar_name;
619 if (LLAvatarNameCache::get(agent_id, &avatar_name))
620 {
621 // Always show "Display Name [Legacy Name]" for security reasons
622 first = avatar_name.getNames();
623 size_t i = first.find(" ");
624 if (i != std::string::npos)
625 {
626 last = first.substr(i + 1);
627 first = first.substr(0, i);
628 }
629 else
630 {
631 last = "";
632 }
633 }
634 }
616 args["FIRST_NAME"] = first; 635 args["FIRST_NAME"] = first;
617 args["LAST_NAME"] = last; 636 args["LAST_NAME"] = last;
618 } 637 }
@@ -669,6 +688,31 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
669 std::string first, last; 688 std::string first, last;
670 if(gCacheName->getName(agent_id, first, last)) 689 if(gCacheName->getName(agent_id, first, last))
671 { 690 {
691 if (LLAvatarNameCache::useDisplayNames() && !gSavedSettings.getBOOL("LegacyNamesForFriends"))
692 {
693 LLAvatarName avatar_name;
694 if (LLAvatarNameCache::get(agent_id, &avatar_name))
695 {
696 if (LLAvatarNameCache::useDisplayNames() == 1)
697 {
698 first = avatar_name.mDisplayName;
699 }
700 else
701 {
702 first = avatar_name.getNames();
703 }
704 size_t i = first.find(" ");
705 if (i != std::string::npos)
706 {
707 last = first.substr(i + 1);
708 first = first.substr(0, i);
709 }
710 else
711 {
712 last = "";
713 }
714 }
715 }
672 notify = TRUE; 716 notify = TRUE;
673 args["FIRST"] = first; 717 args["FIRST"] = first;
674 args["LAST"] = last; 718 args["LAST"] = last;
@@ -745,6 +789,12 @@ void LLAvatarTracker::processTerminateFriendship(LLMessageSystem* msg, void**)
745 } 789 }
746} 790}
747 791
792void LLAvatarTracker::dirtyBuddies()
793{
794 mModifyMask |= LLFriendObserver::REMOVE | LLFriendObserver::ADD;
795 notifyObservers();
796}
797
748///---------------------------------------------------------------------------- 798///----------------------------------------------------------------------------
749/// Tracking Data 799/// Tracking Data
750///---------------------------------------------------------------------------- 800///----------------------------------------------------------------------------
diff --git a/linden/indra/newview/llcallingcard.h b/linden/indra/newview/llcallingcard.h
index d3f53c6..d5496ae 100644
--- a/linden/indra/newview/llcallingcard.h
+++ b/linden/indra/newview/llcallingcard.h
@@ -122,6 +122,9 @@ public:
122 // deal with termination of friendhsip 122 // deal with termination of friendhsip
123 void terminateBuddy(const LLUUID& id); 123 void terminateBuddy(const LLUUID& id);
124 124
125 // flag the buddy list dirty to force an update
126 void dirtyBuddies();
127
125 // get full info 128 // get full info
126 const LLRelationship* getBuddyInfo(const LLUUID& id) const; 129 const LLRelationship* getBuddyInfo(const LLUUID& id) const;
127 130
diff --git a/linden/indra/newview/llfilepicker.cpp b/linden/indra/newview/llfilepicker.cpp
index a59fa06..ec4e294 100644
--- a/linden/indra/newview/llfilepicker.cpp
+++ b/linden/indra/newview/llfilepicker.cpp
@@ -1181,7 +1181,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
1181 break; 1181 break;
1182 case FFSAVE_RAW: 1182 case FFSAVE_RAW:
1183 caption += add_simple_pattern_filter_to_gtkchooser 1183 caption += add_simple_pattern_filter_to_gtkchooser
1184 (picker, "*.raw", LLTrans::getString("dot_raw_file") + " (*.raw)"); 1184 (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)");
1185 suggest_ext = ".raw"; 1185 suggest_ext = ".raw";
1186 break; 1186 break;
1187 case FFSAVE_J2C: 1187 case FFSAVE_J2C:
diff --git a/linden/indra/newview/llfirstuse.cpp b/linden/indra/newview/llfirstuse.cpp
index 18efa9e..f482d1c 100644
--- a/linden/indra/newview/llfirstuse.cpp
+++ b/linden/indra/newview/llfirstuse.cpp
@@ -390,3 +390,31 @@ void LLFirstUse::voiceLicenseAgreement()
390 LLStartUp::setStartupState(STATE_LOGIN_AUTH_INIT); 390 LLStartUp::setStartupState(STATE_LOGIN_AUTH_INIT);
391 } 391 }
392} 392}
393
394void LLFirstUse::callbackPrivacy(const LLSD& notification, const LLSD& response)
395{
396
397 S32 option = LLNotification::getSelectedOption(notification, response);
398 if ( 0 == option )
399 {
400 gSavedSettings.setWarning("FirstPrivacy", FALSE);
401 LLStartUp::setStartupState(STATE_PRIVACY_LECTURED);
402 }
403 if ( 1 == option )
404 {
405 LLStartUp::resetLogin();
406 }
407}
408
409// static
410void LLFirstUse::Privacy()
411{
412 if (gSavedSettings.getWarning("FirstPrivacy"))
413 {
414 LLNotifications::instance().add("FirstPrivacy", LLSD(), LLSD(), callbackPrivacy);
415 }
416 else
417 {
418 LLStartUp::setStartupState(STATE_PRIVACY_LECTURED);
419 }
420} \ No newline at end of file
diff --git a/linden/indra/newview/llfirstuse.h b/linden/indra/newview/llfirstuse.h
index 42443ff..8c2ca35 100644
--- a/linden/indra/newview/llfirstuse.h
+++ b/linden/indra/newview/llfirstuse.h
@@ -116,7 +116,8 @@ public:
116 static void callbackClientTags(const LLSD& notification, const LLSD& response); 116 static void callbackClientTags(const LLSD& notification, const LLSD& response);
117 static void ClientTags(); 117 static void ClientTags();
118 static void voiceLicenseAgreement(); 118 static void voiceLicenseAgreement();
119 119 static void callbackPrivacy(const LLSD& notification, const LLSD& response);
120 static void Privacy();
120protected: 121protected:
121 static std::set<std::string> sConfigVariables; 122 static std::set<std::string> sConfigVariables;
122 123
diff --git a/linden/indra/newview/llfloateractivespeakers.cpp b/linden/indra/newview/llfloateractivespeakers.cpp
index 59de717..75cf176 100644
--- a/linden/indra/newview/llfloateractivespeakers.cpp
+++ b/linden/indra/newview/llfloateractivespeakers.cpp
@@ -92,18 +92,19 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy
92 92
93void LLSpeaker::lookupName() 93void LLSpeaker::lookupName()
94{ 94{
95 gCacheName->getName(mID, onAvatarNameLookup, new LLHandle<LLSpeaker>(getHandle())); 95 LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onAvatarNameLookup, _1, _2, new LLHandle<LLSpeaker>(getHandle())));
96} 96}
97 97
98//static 98//static
99void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data) 99void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data)
100{ 100{
101 LLSpeaker* speaker_ptr = ((LLHandle<LLSpeaker>*)user_data)->get(); 101 LLSpeaker* speaker_ptr = ((LLHandle<LLSpeaker>*)user_data)->get();
102 delete (LLHandle<LLSpeaker>*)user_data; 102 delete (LLHandle<LLSpeaker>*)user_data;
103 103
104 if (speaker_ptr) 104 if (speaker_ptr)
105 { 105 {
106 speaker_ptr->mDisplayName = first + " " + last; 106 // Always show "Display Name [Legacy Name]" for security reasons
107 speaker_ptr->mDisplayName = avatar_name.getNames();
107// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g 108// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g
108 // TODO-RLVa: this seems to get called per frame which is very likely an LL bug that will eventuall get fixed 109 // TODO-RLVa: this seems to get called per frame which is very likely an LL bug that will eventuall get fixed
109 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 110 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
diff --git a/linden/indra/newview/llfloateractivespeakers.h b/linden/indra/newview/llfloateractivespeakers.h
index b2c44e2..dc3dd73 100644
--- a/linden/indra/newview/llfloateractivespeakers.h
+++ b/linden/indra/newview/llfloateractivespeakers.h
@@ -33,6 +33,7 @@
33#ifndef LL_LLFLOATERACTIVESPEAKERS_H 33#ifndef LL_LLFLOATERACTIVESPEAKERS_H
34#define LL_LLFLOATERACTIVESPEAKERS_H 34#define LL_LLFLOATERACTIVESPEAKERS_H
35 35
36#include "llavatarnamecache.h"
36#include "llfloater.h" 37#include "llfloater.h"
37#include "llmemory.h" 38#include "llmemory.h"
38#include "llvoiceclient.h" 39#include "llvoiceclient.h"
@@ -73,7 +74,7 @@ public:
73 ~LLSpeaker() {}; 74 ~LLSpeaker() {};
74 void lookupName(); 75 void lookupName();
75 76
76 static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data); 77 static void onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data);
77 78
78 ESpeakerStatus mStatus; // current activity status in speech group 79 ESpeakerStatus mStatus; // current activity status in speech group
79 F32 mLastSpokeTime; // timestamp when this speaker last spoke 80 F32 mLastSpokeTime; // timestamp when this speaker last spoke
diff --git a/linden/indra/newview/llfloateravatarinfo.cpp b/linden/indra/newview/llfloateravatarinfo.cpp
index 0618875..13805fb 100644
--- a/linden/indra/newview/llfloateravatarinfo.cpp
+++ b/linden/indra/newview/llfloateravatarinfo.cpp
@@ -122,7 +122,7 @@ LLFloaterAvatarInfo::LLFloaterAvatarInfo(const std::string& name, const LLRect &
122 } 122 }
123 123
124 gAvatarInfoInstances.addData(avatar_id, this); // must be done before callback below is called. 124 gAvatarInfoInstances.addData(avatar_id, this); // must be done before callback below is called.
125 gCacheName->get(avatar_id, FALSE, callbackLoadAvatarName); 125 LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterAvatarInfo::callbackLoadAvatarName, _1, _2));
126} 126}
127 127
128// virtual 128// virtual
@@ -242,18 +242,16 @@ void LLFloaterAvatarInfo::showProfileCallback(S32 option, void *userdata)
242 242
243// static 243// static
244void LLFloaterAvatarInfo::callbackLoadAvatarName(const LLUUID& id, 244void LLFloaterAvatarInfo::callbackLoadAvatarName(const LLUUID& id,
245 const std::string& first, 245 const LLAvatarName& avatar_name)
246 const std::string& last,
247 BOOL is_group,
248 void* data)
249{ 246{
250 LLFloaterAvatarInfo *floater = gAvatarInfoInstances.getIfThere(id); 247 LLFloaterAvatarInfo *floater = gAvatarInfoInstances.getIfThere(id);
251 248
252 if (floater) 249 if (floater)
253 { 250 {
254 // Build a new title including the avatar name. 251 // Build a new title including the avatar name.
252 // Always show "Display Name [Legacy Name]" for security reasons
255 std::ostringstream title; 253 std::ostringstream title;
256 title << first << " " << last << " - " << floater->getTitle(); 254 title << avatar_name.getNames() << " - " << floater->getTitle();
257 floater->setTitle(title.str()); 255 floater->setTitle(title.str());
258 } 256 }
259} 257}
diff --git a/linden/indra/newview/llfloateravatarinfo.h b/linden/indra/newview/llfloateravatarinfo.h
index 1cc17d1..f65e1f4 100644
--- a/linden/indra/newview/llfloateravatarinfo.h
+++ b/linden/indra/newview/llfloateravatarinfo.h
@@ -39,6 +39,7 @@
39#ifndef LL_LLFLOATERAVATARINFO_H 39#ifndef LL_LLFLOATERAVATARINFO_H
40#define LL_LLFLOATERAVATARINFO_H 40#define LL_LLFLOATERAVATARINFO_H
41 41
42#include "llavatarnamecache.h"
42#include "llfloater.h" 43#include "llfloater.h"
43#include "llpreview.h" 44#include "llpreview.h"
44#include "lluuid.h" 45#include "lluuid.h"
@@ -91,8 +92,7 @@ public:
91 92
92 static LLFloaterAvatarInfo* getInstance(const LLUUID &id); 93 static LLFloaterAvatarInfo* getInstance(const LLUUID &id);
93 static void showProfileCallback(S32 option, void *userdata); 94 static void showProfileCallback(S32 option, void *userdata);
94 static void callbackLoadAvatarName(const LLUUID& id, 95 static void callbackLoadAvatarName(const LLUUID& agent_id, const LLAvatarName& avatar_name);
95 const std::string& first, const std::string& last, BOOL is_group, void* data);
96 void resetGroupList(); 96 void resetGroupList();
97 97
98private: 98private:
diff --git a/linden/indra/newview/llfloaterchatterbox.cpp b/linden/indra/newview/llfloaterchatterbox.cpp
index 1ef75d1..ba1c83c 100644
--- a/linden/indra/newview/llfloaterchatterbox.cpp
+++ b/linden/indra/newview/llfloaterchatterbox.cpp
@@ -43,6 +43,7 @@
43#include "llviewercontrol.h" 43#include "llviewercontrol.h"
44#include "llimview.h" 44#include "llimview.h"
45#include "llimpanel.h" 45#include "llimpanel.h"
46#include "llcallingcard.h"
46 47
47// 48//
48// LLFloaterMyFriends 49// LLFloaterMyFriends
@@ -218,6 +219,8 @@ void LLFloaterChatterBox::draw()
218void LLFloaterChatterBox::onOpen() 219void LLFloaterChatterBox::onOpen()
219{ 220{
220 gSavedSettings.setBOOL("ShowCommunicate", TRUE); 221 gSavedSettings.setBOOL("ShowCommunicate", TRUE);
222 // Force a refresh to get latest display names in the new IM panel.
223 LLAvatarTracker::instance().dirtyBuddies();
221} 224}
222 225
223void LLFloaterChatterBox::onClose(bool app_quitting) 226void LLFloaterChatterBox::onClose(bool app_quitting)
diff --git a/linden/indra/newview/llfloatercustomize.cpp b/linden/indra/newview/llfloatercustomize.cpp
index db51556..21dfc36 100644
--- a/linden/indra/newview/llfloatercustomize.cpp
+++ b/linden/indra/newview/llfloatercustomize.cpp
@@ -448,9 +448,7 @@ LLPanelEditWearable::LLPanelEditWearable( EWearableType type )
448BOOL LLPanelEditWearable::postBuild() 448BOOL LLPanelEditWearable::postBuild()
449{ 449{
450 LLAssetType::EType asset_type = LLWearable::typeToAssetType( mType ); 450 LLAssetType::EType asset_type = LLWearable::typeToAssetType( mType );
451 std::string icon_name = (asset_type == LLAssetType::AT_CLOTHING ? 451 std::string icon_name = get_item_icon_name(asset_type, LLInventoryType::IT_WEARABLE, mType, FALSE);
452 "inv_item_clothing.tga" :
453 "inv_item_skin.tga" );
454 childSetValue("icon", icon_name); 452 childSetValue("icon", icon_name);
455 453
456 childSetAction("Create New", LLPanelEditWearable::onBtnCreateNew, this ); 454 childSetAction("Create New", LLPanelEditWearable::onBtnCreateNew, this );
@@ -553,7 +551,7 @@ void LLPanelEditWearable::setSubpart( ESubpart subpart )
553 param = (LLViewerVisualParam *)avatar->getNextVisualParam()) 551 param = (LLViewerVisualParam *)avatar->getNextVisualParam())
554 { 552 {
555 if (param->getID() == -1 553 if (param->getID() == -1
556 || param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE 554 || !param->isTweakable()
557 || param->getEditGroup() != part->mEditGroup 555 || param->getEditGroup() != part->mEditGroup
558 || !(param->getSex() & avatar_sex)) 556 || !(param->getSex() & avatar_sex))
559 { 557 {
@@ -763,7 +761,6 @@ void LLPanelEditWearable::onColorCommit( LLUICtrl* ctrl, void* userdata )
763 } 761 }
764} 762}
765 763
766
767void LLPanelEditWearable::initPreviousTextureList() 764void LLPanelEditWearable::initPreviousTextureList()
768{ 765{
769 initPreviousTextureListEntry(TEX_LOWER_ALPHA); 766 initPreviousTextureListEntry(TEX_LOWER_ALPHA);
@@ -2338,6 +2335,7 @@ void LLFloaterCustomize::initWearablePanels()
2338 panel->addTextureDropTarget(TEX_HEAD_TATTOO, "Head Tattoo", 2335 panel->addTextureDropTarget(TEX_HEAD_TATTOO, "Head Tattoo",
2339 LLUUID::null, 2336 LLUUID::null,
2340 TRUE); 2337 TRUE);
2338 panel->addColorSwatch(TEX_LOWER_TATTOO, "Color/Tint");
2341 } 2339 }
2342} 2340}
2343 2341
diff --git a/linden/indra/newview/llfloaterdirectory.cpp b/linden/indra/newview/llfloaterdirectory.cpp
index 8018c31..7c8ddf1 100644
--- a/linden/indra/newview/llfloaterdirectory.cpp
+++ b/linden/indra/newview/llfloaterdirectory.cpp
@@ -466,7 +466,9 @@ void LLFloaterDirectory::setVisible(BOOL visible)
466 466
467void LLFloaterDirectory::onClose(bool app_quitting) 467void LLFloaterDirectory::onClose(bool app_quitting)
468{ 468{
469 setVisible(FALSE); 469 LLFloater::onClose(app_quitting);
470
471 //setVisible(FALSE); //meaning you hide 3 web browsers - one SLPlugin each
470} 472}
471 473
472// static 474// static
diff --git a/linden/indra/newview/llfloaterdisplayname.cpp b/linden/indra/newview/llfloaterdisplayname.cpp
new file mode 100644
index 0000000..31ceda9
--- /dev/null
+++ b/linden/indra/newview/llfloaterdisplayname.cpp
@@ -0,0 +1,224 @@
1/**
2 * @file llfloaterdisplayname.cpp
3 * @author Leyla Farazha
4 * @brief Implementation of the LLFloaterDisplayName class.
5 *
6 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
7 * Second Life Viewer Source Code
8 * Copyright (C) 2010, Linden Research, Inc.
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation;
13 * version 2.1 of the License only.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *
24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
25 * $/LicenseInfo$
26 */
27
28
29#include "llviewerprecompiledheaders.h"
30#include "llfloater.h"
31
32#include "llnotifications.h"
33#include "llviewerdisplayname.h"
34
35#include "llnotify.h"
36#include "llfloaterdisplayname.h"
37#include "llavatarnamecache.h"
38#include "lluictrlfactory.h"
39#include "llviewercontrol.h"
40
41#include "llagent.h"
42
43
44LLFloaterDisplayName* LLFloaterDisplayName::sInstance = NULL;
45
46LLFloaterDisplayName::LLFloaterDisplayName() : LLFloater(std::string("Display Name"))
47{
48 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_display_name.xml");
49 LLFloaterDisplayName::sInstance = this;
50}
51
52LLFloaterDisplayName::~LLFloaterDisplayName()
53{
54 LLFloaterDisplayName::sInstance = NULL;
55}
56
57void LLFloaterDisplayName::show()
58{
59 if (!LLFloaterDisplayName::sInstance)
60 {
61 LLFloaterDisplayName::sInstance = new LLFloaterDisplayName();
62 }
63 LLFloaterDisplayName::sInstance->open();
64}
65
66void LLFloaterDisplayName::onOpen()
67{
68 getChild<LLUICtrl>("display_name_editor")->clear();
69 getChild<LLUICtrl>("display_name_confirm")->clear();
70
71 LLAvatarName av_name;
72 LLAvatarNameCache::get(gAgent.getID(), &av_name);
73
74 F64 now_secs = LLDate::now().secondsSinceEpoch();
75
76 if (now_secs < av_name.mNextUpdate)
77 {
78 // ...can't update until some time in the future
79 F64 next_update_local_secs = av_name.mNextUpdate;
80 std::string next_update_string;
81#ifdef LOCALIZED_TIME
82 timeToFormattedString((time_t)next_update_local_secs,
83 gSavedSettings.getString("LongDateFormat"),
84 next_update_string);
85#else
86 LLDate next_update_local(next_update_local_secs);
87 next_update_string = next_update_local.asString();
88#endif
89 getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string);
90 getChild<LLUICtrl>("lockout_text")->setVisible(true);
91 getChild<LLUICtrl>("now_ok_text")->setVisible(false);
92 getChild<LLUICtrl>("save_btn")->setEnabled(false);
93 getChild<LLUICtrl>("display_name_editor")->setEnabled(false);
94 getChild<LLUICtrl>("display_name_confirm")->setEnabled(false);
95 getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE);
96
97 }
98 else
99 {
100 getChild<LLUICtrl>("lockout_text")->setVisible(false);
101 getChild<LLUICtrl>("now_ok_text")->setVisible(true);
102 getChild<LLUICtrl>("save_btn")->setEnabled(true);
103 getChild<LLUICtrl>("display_name_editor")->setEnabled(true);
104 getChild<LLUICtrl>("display_name_confirm")->setEnabled(true);
105
106 }
107}
108
109BOOL LLFloaterDisplayName::postBuild()
110{
111 childSetAction("reset_btn", onReset, this);
112 childSetAction("cancel_btn", onCancel, this);
113 childSetAction("save_btn", onSave, this);
114
115 center();
116
117 return TRUE;
118}
119
120void LLFloaterDisplayName::onCacheSetName(bool success,
121 const std::string& reason,
122 const LLSD& content)
123{
124 if (success)
125 {
126 // Inform the user that the change took place, but will take a while
127 // to percolate.
128 LLSD args;
129 args["DISPLAY_NAME"] = content["display_name"];
130 LLNotifications::instance().add("SetDisplayNameSuccess", args);
131
132 // Re-fetch my name, as it may have been sanitized by the service
133 //LLAvatarNameCache::get(getAvatarId(),
134 // boost::bind(&LLPanelMyProfileEdit::onNameCache, this, _1, _2));
135 return;
136 }
137
138 // Request failed, notify the user
139 std::string error_tag = content["error_tag"].asString();
140 llinfos << "set name failure error_tag " << error_tag << llendl;
141
142 // We might have a localized string for this message
143 // error_args will usually be empty from the server.
144 if (!error_tag.empty()
145 && LLNotifications::getInstance()->templateExists(error_tag))
146 {
147 LLNotifications::instance().add(error_tag);
148 return;
149 }
150
151 // The server error might have a localized message for us
152 std::string lang_code = LLUI::getLanguage();
153 LLSD error_desc = content["error_description"];
154 if (error_desc.has( lang_code ))
155 {
156 LLSD args;
157 args["MESSAGE"] = error_desc[lang_code].asString();
158 LLNotifications::instance().add("GenericAlert", args);
159 return;
160 }
161
162 // No specific error, throw a generic one
163 LLNotifications::instance().add("SetDisplayNameFailedGeneric");
164}
165
166void LLFloaterDisplayName::onCancel(void* data)
167{
168 LLFloaterDisplayName* self = (LLFloaterDisplayName*)data;
169 self->setVisible(false);
170}
171
172void LLFloaterDisplayName::onReset(void* data)
173{
174 LLFloaterDisplayName* self = (LLFloaterDisplayName*)data;
175
176 if (LLAvatarNameCache::useDisplayNames())
177 {
178 LLViewerDisplayName::set("",
179 boost::bind(&LLFloaterDisplayName::onCacheSetName, self, _1, _2, _3));
180 }
181 else
182 {
183 LLNotifications::instance().add("SetDisplayNameFailedGeneric");
184 }
185
186 self->setVisible(false);
187}
188
189
190void LLFloaterDisplayName::onSave(void* data)
191{
192 LLFloaterDisplayName* self = (LLFloaterDisplayName*)data;
193
194 std::string display_name_utf8 = self->getChild<LLUICtrl>("display_name_editor")->getValue().asString();
195 std::string display_name_confirm = self->getChild<LLUICtrl>("display_name_confirm")->getValue().asString();
196
197 if (display_name_utf8.compare(display_name_confirm))
198 {
199 LLNotifications::instance().add("SetDisplayNameMismatch");
200 return;
201 }
202
203 const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
204 LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
205 if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
206 {
207 LLSD args;
208 args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
209 LLNotifications::instance().add("SetDisplayNameFailedLength", args);
210 return;
211 }
212
213 if (LLAvatarNameCache::useDisplayNames())
214 {
215 LLViewerDisplayName::set(display_name_utf8,
216 boost::bind(&LLFloaterDisplayName::onCacheSetName, self, _1, _2, _3));
217 }
218 else
219 {
220 LLNotifications::instance().add("SetDisplayNameFailedGeneric");
221 }
222
223 self->setVisible(false);
224}
diff --git a/linden/indra/newview/llfloaterdisplayname.h b/linden/indra/newview/llfloaterdisplayname.h
new file mode 100644
index 0000000..4b25670
--- /dev/null
+++ b/linden/indra/newview/llfloaterdisplayname.h
@@ -0,0 +1,48 @@
1/**
2 * @file llfloaterdisplayname.h
3 *
4 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
5 * Second Life Viewer Source Code
6 * Copyright (C) 2010, Linden Research, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation;
11 * version 2.1 of the License only.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
23 * $/LicenseInfo$
24 */
25
26#ifndef LLFLOATERDISPLAYNAME_H
27#define LLFLOATERDISPLAYNAME_H
28
29
30class LLFloaterDisplayName : public LLFloater
31{
32public:
33 LLFloaterDisplayName();
34 virtual ~LLFloaterDisplayName();
35 /* virtual */ BOOL postBuild();
36 /* virtual */ void onOpen();
37 static void show();
38 static void onSave(void* data);
39 static void onReset(void* data);
40 static void onCancel(void* data);
41
42private:
43 static LLFloaterDisplayName* sInstance;
44 void onCacheSetName(bool success, const std::string& reason, const LLSD& content);
45};
46
47
48#endif
diff --git a/linden/indra/newview/llfloaterfriends.cpp b/linden/indra/newview/llfloaterfriends.cpp
index c33deae..84ba81e 100644
--- a/linden/indra/newview/llfloaterfriends.cpp
+++ b/linden/indra/newview/llfloaterfriends.cpp
@@ -39,6 +39,7 @@
39 39
40#include <sstream> 40#include <sstream>
41 41
42#include "llavatarnamecache.h"
42#include "lldir.h" 43#include "lldir.h"
43 44
44#include "llagent.h" 45#include "llagent.h"
@@ -254,6 +255,24 @@ BOOL LLPanelFriends::addFriend(const LLUUID& agent_id)
254 255
255 std::string fullname; 256 std::string fullname;
256 BOOL have_name = gCacheName->getFullName(agent_id, fullname); 257 BOOL have_name = gCacheName->getFullName(agent_id, fullname);
258 if (have_name)
259 {
260 if (LLAvatarNameCache::useDisplayNames() && !gSavedSettings.getBOOL("LegacyNamesForFriends"))
261 {
262 LLAvatarName avatar_name;
263 if (LLAvatarNameCache::get(agent_id, &avatar_name))
264 {
265 if (LLAvatarNameCache::useDisplayNames() == 1)
266 {
267 fullname = avatar_name.mDisplayName;
268 }
269 else
270 {
271 fullname = avatar_name.getNames();
272 }
273 }
274 }
275 }
257 276
258 LLSD element; 277 LLSD element;
259 element["id"] = agent_id; 278 element["id"] = agent_id;
@@ -332,6 +351,24 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh
332 351
333 std::string fullname; 352 std::string fullname;
334 BOOL have_name = gCacheName->getFullName(agent_id, fullname); 353 BOOL have_name = gCacheName->getFullName(agent_id, fullname);
354 if (have_name)
355 {
356 if (LLAvatarNameCache::useDisplayNames() && !gSavedSettings.getBOOL("LegacyNamesForFriends"))
357 {
358 LLAvatarName avatar_name;
359 if (LLAvatarNameCache::get(agent_id, &avatar_name))
360 {
361 if (LLAvatarNameCache::useDisplayNames() == 1)
362 {
363 fullname = avatar_name.mDisplayName;
364 }
365 else
366 {
367 fullname = avatar_name.getNames();
368 }
369 }
370 }
371 }
335 372
336 // Name of the status icon to use 373 // Name of the status icon to use
337 std::string statusIcon; 374 std::string statusIcon;
@@ -790,6 +827,25 @@ void LLPanelFriends::onClickRemove(void* user_data)
790 std::string first, last; 827 std::string first, last;
791 if(gCacheName->getName(agent_id, first, last)) 828 if(gCacheName->getName(agent_id, first, last))
792 { 829 {
830 if (LLAvatarNameCache::useDisplayNames() && !gSavedSettings.getBOOL("LegacyNamesForFriends"))
831 {
832 LLAvatarName avatar_name;
833 if (LLAvatarNameCache::get(agent_id, &avatar_name))
834 {
835 // Always show "Display Name [Legacy Name]" for security reasons
836 first = avatar_name.getNames();
837 size_t i = first.find(" ");
838 if (i != std::string::npos)
839 {
840 last = first.substr(i + 1);
841 first = first.substr(0, i);
842 }
843 else
844 {
845 last = "";
846 }
847 }
848 }
793 args["FIRST_NAME"] = first; 849 args["FIRST_NAME"] = first;
794 args["LAST_NAME"] = last; 850 args["LAST_NAME"] = last;
795 } 851 }
@@ -854,6 +910,25 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command
854 std::string first, last; 910 std::string first, last;
855 if(gCacheName->getName(agent_id, first, last)) 911 if(gCacheName->getName(agent_id, first, last))
856 { 912 {
913 if (LLAvatarNameCache::useDisplayNames() && !gSavedSettings.getBOOL("LegacyNamesForFriends"))
914 {
915 LLAvatarName avatar_name;
916 if (LLAvatarNameCache::get(agent_id, &avatar_name))
917 {
918 // Always show "Display Name [Legacy Name]" for security reasons
919 first = avatar_name.getNames();
920 size_t i = first.find(" ");
921 if (i != std::string::npos)
922 {
923 last = first.substr(i + 1);
924 first = first.substr(0, i);
925 }
926 else
927 {
928 last = "";
929 }
930 }
931 }
857 args["FIRST_NAME"] = first; 932 args["FIRST_NAME"] = first;
858 args["LAST_NAME"] = last; 933 args["LAST_NAME"] = last;
859 } 934 }
diff --git a/linden/indra/newview/llfloaternewim.cpp b/linden/indra/newview/llfloaternewim.cpp
index 48920c1..272cb53 100644
--- a/linden/indra/newview/llfloaternewim.cpp
+++ b/linden/indra/newview/llfloaternewim.cpp
@@ -38,10 +38,9 @@
38#include "lltabcontainer.h" 38#include "lltabcontainer.h"
39#include "llimview.h" 39#include "llimview.h"
40 40
41S32 COL_1_WIDTH = 200; 41S32 COL_1_WIDTH = 400;
42 42
43static std::string sOnlineDescriptor = "*"; 43static std::string sOnlineDescriptor = "*";
44static std::string sNameFormat = "[FIRST] [LAST]";
45 44
46LLFloaterNewIM::LLFloaterNewIM() 45LLFloaterNewIM::LLFloaterNewIM()
47{ 46{
@@ -69,7 +68,6 @@ BOOL LLFloaterNewIM::postBuild()
69 llwarns << "LLUICtrlFactory::getNameListByName() returned NULL for 'user_list'" << llendl; 68 llwarns << "LLUICtrlFactory::getNameListByName() returned NULL for 'user_list'" << llendl;
70 } 69 }
71 sOnlineDescriptor = getString("online_descriptor"); 70 sOnlineDescriptor = getString("online_descriptor");
72 sNameFormat = getString("name_format");
73 setDefaultBtn("start_btn"); 71 setDefaultBtn("start_btn");
74 return TRUE; 72 return TRUE;
75 } 73 }
@@ -135,11 +133,8 @@ void LLFloaterNewIM::addGroup(const LLUUID& uuid, void* data, BOOL bold, BOOL on
135 133
136void LLFloaterNewIM::addAgent(const LLUUID& uuid, void* data, BOOL online) 134void LLFloaterNewIM::addAgent(const LLUUID& uuid, void* data, BOOL online)
137{ 135{
138 std::string first, last; 136 std::string fullname;
139 gCacheName->getName(uuid, first, last); 137 gCacheName->getFullName(uuid, fullname);
140 LLUIString fullname = sNameFormat;
141 fullname.setArg("[FIRST]", first);
142 fullname.setArg("[LAST]", last);
143 138
144 LLSD row; 139 LLSD row;
145 row["id"] = uuid; 140 row["id"] = uuid;
@@ -184,13 +179,20 @@ void LLFloaterNewIM::onStart(void* userdata)
184 const LLScrollListCell* cell = item->getColumn(0); 179 const LLScrollListCell* cell = item->getColumn(0);
185 std::string name(cell->getValue()); 180 std::string name(cell->getValue());
186 181
187 // *NOTE: Do a live detrmination of what type of session it 182 // *NOTE: Do a live determination of what type of session it
188 // should be. If we restrict the new im panel to online users, 183 // should be. If we restrict the new im panel to online users,
189 // then we can remove some of this code. 184 // then we can remove some of this code.
190 EInstantMessage type; 185 EInstantMessage type;
191 EInstantMessage* t = (EInstantMessage*)item->getUserdata(); 186 EInstantMessage* t = (EInstantMessage*)item->getUserdata();
192 if(t) type = (*t); 187 if(t) type = (*t);
193 else type = LLIMMgr::defaultIMTypeForAgent(item->getUUID()); 188 else type = LLIMMgr::defaultIMTypeForAgent(item->getUUID());
189 if (type != IM_SESSION_GROUP_START)
190 {
191 // Needed to avoid catching a display name, which would
192 // make us use a wrong IM log file...
193 gCacheName->getFullName(item->getUUID(), name);
194 }
195
194 gIMMgr->addSession(name, type, item->getUUID()); 196 gIMMgr->addSession(name, type, item->getUUID());
195 197
196 make_ui_sound("UISndStartIM"); 198 make_ui_sound("UISndStartIM");
diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp
index 0cb35e3..2aed361 100644
--- a/linden/indra/newview/llfloatertools.cpp
+++ b/linden/indra/newview/llfloatertools.cpp
@@ -1259,7 +1259,9 @@ void LLFloaterTools::onClickLink(void* data)
1259 } 1259 }
1260 1260
1261 S32 max_linked_prims = 0; 1261 S32 max_linked_prims = 0;
1262 if(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->usePhysics()) 1262
1263 LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
1264 if(object && object->usePhysics())
1263 { 1265 {
1264 //Physical - use phys prim limit 1266 //Physical - use phys prim limit
1265 max_linked_prims = gHippoLimits->getMaxPhysLinkedPrims(); 1267 max_linked_prims = gHippoLimits->getMaxPhysLinkedPrims();
diff --git a/linden/indra/newview/llhoverview.cpp b/linden/indra/newview/llhoverview.cpp
index 10d27cd..4f248e4 100644
--- a/linden/indra/newview/llhoverview.cpp
+++ b/linden/indra/newview/llhoverview.cpp
@@ -253,10 +253,29 @@ void LLHoverView::updateText()
253 LLNameValue* lastname = hit_object->getNVPair("LastName"); 253 LLNameValue* lastname = hit_object->getNVPair("LastName");
254 if (firstname && lastname) 254 if (firstname && lastname)
255 { 255 {
256 std::string complete_name = firstname->getString();
257 complete_name += " ";
258 complete_name += lastname->getString();
259
260 if (LLAvatarNameCache::useDisplayNames())
261 {
262 LLAvatarName avatar_name;
263 if (LLAvatarNameCache::get(hit_object->getID(), &avatar_name))
264 {
265 if (LLAvatarNameCache::useDisplayNames() == 1)
266 {
267 complete_name = avatar_name.mDisplayName;
268 }
269 else
270 {
271 complete_name = avatar_name.getNames();
272 }
273 }
274 }
256// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) 275// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
257 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) 276 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
258 { 277 {
259 line = RlvStrings::getAnonym(line.append(firstname->getString()).append(1, ' ').append(lastname->getString())); 278 line = RlvStrings::getAnonym(complete_name);
260 } 279 }
261 else 280 else
262 { 281 {
diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp
index 41727f2..a3e917f 100644
--- a/linden/indra/newview/llimpanel.cpp
+++ b/linden/indra/newview/llimpanel.cpp
@@ -106,6 +106,8 @@ LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL;
106 106
107BOOL LLVoiceChannel::sSuspended = FALSE; 107BOOL LLVoiceChannel::sSuspended = FALSE;
108 108
109std::set<LLFloaterIMPanel*> LLFloaterIMPanel::sFloaterIMPanels;
110
109void session_starter_helper( 111void session_starter_helper(
110 const LLUUID& temp_session_id, 112 const LLUUID& temp_session_id,
111 const LLUUID& other_participant_id, 113 const LLUUID& other_participant_id,
@@ -1108,6 +1110,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(
1108 mFirstKeystrokeTimer(), 1110 mFirstKeystrokeTimer(),
1109 mLastKeystrokeTimer() 1111 mLastKeystrokeTimer()
1110{ 1112{
1113 sFloaterIMPanels.insert(this);
1111 init(session_label); 1114 init(session_label);
1112} 1115}
1113 1116
@@ -1149,6 +1152,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(
1149void LLFloaterIMPanel::init(const std::string& session_label) 1152void LLFloaterIMPanel::init(const std::string& session_label)
1150{ 1153{
1151 mSessionLabel = session_label; 1154 mSessionLabel = session_label;
1155 mProfileButtonEnabled = FALSE;
1152 1156
1153 std::string xml_filename; 1157 std::string xml_filename;
1154 switch(mDialog) 1158 switch(mDialog)
@@ -1211,6 +1215,10 @@ void LLFloaterIMPanel::init(const std::string& session_label)
1211 FALSE); 1215 FALSE);
1212 1216
1213 setTitle(mSessionLabel); 1217 setTitle(mSessionLabel);
1218 if (mProfileButtonEnabled)
1219 {
1220 lookupName();
1221 }
1214 1222
1215 mInputEditor->setMaxTextLength(DB_IM_MSG_STR_LEN); 1223 mInputEditor->setMaxTextLength(DB_IM_MSG_STR_LEN);
1216 // enable line history support for instant message bar 1224 // enable line history support for instant message bar
@@ -1253,9 +1261,32 @@ void LLFloaterIMPanel::init(const std::string& session_label)
1253 } 1261 }
1254} 1262}
1255 1263
1264void LLFloaterIMPanel::lookupName()
1265{
1266 LLAvatarNameCache::get(mOtherParticipantUUID, boost::bind(&LLFloaterIMPanel::onAvatarNameLookup, _1, _2, this));
1267}
1268
1269//static
1270void LLFloaterIMPanel::onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data)
1271{
1272 LLFloaterIMPanel* self = (LLFloaterIMPanel*)user_data;
1273
1274 if (self && sFloaterIMPanels.count(self) != 0)
1275 {
1276 // Always show "Display Name [Legacy Name]" for security reasons
1277 std::string title = avatar_name.getNames();
1278 if (!title.empty())
1279 {
1280 self->setTitle(title);
1281 }
1282 }
1283}
1284
1256 1285
1257LLFloaterIMPanel::~LLFloaterIMPanel() 1286LLFloaterIMPanel::~LLFloaterIMPanel()
1258{ 1287{
1288 sFloaterIMPanels.erase(this);
1289
1259 delete mSpeakers; 1290 delete mSpeakers;
1260 mSpeakers = NULL; 1291 mSpeakers = NULL;
1261 1292
@@ -1550,8 +1581,9 @@ BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
1550 return TRUE; 1581 return TRUE;
1551} 1582}
1552 1583
1553void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file, const LLUUID& source, const std::string& name) 1584void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file, const LLUUID& source, const std::string& const_name)
1554{ 1585{
1586 std::string name = const_name;
1555 // start tab flashing when receiving im for background session from user 1587 // start tab flashing when receiving im for background session from user
1556 if (source != LLUUID::null) 1588 if (source != LLUUID::null)
1557 { 1589 {
@@ -1602,6 +1634,21 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
1602 } 1634 }
1603 else 1635 else
1604 { 1636 {
1637 if (LLAvatarNameCache::useDisplayNames() && source != LLUUID::null)
1638 {
1639 LLAvatarName avatar_name;
1640 if (LLAvatarNameCache::get(source, &avatar_name))
1641 {
1642 if (LLAvatarNameCache::useDisplayNames() == 1)
1643 {
1644 name = avatar_name.mDisplayName;
1645 }
1646 else
1647 {
1648 name = avatar_name.getNames();
1649 }
1650 }
1651 }
1605 // Convert the name to a hotlink and add to message. 1652 // Convert the name to a hotlink and add to message.
1606 const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source); 1653 const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source);
1607 mHistoryEditor->appendStyledText(name,false,prepend_newline,source_style); 1654 mHistoryEditor->appendStyledText(name,false,prepend_newline,source_style);
@@ -1619,7 +1666,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
1619 else 1666 else
1620 histstr = name + utf8msg; 1667 histstr = name + utf8msg;
1621 1668
1622 LLLogChat::saveHistory(getTitle(),histstr); 1669 LLLogChat::saveHistory(mSessionLabel, histstr);
1623 } 1670 }
1624 1671
1625 if (!isInVisibleChain()) 1672 if (!isInVisibleChain())
@@ -2168,6 +2215,21 @@ void LLFloaterIMPanel::sendMsg()
2168 { 2215 {
2169 std::string history_echo; 2216 std::string history_echo;
2170 gAgent.buildFullname(history_echo); 2217 gAgent.buildFullname(history_echo);
2218 if (LLAvatarNameCache::useDisplayNames())
2219 {
2220 LLAvatarName avatar_name;
2221 if (LLAvatarNameCache::get(gAgent.getID(), &avatar_name))
2222 {
2223 if (LLAvatarNameCache::useDisplayNames() == 1)
2224 {
2225 history_echo = avatar_name.mDisplayName;
2226 }
2227 else
2228 {
2229 history_echo = avatar_name.getNames();
2230 }
2231 }
2232 }
2171 2233
2172 // Look for IRC-style emotes here. 2234 // Look for IRC-style emotes here.
2173 std::string prefix = utf8_text.substr(0, 4); 2235 std::string prefix = utf8_text.substr(0, 4);
diff --git a/linden/indra/newview/llimpanel.h b/linden/indra/newview/llimpanel.h
index ddcbdc7..b5a0165 100644
--- a/linden/indra/newview/llimpanel.h
+++ b/linden/indra/newview/llimpanel.h
@@ -33,6 +33,7 @@
33#ifndef LL_IMPANEL_H 33#ifndef LL_IMPANEL_H
34#define LL_IMPANEL_H 34#define LL_IMPANEL_H
35 35
36#include "llavatarnamecache.h"
36#include "llfloater.h" 37#include "llfloater.h"
37#include "lllogchat.h" 38#include "lllogchat.h"
38#include "lluuid.h" 39#include "lluuid.h"
@@ -194,6 +195,9 @@ public:
194 EInstantMessage dialog); 195 EInstantMessage dialog);
195 virtual ~LLFloaterIMPanel(); 196 virtual ~LLFloaterIMPanel();
196 197
198 void lookupName();
199 static void onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data);
200
197 /*virtual*/ BOOL postBuild(); 201 /*virtual*/ BOOL postBuild();
198 202
199 // Check typing timeout timer. 203 // Check typing timeout timer.
@@ -365,6 +369,8 @@ private:
365 typedef std::map<LLUUID, LLStyleSP> styleMap; 369 typedef std::map<LLUUID, LLStyleSP> styleMap;
366 static styleMap mStyleMap; 370 static styleMap mStyleMap;
367 371
372 static std::set<LLFloaterIMPanel*> sFloaterIMPanels;
373
368 typedef enum e_im_format 374 typedef enum e_im_format
369 { 375 {
370 IM_PANEL_PLAIN, 376 IM_PANEL_PLAIN,
diff --git a/linden/indra/newview/llmanipscale.cpp b/linden/indra/newview/llmanipscale.cpp
index 268e431..b38abe4 100644
--- a/linden/indra/newview/llmanipscale.cpp
+++ b/linden/indra/newview/llmanipscale.cpp
@@ -1523,7 +1523,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
1523 F32 max_subdivisions = sGridMaxSubdivisionLevel; 1523 F32 max_subdivisions = sGridMaxSubdivisionLevel;
1524 F32 grid_alpha = gSavedSettings.getF32("GridOpacity"); 1524 F32 grid_alpha = gSavedSettings.getF32("GridOpacity");
1525 1525
1526 F32 max_point_on_scale_line = partToMaxScale(mManipPart, bbox); 1526 F32 max_point_on_scale_line = llmin(partToMaxScale(mManipPart, bbox), LLWorld::getInstance()->getRegionWidthInMeters());
1527 LLVector3 drag_point = gAgent.getPosAgentFromGlobal(mDragPointGlobal); 1527 LLVector3 drag_point = gAgent.getPosAgentFromGlobal(mDragPointGlobal);
1528 1528
1529 updateGridSettings(); 1529 updateGridSettings();
diff --git a/linden/indra/newview/llnamelistctrl.cpp b/linden/indra/newview/llnamelistctrl.cpp
index e445df5..e30c129 100644
--- a/linden/indra/newview/llnamelistctrl.cpp
+++ b/linden/indra/newview/llnamelistctrl.cpp
@@ -39,6 +39,7 @@
39#include "llcachename.h" 39#include "llcachename.h"
40#include "llagent.h" 40#include "llagent.h"
41#include "llinventory.h" 41#include "llinventory.h"
42#include "llviewercontrol.h"
42 43
43static LLRegisterWidget<LLNameListCtrl> r("name_list"); 44static LLRegisterWidget<LLNameListCtrl> r("name_list");
44 45
@@ -56,7 +57,8 @@ LLNameListCtrl::LLNameListCtrl(const std::string& name,
56: LLScrollListCtrl(name, rect, cb, userdata, allow_multiple_selection, 57: LLScrollListCtrl(name, rect, cb, userdata, allow_multiple_selection,
57 draw_border), 58 draw_border),
58 mNameColumnIndex(name_column_index), 59 mNameColumnIndex(name_column_index),
59 mAllowCallingCardDrop(FALSE) 60 mAllowCallingCardDrop(FALSE),
61 mUseDisplayNames(FALSE)
60{ 62{
61 setToolTip(tooltip); 63 setToolTip(tooltip);
62 LLNameListCtrl::sInstances.insert(this); 64 LLNameListCtrl::sInstances.insert(this);
@@ -77,7 +79,7 @@ BOOL LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
77 //llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl; 79 //llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl;
78 80
79 std::string fullname; 81 std::string fullname;
80 BOOL result = gCacheName->getFullName(agent_id, fullname); 82 BOOL result = getResidentName(agent_id, fullname);
81 83
82 fullname.append(suffix); 84 fullname.append(suffix);
83 85
@@ -164,7 +166,7 @@ BOOL LLNameListCtrl::addNameItem(LLScrollListItem* item, EAddPosition pos)
164 //llinfos << "LLNameListCtrl::addNameItem " << item->getUUID() << llendl; 166 //llinfos << "LLNameListCtrl::addNameItem " << item->getUUID() << llendl;
165 167
166 std::string fullname; 168 std::string fullname;
167 BOOL result = gCacheName->getFullName(item->getUUID(), fullname); 169 BOOL result = getResidentName(item->getUUID(), fullname);
168 170
169 LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); 171 LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
170 ((LLScrollListText*)cell)->setText( fullname ); 172 ((LLScrollListText*)cell)->setText( fullname );
@@ -199,7 +201,7 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos
199 else // normal resident 201 else // normal resident
200 { 202 {
201 std::string name; 203 std::string name;
202 if (gCacheName->getFullName(item->getUUID(), name)) 204 if (getResidentName(item->getUUID(), name))
203 { 205 {
204 fullname = name; 206 fullname = name;
205 } 207 }
@@ -346,6 +348,12 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
346 name_list->setAllowCallingCardDrop(allow_calling_card_drop); 348 name_list->setAllowCallingCardDrop(allow_calling_card_drop);
347 } 349 }
348 350
351 BOOL use_display_names;
352 if (node->getAttributeBOOL("use_display_names", use_display_names))
353 {
354 name_list->setUseDisplayNames(use_display_names);
355 }
356
349 name_list->setScrollListParameters(node); 357 name_list->setScrollListParameters(node);
350 358
351 name_list->initFromXML(node, parent); 359 name_list->initFromXML(node, parent);
@@ -456,5 +464,31 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
456 return name_list; 464 return name_list;
457} 465}
458 466
459 467bool LLNameListCtrl::getResidentName(const LLUUID& agent_id, std::string& fullname)
460 468{
469 std::string name;
470 if (gCacheName->getFullName(agent_id, name))
471 {
472 fullname = name;
473 if (mUseDisplayNames && LLAvatarNameCache::useDisplayNames() && !gSavedSettings.getBOOL("LegacyNamesForFriends"))
474 {
475 LLAvatarName avatar_name;
476 if (LLAvatarNameCache::get(agent_id, &avatar_name))
477 {
478 if (LLAvatarNameCache::useDisplayNames() == 1)
479 {
480 fullname = avatar_name.mDisplayName;
481 }
482 else
483 {
484 fullname = avatar_name.getNames();
485 }
486 }
487 }
488 return true;
489 }
490 else
491 {
492 return false;
493 }
494}
diff --git a/linden/indra/newview/llnamelistctrl.h b/linden/indra/newview/llnamelistctrl.h
index beb4ede..d6cf578 100644
--- a/linden/indra/newview/llnamelistctrl.h
+++ b/linden/indra/newview/llnamelistctrl.h
@@ -84,7 +84,12 @@ public:
84 84
85 void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; } 85 void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; }
86 86
87 void setUseDisplayNames(BOOL b) { mUseDisplayNames = b; }
88
87private: 89private:
90 bool getResidentName(const LLUUID& agent_id, std::string& fullname);
91 BOOL mUseDisplayNames;
92
88 static std::set<LLNameListCtrl*> sInstances; 93 static std::set<LLNameListCtrl*> sInstances;
89 S32 mNameColumnIndex; 94 S32 mNameColumnIndex;
90 BOOL mAllowCallingCardDrop; 95 BOOL mAllowCallingCardDrop;
diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp
index b9dc482..06257f0 100644
--- a/linden/indra/newview/llnetmap.cpp
+++ b/linden/indra/newview/llnetmap.cpp
@@ -36,6 +36,7 @@
36#include "llnetmap.h" 36#include "llnetmap.h"
37 37
38#include "indra_constants.h" 38#include "indra_constants.h"
39#include "llavatarnamecache.h"
39#include "llui.h" 40#include "llui.h"
40#include "llmath.h" // clampf() 41#include "llmath.h" // clampf()
41#include "llfocusmgr.h" 42#include "llfocusmgr.h"
@@ -640,7 +641,29 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec
640 { 641 {
641 msg.assign(""); 642 msg.assign("");
642 std::string fullname; 643 std::string fullname;
643 if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname)) 644 BOOL result = FALSE;
645 if (!LLAvatarNameCache::useDisplayNames())
646 {
647 result = gCacheName->getFullName(mClosestAgentToCursor, fullname);
648 }
649 else
650 {
651 LLAvatarName avatar_name;
652 if (LLAvatarNameCache::get(mClosestAgentToCursor, &avatar_name))
653 {
654 result = TRUE;
655 if (LLAvatarNameCache::useDisplayNames() == 1)
656 {
657 fullname = avatar_name.mDisplayName;
658 }
659 else
660 {
661 fullname = avatar_name.getNames(true);
662 }
663 }
664 }
665
666 if(mClosestAgentToCursor.notNull() && result)
644 { 667 {
645// msg.append(fullname); 668// msg.append(fullname);
646// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b 669// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b
diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp
index ed406e8..4e1d03e 100644
--- a/linden/indra/newview/lloverlaybar.cpp
+++ b/linden/indra/newview/lloverlaybar.cpp
@@ -38,7 +38,7 @@
38#include "lloverlaybar.h" 38#include "lloverlaybar.h"
39 39
40#include "aoremotectrl.h" 40#include "aoremotectrl.h"
41#include "llaudioengine.h" 41#include "kokuastreamingaudio.h"
42#include "llrender.h" 42#include "llrender.h"
43#include "llagent.h" 43#include "llagent.h"
44#include "llbutton.h" 44#include "llbutton.h"
@@ -438,17 +438,16 @@ void LLOverlayBar::toggleMusicPlay(void*)
438 if (gOverlayBar->mMusicState != PLAYING) 438 if (gOverlayBar->mMusicState != PLAYING)
439 { 439 {
440 gOverlayBar->mMusicState = PLAYING; // desired state 440 gOverlayBar->mMusicState = PLAYING; // desired state
441 if (gAudiop) 441 if (gAudioStream)
442 { 442 {
443 LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); 443 LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
444 if ( parcel ) 444 if ( parcel )
445 { 445 {
446 // this doesn't work properly when crossing parcel boundaries - even when the 446 // this doesn't work properly when crossing parcel boundaries - even when the
447 // stream is stopped, it doesn't return the right thing - commenting out for now. 447 // stream is stopped, it doesn't return the right thing - commenting out for now.
448 // if ( gAudiop->isInternetStreamPlaying() == 0 ) 448 // if ( gAudioStream->isInternetStreamPlaying() == 0 )
449 { 449 {
450 gAudiop->startInternetStream(parcel->getMusicURL()); 450 gAudioStream->startInternetStream(parcel->getMusicURL());
451//awfixme sTitleObserver.init(parcel->getMusicURL());
452 } 451 }
453 } 452 }
454 } 453 }
@@ -456,9 +455,9 @@ void LLOverlayBar::toggleMusicPlay(void*)
456 else 455 else
457 { 456 {
458 gOverlayBar->mMusicState = STOPPED; // desired state 457 gOverlayBar->mMusicState = STOPPED; // desired state
459 if (gAudiop) 458 if (gAudioStream)
460 { 459 {
461 gAudiop->stopInternetStream(); 460 gAudioStream->stopInternetStream();
462 } 461 }
463 } 462 }
464} 463}
diff --git a/linden/indra/newview/llpanelavatar.cpp b/linden/indra/newview/llpanelavatar.cpp
index e47ae2a..6b3be29 100644
--- a/linden/indra/newview/llpanelavatar.cpp
+++ b/linden/indra/newview/llpanelavatar.cpp
@@ -416,6 +416,7 @@ BOOL LLPanelAvatarWeb::postBuild(void)
416 childSetControlName("auto_load","AutoLoadWebProfiles"); 416 childSetControlName("auto_load","AutoLoadWebProfiles");
417 417
418 mWebBrowser = getChild<LLMediaCtrl>("profile_html"); 418 mWebBrowser = getChild<LLMediaCtrl>("profile_html");
419
419 mWebBrowser->addObserver(this); 420 mWebBrowser->addObserver(this);
420 421
421 // links open in internally 422 // links open in internally
@@ -490,7 +491,17 @@ void LLPanelAvatarWeb::refresh()
490 mNavigateTo = ""; 491 mNavigateTo = "";
491 } 492 }
492} 493}
494void LLPanelAvatarWeb::onVisibilityChange(BOOL new_visibility)
495{
496 LLPluginClassMedia::EPriority new_priority;
493 497
498 if (new_visibility)
499 new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
500 else
501 new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
502
503 mWebBrowser->getMediaPlugin()->setPriority(new_priority);
504}
494 505
495void LLPanelAvatarWeb::enableControls(BOOL self) 506void LLPanelAvatarWeb::enableControls(BOOL self)
496{ 507{
@@ -1346,7 +1357,33 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const std::string &name
1346 { 1357 {
1347 name_edit->setText(name); 1358 name_edit->setText(name);
1348 } 1359 }
1360 childSetVisible("name", TRUE);
1361 }
1362 LLNameEditor* complete_name_edit = getChild<LLNameEditor>("complete_name");
1363 if (complete_name_edit)
1364 {
1365 if (LLAvatarNameCache::useDisplayNames())
1366 {
1367 LLAvatarName avatar_name;
1368 if (LLAvatarNameCache::get(avatar_id, &avatar_name))
1369 {
1370 // Always show "Display Name [Legacy Name]" for security reasons
1371 complete_name_edit->setText(avatar_name.getNames());
1372 }
1373 else
1374 {
1375 complete_name_edit->setText(name_edit->getText());
1376 LLAvatarNameCache::get(avatar_id, boost::bind(&LLPanelAvatar::completeNameCallback, _1, _2, this));
1377 }
1378 childSetVisible("name", FALSE);
1379 childSetVisible("complete_name", TRUE);
1380 }
1381 else
1382 {
1383 childSetVisible("complete_name", FALSE);
1384 }
1349 } 1385 }
1386
1350// if (avatar_changed) 1387// if (avatar_changed)
1351 { 1388 {
1352 // While we're waiting for data off the network, clear out the 1389 // While we're waiting for data off the network, clear out the
@@ -1469,6 +1506,22 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const std::string &name
1469 } 1506 }
1470} 1507}
1471 1508
1509void LLPanelAvatar::completeNameCallback(const LLUUID& agent_id,
1510 const LLAvatarName& avatar_name,
1511 void *userdata)
1512{
1513 LLPanelAvatar* self = (LLPanelAvatar*)userdata;
1514 if (!LLAvatarNameCache::useDisplayNames() || agent_id != self->mAvatarID)
1515 {
1516 return;
1517 }
1518 LLLineEditor* complete_name_edit = self->getChild<LLLineEditor>("complete_name");
1519 if (complete_name_edit)
1520 {
1521 // Always show "Display Name [Legacy Name]" for security reasons
1522 complete_name_edit->setText(avatar_name.getNames());
1523 }
1524}
1472 1525
1473void LLPanelAvatar::resetGroupList() 1526void LLPanelAvatar::resetGroupList()
1474{ 1527{
diff --git a/linden/indra/newview/llpanelavatar.h b/linden/indra/newview/llpanelavatar.h
index b687cd8..3a90196 100644
--- a/linden/indra/newview/llpanelavatar.h
+++ b/linden/indra/newview/llpanelavatar.h
@@ -33,6 +33,7 @@
33#ifndef LL_LLPANELAVATAR_H 33#ifndef LL_LLPANELAVATAR_H
34#define LL_LLPANELAVATAR_H 34#define LL_LLPANELAVATAR_H
35 35
36#include "llavatarnamecache.h"
36#include "llpanel.h" 37#include "llpanel.h"
37#include "v3dmath.h" 38#include "v3dmath.h"
38#include "lluuid.h" 39#include "lluuid.h"
@@ -76,7 +77,6 @@ public:
76 /*virtual*/ void draw(); 77 /*virtual*/ void draw();
77 78
78 LLPanelAvatar* getPanelAvatar() const { return mPanelAvatar; } 79 LLPanelAvatar* getPanelAvatar() const { return mPanelAvatar; }
79
80 void setDataRequested(bool requested) { mDataRequested = requested; } 80 void setDataRequested(bool requested) { mDataRequested = requested; }
81 bool isDataRequested() const { return mDataRequested; } 81 bool isDataRequested() const { return mDataRequested; }
82 82
@@ -143,14 +143,15 @@ public:
143 LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar); 143 LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar);
144 /*virtual*/ ~LLPanelAvatarWeb(); 144 /*virtual*/ ~LLPanelAvatarWeb();
145 /*virtual*/ BOOL postBuild(void); 145 /*virtual*/ BOOL postBuild(void);
146
147 /*virtual*/ void refresh(); 146 /*virtual*/ void refresh();
147 /*virtual*/ void onVisibilityChange(BOOL new_visibility);
148 148
149 void enableControls(BOOL own_avatar); 149 void enableControls(BOOL own_avatar);
150 150
151 void setWebURL(std::string url); 151 void setWebURL(std::string url);
152 152
153 void load(std::string url); 153 void load(std::string url);
154
154 static void onURLKeystroke(LLLineEditor* editor, void* data); 155 static void onURLKeystroke(LLLineEditor* editor, void* data);
155 static void onCommitLoad(LLUICtrl* ctrl, void* data); 156 static void onCommitLoad(LLUICtrl* ctrl, void* data);
156 static void onCommitURL(LLUICtrl* ctrl, void* data); 157 static void onCommitURL(LLUICtrl* ctrl, void* data);
@@ -335,6 +336,9 @@ private:
335 static bool finishUnfreeze(const LLSD& notification, const LLSD& response); 336 static bool finishUnfreeze(const LLSD& notification, const LLSD& response);
336 337
337 static void showProfileCallback(S32 option, void *userdata); 338 static void showProfileCallback(S32 option, void *userdata);
339 static void completeNameCallback(const LLUUID& agent_id,
340 const LLAvatarName& avatar_name,
341 void *userdata);
338 342
339 static void* createPanelAvatar(void* data); 343 static void* createPanelAvatar(void* data);
340 static void* createFloaterAvatarInfo(void* data); 344 static void* createFloaterAvatarInfo(void* data);
diff --git a/linden/indra/newview/llpaneldirfind.cpp b/linden/indra/newview/llpaneldirfind.cpp
index 342ffec..719a7a0 100644
--- a/linden/indra/newview/llpaneldirfind.cpp
+++ b/linden/indra/newview/llpaneldirfind.cpp
@@ -62,6 +62,7 @@
62#include "lluictrlfactory.h" 62#include "lluictrlfactory.h"
63#include "llfloaterdirectory.h" 63#include "llfloaterdirectory.h"
64#include "llpaneldirbrowser.h" 64#include "llpaneldirbrowser.h"
65#include "llpluginclassmedia.h"
65 66
66#include <boost/tokenizer.hpp> 67#include <boost/tokenizer.hpp>
67#if LL_WINDOWS 68#if LL_WINDOWS
@@ -196,10 +197,17 @@ void LLPanelDirFind::draw()
196// virtual 197// virtual
197void LLPanelDirFind::onVisibilityChange(BOOL new_visibility) 198void LLPanelDirFind::onVisibilityChange(BOOL new_visibility)
198{ 199{
200 LLPluginClassMedia::EPriority new_priority;
199 if (new_visibility) 201 if (new_visibility)
200 { 202 {
201 mFloaterDirectory->hideAllDetailPanels(); 203 mFloaterDirectory->hideAllDetailPanels();
204 new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
202 } 205 }
206 else
207 new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
208
209 mWebBrowser->getMediaPlugin()->setPriority(new_priority);
210
203 LLPanel::onVisibilityChange(new_visibility); 211 LLPanel::onVisibilityChange(new_visibility);
204} 212}
205 213
diff --git a/linden/indra/newview/llpanelgeneral.cpp b/linden/indra/newview/llpanelgeneral.cpp
index fc6073a..70146ce 100644
--- a/linden/indra/newview/llpanelgeneral.cpp
+++ b/linden/indra/newview/llpanelgeneral.cpp
@@ -98,6 +98,9 @@ BOOL LLPanelGeneral::postBuild()
98 childSetValue("mini_map_notify_chat", gSavedSettings.getBOOL("MiniMapNotifyChatRange")); 98 childSetValue("mini_map_notify_chat", gSavedSettings.getBOOL("MiniMapNotifyChatRange"));
99 childSetValue("mini_map_notify_sim", gSavedSettings.getBOOL("MiniMapNotifySimRange")); 99 childSetValue("mini_map_notify_sim", gSavedSettings.getBOOL("MiniMapNotifySimRange"));
100 100
101// mDisplayNamesUsage = gSavedSettings.getU32("DisplayNamesUsage");
102// mLegacyNamesForFriends = gSavedSettings.getBOOL("LegacyNamesForFriends");
103
101 getChild<LLColorSwatchCtrl>("effect_color_swatch")->set(gSavedSettings.getColor4("EffectColor")); 104 getChild<LLColorSwatchCtrl>("effect_color_swatch")->set(gSavedSettings.getColor4("EffectColor"));
102 105
103 childSetValue("ui_scale_slider", gSavedSettings.getF32("UIScaleFactor")); 106 childSetValue("ui_scale_slider", gSavedSettings.getF32("UIScaleFactor"));
@@ -210,6 +213,8 @@ void LLPanelGeneral::apply()
210 213
211void LLPanelGeneral::cancel() 214void LLPanelGeneral::cancel()
212{ 215{
216// gSavedSettings.setU32("DisplayNamesUsage", mDisplayNamesUsage);
217// gSavedSettings.setBOOL("LegacyNamesForFriends", mDisplayNamesUsage);
213} 218}
214 219
215// static 220// static
diff --git a/linden/indra/newview/llpanelgeneral.h b/linden/indra/newview/llpanelgeneral.h
index e85fdf8..56cc3de 100644
--- a/linden/indra/newview/llpanelgeneral.h
+++ b/linden/indra/newview/llpanelgeneral.h
@@ -51,6 +51,9 @@ private:
51 static void onClickResetUISize(void*); 51 static void onClickResetUISize(void*);
52 static void onClickGrid(void*); 52 static void onClickGrid(void*);
53 static void onLocationChanged(LLUICtrl* ctrl, void* data); 53 static void onLocationChanged(LLUICtrl* ctrl, void* data);
54
55 U32 mDisplayNamesUsage;
56 bool mLegacyNamesForFriends;
54}; 57};
55 58
56#endif 59#endif
diff --git a/linden/indra/newview/llpanelgroupgeneral.cpp b/linden/indra/newview/llpanelgroupgeneral.cpp
index 6878f84..7ff25a7 100644
--- a/linden/indra/newview/llpanelgroupgeneral.cpp
+++ b/linden/indra/newview/llpanelgroupgeneral.cpp
@@ -561,9 +561,13 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)
561 gIMMgr->saveIgnoreGroup(); 561 gIMMgr->saveIgnoreGroup();
562 } 562 }
563 563
564 mCtrlReceiveNotices->resetDirty(); //resetDirty() here instead of in update because this is where the settings 564 // Make sure we update the group list in our contacts list and our IMs -- MC
565 mCtrlListGroup->resetDirty(); //are actually being applied. onCommitUserOnly doesn't call updateChanged directly. 565 if (gIMMgr)
566 mCtrlReceiveChat->resetDirty(); 566 {
567 // update the talk view
568 gIMMgr->refresh();
569 }
570 gAgent.fireEvent(new LLEvent(&gAgent, "new group"), "");
567 571
568 mChanged = FALSE; 572 mChanged = FALSE;
569 573
@@ -778,21 +782,14 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
778 { 782 {
779 mCtrlReceiveNotices->setEnabled(mAllowEdit); 783 mCtrlReceiveNotices->setEnabled(mAllowEdit);
780 } 784 }
785 mCtrlReceiveNotices->resetDirty();
781 } 786 }
782 787
783 if (mCtrlReceiveChat) 788 if (mCtrlReceiveChat)
784 { 789 {
785 mCtrlReceiveChat->setVisible(is_member); 790 mCtrlReceiveChat->setVisible(is_member);
786 mCtrlReceiveChat->setEnabled(TRUE); 791 mCtrlReceiveChat->setEnabled(TRUE);
787 } 792 mCtrlReceiveChat->resetDirty();
788
789 if (mCtrlListGroup)
790 {
791 mCtrlListGroup->setVisible(is_member);
792 if (is_member)
793 {
794 mCtrlListGroup->setEnabled(mAllowEdit);
795 }
796 } 793 }
797 794
798 795
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index b744961..4bfcf52 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -41,6 +41,7 @@
41#endif 41#endif
42#include "llpluginclassmediaowner.h" 42#include "llpluginclassmediaowner.h"
43#include "llviewermedia_streamingaudio.h" 43#include "llviewermedia_streamingaudio.h"
44#include "kokuastreamingaudio.h"
44#include "llaudioengine.h" 45#include "llaudioengine.h"
45 46
46#ifdef LL_FMOD 47#ifdef LL_FMOD
@@ -681,19 +682,13 @@ bool idle_startup()
681 delete gAudiop; 682 delete gAudiop;
682 gAudiop = NULL; 683 gAudiop = NULL;
683 } 684 }
684
685 if (gAudiop)
686 {
687 // if the audio engine hasn't set up its own preferred handler for streaming audio then set up the generic streaming audio implementation which uses media plugins
688 if (NULL == gAudiop->getStreamingAudioImpl())
689 {
690 LL_INFOS("AppInit") << "Using media plugins to render streaming audio" << LL_ENDL;
691 gAudiop->setStreamingAudioImpl(new LLStreamingAudio_MediaPlugins());
692 } 685 }
693 } 686 }
694 } 687
695 } 688
696 689 if (!gAudioStream)
690 gAudioStream = new KOKUAStreamingAudio(new LLStreamingAudio_MediaPlugins());
691
697 LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL; 692 LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL;
698 693
699 694
@@ -877,7 +872,47 @@ bool idle_startup()
877 872
878 if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState()) 873 if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
879 { 874 {
875
880 LL_DEBUGS("AppInitStartupState") << "STATE_LOGIN_CLEANUP" << LL_ENDL; 876 LL_DEBUGS("AppInitStartupState") << "STATE_LOGIN_CLEANUP" << LL_ENDL;
877
878 gDisconnected = TRUE;
879
880 std::string cmd_line_grid_choice = gSavedSettings.getString("CmdLineGridChoice");
881 std::string cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI").asString();
882 if(!cmd_line_grid_choice.empty() && cmd_line_login_uri.empty())
883 {
884 gHippoGridManager->setCurrentGrid(cmd_line_grid_choice);
885 }
886
887 gHippoGridManager->setCurrentGridAsConnected();
888 gHippoLimits->setLimits();
889
890 if (gHippoGridManager->getConnectedGrid()->isSecondLife())
891 {
892 LLStartUp::setStartupState( STATE_LECTURE_PRIVACY );
893 LLFirstUse::Privacy();
894 }
895 else
896 {
897 LLStartUp::setStartupState( STATE_PRIVACY_LECTURED );
898 }
899
900 return FALSE;
901
902 }
903
904 if (STATE_LECTURE_PRIVACY == LLStartUp::getStartupState())
905 {
906 LL_DEBUGS("AppInitStartupState") << "STATE_LECTURE_PRIVACY" << LL_ENDL;
907
908 //wait for the user to decide
909 ms_sleep(1);
910 return FALSE;
911 }
912
913 if (STATE_PRIVACY_LECTURED == LLStartUp::getStartupState())
914 {
915 LL_DEBUGS("AppInitStartupState") << "STATE_PRIVACY_LECTURED" << LL_ENDL;
881 //reset the values that could have come in from a slurl 916 //reset the values that could have come in from a slurl
882 if (!gLoginHandler.getWebLoginKey().isNull()) 917 if (!gLoginHandler.getWebLoginKey().isNull())
883 { 918 {
@@ -919,15 +954,9 @@ bool idle_startup()
919 gDebugInfo["LoginName"] = firstname + " " + lastname; 954 gDebugInfo["LoginName"] = firstname + " " + lastname;
920 } 955 }
921 956
922 std::string cmd_line_grid_choice = gSavedSettings.getString("CmdLineGridChoice");
923 std::string cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI").asString();
924 if(!cmd_line_grid_choice.empty() && cmd_line_login_uri.empty())
925 {
926 gHippoGridManager->setCurrentGrid(cmd_line_grid_choice);
927 }
928 957
929 gHippoGridManager->setCurrentGridAsConnected(); 958
930 gHippoLimits->setLimits(); 959
931 // create necessary directories 960 // create necessary directories
932 // *FIX: these mkdir's should error check 961 // *FIX: these mkdir's should error check
933 gDirUtilp->setLindenUserDir(gHippoGridManager->getCurrentGridNick(), firstname, lastname); 962 gDirUtilp->setLindenUserDir(gHippoGridManager->getCurrentGridNick(), firstname, lastname);
@@ -2005,6 +2034,12 @@ bool idle_startup()
2005 2034
2006 // Load stored cache if possible 2035 // Load stored cache if possible
2007 LLAppViewer::instance()->loadNameCache(); 2036 LLAppViewer::instance()->loadNameCache();
2037
2038 // Start cache in not-running state until we figure out if we have
2039 // capabilities for display name lookup
2040 LLAvatarNameCache::initClass(false);
2041 LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getU32("DisplayNamesUsage"));
2042 LLAvatarName::sOmitResidentAsLastName = (bool)gSavedSettings.getBOOL("OmitResidentAsLastName");
2008 } 2043 }
2009 2044
2010 // *Note: this is where gWorldMap used to be initialized. 2045 // *Note: this is where gWorldMap used to be initialized.
@@ -3772,6 +3807,8 @@ std::string LLStartUp::startupStateToString(EStartupState state)
3772 RTNENUM( STATE_LOGIN_SHOW ); 3807 RTNENUM( STATE_LOGIN_SHOW );
3773 RTNENUM( STATE_LOGIN_WAIT ); 3808 RTNENUM( STATE_LOGIN_WAIT );
3774 RTNENUM( STATE_LOGIN_CLEANUP ); 3809 RTNENUM( STATE_LOGIN_CLEANUP );
3810 RTNENUM( STATE_LECTURE_PRIVACY );
3811 RTNENUM( STATE_PRIVACY_LECTURED );
3775 RTNENUM( STATE_LOGIN_VOICE_LICENSE ); 3812 RTNENUM( STATE_LOGIN_VOICE_LICENSE );
3776 RTNENUM( STATE_UPDATE_CHECK ); 3813 RTNENUM( STATE_UPDATE_CHECK );
3777 RTNENUM( STATE_LOGIN_AUTH_INIT ); 3814 RTNENUM( STATE_LOGIN_AUTH_INIT );
diff --git a/linden/indra/newview/llstartup.h b/linden/indra/newview/llstartup.h
index 08862e6..3fe8daa 100644
--- a/linden/indra/newview/llstartup.h
+++ b/linden/indra/newview/llstartup.h
@@ -49,7 +49,9 @@ typedef enum {
49 STATE_BROWSER_INIT, // Initialize web browser for login screen 49 STATE_BROWSER_INIT, // Initialize web browser for login screen
50 STATE_LOGIN_SHOW, // Show login screen 50 STATE_LOGIN_SHOW, // Show login screen
51 STATE_LOGIN_WAIT, // Wait for user input at login screen 51 STATE_LOGIN_WAIT, // Wait for user input at login screen
52 STATE_LOGIN_CLEANUP, // Get rid of login screen and start login 52 STATE_LOGIN_CLEANUP, // lecture about privacy
53 STATE_LECTURE_PRIVACY, // wait until the lecture was read
54 STATE_PRIVACY_LECTURED, // Get rid of login screen and start login
53 STATE_LOGIN_VOICE_LICENSE, // Show license agreement for using voice 55 STATE_LOGIN_VOICE_LICENSE, // Show license agreement for using voice
54 STATE_UPDATE_CHECK, // Wait for user at a dialog box (updates, term-of-service, etc) 56 STATE_UPDATE_CHECK, // Wait for user at a dialog box (updates, term-of-service, etc)
55 STATE_LOGIN_AUTH_INIT, // Start login to SL servers 57 STATE_LOGIN_AUTH_INIT, // Start login to SL servers
diff --git a/linden/indra/newview/lltexlayer.cpp b/linden/indra/newview/lltexlayer.cpp
index c8e1298..ceef28b 100644
--- a/linden/indra/newview/lltexlayer.cpp
+++ b/linden/indra/newview/lltexlayer.cpp
@@ -213,6 +213,7 @@ BOOL LLTexLayerSetBuffer::needsRender()
213 LLVOAvatar* avatar = mTexLayerSet->getAvatar(); 213 LLVOAvatar* avatar = mTexLayerSet->getAvatar();
214 BOOL upload_now = needsUploadNow(); 214 BOOL upload_now = needsUploadNow();
215 BOOL needs_update = (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating; 215 BOOL needs_update = (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating;
216
216 if (needs_update) 217 if (needs_update)
217 { 218 {
218 BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT); 219 BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT);
@@ -275,16 +276,16 @@ BOOL LLTexLayerSetBuffer::render()
275 } 276 }
276 else 277 else
277 { 278 {
278 // mUploadPending = FALSE;//see... 279 //mUploadPending = FALSE;//see...
279 // mNeedsUpload = FALSE;// ...below... 280 //mNeedsUpload = FALSE;// ...below...
280 LLVOAvatar* avatar = mTexLayerSet->getAvatar(); 281 LLVOAvatar* avatar = mTexLayerSet->getAvatar();
281 if (avatar) 282 if (avatar)
282 { 283 {
283 avatar->setNewBakedTexture(avatar->getBakedTE(mTexLayerSet), IMG_INVISIBLE); 284 avatar->setNewBakedTexture(avatar->getBakedTE(mTexLayerSet), IMG_INVISIBLE);
284 llinfos << "Invisible baked texture set for " << mTexLayerSet->getBodyRegion() << llendl; 285 llinfos << "Invisible baked texture set for " << mTexLayerSet->getBodyRegion() << llendl;
285 } 286 }
286 readBackAndUpload(); //... here: Opensim is not happy if we don't 287 readBackAndUpload(); //... here: Opensim is not happy if we don't
287 //TODO: find out if SL is happy if we do 288 //TODO: find out if SL is happy if we do
288 } 289 }
289 } 290 }
290 } 291 }
@@ -350,12 +351,11 @@ void LLTexLayerSetBuffer::readBackAndUpload()
350 // writes into baked_color_data 351 // writes into baked_color_data
351 const char* comment_text = NULL; 352 const char* comment_text = NULL;
352 353
353 S32 baked_image_components = 5; // red green blue bump clothing 354 S32 baked_image_components = 5; // red green blue bump clothing
354 LLPointer<LLImageRaw> baked_image = new LLImageRaw( mWidth, mHeight, baked_image_components ); 355 LLPointer<LLImageRaw> baked_image = new LLImageRaw( mWidth, mHeight, baked_image_components );
355 U8* baked_image_data = baked_image->getData(); 356 U8* baked_image_data = baked_image->getData();
356 357
357 comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask 358 comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask
358
359 S32 i = 0; 359 S32 i = 0;
360 for (S32 u = 0; u < mWidth; u++) 360 for (S32 u = 0; u < mWidth; u++)
361 { 361 {
@@ -492,7 +492,7 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* user
492 avatar->setNewBakedTexture(baked_te, uuid); 492 avatar->setNewBakedTexture(baked_te, uuid);
493 } 493 }
494 else 494 else
495 { 495 {
496 ++failures; 496 ++failures;
497 llinfos << "Baked upload failed (attempt " << failures << "/" << MAX_BAKE_UPLOAD_ATTEMPTS << "), "; 497 llinfos << "Baked upload failed (attempt " << failures << "/" << MAX_BAKE_UPLOAD_ATTEMPTS << "), ";
498 if (failures >= MAX_BAKE_UPLOAD_ATTEMPTS) 498 if (failures >= MAX_BAKE_UPLOAD_ATTEMPTS)
@@ -1412,7 +1412,7 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
1412 1412
1413 LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); 1413 LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode();
1414 1414
1415 gGL.getTexUnit(0)->bind(image_gl); 1415 gGL.getTexUnit(0)->bind(image_gl, TRUE);
1416 gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); 1416 gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
1417 1417
1418 gl_rect_2d_simple_tex( width, height ); 1418 gl_rect_2d_simple_tex( width, height );
@@ -1430,7 +1430,7 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
1430 LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); 1430 LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
1431 if( image_gl ) 1431 if( image_gl )
1432 { 1432 {
1433 gGL.getTexUnit(0)->bind(image_gl); 1433 gGL.getTexUnit(0)->bind(image_gl, TRUE);
1434 gl_rect_2d_simple_tex( width, height ); 1434 gl_rect_2d_simple_tex( width, height );
1435 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 1435 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
1436 } 1436 }
@@ -1656,7 +1656,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
1656 1656
1657 LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode(); 1657 LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode();
1658 1658
1659 gGL.getTexUnit(0)->bind(image_gl); 1659 gGL.getTexUnit(0)->bind(image_gl, TRUE);
1660 gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); 1660 gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
1661 1661
1662 gl_rect_2d_simple_tex( width, height ); 1662 gl_rect_2d_simple_tex( width, height );
@@ -1678,7 +1678,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
1678 ( (image_gl->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) 1678 ( (image_gl->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
1679 { 1679 {
1680 LLGLSNoAlphaTest gls_no_alpha_test; 1680 LLGLSNoAlphaTest gls_no_alpha_test;
1681 gGL.getTexUnit(0)->bind(image_gl); 1681 gGL.getTexUnit(0)->bind(image_gl, TRUE);
1682 gl_rect_2d_simple_tex( width, height ); 1682 gl_rect_2d_simple_tex( width, height );
1683 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 1683 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
1684 } 1684 }
@@ -2146,7 +2146,7 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
2146 } 2146 }
2147 2147
2148 LLGLSNoAlphaTest gls_no_alpha_test; 2148 LLGLSNoAlphaTest gls_no_alpha_test;
2149 gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); 2149 gGL.getTexUnit(0)->bind(mCachedProcessedImageGL, TRUE);
2150 gl_rect_2d_simple_tex( width, height ); 2150 gl_rect_2d_simple_tex( width, height );
2151 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 2151 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
2152 stop_glerror(); 2152 stop_glerror();
diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp
index 4679137..2e7d585 100644
--- a/linden/indra/newview/lltexturecache.cpp
+++ b/linden/indra/newview/lltexturecache.cpp
@@ -736,9 +736,6 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted)
736 736
737LLTextureCache::LLTextureCache(bool threaded) 737LLTextureCache::LLTextureCache(bool threaded)
738 : LLWorkerThread("TextureCache", threaded), 738 : LLWorkerThread("TextureCache", threaded),
739 mWorkersMutex(NULL),
740 mHeaderMutex(NULL),
741 mListMutex(NULL),
742 mHeaderAPRFile(NULL), 739 mHeaderAPRFile(NULL),
743 mReadOnly(FALSE), 740 mReadOnly(FALSE),
744 mTexturesSizeTotal(0), 741 mTexturesSizeTotal(0),
@@ -1543,7 +1540,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)
1543 } 1540 }
1544 } 1541 }
1545 1542
1546 unlockWorkers(); 1543 unlockWorkers();
1547 1544
1548 if (delete_worker) worker->scheduleDelete(); 1545 if (delete_worker) worker->scheduleDelete();
1549 1546
diff --git a/linden/indra/newview/lltexturecache.h b/linden/indra/newview/lltexturecache.h
index c859b9a..56b4c4f 100644
--- a/linden/indra/newview/lltexturecache.h
+++ b/linden/indra/newview/lltexturecache.h
@@ -139,9 +139,6 @@ protected:
139 std::string getTextureFileName(const LLUUID& id); 139 std::string getTextureFileName(const LLUUID& id);
140 void addCompleted(Responder* responder, bool success); 140 void addCompleted(Responder* responder, bool success);
141 141
142protected:
143 //void setFileAPRPool(apr_pool_t* pool) { mFileAPRPool = pool ; }
144
145private: 142private:
146 void setDirNames(ELLPath location); 143 void setDirNames(ELLPath location);
147 void readHeaderCache(); 144 void readHeaderCache();
diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp
index f93a574..072af25 100644
--- a/linden/indra/newview/lltexturefetch.cpp
+++ b/linden/indra/newview/lltexturefetch.cpp
@@ -428,7 +428,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
428 mRetryAttempt(0), 428 mRetryAttempt(0),
429 mActiveCount(0), 429 mActiveCount(0),
430 mGetStatus(0), 430 mGetStatus(0),
431 mWorkMutex(NULL),
432 mFirstPacket(0), 431 mFirstPacket(0),
433 mLastPacket(-1), 432 mLastPacket(-1),
434 mTotalPackets(0), 433 mTotalPackets(0),
@@ -1540,8 +1539,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
1540 mDebugPause(FALSE), 1539 mDebugPause(FALSE),
1541 mPacketCount(0), 1540 mPacketCount(0),
1542 mBadPacketCount(0), 1541 mBadPacketCount(0),
1543 mQueueMutex(getAPRPool()),
1544 mNetworkQueueMutex(getAPRPool()),
1545 mTextureCache(cache), 1542 mTextureCache(cache),
1546 mImageDecodeThread(imagedecodethread), 1543 mImageDecodeThread(imagedecodethread),
1547 mTextureBandwidth(0), 1544 mTextureBandwidth(0),
diff --git a/linden/indra/newview/lltoolpie.cpp b/linden/indra/newview/lltoolpie.cpp
index 296d1bb..34735a3 100644
--- a/linden/indra/newview/lltoolpie.cpp
+++ b/linden/indra/newview/lltoolpie.cpp
@@ -645,8 +645,6 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
645 } 645 }
646 */ 646 */
647 647
648
649 gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
650 648
651 LLViewerObject *object = NULL; 649 LLViewerObject *object = NULL;
652 LLViewerObject *parent = NULL; 650 LLViewerObject *parent = NULL;
@@ -697,9 +695,14 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
697 { 695 {
698 gViewerWindow->getWindow()->setCursor(UI_CURSOR_HAND); 696 gViewerWindow->getWindow()->setCursor(UI_CURSOR_HAND);
699 } 697 }
698 else
699 {
700 gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
701 }
700 } 702 }
701 else 703 else
702 { 704 {
705 gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
703 // We need to clear media hover flag 706 // We need to clear media hover flag
704 if (LLViewerMediaFocus::getInstance()->getMouseOverFlag()) 707 if (LLViewerMediaFocus::getInstance()->getMouseOverFlag())
705 { 708 {
diff --git a/linden/indra/newview/llvieweraudio.cpp b/linden/indra/newview/llvieweraudio.cpp
index 91e7ce5..d465177 100644
--- a/linden/indra/newview/llvieweraudio.cpp
+++ b/linden/indra/newview/llvieweraudio.cpp
@@ -33,6 +33,7 @@
33#include "llviewerprecompiledheaders.h" 33#include "llviewerprecompiledheaders.h"
34 34
35#include "llaudioengine.h" 35#include "llaudioengine.h"
36#include "kokuastreamingaudio.h"
36#include "llagent.h" 37#include "llagent.h"
37#include "llappviewer.h" 38#include "llappviewer.h"
38#include "llvieweraudio.h" 39#include "llvieweraudio.h"
@@ -46,69 +47,71 @@
46 47
47void init_audio() 48void init_audio()
48{ 49{
49 if (!gAudiop) 50 if (gAudiop)
50 { 51 {
51 llwarns << "Failed to create an appropriate Audio Engine" << llendl; 52 LLVector3d lpos_global = gAgent.getCameraPositionGlobal();
52 return; 53 LLVector3 lpos_global_f;
54
55 lpos_global_f.setVec(lpos_global);
56
57 gAudiop->setListener(lpos_global_f,
58 LLVector3::zero, // LLViewerCamera::getInstance()->getVelocity(), // !!! BUG need to replace this with smoothed velocity!
59 LLViewerCamera::getInstance()->getUpAxis(),
60 LLViewerCamera::getInstance()->getAtAxis());
61
62 // load up our initial set of sounds we'll want so they're in memory and ready to be played
63
64 bool mute_audio = gSavedSettings.getBOOL("MuteAudio");
65
66 if (!mute_audio && FALSE == gSavedSettings.getBOOL("NoPreload"))
67 {
68 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndAlert")));
69 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndBadKeystroke")));
70 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndChatFromObject")));
71 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClick")));
72 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClickRelease")));
73 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionF")));
74 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionM")));
75 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndIncomingChat")));
76 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndIncomingIM")));
77 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInvApplyToObject")));
78 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInvalidOp")));
79 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInventoryCopyToInv")));
80 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeDown")));
81 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeUp")));
82 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectCopyToInv")));
83 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectCreate")));
84 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectDelete")));
85 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezIn")));
86 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezOut")));
87 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuAppear")));
88 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuHide")));
89 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight0")));
90 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight1")));
91 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight2")));
92 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight3")));
93 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight4")));
94 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight5")));
95 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight6")));
96 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight7")));
97 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndSnapshot")));
98 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartAutopilot")));
99 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartFollowpilot")));
100 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartIM")));
101 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStopAutopilot")));
102 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTeleportOut")));
103 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTextureApplyToObject")));
104 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTextureCopyToInv")));
105 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTyping")));
106 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowClose")));
107 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen")));
108 }
53 } 109 }
54 LLVector3d lpos_global = gAgent.getCameraPositionGlobal(); 110 else
55 LLVector3 lpos_global_f;
56
57 lpos_global_f.setVec(lpos_global);
58
59 gAudiop->setListener(lpos_global_f,
60 LLVector3::zero, // LLViewerCamera::getInstance()->getVelocity(), // !!! BUG need to replace this with smoothed velocity!
61 LLViewerCamera::getInstance()->getUpAxis(),
62 LLViewerCamera::getInstance()->getAtAxis());
63
64// load up our initial set of sounds we'll want so they're in memory and ready to be played
65
66 bool mute_audio = gSavedSettings.getBOOL("MuteAudio");
67
68 if (!mute_audio && FALSE == gSavedSettings.getBOOL("NoPreload"))
69 { 111 {
70 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndAlert"))); 112 llwarns << "Failed to create an appropriate Audio Engine" << llendl;
71 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndBadKeystroke"))); 113 return;
72 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndChatFromObject")));
73 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClick")));
74 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClickRelease")));
75 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionF")));
76 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionM")));
77 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndIncomingChat")));
78 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndIncomingIM")));
79 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInvApplyToObject")));
80 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInvalidOp")));
81 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInventoryCopyToInv")));
82 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeDown")));
83 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeUp")));
84 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectCopyToInv")));
85 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectCreate")));
86 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectDelete")));
87 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezIn")));
88 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezOut")));
89 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuAppear")));
90 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuHide")));
91 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight0")));
92 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight1")));
93 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight2")));
94 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight3")));
95 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight4")));
96 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight5")));
97 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight6")));
98 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight7")));
99 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndSnapshot")));
100 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartAutopilot")));
101 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartFollowpilot")));
102 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartIM")));
103 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStopAutopilot")));
104 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTeleportOut")));
105 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTextureApplyToObject")));
106 //gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTextureCopyToInv")));
107 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTyping")));
108 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowClose")));
109 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen")));
110 } 114 }
111
112 audio_update_volume(true); 115 audio_update_volume(true);
113} 116}
114 117
@@ -158,12 +161,12 @@ void audio_update_volume(bool force_update)
158 } 161 }
159 162
160 // Streaming Music 163 // Streaming Music
161 if (gAudiop) 164 if (gAudioStream)
162 { 165 {
163 F32 music_volume = gSavedSettings.getF32("AudioLevelMusic"); 166 F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
164 BOOL music_muted = gSavedSettings.getBOOL("MuteMusic"); 167 BOOL music_muted = gSavedSettings.getBOOL("MuteMusic");
165 music_volume = mute_volume * master_volume * (music_volume*music_volume); 168 music_volume = mute_volume * master_volume * (music_volume*music_volume);
166 gAudiop->setInternetStreamGain ( music_muted ? 0.f : music_volume ); 169 gAudioStream->setInternetStreamGain ( music_muted ? 0.f : music_volume );
167 170
168 } 171 }
169 172
diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp
index 3675072..572f64a 100644
--- a/linden/indra/newview/llviewercontrol.cpp
+++ b/linden/indra/newview/llviewercontrol.cpp
@@ -38,8 +38,11 @@
38#include "indra_constants.h" 38#include "indra_constants.h"
39 39
40// For Listeners 40// For Listeners
41#include "llaudioengine.h" 41// #include "llaudioengine.h"
42#include "kokuastreamingaudio.h"
42#include "llagent.h" 43#include "llagent.h"
44#include "llavatarnamecache.h"
45#include "llcallingcard.h"
43#include "llconsole.h" 46#include "llconsole.h"
44#include "lldrawpoolterrain.h" 47#include "lldrawpoolterrain.h"
45#include "llflexibleobject.h" 48#include "llflexibleobject.h"
@@ -310,7 +313,7 @@ static bool handleJoystickChanged(const LLSD& newvalue)
310 313
311static bool handleAudioStreamMusicChanged(const LLSD& newvalue) 314static bool handleAudioStreamMusicChanged(const LLSD& newvalue)
312{ 315{
313 if (gAudiop) 316 if (gAudioStream)
314 { 317 {
315 if ( newvalue.asBoolean() ) 318 if ( newvalue.asBoolean() )
316 { 319 {
@@ -319,15 +322,15 @@ static bool handleAudioStreamMusicChanged(const LLSD& newvalue)
319 { 322 {
320 // if stream is already playing, don't call this 323 // if stream is already playing, don't call this
321 // otherwise music will briefly stop 324 // otherwise music will briefly stop
322 if ( !gAudiop->isInternetStreamPlaying() ) 325 if ( !gAudioStream->isInternetStreamPlaying() )
323 { 326 {
324 gAudiop->startInternetStream(LLViewerParcelMgr::getInstance()->getAgentParcel()->getMusicURL()); 327 gAudioStream->startInternetStream(LLViewerParcelMgr::getInstance()->getAgentParcel()->getMusicURL());
325 } 328 }
326 } 329 }
327 } 330 }
328 else 331 else
329 { 332 {
330 gAudiop->stopInternetStream(); 333 gAudioStream->stopInternetStream();
331 } 334 }
332 } 335 }
333 return true; 336 return true;
@@ -425,6 +428,28 @@ static bool handleAuditTextureChanged(const LLSD& newvalue)
425 return true; 428 return true;
426} 429}
427 430
431static bool handleDisplayNamesUsageChanged(const LLSD& newvalue)
432{
433 LLAvatarNameCache::setUseDisplayNames((U32)newvalue.asInteger());
434 LLVOAvatar::invalidateNameTags();
435 LLAvatarTracker::instance().dirtyBuddies();
436 return true;
437}
438
439static bool handleOmitResidentAsLastNameChanged(const LLSD& newvalue)
440{
441 LLAvatarName::sOmitResidentAsLastName =(bool)newvalue.asBoolean();
442 LLVOAvatar::invalidateNameTags();
443 LLAvatarTracker::instance().dirtyBuddies();
444 return true;
445}
446
447static bool handleLegacyNamesForFriendsChanged(const LLSD& newvalue)
448{
449 LLAvatarTracker::instance().dirtyBuddies();
450 return true;
451}
452
428static bool handleRenderDebugGLChanged(const LLSD& newvalue) 453static bool handleRenderDebugGLChanged(const LLSD& newvalue)
429{ 454{
430 gDebugGL = newvalue.asBoolean(); 455 gDebugGL = newvalue.asBoolean();
@@ -572,6 +597,9 @@ void settings_setup_listeners()
572 gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); 597 gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
573 gSavedSettings.getControl("AudioStreamingMusic")->getSignal()->connect(boost::bind(&handleAudioStreamMusicChanged, _1)); 598 gSavedSettings.getControl("AudioStreamingMusic")->getSignal()->connect(boost::bind(&handleAudioStreamMusicChanged, _1));
574 gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1)); 599 gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1));
600 gSavedSettings.getControl("DisplayNamesUsage")->getSignal()->connect(boost::bind(&handleDisplayNamesUsageChanged, _1));
601 gSavedSettings.getControl("OmitResidentAsLastName")->getSignal()->connect(boost::bind(&handleOmitResidentAsLastNameChanged, _1));
602 gSavedSettings.getControl("LegacyNamesForFriends")->getSignal()->connect(boost::bind(&handleLegacyNamesForFriendsChanged, _1));
575 gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); 603 gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
576 gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); 604 gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
577 gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); 605 gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
diff --git a/linden/indra/newview/llviewerdisplayname.cpp b/linden/indra/newview/llviewerdisplayname.cpp
new file mode 100644
index 0000000..6a7cab3
--- /dev/null
+++ b/linden/indra/newview/llviewerdisplayname.cpp
@@ -0,0 +1,208 @@
1/**
2 * @file llviewerdisplayname.cpp
3 * @brief Wrapper for display name functionality
4 *
5 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
6 * Second Life Viewer Source Code
7 * Copyright (C) 2010, Linden Research, Inc.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation;
12 * version 2.1 of the License only.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
24 * $/LicenseInfo$
25 */
26
27#include "llviewerprecompiledheaders.h"
28
29#include "llviewerdisplayname.h"
30
31// viewer includes
32#include "llagent.h"
33#include "llviewerregion.h"
34#include "llvoavatar.h"
35
36// library includes
37#include "llavatarnamecache.h"
38#include "llhttpclient.h"
39#include "llhttpnode.h"
40#include "llnotifications.h"
41#include "llui.h" // getLanguage()
42
43namespace LLViewerDisplayName
44{
45 // Fired when viewer receives server response to display name change
46 set_name_signal_t sSetDisplayNameSignal;
47
48 // Fired when there is a change in the agent's name
49 name_changed_signal_t sNameChangedSignal;
50
51 void addNameChangedCallback(const name_changed_signal_t::slot_type& cb)
52 {
53 sNameChangedSignal.connect(cb);
54 }
55
56}
57
58class LLSetDisplayNameResponder : public LLHTTPClient::Responder
59{
60public:
61 // only care about errors
62 /*virtual*/ void error(U32 status, const std::string& reason)
63 {
64 LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
65 LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
66 }
67};
68
69void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
70{
71 // TODO: simple validation here
72
73 LLViewerRegion* region = gAgent.getRegion();
74 llassert(region);
75 std::string cap_url = region->getCapability("SetDisplayName");
76 if (cap_url.empty())
77 {
78 // this server does not support display names, report error
79 slot(false, "unsupported", LLSD());
80 return;
81 }
82
83 // People API can return localized error messages. Indicate our
84 // language preference via header.
85 LLSD headers;
86 headers["Accept-Language"] = LLUI::getLanguage();
87
88 // People API requires both the old and new value to change a variable.
89 // Our display name will be in cache before the viewer's UI is available
90 // to request a change, so we can use direct lookup without callback.
91 LLAvatarName av_name;
92 if (!LLAvatarNameCache::get( gAgent.getID(), &av_name))
93 {
94 slot(false, "name unavailable", LLSD());
95 return;
96 }
97
98 // People API expects array of [ "old value", "new value" ]
99 LLSD change_array = LLSD::emptyArray();
100 change_array.append(av_name.mDisplayName);
101 change_array.append(display_name);
102
103 llinfos << "Set name POST to " << cap_url << llendl;
104
105 // Record our caller for when the server sends back a reply
106 sSetDisplayNameSignal.connect(slot);
107
108 // POST the requested change. The sim will not send a response back to
109 // this request directly, rather it will send a separate message after it
110 // communicates with the back-end.
111 LLSD body;
112 body["display_name"] = change_array;
113 LLHTTPClient::post(cap_url, body, new LLSetDisplayNameResponder, headers);
114}
115
116class LLSetDisplayNameReply : public LLHTTPNode
117{
118 LOG_CLASS(LLSetDisplayNameReply);
119public:
120 /*virtual*/ void post(
121 LLHTTPNode::ResponsePtr response,
122 const LLSD& context,
123 const LLSD& input) const
124 {
125 LLSD body = input["body"];
126
127 S32 status = body["status"].asInteger();
128 bool success = (status == 200);
129 std::string reason = body["reason"].asString();
130 LLSD content = body["content"];
131
132 llinfos << "status " << status << " reason " << reason << llendl;
133
134 // If viewer's concept of display name is out-of-date, the set request
135 // will fail with 409 Conflict. If that happens, fetch up-to-date
136 // name information.
137 if (status == 409)
138 {
139 LLUUID agent_id = gAgent.getID();
140 // Flush stale data
141 LLAvatarNameCache::erase( agent_id );
142 // Queue request for new data
143 LLAvatarName ignored;
144 LLAvatarNameCache::get( agent_id, &ignored );
145 // Kill name tag, as it is wrong
146 LLVOAvatar::invalidateNameTag( agent_id );
147 }
148
149 // inform caller of result
150 LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
151 LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
152 }
153};
154
155
156class LLDisplayNameUpdate : public LLHTTPNode
157{
158 /*virtual*/ void post(
159 LLHTTPNode::ResponsePtr response,
160 const LLSD& context,
161 const LLSD& input) const
162 {
163 LLSD body = input["body"];
164 LLUUID agent_id = body["agent_id"];
165 std::string old_display_name = body["old_display_name"];
166 // By convention this record is called "agent" in the People API
167 LLSD name_data = body["agent"];
168
169 // Inject the new name data into cache
170 LLAvatarName av_name;
171 av_name.fromLLSD( name_data );
172
173 llinfos << "name-update now " << LLDate::now()
174 << " next_update " << LLDate(av_name.mNextUpdate)
175 << llendl;
176
177 // Name expiration time may be provided in headers, or we may use a
178 // default value
179 // *TODO: get actual headers out of ResponsePtr
180 //LLSD headers = response->mHeaders;
181 LLSD headers;
182 av_name.mExpires =
183 LLAvatarNameCache::nameExpirationFromHeaders(headers);
184
185 LLAvatarNameCache::insert(agent_id, av_name);
186
187 // force name tag to update
188 LLVOAvatar::invalidateNameTag(agent_id);
189
190 LLSD args;
191 args["OLD_NAME"] = old_display_name;
192 args["SLID"] = av_name.mUsername;
193 args["NEW_NAME"] = av_name.mDisplayName;
194 LLNotifications::instance().add("DisplayNameUpdate", args);
195 if (agent_id == gAgent.getID())
196 {
197 LLViewerDisplayName::sNameChangedSignal();
198 }
199 }
200};
201
202LLHTTPRegistration<LLSetDisplayNameReply>
203 gHTTPRegistrationMessageSetDisplayNameReply(
204 "/message/SetDisplayNameReply");
205
206LLHTTPRegistration<LLDisplayNameUpdate>
207 gHTTPRegistrationMessageDisplayNameUpdate(
208 "/message/DisplayNameUpdate");
diff --git a/linden/indra/newview/llviewerdisplayname.h b/linden/indra/newview/llviewerdisplayname.h
new file mode 100644
index 0000000..16d59ae
--- /dev/null
+++ b/linden/indra/newview/llviewerdisplayname.h
@@ -0,0 +1,53 @@
1/**
2 * @file llviewerdisplayname.h
3 * @brief Wrapper for display name functionality
4 *
5 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
6 * Second Life Viewer Source Code
7 * Copyright (C) 2010, Linden Research, Inc.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation;
12 * version 2.1 of the License only.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
24 * $/LicenseInfo$
25 */
26
27#ifndef LLVIEWERDISPLAYNAME_H
28#define LLVIEWERDISPLAYNAME_H
29
30#include <boost/signals2.hpp>
31
32class LLSD;
33class LLUUID;
34
35namespace LLViewerDisplayName
36{
37 typedef boost::signals2::signal<
38 void (bool success, const std::string& reason, const LLSD& content)>
39 set_name_signal_t;
40 typedef set_name_signal_t::slot_type set_name_slot_t;
41
42 typedef boost::signals2::signal<void (void)> name_changed_signal_t;
43 typedef name_changed_signal_t::slot_type name_changed_slot_t;
44
45 // Sends an update to the server to change a display name
46 // and call back when done. May not succeed due to service
47 // unavailable or name not available.
48 void set(const std::string& display_name, const set_name_slot_t& slot);
49
50 void addNameChangedCallback(const name_changed_signal_t::slot_type& cb);
51}
52
53#endif // LLVIEWERDISPLAYNAME_H
diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp
index 5c01b25..f0faedf 100644
--- a/linden/indra/newview/llviewermedia.cpp
+++ b/linden/indra/newview/llviewermedia.cpp
@@ -402,7 +402,7 @@ bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
402 { 402 {
403 if(! initializePlugin(mime_type)) 403 if(! initializePlugin(mime_type))
404 { 404 {
405 LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << mime_type << LL_ENDL; 405 LL_WARNS("PluginViewerMedia") << "plugin intialization failed for mime type: " << mime_type << LL_ENDL;
406 LLSD args; 406 LLSD args;
407 args["MIME_TYPE"] = mime_type; 407 args["MIME_TYPE"] = mime_type;
408 LLNotifications::instance().add("NoPlugin", args); 408 LLNotifications::instance().add("NoPlugin", args);
@@ -520,7 +520,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
520 } 520 }
521 } 521 }
522 522
523 LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << media_type << LL_ENDL; 523 LL_WARNS("PluginViewerMedia") << "plugin intialization failed for mime type: " << media_type << LL_ENDL;
524 LLSD args; 524 LLSD args;
525 args["MIME_TYPE"] = media_type; 525 args["MIME_TYPE"] = media_type;
526 LLNotifications::instance().add("NoPlugin", args); 526 LLNotifications::instance().add("NoPlugin", args);
diff --git a/linden/indra/newview/llviewermedia_streamingaudio.cpp b/linden/indra/newview/llviewermedia_streamingaudio.cpp
index 575dbc8..6a4dd0f 100644
--- a/linden/indra/newview/llviewermedia_streamingaudio.cpp
+++ b/linden/indra/newview/llviewermedia_streamingaudio.cpp
@@ -69,8 +69,13 @@ void LLStreamingAudio_MediaPlugins::start(const std::string& url)
69 llinfos << "mMediaPlugin is now " << mMediaPlugin << llendl; 69 llinfos << "mMediaPlugin is now " << mMediaPlugin << llendl;
70 } 70 }
71 71
72 mVersion = mMediaPlugin ? mMediaPlugin->getPluginVersion() : std::string();
73
72 if(!mMediaPlugin) 74 if(!mMediaPlugin)
75 {
76 llinfos << "mMediaPlugin failed to initialize!" << llendl;
73 return; 77 return;
78 }
74 79
75 if (!url.empty()) { 80 if (!url.empty()) {
76 llinfos << "Starting internet stream: " << url << llendl; 81 llinfos << "Starting internet stream: " << url << llendl;
@@ -156,6 +161,11 @@ std::string LLStreamingAudio_MediaPlugins::getURL()
156 return mURL; 161 return mURL;
157} 162}
158 163
164std::string LLStreamingAudio_MediaPlugins::getVersion()
165{
166 return mVersion;
167}
168
159void LLStreamingAudio_MediaPlugins::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) 169void LLStreamingAudio_MediaPlugins::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
160{ 170{
161 if (event == MEDIA_EVENT_NAME_CHANGED) 171 if (event == MEDIA_EVENT_NAME_CHANGED)
diff --git a/linden/indra/newview/llviewermedia_streamingaudio.h b/linden/indra/newview/llviewermedia_streamingaudio.h
index 816e213..5802a31 100644
--- a/linden/indra/newview/llviewermedia_streamingaudio.h
+++ b/linden/indra/newview/llviewermedia_streamingaudio.h
@@ -56,6 +56,7 @@ class LLStreamingAudio_MediaPlugins :
56 /*virtual*/ void setGain(F32 vol); 56 /*virtual*/ void setGain(F32 vol);
57 /*virtual*/ F32 getGain(); 57 /*virtual*/ F32 getGain();
58 /*virtual*/ std::string getURL(); 58 /*virtual*/ std::string getURL();
59 /*virtual*/ std::string getVersion();
59 60
60 // inherited from LLPluginClassMediaOwner 61 // inherited from LLPluginClassMediaOwner
61 /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); 62 /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
@@ -66,6 +67,7 @@ private:
66 LLPluginClassMedia *mMediaPlugin; 67 LLPluginClassMedia *mMediaPlugin;
67 std::string mURL; 68 std::string mURL;
68 F32 mGain; 69 F32 mGain;
70 std::string mVersion;
69}; 71};
70 72
71 73
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp
index 7f00382..777a871 100644
--- a/linden/indra/newview/llviewermenu.cpp
+++ b/linden/indra/newview/llviewermenu.cpp
@@ -41,6 +41,7 @@
41 41
42// linden library includes 42// linden library includes
43#include "llaudioengine.h" 43#include "llaudioengine.h"
44#include "llavatarnamecache.h"
44#include "indra_constants.h" 45#include "indra_constants.h"
45#include "llassetstorage.h" 46#include "llassetstorage.h"
46#include "llchat.h" 47#include "llchat.h"
@@ -102,6 +103,7 @@
102#include "llfloatercustomize.h" 103#include "llfloatercustomize.h"
103#include "llfloaterdaycycle.h" 104#include "llfloaterdaycycle.h"
104#include "llfloaterdirectory.h" 105#include "llfloaterdirectory.h"
106#include "llfloaterdisplayname.h"
105#include "llfloatereditui.h" 107#include "llfloatereditui.h"
106#include "llfloaterchatterbox.h" 108#include "llfloaterchatterbox.h"
107#include "llfloaterfriends.h" 109#include "llfloaterfriends.h"
@@ -3434,6 +3436,16 @@ class LLEditEnableCustomizeAvatar : public view_listener_t
3434 } 3436 }
3435}; 3437};
3436 3438
3439class LLEditEnableDisplayName : public view_listener_t
3440{
3441 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3442 {
3443 bool new_value = (LLAvatarNameCache::useDisplayNames() != 0);
3444 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
3445 return true;
3446 }
3447};
3448
3437// only works on pie menu 3449// only works on pie menu
3438bool handle_sit_or_stand() 3450bool handle_sit_or_stand()
3439{ 3451{
@@ -5959,6 +5971,10 @@ class LLShowFloater : public view_listener_t
5959 { 5971 {
5960 LLToolBar::toggle(NULL); 5972 LLToolBar::toggle(NULL);
5961 } 5973 }
5974 else if (floater_name == "displayname")
5975 {
5976 LLFloaterDisplayName::show();
5977 }
5962 else if (floater_name == "chat history") 5978 else if (floater_name == "chat history")
5963 { 5979 {
5964 LLFloaterChat::toggleInstance(LLSD()); 5980 LLFloaterChat::toggleInstance(LLSD());
@@ -10666,6 +10682,20 @@ class LLAdvancedDumpAvatarLocalTextures : public view_listener_t
10666 } 10682 }
10667}; 10683};
10668 10684
10685///////////////////////////////////
10686// Reload Avatar Cloud Particles //
10687///////////////////////////////////
10688
10689
10690class LLAdvancedReloadAvatarCloudParticle : public view_listener_t
10691{
10692 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
10693 {
10694 LLVOAvatar::initCloud();
10695 return true;
10696 }
10697};
10698
10669/////////// 10699///////////
10670// Crash // 10700// Crash //
10671/////////// 10701///////////
@@ -11118,6 +11148,7 @@ void initialize_menus()
11118 addMenu(new LLEditEnableDuplicate(), "Edit.EnableDuplicate"); 11148 addMenu(new LLEditEnableDuplicate(), "Edit.EnableDuplicate");
11119 addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff"); 11149 addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff");
11120 addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar"); 11150 addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar");
11151 addMenu(new LLEditEnableDisplayName(), "Edit.EnableDisplayName");
11121 addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures"); 11152 addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
11122 11153
11123 // View menu 11154 // View menu
@@ -11453,6 +11484,7 @@ void initialize_menus()
11453 addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments"); 11484 addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
11454 addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures"); 11485 addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
11455 addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures"); 11486 addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
11487 addMenu(new LLAdvancedReloadAvatarCloudParticle(), "Advanced.ReloadAvatarCloudParticle");
11456 11488
11457 // Advanced > Crash 11489 // Advanced > Crash
11458 addMenu(new LLAdvancedCrash(), "Advanced.Crash"); 11490 addMenu(new LLAdvancedCrash(), "Advanced.Crash");
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 5f333e9..9ebfd04 100755
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -2998,6 +2998,33 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2998 2998
2999 if (is_audible) 2999 if (is_audible)
3000 { 3000 {
3001 if (chatter && chatter->isAvatar())
3002 {
3003#ifdef LL_RRINTERFACE_H //MK
3004 if (!gRRenabled || !gAgent.mRRInterface.mContainsShownames)
3005 {
3006#endif //mk
3007 if (LLAvatarNameCache::useDisplayNames())
3008 {
3009 LLAvatarName avatar_name;
3010 if (LLAvatarNameCache::get(from_id, &avatar_name))
3011 {
3012 if (LLAvatarNameCache::useDisplayNames() == 1)
3013 {
3014 from_name = avatar_name.mDisplayName;
3015 }
3016 else
3017 {
3018 from_name = avatar_name.getNames();
3019 }
3020 }
3021 chat.mFromName = from_name;
3022 }
3023#ifdef LL_RRINTERFACE_H //MK
3024 }
3025#endif //mk
3026 }
3027
3001 BOOL visible_in_chat_bubble = FALSE; 3028 BOOL visible_in_chat_bubble = FALSE;
3002 std::string verb; 3029 std::string verb;
3003 3030
diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp
index a2be26a..65c1d11 100644
--- a/linden/indra/newview/llviewerobject.cpp
+++ b/linden/indra/newview/llviewerobject.cpp
@@ -4206,7 +4206,7 @@ void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters,
4206 LLViewerImage* image; 4206 LLViewerImage* image;
4207 if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null) 4207 if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
4208 { 4208 {
4209 image = gImageList.getImageFromFile("pixiesmall.tga"); 4209 image = gImageList.getImageFromFile("pixiesmall.j2c");
4210 } 4210 }
4211 else 4211 else
4212 { 4212 {
diff --git a/linden/indra/newview/llviewerparcelmgr.cpp b/linden/indra/newview/llviewerparcelmgr.cpp
index b589f2e..630da54 100644
--- a/linden/indra/newview/llviewerparcelmgr.cpp
+++ b/linden/indra/newview/llviewerparcelmgr.cpp
@@ -35,7 +35,7 @@
35#include "llviewerparcelmgr.h" 35#include "llviewerparcelmgr.h"
36 36
37// Library includes 37// Library includes
38#include "llaudioengine.h" 38#include "kokuastreamingaudio.h"
39#include "indra_constants.h" 39#include "indra_constants.h"
40#include "llcachename.h" 40#include "llcachename.h"
41#include "llgl.h" 41#include "llgl.h"
@@ -1672,7 +1672,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
1672 else 1672 else
1673 { 1673 {
1674 // look for music. 1674 // look for music.
1675 if (gAudiop) 1675 if (gAudioStream)
1676 { 1676 {
1677 if (parcel) 1677 if (parcel)
1678 { 1678 {
@@ -1685,12 +1685,12 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
1685 // On entering a new parcel, stop the last stream if the 1685 // On entering a new parcel, stop the last stream if the
1686 // new parcel has a different music url. (Empty URL counts 1686 // new parcel has a different music url. (Empty URL counts
1687 // as different.) 1687 // as different.)
1688 const std::string& stream_url = gAudiop->getInternetStreamURL(); 1688 const std::string& stream_url = gAudioStream->getInternetStreamURL();
1689 1689
1690 if (music_url.empty() || music_url != stream_url) 1690 if (music_url.empty() || music_url != stream_url)
1691 { 1691 {
1692 // URL is different from one currently playing. 1692 // URL is different from one currently playing.
1693 gAudiop->stopInternetStream(); 1693 gAudioStream->stopInternetStream();
1694 1694
1695 // If there is a new music URL and it's valid, play it. 1695 // If there is a new music URL and it's valid, play it.
1696 if (music_url.size() > 12) 1696 if (music_url.size() > 12)
@@ -1700,19 +1700,19 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
1700 optionally_start_music(music_url); 1700 optionally_start_music(music_url);
1701 } 1701 }
1702 } 1702 }
1703 else if (!gAudiop->getInternetStreamURL().empty()) 1703 else if (!gAudioStream->getInternetStreamURL().empty())
1704 { 1704 {
1705 llinfos << "Stopping parcel music" << llendl; 1705 llinfos << "Stopping parcel music" << llendl;
1706 gAudiop->startInternetStream(LLStringUtil::null); 1706 gAudioStream->startInternetStream(LLStringUtil::null);
1707 } 1707 }
1708 } 1708 }
1709 } 1709 }
1710 else 1710 else
1711 { 1711 {
1712 // Public land has no music 1712 // Public land has no music
1713 gAudiop->stopInternetStream(); 1713 gAudioStream->stopInternetStream();
1714 } 1714 }
1715 }//if gAudiop 1715 }//if gAudioStream
1716 1716
1717 // now check for video 1717 // now check for video
1718 LLViewerParcelMedia::update( parcel ); 1718 LLViewerParcelMedia::update( parcel );
@@ -1730,7 +1730,7 @@ void optionally_start_music(const std::string& music_url)
1730 // changed as part of SL-4878 1730 // changed as part of SL-4878
1731 if ( gOverlayBar && gOverlayBar->musicPlaying()) 1731 if ( gOverlayBar && gOverlayBar->musicPlaying())
1732 { 1732 {
1733 gAudiop->startInternetStream(music_url); 1733 gAudioStream->startInternetStream(music_url);
1734 } 1734 }
1735 } 1735 }
1736} 1736}
diff --git a/linden/indra/newview/llviewerprecompiledheaders.h b/linden/indra/newview/llviewerprecompiledheaders.h
index 9bc6574..a0b99bf 100644
--- a/linden/indra/newview/llviewerprecompiledheaders.h
+++ b/linden/indra/newview/llviewerprecompiledheaders.h
@@ -165,7 +165,7 @@
165#include "llinstantmessage.h" 165#include "llinstantmessage.h"
166#include "llinvite.h" 166#include "llinvite.h"
167//#include "llloginflags.h" 167//#include "llloginflags.h"
168#include "llmail.h" 168//#include "llmail.h"
169#include "llmessagethrottle.h" 169#include "llmessagethrottle.h"
170#include "llnamevalue.h" 170#include "llnamevalue.h"
171#include "llpacketack.h" 171#include "llpacketack.h"
diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp
index d93c425..a8047b8 100644
--- a/linden/indra/newview/llviewerregion.cpp
+++ b/linden/indra/newview/llviewerregion.cpp
@@ -127,6 +127,8 @@ public:
127 } 127 }
128 } 128 }
129 129
130 mRegion->setCapabilitiesReceived(true);
131
130 if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) 132 if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
131 { 133 {
132 LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED ); 134 LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
@@ -172,7 +174,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
172 mCacheEntriesCount(0), 174 mCacheEntriesCount(0),
173 mCacheID(), 175 mCacheID(),
174 mEventPoll(NULL), 176 mEventPoll(NULL),
175 mReleaseNotesRequested(FALSE) 177 mReleaseNotesRequested(FALSE),
178 mCapabilitiesReceived(false)
176{ 179{
177 mWidth = region_width_meters; 180 mWidth = region_width_meters;
178 mOriginGlobal = from_region_handle(handle); 181 mOriginGlobal = from_region_handle(handle);
@@ -1431,6 +1434,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
1431 capabilityNames.append("FetchInventory"); 1434 capabilityNames.append("FetchInventory");
1432 capabilityNames.append("FetchLib"); 1435 capabilityNames.append("FetchLib");
1433 capabilityNames.append("FetchLibDescendents"); 1436 capabilityNames.append("FetchLibDescendents");
1437 capabilityNames.append("GetDisplayNames");
1438 capabilityNames.append("SetDisplayName");
1434 capabilityNames.append("GetTexture"); 1439 capabilityNames.append("GetTexture");
1435 capabilityNames.append("GroupProposalBallot"); 1440 capabilityNames.append("GroupProposalBallot");
1436 capabilityNames.append("HomeLocation"); 1441 capabilityNames.append("HomeLocation");
@@ -1509,6 +1514,16 @@ std::string LLViewerRegion::getCapability(const std::string& name) const
1509 return iter->second; 1514 return iter->second;
1510} 1515}
1511 1516
1517bool LLViewerRegion::capabilitiesReceived() const
1518{
1519 return mCapabilitiesReceived;
1520}
1521
1522void LLViewerRegion::setCapabilitiesReceived(bool received)
1523{
1524 mCapabilitiesReceived = received;
1525}
1526
1512void LLViewerRegion::logActiveCapabilities() const 1527void LLViewerRegion::logActiveCapabilities() const
1513{ 1528{
1514 int count = 0; 1529 int count = 0;
diff --git a/linden/indra/newview/llviewerregion.h b/linden/indra/newview/llviewerregion.h
index 8cc80e3..5ce8b2e 100644
--- a/linden/indra/newview/llviewerregion.h
+++ b/linden/indra/newview/llviewerregion.h
@@ -229,6 +229,11 @@ public:
229 void setSeedCapability(const std::string& url); 229 void setSeedCapability(const std::string& url);
230 void setCapability(const std::string& name, const std::string& url); 230 void setCapability(const std::string& name, const std::string& url);
231 std::string getCapability(const std::string& name) const; 231 std::string getCapability(const std::string& name) const;
232
233 // has region received its final (not seed) capability list?
234 bool capabilitiesReceived() const;
235 void setCapabilitiesReceived(bool received);
236
232 static bool isSpecialCapabilityName(const std::string &name); 237 static bool isSpecialCapabilityName(const std::string &name);
233 void logActiveCapabilities() const; 238 void logActiveCapabilities() const;
234 239
@@ -399,6 +404,7 @@ private:
399 404
400private: 405private:
401 bool mAlive; // can become false if circuit disconnects 406 bool mAlive; // can become false if circuit disconnects
407 bool mCapabilitiesReceived;
402 408
403 //spatial partitions for objects in this region 409 //spatial partitions for objects in this region
404 std::vector<LLSpatialPartition*> mObjectPartition; 410 std::vector<LLSpatialPartition*> mObjectPartition;
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp
index 6904bb2..27a848f 100644
--- a/linden/indra/newview/llvoavatar.cpp
+++ b/linden/indra/newview/llvoavatar.cpp
@@ -38,6 +38,7 @@
38#include <ctype.h> 38#include <ctype.h>
39 39
40#include "llaudioengine.h" 40#include "llaudioengine.h"
41#include "llavatarnamecache.h"
41#include "noise.h" 42#include "noise.h"
42 43
43#include "llagent.h" // Get state values from here 44#include "llagent.h" // Get state values from here
@@ -748,6 +749,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
748 mAppearanceAnimating(FALSE), 749 mAppearanceAnimating(FALSE),
749 mNameString(), 750 mNameString(),
750 mTitle(), 751 mTitle(),
752 mCompleteName(),
751 mNameAway(FALSE), 753 mNameAway(FALSE),
752 mNameBusy(FALSE), 754 mNameBusy(FALSE),
753 mNameMute(FALSE), 755 mNameMute(FALSE),
@@ -1474,6 +1476,7 @@ void LLVOAvatar::initClass()
1474 { 1476 {
1475 loadClientTags(); 1477 loadClientTags();
1476 } 1478 }
1479 initCloud();
1477} 1480}
1478 1481
1479 1482
@@ -1489,6 +1492,21 @@ void LLVOAvatar::cleanupClass()
1489 sXMLTree.cleanup(); 1492 sXMLTree.cleanup();
1490} 1493}
1491 1494
1495LLPartSysData LLVOAvatar::sCloud;
1496void LLVOAvatar::initCloud()
1497{
1498 // fancy particle cloud designed by Brent
1499
1500 std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "cloud.xml");
1501 LLSD cloud;
1502 llifstream in_file(filename);
1503 LLSDSerialize::fromXMLDocument(cloud, in_file);
1504 sCloud.fromLLSD(cloud);
1505 LLViewerImage* cloud_image = gImageList.getImageFromFile("cloud-particle.j2c");
1506 sCloud.mPartImageID = cloud_image->getID();
1507
1508}
1509
1492const LLVector3 LLVOAvatar::getRenderPosition() const 1510const LLVector3 LLVOAvatar::getRenderPosition() const
1493{ 1511{
1494 if (mDrawable.isNull() || mDrawable->getGeneration() < 0) 1512 if (mDrawable.isNull() || mDrawable->getGeneration() < 0)
@@ -2872,7 +2890,7 @@ void LLVOAvatar::idleUpdateAppearanceAnimation()
2872 param; 2890 param;
2873 param = getNextVisualParam()) 2891 param = getNextVisualParam())
2874 { 2892 {
2875 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) 2893 if (param->isTweakable())
2876 { 2894 {
2877 param->stopAnimating(mAppearanceAnimSetByUser); 2895 param->stopAnimating(mAppearanceAnimSetByUser);
2878 } 2896 }
@@ -2904,7 +2922,7 @@ void LLVOAvatar::idleUpdateAppearanceAnimation()
2904 param; 2922 param;
2905 param = getNextVisualParam()) 2923 param = getNextVisualParam())
2906 { 2924 {
2907 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) 2925 if (param->isTweakable())
2908 { 2926 {
2909 // so boobs don't go spastic when a shape's changed, but still seems buggy 2927 // so boobs don't go spastic when a shape's changed, but still seems buggy
2910 //if(param->getID() != 507) 2928 //if(param->getID() != 507)
@@ -3070,34 +3088,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
3070 } 3088 }
3071 else 3089 else
3072 { 3090 {
3073 LLPartSysData particle_parameters; 3091 setParticleSource(sCloud, getID());
3074
3075 // fancy particle cloud designed by Brent
3076 particle_parameters.mPartData.mMaxAge = 4.f;
3077 particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
3078 particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
3079 particle_parameters.mPartData.mStartScale.mV[VY] = 1.0f;
3080 particle_parameters.mPartData.mEndScale.mV[VX] = 0.02f;
3081 particle_parameters.mPartData.mEndScale.mV[VY] = 0.02f;
3082 particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f);
3083 particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f);
3084 particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
3085 LLViewerImage* cloud = gImageList.getImageFromFile("cloud-particle.j2c");
3086 particle_parameters.mPartImageID = cloud->getID();
3087 particle_parameters.mMaxAge = 0.f;
3088 particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE;
3089 particle_parameters.mInnerAngle = 3.14159f;
3090 particle_parameters.mOuterAngle = 0.f;
3091 particle_parameters.mBurstRate = 0.02f;
3092 particle_parameters.mBurstRadius = 0.0f;
3093 particle_parameters.mBurstPartCount = 1;
3094 particle_parameters.mBurstSpeedMin = 0.1f;
3095 particle_parameters.mBurstSpeedMax = 1.f;
3096 particle_parameters.mPartData.mFlags = ( LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
3097 LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK |
3098 LLPartData::LL_PART_TARGET_POS_MASK );
3099
3100 setParticleSource(particle_parameters, getID());
3101 } 3092 }
3102 } 3093 }
3103} 3094}
@@ -3620,6 +3611,35 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3620 3611
3621 if (mNameText.notNull() && firstname && lastname) 3612 if (mNameText.notNull() && firstname && lastname)
3622 { 3613 {
3614 std::string complete_name = firstname->getString();
3615 if (sRenderGroupTitles)
3616 {
3617 complete_name += " ";
3618 }
3619 else
3620 {
3621 // If all group titles are turned off, stack first name
3622 // on a line above last name
3623 complete_name += "\n";
3624 }
3625 complete_name += lastname->getString();
3626
3627 if (LLAvatarNameCache::useDisplayNames())
3628 {
3629 LLAvatarName avatar_name;
3630 if (LLAvatarNameCache::get(getID(), &avatar_name))
3631 {
3632 if (LLAvatarNameCache::useDisplayNames() == 1)
3633 {
3634 complete_name = avatar_name.mDisplayName;
3635 }
3636 else
3637 {
3638 complete_name = avatar_name.getNames(true);
3639 }
3640 }
3641 }
3642
3623 BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); 3643 BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end();
3624 BOOL is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end(); 3644 BOOL is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end();
3625 BOOL is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); 3645 BOOL is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
@@ -3634,7 +3654,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3634 } 3654 }
3635 3655
3636 if (mNameString.empty() || 3656 if (mNameString.empty() ||
3637 new_name || 3657 new_name || complete_name != mCompleteName ||
3638 (!title && !mTitle.empty()) || 3658 (!title && !mTitle.empty()) ||
3639 (title && mTitle != title->getString()) || 3659 (title && mTitle != title->getString()) ||
3640 (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) 3660 (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute)
@@ -3650,20 +3670,19 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3650 line += title->getString(); 3670 line += title->getString();
3651 //LLStringFn::replace_ascii_controlchars(line,LL_UNKNOWN_CHAR); IMP-136 -- McCabe 3671 //LLStringFn::replace_ascii_controlchars(line,LL_UNKNOWN_CHAR); IMP-136 -- McCabe
3652 line += "\n"; 3672 line += "\n";
3653 line += firstname->getString(); 3673 line += complete_name;
3654 } 3674 }
3655 else 3675 else
3656 { 3676 {
3657 line += firstname->getString(); 3677 line += complete_name;
3658 } 3678 }
3659 3679
3660 line += " "; 3680
3661 line += lastname->getString();
3662// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b 3681// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b
3663 } 3682 }
3664 else 3683 else
3665 { 3684 {
3666 line = RlvStrings::getAnonym(line.assign(firstname->getString()).append(" ").append(lastname->getString())); 3685 line = RlvStrings::getAnonym(complete_name);
3667 } 3686 }
3668// [/RLVa:KB] 3687// [/RLVa:KB]
3669 3688
@@ -3673,7 +3692,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3673 bool show_client = client.length() != 0 && (*sShowClientNameTag); 3692 bool show_client = client.length() != 0 && (*sShowClientNameTag);
3674 if (is_away || is_muted || is_busy || show_client) 3693 if (is_away || is_muted || is_busy || show_client)
3675 { 3694 {
3676 line += " ("; 3695 line += "\n(";
3677 if (is_away) 3696 if (is_away)
3678 { 3697 {
3679 line += "Away"; 3698 line += "Away";
@@ -3718,6 +3737,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3718 mNameMute = is_muted; 3737 mNameMute = is_muted;
3719 mNameAppearance = is_appearance; 3738 mNameAppearance = is_appearance;
3720 mTitle = title ? title->getString() : ""; 3739 mTitle = title ? title->getString() : "";
3740 mCompleteName = complete_name;
3721 //LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); IMP-136 -- McCabe 3741 //LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); IMP-136 -- McCabe
3722 mNameString = utf8str_to_wstring(line); 3742 mNameString = utf8str_to_wstring(line);
3723 new_name = TRUE; 3743 new_name = TRUE;
@@ -3834,6 +3854,41 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3834 } 3854 }
3835} 3855}
3836 3856
3857void LLVOAvatar::clearNameTag()
3858{
3859 mNameString.clear();
3860 if (mNameText)
3861 {
3862 mNameText->setLabel("");
3863 mNameText->setString(mNameString);
3864 }
3865}
3866
3867//static
3868void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id)
3869{
3870 LLViewerObject* obj = gObjectList.findObject(agent_id);
3871 if (!obj) return;
3872
3873 LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(obj);
3874 if (!avatar) return;
3875
3876 avatar->clearNameTag();
3877}
3878
3879//static
3880void LLVOAvatar::invalidateNameTags()
3881{
3882 std::vector<LLCharacter*>::iterator it;
3883 for (it = LLCharacter::sInstances.begin(); it != LLCharacter::sInstances.end(); ++it)
3884 {
3885 LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*it);
3886 if (!avatar) continue;
3887 if (avatar->isDead()) continue;
3888
3889 avatar->clearNameTag();
3890 }
3891}
3837 3892
3838void LLVOAvatar::idleUpdateTractorBeam() 3893void LLVOAvatar::idleUpdateTractorBeam()
3839{ 3894{
@@ -4820,6 +4875,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
4820 && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked 4875 && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
4821 && !LLDrawPoolAvatar::sSkipTransparent; 4876 && !LLDrawPoolAvatar::sSkipTransparent;
4822 4877
4878
4823 LLGLState test(GL_ALPHA_TEST, should_alpha_mask); 4879 LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
4824 4880
4825 if (should_alpha_mask) 4881 if (should_alpha_mask)
@@ -4935,7 +4991,6 @@ U32 LLVOAvatar::renderRigid()
4935 && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked 4991 && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
4936 && !LLDrawPoolAvatar::sSkipTransparent; 4992 && !LLDrawPoolAvatar::sSkipTransparent;
4937 4993
4938
4939 LLGLState test(GL_ALPHA_TEST, should_alpha_mask); 4994 LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
4940 4995
4941 if (should_alpha_mask) 4996 if (should_alpha_mask)
@@ -5918,6 +5973,7 @@ BOOL LLVOAvatar::loadAvatar()
5918 if (sAvatarXmlInfo->mLayerInfoList.empty()) 5973 if (sAvatarXmlInfo->mLayerInfoList.empty())
5919 { 5974 {
5920 llwarns << "avatar file: missing <layer_set> node" << llendl; 5975 llwarns << "avatar file: missing <layer_set> node" << llendl;
5976 return FALSE;
5921 } 5977 }
5922 else 5978 else
5923 { 5979 {
@@ -5958,23 +6014,22 @@ BOOL LLVOAvatar::loadAvatar()
5958 } 6014 }
5959 6015
5960 // avatar_lad.xml : <driver_parameters> 6016 // avatar_lad.xml : <driver_parameters>
6017 LLVOAvatarXmlInfo::driver_info_list_t::iterator iter;
6018 for (iter = sAvatarXmlInfo->mDriverInfoList.begin();
6019 iter != sAvatarXmlInfo->mDriverInfoList.end(); iter++)
5961 { 6020 {
5962 LLVOAvatarXmlInfo::driver_info_list_t::iterator iter; 6021 LLDriverParamInfo *info = *iter;
5963 for (iter = sAvatarXmlInfo->mDriverInfoList.begin(); 6022 LLDriverParam* driver_param = new LLDriverParam( this );
5964 iter != sAvatarXmlInfo->mDriverInfoList.end(); iter++) 6023 if (driver_param->setInfo(info))
5965 { 6024 {
5966 LLDriverParamInfo *info = *iter; 6025 addVisualParam( driver_param );
5967 LLDriverParam* driver_param = new LLDriverParam( this ); 6026 }
5968 if (driver_param->setInfo(info)) 6027 else
5969 { 6028 {
5970 addVisualParam( driver_param ); 6029 delete driver_param;
5971 } 6030 llwarns << "avatar file: driver_param->parseData() failed" << llendl;
5972 else 6031 return FALSE;
5973 { 6032
5974 delete driver_param;
5975 llwarns << "avatar file: driver_param->parseData() failed" << llendl;
5976 return FALSE;
5977 }
5978 } 6033 }
5979 } 6034 }
5980 6035
@@ -8147,6 +8202,14 @@ BOOL LLVOAvatar::teToColorParams( ETextureIndex te, const char* param_name[3] )
8147 param_name[2] = "skirt_blue"; 8202 param_name[2] = "skirt_blue";
8148 break; 8203 break;
8149 8204
8205 case TEX_HEAD_TATTOO:
8206 case TEX_LOWER_TATTOO:
8207 case TEX_UPPER_TATTOO:
8208 param_name[0] = "tattoo_red";
8209 param_name[1] = "tattoo_green";
8210 param_name[2] = "tattoo_blue";
8211 break;
8212
8150 default: 8213 default:
8151 llassert(0); 8214 llassert(0);
8152 return FALSE; 8215 return FALSE;
@@ -8606,7 +8669,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
8606 { 8669 {
8607 for( S32 i = 0; i < num_blocks; i++ ) 8670 for( S32 i = 0; i < num_blocks; i++ )
8608 { 8671 {
8609 while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) 8672 while( param && (!param->isTweakable()) )
8610 { 8673 {
8611 param = getNextVisualParam(); 8674 param = getNextVisualParam();
8612 } 8675 }
@@ -8614,7 +8677,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
8614 if( !param ) 8677 if( !param )
8615 { 8678 {
8616 llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl; 8679 llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl;
8617 return; 8680 break;
8618 } 8681 }
8619 8682
8620 U8 value; 8683 U8 value;
@@ -8655,14 +8718,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
8655 } 8718 }
8656 } 8719 }
8657 8720
8658 while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) 8721 S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
8722 if (num_blocks != expected_tweakable_count)
8659 { 8723 {
8660 param = getNextVisualParam(); 8724 llinfos << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. Object: " << getID() << llendl;
8661 }
8662 if( param )
8663 {
8664 llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl;
8665 return;
8666 } 8725 }
8667 8726
8668 if (params_changed) 8727 if (params_changed)
@@ -8933,8 +8992,7 @@ void LLVOAvatar::dumpArchetypeXML( void* )
8933 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) 8992 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
8934 { 8993 {
8935 LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; 8994 LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
8936 if( (viewer_param->getWearableType() == type) && 8995 if (viewer_param->getWearableType() == type && viewer_param->isTweakable())
8937 (viewer_param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) )
8938 { 8996 {
8939 apr_file_printf( file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n", 8997 apr_file_printf( file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n",
8940 viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight() ); 8998 viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight() );
diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h
index 548818d..e585a6a 100644
--- a/linden/indra/newview/llvoavatar.h
+++ b/linden/indra/newview/llvoavatar.h
@@ -97,6 +97,7 @@ public:
97 static void initClass(); // Initialize data that's only init'd once per class. 97 static void initClass(); // Initialize data that's only init'd once per class.
98 static void cleanupClass(); // Cleanup data that's only init'd once per class. 98 static void cleanupClass(); // Cleanup data that's only init'd once per class.
99 static BOOL parseSkeletonFile(const std::string& filename); 99 static BOOL parseSkeletonFile(const std::string& filename);
100 static void initCloud();
100 virtual U32 processUpdateMessage(LLMessageSystem *mesgsys, 101 virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
101 void **user_data, 102 void **user_data,
102 U32 block_num, 103 U32 block_num,
@@ -111,6 +112,10 @@ public:
111 void idleUpdateWindEffect(); 112 void idleUpdateWindEffect();
112 void idleUpdateBoobEffect(); 113 void idleUpdateBoobEffect();
113 void idleUpdateNameTag(const LLVector3& root_pos_last); 114 void idleUpdateNameTag(const LLVector3& root_pos_last);
115 void clearNameTag();
116 static void invalidateNameTag(const LLUUID& agent_id);
117 // force all name tags to rebuild, useful when display names turned on/off
118 static void invalidateNameTags();
114 void idleUpdateRenderCost(); 119 void idleUpdateRenderCost();
115 void idleUpdateTractorBeam(); 120 void idleUpdateTractorBeam();
116 void idleUpdateBelowWater(); 121 void idleUpdateBelowWater();
@@ -582,6 +587,7 @@ public:
582 static F32 sLODFactor; // user-settable LOD factor 587 static F32 sLODFactor; // user-settable LOD factor
583 static BOOL sJointDebug; // output total number of joints being touched for each avatar 588 static BOOL sJointDebug; // output total number of joints being touched for each avatar
584 static BOOL sDebugAvatarRotation; 589 static BOOL sDebugAvatarRotation;
590 static LLPartSysData sCloud;
585 591
586 static S32 sNumVisibleAvatars; // Number of instances of this class 592 static S32 sNumVisibleAvatars; // Number of instances of this class
587 593
@@ -675,6 +681,7 @@ protected:
675 681
676 LLWString mNameString; 682 LLWString mNameString;
677 std::string mTitle; 683 std::string mTitle;
684 std::string mCompleteName;
678 BOOL mNameAway; 685 BOOL mNameAway;
679 BOOL mNameBusy; 686 BOOL mNameBusy;
680 BOOL mNameMute; 687 BOOL mNameMute;
diff --git a/linden/indra/newview/llvoiceclient.cpp b/linden/indra/newview/llvoiceclient.cpp
index d67b9e3..7b1ed95 100644
--- a/linden/indra/newview/llvoiceclient.cpp
+++ b/linden/indra/newview/llvoiceclient.cpp
@@ -1795,7 +1795,7 @@ void LLVoiceClient::stateMachine()
1795 1795
1796 if(!mSocket) 1796 if(!mSocket)
1797 { 1797 {
1798 mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); 1798 mSocket = LLSocket::create(LLSocket::STREAM_TCP);
1799 } 1799 }
1800 1800
1801 mConnected = mSocket->blockingConnect(mDaemonHost); 1801 mConnected = mSocket->blockingConnect(mDaemonHost);
diff --git a/linden/indra/newview/llwatchdog.cpp b/linden/indra/newview/llwatchdog.cpp
index 330bc8a..9af050c 100644
--- a/linden/indra/newview/llwatchdog.cpp
+++ b/linden/indra/newview/llwatchdog.cpp
@@ -184,8 +184,8 @@ void LLWatchdog::init(killer_event_callback func)
184 mKillerCallback = func; 184 mKillerCallback = func;
185 if(!mSuspectsAccessMutex && !mTimer) 185 if(!mSuspectsAccessMutex && !mTimer)
186 { 186 {
187 mSuspectsAccessMutex = new LLMutex(NULL); 187 mSuspectsAccessMutex = new LLMutex;
188 mTimer = new LLWatchdogTimerThread(); 188 mTimer = new LLWatchdogTimerThread;
189 mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000); 189 mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000);
190 mLastClockCount = LLTimer::getTotalTime(); 190 mLastClockCount = LLTimer::getTotalTime();
191 191
diff --git a/linden/indra/newview/llwearable.cpp b/linden/indra/newview/llwearable.cpp
index b74ef02..f8123bb 100644
--- a/linden/indra/newview/llwearable.cpp
+++ b/linden/indra/newview/llwearable.cpp
@@ -535,7 +535,7 @@ BOOL LLWearable::isOldVersion()
535 param; 535 param;
536 param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) 536 param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
537 { 537 {
538 if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) 538 if (param->getWearableType() == mType && param->isTweakable())
539 { 539 {
540 param_count++; 540 param_count++;
541 if( !is_in_map(mVisualParamMap, param->getID() ) ) 541 if( !is_in_map(mVisualParamMap, param->getID() ) )
@@ -591,7 +591,7 @@ BOOL LLWearable::isDirty()
591 param; 591 param;
592 param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) 592 param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
593 { 593 {
594 if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) 594 if (param->getWearableType() == mType && param->isTweakable())
595 { 595 {
596 F32 weight = get_if_there(mVisualParamMap, param->getID(), param->getDefaultWeight()); 596 F32 weight = get_if_there(mVisualParamMap, param->getID(), param->getDefaultWeight());
597 weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); 597 weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() );
@@ -690,7 +690,7 @@ void LLWearable::setParamsToDefaults()
690 mVisualParamMap.clear(); 690 mVisualParamMap.clear();
691 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) 691 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
692 { 692 {
693 if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) 693 if (((LLViewerVisualParam*)param)->getWearableType() == mType && param->isTweakable())
694 { 694 {
695 mVisualParamMap[param->getID()] = param->getDefaultWeight(); 695 mVisualParamMap[param->getID()] = param->getDefaultWeight();
696 } 696 }
@@ -724,7 +724,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user )
724 // Pull params 724 // Pull params
725 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) 725 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
726 { 726 {
727 if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) 727 if (((LLViewerVisualParam*)param)->getWearableType() == mType && param->isTweakable())
728 { 728 {
729 S32 param_id = param->getID(); 729 S32 param_id = param->getID();
730 F32 weight = get_if_there(mVisualParamMap, param_id, param->getDefaultWeight()); 730 F32 weight = get_if_there(mVisualParamMap, param_id, param->getDefaultWeight());
@@ -825,7 +825,7 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user )
825 // Pull params 825 // Pull params
826 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) 826 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
827 { 827 {
828 if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) 828 if (((LLViewerVisualParam*)param)->getWearableType() == type && param->isTweakable())
829 { 829 {
830 S32 param_id = param->getID(); 830 S32 param_id = param->getID();
831 avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), set_by_user ); 831 avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), set_by_user );
@@ -873,7 +873,7 @@ void LLWearable::readFromAvatar()
873 mVisualParamMap.clear(); 873 mVisualParamMap.clear();
874 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) 874 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
875 { 875 {
876 if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) 876 if (((LLViewerVisualParam*)param)->getWearableType() == mType && param->isTweakable())
877 { 877 {
878 878
879 //pretty sure is right 879 //pretty sure is right
@@ -938,7 +938,7 @@ void LLWearable::copyDataFrom( LLWearable* src )
938 param; 938 param;
939 param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) 939 param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
940 { 940 {
941 if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) 941 if (param->getWearableType() == mType && param->isTweakable())
942 { 942 {
943 S32 id = param->getID(); 943 S32 id = param->getID();
944 F32 weight = get_if_there(src->mVisualParamMap, id, param->getDefaultWeight() ); 944 F32 weight = get_if_there(src->mVisualParamMap, id, param->getDefaultWeight() );
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml b/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml
index a0dd938..d5b61a7 100644
--- a/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml
@@ -1172,11 +1172,15 @@ scratch and wear it.
1172 <texture_picker name="Lower Tattoo" label="Lower Tattoo" tool_tip="Click to choose a picture" 1172 <texture_picker name="Lower Tattoo" label="Lower Tattoo" tool_tip="Click to choose a picture"
1173 can_apply_immediately="true" default_image_name="Default" allow_no_texture="true" 1173 can_apply_immediately="true" default_image_name="Default" allow_no_texture="true"
1174 follows="left|top" width="70" height="80" left="14" bottom="-325"/> 1174 follows="left|top" width="70" height="80" left="14" bottom="-325"/>
1175 <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-415"
1176 can_apply_immediately="true" color="1 1 1 1" follows="left|top" height="80"
1177 label="Color/Tint" left="14" mouse_opaque="true" name="Color/Tint"
1178 tool_tip="Click to open Color Picker" width="70" />
1175 <button name="Create New" label="Create New Tattoo" label_selected="Create New Tattoo" 1179 <button name="Create New" label="Create New Tattoo" label_selected="Create New Tattoo"
1176 follows="left|top" halign="center" width="170" height="24" left="8" bottom="-128" 1180 follows="left|top" halign="center" width="170" height="24" left="8" bottom="-128"
1177 mouse_opaque="true" scale_image="true"/> 1181 mouse_opaque="true" scale_image="true"/>
1178 <button name="Take Off" label="Take Off" label_selected="Take Off" 1182 <button name="Take Off" label="Take Off" label_selected="Take Off"
1179 follows="left|top" width="82" height="20" left="8" bottom="-365"/> 1183 follows="left|top" width="82" height="20" left="8" bottom="-440"/>
1180 <button name="Save" label="Save" label_selected="Save" 1184 <button name="Save" label="Save" label_selected="Save"
1181 follows="right|bottom" width="82" height="20" left="123" bottom="-478"/> 1185 follows="right|bottom" width="82" height="20" left="123" bottom="-478"/>
1182 <button name="Save As" label="Save As..." label_selected="Save As..." 1186 <button name="Save As" label="Save As..." label_selected="Save As..."
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_display_name.xml b/linden/indra/newview/skins/default/xui/en-us/floater_display_name.xml
new file mode 100644
index 0000000..5875efb
--- /dev/null
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_display_name.xml
@@ -0,0 +1,42 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater name="Display Name" title="CHANGE DISPLAY NAME"
3 can_minimize="true" can_close="true" can_resize="false"
4 enabled="true" mouse_opaque="true"
5 height="235" width="440">
6 <text name="info_text1" font="SansSerif" wrap="true"
7 height="18" width="380" left="42" bottom_delta="-48" follows="left|top">
8 The name you give to your avatar is called your Display Name.
9 </text>
10 <text name="info_text2" font="SansSerif" wrap="true"
11 height="18" width="300" left="120" bottom_delta="-18" follows="left|top">
12 You can change it once a week.
13 </text>
14 <text name="now_ok_text" font="SansSerif"
15 height="18" width="320" left="105" bottom_delta="-25" follows="left|top">
16 You can change it now if you so wish.
17 </text>
18 <text name="lockout_text" font="SansSerif" visible="false"
19 height="18" width="380" left="20" bottom_delta="0" follows="left|top">
20 You cannot change it before: [TIME].
21 </text>
22 <text name="set_name_label" font="SansSerif"
23 height="20" width="380" left="20" bottom_delta="-25" follows="left|top">
24 New Display Name:
25 </text>
26 <line_editor name="display_name_editor" max_length="31"
27 height="20" width="360" left="40" bottom_delta="-20" follows="left|top" />
28 <text name="name_confirm_label" font="SansSerif"
29 height="20" width="380" left="20" bottom_delta="-32" follows="left|top">
30 Type your new name again to confirm:
31 </text>
32 <line_editor name="display_name_confirm" max_length="31"
33 height="20" width="360" left="40" bottom_delta="-20" follows="left|top" />
34 <button name="save_btn" label="Save" font="SansSerif"
35 tool_tip="Save your new Display Name"
36 height="20" width="120" left="30" bottom_delta="-32"/>
37 <button name="reset_btn" label="Reset" font="SansSerif"
38 tool_tip="Make Display Name the same as Username"
39 height="20" width="120" left_delta="130" bottom_delta="0"/>
40 <button name="cancel_btn" label="Cancel" font="SansSerif"
41 height="20" width="120" left_delta="130" bottom_delta="0"/>
42</floater>
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_new_im.xml b/linden/indra/newview/skins/default/xui/en-us/floater_new_im.xml
index c93b890..5d766be 100644
--- a/linden/indra/newview/skins/default/xui/en-us/floater_new_im.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_new_im.xml
@@ -8,7 +8,7 @@
8 column_padding="5" draw_border="true" draw_heading="false" 8 column_padding="5" draw_border="true" draw_heading="false"
9 draw_stripes="true" enabled="true" follows="left|top|right|bottom" 9 draw_stripes="true" enabled="true" follows="left|top|right|bottom"
10 height="290" left="6" mouse_opaque="true" multi_select="false" 10 height="290" left="6" mouse_opaque="true" multi_select="false"
11 name="user_list" width="421" /> 11 name="user_list" use_display_names="true" width="421" />
12 <button bottom="-271" enabled="true" follows="right|bottom" font="SansSerif" 12 <button bottom="-271" enabled="true" follows="right|bottom" font="SansSerif"
13 halign="center" height="20" label="Start" label_selected="Start" left="435" 13 halign="center" height="20" label="Start" label_selected="Start" left="435"
14 mouse_opaque="true" name="start_btn" scale_image="true" sound_flags="0" 14 mouse_opaque="true" name="start_btn" scale_image="true" sound_flags="0"
@@ -17,9 +17,6 @@
17 halign="center" height="20" label="Close" label_selected="Close" left="435" 17 halign="center" height="20" label="Close" label_selected="Close" left="435"
18 mouse_opaque="true" name="close_btn" scale_image="true" sound_flags="0" 18 mouse_opaque="true" name="close_btn" scale_image="true" sound_flags="0"
19 width="60" /> 19 width="60" />
20 <string name="name_format">
21 [FIRST] [LAST]
22 </string>
23 <string name="online_descriptor"> 20 <string name="online_descriptor">
24 (online) 21 (online)
25 </string> 22 </string>
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml b/linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml
index 81dd05a..69e62f8 100644
--- a/linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_new_outfit_dialog.xml
@@ -21,7 +21,7 @@
21 <check_box bottom="-276" enabled="true" follows="left|top" font="SansSerifSmall" 21 <check_box bottom="-276" enabled="true" follows="left|top" font="SansSerifSmall"
22 height="16" initial_value="false" label="Eyes" left="13" 22 height="16" initial_value="false" label="Eyes" left="13"
23 mouse_opaque="true" name="checkbox_Eyes" radio_style="false" width="100" /> 23 mouse_opaque="true" name="checkbox_Eyes" radio_style="false" width="100" />
24 <check_box bottom="-456" enabled="true" follows="left|top" font="SansSerifSmall" 24 <check_box bottom="-434" enabled="true" follows="left|top" font="SansSerifSmall"
25 height="16" initial_value="false" label="Rename Clothing To Folder Name" 25 height="16" initial_value="false" label="Rename Clothing To Folder Name"
26 left="13" mouse_opaque="true" name="rename" radio_style="false" width="210" /> 26 left="13" mouse_opaque="true" name="rename" radio_style="false" width="210" />
27 <check_box bottom="-216" enabled="true" follows="left|top" font="SansSerifSmall" 27 <check_box bottom="-216" enabled="true" follows="left|top" font="SansSerifSmall"
@@ -256,7 +256,7 @@ now wearing into it.
256 Attachments: 256 Attachments:
257 </text> 257 </text>
258 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 258 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
259 bottom="-436" drop_shadow_visible="true" enabled="true" follows="left|top" 259 bottom="-414" drop_shadow_visible="true" enabled="true" follows="left|top"
260 font="SansSerifSmall" h_pad="0" halign="left" height="14" left="13" 260 font="SansSerifSmall" h_pad="0" halign="left" height="14" left="13"
261 mouse_opaque="true" name="Options:" v_pad="0" width="100"> 261 mouse_opaque="true" name="Options:" v_pad="0" width="100">
262 Options: 262 Options:
diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml
index 31e730a..c2424d7 100644
--- a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml
@@ -259,6 +259,11 @@
259 userdata="appearance" /> 259 userdata="appearance" />
260 <on_enable function="Edit.EnableCustomizeAvatar" /> 260 <on_enable function="Edit.EnableCustomizeAvatar" />
261 </menu_item_call> 261 </menu_item_call>
262 <menu_item_call bottom="-362" enabled="true" height="19" label="Display Name..." left="0"
263 mouse_opaque="true" name="Display Name..." width="153">
264 <on_click function="ShowFloater" userdata="displayname" />
265 <on_enable function="Edit.EnableDisplayName" />
266 </menu_item_call>
262 <menu_item_separator /> 267 <menu_item_separator />
263 <menu_item_check name="Friends" label="Friends" 268 <menu_item_check name="Friends" label="Friends"
264 shortcut="control|shift|F"> 269 shortcut="control|shift|F">
@@ -267,7 +272,8 @@
267 <on_check function="FloaterVisible" 272 <on_check function="FloaterVisible"
268 userdata="friends" /> 273 userdata="friends" />
269 </menu_item_check> 274 </menu_item_check>
270 <menu_item_call name="Groups" label="Groups"> 275 <menu_item_call name="Groups" label="Groups"
276 shortcut="control|shift|G">
271 <on_click function="ShowAgentGroups" 277 <on_click function="ShowAgentGroups"
272 userdata="agent" /> 278 userdata="agent" />
273 </menu_item_call> 279 </menu_item_call>
@@ -1965,6 +1971,13 @@
1965 <on_click function="Advanced.DumpAttachments" 1971 <on_click function="Advanced.DumpAttachments"
1966 userdata="" /> 1972 userdata="" />
1967 </menu_item_call> 1973 </menu_item_call>
1974 <menu_item_call
1975 label="Reload Avatar Cloud Particle"
1976 name="Reload Avatar Cloud Particle">
1977 <on_click
1978 function="Advanced.ReloadAvatarCloudParticle"
1979 userdata="" />
1980 </menu_item_call>
1968 </menu> 1981 </menu>
1969 1982
1970 <!-- CRASH --> 1983 <!-- CRASH -->
diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml
index 61067da..5ee4ed0 100644
--- a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml
@@ -142,7 +142,7 @@
142 audio 142 audio
143 </widgettype> 143 </widgettype>
144 <impl> 144 <impl>
145 media_plugin_quicktime 145 media_plugin_gstreamer010
146 </impl> 146 </impl>
147 </mimetype> 147 </mimetype>
148 <mimetype name="video/*"> 148 <mimetype name="video/*">
@@ -197,8 +197,8 @@
197 audio 197 audio
198 </widgettype> 198 </widgettype>
199 <impl> 199 <impl>
200 media_plugin_quicktime 200 media_plugin_gstreamer010
201 </impl> 201 </impl>
202 </mimetype> 202 </mimetype>
203 <mimetype name="application/pdf"> 203 <mimetype name="application/pdf">
204 <label name="application/pdf_label"> 204 <label name="application/pdf_label">
@@ -274,8 +274,8 @@
274 audio 274 audio
275 </widgettype> 275 </widgettype>
276 <impl> 276 <impl>
277 media_plugin_quicktime 277 media_plugin_gstreamer010
278 </impl> 278 </impl>
279 </mimetype> 279 </mimetype>
280 <mimetype name="audio/mpeg"> 280 <mimetype name="audio/mpeg">
281 <label name="audio/mpeg_label"> 281 <label name="audio/mpeg_label">
@@ -285,8 +285,8 @@
285 audio 285 audio
286 </widgettype> 286 </widgettype>
287 <impl> 287 <impl>
288 media_plugin_quicktime 288 media_plugin_gstreamer010
289 </impl> 289 </impl>
290 </mimetype> 290 </mimetype>
291 <mimetype name="audio/x-aiff"> 291 <mimetype name="audio/x-aiff">
292 <label name="audio/x-aiff_label"> 292 <label name="audio/x-aiff_label">
@@ -296,8 +296,8 @@
296 audio 296 audio
297 </widgettype> 297 </widgettype>
298 <impl> 298 <impl>
299 media_plugin_quicktime 299 media_plugin_gstreamer010
300 </impl> 300 </impl>
301 </mimetype> 301 </mimetype>
302 <mimetype name="audio/x-wav"> 302 <mimetype name="audio/x-wav">
303 <label name="audio/x-wav_label"> 303 <label name="audio/x-wav_label">
@@ -307,8 +307,8 @@
307 audio 307 audio
308 </widgettype> 308 </widgettype>
309 <impl> 309 <impl>
310 media_plugin_quicktime 310 media_plugin_gstreamer010
311 </impl> 311 </impl>
312 </mimetype> 312 </mimetype>
313 <mimetype menu="1" name="image/bmp"> 313 <mimetype menu="1" name="image/bmp">
314 <label name="image/bmp_label"> 314 <label name="image/bmp_label">
diff --git a/linden/indra/newview/skins/default/xui/en-us/notifications.xml b/linden/indra/newview/skins/default/xui/en-us/notifications.xml
index 6e361fa..d4d86c0 100644
--- a/linden/indra/newview/skins/default/xui/en-us/notifications.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/notifications.xml
@@ -5218,6 +5218,88 @@ The string [STRING_NAME] is missing from strings.xml
5218</notification> 5218</notification>
5219 5219
5220<notification 5220<notification
5221 icon="alertmodal.tga"
5222 name="SetDisplayNameSuccess"
5223 type="alert">
5224Hi [DISPLAY_NAME]!
5225
5226Just like in real life, it takes a while for everyone to learn about a new name. Please allow several days for your name to update in objects, scripts, search, etc.
5227 </notification>
5228
5229 <notification
5230 icon="alertmodal.tga"
5231 name="SetDisplayNameBlocked"
5232 type="alert">
5233Sorry, you cannot change your display name. If you feel this is in error, please contact support.
5234 </notification>
5235
5236 <notification
5237 icon="alertmodal.tga"
5238 name="SetDisplayNameFailedLength"
5239 type="alertmodal">
5240Sorry, that name is too long. Display names can have a maximum of [LENGTH] characters.
5241
5242Please try a shorter name.
5243 </notification>
5244
5245 <notification
5246 icon="alertmodal.tga"
5247 name="SetDisplayNameFailedGeneric"
5248 type="alertmodal">
5249 Sorry, we could not set your display name. Please try again later.
5250 </notification>
5251
5252 <notification
5253 icon="alertmodal.tga"
5254 name="SetDisplayNameMismatch"
5255 type="alertmodal">
5256 The display names you entered do not match. Please re-enter.
5257 </notification>
5258
5259 <!-- *NOTE: This should never happen -->
5260 <notification
5261 icon="alertmodal.tga"
5262 name="AgentDisplayNameUpdateThresholdExceeded"
5263 type="alertmodal">
5264Sorry, you have to wait longer before you can change your display name.
5265
5266See http://wiki.secondlife.com/wiki/Setting_your_display_name
5267
5268Please try again later.
5269 </notification>
5270
5271 <notification
5272 icon="alertmodal.tga"
5273 name="AgentDisplayNameSetBlocked"
5274 type="alertmodal">
5275 Sorry, we could not set your requested name because it contains a banned word.
5276
5277 Please try a different name.
5278 </notification>
5279
5280 <notification
5281 icon="alertmodal.tga"
5282 name="AgentDisplayNameSetInvalidUnicode"
5283 type="alertmodal">
5284 The display name you wish to set contains invalid characters.
5285 </notification>
5286
5287 <notification
5288 icon="alertmodal.tga"
5289 name="AgentDisplayNameSetOnlyPunctuation"
5290 type="alertmodal">
5291 Your display name must contain letters other than punctuation.
5292 </notification>
5293
5294
5295 <notification
5296 icon="notifytip.tga"
5297 name="DisplayNameUpdate"
5298 type="notifytip">
5299 [OLD_NAME] ([SLID]) is now known as [NEW_NAME].
5300 </notification>
5301
5302<notification
5221 icon="notifytip.tga" 5303 icon="notifytip.tga"
5222 name="Cancelled" 5304 name="Cancelled"
5223 type="notifytip"> 5305 type="notifytip">
@@ -6855,7 +6937,7 @@ GRAVITY -- -9.8
6855 6937
6856* -- Multiplication 6938* -- Multiplication
6857\ -- Division 6939\ -- Division
6858+ -- Addition 6940 -- Addition
6859- -- Subtraction 6941- -- Subtraction
6860 6942
6861For information about this feature, click "More Info". 6943For information about this feature, click "More Info".
@@ -6884,7 +6966,7 @@ GLOW -- Glow
6884 6966
6885* -- Multiplication 6967* -- Multiplication
6886\ -- Division 6968\ -- Division
6887+ -- Addition 6969 -- Addition
6888- -- Subtraction 6970- -- Subtraction
6889 6971
6890For information about this feature, click "More Info". 6972For information about this feature, click "More Info".
@@ -7202,6 +7284,24 @@ Apply this region's settings? (&quot;Ignore&quot; will ignore all region setting
7202The new font will appear after you restart [VIEWER_NAME]. 7284The new font will appear after you restart [VIEWER_NAME].
7203</notification> 7285</notification>
7204 7286
7287<notification
7288 icon="alertmodal.tga"
7289 name="FirstPrivacy"
7290 type="alertmodal">
7291Terms of service of the grid you are connecting to require sending a "statistics packet" every 5 minutes.
7292That is for example: Data about your hardware (CPU, RAM), number of avatars around, number of sims visited.
7293Please check *the grids* privacy policy about usage of that data.
7294 <form name="form">
7295 <button
7296 index="0"
7297 name="ok"
7298 text="Login anyway"/>
7299 <button
7300 index="1"
7301 name="notok"
7302 text="Do not log in"/>
7303 </form>
7304</notification>
7205 7305
7206<!--End Imprudence notifications--> 7306<!--End Imprudence notifications-->
7207 <!-- [KITTY VIEWER] --> 7307 <!-- [KITTY VIEWER] -->
diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_avatar.xml b/linden/indra/newview/skins/default/xui/en-us/panel_avatar.xml
index 0df65e7..f459e6a 100644
--- a/linden/indra/newview/skins/default/xui/en-us/panel_avatar.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/panel_avatar.xml
@@ -127,6 +127,11 @@
127 font="SansSerifSmall" height="16" is_unicode="false" left="12" 127 font="SansSerifSmall" height="16" is_unicode="false" left="12"
128 max_length="254" mouse_opaque="false" name="name" 128 max_length="254" mouse_opaque="false" name="name"
129 width="155" /> 129 width="155" />
130 <name_editor bevel_style="in" border_style="line" visible="false"
131 border_thickness="1" bottom="-24" enabled="false" follows="left|top"
132 font="SansSerifSmall" height="16" is_unicode="false" left_delta="0"
133 max_length="254" mouse_opaque="false" name="complete_name"
134 width="155" />
130 <button bottom_delta="0" font="SansSerif" halign="center" height="20" 135 <button bottom_delta="0" font="SansSerif" halign="center" height="20"
131 label="Copy Key" label_selected="Copy Key" 136 label="Copy Key" label_selected="Copy Key"
132 left_delta="157" mouse_opaque="true" name="btn_copy_uuid" width="80" /> 137 left_delta="157" mouse_opaque="true" name="btn_copy_uuid" width="80" />
diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml
index 4b0b292..6ced7d6 100644
--- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml
@@ -2,6 +2,15 @@
2<panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom" 2<panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom"
3 height="408" label="General" left="102" mouse_opaque="true" 3 height="408" label="General" left="102" mouse_opaque="true"
4 name="general_panel" width="517"> 4 name="general_panel" width="517">
5 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
6 bottom="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
7 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
8 mouse_opaque="true" name="start_location_textbox" v_pad="0" width="394">
9 Start Location:
10 </text>
11 <string name="region_name_prompt">
12 &lt;Type region name&gt;
13 </string>
5 <combo_box name="default_location_combo" 14 <combo_box name="default_location_combo"
6 bottom="-22" left="155" height="16" width="150" 15 bottom="-22" left="155" height="16" width="150"
7 follows="left|top" font="SansSerifSmall" 16 follows="left|top" font="SansSerifSmall"
@@ -24,7 +33,13 @@
24 font="SansSerifSmall" height="16" initial_value="true" 33 font="SansSerifSmall" height="16" initial_value="true"
25 label="Show start location at login screen" left="151" mouse_opaque="true" 34 label="Show start location at login screen" left="151" mouse_opaque="true"
26 name="show_location_checkbox" radio_style="false" width="256" /> 35 name="show_location_checkbox" radio_style="false" width="256" />
27 <combo_box bottom_delta="-25" follows="left|top" height="18" left="155" 36 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
37 bottom_delta="-24" drop_shadow_visible="true" enabled="true" follows="left|top"
38 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
39 mouse_opaque="true" name="show_names_textbox" v_pad="0" width="394">
40 Nametags:
41 </text>
42 <combo_box bottom_delta="0" follows="left|top" height="18" left="155"
28 mouse_opaque="true" name="fade_out_combobox" width="146"> 43 mouse_opaque="true" name="fade_out_combobox" width="146">
29 <combo_item name="Never" value="Never"> 44 <combo_item name="Never" value="Never">
30 Never show 45 Never show
@@ -44,11 +59,35 @@
44 font="SansSerifSmall" height="16" initial_value="false" 59 font="SansSerifSmall" height="16" initial_value="false"
45 label="Hide my name on my screen" left="151" name="show_my_name_checkbox" 60 label="Hide my name on my screen" left="151" name="show_my_name_checkbox"
46 width="200" /> 61 width="200" />
62
47 <check_box bottom_delta="-20" follows="left|top" 63 <check_box bottom_delta="-20" follows="left|top"
48 font="SansSerifSmall" height="16" initial_value="false" 64 font="SansSerifSmall" height="16" initial_value="false"
49 label="Highlight friends tags" left="151" name="highlight_friends_checkbox" 65 label="Highlight friends tags" left="151" name="highlight_friends_checkbox"
50 width="200" /> 66 width="200" />
51 <text type="string" length="1" bottom_delta="-24" follows="left|top" font="SansSerifSmall" h_pad="0" 67 <text type="string" length="1" bottom_delta="-24" follows="left|top" font="SansSerifSmall" h_pad="0"
68 halign="left" height="16" left="10" name="Display_Names_textbox" v_pad="0"
69 width="394">
70 Display Names:
71 </text>
72 <radio_group name="displaynames" draw_border="false"
73 bottom_delta="0" left_delta="60" height="18"
74 follows="top|left"
75 control_name="DisplayNamesUsage">
76 <radio_item name="0" bottom_delta="-8" left_delta="40" height="18">
77 Legacy Names
78 </radio_item>
79 <radio_item name="1" bottom_delta="0" left_delta="50" height="18">
80 Display Names
81 </radio_item>
82 <radio_item name="2" bottom_delta="0" left_delta="50" height="18">
83 Show Both
84 </radio_item>
85 </radio_group>
86 <check_box bottom_delta="-20" follows="left|top" control_name="LegacyNamesForFriends"
87 font="SansSerifSmall" height="16" initial_value="false"
88 label="Show legacy names for friends" left="151" name="legacy_friends_checkbox"
89 width="200" />
90 <text type="string" length="1" bottom_delta="-24" follows="left|top" font="SansSerifSmall" h_pad="0"
52 halign="left" height="16" left="10" name="group_titles_textbox" v_pad="0" 91 halign="left" height="16" left="10" name="group_titles_textbox" v_pad="0"
53 width="394"> 92 width="394">
54 Group Titles: 93 Group Titles:
@@ -61,37 +100,49 @@
61 font="SansSerifSmall" height="16" initial_value="false" 100 font="SansSerifSmall" height="16" initial_value="false"
62 label="Hide my group title" left="330" name="show_my_title_checkbox" 101 label="Hide my group title" left="330" name="show_my_title_checkbox"
63 radio_style="false" width="256" /> 102 radio_style="false" width="256" />
64 <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-210" 103 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
104 bottom_delta="-24" drop_shadow_visible="true" enabled="true" follows="left|top"
105 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
106 mouse_opaque="true" name="effects_color_textbox" v_pad="0" width="394">
107 Selection Beam Color:
108 </text>
109 <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom_delta="-44"
65 can_apply_immediately="false" color="1 1 1 1" 110 can_apply_immediately="false" color="1 1 1 1"
66 enabled="true" follows="left|top" height="65" label="" left="153" 111 enabled="true" follows="left|top" height="55" label="" left="153"
67 mouse_opaque="true" name="effect_color_swatch" 112 mouse_opaque="true" name="effect_color_swatch"
68 tool_tip="Click to open Color Picker" width="55" /> 113 tool_tip="Click to open Color Picker" width="45" />
69 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 114 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
70 bottom="-215" drop_shadow_visible="true" enabled="true" follows="left|top" 115 bottom_delta="-18" drop_shadow_visible="true" enabled="true" follows="left|top"
71 font="SansSerifSmall" h_pad="0" halign="left" height="12" left="10" 116 font="SansSerifSmall" h_pad="0" halign="left" height="12" left="10"
72 mouse_opaque="true" name="UI Size:" v_pad="0" width="128"> 117 mouse_opaque="true" name="UI Size:" v_pad="0" width="128">
73 UI Size: 118 UI Size:
74 </text> 119 </text>
75 <slider bottom="-217" can_edit_text="true" 120 <slider bottom_delta="42" can_edit_text="true"
76 decimal_digits="3" enabled="true" height="16" increment="0.001" 121 decimal_digits="3" enabled="true" height="16" increment="0.001"
77 initial_val="1" left="148" max_val="1.4" min_val="0.75" mouse_opaque="true" 122 initial_val="1" left="148" max_val="1.4" min_val="0.75" mouse_opaque="true"
78 name="ui_scale_slider" show_text="true" value="1" width="220" /> 123 name="ui_scale_slider" show_text="true" value="1" width="220" />
79 <button bottom="-221" enabled="true" follows="left|top" 124 <button bottom_delta="-48" enabled="true" follows="left|top"
80 font="SansSerif" halign="center" height="22" label="Reset" 125 font="SansSerif" halign="center" height="22" label="Reset"
81 label_selected="Reset" left_delta="226" mouse_opaque="true" 126 label_selected="Reset" left_delta="226" mouse_opaque="true"
82 name="reset_ui_size" scale_image="true" width="80" /> 127 name="reset_ui_size" scale_image="true" width="80" />
83 <check_box bottom="-236" enabled="true" follows="left|top" 128 <check_box bottom_delta="-14" enabled="true" follows="left|top"
84 font="SansSerifSmall" height="16" initial_value="false" 129 font="SansSerifSmall" height="16" initial_value="false"
85 label="Use resolution independent scale" left="151" mouse_opaque="true" 130 label="Use resolution independent scale" left="151" mouse_opaque="true"
86 name="ui_auto_scale" radio_style="false" width="256" /> 131 name="ui_auto_scale" radio_style="false" width="256" />
87 <check_box bottom="-260" enabled="true" follows="left|top" 132 <spinner bottom_delta="-24" decimal_digits="0" enabled="true"
88 font="SansSerifSmall" height="16" initial_value="false"
89 label="Go Away/AFK when idle" left="330" mouse_opaque="true"
90 name="afk_timeout_checkbox" radio_style="false" width="256" />
91 <spinner bottom="-260" decimal_digits="0" enabled="true"
92 follows="left|top" height="16" increment="1" initial_val="300" 133 follows="left|top" height="16" increment="1" initial_val="300"
93 label="Away Timeout:" label_width="141" left="10" max_val="600" 134 label="Away Timeout:" label_width="141" left="10" max_val="600"
94 min_val="30" mouse_opaque="true" name="afk_timeout_spinner" width="202" /> 135 min_val="30" mouse_opaque="true" name="afk_timeout_spinner" width="202" />
136 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
137 bottom_delta="6" drop_shadow_visible="true" enabled="true" follows="left|top"
138 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="220"
139 mouse_opaque="true" name="seconds_textbox" v_pad="0" width="128">
140 seconds
141 </text>
142 <check_box bottom_delta="-5" enabled="true" follows="left|top"
143 font="SansSerifSmall" height="16" initial_value="false"
144 label="Go Away/AFK when idle" left="330" mouse_opaque="true"
145 name="afk_timeout_checkbox" radio_style="false" width="256" />
95 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 146 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
96 bottom_delta="-27" drop_shadow_visible="true" enabled="true" follows="left|top" 147 bottom_delta="-27" drop_shadow_visible="true" enabled="true" follows="left|top"
97 font="SansSerifSmall" h_pad="0" halign="left" height="12" left="10" 148 font="SansSerifSmall" h_pad="0" halign="left" height="12" left="10"
@@ -109,18 +160,18 @@
109 mouse_opaque="true" name="mini_map_notify_sim" radio_style="false" 160 mouse_opaque="true" name="mini_map_notify_sim" radio_style="false"
110 width="256" /> 161 width="256" />
111 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 162 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
112 bottom="-312" drop_shadow_visible="true" enabled="true" follows="left|top" 163 bottom_delta="-24" drop_shadow_visible="true" enabled="true" follows="left|top"
113 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10" 164 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
114 mouse_opaque="true" name="maturity_desired_label" v_pad="0" width="394"> 165 mouse_opaque="true" name="maturity_desired_label" v_pad="0" width="394">
115 Rating: 166 Rating:
116 </text> 167 </text>
117 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 168 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
118 bottom="-312" drop_shadow_visible="true" enabled="true" follows="left|top" 169 bottom_delta="0" drop_shadow_visible="true" enabled="true" follows="left|top"
119 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="151" 170 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="151"
120 mouse_opaque="true" name="maturity_desired_prompt" v_pad="0" width="394"> 171 mouse_opaque="true" name="maturity_desired_prompt" v_pad="0" width="394">
121 I want to access content rated: 172 I want to access content rated:
122 </text> 173 </text>
123 <combo_box bottom="-318" follows="left|top" height="18" left="315" 174 <combo_box bottom_delta="-6" follows="left|top" height="18" left="315"
124 mouse_opaque="true" name="maturity_desired_combobox" width="150"> 175 mouse_opaque="true" name="maturity_desired_combobox" width="150">
125 <combo_item name="Desired_Adult" value="42"> 176 <combo_item name="Desired_Adult" value="42">
126 PG, Mature and Adult 177 PG, Mature and Adult
@@ -133,58 +184,20 @@
133 </combo_item> 184 </combo_item>
134 </combo_box> 185 </combo_box>
135 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 186 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
136 bottom="-312" drop_shadow_visible="true" enabled="true" follows="left|top" 187 bottom_delta="0" drop_shadow_visible="true" enabled="true" follows="left|top"
137 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="315" 188 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="315"
138 mouse_opaque="true" name="maturity_desired_textbox" v_pad="0" width="150"> 189 mouse_opaque="true" name="maturity_desired_textbox" v_pad="0" width="150">
139 PG only 190 PG only
140 </text> 191 </text>
192
193
141 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 194 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
142 bottom="-20" drop_shadow_visible="true" enabled="true" follows="left|top" 195 bottom_delta="-24" drop_shadow_visible="true" enabled="true" follows="left|top"
143 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
144 mouse_opaque="true" name="start_location_textbox" v_pad="0" width="394">
145 Start Location:
146 </text>
147 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
148 bottom="-64" drop_shadow_visible="true" enabled="true" follows="left|top"
149 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
150 mouse_opaque="true" name="show_names_textbox" v_pad="0" width="394">
151 Nametags:
152 </text>
153 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
154 bottom="-155" drop_shadow_visible="true" enabled="true" follows="left|top"
155 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
156 mouse_opaque="true" name="effects_color_textbox" v_pad="0" width="394">
157 Selection Beam Color:
158 </text>
159 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
160 bottom="-254" drop_shadow_visible="true" enabled="true" follows="left|top"
161 font="SansSerifSmall" h_pad="0" halign="left" height="10" left="220"
162 mouse_opaque="true" name="seconds_textbox" v_pad="0" width="128">
163 seconds
164 </text>
165 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
166 bottom="-352" drop_shadow_visible="true" enabled="true" follows="left|top"
167 font="SansSerifSmall" h_pad="0" halign="left" height="18" left="10" 196 font="SansSerifSmall" h_pad="0" halign="left" height="18" left="10"
168 mouse_opaque="true" name="time_textbox" v_pad="0" width="394"> 197 mouse_opaque="true" name="time_textbox" v_pad="0" width="394">
169 Clock: 198 Clock:
170 </text> 199 </text>
171 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" 200 <combo_box allow_text_entry="false" bottom_delta="0" enabled="true" follows="left|top"
172 bottom="-384" drop_shadow_visible="true" enabled="true" follows="left|top"
173 font="SansSerifSmall" h_pad="0" halign="left" height="18" left="10"
174 mouse_opaque="true" name="language_textbox" v_pad="0" width="394">
175 Language:
176 </text>
177 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
178 bottom_delta="-1" drop_shadow_visible="true" enabled="true"
179 follows="left|top" font="SansSerifSmall" h_pad="0" halign="left"
180 height="18" left_delta="293" mouse_opaque="true" name="language_textbox2"
181 v_pad="0" width="400">
182 (requires restart for full effect)
183 </text>
184 <string name="region_name_prompt">
185 &lt;Type region name&gt;
186 </string>
187 <combo_box allow_text_entry="false" bottom="-352" enabled="true" follows="left|top"
188 height="18" left="153" max_chars="20" mouse_opaque="true" 201 height="18" left="153" max_chars="20" mouse_opaque="true"
189 name="time_combobox" width="146"> 202 name="time_combobox" width="146">
190 <combo_item type="string" name="12HourTime" value="PST 12"> 203 <combo_item type="string" name="12HourTime" value="PST 12">
@@ -197,7 +210,13 @@
197 UTC 210 UTC
198 </combo_item> 211 </combo_item>
199 </combo_box> 212 </combo_box>
200 <combo_box allow_text_entry="true" bottom="-382" enabled="true" 213 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
214 bottom_delta="-24" drop_shadow_visible="true" enabled="true" follows="left|top"
215 font="SansSerifSmall" h_pad="0" halign="left" height="18" left="10"
216 mouse_opaque="true" name="language_textbox" v_pad="0" width="394">
217 Language:
218 </text>
219 <combo_box allow_text_entry="true" bottom_delta="0" enabled="true"
201 follows="left|top" height="16" left="153" max_chars="135" 220 follows="left|top" height="16" left="153" max_chars="135"
202 mouse_opaque="true" name="language_combobox" width="146"> 221 mouse_opaque="true" name="language_combobox" width="146">
203 <combo_item type="string" length="1" enabled="true" name="System Default Language" value="default"> 222 <combo_item type="string" length="1" enabled="true" name="System Default Language" value="default">
@@ -255,5 +274,11 @@
255 한국어 (Korean) - Beta 274 한국어 (Korean) - Beta
256 </combo_item> 275 </combo_item>
257 </combo_box> 276 </combo_box>
258 277 <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
278 bottom_delta="0" drop_shadow_visible="true" enabled="true"
279 follows="left|top" font="SansSerifSmall" h_pad="0" halign="left"
280 height="18" left_delta="150" mouse_opaque="true" name="language_textbox2"
281 v_pad="0" width="400">
282 (requires restart for full effect)
283 </text>
259</panel> 284</panel>
diff --git a/linden/indra/test/lltemplatemessagebuilder_tut.cpp b/linden/indra/test/lltemplatemessagebuilder_tut.cpp
index 5b33d02..9fecc2f 100644
--- a/linden/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/linden/indra/test/lltemplatemessagebuilder_tut.cpp
@@ -35,7 +35,6 @@
35#include "linden_common.h" 35#include "linden_common.h"
36#include "lltut.h" 36#include "lltut.h"
37 37
38#include "llapr.h"
39#include "llmessagetemplate.h" 38#include "llmessagetemplate.h"
40#include "llquaternion.h" 39#include "llquaternion.h"
41#include "lltemplatemessagebuilder.h" 40#include "lltemplatemessagebuilder.h"
@@ -59,7 +58,6 @@ namespace tut
59 static bool init = false; 58 static bool init = false;
60 if(! init) 59 if(! init)
61 { 60 {
62 ll_init_apr();
63 const F32 circuit_heartbeat_interval=5; 61 const F32 circuit_heartbeat_interval=5;
64 const F32 circuit_timeout=100; 62 const F32 circuit_timeout=100;
65 63
diff --git a/linden/indra/test/message_tut.cpp b/linden/indra/test/message_tut.cpp
index 3fede26..694db52 100644
--- a/linden/indra/test/message_tut.cpp
+++ b/linden/indra/test/message_tut.cpp
@@ -35,7 +35,6 @@
35#include "linden_common.h" 35#include "linden_common.h"
36#include "lltut.h" 36#include "lltut.h"
37 37
38#include "llapr.h"
39#include "llmessageconfig.h" 38#include "llmessageconfig.h"
40#include "llsdserialize.h" 39#include "llsdserialize.h"
41#include "llversionserver.h" 40#include "llversionserver.h"
@@ -68,7 +67,6 @@ namespace tut
68 static bool init = false; 67 static bool init = false;
69 if(!init) 68 if(!init)
70 { 69 {
71 ll_init_apr();
72 //init_prehash_data(); 70 //init_prehash_data();
73 init = true; 71 init = true;
74 } 72 }
diff --git a/linden/indra/test/test.cpp b/linden/indra/test/test.cpp
index ba81c6e..b699f74 100644
--- a/linden/indra/test/test.cpp
+++ b/linden/indra/test/test.cpp
@@ -43,8 +43,8 @@
43#include "linden_common.h" 43#include "linden_common.h"
44#include "llerrorcontrol.h" 44#include "llerrorcontrol.h"
45#include "lltut.h" 45#include "lltut.h"
46#include "aiaprpool.h"
46 47
47#include "apr_pools.h"
48#include "apr_getopt.h" 48#include "apr_getopt.h"
49 49
50// the CTYPE_WORKAROUND is needed for linux dev stations that don't 50// the CTYPE_WORKAROUND is needed for linux dev stations that don't
@@ -248,17 +248,12 @@ int main(int argc, char **argv)
248 ctype_workaround(); 248 ctype_workaround();
249#endif 249#endif
250 250
251 apr_initialize(); 251 LLAPRPool pool;
252 apr_pool_t* pool = NULL; 252 pool.create();
253 if(APR_SUCCESS != apr_pool_create(&pool, NULL))
254 {
255 std::cerr << "Unable to initialize pool" << std::endl;
256 return 1;
257 }
258 apr_getopt_t* os = NULL; 253 apr_getopt_t* os = NULL;
259 if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv)) 254 if(APR_SUCCESS != apr_getopt_init(&os, pool(), argc, argv))
260 { 255 {
261 std::cerr << "Unable to pool" << std::endl; 256 std::cerr << "Unable to initialize the arguments for parsing by apr_getopt()." << std::endl;
262 return 1; 257 return 1;
263 } 258 }
264 259
@@ -360,6 +355,5 @@ int main(int argc, char **argv)
360 s.close(); 355 s.close();
361 } 356 }
362 357
363 apr_terminate();
364 return 0; 358 return 0;
365} 359}
diff --git a/linden/indra/test_apps/llplugintest/demo_plugin.cpp b/linden/indra/test_apps/llplugintest/demo_plugin.cpp
index 772fa16..fd67a58 100644
--- a/linden/indra/test_apps/llplugintest/demo_plugin.cpp
+++ b/linden/indra/test_apps/llplugintest/demo_plugin.cpp
@@ -33,6 +33,8 @@
33#include "linden_common.h" 33#include "linden_common.h"
34 34
35#ifdef WIN32 35#ifdef WIN32
36# define WIN32_LEAN_AND_MEAN
37# include <winsock2.h>
36#include <windows.h> 38#include <windows.h>
37#endif 39#endif
38 40
diff --git a/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp b/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp
index bc3703d..bf0a47b 100644
--- a/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -190,9 +190,6 @@ LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int wind
190 std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl; 190 std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl;
191 }; 191 };
192 192
193 // initialize linden lab APR module
194 ll_init_apr();
195
196 // Set up llerror logging 193 // Set up llerror logging
197 { 194 {
198 LLError::initForApplication("."); 195 LLError::initForApplication(".");
diff --git a/linden/indra/win_crash_logger/StdAfx.h b/linden/indra/win_crash_logger/StdAfx.h
index 021a995..79198c2 100644
--- a/linden/indra/win_crash_logger/StdAfx.h
+++ b/linden/indra/win_crash_logger/StdAfx.h
@@ -46,6 +46,8 @@
46 46
47 47
48// Windows Header Files: 48// Windows Header Files:
49# define WIN32_LEAN_AND_MEAN
50# include <winsock2.h>
49#include <windows.h> 51#include <windows.h>
50 52
51// C RunTime Header Files 53// C RunTime Header Files
diff --git a/linden/indra/win_crash_logger/llcrashloggerwindows.h b/linden/indra/win_crash_logger/llcrashloggerwindows.h
index e6a9c77..f2a877e 100644
--- a/linden/indra/win_crash_logger/llcrashloggerwindows.h
+++ b/linden/indra/win_crash_logger/llcrashloggerwindows.h
@@ -34,6 +34,8 @@
34#define LLCRASHLOGGERWINDOWS_H 34#define LLCRASHLOGGERWINDOWS_H
35 35
36#include "llcrashlogger.h" 36#include "llcrashlogger.h"
37# define WIN32_LEAN_AND_MEAN
38# include <winsock2.h>
37#include "windows.h" 39#include "windows.h"
38#include "llstring.h" 40#include "llstring.h"
39 41
diff --git a/linden/indra/win_updater/updater.cpp b/linden/indra/win_updater/updater.cpp
index 5031270..c6fa3c8 100644
--- a/linden/indra/win_updater/updater.cpp
+++ b/linden/indra/win_updater/updater.cpp
@@ -39,6 +39,8 @@
39// *TODO: Switch to fopen_s, strtok_s, etc. 39// *TODO: Switch to fopen_s, strtok_s, etc.
40#define _CRT_SECURE_NO_DEPRECATE 40#define _CRT_SECURE_NO_DEPRECATE
41 41
42# define WIN32_LEAN_AND_MEAN
43# include <winsock2.h>
42#include <windows.h> 44#include <windows.h>
43#include <wininet.h> 45#include <wininet.h>
44#include <stdio.h> 46#include <stdio.h>
diff --git a/linden/install.xml b/linden/install.xml
index e8c8b54..846c489 100755
--- a/linden/install.xml
+++ b/linden/install.xml
@@ -228,9 +228,9 @@
228 <key>windows</key> 228 <key>windows</key>
229 <map> 229 <map>
230 <key>md5sum</key> 230 <key>md5sum</key>
231 <string>094acc8173faca882ed9532e868d767f</string> 231 <string>ed53511382d0fd9fec59a9f6544d9672</string>
232 <key>url</key> 232 <key>url</key>
233 <uri>http://imprudenceviewer.org/download/libs/boost-1.36.0-windows-20091124.tar.bz2</uri> 233 <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.39.0-windows-20091029.tar.bz2</uri>
234 </map> 234 </map>
235 </map> 235 </map>
236 </map> 236 </map>
@@ -1343,6 +1343,13 @@ Copyright (C) 2004-2005 Vladimir Berezniker @ http://public.xdi.org/=vmpn
1343 <key>url</key> 1343 <key>url</key>
1344 <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/linux-pulse-headers-0.9.14.tar.bz2</uri> 1344 <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/linux-pulse-headers-0.9.14.tar.bz2</uri>
1345 </map> 1345 </map>
1346 <key>linux64</key>
1347 <map>
1348 <key>md5sum</key>
1349 <string>30cb00069fe2a545fbf7be1070386236</string>
1350 <key>url</key>
1351 <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/linux-pulse-headers-0.9.14.tar.bz2</uri>
1352 </map>
1346 </map> 1353 </map>
1347 </map> 1354 </map>
1348 <key>quicktime</key> 1355 <key>quicktime</key>