Subject: Re: links-gui on cgsix
To: der Mouse <mouse@Rodents.Montreal.QC.CA>
From: Eric Radman <theman@eradman.com>
List: port-sparc
Date: 06/27/2006 13:51:36
On 22:41 Sat 24 Jun     , der Mouse wrote:
> >> Since a cgsix cannot support multiple colourmaps on the screen at
> >> once, [...technicolour colourmap flashing...]
> > That's fine, in fact that's what happens on my IBM T30 when I run X
> > in 8-bit color, so the 8-bit color on my cgsix is somehow different
> > than say an ATI Radeon.
> 
> Really?  How?  Your description sounded exactly like colourmap
> contention to me.  How does the behaviour on your cgsix differ from
> that on your Radeon?

I should have been more observant, the color map may be fine, the
problem is the background is always black, so the text is missing or
hard to read on backgrounds that where intended to contrast with the
text and other content.

> Okay, it's using a fairly boring 3,3,2 pseudo-TrueColor scheme.  (It's
> also doing it badly; it really should be doing one XStoreColors() call
> rather than 256 XStoreColor() calls.)

This is one of those programs that has a long and interesting history,
including the fact that it was built to run without X using SVGALib or
even access a framebuffer directly.

> > The other theory I have is that there is function being used that has
> > platform-specific behavior such as WhitePixel and BlackPixel:
> 
> > According to the Xlib Programming Manual, these are not always equal
> > to #000000 and #ffffff.
> 
> Right.  They are neither always pure white and pure black nor are they
> always any particular pixel values.
> 
> It's less likely to be a result of links using WhitePixel and
> BlackPixel than it is to be a result of other applications doing so
> (or, in some sense equivalently, looking up the values they want in the
> default colourmap).

I assembled a little program that opens the first display and prints the
values of BlackPixel and WhitePixel as reported by Xlib, and discovered
that in 8-bit mode the results are different on i386 and Sparc:

i386, 24-bit:
  black_pixel=0 white_pixel=16777215

i386, 8-bit:
  black_pixel=0 white_pixel=1

sparc, 8-bit: 
  black_pixel=1 white_pixel=0

Notice that white and black are flipped. I don't know if this really
matters or not, but it does suggest that links-gui is making an
assumption about the values returned by these calls.

> Your default visual is StaticGray, which has a predefined colourmap
> containing implementation-specific grayscale values.  It's quite
> possible that, for example, the server on your Sun uses pixel value 0
> for white and 1 for black, with the rest containing other greyscale
> values, while on the Radeon, the server uses 0 for black and 255 for
> white.  This would make a difference because a black-and-white
> application, while looking identical when using the correct colourmap,
> will look very different using links's pseudo-TrueColor colourmap.
> 
> > I couldn't find a way to force anything.  I don't yet understand why
> > a an application would use anything but the DefaultColormap and
> > DefaultVisual to begin with.
> 
> Because it wants to be able to display colour and the default visual
> doesn't support it, would be my guess.  Since there are colour visuals
> available, it uses one of them.  (Why it picks a PseudoColor visual
> when there's a TrueColor visual available and it appears to to want
> TrueColor, that I find baffling.  The use of XStoreColor instead of
> XStoreColors leads me to suspect that the author may have had a shaky
> understanding of Xlib, which likely would include a weak grasp of the
> Visual model.)

He also has excerpts of Xlib documentation in the source...so you may be
right that the author wasn't well versed in X11 programming.

--------------
#include <stdio.h>
#include <X11/Xlib.h>

main()
{
    Display *x_display;
    int x_screen;
    int x_black_pixel,x_white_pixel;
    char *display;

    display=":0.0";
    x_display=XOpenDisplay(display);
    x_screen=DefaultScreen(x_display);

    x_black_pixel=BlackPixel(x_display,x_screen);
    x_white_pixel=WhitePixel(x_display,x_screen);

    printf("black_pixel=%d white_pixel=%d\n", x_black_pixel,x_white_pixel);

    return 0;
}

--
Eric Radman