00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034
00035 #include "llwebbrowserctrl.h"
00036
00037
00038 #include "llfloaterhtml.h"
00039 #include "llfloaterworldmap.h"
00040 #include "lluictrlfactory.h"
00041 #include "llurldispatcher.h"
00042 #include "llurlsimstring.h"
00043 #include "llviewborder.h"
00044 #include "llviewercontrol.h"
00045 #include "llviewerwindow.h"
00046 #include "llweb.h"
00047 #include "llglimmediate.h"
00048
00049
00050 #include "llfocusmgr.h"
00051
00052
00053
00054 const S32 MAX_DIMENSION = 2000;
00055 const S32 MAX_TEXTURE_DIMENSION = 2048;
00056
00057 static LLRegisterWidget<LLWebBrowserCtrl> r("web_browser");
00058
00059 LLWebBrowserCtrl::LLWebBrowserCtrl( const std::string& name, const LLRect& rect ) :
00060 LLUICtrl( name, rect, FALSE, NULL, NULL ),
00061 mTextureDepthBytes( 4 ),
00062 mWebBrowserImage( 0 ),
00063 mEmbeddedBrowserWindowId( 0 ),
00064 mBorder(NULL),
00065 mFrequentUpdates( true ),
00066 mForceUpdate( false ),
00067 mOpenLinksInExternalBrowser( false ),
00068 mOpenLinksInInternalBrowser( false ),
00069 mOpenAppSLURLs( false ),
00070 mHomePageUrl( "" ),
00071 mIgnoreUIScale( true ),
00072 mAlwaysRefresh( false ),
00073 mExternalUrl( "" ),
00074 mMediaSource( 0 ),
00075 mTakeFocusOnClick( true )
00076 {
00077 S32 screen_width = mIgnoreUIScale ?
00078 llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth();
00079 S32 screen_height = mIgnoreUIScale ?
00080 llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight();
00081
00082
00083 LLMediaManager *mgr = LLMediaManager::getInstance();
00084
00085 if (!mgr)
00086 {
00087 llwarns << "cannot get media manager" << llendl;
00088 return;
00089 }
00090
00091 mMediaSource = mgr->createSourceFromMimeType("http", "text/html" );
00092 if ( !mMediaSource )
00093 {
00094 llwarns << "media source create failed " << llendl;
00095
00096 }
00097 else
00098 {
00099
00100
00101 mMediaSource->addCommand( LLMediaBase::COMMAND_START );
00102
00103
00104 mMediaSource->addObserver(this);
00105
00106
00107 mWebBrowserImage = new LLWebBrowserTexture( screen_width, screen_height, this, mMediaSource );
00108 }
00109
00110 LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 );
00111 mBorder = new LLViewBorder( "web control border", border_rect, LLViewBorder::BEVEL_IN );
00112 addChild( mBorder );
00113 }
00114
00116
00117 LLWebBrowserCtrl::~LLWebBrowserCtrl()
00118 {
00119 LLMediaManager *mgr = LLMediaManager::getInstance();
00120
00121 if (!mgr)
00122 {
00123 llwarns << "cannot get media manager" << llendl;
00124 return;
00125 }
00126
00127 if (mMediaSource)
00128 {
00129 mgr->destroySource(mMediaSource);
00130 mMediaSource = NULL;
00131 }
00132
00133 if ( mWebBrowserImage )
00134 {
00135 delete mWebBrowserImage;
00136 mWebBrowserImage = 0;
00137 };
00138 }
00139
00141
00142 bool LLWebBrowserCtrl::addObserver( LLWebBrowserCtrlObserver* subjectIn )
00143 {
00144 return mEventEmitter.addObserver( subjectIn );
00145 }
00146
00148
00149 bool LLWebBrowserCtrl::remObserver( LLWebBrowserCtrlObserver* subjectIn )
00150 {
00151 return mEventEmitter.remObserver( subjectIn );
00152 }
00153
00155
00156 void LLWebBrowserCtrl::setBorderVisible( BOOL border_visible )
00157 {
00158 if ( mBorder )
00159 {
00160 mBorder->setVisible( border_visible );
00161 };
00162 };
00163
00165
00166 void LLWebBrowserCtrl::setTakeFocusOnClick( bool take_focus )
00167 {
00168 mTakeFocusOnClick = take_focus;
00169 }
00170
00172
00173 void LLWebBrowserCtrl::setOpenInExternalBrowser( bool valIn )
00174 {
00175 mOpenLinksInExternalBrowser = valIn;
00176 };
00177
00179
00180 void LLWebBrowserCtrl::setOpenInInternalBrowser( bool valIn )
00181 {
00182 mOpenLinksInInternalBrowser = valIn;
00183 };
00184
00186 void LLWebBrowserCtrl::setOpenAppSLURLs( bool valIn )
00187 {
00188 mOpenAppSLURLs = valIn;
00189 };
00190
00192
00193 BOOL LLWebBrowserCtrl::handleHover( S32 x, S32 y, MASK mask )
00194 {
00195 convertInputCoords(x, y);
00196
00197 if (mMediaSource)
00198 mMediaSource->mouseMove(x, y);
00199
00200 return TRUE;
00201 }
00202
00204
00205 BOOL LLWebBrowserCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
00206 {
00207 if (mMediaSource)
00208 mMediaSource->scrollByLines(clicks);
00209
00210 return TRUE;
00211 }
00212
00214
00215 BOOL LLWebBrowserCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
00216 {
00217 convertInputCoords(x, y);
00218
00219 if (mMediaSource)
00220 {
00221 mMediaSource->mouseUp(x, y);
00222
00223
00224
00225 if (!mTakeFocusOnClick)
00226 {
00227 mMediaSource->focus(false);
00228 gViewerWindow->focusClient();
00229 }
00230 }
00231
00232 gViewerWindow->setMouseCapture( NULL );
00233
00234 return TRUE;
00235 }
00236
00238
00239 BOOL LLWebBrowserCtrl::handleMouseDown( S32 x, S32 y, MASK mask )
00240 {
00241 convertInputCoords(x, y);
00242
00243 if (mMediaSource)
00244 mMediaSource->mouseDown(x, y);
00245
00246 gViewerWindow->setMouseCapture( this );
00247
00248 if (mTakeFocusOnClick)
00249 {
00250 setFocus( TRUE );
00251 }
00252
00253 return TRUE;
00254 }
00255
00257
00258 BOOL LLWebBrowserCtrl::handleDoubleClick( S32 x, S32 y, MASK mask )
00259 {
00260 convertInputCoords(x, y);
00261
00262 if (mMediaSource)
00263 mMediaSource->mouseLeftDoubleClick( x, y );
00264
00265 gViewerWindow->setMouseCapture( this );
00266
00267 if (mTakeFocusOnClick)
00268 {
00269 setFocus( TRUE );
00270 }
00271
00272 return TRUE;
00273 }
00274
00276
00277 void LLWebBrowserCtrl::onFocusReceived()
00278 {
00279 if (mMediaSource)
00280 mMediaSource->focus(true);
00281
00282
00283 LLUICtrl::onFocusReceived();
00284 }
00285
00287
00288 void LLWebBrowserCtrl::onFocusLost()
00289 {
00290 if (mMediaSource)
00291 mMediaSource->focus(false);
00292
00293 gViewerWindow->focusClient();
00294
00295 LLUICtrl::onFocusLost();
00296 }
00297
00299
00300 BOOL LLWebBrowserCtrl::handleKeyHere( KEY key, MASK mask )
00301 {
00302 unsigned long media_key;
00303
00304
00305
00306
00307
00308
00309
00310
00311 switch (key)
00312 {
00313 case KEY_BACKSPACE:
00314 media_key = LL_MEDIA_KEY_BACKSPACE; break;
00315 case KEY_TAB:
00316 media_key = LL_MEDIA_KEY_TAB; break;
00317 case KEY_RETURN:
00318 media_key = LL_MEDIA_KEY_RETURN; break;
00319 case KEY_PAD_RETURN:
00320 media_key = LL_MEDIA_KEY_PAD_RETURN; break;
00321 case KEY_ESCAPE:
00322 media_key = LL_MEDIA_KEY_ESCAPE; break;
00323 case KEY_PAGE_UP:
00324 media_key = LL_MEDIA_KEY_PAGE_UP; break;
00325 case KEY_PAGE_DOWN:
00326 media_key = LL_MEDIA_KEY_PAGE_DOWN; break;
00327 case KEY_END:
00328 media_key = LL_MEDIA_KEY_END; break;
00329 case KEY_HOME:
00330 media_key = LL_MEDIA_KEY_HOME; break;
00331 case KEY_LEFT:
00332 media_key = LL_MEDIA_KEY_LEFT; break;
00333 case KEY_UP:
00334 media_key = LL_MEDIA_KEY_UP; break;
00335 case KEY_RIGHT:
00336 media_key = LL_MEDIA_KEY_RIGHT; break;
00337 case KEY_DOWN:
00338 media_key = LL_MEDIA_KEY_DOWN; break;
00339 case KEY_INSERT:
00340 media_key = LL_MEDIA_KEY_INSERT; break;
00341 case KEY_DELETE:
00342 media_key = LL_MEDIA_KEY_DELETE; break;
00343 default:
00344 llinfos << "Don't know how to map LL keycode " << U32(key)
00345 << " to DOM key. Ignoring." << llendl;
00346 return FALSE;
00347 }
00348
00349 if (mMediaSource)
00350 mMediaSource->keyPress(media_key);
00351
00352 return TRUE;
00353 }
00354
00355 BOOL LLWebBrowserCtrl::handleUnicodeCharHere(llwchar uni_char)
00356 {
00357
00358 if (uni_char >= 32
00359 && uni_char != 127)
00360 {
00361 if (mMediaSource)
00362 mMediaSource->unicodeInput(uni_char);
00363 }
00364
00365 return TRUE;
00366 }
00367
00369
00370 void LLWebBrowserCtrl::onVisibilityChange ( BOOL new_visibility )
00371 {
00372
00373 if ( new_visibility )
00374 {
00375 mFrequentUpdates = true;
00376 }
00377 else
00378 {
00379 mFrequentUpdates = false;
00380 }
00381 LLUICtrl::onVisibilityChange(new_visibility);
00382 }
00383
00385
00386 void LLWebBrowserCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
00387 {
00388 S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width;
00389 S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height;
00390
00391
00392 if ( mWebBrowserImage && screen_height > 0 && screen_width > 0 )
00393 {
00394 mWebBrowserImage->resize( screen_width, screen_height );
00395 mForceUpdate = true;
00396 }
00397
00398 LLUICtrl::reshape( width, height, called_from_parent );
00399 }
00400
00402
00403 void LLWebBrowserCtrl::navigateBack()
00404 {
00405 if (mMediaSource)
00406 mMediaSource->navigateBack();
00407 }
00408
00410
00411 void LLWebBrowserCtrl::navigateForward()
00412 {
00413 if (mMediaSource)
00414 mMediaSource->navigateForward();
00415 }
00416
00418
00419 bool LLWebBrowserCtrl::canNavigateBack()
00420 {
00421 if (mMediaSource)
00422 return mMediaSource->canNavigateBack();
00423 else
00424 return false;
00425 }
00426
00428
00429 bool LLWebBrowserCtrl::canNavigateForward()
00430 {
00431 if (mMediaSource)
00432 return mMediaSource->canNavigateForward();
00433 else
00434 return false;
00435 }
00436
00438
00439 bool LLWebBrowserCtrl::set404RedirectUrl( std::string redirect_url )
00440 {
00441 if(mMediaSource)
00442 return mMediaSource->set404RedirectUrl( redirect_url );
00443 else
00444 return false;
00445 }
00446
00448
00449 bool LLWebBrowserCtrl::clr404RedirectUrl()
00450 {
00451 if(mMediaSource)
00452 return mMediaSource->clr404RedirectUrl();
00453 else
00454 return false;
00455 }
00456
00458
00459 void LLWebBrowserCtrl::navigateTo( std::string urlIn )
00460 {
00461
00462 const std::string protocol1 = "secondlife://";
00463 const std::string protocol2 = "sl://";
00464 if ((LLString::compareInsensitive(urlIn.substr(0, protocol1.length()).c_str(), protocol1.c_str()) == 0) ||
00465 (LLString::compareInsensitive(urlIn.substr(0, protocol2.length()).c_str(), protocol2.c_str()) == 0))
00466 {
00467
00468
00469 return;
00470 }
00471
00472 if (mMediaSource)
00473 mMediaSource->navigateTo(urlIn);
00474 }
00475
00476
00477 void LLWebBrowserCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )
00478 {
00479 std::string language = gSavedSettings.getString("Language");
00480
00481 if(language == "default")
00482 {
00483 language = gSavedSettings.getString("SystemLanguage");
00484 }
00485
00486 std::string delim = gDirUtilp->getDirDelimiter();
00487 std::string filename;
00488
00489 filename += subdir;
00490 filename += delim;
00491 filename += filename_in;
00492
00493 std::string expanded_filename = gDirUtilp->getExpandedFilename(LL_PATH_HTML, language, filename);
00494
00495 if (gDirUtilp->fileExists(expanded_filename))
00496 {
00497 navigateTo(expanded_filename);
00498 return;
00499 }
00500 if (language != "en-us")
00501 {
00502 expanded_filename = gDirUtilp->getExpandedFilename(LL_PATH_HTML, "en-us", filename);
00503 if (gDirUtilp->fileExists(expanded_filename))
00504 {
00505 navigateTo(expanded_filename);
00506 return;
00507 }
00508 }
00509
00510 llwarns << "File " << subdir << delim << filename_in << "not found" << llendl;
00511 }
00512
00513
00515
00516 void LLWebBrowserCtrl::navigateHome()
00517 {
00518 if( mHomePageUrl.length() )
00519 {
00520 if (mMediaSource)
00521 mMediaSource->navigateTo(mHomePageUrl);
00522 };
00523 }
00524
00526
00527 void LLWebBrowserCtrl::setHomePageUrl( const std::string urlIn )
00528 {
00529 mHomePageUrl = urlIn;
00530 }
00531
00533
00534 bool LLWebBrowserCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue)
00535 {
00536 if (mMediaSource)
00537 return mMediaSource->setCaretColor(red, green, blue);
00538 else
00539 return false;
00540 }
00542
00543 std::string LLWebBrowserCtrl::getHomePageUrl()
00544 {
00545 return mHomePageUrl;
00546 }
00547
00549
00550 void LLWebBrowserCtrl::draw()
00551 {
00552 if ( ! mWebBrowserImage )
00553 return;
00554
00555
00556
00557 const LLUICtrl* ptr = findRootMostFocusRoot();
00558 if ( ptr && ptr->hasFocus() )
00559 {
00560 setFrequentUpdates( true );
00561 }
00562 else
00563 {
00564 setFrequentUpdates( false );
00565 };
00566
00567
00568 LLGLSUIDefault gls_ui;
00569 LLGLDisable gls_alphaTest( GL_ALPHA_TEST );
00570
00571 gGL.pushMatrix();
00572 {
00573 if (mIgnoreUIScale)
00574 {
00575 glLoadIdentity();
00576
00577
00578 gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::sGLScaleFactor.mV[VX]),
00579 floorf(LLFontGL::sCurOrigin.mY * LLUI::sGLScaleFactor.mV[VY]),
00580 LLFontGL::sCurOrigin.mZ);
00581 }
00582
00583
00584 mWebBrowserImage->bindTexture();
00585 gGL.color4fv( LLColor4::white.mV );
00586 F32 max_u = ( F32 )mWebBrowserImage->getBrowserWidth() / ( F32 )mWebBrowserImage->getWidth();
00587 F32 max_v = ( F32 )mWebBrowserImage->getBrowserHeight() / ( F32 )mWebBrowserImage->getHeight();
00588
00589
00590 gGL.blendFunc( GL_ONE, GL_ZERO );
00591 gGL.begin( LLVertexBuffer::QUADS );
00592 {
00593
00594 gGL.texCoord2f( max_u, max_v );
00595 gGL.vertex2i( mWebBrowserImage->getBrowserWidth(), mWebBrowserImage->getBrowserHeight() );
00596
00597 gGL.texCoord2f( 0.f, max_v );
00598 gGL.vertex2i( 0, mWebBrowserImage->getBrowserHeight() );
00599
00600 gGL.texCoord2f( 0.f, 0.f );
00601 gGL.vertex2i( 0, 0 );
00602
00603 gGL.texCoord2f( max_u, 0.f );
00604 gGL.vertex2i( mWebBrowserImage->getBrowserWidth(), 0 );
00605 }
00606 gGL.end();
00607 gGL.blendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00608 }
00609 gGL.popMatrix();
00610
00611
00612 if ( mBorder->getVisible() )
00613 mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) );
00614
00615
00616 LLUICtrl::draw();
00617 }
00618
00619 void LLWebBrowserCtrl::convertInputCoords(S32& x, S32& y)
00620 {
00621 x = mIgnoreUIScale ? llround((F32)x * LLUI::sGLScaleFactor.mV[VX]) : x;
00622 y = mIgnoreUIScale ? llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight() - y;
00623 }
00624
00626
00627 void LLWebBrowserCtrl::onNavigateBegin( const EventType& eventIn )
00628 {
00629 LLWebBrowserCtrlEvent event( eventIn.getStringValue() );
00630 mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateBegin, event );
00631 }
00632
00634
00635 void LLWebBrowserCtrl::onNavigateComplete( const EventType& eventIn )
00636 {
00637
00638 LLWebBrowserCtrlEvent event( eventIn.getStringValue() );
00639 mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateComplete, event );
00640 }
00641
00643
00644 void LLWebBrowserCtrl::onUpdateProgress( const EventType& eventIn )
00645 {
00646
00647 LLWebBrowserCtrlEvent event( eventIn.getIntValue() );
00648 mEventEmitter.update( &LLWebBrowserCtrlObserver::onUpdateProgress, event );
00649 }
00650
00652
00653 void LLWebBrowserCtrl::onStatusTextChange( const EventType& eventIn )
00654 {
00655
00656 LLWebBrowserCtrlEvent event( eventIn.getStringValue() );
00657 mEventEmitter.update( &LLWebBrowserCtrlObserver::onStatusTextChange, event );
00658 }
00659
00661
00662 void LLWebBrowserCtrl::onLocationChange( const EventType& eventIn )
00663 {
00664 const LLURI url(eventIn.getStringValue());
00665 LLSD queryMap(url.queryMap());
00666 std::string redirect_http_hack = queryMap["redirect-http-hack"].asString();
00667 if (!redirect_http_hack.empty())
00668 {
00669 const bool from_external_browser = false;
00670 LLURLDispatcher::dispatch(redirect_http_hack, from_external_browser);
00671 return;
00672 }
00673
00674
00675 LLWebBrowserCtrlEvent event( eventIn.getStringValue() );
00676 mEventEmitter.update( &LLWebBrowserCtrlObserver::onLocationChange, event );
00677 }
00678
00680
00681 void LLWebBrowserCtrl::onMediaContentsChange( const EventType& event_in )
00682 {
00683 if ( mWebBrowserImage )
00684 {
00685 mWebBrowserImage->setNeedsUpdate();
00686 mForceUpdate = true;
00687 }
00688 }
00689
00691
00692 void LLWebBrowserCtrl::onClickLinkExternalTarget( S32 option, void* userdata )
00693 {
00694 if ( 0 == option )
00695 {
00696
00697
00698 LLWeb::loadURLExternal( ((LLWebBrowserCtrl*)userdata)->mExternalUrl );
00699 };
00700 }
00701
00703
00704 void LLWebBrowserCtrl::onClickLinkHref( const EventType& eventIn )
00705 {
00706
00707 if ( eventIn.getStringValueEx().length() )
00708 {
00709
00710 if ( eventIn.getStringValueEx() == "_external" ) {
00711 mExternalUrl = eventIn.getStringValue();
00712 gViewerWindow->alertXml( "WebLaunchExternalTarget", onClickLinkExternalTarget, (void*)this );
00713 return;
00714 };
00715 };
00716
00717 const std::string protocol1( "http://" );
00718 const std::string protocol2( "https://" );
00719 if( mOpenLinksInExternalBrowser )
00720 {
00721 if ( eventIn.getStringValue().length() )
00722 {
00723 if ( LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol1.length() ).c_str(), protocol1.c_str() ) == 0 ||
00724 LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol2.length() ).c_str(), protocol2.c_str() ) == 0 )
00725 {
00726 LLWeb::loadURLExternal( eventIn.getStringValue() );
00727 };
00728 };
00729 }
00730 else
00731 if( mOpenLinksInInternalBrowser )
00732 {
00733 if ( eventIn.getStringValue().length() )
00734 {
00735 if ( LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol1.length() ).c_str(), protocol1.c_str() ) == 0 ||
00736 LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol2.length() ).c_str(), protocol2.c_str() ) == 0 )
00737 {
00738
00739
00740
00741 const bool open_links_externally = false;
00742 LLFloaterHtml::getInstance()->show(
00743 eventIn.getStringValue(),
00744 "Second Life Browser",
00745 open_links_externally,
00746 mOpenAppSLURLs);
00747 };
00748 };
00749 };
00750
00751
00752 LLWebBrowserCtrlEvent event( eventIn.getStringValue(), eventIn.getStringValueEx() );
00753 mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkHref, event );
00754 }
00755
00757
00758 void LLWebBrowserCtrl::onClickLinkNoFollow( const EventType& eventIn )
00759 {
00760 std::string url = eventIn.getStringValue();
00761 if (LLURLDispatcher::isSLURLCommand(url)
00762 && !mOpenAppSLURLs)
00763 {
00764
00765 return;
00766 }
00767
00768 const bool from_external_browser = false;
00769 LLURLDispatcher::dispatch(url, from_external_browser);
00770
00771
00772 LLWebBrowserCtrlEvent event( eventIn.getStringValue() );
00773 mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkNoFollow, event );
00774 }
00775
00777
00778 LLWebBrowserTexture::LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, LLMediaBase *media_source ) :
00779 LLDynamicTexture( 512, 512, 4, ORDER_FIRST, TRUE ),
00780 mLastBrowserDepth( 0 ),
00781 mNeedsUpdate( true ),
00782 mWebBrowserCtrl( browserCtrl ),
00783 mMediaSource(media_source)
00784 {
00785 mElapsedTime.start();
00786
00787 resize( width, height );
00788 }
00789
00791
00792 LLWebBrowserTexture::~LLWebBrowserTexture()
00793 {
00794 mElapsedTime.stop();
00795 }
00796
00798
00799 BOOL LLWebBrowserTexture::needsRender()
00800 {
00801 if ( mWebBrowserCtrl->getFrequentUpdates() ||
00802 mWebBrowserCtrl->getAlwaysRefresh() ||
00803 mWebBrowserCtrl->getForceUpdate() )
00804 {
00805
00806 if ( mElapsedTime.getElapsedTimeF32() > ( 1.0f / 15.0f ) )
00807 {
00808 return TRUE;
00809 }
00810 }
00811
00812 return FALSE;
00813 }
00814
00816
00817 BOOL LLWebBrowserTexture::render()
00818 {
00819 if (!mMediaSource)
00820 return FALSE;
00821
00822
00823 if ( mWebBrowserCtrl->getFrequentUpdates() ||
00824 mWebBrowserCtrl->getAlwaysRefresh() ||
00825 mWebBrowserCtrl->getForceUpdate() )
00826 {
00827
00828 if ( mNeedsUpdate )
00829 {
00830
00831 const unsigned char* pixels = mMediaSource->getMediaData();
00832 if ( ! pixels )
00833 return FALSE;
00834
00835 mNeedsUpdate = false;
00836 mWebBrowserCtrl->setForceUpdate(false);
00837
00838 S32 media_depth = mMediaSource->getMediaDepth();
00839 S32 media_width = mMediaSource->getMediaWidth();
00840 S32 media_height = mMediaSource->getMediaHeight();
00841
00842
00843 if ((media_width < 1) || (media_depth < 2))
00844 return FALSE;
00845
00846
00847 if(mLastBrowserDepth == media_depth)
00848 {
00849 S32 width = llmin(media_width, mBrowserWidth);
00850 S32 height = llmin(media_height, mBrowserHeight);
00851
00852 S32 media_data_width = mMediaSource->getMediaDataWidth();
00853 S32 media_data_height = mMediaSource->getMediaDataHeight();
00854
00855
00856 if ( media_data_width > 0 && media_data_height > 0 &&
00857 media_data_width < MAX_DIMENSION && media_data_height < MAX_DIMENSION )
00858 {
00859 mTexture->setSubImage( pixels,
00860 media_data_width, media_data_height,
00861 0, 0,
00862 width, height );
00863 };
00864 }
00865 else
00866 {
00867
00868 resize(mBrowserWidth, mBrowserHeight);
00869 };
00870 };
00871 };
00872
00873 return TRUE;
00874 }
00875
00877
00878 S32 LLWebBrowserTexture::getBrowserWidth()
00879 {
00880 return mBrowserWidth;
00881 }
00882
00884
00885 S32 LLWebBrowserTexture::getBrowserHeight()
00886 {
00887 return mBrowserHeight;
00888 }
00889
00891
00892 void LLWebBrowserTexture::setNeedsUpdate()
00893 {
00894 mNeedsUpdate = true;
00895 }
00896
00898
00899 void LLWebBrowserTexture::resize( S32 new_width, S32 new_height )
00900 {
00901 if (!mMediaSource)
00902 return;
00903
00904 F32 scale_ratio = 1.f;
00905 if (new_width > MAX_DIMENSION)
00906 {
00907 scale_ratio = (F32)MAX_DIMENSION / (F32)new_width;
00908 }
00909 if (new_height > MAX_DIMENSION)
00910 {
00911 scale_ratio = llmin(scale_ratio, (F32)MAX_DIMENSION / (F32)new_height);
00912 }
00913
00914 mBrowserWidth = llround(scale_ratio * (F32)new_width);
00915 mBrowserHeight = llround(scale_ratio * (F32)new_height);
00916
00917 mMediaSource->setRequestedMediaSize(mBrowserWidth, mBrowserHeight);
00918
00919
00920
00921
00922 const unsigned char* pixels = mMediaSource->getMediaData();
00923
00924 S32 media_width = mMediaSource->getMediaWidth();
00925 S32 media_height = mMediaSource->getMediaHeight();
00926 S32 media_depth = mMediaSource->getMediaDepth();
00927
00928
00929 if ( media_width < 1 || media_depth < 2 )
00930 return;
00931
00932 releaseGLTexture();
00933
00934
00935 for ( mWidth = 1; mWidth < mBrowserWidth; mWidth <<= 1 )
00936 {
00937 if ( mWidth >= MAX_TEXTURE_DIMENSION )
00938 {
00939 break;
00940 };
00941 };
00942
00943 for ( mHeight = 1; mHeight < mBrowserHeight; mHeight <<= 1 )
00944 {
00945 if ( mHeight >= MAX_TEXTURE_DIMENSION )
00946 {
00947 break;
00948 };
00949 };
00950
00951 LLGLint internal_format;
00952 LLGLenum primary_format;
00953 LLGLenum type_format;
00954 BOOL swap_bytes = FALSE;
00955
00956 switch(media_depth)
00957 {
00958 default:
00959 case 4:
00960 internal_format = GL_RGBA8;
00961 primary_format = GL_BGRA_EXT;
00962 #if LL_DARWIN
00963 #if LL_BIG_ENDIAN
00964 type_format = GL_UNSIGNED_INT_8_8_8_8_REV;
00965 #else
00966 type_format = GL_UNSIGNED_INT_8_8_8_8;
00967 #endif
00968 #else // windows or linux
00969 type_format = GL_UNSIGNED_BYTE;
00970 #endif
00971 break;
00972
00973 case 2:
00974 #if LL_DARWIN
00975 internal_format = GL_RGBA8;
00976 primary_format = GL_BGRA_EXT;
00977 type_format = GL_UNSIGNED_SHORT_1_5_5_5_REV;
00978 #if LL_LITTLE_ENDIAN
00979 swap_bytes = TRUE;
00980 #endif
00981 #else // windows or linux
00982
00983 internal_format = GL_RGB8;
00984 primary_format = GL_RGB;
00985 type_format = GL_UNSIGNED_SHORT_5_6_5;
00986 #endif
00987 break;
00988 }
00989
00990
00991 LLDynamicTexture::generateGLTexture(internal_format, primary_format, type_format, swap_bytes);
00992
00993
00994 S32 width = llmin(media_width, mBrowserWidth);
00995 S32 height = llmin(media_height, mBrowserHeight);
00996
00997 S32 media_data_width = mMediaSource->getMediaDataWidth();
00998 S32 media_data_height = mMediaSource->getMediaDataHeight();
00999
01000 if (pixels)
01001 {
01002 mTexture->setSubImage( pixels, media_data_width, media_data_height,
01003 0, 0, width, height );
01004 }
01005
01006 mLastBrowserDepth = media_depth;
01007 }
01008
01009 LLView* LLWebBrowserCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
01010 {
01011 LLString name("web_browser");
01012 node->getAttributeString("name", name);
01013
01014 LLString start_url("start_url");
01015 node->getAttributeString("start_url", start_url );
01016
01017 BOOL border_visible = true;
01018 node->getAttributeBOOL("border_visible", border_visible);
01019
01020 LLRect rect;
01021 createRect(node, rect, parent, LLRect());
01022
01023 LLWebBrowserCtrl* web_browser = new LLWebBrowserCtrl( name, rect );
01024
01025 if(node->hasAttribute("caret_color"))
01026 {
01027 LLColor4 color;
01028 LLUICtrlFactory::getAttributeColor(node, "caret_color", color);
01029 LLColor4U colorU = LLColor4U(color);
01030 web_browser->setCaretColor( colorU.mV[0], colorU.mV[1], colorU.mV[2] );
01031 }
01032
01033 BOOL ignore_ui_scale = web_browser->getIgnoreUIScale();
01034 node->getAttributeBOOL("ignore_ui_scale", ignore_ui_scale);
01035 web_browser->setIgnoreUIScale((bool)ignore_ui_scale);
01036
01037 web_browser->initFromXML(node, parent);
01038
01039 web_browser->setHomePageUrl( start_url );
01040
01041 web_browser->setBorderVisible( border_visible );
01042
01043 web_browser->navigateHome();
01044
01045 return web_browser;
01046 }
01047
01048