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