RestoreVisRgn patch

Rein Klazes rklazes at xs4all.nl
Wed Jan 2 15:20:28 CST 2002


Hi,

Painting code in girotel 2.1 seems to be buggy, it does the following:

  hdc=BeginPaint(...)

  ...

  hpen=CreatePen(...) 
  SelectObject(hdc,hpen);

  MoveTo(...);LineTo();

  DeleteObject(hpen);

  DrawTextA( pSomeText );

  DeleteObject(hpen); /* ???????? */

The code deletes an object that is already deleted. This should not be
so bad if the object handle hadn't been re-used. The re-use happens
within the DrawTextA(0 which does a SaveVisRgn(hdc) ...
RestoreVisRgn(hdc). The nett result is that the hVisRgn of the dc gets
the same value as hpen, and the object is deleted subsequently leading
to severe diplay problems.

The following patch modifies the RestoreVisRgn() so that it copies the
saved visible region back instead of just replacing the existing one. 

I am quite aware that this is working around a bug in a application,
I'm open to other suggestions.

(please review for possible violations of proper GDI locks handling)

Changelog:
	objects/:		clipping.c
	Modify RestoreVisRgn so that the visible region handle stays 
	the same.
	
Rein.
-- 
Rein Klazes
rklazes at xs4all.nl
-------------- next part --------------
--- wine/objects/clipping.c	Thu Dec 27 08:35:04 2001
+++ mywine/objects/clipping.c	Wed Jan  2 21:45:54 2002
@@ -590,15 +590,22 @@
     if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) goto done;
 
     saved = obj->header.hNext;
-    GDI_ReleaseObj( dc->hVisRgn );
-    if (!saved || !(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC ))) goto done;
 
-    DeleteObject( dc->hVisRgn );
-    dc->hVisRgn = saved;
+    if (!saved || !(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC ))) {
+        GDI_ReleaseObj( dc->hVisRgn  );
+        goto done;
+    }
+    
+    CombineRgn(dc->hVisRgn, saved,  0, RGN_COPY );
+    
+    obj->header.hNext = savedObj->header.hNext;
+    
+    GDI_ReleaseObj( saved  );
+    DeleteObject( saved );
     dc->flags &= ~DC_DIRTY;
     CLIPPING_UpdateGCRegion( dc );
-    ret = savedObj->rgn->type; /* FIXME */
-    GDI_ReleaseObj( saved );
+    ret = obj->rgn->type; /* FIXME */
+    GDI_ReleaseObj( dc->hVisRgn  );
  done:
     GDI_ReleaseObj( hdc );
     return ret;


More information about the wine-patches mailing list