Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / widget / src / xpwidgets / nsBaseWidget.cpp
bloba2307272be1d0a7555de8108998af33644112cad
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
13 * License.
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.
22 * Contributor(s):
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"
41 #include "nsCOMPtr.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"
51 #ifdef DEBUG
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;
60 #endif
62 #ifdef NOISY_WIDGET_LEAKS
63 static PRInt32 gNumWidgets;
64 #endif
66 nsIContent* nsBaseWidget::mLastRollup = nsnull;
68 // nsBaseWidget
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()
94 : mClientData(nsnull)
95 , mEventCallback(nsnull)
96 , mContext(nsnull)
97 , mToolkit(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)
107 , mBounds(0,0,0,0)
108 , mOriginalBounds(nsnull)
109 , mZIndex(0)
110 , mSizeMode(nsSizeMode_Normal)
112 #ifdef NOISY_WIDGET_LEAKS
113 gNumWidgets++;
114 printf("WIDGETS+ = %d\n", gNumWidgets);
115 #endif
117 #ifdef DEBUG
118 debug_RegisterPrefCallbacks();
119 #endif
123 //-------------------------------------------------------------------------
125 // nsBaseWidget destructor
127 //-------------------------------------------------------------------------
128 nsBaseWidget::~nsBaseWidget()
130 #ifdef NOISY_WIDGET_LEAKS
131 gNumWidgets--;
132 printf("WIDGETS- = %d\n", gNumWidgets);
133 #endif
135 NS_IF_RELEASE(mToolkit);
136 NS_IF_RELEASE(mContext);
137 if (mOriginalBounds)
138 delete mOriginalBounds;
142 //-------------------------------------------------------------------------
144 // Basic create.
146 //-------------------------------------------------------------------------
147 void nsBaseWidget::BaseCreate(nsIWidget *aParent,
148 const nsRect &aRect,
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;
158 NS_ADDREF(mToolkit);
160 else {
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)
168 else {
169 static NS_DEFINE_CID(kToolkitCID, NS_TOOLKIT_CID);
171 nsresult res;
172 res = CallCreateInstance(kToolkitCID, &mToolkit);
173 NS_ASSERTION(NS_SUCCEEDED(res), "Can not create a toolkit in nsBaseWidget::Create");
174 if (mToolkit)
175 mToolkit->Init(PR_GetCurrentThread());
177 #else /* USE_TLS_FOR_TOOLKIT */
178 else {
179 nsresult rv;
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
192 if (aContext) {
193 mContext = aContext;
194 NS_ADDREF(mContext);
196 else {
197 nsresult res;
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);
211 if (aParent) {
212 aParent->AddChild(this);
216 NS_IMETHODIMP nsBaseWidget::CaptureMouse(PRBool aCapture)
218 return NS_OK;
221 NS_IMETHODIMP nsBaseWidget::Validate()
223 return NS_OK;
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;
240 return NS_OK;
243 NS_IMETHODIMP nsBaseWidget::SetClientData(void* aClientData)
245 mClientData = aClientData;
246 return NS_OK;
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();
261 if (parent) {
262 parent->RemoveChild(this);
264 // disconnect listeners.
265 NS_IF_RELEASE(mEventListener);
267 return NS_OK;
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)
289 return nsnull;
292 //-------------------------------------------------------------------------
294 // Get this nsBaseWidget top level widget
296 //-------------------------------------------------------------------------
297 nsIWidget* nsBaseWidget::GetTopLevelWidget(PRInt32* aLevelsUp)
299 nsIWidget *topLevelWidget = nsnull, *widget = this;
300 if (aLevelsUp)
301 *aLevelsUp = -1;
302 while (widget) {
303 topLevelWidget = widget;
304 widget = widget->GetParent();
305 if (aLevelsUp)
306 ++*aLevelsUp;
308 return topLevelWidget;
311 //-------------------------------------------------------------------------
313 // Get this nsBaseWidget's top (non-sheet) parent (if it's a sheet)
315 //-------------------------------------------------------------------------
316 nsIWidget* nsBaseWidget::GetSheetWindowParent(void)
318 return nsnull;
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");
331 if (!mFirstChild) {
332 mFirstChild = mLastChild = aChild;
333 } else {
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);
339 mLastChild = aChild;
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();
364 if (prev) {
365 prev->SetNextSibling(next);
367 if (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
384 // from our parent.
385 nsCOMPtr<nsIWidget> kungFuDeathGrip(this);
387 mZIndex = aZIndex;
389 // reorder this child in its parent's list.
390 nsBaseWidget* parent = static_cast<nsBaseWidget*>(GetParent());
391 if (parent) {
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()) {
396 PRInt32 childZIndex;
397 if (NS_SUCCEEDED(sib->GetZIndex(&childZIndex))) {
398 if (aZIndex < childZIndex) {
399 // Insert ourselves before sib
400 nsIWidget* prev = sib->GetPrevSibling();
401 mNextSibling = sib;
402 mPrevSibling = prev;
403 sib->SetPrevSibling(this);
404 if (prev) {
405 prev->SetNextSibling(this);
406 } else {
407 NS_ASSERTION(sib == parent->mFirstChild, "Broken child list");
408 // We've taken ownership of sib, so it's safe to have parent let
409 // go of it
410 parent->mFirstChild = this;
412 PlaceBehind(eZPlacementBelow, sib, PR_FALSE);
413 break;
417 // were we added to the list?
418 if (!sib) {
419 parent->AddChild(this);
422 return NS_OK;
425 //-------------------------------------------------------------------------
427 // Gets widget's position within its parent's child list.
429 //-------------------------------------------------------------------------
430 NS_IMETHODIMP nsBaseWidget::GetZIndex(PRInt32* aZIndex)
432 *aZIndex = mZIndex;
433 return NS_OK;
436 //-------------------------------------------------------------------------
438 // Places widget behind the given widget (platforms must override)
440 //-------------------------------------------------------------------------
441 NS_IMETHODIMP nsBaseWidget::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
442 nsIWidget *aWidget, PRBool aActivate)
444 return NS_OK;
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;
459 return NS_OK;
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) {
471 *aMode = mSizeMode;
472 return NS_OK;
475 //-------------------------------------------------------------------------
477 // Get the foreground color
479 //-------------------------------------------------------------------------
480 nscolor nsBaseWidget::GetForegroundColor(void)
482 return mForeground;
486 //-------------------------------------------------------------------------
488 // Set the foreground color
490 //-------------------------------------------------------------------------
491 NS_METHOD nsBaseWidget::SetForegroundColor(const nscolor &aColor)
493 mForeground = aColor;
494 return NS_OK;
498 //-------------------------------------------------------------------------
500 // Get the background color
502 //-------------------------------------------------------------------------
503 nscolor nsBaseWidget::GetBackgroundColor(void)
505 return mBackground;
508 //-------------------------------------------------------------------------
510 // Set the background color
512 //-------------------------------------------------------------------------
513 NS_METHOD nsBaseWidget::SetBackgroundColor(const nscolor &aColor)
515 mBackground = aColor;
516 return NS_OK;
519 //-------------------------------------------------------------------------
521 // Get this component cursor
523 //-------------------------------------------------------------------------
524 nsCursor nsBaseWidget::GetCursor()
526 return mCursor;
529 NS_METHOD nsBaseWidget::SetCursor(nsCursor aCursor)
531 mCursor = aCursor;
532 return NS_OK;
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;
549 return NS_OK;
552 NS_IMETHODIMP nsBaseWidget::SetWindowType(nsWindowType aWindowType)
554 mWindowType = aWindowType;
555 return NS_OK;
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");
603 if (aFullScreen) {
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.");
612 if (screenManager) {
613 nsCOMPtr<nsIScreen> screen;
614 screenManager->ScreenForRect(mOriginalBounds->x, mOriginalBounds->y,
615 mOriginalBounds->width, mOriginalBounds->height,
616 getter_AddRefs(screen));
617 if (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
624 if (fullScreen)
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
635 if (fullScreen)
636 fullScreen->ShowAllOSChrome();
639 return NS_OK;
642 //-------------------------------------------------------------------------
644 // Create a rendering context from this nsBaseWidget
646 //-------------------------------------------------------------------------
647 nsIRenderingContext* nsBaseWidget::GetRenderingContext()
649 nsresult rv;
650 nsCOMPtr<nsIRenderingContext> renderingCtx;
652 if (mOnDestroyCalled)
653 return nsnull;
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... */
664 NS_ADDREF(ret);
665 return ret;
667 else {
668 NS_WARNING("GetRenderingContext: nsIRenderingContext::Init() failed.");
671 else {
672 NS_WARNING("GetRenderingContext: Cannot create RenderingContext.");
675 return nsnull;
678 //-------------------------------------------------------------------------
680 // Return the toolkit this widget was created on
682 //-------------------------------------------------------------------------
683 nsIToolkit* nsBaseWidget::GetToolkit()
685 return mToolkit;
689 //-------------------------------------------------------------------------
691 // Return the used device context
693 //-------------------------------------------------------------------------
694 nsIDeviceContext* nsBaseWidget::GetDeviceContext()
696 return mContext;
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
708 return nsnull;
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;
732 return NS_OK;
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;
746 return NS_OK;
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)
764 aRect = mBounds;
765 return NS_OK;
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)
784 mBounds = aRect;
786 return NS_OK;
792 * Calculates the border width and height
795 NS_METHOD nsBaseWidget::GetBorderSize(PRInt32 &aWidth, PRInt32 &aHeight)
797 nsRect rectWin;
798 nsRect rect;
799 GetBounds(rectWin);
800 GetClientBounds(rect);
802 aWidth = (rectWin.width - rect.width) / 2;
803 aHeight = (rectWin.height - rect.height) / 2;
805 return NS_OK;
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)
820 return NS_OK;
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,
830 PRBool *aForWindow)
832 *aForWindow = PR_TRUE;
833 return NS_OK;
836 NS_IMETHODIMP
837 nsBaseWidget::GetAttention(PRInt32 aCycleCount) {
838 return NS_OK;
841 NS_IMETHODIMP
842 nsBaseWidget::GetLastInputEventTime(PRUint32& aTime) {
843 return NS_ERROR_NOT_IMPLEMENTED;
846 NS_IMETHODIMP
847 nsBaseWidget::SetIcon(const nsAString&)
849 return NS_OK;
852 NS_IMETHODIMP
853 nsBaseWidget::BeginSecureKeyboardInput()
855 #ifdef DEBUG
856 NS_ASSERTION(!debug_InSecureKeyboardInputMode, "Attempting to nest call to BeginSecureKeyboardInput!");
857 debug_InSecureKeyboardInputMode = PR_TRUE;
858 #endif
859 return NS_OK;
862 NS_IMETHODIMP
863 nsBaseWidget::EndSecureKeyboardInput()
865 #ifdef DEBUG
866 NS_ASSERTION(debug_InSecureKeyboardInputMode, "Calling EndSecureKeyboardInput when it hasn't been enabled!");
867 debug_InSecureKeyboardInputMode = PR_FALSE;
868 #endif
869 return NS_OK;
872 NS_IMETHODIMP
873 nsBaseWidget::SetWindowTitlebarColor(nscolor aColor, PRBool aActive)
875 return NS_ERROR_NOT_IMPLEMENTED;
878 PRBool
879 nsBaseWidget::ShowsResizeIndicator(nsIntRect* aResizerRect)
881 return PR_FALSE;
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.
890 static PRBool
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);
899 PRBool readable;
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.
910 void
911 nsBaseWidget::ResolveIconName(const nsAString &aIconName,
912 const nsAString &aIconSuffix,
913 nsILocalFile **aResult)
915 *aResult = nsnull;
917 nsCOMPtr<nsIProperties> dirSvc = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
918 if (!dirSvc)
919 return;
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));
926 if (dirs) {
927 PRBool hasMore;
928 while (NS_SUCCEEDED(dirs->HasMoreElements(&hasMore)) && hasMore) {
929 nsCOMPtr<nsISupports> element;
930 dirs->GetNext(getter_AddRefs(element));
931 if (!element)
932 continue;
933 nsCOMPtr<nsILocalFile> file = do_QueryInterface(element);
934 if (!file)
935 continue;
936 if (ResolveIconNameHelper(file, aIconName, aIconSuffix)) {
937 NS_ADDREF(*aResult = file);
938 return;
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);
952 NS_IMETHODIMP
953 nsBaseWidget::BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical)
955 return NS_ERROR_NOT_IMPLEMENTED;
958 #ifdef DEBUG
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
966 // this.
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
1026 default:
1028 char buf[32];
1030 sprintf(buf,"UNKNOWN: %d",aGuiEvent->message);
1032 eventName.AssignWithConversion(buf);
1034 break;
1037 return nsAutoString(eventName);
1039 //////////////////////////////////////////////////////////////
1041 // Code to deal with paint and event debug prefs.
1043 //////////////////////////////////////////////////////////////
1044 struct PrefPair
1046 const char * name;
1047 PRBool value;
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;
1072 if (aPrefs)
1074 aPrefs->GetBoolPref(aPrefName,&value);
1077 return value;
1079 //////////////////////////////////////////////////////////////
1080 PRBool
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;
1093 return PR_FALSE;
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;
1106 return;
1110 NS_ASSERTION(PR_FALSE, "cmon, this code is not reached dude.");
1113 //////////////////////////////////////////////////////////////
1114 class Debug_PrefObserver : public nsIObserver {
1115 public:
1116 NS_DECL_ISUPPORTS
1117 NS_DECL_NSIOBSERVER
1120 NS_IMPL_ISUPPORTS1(Debug_PrefObserver, nsIObserver)
1122 NS_IMETHODIMP
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);
1134 return NS_OK;
1137 //////////////////////////////////////////////////////////////
1138 /* static */ void
1139 debug_RegisterPrefCallbacks()
1141 static PRBool once = PR_TRUE;
1143 if (once)
1145 once = PR_FALSE;
1147 nsCOMPtr<nsIPrefBranch2> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
1149 NS_ASSERTION(prefs, "Prefs services is null.");
1151 if (prefs)
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);
1160 if (obs) {
1161 // Register callbacks for when these change
1162 prefs->AddObserver(debug_PrefValues[i].name, obs, PR_FALSE);
1168 //////////////////////////////////////////////////////////////
1169 static PRInt32
1170 _GetPrintCount()
1172 static PRInt32 sCount = 0;
1174 return ++sCount;
1176 //////////////////////////////////////////////////////////////
1177 /* static */ PRBool
1178 nsBaseWidget::debug_WantPaintFlashing()
1180 return debug_GetCachedBoolPref("nglayout.debug.paint_flashing");
1182 //////////////////////////////////////////////////////////////
1183 /* static */ void
1184 nsBaseWidget::debug_DumpEvent(FILE * aFileOut,
1185 nsIWidget * aWidget,
1186 nsGUIEvent * aGuiEvent,
1187 const nsCAutoString & aWidgetName,
1188 PRInt32 aWindowID)
1190 // NS_PAINT is handled by debug_DumpPaintEvent()
1191 if (aGuiEvent->message == NS_PAINT)
1192 return;
1194 if (aGuiEvent->message == NS_MOUSE_MOVE)
1196 if (!debug_GetCachedBoolPref("nglayout.debug.motion_event_dumping"))
1197 return;
1200 if (aGuiEvent->message == NS_MOUSE_ENTER ||
1201 aGuiEvent->message == NS_MOUSE_EXIT)
1203 if (!debug_GetCachedBoolPref("nglayout.debug.crossing_event_dumping"))
1204 return;
1207 if (!debug_GetCachedBoolPref("nglayout.debug.event_dumping"))
1208 return;
1210 nsCAutoString tempString; tempString.AssignWithConversion(debug_GuiEventToString(aGuiEvent).get());
1212 fprintf(aFileOut,
1213 "%4d %-26s widget=%-8p name=%-12s id=%-8p refpt=%d,%d\n",
1214 _GetPrintCount(),
1215 tempString.get(),
1216 (void *) aWidget,
1217 aWidgetName.get(),
1218 (void *) (aWindowID ? aWindowID : 0x0),
1219 aGuiEvent->refPoint.x,
1220 aGuiEvent->refPoint.y);
1222 //////////////////////////////////////////////////////////////
1223 /* static */ void
1224 nsBaseWidget::debug_DumpPaintEvent(FILE * aFileOut,
1225 nsIWidget * aWidget,
1226 nsPaintEvent * aPaintEvent,
1227 const nsCAutoString & aWidgetName,
1228 PRInt32 aWindowID)
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"))
1235 return;
1237 fprintf(aFileOut,
1238 "%4d PAINT widget=%p name=%-12s id=%-8p rect=",
1239 _GetPrintCount(),
1240 (void *) aWidget,
1241 aWidgetName.get(),
1242 (void *) aWindowID);
1244 if (aPaintEvent->rect)
1246 fprintf(aFileOut,
1247 "%3d,%-3d %3d,%-3d",
1248 aPaintEvent->rect->x,
1249 aPaintEvent->rect->y,
1250 aPaintEvent->rect->width,
1251 aPaintEvent->rect->height);
1253 else
1255 fprintf(aFileOut,"none");
1258 fprintf(aFileOut,"\n");
1260 //////////////////////////////////////////////////////////////
1261 /* static */ void
1262 nsBaseWidget::debug_DumpInvalidate(FILE * aFileOut,
1263 nsIWidget * aWidget,
1264 const nsRect * aRect,
1265 PRBool aIsSynchronous,
1266 const nsCAutoString & aWidgetName,
1267 PRInt32 aWindowID)
1269 if (!debug_GetCachedBoolPref("nglayout.debug.invalidate_dumping"))
1270 return;
1272 NS_ASSERTION(nsnull != aFileOut,"cmon, null output FILE");
1273 NS_ASSERTION(nsnull != aWidget,"cmon, the widget is null");
1275 fprintf(aFileOut,
1276 "%4d Invalidate widget=%p name=%-12s id=%-8p",
1277 _GetPrintCount(),
1278 (void *) aWidget,
1279 aWidgetName.get(),
1280 (void *) aWindowID);
1282 if (aRect)
1284 fprintf(aFileOut,
1285 " rect=%3d,%-3d %3d,%-3d",
1286 aRect->x,
1287 aRect->y,
1288 aRect->width,
1289 aRect->height);
1291 else
1293 fprintf(aFileOut,
1294 " rect=%-15s",
1295 "none");
1298 fprintf(aFileOut,
1299 " sync=%s",
1300 (const char *) (aIsSynchronous ? "yes" : "no "));
1302 fprintf(aFileOut,"\n");
1304 //////////////////////////////////////////////////////////////
1306 #endif // DEBUG