Subject: Bug in [BD]Gradient?

From: Danek Duvall <[email-masked]>
Date: Tue, 26 Jan 1999 14:17:07 -0800

With CVS sources of about five hours ago, I'm having a severe problem with
DGradient on a Solaris 2.7 box.  I'm not sure how to explain it ... if
anyone can tell me how to take a snapshot of a menu, I'd be grateful.
Basically, though, it's coming across in what looks like two colors, with
lines drawn in one color rather haphazardly across the menu.  This happens
for linear as well as nonlinear gradients.  Changing the number of steps
doesn't seem to help.  Horizontal and Vertical gradients are perfectly
smooth.

The line I'm using is

MenuStyle * MenuFace DGradient 128 2 grey50 50 grey70 50 grey60

I tried the examples in the manpage, but they had the same problem.

When I get home, I'll try to reproduce it on my Linux box.

Sorry for throwing this in so late; I haven't been keeping up with the code
base.

Danek
--
Visit the official FVWM web page at <URL:http://fvwm.math.uh.edu/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Kent Howard <[email-masked]>
Date: Tue, 26 Jan 1999 16:20:28 -0800

On Tue, Jan 26, 1999 at 02:17:07PM -0800, Danek Duvall wrote:
+----------
| DGradient on a Solaris 2.7 box.  I'm not sure how to explain it ... if
| anyone can tell me how to take a snapshot of a menu, I'd be grateful.
+----------

Try

sleep 5 ; xwd -root > snapshot.xwd

then popup the menu and wait.  You'll get a snapshot of your
whole screen with the menu included.

- Kent

---

From: Danek Duvall <[email-masked]>
Date: Tue, 26 Jan 1999 17:10:46 -0800

> sleep 5 ; xwd -root > snapshot.xwd

Thanks.  I've put a .tiff file of the problem at

    http://www.campusclub.princeton.edu/duvall/menu.tiff

HTH,
Danek

---

From: Dominik Vogt <[email-masked]>
Date: Wed, 27 Jan 1999 02:11:47 +0100

> doesn't seem to help.  Horizontal and Vertical gradients are perfectly

Let me make a guess: You have submenus that overlap the parent menu
and when you move the pointer up and down the menu you may end up
with some portions that were overlapped by the submenu coloured
plain gray (the colour that the menus would have without the gradient).

Correct?

If yes I fixed this one a couple of minutes ago and I think it
will go into 2.2

Bye

Dominik

--
Dominik Vogt, [email-masked]
Reply-To: [email-masked]

---

From: Danek Duvall <[email-masked]>
Date: Tue, 26 Jan 1999 17:24:26 -0800

On Wed, Jan 27, 1999 at 02:11:47AM +0100, Dominik Vogt wrote:

> Let me make a guess: You have submenus that overlap the parent menu and
> when you move the pointer up and down the menu you may end up with some
> portions that were overlapped by the submenu coloured plain gray (the
> colour that the menus would have without the gradient).
> 
> Correct?

If only it were that easy!  <grin>  No, I checked to make sure that wasn't
the problem.  It doesn't have anything to do with submenus or repainting.
Just plop a menu up on the screen, and it's colored all funny.  (I actually
don't see this bug at all.)

I'll try the new code tomorrow, though, just in case it happens to also fix
my bug.

Danek

---

From: Kent Howard <[email-masked]>
Date: Tue, 26 Jan 1999 17:25:25 -0800

On Tue, Jan 26, 1999 at 05:10:46PM -0800, Danek Duvall wrote:
+----------
| On Tue, Jan 26, 1999 at 04:20:28PM -0800, Kent Howard wrote:
| 
| > sleep 5 ; xwd -root > snapshot.xwd
| 
| Thanks.  I've put a .tiff file of the problem at
| 
|     http://www.campusclub.princeton.edu/duvall/menu.tiff
| 
| HTH,
| Danek
+----------

I think you meant

      http://www.campusclub.princeton.edu/~duvall/menu.tiff

That problem definitely would have been hard to describe in
words.  ;)

- Kent

---

From: Danek Duvall <[email-masked]>
Date: Tue, 26 Jan 1999 18:30:04 -0800

>       http://www.campusclub.princeton.edu/~duvall/menu.tiff

Yes, I did.  It's been a long day.  And it ain't over yet.  <sigh>

