]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkcolor-win32.c
037d3d3b9337d165937167d4c46d08758054f8da
[~andy/gtk] / gdk / win32 / gdkcolor-win32.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <time.h>
33
34 #include "gdkcolor.h"
35 #include "gdkwin32.h"
36
37 static gint  gdk_colormap_match_color (GdkColormap *cmap,
38                                        GdkColor    *color,
39                                        const gchar *available);
40 static void  gdk_colormap_add         (GdkColormap *cmap);
41 static void  gdk_colormap_remove      (GdkColormap *cmap);
42 static guint gdk_colormap_hash        (Colormap    *cmap);
43 static gint  gdk_colormap_cmp         (Colormap    *a,
44                                        Colormap    *b);
45
46 static GHashTable *colormap_hash = NULL;
47
48 static Status
49 alloc_color_cells(Colormap      colormap,
50                   gboolean      contig,
51                   unsigned long plane_masks_return[],
52                   unsigned int  nplanes,
53                   unsigned long pixels_return[],
54                   unsigned int  npixels)
55 {
56   unsigned int i, nfree, iret;
57
58   nfree = 0;
59   for (i = 0; i < colormap->size && nfree < npixels; i++)
60     if (!colormap->in_use[i])
61       nfree++;
62
63   if (colormap->size + npixels - nfree > colormap->sizepalette)
64     {
65       g_warning ("alloc_color_cells: too large palette: %d",
66                  colormap->size + npixels);
67       return FALSE;
68     }
69
70   iret = 0;
71   for (i = 0; i < colormap->size && iret < npixels; i++)
72     if (!colormap->in_use[i])
73       {
74         colormap->in_use[i] = TRUE;
75         pixels_return[iret] = i;
76         iret++;
77       }
78
79   if (nfree < npixels)
80     {
81       int nmore = npixels - nfree;
82
83       /* I don't understand why, if the code below in #if 0 is
84          enabled, gdkrgb fails miserably. The palette doesn't get
85          realized correctly. There doesn't seem to be any harm done by
86          keeping this code out, either.  */
87 #ifdef SOME_STRANGE_BUG
88       if (!ResizePalette (colormap->palette, colormap->size + nmore))
89         {
90           WIN32_GDI_FAILED ("ResizePalette")
91           return FALSE;
92         }
93       g_print("alloc_color_cells: %#x to %d\n",
94               colormap->palette, colormap->size + nmore);
95 #endif
96       for (i = colormap->size; i < colormap->size + nmore; i++)
97         {
98           pixels_return[iret] = i;
99           iret++;
100           colormap->in_use[i] = TRUE;
101         }
102 #ifdef SOME_STRANGE_BUG
103       colormap->size += nmore;
104 #endif
105     }
106   return TRUE;
107 }
108
109 /* The following functions are from Tk8.0, but heavily modified.
110    Here are tk's licensing terms. I hope these terms don't conflict
111    with the GNU Library General Public License? They shouldn't, as
112    they are looser that the GLPL, yes? */
113
114 /*
115 This software is copyrighted by the Regents of the University of
116 California, Sun Microsystems, Inc., and other parties.  The following
117 terms apply to all files associated with the software unless explicitly
118 disclaimed in individual files.
119
120 The authors hereby grant permission to use, copy, modify, distribute,
121 and license this software and its documentation for any purpose, provided
122 that existing copyright notices are retained in all copies and that this
123 notice is included verbatim in any distributions. No written agreement,
124 license, or royalty fee is required for any of the authorized uses.
125 Modifications to this software may be copyrighted by their authors
126 and need not follow the licensing terms described here, provided that
127 the new terms are clearly indicated on the first page of each file where
128 they apply.
129
130 IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
131 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
132 ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
133 DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
134 POSSIBILITY OF SUCH DAMAGE.
135
136 THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
137 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
138 FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
139 IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
140 NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
141 MODIFICATIONS.
142
143 GOVERNMENT USE: If you are acquiring this software on behalf of the
144 U.S. government, the Government shall have only "Restricted Rights"
145 in the software and related documentation as defined in the Federal 
146 Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
147 are acquiring the software on behalf of the Department of Defense, the
148 software shall be classified as "Commercial Computer Software" and the
149 Government shall have only "Restricted Rights" as defined in Clause
150 252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the
151 authors grant the U.S. Government and others acting in its behalf
152 permission to use and distribute the software in accordance with the
153 terms specified in this license.
154 */
155 /*
156  *----------------------------------------------------------------------
157  *
158  * XAllocColor --
159  *
160  *      Find the closest available color to the specified XColor.
161  *
162  * Results:
163  *      Updates the color argument and returns 1 on success.  Otherwise
164  *      returns 0.
165  *
166  * Side effects:
167  *      Allocates a new color in the palette.
168  *
169  *----------------------------------------------------------------------
170  */
171
172 static int
173 alloc_color(Colormap  colormap,
174             XColor   *color,
175             gulong   *pixelp)
176 {
177   PALETTEENTRY entry, closeEntry;
178   HDC hdc;
179   unsigned int i;
180     
181   entry = *color;
182   entry.peFlags = 0;
183
184   if (colormap->rc_palette)
185     {
186       COLORREF newPixel, closePixel;
187       UINT index;
188
189       /*
190        * Find the nearest existing palette entry.
191        */
192         
193       newPixel = RGB (entry.peRed, entry.peGreen, entry.peBlue);
194       index = GetNearestPaletteIndex (colormap->palette, newPixel);
195       GetPaletteEntries (colormap->palette, index, 1, &closeEntry);
196       closePixel = RGB (closeEntry.peRed, closeEntry.peGreen,
197                         closeEntry.peBlue);
198
199       if (newPixel != closePixel)
200         {
201           /* Not a perfect match. */
202           if (!colormap->in_use[index])
203             {
204               /* It was a free'd entry anyway, so we can use it, and
205                  set it to the correct color. */
206               if (SetPaletteEntries (colormap->palette, index, 1, &entry) == 0)
207                 WIN32_GDI_FAILED ("SetPaletteEntries");
208             }
209           else
210             {
211               /* The close entry found is in use, so search for a
212                  unused slot. */
213                  
214               for (i = 0; i < colormap->size; i++)
215                 if (!colormap->in_use[i])
216                   {
217                     /* A free slot, use it. */
218                     if (SetPaletteEntries (colormap->palette,
219                                            index, 1, &entry) == 0)
220                       WIN32_GDI_FAILED ("SetPaletteEntries");
221                     index = i;
222                     break;
223                   }
224               if (i == colormap->size)
225                 {
226                   /* No free slots found. If the palette isn't maximal
227                      yet, grow it. */
228                   if (colormap->size == colormap->sizepalette)
229                     {
230                       /* The palette is maximal, and no free slots available,
231                          so use the close entry, then, dammit. */
232                       *color = closeEntry;
233                     }
234                   else
235                     {
236                       /* There is room to grow the palette. */
237                       index = colormap->size;
238                       colormap->size++;
239                       if (!ResizePalette (colormap->palette, colormap->size))
240                         WIN32_GDI_FAILED ("ResizePalette");
241                       if (SetPaletteEntries (colormap->palette, index, 1, &entry) == 0)
242                         WIN32_GDI_FAILED ("SetPaletteEntries");
243                     }
244                 }
245             }
246           colormap->stale = TRUE;
247         }
248       else
249         {
250           /* We got a match, so use it. */
251         }
252
253       *pixelp = index;
254       colormap->in_use[index] = TRUE;
255 #if 0
256       g_print("alloc_color from %#x: index %d for %02x %02x %02x\n",
257               colormap->palette, index,
258               entry.peRed, entry.peGreen, entry.peBlue);
259 #endif
260     }
261   else
262     {
263       /*
264        * Determine what color will actually be used on non-colormap systems.
265        */
266       *pixelp = GetNearestColor (gdk_DC, RGB(entry.peRed, entry.peGreen, entry.peBlue));
267       
268       color->peRed = GetRValue (*pixelp);
269       color->peGreen = GetGValue (*pixelp);
270       color->peBlue = GetBValue (*pixelp);
271     }
272   
273   return 1;
274 }
275
276 /*
277  *----------------------------------------------------------------------
278  *
279  * XFreeColors --
280  *
281  *      Deallocate a block of colors.
282  *
283  * Results:
284  *      None.
285  *
286  * Side effects:
287  *      Removes entries for the current palette and compacts the
288  *      remaining set.
289  *
290  *----------------------------------------------------------------------
291  */
292
293 static void
294 free_colors (Colormap colormap,
295              gulong  *pixels,
296              gint     npixels,
297              gulong   planes)
298 {
299   gint i;
300   PALETTEENTRY entries[256];
301
302   /*
303    * We don't have to do anything for non-palette devices.
304    */
305   
306   if (colormap->rc_palette)
307     {
308       int npal;
309       int lowestpixel = 256;
310       int highestpixel = -1;
311
312       npal = GetPaletteEntries (colormap->palette, 0, 256, entries);
313       for (i = 0; i < npixels; i++)
314         {
315           int pixel = pixels[i];
316
317           if (pixel < lowestpixel)
318             lowestpixel = pixel;
319           if (pixel > highestpixel)
320             highestpixel = pixel;
321
322           colormap->in_use[pixel] = FALSE;
323
324           entries[pixel] = entries[0];
325         }
326 #if 0
327       if (SetPaletteEntries (colormap->palette, lowestpixel,
328                              highestpixel - lowestpixel + 1,
329                              entries + lowestpixel) == 0)
330         WIN32_GDI_FAILED ("SetPaletteEntries");
331 #endif
332       colormap->stale = TRUE;
333 #if 0
334       g_print("free_colors %#x lowestpixel = %d, highestpixel = %d\n",
335               colormap->palette, lowestpixel, highestpixel);
336 #endif
337     }
338 }
339
340 /*
341  *----------------------------------------------------------------------
342  *
343  * XCreateColormap --
344  *
345  *      Allocate a new colormap.
346  *
347  * Results:
348  *      Returns a newly allocated colormap.
349  *
350  * Side effects:
351  *      Allocates an empty palette and color list.
352  *
353  *----------------------------------------------------------------------
354  */
355
356 static Colormap
357 create_colormap (HWND     w,
358                  Visual  *visual,
359                  gboolean alloc)
360 {
361   char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
362   LOGPALETTE *logPalettePtr;
363   PALETTEENTRY *entryPtr;
364   Colormap colormap;
365   guint i;
366   HPALETTE sysPal;
367   HDC hdc;
368
369   /* Should the alloc parameter do something? */
370
371
372   /* Allocate a starting palette with all of the reserved colors. */
373   
374   logPalettePtr = (LOGPALETTE *) logPalBuf;
375   logPalettePtr->palVersion = 0x300;
376   sysPal = (HPALETTE) GetStockObject (DEFAULT_PALETTE);
377   logPalettePtr->palNumEntries =
378     GetPaletteEntries (sysPal, 0, 256, logPalettePtr->palPalEntry);
379   
380   colormap = (Colormap) g_new (ColormapStruct, 1);
381   colormap->size = logPalettePtr->palNumEntries;
382   colormap->stale = TRUE;
383   colormap->palette = CreatePalette (logPalettePtr);
384   hdc = GetDC (NULL);
385   colormap->rc_palette = ((GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) != 0);
386   if (colormap->rc_palette)
387     {
388       colormap->sizepalette = GetDeviceCaps (hdc, SIZEPALETTE);
389       colormap->in_use = g_new (gboolean, colormap->sizepalette);
390       /* Mark static colors in use. */
391       for (i = 0; i < logPalettePtr->palNumEntries; i++)
392         colormap->in_use[i] = TRUE;
393       /* Mark rest not in use */
394       for (i = logPalettePtr->palNumEntries; i < colormap->sizepalette; i++)
395         colormap->in_use[i] = FALSE;
396     }
397   ReleaseDC (NULL, hdc);
398
399   return colormap;
400 }
401
402 /*
403  *----------------------------------------------------------------------
404  *
405  * XFreeColormap --
406  *
407  *      Frees the resources associated with the given colormap.
408  *
409  * Results:
410  *      None.
411  *
412  * Side effects:
413  *      Deletes the palette associated with the colormap.  Note that
414  *      the palette must not be selected into a device context when
415  *      this occurs.
416  *
417  *----------------------------------------------------------------------
418  */
419
420 static void
421 free_colormap(Colormap  colormap)
422  
423 {
424   if (!DeleteObject (colormap->palette))
425     {
426       g_error ("Unable to free colormap, palette is still selected.");
427     }
428   g_free (colormap);
429 }
430
431 typedef struct {
432     char *name;
433     unsigned char red;
434     unsigned char green;
435     unsigned char blue;
436 } XColorEntry;
437
438 static XColorEntry xColors[] = {
439     { "alice blue", 240, 248, 255 },
440     { "AliceBlue", 240, 248, 255 },
441     { "antique white", 250, 235, 215 },
442     { "AntiqueWhite", 250, 235, 215 },
443     { "AntiqueWhite1", 255, 239, 219 },
444     { "AntiqueWhite2", 238, 223, 204 },
445     { "AntiqueWhite3", 205, 192, 176 },
446     { "AntiqueWhite4", 139, 131, 120 },
447     { "aquamarine", 127, 255, 212 },
448     { "aquamarine1", 127, 255, 212 },
449     { "aquamarine2", 118, 238, 198 },
450     { "aquamarine3", 102, 205, 170 },
451     { "aquamarine4", 69, 139, 116 },
452     { "azure", 240, 255, 255 },
453     { "azure1", 240, 255, 255 },
454     { "azure2", 224, 238, 238 },
455     { "azure3", 193, 205, 205 },
456     { "azure4", 131, 139, 139 },
457     { "beige", 245, 245, 220 },
458     { "bisque", 255, 228, 196 },
459     { "bisque1", 255, 228, 196 },
460     { "bisque2", 238, 213, 183 },
461     { "bisque3", 205, 183, 158 },
462     { "bisque4", 139, 125, 107 },
463     { "black", 0, 0, 0 },
464     { "blanched almond", 255, 235, 205 },
465     { "BlanchedAlmond", 255, 235, 205 },
466     { "blue", 0, 0, 255 },
467     { "blue violet", 138, 43, 226 },
468     { "blue1", 0, 0, 255 },
469     { "blue2", 0, 0, 238 },
470     { "blue3", 0, 0, 205 },
471     { "blue4", 0, 0, 139 },
472     { "BlueViolet", 138, 43, 226 },
473     { "brown", 165, 42, 42 },
474     { "brown1", 255, 64, 64 },
475     { "brown2", 238, 59, 59 },
476     { "brown3", 205, 51, 51 },
477     { "brown4", 139, 35, 35 },
478     { "burlywood", 222, 184, 135 },
479     { "burlywood1", 255, 211, 155 },
480     { "burlywood2", 238, 197, 145 },
481     { "burlywood3", 205, 170, 125 },
482     { "burlywood4", 139, 115, 85 },
483     { "cadet blue", 95, 158, 160 },
484     { "CadetBlue", 95, 158, 160 },
485     { "CadetBlue1", 152, 245, 255 },
486     { "CadetBlue2", 142, 229, 238 },
487     { "CadetBlue3", 122, 197, 205 },
488     { "CadetBlue4", 83, 134, 139 },
489     { "chartreuse", 127, 255, 0 },
490     { "chartreuse1", 127, 255, 0 },
491     { "chartreuse2", 118, 238, 0 },
492     { "chartreuse3", 102, 205, 0 },
493     { "chartreuse4", 69, 139, 0 },
494     { "chocolate", 210, 105, 30 },
495     { "chocolate1", 255, 127, 36 },
496     { "chocolate2", 238, 118, 33 },
497     { "chocolate3", 205, 102, 29 },
498     { "chocolate4", 139, 69, 19 },
499     { "coral", 255, 127, 80 },
500     { "coral1", 255, 114, 86 },
501     { "coral2", 238, 106, 80 },
502     { "coral3", 205, 91, 69 },
503     { "coral4", 139, 62, 47 },
504     { "cornflower blue", 100, 149, 237 },
505     { "CornflowerBlue", 100, 149, 237 },
506     { "cornsilk", 255, 248, 220 },
507     { "cornsilk1", 255, 248, 220 },
508     { "cornsilk2", 238, 232, 205 },
509     { "cornsilk3", 205, 200, 177 },
510     { "cornsilk4", 139, 136, 120 },
511     { "cyan", 0, 255, 255 },
512     { "cyan1", 0, 255, 255 },
513     { "cyan2", 0, 238, 238 },
514     { "cyan3", 0, 205, 205 },
515     { "cyan4", 0, 139, 139 },
516     { "dark blue", 0, 0, 139 },
517     { "dark cyan", 0, 139, 139 },
518     { "dark goldenrod", 184, 134, 11 },
519     { "dark gray", 169, 169, 169 },
520     { "dark green", 0, 100, 0 },
521     { "dark grey", 169, 169, 169 },
522     { "dark khaki", 189, 183, 107 },
523     { "dark magenta", 139, 0, 139 },
524     { "dark olive green", 85, 107, 47 },
525     { "dark orange", 255, 140, 0 },
526     { "dark orchid", 153, 50, 204 },
527     { "dark red", 139, 0, 0 },
528     { "dark salmon", 233, 150, 122 },
529     { "dark sea green", 143, 188, 143 },
530     { "dark slate blue", 72, 61, 139 },
531     { "dark slate gray", 47, 79, 79 },
532     { "dark slate grey", 47, 79, 79 },
533     { "dark turquoise", 0, 206, 209 },
534     { "dark violet", 148, 0, 211 },
535     { "DarkBlue", 0, 0, 139 },
536     { "DarkCyan", 0, 139, 139 },
537     { "DarkGoldenrod", 184, 134, 11 },
538     { "DarkGoldenrod1", 255, 185, 15 },
539     { "DarkGoldenrod2", 238, 173, 14 },
540     { "DarkGoldenrod3", 205, 149, 12 },
541     { "DarkGoldenrod4", 139, 101, 8 },
542     { "DarkGray", 169, 169, 169 },
543     { "DarkGreen", 0, 100, 0 },
544     { "DarkGrey", 169, 169, 169 },
545     { "DarkKhaki", 189, 183, 107 },
546     { "DarkMagenta", 139, 0, 139 },
547     { "DarkOliveGreen", 85, 107, 47 },
548     { "DarkOliveGreen1", 202, 255, 112 },
549     { "DarkOliveGreen2", 188, 238, 104 },
550     { "DarkOliveGreen3", 162, 205, 90 },
551     { "DarkOliveGreen4", 110, 139, 61 },
552     { "DarkOrange", 255, 140, 0 },
553     { "DarkOrange1", 255, 127, 0 },
554     { "DarkOrange2", 238, 118, 0 },
555     { "DarkOrange3", 205, 102, 0 },
556     { "DarkOrange4", 139, 69, 0 },
557     { "DarkOrchid", 153, 50, 204 },
558     { "DarkOrchid1", 191, 62, 255 },
559     { "DarkOrchid2", 178, 58, 238 },
560     { "DarkOrchid3", 154, 50, 205 },
561     { "DarkOrchid4", 104, 34, 139 },
562     { "DarkRed", 139, 0, 0 },
563     { "DarkSalmon", 233, 150, 122 },
564     { "DarkSeaGreen", 143, 188, 143 },
565     { "DarkSeaGreen1", 193, 255, 193 },
566     { "DarkSeaGreen2", 180, 238, 180 },
567     { "DarkSeaGreen3", 155, 205, 155 },
568     { "DarkSeaGreen4", 105, 139, 105 },
569     { "DarkSlateBlue", 72, 61, 139 },
570     { "DarkSlateGray", 47, 79, 79 },
571     { "DarkSlateGray1", 151, 255, 255 },
572     { "DarkSlateGray2", 141, 238, 238 },
573     { "DarkSlateGray3", 121, 205, 205 },
574     { "DarkSlateGray4", 82, 139, 139 },
575     { "DarkSlateGrey", 47, 79, 79 },
576     { "DarkTurquoise", 0, 206, 209 },
577     { "DarkViolet", 148, 0, 211 },
578     { "deep pink", 255, 20, 147 },
579     { "deep sky blue", 0, 191, 255 },
580     { "DeepPink", 255, 20, 147 },
581     { "DeepPink1", 255, 20, 147 },
582     { "DeepPink2", 238, 18, 137 },
583     { "DeepPink3", 205, 16, 118 },
584     { "DeepPink4", 139, 10, 80 },
585     { "DeepSkyBlue", 0, 191, 255 },
586     { "DeepSkyBlue1", 0, 191, 255 },
587     { "DeepSkyBlue2", 0, 178, 238 },
588     { "DeepSkyBlue3", 0, 154, 205 },
589     { "DeepSkyBlue4", 0, 104, 139 },
590     { "dim gray", 105, 105, 105 },
591     { "dim grey", 105, 105, 105 },
592     { "DimGray", 105, 105, 105 },
593     { "DimGrey", 105, 105, 105 },
594     { "dodger blue", 30, 144, 255 },
595     { "DodgerBlue", 30, 144, 255 },
596     { "DodgerBlue1", 30, 144, 255 },
597     { "DodgerBlue2", 28, 134, 238 },
598     { "DodgerBlue3", 24, 116, 205 },
599     { "DodgerBlue4", 16, 78, 139 },
600     { "firebrick", 178, 34, 34 },
601     { "firebrick1", 255, 48, 48 },
602     { "firebrick2", 238, 44, 44 },
603     { "firebrick3", 205, 38, 38 },
604     { "firebrick4", 139, 26, 26 },
605     { "floral white", 255, 250, 240 },
606     { "FloralWhite", 255, 250, 240 },
607     { "forest green", 34, 139, 34 },
608     { "ForestGreen", 34, 139, 34 },
609     { "gainsboro", 220, 220, 220 },
610     { "ghost white", 248, 248, 255 },
611     { "GhostWhite", 248, 248, 255 },
612     { "gold", 255, 215, 0 },
613     { "gold1", 255, 215, 0 },
614     { "gold2", 238, 201, 0 },
615     { "gold3", 205, 173, 0 },
616     { "gold4", 139, 117, 0 },
617     { "goldenrod", 218, 165, 32 },
618     { "goldenrod1", 255, 193, 37 },
619     { "goldenrod2", 238, 180, 34 },
620     { "goldenrod3", 205, 155, 29 },
621     { "goldenrod4", 139, 105, 20 },
622     { "gray", 190, 190, 190 },
623     { "gray0", 0, 0, 0 },
624     { "gray1", 3, 3, 3 },
625     { "gray10", 26, 26, 26 },
626     { "gray100", 255, 255, 255 },
627     { "gray11", 28, 28, 28 },
628     { "gray12", 31, 31, 31 },
629     { "gray13", 33, 33, 33 },
630     { "gray14", 36, 36, 36 },
631     { "gray15", 38, 38, 38 },
632     { "gray16", 41, 41, 41 },
633     { "gray17", 43, 43, 43 },
634     { "gray18", 46, 46, 46 },
635     { "gray19", 48, 48, 48 },
636     { "gray2", 5, 5, 5 },
637     { "gray20", 51, 51, 51 },
638     { "gray21", 54, 54, 54 },
639     { "gray22", 56, 56, 56 },
640     { "gray23", 59, 59, 59 },
641     { "gray24", 61, 61, 61 },
642     { "gray25", 64, 64, 64 },
643     { "gray26", 66, 66, 66 },
644     { "gray27", 69, 69, 69 },
645     { "gray28", 71, 71, 71 },
646     { "gray29", 74, 74, 74 },
647     { "gray3", 8, 8, 8 },
648     { "gray30", 77, 77, 77 },
649     { "gray31", 79, 79, 79 },
650     { "gray32", 82, 82, 82 },
651     { "gray33", 84, 84, 84 },
652     { "gray34", 87, 87, 87 },
653     { "gray35", 89, 89, 89 },
654     { "gray36", 92, 92, 92 },
655     { "gray37", 94, 94, 94 },
656     { "gray38", 97, 97, 97 },
657     { "gray39", 99, 99, 99 },
658     { "gray4", 10, 10, 10 },
659     { "gray40", 102, 102, 102 },
660     { "gray41", 105, 105, 105 },
661     { "gray42", 107, 107, 107 },
662     { "gray43", 110, 110, 110 },
663     { "gray44", 112, 112, 112 },
664     { "gray45", 115, 115, 115 },
665     { "gray46", 117, 117, 117 },
666     { "gray47", 120, 120, 120 },
667     { "gray48", 122, 122, 122 },
668     { "gray49", 125, 125, 125 },
669     { "gray5", 13, 13, 13 },
670     { "gray50", 127, 127, 127 },
671     { "gray51", 130, 130, 130 },
672     { "gray52", 133, 133, 133 },
673     { "gray53", 135, 135, 135 },
674     { "gray54", 138, 138, 138 },
675     { "gray55", 140, 140, 140 },
676     { "gray56", 143, 143, 143 },
677     { "gray57", 145, 145, 145 },
678     { "gray58", 148, 148, 148 },
679     { "gray59", 150, 150, 150 },
680     { "gray6", 15, 15, 15 },
681     { "gray60", 153, 153, 153 },
682     { "gray61", 156, 156, 156 },
683     { "gray62", 158, 158, 158 },
684     { "gray63", 161, 161, 161 },
685     { "gray64", 163, 163, 163 },
686     { "gray65", 166, 166, 166 },
687     { "gray66", 168, 168, 168 },
688     { "gray67", 171, 171, 171 },
689     { "gray68", 173, 173, 173 },
690     { "gray69", 176, 176, 176 },
691     { "gray7", 18, 18, 18 },
692     { "gray70", 179, 179, 179 },
693     { "gray71", 181, 181, 181 },
694     { "gray72", 184, 184, 184 },
695     { "gray73", 186, 186, 186 },
696     { "gray74", 189, 189, 189 },
697     { "gray75", 191, 191, 191 },
698     { "gray76", 194, 194, 194 },
699     { "gray77", 196, 196, 196 },
700     { "gray78", 199, 199, 199 },
701     { "gray79", 201, 201, 201 },
702     { "gray8", 20, 20, 20 },
703     { "gray80", 204, 204, 204 },
704     { "gray81", 207, 207, 207 },
705     { "gray82", 209, 209, 209 },
706     { "gray83", 212, 212, 212 },
707     { "gray84", 214, 214, 214 },
708     { "gray85", 217, 217, 217 },
709     { "gray86", 219, 219, 219 },
710     { "gray87", 222, 222, 222 },
711     { "gray88", 224, 224, 224 },
712     { "gray89", 227, 227, 227 },
713     { "gray9", 23, 23, 23 },
714     { "gray90", 229, 229, 229 },
715     { "gray91", 232, 232, 232 },
716     { "gray92", 235, 235, 235 },
717     { "gray93", 237, 237, 237 },
718     { "gray94", 240, 240, 240 },
719     { "gray95", 242, 242, 242 },
720     { "gray96", 245, 245, 245 },
721     { "gray97", 247, 247, 247 },
722     { "gray98", 250, 250, 250 },
723     { "gray99", 252, 252, 252 },
724     { "green", 0, 255, 0 },
725     { "green yellow", 173, 255, 47 },
726     { "green1", 0, 255, 0 },
727     { "green2", 0, 238, 0 },
728     { "green3", 0, 205, 0 },
729     { "green4", 0, 139, 0 },
730     { "GreenYellow", 173, 255, 47 },
731     { "grey", 190, 190, 190 },
732     { "grey0", 0, 0, 0 },
733     { "grey1", 3, 3, 3 },
734     { "grey10", 26, 26, 26 },
735     { "grey100", 255, 255, 255 },
736     { "grey11", 28, 28, 28 },
737     { "grey12", 31, 31, 31 },
738     { "grey13", 33, 33, 33 },
739     { "grey14", 36, 36, 36 },
740     { "grey15", 38, 38, 38 },
741     { "grey16", 41, 41, 41 },
742     { "grey17", 43, 43, 43 },
743     { "grey18", 46, 46, 46 },
744     { "grey19", 48, 48, 48 },
745     { "grey2", 5, 5, 5 },
746     { "grey20", 51, 51, 51 },
747     { "grey21", 54, 54, 54 },
748     { "grey22", 56, 56, 56 },
749     { "grey23", 59, 59, 59 },
750     { "grey24", 61, 61, 61 },
751     { "grey25", 64, 64, 64 },
752     { "grey26", 66, 66, 66 },
753     { "grey27", 69, 69, 69 },
754     { "grey28", 71, 71, 71 },
755     { "grey29", 74, 74, 74 },
756     { "grey3", 8, 8, 8 },
757     { "grey30", 77, 77, 77 },
758     { "grey31", 79, 79, 79 },
759     { "grey32", 82, 82, 82 },
760     { "grey33", 84, 84, 84 },
761     { "grey34", 87, 87, 87 },
762     { "grey35", 89, 89, 89 },
763     { "grey36", 92, 92, 92 },
764     { "grey37", 94, 94, 94 },
765     { "grey38", 97, 97, 97 },
766     { "grey39", 99, 99, 99 },
767     { "grey4", 10, 10, 10 },
768     { "grey40", 102, 102, 102 },
769     { "grey41", 105, 105, 105 },
770     { "grey42", 107, 107, 107 },
771     { "grey43", 110, 110, 110 },
772     { "grey44", 112, 112, 112 },
773     { "grey45", 115, 115, 115 },
774     { "grey46", 117, 117, 117 },
775     { "grey47", 120, 120, 120 },
776     { "grey48", 122, 122, 122 },
777     { "grey49", 125, 125, 125 },
778     { "grey5", 13, 13, 13 },
779     { "grey50", 127, 127, 127 },
780     { "grey51", 130, 130, 130 },
781     { "grey52", 133, 133, 133 },
782     { "grey53", 135, 135, 135 },
783     { "grey54", 138, 138, 138 },
784     { "grey55", 140, 140, 140 },
785     { "grey56", 143, 143, 143 },
786     { "grey57", 145, 145, 145 },
787     { "grey58", 148, 148, 148 },
788     { "grey59", 150, 150, 150 },
789     { "grey6", 15, 15, 15 },
790     { "grey60", 153, 153, 153 },
791     { "grey61", 156, 156, 156 },
792     { "grey62", 158, 158, 158 },
793     { "grey63", 161, 161, 161 },
794     { "grey64", 163, 163, 163 },
795     { "grey65", 166, 166, 166 },
796     { "grey66", 168, 168, 168 },
797     { "grey67", 171, 171, 171 },
798     { "grey68", 173, 173, 173 },
799     { "grey69", 176, 176, 176 },
800     { "grey7", 18, 18, 18 },
801     { "grey70", 179, 179, 179 },
802     { "grey71", 181, 181, 181 },
803     { "grey72", 184, 184, 184 },
804     { "grey73", 186, 186, 186 },
805     { "grey74", 189, 189, 189 },
806     { "grey75", 191, 191, 191 },
807     { "grey76", 194, 194, 194 },
808     { "grey77", 196, 196, 196 },
809     { "grey78", 199, 199, 199 },
810     { "grey79", 201, 201, 201 },
811     { "grey8", 20, 20, 20 },
812     { "grey80", 204, 204, 204 },
813     { "grey81", 207, 207, 207 },
814     { "grey82", 209, 209, 209 },
815     { "grey83", 212, 212, 212 },
816     { "grey84", 214, 214, 214 },
817     { "grey85", 217, 217, 217 },
818     { "grey86", 219, 219, 219 },
819     { "grey87", 222, 222, 222 },
820     { "grey88", 224, 224, 224 },
821     { "grey89", 227, 227, 227 },
822     { "grey9", 23, 23, 23 },
823     { "grey90", 229, 229, 229 },
824     { "grey91", 232, 232, 232 },
825     { "grey92", 235, 235, 235 },
826     { "grey93", 237, 237, 237 },
827     { "grey94", 240, 240, 240 },
828     { "grey95", 242, 242, 242 },
829     { "grey96", 245, 245, 245 },
830     { "grey97", 247, 247, 247 },
831     { "grey98", 250, 250, 250 },
832     { "grey99", 252, 252, 252 },
833     { "honeydew", 240, 255, 240 },
834     { "honeydew1", 240, 255, 240 },
835     { "honeydew2", 224, 238, 224 },
836     { "honeydew3", 193, 205, 193 },
837     { "honeydew4", 131, 139, 131 },
838     { "hot pink", 255, 105, 180 },
839     { "HotPink", 255, 105, 180 },
840     { "HotPink1", 255, 110, 180 },
841     { "HotPink2", 238, 106, 167 },
842     { "HotPink3", 205, 96, 144 },
843     { "HotPink4", 139, 58, 98 },
844     { "indian red", 205, 92, 92 },
845     { "IndianRed", 205, 92, 92 },
846     { "IndianRed1", 255, 106, 106 },
847     { "IndianRed2", 238, 99, 99 },
848     { "IndianRed3", 205, 85, 85 },
849     { "IndianRed4", 139, 58, 58 },
850     { "ivory", 255, 255, 240 },
851     { "ivory1", 255, 255, 240 },
852     { "ivory2", 238, 238, 224 },
853     { "ivory3", 205, 205, 193 },
854     { "ivory4", 139, 139, 131 },
855     { "khaki", 240, 230, 140 },
856     { "khaki1", 255, 246, 143 },
857     { "khaki2", 238, 230, 133 },
858     { "khaki3", 205, 198, 115 },
859     { "khaki4", 139, 134, 78 },
860     { "lavender", 230, 230, 250 },
861     { "lavender blush", 255, 240, 245 },
862     { "LavenderBlush", 255, 240, 245 },
863     { "LavenderBlush1", 255, 240, 245 },
864     { "LavenderBlush2", 238, 224, 229 },
865     { "LavenderBlush3", 205, 193, 197 },
866     { "LavenderBlush4", 139, 131, 134 },
867     { "lawn green", 124, 252, 0 },
868     { "LawnGreen", 124, 252, 0 },
869     { "lemon chiffon", 255, 250, 205 },
870     { "LemonChiffon", 255, 250, 205 },
871     { "LemonChiffon1", 255, 250, 205 },
872     { "LemonChiffon2", 238, 233, 191 },
873     { "LemonChiffon3", 205, 201, 165 },
874     { "LemonChiffon4", 139, 137, 112 },
875     { "light blue", 173, 216, 230 },
876     { "light coral", 240, 128, 128 },
877     { "light cyan", 224, 255, 255 },
878     { "light goldenrod", 238, 221, 130 },
879     { "light goldenrod yellow", 250, 250, 210 },
880     { "light gray", 211, 211, 211 },
881     { "light green", 144, 238, 144 },
882     { "light grey", 211, 211, 211 },
883     { "light pink", 255, 182, 193 },
884     { "light salmon", 255, 160, 122 },
885     { "light sea green", 32, 178, 170 },
886     { "light sky blue", 135, 206, 250 },
887     { "light slate blue", 132, 112, 255 },
888     { "light slate gray", 119, 136, 153 },
889     { "light slate grey", 119, 136, 153 },
890     { "light steel blue", 176, 196, 222 },
891     { "light yellow", 255, 255, 224 },
892     { "LightBlue", 173, 216, 230 },
893     { "LightBlue1", 191, 239, 255 },
894     { "LightBlue2", 178, 223, 238 },
895     { "LightBlue3", 154, 192, 205 },
896     { "LightBlue4", 104, 131, 139 },
897     { "LightCoral", 240, 128, 128 },
898     { "LightCyan", 224, 255, 255 },
899     { "LightCyan1", 224, 255, 255 },
900     { "LightCyan2", 209, 238, 238 },
901     { "LightCyan3", 180, 205, 205 },
902     { "LightCyan4", 122, 139, 139 },
903     { "LightGoldenrod", 238, 221, 130 },
904     { "LightGoldenrod1", 255, 236, 139 },
905     { "LightGoldenrod2", 238, 220, 130 },
906     { "LightGoldenrod3", 205, 190, 112 },
907     { "LightGoldenrod4", 139, 129, 76 },
908     { "LightGoldenrodYellow", 250, 250, 210 },
909     { "LightGray", 211, 211, 211 },
910     { "LightGreen", 144, 238, 144 },
911     { "LightGrey", 211, 211, 211 },
912     { "LightPink", 255, 182, 193 },
913     { "LightPink1", 255, 174, 185 },
914     { "LightPink2", 238, 162, 173 },
915     { "LightPink3", 205, 140, 149 },
916     { "LightPink4", 139, 95, 101 },
917     { "LightSalmon", 255, 160, 122 },
918     { "LightSalmon1", 255, 160, 122 },
919     { "LightSalmon2", 238, 149, 114 },
920     { "LightSalmon3", 205, 129, 98 },
921     { "LightSalmon4", 139, 87, 66 },
922     { "LightSeaGreen", 32, 178, 170 },
923     { "LightSkyBlue", 135, 206, 250 },
924     { "LightSkyBlue1", 176, 226, 255 },
925     { "LightSkyBlue2", 164, 211, 238 },
926     { "LightSkyBlue3", 141, 182, 205 },
927     { "LightSkyBlue4", 96, 123, 139 },
928     { "LightSlateBlue", 132, 112, 255 },
929     { "LightSlateGray", 119, 136, 153 },
930     { "LightSlateGrey", 119, 136, 153 },
931     { "LightSteelBlue", 176, 196, 222 },
932     { "LightSteelBlue1", 202, 225, 255 },
933     { "LightSteelBlue2", 188, 210, 238 },
934     { "LightSteelBlue3", 162, 181, 205 },
935     { "LightSteelBlue4", 110, 123, 139 },
936     { "LightYellow", 255, 255, 224 },
937     { "LightYellow1", 255, 255, 224 },
938     { "LightYellow2", 238, 238, 209 },
939     { "LightYellow3", 205, 205, 180 },
940     { "LightYellow4", 139, 139, 122 },
941     { "lime green", 50, 205, 50 },
942     { "LimeGreen", 50, 205, 50 },
943     { "linen", 250, 240, 230 },
944     { "magenta", 255, 0, 255 },
945     { "magenta1", 255, 0, 255 },
946     { "magenta2", 238, 0, 238 },
947     { "magenta3", 205, 0, 205 },
948     { "magenta4", 139, 0, 139 },
949     { "maroon", 176, 48, 96 },
950     { "maroon1", 255, 52, 179 },
951     { "maroon2", 238, 48, 167 },
952     { "maroon3", 205, 41, 144 },
953     { "maroon4", 139, 28, 98 },
954     { "medium aquamarine", 102, 205, 170 },
955     { "medium blue", 0, 0, 205 },
956     { "medium orchid", 186, 85, 211 },
957     { "medium purple", 147, 112, 219 },
958     { "medium sea green", 60, 179, 113 },
959     { "medium slate blue", 123, 104, 238 },
960     { "medium spring green", 0, 250, 154 },
961     { "medium turquoise", 72, 209, 204 },
962     { "medium violet red", 199, 21, 133 },
963     { "MediumAquamarine", 102, 205, 170 },
964     { "MediumBlue", 0, 0, 205 },
965     { "MediumOrchid", 186, 85, 211 },
966     { "MediumOrchid1", 224, 102, 255 },
967     { "MediumOrchid2", 209, 95, 238 },
968     { "MediumOrchid3", 180, 82, 205 },
969     { "MediumOrchid4", 122, 55, 139 },
970     { "MediumPurple", 147, 112, 219 },
971     { "MediumPurple1", 171, 130, 255 },
972     { "MediumPurple2", 159, 121, 238 },
973     { "MediumPurple3", 137, 104, 205 },
974     { "MediumPurple4", 93, 71, 139 },
975     { "MediumSeaGreen", 60, 179, 113 },
976     { "MediumSlateBlue", 123, 104, 238 },
977     { "MediumSpringGreen", 0, 250, 154 },
978     { "MediumTurquoise", 72, 209, 204 },
979     { "MediumVioletRed", 199, 21, 133 },
980     { "midnight blue", 25, 25, 112 },
981     { "MidnightBlue", 25, 25, 112 },
982     { "mint cream", 245, 255, 250 },
983     { "MintCream", 245, 255, 250 },
984     { "misty rose", 255, 228, 225 },
985     { "MistyRose", 255, 228, 225 },
986     { "MistyRose1", 255, 228, 225 },
987     { "MistyRose2", 238, 213, 210 },
988     { "MistyRose3", 205, 183, 181 },
989     { "MistyRose4", 139, 125, 123 },
990     { "moccasin", 255, 228, 181 },
991     { "navajo white", 255, 222, 173 },
992     { "NavajoWhite", 255, 222, 173 },
993     { "NavajoWhite1", 255, 222, 173 },
994     { "NavajoWhite2", 238, 207, 161 },
995     { "NavajoWhite3", 205, 179, 139 },
996     { "NavajoWhite4", 139, 121, 94 },
997     { "navy", 0, 0, 128 },
998     { "navy blue", 0, 0, 128 },
999     { "NavyBlue", 0, 0, 128 },
1000     { "old lace", 253, 245, 230 },
1001     { "OldLace", 253, 245, 230 },
1002     { "olive drab", 107, 142, 35 },
1003     { "OliveDrab", 107, 142, 35 },
1004     { "OliveDrab1", 192, 255, 62 },
1005     { "OliveDrab2", 179, 238, 58 },
1006     { "OliveDrab3", 154, 205, 50 },
1007     { "OliveDrab4", 105, 139, 34 },
1008     { "orange", 255, 165, 0 },
1009     { "orange red", 255, 69, 0 },
1010     { "orange1", 255, 165, 0 },
1011     { "orange2", 238, 154, 0 },
1012     { "orange3", 205, 133, 0 },
1013     { "orange4", 139, 90, 0 },
1014     { "OrangeRed", 255, 69, 0 },
1015     { "OrangeRed1", 255, 69, 0 },
1016     { "OrangeRed2", 238, 64, 0 },
1017     { "OrangeRed3", 205, 55, 0 },
1018     { "OrangeRed4", 139, 37, 0 },
1019     { "orchid", 218, 112, 214 },
1020     { "orchid1", 255, 131, 250 },
1021     { "orchid2", 238, 122, 233 },
1022     { "orchid3", 205, 105, 201 },
1023     { "orchid4", 139, 71, 137 },
1024     { "pale goldenrod", 238, 232, 170 },
1025     { "pale green", 152, 251, 152 },
1026     { "pale turquoise", 175, 238, 238 },
1027     { "pale violet red", 219, 112, 147 },
1028     { "PaleGoldenrod", 238, 232, 170 },
1029     { "PaleGreen", 152, 251, 152 },
1030     { "PaleGreen1", 154, 255, 154 },
1031     { "PaleGreen2", 144, 238, 144 },
1032     { "PaleGreen3", 124, 205, 124 },
1033     { "PaleGreen4", 84, 139, 84 },
1034     { "PaleTurquoise", 175, 238, 238 },
1035     { "PaleTurquoise1", 187, 255, 255 },
1036     { "PaleTurquoise2", 174, 238, 238 },
1037     { "PaleTurquoise3", 150, 205, 205 },
1038     { "PaleTurquoise4", 102, 139, 139 },
1039     { "PaleVioletRed", 219, 112, 147 },
1040     { "PaleVioletRed1", 255, 130, 171 },
1041     { "PaleVioletRed2", 238, 121, 159 },
1042     { "PaleVioletRed3", 205, 104, 137 },
1043     { "PaleVioletRed4", 139, 71, 93 },
1044     { "papaya whip", 255, 239, 213 },
1045     { "PapayaWhip", 255, 239, 213 },
1046     { "peach puff", 255, 218, 185 },
1047     { "PeachPuff", 255, 218, 185 },
1048     { "PeachPuff1", 255, 218, 185 },
1049     { "PeachPuff2", 238, 203, 173 },
1050     { "PeachPuff3", 205, 175, 149 },
1051     { "PeachPuff4", 139, 119, 101 },
1052     { "peru", 205, 133, 63 },
1053     { "pink", 255, 192, 203 },
1054     { "pink1", 255, 181, 197 },
1055     { "pink2", 238, 169, 184 },
1056     { "pink3", 205, 145, 158 },
1057     { "pink4", 139, 99, 108 },
1058     { "plum", 221, 160, 221 },
1059     { "plum1", 255, 187, 255 },
1060     { "plum2", 238, 174, 238 },
1061     { "plum3", 205, 150, 205 },
1062     { "plum4", 139, 102, 139 },
1063     { "powder blue", 176, 224, 230 },
1064     { "PowderBlue", 176, 224, 230 },
1065     { "purple", 160, 32, 240 },
1066     { "purple1", 155, 48, 255 },
1067     { "purple2", 145, 44, 238 },
1068     { "purple3", 125, 38, 205 },
1069     { "purple4", 85, 26, 139 },
1070     { "red", 255, 0, 0 },
1071     { "red1", 255, 0, 0 },
1072     { "red2", 238, 0, 0 },
1073     { "red3", 205, 0, 0 },
1074     { "red4", 139, 0, 0 },
1075     { "rosy brown", 188, 143, 143 },
1076     { "RosyBrown", 188, 143, 143 },
1077     { "RosyBrown1", 255, 193, 193 },
1078     { "RosyBrown2", 238, 180, 180 },
1079     { "RosyBrown3", 205, 155, 155 },
1080     { "RosyBrown4", 139, 105, 105 },
1081     { "royal blue", 65, 105, 225 },
1082     { "RoyalBlue", 65, 105, 225 },
1083     { "RoyalBlue1", 72, 118, 255 },
1084     { "RoyalBlue2", 67, 110, 238 },
1085     { "RoyalBlue3", 58, 95, 205 },
1086     { "RoyalBlue4", 39, 64, 139 },
1087     { "saddle brown", 139, 69, 19 },
1088     { "SaddleBrown", 139, 69, 19 },
1089     { "salmon", 250, 128, 114 },
1090     { "salmon1", 255, 140, 105 },
1091     { "salmon2", 238, 130, 98 },
1092     { "salmon3", 205, 112, 84 },
1093     { "salmon4", 139, 76, 57 },
1094     { "sandy brown", 244, 164, 96 },
1095     { "SandyBrown", 244, 164, 96 },
1096     { "sea green", 46, 139, 87 },
1097     { "SeaGreen", 46, 139, 87 },
1098     { "SeaGreen1", 84, 255, 159 },
1099     { "SeaGreen2", 78, 238, 148 },
1100     { "SeaGreen3", 67, 205, 128 },
1101     { "SeaGreen4", 46, 139, 87 },
1102     { "seashell", 255, 245, 238 },
1103     { "seashell1", 255, 245, 238 },
1104     { "seashell2", 238, 229, 222 },
1105     { "seashell3", 205, 197, 191 },
1106     { "seashell4", 139, 134, 130 },
1107     { "sienna", 160, 82, 45 },
1108     { "sienna1", 255, 130, 71 },
1109     { "sienna2", 238, 121, 66 },
1110     { "sienna3", 205, 104, 57 },
1111     { "sienna4", 139, 71, 38 },
1112     { "sky blue", 135, 206, 235 },
1113     { "SkyBlue", 135, 206, 235 },
1114     { "SkyBlue1", 135, 206, 255 },
1115     { "SkyBlue2", 126, 192, 238 },
1116     { "SkyBlue3", 108, 166, 205 },
1117     { "SkyBlue4", 74, 112, 139 },
1118     { "slate blue", 106, 90, 205 },
1119     { "slate gray", 112, 128, 144 },
1120     { "slate grey", 112, 128, 144 },
1121     { "SlateBlue", 106, 90, 205 },
1122     { "SlateBlue1", 131, 111, 255 },
1123     { "SlateBlue2", 122, 103, 238 },
1124     { "SlateBlue3", 105, 89, 205 },
1125     { "SlateBlue4", 71, 60, 139 },
1126     { "SlateGray", 112, 128, 144 },
1127     { "SlateGray1", 198, 226, 255 },
1128     { "SlateGray2", 185, 211, 238 },
1129     { "SlateGray3", 159, 182, 205 },
1130     { "SlateGray4", 108, 123, 139 },
1131     { "SlateGrey", 112, 128, 144 },
1132     { "snow", 255, 250, 250 },
1133     { "snow1", 255, 250, 250 },
1134     { "snow2", 238, 233, 233 },
1135     { "snow3", 205, 201, 201 },
1136     { "snow4", 139, 137, 137 },
1137     { "spring green", 0, 255, 127 },
1138     { "SpringGreen", 0, 255, 127 },
1139     { "SpringGreen1", 0, 255, 127 },
1140     { "SpringGreen2", 0, 238, 118 },
1141     { "SpringGreen3", 0, 205, 102 },
1142     { "SpringGreen4", 0, 139, 69 },
1143     { "steel blue", 70, 130, 180 },
1144     { "SteelBlue", 70, 130, 180 },
1145     { "SteelBlue1", 99, 184, 255 },
1146     { "SteelBlue2", 92, 172, 238 },
1147     { "SteelBlue3", 79, 148, 205 },
1148     { "SteelBlue4", 54, 100, 139 },
1149     { "tan", 210, 180, 140 },
1150     { "tan1", 255, 165, 79 },
1151     { "tan2", 238, 154, 73 },
1152     { "tan3", 205, 133, 63 },
1153     { "tan4", 139, 90, 43 },
1154     { "thistle", 216, 191, 216 },
1155     { "thistle1", 255, 225, 255 },
1156     { "thistle2", 238, 210, 238 },
1157     { "thistle3", 205, 181, 205 },
1158     { "thistle4", 139, 123, 139 },
1159     { "tomato", 255, 99, 71 },
1160     { "tomato1", 255, 99, 71 },
1161     { "tomato2", 238, 92, 66 },
1162     { "tomato3", 205, 79, 57 },
1163     { "tomato4", 139, 54, 38 },
1164     { "turquoise", 64, 224, 208 },
1165     { "turquoise1", 0, 245, 255 },
1166     { "turquoise2", 0, 229, 238 },
1167     { "turquoise3", 0, 197, 205 },
1168     { "turquoise4", 0, 134, 139 },
1169     { "violet", 238, 130, 238 },
1170     { "violet red", 208, 32, 144 },
1171     { "VioletRed", 208, 32, 144 },
1172     { "VioletRed1", 255, 62, 150 },
1173     { "VioletRed2", 238, 58, 140 },
1174     { "VioletRed3", 205, 50, 120 },
1175     { "VioletRed4", 139, 34, 82 },
1176     { "wheat", 245, 222, 179 },
1177     { "wheat1", 255, 231, 186 },
1178     { "wheat2", 238, 216, 174 },
1179     { "wheat3", 205, 186, 150 },
1180     { "wheat4", 139, 126, 102 },
1181     { "white", 255, 255, 255 },
1182     { "white smoke", 245, 245, 245 },
1183     { "WhiteSmoke", 245, 245, 245 },
1184     { "yellow", 255, 255, 0 },
1185     { "yellow green", 154, 205, 50 },
1186     { "yellow1", 255, 255, 0 },
1187     { "yellow2", 238, 238, 0 },
1188     { "yellow3", 205, 205, 0 },
1189     { "yellow4", 139, 139, 0 },
1190     { "YellowGreen", 154, 205, 50 }
1191 };
1192  
1193 #define numXColors (sizeof (xColors) / sizeof (*xColors))
1194  
1195 /*
1196  *----------------------------------------------------------------------
1197  *
1198  * FindColor --
1199  *
1200  *      This routine finds the color entry that corresponds to the
1201  *      specified color.
1202  *
1203  * Results:
1204  *      Returns non-zero on success.  The RGB values of the XColor
1205  *      will be initialized to the proper values on success.
1206  *
1207  * Side effects:
1208  *      None.
1209  *
1210  *----------------------------------------------------------------------
1211  */
1212
1213 static int
1214 compare_xcolor_entries (const void *a, const void *b)
1215 {
1216   return strcasecmp ((const char *) a, ((const XColorEntry *) b)->name);
1217 }
1218
1219 static int
1220 FindColor(const char *name,
1221           GdkColor   *colorPtr)
1222 {
1223   XColorEntry *found;
1224
1225   found = bsearch (name, xColors, numXColors, sizeof (XColorEntry),
1226                    compare_xcolor_entries);
1227   if (found == NULL)
1228     return 0;
1229   
1230   colorPtr->red = (found->red * 65535) / 255;
1231   colorPtr->green = (found->green * 65535) / 255;
1232   colorPtr->blue = (found->blue * 65535) / 255;
1233   return 1;
1234 }
1235
1236 /*
1237  *----------------------------------------------------------------------
1238  *
1239  * parse_color --
1240  *
1241  *      Partial implementation of X color name parsing interface.
1242  *
1243  * Results:
1244  *      Returns non-zero on success.
1245  *
1246  * Side effects:
1247  *      None.
1248  *
1249  *----------------------------------------------------------------------
1250  */
1251
1252 gboolean
1253 parse_color(Colormap    map,
1254             const char *spec,
1255             GdkColor   *colorPtr)
1256 {
1257     if (spec[0] == '#') {
1258         char fmt[16];
1259         int i, red, green, blue;
1260
1261         if ((i = strlen(spec+1))%3) {
1262             return 0;
1263         }
1264         i /= 3;
1265
1266         sprintf(fmt, "%%%dx%%%dx%%%dx", i, i, i);
1267         if (sscanf(spec+1, fmt, &red, &green, &blue) != 3) {
1268             return 0;
1269         }
1270         if (i == 4)
1271           {
1272             colorPtr->red = red;
1273             colorPtr->green = green;
1274             colorPtr->blue = blue;
1275           }
1276         else if (i == 1)
1277           {
1278             colorPtr->red = (red * 65535) / 15;
1279             colorPtr->green = (green * 65535) / 15;
1280             colorPtr->blue = (blue * 65535) / 15;
1281           }
1282         else if (i == 2)
1283           {
1284             colorPtr->red = (red * 65535) / 255;
1285             colorPtr->green = (green * 65535) / 255;
1286             colorPtr->blue = (blue * 65535) / 255;
1287           }
1288         else /* if (i == 3) */
1289           {
1290             colorPtr->red = (red * 65535) / 4095;
1291             colorPtr->green = (green * 65535) / 4095;
1292             colorPtr->blue = (blue * 65535) / 4095;
1293           }
1294     } else {
1295         if (!FindColor(spec, colorPtr)) {
1296             return 0;
1297         }
1298     }
1299     return 1;
1300 }
1301
1302 /* End of code from Tk8.0 */
1303
1304 static Colormap
1305 default_colormap ()
1306 {
1307   static Colormap colormap;
1308   gint i;
1309
1310   if (colormap)
1311     return colormap;
1312
1313   colormap = create_colormap ( NULL, NULL, FALSE);
1314   return colormap;
1315 }
1316
1317 GdkColormap*
1318 gdk_colormap_new (GdkVisual *visual,
1319                   gint       private_cmap)
1320 {
1321   GdkColormap *colormap;
1322   GdkColormapPrivateWin32 *private;
1323   Visual *xvisual;
1324   int size;
1325   int i;
1326
1327   g_return_val_if_fail (visual != NULL, NULL);
1328
1329   private = g_new (GdkColormapPrivateWin32, 1);
1330   colormap = (GdkColormap*) private;
1331
1332   private->base.visual = visual;
1333   private->base.ref_count = 1;
1334
1335   private->hash = NULL;
1336   private->last_sync_time = 0;
1337   private->info = NULL;
1338   
1339   xvisual = ((GdkVisualPrivate*) visual)->xvisual;
1340
1341   colormap->size = visual->colormap_size;
1342   colormap->colors = g_new (GdkColor, colormap->size);
1343
1344   switch (visual->type)
1345     {
1346     case GDK_VISUAL_GRAYSCALE:
1347     case GDK_VISUAL_PSEUDO_COLOR:
1348       private->info = g_new0 (GdkColorInfo, colormap->size);
1349       
1350       private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
1351                                         (GCompareFunc) gdk_color_equal);
1352       
1353       private->private_val = private_cmap;
1354       private->xcolormap = create_colormap (gdk_root_window, xvisual,
1355                                             private_cmap);
1356
1357       if (private_cmap)
1358         {
1359           PALETTEENTRY pal[256];
1360           guint npal;
1361
1362           npal = GetPaletteEntries (private->xcolormap->palette, 0, colormap->size, pal);
1363           for (i = 0; i < colormap->size; i++)
1364             {
1365               colormap->colors[i].pixel = i;
1366               if (i >= npal)
1367                 {
1368                   colormap->colors[i].red =
1369                     colormap->colors[i].green =
1370                     colormap->colors[i].blue = 0;
1371                 }
1372               else
1373                 {
1374                   colormap->colors[i].red = (pal[i].peRed * 65535) / 255;
1375                   colormap->colors[i].green = (pal[i].peGreen * 65525) / 255;
1376                   colormap->colors[i].blue = (pal[i].peBlue * 65535) / 255;
1377                 }
1378             }
1379           gdk_colormap_change (colormap, colormap->size);
1380         }
1381       break;
1382
1383     case GDK_VISUAL_STATIC_GRAY:
1384     case GDK_VISUAL_STATIC_COLOR:
1385     case GDK_VISUAL_TRUE_COLOR:
1386       private->private_val = FALSE;
1387       private->xcolormap = create_colormap (gdk_root_window,
1388                                             xvisual, FALSE);
1389       break;
1390     }
1391
1392   gdk_colormap_add (colormap);
1393
1394   return colormap;
1395 }
1396
1397 void
1398 _gdk_colormap_real_destroy (GdkColormap *colormap)
1399 {
1400   GdkColormapPrivateWin32 *private = (GdkColormapPrivateWin32 *) colormap;
1401
1402   g_return_if_fail (colormap != NULL);
1403   g_return_if_fail (private->base.ref_count == 0);
1404
1405   gdk_colormap_remove (colormap);
1406   free_colormap (private->xcolormap);
1407
1408   if (private->hash)
1409     g_hash_table_destroy (private->hash);
1410   
1411   g_free (private->info);
1412   g_free (colormap->colors);
1413   g_free (colormap);
1414 }
1415
1416 #define MIN_SYNC_TIME 2
1417
1418 void
1419 gdk_colormap_sync (GdkColormap *colormap,
1420                    gboolean     force)
1421 {
1422   time_t current_time;
1423   GdkColormapPrivateWin32 *private = (GdkColormapPrivateWin32 *) colormap;
1424   XColor *xpalette;
1425   gint nlookup;
1426   gint i;
1427   
1428   g_return_if_fail (colormap != NULL);
1429
1430   current_time = time (NULL);
1431   if (!force && ((current_time - private->last_sync_time) < MIN_SYNC_TIME))
1432     return;
1433
1434   private->last_sync_time = current_time;
1435
1436   nlookup = 0;
1437   xpalette = g_new (XColor, colormap->size);
1438   
1439   nlookup = GetPaletteEntries (private->xcolormap->palette,
1440                                0, colormap->size, xpalette);
1441   
1442   for (i = 0; i < nlookup; i++)
1443     {
1444       colormap->colors[i].pixel = i;
1445       colormap->colors[i].red = (xpalette[i].peRed * 65535) / 255;
1446       colormap->colors[i].green = (xpalette[i].peGreen * 65535) / 255;
1447       colormap->colors[i].blue = (xpalette[i].peBlue * 65535) / 255;
1448     }
1449
1450   for (  ; i < colormap->size; i++)
1451     {
1452       colormap->colors[i].pixel = i;
1453       colormap->colors[i].red = 0;
1454       colormap->colors[i].green = 0;
1455       colormap->colors[i].blue = 0;
1456     }
1457
1458   g_free (xpalette);
1459 }
1460                    
1461 GdkColormap*
1462 gdk_colormap_get_system (void)
1463 {
1464   static GdkColormap *colormap = NULL;
1465   GdkColormapPrivateWin32 *private;
1466   gint i;
1467
1468   if (!colormap)
1469     {
1470       private = g_new (GdkColormapPrivateWin32, 1);
1471       colormap = (GdkColormap*) private;
1472
1473       private->xcolormap = default_colormap ();
1474       private->base.visual = gdk_visual_get_system ();
1475       private->private_val = FALSE;
1476       private->base.ref_count = 1;
1477
1478       private->hash = NULL;
1479       private->last_sync_time = 0;
1480       private->info = NULL;
1481
1482       colormap->colors = NULL;
1483       colormap->size = private->base.visual->colormap_size;
1484
1485       if ((private->base.visual->type == GDK_VISUAL_GRAYSCALE) ||
1486           (private->base.visual->type == GDK_VISUAL_PSEUDO_COLOR))
1487         {
1488           private->info = g_new0 (GdkColorInfo, colormap->size);
1489           colormap->colors = g_new (GdkColor, colormap->size);
1490           
1491           private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
1492                                             (GCompareFunc) gdk_color_equal);
1493
1494           gdk_colormap_sync (colormap, TRUE);
1495         }
1496       gdk_colormap_add (colormap);
1497     }
1498
1499   return colormap;
1500 }
1501
1502 gint
1503 gdk_colormap_get_system_size (void)
1504 {
1505   gint bitspixel;
1506   
1507   bitspixel = GetDeviceCaps (gdk_DC, BITSPIXEL);
1508
1509   if (bitspixel == 1)
1510     return 2;
1511   else if (bitspixel == 4)
1512     return 16;
1513   else if (bitspixel == 8)
1514     return 256;
1515   else if (bitspixel == 12)
1516     return 32;
1517   else if (bitspixel == 16)
1518     return 64;
1519   else /* if (bitspixel >= 24) */
1520     return 256;
1521 }
1522
1523 void
1524 gdk_colormap_change (GdkColormap *colormap,
1525                      gint         ncolors)
1526 {
1527   GdkColormapPrivateWin32 *private;
1528   GdkVisual *visual;
1529   XColor *palette;
1530   gint shift;
1531   int max_colors;
1532   int size;
1533   int i;
1534
1535   g_return_if_fail (colormap != NULL);
1536
1537   palette = g_new (XColor, ncolors);
1538
1539   private = (GdkColormapPrivateWin32 *) colormap;
1540   switch (private->base.visual->type)
1541     {
1542     case GDK_VISUAL_GRAYSCALE:
1543     case GDK_VISUAL_PSEUDO_COLOR:
1544       for (i = 0; i < ncolors; i++)
1545         {
1546           palette[i].peRed = (colormap->colors[i].red >> 8);
1547           palette[i].peGreen = (colormap->colors[i].green >> 8);
1548           palette[i].peBlue = (colormap->colors[i].blue >> 8);
1549           palette[i].peFlags = 0;
1550         }
1551
1552       if (SetPaletteEntries (private->xcolormap->palette,
1553                              0, ncolors, palette) == 0)
1554         WIN32_GDI_FAILED ("SetPaletteEntries");
1555       private->xcolormap->stale = TRUE;
1556       break;
1557
1558     default:
1559       break;
1560     }
1561
1562   g_free (palette);
1563 }
1564
1565 gboolean
1566 gdk_colors_alloc (GdkColormap   *colormap,
1567                   gint           contiguous,
1568                   gulong        *planes,
1569                   gint           nplanes,
1570                   gulong        *pixels,
1571                   gint           npixels)
1572 {
1573   GdkColormapPrivateWin32 *private;
1574   gint return_val;
1575   gint i;
1576
1577   g_return_val_if_fail (colormap != NULL, 0);
1578
1579   private = (GdkColormapPrivateWin32 *) colormap;
1580
1581   return_val = alloc_color_cells (private->xcolormap, contiguous,
1582                                   planes, nplanes, pixels, npixels);
1583
1584   if (return_val)
1585     {
1586       for (i=0; i<npixels; i++)
1587         {
1588           private->info[pixels[i]].ref_count++;
1589           private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
1590         }
1591     }
1592
1593   return return_val != 0;
1594 }
1595
1596 gboolean
1597 gdk_color_parse (const gchar *spec,
1598                  GdkColor *color)
1599 {
1600   Colormap xcolormap;
1601   XColor xcolor;
1602
1603   g_return_val_if_fail (spec != NULL, FALSE);
1604   g_return_val_if_fail (color != NULL, FALSE);
1605
1606   xcolormap = default_colormap ();
1607
1608   return parse_color (xcolormap, spec, color);
1609 }
1610
1611 /* This is almost identical to gdk_colormap_free_colors.
1612  * Keep them in sync!
1613  */
1614 void
1615 gdk_colors_free (GdkColormap *colormap,
1616                  gulong      *in_pixels,
1617                  gint         in_npixels,
1618                  gulong       planes)
1619 {
1620   GdkColormapPrivateWin32 *private;
1621   gulong *pixels;
1622   gint npixels = 0;
1623   gint i;
1624
1625   g_return_if_fail (colormap != NULL);
1626   g_return_if_fail (in_pixels != NULL);
1627
1628   private = (GdkColormapPrivateWin32 *) colormap;
1629
1630   if ((private->base.visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
1631       (private->base.visual->type != GDK_VISUAL_GRAYSCALE))
1632     return;
1633   
1634   pixels = g_new (gulong, in_npixels);
1635
1636   for (i=0; i<in_npixels; i++)
1637     {
1638       gulong pixel = in_pixels[i];
1639       
1640       if (private->info[pixel].ref_count)
1641         {
1642           private->info[pixel].ref_count--;
1643
1644           if (private->info[pixel].ref_count == 0)
1645             {
1646               pixels[npixels++] = pixel;
1647               if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
1648                 g_hash_table_remove (private->hash, &colormap->colors[pixel]);
1649               private->info[pixel].flags = 0;
1650             }
1651         }
1652     }
1653
1654   if (npixels)
1655     free_colors (private->xcolormap, pixels, npixels, planes);
1656
1657   g_free (pixels);
1658 }
1659
1660 /* This is almost identical to gdk_colors_free.
1661  * Keep them in sync!
1662  */
1663 void
1664 gdk_colormap_free_colors (GdkColormap *colormap,
1665                           GdkColor    *colors,
1666                           gint         ncolors)
1667 {
1668   GdkColormapPrivateWin32 *private;
1669   gulong *pixels;
1670   gint npixels = 0;
1671   gint i;
1672
1673   g_return_if_fail (colormap != NULL);
1674   g_return_if_fail (colors != NULL);
1675
1676   private = (GdkColormapPrivateWin32 *) colormap;
1677
1678   if ((private->base.visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
1679       (private->base.visual->type != GDK_VISUAL_GRAYSCALE))
1680     return;
1681
1682   pixels = g_new (gulong, ncolors);
1683
1684   for (i=0; i<ncolors; i++)
1685     {
1686       gulong pixel = colors[i].pixel;
1687       
1688       if (private->info[pixel].ref_count)
1689         {
1690           private->info[pixel].ref_count--;
1691
1692           if (private->info[pixel].ref_count == 0)
1693             {
1694               pixels[npixels++] = pixel;
1695               if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
1696                 g_hash_table_remove (private->hash, &colormap->colors[pixel]);
1697               private->info[pixel].flags = 0;
1698             }
1699         }
1700     }
1701   if (npixels)
1702     free_colors (private->xcolormap, pixels, npixels, 0);
1703   g_free (pixels);
1704 }
1705
1706 /********************
1707  * Color allocation *
1708  ********************/
1709
1710 /* Try to allocate a single color using alloc_color. If it succeeds,
1711  * cache the result in our colormap, and store in ret.
1712  */
1713 static gboolean 
1714 gdk_colormap_alloc1 (GdkColormap *colormap,
1715                      GdkColor    *color,
1716                      GdkColor    *ret)
1717 {
1718   GdkColormapPrivateWin32 *private;
1719   XColor xcolor;
1720
1721   private = (GdkColormapPrivateWin32 *) colormap;
1722
1723   xcolor.peRed = color->red >> 8;
1724   xcolor.peGreen = color->green >> 8;
1725   xcolor.peBlue = color->blue >> 8;
1726
1727   if (alloc_color (private->xcolormap, &xcolor, &ret->pixel))
1728     {
1729       ret->red = (xcolor.peRed * 65535) / 255;
1730       ret->green = (xcolor.peGreen * 65535) / 255;;
1731       ret->blue = (xcolor.peBlue * 65535) / 255;
1732       
1733       if ((guint) ret->pixel < colormap->size)
1734         {
1735           if (private->info[ret->pixel].ref_count) /* got a duplicate */
1736             {
1737               /* XXX */
1738             }
1739           else
1740             {
1741               colormap->colors[ret->pixel] = *color;
1742               private->info[ret->pixel].ref_count = 1;
1743
1744               g_hash_table_insert (private->hash,
1745                                    &colormap->colors[ret->pixel],
1746                                    &colormap->colors[ret->pixel]);
1747             }
1748         }
1749       return TRUE;
1750     }
1751   else
1752     {
1753       return FALSE;
1754     }
1755 }
1756
1757 static gint
1758 gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
1759                                      GdkColor    *colors,
1760                                      gint         ncolors,
1761                                      gboolean     writeable,
1762                                      gboolean     best_match,
1763                                      gboolean    *success)
1764 {
1765   GdkColormapPrivateWin32 *private;
1766   gulong *pixels;
1767   Status status;
1768   gint i, index;
1769
1770   private = (GdkColormapPrivateWin32 *) colormap;
1771
1772   if (private->private_val)
1773     {
1774       index = 0;
1775       for (i=0; i<ncolors; i++)
1776         {
1777           while ((index < colormap->size) && (private->info[index].ref_count != 0))
1778             index++;
1779           
1780           if (index < colormap->size)
1781             {
1782               colors[i].pixel = index;
1783               success[i] = TRUE;
1784               private->info[index].ref_count++;
1785               private->info[i].flags |= GDK_COLOR_WRITEABLE;
1786             }
1787           else
1788             break;
1789         }
1790       return i;
1791     }
1792   else
1793     {
1794       pixels = g_new (gulong, ncolors);
1795       /* Allocation of a writeable color cells */
1796       
1797       status =  alloc_color_cells (private->xcolormap, FALSE, NULL,
1798                                    0, pixels, ncolors);
1799       if (status)
1800         {
1801           for (i=0; i<ncolors; i++)
1802             {
1803               colors[i].pixel = pixels[i];
1804               private->info[pixels[i]].ref_count++;
1805               private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
1806             }
1807         }
1808       
1809       g_free (pixels);
1810
1811       return status ? ncolors : 0; 
1812     }
1813 }
1814
1815 static gint
1816 gdk_colormap_alloc_colors_private (GdkColormap *colormap,
1817                                    GdkColor    *colors,
1818                                    gint         ncolors,
1819                                    gboolean     writeable,
1820                                    gboolean     best_match,
1821                                    gboolean    *success)
1822 {
1823   GdkColormapPrivateWin32 *private;
1824   gint i, index;
1825   XColor *store = g_new (XColor, ncolors);
1826   gint nstore = 0;
1827   gint nremaining = 0;
1828   
1829   private = (GdkColormapPrivateWin32 *) colormap;
1830   index = -1;
1831
1832   /* First, store the colors we have room for */
1833
1834   index = 0;
1835   for (i=0; i<ncolors; i++)
1836     {
1837       if (!success[i])
1838         {
1839           while ((index < colormap->size) && (private->info[index].ref_count != 0))
1840             index++;
1841
1842           if (index < colormap->size)
1843             {
1844               store[nstore].peRed = colors[i].red >> 8;
1845               store[nstore].peBlue = colors[i].blue >> 8;
1846               store[nstore].peGreen = colors[i].green >> 8;
1847               nstore++;
1848
1849               success[i] = TRUE;
1850
1851               colors[i].pixel = index;
1852               private->info[index].ref_count++;
1853             }
1854           else
1855             nremaining++;
1856         }
1857     }
1858   
1859   if (SetPaletteEntries (private->xcolormap->palette,
1860                          0, nstore, store) == 0)
1861     WIN32_GDI_FAILED ("SetPaletteEntries");
1862   private->xcolormap->stale = TRUE;
1863
1864   g_free (store);
1865
1866   if (nremaining > 0 && best_match)
1867     {
1868       /* Get best matches for remaining colors */
1869
1870       gchar *available = g_new (gchar, colormap->size);
1871       for (i = 0; i < colormap->size; i++)
1872         available[i] = TRUE;
1873
1874       for (i=0; i<ncolors; i++)
1875         {
1876           if (!success[i])
1877             {
1878               index = gdk_colormap_match_color (colormap, 
1879                                                 &colors[i], 
1880                                                 available);
1881               if (index != -1)
1882                 {
1883                   colors[i] = colormap->colors[index];
1884                   private->info[index].ref_count++;
1885
1886                   success[i] = TRUE;
1887                   nremaining--;
1888                 }
1889             }
1890         }
1891       g_free (available);
1892     }
1893
1894   return (ncolors - nremaining);
1895 }
1896
1897 static gint
1898 gdk_colormap_alloc_colors_shared (GdkColormap *colormap,
1899                                   GdkColor    *colors,
1900                                   gint         ncolors,
1901                                   gboolean     writeable,
1902                                   gboolean     best_match,
1903                                   gboolean    *success)
1904 {
1905   GdkColormapPrivateWin32 *private;
1906   gint i, index;
1907   gint nremaining = 0;
1908   gint nfailed = 0;
1909
1910   private = (GdkColormapPrivateWin32 *) colormap;
1911   index = -1;
1912
1913   for (i=0; i<ncolors; i++)
1914     {
1915       if (!success[i])
1916         {
1917           if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))
1918             success[i] = TRUE;
1919           else
1920             nremaining++;
1921         }
1922     }
1923
1924
1925   if (nremaining > 0 && best_match)
1926     {
1927       gchar *available = g_new (gchar, colormap->size);
1928       for (i = 0; i < colormap->size; i++)
1929         available[i] = ((private->info[i].ref_count == 0) ||
1930                         !(private->info[i].flags && GDK_COLOR_WRITEABLE));
1931       gdk_colormap_sync (colormap, FALSE);
1932       
1933       while (nremaining > 0)
1934         {
1935           for (i=0; i<ncolors; i++)
1936             {
1937               if (!success[i])
1938                 {
1939                   index = gdk_colormap_match_color (colormap, &colors[i], available);
1940                   if (index != -1)
1941                     {
1942                       if (private->info[index].ref_count)
1943                         {
1944                           private->info[index].ref_count++;
1945                           colors[i] = colormap->colors[index];
1946                           success[i] = TRUE;
1947                           nremaining--;
1948                         }
1949                       else
1950                         {
1951                           if (gdk_colormap_alloc1 (colormap, 
1952                                                    &colormap->colors[index],
1953                                                    &colors[i]))
1954                             {
1955                               success[i] = TRUE;
1956                               nremaining--;
1957                               break;
1958                             }
1959                           else
1960                             {
1961                               available[index] = FALSE;
1962                             }
1963                         }
1964                     }
1965                   else
1966                     {
1967                       nfailed++;
1968                       nremaining--;
1969                       success[i] = 2; /* flag as permanent failure */
1970                     }
1971                 }
1972             }
1973         }
1974       g_free (available);
1975     }
1976
1977   /* Change back the values we flagged as permanent failures */
1978   if (nfailed > 0)
1979     {
1980       for (i=0; i<ncolors; i++)
1981         if (success[i] == 2)
1982           success[i] = FALSE;
1983       nremaining = nfailed;
1984     }
1985   
1986   return (ncolors - nremaining);
1987 }
1988
1989 static gint
1990 gdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,
1991                                        GdkColor    *colors,
1992                                        gint         ncolors,
1993                                        gboolean     writeable,
1994                                        gboolean     best_match,
1995                                        gboolean    *success)
1996 {
1997   GdkColormapPrivateWin32 *private;
1998   GdkColor *lookup_color;
1999   gint i;
2000   gint nremaining = 0;
2001
2002   private = (GdkColormapPrivateWin32 *) colormap;
2003
2004   /* Check for an exact match among previously allocated colors */
2005
2006   for (i=0; i<ncolors; i++)
2007     {
2008       if (!success[i])
2009         {
2010           lookup_color = g_hash_table_lookup (private->hash, &colors[i]);
2011           if (lookup_color)
2012             {
2013               private->info[lookup_color->pixel].ref_count++;
2014               colors[i].pixel = lookup_color->pixel;
2015               success[i] = TRUE;
2016             }
2017           else
2018             nremaining++;
2019         }
2020     }
2021
2022   /* If that failed, we try to allocate a new color, or approxmiate
2023    * with what we can get if best_match is TRUE.
2024    */
2025   if (nremaining > 0)
2026     {
2027       if (private->private_val)
2028         return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);
2029       else
2030         return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);
2031     }
2032   else
2033     return 0;
2034 }
2035
2036 gint
2037 gdk_colormap_alloc_colors (GdkColormap *colormap,
2038                            GdkColor    *colors,
2039                            gint         ncolors,
2040                            gboolean     writeable,
2041                            gboolean     best_match,
2042                            gboolean    *success)
2043 {
2044   GdkColormapPrivateWin32 *private;
2045   GdkVisual *visual;
2046   gint i;
2047   gint nremaining = 0;
2048   XColor xcolor;
2049
2050   g_return_val_if_fail (colormap != NULL, FALSE);
2051   g_return_val_if_fail (colors != NULL, FALSE);
2052
2053   private = (GdkColormapPrivateWin32 *) colormap;
2054
2055   for (i=0; i<ncolors; i++)
2056     {
2057       success[i] = FALSE;
2058     }
2059
2060   switch (private->base.visual->type)
2061     {
2062     case GDK_VISUAL_PSEUDO_COLOR:
2063     case GDK_VISUAL_GRAYSCALE:
2064       if (writeable)
2065         return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,
2066                                                     writeable, best_match, success);
2067       else
2068         return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,
2069                                                     writeable, best_match, success);
2070       break;
2071
2072     case GDK_VISUAL_TRUE_COLOR:
2073       visual = private->base.visual;
2074
2075       for (i=0; i<ncolors; i++)
2076         {
2077           colors[i].pixel = (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
2078                              ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +
2079                              ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));
2080           success[i] = TRUE;
2081         }
2082       break;
2083
2084     case GDK_VISUAL_STATIC_GRAY:
2085     case GDK_VISUAL_STATIC_COLOR:
2086       for (i=0; i<ncolors; i++)
2087         {
2088           xcolor.peRed = colors[i].red >> 8;
2089           xcolor.peGreen = colors[i].green >> 8;
2090           xcolor.peBlue = colors[i].blue >> 8;
2091           if (alloc_color (private->xcolormap, &xcolor, &colors[i].pixel))
2092             success[i] = TRUE;
2093           else
2094             nremaining++;
2095         }
2096       break;
2097     }
2098   return nremaining;
2099 }
2100
2101 gboolean
2102 gdk_color_change (GdkColormap *colormap,
2103                   GdkColor    *color)
2104 {
2105   GdkColormapPrivateWin32 *private;
2106   XColor xcolor;
2107
2108   g_return_val_if_fail (colormap != NULL, FALSE);
2109   g_return_val_if_fail (color != NULL, FALSE);
2110
2111   private = (GdkColormapPrivateWin32 *) colormap;
2112
2113   xcolor.peRed = color->red >> 8;
2114   xcolor.peGreen = color->green >> 8;
2115   xcolor.peBlue = color->blue >> 8;
2116
2117   if (SetPaletteEntries (private->xcolormap->palette,
2118                          color->pixel, 1, &xcolor) == 0)
2119     WIN32_GDI_FAILED ("SetPaletteEntries");
2120   private->xcolormap->stale = TRUE;
2121
2122   return TRUE;
2123 }
2124
2125 static gint
2126 gdk_colormap_match_color (GdkColormap *cmap,
2127                           GdkColor    *color,
2128                           const gchar *available)
2129 {
2130   GdkColor *colors;
2131   guint sum, max;
2132   gint rdiff, gdiff, bdiff;
2133   gint i, index;
2134
2135   g_return_val_if_fail (cmap != NULL, 0);
2136   g_return_val_if_fail (color != NULL, 0);
2137
2138   colors = cmap->colors;
2139   max = 3 * (65536);
2140   index = -1;
2141
2142   for (i = 0; i < cmap->size; i++)
2143     {
2144       if ((!available) || (available && available[i]))
2145         {
2146           rdiff = (color->red - colors[i].red);
2147           gdiff = (color->green - colors[i].green);
2148           bdiff = (color->blue - colors[i].blue);
2149
2150           sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
2151
2152           if (sum < max)
2153             {
2154               index = i;
2155               max = sum;
2156             }
2157         }
2158     }
2159
2160   return index;
2161 }
2162
2163 GdkColormap*
2164 gdk_colormap_lookup (Colormap xcolormap)
2165 {
2166   GdkColormap *cmap;
2167
2168   if (!colormap_hash)
2169     return NULL;
2170
2171   cmap = g_hash_table_lookup (colormap_hash, &xcolormap);
2172   return cmap;
2173 }
2174
2175 static void
2176 gdk_colormap_add (GdkColormap *cmap)
2177 {
2178   GdkColormapPrivateWin32 *private;
2179
2180   if (!colormap_hash)
2181     colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
2182                                       (GCompareFunc) gdk_colormap_cmp);
2183
2184   private = (GdkColormapPrivateWin32 *) cmap;
2185
2186   g_hash_table_insert (colormap_hash, &private->xcolormap, cmap);
2187 }
2188
2189 static void
2190 gdk_colormap_remove (GdkColormap *cmap)
2191 {
2192   GdkColormapPrivateWin32 *private;
2193
2194   if (!colormap_hash)
2195     colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
2196                                       (GCompareFunc) gdk_colormap_cmp);
2197
2198   private = (GdkColormapPrivateWin32 *) cmap;
2199
2200   g_hash_table_remove (colormap_hash, &private->xcolormap);
2201 }
2202
2203 static guint
2204 gdk_colormap_hash (Colormap *cmap)
2205 {
2206   return (guint) *cmap;
2207 }
2208
2209 static gint
2210 gdk_colormap_cmp (Colormap *a,
2211                   Colormap *b)
2212 {
2213   return (*a == *b);
2214 }
2215
2216 gchar *
2217 gdk_color_to_string (const GdkColor *color)
2218 {
2219   static char buf[100];
2220
2221   sprintf (buf, "(%.04x,%.04x,%.04x):%.06x",
2222            color->red, color->green, color->blue, color->pixel);
2223
2224   return buf;
2225 }