Back to index

lightning-sunbird  0.9+nobinonly
nsBaseWidget.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Dean Tessman <dean_tessman@hotmail.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsBaseWidget.h"
00040 #include "nsIDeviceContext.h"
00041 #include "nsCOMPtr.h"
00042 #include "nsIMenuListener.h"
00043 #include "nsIEnumerator.h"
00044 #include "nsGfxCIID.h"
00045 #include "nsWidgetsCID.h"
00046 #include "nsIFullScreen.h"
00047 #include "nsServiceManagerUtils.h"
00048 #include "nsIScreenManager.h"
00049 #include "nsAppDirectoryServiceDefs.h"
00050 
00051 #ifdef DEBUG
00052 #include "nsIServiceManager.h"
00053 #include "nsIPref.h"
00054 
00055 static void debug_RegisterPrefCallbacks();
00056 
00057 #endif
00058 
00059 #ifdef NOISY_WIDGET_LEAKS
00060 static PRInt32 gNumWidgets;
00061 #endif
00062 
00063 // nsBaseWidget
00064 NS_IMPL_ISUPPORTS1(nsBaseWidget, nsIWidget)
00065 
00066 
00067 //-------------------------------------------------------------------------
00068 //
00069 // nsBaseWidget constructor
00070 //
00071 //-------------------------------------------------------------------------
00072 
00073 nsBaseWidget::nsBaseWidget()
00074 : mClientData(nsnull)
00075 , mEventCallback(nsnull)
00076 , mContext(nsnull)
00077 , mToolkit(nsnull)
00078 , mMouseListener(nsnull)
00079 , mEventListener(nsnull)
00080 , mMenuListener(nsnull)
00081 , mCursor(eCursor_standard)
00082 , mWindowType(eWindowType_child)
00083 , mBorderStyle(eBorderStyle_none)
00084 , mIsShiftDown(PR_FALSE)
00085 , mIsControlDown(PR_FALSE)
00086 , mIsAltDown(PR_FALSE)
00087 , mIsDestroying(PR_FALSE)
00088 , mOnDestroyCalled(PR_FALSE)
00089 , mBounds(0,0,0,0)
00090 , mOriginalBounds(nsnull)
00091 , mZIndex(0)
00092 , mSizeMode(nsSizeMode_Normal)
00093 {
00094 #ifdef NOISY_WIDGET_LEAKS
00095   gNumWidgets++;
00096   printf("WIDGETS+ = %d\n", gNumWidgets);
00097 #endif
00098 
00099 #ifdef DEBUG
00100     debug_RegisterPrefCallbacks();
00101 #endif
00102 }
00103 
00104 
00105 //-------------------------------------------------------------------------
00106 //
00107 // nsBaseWidget destructor
00108 //
00109 //-------------------------------------------------------------------------
00110 nsBaseWidget::~nsBaseWidget()
00111 {
00112 #ifdef NOISY_WIDGET_LEAKS
00113   gNumWidgets--;
00114   printf("WIDGETS- = %d\n", gNumWidgets);
00115 #endif
00116 
00117   NS_IF_RELEASE(mMenuListener);
00118   NS_IF_RELEASE(mToolkit);
00119   NS_IF_RELEASE(mContext);
00120   if (mOriginalBounds)
00121     delete mOriginalBounds;
00122 }
00123 
00124 
00125 //-------------------------------------------------------------------------
00126 //
00127 // Basic create.
00128 //
00129 //-------------------------------------------------------------------------
00130 void nsBaseWidget::BaseCreate(nsIWidget *aParent,
00131                               const nsRect &aRect,
00132                               EVENT_CALLBACK aHandleEventFunction,
00133                               nsIDeviceContext *aContext,
00134                               nsIAppShell *aAppShell,
00135                               nsIToolkit *aToolkit,
00136                               nsWidgetInitData *aInitData)
00137 {
00138   if (nsnull == mToolkit) {
00139     if (nsnull != aToolkit) {
00140       mToolkit = (nsIToolkit*)aToolkit;
00141       NS_ADDREF(mToolkit);
00142     }
00143     else {
00144       if (nsnull != aParent) {
00145         mToolkit = (nsIToolkit*)(aParent->GetToolkit()); // the call AddRef's, we don't have to
00146       }
00147       // it's some top level window with no toolkit passed in.
00148       // Create a default toolkit with the current thread
00149 #if !defined(USE_TLS_FOR_TOOLKIT)
00150       else {
00151         static NS_DEFINE_CID(kToolkitCID, NS_TOOLKIT_CID);
00152         
00153         nsresult res;
00154         res = CallCreateInstance(kToolkitCID, &mToolkit);
00155         NS_ASSERTION(NS_SUCCEEDED(res), "Can not create a toolkit in nsBaseWidget::Create");
00156         if (mToolkit)
00157           mToolkit->Init(PR_GetCurrentThread());
00158       }
00159 #else /* USE_TLS_FOR_TOOLKIT */
00160       else {
00161         nsresult rv;
00162 
00163         rv = NS_GetCurrentToolkit(&mToolkit);
00164       }
00165 #endif /* USE_TLS_FOR_TOOLKIT */
00166     }
00167     
00168   }
00169   
00170   mAppShell = aAppShell;    // addrefs
00171   
00172   // save the event callback function
00173   mEventCallback = aHandleEventFunction;
00174   
00175   // keep a reference to the device context
00176   if (aContext) {
00177     mContext = aContext;
00178     NS_ADDREF(mContext);
00179   }
00180   else {
00181     nsresult  res;
00182     
00183     static NS_DEFINE_CID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID);
00184     
00185     res = CallCreateInstance(kDeviceContextCID, &mContext);
00186 
00187     if (NS_SUCCEEDED(res))
00188       mContext->Init(nsnull);
00189   }
00190 
00191   if (nsnull != aInitData) {
00192     PreCreateWidget(aInitData);
00193   }
00194 
00195   if (aParent) {
00196     aParent->AddChild(this);
00197   }
00198 }
00199 
00200 NS_IMETHODIMP nsBaseWidget::CaptureMouse(PRBool aCapture)
00201 {
00202   return NS_OK;
00203 }
00204 
00205 NS_IMETHODIMP nsBaseWidget::Validate()
00206 {
00207   return NS_OK;
00208 }
00209 
00210 NS_IMETHODIMP nsBaseWidget::InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous)
00211 {
00212   return NS_ERROR_FAILURE;
00213 }
00214 
00215 //-------------------------------------------------------------------------
00216 //
00217 // Accessor functions to get/set the client data
00218 //
00219 //-------------------------------------------------------------------------
00220 
00221 NS_IMETHODIMP nsBaseWidget::GetClientData(void*& aClientData)
00222 {
00223   aClientData = mClientData;
00224   return NS_OK;
00225 }
00226 
00227 NS_IMETHODIMP nsBaseWidget::SetClientData(void* aClientData)
00228 {
00229   mClientData = aClientData;
00230   return NS_OK;
00231 }
00232 
00233 //-------------------------------------------------------------------------
00234 //
00235 // Close this nsBaseWidget
00236 //
00237 //-------------------------------------------------------------------------
00238 NS_METHOD nsBaseWidget::Destroy()
00239 {
00240   // Just in case our parent is the only ref to us
00241   nsCOMPtr<nsIWidget> kungFuDeathGrip(this);
00242   
00243   // disconnect from the parent
00244   nsIWidget *parent = GetParent();
00245   if (parent) {
00246     parent->RemoveChild(this);
00247     NS_RELEASE(parent);
00248   }
00249   // disconnect listeners.
00250   NS_IF_RELEASE(mMouseListener);
00251   NS_IF_RELEASE(mEventListener);
00252   NS_IF_RELEASE(mMenuListener);
00253 
00254   return NS_OK;
00255 }
00256 
00257 
00258 //-------------------------------------------------------------------------
00259 //
00260 // Set this nsBaseWidget's parent
00261 //
00262 //-------------------------------------------------------------------------
00263 NS_IMETHODIMP nsBaseWidget::SetParent(nsIWidget* aNewParent)
00264 {
00265   return NS_ERROR_NOT_IMPLEMENTED;
00266 }
00267 
00268 
00269 //-------------------------------------------------------------------------
00270 //
00271 // Get this nsBaseWidget parent
00272 //
00273 //-------------------------------------------------------------------------
00274 nsIWidget* nsBaseWidget::GetParent(void)
00275 {
00276   return nsnull;
00277 }
00278 
00279 //-------------------------------------------------------------------------
00280 //
00281 // Add a child to the list of children
00282 //
00283 //-------------------------------------------------------------------------
00284 void nsBaseWidget::AddChild(nsIWidget* aChild)
00285 {
00286   NS_PRECONDITION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(),
00287                   "aChild not properly removed from its old child list");
00288   
00289   if (!mFirstChild) {
00290     mFirstChild = mLastChild = aChild;
00291   } else {
00292     // append to the list
00293     NS_ASSERTION(mLastChild, "Bogus state");
00294     NS_ASSERTION(!mLastChild->GetNextSibling(), "Bogus state");
00295     mLastChild->SetNextSibling(aChild);
00296     aChild->SetPrevSibling(mLastChild);
00297     mLastChild = aChild;
00298   }
00299 }
00300 
00301 
00302 //-------------------------------------------------------------------------
00303 //
00304 // Remove a child from the list of children
00305 //
00306 //-------------------------------------------------------------------------
00307 void nsBaseWidget::RemoveChild(nsIWidget* aChild)
00308 {
00309   NS_ASSERTION(nsCOMPtr<nsIWidget>(dont_AddRef(aChild->GetParent())) ==
00310                  NS_STATIC_CAST(nsIWidget*, this),
00311                "Not one of our kids!");
00312   
00313   if (mLastChild == aChild) {
00314     mLastChild = mLastChild->GetPrevSibling();
00315   }
00316   if (mFirstChild == aChild) {
00317     mFirstChild = mFirstChild->GetNextSibling();
00318   }
00319 
00320   // Now remove from the list.  Make sure that we pass ownership of the tail
00321   // of the list correctly before we have aChild let go of it.
00322   nsIWidget* prev = aChild->GetPrevSibling();
00323   nsIWidget* next = aChild->GetNextSibling();
00324   if (prev) {
00325     prev->SetNextSibling(next);
00326   }
00327   if (next) {
00328     next->SetPrevSibling(prev);
00329   }
00330   
00331   aChild->SetNextSibling(nsnull);
00332   aChild->SetPrevSibling(nsnull);
00333 }
00334 
00335 
00336 //-------------------------------------------------------------------------
00337 //
00338 // Sets widget's position within its parent's child list.
00339 //
00340 //-------------------------------------------------------------------------
00341 NS_IMETHODIMP nsBaseWidget::SetZIndex(PRInt32 aZIndex)
00342 {
00343   mZIndex = aZIndex;
00344 
00345   // reorder this child in its parent's list.
00346   nsBaseWidget* parent = NS_STATIC_CAST(nsBaseWidget*, GetParent());
00347   if (parent) {
00348     parent->RemoveChild(this);
00349     // Scope sib outside the for loop so we can check it afterward
00350     nsIWidget* sib = parent->GetFirstChild();
00351     for ( ; sib; sib = sib->GetNextSibling()) {
00352       PRInt32 childZIndex;
00353       if (NS_SUCCEEDED(sib->GetZIndex(&childZIndex))) {
00354         if (aZIndex < childZIndex) {
00355           // Insert ourselves before sib
00356           nsIWidget* prev = sib->GetPrevSibling();
00357           mNextSibling = sib;
00358           mPrevSibling = prev;
00359           sib->SetPrevSibling(this);
00360           if (prev) {
00361             prev->SetNextSibling(this);
00362           } else {
00363             NS_ASSERTION(sib == parent->mFirstChild, "Broken child list");
00364             // We've taken ownership of sib, so it's safe to have parent let
00365             // go of it
00366             parent->mFirstChild = this;
00367           }
00368           PlaceBehind(eZPlacementBelow, sib, PR_FALSE);
00369           break;
00370         }
00371       }
00372     }
00373     // were we added to the list?
00374     if (!sib) {
00375       parent->AddChild(this);
00376     }
00377     
00378     NS_RELEASE(parent);
00379   }
00380   return NS_OK;
00381 }
00382 
00383 //-------------------------------------------------------------------------
00384 //
00385 // Gets widget's position within its parent's child list.
00386 //
00387 //-------------------------------------------------------------------------
00388 NS_IMETHODIMP nsBaseWidget::GetZIndex(PRInt32* aZIndex)
00389 {
00390   *aZIndex = mZIndex;
00391   return NS_OK;
00392 }
00393 
00394 //-------------------------------------------------------------------------
00395 //
00396 // Places widget behind the given widget (platforms must override)
00397 //
00398 //-------------------------------------------------------------------------
00399 NS_IMETHODIMP nsBaseWidget::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
00400                                         nsIWidget *aWidget, PRBool aActivate)
00401 {
00402   return NS_OK;
00403 }
00404 
00405 //-------------------------------------------------------------------------
00406 //
00407 // Maximize, minimize or restore the window. The BaseWidget implementation
00408 // merely stores the state.
00409 //
00410 //-------------------------------------------------------------------------
00411 NS_IMETHODIMP nsBaseWidget::SetSizeMode(PRInt32 aMode) {
00412 
00413   if (aMode == nsSizeMode_Normal || aMode == nsSizeMode_Minimized ||
00414       aMode == nsSizeMode_Maximized) {
00415 
00416     mSizeMode = (nsSizeMode) aMode;
00417     return NS_OK;
00418   }
00419   return NS_ERROR_ILLEGAL_VALUE;
00420 }
00421 
00422 //-------------------------------------------------------------------------
00423 //
00424 // Get the size mode (minimized, maximized, that sort of thing...)
00425 //
00426 //-------------------------------------------------------------------------
00427 NS_IMETHODIMP nsBaseWidget::GetSizeMode(PRInt32* aMode) {
00428 
00429   *aMode = mSizeMode;
00430   return NS_OK;
00431 }
00432 
00433 //-------------------------------------------------------------------------
00434 //
00435 // Get the foreground color
00436 //
00437 //-------------------------------------------------------------------------
00438 nscolor nsBaseWidget::GetForegroundColor(void)
00439 {
00440   return mForeground;
00441 }
00442 
00443     
00444 //-------------------------------------------------------------------------
00445 //
00446 // Set the foreground color
00447 //
00448 //-------------------------------------------------------------------------
00449 NS_METHOD nsBaseWidget::SetForegroundColor(const nscolor &aColor)
00450 {
00451   mForeground = aColor;
00452   return NS_OK;
00453 }
00454 
00455     
00456 //-------------------------------------------------------------------------
00457 //
00458 // Get the background color
00459 //
00460 //-------------------------------------------------------------------------
00461 nscolor nsBaseWidget::GetBackgroundColor(void)
00462 {
00463   return mBackground;
00464 }
00465 
00466 //-------------------------------------------------------------------------
00467 //
00468 // Set the background color
00469 //
00470 //-------------------------------------------------------------------------
00471 NS_METHOD nsBaseWidget::SetBackgroundColor(const nscolor &aColor)
00472 {
00473   mBackground = aColor;
00474   return NS_OK;
00475 }
00476      
00477 //-------------------------------------------------------------------------
00478 //
00479 // Get this component cursor
00480 //
00481 //-------------------------------------------------------------------------
00482 nsCursor nsBaseWidget::GetCursor()
00483 {
00484   return mCursor;
00485 }
00486 
00487 NS_METHOD nsBaseWidget::SetCursor(nsCursor aCursor)
00488 {
00489   mCursor = aCursor; 
00490   return NS_OK;
00491 }
00492 
00493 NS_IMETHODIMP nsBaseWidget::SetCursor(imgIContainer* aCursor,
00494                                       PRUint32 aHotspotX, PRUint32 aHotspotY)
00495 {
00496   return NS_ERROR_NOT_IMPLEMENTED;
00497 }
00498     
00499 //-------------------------------------------------------------------------
00500 //
00501 // Get the window type for this widget
00502 //
00503 //-------------------------------------------------------------------------
00504 NS_IMETHODIMP nsBaseWidget::GetWindowType(nsWindowType& aWindowType)
00505 {
00506   aWindowType = mWindowType;
00507   return NS_OK;
00508 }
00509 
00510 NS_IMETHODIMP nsBaseWidget::SetWindowType(nsWindowType aWindowType) 
00511 {
00512   mWindowType = aWindowType;
00513   return NS_OK;
00514 }
00515 
00516 //-------------------------------------------------------------------------
00517 //
00518 // Window transparency methods
00519 //
00520 //-------------------------------------------------------------------------
00521 
00522 NS_IMETHODIMP nsBaseWidget::SetWindowTranslucency(PRBool aTranslucent) {
00523   return NS_ERROR_NOT_IMPLEMENTED;
00524 }
00525 
00526 NS_IMETHODIMP nsBaseWidget::GetWindowTranslucency(PRBool& aTranslucent) {
00527   aTranslucent = PR_FALSE;
00528   return NS_OK;
00529 }
00530 
00531 NS_IMETHODIMP nsBaseWidget::UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas) {
00532   NS_ASSERTION(PR_FALSE, "Window is not translucent");
00533   return NS_ERROR_NOT_IMPLEMENTED;
00534 }
00535 
00536 //-------------------------------------------------------------------------
00537 //
00538 // Hide window borders/decorations for this widget
00539 //
00540 //-------------------------------------------------------------------------
00541 NS_IMETHODIMP nsBaseWidget::HideWindowChrome(PRBool aShouldHide)
00542 {
00543   return NS_ERROR_NOT_IMPLEMENTED;
00544 }
00545 
00546 //-------------------------------------------------------------------------
00547 //
00548 // Put the window into full-screen mode
00549 //
00550 //-------------------------------------------------------------------------
00551 NS_IMETHODIMP nsBaseWidget::MakeFullScreen(PRBool aFullScreen)
00552 {
00553   HideWindowChrome(aFullScreen);
00554   return MakeFullScreenInternal(aFullScreen);
00555 }
00556 
00557 nsresult nsBaseWidget::MakeFullScreenInternal(PRBool aFullScreen)
00558 {
00559   nsCOMPtr<nsIFullScreen> fullScreen = do_GetService("@mozilla.org/browser/fullscreen;1");
00560 
00561   if (aFullScreen) {
00562     if (!mOriginalBounds)
00563       mOriginalBounds = new nsRect();
00564     GetScreenBounds(*mOriginalBounds);
00565 
00566     // Move to top-left corner of screen and size to the screen dimensions
00567     nsCOMPtr<nsIScreenManager> screenManager;
00568     screenManager = do_GetService("@mozilla.org/gfx/screenmanager;1"); 
00569     NS_ASSERTION(screenManager, "Unable to grab screenManager.");
00570     if (screenManager) {
00571       nsCOMPtr<nsIScreen> screen;
00572       screenManager->ScreenForRect(mOriginalBounds->x, mOriginalBounds->y,
00573                                    mOriginalBounds->width, mOriginalBounds->height,
00574                                    getter_AddRefs(screen));
00575       if (screen) {
00576         PRInt32 left, top, width, height;
00577         if (NS_SUCCEEDED(screen->GetRect(&left, &top, &width, &height))) {
00578           SetSizeMode(nsSizeMode_Normal);
00579           Resize(left, top, width, height, PR_TRUE);
00580     
00581           // Hide all of the OS chrome
00582           if (fullScreen)
00583             fullScreen->HideAllOSChrome();
00584         }
00585       }
00586     }
00587 
00588   } else if (mOriginalBounds) {
00589     Resize(mOriginalBounds->x, mOriginalBounds->y, mOriginalBounds->width,
00590            mOriginalBounds->height, PR_TRUE);
00591 
00592     // Show all of the OS chrome
00593     if (fullScreen)
00594       fullScreen->ShowAllOSChrome();
00595   }
00596 
00597   return NS_OK;
00598 }
00599 
00600 //-------------------------------------------------------------------------
00601 //
00602 // Create a rendering context from this nsBaseWidget
00603 //
00604 //-------------------------------------------------------------------------
00605 nsIRenderingContext* nsBaseWidget::GetRenderingContext()
00606 {
00607   nsresult                      rv;
00608   nsCOMPtr<nsIRenderingContext> renderingCtx;
00609 
00610   if (mOnDestroyCalled)
00611     return nsnull;
00612 
00613   rv = mContext->CreateRenderingContextInstance(*getter_AddRefs(renderingCtx));
00614   if (NS_SUCCEEDED(rv)) {
00615     rv = renderingCtx->Init(mContext, this);
00616     if (NS_SUCCEEDED(rv)) {
00617       nsIRenderingContext *ret = renderingCtx;
00618       /* Increment object refcount that the |ret| object is still a valid one
00619        * after we leave this function... */
00620       NS_ADDREF(ret);
00621       return ret;
00622     }
00623     else {
00624       NS_WARNING("GetRenderingContext: nsIRenderingContext::Init() failed.");
00625     }  
00626   }
00627   else {
00628     NS_WARNING("GetRenderingContext: Cannot create RenderingContext.");
00629   }  
00630   
00631   return nsnull;
00632 }
00633 
00634 //-------------------------------------------------------------------------
00635 //
00636 // Return the toolkit this widget was created on
00637 //
00638 //-------------------------------------------------------------------------
00639 nsIToolkit* nsBaseWidget::GetToolkit()
00640 {
00641   NS_IF_ADDREF(mToolkit);
00642   return mToolkit;
00643 }
00644 
00645 
00646 //-------------------------------------------------------------------------
00647 //
00648 // Return the used device context
00649 //
00650 //-------------------------------------------------------------------------
00651 nsIDeviceContext* nsBaseWidget::GetDeviceContext() 
00652 {
00653   NS_IF_ADDREF(mContext);
00654   return mContext; 
00655 }
00656 
00657 //-------------------------------------------------------------------------
00658 //
00659 // Return the App Shell
00660 //
00661 //-------------------------------------------------------------------------
00662 
00663 nsIAppShell *nsBaseWidget::GetAppShell()
00664 {
00665   nsIAppShell*  theAppShell = mAppShell;
00666   NS_IF_ADDREF(theAppShell);
00667   return theAppShell;
00668 }
00669 
00670 
00671 //-------------------------------------------------------------------------
00672 //
00673 // Destroy the window
00674 //
00675 //-------------------------------------------------------------------------
00676 void nsBaseWidget::OnDestroy()
00677 {
00678   // release references to device context, toolkit, and app shell
00679   NS_IF_RELEASE(mContext);
00680   NS_IF_RELEASE(mToolkit);
00681   mAppShell = nsnull;     // clear out nsCOMPtr
00682 }
00683 
00684 NS_METHOD nsBaseWidget::GetWindowClass(char *aClass)
00685 {
00686   return NS_ERROR_NOT_IMPLEMENTED;
00687 }
00688 
00689 NS_METHOD nsBaseWidget::SetWindowClass(char *aClass)
00690 {
00691   return NS_ERROR_NOT_IMPLEMENTED;
00692 }
00693 
00694 NS_METHOD nsBaseWidget::SetBorderStyle(nsBorderStyle aBorderStyle)
00695 {
00696   mBorderStyle = aBorderStyle;
00697   return NS_OK;
00698 }
00699 
00700 
00705 NS_METHOD nsBaseWidget::AddMouseListener(nsIMouseListener * aListener)
00706 {
00707   NS_PRECONDITION(mMouseListener == nsnull, "Null mouse listener");
00708   NS_IF_RELEASE(mMouseListener);
00709   NS_ADDREF(aListener);
00710   mMouseListener = aListener;
00711   return NS_OK;
00712 }
00713 
00718 NS_METHOD nsBaseWidget::AddEventListener(nsIEventListener * aListener)
00719 {
00720   NS_PRECONDITION(mEventListener == nsnull, "Null mouse listener");
00721   NS_IF_RELEASE(mEventListener);
00722   NS_ADDREF(aListener);
00723   mEventListener = aListener;
00724   return NS_OK;
00725 }
00726 
00735 NS_METHOD nsBaseWidget::AddMenuListener(nsIMenuListener * aListener)
00736 {
00737   NS_IF_RELEASE(mMenuListener);
00738   NS_IF_ADDREF(aListener);
00739   mMenuListener = aListener;
00740   return NS_OK;
00741 }
00742 
00743 
00748 NS_METHOD nsBaseWidget::GetClientBounds(nsRect &aRect)
00749 {
00750   return GetBounds(aRect);
00751 }
00752 
00757 NS_METHOD nsBaseWidget::GetBounds(nsRect &aRect)
00758 {
00759   aRect = mBounds;
00760   return NS_OK;
00761 }
00762 
00768 NS_METHOD nsBaseWidget::GetScreenBounds(nsRect &aRect)
00769 {
00770   return GetBounds(aRect);
00771 }
00772 
00777 NS_METHOD nsBaseWidget::GetBoundsAppUnits(nsRect &aRect, float aAppUnits)
00778 {
00779   aRect = mBounds;
00780   // Convert to twips
00781   aRect.x      = nscoord((PRFloat64)aRect.x * aAppUnits);
00782   aRect.y      = nscoord((PRFloat64)aRect.y * aAppUnits);
00783   aRect.width  = nscoord((PRFloat64)aRect.width * aAppUnits); 
00784   aRect.height = nscoord((PRFloat64)aRect.height * aAppUnits);
00785   return NS_OK;
00786 }
00787 
00792 NS_METHOD nsBaseWidget::SetBounds(const nsRect &aRect)
00793 {
00794   mBounds = aRect;
00795 
00796   return NS_OK;
00797 }
00798  
00799 
00800 
00805 NS_METHOD nsBaseWidget::GetBorderSize(PRInt32 &aWidth, PRInt32 &aHeight)
00806 {
00807   nsRect rectWin;
00808   nsRect rect;
00809   GetBounds(rectWin);
00810   GetClientBounds(rect);
00811 
00812   aWidth  = (rectWin.width - rect.width) / 2;
00813   aHeight = (rectWin.height - rect.height) / 2;
00814 
00815   return NS_OK;
00816 }
00817 
00818 
00823 void nsBaseWidget::DrawScaledRect(nsIRenderingContext& aRenderingContext, const nsRect & aRect, float aScale, float aAppUnits)
00824 {
00825   nsRect rect = aRect;
00826 
00827   float x = (float)rect.x;
00828   float y = (float)rect.y;
00829   float w = (float)rect.width;
00830   float h = (float)rect.height;
00831   float twoAppUnits = aAppUnits * 2.0f;
00832 
00833   for (int i=0;i<int(aScale);i++) {
00834     rect.x      = nscoord(x);
00835     rect.y      = nscoord(y);
00836     rect.width  = nscoord(w);
00837     rect.height = nscoord(h);
00838     aRenderingContext.DrawRect(rect);
00839     x += aAppUnits; 
00840     y += aAppUnits;
00841     w -= twoAppUnits; 
00842     h -= twoAppUnits;
00843   }
00844 }
00845 
00850 void nsBaseWidget::DrawScaledLine(nsIRenderingContext& aRenderingContext, 
00851                                   nscoord aSX, 
00852                                   nscoord aSY, 
00853                                   nscoord aEX, 
00854                                   nscoord aEY, 
00855                                   float   aScale, 
00856                                   float   aAppUnits,
00857                                   PRBool  aIsHorz)
00858 {
00859   float sx = (float)aSX;
00860   float sy = (float)aSY;
00861   float ex = (float)aEX;
00862   float ey = (float)aEY;
00863 
00864   for (int i=0;i<int(aScale);i++) {
00865     aSX = nscoord(sx);
00866     aSY = nscoord(sy);
00867     aEX = nscoord(ex);
00868     aEY = nscoord(ey);
00869     aRenderingContext.DrawLine(aSX, aSY, aEX, aEY);
00870     if (aIsHorz) {
00871       sy += aAppUnits; 
00872       ey += aAppUnits;
00873     } else {
00874       sx += aAppUnits; 
00875       ex += aAppUnits;
00876     }
00877   }
00878 }
00879 
00884 NS_METHOD nsBaseWidget::Paint(nsIRenderingContext& aRenderingContext,
00885                               const nsRect&        aDirtyRect)
00886 {
00887   nsRect rect;
00888   float  appUnits;
00889   float  scale;
00890   nsIDeviceContext * context;
00891   aRenderingContext.GetDeviceContext(context);
00892 
00893   context->GetCanonicalPixelScale(scale);
00894   appUnits = context->DevUnitsToAppUnits();
00895 
00896   GetBoundsAppUnits(rect, appUnits);
00897   aRenderingContext.SetColor(NS_RGB(0,0,0));
00898 
00899   DrawScaledRect(aRenderingContext, rect, scale, appUnits);
00900 
00901   NS_RELEASE(context);
00902   return NS_OK;
00903 }
00904 
00905 NS_IMETHODIMP nsBaseWidget::ScrollWidgets(PRInt32 aDx, PRInt32 aDy)
00906 {
00907   return NS_ERROR_FAILURE;
00908 }
00909 
00910 NS_IMETHODIMP nsBaseWidget::ScrollRect(nsRect &aRect, PRInt32 aDx, PRInt32 aDy)
00911 {
00912   return NS_ERROR_FAILURE;
00913 }
00914 
00915 NS_METHOD nsBaseWidget::EnableDragDrop(PRBool aEnable)
00916 {
00917   return NS_OK;
00918 }
00919 
00920 NS_METHOD nsBaseWidget::SetModal(PRBool aModal)
00921 {
00922   return NS_ERROR_FAILURE;
00923 }
00924 
00925 // generic xp assumption is that events should be processed
00926 NS_METHOD nsBaseWidget::ModalEventFilter(PRBool aRealEvent, void *aEvent,
00927                             PRBool *aForWindow)
00928 {
00929   *aForWindow = PR_TRUE;
00930   return NS_OK;
00931 }
00932 
00933 NS_IMETHODIMP
00934 nsBaseWidget::GetAttention(PRInt32 aCycleCount) {
00935     return NS_OK;
00936 }
00937 
00938 NS_IMETHODIMP
00939 nsBaseWidget::GetLastInputEventTime(PRUint32& aTime) {
00940     return NS_ERROR_NOT_IMPLEMENTED;
00941 }
00942 
00943 NS_IMETHODIMP
00944 nsBaseWidget::SetIcon(const nsAString&)
00945 {
00946   return NS_OK;
00947 }
00948 
00954 static PRBool
00955 ResolveIconNameHelper(nsILocalFile *aFile,
00956                       const nsAString &aIconName,
00957                       const nsAString &aIconSuffix)
00958 {
00959   aFile->Append(NS_LITERAL_STRING("icons"));
00960   aFile->Append(NS_LITERAL_STRING("default"));
00961   aFile->Append(aIconName + aIconSuffix);
00962 
00963   PRBool readable;
00964   return NS_SUCCEEDED(aFile->IsReadable(&readable)) && readable;
00965 }
00966 
00974 void
00975 nsBaseWidget::ResolveIconName(const nsAString &aIconName,
00976                               const nsAString &aIconSuffix,
00977                               nsILocalFile **aResult)
00978 { 
00979   *aResult = nsnull;
00980 
00981   nsCOMPtr<nsIProperties> dirSvc = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
00982   if (!dirSvc)
00983     return;
00984 
00985   // first check auxilary chrome directories
00986 
00987   nsCOMPtr<nsISimpleEnumerator> dirs;
00988   dirSvc->Get(NS_APP_CHROME_DIR_LIST, NS_GET_IID(nsISimpleEnumerator),
00989               getter_AddRefs(dirs));
00990   if (dirs) {
00991     PRBool hasMore;
00992     while (NS_SUCCEEDED(dirs->HasMoreElements(&hasMore)) && hasMore) {
00993       nsCOMPtr<nsISupports> element;
00994       dirs->GetNext(getter_AddRefs(element));
00995       if (!element)
00996         continue;
00997       nsCOMPtr<nsILocalFile> file = do_QueryInterface(element);
00998       if (!file)
00999         continue;
01000       if (ResolveIconNameHelper(file, aIconName, aIconSuffix)) {
01001         NS_ADDREF(*aResult = file);
01002         return;
01003       }
01004     }
01005   }
01006 
01007   // then check the main app chrome directory
01008 
01009   nsCOMPtr<nsILocalFile> file;
01010   dirSvc->Get(NS_APP_CHROME_DIR, NS_GET_IID(nsILocalFile),
01011               getter_AddRefs(file));
01012   if (file && ResolveIconNameHelper(file, aIconName, aIconSuffix))
01013     NS_ADDREF(*aResult = file);
01014 }
01015 
01016 #ifdef DEBUG
01017 
01018 //
01019 // Convert a GUI event message code to a string.
01020 // Makes it a lot easier to debug events.
01021 //
01022 // See gtk/nsWidget.cpp and windows/nsWindow.cpp
01023 // for a DebugPrintEvent() function that uses
01024 // this.
01025 //
01027 /* static */ nsAutoString
01028 nsBaseWidget::debug_GuiEventToString(nsGUIEvent * aGuiEvent)
01029 {
01030   NS_ASSERTION(nsnull != aGuiEvent,"cmon, null gui event.");
01031 
01032   nsAutoString eventName(NS_LITERAL_STRING("UNKNOWN"));
01033 
01034 #define _ASSIGN_eventName(_value,_name)\
01035 case _value: eventName.AssignWithConversion(_name) ; break
01036 
01037   switch(aGuiEvent->message)
01038   {
01039     _ASSIGN_eventName(NS_BLUR_CONTENT,"NS_BLUR_CONTENT");
01040     _ASSIGN_eventName(NS_CONTROL_CHANGE,"NS_CONTROL_CHANGE");
01041     _ASSIGN_eventName(NS_CREATE,"NS_CREATE");
01042     _ASSIGN_eventName(NS_DESTROY,"NS_DESTROY");
01043     _ASSIGN_eventName(NS_DRAGDROP_GESTURE,"NS_DND_GESTURE");
01044     _ASSIGN_eventName(NS_DRAGDROP_DROP,"NS_DND_DROP");
01045     _ASSIGN_eventName(NS_DRAGDROP_ENTER,"NS_DND_ENTER");
01046     _ASSIGN_eventName(NS_DRAGDROP_EXIT,"NS_DND_EXIT");
01047     _ASSIGN_eventName(NS_DRAGDROP_OVER,"NS_DND_OVER");
01048     _ASSIGN_eventName(NS_FOCUS_CONTENT,"NS_FOCUS_CONTENT");
01049     _ASSIGN_eventName(NS_FORM_SELECTED,"NS_FORM_SELECTED");
01050     _ASSIGN_eventName(NS_FORM_CHANGE,"NS_FORM_CHANGE");
01051     _ASSIGN_eventName(NS_FORM_INPUT,"NS_FORM_INPUT");
01052     _ASSIGN_eventName(NS_FORM_RESET,"NS_FORM_RESET");
01053     _ASSIGN_eventName(NS_FORM_SUBMIT,"NS_FORM_SUBMIT");
01054     _ASSIGN_eventName(NS_GOTFOCUS,"NS_GOTFOCUS");
01055     _ASSIGN_eventName(NS_IMAGE_ABORT,"NS_IMAGE_ABORT");
01056     _ASSIGN_eventName(NS_IMAGE_ERROR,"NS_IMAGE_ERROR");
01057     _ASSIGN_eventName(NS_IMAGE_LOAD,"NS_IMAGE_LOAD");
01058     _ASSIGN_eventName(NS_KEY_DOWN,"NS_KEY_DOWN");
01059     _ASSIGN_eventName(NS_KEY_PRESS,"NS_KEY_PRESS");
01060     _ASSIGN_eventName(NS_KEY_UP,"NS_KEY_UP");
01061     _ASSIGN_eventName(NS_LOSTFOCUS,"NS_LOSTFOCUS");
01062     _ASSIGN_eventName(NS_MENU_SELECTED,"NS_MENU_SELECTED");
01063     _ASSIGN_eventName(NS_MOUSE_ENTER,"NS_MOUSE_ENTER");
01064     _ASSIGN_eventName(NS_MOUSE_EXIT,"NS_MOUSE_EXIT");
01065     _ASSIGN_eventName(NS_MOUSE_LEFT_BUTTON_DOWN,"NS_MOUSE_LEFT_BTN_DOWN");
01066     _ASSIGN_eventName(NS_MOUSE_LEFT_BUTTON_UP,"NS_MOUSE_LEFT_BTN_UP");
01067     _ASSIGN_eventName(NS_MOUSE_LEFT_CLICK,"NS_MOUSE_LEFT_CLICK");
01068     _ASSIGN_eventName(NS_MOUSE_LEFT_DOUBLECLICK,"NS_MOUSE_LEFT_DBLCLICK");
01069     _ASSIGN_eventName(NS_MOUSE_MIDDLE_BUTTON_DOWN,"NS_MOUSE_MIDDLE_BTN_DOWN");
01070     _ASSIGN_eventName(NS_MOUSE_MIDDLE_BUTTON_UP,"NS_MOUSE_MIDDLE_BTN_UP");
01071     _ASSIGN_eventName(NS_MOUSE_MIDDLE_CLICK,"NS_MOUSE_MIDDLE_CLICK");
01072     _ASSIGN_eventName(NS_MOUSE_MIDDLE_DOUBLECLICK,"NS_MOUSE_MIDDLE_DBLCLICK");
01073     _ASSIGN_eventName(NS_MOUSE_MOVE,"NS_MOUSE_MOVE");
01074     _ASSIGN_eventName(NS_MOUSE_RIGHT_BUTTON_DOWN,"NS_MOUSE_RIGHT_BTN_DOWN");
01075     _ASSIGN_eventName(NS_MOUSE_RIGHT_BUTTON_UP,"NS_MOUSE_RIGHT_BTN_UP");
01076     _ASSIGN_eventName(NS_MOUSE_RIGHT_CLICK,"NS_MOUSE_RIGHT_CLICK");
01077     _ASSIGN_eventName(NS_MOUSE_RIGHT_DOUBLECLICK,"NS_MOUSE_RIGHT_DBLCLICK");
01078     _ASSIGN_eventName(NS_MOVE,"NS_MOVE");
01079     _ASSIGN_eventName(NS_PAGE_LOAD,"NS_PAGE_LOAD");
01080     _ASSIGN_eventName(NS_PAGE_UNLOAD,"NS_PAGE_UNLOAD");
01081     _ASSIGN_eventName(NS_PAINT,"NS_PAINT");
01082     _ASSIGN_eventName(NS_XUL_BROADCAST, "NS_XUL_BROADCAST");
01083     _ASSIGN_eventName(NS_XUL_COMMAND_UPDATE, "NS_XUL_COMMAND_UPDATE");
01084     _ASSIGN_eventName(NS_SCROLLBAR_LINE_NEXT,"NS_SB_LINE_NEXT");
01085     _ASSIGN_eventName(NS_SCROLLBAR_LINE_PREV,"NS_SB_LINE_PREV");
01086     _ASSIGN_eventName(NS_SCROLLBAR_PAGE_NEXT,"NS_SB_PAGE_NEXT");
01087     _ASSIGN_eventName(NS_SCROLLBAR_PAGE_PREV,"NS_SB_PAGE_PREV");
01088     _ASSIGN_eventName(NS_SCROLLBAR_POS,"NS_SB_POS");
01089     _ASSIGN_eventName(NS_SIZE,"NS_SIZE");
01090 
01091 #undef _ASSIGN_eventName
01092 
01093   default: 
01094     {
01095       char buf[32];
01096       
01097       sprintf(buf,"UNKNOWN: %d",aGuiEvent->message);
01098       
01099       eventName.AssignWithConversion(buf);
01100     }
01101     break;
01102   }
01103   
01104   return nsAutoString(eventName);
01105 }
01107 //
01108 // Code to deal with paint and event debug prefs.
01109 //
01111 struct PrefPair
01112 {
01113   const char * name;
01114   PRBool value;
01115 };
01116 
01117 static PrefPair debug_PrefValues[] =
01118 {
01119   { "nglayout.debug.crossing_event_dumping", PR_FALSE },
01120   { "nglayout.debug.event_dumping", PR_FALSE },
01121   { "nglayout.debug.invalidate_dumping", PR_FALSE },
01122   { "nglayout.debug.motion_event_dumping", PR_FALSE },
01123   { "nglayout.debug.paint_dumping", PR_FALSE },
01124   { "nglayout.debug.paint_flashing", PR_FALSE }
01125 };
01126 
01127 static PRUint32 debug_NumPrefValues = 
01128   (sizeof(debug_PrefValues) / sizeof(debug_PrefValues[0]));
01129 
01130 
01132 static PRBool debug_GetBoolPref(nsIPref * aPrefs,const char * aPrefName)
01133 {
01134   NS_ASSERTION(nsnull != aPrefName,"cmon, pref name is null.");
01135   NS_ASSERTION(nsnull != aPrefs,"cmon, prefs are null.");
01136 
01137   PRBool value = PR_FALSE;
01138 
01139   if (aPrefs)
01140   {
01141     aPrefs->GetBoolPref(aPrefName,&value);
01142   }
01143 
01144   return value;
01145 }
01147 PRBool
01148 nsBaseWidget::debug_GetCachedBoolPref(const char * aPrefName)
01149 {
01150   NS_ASSERTION(nsnull != aPrefName,"cmon, pref name is null.");
01151 
01152   for (PRUint32 i = 0; i < debug_NumPrefValues; i++)
01153   {
01154     if (strcmp(debug_PrefValues[i].name, aPrefName) == 0)
01155     {
01156       return debug_PrefValues[i].value;
01157     }
01158   }
01159 
01160   return PR_FALSE;
01161 }
01163 static void debug_SetCachedBoolPref(const char * aPrefName,PRBool aValue)
01164 {
01165   NS_ASSERTION(nsnull != aPrefName,"cmon, pref name is null.");
01166 
01167   for (PRUint32 i = 0; i < debug_NumPrefValues; i++)
01168   {
01169     if (strcmp(debug_PrefValues[i].name, aPrefName) == 0)
01170     {
01171       debug_PrefValues[i].value = aValue;
01172 
01173       return;
01174     }
01175   }
01176 
01177   NS_ASSERTION(PR_FALSE, "cmon, this code is not reached dude.");
01178 }
01179 
01180 static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
01181 
01183 /* static */ int PR_CALLBACK 
01184 debug_PrefChangedCallback(const char * name,void * closure)
01185 {
01186 
01187   nsIPref * prefs = nsnull;
01188   
01189   nsresult rv = CallGetService(kPrefCID, &prefs);
01190   
01191   NS_ASSERTION(NS_SUCCEEDED(rv),"Could not get prefs service.");
01192   NS_ASSERTION(nsnull != prefs,"Prefs services is null.");
01193 
01194   if (NS_SUCCEEDED(rv))
01195   {
01196     PRBool value = PR_FALSE;
01197 
01198     prefs->GetBoolPref(name,&value);
01199 
01200     debug_SetCachedBoolPref(name,value);
01201 
01202     NS_RELEASE(prefs);
01203   }
01204 
01205      return 0;
01206 }
01208 /* static */ void
01209 debug_RegisterPrefCallbacks()
01210 {
01211   static PRBool once = PR_TRUE;
01212 
01213   if (once)
01214   {
01215     once = PR_FALSE;
01216 
01217     nsIPref * prefs = nsnull;
01218 
01219     nsresult rv = CallGetService(kPrefCID, &prefs);
01220     
01221     NS_ASSERTION(NS_SUCCEEDED(rv),"Could not get prefs service.");
01222     NS_ASSERTION(nsnull != prefs,"Prefs services is null.");
01223 
01224     if (NS_SUCCEEDED(rv))
01225     {
01226       for (PRUint32 i = 0; i < debug_NumPrefValues; i++)
01227       {
01228         // Initialize the pref values
01229         debug_PrefValues[i].value = 
01230           debug_GetBoolPref(prefs,debug_PrefValues[i].name);
01231 
01232         // Register callbacks for when these change
01233         prefs->RegisterCallback(debug_PrefValues[i].name,
01234                     debug_PrefChangedCallback,
01235                     NULL);
01236       }
01237       
01238       NS_RELEASE(prefs);
01239     }
01240   }
01241 }
01243 static PRInt32
01244 _GetPrintCount()
01245 {
01246   static PRInt32 sCount = 0;
01247   
01248   return ++sCount;
01249 }
01251 /* static */ PRBool
01252 nsBaseWidget::debug_WantPaintFlashing()
01253 {
01254   return debug_GetCachedBoolPref("nglayout.debug.paint_flashing");
01255 }
01257 /* static */ void
01258 nsBaseWidget::debug_DumpEvent(FILE *                aFileOut,
01259                               nsIWidget *           aWidget,
01260                               nsGUIEvent *          aGuiEvent,
01261                               const nsCAutoString & aWidgetName,
01262                               PRInt32               aWindowID)
01263 {
01264   // NS_PAINT is handled by debug_DumpPaintEvent()
01265   if (aGuiEvent->message == NS_PAINT)
01266     return;
01267 
01268   if (aGuiEvent->message == NS_MOUSE_MOVE)
01269   {
01270     if (!debug_GetCachedBoolPref("nglayout.debug.motion_event_dumping"))
01271       return;
01272   }
01273   
01274   if (aGuiEvent->message == NS_MOUSE_ENTER || 
01275       aGuiEvent->message == NS_MOUSE_EXIT)
01276   {
01277     if (!debug_GetCachedBoolPref("nglayout.debug.crossing_event_dumping"))
01278       return;
01279   }
01280 
01281   if (!debug_GetCachedBoolPref("nglayout.debug.event_dumping"))
01282     return;
01283 
01284   nsCAutoString tempString; tempString.AssignWithConversion(debug_GuiEventToString(aGuiEvent).get());
01285   
01286   fprintf(aFileOut,
01287           "%4d %-26s widget=%-8p name=%-12s id=%-8p pos=%d,%d\n",
01288           _GetPrintCount(),
01289           tempString.get(),
01290           (void *) aWidget,
01291           aWidgetName.get(),
01292           (void *) (aWindowID ? aWindowID : 0x0),
01293           aGuiEvent->point.x,
01294           aGuiEvent->point.y);
01295 }
01297 /* static */ void
01298 nsBaseWidget::debug_DumpPaintEvent(FILE *                aFileOut,
01299                                    nsIWidget *           aWidget,
01300                                    nsPaintEvent *        aPaintEvent,
01301                                    const nsCAutoString & aWidgetName,
01302                                    PRInt32               aWindowID)
01303 {
01304   NS_ASSERTION(nsnull != aFileOut,"cmon, null output FILE");
01305   NS_ASSERTION(nsnull != aWidget,"cmon, the widget is null");
01306   NS_ASSERTION(nsnull != aPaintEvent,"cmon, the paint event is null");
01307 
01308   if (!debug_GetCachedBoolPref("nglayout.debug.paint_dumping"))
01309     return;
01310   
01311   fprintf(aFileOut,
01312           "%4d PAINT      widget=%p name=%-12s id=%-8p rect=", 
01313           _GetPrintCount(),
01314           (void *) aWidget,
01315           aWidgetName.get(),
01316           (void *) aWindowID);
01317   
01318   if (aPaintEvent->rect) 
01319   {
01320     fprintf(aFileOut,
01321             "%3d,%-3d %3d,%-3d",
01322             aPaintEvent->rect->x, 
01323             aPaintEvent->rect->y,
01324             aPaintEvent->rect->width, 
01325             aPaintEvent->rect->height);
01326   }
01327   else
01328   {
01329     fprintf(aFileOut,"none");
01330   }
01331   
01332   fprintf(aFileOut,"\n");
01333 }
01335 /* static */ void
01336 nsBaseWidget::debug_DumpInvalidate(FILE *                aFileOut,
01337                                    nsIWidget *           aWidget,
01338                                    const nsRect *        aRect,
01339                                    PRBool                aIsSynchronous,
01340                                    const nsCAutoString & aWidgetName,
01341                                    PRInt32               aWindowID)
01342 {
01343   if (!debug_GetCachedBoolPref("nglayout.debug.invalidate_dumping"))
01344     return;
01345 
01346   NS_ASSERTION(nsnull != aFileOut,"cmon, null output FILE");
01347   NS_ASSERTION(nsnull != aWidget,"cmon, the widget is null");
01348 
01349   fprintf(aFileOut,
01350           "%4d Invalidate widget=%p name=%-12s id=%-8p",
01351           _GetPrintCount(),
01352           (void *) aWidget,
01353           aWidgetName.get(),
01354           (void *) aWindowID);
01355 
01356   if (aRect) 
01357   {
01358     fprintf(aFileOut,
01359             " rect=%3d,%-3d %3d,%-3d",
01360             aRect->x, 
01361             aRect->y,
01362             aRect->width, 
01363             aRect->height);
01364   }
01365   else
01366   {
01367     fprintf(aFileOut,
01368             " rect=%-15s",
01369             "none");
01370   }
01371 
01372   fprintf(aFileOut,
01373           " sync=%s",
01374           (const char *) (aIsSynchronous ? "yes" : "no "));
01375   
01376   fprintf(aFileOut,"\n");
01377 }
01379 
01380 #endif // DEBUG
01381