xserver: Branch 'master'

Alan Coopersmith alanc at kemper.freedesktop.org
Tue Jul 1 13:38:04 PDT 2008


 hw/kdrive/ephyr/hostx.c |   30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

New commits:
commit c8216aede6c4ac41976947521d884fa010913204
Author: Jeremy Uejio <jeremy.uejio at sun.com>
Date:   Tue Jul 1 13:37:12 2008 -0700

    Sun bug #6685465: Xephyr uses wrong or bad colortable in 8-bit mode
    
    <http://bugs.opensolaris.org/view_bug.do?bug_id=6685465>
    
    This bug is caused by Xephyr not handling the RGB byte order correctly
    of the server where Xephyr is displaying on. The previous code just
    assumed that the order was RGB and did not take into account that
    Xservers may use different order (such as BGR).
    
    The fix is to add a function to calculate the byte order and bits
    to shift based on the visual mask and the visual bits_per_rgb (which
    is usually 8, but could be server dependent).  Since the shifts won't
    change once the display connection has been made, I can cache these
    values so that Xephyr doesn't have to keep recalculating them everytime
    it tries to translate the Xephyr colormap entries for Xephyr clients to
    the actual server colormap entries (i.e. calling the function
    hostx_set_cmap_entry() repeatedly for every colormap entry).

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 74f9f16..171d78c 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -565,14 +565,40 @@ hostx_get_visual_masks (EphyrScreenInfo screen,
     }
 }
 
+static int 
+hostx_calculate_color_shift(unsigned long mask,
+			    int bits_per_rgb)
+{
+    int shift = 0;
+    while(mask) {
+	mask = mask >> bits_per_rgb;
+	if (mask) shift += bits_per_rgb;
+    }
+    return shift;
+}
+
 void
 hostx_set_cmap_entry(unsigned char idx,
 		     unsigned char r,
 		     unsigned char g,
 		     unsigned char b)
 {
-  /* XXX Will likely break for 8 on 16, not sure if this is correct */
-  HostX.cmap[idx] = (r << 16) | (g << 8) | (b);
+/* need to calculate the shifts for RGB because server could be BGR. */
+/* XXX Not sure if this is correct for 8 on 16, but this works for 8 on 24.*/
+    static int rshift, bshift, gshift = 0;
+    static int first_time = 1;
+    if (first_time) {
+	first_time = 0;
+	rshift = hostx_calculate_color_shift(HostX.visual->red_mask,
+					     HostX.visual->bits_per_rgb);
+	gshift = hostx_calculate_color_shift(HostX.visual->green_mask,
+					     HostX.visual->bits_per_rgb);
+	bshift = hostx_calculate_color_shift(HostX.visual->blue_mask,
+					     HostX.visual->bits_per_rgb);
+    }
+    HostX.cmap[idx] = ((r << rshift) & HostX.visual->red_mask) |
+		      ((g << gshift) & HostX.visual->green_mask) |
+		      ((b << bshift) & HostX.visual->blue_mask);
 }
 
 /**


More information about the xorg-commit mailing list