diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llwebbrowserctrl.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llwebbrowserctrl.cpp')
-rw-r--r-- | linden/indra/newview/llwebbrowserctrl.cpp | 641 |
1 files changed, 641 insertions, 0 deletions
diff --git a/linden/indra/newview/llwebbrowserctrl.cpp b/linden/indra/newview/llwebbrowserctrl.cpp new file mode 100644 index 0000000..afbff65 --- /dev/null +++ b/linden/indra/newview/llwebbrowserctrl.cpp | |||
@@ -0,0 +1,641 @@ | |||
1 | /** | ||
2 | * @file llwebbrowserctrl.cpp | ||
3 | * @brief Web browser UI control | ||
4 | * | ||
5 | * Copyright (c) 2006-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #if LL_LIBXUL_ENABLED | ||
31 | |||
32 | #include "llwebbrowserctrl.h" | ||
33 | #include "llviewborder.h" | ||
34 | #include "llviewerwindow.h" | ||
35 | #include "llfloaterworldmap.h" | ||
36 | #include "llfocusmgr.h" | ||
37 | #include "llweb.h" | ||
38 | #include "viewer.h" | ||
39 | #include "llpanellogin.h" | ||
40 | |||
41 | // Setting the mozilla buffer width to 2048 exactly doesn't work, since it pads its rowbytes a bit, pushing the texture width over 2048. | ||
42 | // 2000 should give enough headroom for any amount of padding it cares to add. | ||
43 | const S32 MAX_DIMENSION = 2000; | ||
44 | const S32 MAX_TEXTURE_DIMENSION = 2048; | ||
45 | |||
46 | LLWebBrowserCtrl::LLWebBrowserCtrl( const std::string& name, const LLRect& rect ) : | ||
47 | LLUICtrl( name, rect, FALSE, NULL, NULL ), | ||
48 | mEmbeddedBrowserWindowId( 0 ), | ||
49 | mTextureDepthBytes( 4 ), | ||
50 | mBorder( 0 ), | ||
51 | mFrequentUpdates( true ), | ||
52 | mOpenLinksInExternalBrowser( false ), | ||
53 | mHomePageUrl( "" ) | ||
54 | { | ||
55 | // create a new browser window | ||
56 | mEmbeddedBrowserWindowId = LLMozLib::getInstance()->createBrowserWindow( gViewerWindow->getPlatformWindow(), mRect.getWidth(), mRect.getHeight() ); | ||
57 | |||
58 | // change color to black so transisitons aren't so noticable (this should be in XML eventually) | ||
59 | LLMozLib::getInstance()->setBackgroundColor( mEmbeddedBrowserWindowId, 0x00, 0x00, 0x00 ); | ||
60 | |||
61 | // observe the browser so we can trap HREF events) | ||
62 | LLMozLib::getInstance()->addObserver( mEmbeddedBrowserWindowId, this ); | ||
63 | |||
64 | // create a new texture (based on LLDynamic texture) that will be used to display the output | ||
65 | mWebBrowserImage = new LLWebBrowserTexture( mRect.getWidth(), mRect.getHeight(), this, mEmbeddedBrowserWindowId ); | ||
66 | |||
67 | LLRect border_rect( 0, mRect.getHeight() + 2, mRect.getWidth() + 2, 0 ); | ||
68 | mBorder = new LLViewBorder( "web control border", border_rect, LLViewBorder::BEVEL_IN ); | ||
69 | addChild( mBorder ); | ||
70 | } | ||
71 | |||
72 | //////////////////////////////////////////////////////////////////////////////// | ||
73 | // note: this is now a singleton and destruction happens via initClass() now | ||
74 | LLWebBrowserCtrl::~LLWebBrowserCtrl() | ||
75 | { | ||
76 | LLMozLib::getInstance()->remObserver( mEmbeddedBrowserWindowId, this ); | ||
77 | |||
78 | LLMozLib::getInstance()->destroyBrowserWindow( mEmbeddedBrowserWindowId ); | ||
79 | |||
80 | if ( mWebBrowserImage ) | ||
81 | { | ||
82 | delete mWebBrowserImage; | ||
83 | mWebBrowserImage = 0; | ||
84 | }; | ||
85 | } | ||
86 | |||
87 | //////////////////////////////////////////////////////////////////////////////// | ||
88 | // | ||
89 | bool LLWebBrowserCtrl::addObserver( LLWebBrowserCtrlObserver* subjectIn ) | ||
90 | { | ||
91 | return mEventEmitter.addObserver( subjectIn ); | ||
92 | } | ||
93 | |||
94 | //////////////////////////////////////////////////////////////////////////////// | ||
95 | // | ||
96 | bool LLWebBrowserCtrl::remObserver( LLWebBrowserCtrlObserver* subjectIn ) | ||
97 | { | ||
98 | return mEventEmitter.remObserver( subjectIn ); | ||
99 | } | ||
100 | |||
101 | //////////////////////////////////////////////////////////////////////////////// | ||
102 | // | ||
103 | void LLWebBrowserCtrl::setBorderVisible( BOOL border_visible ) | ||
104 | { | ||
105 | if ( mBorder ) | ||
106 | { | ||
107 | mBorder->setVisible( border_visible ); | ||
108 | }; | ||
109 | }; | ||
110 | |||
111 | //////////////////////////////////////////////////////////////////////////////// | ||
112 | // allows access to the raw web browser window by consumers of this class | ||
113 | void LLWebBrowserCtrl::setOpenInExternalBrowser( bool valIn ) | ||
114 | { | ||
115 | mOpenLinksInExternalBrowser = valIn; | ||
116 | }; | ||
117 | |||
118 | //////////////////////////////////////////////////////////////////////////////// | ||
119 | // | ||
120 | BOOL LLWebBrowserCtrl::handleHover( S32 x, S32 y, MASK mask ) | ||
121 | { | ||
122 | LLMozLib::getInstance()->mouseMove( mEmbeddedBrowserWindowId, x, mRect.getHeight() - y ); | ||
123 | |||
124 | return TRUE; | ||
125 | } | ||
126 | |||
127 | //////////////////////////////////////////////////////////////////////////////// | ||
128 | // | ||
129 | BOOL LLWebBrowserCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) | ||
130 | { | ||
131 | LLMozLib::getInstance()->scrollByLines( mEmbeddedBrowserWindowId, clicks ); | ||
132 | |||
133 | // note: this isn't really necessary right now since the page is updated | ||
134 | // on a timer but if that becomes too burdensome and the page is only updated | ||
135 | // once after load then this will be nexessary | ||
136 | LLMozLib::getInstance()->grabBrowserWindow( mEmbeddedBrowserWindowId ); | ||
137 | |||
138 | return TRUE; | ||
139 | } | ||
140 | |||
141 | //////////////////////////////////////////////////////////////////////////////// | ||
142 | // | ||
143 | BOOL LLWebBrowserCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) | ||
144 | { | ||
145 | LLMozLib::getInstance()->mouseUp( mEmbeddedBrowserWindowId, x, mRect.getHeight() - y ); | ||
146 | |||
147 | gViewerWindow->setMouseCapture( 0, 0 ); | ||
148 | |||
149 | return TRUE; | ||
150 | } | ||
151 | |||
152 | //////////////////////////////////////////////////////////////////////////////// | ||
153 | // | ||
154 | BOOL LLWebBrowserCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) | ||
155 | { | ||
156 | LLMozLib::getInstance()->mouseDown( mEmbeddedBrowserWindowId, x, mRect.getHeight() - y ); | ||
157 | |||
158 | gViewerWindow->setMouseCapture( this, 0 ); | ||
159 | |||
160 | setFocus( TRUE ); | ||
161 | |||
162 | return TRUE; | ||
163 | } | ||
164 | |||
165 | //////////////////////////////////////////////////////////////////////////////// | ||
166 | // | ||
167 | void LLWebBrowserCtrl::onFocusReceived() | ||
168 | { | ||
169 | LLMozLib::getInstance()->focusBrowser( mEmbeddedBrowserWindowId, true ); | ||
170 | |||
171 | LLUICtrl::onFocusReceived(); | ||
172 | } | ||
173 | |||
174 | //////////////////////////////////////////////////////////////////////////////// | ||
175 | // | ||
176 | void LLWebBrowserCtrl::onFocusLost() | ||
177 | { | ||
178 | LLMozLib::getInstance()->focusBrowser( mEmbeddedBrowserWindowId, false ); | ||
179 | |||
180 | gViewerWindow->focusClient(); | ||
181 | } | ||
182 | |||
183 | //////////////////////////////////////////////////////////////////////////////// | ||
184 | // | ||
185 | BOOL LLWebBrowserCtrl::handleKey( KEY key, MASK mask, BOOL called_from_parent ) | ||
186 | { | ||
187 | LLMozLib::getInstance()->keyPress( mEmbeddedBrowserWindowId, key ); | ||
188 | |||
189 | return FALSE; | ||
190 | } | ||
191 | |||
192 | //////////////////////////////////////////////////////////////////////////////// | ||
193 | // | ||
194 | void LLWebBrowserCtrl::onVisibilityChange ( BOOL curVisibilityIn ) | ||
195 | { | ||
196 | // set state of frequent updates automatically if visibility changes | ||
197 | if ( curVisibilityIn ) | ||
198 | { | ||
199 | mFrequentUpdates = true; | ||
200 | } | ||
201 | else | ||
202 | { | ||
203 | mFrequentUpdates = false; | ||
204 | }; | ||
205 | } | ||
206 | |||
207 | //////////////////////////////////////////////////////////////////////////////// | ||
208 | // | ||
209 | void LLWebBrowserCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) | ||
210 | { | ||
211 | // when floater is minimized, these sizes are negative | ||
212 | if ( height > 0 && width > 0 ) | ||
213 | mWebBrowserImage->resize( width, height ); | ||
214 | |||
215 | LLUICtrl::reshape( width, height, called_from_parent ); | ||
216 | } | ||
217 | |||
218 | //////////////////////////////////////////////////////////////////////////////// | ||
219 | // | ||
220 | void LLWebBrowserCtrl::navigateBack() | ||
221 | { | ||
222 | LLMozLib::getInstance()->navigateBack( mEmbeddedBrowserWindowId ); | ||
223 | } | ||
224 | |||
225 | //////////////////////////////////////////////////////////////////////////////// | ||
226 | // | ||
227 | void LLWebBrowserCtrl::navigateForward() | ||
228 | { | ||
229 | LLMozLib::getInstance()->navigateForward( mEmbeddedBrowserWindowId ); | ||
230 | } | ||
231 | |||
232 | //////////////////////////////////////////////////////////////////////////////// | ||
233 | // | ||
234 | bool LLWebBrowserCtrl::canNavigateBack() | ||
235 | { | ||
236 | return LLMozLib::getInstance()->canNavigateBack( mEmbeddedBrowserWindowId ); | ||
237 | } | ||
238 | |||
239 | //////////////////////////////////////////////////////////////////////////////// | ||
240 | // | ||
241 | bool LLWebBrowserCtrl::canNavigateForward() | ||
242 | { | ||
243 | return LLMozLib::getInstance()->canNavigateForward( mEmbeddedBrowserWindowId ); | ||
244 | } | ||
245 | |||
246 | //////////////////////////////////////////////////////////////////////////////// | ||
247 | // | ||
248 | void LLWebBrowserCtrl::navigateTo( std::string urlIn ) | ||
249 | { | ||
250 | const std::string protocol( "secondlife://" ); | ||
251 | |||
252 | // don't browse to anything that starts with secondlife:// | ||
253 | if ( urlIn.length() >= protocol.length() ) | ||
254 | if ( LLString::compareInsensitive( urlIn.substr( 0, protocol.length() ).c_str(), protocol.c_str() ) != 0 ) | ||
255 | LLMozLib::getInstance()->navigateTo( mEmbeddedBrowserWindowId, urlIn ); | ||
256 | } | ||
257 | |||
258 | //////////////////////////////////////////////////////////////////////////////// | ||
259 | // | ||
260 | void LLWebBrowserCtrl::navigateHome() | ||
261 | { | ||
262 | if( mHomePageUrl.length() ) | ||
263 | { | ||
264 | LLMozLib::getInstance()->navigateTo( mEmbeddedBrowserWindowId, mHomePageUrl ); | ||
265 | }; | ||
266 | } | ||
267 | |||
268 | //////////////////////////////////////////////////////////////////////////////// | ||
269 | // | ||
270 | void LLWebBrowserCtrl::setHomePageUrl( const std::string urlIn ) | ||
271 | { | ||
272 | mHomePageUrl = urlIn; | ||
273 | } | ||
274 | |||
275 | //////////////////////////////////////////////////////////////////////////////// | ||
276 | // | ||
277 | std::string LLWebBrowserCtrl::getHomePageUrl() | ||
278 | { | ||
279 | return mHomePageUrl; | ||
280 | } | ||
281 | |||
282 | //////////////////////////////////////////////////////////////////////////////// | ||
283 | // | ||
284 | void LLWebBrowserCtrl::draw() | ||
285 | { | ||
286 | if ( ! getVisible() ) | ||
287 | return; | ||
288 | |||
289 | // NOTE: optimization needed here - probably only need to do this once | ||
290 | // unless tearoffs change the parent which they problably do. | ||
291 | LLUICtrl* ptr = (LLUICtrl*)findRootMostFocusRoot(); | ||
292 | if ( ptr && ptr->hasFocus() ) | ||
293 | { | ||
294 | setFrequentUpdates( true ); | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | setFrequentUpdates( false ); | ||
299 | }; | ||
300 | |||
301 | // alpha off for this | ||
302 | LLGLSUIDefault gls_ui; | ||
303 | LLGLDisable gls_alphaTest( GL_ALPHA_TEST ); | ||
304 | |||
305 | // scale texture to fit the space using texture coords | ||
306 | mWebBrowserImage->bindTexture(); | ||
307 | glColor4fv( LLColor4::white.mV ); | ||
308 | F32 max_u = ( F32 )mWebBrowserImage->getBrowserWidth() / ( F32 )mWebBrowserImage->getWidth(); | ||
309 | F32 max_v = ( F32 )mWebBrowserImage->getBrowserHeight() / ( F32 )mWebBrowserImage->getHeight(); | ||
310 | |||
311 | // draw the browser | ||
312 | glBlendFunc( GL_ONE, GL_ZERO ); | ||
313 | glBegin( GL_QUADS ); | ||
314 | { | ||
315 | glTexCoord2f( max_u, 0.f ); | ||
316 | glVertex2i( mRect.getWidth(), mRect.getHeight() ); | ||
317 | |||
318 | glTexCoord2f( 0.f, 0.f ); | ||
319 | glVertex2i( 0, mRect.getHeight() ); | ||
320 | |||
321 | glTexCoord2f( 0.f, max_v ); | ||
322 | glVertex2i( 0, 0 ); | ||
323 | |||
324 | glTexCoord2f( max_u, max_v ); | ||
325 | glVertex2i( mRect.getWidth(), 0 ); | ||
326 | } | ||
327 | glEnd(); | ||
328 | glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); | ||
329 | |||
330 | // highlight if keyboard focus here. (TODO: this needs some work) | ||
331 | if ( mBorder->getVisible() ) | ||
332 | mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) ); | ||
333 | |||
334 | LLUICtrl::draw(); | ||
335 | } | ||
336 | |||
337 | //////////////////////////////////////////////////////////////////////////////// | ||
338 | // virtual | ||
339 | void LLWebBrowserCtrl::onNavigateBegin( const EventType& eventIn ) | ||
340 | { | ||
341 | LLWebBrowserCtrlEvent event; | ||
342 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateBegin, event ); | ||
343 | } | ||
344 | |||
345 | //////////////////////////////////////////////////////////////////////////////// | ||
346 | // virtual | ||
347 | void LLWebBrowserCtrl::onNavigateComplete( const EventType& eventIn ) | ||
348 | { | ||
349 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
350 | LLWebBrowserCtrlEvent event; | ||
351 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateComplete, event ); | ||
352 | } | ||
353 | |||
354 | //////////////////////////////////////////////////////////////////////////////// | ||
355 | // virtual | ||
356 | void LLWebBrowserCtrl::onUpdateProgress( const EventType& eventIn ) | ||
357 | { | ||
358 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
359 | LLWebBrowserCtrlEvent event( eventIn.getIntValue() ); | ||
360 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onUpdateProgress, event ); | ||
361 | } | ||
362 | |||
363 | //////////////////////////////////////////////////////////////////////////////// | ||
364 | // virtual | ||
365 | void LLWebBrowserCtrl::onStatusTextChange( const EventType& eventIn ) | ||
366 | { | ||
367 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
368 | LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); | ||
369 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onStatusTextChange, event ); | ||
370 | } | ||
371 | |||
372 | //////////////////////////////////////////////////////////////////////////////// | ||
373 | // virtual | ||
374 | void LLWebBrowserCtrl::onLocationChange( const EventType& eventIn ) | ||
375 | { | ||
376 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
377 | LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); | ||
378 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onLocationChange, event ); | ||
379 | } | ||
380 | |||
381 | //////////////////////////////////////////////////////////////////////////////// | ||
382 | // virtual | ||
383 | void LLWebBrowserCtrl::onClickLinkHref( const EventType& eventIn ) | ||
384 | { | ||
385 | const std::string protocol( "http://" ); | ||
386 | |||
387 | if( mOpenLinksInExternalBrowser ) | ||
388 | if ( eventIn.getStringValue().length() ) | ||
389 | if ( LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol.length() ).c_str(), protocol.c_str() ) == 0 ) | ||
390 | LLWeb::loadURL( eventIn.getStringValue() ); | ||
391 | |||
392 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
393 | LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); | ||
394 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkHref, event ); | ||
395 | } | ||
396 | |||
397 | //////////////////////////////////////////////////////////////////////////////// | ||
398 | // virtual | ||
399 | void LLWebBrowserCtrl::onClickLinkSecondLife( const EventType& eventIn ) | ||
400 | { | ||
401 | const std::string protocol( "secondlife://" ); | ||
402 | |||
403 | if ( eventIn.getStringValue().length() ) | ||
404 | { | ||
405 | if ( LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol.length() ).c_str(), protocol.c_str() ) == 0 ) | ||
406 | { | ||
407 | // parse out sim name and coordinates | ||
408 | LLURLSimString::setString( eventIn.getStringValue() ); | ||
409 | LLURLSimString::parse(); | ||
410 | |||
411 | // if there is a world map | ||
412 | if ( gFloaterWorldMap ) | ||
413 | { | ||
414 | #if ! LL_RELEASE_FOR_DOWNLOAD | ||
415 | llinfos << "MOZ> opening map to " << LLURLSimString::sInstance.mSimName.c_str() << " at " << LLURLSimString::sInstance.mX << "," << LLURLSimString::sInstance.mY << "," << LLURLSimString::sInstance.mZ << llendl; | ||
416 | #endif | ||
417 | |||
418 | // mark where the destination is | ||
419 | gFloaterWorldMap->trackURL( LLURLSimString::sInstance.mSimName.c_str(), | ||
420 | LLURLSimString::sInstance.mX, | ||
421 | LLURLSimString::sInstance.mY, | ||
422 | LLURLSimString::sInstance.mZ ); | ||
423 | |||
424 | // display map | ||
425 | LLFloaterWorldMap::show( NULL, TRUE ); | ||
426 | } | ||
427 | else | ||
428 | // if there is no world map, assume we're on the login page.. (this might be bad but I don't see a way to tell if you're at login or not) | ||
429 | { | ||
430 | // refresh the login page and force the location combo box to be visible | ||
431 | LLPanelLogin::refreshLocation( true ); | ||
432 | }; | ||
433 | }; | ||
434 | }; | ||
435 | |||
436 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
437 | LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); | ||
438 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkSecondLife, event ); | ||
439 | } | ||
440 | |||
441 | //////////////////////////////////////////////////////////////////////////////// | ||
442 | // | ||
443 | LLWebBrowserTexture::LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, int browserWindowId ) : | ||
444 | LLDynamicTexture( 512, 512, 4, ORDER_FIRST, TRUE ), | ||
445 | mLastBrowserDepth( 0 ), | ||
446 | mWebBrowserCtrl( browserCtrl ), | ||
447 | mEmbeddedBrowserWindowId( browserWindowId ) | ||
448 | { | ||
449 | mElapsedTime.start(); | ||
450 | |||
451 | resize( width, height ); | ||
452 | } | ||
453 | |||
454 | //////////////////////////////////////////////////////////////////////////////// | ||
455 | // | ||
456 | LLWebBrowserTexture::~LLWebBrowserTexture() | ||
457 | { | ||
458 | mElapsedTime.stop(); | ||
459 | } | ||
460 | |||
461 | //////////////////////////////////////////////////////////////////////////////// | ||
462 | // | ||
463 | BOOL LLWebBrowserTexture::render() | ||
464 | { | ||
465 | // frequent updates turned on? | ||
466 | if ( mWebBrowserCtrl->getFrequentUpdates() ) | ||
467 | { | ||
468 | // only update mozilla/texture occasionally | ||
469 | if ( mElapsedTime.getElapsedTimeF32() > ( 1.0f / 15.0f ) ) | ||
470 | { | ||
471 | mElapsedTime.reset(); | ||
472 | |||
473 | const unsigned char* pixels = LLMozLib::getInstance()->grabBrowserWindow( mEmbeddedBrowserWindowId ); | ||
474 | |||
475 | S32 actual_rowspan = LLMozLib::getInstance()->getBrowserRowSpan( mEmbeddedBrowserWindowId ); | ||
476 | S32 browser_depth = LLMozLib::getInstance()->getBrowserDepth( mEmbeddedBrowserWindowId ); | ||
477 | |||
478 | // these are both invalid conditions and should never happen but SL-27583 indicates it does | ||
479 | if ( actual_rowspan < 1 || browser_depth < 2 ) | ||
480 | return FALSE; | ||
481 | |||
482 | S32 pagebuffer_width = actual_rowspan / browser_depth; | ||
483 | |||
484 | if(mLastBrowserDepth == browser_depth) | ||
485 | { | ||
486 | // Browser depth hasn't changed. Just grab the pixels. | ||
487 | |||
488 | mTexture->setSubImage( pixels, | ||
489 | pagebuffer_width, mBrowserHeight, | ||
490 | 0, 0, pagebuffer_width, mBrowserHeight ); | ||
491 | } | ||
492 | else | ||
493 | { | ||
494 | // Browser depth has changed -- need to recreate texture to match. | ||
495 | resize(mBrowserWidth, mBrowserHeight); | ||
496 | } | ||
497 | }; | ||
498 | }; | ||
499 | |||
500 | return TRUE; | ||
501 | } | ||
502 | |||
503 | //////////////////////////////////////////////////////////////////////////////// | ||
504 | // | ||
505 | S32 LLWebBrowserTexture::getBrowserWidth() | ||
506 | { | ||
507 | return mBrowserWidth; | ||
508 | } | ||
509 | |||
510 | //////////////////////////////////////////////////////////////////////////////// | ||
511 | // | ||
512 | S32 LLWebBrowserTexture::getBrowserHeight() | ||
513 | { | ||
514 | return mBrowserHeight; | ||
515 | } | ||
516 | |||
517 | |||
518 | //////////////////////////////////////////////////////////////////////////////// | ||
519 | // | ||
520 | void LLWebBrowserTexture::resize( S32 new_width, S32 new_height ) | ||
521 | { | ||
522 | F32 scale_ratio = 1.f; | ||
523 | if (new_width > MAX_DIMENSION) | ||
524 | { | ||
525 | scale_ratio = (F32)MAX_DIMENSION / (F32)new_width; | ||
526 | } | ||
527 | if (new_height > MAX_DIMENSION) | ||
528 | { | ||
529 | scale_ratio = llmin(scale_ratio, (F32)MAX_DIMENSION / (F32)new_height); | ||
530 | } | ||
531 | |||
532 | mBrowserWidth = llround(scale_ratio * (F32)new_width); | ||
533 | mBrowserHeight = llround(scale_ratio * (F32)new_height); | ||
534 | |||
535 | LLMozLib::getInstance()->setSize( mEmbeddedBrowserWindowId, mBrowserWidth, mBrowserHeight ); | ||
536 | |||
537 | const unsigned char* pixels = LLMozLib::getInstance()->grabBrowserWindow( mEmbeddedBrowserWindowId ); | ||
538 | |||
539 | S32 actual_rowspan = LLMozLib::getInstance()->getBrowserRowSpan( mEmbeddedBrowserWindowId ); | ||
540 | S32 browser_depth = LLMozLib::getInstance()->getBrowserDepth( mEmbeddedBrowserWindowId ); | ||
541 | |||
542 | // these are both invalid conditions and should never happen but SL-27583 indicates it does | ||
543 | if ( actual_rowspan < 1 || browser_depth < 2 ) | ||
544 | return; | ||
545 | |||
546 | S32 pagebuffer_width = actual_rowspan / browser_depth; | ||
547 | |||
548 | // calculate the next power of 2 bigger than reqquested size for width and height | ||
549 | for ( mWidth = 1; mWidth < pagebuffer_width; mWidth <<= 1 ) | ||
550 | { | ||
551 | if ( mWidth >= MAX_TEXTURE_DIMENSION ) | ||
552 | { | ||
553 | break; | ||
554 | }; | ||
555 | }; | ||
556 | |||
557 | for ( mHeight = 1; mHeight < mBrowserHeight; mHeight <<= 1 ) | ||
558 | { | ||
559 | if ( mHeight >= MAX_TEXTURE_DIMENSION ) | ||
560 | { | ||
561 | break; | ||
562 | }; | ||
563 | }; | ||
564 | |||
565 | LLGLint internal_format; | ||
566 | LLGLenum primary_format; | ||
567 | LLGLenum type_format; | ||
568 | BOOL swap_bytes = FALSE; | ||
569 | |||
570 | switch(browser_depth) | ||
571 | { | ||
572 | default: | ||
573 | case 4: | ||
574 | internal_format = GL_RGBA8; | ||
575 | primary_format = GL_BGRA_EXT; | ||
576 | #if LL_DARWIN | ||
577 | #if LL_BIG_ENDIAN | ||
578 | type_format = GL_UNSIGNED_INT_8_8_8_8_REV; | ||
579 | #else | ||
580 | type_format = GL_UNSIGNED_INT_8_8_8_8; | ||
581 | #endif | ||
582 | #else // windows or linux | ||
583 | type_format = GL_UNSIGNED_BYTE; | ||
584 | #endif | ||
585 | break; | ||
586 | |||
587 | case 2: | ||
588 | #if LL_DARWIN | ||
589 | internal_format = GL_RGBA8; | ||
590 | primary_format = GL_BGRA_EXT; | ||
591 | type_format = GL_UNSIGNED_SHORT_1_5_5_5_REV; | ||
592 | #if LL_LITTLE_ENDIAN | ||
593 | swap_bytes = TRUE; | ||
594 | #endif | ||
595 | #else // windows or linux | ||
596 | // MBW -- XXX -- This is just a guess on my part. Someone needs to verify which GL texture format matches the 16-bit format used on windows. | ||
597 | internal_format = GL_RGB8; | ||
598 | primary_format = GL_RGB; | ||
599 | type_format = GL_UNSIGNED_SHORT_5_6_5; | ||
600 | #endif | ||
601 | break; | ||
602 | } | ||
603 | |||
604 | // will create mWidth * mHeight sized texture, using BGR ordering | ||
605 | LLDynamicTexture::generateGLTexture(internal_format, primary_format, type_format, swap_bytes); | ||
606 | |||
607 | mTexture->setSubImage( pixels, | ||
608 | pagebuffer_width, mBrowserHeight, | ||
609 | 0, 0, pagebuffer_width, mBrowserHeight ); | ||
610 | |||
611 | mLastBrowserDepth = browser_depth; | ||
612 | } | ||
613 | |||
614 | LLView* LLWebBrowserCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | ||
615 | { | ||
616 | LLString name("web_browser"); | ||
617 | node->getAttributeString("name", name); | ||
618 | |||
619 | LLString start_url("start_url"); | ||
620 | node->getAttributeString("start_url", start_url ); | ||
621 | |||
622 | BOOL border_visible = true; | ||
623 | node->getAttributeBOOL("border_visible", border_visible); | ||
624 | |||
625 | LLRect rect; | ||
626 | createRect(node, rect, parent, LLRect()); | ||
627 | |||
628 | LLWebBrowserCtrl* web_browser = new LLWebBrowserCtrl( name, rect ); | ||
629 | |||
630 | web_browser->initFromXML(node, parent); | ||
631 | |||
632 | web_browser->setHomePageUrl( start_url ); | ||
633 | |||
634 | web_browser->setBorderVisible( border_visible ); | ||
635 | |||
636 | web_browser->navigateHome(); | ||
637 | |||
638 | return web_browser; | ||
639 | } | ||
640 | |||
641 | #endif // LL_LIBXUL_ENABLED | ||