Back to index

lightning-sunbird  0.9+nobinonly
nsViewManager.h
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  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nsViewManager_h___
00039 #define nsViewManager_h___
00040 #include "nsCOMPtr.h"
00041 #include "nsIViewManager.h"
00042 #include "nsCRT.h"
00043 #include "nsIWidget.h"
00044 #include "nsITimer.h"
00045 #include "prtime.h"
00046 #include "prinrval.h"
00047 #include "nsVoidArray.h"
00048 #include "nsIScrollableView.h"
00049 #include "nsIRegion.h"
00050 #include "nsIBlender.h"
00051 #include "nsIEventQueueService.h"
00052 #include "nsIEventQueue.h"
00053 #include "nsView.h"
00054 
00055 class nsIRegion;
00056 class nsIEvent;
00057 class nsISupportsArray;
00058 struct DisplayListElement2;
00059 struct DisplayZTreeNode;
00060 class BlendingBuffers;
00061 struct PLArenaPool;
00062 class nsHashtable;
00063 
00064 //Uncomment the following line to enable generation of viewmanager performance data.
00065 #ifdef MOZ_PERF_METRICS
00066 //#define NS_VM_PERF_METRICS 1 
00067 #endif
00068 
00069 #ifdef NS_VM_PERF_METRICS
00070 #include "nsTimer.h"
00071 #endif
00072 
00126 class nsZPlaceholderView : public nsView
00127 {
00128 public:
00129   nsZPlaceholderView(nsViewManager* aViewManager) : nsView(aViewManager) {}
00130 
00131   void RemoveReparentedView() { mReparentedView = nsnull; }
00132   void SetReparentedView(nsView* aView) { mReparentedView = aView; }
00133   nsView* GetReparentedView() const { return mReparentedView; }
00134 
00135   virtual PRBool IsZPlaceholderView() const { return PR_TRUE; }
00136 
00137 protected:
00138   virtual ~nsZPlaceholderView() {
00139     if (nsnull != mReparentedView) {
00140       mReparentedView->SetZParent(nsnull);
00141     }
00142   }
00143 
00144 protected:
00145   nsView   *mReparentedView;
00146 };
00147 
00148 class nsViewManager : public nsIViewManager {
00149 public:
00150   nsViewManager();
00151 
00152   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
00153 
00154   NS_DECL_ISUPPORTS
00155 
00156   NS_IMETHOD  Init(nsIDeviceContext* aContext);
00157 
00158   NS_IMETHOD_(nsIView*) CreateView(const nsRect& aBounds,
00159                                    const nsIView* aParent,
00160                                    nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow);
00161 
00162   NS_IMETHOD_(nsIScrollableView*) CreateScrollableView(const nsRect& aBounds,
00163                                                        const nsIView* aParent);
00164 
00165   NS_IMETHOD  GetRootView(nsIView *&aView);
00166   NS_IMETHOD  SetRootView(nsIView *aView);
00167 
00168   NS_IMETHOD  GetWindowDimensions(nscoord *width, nscoord *height);
00169   NS_IMETHOD  SetWindowDimensions(nscoord width, nscoord height);
00170 
00171   NS_IMETHOD  Composite(void);
00172 
00173   NS_IMETHOD  UpdateView(nsIView *aView, PRUint32 aUpdateFlags);
00174   NS_IMETHOD  UpdateView(nsIView *aView, const nsRect &aRect, PRUint32 aUpdateFlags);
00175   NS_IMETHOD  UpdateAllViews(PRUint32 aUpdateFlags);
00176 
00177   NS_IMETHOD  DispatchEvent(nsGUIEvent *aEvent, nsEventStatus* aStatus);
00178 
00179   NS_IMETHOD  GrabMouseEvents(nsIView *aView, PRBool &aResult);
00180   NS_IMETHOD  GrabKeyEvents(nsIView *aView, PRBool &aresult);
00181 
00182   NS_IMETHOD  GetMouseEventGrabber(nsIView *&aView);
00183   NS_IMETHOD  GetKeyEventGrabber(nsIView *&aView);
00184 
00185   NS_IMETHOD  InsertChild(nsIView *parent, nsIView *child, nsIView *sibling,
00186                           PRBool above);
00187 
00188   NS_IMETHOD  InsertChild(nsIView *parent, nsIView *child,
00189                           PRInt32 zindex);
00190 
00191   NS_IMETHOD  InsertZPlaceholder(nsIView *parent, nsIView *child, nsIView *sibling,
00192                                  PRBool above);
00193 
00194   NS_IMETHOD  RemoveChild(nsIView *parent);
00195 
00196   NS_IMETHOD  MoveViewBy(nsIView *aView, nscoord aX, nscoord aY);
00197 
00198   NS_IMETHOD  MoveViewTo(nsIView *aView, nscoord aX, nscoord aY);
00199 
00200   NS_IMETHOD  ResizeView(nsIView *aView, const nsRect &aRect, PRBool aRepaintExposedAreaOnly = PR_FALSE);
00201 
00202   NS_IMETHOD  SetViewChildClipRegion(nsIView *aView, const nsRegion *aRegion);
00203 
00204   NS_IMETHOD  SetViewBitBltEnabled(nsIView *aView, PRBool aEnable);
00205 
00206   NS_IMETHOD  SetViewCheckChildEvents(nsIView *aView, PRBool aEnable);
00207 
00208   NS_IMETHOD  SetViewFloating(nsIView *aView, PRBool aFloating);
00209 
00210   NS_IMETHOD  SetViewVisibility(nsIView *aView, nsViewVisibility aVisible);
00211 
00212   NS_IMETHOD  SetViewZIndex(nsIView *aView, PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost=PR_FALSE);
00213   NS_IMETHOD  SetViewContentTransparency(nsIView *aView, PRBool aTransparent);
00214   NS_IMETHOD  SetViewOpacity(nsIView *aView, float aOpacity);
00215 
00216   NS_IMETHOD  SetViewObserver(nsIViewObserver *aObserver);
00217   NS_IMETHOD  GetViewObserver(nsIViewObserver *&aObserver);
00218 
00219   NS_IMETHOD  GetDeviceContext(nsIDeviceContext *&aContext);
00220 
00221   NS_IMETHOD  DisableRefresh(void);
00222   NS_IMETHOD  EnableRefresh(PRUint32 aUpdateFlags);
00223 
00224   NS_IMETHOD  BeginUpdateViewBatch(void);
00225   NS_IMETHOD  EndUpdateViewBatch(PRUint32 aUpdateFlags);
00226 
00227   NS_IMETHOD  SetRootScrollableView(nsIScrollableView *aScrollable);
00228   NS_IMETHOD  GetRootScrollableView(nsIScrollableView **aScrollable);
00229 
00230   NS_IMETHOD Display(nsIView *aView, nscoord aX, nscoord aY, const nsRect& aClipRect);
00231 
00232   NS_IMETHOD RenderOffscreen(nsIView* aView, nsRect aRect, PRBool aUntrusted,
00233                              PRBool aIgnoreViewportScrolling,
00234                              nscolor aBackgroundColor,
00235                              nsIRenderingContext** aRenderedContext);
00236 
00237   NS_IMETHOD AddCompositeListener(nsICompositeListener *aListener);
00238   NS_IMETHOD RemoveCompositeListener(nsICompositeListener *aListener);
00239 
00240   NS_IMETHOD GetWidget(nsIWidget **aWidget);
00241   nsIWidget* GetWidget() { return mRootView ? mRootView->GetWidget() : nsnull; }
00242   NS_IMETHOD ForceUpdate();
00243  
00244   NS_IMETHOD AllowDoubleBuffering(PRBool aDoubleBuffer);
00245   NS_IMETHOD IsPainting(PRBool& aIsPainting);
00246   NS_IMETHOD SetDefaultBackgroundColor(nscolor aColor);
00247   NS_IMETHOD GetDefaultBackgroundColor(nscolor* aColor);
00248   NS_IMETHOD GetLastUserEventTime(PRUint32& aTime);
00249   void ProcessInvalidateEvent();
00250   static PRInt32 GetViewManagerCount();
00251   static const nsVoidArray* GetViewManagerArray();
00252   static PRUint32 gLastUserEventTime;
00253 
00264   NS_IMETHOD GetRectVisibility(nsIView *aView, const nsRect &aRect, 
00265                                PRUint16 aMinTwips, 
00266                                nsRectVisibility *aRectVisibility);
00267 
00268   NS_IMETHOD SynthesizeMouseMove(PRBool aFromScroll);
00269   void ProcessSynthMouseMoveEvent(PRBool aFromScroll);
00270 
00271   /* Update the cached RootViewManager pointer on this view manager. */
00272   void InvalidateHierarchy();
00273 
00274 protected:
00275   virtual ~nsViewManager();
00276 
00277 private:
00278   void FlushPendingInvalidates();
00279   void ProcessPendingUpdates(nsView *aView, PRBool aDoInvalidate);
00280   void ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget);
00281   void ReparentWidgets(nsIView* aView, nsIView *aParent);
00282   already_AddRefed<nsIRenderingContext> CreateRenderingContext(nsView &aView);
00283   void UpdateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion,
00284                         nsView* aIgnoreWidgetView);
00285 
00286   void UpdateViews(nsView *aView, PRUint32 aUpdateFlags);
00287 
00288   void Refresh(nsView *aView, nsIRenderingContext *aContext,
00289                nsIRegion *region, PRUint32 aUpdateFlags);
00293   void DefaultRefresh(nsView* aView, const nsRect* aRect);
00294   PRBool BuildRenderingDisplayList(nsIView* aRootView,
00295     const nsRegion& aRegion, nsVoidArray* aDisplayList, PLArenaPool &aPool,
00296     PRBool aIgnoreCoveringWidgets, PRBool aIgnoreOutsideClipping,
00297     nsIView* aSuppressScrolling);
00298   void RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
00299                    const nsRegion& aRegion, nsIDrawingSurface* aRCSurface,
00300                    const nsVoidArray& aDisplayList);
00301 
00302   void RenderDisplayListElement(DisplayListElement2* element,
00303                                 nsIRenderingContext* aRC);
00304 
00305   void PaintView(nsView *aView, nsIRenderingContext &aRC, nscoord x, nscoord y,
00306                  const nsRect &aDamageRect);
00307 
00308   void InvalidateRectDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut, PRUint32 aUpdateFlags);
00309   void InvalidateHorizontalBandDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut,
00310                                           PRUint32 aUpdateFlags, nscoord aY1, nscoord aY2, PRBool aInCutOut);
00311 
00312   BlendingBuffers* CreateBlendingBuffers(nsIRenderingContext *aRC, PRBool aBorrowContext,
00313                                          nsIDrawingSurface* aBorrowSurface, PRBool aNeedAlpha,
00314                                          const nsRect& aArea);
00315 
00316   void ReparentViews(DisplayZTreeNode* aNode, nsHashtable &);
00317   void BuildDisplayList(nsView* aView, const nsRect& aRect, PRBool aEventProcessing,
00318                         PRBool aCaptured, nsIView* aSuppressScrolling,
00319                         nsVoidArray* aDisplayList, PLArenaPool &aPool);
00320   void BuildEventTargetList(nsVoidArray &aTargets, nsView* aView,
00321                             nsGUIEvent* aEvent, PRBool aCaptured, PLArenaPool &aPool);
00322 
00323   PRBool CreateDisplayList(nsView *aView,
00324                            DisplayZTreeNode* &aResult,
00325                            nscoord aOriginX, nscoord aOriginY,
00326                            nsView *aRealView, const nsRect *aDamageRect,
00327                            nsView *aTopView, nscoord aX, nscoord aY,
00328                            PRBool aPaintFloats, PRBool aEventProcessing,
00329                            nsIView* aSuppressClip,
00330                            nsHashtable&, PLArenaPool &aPool);
00331   PRBool AddToDisplayList(nsView *aView,
00332                           DisplayZTreeNode* &aParent, nsRect &aClipRect,
00333                           nsRect& aDirtyRect, PRUint32 aFlags, nscoord aAbsX, nscoord aAbsY,
00334                           PRBool aAssumeIntersection, PLArenaPool &aPool,
00335                           nsIView* aStopClippingAtView);
00336   void OptimizeDisplayList(const nsVoidArray* aDisplayList, const nsRegion& aDirtyRegion,
00337                            nsRect& aFinalTransparentRect, nsRegion& aOpaqueRgn,
00338                            PRBool aTreatUniformAsOpaque);
00339 
00340   void AddCoveringWidgetsToOpaqueRegion(nsRegion &aRgn, nsIDeviceContext* aContext,
00341                                         nsView* aRootView);
00342 
00343   // Predicates
00344   PRBool DoesViewHaveNativeWidget(nsView* aView);
00345 
00346   void PauseTimer(void);
00347   void RestartTimer(void);
00348   void OptimizeDisplayListClipping(const nsVoidArray* aDisplayList, PRBool aHaveClip,
00349                                    nsRect& aClipRect, PRInt32& aIndex,
00350                                    PRBool& aAnyRendered);
00351   nsRect OptimizeTranslucentRegions(const nsVoidArray& aDisplayList,
00352                                     PRInt32* aIndex, nsRegion* aOpaqueRegion);
00353 
00354   void ShowDisplayList(const nsVoidArray* aDisplayList);
00355 
00356   // Utilities
00357 
00358   PRBool IsViewInserted(nsView *aView);
00359 
00364   void UpdateWidgetsForView(nsView* aView);
00365 
00370   static nsView* GetWidgetView(nsView *aView);
00371 
00376   void ViewToWidget(nsView *aView, nsView* aWidgetView, nsRect &aRect) const;
00377 
00388   nsresult GetAbsoluteRect(nsView *aView, const nsRect &aRect, 
00389                            nsRect& aAbsRect);
00396   nsresult GetVisibleRect(nsRect& aVisibleRect);
00397 
00398   // Utilities used to size the offscreen drawing surface
00399 
00407   void GetMaxWidgetBounds(nsRect& aMaxWidgetBounds) const;
00408 
00409   void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight)
00410   {
00411     nsRect oldDim;
00412     nsRect newDim(0, 0, aWidth, aHeight);
00413     mRootView->GetDimensions(oldDim);
00414     if (oldDim != newDim) {
00415       // Don't resize the widget. It is already being set elsewhere.
00416       mRootView->SetDimensions(newDim, PR_TRUE, PR_FALSE);
00417       if (mObserver)
00418         mObserver->ResizeReflow(mRootView, aWidth, aHeight);
00419     }
00420   }
00421 
00422   // Safety helpers
00423   void IncrementUpdateCount() {
00424     NS_ASSERTION(IsRootVM(),
00425                  "IncrementUpdateCount called on non-root viewmanager");
00426     ++mUpdateCnt;
00427   }
00428 
00429   void DecrementUpdateCount() {
00430     NS_ASSERTION(IsRootVM(),
00431                  "DecrementUpdateCount called on non-root viewmanager");
00432     --mUpdateCnt;
00433   }
00434 
00435   PRInt32 UpdateCount() const {
00436     NS_ASSERTION(IsRootVM(),
00437                  "DecrementUpdateCount called on non-root viewmanager");
00438     return mUpdateCnt;
00439   }
00440 
00441   void ClearUpdateCount() {
00442     NS_ASSERTION(IsRootVM(),
00443                  "DecrementUpdateCount called on non-root viewmanager");
00444     mUpdateCnt = 0;
00445   }
00446 
00447   PRBool IsPainting() const {
00448     return RootViewManager()->mPainting;
00449   }
00450 
00451   void SetPainting(PRBool aPainting) {
00452     RootViewManager()->mPainting = aPainting;
00453   }
00454 
00455 public: // NOT in nsIViewManager, so private to the view module
00456   nsView* GetRootView() const { return mRootView; }
00457   nsView* GetMouseEventGrabber() const {
00458     return RootViewManager()->mMouseGrabber;
00459   }
00460   nsView* GetKeyEventGrabber() const { return mKeyGrabber; }
00461   nsViewManager* RootViewManager() const { return mRootViewManager; }
00462   PRBool IsRootVM() const { return this == RootViewManager(); }
00463 
00464   nsEventStatus HandleEvent(nsView* aView, nsGUIEvent* aEvent, PRBool aCaptured);
00465 
00471   void WillBitBlit(nsView* aView, nsPoint aScrollAmount);
00472   
00480   void UpdateViewAfterScroll(nsView *aView);
00481 
00482   PRBool CanScrollWithBitBlt(nsView* aView);
00483 
00484   nsresult CreateRegion(nsIRegion* *result);
00485 
00486   // return the sum of all view offsets from aView right up to the
00487   // root of this view hierarchy (the view with no parent, which might
00488   // not be in this view manager).
00489   static nsPoint ComputeViewOffset(const nsView *aView);
00490 
00491   PRBool IsRefreshEnabled() { return RootViewManager()->mRefreshEnabled; }
00492 
00493   nsIViewObserver* GetViewObserver() { return mObserver; }
00494 
00495   // Call this when you need to let the viewmanager know that it now has
00496   // pending updates.
00497   void PostPendingUpdate() { RootViewManager()->mHasPendingUpdates = PR_TRUE; }
00498 private:
00499   nsIDeviceContext  *mContext;
00500   float             mTwipsToPixels;
00501   float             mPixelsToTwips;
00502   nsIViewObserver   *mObserver;
00503   nsView            *mKeyGrabber;
00504   nsIScrollableView *mRootScrollable;
00505   nscolor           mDefaultBackgroundColor;
00506   nsPoint           mMouseLocation; // device units, relative to mRootView
00507 
00508   // The size for a resize that we delayed until the root view becomes
00509   // visible again.
00510   nsSize            mDelayedResize;
00511 
00512   nsCOMPtr<nsIBlender> mBlender;
00513   nsISupportsArray  *mCompositeListeners;
00514   nsCOMPtr<nsIFactory> mRegionFactory;
00515   nsView            *mRootView;
00516   // mRootViewManager is a strong ref unless it equals |this|.  It's
00517   // never null (if we have no ancestors, it will be |this|).
00518   nsViewManager     *mRootViewManager;
00519   nsCOMPtr<nsIEventQueueService>  mEventQueueService;
00520   nsCOMPtr<nsIEventQueue>         mSynthMouseMoveEventQueue;
00521   PRPackedBool      mAllowDoubleBuffering;
00522 
00523   // The following members should not be accessed directly except by
00524   // the root view manager.  Some have accessor functions to enforce
00525   // this, as noted.
00526   
00527   // Use GrabMouseEvents() and GetMouseEventGrabber() to access mMouseGrabber.
00528   nsView            *mMouseGrabber;
00529   // Use IncrementUpdateCount(), DecrementUpdateCount(), UpdateCount(),
00530   // ClearUpdateCount() on the root viewmanager to access mUpdateCnt.
00531   PRInt32           mUpdateCnt;
00532   PRInt32           mUpdateBatchCnt;
00533   PRUint32          mUpdateBatchFlags;
00534   PRInt32           mScrollCnt;
00535   nsCOMPtr<nsIEventQueue>         mInvalidateEventQueue;
00536   // Use IsRefreshEnabled() to check the value of mRefreshEnabled.
00537   PRPackedBool      mRefreshEnabled;
00538   // Use IsPainting() and SetPainting() to access mPainting.
00539   PRPackedBool      mPainting;
00540   PRPackedBool      mRecursiveRefreshPending;
00541   PRPackedBool      mHasPendingUpdates;
00542   PRPackedBool      mInScroll;
00543 
00544   //from here to public should be static and locked... MMP
00545   static PRInt32           mVMCount;        //number of viewmanagers
00546 
00547   //Rendering context used to cleanup the blending buffers
00548   static nsIRenderingContext* gCleanupContext;
00549 
00550   //list of view managers
00551   static nsVoidArray       *gViewManagers;
00552 
00553   void PostInvalidateEvent();
00554 
00555 #ifdef NS_VM_PERF_METRICS
00556   MOZ_TIMER_DECLARE(mWatch) //  Measures compositing+paint time for current document
00557 #endif
00558 };
00559 
00560 //when the refresh happens, should it be double buffered?
00561 #define NS_VMREFRESH_DOUBLE_BUFFER      0x0001
00562 
00563 #endif /* nsViewManager_h___ */