diff --git a/dlls/ddraw/dpalette/dga.c b/dlls/ddraw/dpalette/dga.c
index 411c8001c9ff6f3b1bfae9a5468ea3d6bab7ef0b..02747c8dfbdac75d32cb8cfb97b42dce859db662 100644
--- a/dlls/ddraw/dpalette/dga.c
+++ b/dlls/ddraw/dpalette/dga.c
@@ -26,36 +26,29 @@ HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
 ) {
     ICOM_THIS(IDirectDrawPaletteImpl,iface);
     DPPRIVATE(This);
-    DDPRIVATE(This->ddraw);
     XColor	xc;
-    Colormap	cm;
     int		i;
 
     TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,x,start,count,palent);
     if (!dppriv->cm) /* should not happen */ {
-	FIXME("app tried to set colormap in non-palettized mode\n");
-	return DDERR_GENERIC;
+	TRACE("app tried to set colormap in non-palettized mode\n");
     }
-    /* FIXME: free colorcells instead of freeing whole map */
-    cm = dppriv->cm;
-    dppriv->cm = TSXCopyColormapAndFree(display,dppriv->cm);
-    TSXFreeColormap(display,cm);
-
     for (i=0;i<count;i++) {
 	xc.red = palent[i].peRed<<8;
 	xc.blue = palent[i].peBlue<<8;
 	xc.green = palent[i].peGreen<<8;
 	xc.flags = DoRed|DoBlue|DoGreen;
 	xc.pixel = i+start;
-
-	TSXStoreColor(display,dppriv->cm,&xc);
+	
+	if (dppriv->cm)
+	  TSXStoreColor(display,dppriv->cm,&xc);
 
 	This->palents[start+i].peRed = palent[i].peRed;
 	This->palents[start+i].peBlue = palent[i].peBlue;
 	This->palents[start+i].peGreen = palent[i].peGreen;
 	This->palents[start+i].peFlags = palent[i].peFlags;
     }
-    ddpriv->InstallColormap(display,DefaultScreen(display),dppriv->cm);
+    /* Flush the display queue so that palette updates are visible directly */
     TSXFlush(display);
     return DD_OK;
 }
diff --git a/dlls/ddraw/dsurface/dga.c b/dlls/ddraw/dsurface/dga.c
index c405ecae8324bc1c7b1b17ec1f6b8606181b0d9c..bc91fd67b72cc8624ad980562728676b38f481e4 100644
--- a/dlls/ddraw/dsurface/dga.c
+++ b/dlls/ddraw/dsurface/dga.c
@@ -100,7 +100,28 @@ HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
 	    IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
 	This->s.palette = ipal;
 	fppriv = (dga_dp_private*)This->s.palette->private;
-	ddpriv->InstallColormap(display,DefaultScreen(display),fppriv->cm);
+
+	if (!fppriv->cm &&
+	    (This->s.ddraw->d->screen_pixelformat.u.dwRGBBitCount<=8) ) {
+	  int i;
+	  
+	  /* Delayed palette creation */
+	  fppriv->cm = TSXCreateColormap(display,DefaultRootWindow(display),
+					 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
+	    
+	  for (i=0;i<256;i++) {
+	    XColor xc;
+	    
+	    xc.red		= ipal->palents[i].peRed<<8;
+	    xc.blue		= ipal->palents[i].peBlue<<8;
+	    xc.green	= ipal->palents[i].peGreen<<8;
+	    xc.flags	= DoRed|DoBlue|DoGreen;
+	    xc.pixel	= i;
+	    TSXStoreColor(display,fppriv->cm,&xc);
+	  }
+	}
+
+	TSXF86DGAInstallColormap(display,DefaultScreen(display),fppriv->cm);
 
         if (This->s.hdc != 0) {
 	    /* hack: set the DIBsection color map */
diff --git a/dlls/ddraw/dsurface/dga2.c b/dlls/ddraw/dsurface/dga2.c
index 0e7ae8dd50eabd42f48ebb22086aeb59e989bd5e..b253fa02cb06fa90df0879da84ad05c98542b694 100644
--- a/dlls/ddraw/dsurface/dga2.c
+++ b/dlls/ddraw/dsurface/dga2.c
@@ -14,6 +14,7 @@
 
 #include "debugtools.h"
 #include "dga2_private.h"
+#include "bitmap.h"
 
 DEFAULT_DEBUG_CHANNEL(ddraw);
 
@@ -69,6 +70,61 @@ HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
     return DD_OK;
 }
 
+HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_SetPalette(
+    LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    DDPRIVATE(This->s.ddraw);
+    IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
+
+    TRACE("(%p)->(%p)\n",This,ipal);
+
+    /* According to spec, we are only supposed to 
+     * AddRef if this is not the same palette.
+     */
+    if( This->s.palette != ipal ) {
+	dga_dp_private	*fppriv;
+	if( ipal != NULL )
+	    IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
+	if( This->s.palette != NULL )
+	    IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
+	This->s.palette = ipal;
+	fppriv = (dga_dp_private*)This->s.palette->private;
+
+	if (!fppriv->cm &&
+	    (This->s.ddraw->d->screen_pixelformat.u.dwRGBBitCount<=8) ) {
+	  int i;
+	  
+	  /* Delayed palette creation */
+	  fppriv->cm = TSXDGACreateColormap(display,DefaultScreen(display), ddpriv->dev, AllocAll);
+	    
+	  for (i=0;i<256;i++) {
+	    XColor xc;
+	    
+	    xc.red		= ipal->palents[i].peRed<<8;
+	    xc.blue		= ipal->palents[i].peBlue<<8;
+	    xc.green	= ipal->palents[i].peGreen<<8;
+	    xc.flags	= DoRed|DoBlue|DoGreen;
+	    xc.pixel	= i;
+	    TSXStoreColor(display,fppriv->cm,&xc);
+	  }
+	}
+
+	TSXDGAInstallColormap(display,DefaultScreen(display),fppriv->cm);
+
+        if (This->s.hdc != 0) {
+	    /* hack: set the DIBsection color map */
+	    BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(This->s.DIBsection, BITMAP_MAGIC);
+	    X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *)bmp->dib;
+	    dib->colorMap = This->s.palette ? This->s.palette->screen_palents : NULL;
+	    GDI_ReleaseObj(This->s.DIBsection);
+	}
+	TSXFlush(display);
+    }
+    return DD_OK;
+}
+
+
 ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt = 
 {
     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
@@ -103,7 +159,7 @@ ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
     IDirectDrawSurface4Impl_SetClipper,
     IDirectDrawSurface4Impl_SetColorKey,
     IDirectDrawSurface4Impl_SetOverlayPosition,
-    DGA_IDirectDrawSurface4Impl_SetPalette,
+    DGA2_IDirectDrawSurface4Impl_SetPalette,
     DGA_IDirectDrawSurface4Impl_Unlock,
     IDirectDrawSurface4Impl_UpdateOverlay,
     IDirectDrawSurface4Impl_UpdateOverlayDisplay,