From 81d3b1634689889be2647e9e5306188b50cb3c99 Mon Sep 17 00:00:00 2001 From: spider Date: Sun, 21 Jun 1998 07:02:44 +0000 Subject: [PATCH] Support for Optimized GC and Regions in Rendering git-svn-id: svn://10.0.0.236/trunk@4211 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/gfx/src/motif/nsRegionUnix.cpp | 102 ++++-- mozilla/gfx/src/motif/nsRegionUnix.h | 4 + .../gfx/src/motif/nsRenderingContextUnix.cpp | 319 +++++++++++------- .../gfx/src/motif/nsRenderingContextUnix.h | 2 + mozilla/view/src/nsView.cpp | 15 - mozilla/widget/src/motif/nsToolkit.cpp | 8 + mozilla/widget/src/motif/nsToolkit.h | 20 +- mozilla/widget/src/motif/nsWindow.cpp | 68 ++-- mozilla/widget/src/motif/nsWindow.h | 2 + 9 files changed, 342 insertions(+), 198 deletions(-) diff --git a/mozilla/gfx/src/motif/nsRegionUnix.cpp b/mozilla/gfx/src/motif/nsRegionUnix.cpp index ab03406d49b..9a615d1df68 100644 --- a/mozilla/gfx/src/motif/nsRegionUnix.cpp +++ b/mozilla/gfx/src/motif/nsRegionUnix.cpp @@ -51,23 +51,28 @@ void nsRegionUnix :: SetTo(const nsIRegion &aRegion) { nsRegionUnix * pRegion = (nsRegionUnix *)&aRegion; - ::XDestroyRegion(mRegion); - mRegion = ::XCreateRegion(); + SetRegionEmpty(); ::XUnionRegion(mRegion, pRegion->mRegion, mRegion); - mRegionType = eRegionType_rect ; // XXX: Should probably set to complex + SetRegionType(); } void nsRegionUnix :: SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) { - ::XDestroyRegion(mRegion); - mRegion = ::XCreateRegion(); - ::XOffsetRegion(mRegion, aX, aY); - ::XShrinkRegion(mRegion, -aWidth, -aHeight); + SetRegionEmpty(); - mRegionType = eRegionType_rect ; + XRectangle xrect; + + xrect.x = aX; + xrect.y = aY; + xrect.width = aWidth; + xrect.height = aHeight; + + ::XUnionRectWithRegion(&xrect, mRegion, mRegion); + + SetRegionType(); } void nsRegionUnix :: Intersect(const nsIRegion &aRegion) @@ -76,23 +81,19 @@ void nsRegionUnix :: Intersect(const nsIRegion &aRegion) ::XIntersectRegion(mRegion, pRegion->mRegion, mRegion); - mRegionType = eRegionType_rect ; + SetRegionType(); } void nsRegionUnix :: Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) { - Region tRegion; + Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight); - tRegion = ::XCreateRegion(); - - ::XOffsetRegion(tRegion, aX, aY); - ::XShrinkRegion(tRegion, -aWidth, -aHeight); - ::XIntersectRegion(mRegion, tRegion, mRegion); ::XDestroyRegion(tRegion); - mRegionType = eRegionType_rect ; + SetRegionType(); + } void nsRegionUnix :: Union(const nsIRegion &aRegion) @@ -101,23 +102,21 @@ void nsRegionUnix :: Union(const nsIRegion &aRegion) ::XUnionRegion(mRegion, pRegion->mRegion, mRegion); - mRegionType = eRegionType_rect ; + SetRegionType(); + } void nsRegionUnix :: Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) { - Region tRegion; - tRegion = ::XCreateRegion(); + Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight); - ::XOffsetRegion(tRegion, aX, aY); - ::XShrinkRegion(tRegion, -aWidth, -aHeight); - ::XUnionRegion(mRegion, tRegion, mRegion); ::XDestroyRegion(tRegion); - mRegionType = eRegionType_rect ; + SetRegionType(); + } void nsRegionUnix :: Subtract(const nsIRegion &aRegion) @@ -126,27 +125,28 @@ void nsRegionUnix :: Subtract(const nsIRegion &aRegion) ::XSubtractRegion(mRegion, pRegion->mRegion, mRegion); - mRegionType = eRegionType_rect ; + SetRegionType(); + } + void nsRegionUnix :: Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) { - Region tRegion; - - tRegion = ::XCreateRegion(); - - ::XOffsetRegion(tRegion, aX, aY); - ::XShrinkRegion(tRegion, -aWidth, -aHeight); + Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight); ::XSubtractRegion(mRegion, tRegion, mRegion); ::XDestroyRegion(tRegion); - mRegionType = eRegionType_rect ; + SetRegionType(); + } PRBool nsRegionUnix :: IsEmpty(void) { - return (::XEmptyRegion(mRegion)); + if (mRegionType == eRegionType_empty) + return PR_TRUE; + + return PR_FALSE; } PRBool nsRegionUnix :: IsEqual(const nsIRegion &aRegion) @@ -197,3 +197,41 @@ Region nsRegionUnix :: GetXRegion(void) { return (mRegion); } + +void nsRegionUnix :: SetRegionType() +{ + if (::XEmptyRegion(mRegion) == True) + mRegionType = eRegionType_empty; + else + mRegionType = eRegionType_rect ; +} + +void nsRegionUnix :: SetRegionEmpty() +{ + ::XDestroyRegion(mRegion); + mRegion = ::XCreateRegion(); +} + +Region nsRegionUnix :: CreateRectRegion(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) +{ + Region r = ::XCreateRegion(); + + XRectangle xrect; + + xrect.x = aX; + xrect.y = aY; + xrect.width = aWidth; + xrect.height = aHeight; + + ::XUnionRectWithRegion(&xrect, r, r); + + return (r); +} + + + + + + + + diff --git a/mozilla/gfx/src/motif/nsRegionUnix.h b/mozilla/gfx/src/motif/nsRegionUnix.h index d6f4631a4eb..5df89494e47 100644 --- a/mozilla/gfx/src/motif/nsRegionUnix.h +++ b/mozilla/gfx/src/motif/nsRegionUnix.h @@ -63,6 +63,10 @@ private: Region mRegion; nsRegionType mRegionType; +private: + virtual void SetRegionType(); + virtual void SetRegionEmpty(); + virtual Region CreateRectRegion(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); }; diff --git a/mozilla/gfx/src/motif/nsRenderingContextUnix.cpp b/mozilla/gfx/src/motif/nsRenderingContextUnix.cpp index 50ca8eef9d9..160efd1ed2b 100644 --- a/mozilla/gfx/src/motif/nsRenderingContextUnix.cpp +++ b/mozilla/gfx/src/motif/nsRenderingContextUnix.cpp @@ -28,7 +28,18 @@ #include "X11/Xlib.h" #include "X11/Xutil.h" -#define CLIPPING_NOT_FUNCTIONAL 1 +//#define NO_CLIP + +/* + Some Implementation Notes + + REGIONS: Regions are clipping rects associated with a GC. Since + multiple Drawable's can and do share GC's (they are hardware cached) + In order to select clip rect's into GC's, they must be writeable. Thus, + any consumer of the 'gfx' library must assume that GC's created by them + will be modified in gfx. + + */ class GraphicsState { @@ -56,21 +67,9 @@ GraphicsState :: GraphicsState() GraphicsState :: ~GraphicsState() { - if (nsnull != mClipRegion) - { - ::XDestroyRegion(mClipRegion); - mClipRegion = NULL; - } - mFont = nsnull; - } - -typedef unsigned char BYTE; - -#define RGB(r,g,b) ((unsigned long) (((BYTE) (r) | ((unsigned long) ((BYTE) (g)) <<8)) | (((unsigned long)(BYTE)(b)) << 16))) - static NS_DEFINE_IID(kRenderingContextIID, NS_IRENDERING_CONTEXT_IID); nsRenderingContextUnix :: nsRenderingContextUnix() @@ -103,8 +102,10 @@ nsRenderingContextUnix :: ~nsRenderingContextUnix() } mTMatrix = nsnull; + PopState(); + // Destroy the State Machine if (nsnull != mStateCache) { PRInt32 cnt = mStateCache->Count(); @@ -122,7 +123,14 @@ nsRenderingContextUnix :: ~nsRenderingContextUnix() mStateCache = nsnull; } - delete mFrontBuffer; + // Destroy the front buffer and it's GC if one was allocated for it + if (nsnull != mFrontBuffer) { + if (mFrontBuffer != mRenderingSurface) { + ::XFreeGC(mFrontBuffer->display, + mFrontBuffer->gc); + } + delete mFrontBuffer; + } } NS_IMPL_QUERY_INTERFACE(nsRenderingContextUnix, kRenderingContextIID) @@ -156,17 +164,7 @@ nsresult nsRenderingContextUnix :: Init(nsIDeviceContext* aContext, mFrontBuffer = mRenderingSurface; - ((nsDeviceContextUnix *)aContext)->SetDrawingSurface(mRenderingSurface); - ((nsDeviceContextUnix *)aContext)->InstallColormap(); - - mFontCache = mContext->GetFontCache(); - mP2T = mContext->GetDevUnitsToAppUnits(); - mTMatrix->AddScale(mContext->GetAppUnitsToDevUnits(), - mContext->GetAppUnitsToDevUnits()); - - mRegion = ::XCreateRegion(); - // Select a default font here? - return NS_OK; + return (CommonInit()); } nsresult nsRenderingContextUnix :: Init(nsIDeviceContext* aContext, @@ -177,20 +175,33 @@ nsresult nsRenderingContextUnix :: Init(nsIDeviceContext* aContext, NS_IF_ADDREF(mContext); mRenderingSurface = (nsDrawingSurfaceUnix *) aSurface; - ((nsDeviceContextUnix *)aContext)->SetDrawingSurface(mRenderingSurface); - ((nsDeviceContextUnix *)aContext)->InstallColormap(); + + return (CommonInit()); +} + +nsresult nsRenderingContextUnix :: CommonInit() +{ + ((nsDeviceContextUnix *)mContext)->SetDrawingSurface(mRenderingSurface); + ((nsDeviceContextUnix *)mContext)->InstallColormap(); mFontCache = mContext->GetFontCache(); mP2T = mContext->GetDevUnitsToAppUnits(); mTMatrix->AddScale(mContext->GetAppUnitsToDevUnits(), mContext->GetAppUnitsToDevUnits()); - mRegion = ::XCreateRegion(); return NS_OK; } nsresult nsRenderingContextUnix :: SelectOffScreenDrawingSurface(nsDrawingSurface aSurface) { - mRenderingSurface = (nsDrawingSurfaceUnix *) aSurface; + + if (mFrontBuffer == mRenderingSurface) { + XGCValues values; + mFrontBuffer->gc = ::XCreateGC(mRenderingSurface->display, + mRenderingSurface->drawable, + nsnull, &values); + } + + mRenderingSurface = (nsDrawingSurfaceUnix *) aSurface; return NS_OK; } @@ -206,6 +217,9 @@ nsIDeviceContext * nsRenderingContextUnix :: GetDeviceContext(void) void nsRenderingContextUnix :: PushState(void) { + + nsRect rect; + GraphicsState * state = new GraphicsState(); // Push into this state object, add to vector @@ -218,11 +232,32 @@ void nsRenderingContextUnix :: PushState(void) else mTMatrix = new nsTransform2D(mTMatrix); + GetClipRect(state->mLocalClip); + + state->mClipRegion = mRegion; + + if (nsnull != state->mClipRegion) { + mRegion = ::XCreateRegion(); + + XRectangle xrect; + + xrect.x = state->mLocalClip.x; + xrect.y = state->mLocalClip.y; + xrect.width = state->mLocalClip.width; + xrect.height = state->mLocalClip.height; + + ::XUnionRectWithRegion(&xrect, mRegion, mRegion); + } + + state->mColor = mCurrentColor; } PRBool nsRenderingContextUnix :: PopState(void) { + + PRBool bEmpty = PR_FALSE; + PRUint32 cnt = mStateCache->Count(); GraphicsState * state; @@ -235,12 +270,34 @@ PRBool nsRenderingContextUnix :: PopState(void) delete mTMatrix; mTMatrix = state->mMatrix; + if (nsnull != mRegion) + ::XDestroyRegion(mRegion); + + mRegion = state->mClipRegion; + + if (nsnull != mRegion && ::XEmptyRegion(mRegion) == True){ + bEmpty = PR_TRUE; + }else{ + + // Select in the old region. We probably want to set a dirty flag and only + // do this IFF we need to draw before the next Pop. We'd need to check the + // state flag on every draw operation. + if (nsnull != mRegion) + ::XSetRegion(mRenderingSurface->display, + mRenderingSurface->gc, + mRegion); + + } + + if (state->mColor != mCurrentColor) + SetColor(state->mColor); + + // Delete this graphics state object delete state; } - //XXX need to return if clip region is empty after pop. see nsirendering....h MMP - return PR_FALSE; + return bEmpty; } PRBool nsRenderingContextUnix :: IsVisibleRect(const nsRect& aRect) @@ -248,75 +305,71 @@ PRBool nsRenderingContextUnix :: IsVisibleRect(const nsRect& aRect) return PR_TRUE; } -PRBool nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine) +PRBool nsRenderingContextUnix :: SetClipRectInPixels(const nsRect& aRect, nsClipCombine aCombine) { -#ifdef CLIPPING_NOT_FUNCTIONAL - return PR_FALSE; -#endif - - // Essentially, create the rect and select it into the GC. Get the current - // ClipRegion first + PRBool bEmpty = PR_FALSE; nsRect trect = aRect; - mTMatrix->TransformCoord(&trect.x, &trect.y, - &trect.width, &trect.height); + XRectangle xrect; + + xrect.x = trect.x; + xrect.y = trect.y; + xrect.width = trect.width; + xrect.height = trect.height; + + Region a = ::XCreateRegion(); + ::XUnionRectWithRegion(&xrect, a, a); - //how we combine the new rect with the previous? if (aCombine == nsClipCombine_kIntersect) { - Region a = ::XCreateRegion(); Region tRegion = ::XCreateRegion(); - ::XOffsetRegion(a, trect.x, trect.y); - ::XShrinkRegion(a, -trect.width, -trect.height); - - ::XIntersectRegion(a, mRegion, tRegion); - - ::XDestroyRegion(mRegion); - ::XDestroyRegion(a); - - mRegion = tRegion; + if (nsnull != mRegion) { + ::XIntersectRegion(a, mRegion, tRegion); + ::XDestroyRegion(mRegion); + ::XDestroyRegion(a); + mRegion = tRegion; + } else { + ::XDestroyRegion(tRegion); + mRegion = a; + } } else if (aCombine == nsClipCombine_kUnion) { - Region a = ::XCreateRegion(); - Region tRegion = ::XCreateRegion(); + if (nsnull != mRegion) { + Region tRegion = ::XCreateRegion(); + ::XUnionRegion(a, mRegion, tRegion); + ::XDestroyRegion(mRegion); + ::XDestroyRegion(a); + mRegion = tRegion; + } else { + mRegion = a; + } - ::XOffsetRegion(a, trect.x, trect.y); - ::XShrinkRegion(a, -trect.width, -trect.height); - - ::XUnionRegion(a, mRegion, tRegion); - - ::XDestroyRegion(mRegion); - ::XDestroyRegion(a); - - mRegion = tRegion; } else if (aCombine == nsClipCombine_kSubtract) { - Region a = ::XCreateRegion(); - Region tRegion = ::XCreateRegion(); - ::XOffsetRegion(a, trect.x, trect.y); - ::XShrinkRegion(a, -trect.width, -trect.height); + if (nsnull != mRegion) { - ::XSubtractRegion(a, mRegion, tRegion); + Region tRegion = ::XCreateRegion(); + ::XSubtractRegion(mRegion, a, tRegion); + ::XDestroyRegion(mRegion); + ::XDestroyRegion(a); + mRegion = tRegion; - ::XDestroyRegion(mRegion); - ::XDestroyRegion(a); + } else { + mRegion = a; + } - mRegion = tRegion; } else if (aCombine == nsClipCombine_kReplace) { - Region a = ::XCreateRegion(); - ::XOffsetRegion(a, trect.x, trect.y); - ::XShrinkRegion(a, -trect.width, -trect.height); - - ::XDestroyRegion(mRegion); + if (nsnull != mRegion) + ::XDestroyRegion(mRegion); mRegion = a; @@ -324,18 +377,35 @@ PRBool nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine else NS_ASSERTION(PR_FALSE, "illegal clip combination"); - ::XSetRegion(mRenderingSurface->display, - mRenderingSurface->gc, - mRegion); + if (::XEmptyRegion(mRegion) == True) { - return PR_TRUE; + bEmpty = PR_TRUE; + ::XSetClipMask(mRenderingSurface->display, + mRenderingSurface->gc, + None); + + } else { + + ::XSetRegion(mRenderingSurface->display, + mRenderingSurface->gc, + mRegion); + + } + + return bEmpty; +} + +PRBool nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine) +{ + nsRect trect = aRect; + + mTMatrix->TransformCoord(&trect.x, &trect.y, + &trect.width, &trect.height); + return(SetClipRectInPixels(trect,aCombine)); } PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect) { -#ifdef CLIPPING_NOT_FUNCTIONAL - return PR_FALSE; -#endif if (mRegion != nsnull) { XRectangle xrect; @@ -343,35 +413,42 @@ PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect) aRect.SetRect(xrect.x, xrect.y, xrect.width, xrect.height); } else { aRect.SetRect(0,0,0,0); + return (PR_TRUE); } - return PR_TRUE; + if (::XEmptyRegion(mRegion) == True) + return PR_TRUE; + else + return PR_FALSE; } PRBool nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine) { - -#ifdef CLIPPING_NOT_FUNCTIONAL - return PR_FALSE; -#endif - nsRect rect; XRectangle xrect; nsRegionUnix *pRegion = (nsRegionUnix *)&aRegion; Region xregion = pRegion->GetXRegion(); + + ::XClipBox(xregion, &xrect); - ::XSetRegion(mRenderingSurface->display, - mRenderingSurface->gc, - xregion); + rect.x = xrect.x; + rect.y = xrect.y; + rect.width = xrect.width; + rect.height = xrect.height; - mRegion = xregion ; + SetClipRectInPixels(rect, aCombine); + + if (::XEmptyRegion(mRegion) == True) + return PR_TRUE; + else + return PR_FALSE; - return (PR_TRUE); } void nsRenderingContextUnix :: GetClipRegion(nsIRegion **aRegion) { + nsIRegion * pRegion ; static NS_DEFINE_IID(kCRegionCID, NS_REGION_CID); @@ -398,16 +475,7 @@ void nsRenderingContextUnix :: SetColor(nscolor aColor) { XGCValues values ; - mCurrentColor = aColor ; - - // XXX - //mCurrentColor++; - - PRUint32 pixel ; - - pixel = ((nsDeviceContextUnix *)mContext)->ConvertPixel(aColor); - - mCurrentColor = pixel; + mCurrentColor = ((nsDeviceContextUnix *)mContext)->ConvertPixel(aColor); values.foreground = mCurrentColor; values.background = mCurrentColor; @@ -416,6 +484,8 @@ void nsRenderingContextUnix :: SetColor(nscolor aColor) mRenderingSurface->gc, GCForeground | GCBackground, &values); + + mCurrentColor = aColor ; } @@ -431,7 +501,7 @@ void nsRenderingContextUnix :: SetFont(const nsFont& aFont) if (mFontMetrics) { -// mCurrFontHandle = (Font)mFontMetrics->GetFontHandle(); + mCurrFontHandle = ::XLoadFont(mRenderingSurface->display, (char *)mFontMetrics->GetFontHandle()); ::XSetFont(mRenderingSurface->display, @@ -476,22 +546,22 @@ nsDrawingSurface nsRenderingContextUnix :: CreateDrawingSurface(nsRect *aBounds) PRUint32 depth = DefaultDepth(mRenderingSurface->display, DefaultScreen(mRenderingSurface->display)); Pixmap p; - + if (aBounds != nsnull) { p = ::XCreatePixmap(mRenderingSurface->display, - mRenderingSurface->drawable, - aBounds->width, aBounds->height, depth); + mRenderingSurface->drawable, + aBounds->width, aBounds->height, depth); } else { p = ::XCreatePixmap(mRenderingSurface->display, - mRenderingSurface->drawable, - 2, 2, depth); + mRenderingSurface->drawable, + 2, 2, depth); } nsDrawingSurfaceUnix * surface = new nsDrawingSurfaceUnix(); surface->drawable = p ; surface->display = mRenderingSurface->display; - surface->gc = mRenderingSurface->gc; + surface->gc = mFrontBuffer->gc; surface->visual = mRenderingSurface->visual; surface->depth = mRenderingSurface->depth; @@ -506,8 +576,8 @@ void nsRenderingContextUnix :: DestroyDrawingSurface(nsDrawingSurface aDS) ::XFreePixmap(surface->display, surface->drawable); //XXX greg, this seems bad. MMP - if (mRenderingSurface == surface) - mRenderingSurface = nsnull; + if (mRenderingSurface == surface) + mRenderingSurface = nsnull; delete aDS; } @@ -805,17 +875,17 @@ void nsRenderingContextUnix :: DrawString(const nsString& aString, void nsRenderingContextUnix :: DrawImage(nsIImage *aImage, nscoord aX, nscoord aY) { -nscoord width,height; + nscoord width,height; width = NS_TO_INT_ROUND(mP2T * aImage->GetWidth()); height = NS_TO_INT_ROUND(mP2T * aImage->GetHeight()); - + this->DrawImage(aImage,aX,aY,width,height); } void nsRenderingContextUnix :: DrawImage(nsIImage *aImage, nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) { -nsRect tr; + nsRect tr; tr.x = aX; tr.y = aY; @@ -826,7 +896,7 @@ nsRect tr; void nsRenderingContextUnix :: DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect) { -nsRect sr,dr; + nsRect sr,dr; sr = aSRect; mTMatrix ->TransformCoord(&sr.x,&sr.y,&sr.width,&sr.height); @@ -840,11 +910,11 @@ nsRect sr,dr; void nsRenderingContextUnix :: DrawImage(nsIImage *aImage, const nsRect& aRect) { -nsRect tr; + nsRect tr; tr = aRect; mTMatrix->TransformCoord(&tr.x,&tr.y,&tr.width,&tr.height); - + if (aImage != nsnull) { ((nsImageUnix*)aImage)->Draw(*this,mRenderingSurface,tr.x,tr.y,tr.width,tr.height); } else { @@ -854,13 +924,24 @@ nsRect tr; nsresult nsRenderingContextUnix :: CopyOffScreenBits(nsRect &aBounds) { + + + ::XSetClipMask(mFrontBuffer->display, + mFrontBuffer->gc, + None); + ::XCopyArea(mRenderingSurface->display, mRenderingSurface->drawable, mFrontBuffer->drawable, mFrontBuffer->gc, aBounds.x, aBounds.y, aBounds.width, aBounds.height, 0, 0); - + + if (nsnull != mRegion) + ::XSetRegion(mRenderingSurface->display, + mRenderingSurface->gc, + mRegion); + return NS_OK; } diff --git a/mozilla/gfx/src/motif/nsRenderingContextUnix.h b/mozilla/gfx/src/motif/nsRenderingContextUnix.h index f4413a7f5e8..3bc647fb711 100644 --- a/mozilla/gfx/src/motif/nsRenderingContextUnix.h +++ b/mozilla/gfx/src/motif/nsRenderingContextUnix.h @@ -58,6 +58,7 @@ public: virtual nsresult Init(nsIDeviceContext* aContext, nsIWidget *aWindow); virtual nsresult Init(nsIDeviceContext* aContext, nsDrawingSurface aSurface); + virtual nsresult CommonInit(); virtual void Reset(); @@ -70,6 +71,7 @@ public: virtual PRBool IsVisibleRect(const nsRect& aRect); + virtual PRBool SetClipRectInPixels(const nsRect& aRect, nsClipCombine aCombine); virtual PRBool SetClipRect(const nsRect& aRect, nsClipCombine aCombine); virtual PRBool GetClipRect(nsRect &aRect); virtual PRBool SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine); diff --git a/mozilla/view/src/nsView.cpp b/mozilla/view/src/nsView.cpp index 63f463e7ec1..09b9b74855e 100644 --- a/mozilla/view/src/nsView.cpp +++ b/mozilla/view/src/nsView.cpp @@ -96,24 +96,9 @@ nsEventStatus PR_CALLBACK HandleEvent(nsGUIEvent *aEvent) //printf("damage repair...\n"); -#ifdef NS_UNIX - view->GetBounds(vrect); - - PRBool db = PR_FALSE; - - if ((((float)trect.width * trect.height) / ((float)vrect.width * vrect.height)) > 0.75f) - db = PR_TRUE; - - vm->Refresh(view, ((nsPaintEvent *)aEvent)->renderingContext, &trect, - ((db == PR_TRUE) ? NS_VMREFRESH_DOUBLE_BUFFER : 0) | NS_VMREFRESH_SCREEN_RECT); -#else - vm->UpdateView(view, trect, -// ((db == PR_TRUE) ? NS_VMREFRESH_DOUBLE_BUFFER : 0) | NS_VMREFRESH_SCREEN_RECT); -// NS_VMREFRESH_IMMEDIATE); vm->Composite(); -#endif NS_RELEASE(dx); NS_RELEASE(px); diff --git a/mozilla/widget/src/motif/nsToolkit.cpp b/mozilla/widget/src/motif/nsToolkit.cpp index 7d47851870b..912e5b7fd62 100644 --- a/mozilla/widget/src/motif/nsToolkit.cpp +++ b/mozilla/widget/src/motif/nsToolkit.cpp @@ -67,4 +67,12 @@ void nsToolkit::Init(PRThread *aThread) { } +void nsToolkit::SetSharedGC(GC aGC) +{ + mSharedGC = aGC; +} +GC nsToolkit::GetSharedGC() +{ + return (mSharedGC); +} diff --git a/mozilla/widget/src/motif/nsToolkit.h b/mozilla/widget/src/motif/nsToolkit.h index 1c1ea89239c..226cdf673e6 100644 --- a/mozilla/widget/src/motif/nsToolkit.h +++ b/mozilla/widget/src/motif/nsToolkit.h @@ -20,6 +20,7 @@ #define TOOLKIT_H #include "nsIToolkit.h" +#include "X11/Xlib.h" struct MethodInfo; @@ -32,15 +33,20 @@ struct MethodInfo; class nsToolkit : public nsIToolkit { - public: - nsToolkit(); - virtual ~nsToolkit(); - - NS_DECL_ISUPPORTS - +public: + nsToolkit(); + virtual ~nsToolkit(); + + NS_DECL_ISUPPORTS + virtual void Init(PRThread *aThread); + +public: + NS_IMETHOD_(GC) GetSharedGC(); + NS_IMETHOD_(void) SetSharedGC(GC aGC); - +private: + GC mSharedGC; }; diff --git a/mozilla/widget/src/motif/nsWindow.cpp b/mozilla/widget/src/motif/nsWindow.cpp index fa04dacb2b8..537fd74debc 100644 --- a/mozilla/widget/src/motif/nsWindow.cpp +++ b/mozilla/widget/src/motif/nsWindow.cpp @@ -180,6 +180,7 @@ nsWindow::nsWindow(nsISupports *aOuter): mOuter = aOuter; else mOuter = &mInner; + mGC = nsnull ; } @@ -190,6 +191,10 @@ nsWindow::nsWindow(nsISupports *aOuter): //------------------------------------------------------------------------- nsWindow::~nsWindow() { + if (nsnull != mGC) { + ::XFreeGC((Display *)GetNativeData(NS_NATIVE_DISPLAY),mGC); + mGC = nsnull; + } } @@ -230,6 +235,9 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent, mToolkit = new nsToolkit(); mToolkit->AddRef(); mToolkit->Init(PR_GetCurrentThread()); + + // Create a shared GC for all widgets + ((nsToolkit *)mToolkit)->SetSharedGC((GC)GetNativeData(NS_NATIVE_GRAPHIC)); } } @@ -246,25 +254,9 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent, else { nsresult res; - // XXX Move this! - For some reason Registering in another DLL (shell) isn't working - -#define GFXWIN_DLL "libgfxunix.so" - - /*static NS_DEFINE_IID(kCRenderingContextIID, NS_RENDERING_CONTEXT_CID); - static NS_DEFINE_IID(kCDeviceContextIID, NS_DEVICE_CONTEXT_CID); - static NS_DEFINE_IID(kCFontMetricsIID, NS_FONT_METRICS_CID); - static NS_DEFINE_IID(kCImageIID, NS_IMAGE_CID); - - NSRepository::RegisterFactory(kCRenderingContextIID, GFXWIN_DLL, PR_FALSE, PR_FALSE); - NSRepository::RegisterFactory(kCDeviceContextIID, GFXWIN_DLL, PR_FALSE, PR_FALSE); - NSRepository::RegisterFactory(kCFontMetricsIID, GFXWIN_DLL, PR_FALSE, PR_FALSE); - NSRepository::RegisterFactory(kCImageIID, GFXWIN_DLL, PR_FALSE, PR_FALSE); - - */ - static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID); static NS_DEFINE_IID(kDeviceContextIID, NS_IDEVICE_CONTEXT_IID); - + //res = !NS_OK; res = NSRepository::CreateInstance(kDeviceContextCID, nsnull, @@ -303,8 +295,9 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent, XmNmarginWidth, 0, nsnull); - mWidget = frame ; + + mWidget = frame ; if (mainWindow) { XmMainWindowSetAreas (mainWindow, nsnull, nsnull, nsnull, nsnull, frame); @@ -325,12 +318,36 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent, nsXtWidget_Resize_Callback, this); + + /*XtAddCallback(mWidget, XmNexposeCallback, nsXtWidget_Expose_Callback, this);*/ + // Create a Writeable GC for this Widget. Unfortunatley, + // the Window for the Widget is not created properly at this point and + // we Need the GC prior to the Rendering Context getting created, so + // we create a small dummy window of the default depth as our dummy Drawable + // to create a compatible GC + + if (nsnull == mGC) { + + XGCValues values; + Window w; + Display * d = XtDisplay(mWidget); + + w = ::XCreateSimpleWindow(d, + RootWindow(d,DefaultScreen(d)), + 0,0,1,1,0, + BlackPixel(d,DefaultScreen(d)), + WhitePixel(d,DefaultScreen(d))); + mGC = ::XCreateGC(d, w, nsnull, &values); + + ::XDestroyWindow(d,w); + } + } @@ -732,14 +749,14 @@ void* nsWindow::GetNativeData(PRUint32 aDataType) break; case NS_NATIVE_GRAPHIC: { - XGCValues values; - GC aGC; - - aGC= ::XtGetGC(mWidget, - nsnull, - &values); + // We Cache a Read-Only Shared GC in the Toolkit. If we don't + // have one ourselves (because it needs to be writeable) grab the + // the shared GC + + if (nsnull == mGC) + return (((nsToolkit *)mToolkit)->GetSharedGC()); - return (void*)aGC; + return ((void*)mGC); } break; case NS_NATIVE_COLORMAP: @@ -762,6 +779,7 @@ nsIRenderingContext* nsWindow::GetRenderingContext() nsIRenderingContext * ctx = nsnull; if (GetNativeData(NS_NATIVE_WIDGET)) { + nsresult res; static NS_DEFINE_IID(kRenderingContextCID, NS_RENDERING_CONTEXT_CID); diff --git a/mozilla/widget/src/motif/nsWindow.h b/mozilla/widget/src/motif/nsWindow.h index 081dce83843..7eeeda906d6 100644 --- a/mozilla/widget/src/motif/nsWindow.h +++ b/mozilla/widget/src/motif/nsWindow.h @@ -181,6 +181,8 @@ protected: } mInner; friend InnerSupport; +private: + GC mGC; }; //