diff -Nurd xorg-server-1.3.0.0/hw/kdrive/fbdev/fbdev.c xorg-server-1.3.0.0.patched/hw/kdrive/fbdev/fbdev.c
--- xorg-server-1.3.0.0/hw/kdrive/fbdev/fbdev.c	2006-11-16 19:01:23.000000000 +0100
+++ xorg-server-1.3.0.0.patched/hw/kdrive/fbdev/fbdev.c	2007-09-15 16:53:20.152045000 +0200
@@ -213,6 +213,24 @@
 
     /* Now get the new screeninfo */
     ioctl (priv->fd, FBIOGET_VSCREENINFO, &priv->var);
+    /* Special treatment of 18bpp */
+    if ((priv->var.red.length == 6) && (priv->var.green.length == 6) && 
+	(priv->var.blue.length == 6))
+    {
+      priv->var.red.length = 8;
+      if (priv->var.red.offset != 0)
+        priv->var.red.offset = 16;
+      priv->var.green.length = 8;
+      priv->var.green.offset = 8;
+      priv->var.blue.length = 8;
+      if (priv->var.blue.offset != 0)
+        priv->var.blue.offset = 16;
+      priv->var.bits_per_pixel = 32;
+      priv->Have18Bpp = TRUE;
+    }
+    else
+      priv->Have18Bpp = FALSE;
+
     depth = priv->var.bits_per_pixel;
     gray = priv->var.grayscale;
     
@@ -334,7 +352,7 @@
     KdMouseMatrix	m;
     FbdevPriv		*priv = screen->card->driver;
 
-    if (scrpriv->randr != RR_Rotate_0)
+    if (scrpriv->randr != RR_Rotate_0 || priv->Have18Bpp)
 	scrpriv->shadow = TRUE;
     else
 	scrpriv->shadow = FALSE;
@@ -398,6 +416,354 @@
     return TRUE;
 }
 
