mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 12:55:46 +00:00
[OS/2] Bug 371505: finally fix repaint issues with Thebes
This commit is contained in:
parent
56b4260049
commit
ba6c9a3377
@ -47,8 +47,6 @@
|
||||
class THEBES_API gfxOS2Surface : public gfxASurface {
|
||||
|
||||
public:
|
||||
// constructor to create a cairo surface using an existing PS
|
||||
gfxOS2Surface(HPS aPS, const gfxIntSize& aSize);
|
||||
// constructor used to create a memory surface of given size
|
||||
gfxOS2Surface(const gfxIntSize& aSize,
|
||||
gfxASurface::gfxImageFormat aImageFormat);
|
||||
@ -56,11 +54,20 @@ public:
|
||||
gfxOS2Surface(HWND aWnd);
|
||||
virtual ~gfxOS2Surface();
|
||||
|
||||
// Special functions that only make sense for the OS/2 port of cairo:
|
||||
|
||||
// Update the cairo surface.
|
||||
// While gfxOS2Surface keeps track of the presentation handle itself,
|
||||
// use the one from WinBeginPaint() here.
|
||||
void Refresh(RECTL *aRect, HPS aPS);
|
||||
|
||||
// Reset the cairo surface to the given size.
|
||||
int Resize(const gfxIntSize& aSize);
|
||||
|
||||
HPS GetPS() { return mPS; }
|
||||
gfxIntSize GetSize() { return mSize; }
|
||||
|
||||
private:
|
||||
PRBool mOwnsPS;
|
||||
PRBool mHasWnd; // indicates if created through the HWND constructor
|
||||
HDC mDC; // memory device context
|
||||
HPS mPS; // presentation space connected to window or memory device
|
||||
|
@ -43,28 +43,9 @@
|
||||
* class gfxOS2Surface
|
||||
**********************************************************************/
|
||||
|
||||
gfxOS2Surface::gfxOS2Surface(HPS aPS, const gfxIntSize& aSize)
|
||||
: mOwnsPS(PR_FALSE), mHasWnd(PR_FALSE), mDC(nsnull), mPS(aPS), mBitmap(nsnull), mSize(aSize)
|
||||
{
|
||||
#ifdef DEBUG_thebes_2
|
||||
printf("gfxOS2Surface[%#x]::gfxOS2Surface(HPS=%#x, Size=%dx%d)\n", (unsigned int)this,
|
||||
(unsigned int)mPS, aSize.width, aSize.height);
|
||||
#endif
|
||||
|
||||
// create the cairo surface on the passed PS
|
||||
cairo_surface_t *surf = cairo_os2_surface_create(mPS, mSize.width, mSize.height);
|
||||
#ifdef DEBUG_thebes_2
|
||||
printf(" type(%#x)=%d (ID=%#x, h/w=%d/%d)\n", (unsigned int)surf,
|
||||
cairo_surface_get_type(surf), (unsigned int)mPS, mSize.width, mSize.height);
|
||||
#endif
|
||||
// XXX for now uncomment the mark_dirty function, see bug 371505
|
||||
//cairo_surface_mark_dirty(surf);
|
||||
Init(surf);
|
||||
}
|
||||
|
||||
gfxOS2Surface::gfxOS2Surface(const gfxIntSize& aSize,
|
||||
gfxASurface::gfxImageFormat aImageFormat)
|
||||
: mOwnsPS(PR_TRUE), mHasWnd(PR_FALSE), mSize(aSize)
|
||||
: mHasWnd(PR_FALSE), mSize(aSize)
|
||||
{
|
||||
#ifdef DEBUG_thebes_2
|
||||
printf("gfxOS2Surface[%#x]::gfxOS2Surface(Size=%dx%d, %d)\n", (unsigned int)this,
|
||||
@ -105,13 +86,18 @@ gfxOS2Surface::gfxOS2Surface(const gfxIntSize& aSize,
|
||||
printf(" type(%#x)=%d (ID=%#x, h/w=%d/%d)\n", (unsigned int)surf,
|
||||
cairo_surface_get_type(surf), (unsigned int)mPS, mSize.width, mSize.height);
|
||||
#endif
|
||||
// XXX for now uncomment the mark_dirty function, see bug 371505
|
||||
//cairo_surface_mark_dirty(surf);
|
||||
// Normally, OS/2 cairo surfaces have to be forced to redraw completely
|
||||
// by calling cairo_surface_mark_dirty(surf), but Mozilla paints them in
|
||||
// full, so that is not necessary here.
|
||||
|
||||
// manual refresh is done from nsWindow::OnPaint
|
||||
cairo_os2_surface_set_manual_window_refresh(surf, 1);
|
||||
|
||||
Init(surf);
|
||||
}
|
||||
|
||||
gfxOS2Surface::gfxOS2Surface(HWND aWnd)
|
||||
: mOwnsPS(PR_TRUE), mHasWnd(PR_TRUE), mDC(nsnull), mBitmap(nsnull)
|
||||
: mHasWnd(PR_TRUE), mDC(nsnull), mBitmap(nsnull)
|
||||
{
|
||||
#ifdef DEBUG_thebes_2
|
||||
printf("gfxOS2Surface[%#x]::gfxOS2Surface(HWND=%#x)\n", (unsigned int)this,
|
||||
@ -131,10 +117,15 @@ gfxOS2Surface::gfxOS2Surface(HWND aWnd)
|
||||
printf(" type(%#x)=%d (ID=%#x, h/w=%d/%d)\n", (unsigned int)surf,
|
||||
cairo_surface_get_type(surf), (unsigned int)mPS, mSize.width, mSize.height);
|
||||
#endif
|
||||
// Normally, OS/2 cairo surfaces have to be forced to redraw completely
|
||||
// by calling cairo_surface_mark_dirty(surf), but Mozilla paints them in
|
||||
// full, so that is not necessary here.
|
||||
|
||||
// record the window handle in the cairo surface, so that refresh works
|
||||
cairo_os2_surface_set_hwnd(surf, aWnd);
|
||||
// XXX for now uncomment the mark_dirty function, see bug 371505
|
||||
//cairo_surface_mark_dirty(surf);
|
||||
// manual refresh is done from nsWindow::OnPaint
|
||||
cairo_os2_surface_set_manual_window_refresh(surf, 1);
|
||||
|
||||
Init(surf);
|
||||
}
|
||||
|
||||
@ -149,7 +140,7 @@ gfxOS2Surface::~gfxOS2Surface()
|
||||
// hand were created on memory device contexts with the GPI functions, so
|
||||
// use those to clean up stuff.
|
||||
if (mHasWnd) {
|
||||
if (mOwnsPS && mPS) {
|
||||
if (mPS) {
|
||||
WinReleasePS(mPS);
|
||||
}
|
||||
} else {
|
||||
@ -157,7 +148,7 @@ gfxOS2Surface::~gfxOS2Surface()
|
||||
GpiSetBitmap(mPS, NULL);
|
||||
GpiDeleteBitmap(mBitmap);
|
||||
}
|
||||
if (mOwnsPS && mPS) {
|
||||
if (mPS) {
|
||||
GpiDestroyPS(mPS);
|
||||
}
|
||||
if (mDC) {
|
||||
@ -165,3 +156,25 @@ gfxOS2Surface::~gfxOS2Surface()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gfxOS2Surface::Refresh(RECTL *aRect, HPS aPS)
|
||||
{
|
||||
#ifdef DEBUG_thebes_2
|
||||
printf("gfxOS2Surface[%#x]::Refresh(x=%ld,%ld/y=%ld,%ld, HPS=%#x), mPS=%#x\n",
|
||||
(unsigned int)this,
|
||||
aRect->xLeft, aRect->xRight, aRect->yBottom, aRect->yTop,
|
||||
(unsigned int)aPS, (unsigned int)mPS);
|
||||
#endif
|
||||
cairo_os2_surface_refresh_window(CairoSurface(), aPS, aRect);
|
||||
}
|
||||
|
||||
int gfxOS2Surface::Resize(const gfxIntSize& aSize)
|
||||
{
|
||||
#ifdef DEBUG_thebes_2
|
||||
printf("gfxOS2Surface[%#x]::Resize(%dx%d)\n", (unsigned int)this,
|
||||
aSize.width, aSize.height);
|
||||
#endif
|
||||
mSize = aSize; // record the new size
|
||||
// hardcode mutex timeout to 50ms for now
|
||||
return cairo_os2_surface_set_size(CairoSurface(), mSize.width, mSize.height, 50);
|
||||
}
|
||||
|
@ -1125,9 +1125,6 @@ NS_METHOD nsWindow::Destroy()
|
||||
CaptureRollupEvents(nsnull, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
// Destroy thebes surface now, XXX do we need this at all??
|
||||
mThebesSurface = nsnull;
|
||||
|
||||
if (mWnd) {
|
||||
HWND hwndBeingDestroyed = mFrameWnd ? mFrameWnd : mWnd;
|
||||
DEBUGFOCUS(Destroy);
|
||||
@ -3165,16 +3162,7 @@ PRBool nsWindow::OnPaint()
|
||||
(PRInt32)mWnd);
|
||||
#endif // NS_DEBUG
|
||||
|
||||
// Thebes code version, adapted from windows/nsWindow.cpp
|
||||
// XXX as a preliminary solution for repaint problems of cairo-os2
|
||||
// builds, repaint the whole window for each paint event
|
||||
// see Bug 371505
|
||||
SWP swp;
|
||||
WinQueryWindowPos(mWnd, &swp);
|
||||
nsRefPtr<gfxASurface> targetSurface =
|
||||
new gfxOS2Surface(hPS, gfxIntSize(swp.cx, swp.cy));
|
||||
//new gfxOS2Surface(hPS, gfxIntSize(rect.width, rect.height));
|
||||
nsRefPtr<gfxContext> thebesContext = new gfxContext(targetSurface);
|
||||
nsRefPtr<gfxContext> thebesContext = new gfxContext(mThebesSurface);
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> context;
|
||||
nsresult rv = mContext->CreateRenderingContextInstance(*getter_AddRefs(context));
|
||||
@ -3190,7 +3178,15 @@ PRBool nsWindow::OnPaint()
|
||||
}
|
||||
|
||||
event.renderingContext = context;
|
||||
rc = DispatchWindowEvent(&event, eventStatus);
|
||||
// try to dispatch a few times, 10 should be more than enough, in tests
|
||||
// we get something at the second try at the latest
|
||||
for (int i = 0; i < 10; i++) {
|
||||
rc = DispatchWindowEvent(&event, eventStatus);
|
||||
if (rc) {
|
||||
// this was handled, so we can stop trying
|
||||
break;
|
||||
}
|
||||
}
|
||||
event.renderingContext = nsnull;
|
||||
|
||||
if (rc) {
|
||||
@ -3200,7 +3196,9 @@ PRBool nsWindow::OnPaint()
|
||||
thebesContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
thebesContext->Paint();
|
||||
}
|
||||
NS_RELEASE(event.widget);
|
||||
} // if (mEventCallback)
|
||||
mThebesSurface->Refresh(&rcl, hPS);
|
||||
} // if (!WinIsRectEmpty(0, &rcl))
|
||||
|
||||
WinEndPaint(hPS);
|
||||
@ -3243,6 +3241,16 @@ PRBool nsWindow::OnResize(PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
mBounds.width = aX;
|
||||
mBounds.height = aY;
|
||||
|
||||
// resize the thebes surface to the new size
|
||||
if (!mThebesSurface) {
|
||||
// So we need to create a thebes surface for this window.
|
||||
// (This is necessary for the first resize of a window.)
|
||||
mThebesSurface = new gfxOS2Surface(mWnd);
|
||||
}
|
||||
|
||||
mThebesSurface->Resize(gfxIntSize(aX, aY));
|
||||
|
||||
return DispatchResizeEvent( aX, aY);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user