XQueryColor() - Xwindows

This is a discussion on XQueryColor() - Xwindows ; Is is necessary to use XFreeColors() after using XQueryColor()? Thanks in advance, Charlie...

+ Reply to Thread
Results 1 to 8 of 8

Thread: XQueryColor()

  1. XQueryColor()

    Is is necessary to use XFreeColors() after using XQueryColor()?

    Thanks in advance,
    Charlie

  2. Re: XQueryColor()

    CharlieB wrote:
    > Is is necessary to use XFreeColors() after using XQueryColor()?


    I only if you use XAlloc*Color*
    The alloc/free pair is needed mostly for colormap screens,
    which are obsolete for about 10 years now.
    Most graphics cards (and even cell phones) are true color
    now, so using XAllocColors is no longer necessary.
    Colormap handling adds a lot of complexity to the code,
    don't do it unless you really badly need it.

    Best regards,

    Dušan Peterc
    http://www.arahne.si

  3. Re: XQueryColor()

    arahne wrote:

    > CharlieB wrote:
    >> Is is necessary to use XFreeColors() after using XQueryColor()?

    >
    > I only if you use XAlloc*Color*


    OK Thanks.

    > The alloc/free pair is needed mostly for colormap screens,
    > which are obsolete for about 10 years now.
    > Most graphics cards (and even cell phones) are true color
    > now, so using XAllocColors is no longer necessary.
    > Colormap handling adds a lot of complexity to the code,
    > don't do it unless you really badly need it.
    >

    Oh my. I have been using XAllocColor all along with non-palletted displays.
    However, how would you get a pixel for a specific RGB color without using
    XAllocColor? Also how do you do the reverse without XQueryColor?

    Thanks again.

  4. Re: XQueryColor()

    CharlieB wrote:
    > Oh my. I have been using XAllocColor all along with non-palletted displays.
    > However, how would you get a pixel for a specific RGB color without using
    > XAllocColor? Also how do you do the reverse without XQueryColor?


    I have cut out a piece of the code which I use for this purpose,
    with some modifications to remove dependencies from the rest of
    the code. It is better to get the depth only once.
    And the evaluation of depth can be more complex, if you need
    to handle more screen depths or more than 8 bits per r,g,b.

    The memory for "xc" must be allocated prior to the call.

    unsigned long rgbToXColor(int red, int green, int blue, XColor *xc)
    {
    int depth = XDefaultDepth(XtDisplay(some_widgetID),
    XDefaultScreen(XtDisplay(some_widgetID)));
    unsigned long pixel;

    xc->flags = DoRed | DoGreen | DoBlue;
    xc->red = red;
    xc->green = green;
    xc->blue = blue;
    if (xinfo.depth==16)
    xc->pixel = (((unsigned long)red & 248)<<8)+(((unsigned long)green &
    252)<<3)+(((unsigned long)blue & 248)>>3);
    else
    xc->pixel = (((unsigned long)xc->red)<<16)+(((unsigned
    long)xc->green)<<8)+(unsigned long)xc->blue;
    xc->red <<= 8;
    xc->green <<= 8;
    xc->blue <<= 8;
    return(xc->pixel);
    }

    XQueryColor does not hurt, if you want to get the RGB values out of
    a color name. If you prefer using the X color names.
    You just do not need to allocate the color with XAllocColor
    in order to use it, if you are on true color display.

    Hope this helps,

    Dušan Peterc
    http://www.arahne.si


  5. Re: XQueryColor()

    On 2008-03-09, CharlieB wrote:
    > arahne wrote:
    >> CharlieB wrote:
    >>
    >>> Is is necessary to use XFreeColors() after using XQueryColor()?

    >>
    >> I only if you use XAlloc*Color*

    >
    > OK Thanks.
    >
    >> The alloc/free pair is needed mostly for colormap screens,
    >> which are obsolete for about 10 years now.
    >> Most graphics cards (and even cell phones) are true color
    >> now, so using XAllocColors is no longer necessary.
    >> Colormap handling adds a lot of complexity to the code,
    >> don't do it unless you really badly need it.
    >>

    > Oh my. I have been using XAllocColor all along with
    > non-palletted displays.


    That doesn't hurt. In fact, it's a good thing in that your app
    will also work on PseudoColor displays. Which probably account
    for less than 1% of your users. Is supporting them worth the
    effort ? It's up to you to decide.

    However, if you have more than a dozen colours to allocate, you
    don't want to unnecessarily call XAllocColor() because it means
    a round trip to the server. If somebody ever runs your app
    remotely over an ADSL connection, they'll have to wait on the
    order of 100 ms per XAllocColor(). I had an app that took an
    extra 22 seconds to start just because of that.

    > However, how would you get a pixel for a specific RGB color
    > without using XAllocColor?


    You use the Visual's red, green and blue masks. For example,
    supposing the masks are 0x0000f800, 0x000007e0 and 0x0000001f,
    the pixel value for colour #5500aa is 0x55 << 11 & 0x0000f800 |
    0x00 << 5 & 0x000007e0 | 0xaa << 0 & 0x0000001f = 0x0000a80a.

    The right-hand operand of the bit shift operator is the number
    of zeros to the right of the corresponding mask. Here's some C
    code to parse a mask :

    /*
    * parse_mask - parse a pattern of the form 0*1*0*
    *
    * Set *shift to the number of zeros to the right of the block of
    * ones. Set *bits to the number of consecutive ones. If the
    * pattern is all zeros, set *shift to the number of bits in a
    * unsigned long and *bits to zero.
    *
    * If the pattern has more than one block of ones, only the
    * rightmost one is taken into account.
    */
    void parse_pattern (unsigned long pattern, int *shifts, int *bits)
    {
    unsigned long mask = 1;

    for (*shifts = 0; mask != 0 && (pattern & mask) == 0; mask <<= 1)
    (*shifts)++;
    for (*bits = 0; mask != 0 && (pattern & mask) != 0; mask <<= 1)
    (*bits)++;
    }

    --
    Andr Majorel
    (Counterfeit: kunazar@inverse.com aqoc@midland.com)
    "I drink, I smoke, I gamble, I chase girls--but postal chess is
    one vice I don't have." -- Mikhail Tal

  6. Re: XQueryColor()

    CharlieB writes:

    > Andre Majorel wrote:
    >
    >> On 2008-03-09, CharlieB wrote:
    >>> arahne wrote:
    >>>> CharlieB wrote:

    > I will keep those suggestions in mind to replace XAllocColor. They look
    > confusing and worry me because they would work fine on my hardware but
    > someone else's they may not since I can only test the code on mine. Sigh...


    If you're on Linux, at runlevel 3 you can start another
    X session at 8 bit with:

    startx -- :1 -bpp 8 vt8

    That will be $DISPLAY=:1
    and use VT8.

  7. Re: XQueryColor()

    Andre Majorel wrote:

    > On 2008-03-09, CharlieB wrote:
    >> arahne wrote:
    >>> CharlieB wrote:
    >>>
    >>>> Is is necessary to use XFreeColors() after using XQueryColor()?
    >>>
    >>> I only if you use XAlloc*Color*

    >>
    >> OK Thanks.
    >>
    >>> The alloc/free pair is needed mostly for colormap screens,
    >>> which are obsolete for about 10 years now.
    >>> Most graphics cards (and even cell phones) are true color
    >>> now, so using XAllocColors is no longer necessary.
    >>> Colormap handling adds a lot of complexity to the code,
    >>> don't do it unless you really badly need it.
    >>>

    >> Oh my. I have been using XAllocColor all along with
    >> non-palletted displays.

    >
    > That doesn't hurt. In fact, it's a good thing in that your app
    > will also work on PseudoColor displays. Which probably account
    > for less than 1% of your users. Is supporting them worth the
    > effort ? It's up to you to decide.
    >
    > However, if you have more than a dozen colours to allocate, you
    > don't want to unnecessarily call XAllocColor() because it means
    > a round trip to the server. If somebody ever runs your app
    > remotely over an ADSL connection, they'll have to wait on the
    > order of 100 ms per XAllocColor(). I had an app that took an
    > extra 22 seconds to start just because of that.
    >

    I just wrote code to call XAllocColor 1000s of times to create an ximage
    from a png file. It does cache the frequently used colors though. It is
    fast enough for me on a stand alone computer. It would drive someone mad on
    a network judging by what you just said.

    I will keep those suggestions in mind to replace XAllocColor. They look
    confusing and worry me because they would work fine on my hardware but
    someone else's they may not since I can only test the code on mine. Sigh...

    I wonder why XAllocColor doesn't just do what you both have been telling me
    instead of actually using a color map? In other words if a program requests
    a color map on a display that doesn't use a pallette xlib should just
    silently ignore the request (or set the color map to a fake value). Then
    when XAllocColor is called on that type of display it should just construct
    the pixel and not allocate it in a color map. Conseqently XFreeColors would
    be ignored also.


  8. Re: XQueryColor()

    On 2008-03-13, CharlieB wrote:
    > Andre Majorel wrote:
    >> On 2008-03-09, CharlieB wrote:
    >>
    >>> Oh my. I have been using XAllocColor all along with
    >>> non-palletted displays.

    >>
    >> That doesn't hurt. In fact, it's a good thing in that your app
    >> will also work on PseudoColor displays. Which probably account
    >> for less than 1% of your users. Is supporting them worth the
    >> effort ? It's up to you to decide.
    >>
    >> However, if you have more than a dozen colours to allocate, you
    >> don't want to unnecessarily call XAllocColor() because it means
    >> a round trip to the server. If somebody ever runs your app
    >> remotely over an ADSL connection, they'll have to wait on the
    >> order of 100 ms per XAllocColor(). I had an app that took an
    >> extra 22 seconds to start just because of that.
    >>

    > I just wrote code to call XAllocColor 1000s of times to create
    > an ximage from a png file. It does cache the frequently used
    > colors though. It is fast enough for me on a stand alone
    > computer. It would drive someone mad on a network judging by
    > what you just said.


    With X, it's not just the bandwidth of the link between the
    client and server that matters, it's also the latency. An ADSL
    link has huge latency compared to a local link. On mine, the
    round trip time to my ISP oscillates between 40 and 100 ms. That
    means every synchronous operation (like XAllocColor()) will take
    *at least* 40 ms before it returns, even if it takes the server
    a microsecond to complete.

    > I will keep those suggestions in mind to replace XAllocColor.
    > They look confusing and worry me because they would work fine
    > on my hardware but someone else's they may not since I can
    > only test the code on mine. Sigh...


    If you have access to a machine on the other side of your modem,
    you can test your code. Open an SSH connection to tunnel the X
    protocol between both hosts :

    charlie@local$ ssh -CX user@remote

    At that point you are logged as user on remote. Because you gave
    ssh the -X flag, you should have a DISPLAY environment variable
    that looks like "localhost:10.0". If not, set X11Forwarding to
    "yes" in /etc/ssh/sshd_config on the remote, restart sshd and
    try again.

    Compile and run your app on the remote. Any windows it opens
    will appear on your local X display. Enjoy the minute-long wait
    while your app repeatedly queries your server. :-)

    > I wonder why XAllocColor doesn't just do what you both have
    > been telling me instead of actually using a color map?


    The fact that XAllocColor() queries the server does not mean it
    uses a colour map. Colour maps live on the server and the server
    does not create any for TrueColor visuals.

    > In other words if a program requests a color map on a display
    > that doesn't use a pallette xlib should just silently ignore
    > the request (or set the color map to a fake value). Then when
    > XAllocColor is called on that type of display it should just
    > construct the pixel and not allocate it in a color map.
    > Conseqently XFreeColors would be ignored also.


    Exactly. And indeed, I bet that the server code that
    XAllocColor() causes to be executed looks like this :

    if visual is TrueColor
    convert colour to pixel value according to R/G/B masks
    return pixel value
    if visual is PseudoColor
    try to satisfy the request by re-use or allocation
    either fail or update the colour map and return pixel value

    Likewise for XFreeColors () :

    if visual is TrueColor
    return
    if visual is PseudoColor
    update the colour map
    return

    No colour map is involved on TrueColor visuals. Colour
    allocation degenerates into bit shifting and colour deallocation
    is a no-op. Just as you proposed.

    So why does XAllocColor() need to query the server ? Xlib is a
    thin wrapper. It does little more than translate your request to
    X protocol, send that to the server, decode the server's reply
    and present the result to you. I wouldn't be surprised if Xlib
    didn't even *know* whether a given window uses a colour map or
    not.

    --
    Andr Majorel
    (Counterfeit: ehigopot@gravid.com zubofelel@interpret.com)
    "I drink, I smoke, I gamble, I chase girls--but postal chess is
    one vice I don't have." -- Mikhail Tal

+ Reply to Thread