+void
+shadowUpdatePacked18 (ScreenPtr	    pScreen,
+			 shadowBufPtr    pBuf)
+{
+    RegionPtr	damage = shadowDamage (pBuf);
+    PixmapPtr	pShadow = pBuf->pPixmap;
+    int		nbox = REGION_NUM_RECTS (damage);
+    BoxPtr	pbox = REGION_RECTS (damage);
+    FbBits	*shaBase, *shaLine, *sha;
+    FbStride	shaStride;
+    int		scrBase, scrLine, scr;
+    int		shaBpp;
+    int		shaXoff, shaYoff; /* XXX assumed to be zero */
+    int		x, y, w, h, width;
+    int         i;
+    char	*winBase = NULL, *win;
+    CARD32      winSize;
+
+    fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
+    while (nbox--)
+    {
+	x = pbox->x1 * shaBpp;
+	y = pbox->y1;
+	w = (pbox->x2 - pbox->x1) * shaBpp;
+	h = pbox->y2 - pbox->y1;
+
+	scrLine = (x >> FB_SHIFT);
+	shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+				   
+	x &= FB_MASK;
+	w = (w + x + FB_MASK) >> FB_SHIFT;
+	
+	while (h--)
+	{
+	    winSize = 0;
+	    scrBase = 0;
+	    width = w;
+	    scr = scrLine;
+	    sha = shaLine;
+	    while (width) {
+		/* how much remains in this window */
+		i = scrBase + winSize - scr;
+		if (i <= 0 || scr < scrBase)
+		{
+		    winBase = (char *) (*pBuf->window) (pScreen,
+							  y,
+							  scr * 3,
+							  SHADOW_WINDOW_WRITE,
+							  &winSize,
+							  pBuf->closure);
+		    if(!winBase)
+			return;
+		    scrBase = scr;
+		    winSize /= 3;
+		    i = winSize;
+		}
+		win = winBase + (scr - scrBase);
+		if (i > width)
+		    i = width;
+		width -= i;
+		scr += i;
+#define PickBit(a,i)	(((a) >> (i)) & 1)
+		while (i--)
+		  {
+		    FbBits bits = *sha++;
+		    *win++ = ((bits & 0xFC) >> 2) | 
+                ((bits & 0xC00) >> 4);
+		    *win++ = ((bits & 0xF000) >> 12) | 
+		      ((bits & 0x3C0000) >> 14);
+		    *win++ = (bits & 0xC00000) >> 22;
+		  }
+	    }
+	    shaLine += shaStride;
+	    y++;
+	}
+	pbox++;
+    }
+}
+
+#define LEFT_TO_RIGHT	1
+#define RIGHT_TO_LEFT	-1
+#define TOP_TO_BOTTOM	2
+#define BOTTOM_TO_TOP	-2
+
+void
+shadowUpdateRotatePacked18 (ScreenPtr	pScreen,
+			       shadowBufPtr	pBuf)
+{
+    RegionPtr	damage = shadowDamage (pBuf);
+    PixmapPtr	pShadow = pBuf->pPixmap;
+    int		nbox = REGION_NUM_RECTS (damage);
+    BoxPtr	pbox = REGION_RECTS (damage);
+    FbBits	*shaBits;
+    FbStride	shaStride;
+    int		shaBpp;
+    int		shaXoff, shaYoff;
+    int		box_x1, box_x2, box_y1, box_y2;
+    int		sha_x1 = 0, sha_y1 = 0;
+    int		scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h;
+    int		scr_x, scr_y;
+    int		w;
+    int		pixelsPerBits;
+    int		pixelsMask;
+    FbStride	shaStepOverY = 0, shaStepDownY = 0;
+    FbStride	shaStepOverX = 0, shaStepDownX = 0;
+    FbBits	*shaLine, *sha;
+    int		shaHeight = pShadow->drawable.height;
+    int		shaWidth = pShadow->drawable.width;
+    FbBits	shaMask;
+    int		shaFirstShift, shaShift;
+    int		o_x_dir;
+    int		o_y_dir;
+    int		x_dir;
+    int		y_dir;
+
+    fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
+    pixelsPerBits = (sizeof (FbBits) * 8) / shaBpp;
+    pixelsMask = ~(pixelsPerBits - 1);
+    shaMask = FbBitsMask (FB_UNIT-shaBpp, shaBpp);
+    /*
+     * Compute rotation related constants to walk the shadow
+     */
+    o_x_dir = LEFT_TO_RIGHT;
+    o_y_dir = TOP_TO_BOTTOM;
+    if (pBuf->randr & SHADOW_REFLECT_X)
+	o_x_dir = -o_x_dir;
+    if (pBuf->randr & SHADOW_REFLECT_Y)
+	o_y_dir = -o_y_dir;
+    switch (pBuf->randr & (SHADOW_ROTATE_ALL)) {
+    case SHADOW_ROTATE_0:	/* upper left shadow -> upper left screen */
+    default:
+	x_dir = o_x_dir;
+	y_dir = o_y_dir;
+	break;
+    case SHADOW_ROTATE_90:    	/* upper right shadow -> upper left screen */
+	x_dir = o_y_dir;
+	y_dir = -o_x_dir;
+	break;
+    case SHADOW_ROTATE_180:	/* lower right shadow -> upper left screen */
+	x_dir = -o_x_dir;
+	y_dir = -o_y_dir;
+	break;
+    case SHADOW_ROTATE_270:	/* lower left shadow -> upper left screen */
+	x_dir = -o_y_dir;
+	y_dir = o_x_dir;
+	break;
+    }
+    switch (x_dir) {
+    case LEFT_TO_RIGHT:
+	shaStepOverX = shaBpp;
+	shaStepOverY = 0;
+	break;
+    case TOP_TO_BOTTOM:
+	shaStepOverX = 0;
+	shaStepOverY = shaStride;
+	break;
+    case RIGHT_TO_LEFT:
+	shaStepOverX = -shaBpp;
+	shaStepOverY = 0;
+	break;
+    case BOTTOM_TO_TOP:
+	shaStepOverX = 0;
+	shaStepOverY = -shaStride;
+	break;
+    }
+    switch (y_dir) {
+    case TOP_TO_BOTTOM:
+	shaStepDownX = 0;
+	shaStepDownY = shaStride;
+	break;
+    case RIGHT_TO_LEFT:
+	shaStepDownX = -shaBpp;
+	shaStepDownY = 0;
+	break;
+    case BOTTOM_TO_TOP:
+	shaStepDownX = 0;
+	shaStepDownY = -shaStride;
+	break;
+    case LEFT_TO_RIGHT:
+	shaStepDownX = shaBpp;
+	shaStepDownY = 0;
+	break;
+    }
+    
+    while (nbox--)
+    {
+        box_x1 = pbox->x1;
+        box_y1 = pbox->y1;
+        box_x2 = pbox->x2;
+        box_y2 = pbox->y2;
+        pbox++;
+
+	/*
+	 * Compute screen and shadow locations for this box
+	 */
+	switch (x_dir) {
+	case LEFT_TO_RIGHT:
+	    scr_x1 = box_x1 & pixelsMask;
+	    scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask;
+	    
+	    sha_x1 = scr_x1;
+	    break;
+	case TOP_TO_BOTTOM:
+	    scr_x1 = box_y1 & pixelsMask;
+	    scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask;
+
+	    sha_y1 = scr_x1;
+	    break;
+	case RIGHT_TO_LEFT:
+	    scr_x1 = (shaWidth - box_x2) & pixelsMask;
+	    scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask;
+
+	    sha_x1 = (shaWidth - scr_x1 - 1);
+	    break;
+	case BOTTOM_TO_TOP:
+	    scr_x1 = (shaHeight - box_y2) & pixelsMask;
+	    scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask;
+	    
+	    sha_y1 = (shaHeight - scr_x1 - 1);
+	    break;
+	}
+	switch (y_dir) {
+	case TOP_TO_BOTTOM:
+	    scr_y1 = box_y1;
+	    scr_y2 = box_y2;
+
+	    sha_y1 = scr_y1;
+	    break;
+	case RIGHT_TO_LEFT:
+	    scr_y1 = (shaWidth - box_x2);
+	    scr_y2 = (shaWidth - box_x1);
+
+	    sha_x1 = box_x2 - 1;
+	    break;
+	case BOTTOM_TO_TOP:
+	    scr_y1 = shaHeight - box_y2;
+	    scr_y2 = shaHeight - box_y1;
+	    
+	    sha_y1 = box_y2 - 1;
+	    break;
+	case LEFT_TO_RIGHT:
+	    scr_y1 = box_x1;
+	    scr_y2 = box_x2;
+
+	    sha_x1 = box_x1;
+	    break;
+	}
+	scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT;
+	scr_h = scr_y2 - scr_y1;
+	scr_y = scr_y1;
+
+	/* shift amount for first pixel on screen */ 
+	shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp;
+	
+	/* pointer to shadow data first placed on screen */
+	shaLine = (shaBits + 
+		   sha_y1 * shaStride + 
+		   ((sha_x1 * shaBpp) >> FB_SHIFT));
+
+	/*
+	 * Copy the bits, always write across the physical frame buffer
+	 * to take advantage of write combining.
+	 */
+	while (scr_h--)
+	{
+	    int	    p;
+	    FbBits  bits;
+	    char  *win;
+	    int	    i;
+	    CARD32  winSize;
+	    
+	    sha = shaLine;
+	    shaShift = shaFirstShift;
+	    w = scr_w;
+	    scr_x = scr_x1 * shaBpp >> FB_SHIFT;
+
+	    while (w)
+	    {
+		/*
+		 * Map some of this line
+		 */
+		win = (char *) (*pBuf->window) (pScreen,
+						scr_y,
+						scr_x * 3,
+						SHADOW_WINDOW_WRITE,
+						&winSize,
+						pBuf->closure);
+		i = winSize / 3;
+		if (i > w)
+		    i = w;
+		w -= i;
+		scr_x += i;
+		/*
+		 * Copy the portion of the line mapped
+		 */
+		while (i--)
+		{
+		    bits = 0;
+		    p = pixelsPerBits;
+		    /*
+		     * Build one word of output from multiple inputs
+		     * 
+		     * Note that for 90/270 rotations, this will walk
+		     * down the shadow hitting each scanline once.
+		     * This is probably not very efficient.
+		     */
+		    while (p--)
+		    {
+			bits = FbScrLeft(bits, shaBpp);
+			bits |= FbScrRight (*sha, shaShift) & shaMask;
+
+			shaShift -= shaStepOverX;
+			if (shaShift >= FB_UNIT)
+			{
+			    shaShift -= FB_UNIT;
+			    sha--;
+			}
+			else if (shaShift < 0)
+			{
+			    shaShift += FB_UNIT;
+			    sha++;
+			}
+			sha += shaStepOverY;
+		    }
+		    *win++ = ((bits & 0xFC) >> 2) | 
+                ((bits & 0xC00) >> 4);
+		    *win++ = ((bits & 0xF000) >> 12) | 
+		      ((bits & 0x3C0000) >> 14);
+		    *win++ = (bits & 0xC00000) >> 22;
+		}
+	    }
+	    scr_y++;
+	    shaFirstShift -= shaStepDownX;
+	    if (shaFirstShift >= FB_UNIT)
+	    {
+		shaFirstShift -= FB_UNIT;
+		shaLine--;
+	    }
+	    else if (shaFirstShift < 0)
+	    {
+		shaFirstShift += FB_UNIT;
+		shaLine++;
+	    }
+	    shaLine += shaStepDownY;
+	}
+    }
+}
+
 Bool
 fbdevSetShadow (ScreenPtr pScreen)
 {
@@ -418,7 +784,14 @@
 
     window = fbdevWindowLinear;
     update = 0;
-    if (scrpriv->randr)
+      if (priv->Have18Bpp)
+        {
+        if (scrpriv->randr != RR_Rotate_0)
+          update = shadowUpdateRotatePacked18;
+        else
+          update = shadowUpdatePacked18;
+        }
+      else if (scrpriv->randr)
 	if (priv->var.bits_per_pixel == 16) {
 	    switch (scrpriv->randr) {
 	    case RR_Rotate_90:
diff -Nurd xorg-server-1.3.0.0/hw/kdrive/fbdev/fbdev.h xorg-server-1.3.0.0.patched/hw/kdrive/fbdev/fbdev.h
--- xorg-server-1.3.0.0/hw/kdrive/fbdev/fbdev.h	2006-09-18 08:04:17.000000000 +0200
+++ xorg-server-1.3.0.0.patched/hw/kdrive/fbdev/fbdev.h	2007-09-15 16:45:07.362045000 +0200
@@ -44,6 +44,7 @@
     int				fd;
     char			*fb;
     char			*fb_base;
+    Bool			Have18Bpp;
 } FbdevPriv;
     
 typedef struct _fbdevScrPriv {
