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