Add Syspalette index type to COLORREF - Resend

Glenn Wurster gwurster at scs.carleton.ca
Mon Dec 6 02:35:32 CST 2004


I sent this a while ago and it was dropped.  I'm resending it now with
the hopes that someone may be able to tell me why it was dropped.  The
feature is used in Sid Meir's Alpha Centauri, and is hanging up bug
882 (along with another patch on antialiasing fonts in palette mode).
I can't split it up anymore as it only really does one thing.

Authors:
  Doug Paul <doug at elemental.ath.cx>,
  Glenn Wurster <gwurster at scs.carleton.ca>

Description:
* In addition to PALETTEINDEX(0x01) and PALETTERGB(0x00) as macros for
specifying colour through the GDI colour functions, there is also
SYSPALETTEINDEX(0x10).  0x10 as a value maps the colour to the system
palette, which is the palette used by Alpha Centauri for text (bug 882).

Changelog:
 * Handle SYSPALETTEINDEX(0x10) as a COLORREF high byte

Glenn.

Index: dlls/x11drv/palette.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/palette.c,v
retrieving revision 1.9
diff -u -r1.9 palette.c
--- dlls/x11drv/palette.c	30 Nov 2004 21:38:58 -0000	1.9
+++ dlls/x11drv/palette.c	6 Dec 2004 00:02:18 -0000
@@ -227,21 +227,19 @@
     {
         palette_size = 0;
     }
+
+    if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
+        X11DRV_PALETTE_BuildPrivateMap( sys_pal_template );
     else
-    {
-        if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
-            X11DRV_PALETTE_BuildPrivateMap( sys_pal_template );
-        else
-            X11DRV_PALETTE_BuildSharedMap( sys_pal_template );
+        X11DRV_PALETTE_BuildSharedMap( sys_pal_template );
 
-        /* Build free list */
+    /* Build free list */
 
-        if( X11DRV_PALETTE_firstFree != -1 )
-            X11DRV_PALETTE_FormatSystemPalette();
+    if( X11DRV_PALETTE_firstFree != -1 )
+        X11DRV_PALETTE_FormatSystemPalette();
 
-        X11DRV_PALETTE_FillDefaultColors( sys_pal_template );
-        palette_size = visual->map_entries;
-    }
+    X11DRV_PALETTE_FillDefaultColors( sys_pal_template );
+    palette_size = visual->map_entries;
 
     return palette_size;
 }