> That problem definitely would have been hard to describe in words.  ;)

Good.  At least we've established that it isn't just something growing on
my contacts.  Now if someone else can reproduce the problem I'll feel
better.

Danek

---

From: Danek Duvall <[email-masked]>
Date: Tue, 26 Jan 1999 20:20:21 -0800

> my contacts.  Now if someone else can reproduce the problem I'll feel

Well, it seems to work just fine at home on my Linux box.  I'll try to
compile and run it on a Solaris 2.6 machine, and see if that makes any
difference.  If anyone else has a 2.7 box, though confirmation would be
nice.

Thanks,
Danek

---

From: Keith Bisset <[email-masked]>
Date: 27 Jan 1999 08:31:09 -0700

> difference.  If anyone else has a 2.7 box, though confirmation would be

I just tried it on my Solaris 2.5 machine and have the same problem,
or at least similar.  My menus appear horizontally stripped rather
than vertical, but it looks like the same problem.  I have the latest
CVS sources, compiled with Sun's acc compiler.  Not having looked at
the code at all, and given that it works on other systems, my first
thought is a missing prototype for some math function.

Keith Bisset

---

From: [email-masked] (Paul D. Smith)
Date: 27 Jan 1999 11:22:06 -0500

Hmm.  Maybe this is a stupid question, but are you sure it's not a
colormap issue?

Most of the Solaris systems I've seen have only an 8-bit videocard; it's
almost impossible to get decent gradients with only 256 colors, of which
many are taken up by pixmaps, etc.

Are you running at more than 8 bpp?  Are you getting any messages about
"can't alloc color" or similar from fvwm (or other apps you start)?

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <[email-masked]>         Network Management Development
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist
-------------------------------------------------------------------------------
   These are my opinions---Nortel Networks takes no responsibility for them.
--
Visit the official FVWM web page at <URL:http://fvwm.math.uh.edu/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Keith Bisset <[email-masked]>
Date: 27 Jan 1999 09:24:53 -0700

> "can't alloc color" or similar from fvwm (or other apps you start)?

No, that isn't it.  I'm running on a machine with a 24-bit display.
Also horizontal and vertical gradients work fine, its just the
diagonal ones that have the problem.

Keith Bisset

---

From: Pekka Marjola <[email-masked]>
Date: 27 Jan 1999 21:42:19 +0200

>>>>> In <[email-masked]>,
>>>>> On 27 Jan 1999 11:22:06 -0500,
>>>>> "Paul" == [email-masked] (Paul D. Smith) writes:

Paul> Hmm.  Maybe this is a stupid question, but are you sure it's not a
Paul> colormap issue?

Paul> Are you running at more than 8 bpp?  Are you getting any messages about
Paul> "can't alloc color" or similar from fvwm (or other apps you start)?

I have the same problem using 16bpp in HP-UX 10.01. Works correctly in 
8bpp.

-- 
Pekka Marjola * [email-masked] * http://www.iki.fi/pema/ * PGPid 0x2865206D

---

From: Dominik Vogt <[email-masked]>
Date: Wed, 27 Jan 1999 19:26:06 +0100

>     http://www.campusclub.princeton.edu/~duvall/menu.tiff

To me that looks as if X was trying to display the pixmap
in a different resolution/depth than it was originally
drawn. I can't imagine anything else that could cause this
many lines.

With xmag I saw at least four different colours.

Bye

Dominik

---

From: Keith Bisset <[email-masked]>
Date: 28 Jan 1999 17:44:28 -0700

The changes to menu.c that Dominik just made don't fix the Gradient
bug.  It turns out that a float (ds) was being passed as a point to
XDrawLine() in PaintMenu().  I'm not sure why this was working for
anybody.  The fix seems just to be to cast the float to an int in the
XDrawLine() call.  A patch to the latest menu.c is attached below.

Keith Bisset

*** menus.c	Thu Jan 28 17:23:50 1999
--- menus.c.orig	Thu Jan 28 17:24:10 1999
***************
*** 2070,2076 ****
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, 0, (int)(i*ds), i, 0);
  	    }
  	    for(i = 0; i < mr->width; i++)
  	    {
--- 2070,2076 ----
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, 0, i*ds, i, 0);
  	    }
  	    for(i = 0; i < mr->width; i++)
  	    {
***************
*** 2078,2084 ****
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
  	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, i, mr->height, mr->width,
! 			(int)(i*ds));
  	    }
  	  }
  	  else
