From xemacs-m  Mon Mar 17 02:23:12 1997
Received: from GS213.SP.CS.CMU.EDU (GS213.SP.CS.CMU.EDU [128.2.209.183])
	by xemacs.org (8.8.5/8.8.5) with SMTP id CAA10370
	for <xemacs-beta@xemacs.org>; Mon, 17 Mar 1997 02:23:11 -0600 (CST)
Received: by GS213.SP.CS.CMU.EDU (AIX 3.2/UCB 5.64/4.03)
          id AA46475; Mon, 17 Mar 1997 03:23:09 -0500
Date: Mon, 17 Mar 1997 03:23:09 -0500
Message-Id: <9703170823.AA46475@GS213.SP.CS.CMU.EDU>
From: Darrell Kindred <dkindred@cmu.edu>
To: xemacs-beta@xemacs.org
Subject: pixmap bug [w/ PATCH]
Organization: Carnegie Mellon University School of Computer Science

Hi,

I noticed the following bug today:

  - xrdb /dev/null; xemacs -q
    do "About XEmacs..." then place another window so that
    it obscures the right half of the XEmacs logo.  Now,
    bring the XEmacs frame back to the top.  The background
    of the logo changes to black.

The same bug can cause the new display-time digits to get a
black background under similar circumstances.

The problem is that, when part of the pixmap is revealed,
x_output_x_pixmap() sets a clip rectangle so that only the
revealed part gets redrawn.  But the gc already has a
clipmask (corresponding to the transparent bits of the
image), and that gets obliterated when the new clip
rectangle is set.

The patch below fixes this bug, at the cost of some
unnecessary drawing.  The comments I've added suggest a
couple of ways the extra drawing might be eliminated, but I
didn't have time to try them out.

- Darrell

--- src/redisplay-x.c.orig	Mon Mar 17 01:52:48 1997
+++ src/redisplay-x.c	Mon Mar 17 02:46:40 1997
@@ -1120,6 +1120,7 @@
   GC gc;
   XGCValues gcv;
   unsigned long pixmap_mask;
+  int need_clipping = (clip_x || clip_y);
 
   if (!override_gc)
     {
@@ -1137,14 +1138,27 @@
 	  gcv.clip_y_origin = y - pixmap_offset;
 	  pixmap_mask |= (GCFunction | GCClipMask | GCClipXOrigin |
 			  GCClipYOrigin);
+	  /* Can't set a clip rectangle below because we already have a mask.
+	     We could conceivably create a new clipmask by zeroing out
+	     everything outside the clip region.  Is it worth it? 
+	     Is it possible to get an equivalent effect by changing the
+	     args to XCopyArea below rather than messing with a clip box?
+	     - dkindred@cs.cmu.edu */
+	  need_clipping = 0; 
 	}
 
       gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, pixmap_mask);
     }
   else
-    gc = override_gc;
+    {
+      gc = override_gc;
+      /* override_gc might have a mask already--we don't want to nuke it.
+	 Maybe we can insist that override_gc have no mask, or use
+	 one of the suggestions above. */
+      need_clipping = 0;
+    }
 
-  if (clip_x || clip_y)
+  if (need_clipping)
     {
       XRectangle clip_box[1];
 
@@ -1179,7 +1193,7 @@
 		  1L);
     }
 
-  if (clip_x || clip_y)
+  if (need_clipping)
     {
       XSetClipMask (dpy, gc, None);
       XSetClipOrigin (dpy, gc, 0, 0);

