| /* |
| * Color functions |
| * |
| * Copyright 1993 Alexandre Julliard |
| */ |
| |
| static char Copyright[] = "Copyright Alexandre Julliard, 1993"; |
| |
| #include <stdlib.h> |
| #include <X11/Xlib.h> |
| |
| #include "windows.h" |
| #include "options.h" |
| #include "gdi.h" |
| |
| |
| Colormap COLOR_WinColormap = 0; |
| |
| /* System palette static colors */ |
| |
| #define NB_RESERVED_COLORS 20 |
| |
| /* The first and last eight colors are EGA colors */ |
| static PALETTEENTRY COLOR_sysPaletteEntries[NB_RESERVED_COLORS] = |
| { |
| /* red green blue flags */ |
| { 0x00, 0x00, 0x00, 0 }, |
| { 0x80, 0x00, 0x00, 0 }, |
| { 0x00, 0x80, 0x00, 0 }, |
| { 0x80, 0x80, 0x00, 0 }, |
| { 0x00, 0x00, 0x80, 0 }, |
| { 0x80, 0x00, 0x80, 0 }, |
| { 0x00, 0x80, 0x80, 0 }, |
| { 0xc0, 0xc0, 0xc0, 0 }, |
| { 0xc0, 0xdc, 0xc0, 0 }, |
| { 0xa6, 0xca, 0xf0, 0 }, |
| |
| { 0xff, 0xfb, 0xf0, 0 }, |
| { 0xa0, 0xa0, 0xa4, 0 }, |
| { 0x80, 0x80, 0x80, 0 }, |
| { 0xff, 0x00, 0x00, 0 }, |
| { 0x00, 0xff, 0x00, 0 }, |
| { 0xff, 0xff, 0x00, 0 }, |
| { 0x00, 0x00, 0xff, 0 }, |
| { 0xff, 0x00, 0xff, 0 }, |
| { 0x00, 0xff, 0xff, 0 }, |
| { 0xff, 0xff, 0xff, 0 } |
| }; |
| |
| static HANDLE hSysColorTranslation = 0; |
| |
| /* Map an EGA index (0..15) to a pixel value. Used for dithering. */ |
| int COLOR_mapEGAPixel[16]; |
| |
| |
| /*********************************************************************** |
| * COLOR_BuildMap |
| * |
| * Fill the private colormap. |
| */ |
| static BOOL COLOR_BuildMap( Colormap map, int depth, int size ) |
| { |
| XColor color; |
| int r, g, b, red_incr, green_incr, blue_incr; |
| int index = 0; |
| |
| /* Fill the whole map with a range of colors */ |
| |
| blue_incr = 0x10000 >> (depth / 3); |
| red_incr = 0x10000 >> ((depth + 1) / 3); |
| green_incr = 0x10000 >> ((depth + 2) / 3); |
| |
| for (r = red_incr - 1; r < 0x10000; r += red_incr) |
| for (g = green_incr - 1; g < 0x10000; g += green_incr) |
| for (b = blue_incr - 1; b < 0x10000; b += blue_incr) |
| { |
| if (index >= size) break; |
| color.pixel = index++; |
| color.red = r; |
| color.green = g; |
| color.blue = b; |
| XStoreColor( display, map, &color ); |
| } |
| |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * COLOR_InitPalette |
| * |
| * Create the system palette. |
| */ |
| static HPALETTE COLOR_InitPalette() |
| { |
| int i, size; |
| XColor color; |
| HPALETTE hpalette; |
| LOGPALETTE * palPtr; |
| WORD *colorTranslation; |
| |
| if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE, |
| sizeof(WORD)*NB_RESERVED_COLORS ))) return FALSE; |
| colorTranslation = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation ); |
| size = DefaultVisual( display, DefaultScreen(display) )->map_entries; |
| for (i = 0; i < NB_RESERVED_COLORS; i++) |
| { |
| color.red = COLOR_sysPaletteEntries[i].peRed * 65535 / 255; |
| color.green = COLOR_sysPaletteEntries[i].peGreen * 65535 / 255; |
| color.blue = COLOR_sysPaletteEntries[i].peBlue * 65535 / 255; |
| color.flags = DoRed | DoGreen | DoBlue; |
| |
| if (COLOR_WinColormap != DefaultColormapOfScreen(screen)) |
| { |
| if (i < NB_RESERVED_COLORS/2) |
| { |
| /* Bottom half of the colormap */ |
| color.pixel = i; |
| if (color.pixel >= size/2) continue; |
| } |
| else |
| { |
| /* Top half of the colormap */ |
| color.pixel = size - NB_RESERVED_COLORS + i; |
| if (color.pixel < size/2) continue; |
| } |
| XStoreColor( display, COLOR_WinColormap, &color ); |
| } |
| else if (!XAllocColor( display, COLOR_WinColormap, &color )) |
| { |
| printf( "Warning: Not enough free colors. Try using the -privatemap option.\n" ); |
| color.pixel = color.red = color.green = color.blue = 0; |
| } |
| colorTranslation[i] = color.pixel; |
| #if 0 |
| /* Put the allocated colors back in the list */ |
| COLOR_sysPaletteEntries[i].peRed = color.red >> 8; |
| COLOR_sysPaletteEntries[i].peGreen = color.green >> 8; |
| COLOR_sysPaletteEntries[i].peBlue = color.blue >> 8; |
| #endif |
| /* Set EGA mapping if color in the first or last eight */ |
| if (i < 8) |
| COLOR_mapEGAPixel[i] = color.pixel; |
| else if (i >= NB_RESERVED_COLORS-8) |
| COLOR_mapEGAPixel[i - (NB_RESERVED_COLORS-16)] = color.pixel; |
| } |
| |
| palPtr = malloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) ); |
| if (!palPtr) return FALSE; |
| palPtr->palVersion = 0x300; |
| palPtr->palNumEntries = NB_RESERVED_COLORS; |
| memcpy( palPtr->palPalEntry, COLOR_sysPaletteEntries, |
| sizeof(COLOR_sysPaletteEntries) ); |
| hpalette = CreatePalette( palPtr ); |
| free( palPtr ); |
| return hpalette; |
| } |
| |
| |
| /*********************************************************************** |
| * COLOR_Init |
| * |
| * Initialize color map and system palette. |
| */ |
| HPALETTE COLOR_Init() |
| { |
| Visual * visual = DefaultVisual( display, DefaultScreen(display) ); |
| |
| switch(visual->class) |
| { |
| case GrayScale: |
| case PseudoColor: |
| case DirectColor: |
| if (Options.usePrivateMap) |
| { |
| COLOR_WinColormap = XCreateColormap( display, rootWindow, |
| visual, AllocAll ); |
| if (COLOR_WinColormap) |
| { |
| COLOR_BuildMap( COLOR_WinColormap, screenDepth, |
| visual->map_entries ); |
| if (rootWindow != DefaultRootWindow(display)) |
| { |
| XSetWindowAttributes win_attr; |
| win_attr.colormap = COLOR_WinColormap; |
| XChangeWindowAttributes( display, rootWindow, |
| CWColormap, &win_attr ); |
| } |
| break; |
| } |
| } |
| /* Fall through */ |
| case StaticGray: |
| case StaticColor: |
| case TrueColor: |
| COLOR_WinColormap = DefaultColormapOfScreen( screen ); |
| break; |
| } |
| return COLOR_InitPalette(); |
| } |
| |
| |
| /*********************************************************************** |
| * COLOR_IsSolid |
| * |
| * Check whether 'color' can be represented with a solid color. |
| */ |
| BOOL COLOR_IsSolid( COLORREF color ) |
| { |
| int i; |
| PALETTEENTRY *pEntry = COLOR_sysPaletteEntries; |
| |
| if (color & 0xff000000) return TRUE; |
| if (!color || (color == 0xffffff)) return TRUE; |
| for (i = NB_RESERVED_COLORS; i > 0; i--, pEntry++) |
| { |
| if ((GetRValue(color) == pEntry->peRed) && |
| (GetGValue(color) == pEntry->peGreen) && |
| (GetBValue(color) == pEntry->peBlue)) return TRUE; |
| } |
| return FALSE; |
| } |
| |
| |
| /*********************************************************************** |
| * COLOR_ToPhysical |
| * |
| * Return the physical color closest to 'color'. |
| */ |
| WORD COLOR_ToPhysical( DC *dc, COLORREF color ) |
| { |
| WORD index = 0; |
| WORD *mapping; |
| |
| if (!dc->u.x.pal.hMapping) return 0; |
| switch(color & 0xff000000) |
| { |
| case 0: /* RGB */ |
| index = GetNearestPaletteIndex( STOCK_DEFAULT_PALETTE, color ); |
| break; |
| case 1: /* PALETTEINDEX */ |
| index = color & 0xffff; |
| break; |
| case 2: /* PALETTERGB */ |
| index = GetNearestPaletteIndex( dc->w.hPalette, color ); |
| break; |
| } |
| if (index >= dc->u.x.pal.mappingSize) return 0; |
| mapping = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping ); |
| return mapping[index]; |
| } |
| |
| |
| /*********************************************************************** |
| * COLOR_SetMapping |
| * |
| * Set the color-mapping table in a DC. |
| */ |
| void COLOR_SetMapping( DC *dc, HANDLE map, WORD size ) |
| { |
| WORD *pmap, *pnewmap; |
| |
| if (dc->u.x.pal.hMapping && (dc->u.x.pal.hMapping != hSysColorTranslation)) |
| GDI_HEAP_FREE( dc->u.x.pal.hMapping ); |
| if (map && (map != hSysColorTranslation)) |
| { |
| /* Copy mapping table */ |
| dc->u.x.pal.hMapping = GDI_HEAP_ALLOC(GMEM_MOVEABLE,sizeof(WORD)*size); |
| pmap = (WORD *) GDI_HEAP_ADDR( map ); |
| pnewmap = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping ); |
| memcpy( pnewmap, pmap, sizeof(WORD)*size ); |
| } |
| else dc->u.x.pal.hMapping = map; |
| dc->u.x.pal.mappingSize = size; |
| } |
| |
| |
| /*********************************************************************** |
| * GetNearestColor (GDI.154) |
| */ |
| COLORREF GetNearestColor( HDC hdc, COLORREF color ) |
| { |
| WORD index; |
| DC *dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); |
| if (!dc) return 0; |
| index = COLOR_ToPhysical( dc, color & 0xffffff ); |
| return PALETTEINDEX( index ); |
| } |
| |
| |
| /*********************************************************************** |
| * RealizeDefaultPalette (GDI.365) |
| */ |
| WORD RealizeDefaultPalette( HDC hdc ) |
| { |
| DC *dc; |
| if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; |
| dc->w.hPalette = STOCK_DEFAULT_PALETTE; |
| COLOR_SetMapping( dc, hSysColorTranslation, NB_RESERVED_COLORS ); |
| return NB_RESERVED_COLORS; |
| } |