1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
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.
22 #include "gdkprivate.h"
26 static gint gdk_colormap_match_color (GdkColormap *cmap,
28 const gchar *available);
29 static void gdk_colormap_add (GdkColormap *cmap);
30 static void gdk_colormap_remove (GdkColormap *cmap);
31 static guint gdk_colormap_hash (Colormap *cmap);
32 static gint gdk_colormap_cmp (Colormap *a,
34 static void gdk_colormap_real_destroy (GdkColormap *colormap);
36 static GHashTable *colormap_hash = NULL;
40 gdk_colormap_new (GdkVisual *visual,
43 GdkColormap *colormap;
44 GdkColormapPrivate *private;
49 g_return_val_if_fail (visual != NULL, NULL);
51 private = g_new (GdkColormapPrivate, 1);
52 colormap = (GdkColormap*) private;
54 private->xdisplay = gdk_display;
55 private->visual = visual;
56 private->ref_count = 1;
59 private->last_sync_time = 0;
62 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
64 colormap->size = visual->colormap_size;
65 colormap->colors = g_new (GdkColor, colormap->size);
69 case GDK_VISUAL_GRAYSCALE:
70 case GDK_VISUAL_PSEUDO_COLOR:
71 private->info = g_new0 (GdkColorInfo, colormap->size);
72 colormap->colors = g_new (GdkColor, colormap->size);
74 private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
75 (GCompareFunc) gdk_color_equal);
77 private->private_val = private_cmap;
78 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
79 xvisual, (private_cmap) ? (AllocAll) : (AllocNone));
83 XColor *default_colors;
85 default_colors = g_new (XColor, colormap->size);
87 for (i = 0; i < colormap->size; i++)
88 default_colors[i].pixel = i;
90 XQueryColors (private->xdisplay,
91 DefaultColormap (private->xdisplay, gdk_screen),
92 default_colors, colormap->size);
94 for (i = 0; i < colormap->size; i++)
96 colormap->colors[i].pixel = default_colors[i].pixel;
97 colormap->colors[i].red = default_colors[i].red;
98 colormap->colors[i].green = default_colors[i].green;
99 colormap->colors[i].blue = default_colors[i].blue;
102 gdk_colormap_change (colormap, colormap->size);
104 g_free (default_colors);
108 case GDK_VISUAL_DIRECT_COLOR:
109 private->private_val = TRUE;
110 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
113 size = 1 << visual->red_prec;
114 for (i = 0; i < size; i++)
115 colormap->colors[i].red = i * 65535 / (size - 1);
117 size = 1 << visual->green_prec;
118 for (i = 0; i < size; i++)
119 colormap->colors[i].green = i * 65535 / (size - 1);
121 size = 1 << visual->blue_prec;
122 for (i = 0; i < size; i++)
123 colormap->colors[i].blue = i * 65535 / (size - 1);
125 gdk_colormap_change (colormap, colormap->size);
128 case GDK_VISUAL_STATIC_GRAY:
129 case GDK_VISUAL_STATIC_COLOR:
130 case GDK_VISUAL_TRUE_COLOR:
131 private->private_val = FALSE;
132 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
137 gdk_colormap_add (colormap);
143 gdk_colormap_real_destroy (GdkColormap *colormap)
145 GdkColormapPrivate *private = (GdkColormapPrivate*) colormap;
147 g_return_if_fail (colormap != NULL);
148 g_return_if_fail (private->ref_count > 0);
150 gdk_colormap_remove (colormap);
151 XFreeColormap (private->xdisplay, private->xcolormap);
154 g_hash_table_destroy (private->hash);
156 g_free (private->info);
157 g_free (colormap->colors);
162 gdk_colormap_ref (GdkColormap *cmap)
164 GdkColormapPrivate *private = (GdkColormapPrivate *)cmap;
165 g_return_val_if_fail (cmap != NULL, NULL);
167 private->ref_count += 1;
172 gdk_colormap_unref (GdkColormap *cmap)
174 GdkColormapPrivate *private = (GdkColormapPrivate *)cmap;
175 g_return_if_fail (cmap != NULL);
177 private->ref_count -= 1;
178 if (private->ref_count == 0)
179 gdk_colormap_real_destroy (cmap);
182 #define MIN_SYNC_TIME 2
185 gdk_colormap_sync (GdkColormap *colormap,
189 GdkColormapPrivate *private = (GdkColormapPrivate *)colormap;
194 g_return_if_fail (colormap != NULL);
196 current_time = time (NULL);
197 if (!force && ((current_time - private->last_sync_time) < MIN_SYNC_TIME))
200 private->last_sync_time = current_time;
203 xpalette = g_new (XColor, colormap->size);
205 for (i = 0; i < colormap->size; i++)
207 if (private->info[i].ref_count == 0)
209 xpalette[nlookup].pixel = i;
210 xpalette[nlookup].red = 0;
211 xpalette[nlookup].green = 0;
212 xpalette[nlookup].blue = 0;
217 XQueryColors (gdk_display, private->xcolormap, xpalette, nlookup);
219 for (i = 0; i < nlookup; i++)
221 gulong pixel = xpalette[i].pixel;
222 colormap->colors[pixel].pixel = pixel;
223 colormap->colors[pixel].red = xpalette[i].red;
224 colormap->colors[pixel].green = xpalette[i].green;
225 colormap->colors[pixel].blue = xpalette[i].blue;
233 gdk_colormap_get_system (void)
235 static GdkColormap *colormap = NULL;
236 GdkColormapPrivate *private;
240 private = g_new (GdkColormapPrivate, 1);
241 colormap = (GdkColormap*) private;
243 private->xdisplay = gdk_display;
244 private->xcolormap = DefaultColormap (gdk_display, gdk_screen);
245 private->visual = gdk_visual_get_system ();
246 private->private_val = FALSE;
247 private->ref_count = 1;
249 private->hash = NULL;
250 private->last_sync_time = 0;
251 private->info = NULL;
253 colormap->colors = NULL;
254 colormap->size = private->visual->colormap_size;
256 if ((private->visual->type == GDK_VISUAL_GRAYSCALE) ||
257 (private->visual->type == GDK_VISUAL_PSEUDO_COLOR))
259 private->info = g_new0 (GdkColorInfo, colormap->size);
260 colormap->colors = g_new (GdkColor, colormap->size);
262 private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
263 (GCompareFunc) gdk_color_equal);
265 gdk_colormap_sync (colormap, TRUE);
268 gdk_colormap_add (colormap);
275 gdk_colormap_get_system_size (void)
277 return DisplayCells (gdk_display, gdk_screen);
281 gdk_colormap_change (GdkColormap *colormap,
284 GdkColormapPrivate *private;
292 g_return_if_fail (colormap != NULL);
294 palette = g_new (XColor, ncolors);
296 private = (GdkColormapPrivate*) colormap;
297 switch (private->visual->type)
299 case GDK_VISUAL_GRAYSCALE:
300 case GDK_VISUAL_PSEUDO_COLOR:
301 for (i = 0; i < ncolors; i++)
303 palette[i].pixel = colormap->colors[i].pixel;
304 palette[i].red = colormap->colors[i].red;
305 palette[i].green = colormap->colors[i].green;
306 palette[i].blue = colormap->colors[i].blue;
307 palette[i].flags = DoRed | DoGreen | DoBlue;
310 XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
313 case GDK_VISUAL_DIRECT_COLOR:
314 visual = private->visual;
316 shift = visual->red_shift;
317 max_colors = 1 << visual->red_prec;
318 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
320 for (i = 0; i < size; i++)
322 palette[i].pixel = i << shift;
323 palette[i].red = colormap->colors[i].red;
324 palette[i].flags = DoRed;
327 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
329 shift = visual->green_shift;
330 max_colors = 1 << visual->green_prec;
331 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
333 for (i = 0; i < size; i++)
335 palette[i].pixel = i << shift;
336 palette[i].green = colormap->colors[i].green;
337 palette[i].flags = DoGreen;
340 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
342 shift = visual->blue_shift;
343 max_colors = 1 << visual->blue_prec;
344 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
346 for (i = 0; i < size; i++)
348 palette[i].pixel = i << shift;
349 palette[i].blue = colormap->colors[i].blue;
350 palette[i].flags = DoBlue;
353 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
364 gdk_colors_store (GdkColormap *colormap,
370 for (i = 0; i < ncolors; i++)
372 colormap->colors[i].pixel = colors[i].pixel;
373 colormap->colors[i].red = colors[i].red;
374 colormap->colors[i].green = colors[i].green;
375 colormap->colors[i].blue = colors[i].blue;
378 gdk_colormap_change (colormap, ncolors);
382 gdk_colors_alloc (GdkColormap *colormap,
389 GdkColormapPrivate *private;
393 g_return_val_if_fail (colormap != NULL, 0);
395 private = (GdkColormapPrivate*) colormap;
397 return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
398 contiguous, planes, nplanes, pixels, npixels);
402 for (i=0; i<npixels; i++)
404 private->info[pixels[i]].ref_count++;
405 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
412 /* This is almost identical to gdk_colormap_free_colors.
416 gdk_colors_free (GdkColormap *colormap,
421 GdkColormapPrivate *private;
426 g_return_if_fail (colormap != NULL);
427 g_return_if_fail (in_pixels != NULL);
429 private = (GdkColormapPrivate*) colormap;
431 if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
432 (private->visual->type != GDK_VISUAL_GRAYSCALE))
435 pixels = g_new (gulong, in_npixels);
437 for (i=0; i<in_npixels; i++)
439 gulong pixel = in_pixels[i];
441 if (private->info[pixel].ref_count)
443 private->info[pixel].ref_count--;
445 if (private->info[pixel].ref_count == 0)
447 pixels[npixels++] = pixel;
448 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
449 g_hash_table_remove (private->hash, &colormap->colors[in_pixels[i]]);
450 private->info[pixel].flags = 0;
456 XFreeColors (private->xdisplay, private->xcolormap,
457 pixels, npixels, planes);
462 *--------------------------------------------------------------
465 * Copy a color structure into new storage.
468 * "color" is the color struct to copy.
471 * A new color structure. Free it with gdk_color_free.
473 *--------------------------------------------------------------
476 static GMemChunk *color_chunk;
479 gdk_color_copy (GdkColor *color)
483 g_return_val_if_fail (color != NULL, NULL);
485 if (color_chunk == NULL)
486 color_chunk = g_mem_chunk_new ("colors",
491 new_color = g_chunk_new (GdkColor, color_chunk);
497 *--------------------------------------------------------------
500 * Free a color structure obtained from gdk_color_copy. Do not use
501 * with other color structures.
504 * "color" is the color struct to free.
506 *-------------------------------------------------------------- */
509 gdk_color_free (GdkColor *color)
511 g_assert (color_chunk != NULL);
512 g_return_if_fail (color != NULL);
514 g_mem_chunk_free (color_chunk, color);
518 gdk_color_white (GdkColormap *colormap,
523 g_return_val_if_fail (colormap != NULL, FALSE);
527 color->pixel = WhitePixel (gdk_display, gdk_screen);
529 color->green = 65535;
532 return_val = gdk_color_alloc (colormap, color);
541 gdk_color_black (GdkColormap *colormap,
546 g_return_val_if_fail (colormap != NULL, FALSE);
550 color->pixel = BlackPixel (gdk_display, gdk_screen);
555 return_val = gdk_color_alloc (colormap, color);
564 gdk_color_parse (const gchar *spec,
571 g_return_val_if_fail (spec != NULL, FALSE);
572 g_return_val_if_fail (color != NULL, FALSE);
574 xcolormap = DefaultColormap (gdk_display, gdk_screen);
576 if (XParseColor (gdk_display, xcolormap, spec, &xcolor))
579 color->red = xcolor.red;
580 color->green = xcolor.green;
581 color->blue = xcolor.blue;
589 /********************
591 ********************/
593 /* Try to allocate a single color using XAllocColor. If it succeeds,
594 * cache the result in our colormap, and store in ret.
597 gdk_colormap_alloc1 (GdkColormap *colormap,
601 GdkColormapPrivate *private;
604 private = (GdkColormapPrivate*) colormap;
606 xcolor.red = color->red;
607 xcolor.green = color->green;
608 xcolor.blue = color->blue;
609 xcolor.pixel = color->pixel;
610 xcolor.flags = DoRed | DoGreen | DoBlue;
612 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
614 ret->pixel = xcolor.pixel;
615 ret->red = xcolor.red;
616 ret->green = xcolor.green;
617 ret->blue = xcolor.blue;
619 if (ret->pixel < colormap->size)
621 if (private->info[ret->pixel].ref_count) /* got a duplicate */
623 XFreeColors (private->xdisplay, private->xcolormap,
628 colormap->colors[ret->pixel] = *color;
629 private->info[ret->pixel].ref_count = 1;
631 g_hash_table_insert (private->hash,
632 &colormap->colors[ret->pixel],
633 &colormap->colors[ret->pixel]);
645 gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
652 GdkColormapPrivate *private;
657 private = (GdkColormapPrivate*) colormap;
659 if (private->private_val)
662 for (i=0; i<ncolors; i++)
664 while ((index < colormap->size) && (private->info[index].ref_count != 0))
667 if (index < colormap->size)
669 colors[i].pixel = index;
671 private->info[index].ref_count++;
672 private->info[i].flags |= GDK_COLOR_WRITEABLE;
681 pixels = g_new (gulong, ncolors);
682 /* Allocation of a writeable color cells */
684 status = XAllocColorCells (private->xdisplay, private->xcolormap,
685 FALSE, NULL, 0, pixels, ncolors);
688 for (i=0; i<ncolors; i++)
690 colors[i].pixel = pixels[i];
691 private->info[pixels[i]].ref_count++;
692 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
698 return status ? ncolors : 0;
703 gdk_colormap_alloc_colors_private (GdkColormap *colormap,
710 GdkColormapPrivate *private;
712 XColor *store = g_new (XColor, ncolors);
716 private = (GdkColormapPrivate*) colormap;
719 /* First, store the colors we have room for */
722 for (i=0; i<ncolors; i++)
726 while ((index < colormap->size) && (private->info[index].ref_count != 0))
729 if (index < colormap->size)
731 store[nstore].red = colors[i].red;
732 store[nstore].blue = colors[i].blue;
733 store[nstore].green = colors[i].green;
734 store[nstore].pixel = index;
739 colors[i].pixel = index;
740 private->info[index].ref_count++;
747 XStoreColors (private->xdisplay, private->xcolormap, store, nstore);
750 if (nremaining > 0 && best_match)
752 /* Get best matches for remaining colors */
754 gchar *available = g_new (gchar, colormap->size);
755 for (i = 0; i < colormap->size; i++)
758 for (i=0; i<ncolors; i++)
762 index = gdk_colormap_match_color (colormap,
767 colors[i] = colormap->colors[index];
768 private->info[index].ref_count++;
778 return (ncolors - nremaining);
782 gdk_colormap_alloc_colors_shared (GdkColormap *colormap,
789 GdkColormapPrivate *private;
794 private = (GdkColormapPrivate*) colormap;
797 for (i=0; i<ncolors; i++)
801 if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))
809 if (nremaining > 0 && best_match)
811 gchar *available = g_new (gchar, colormap->size);
812 for (i = 0; i < colormap->size; i++)
813 available[i] = ((private->info[i].ref_count == 0) ||
814 !(private->info[i].flags && GDK_COLOR_WRITEABLE));
815 gdk_colormap_sync (colormap, FALSE);
817 while (nremaining > 0)
819 for (i=0; i<ncolors; i++)
823 index = gdk_colormap_match_color (colormap, &colors[i], available);
826 if (private->info[index].ref_count)
828 private->info[index].ref_count++;
829 colors[i] = colormap->colors[index];
835 if (gdk_colormap_alloc1 (colormap,
836 &colormap->colors[index],
845 available[index] = FALSE;
853 success[i] = 2; /* flag as permanent failure */
861 /* Change back the values we flagged as permanent failures */
864 for (i=0; i<ncolors; i++)
867 nremaining = nfailed;
870 return (ncolors - nremaining);
874 gdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,
881 GdkColormapPrivate *private;
882 GdkColor *lookup_color;
886 private = (GdkColormapPrivate*) colormap;
888 /* Check for an exact match among previously allocated colors */
890 for (i=0; i<ncolors; i++)
894 lookup_color = g_hash_table_lookup (private->hash, &colors[i]);
897 private->info[lookup_color->pixel].ref_count++;
898 colors[i].pixel = lookup_color->pixel;
906 /* If that failed, we try to allocate a new color, or approxmiate
907 * with what we can get if best_match is TRUE.
911 if (private->private_val)
912 return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);
914 return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);
921 gdk_colormap_alloc_colors (GdkColormap *colormap,
928 GdkColormapPrivate *private;
934 g_return_val_if_fail (colormap != NULL, FALSE);
935 g_return_val_if_fail (colors != NULL, FALSE);
937 private = (GdkColormapPrivate*) colormap;
939 for (i=0; i<ncolors; i++)
944 switch (private->visual->type)
946 case GDK_VISUAL_PSEUDO_COLOR:
947 case GDK_VISUAL_GRAYSCALE:
949 return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,
950 writeable, best_match, success);
952 return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,
953 writeable, best_match, success);
956 case GDK_VISUAL_DIRECT_COLOR:
957 case GDK_VISUAL_TRUE_COLOR:
958 visual = private->visual;
960 for (i=0; i<ncolors; i++)
962 colors[i].pixel = (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
963 ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +
964 ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));
969 case GDK_VISUAL_STATIC_GRAY:
970 case GDK_VISUAL_STATIC_COLOR:
971 for (i=0; i<ncolors; i++)
973 xcolor.red = colors[i].red;
974 xcolor.green = colors[i].green;
975 xcolor.blue = colors[i].blue;
976 xcolor.pixel = colors[i].pixel;
977 xcolor.flags = DoRed | DoGreen | DoBlue;
979 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
981 colors[i].pixel = xcolor.pixel;
993 gdk_colormap_alloc_color (GdkColormap *colormap,
1000 gdk_colormap_alloc_colors (colormap, color, 1, writeable, best_match,
1006 /* This is almost identical to gdk_colors_free.
1007 * Keep them in sync!
1010 gdk_colormap_free_colors (GdkColormap *colormap,
1014 GdkColormapPrivate *private;
1019 g_return_if_fail (colormap != NULL);
1020 g_return_if_fail (colors != NULL);
1022 private = (GdkColormapPrivate*) colormap;
1024 if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
1025 (private->visual->type != GDK_VISUAL_GRAYSCALE))
1028 pixels = g_new (gulong, ncolors);
1030 for (i=0; i<ncolors; i++)
1032 gulong pixel = colors[i].pixel;
1034 if (private->info[pixel].ref_count)
1036 private->info[pixel].ref_count--;
1038 if (private->info[pixel].ref_count == 0)
1040 pixels[npixels++] = pixel;
1041 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
1042 g_hash_table_remove (private->hash, &colors[i]);
1043 private->info[pixel].flags = 0;
1049 XFreeColors (private->xdisplay, private->xcolormap,
1050 pixels, npixels, 0);
1056 gdk_color_alloc (GdkColormap *colormap,
1061 gdk_colormap_alloc_colors (colormap, color, 1, FALSE, TRUE, &success);
1067 gdk_color_change (GdkColormap *colormap,
1070 GdkColormapPrivate *private;
1073 g_return_val_if_fail (colormap != NULL, FALSE);
1074 g_return_val_if_fail (color != NULL, FALSE);
1076 xcolor.pixel = color->pixel;
1077 xcolor.red = color->red;
1078 xcolor.green = color->green;
1079 xcolor.blue = color->blue;
1080 xcolor.flags = DoRed | DoGreen | DoBlue;
1082 private = (GdkColormapPrivate*) colormap;
1083 XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
1089 gdk_color_hash (const GdkColor *colora,
1090 const GdkColor *colorb)
1092 return ((colora->red) +
1093 (colora->green << 11) +
1094 (colora->blue << 22) +
1095 (colora->blue >> 6));
1099 gdk_color_equal (const GdkColor *colora,
1100 const GdkColor *colorb)
1102 g_return_val_if_fail (colora != NULL, FALSE);
1103 g_return_val_if_fail (colorb != NULL, FALSE);
1105 return ((colora->red == colorb->red) &&
1106 (colora->green == colorb->green) &&
1107 (colora->blue == colorb->blue));
1110 /* XXX: Do not use this function until it is fixed. An X Colormap
1111 * is useless unless we also have the visual.
1114 gdkx_colormap_get (Colormap xcolormap)
1116 GdkColormap *colormap;
1117 GdkColormapPrivate *private;
1119 colormap = gdk_colormap_lookup (xcolormap);
1123 if (xcolormap == DefaultColormap (gdk_display, gdk_screen))
1124 return gdk_colormap_get_system ();
1126 private = g_new (GdkColormapPrivate, 1);
1127 colormap = (GdkColormap*) private;
1129 private->xdisplay = gdk_display;
1130 private->xcolormap = xcolormap;
1131 private->visual = NULL;
1132 private->private_val = TRUE;
1134 /* To do the following safely, we would have to have some way of finding
1135 * out what the size or visual of the given colormap is. It seems
1136 * X doesn't allow this
1140 for (i = 0; i < 256; i++)
1142 xpalette[i].pixel = i;
1143 xpalette[i].red = 0;
1144 xpalette[i].green = 0;
1145 xpalette[i].blue = 0;
1148 XQueryColors (gdk_display, private->xcolormap, xpalette, 256);
1150 for (i = 0; i < 256; i++)
1152 colormap->colors[i].pixel = xpalette[i].pixel;
1153 colormap->colors[i].red = xpalette[i].red;
1154 colormap->colors[i].green = xpalette[i].green;
1155 colormap->colors[i].blue = xpalette[i].blue;
1159 colormap->colors = NULL;
1162 gdk_colormap_add (colormap);
1169 gdk_colormap_match_color (GdkColormap *cmap,
1171 const gchar *available)
1175 gint rdiff, gdiff, bdiff;
1178 g_return_val_if_fail (cmap != NULL, 0);
1179 g_return_val_if_fail (color != NULL, 0);
1181 colors = cmap->colors;
1185 for (i = 0; i < cmap->size; i++)
1187 if ((!available) || (available && available[i]))
1189 rdiff = (color->red - colors[i].red);
1190 gdiff = (color->green - colors[i].green);
1191 bdiff = (color->blue - colors[i].blue);
1193 sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
1208 gdk_colormap_lookup (Colormap xcolormap)
1215 cmap = g_hash_table_lookup (colormap_hash, &xcolormap);
1220 gdk_colormap_add (GdkColormap *cmap)
1222 GdkColormapPrivate *private;
1225 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1226 (GCompareFunc) gdk_colormap_cmp);
1228 private = (GdkColormapPrivate*) cmap;
1230 g_hash_table_insert (colormap_hash, &private->xcolormap, cmap);
1234 gdk_colormap_remove (GdkColormap *cmap)
1236 GdkColormapPrivate *private;
1239 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1240 (GCompareFunc) gdk_colormap_cmp);
1242 private = (GdkColormapPrivate*) cmap;
1244 g_hash_table_remove (colormap_hash, &private->xcolormap);
1248 gdk_colormap_hash (Colormap *cmap)
1254 gdk_colormap_cmp (Colormap *a,