1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Dean Tessman <dean_tessman@hotmail.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "mozilla/Util.h"
40 :
41 : #include "mozilla/layers/CompositorChild.h"
42 : #include "mozilla/layers/CompositorParent.h"
43 : #include "nsBaseWidget.h"
44 : #include "nsDeviceContext.h"
45 : #include "nsCOMPtr.h"
46 : #include "nsGfxCIID.h"
47 : #include "nsWidgetsCID.h"
48 : #include "nsServiceManagerUtils.h"
49 : #include "nsIScreenManager.h"
50 : #include "nsAppDirectoryServiceDefs.h"
51 : #include "nsISimpleEnumerator.h"
52 : #include "nsIContent.h"
53 : #include "nsIServiceManager.h"
54 : #include "mozilla/Preferences.h"
55 : #include "BasicLayers.h"
56 : #include "LayerManagerOGL.h"
57 : #include "nsIXULRuntime.h"
58 : #include "nsIGfxInfo.h"
59 : #include "npapi.h"
60 : #include "base/thread.h"
61 :
62 : #ifdef DEBUG
63 : #include "nsIObserver.h"
64 :
65 : static void debug_RegisterPrefCallbacks();
66 :
67 : static bool debug_InSecureKeyboardInputMode = false;
68 : #endif
69 :
70 : #ifdef NOISY_WIDGET_LEAKS
71 : static PRInt32 gNumWidgets;
72 : #endif
73 :
74 : using namespace mozilla::layers;
75 : using namespace mozilla;
76 : using base::Thread;
77 : using mozilla::ipc::AsyncChannel;
78 :
79 : nsIContent* nsBaseWidget::mLastRollup = nsnull;
80 :
81 : // nsBaseWidget
82 0 : NS_IMPL_ISUPPORTS1(nsBaseWidget, nsIWidget)
83 :
84 :
85 0 : nsAutoRollup::nsAutoRollup()
86 : {
87 : // remember if mLastRollup was null, and only clear it upon destruction
88 : // if so. This prevents recursive usage of nsAutoRollup from clearing
89 : // mLastRollup when it shouldn't.
90 0 : wasClear = !nsBaseWidget::mLastRollup;
91 0 : }
92 :
93 0 : nsAutoRollup::~nsAutoRollup()
94 : {
95 0 : if (nsBaseWidget::mLastRollup && wasClear) {
96 0 : NS_RELEASE(nsBaseWidget::mLastRollup);
97 : }
98 0 : }
99 :
100 : //-------------------------------------------------------------------------
101 : //
102 : // nsBaseWidget constructor
103 : //
104 : //-------------------------------------------------------------------------
105 :
106 0 : nsBaseWidget::nsBaseWidget()
107 : : mClientData(nsnull)
108 : , mViewWrapperPtr(nsnull)
109 : , mEventCallback(nsnull)
110 : , mViewCallback(nsnull)
111 : , mContext(nsnull)
112 : , mCompositorThread(nsnull)
113 : , mCursor(eCursor_standard)
114 : , mWindowType(eWindowType_child)
115 : , mBorderStyle(eBorderStyle_none)
116 : , mOnDestroyCalled(false)
117 : , mUseAcceleratedRendering(false)
118 : , mForceLayersAcceleration(false)
119 : , mTemporarilyUseBasicLayerManager(false)
120 : , mBounds(0,0,0,0)
121 : , mOriginalBounds(nsnull)
122 : , mClipRectCount(0)
123 : , mZIndex(0)
124 : , mSizeMode(nsSizeMode_Normal)
125 0 : , mPopupLevel(ePopupLevelTop)
126 : {
127 : #ifdef NOISY_WIDGET_LEAKS
128 : gNumWidgets++;
129 : printf("WIDGETS+ = %d\n", gNumWidgets);
130 : #endif
131 :
132 : #ifdef DEBUG
133 0 : debug_RegisterPrefCallbacks();
134 : #endif
135 0 : }
136 :
137 :
138 : //-------------------------------------------------------------------------
139 : //
140 : // nsBaseWidget destructor
141 : //
142 : //-------------------------------------------------------------------------
143 0 : nsBaseWidget::~nsBaseWidget()
144 : {
145 0 : if (mLayerManager &&
146 0 : mLayerManager->GetBackendType() == LayerManager::LAYERS_BASIC) {
147 0 : static_cast<BasicLayerManager*>(mLayerManager.get())->ClearRetainerWidget();
148 : }
149 :
150 0 : if (mLayerManager) {
151 0 : mLayerManager->Destroy();
152 0 : mLayerManager = nsnull;
153 : }
154 :
155 0 : if (mCompositorChild) {
156 0 : mCompositorChild->Destroy();
157 0 : delete mCompositorThread;
158 : }
159 :
160 : #ifdef NOISY_WIDGET_LEAKS
161 : gNumWidgets--;
162 : printf("WIDGETS- = %d\n", gNumWidgets);
163 : #endif
164 :
165 0 : NS_IF_RELEASE(mContext);
166 0 : delete mOriginalBounds;
167 0 : }
168 :
169 :
170 : //-------------------------------------------------------------------------
171 : //
172 : // Basic create.
173 : //
174 : //-------------------------------------------------------------------------
175 0 : void nsBaseWidget::BaseCreate(nsIWidget *aParent,
176 : const nsIntRect &aRect,
177 : EVENT_CALLBACK aHandleEventFunction,
178 : nsDeviceContext *aContext,
179 : nsWidgetInitData *aInitData)
180 : {
181 : // save the event callback function
182 0 : mEventCallback = aHandleEventFunction;
183 :
184 : // keep a reference to the device context
185 0 : if (aContext) {
186 0 : mContext = aContext;
187 0 : NS_ADDREF(mContext);
188 : }
189 : else {
190 0 : mContext = new nsDeviceContext();
191 0 : NS_ADDREF(mContext);
192 0 : mContext->Init(nsnull);
193 : }
194 :
195 0 : if (nsnull != aInitData) {
196 0 : mWindowType = aInitData->mWindowType;
197 0 : mBorderStyle = aInitData->mBorderStyle;
198 0 : mPopupLevel = aInitData->mPopupLevel;
199 : }
200 :
201 0 : if (aParent) {
202 0 : aParent->AddChild(this);
203 : }
204 0 : }
205 :
206 0 : NS_IMETHODIMP nsBaseWidget::CaptureMouse(bool aCapture)
207 : {
208 0 : return NS_OK;
209 : }
210 :
211 : //-------------------------------------------------------------------------
212 : //
213 : // Accessor functions to get/set the client data
214 : //
215 : //-------------------------------------------------------------------------
216 :
217 0 : NS_IMETHODIMP nsBaseWidget::GetClientData(void*& aClientData)
218 : {
219 0 : aClientData = mClientData;
220 0 : return NS_OK;
221 : }
222 :
223 0 : NS_IMETHODIMP nsBaseWidget::SetClientData(void* aClientData)
224 : {
225 0 : mClientData = aClientData;
226 0 : return NS_OK;
227 : }
228 :
229 : already_AddRefed<nsIWidget>
230 0 : nsBaseWidget::CreateChild(const nsIntRect &aRect,
231 : EVENT_CALLBACK aHandleEventFunction,
232 : nsDeviceContext *aContext,
233 : nsWidgetInitData *aInitData,
234 : bool aForceUseIWidgetParent)
235 : {
236 0 : nsIWidget* parent = this;
237 0 : nsNativeWidget nativeParent = nsnull;
238 :
239 0 : if (!aForceUseIWidgetParent) {
240 : // Use only either parent or nativeParent, not both, to match
241 : // existing code. Eventually Create() should be divested of its
242 : // nativeWidget parameter.
243 0 : nativeParent = parent ? parent->GetNativeData(NS_NATIVE_WIDGET) : nsnull;
244 0 : parent = nativeParent ? nsnull : parent;
245 0 : NS_ABORT_IF_FALSE(!parent || !nativeParent, "messed up logic");
246 : }
247 :
248 0 : nsCOMPtr<nsIWidget> widget;
249 0 : if (aInitData && aInitData->mWindowType == eWindowType_popup) {
250 0 : widget = AllocateChildPopupWidget();
251 : } else {
252 : static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID);
253 0 : widget = do_CreateInstance(kCChildCID);
254 : }
255 :
256 0 : if (widget &&
257 0 : NS_SUCCEEDED(widget->Create(parent, nativeParent, aRect,
258 : aHandleEventFunction,
259 : aContext, aInitData))) {
260 0 : return widget.forget();
261 : }
262 :
263 0 : return nsnull;
264 : }
265 :
266 : NS_IMETHODIMP
267 0 : nsBaseWidget::SetEventCallback(EVENT_CALLBACK aEventFunction,
268 : nsDeviceContext *aContext)
269 : {
270 0 : NS_ASSERTION(aEventFunction, "Must have valid event callback!");
271 :
272 0 : mEventCallback = aEventFunction;
273 :
274 0 : if (aContext) {
275 0 : NS_IF_RELEASE(mContext);
276 0 : mContext = aContext;
277 0 : NS_ADDREF(mContext);
278 : }
279 :
280 0 : return NS_OK;
281 : }
282 :
283 : // Attach a view to our widget which we'll send events to.
284 : NS_IMETHODIMP
285 0 : nsBaseWidget::AttachViewToTopLevel(EVENT_CALLBACK aViewEventFunction,
286 : nsDeviceContext *aContext)
287 : {
288 0 : NS_ASSERTION((mWindowType == eWindowType_toplevel ||
289 : mWindowType == eWindowType_dialog ||
290 : mWindowType == eWindowType_invisible ||
291 : mWindowType == eWindowType_child),
292 : "Can't attach to window of that type");
293 :
294 0 : mViewCallback = aViewEventFunction;
295 :
296 0 : if (aContext) {
297 0 : if (mContext) {
298 0 : NS_IF_RELEASE(mContext);
299 : }
300 0 : mContext = aContext;
301 0 : NS_ADDREF(mContext);
302 : }
303 :
304 0 : return NS_OK;
305 : }
306 :
307 0 : ViewWrapper* nsBaseWidget::GetAttachedViewPtr()
308 : {
309 0 : return mViewWrapperPtr;
310 : }
311 :
312 0 : NS_IMETHODIMP nsBaseWidget::SetAttachedViewPtr(ViewWrapper* aViewWrapper)
313 : {
314 0 : mViewWrapperPtr = aViewWrapper;
315 0 : return NS_OK;
316 : }
317 :
318 : //-------------------------------------------------------------------------
319 : //
320 : // Close this nsBaseWidget
321 : //
322 : //-------------------------------------------------------------------------
323 0 : NS_METHOD nsBaseWidget::Destroy()
324 : {
325 : // Just in case our parent is the only ref to us
326 0 : nsCOMPtr<nsIWidget> kungFuDeathGrip(this);
327 : // disconnect from the parent
328 0 : nsIWidget *parent = GetParent();
329 0 : if (parent) {
330 0 : parent->RemoveChild(this);
331 : }
332 :
333 0 : return NS_OK;
334 : }
335 :
336 :
337 : //-------------------------------------------------------------------------
338 : //
339 : // Set this nsBaseWidget's parent
340 : //
341 : //-------------------------------------------------------------------------
342 0 : NS_IMETHODIMP nsBaseWidget::SetParent(nsIWidget* aNewParent)
343 : {
344 0 : return NS_ERROR_NOT_IMPLEMENTED;
345 : }
346 :
347 :
348 : //-------------------------------------------------------------------------
349 : //
350 : // Get this nsBaseWidget parent
351 : //
352 : //-------------------------------------------------------------------------
353 0 : nsIWidget* nsBaseWidget::GetParent(void)
354 : {
355 0 : return nsnull;
356 : }
357 :
358 : //-------------------------------------------------------------------------
359 : //
360 : // Get this nsBaseWidget top level widget
361 : //
362 : //-------------------------------------------------------------------------
363 0 : nsIWidget* nsBaseWidget::GetTopLevelWidget()
364 : {
365 0 : nsIWidget *topLevelWidget = nsnull, *widget = this;
366 0 : while (widget) {
367 0 : topLevelWidget = widget;
368 0 : widget = widget->GetParent();
369 : }
370 0 : return topLevelWidget;
371 : }
372 :
373 : //-------------------------------------------------------------------------
374 : //
375 : // Get this nsBaseWidget's top (non-sheet) parent (if it's a sheet)
376 : //
377 : //-------------------------------------------------------------------------
378 0 : nsIWidget* nsBaseWidget::GetSheetWindowParent(void)
379 : {
380 0 : return nsnull;
381 : }
382 :
383 0 : float nsBaseWidget::GetDPI()
384 : {
385 0 : return 96.0f;
386 : }
387 :
388 0 : double nsBaseWidget::GetDefaultScale()
389 : {
390 0 : return 1.0;
391 : }
392 :
393 : //-------------------------------------------------------------------------
394 : //
395 : // Add a child to the list of children
396 : //
397 : //-------------------------------------------------------------------------
398 0 : void nsBaseWidget::AddChild(nsIWidget* aChild)
399 : {
400 0 : NS_PRECONDITION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(),
401 : "aChild not properly removed from its old child list");
402 :
403 0 : if (!mFirstChild) {
404 0 : mFirstChild = mLastChild = aChild;
405 : } else {
406 : // append to the list
407 0 : NS_ASSERTION(mLastChild, "Bogus state");
408 0 : NS_ASSERTION(!mLastChild->GetNextSibling(), "Bogus state");
409 0 : mLastChild->SetNextSibling(aChild);
410 0 : aChild->SetPrevSibling(mLastChild);
411 0 : mLastChild = aChild;
412 : }
413 0 : }
414 :
415 :
416 : //-------------------------------------------------------------------------
417 : //
418 : // Remove a child from the list of children
419 : //
420 : //-------------------------------------------------------------------------
421 0 : void nsBaseWidget::RemoveChild(nsIWidget* aChild)
422 : {
423 0 : NS_ASSERTION(aChild->GetParent() == this, "Not one of our kids!");
424 :
425 0 : if (mLastChild == aChild) {
426 0 : mLastChild = mLastChild->GetPrevSibling();
427 : }
428 0 : if (mFirstChild == aChild) {
429 0 : mFirstChild = mFirstChild->GetNextSibling();
430 : }
431 :
432 : // Now remove from the list. Make sure that we pass ownership of the tail
433 : // of the list correctly before we have aChild let go of it.
434 0 : nsIWidget* prev = aChild->GetPrevSibling();
435 0 : nsIWidget* next = aChild->GetNextSibling();
436 0 : if (prev) {
437 0 : prev->SetNextSibling(next);
438 : }
439 0 : if (next) {
440 0 : next->SetPrevSibling(prev);
441 : }
442 :
443 0 : aChild->SetNextSibling(nsnull);
444 0 : aChild->SetPrevSibling(nsnull);
445 0 : }
446 :
447 :
448 : //-------------------------------------------------------------------------
449 : //
450 : // Sets widget's position within its parent's child list.
451 : //
452 : //-------------------------------------------------------------------------
453 0 : NS_IMETHODIMP nsBaseWidget::SetZIndex(PRInt32 aZIndex)
454 : {
455 : // Hold a ref to ourselves just in case, since we're going to remove
456 : // from our parent.
457 0 : nsCOMPtr<nsIWidget> kungFuDeathGrip(this);
458 :
459 0 : mZIndex = aZIndex;
460 :
461 : // reorder this child in its parent's list.
462 0 : nsBaseWidget* parent = static_cast<nsBaseWidget*>(GetParent());
463 0 : if (parent) {
464 0 : parent->RemoveChild(this);
465 : // Scope sib outside the for loop so we can check it afterward
466 0 : nsIWidget* sib = parent->GetFirstChild();
467 0 : for ( ; sib; sib = sib->GetNextSibling()) {
468 : PRInt32 childZIndex;
469 0 : if (NS_SUCCEEDED(sib->GetZIndex(&childZIndex))) {
470 0 : if (aZIndex < childZIndex) {
471 : // Insert ourselves before sib
472 0 : nsIWidget* prev = sib->GetPrevSibling();
473 0 : mNextSibling = sib;
474 0 : mPrevSibling = prev;
475 0 : sib->SetPrevSibling(this);
476 0 : if (prev) {
477 0 : prev->SetNextSibling(this);
478 : } else {
479 0 : NS_ASSERTION(sib == parent->mFirstChild, "Broken child list");
480 : // We've taken ownership of sib, so it's safe to have parent let
481 : // go of it
482 0 : parent->mFirstChild = this;
483 : }
484 0 : PlaceBehind(eZPlacementBelow, sib, false);
485 0 : break;
486 : }
487 : }
488 : }
489 : // were we added to the list?
490 0 : if (!sib) {
491 0 : parent->AddChild(this);
492 : }
493 : }
494 0 : return NS_OK;
495 : }
496 :
497 : //-------------------------------------------------------------------------
498 : //
499 : // Gets widget's position within its parent's child list.
500 : //
501 : //-------------------------------------------------------------------------
502 0 : NS_IMETHODIMP nsBaseWidget::GetZIndex(PRInt32* aZIndex)
503 : {
504 0 : *aZIndex = mZIndex;
505 0 : return NS_OK;
506 : }
507 :
508 : //-------------------------------------------------------------------------
509 : //
510 : // Places widget behind the given widget (platforms must override)
511 : //
512 : //-------------------------------------------------------------------------
513 0 : NS_IMETHODIMP nsBaseWidget::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
514 : nsIWidget *aWidget, bool aActivate)
515 : {
516 0 : return NS_OK;
517 : }
518 :
519 : //-------------------------------------------------------------------------
520 : //
521 : // Maximize, minimize or restore the window. The BaseWidget implementation
522 : // merely stores the state.
523 : //
524 : //-------------------------------------------------------------------------
525 0 : NS_IMETHODIMP nsBaseWidget::SetSizeMode(PRInt32 aMode)
526 : {
527 0 : if (aMode == nsSizeMode_Normal ||
528 : aMode == nsSizeMode_Minimized ||
529 : aMode == nsSizeMode_Maximized ||
530 : aMode == nsSizeMode_Fullscreen) {
531 :
532 0 : mSizeMode = (nsSizeMode) aMode;
533 0 : return NS_OK;
534 : }
535 0 : return NS_ERROR_ILLEGAL_VALUE;
536 : }
537 :
538 : //-------------------------------------------------------------------------
539 : //
540 : // Get the size mode (minimized, maximized, that sort of thing...)
541 : //
542 : //-------------------------------------------------------------------------
543 0 : NS_IMETHODIMP nsBaseWidget::GetSizeMode(PRInt32* aMode)
544 : {
545 0 : *aMode = mSizeMode;
546 0 : return NS_OK;
547 : }
548 :
549 : //-------------------------------------------------------------------------
550 : //
551 : // Get the foreground color
552 : //
553 : //-------------------------------------------------------------------------
554 0 : nscolor nsBaseWidget::GetForegroundColor(void)
555 : {
556 0 : return mForeground;
557 : }
558 :
559 :
560 : //-------------------------------------------------------------------------
561 : //
562 : // Set the foreground color
563 : //
564 : //-------------------------------------------------------------------------
565 0 : NS_METHOD nsBaseWidget::SetForegroundColor(const nscolor &aColor)
566 : {
567 0 : mForeground = aColor;
568 0 : return NS_OK;
569 : }
570 :
571 :
572 : //-------------------------------------------------------------------------
573 : //
574 : // Get the background color
575 : //
576 : //-------------------------------------------------------------------------
577 0 : nscolor nsBaseWidget::GetBackgroundColor(void)
578 : {
579 0 : return mBackground;
580 : }
581 :
582 : //-------------------------------------------------------------------------
583 : //
584 : // Set the background color
585 : //
586 : //-------------------------------------------------------------------------
587 0 : NS_METHOD nsBaseWidget::SetBackgroundColor(const nscolor &aColor)
588 : {
589 0 : mBackground = aColor;
590 0 : return NS_OK;
591 : }
592 :
593 : //-------------------------------------------------------------------------
594 : //
595 : // Get this component cursor
596 : //
597 : //-------------------------------------------------------------------------
598 0 : nsCursor nsBaseWidget::GetCursor()
599 : {
600 0 : return mCursor;
601 : }
602 :
603 0 : NS_METHOD nsBaseWidget::SetCursor(nsCursor aCursor)
604 : {
605 0 : mCursor = aCursor;
606 0 : return NS_OK;
607 : }
608 :
609 0 : NS_IMETHODIMP nsBaseWidget::SetCursor(imgIContainer* aCursor,
610 : PRUint32 aHotspotX, PRUint32 aHotspotY)
611 : {
612 0 : return NS_ERROR_NOT_IMPLEMENTED;
613 : }
614 :
615 : //-------------------------------------------------------------------------
616 : //
617 : // Get the window type for this widget
618 : //
619 : //-------------------------------------------------------------------------
620 0 : NS_IMETHODIMP nsBaseWidget::GetWindowType(nsWindowType& aWindowType)
621 : {
622 0 : aWindowType = mWindowType;
623 0 : return NS_OK;
624 : }
625 :
626 : //-------------------------------------------------------------------------
627 : //
628 : // Window transparency methods
629 : //
630 : //-------------------------------------------------------------------------
631 :
632 0 : void nsBaseWidget::SetTransparencyMode(nsTransparencyMode aMode) {
633 0 : }
634 :
635 0 : nsTransparencyMode nsBaseWidget::GetTransparencyMode() {
636 0 : return eTransparencyOpaque;
637 : }
638 :
639 : bool
640 0 : nsBaseWidget::StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects)
641 : {
642 0 : if (mClipRects && mClipRectCount == aRects.Length() &&
643 0 : memcmp(mClipRects, aRects.Elements(), sizeof(nsIntRect)*mClipRectCount) == 0)
644 0 : return false;
645 :
646 0 : mClipRectCount = aRects.Length();
647 0 : mClipRects = new nsIntRect[mClipRectCount];
648 0 : if (mClipRects) {
649 0 : memcpy(mClipRects, aRects.Elements(), sizeof(nsIntRect)*mClipRectCount);
650 : }
651 0 : return true;
652 : }
653 :
654 : void
655 0 : nsBaseWidget::GetWindowClipRegion(nsTArray<nsIntRect>* aRects)
656 : {
657 0 : if (mClipRects) {
658 0 : aRects->AppendElements(mClipRects.get(), mClipRectCount);
659 : } else {
660 0 : aRects->AppendElement(nsIntRect(0, 0, mBounds.width, mBounds.height));
661 : }
662 0 : }
663 :
664 : //-------------------------------------------------------------------------
665 : //
666 : // Set window shadow style
667 : //
668 : //-------------------------------------------------------------------------
669 :
670 0 : NS_IMETHODIMP nsBaseWidget::SetWindowShadowStyle(PRInt32 aMode)
671 : {
672 0 : return NS_ERROR_NOT_IMPLEMENTED;
673 : }
674 :
675 : //-------------------------------------------------------------------------
676 : //
677 : // Hide window borders/decorations for this widget
678 : //
679 : //-------------------------------------------------------------------------
680 0 : NS_IMETHODIMP nsBaseWidget::HideWindowChrome(bool aShouldHide)
681 : {
682 0 : return NS_ERROR_NOT_IMPLEMENTED;
683 : }
684 :
685 : //-------------------------------------------------------------------------
686 : //
687 : // Put the window into full-screen mode
688 : //
689 : //-------------------------------------------------------------------------
690 0 : NS_IMETHODIMP nsBaseWidget::MakeFullScreen(bool aFullScreen)
691 : {
692 0 : HideWindowChrome(aFullScreen);
693 :
694 0 : if (aFullScreen) {
695 0 : if (!mOriginalBounds)
696 0 : mOriginalBounds = new nsIntRect();
697 0 : GetScreenBounds(*mOriginalBounds);
698 :
699 : // Move to top-left corner of screen and size to the screen dimensions
700 0 : nsCOMPtr<nsIScreenManager> screenManager;
701 0 : screenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
702 0 : NS_ASSERTION(screenManager, "Unable to grab screenManager.");
703 0 : if (screenManager) {
704 0 : nsCOMPtr<nsIScreen> screen;
705 0 : screenManager->ScreenForRect(mOriginalBounds->x, mOriginalBounds->y,
706 : mOriginalBounds->width, mOriginalBounds->height,
707 0 : getter_AddRefs(screen));
708 0 : if (screen) {
709 : PRInt32 left, top, width, height;
710 0 : if (NS_SUCCEEDED(screen->GetRect(&left, &top, &width, &height))) {
711 0 : Resize(left, top, width, height, true);
712 : }
713 : }
714 : }
715 :
716 0 : } else if (mOriginalBounds) {
717 : Resize(mOriginalBounds->x, mOriginalBounds->y, mOriginalBounds->width,
718 0 : mOriginalBounds->height, true);
719 : }
720 :
721 0 : return NS_OK;
722 : }
723 :
724 0 : nsBaseWidget::AutoLayerManagerSetup::AutoLayerManagerSetup(
725 : nsBaseWidget* aWidget, gfxContext* aTarget,
726 : BasicLayerManager::BufferMode aDoubleBuffering)
727 0 : : mWidget(aWidget)
728 : {
729 : BasicLayerManager* manager =
730 0 : static_cast<BasicLayerManager*>(mWidget->GetLayerManager());
731 0 : if (manager) {
732 0 : NS_ASSERTION(manager->GetBackendType() == LayerManager::LAYERS_BASIC,
733 : "AutoLayerManagerSetup instantiated for non-basic layer backend!");
734 0 : manager->SetDefaultTarget(aTarget, aDoubleBuffering);
735 : }
736 0 : }
737 :
738 0 : nsBaseWidget::AutoLayerManagerSetup::~AutoLayerManagerSetup()
739 : {
740 : BasicLayerManager* manager =
741 0 : static_cast<BasicLayerManager*>(mWidget->GetLayerManager());
742 0 : if (manager) {
743 0 : NS_ASSERTION(manager->GetBackendType() == LayerManager::LAYERS_BASIC,
744 : "AutoLayerManagerSetup instantiated for non-basic layer backend!");
745 0 : manager->SetDefaultTarget(nsnull, BasicLayerManager::BUFFER_NONE);
746 : }
747 0 : }
748 :
749 0 : nsBaseWidget::AutoUseBasicLayerManager::AutoUseBasicLayerManager(nsBaseWidget* aWidget)
750 0 : : mWidget(aWidget)
751 : {
752 0 : mWidget->mTemporarilyUseBasicLayerManager = true;
753 0 : }
754 :
755 0 : nsBaseWidget::AutoUseBasicLayerManager::~AutoUseBasicLayerManager()
756 : {
757 0 : mWidget->mTemporarilyUseBasicLayerManager = false;
758 0 : }
759 :
760 : bool
761 0 : nsBaseWidget::GetShouldAccelerate()
762 : {
763 : #if defined(XP_WIN) || defined(ANDROID) || (MOZ_PLATFORM_MAEMO > 5)
764 : bool accelerateByDefault = true;
765 : #elif defined(XP_MACOSX)
766 : /* quickdraw plugins don't work with OpenGL so we need to avoid OpenGL when we want to support
767 : * them. e.g. 10.5 */
768 : # if defined(NP_NO_QUICKDRAW)
769 : bool accelerateByDefault = true;
770 :
771 : // 10.6.2 and lower have a bug involving textures and pixel buffer objects
772 : // that caused bug 629016, so we don't allow OpenGL-accelerated layers on
773 : // those versions of the OS.
774 : // This will still let full-screen video be accelerated on OpenGL, because
775 : // that XUL widget opts in to acceleration, but that's probably OK.
776 : SInt32 major, minor, bugfix;
777 : OSErr err1 = ::Gestalt(gestaltSystemVersionMajor, &major);
778 : OSErr err2 = ::Gestalt(gestaltSystemVersionMinor, &minor);
779 : OSErr err3 = ::Gestalt(gestaltSystemVersionBugFix, &bugfix);
780 : if (err1 == noErr && err2 == noErr && err3 == noErr) {
781 : if (major == 10 && minor == 6) {
782 : if (bugfix <= 2) {
783 : accelerateByDefault = false;
784 : }
785 : }
786 : }
787 :
788 : # else
789 : bool accelerateByDefault = false;
790 : # endif
791 :
792 : #else
793 0 : bool accelerateByDefault = false;
794 : #endif
795 :
796 : // we should use AddBoolPrefVarCache
797 : bool disableAcceleration =
798 0 : Preferences::GetBool("layers.acceleration.disabled", false);
799 : mForceLayersAcceleration =
800 0 : Preferences::GetBool("layers.acceleration.force-enabled", false);
801 :
802 0 : const char *acceleratedEnv = PR_GetEnv("MOZ_ACCELERATED");
803 : accelerateByDefault = accelerateByDefault ||
804 0 : (acceleratedEnv && (*acceleratedEnv != '0'));
805 :
806 0 : nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1");
807 0 : bool safeMode = false;
808 0 : if (xr)
809 0 : xr->GetInSafeMode(&safeMode);
810 :
811 0 : bool whitelisted = false;
812 :
813 0 : nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
814 0 : if (gfxInfo) {
815 : // bug 655578: on X11 at least, we must always call GetData (even if we don't need that information)
816 : // as that's what causes GfxInfo initialization which kills the zombie 'glxtest' process.
817 : // initially we relied on the fact that GetFeatureStatus calls GetData for us, but bug 681026 showed
818 : // that assumption to be unsafe.
819 0 : gfxInfo->GetData();
820 :
821 : PRInt32 status;
822 0 : if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_OPENGL_LAYERS, &status))) {
823 0 : if (status == nsIGfxInfo::FEATURE_NO_INFO) {
824 0 : whitelisted = true;
825 : }
826 : }
827 : }
828 :
829 0 : if (disableAcceleration || safeMode)
830 0 : return false;
831 :
832 0 : if (mForceLayersAcceleration)
833 0 : return true;
834 :
835 0 : if (!whitelisted) {
836 0 : NS_WARNING("OpenGL-accelerated layers are not supported on this system.");
837 0 : return false;
838 : }
839 :
840 0 : if (accelerateByDefault)
841 0 : return true;
842 :
843 : /* use the window acceleration flag */
844 0 : return mUseAcceleratedRendering;
845 : }
846 :
847 0 : void nsBaseWidget::CreateCompositor()
848 : {
849 0 : mCompositorParent = new CompositorParent(this);
850 0 : mCompositorThread = new Thread("CompositorThread");
851 0 : if (mCompositorThread->Start()) {
852 0 : LayerManager* lm = CreateBasicLayerManager();
853 0 : MessageLoop *childMessageLoop = mCompositorThread->message_loop();
854 0 : mCompositorChild = new CompositorChild(lm);
855 0 : AsyncChannel *parentChannel = mCompositorParent->GetIPCChannel();
856 0 : AsyncChannel::Side childSide = mozilla::ipc::AsyncChannel::Child;
857 0 : mCompositorChild->Open(parentChannel, childMessageLoop, childSide);
858 : PLayersChild* shadowManager =
859 0 : mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_OPENGL);
860 :
861 0 : if (shadowManager) {
862 0 : ShadowLayerForwarder* lf = lm->AsShadowForwarder();
863 0 : if (!lf) {
864 0 : delete lm;
865 0 : mCompositorChild = nsnull;
866 0 : return;
867 : }
868 0 : lf->SetShadowManager(shadowManager);
869 0 : lf->SetParentBackendType(LayerManager::LAYERS_OPENGL);
870 :
871 0 : mLayerManager = lm;
872 : } else {
873 0 : NS_WARNING("fail to construct LayersChild");
874 0 : delete lm;
875 0 : mCompositorChild = nsnull;
876 : }
877 : }
878 : }
879 :
880 0 : LayerManager* nsBaseWidget::GetLayerManager(PLayersChild* aShadowManager,
881 : LayersBackend aBackendHint,
882 : LayerManagerPersistence aPersistence,
883 : bool* aAllowRetaining)
884 : {
885 0 : if (!mLayerManager) {
886 :
887 0 : mUseAcceleratedRendering = GetShouldAccelerate();
888 :
889 0 : if (mUseAcceleratedRendering) {
890 :
891 : // Try to use an async compositor first, if possible
892 : bool useCompositor =
893 0 : Preferences::GetBool("layers.offmainthreadcomposition.enabled", false);
894 0 : if (useCompositor) {
895 : // e10s uses the parameter to pass in the shadow manager from the TabChild
896 : // so we don't expect to see it there since this doesn't support e10s.
897 0 : NS_ASSERTION(aShadowManager == nsnull, "Async Compositor not supported with e10s");
898 0 : CreateCompositor();
899 : }
900 :
901 0 : if (!mLayerManager) {
902 0 : nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(this);
903 : /**
904 : * XXX - On several OSes initialization is expected to fail for now.
905 : * If we'd get a non-basic layer manager they'd crash. This is ok though
906 : * since on those platforms it will fail. Anyone implementing new
907 : * platforms on LayerManagerOGL should ensure their widget is able to
908 : * deal with it though!
909 : */
910 :
911 0 : if (layerManager->Initialize(mForceLayersAcceleration)) {
912 0 : mLayerManager = layerManager;
913 : }
914 : }
915 : }
916 0 : if (!mLayerManager) {
917 0 : mBasicLayerManager = mLayerManager = CreateBasicLayerManager();
918 : }
919 : }
920 0 : if (mTemporarilyUseBasicLayerManager && !mBasicLayerManager) {
921 0 : mBasicLayerManager = CreateBasicLayerManager();
922 : }
923 : LayerManager* usedLayerManager = mTemporarilyUseBasicLayerManager ?
924 0 : mBasicLayerManager : mLayerManager;
925 0 : if (aAllowRetaining) {
926 0 : *aAllowRetaining = (usedLayerManager == mLayerManager);
927 : }
928 0 : return usedLayerManager;
929 : }
930 :
931 0 : BasicLayerManager* nsBaseWidget::CreateBasicLayerManager()
932 : {
933 0 : return new BasicShadowLayerManager(this);
934 : }
935 :
936 : //-------------------------------------------------------------------------
937 : //
938 : // Return the used device context
939 : //
940 : //-------------------------------------------------------------------------
941 0 : nsDeviceContext* nsBaseWidget::GetDeviceContext()
942 : {
943 0 : return mContext;
944 : }
945 :
946 : //-------------------------------------------------------------------------
947 : //
948 : // Get the thebes surface
949 : //
950 : //-------------------------------------------------------------------------
951 0 : gfxASurface *nsBaseWidget::GetThebesSurface()
952 : {
953 : // in theory we should get our parent's surface,
954 : // clone it, and set a device offset before returning
955 0 : return nsnull;
956 : }
957 :
958 :
959 : //-------------------------------------------------------------------------
960 : //
961 : // Destroy the window
962 : //
963 : //-------------------------------------------------------------------------
964 0 : void nsBaseWidget::OnDestroy()
965 : {
966 : // release references to device context and app shell
967 0 : NS_IF_RELEASE(mContext);
968 0 : }
969 :
970 0 : NS_METHOD nsBaseWidget::SetWindowClass(const nsAString& xulWinType)
971 : {
972 0 : return NS_ERROR_NOT_IMPLEMENTED;
973 : }
974 :
975 0 : NS_METHOD nsBaseWidget::MoveClient(PRInt32 aX, PRInt32 aY)
976 : {
977 0 : nsIntPoint clientOffset(GetClientOffset());
978 0 : aX -= clientOffset.x;
979 0 : aY -= clientOffset.y;
980 0 : return Move(aX, aY);
981 : }
982 :
983 0 : NS_METHOD nsBaseWidget::ResizeClient(PRInt32 aWidth,
984 : PRInt32 aHeight,
985 : bool aRepaint)
986 : {
987 0 : NS_ASSERTION((aWidth >=0) , "Negative width passed to ResizeClient");
988 0 : NS_ASSERTION((aHeight >=0), "Negative height passed to ResizeClient");
989 :
990 0 : nsIntRect clientBounds;
991 0 : GetClientBounds(clientBounds);
992 0 : aWidth = mBounds.width + (aWidth - clientBounds.width);
993 0 : aHeight = mBounds.height + (aHeight - clientBounds.height);
994 :
995 0 : return Resize(aWidth, aHeight, aRepaint);
996 : }
997 :
998 0 : NS_METHOD nsBaseWidget::ResizeClient(PRInt32 aX,
999 : PRInt32 aY,
1000 : PRInt32 aWidth,
1001 : PRInt32 aHeight,
1002 : bool aRepaint)
1003 : {
1004 0 : NS_ASSERTION((aWidth >=0) , "Negative width passed to ResizeClient");
1005 0 : NS_ASSERTION((aHeight >=0), "Negative height passed to ResizeClient");
1006 :
1007 0 : nsIntRect clientBounds;
1008 0 : GetClientBounds(clientBounds);
1009 0 : aWidth = mBounds.width + (aWidth - clientBounds.width);
1010 0 : aHeight = mBounds.height + (aHeight - clientBounds.height);
1011 :
1012 0 : nsIntPoint clientOffset(GetClientOffset());
1013 0 : aX -= clientOffset.x;
1014 0 : aY -= clientOffset.y;
1015 :
1016 0 : return Resize(aX, aY, aWidth, aHeight, aRepaint);
1017 : }
1018 :
1019 : //-------------------------------------------------------------------------
1020 : //
1021 : // Bounds
1022 : //
1023 : //-------------------------------------------------------------------------
1024 :
1025 : /**
1026 : * If the implementation of nsWindow supports borders this method MUST be overridden
1027 : *
1028 : **/
1029 0 : NS_METHOD nsBaseWidget::GetClientBounds(nsIntRect &aRect)
1030 : {
1031 0 : return GetBounds(aRect);
1032 : }
1033 :
1034 : /**
1035 : * If the implementation of nsWindow supports borders this method MUST be overridden
1036 : *
1037 : **/
1038 0 : NS_METHOD nsBaseWidget::GetBounds(nsIntRect &aRect)
1039 : {
1040 0 : aRect = mBounds;
1041 0 : return NS_OK;
1042 : }
1043 :
1044 : /**
1045 : * If the implementation of nsWindow uses a local coordinate system within the window,
1046 : * this method must be overridden
1047 : *
1048 : **/
1049 0 : NS_METHOD nsBaseWidget::GetScreenBounds(nsIntRect &aRect)
1050 : {
1051 0 : return GetBounds(aRect);
1052 : }
1053 :
1054 0 : nsIntPoint nsBaseWidget::GetClientOffset()
1055 : {
1056 0 : return nsIntPoint(0, 0);
1057 : }
1058 :
1059 0 : NS_METHOD nsBaseWidget::SetBounds(const nsIntRect &aRect)
1060 : {
1061 0 : mBounds = aRect;
1062 :
1063 0 : return NS_OK;
1064 : }
1065 :
1066 : NS_IMETHODIMP
1067 0 : nsBaseWidget::GetNonClientMargins(nsIntMargin &margins)
1068 : {
1069 0 : return NS_ERROR_NOT_IMPLEMENTED;
1070 : }
1071 :
1072 : NS_IMETHODIMP
1073 0 : nsBaseWidget::SetNonClientMargins(nsIntMargin &margins)
1074 : {
1075 0 : return NS_ERROR_NOT_IMPLEMENTED;
1076 : }
1077 :
1078 0 : NS_METHOD nsBaseWidget::EnableDragDrop(bool aEnable)
1079 : {
1080 0 : return NS_OK;
1081 : }
1082 :
1083 0 : NS_METHOD nsBaseWidget::SetModal(bool aModal)
1084 : {
1085 0 : return NS_ERROR_FAILURE;
1086 : }
1087 :
1088 : NS_IMETHODIMP
1089 0 : nsBaseWidget::GetAttention(PRInt32 aCycleCount) {
1090 0 : return NS_OK;
1091 : }
1092 :
1093 : bool
1094 0 : nsBaseWidget::HasPendingInputEvent()
1095 : {
1096 0 : return false;
1097 : }
1098 :
1099 : NS_IMETHODIMP
1100 0 : nsBaseWidget::SetIcon(const nsAString&)
1101 : {
1102 0 : return NS_OK;
1103 : }
1104 :
1105 : NS_IMETHODIMP
1106 0 : nsBaseWidget::BeginSecureKeyboardInput()
1107 : {
1108 : #ifdef DEBUG
1109 0 : NS_ASSERTION(!debug_InSecureKeyboardInputMode, "Attempting to nest call to BeginSecureKeyboardInput!");
1110 0 : debug_InSecureKeyboardInputMode = true;
1111 : #endif
1112 0 : return NS_OK;
1113 : }
1114 :
1115 : NS_IMETHODIMP
1116 0 : nsBaseWidget::EndSecureKeyboardInput()
1117 : {
1118 : #ifdef DEBUG
1119 0 : NS_ASSERTION(debug_InSecureKeyboardInputMode, "Calling EndSecureKeyboardInput when it hasn't been enabled!");
1120 0 : debug_InSecureKeyboardInputMode = false;
1121 : #endif
1122 0 : return NS_OK;
1123 : }
1124 :
1125 : NS_IMETHODIMP
1126 0 : nsBaseWidget::SetWindowTitlebarColor(nscolor aColor, bool aActive)
1127 : {
1128 0 : return NS_ERROR_NOT_IMPLEMENTED;
1129 : }
1130 :
1131 : bool
1132 0 : nsBaseWidget::ShowsResizeIndicator(nsIntRect* aResizerRect)
1133 : {
1134 0 : return false;
1135 : }
1136 :
1137 : NS_IMETHODIMP
1138 0 : nsBaseWidget::SetAcceleratedRendering(bool aEnabled)
1139 : {
1140 0 : if (mUseAcceleratedRendering == aEnabled) {
1141 0 : return NS_OK;
1142 : }
1143 0 : mUseAcceleratedRendering = aEnabled;
1144 0 : if (mLayerManager) {
1145 0 : mLayerManager->Destroy();
1146 : }
1147 0 : mLayerManager = NULL;
1148 0 : return NS_OK;
1149 : }
1150 :
1151 : bool
1152 0 : nsBaseWidget::GetAcceleratedRendering()
1153 : {
1154 0 : return mUseAcceleratedRendering;
1155 : }
1156 :
1157 0 : NS_METHOD nsBaseWidget::RegisterTouchWindow()
1158 : {
1159 0 : return NS_ERROR_NOT_IMPLEMENTED;
1160 : }
1161 :
1162 0 : NS_METHOD nsBaseWidget::UnregisterTouchWindow()
1163 : {
1164 0 : return NS_ERROR_NOT_IMPLEMENTED;
1165 : }
1166 :
1167 : NS_IMETHODIMP
1168 0 : nsBaseWidget::OverrideSystemMouseScrollSpeed(PRInt32 aOriginalDelta,
1169 : bool aIsHorizontal,
1170 : PRInt32 &aOverriddenDelta)
1171 : {
1172 0 : aOverriddenDelta = aOriginalDelta;
1173 :
1174 : const char* kPrefNameOverrideEnabled =
1175 0 : "mousewheel.system_scroll_override_on_root_content.enabled";
1176 : bool isOverrideEnabled =
1177 0 : Preferences::GetBool(kPrefNameOverrideEnabled, false);
1178 0 : if (!isOverrideEnabled) {
1179 0 : return NS_OK;
1180 : }
1181 :
1182 : nsCAutoString factorPrefName(
1183 0 : "mousewheel.system_scroll_override_on_root_content.");
1184 0 : if (aIsHorizontal) {
1185 0 : factorPrefName.AppendLiteral("horizontal.");
1186 : } else {
1187 0 : factorPrefName.AppendLiteral("vertical.");
1188 : }
1189 0 : factorPrefName.AppendLiteral("factor");
1190 0 : PRInt32 iFactor = Preferences::GetInt(factorPrefName.get(), 0);
1191 : // The pref value must be larger than 100, otherwise, we don't override the
1192 : // delta value.
1193 0 : if (iFactor <= 100) {
1194 0 : return NS_OK;
1195 : }
1196 0 : double factor = (double)iFactor / 100;
1197 0 : aOverriddenDelta = PRInt32(NS_round((double)aOriginalDelta * factor));
1198 :
1199 0 : return NS_OK;
1200 : }
1201 :
1202 :
1203 : /**
1204 : * Modifies aFile to point at an icon file with the given name and suffix. The
1205 : * suffix may correspond to a file extension with leading '.' if appropriate.
1206 : * Returns true if the icon file exists and can be read.
1207 : */
1208 : static bool
1209 0 : ResolveIconNameHelper(nsILocalFile *aFile,
1210 : const nsAString &aIconName,
1211 : const nsAString &aIconSuffix)
1212 : {
1213 0 : aFile->Append(NS_LITERAL_STRING("icons"));
1214 0 : aFile->Append(NS_LITERAL_STRING("default"));
1215 0 : aFile->Append(aIconName + aIconSuffix);
1216 :
1217 : bool readable;
1218 0 : return NS_SUCCEEDED(aFile->IsReadable(&readable)) && readable;
1219 : }
1220 :
1221 : /**
1222 : * Resolve the given icon name into a local file object. This method is
1223 : * intended to be called by subclasses of nsBaseWidget. aIconSuffix is a
1224 : * platform specific icon file suffix (e.g., ".ico" under Win32).
1225 : *
1226 : * If no file is found matching the given parameters, then null is returned.
1227 : */
1228 : void
1229 0 : nsBaseWidget::ResolveIconName(const nsAString &aIconName,
1230 : const nsAString &aIconSuffix,
1231 : nsILocalFile **aResult)
1232 : {
1233 0 : *aResult = nsnull;
1234 :
1235 0 : nsCOMPtr<nsIProperties> dirSvc = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
1236 0 : if (!dirSvc)
1237 : return;
1238 :
1239 : // first check auxilary chrome directories
1240 :
1241 0 : nsCOMPtr<nsISimpleEnumerator> dirs;
1242 0 : dirSvc->Get(NS_APP_CHROME_DIR_LIST, NS_GET_IID(nsISimpleEnumerator),
1243 0 : getter_AddRefs(dirs));
1244 0 : if (dirs) {
1245 : bool hasMore;
1246 0 : while (NS_SUCCEEDED(dirs->HasMoreElements(&hasMore)) && hasMore) {
1247 0 : nsCOMPtr<nsISupports> element;
1248 0 : dirs->GetNext(getter_AddRefs(element));
1249 0 : if (!element)
1250 0 : continue;
1251 0 : nsCOMPtr<nsILocalFile> file = do_QueryInterface(element);
1252 0 : if (!file)
1253 0 : continue;
1254 0 : if (ResolveIconNameHelper(file, aIconName, aIconSuffix)) {
1255 0 : NS_ADDREF(*aResult = file);
1256 : return;
1257 : }
1258 : }
1259 : }
1260 :
1261 : // then check the main app chrome directory
1262 :
1263 0 : nsCOMPtr<nsILocalFile> file;
1264 0 : dirSvc->Get(NS_APP_CHROME_DIR, NS_GET_IID(nsILocalFile),
1265 0 : getter_AddRefs(file));
1266 0 : if (file && ResolveIconNameHelper(file, aIconName, aIconSuffix))
1267 0 : NS_ADDREF(*aResult = file);
1268 : }
1269 :
1270 : NS_IMETHODIMP
1271 0 : nsBaseWidget::BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical)
1272 : {
1273 0 : return NS_ERROR_NOT_IMPLEMENTED;
1274 : }
1275 :
1276 : NS_IMETHODIMP
1277 0 : nsBaseWidget::BeginMoveDrag(nsMouseEvent* aEvent)
1278 : {
1279 0 : return NS_ERROR_NOT_IMPLEMENTED;
1280 : }
1281 :
1282 : PRUint32
1283 0 : nsBaseWidget::GetGLFrameBufferFormat()
1284 : {
1285 0 : if (mLayerManager &&
1286 0 : mLayerManager->GetBackendType() == LayerManager::LAYERS_OPENGL) {
1287 : // Assume that the default framebuffer has RGBA format. Specific
1288 : // backends that know differently will override this method.
1289 0 : return LOCAL_GL_RGBA;
1290 : }
1291 0 : return LOCAL_GL_NONE;
1292 : }
1293 :
1294 : #ifdef DEBUG
1295 : //////////////////////////////////////////////////////////////
1296 : //
1297 : // Convert a GUI event message code to a string.
1298 : // Makes it a lot easier to debug events.
1299 : //
1300 : // See gtk/nsWidget.cpp and windows/nsWindow.cpp
1301 : // for a DebugPrintEvent() function that uses
1302 : // this.
1303 : //
1304 : //////////////////////////////////////////////////////////////
1305 : /* static */ nsAutoString
1306 0 : nsBaseWidget::debug_GuiEventToString(nsGUIEvent * aGuiEvent)
1307 : {
1308 0 : NS_ASSERTION(nsnull != aGuiEvent,"cmon, null gui event.");
1309 :
1310 0 : nsAutoString eventName(NS_LITERAL_STRING("UNKNOWN"));
1311 :
1312 : #define _ASSIGN_eventName(_value,_name)\
1313 : case _value: eventName.AssignLiteral(_name) ; break
1314 :
1315 0 : switch(aGuiEvent->message)
1316 : {
1317 0 : _ASSIGN_eventName(NS_BLUR_CONTENT,"NS_BLUR_CONTENT");
1318 0 : _ASSIGN_eventName(NS_CREATE,"NS_CREATE");
1319 0 : _ASSIGN_eventName(NS_DESTROY,"NS_DESTROY");
1320 0 : _ASSIGN_eventName(NS_DRAGDROP_GESTURE,"NS_DND_GESTURE");
1321 0 : _ASSIGN_eventName(NS_DRAGDROP_DROP,"NS_DND_DROP");
1322 0 : _ASSIGN_eventName(NS_DRAGDROP_ENTER,"NS_DND_ENTER");
1323 0 : _ASSIGN_eventName(NS_DRAGDROP_EXIT,"NS_DND_EXIT");
1324 0 : _ASSIGN_eventName(NS_DRAGDROP_OVER,"NS_DND_OVER");
1325 0 : _ASSIGN_eventName(NS_FOCUS_CONTENT,"NS_FOCUS_CONTENT");
1326 0 : _ASSIGN_eventName(NS_FORM_SELECTED,"NS_FORM_SELECTED");
1327 0 : _ASSIGN_eventName(NS_FORM_CHANGE,"NS_FORM_CHANGE");
1328 0 : _ASSIGN_eventName(NS_FORM_INPUT,"NS_FORM_INPUT");
1329 0 : _ASSIGN_eventName(NS_FORM_RESET,"NS_FORM_RESET");
1330 0 : _ASSIGN_eventName(NS_FORM_SUBMIT,"NS_FORM_SUBMIT");
1331 0 : _ASSIGN_eventName(NS_IMAGE_ABORT,"NS_IMAGE_ABORT");
1332 0 : _ASSIGN_eventName(NS_LOAD_ERROR,"NS_LOAD_ERROR");
1333 0 : _ASSIGN_eventName(NS_KEY_DOWN,"NS_KEY_DOWN");
1334 0 : _ASSIGN_eventName(NS_KEY_PRESS,"NS_KEY_PRESS");
1335 0 : _ASSIGN_eventName(NS_KEY_UP,"NS_KEY_UP");
1336 0 : _ASSIGN_eventName(NS_MOUSE_ENTER,"NS_MOUSE_ENTER");
1337 0 : _ASSIGN_eventName(NS_MOUSE_EXIT,"NS_MOUSE_EXIT");
1338 0 : _ASSIGN_eventName(NS_MOUSE_BUTTON_DOWN,"NS_MOUSE_BUTTON_DOWN");
1339 0 : _ASSIGN_eventName(NS_MOUSE_BUTTON_UP,"NS_MOUSE_BUTTON_UP");
1340 0 : _ASSIGN_eventName(NS_MOUSE_CLICK,"NS_MOUSE_CLICK");
1341 0 : _ASSIGN_eventName(NS_MOUSE_DOUBLECLICK,"NS_MOUSE_DBLCLICK");
1342 0 : _ASSIGN_eventName(NS_MOUSE_MOVE,"NS_MOUSE_MOVE");
1343 0 : _ASSIGN_eventName(NS_MOVE,"NS_MOVE");
1344 0 : _ASSIGN_eventName(NS_LOAD,"NS_LOAD");
1345 0 : _ASSIGN_eventName(NS_POPSTATE,"NS_POPSTATE");
1346 0 : _ASSIGN_eventName(NS_BEFORE_SCRIPT_EXECUTE,"NS_BEFORE_SCRIPT_EXECUTE");
1347 0 : _ASSIGN_eventName(NS_AFTER_SCRIPT_EXECUTE,"NS_AFTER_SCRIPT_EXECUTE");
1348 0 : _ASSIGN_eventName(NS_PAGE_UNLOAD,"NS_PAGE_UNLOAD");
1349 0 : _ASSIGN_eventName(NS_HASHCHANGE,"NS_HASHCHANGE");
1350 0 : _ASSIGN_eventName(NS_READYSTATECHANGE,"NS_READYSTATECHANGE");
1351 0 : _ASSIGN_eventName(NS_PAINT,"NS_PAINT");
1352 0 : _ASSIGN_eventName(NS_XUL_BROADCAST, "NS_XUL_BROADCAST");
1353 0 : _ASSIGN_eventName(NS_XUL_COMMAND_UPDATE, "NS_XUL_COMMAND_UPDATE");
1354 0 : _ASSIGN_eventName(NS_SCROLLBAR_LINE_NEXT,"NS_SB_LINE_NEXT");
1355 0 : _ASSIGN_eventName(NS_SCROLLBAR_LINE_PREV,"NS_SB_LINE_PREV");
1356 0 : _ASSIGN_eventName(NS_SCROLLBAR_PAGE_NEXT,"NS_SB_PAGE_NEXT");
1357 0 : _ASSIGN_eventName(NS_SCROLLBAR_PAGE_PREV,"NS_SB_PAGE_PREV");
1358 0 : _ASSIGN_eventName(NS_SCROLLBAR_POS,"NS_SB_POS");
1359 0 : _ASSIGN_eventName(NS_SIZE,"NS_SIZE");
1360 :
1361 : #undef _ASSIGN_eventName
1362 :
1363 : default:
1364 : {
1365 : char buf[32];
1366 :
1367 0 : sprintf(buf,"UNKNOWN: %d",aGuiEvent->message);
1368 :
1369 0 : CopyASCIItoUTF16(buf, eventName);
1370 : }
1371 0 : break;
1372 : }
1373 :
1374 0 : return nsAutoString(eventName);
1375 : }
1376 : //////////////////////////////////////////////////////////////
1377 : //
1378 : // Code to deal with paint and event debug prefs.
1379 : //
1380 : //////////////////////////////////////////////////////////////
1381 : struct PrefPair
1382 : {
1383 : const char * name;
1384 : bool value;
1385 : };
1386 :
1387 : static PrefPair debug_PrefValues[] =
1388 : {
1389 : { "nglayout.debug.crossing_event_dumping", false },
1390 : { "nglayout.debug.event_dumping", false },
1391 : { "nglayout.debug.invalidate_dumping", false },
1392 : { "nglayout.debug.motion_event_dumping", false },
1393 : { "nglayout.debug.paint_dumping", false },
1394 : { "nglayout.debug.paint_flashing", false }
1395 : };
1396 :
1397 : //////////////////////////////////////////////////////////////
1398 : bool
1399 0 : nsBaseWidget::debug_GetCachedBoolPref(const char * aPrefName)
1400 : {
1401 0 : NS_ASSERTION(nsnull != aPrefName,"cmon, pref name is null.");
1402 :
1403 0 : for (PRUint32 i = 0; i < ArrayLength(debug_PrefValues); i++)
1404 : {
1405 0 : if (strcmp(debug_PrefValues[i].name, aPrefName) == 0)
1406 : {
1407 0 : return debug_PrefValues[i].value;
1408 : }
1409 : }
1410 :
1411 0 : return false;
1412 : }
1413 : //////////////////////////////////////////////////////////////
1414 0 : static void debug_SetCachedBoolPref(const char * aPrefName,bool aValue)
1415 : {
1416 0 : NS_ASSERTION(nsnull != aPrefName,"cmon, pref name is null.");
1417 :
1418 0 : for (PRUint32 i = 0; i < ArrayLength(debug_PrefValues); i++)
1419 : {
1420 0 : if (strcmp(debug_PrefValues[i].name, aPrefName) == 0)
1421 : {
1422 0 : debug_PrefValues[i].value = aValue;
1423 :
1424 0 : return;
1425 : }
1426 : }
1427 :
1428 0 : NS_ASSERTION(false, "cmon, this code is not reached dude.");
1429 : }
1430 :
1431 : //////////////////////////////////////////////////////////////
1432 0 : class Debug_PrefObserver : public nsIObserver {
1433 : public:
1434 : NS_DECL_ISUPPORTS
1435 : NS_DECL_NSIOBSERVER
1436 : };
1437 :
1438 0 : NS_IMPL_ISUPPORTS1(Debug_PrefObserver, nsIObserver)
1439 :
1440 : NS_IMETHODIMP
1441 0 : Debug_PrefObserver::Observe(nsISupports* subject, const char* topic,
1442 : const PRUnichar* data)
1443 : {
1444 0 : NS_ConvertUTF16toUTF8 prefName(data);
1445 :
1446 0 : bool value = Preferences::GetBool(prefName.get(), false);
1447 0 : debug_SetCachedBoolPref(prefName.get(), value);
1448 0 : return NS_OK;
1449 : }
1450 :
1451 : //////////////////////////////////////////////////////////////
1452 : /* static */ void
1453 0 : debug_RegisterPrefCallbacks()
1454 : {
1455 : static bool once = true;
1456 :
1457 0 : if (!once) {
1458 0 : return;
1459 : }
1460 :
1461 0 : once = false;
1462 :
1463 0 : nsCOMPtr<nsIObserver> obs(new Debug_PrefObserver());
1464 0 : for (PRUint32 i = 0; i < ArrayLength(debug_PrefValues); i++) {
1465 : // Initialize the pref values
1466 : debug_PrefValues[i].value =
1467 0 : Preferences::GetBool(debug_PrefValues[i].name, false);
1468 :
1469 0 : if (obs) {
1470 : // Register callbacks for when these change
1471 0 : Preferences::AddStrongObserver(obs, debug_PrefValues[i].name);
1472 : }
1473 : }
1474 : }
1475 : //////////////////////////////////////////////////////////////
1476 : static PRInt32
1477 0 : _GetPrintCount()
1478 : {
1479 : static PRInt32 sCount = 0;
1480 :
1481 0 : return ++sCount;
1482 : }
1483 : //////////////////////////////////////////////////////////////
1484 : /* static */ bool
1485 0 : nsBaseWidget::debug_WantPaintFlashing()
1486 : {
1487 0 : return debug_GetCachedBoolPref("nglayout.debug.paint_flashing");
1488 : }
1489 : //////////////////////////////////////////////////////////////
1490 : /* static */ void
1491 0 : nsBaseWidget::debug_DumpEvent(FILE * aFileOut,
1492 : nsIWidget * aWidget,
1493 : nsGUIEvent * aGuiEvent,
1494 : const nsCAutoString & aWidgetName,
1495 : PRInt32 aWindowID)
1496 : {
1497 : // NS_PAINT is handled by debug_DumpPaintEvent()
1498 0 : if (aGuiEvent->message == NS_PAINT)
1499 0 : return;
1500 :
1501 0 : if (aGuiEvent->message == NS_MOUSE_MOVE)
1502 : {
1503 0 : if (!debug_GetCachedBoolPref("nglayout.debug.motion_event_dumping"))
1504 0 : return;
1505 : }
1506 :
1507 0 : if (aGuiEvent->message == NS_MOUSE_ENTER ||
1508 : aGuiEvent->message == NS_MOUSE_EXIT)
1509 : {
1510 0 : if (!debug_GetCachedBoolPref("nglayout.debug.crossing_event_dumping"))
1511 0 : return;
1512 : }
1513 :
1514 0 : if (!debug_GetCachedBoolPref("nglayout.debug.event_dumping"))
1515 0 : return;
1516 :
1517 0 : NS_LossyConvertUTF16toASCII tempString(debug_GuiEventToString(aGuiEvent).get());
1518 :
1519 : fprintf(aFileOut,
1520 : "%4d %-26s widget=%-8p name=%-12s id=%-8p refpt=%d,%d\n",
1521 : _GetPrintCount(),
1522 : tempString.get(),
1523 : (void *) aWidget,
1524 : aWidgetName.get(),
1525 : (void *) (aWindowID ? aWindowID : 0x0),
1526 : aGuiEvent->refPoint.x,
1527 0 : aGuiEvent->refPoint.y);
1528 : }
1529 : //////////////////////////////////////////////////////////////
1530 : /* static */ void
1531 0 : nsBaseWidget::debug_DumpPaintEvent(FILE * aFileOut,
1532 : nsIWidget * aWidget,
1533 : nsPaintEvent * aPaintEvent,
1534 : const nsCAutoString & aWidgetName,
1535 : PRInt32 aWindowID)
1536 : {
1537 0 : NS_ASSERTION(nsnull != aFileOut,"cmon, null output FILE");
1538 0 : NS_ASSERTION(nsnull != aWidget,"cmon, the widget is null");
1539 0 : NS_ASSERTION(nsnull != aPaintEvent,"cmon, the paint event is null");
1540 :
1541 0 : if (!debug_GetCachedBoolPref("nglayout.debug.paint_dumping"))
1542 0 : return;
1543 :
1544 0 : nsIntRect rect = aPaintEvent->region.GetBounds();
1545 : fprintf(aFileOut,
1546 : "%4d PAINT widget=%p name=%-12s id=%-8p bounds-rect=%3d,%-3d %3d,%-3d",
1547 : _GetPrintCount(),
1548 : (void *) aWidget,
1549 : aWidgetName.get(),
1550 : (void *) aWindowID,
1551 : rect.x, rect.y, rect.width, rect.height
1552 0 : );
1553 :
1554 0 : fprintf(aFileOut,"\n");
1555 : }
1556 : //////////////////////////////////////////////////////////////
1557 : /* static */ void
1558 0 : nsBaseWidget::debug_DumpInvalidate(FILE * aFileOut,
1559 : nsIWidget * aWidget,
1560 : const nsIntRect * aRect,
1561 : const nsCAutoString & aWidgetName,
1562 : PRInt32 aWindowID)
1563 : {
1564 0 : if (!debug_GetCachedBoolPref("nglayout.debug.invalidate_dumping"))
1565 0 : return;
1566 :
1567 0 : NS_ASSERTION(nsnull != aFileOut,"cmon, null output FILE");
1568 0 : NS_ASSERTION(nsnull != aWidget,"cmon, the widget is null");
1569 :
1570 : fprintf(aFileOut,
1571 : "%4d Invalidate widget=%p name=%-12s id=%-8p",
1572 : _GetPrintCount(),
1573 : (void *) aWidget,
1574 : aWidgetName.get(),
1575 0 : (void *) aWindowID);
1576 :
1577 0 : if (aRect)
1578 : {
1579 : fprintf(aFileOut,
1580 : " rect=%3d,%-3d %3d,%-3d",
1581 : aRect->x,
1582 : aRect->y,
1583 : aRect->width,
1584 0 : aRect->height);
1585 : }
1586 : else
1587 : {
1588 : fprintf(aFileOut,
1589 : " rect=%-15s",
1590 0 : "none");
1591 : }
1592 :
1593 0 : fprintf(aFileOut,"\n");
1594 : }
1595 : //////////////////////////////////////////////////////////////
1596 :
1597 : #endif // DEBUG
1598 :
|