--- 2078,2084 ----
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
  	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, i, mr->height, mr->width,
! 			i*ds);
  	    }
  	  }
  	  else
***************
*** 2090,2103 ****
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, 0, i, (int)(i*ds), 0);
  	    }
  	    for(i = 0; i < mr->height; i++)
  	    {
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, (int)(i*ds), mr->height,
  			mr->width, i);
  	    }
  	  }
--- 2090,2103 ----
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, 0, i, i*ds, 0);
  	    }
  	    for(i = 0; i < mr->height; i++)
  	    {
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, i*ds, mr->height,
  			mr->width, i);
  	    }
  	  }
***************
*** 2117,2123 ****
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, 0, mr->height - (int)(i*ds), i,
  			mr->height);
  	    }
  	    for(i = 0; i < mr->width; i++)
--- 2117,2123 ----
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, 0, mr->height - i*ds, i,
  			mr->height);
  	    }
  	    for(i = 0; i < mr->width; i++)
***************
*** 2126,2132 ****
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
  	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, i, 0, mr->width,
! 			mr->height - (int)(i*ds));
  	    }
  	  }
  	  else
--- 2126,2132 ----
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
  	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, i, 0, mr->width,
! 			mr->height - i*ds);
  	    }
  	  }
  	  else
***************
*** 2138,2144 ****
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, 0, mr->height - i, (int)(i*ds),
  			mr->height);
  	    }
  	    for(i = 0; i < mr->height; i++)
--- 2138,2144 ----
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, 0, mr->height - i, i*ds,
  			mr->height);
  	    }
  	    for(i = 0; i < mr->height; i++)
***************
*** 2146,2152 ****
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, (int)(i*ds), 0, mr->width,
  			mr->height - i);
  	    }
  	  }
--- 2146,2152 ----
  	      if( i % dc == 0 )
  		XSetForeground(dpy, Scr.TransMaskGC,
  			       ms->look.face.u.grad.pixels[cindex++]);
! 	      XDrawLine(dpy, mr->w, Scr.TransMaskGC, i*ds, 0, mr->width,
  			mr->height - i);
  	    }
  	  }

---

From: Danek Duvall <[email-masked]>
Date: Thu, 28 Jan 1999 17:21:13 -0800

> XDrawLine() call.  A patch to the latest menu.c is attached below.

The patch is reversed, but it works very nicely.  Thanks!

(I was almost getting used to that ... thing.  <grin>)

Danek

---

From: Steve Robbins <[email-masked]>
Date: Thu, 28 Jan 1999 21:23:43 -0500 (EST)

On 28 Jan 1999, Keith Bisset wrote:

> anybody.

Maybe the person who wrote this code has a prototype for XDrawLine() in
their X11 includes and you don't.  I think a prototype causes the argument
to be automatically converted.

This error can be detected by "gcc -Wconversion", by the way:

../../fvwm/menus.c:2069: warning: passing arg 5 of `XDrawLine' as integer
rather than floating due to prototype
../../fvwm/menus.c:2077: warning: passing arg 7 of `XDrawLine' as integer
rather than floating due to prototype
../../fvwm/menus.c:2089: warning: passing arg 6 of `XDrawLine' as integer
rather than floating due to prototype
../../fvwm/menus.c:2097: warning: passing arg 4 of `XDrawLine' as integer
rather than floating due to prototype
../../fvwm/menus.c:2117: warning: passing arg 5 of `XDrawLine' as integer
rather than floating due to prototype
../../fvwm/menus.c:2125: warning: passing arg 7 of `XDrawLine' as integer
rather than floating due to prototype
../../fvwm/menus.c:2138: warning: passing arg 6 of `XDrawLine' as integer
rather than floating due to prototype
../../fvwm/menus.c:2146: warning: passing arg 4 of `XDrawLine' as integer
rather than floating due to prototype

I'm sure there are zillions of other bugs like this waiting to happen....

>  The fix seems just to be to cast the float to an int in the

--
Steve Robbins                              <[email-masked]>

A woman came up to me and said, "I'd like to poison your mind,
with wrong ideas that appeal to you, though I am not unkind."

---

