Fix for bug 640 - moving thin frames leaves mess

Pavel Roskin proski at
Fri Sep 26 00:16:04 CDT 2003

On Thu, 25 Sep 2003, Alexandre Julliard wrote:

> Pavel Roskin <proski at> writes:
> > OK, drop that part of the patch for now.  I think that xoring anything
> > with COLOR_WINDOWTEXT is incorrect, but I need to test possible other
> > solutions.
> >
> > After all, the bug is about the white mess from dragging windows, which is
> > a bigger problem.
> Well, yes, but it's a bug in XFree86, not in Wine.

Confirmed.  Accelerated X works correctly with the same hardware and X
libraries, while XFree86 4.2.1 exhibits the bug.

Nevertheless, I checked how the focus rectangle works on Windows 2000 and
found something we may want to fix.

Actually, there are two focus rectangles.  The one displayed on buttons
with keyboard focus is drawn by opaque pen in xor mode using alternating
button face and button text colors.  This guarantees that the focus is
visible if the text on buttons is visible.  Usually it's not different
from the other focus rectangle.  But if the button text is white on
lightgray, the focus rectangle is almost a continuous line.  If the button
text is blue on lightgray, the focus rectangle is drawn by yellow and
black dots.

The other focus rectangle is displayed by calling DrawFocusRectangle().
In this case, the line is transparent and uses simple inversion.  No color
scheme settings affect the color.

I'm attaching a patch that fixes DrawFocusRectangle() to use inversion.
I also removed reference to COLOR_WINDOWTEXT to aesthetic reasons.  The
pen color is unused, but nobody should think that any color schemes affect
this function.

This change is also sufficient to work around the XFree86 bug.  We don't
have to work it around, but we are lucky that it's a side effect of making
DrawFocusRect() correct.

I also included a patch that removes special treatment for R2_XORPEN with
black pen.  I don't see such behavior in Windows 2000.  I also tested
Paintbrush from Windows 3.11 and it has no graphical problems
except Pick->Tilt, which is unaffected by this code.  It's an old hack
that is wrong and unneeded now.

Pavel Roskin
-------------- next part --------------
--- graphics/x11drv/graphics.c
+++ graphics/x11drv/graphics.c
@@ -207,15 +207,6 @@ BOOL X11DRV_SetupGCForPen( X11DRV_PDEVIC
         val.foreground = WhitePixel( gdi_display, DefaultScreen(gdi_display) );
 	val.function = GXcopy;
-    case R2_XORPEN :
-	val.foreground = physDev->pen.pixel;
-	/* It is very unlikely someone wants to XOR with 0 */
-	/* This fixes the rubber-drawings in paintbrush */
-	if (val.foreground == 0)
-            val.foreground = (WhitePixel( gdi_display, DefaultScreen(gdi_display) ) ^
-                              BlackPixel( gdi_display, DefaultScreen(gdi_display) ));
-	val.function = GXxor;
-	break;
     default :
 	val.foreground = physDev->pen.pixel;
 	val.function   = X11DRV_XROPfunction[rop2-1];
--- windows/painting.c
+++ windows/painting.c
@@ -1158,9 +1158,9 @@ BOOL WINAPI DrawFocusRect( HDC hdc, cons
     INT oldDrawMode, oldBkMode;
     hOldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
-    hNewPen = CreatePen(PS_ALTERNATE, 1, GetSysColor(COLOR_WINDOWTEXT));
+    hNewPen = CreatePen(PS_ALTERNATE, 1, RGB(255, 255, 255));
     hOldPen = SelectObject(hdc, hNewPen);
-    oldDrawMode = SetROP2(hdc, R2_XORPEN);
+    oldDrawMode = SetROP2(hdc, R2_NOT);
     oldBkMode = SetBkMode(hdc, TRANSPARENT);
     Rectangle(hdc, rc->left, rc->top, rc->right, rc->bottom);

More information about the wine-devel mailing list