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
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/
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
15 * The Original Code is mozilla.org code.
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.
23 * Dean Tessman <dean_tessman@hotmail.com>
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.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsBaseWidget.h"
40 #include "nsIDeviceContext.h"
42 #include "nsGfxCIID.h"
43 #include "nsWidgetsCID.h"
44 #include "nsIFullScreen.h"
45 #include "nsServiceManagerUtils.h"
46 #include "nsIScreenManager.h"
47 #include "nsAppDirectoryServiceDefs.h"
48 #include "nsISimpleEnumerator.h"
49 #include "nsIContent.h"
52 #include "nsIServiceManager.h"
53 #include "nsIPrefService.h"
54 #include "nsIPrefBranch2.h"
55 #include "nsIObserver.h"
57 static void debug_RegisterPrefCallbacks();
59 static PRBool debug_InSecureKeyboardInputMode
= PR_FALSE
;
62 #ifdef NOISY_WIDGET_LEAKS
63 static PRInt32 gNumWidgets
;
66 nsIContent
* nsBaseWidget::mLastRollup
= nsnull
;
69 NS_IMPL_ISUPPORTS1(nsBaseWidget
, nsIWidget
)
72 nsAutoRollup::nsAutoRollup()
74 // remember if mLastRollup was null, and only clear it upon destruction
75 // if so. This prevents recursive usage of nsAutoRollup from clearing
76 // mLastRollup when it shouldn't.
77 wasClear
= !nsBaseWidget::mLastRollup
;
80 nsAutoRollup::~nsAutoRollup()
82 if (nsBaseWidget::mLastRollup
&& wasClear
) {
83 NS_RELEASE(nsBaseWidget::mLastRollup
);
87 //-------------------------------------------------------------------------
89 // nsBaseWidget constructor
91 //-------------------------------------------------------------------------
93 nsBaseWidget::nsBaseWidget()
95 , mEventCallback(nsnull
)
98 , mEventListener(nsnull
)
99 , mCursor(eCursor_standard
)
100 , mWindowType(eWindowType_child
)
101 , mBorderStyle(eBorderStyle_none
)
102 , mIsShiftDown(PR_FALSE
)
103 , mIsControlDown(PR_FALSE
)
104 , mIsAltDown(PR_FALSE
)
105 , mIsDestroying(PR_FALSE
)
106 , mOnDestroyCalled(PR_FALSE
)
108 , mOriginalBounds(nsnull
)
110 , mSizeMode(nsSizeMode_Normal
)
112 #ifdef NOISY_WIDGET_LEAKS
114 printf("WIDGETS+ = %d\n", gNumWidgets
);
118 debug_RegisterPrefCallbacks();
123 //-------------------------------------------------------------------------
125 // nsBaseWidget destructor
127 //-------------------------------------------------------------------------
128 nsBaseWidget::~nsBaseWidget()
130 #ifdef NOISY_WIDGET_LEAKS
132 printf("WIDGETS- = %d\n", gNumWidgets
);
135 NS_IF_RELEASE(mToolkit
);
136 NS_IF_RELEASE(mContext
);
138 delete mOriginalBounds
;
142 //-------------------------------------------------------------------------
146 //-------------------------------------------------------------------------
147 void nsBaseWidget::BaseCreate(nsIWidget
*aParent
,
149 EVENT_CALLBACK aHandleEventFunction
,
150 nsIDeviceContext
*aContext
,
151 nsIAppShell
*aAppShell
,
152 nsIToolkit
*aToolkit
,
153 nsWidgetInitData
*aInitData
)
155 if (nsnull
== mToolkit
) {
156 if (nsnull
!= aToolkit
) {
157 mToolkit
= (nsIToolkit
*)aToolkit
;
161 if (nsnull
!= aParent
) {
162 mToolkit
= aParent
->GetToolkit();
163 NS_IF_ADDREF(mToolkit
);
165 // it's some top level window with no toolkit passed in.
166 // Create a default toolkit with the current thread
167 #if !defined(USE_TLS_FOR_TOOLKIT)
169 static NS_DEFINE_CID(kToolkitCID
, NS_TOOLKIT_CID
);
172 res
= CallCreateInstance(kToolkitCID
, &mToolkit
);
173 NS_ASSERTION(NS_SUCCEEDED(res
), "Can not create a toolkit in nsBaseWidget::Create");
175 mToolkit
->Init(PR_GetCurrentThread());
177 #else /* USE_TLS_FOR_TOOLKIT */
181 rv
= NS_GetCurrentToolkit(&mToolkit
);
183 #endif /* USE_TLS_FOR_TOOLKIT */
188 // save the event callback function
189 mEventCallback
= aHandleEventFunction
;
191 // keep a reference to the device context
199 static NS_DEFINE_CID(kDeviceContextCID
, NS_DEVICE_CONTEXT_CID
);
201 res
= CallCreateInstance(kDeviceContextCID
, &mContext
);
203 if (NS_SUCCEEDED(res
))
204 mContext
->Init(nsnull
);
207 if (nsnull
!= aInitData
) {
208 PreCreateWidget(aInitData
);
212 aParent
->AddChild(this);
216 NS_IMETHODIMP
nsBaseWidget::CaptureMouse(PRBool aCapture
)
221 NS_IMETHODIMP
nsBaseWidget::Validate()
226 NS_IMETHODIMP
nsBaseWidget::InvalidateRegion(const nsIRegion
*aRegion
, PRBool aIsSynchronous
)
228 return NS_ERROR_FAILURE
;
231 //-------------------------------------------------------------------------
233 // Accessor functions to get/set the client data
235 //-------------------------------------------------------------------------
237 NS_IMETHODIMP
nsBaseWidget::GetClientData(void*& aClientData
)
239 aClientData
= mClientData
;
243 NS_IMETHODIMP
nsBaseWidget::SetClientData(void* aClientData
)
245 mClientData
= aClientData
;
249 //-------------------------------------------------------------------------
251 // Close this nsBaseWidget
253 //-------------------------------------------------------------------------
254 NS_METHOD
nsBaseWidget::Destroy()
256 // Just in case our parent is the only ref to us
257 nsCOMPtr
<nsIWidget
> kungFuDeathGrip(this);
259 // disconnect from the parent
260 nsIWidget
*parent
= GetParent();
262 parent
->RemoveChild(this);
264 // disconnect listeners.
265 NS_IF_RELEASE(mEventListener
);
271 //-------------------------------------------------------------------------
273 // Set this nsBaseWidget's parent
275 //-------------------------------------------------------------------------
276 NS_IMETHODIMP
nsBaseWidget::SetParent(nsIWidget
* aNewParent
)
278 return NS_ERROR_NOT_IMPLEMENTED
;
282 //-------------------------------------------------------------------------
284 // Get this nsBaseWidget parent
286 //-------------------------------------------------------------------------
287 nsIWidget
* nsBaseWidget::GetParent(void)
292 //-------------------------------------------------------------------------
294 // Get this nsBaseWidget top level widget
296 //-------------------------------------------------------------------------
297 nsIWidget
* nsBaseWidget::GetTopLevelWidget(PRInt32
* aLevelsUp
)
299 nsIWidget
*topLevelWidget
= nsnull
, *widget
= this;
303 topLevelWidget
= widget
;
304 widget
= widget
->GetParent();
308 return topLevelWidget
;
311 //-------------------------------------------------------------------------
313 // Get this nsBaseWidget's top (non-sheet) parent (if it's a sheet)
315 //-------------------------------------------------------------------------
316 nsIWidget
* nsBaseWidget::GetSheetWindowParent(void)
321 //-------------------------------------------------------------------------
323 // Add a child to the list of children
325 //-------------------------------------------------------------------------
326 void nsBaseWidget::AddChild(nsIWidget
* aChild
)
328 NS_PRECONDITION(!aChild
->GetNextSibling() && !aChild
->GetPrevSibling(),
329 "aChild not properly removed from its old child list");
332 mFirstChild
= mLastChild
= aChild
;
334 // append to the list
335 NS_ASSERTION(mLastChild
, "Bogus state");
336 NS_ASSERTION(!mLastChild
->GetNextSibling(), "Bogus state");
337 mLastChild
->SetNextSibling(aChild
);
338 aChild
->SetPrevSibling(mLastChild
);
344 //-------------------------------------------------------------------------
346 // Remove a child from the list of children
348 //-------------------------------------------------------------------------
349 void nsBaseWidget::RemoveChild(nsIWidget
* aChild
)
351 NS_ASSERTION(aChild
->GetParent() == this, "Not one of our kids!");
353 if (mLastChild
== aChild
) {
354 mLastChild
= mLastChild
->GetPrevSibling();
356 if (mFirstChild
== aChild
) {
357 mFirstChild
= mFirstChild
->GetNextSibling();
360 // Now remove from the list. Make sure that we pass ownership of the tail
361 // of the list correctly before we have aChild let go of it.
362 nsIWidget
* prev
= aChild
->GetPrevSibling();
363 nsIWidget
* next
= aChild
->GetNextSibling();
365 prev
->SetNextSibling(next
);
368 next
->SetPrevSibling(prev
);
371 aChild
->SetNextSibling(nsnull
);
372 aChild
->SetPrevSibling(nsnull
);
376 //-------------------------------------------------------------------------
378 // Sets widget's position within its parent's child list.
380 //-------------------------------------------------------------------------
381 NS_IMETHODIMP
nsBaseWidget::SetZIndex(PRInt32 aZIndex
)
383 // Hold a ref to ourselves just in case, since we're going to remove
385 nsCOMPtr
<nsIWidget
> kungFuDeathGrip(this);
389 // reorder this child in its parent's list.
390 nsBaseWidget
* parent
= static_cast<nsBaseWidget
*>(GetParent());
392 parent
->RemoveChild(this);
393 // Scope sib outside the for loop so we can check it afterward
394 nsIWidget
* sib
= parent
->GetFirstChild();
395 for ( ; sib
; sib
= sib
->GetNextSibling()) {
397 if (NS_SUCCEEDED(sib
->GetZIndex(&childZIndex
))) {
398 if (aZIndex
< childZIndex
) {
399 // Insert ourselves before sib
400 nsIWidget
* prev
= sib
->GetPrevSibling();
403 sib
->SetPrevSibling(this);
405 prev
->SetNextSibling(this);
407 NS_ASSERTION(sib
== parent
->mFirstChild
, "Broken child list");
408 // We've taken ownership of sib, so it's safe to have parent let
410 parent
->mFirstChild
= this;
412 PlaceBehind(eZPlacementBelow
, sib
, PR_FALSE
);
417 // were we added to the list?
419 parent
->AddChild(this);
425 //-------------------------------------------------------------------------
427 // Gets widget's position within its parent's child list.
429 //-------------------------------------------------------------------------
430 NS_IMETHODIMP
nsBaseWidget::GetZIndex(PRInt32
* aZIndex
)
436 //-------------------------------------------------------------------------
438 // Places widget behind the given widget (platforms must override)
440 //-------------------------------------------------------------------------
441 NS_IMETHODIMP
nsBaseWidget::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement
,
442 nsIWidget
*aWidget
, PRBool aActivate
)
447 //-------------------------------------------------------------------------
449 // Maximize, minimize or restore the window. The BaseWidget implementation
450 // merely stores the state.
452 //-------------------------------------------------------------------------
453 NS_IMETHODIMP
nsBaseWidget::SetSizeMode(PRInt32 aMode
) {
455 if (aMode
== nsSizeMode_Normal
|| aMode
== nsSizeMode_Minimized
||
456 aMode
== nsSizeMode_Maximized
) {
458 mSizeMode
= (nsSizeMode
) aMode
;
461 return NS_ERROR_ILLEGAL_VALUE
;
464 //-------------------------------------------------------------------------
466 // Get the size mode (minimized, maximized, that sort of thing...)
468 //-------------------------------------------------------------------------
469 NS_IMETHODIMP
nsBaseWidget::GetSizeMode(PRInt32
* aMode
) {
475 //-------------------------------------------------------------------------
477 // Get the foreground color
479 //-------------------------------------------------------------------------
480 nscolor
nsBaseWidget::GetForegroundColor(void)
486 //-------------------------------------------------------------------------
488 // Set the foreground color
490 //-------------------------------------------------------------------------
491 NS_METHOD
nsBaseWidget::SetForegroundColor(const nscolor
&aColor
)
493 mForeground
= aColor
;
498 //-------------------------------------------------------------------------
500 // Get the background color
502 //-------------------------------------------------------------------------
503 nscolor
nsBaseWidget::GetBackgroundColor(void)
508 //-------------------------------------------------------------------------
510 // Set the background color
512 //-------------------------------------------------------------------------
513 NS_METHOD
nsBaseWidget::SetBackgroundColor(const nscolor
&aColor
)
515 mBackground
= aColor
;
519 //-------------------------------------------------------------------------
521 // Get this component cursor
523 //-------------------------------------------------------------------------
524 nsCursor
nsBaseWidget::GetCursor()
529 NS_METHOD
nsBaseWidget::SetCursor(nsCursor aCursor
)
535 NS_IMETHODIMP
nsBaseWidget::SetCursor(imgIContainer
* aCursor
,
536 PRUint32 aHotspotX
, PRUint32 aHotspotY
)
538 return NS_ERROR_NOT_IMPLEMENTED
;
541 //-------------------------------------------------------------------------
543 // Get the window type for this widget
545 //-------------------------------------------------------------------------
546 NS_IMETHODIMP
nsBaseWidget::GetWindowType(nsWindowType
& aWindowType
)
548 aWindowType
= mWindowType
;
552 NS_IMETHODIMP
nsBaseWidget::SetWindowType(nsWindowType aWindowType
)
554 mWindowType
= aWindowType
;
558 //-------------------------------------------------------------------------
560 // Window transparency methods
562 //-------------------------------------------------------------------------
564 void nsBaseWidget::SetTransparencyMode(nsTransparencyMode aMode
) {
567 nsTransparencyMode
nsBaseWidget::GetTransparencyMode() {
568 return eTransparencyOpaque
;
571 //-------------------------------------------------------------------------
573 // Set window shadow style
575 //-------------------------------------------------------------------------
577 NS_IMETHODIMP
nsBaseWidget::SetWindowShadowStyle(PRInt32 aMode
)
579 return NS_ERROR_NOT_IMPLEMENTED
;
582 //-------------------------------------------------------------------------
584 // Hide window borders/decorations for this widget
586 //-------------------------------------------------------------------------
587 NS_IMETHODIMP
nsBaseWidget::HideWindowChrome(PRBool aShouldHide
)
589 return NS_ERROR_NOT_IMPLEMENTED
;
592 //-------------------------------------------------------------------------
594 // Put the window into full-screen mode
596 //-------------------------------------------------------------------------
597 NS_IMETHODIMP
nsBaseWidget::MakeFullScreen(PRBool aFullScreen
)
599 HideWindowChrome(aFullScreen
);
601 nsCOMPtr
<nsIFullScreen
> fullScreen
= do_GetService("@mozilla.org/browser/fullscreen;1");
604 if (!mOriginalBounds
)
605 mOriginalBounds
= new nsRect();
606 GetScreenBounds(*mOriginalBounds
);
608 // Move to top-left corner of screen and size to the screen dimensions
609 nsCOMPtr
<nsIScreenManager
> screenManager
;
610 screenManager
= do_GetService("@mozilla.org/gfx/screenmanager;1");
611 NS_ASSERTION(screenManager
, "Unable to grab screenManager.");
613 nsCOMPtr
<nsIScreen
> screen
;
614 screenManager
->ScreenForRect(mOriginalBounds
->x
, mOriginalBounds
->y
,
615 mOriginalBounds
->width
, mOriginalBounds
->height
,
616 getter_AddRefs(screen
));
618 PRInt32 left
, top
, width
, height
;
619 if (NS_SUCCEEDED(screen
->GetRect(&left
, &top
, &width
, &height
))) {
620 SetSizeMode(nsSizeMode_Normal
);
621 Resize(left
, top
, width
, height
, PR_TRUE
);
623 // Hide all of the OS chrome
625 fullScreen
->HideAllOSChrome();
630 } else if (mOriginalBounds
) {
631 Resize(mOriginalBounds
->x
, mOriginalBounds
->y
, mOriginalBounds
->width
,
632 mOriginalBounds
->height
, PR_TRUE
);
634 // Show all of the OS chrome
636 fullScreen
->ShowAllOSChrome();
642 //-------------------------------------------------------------------------
644 // Create a rendering context from this nsBaseWidget
646 //-------------------------------------------------------------------------
647 nsIRenderingContext
* nsBaseWidget::GetRenderingContext()
650 nsCOMPtr
<nsIRenderingContext
> renderingCtx
;
652 if (mOnDestroyCalled
)
655 rv
= mContext
->CreateRenderingContextInstance(*getter_AddRefs(renderingCtx
));
656 if (NS_SUCCEEDED(rv
)) {
657 gfxASurface
* surface
= GetThebesSurface();
658 NS_ENSURE_TRUE(surface
, nsnull
);
659 rv
= renderingCtx
->Init(mContext
, surface
);
660 if (NS_SUCCEEDED(rv
)) {
661 nsIRenderingContext
*ret
= renderingCtx
;
662 /* Increment object refcount that the |ret| object is still a valid one
663 * after we leave this function... */
668 NS_WARNING("GetRenderingContext: nsIRenderingContext::Init() failed.");
672 NS_WARNING("GetRenderingContext: Cannot create RenderingContext.");
678 //-------------------------------------------------------------------------
680 // Return the toolkit this widget was created on
682 //-------------------------------------------------------------------------
683 nsIToolkit
* nsBaseWidget::GetToolkit()
689 //-------------------------------------------------------------------------
691 // Return the used device context
693 //-------------------------------------------------------------------------
694 nsIDeviceContext
* nsBaseWidget::GetDeviceContext()
699 //-------------------------------------------------------------------------
701 // Get the thebes surface
703 //-------------------------------------------------------------------------
704 gfxASurface
*nsBaseWidget::GetThebesSurface()
706 // in theory we should get our parent's surface,
707 // clone it, and set a device offset before returning
712 //-------------------------------------------------------------------------
714 // Destroy the window
716 //-------------------------------------------------------------------------
717 void nsBaseWidget::OnDestroy()
719 // release references to device context, toolkit, and app shell
720 NS_IF_RELEASE(mContext
);
721 NS_IF_RELEASE(mToolkit
);
724 NS_METHOD
nsBaseWidget::SetWindowClass(const nsAString
& xulWinType
)
726 return NS_ERROR_NOT_IMPLEMENTED
;
729 NS_METHOD
nsBaseWidget::SetBorderStyle(nsBorderStyle aBorderStyle
)
731 mBorderStyle
= aBorderStyle
;
737 * Sets the event listener for a widget
740 NS_METHOD
nsBaseWidget::AddEventListener(nsIEventListener
* aListener
)
742 NS_PRECONDITION(mEventListener
== nsnull
, "Null event listener");
743 NS_IF_RELEASE(mEventListener
);
744 NS_ADDREF(aListener
);
745 mEventListener
= aListener
;
750 * If the implementation of nsWindow supports borders this method MUST be overridden
753 NS_METHOD
nsBaseWidget::GetClientBounds(nsRect
&aRect
)
755 return GetBounds(aRect
);
759 * If the implementation of nsWindow supports borders this method MUST be overridden
762 NS_METHOD
nsBaseWidget::GetBounds(nsRect
&aRect
)
769 * If the implementation of nsWindow uses a local coordinate system within the window,
770 * this method must be overridden
773 NS_METHOD
nsBaseWidget::GetScreenBounds(nsRect
&aRect
)
775 return GetBounds(aRect
);
782 NS_METHOD
nsBaseWidget::SetBounds(const nsRect
&aRect
)
792 * Calculates the border width and height
795 NS_METHOD
nsBaseWidget::GetBorderSize(PRInt32
&aWidth
, PRInt32
&aHeight
)
800 GetClientBounds(rect
);
802 aWidth
= (rectWin
.width
- rect
.width
) / 2;
803 aHeight
= (rectWin
.height
- rect
.height
) / 2;
808 NS_IMETHODIMP
nsBaseWidget::ScrollWidgets(PRInt32 aDx
, PRInt32 aDy
)
810 return NS_ERROR_FAILURE
;
813 NS_IMETHODIMP
nsBaseWidget::ScrollRect(nsRect
&aRect
, PRInt32 aDx
, PRInt32 aDy
)
815 return NS_ERROR_FAILURE
;
818 NS_METHOD
nsBaseWidget::EnableDragDrop(PRBool aEnable
)
823 NS_METHOD
nsBaseWidget::SetModal(PRBool aModal
)
825 return NS_ERROR_FAILURE
;
828 // generic xp assumption is that events should be processed
829 NS_METHOD
nsBaseWidget::ModalEventFilter(PRBool aRealEvent
, void *aEvent
,
832 *aForWindow
= PR_TRUE
;
837 nsBaseWidget::GetAttention(PRInt32 aCycleCount
) {
842 nsBaseWidget::GetLastInputEventTime(PRUint32
& aTime
) {
843 return NS_ERROR_NOT_IMPLEMENTED
;
847 nsBaseWidget::SetIcon(const nsAString
&)
853 nsBaseWidget::BeginSecureKeyboardInput()
856 NS_ASSERTION(!debug_InSecureKeyboardInputMode
, "Attempting to nest call to BeginSecureKeyboardInput!");
857 debug_InSecureKeyboardInputMode
= PR_TRUE
;
863 nsBaseWidget::EndSecureKeyboardInput()
866 NS_ASSERTION(debug_InSecureKeyboardInputMode
, "Calling EndSecureKeyboardInput when it hasn't been enabled!");
867 debug_InSecureKeyboardInputMode
= PR_FALSE
;
873 nsBaseWidget::SetWindowTitlebarColor(nscolor aColor
, PRBool aActive
)
875 return NS_ERROR_NOT_IMPLEMENTED
;
879 nsBaseWidget::ShowsResizeIndicator(nsIntRect
* aResizerRect
)
886 * Modifies aFile to point at an icon file with the given name and suffix. The
887 * suffix may correspond to a file extension with leading '.' if appropriate.
888 * Returns true if the icon file exists and can be read.
891 ResolveIconNameHelper(nsILocalFile
*aFile
,
892 const nsAString
&aIconName
,
893 const nsAString
&aIconSuffix
)
895 aFile
->Append(NS_LITERAL_STRING("icons"));
896 aFile
->Append(NS_LITERAL_STRING("default"));
897 aFile
->Append(aIconName
+ aIconSuffix
);
900 return NS_SUCCEEDED(aFile
->IsReadable(&readable
)) && readable
;
904 * Resolve the given icon name into a local file object. This method is
905 * intended to be called by subclasses of nsBaseWidget. aIconSuffix is a
906 * platform specific icon file suffix (e.g., ".ico" under Win32).
908 * If no file is found matching the given parameters, then null is returned.
911 nsBaseWidget::ResolveIconName(const nsAString
&aIconName
,
912 const nsAString
&aIconSuffix
,
913 nsILocalFile
**aResult
)
917 nsCOMPtr
<nsIProperties
> dirSvc
= do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID
);
921 // first check auxilary chrome directories
923 nsCOMPtr
<nsISimpleEnumerator
> dirs
;
924 dirSvc
->Get(NS_APP_CHROME_DIR_LIST
, NS_GET_IID(nsISimpleEnumerator
),
925 getter_AddRefs(dirs
));
928 while (NS_SUCCEEDED(dirs
->HasMoreElements(&hasMore
)) && hasMore
) {
929 nsCOMPtr
<nsISupports
> element
;
930 dirs
->GetNext(getter_AddRefs(element
));
933 nsCOMPtr
<nsILocalFile
> file
= do_QueryInterface(element
);
936 if (ResolveIconNameHelper(file
, aIconName
, aIconSuffix
)) {
937 NS_ADDREF(*aResult
= file
);
943 // then check the main app chrome directory
945 nsCOMPtr
<nsILocalFile
> file
;
946 dirSvc
->Get(NS_APP_CHROME_DIR
, NS_GET_IID(nsILocalFile
),
947 getter_AddRefs(file
));
948 if (file
&& ResolveIconNameHelper(file
, aIconName
, aIconSuffix
))
949 NS_ADDREF(*aResult
= file
);
953 nsBaseWidget::BeginResizeDrag(nsGUIEvent
* aEvent
, PRInt32 aHorizontal
, PRInt32 aVertical
)
955 return NS_ERROR_NOT_IMPLEMENTED
;
959 //////////////////////////////////////////////////////////////
961 // Convert a GUI event message code to a string.
962 // Makes it a lot easier to debug events.
964 // See gtk/nsWidget.cpp and windows/nsWindow.cpp
965 // for a DebugPrintEvent() function that uses
968 //////////////////////////////////////////////////////////////
969 /* static */ nsAutoString
970 nsBaseWidget::debug_GuiEventToString(nsGUIEvent
* aGuiEvent
)
972 NS_ASSERTION(nsnull
!= aGuiEvent
,"cmon, null gui event.");
974 nsAutoString
eventName(NS_LITERAL_STRING("UNKNOWN"));
976 #define _ASSIGN_eventName(_value,_name)\
977 case _value: eventName.AssignWithConversion(_name) ; break
979 switch(aGuiEvent
->message
)
981 _ASSIGN_eventName(NS_BLUR_CONTENT
,"NS_BLUR_CONTENT");
982 _ASSIGN_eventName(NS_CONTROL_CHANGE
,"NS_CONTROL_CHANGE");
983 _ASSIGN_eventName(NS_CREATE
,"NS_CREATE");
984 _ASSIGN_eventName(NS_DESTROY
,"NS_DESTROY");
985 _ASSIGN_eventName(NS_DRAGDROP_GESTURE
,"NS_DND_GESTURE");
986 _ASSIGN_eventName(NS_DRAGDROP_DROP
,"NS_DND_DROP");
987 _ASSIGN_eventName(NS_DRAGDROP_ENTER
,"NS_DND_ENTER");
988 _ASSIGN_eventName(NS_DRAGDROP_EXIT
,"NS_DND_EXIT");
989 _ASSIGN_eventName(NS_DRAGDROP_OVER
,"NS_DND_OVER");
990 _ASSIGN_eventName(NS_FOCUS_CONTENT
,"NS_FOCUS_CONTENT");
991 _ASSIGN_eventName(NS_FORM_SELECTED
,"NS_FORM_SELECTED");
992 _ASSIGN_eventName(NS_FORM_CHANGE
,"NS_FORM_CHANGE");
993 _ASSIGN_eventName(NS_FORM_INPUT
,"NS_FORM_INPUT");
994 _ASSIGN_eventName(NS_FORM_RESET
,"NS_FORM_RESET");
995 _ASSIGN_eventName(NS_FORM_SUBMIT
,"NS_FORM_SUBMIT");
996 _ASSIGN_eventName(NS_GOTFOCUS
,"NS_GOTFOCUS");
997 _ASSIGN_eventName(NS_IMAGE_ABORT
,"NS_IMAGE_ABORT");
998 _ASSIGN_eventName(NS_LOAD_ERROR
,"NS_LOAD_ERROR");
999 _ASSIGN_eventName(NS_KEY_DOWN
,"NS_KEY_DOWN");
1000 _ASSIGN_eventName(NS_KEY_PRESS
,"NS_KEY_PRESS");
1001 _ASSIGN_eventName(NS_KEY_UP
,"NS_KEY_UP");
1002 _ASSIGN_eventName(NS_LOSTFOCUS
,"NS_LOSTFOCUS");
1003 _ASSIGN_eventName(NS_MENU_SELECTED
,"NS_MENU_SELECTED");
1004 _ASSIGN_eventName(NS_MOUSE_ENTER
,"NS_MOUSE_ENTER");
1005 _ASSIGN_eventName(NS_MOUSE_EXIT
,"NS_MOUSE_EXIT");
1006 _ASSIGN_eventName(NS_MOUSE_BUTTON_DOWN
,"NS_MOUSE_BUTTON_DOWN");
1007 _ASSIGN_eventName(NS_MOUSE_BUTTON_UP
,"NS_MOUSE_BUTTON_UP");
1008 _ASSIGN_eventName(NS_MOUSE_CLICK
,"NS_MOUSE_CLICK");
1009 _ASSIGN_eventName(NS_MOUSE_DOUBLECLICK
,"NS_MOUSE_DBLCLICK");
1010 _ASSIGN_eventName(NS_MOUSE_MOVE
,"NS_MOUSE_MOVE");
1011 _ASSIGN_eventName(NS_MOVE
,"NS_MOVE");
1012 _ASSIGN_eventName(NS_LOAD
,"NS_LOAD");
1013 _ASSIGN_eventName(NS_PAGE_UNLOAD
,"NS_PAGE_UNLOAD");
1014 _ASSIGN_eventName(NS_PAINT
,"NS_PAINT");
1015 _ASSIGN_eventName(NS_XUL_BROADCAST
, "NS_XUL_BROADCAST");
1016 _ASSIGN_eventName(NS_XUL_COMMAND_UPDATE
, "NS_XUL_COMMAND_UPDATE");
1017 _ASSIGN_eventName(NS_SCROLLBAR_LINE_NEXT
,"NS_SB_LINE_NEXT");
1018 _ASSIGN_eventName(NS_SCROLLBAR_LINE_PREV
,"NS_SB_LINE_PREV");
1019 _ASSIGN_eventName(NS_SCROLLBAR_PAGE_NEXT
,"NS_SB_PAGE_NEXT");
1020 _ASSIGN_eventName(NS_SCROLLBAR_PAGE_PREV
,"NS_SB_PAGE_PREV");
1021 _ASSIGN_eventName(NS_SCROLLBAR_POS
,"NS_SB_POS");
1022 _ASSIGN_eventName(NS_SIZE
,"NS_SIZE");
1024 #undef _ASSIGN_eventName
1030 sprintf(buf
,"UNKNOWN: %d",aGuiEvent
->message
);
1032 eventName
.AssignWithConversion(buf
);
1037 return nsAutoString(eventName
);
1039 //////////////////////////////////////////////////////////////
1041 // Code to deal with paint and event debug prefs.
1043 //////////////////////////////////////////////////////////////
1050 static PrefPair debug_PrefValues
[] =
1052 { "nglayout.debug.crossing_event_dumping", PR_FALSE
},
1053 { "nglayout.debug.event_dumping", PR_FALSE
},
1054 { "nglayout.debug.invalidate_dumping", PR_FALSE
},
1055 { "nglayout.debug.motion_event_dumping", PR_FALSE
},
1056 { "nglayout.debug.paint_dumping", PR_FALSE
},
1057 { "nglayout.debug.paint_flashing", PR_FALSE
}
1060 static PRUint32 debug_NumPrefValues
=
1061 (sizeof(debug_PrefValues
) / sizeof(debug_PrefValues
[0]));
1064 //////////////////////////////////////////////////////////////
1065 static PRBool
debug_GetBoolPref(nsIPrefBranch
* aPrefs
,const char * aPrefName
)
1067 NS_ASSERTION(nsnull
!= aPrefName
,"cmon, pref name is null.");
1068 NS_ASSERTION(nsnull
!= aPrefs
,"cmon, prefs are null.");
1070 PRBool value
= PR_FALSE
;
1074 aPrefs
->GetBoolPref(aPrefName
,&value
);
1079 //////////////////////////////////////////////////////////////
1081 nsBaseWidget::debug_GetCachedBoolPref(const char * aPrefName
)
1083 NS_ASSERTION(nsnull
!= aPrefName
,"cmon, pref name is null.");
1085 for (PRUint32 i
= 0; i
< debug_NumPrefValues
; i
++)
1087 if (strcmp(debug_PrefValues
[i
].name
, aPrefName
) == 0)
1089 return debug_PrefValues
[i
].value
;
1095 //////////////////////////////////////////////////////////////
1096 static void debug_SetCachedBoolPref(const char * aPrefName
,PRBool aValue
)
1098 NS_ASSERTION(nsnull
!= aPrefName
,"cmon, pref name is null.");
1100 for (PRUint32 i
= 0; i
< debug_NumPrefValues
; i
++)
1102 if (strcmp(debug_PrefValues
[i
].name
, aPrefName
) == 0)
1104 debug_PrefValues
[i
].value
= aValue
;
1110 NS_ASSERTION(PR_FALSE
, "cmon, this code is not reached dude.");
1113 //////////////////////////////////////////////////////////////
1114 class Debug_PrefObserver
: public nsIObserver
{
1120 NS_IMPL_ISUPPORTS1(Debug_PrefObserver
, nsIObserver
)
1123 Debug_PrefObserver::Observe(nsISupports
* subject
, const char* topic
,
1124 const PRUnichar
* data
)
1126 nsCOMPtr
<nsIPrefBranch
> branch(do_QueryInterface(subject
));
1127 NS_ASSERTION(branch
, "must implement nsIPrefBranch");
1129 NS_ConvertUTF16toUTF8
prefName(data
);
1131 PRBool value
= PR_FALSE
;
1132 branch
->GetBoolPref(prefName
.get(), &value
);
1133 debug_SetCachedBoolPref(prefName
.get(), value
);
1137 //////////////////////////////////////////////////////////////
1139 debug_RegisterPrefCallbacks()
1141 static PRBool once
= PR_TRUE
;
1147 nsCOMPtr
<nsIPrefBranch2
> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID
));
1149 NS_ASSERTION(prefs
, "Prefs services is null.");
1153 nsCOMPtr
<nsIObserver
> obs(new Debug_PrefObserver());
1154 for (PRUint32 i
= 0; i
< debug_NumPrefValues
; i
++)
1156 // Initialize the pref values
1157 debug_PrefValues
[i
].value
=
1158 debug_GetBoolPref(prefs
,debug_PrefValues
[i
].name
);
1161 // Register callbacks for when these change
1162 prefs
->AddObserver(debug_PrefValues
[i
].name
, obs
, PR_FALSE
);
1168 //////////////////////////////////////////////////////////////
1172 static PRInt32 sCount
= 0;
1176 //////////////////////////////////////////////////////////////
1178 nsBaseWidget::debug_WantPaintFlashing()
1180 return debug_GetCachedBoolPref("nglayout.debug.paint_flashing");
1182 //////////////////////////////////////////////////////////////
1184 nsBaseWidget::debug_DumpEvent(FILE * aFileOut
,
1185 nsIWidget
* aWidget
,
1186 nsGUIEvent
* aGuiEvent
,
1187 const nsCAutoString
& aWidgetName
,
1190 // NS_PAINT is handled by debug_DumpPaintEvent()
1191 if (aGuiEvent
->message
== NS_PAINT
)
1194 if (aGuiEvent
->message
== NS_MOUSE_MOVE
)
1196 if (!debug_GetCachedBoolPref("nglayout.debug.motion_event_dumping"))
1200 if (aGuiEvent
->message
== NS_MOUSE_ENTER
||
1201 aGuiEvent
->message
== NS_MOUSE_EXIT
)
1203 if (!debug_GetCachedBoolPref("nglayout.debug.crossing_event_dumping"))
1207 if (!debug_GetCachedBoolPref("nglayout.debug.event_dumping"))
1210 nsCAutoString tempString
; tempString
.AssignWithConversion(debug_GuiEventToString(aGuiEvent
).get());
1213 "%4d %-26s widget=%-8p name=%-12s id=%-8p refpt=%d,%d\n",
1218 (void *) (aWindowID
? aWindowID
: 0x0),
1219 aGuiEvent
->refPoint
.x
,
1220 aGuiEvent
->refPoint
.y
);
1222 //////////////////////////////////////////////////////////////
1224 nsBaseWidget::debug_DumpPaintEvent(FILE * aFileOut
,
1225 nsIWidget
* aWidget
,
1226 nsPaintEvent
* aPaintEvent
,
1227 const nsCAutoString
& aWidgetName
,
1230 NS_ASSERTION(nsnull
!= aFileOut
,"cmon, null output FILE");
1231 NS_ASSERTION(nsnull
!= aWidget
,"cmon, the widget is null");
1232 NS_ASSERTION(nsnull
!= aPaintEvent
,"cmon, the paint event is null");
1234 if (!debug_GetCachedBoolPref("nglayout.debug.paint_dumping"))
1238 "%4d PAINT widget=%p name=%-12s id=%-8p rect=",
1242 (void *) aWindowID
);
1244 if (aPaintEvent
->rect
)
1247 "%3d,%-3d %3d,%-3d",
1248 aPaintEvent
->rect
->x
,
1249 aPaintEvent
->rect
->y
,
1250 aPaintEvent
->rect
->width
,
1251 aPaintEvent
->rect
->height
);
1255 fprintf(aFileOut
,"none");
1258 fprintf(aFileOut
,"\n");
1260 //////////////////////////////////////////////////////////////
1262 nsBaseWidget::debug_DumpInvalidate(FILE * aFileOut
,
1263 nsIWidget
* aWidget
,
1264 const nsRect
* aRect
,
1265 PRBool aIsSynchronous
,
1266 const nsCAutoString
& aWidgetName
,
1269 if (!debug_GetCachedBoolPref("nglayout.debug.invalidate_dumping"))
1272 NS_ASSERTION(nsnull
!= aFileOut
,"cmon, null output FILE");
1273 NS_ASSERTION(nsnull
!= aWidget
,"cmon, the widget is null");
1276 "%4d Invalidate widget=%p name=%-12s id=%-8p",
1280 (void *) aWindowID
);
1285 " rect=%3d,%-3d %3d,%-3d",
1300 (const char *) (aIsSynchronous
? "yes" : "no "));
1302 fprintf(aFileOut
,"\n");
1304 //////////////////////////////////////////////////////////////