From: [email-masked] (Paul D. Smith)
Date: 29 Jan 1999 00:04:21 -0500

%% Steve Robbins <[email-masked]> writes:

  sr> Maybe the person who wrote this code has a prototype for
  sr> XDrawLine() in their X11 includes and you don't.  I think a
  sr> prototype causes the argument to be automatically converted.

I don't have my standard handy, but I don't think it does.

Automatic conversion will occur between ints and longs, unsigned and
signed, etc., but I don't think it will automatically cast between
completely different types, like float to int or similar.

Well, maybe I'm wrong: certainly you'd expect that if such a cast was
illegal GCC would complain about it even without specifying
-Wconversion...

---

From: Steve Robbins <[email-masked]>
Date: Fri, 29 Jan 1999 09:36:00 -0500 (EST)

> completely different types, like float to int or similar.

I don't have a standard handy either, but I checked B. Stroustrup's C++
book, on the assumption that the rules for type conversions are the same. 

The code in question goes like this:

	int i;
	float ds;

	XDrawLine( ..., i*ds, ... );

Stroustrup says that for arithmetic expressions, "if either is a float,
the result is a float" (section 4.5, Arithmetic Conversions).  In the
absence of a prototype for XDrawLine(), what is the compiler going to do? 
In fact, it will pass floats as doubles, but that is beside the point. 
The point is that XDrawLine() was expecting an int, not a float (nor a
double). 

In the presence of a prototype for XDrawLine(), the compiler will do the
right thing, and convert the result of "i*ds" to int.  Section r.5.5.2
(Function Call) suggests that the "Standard Conversions" are done when
formal arguments are available, and float to int conversions are listed in
section r.4.4 ("Standard Conversions").

> illegal GCC would complain about it even without specifying

The diff was backwards, by the way.  The problem reported was not REMOVING
the cast, but ADDING it. 

What I showed was the output of "gcc -Wconversion" on the code WITHOUT the
cast.  My system happens to have prototypes for all X11 headers.  Hence
gcc is warning that *the same code* --- on a system WITHOUT prototypes ---
will compile differently. 

Here's what the GCC docs say about -Wconversion:

     Warn if a prototype causes a type conversion that is different
     from what would happen to the same argument in the absence of a
     prototype.  This includes conversions of fixed point to floating
     and vice versa, and conversions changing the width or signedness
     of a fixed point argument except when the same as the default
     promotion.

     Also, warn if a negative integer constant expression is implicitly
     converted to an unsigned type.  For example, warn about the
     assignment `x = -1' if `x' is unsigned.  But do not warn about
     explicit casts like `(unsigned) -1'.

Now, I suspect that lots of old X11 installations will lack prototypes for
their header files.  (Is it true?  I didn't research this.) 

*If* that is the case, then there are likely to be lots of bugs waiting to
happen.

Occasionally, when I have time on my hands, I compile fvwm with lots of
warnings enabled, and then start fixing code.  This is quite a tedious
process, I can assure you.  It would be a great help if others would do
the same (or use lint), especially on files they just modified.

---

From: [email-masked] (Paul D. Smith)
Date: 29 Jan 1999 09:53:35 -0500

sr> In the presence of a prototype for XDrawLine(), the compiler will
  sr> do the right thing, and convert the result of "i*ds" to int.
  sr> Section r.5.5.2 (Function Call) suggests that the "Standard
  sr> Conversions" are done when formal arguments are available, and
  sr> float to int conversions are listed in section r.4.4 ("Standard
  sr> Conversions").

Yep, you're right; I was wrong: these conversions do happen
automatically.

  >> Well, maybe I'm wrong: certainly you'd expect that if such a cast
  >> was illegal GCC would complain about it even without specifying
  >> -Wconversion...

  sr> The diff was backwards, by the way.  The problem reported was not
  sr> REMOVING the cast, but ADDING it.

  sr> What I showed was the output of "gcc -Wconversion" on the code
  sr> WITHOUT the cast.  My system happens to have prototypes for all
  sr> X11 headers.  Hence gcc is warning that *the same code* --- on a
  sr> system WITHOUT prototypes --- will compile differently.

Understood.

What I meant was, if there was no implicit cast, so the types were
indeed incompatible and the compiler couldn't resolve it, then GCC would
be expected to complain even _without_ a special extra flag like
-Wconversion.