diff options
-rw-r--r-- | linden/indra/newview/llfloaterhtml.cpp | 1 | ||||
-rw-r--r-- | linden/indra/newview/llwebbrowserctrl.cpp | 1068 | ||||
-rw-r--r-- | linden/indra/newview/llwebbrowserctrl.h | 325 |
3 files changed, 0 insertions, 1394 deletions
diff --git a/linden/indra/newview/llfloaterhtml.cpp b/linden/indra/newview/llfloaterhtml.cpp index a5d24f4..5822ed5 100644 --- a/linden/indra/newview/llfloaterhtml.cpp +++ b/linden/indra/newview/llfloaterhtml.cpp | |||
@@ -41,7 +41,6 @@ | |||
41 | #include "llviewerwindow.h" | 41 | #include "llviewerwindow.h" |
42 | #include "llweb.h" | 42 | #include "llweb.h" |
43 | 43 | ||
44 | #include "llwebbrowserctrl.h" | ||
45 | 44 | ||
46 | LLFloaterHtml* LLFloaterHtml::sInstance = 0; | 45 | LLFloaterHtml* LLFloaterHtml::sInstance = 0; |
47 | 46 | ||
diff --git a/linden/indra/newview/llwebbrowserctrl.cpp b/linden/indra/newview/llwebbrowserctrl.cpp deleted file mode 100644 index 453b9d2..0000000 --- a/linden/indra/newview/llwebbrowserctrl.cpp +++ /dev/null | |||
@@ -1,1068 +0,0 @@ | |||
1 | /** | ||
2 | * @file llwebbrowserctrl.cpp | ||
3 | * @brief Web browser UI control | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2006&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2006-2009, 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 | #include "llviewerprecompiledheaders.h" | ||
34 | |||
35 | |||
36 | #include "llwebbrowserctrl.h" | ||
37 | |||
38 | // viewer includes | ||
39 | #include "llfloaterhtml.h" | ||
40 | #include "llfloaterworldmap.h" | ||
41 | #include "lluictrlfactory.h" | ||
42 | #include "llurldispatcher.h" | ||
43 | #include "llurlsimstring.h" | ||
44 | #include "llviewborder.h" | ||
45 | #include "llviewercontrol.h" | ||
46 | #include "llviewerwindow.h" | ||
47 | #include "llnotifications.h" | ||
48 | #include "llweb.h" | ||
49 | #include "llrender.h" | ||
50 | |||
51 | // linden library includes | ||
52 | #include "llfocusmgr.h" | ||
53 | |||
54 | extern BOOL gRestoreGL; | ||
55 | |||
56 | // Setting the mozilla buffer width to 2048 exactly doesn't work, since it pads its rowbytes a bit, pushing the texture width over 2048. | ||
57 | // 2000 should give enough headroom for any amount of padding it cares to add. | ||
58 | const S32 MAX_DIMENSION = 2000; | ||
59 | const S32 MAX_TEXTURE_DIMENSION = 2048; | ||
60 | |||
61 | static LLRegisterWidget<LLWebBrowserCtrl> r("web_browser"); | ||
62 | |||
63 | LLWebBrowserCtrl::LLWebBrowserCtrl( const std::string& name, const LLRect& rect ) : | ||
64 | LLUICtrl( name, rect, FALSE, NULL, NULL ), | ||
65 | mTextureDepthBytes( 4 ), | ||
66 | mWebBrowserImage( 0 ), | ||
67 | mEmbeddedBrowserWindowId( 0 ), | ||
68 | mBorder(NULL), | ||
69 | mFrequentUpdates( true ), | ||
70 | mForceUpdate( false ), | ||
71 | mOpenLinksInExternalBrowser( false ), | ||
72 | mOpenLinksInInternalBrowser( false ), | ||
73 | mTrusted( false ), | ||
74 | mHomePageUrl( "" ), | ||
75 | mIgnoreUIScale( true ), | ||
76 | mAlwaysRefresh( false ), | ||
77 | mExternalUrl( "" ), | ||
78 | mMediaSource( 0 ), | ||
79 | mTakeFocusOnClick( true ), | ||
80 | mCurrentNavUrl( "about:blank" ) | ||
81 | { | ||
82 | S32 screen_width = mIgnoreUIScale ? | ||
83 | llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth(); | ||
84 | S32 screen_height = mIgnoreUIScale ? | ||
85 | llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight(); | ||
86 | |||
87 | |||
88 | LLMediaManager *mgr = LLMediaManager::getInstance(); | ||
89 | |||
90 | if (!mgr) | ||
91 | { | ||
92 | llwarns << "cannot get media manager" << llendl; | ||
93 | return; | ||
94 | } | ||
95 | |||
96 | mMediaSource = mgr->createSourceFromMimeType("http", "text/html" ); | ||
97 | if ( !mMediaSource ) | ||
98 | { | ||
99 | llwarns << "media source create failed " << llendl; | ||
100 | // return; | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | |||
105 | // mMediaSource->init(); | ||
106 | mMediaSource->addCommand( LLMediaBase::COMMAND_START ); | ||
107 | |||
108 | // observe the browser so we can trap HREF events) | ||
109 | mMediaSource->addObserver(this); | ||
110 | |||
111 | // create a new texture (based on LLDynamic texture) that will be used to display the output | ||
112 | mWebBrowserImage = new LLWebBrowserTexture( screen_width, screen_height, this, mMediaSource ); | ||
113 | } | ||
114 | |||
115 | LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 ); | ||
116 | mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN ); | ||
117 | addChild( mBorder ); | ||
118 | } | ||
119 | |||
120 | //////////////////////////////////////////////////////////////////////////////// | ||
121 | // note: this is now a singleton and destruction happens via initClass() now | ||
122 | LLWebBrowserCtrl::~LLWebBrowserCtrl() | ||
123 | { | ||
124 | LLMediaManager *mgr = LLMediaManager::getInstance(); | ||
125 | |||
126 | if (!mgr) | ||
127 | { | ||
128 | llwarns << "cannot get media manager" << llendl; | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | if (mMediaSource) | ||
133 | { | ||
134 | mgr->destroySource(mMediaSource); | ||
135 | mMediaSource = NULL; | ||
136 | } | ||
137 | |||
138 | if ( mWebBrowserImage ) | ||
139 | { | ||
140 | delete mWebBrowserImage; | ||
141 | mWebBrowserImage = 0; | ||
142 | }; | ||
143 | } | ||
144 | |||
145 | //////////////////////////////////////////////////////////////////////////////// | ||
146 | // | ||
147 | bool LLWebBrowserCtrl::addObserver( LLWebBrowserCtrlObserver* subjectIn ) | ||
148 | { | ||
149 | return mEventEmitter.addObserver( subjectIn ); | ||
150 | } | ||
151 | |||
152 | //////////////////////////////////////////////////////////////////////////////// | ||
153 | // | ||
154 | bool LLWebBrowserCtrl::remObserver( LLWebBrowserCtrlObserver* subjectIn ) | ||
155 | { | ||
156 | return mEventEmitter.remObserver( subjectIn ); | ||
157 | } | ||
158 | |||
159 | //////////////////////////////////////////////////////////////////////////////// | ||
160 | // | ||
161 | void LLWebBrowserCtrl::setBorderVisible( BOOL border_visible ) | ||
162 | { | ||
163 | if ( mBorder ) | ||
164 | { | ||
165 | mBorder->setVisible( border_visible ); | ||
166 | }; | ||
167 | }; | ||
168 | |||
169 | //////////////////////////////////////////////////////////////////////////////// | ||
170 | // | ||
171 | void LLWebBrowserCtrl::setTakeFocusOnClick( bool take_focus ) | ||
172 | { | ||
173 | mTakeFocusOnClick = take_focus; | ||
174 | } | ||
175 | |||
176 | //////////////////////////////////////////////////////////////////////////////// | ||
177 | // set flag that forces the embedded browser to open links in the external system browser | ||
178 | void LLWebBrowserCtrl::setOpenInExternalBrowser( bool valIn ) | ||
179 | { | ||
180 | mOpenLinksInExternalBrowser = valIn; | ||
181 | }; | ||
182 | |||
183 | //////////////////////////////////////////////////////////////////////////////// | ||
184 | // set flag that forces the embedded browser to open links in the internal browser floater | ||
185 | void LLWebBrowserCtrl::setOpenInInternalBrowser( bool valIn ) | ||
186 | { | ||
187 | mOpenLinksInInternalBrowser = valIn; | ||
188 | }; | ||
189 | |||
190 | //////////////////////////////////////////////////////////////////////////////// | ||
191 | void LLWebBrowserCtrl::setTrusted( bool valIn ) | ||
192 | { | ||
193 | mTrusted = valIn; | ||
194 | } | ||
195 | |||
196 | //////////////////////////////////////////////////////////////////////////////// | ||
197 | // | ||
198 | BOOL LLWebBrowserCtrl::handleHover( S32 x, S32 y, MASK mask ) | ||
199 | { | ||
200 | convertInputCoords(x, y); | ||
201 | |||
202 | if (mMediaSource) | ||
203 | mMediaSource->mouseMove(x, y); | ||
204 | |||
205 | return TRUE; | ||
206 | } | ||
207 | |||
208 | //////////////////////////////////////////////////////////////////////////////// | ||
209 | // | ||
210 | BOOL LLWebBrowserCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) | ||
211 | { | ||
212 | if (mMediaSource) | ||
213 | mMediaSource->scrollByLines(clicks); | ||
214 | |||
215 | return TRUE; | ||
216 | } | ||
217 | |||
218 | //////////////////////////////////////////////////////////////////////////////// | ||
219 | // | ||
220 | BOOL LLWebBrowserCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) | ||
221 | { | ||
222 | convertInputCoords(x, y); | ||
223 | |||
224 | if (mMediaSource) | ||
225 | { | ||
226 | mMediaSource->mouseUp(x, y); | ||
227 | |||
228 | // *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup, | ||
229 | // in addition to the onFocusReceived() call below. Undo this. JC | ||
230 | if (!mTakeFocusOnClick) | ||
231 | { | ||
232 | mMediaSource->focus(false); | ||
233 | gViewerWindow->focusClient(); | ||
234 | } | ||
235 | } | ||
236 | |||
237 | gFocusMgr.setMouseCapture( NULL ); | ||
238 | |||
239 | return TRUE; | ||
240 | } | ||
241 | |||
242 | //////////////////////////////////////////////////////////////////////////////// | ||
243 | // | ||
244 | BOOL LLWebBrowserCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) | ||
245 | { | ||
246 | convertInputCoords(x, y); | ||
247 | |||
248 | if (mMediaSource) | ||
249 | mMediaSource->mouseDown(x, y); | ||
250 | |||
251 | gFocusMgr.setMouseCapture( this ); | ||
252 | |||
253 | if (mTakeFocusOnClick) | ||
254 | { | ||
255 | setFocus( TRUE ); | ||
256 | } | ||
257 | |||
258 | return TRUE; | ||
259 | } | ||
260 | |||
261 | //////////////////////////////////////////////////////////////////////////////// | ||
262 | // | ||
263 | BOOL LLWebBrowserCtrl::handleDoubleClick( S32 x, S32 y, MASK mask ) | ||
264 | { | ||
265 | convertInputCoords(x, y); | ||
266 | |||
267 | if (mMediaSource) | ||
268 | mMediaSource->mouseLeftDoubleClick( x, y ); | ||
269 | |||
270 | gFocusMgr.setMouseCapture( this ); | ||
271 | |||
272 | if (mTakeFocusOnClick) | ||
273 | { | ||
274 | setFocus( TRUE ); | ||
275 | } | ||
276 | |||
277 | return TRUE; | ||
278 | } | ||
279 | |||
280 | //////////////////////////////////////////////////////////////////////////////// | ||
281 | // | ||
282 | void LLWebBrowserCtrl::onFocusReceived() | ||
283 | { | ||
284 | if (mMediaSource) | ||
285 | mMediaSource->focus(true); | ||
286 | |||
287 | |||
288 | LLUICtrl::onFocusReceived(); | ||
289 | } | ||
290 | |||
291 | //////////////////////////////////////////////////////////////////////////////// | ||
292 | // | ||
293 | void LLWebBrowserCtrl::onFocusLost() | ||
294 | { | ||
295 | if (mMediaSource) | ||
296 | mMediaSource->focus(false); | ||
297 | |||
298 | gViewerWindow->focusClient(); | ||
299 | |||
300 | LLUICtrl::onFocusLost(); | ||
301 | } | ||
302 | |||
303 | //////////////////////////////////////////////////////////////////////////////// | ||
304 | // | ||
305 | BOOL LLWebBrowserCtrl::handleKeyHere( KEY key, MASK mask ) | ||
306 | { | ||
307 | unsigned long media_key; | ||
308 | |||
309 | // First, turn SL internal keycode enum into Mozilla keycode enum | ||
310 | |||
311 | // We don't have to deal with printable characters here - they should | ||
312 | // go through handleUnicodeChar(). This table could be more complete | ||
313 | // than it is, but I think this covers all of the important | ||
314 | // non-printables. | ||
315 | |||
316 | switch (key) | ||
317 | { | ||
318 | case KEY_BACKSPACE: | ||
319 | media_key = LL_MEDIA_KEY_BACKSPACE; break; | ||
320 | case KEY_TAB: | ||
321 | media_key = LL_MEDIA_KEY_TAB; break; | ||
322 | case KEY_RETURN: | ||
323 | media_key = LL_MEDIA_KEY_RETURN; break; | ||
324 | case KEY_PAD_RETURN: | ||
325 | media_key = LL_MEDIA_KEY_PAD_RETURN; break; | ||
326 | case KEY_ESCAPE: | ||
327 | media_key = LL_MEDIA_KEY_ESCAPE; break; | ||
328 | case KEY_PAGE_UP: | ||
329 | media_key = LL_MEDIA_KEY_PAGE_UP; break; | ||
330 | case KEY_PAGE_DOWN: | ||
331 | media_key = LL_MEDIA_KEY_PAGE_DOWN; break; | ||
332 | case KEY_END: | ||
333 | media_key = LL_MEDIA_KEY_END; break; | ||
334 | case KEY_HOME: | ||
335 | media_key = LL_MEDIA_KEY_HOME; break; | ||
336 | case KEY_LEFT: | ||
337 | media_key = LL_MEDIA_KEY_LEFT; break; | ||
338 | case KEY_UP: | ||
339 | media_key = LL_MEDIA_KEY_UP; break; | ||
340 | case KEY_RIGHT: | ||
341 | media_key = LL_MEDIA_KEY_RIGHT; break; | ||
342 | case KEY_DOWN: | ||
343 | media_key = LL_MEDIA_KEY_DOWN; break; | ||
344 | case KEY_INSERT: | ||
345 | media_key = LL_MEDIA_KEY_INSERT; break; | ||
346 | case KEY_DELETE: | ||
347 | media_key = LL_MEDIA_KEY_DELETE; break; | ||
348 | default: | ||
349 | llinfos << "Don't know how to map LL keycode " << U32(key) | ||
350 | << " to DOM key. Ignoring." << llendl; | ||
351 | return FALSE; // don't know how to map this key. | ||
352 | } | ||
353 | |||
354 | if (mMediaSource) | ||
355 | mMediaSource->keyPress(media_key); | ||
356 | |||
357 | return TRUE; | ||
358 | } | ||
359 | |||
360 | BOOL LLWebBrowserCtrl::handleUnicodeCharHere(llwchar uni_char) | ||
361 | { | ||
362 | // only accept 'printable' characters, sigh... | ||
363 | if (uni_char >= 32 // discard 'control' characters | ||
364 | && uni_char != 127) // SDL thinks this is 'delete' - yuck. | ||
365 | { | ||
366 | if (mMediaSource) | ||
367 | mMediaSource->unicodeInput(uni_char); | ||
368 | } | ||
369 | |||
370 | return TRUE; | ||
371 | } | ||
372 | |||
373 | //////////////////////////////////////////////////////////////////////////////// | ||
374 | // | ||
375 | void LLWebBrowserCtrl::onVisibilityChange ( BOOL new_visibility ) | ||
376 | { | ||
377 | // set state of frequent updates automatically if visibility changes | ||
378 | if ( new_visibility ) | ||
379 | { | ||
380 | mFrequentUpdates = true; | ||
381 | } | ||
382 | else | ||
383 | { | ||
384 | mFrequentUpdates = false; | ||
385 | } | ||
386 | LLUICtrl::onVisibilityChange(new_visibility); | ||
387 | } | ||
388 | |||
389 | //////////////////////////////////////////////////////////////////////////////// | ||
390 | // | ||
391 | void LLWebBrowserCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) | ||
392 | { | ||
393 | S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width; | ||
394 | S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height; | ||
395 | |||
396 | // when floater is minimized, these sizes are negative | ||
397 | if ( mWebBrowserImage && screen_height > 0 && screen_width > 0 ) | ||
398 | { | ||
399 | mWebBrowserImage->resize( screen_width, screen_height ); | ||
400 | mForceUpdate = true; | ||
401 | } | ||
402 | |||
403 | LLUICtrl::reshape( width, height, called_from_parent ); | ||
404 | } | ||
405 | |||
406 | //////////////////////////////////////////////////////////////////////////////// | ||
407 | // | ||
408 | void LLWebBrowserCtrl::navigateBack() | ||
409 | { | ||
410 | if (mMediaSource) | ||
411 | mMediaSource->navigateBack(); | ||
412 | } | ||
413 | |||
414 | //////////////////////////////////////////////////////////////////////////////// | ||
415 | // | ||
416 | void LLWebBrowserCtrl::navigateForward() | ||
417 | { | ||
418 | if (mMediaSource) | ||
419 | mMediaSource->navigateForward(); | ||
420 | } | ||
421 | |||
422 | //////////////////////////////////////////////////////////////////////////////// | ||
423 | // | ||
424 | bool LLWebBrowserCtrl::canNavigateBack() | ||
425 | { | ||
426 | if (mMediaSource) | ||
427 | return mMediaSource->canNavigateBack(); | ||
428 | else | ||
429 | return false; | ||
430 | } | ||
431 | |||
432 | //////////////////////////////////////////////////////////////////////////////// | ||
433 | // | ||
434 | bool LLWebBrowserCtrl::canNavigateForward() | ||
435 | { | ||
436 | if (mMediaSource) | ||
437 | return mMediaSource->canNavigateForward(); | ||
438 | else | ||
439 | return false; | ||
440 | } | ||
441 | |||
442 | //////////////////////////////////////////////////////////////////////////////// | ||
443 | // | ||
444 | bool LLWebBrowserCtrl::set404RedirectUrl( std::string redirect_url ) | ||
445 | { | ||
446 | if(mMediaSource) | ||
447 | return mMediaSource->set404RedirectUrl( redirect_url ); | ||
448 | else | ||
449 | return false; | ||
450 | } | ||
451 | |||
452 | //////////////////////////////////////////////////////////////////////////////// | ||
453 | // | ||
454 | bool LLWebBrowserCtrl::clr404RedirectUrl() | ||
455 | { | ||
456 | if(mMediaSource) | ||
457 | return mMediaSource->clr404RedirectUrl(); | ||
458 | else | ||
459 | return false; | ||
460 | } | ||
461 | |||
462 | //////////////////////////////////////////////////////////////////////////////// | ||
463 | // | ||
464 | void LLWebBrowserCtrl::navigateTo( std::string urlIn ) | ||
465 | { | ||
466 | // don't browse to anything that starts with secondlife:// or sl:// | ||
467 | const std::string protocol1 = "secondlife://"; | ||
468 | const std::string protocol2 = "sl://"; | ||
469 | if ((LLStringUtil::compareInsensitive(urlIn.substr(0, protocol1.length()), protocol1) == 0) || | ||
470 | (LLStringUtil::compareInsensitive(urlIn.substr(0, protocol2.length()), protocol2) == 0)) | ||
471 | { | ||
472 | // TODO: Print out/log this attempt? | ||
473 | // llinfos << "Rejecting attempt to load restricted website :" << urlIn << llendl; | ||
474 | return; | ||
475 | } | ||
476 | |||
477 | if (mMediaSource) | ||
478 | { | ||
479 | mCurrentNavUrl = urlIn; | ||
480 | mMediaSource->navigateTo(urlIn); | ||
481 | } | ||
482 | } | ||
483 | |||
484 | |||
485 | void LLWebBrowserCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in ) | ||
486 | { | ||
487 | std::string language = LLUI::getLanguage(); | ||
488 | std::string delim = gDirUtilp->getDirDelimiter(); | ||
489 | std::string filename; | ||
490 | |||
491 | filename += subdir; | ||
492 | filename += delim; | ||
493 | filename += filename_in; | ||
494 | |||
495 | std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", language, filename); | ||
496 | |||
497 | if (gDirUtilp->fileExists(expanded_filename)) | ||
498 | { | ||
499 | navigateTo(expanded_filename); | ||
500 | return; | ||
501 | } | ||
502 | if (language != "en-us") | ||
503 | { | ||
504 | expanded_filename = gDirUtilp->findSkinnedFilename("html", "en-us", filename); | ||
505 | if (gDirUtilp->fileExists(expanded_filename)) | ||
506 | { | ||
507 | navigateTo(expanded_filename); | ||
508 | return; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | llwarns << "File " << subdir << delim << filename_in << "not found" << llendl; | ||
513 | } | ||
514 | |||
515 | |||
516 | //////////////////////////////////////////////////////////////////////////////// | ||
517 | // | ||
518 | void LLWebBrowserCtrl::navigateHome() | ||
519 | { | ||
520 | if( mHomePageUrl.length() ) | ||
521 | { | ||
522 | if (mMediaSource) | ||
523 | mMediaSource->navigateTo(mHomePageUrl); | ||
524 | }; | ||
525 | } | ||
526 | |||
527 | //////////////////////////////////////////////////////////////////////////////// | ||
528 | // | ||
529 | void LLWebBrowserCtrl::setHomePageUrl( const std::string urlIn ) | ||
530 | { | ||
531 | mHomePageUrl = urlIn; | ||
532 | } | ||
533 | |||
534 | //////////////////////////////////////////////////////////////////////////////// | ||
535 | // | ||
536 | bool LLWebBrowserCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue) | ||
537 | { | ||
538 | if (mMediaSource) | ||
539 | return mMediaSource->setCaretColor(red, green, blue); | ||
540 | else | ||
541 | return false; | ||
542 | } | ||
543 | //////////////////////////////////////////////////////////////////////////////// | ||
544 | // | ||
545 | std::string LLWebBrowserCtrl::getHomePageUrl() | ||
546 | { | ||
547 | return mHomePageUrl; | ||
548 | } | ||
549 | |||
550 | //////////////////////////////////////////////////////////////////////////////// | ||
551 | // | ||
552 | void LLWebBrowserCtrl::draw() | ||
553 | { | ||
554 | if ( ! mWebBrowserImage ) | ||
555 | return; | ||
556 | |||
557 | if ( gRestoreGL == 1 ) | ||
558 | { | ||
559 | LLRect r = getRect(); | ||
560 | mMediaSource->updateMedia(); | ||
561 | reshape( r.getWidth(), r.getHeight(), FALSE ); | ||
562 | return; | ||
563 | }; | ||
564 | |||
565 | // NOTE: optimization needed here - probably only need to do this once | ||
566 | // unless tearoffs change the parent which they probably do. | ||
567 | const LLUICtrl* ptr = findRootMostFocusRoot(); | ||
568 | if ( ptr && ptr->hasFocus() ) | ||
569 | { | ||
570 | setFrequentUpdates( true ); | ||
571 | } | ||
572 | else | ||
573 | { | ||
574 | setFrequentUpdates( false ); | ||
575 | }; | ||
576 | |||
577 | // alpha off for this | ||
578 | LLGLSUIDefault gls_ui; | ||
579 | LLGLDisable gls_alphaTest( GL_ALPHA_TEST ); | ||
580 | |||
581 | gGL.pushMatrix(); | ||
582 | { | ||
583 | if (mIgnoreUIScale) | ||
584 | { | ||
585 | glLoadIdentity(); | ||
586 | // font system stores true screen origin, need to scale this by UI scale factor | ||
587 | // to get render origin for this view (with unit scale) | ||
588 | gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::sGLScaleFactor.mV[VX]), | ||
589 | floorf(LLFontGL::sCurOrigin.mY * LLUI::sGLScaleFactor.mV[VY]), | ||
590 | LLFontGL::sCurOrigin.mZ); | ||
591 | } | ||
592 | |||
593 | // scale texture to fit the space using texture coords | ||
594 | gGL.getTexUnit(0)->bind(mWebBrowserImage->getTexture()); | ||
595 | gGL.color4fv( LLColor4::white.mV ); | ||
596 | F32 max_u = ( F32 )mWebBrowserImage->getBrowserWidth() / ( F32 )mWebBrowserImage->getWidth(); | ||
597 | F32 max_v = ( F32 )mWebBrowserImage->getBrowserHeight() / ( F32 )mWebBrowserImage->getHeight(); | ||
598 | |||
599 | // draw the browser | ||
600 | gGL.setSceneBlendType(LLRender::BT_REPLACE); | ||
601 | gGL.begin( LLRender::QUADS ); | ||
602 | { | ||
603 | // render using web browser reported width and height, instead of trying to invert GL scale | ||
604 | gGL.texCoord2f( max_u, max_v ); | ||
605 | gGL.vertex2i( mWebBrowserImage->getBrowserWidth(), mWebBrowserImage->getBrowserHeight() ); | ||
606 | |||
607 | gGL.texCoord2f( 0.f, max_v ); | ||
608 | gGL.vertex2i( 0, mWebBrowserImage->getBrowserHeight() ); | ||
609 | |||
610 | gGL.texCoord2f( 0.f, 0.f ); | ||
611 | gGL.vertex2i( 0, 0 ); | ||
612 | |||
613 | gGL.texCoord2f( max_u, 0.f ); | ||
614 | gGL.vertex2i( mWebBrowserImage->getBrowserWidth(), 0 ); | ||
615 | } | ||
616 | gGL.end(); | ||
617 | gGL.setSceneBlendType(LLRender::BT_ALPHA); | ||
618 | } | ||
619 | gGL.popMatrix(); | ||
620 | |||
621 | // highlight if keyboard focus here. (TODO: this needs some work) | ||
622 | if ( mBorder->getVisible() ) | ||
623 | mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) ); | ||
624 | |||
625 | |||
626 | LLUICtrl::draw(); | ||
627 | } | ||
628 | |||
629 | void LLWebBrowserCtrl::convertInputCoords(S32& x, S32& y) | ||
630 | { | ||
631 | x = mIgnoreUIScale ? llround((F32)x * LLUI::sGLScaleFactor.mV[VX]) : x; | ||
632 | y = mIgnoreUIScale ? llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight() - y; | ||
633 | } | ||
634 | |||
635 | //////////////////////////////////////////////////////////////////////////////// | ||
636 | // virtual | ||
637 | void LLWebBrowserCtrl::onNavigateBegin( const EventType& eventIn ) | ||
638 | { | ||
639 | LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); | ||
640 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateBegin, event ); | ||
641 | } | ||
642 | |||
643 | //////////////////////////////////////////////////////////////////////////////// | ||
644 | // virtual | ||
645 | void LLWebBrowserCtrl::onNavigateComplete( const EventType& eventIn ) | ||
646 | { | ||
647 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
648 | LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); | ||
649 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateComplete, event ); | ||
650 | } | ||
651 | |||
652 | //////////////////////////////////////////////////////////////////////////////// | ||
653 | // virtual | ||
654 | void LLWebBrowserCtrl::onUpdateProgress( const EventType& eventIn ) | ||
655 | { | ||
656 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
657 | LLWebBrowserCtrlEvent event( eventIn.getIntValue() ); | ||
658 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onUpdateProgress, event ); | ||
659 | } | ||
660 | |||
661 | //////////////////////////////////////////////////////////////////////////////// | ||
662 | // virtual | ||
663 | void LLWebBrowserCtrl::onStatusTextChange( const EventType& eventIn ) | ||
664 | { | ||
665 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
666 | LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); | ||
667 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onStatusTextChange, event ); | ||
668 | } | ||
669 | |||
670 | //////////////////////////////////////////////////////////////////////////////// | ||
671 | // virtual | ||
672 | void LLWebBrowserCtrl::onLocationChange( const EventType& eventIn ) | ||
673 | { | ||
674 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
675 | LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); | ||
676 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onLocationChange, event ); | ||
677 | } | ||
678 | |||
679 | //////////////////////////////////////////////////////////////////////////////// | ||
680 | // virtual | ||
681 | void LLWebBrowserCtrl::onMediaContentsChange( const EventType& event_in ) | ||
682 | { | ||
683 | if ( mWebBrowserImage ) | ||
684 | { | ||
685 | mWebBrowserImage->setNeedsUpdate(); | ||
686 | mForceUpdate = true; | ||
687 | } | ||
688 | } | ||
689 | |||
690 | //////////////////////////////////////////////////////////////////////////////// | ||
691 | // static | ||
692 | bool LLWebBrowserCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response ) | ||
693 | { | ||
694 | S32 option = LLNotification::getSelectedOption(notification, response); | ||
695 | if ( 0 == option ) | ||
696 | { | ||
697 | // open in external browser because we don't support | ||
698 | // creation of our own secondary browser windows | ||
699 | LLWeb::loadURLExternal( notification["payload"]["external_url"].asString() ); | ||
700 | } | ||
701 | return false; | ||
702 | } | ||
703 | |||
704 | //////////////////////////////////////////////////////////////////////////////// | ||
705 | // virtual | ||
706 | void LLWebBrowserCtrl::onClickLinkHref( const EventType& eventIn ) | ||
707 | { | ||
708 | // if there is a value for the target (passed in stringValueEx) | ||
709 | if ( eventIn.getStringValueEx().length() ) | ||
710 | { | ||
711 | // if the target = "_new" | ||
712 | if ( eventIn.getStringValueEx() == "_external" ) | ||
713 | { | ||
714 | mExternalUrl = eventIn.getStringValue(); | ||
715 | LLSD payload; | ||
716 | payload["external_url"] = mExternalUrl; | ||
717 | LLNotifications::instance().add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget); | ||
718 | return; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | const std::string protocol1( "http://" ); | ||
723 | const std::string protocol2( "https://" ); | ||
724 | if( mOpenLinksInExternalBrowser ) | ||
725 | { | ||
726 | if ( eventIn.getStringValue().length() ) | ||
727 | { | ||
728 | if ( LLStringUtil::compareInsensitive( eventIn.getStringValue().substr( 0, protocol1.length() ), protocol1 ) == 0 || | ||
729 | LLStringUtil::compareInsensitive( eventIn.getStringValue().substr( 0, protocol2.length() ), protocol2 ) == 0 ) | ||
730 | { | ||
731 | LLWeb::loadURLExternal( eventIn.getStringValue() ); | ||
732 | } | ||
733 | } | ||
734 | } | ||
735 | else | ||
736 | if( mOpenLinksInInternalBrowser ) | ||
737 | { | ||
738 | if ( eventIn.getStringValue().length() ) | ||
739 | { | ||
740 | if ( LLStringUtil::compareInsensitive( eventIn.getStringValue().substr( 0, protocol1.length() ), protocol1 ) == 0 || | ||
741 | LLStringUtil::compareInsensitive( eventIn.getStringValue().substr( 0, protocol2.length() ), protocol2 ) == 0 ) | ||
742 | { | ||
743 | // If we spawn a new LLFloaterHTML, assume we want it to | ||
744 | // follow this LLWebBrowserCtrl's trust for whether or | ||
745 | // not to open secondlife:///app/ links. JC. | ||
746 | const bool open_links_externally = false; | ||
747 | LLFloaterHtml::getInstance()->show( | ||
748 | eventIn.getStringValue(), | ||
749 | "Second Life Browser", | ||
750 | open_links_externally, | ||
751 | mTrusted); | ||
752 | } | ||
753 | } | ||
754 | } | ||
755 | |||
756 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
757 | LLWebBrowserCtrlEvent event( eventIn.getStringValue(), eventIn.getStringValueEx() ); | ||
758 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkHref, event ); | ||
759 | } | ||
760 | |||
761 | //////////////////////////////////////////////////////////////////////////////// | ||
762 | // virtual | ||
763 | void LLWebBrowserCtrl::onClickLinkNoFollow( const EventType& eventIn ) | ||
764 | { | ||
765 | std::string url = eventIn.getStringValue(); | ||
766 | if (LLURLDispatcher::isSLURLCommand(url) | ||
767 | && !mTrusted) | ||
768 | { | ||
769 | // block handling of this secondlife:///app/ URL | ||
770 | LLNotifications::instance().add("UnableToOpenCommandURL"); | ||
771 | return; | ||
772 | } | ||
773 | |||
774 | LLURLDispatcher::dispatch(url, this, mTrusted); | ||
775 | |||
776 | // chain this event on to observers of an instance of LLWebBrowserCtrl | ||
777 | LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); | ||
778 | mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkNoFollow, event ); | ||
779 | } | ||
780 | |||
781 | //////////////////////////////////////////////////////////////////////////////// | ||
782 | // | ||
783 | LLWebBrowserTexture::LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, LLMediaBase *media_source ) : | ||
784 | LLDynamicTexture( 512, 512, 4, ORDER_FIRST, TRUE ), | ||
785 | mLastBrowserDepth( 0 ), | ||
786 | mNeedsUpdate( true ), | ||
787 | mWebBrowserCtrl( browserCtrl ), | ||
788 | mMediaSource(media_source) | ||
789 | { | ||
790 | mElapsedTime.start(); | ||
791 | |||
792 | resize( width, height ); | ||
793 | } | ||
794 | |||
795 | //////////////////////////////////////////////////////////////////////////////// | ||
796 | // | ||
797 | LLWebBrowserTexture::~LLWebBrowserTexture() | ||
798 | { | ||
799 | mElapsedTime.stop(); | ||
800 | } | ||
801 | |||
802 | //////////////////////////////////////////////////////////////////////////////// | ||
803 | // | ||
804 | BOOL LLWebBrowserTexture::needsRender() | ||
805 | { | ||
806 | if ( mWebBrowserCtrl->getFrequentUpdates() || | ||
807 | mWebBrowserCtrl->getAlwaysRefresh() || | ||
808 | mWebBrowserCtrl->getForceUpdate() ) | ||
809 | { | ||
810 | // only update mozilla/texture occasionally | ||
811 | if ( mElapsedTime.getElapsedTimeF32() > ( 1.0f / 15.0f ) ) | ||
812 | { | ||
813 | return TRUE; | ||
814 | } | ||
815 | } | ||
816 | |||
817 | return FALSE; | ||
818 | } | ||
819 | |||
820 | //////////////////////////////////////////////////////////////////////////////// | ||
821 | // | ||
822 | BOOL LLWebBrowserTexture::render() | ||
823 | { | ||
824 | if (!mMediaSource) | ||
825 | return FALSE; | ||
826 | |||
827 | // frequent updates turned on? | ||
828 | if ( mWebBrowserCtrl->getFrequentUpdates() || | ||
829 | mWebBrowserCtrl->getAlwaysRefresh() || | ||
830 | mWebBrowserCtrl->getForceUpdate() ) | ||
831 | { | ||
832 | |||
833 | if ( mNeedsUpdate ) | ||
834 | { | ||
835 | |||
836 | const unsigned char* pixels = mMediaSource->getMediaData(); | ||
837 | if ( ! pixels ) | ||
838 | return FALSE; | ||
839 | |||
840 | mNeedsUpdate = false; | ||
841 | mWebBrowserCtrl->setForceUpdate(false); | ||
842 | |||
843 | S32 media_depth = mMediaSource->getMediaDepth(); | ||
844 | S32 media_width = mMediaSource->getMediaWidth(); | ||
845 | S32 media_height = mMediaSource->getMediaHeight(); | ||
846 | |||
847 | // these are both invalid conditions and should never happen but SL-27583 indicates it does | ||
848 | if ((media_width < 1) || (media_depth < 2)) | ||
849 | return FALSE; | ||
850 | |||
851 | // Browser depth hasn't changed. | ||
852 | if(mLastBrowserDepth == media_depth) | ||
853 | { | ||
854 | S32 width = llmin(media_width, mBrowserWidth); | ||
855 | S32 height = llmin(media_height, mBrowserHeight); | ||
856 | |||
857 | S32 media_data_width = mMediaSource->getMediaDataWidth(); | ||
858 | S32 media_data_height = mMediaSource->getMediaDataHeight(); | ||
859 | |||
860 | // Just grab the pixels. | ||
861 | if ( media_data_width > 0 && media_data_height > 0 && | ||
862 | media_data_width < MAX_DIMENSION && media_data_height < MAX_DIMENSION ) | ||
863 | { | ||
864 | mTexture->setSubImage( pixels, | ||
865 | media_data_width, media_data_height, | ||
866 | 0, 0, | ||
867 | llmin(width, media_data_width), llmin(media_data_height, height) ); | ||
868 | }; | ||
869 | } | ||
870 | else | ||
871 | { | ||
872 | // Browser depth has changed -- need to recreate texture to match. | ||
873 | resize(mBrowserWidth, mBrowserHeight); | ||
874 | }; | ||
875 | }; | ||
876 | }; | ||
877 | |||
878 | return TRUE; | ||
879 | } | ||
880 | |||
881 | //////////////////////////////////////////////////////////////////////////////// | ||
882 | // | ||
883 | S32 LLWebBrowserTexture::getBrowserWidth() | ||
884 | { | ||
885 | return mBrowserWidth; | ||
886 | } | ||
887 | |||
888 | //////////////////////////////////////////////////////////////////////////////// | ||
889 | // | ||
890 | S32 LLWebBrowserTexture::getBrowserHeight() | ||
891 | { | ||
892 | return mBrowserHeight; | ||
893 | } | ||
894 | |||
895 | //////////////////////////////////////////////////////////////////////////////// | ||
896 | // | ||
897 | void LLWebBrowserTexture::setNeedsUpdate() | ||
898 | { | ||
899 | mNeedsUpdate = true; | ||
900 | } | ||
901 | |||
902 | //////////////////////////////////////////////////////////////////////////////// | ||
903 | // | ||
904 | void LLWebBrowserTexture::resize( S32 new_width, S32 new_height ) | ||
905 | { | ||
906 | if (!mMediaSource) | ||
907 | return; | ||
908 | |||
909 | F32 scale_ratio = 1.f; | ||
910 | if (new_width > MAX_DIMENSION) | ||
911 | { | ||
912 | scale_ratio = (F32)MAX_DIMENSION / (F32)new_width; | ||
913 | } | ||
914 | if (new_height > MAX_DIMENSION) | ||
915 | { | ||
916 | scale_ratio = llmin(scale_ratio, (F32)MAX_DIMENSION / (F32)new_height); | ||
917 | } | ||
918 | |||
919 | mBrowserWidth = llround(scale_ratio * (F32)new_width); | ||
920 | mBrowserHeight = llround(scale_ratio * (F32)new_height); | ||
921 | |||
922 | mMediaSource->setRequestedMediaSize(mBrowserWidth, mBrowserHeight); | ||
923 | |||
924 | // HACK - this code is executing a render - resize should call render() instead | ||
925 | // (and render() should be refactored so it doesn't call resize()) | ||
926 | |||
927 | mMediaSource->updateMedia(); | ||
928 | const unsigned char* pixels = mMediaSource->getMediaData(); | ||
929 | |||
930 | S32 media_width = mMediaSource->getMediaWidth(); | ||
931 | S32 media_height = mMediaSource->getMediaHeight(); | ||
932 | S32 media_depth = mMediaSource->getMediaDepth(); | ||
933 | |||
934 | // these are both invalid conditions and should never happen but SL-27583 indicates it does | ||
935 | if ( media_width < 1 || media_depth < 2 ) | ||
936 | return; | ||
937 | |||
938 | releaseGLTexture(); | ||
939 | |||
940 | // calculate the next power of 2 bigger than reqquested size for width and height | ||
941 | for ( mWidth = 1; mWidth < mBrowserWidth; mWidth <<= 1 ) | ||
942 | { | ||
943 | if ( mWidth >= MAX_TEXTURE_DIMENSION ) | ||
944 | { | ||
945 | break; | ||
946 | }; | ||
947 | }; | ||
948 | |||
949 | for ( mHeight = 1; mHeight < mBrowserHeight; mHeight <<= 1 ) | ||
950 | { | ||
951 | if ( mHeight >= MAX_TEXTURE_DIMENSION ) | ||
952 | { | ||
953 | break; | ||
954 | }; | ||
955 | }; | ||
956 | |||
957 | LLGLint internal_format; | ||
958 | LLGLenum primary_format; | ||
959 | LLGLenum type_format; | ||
960 | BOOL swap_bytes = FALSE; | ||
961 | |||
962 | switch(media_depth) | ||
963 | { | ||
964 | default: | ||
965 | case 4: | ||
966 | internal_format = GL_RGBA8; | ||
967 | primary_format = GL_BGRA_EXT; | ||
968 | #if LL_DARWIN | ||
969 | #if LL_BIG_ENDIAN | ||
970 | type_format = GL_UNSIGNED_INT_8_8_8_8_REV; | ||
971 | #else | ||
972 | type_format = GL_UNSIGNED_INT_8_8_8_8; | ||
973 | #endif | ||
974 | #else // windows or linux | ||
975 | type_format = GL_UNSIGNED_BYTE; | ||
976 | #endif | ||
977 | break; | ||
978 | |||
979 | case 2: | ||
980 | #if LL_DARWIN | ||
981 | internal_format = GL_RGBA8; | ||
982 | primary_format = GL_BGRA_EXT; | ||
983 | type_format = GL_UNSIGNED_SHORT_1_5_5_5_REV; | ||
984 | #if LL_LITTLE_ENDIAN | ||
985 | swap_bytes = TRUE; | ||
986 | #endif | ||
987 | #else // windows or linux | ||
988 | // 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. | ||
989 | internal_format = GL_RGB8; | ||
990 | primary_format = GL_RGB; | ||
991 | type_format = GL_UNSIGNED_SHORT_5_6_5; | ||
992 | #endif | ||
993 | break; | ||
994 | } | ||
995 | |||
996 | // will create mWidth * mHeight sized texture, using BGR ordering | ||
997 | LLDynamicTexture::generateGLTexture(internal_format, primary_format, type_format, swap_bytes); | ||
998 | |||
999 | |||
1000 | S32 width = llmin(media_width, mBrowserWidth); | ||
1001 | S32 height = llmin(media_height, mBrowserHeight); | ||
1002 | |||
1003 | S32 media_data_width = mMediaSource->getMediaDataWidth(); | ||
1004 | S32 media_data_height = mMediaSource->getMediaDataHeight(); | ||
1005 | |||
1006 | if (pixels) | ||
1007 | { | ||
1008 | mTexture->setSubImage( pixels, media_data_width, media_data_height, | ||
1009 | 0, 0, width, height ); | ||
1010 | } | ||
1011 | |||
1012 | mLastBrowserDepth = media_depth; | ||
1013 | } | ||
1014 | |||
1015 | // virtual | ||
1016 | LLXMLNodePtr LLWebBrowserCtrl::getXML(bool save_children) const | ||
1017 | { | ||
1018 | LLXMLNodePtr node = LLUICtrl::getXML(); | ||
1019 | |||
1020 | node->setName(LL_WEB_BROWSER_CTRL_TAG); | ||
1021 | |||
1022 | return node; | ||
1023 | } | ||
1024 | |||
1025 | LLView* LLWebBrowserCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) | ||
1026 | { | ||
1027 | std::string name("web_browser"); | ||
1028 | node->getAttributeString("name", name); | ||
1029 | |||
1030 | std::string start_url("start_url"); | ||
1031 | node->getAttributeString("start_url", start_url ); | ||
1032 | |||
1033 | BOOL border_visible = true; | ||
1034 | node->getAttributeBOOL("border_visible", border_visible); | ||
1035 | |||
1036 | LLRect rect; | ||
1037 | createRect(node, rect, parent, LLRect()); | ||
1038 | |||
1039 | LLWebBrowserCtrl* web_browser = new LLWebBrowserCtrl( name, rect ); | ||
1040 | |||
1041 | if(node->hasAttribute("caret_color")) | ||
1042 | { | ||
1043 | LLColor4 color; | ||
1044 | LLUICtrlFactory::getAttributeColor(node, "caret_color", color); | ||
1045 | LLColor4U colorU = LLColor4U(color); | ||
1046 | web_browser->setCaretColor( colorU.mV[0], colorU.mV[1], colorU.mV[2] ); | ||
1047 | } | ||
1048 | |||
1049 | BOOL ignore_ui_scale = web_browser->getIgnoreUIScale(); | ||
1050 | node->getAttributeBOOL("ignore_ui_scale", ignore_ui_scale); | ||
1051 | web_browser->setIgnoreUIScale((bool)ignore_ui_scale); | ||
1052 | |||
1053 | web_browser->initFromXML(node, parent); | ||
1054 | |||
1055 | web_browser->setHomePageUrl( start_url ); | ||
1056 | |||
1057 | web_browser->setBorderVisible( border_visible ); | ||
1058 | |||
1059 | web_browser->navigateHome(); | ||
1060 | |||
1061 | return web_browser; | ||
1062 | } | ||
1063 | |||
1064 | std::string LLWebBrowserCtrl::getCurrentNavUrl() | ||
1065 | { | ||
1066 | return mCurrentNavUrl; | ||
1067 | } | ||
1068 | |||
diff --git a/linden/indra/newview/llwebbrowserctrl.h b/linden/indra/newview/llwebbrowserctrl.h deleted file mode 100644 index 79b8942..0000000 --- a/linden/indra/newview/llwebbrowserctrl.h +++ /dev/null | |||
@@ -1,325 +0,0 @@ | |||
1 | /** | ||
2 | * @file llwebbrowserctrl.h | ||
3 | * @brief Web browser UI control | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2006&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2006-2009, 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_LLWEBBROWSERCTRL_H | ||
34 | #define LL_LLWEBBROWSERCTRL_H | ||
35 | |||
36 | //////////////////////////////////////////////////////////////////////////////// | ||
37 | // data class that is passed with an event | ||
38 | class LLWebBrowserCtrlEvent | ||
39 | { | ||
40 | public: | ||
41 | LLWebBrowserCtrlEvent() | ||
42 | { | ||
43 | }; | ||
44 | |||
45 | LLWebBrowserCtrlEvent( int intValIn ) : | ||
46 | mIntVal( intValIn ) | ||
47 | { | ||
48 | }; | ||
49 | |||
50 | LLWebBrowserCtrlEvent( std::string stringValIn ) : | ||
51 | mIntVal(-1), | ||
52 | mStringVal( stringValIn ) | ||
53 | { | ||
54 | }; | ||
55 | |||
56 | LLWebBrowserCtrlEvent( std::string stringValIn, std::string stringValExIn ) : | ||
57 | mIntVal(-1), | ||
58 | mStringVal( stringValIn ), | ||
59 | mStringValEx( stringValExIn ) | ||
60 | { | ||
61 | }; | ||
62 | |||
63 | virtual ~LLWebBrowserCtrlEvent() | ||
64 | { | ||
65 | }; | ||
66 | |||
67 | int getIntValue() const | ||
68 | { | ||
69 | return mIntVal; | ||
70 | }; | ||
71 | |||
72 | std::string getStringValue() const | ||
73 | { | ||
74 | return mStringVal; | ||
75 | }; | ||
76 | |||
77 | std::string getStringValueEx() const | ||
78 | { | ||
79 | return mStringValEx; | ||
80 | }; | ||
81 | |||
82 | private: | ||
83 | int mIntVal; | ||
84 | std::string mStringVal; | ||
85 | std::string mStringValEx; | ||
86 | }; | ||
87 | |||
88 | //////////////////////////////////////////////////////////////////////////////// | ||
89 | // Override these methods to observe web browser control events | ||
90 | // (they are chained and fired after observing LLMozLibEvents) | ||
91 | class LLWebBrowserCtrlObserver | ||
92 | { | ||
93 | public: | ||
94 | virtual ~LLWebBrowserCtrlObserver() { }; | ||
95 | |||
96 | typedef LLWebBrowserCtrlEvent EventType; | ||
97 | virtual void onNavigateBegin( const EventType& eventIn ) { }; | ||
98 | virtual void onNavigateComplete( const EventType& eventIn ) { }; | ||
99 | virtual void onUpdateProgress( const EventType& eventIn ) { }; | ||
100 | virtual void onStatusTextChange( const EventType& eventIn ) { }; | ||
101 | virtual void onLocationChange( const EventType& eventIn ) { }; | ||
102 | virtual void onClickLinkHref( const EventType& eventIn ) { }; | ||
103 | virtual void onClickLinkNoFollow( const EventType& eventIn ) { }; | ||
104 | }; | ||
105 | |||
106 | #include "lluictrl.h" | ||
107 | #include "llframetimer.h" | ||
108 | #include "lldynamictexture.h" | ||
109 | #include "llmediaobserver.h" | ||
110 | |||
111 | class LLViewBorder; | ||
112 | class LLWebBrowserTexture; | ||
113 | |||
114 | /////////////////////////////////////////////////////////////////////////////// | ||
115 | // manages the process of storing and emitting events that the consumer | ||
116 | // of the embedding class can observe | ||
117 | template< class T > | ||
118 | class LLWebBrowserCtrlEventEmitter | ||
119 | { | ||
120 | public: | ||
121 | LLWebBrowserCtrlEventEmitter() { }; | ||
122 | ~LLWebBrowserCtrlEventEmitter() { }; | ||
123 | |||
124 | typedef typename T::EventType EventType; | ||
125 | typedef std::list< T* > ObserverContainer; | ||
126 | typedef void( T::*observerMethod )( const EventType& ); | ||
127 | |||
128 | /////////////////////////////////////////////////////////////////////////////// | ||
129 | // | ||
130 | bool addObserver( T* observerIn ) | ||
131 | { | ||
132 | if ( ! observerIn ) | ||
133 | return false; | ||
134 | |||
135 | if ( std::find( observers.begin(), observers.end(), observerIn ) != observers.end() ) | ||
136 | return false; | ||
137 | |||
138 | observers.push_back( observerIn ); | ||
139 | |||
140 | return true; | ||
141 | }; | ||
142 | |||
143 | /////////////////////////////////////////////////////////////////////////////// | ||
144 | // | ||
145 | bool remObserver( T* observerIn ) | ||
146 | { | ||
147 | if ( ! observerIn ) | ||
148 | return false; | ||
149 | |||
150 | observers.remove( observerIn ); | ||
151 | |||
152 | return true; | ||
153 | }; | ||
154 | |||
155 | /////////////////////////////////////////////////////////////////////////////// | ||
156 | // | ||
157 | void update( observerMethod method, const EventType& msgIn ) | ||
158 | { | ||
159 | typename std::list< T* >::iterator iter = observers.begin(); | ||
160 | |||
161 | while( iter != observers.end() ) | ||
162 | { | ||
163 | ( ( *iter )->*method )( msgIn ); | ||
164 | |||
165 | ++iter; | ||
166 | }; | ||
167 | }; | ||
168 | |||
169 | protected: | ||
170 | ObserverContainer observers; | ||
171 | }; | ||
172 | |||
173 | class LLUICtrlFactory; | ||
174 | |||
175 | //////////////////////////////////////////////////////////////////////////////// | ||
176 | // | ||
177 | class LLWebBrowserCtrl : | ||
178 | public LLUICtrl, | ||
179 | public LLMediaObserver | ||
180 | { | ||
181 | public: | ||
182 | LLWebBrowserCtrl( const std::string& name, const LLRect& rect ); | ||
183 | virtual ~LLWebBrowserCtrl(); | ||
184 | |||
185 | void setBorderVisible( BOOL border_visible ); | ||
186 | |||
187 | // For the tutorial window, we don't want to take focus on clicks, | ||
188 | // as the examples include how to move around with the arrow | ||
189 | // keys. Thus we keep focus on the app by setting this false. | ||
190 | // Defaults to true. | ||
191 | void setTakeFocusOnClick( bool take_focus ); | ||
192 | |||
193 | virtual LLXMLNodePtr getXML(bool save_children = true) const; | ||
194 | static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); | ||
195 | |||
196 | // handle mouse related methods | ||
197 | virtual BOOL handleHover( S32 x, S32 y, MASK mask ); | ||
198 | virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); | ||
199 | virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); | ||
200 | virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); | ||
201 | virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); | ||
202 | |||
203 | // navigation | ||
204 | void navigateTo( std::string urlIn ); | ||
205 | void navigateBack(); | ||
206 | void navigateHome(); | ||
207 | void navigateForward(); | ||
208 | void navigateToLocalPage( const std::string& subdir, const std::string& filename_in ); | ||
209 | bool canNavigateBack(); | ||
210 | bool canNavigateForward(); | ||
211 | void setOpenInExternalBrowser( bool valIn ); | ||
212 | void setOpenInInternalBrowser( bool valIn ); | ||
213 | std::string getCurrentNavUrl(); | ||
214 | |||
215 | // By default, we do not handle "secondlife:///app/" SLURLs, because | ||
216 | // those can cause teleports, open windows, etc. We cannot be sure | ||
217 | // that each "click" is actually due to a user action, versus | ||
218 | // Javascript or some other mechanism. However, we need the search | ||
219 | // floater and login page to handle these URLs. Those are safe | ||
220 | // because we control the page content. See DEV-9530. JC. | ||
221 | void setTrusted( bool valIn ); | ||
222 | |||
223 | void setHomePageUrl( const std::string urlIn ); | ||
224 | std::string getHomePageUrl(); | ||
225 | |||
226 | // set/clear URL to visit when a 404 page is reached | ||
227 | bool set404RedirectUrl( std::string redirect_url ); | ||
228 | bool clr404RedirectUrl(); | ||
229 | |||
230 | // accessor/mutator for flag that indicates if frequent updates to texture happen | ||
231 | bool getFrequentUpdates() { return mFrequentUpdates; }; | ||
232 | void setFrequentUpdates( bool frequentUpdatesIn ) { mFrequentUpdates = frequentUpdatesIn; }; | ||
233 | |||
234 | void setIgnoreUIScale(bool ignore) { mIgnoreUIScale = ignore; } | ||
235 | bool getIgnoreUIScale() { return mIgnoreUIScale; } | ||
236 | |||
237 | void setAlwaysRefresh(bool refresh) { mAlwaysRefresh = refresh; } | ||
238 | bool getAlwaysRefresh() { return mAlwaysRefresh; } | ||
239 | |||
240 | void setForceUpdate(bool force_update) { mForceUpdate = force_update; } | ||
241 | bool getForceUpdate() { return mForceUpdate; } | ||
242 | |||
243 | bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ); | ||
244 | |||
245 | |||
246 | // over-rides | ||
247 | virtual BOOL handleKeyHere( KEY key, MASK mask); | ||
248 | virtual BOOL handleUnicodeCharHere(llwchar uni_char); | ||
249 | virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE); | ||
250 | virtual void draw(); | ||
251 | virtual void onVisibilityChange ( BOOL curVisibilityIn ); | ||
252 | |||
253 | // focus overrides | ||
254 | void onFocusLost(); | ||
255 | void onFocusReceived(); | ||
256 | |||
257 | // observer interface | ||
258 | bool addObserver( LLWebBrowserCtrlObserver* subjectIn ); | ||
259 | bool remObserver( LLWebBrowserCtrlObserver* subjectIn ); | ||
260 | |||
261 | // LLMozlib observer overrides | ||
262 | virtual void onNavigateBegin( const EventType& eventIn ); | ||
263 | virtual void onNavigateComplete( const EventType& eventIn ); | ||
264 | virtual void onUpdateProgress( const EventType& eventIn ); | ||
265 | virtual void onStatusTextChange( const EventType& eventIn ); | ||
266 | virtual void onLocationChange( const EventType& eventIn ); | ||
267 | virtual void onClickLinkHref( const EventType& eventIn ); | ||
268 | virtual void onClickLinkNoFollow( const EventType& eventIn ); | ||
269 | virtual void onMediaContentsChange( const EventType& event_in ); | ||
270 | |||
271 | protected: | ||
272 | void convertInputCoords(S32& x, S32& y); | ||
273 | |||
274 | private: | ||
275 | static bool onClickLinkExternalTarget( const LLSD&, const LLSD& ); | ||
276 | |||
277 | LLWebBrowserCtrlEventEmitter< LLWebBrowserCtrlObserver > mEventEmitter; | ||
278 | const S32 mTextureDepthBytes; | ||
279 | int mEmbeddedBrowserWindowId; | ||
280 | LLWebBrowserTexture* mWebBrowserImage; | ||
281 | LLViewBorder* mBorder; | ||
282 | bool mFrequentUpdates; | ||
283 | bool mForceUpdate; | ||
284 | bool mOpenLinksInExternalBrowser; | ||
285 | bool mOpenLinksInInternalBrowser; | ||
286 | bool mTrusted; | ||
287 | std::string mHomePageUrl; | ||
288 | std::string mExternalUrl; | ||
289 | std::string mCurrentNavUrl; | ||
290 | bool mIgnoreUIScale; | ||
291 | bool mAlwaysRefresh; | ||
292 | LLMediaBase* mMediaSource; | ||
293 | bool mTakeFocusOnClick; | ||
294 | }; | ||
295 | |||
296 | //////////////////////////////////////////////////////////////////////////////// | ||
297 | // | ||
298 | class LLWebBrowserTexture : public LLDynamicTexture | ||
299 | { | ||
300 | public: | ||
301 | LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, LLMediaBase *media_source ); | ||
302 | virtual ~LLWebBrowserTexture(); | ||
303 | |||
304 | virtual BOOL needsRender(); | ||
305 | virtual void preRender( BOOL clear_depth = TRUE ) {}; | ||
306 | virtual void postRender( BOOL success ) {}; | ||
307 | virtual BOOL render(); | ||
308 | |||
309 | S32 getBrowserWidth(); | ||
310 | S32 getBrowserHeight(); | ||
311 | void setNeedsUpdate(); | ||
312 | |||
313 | void resize( S32 new_width, S32 new_height ); | ||
314 | |||
315 | protected: | ||
316 | S32 mBrowserWidth; | ||
317 | S32 mBrowserHeight; | ||
318 | S32 mLastBrowserDepth; | ||
319 | bool mNeedsUpdate; | ||
320 | LLFrameTimer mElapsedTime; | ||
321 | LLWebBrowserCtrl* mWebBrowserCtrl; | ||
322 | LLMediaBase *mMediaSource; | ||
323 | }; | ||
324 | |||
325 | #endif // LL_LLWEBBROWSERCTRL_H | ||