@@ -869,6 +867,29 @@
 
 	switch(spec_type)
         {
+          case 0x10: /* SYSPALETTEINDEX */
+            
+            if( (idx = color & 0xffff) >= palette_size)
+            {
+                WARN("SYSPALETTEINDEX(%lx) : idx %d is out of bounds, assuming black\n", color, idx);
+		GDI_ReleaseObj( hPal );
+                return 0;
+            }
+
+            if (X11DRV_PALETTE_PaletteToXPixel) {
+              GDI_ReleaseObj( hPal );
+              return X11DRV_PALETTE_PaletteToXPixel[idx];
+            }
+              
+	    if (COLOR_sysPal) {
+	      color = *(COLORREF*)&COLOR_sysPal[idx];
+	    } else {
+	      TRACE("System palette not allocated, assuming black\n");
+	      color = 0;
+	    }
+	    
+	    break;
+
           case 1: /* PALETTEINDEX */
 
             if( (idx = color & 0xffff) >= palPtr->logpalette.palNumEntries)
@@ -958,11 +979,19 @@
 		/* TRACE(palette,"RGB(%lx) -> pixel %i\n", color, index);
 		 */
 	    	break;
+       	    case 0x10:  /* SYSPALETTEINDEX */
+		index = color & 0xffff;
+
+	        if( index >= palette_size )
+		    WARN("SYSPALETTEINDEX(%lx) : index %i is out of bounds\n", color, index);
+		else if( X11DRV_PALETTE_PaletteToXPixel ) 
+		    index = X11DRV_PALETTE_PaletteToXPixel[index];
+		break;
        	    case 1:  /* PALETTEINDEX */
 		index = color & 0xffff;
 
 	        if( index >= palPtr->logpalette.palNumEntries )
-		    WARN("RGB(%lx) : index %i is out of bounds\n", color, index);
+		    WARN("PALETTEINDEX(%lx) : index %i is out of bounds\n", color, index);
 		else if( palPtr->mapping ) index = palPtr->mapping[index];
 
 		/*  TRACE(palette,"PALETTEINDEX(%04x) -> pixel %i\n", (WORD)color, index);
@@ -1143,22 +1172,59 @@
                     color.green = palPtr->logpalette.palPalEntry[uStart].peGreen << 8;
                     color.blue = palPtr->logpalette.palPalEntry[uStart].peBlue << 8;
                     color.flags = DoRed | DoGreen | DoBlue;
-                    wine_tsx11_lock();
-                    XStoreColor(gdi_display, X11DRV_PALETTE_PaletteXColormap, &color);
-                    wine_tsx11_unlock();
+                    
+                    if (!(X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_VIRTUAL)) {
+                        wine_tsx11_lock();
+                        XStoreColor(gdi_display, X11DRV_PALETTE_PaletteXColormap, &color);
+                        wine_tsx11_unlock();
+                    }
 
                     COLOR_sysPal[index] = palPtr->logpalette.palPalEntry[uStart];
                     COLOR_sysPal[index].peFlags = flag;
 		    X11DRV_PALETTE_freeList[index] = 0;
 
+                    if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_FIXED) {
+                        if (!XAllocColor( gdi_display, X11DRV_PALETTE_PaletteXColormap, &color ))
+                        {
+                            unsigned int diff, best, cntr;
+                            unsigned int r, g, b;
+                            XColor colours[256];
+
+                            /* reinit color (XAllocColor() may change it)
+                             * and map to the best shared colorcell */
+
+                            color.red = palPtr->logpalette.palPalEntry[uStart].peRed << 8;
+                            color.green = palPtr->logpalette.palPalEntry[uStart].peGreen << 8;
+                            color.blue = palPtr->logpalette.palPalEntry[uStart].peBlue << 8;
+
+                            for( cntr = 0; cntr < 256; cntr++ )
+                                colours[cntr].pixel = cntr;
+
+                            XQueryColors(gdi_display, X11DRV_PALETTE_PaletteXColormap, colours, 256 );
+
+                            r = colours[0].red >> 8;
+                            g = colours[0].green >> 8;
+                            b = colours[0].blue >> 8;
+
+                            diff = r*r + g*g + b*b;
+                            best = 0;
+                            for( cntr = 1; cntr < 256; cntr++ )	
+                            {
+                                r = (colours[cntr].red - colours[best].red)>>8;
+                                g = (colours[cntr].green - colours[best].green)>>8;
+                                b = (colours[cntr].blue - colours[best].blue)>>8;	
+                                r = r*r + g*g + b*b;
+                                if( r < diff ) { best = cntr; diff = r; }
+                            }
+
+                            if( XAllocColor(gdi_display, X11DRV_PALETTE_PaletteXColormap, &colours[best]) )
+                                color.pixel = colours[best].pixel;
+                        }
+
+                        X11DRV_PALETTE_PaletteToXPixel[index] = color.pixel;
+                     }
+
                     if( X11DRV_PALETTE_PaletteToXPixel ) index = X11DRV_PALETTE_PaletteToXPixel[index];
-                    break;
-                }
-                else if ( X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_VIRTUAL )
-                {
-                    index = X11DRV_PALETTE_ToPhysical( NULL, 0x00ffffff &
-                             *(COLORREF*)(palPtr->logpalette.palPalEntry + uStart));
-                    break;
                 }
 
                 /* we have to map to existing entry in the system palette */
@@ -1251,8 +1317,6 @@
 {
     UINT ret;
     PALETTEOBJ *palPtr;
-
-    if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_VIRTUAL) return 0;
 
     if (!(palPtr = GDI_GetObjPtr( hpal, PALETTE_MAGIC ))) return 0;
     ret = X11DRV_PALETTE_SetMapping( palPtr, 0, palPtr->logpalette.palNumEntries, !primary );



More information about the wine-patches mailing list